@medalsocial/meda 2.0.0 → 2.2.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/dist/calendar/calendar-toolbar.d.ts +2 -0
- package/dist/calendar/calendar-toolbar.js +22 -0
- package/dist/calendar/calendar.d.ts +2 -0
- package/dist/calendar/calendar.js +55 -0
- package/dist/calendar/day-view.d.ts +2 -0
- package/dist/calendar/day-view.js +40 -0
- package/dist/calendar/index.d.ts +6 -0
- package/dist/calendar/index.js +7 -0
- package/dist/calendar/internal/date.d.ts +26 -0
- package/dist/calendar/internal/date.js +107 -0
- package/dist/calendar/internal/day-cell.d.ts +15 -0
- package/dist/calendar/internal/day-cell.js +38 -0
- package/dist/calendar/internal/event-pill.d.ts +13 -0
- package/dist/calendar/internal/event-pill.js +30 -0
- package/dist/calendar/internal/time-slot.d.ts +17 -0
- package/dist/calendar/internal/time-slot.js +23 -0
- package/dist/calendar/month-view.d.ts +2 -0
- package/dist/calendar/month-view.js +46 -0
- package/dist/calendar/public.d.ts +6 -0
- package/dist/calendar/public.js +8 -0
- package/dist/calendar/types.d.ts +113 -0
- package/dist/calendar/types.js +15 -0
- package/dist/calendar/week-view.d.ts +2 -0
- package/dist/calendar/week-view.js +39 -0
- package/dist/chat/turn-card.js +10 -5
- package/dist/email-builder/block-error-boundary.d.ts +16 -0
- package/dist/email-builder/block-error-boundary.js +21 -0
- package/dist/email-builder/block-palette.d.ts +7 -0
- package/dist/email-builder/block-palette.js +22 -0
- package/dist/email-builder/block-registry.d.ts +15 -0
- package/dist/email-builder/block-registry.js +157 -0
- package/dist/email-builder/block-renderer.d.ts +5 -0
- package/dist/email-builder/block-renderer.js +40 -0
- package/dist/email-builder/block-renderers/button.d.ts +4 -0
- package/dist/email-builder/block-renderers/button.js +26 -0
- package/dist/email-builder/block-renderers/columns.d.ts +5 -0
- package/dist/email-builder/block-renderers/columns.js +27 -0
- package/dist/email-builder/block-renderers/divider.d.ts +4 -0
- package/dist/email-builder/block-renderers/divider.js +14 -0
- package/dist/email-builder/block-renderers/footer.d.ts +4 -0
- package/dist/email-builder/block-renderers/footer.js +12 -0
- package/dist/email-builder/block-renderers/heading.d.ts +4 -0
- package/dist/email-builder/block-renderers/heading.js +19 -0
- package/dist/email-builder/block-renderers/image.d.ts +4 -0
- package/dist/email-builder/block-renderers/image.js +18 -0
- package/dist/email-builder/block-renderers/social.d.ts +4 -0
- package/dist/email-builder/block-renderers/social.js +19 -0
- package/dist/email-builder/block-renderers/spacer.d.ts +4 -0
- package/dist/email-builder/block-renderers/spacer.js +5 -0
- package/dist/email-builder/block-renderers/text.d.ts +4 -0
- package/dist/email-builder/block-renderers/text.js +17 -0
- package/dist/email-builder/builder-canvas.d.ts +15 -0
- package/dist/email-builder/builder-canvas.js +28 -0
- package/dist/email-builder/builder-header.d.ts +9 -0
- package/dist/email-builder/builder-header.js +8 -0
- package/dist/email-builder/builder-left-tabs.d.ts +11 -0
- package/dist/email-builder/builder-left-tabs.js +20 -0
- package/dist/email-builder/email-builder.d.ts +3 -0
- package/dist/email-builder/email-builder.js +94 -0
- package/dist/email-builder/envelope-card.d.ts +7 -0
- package/dist/email-builder/envelope-card.js +16 -0
- package/dist/email-builder/floating-bar.d.ts +13 -0
- package/dist/email-builder/floating-bar.js +9 -0
- package/dist/email-builder/index.d.ts +4 -0
- package/dist/email-builder/index.js +12 -0
- package/dist/email-builder/internal/builder-state-utils.d.ts +7 -0
- package/dist/email-builder/internal/builder-state-utils.js +53 -0
- package/dist/email-builder/internal/dnd-wrapper.d.ts +10 -0
- package/dist/email-builder/internal/dnd-wrapper.js +9 -0
- package/dist/email-builder/internal/email-font-options.d.ts +5 -0
- package/dist/email-builder/internal/email-font-options.js +12 -0
- package/dist/email-builder/mobile-drawers.d.ts +10 -0
- package/dist/email-builder/mobile-drawers.js +7 -0
- package/dist/email-builder/mobile-tab-bar.d.ts +10 -0
- package/dist/email-builder/mobile-tab-bar.js +9 -0
- package/dist/email-builder/property-editors/_shared.d.ts +58 -0
- package/dist/email-builder/property-editors/_shared.js +54 -0
- package/dist/email-builder/property-editors/button-editor.d.ts +7 -0
- package/dist/email-builder/property-editors/button-editor.js +10 -0
- package/dist/email-builder/property-editors/columns-editor.d.ts +7 -0
- package/dist/email-builder/property-editors/columns-editor.js +15 -0
- package/dist/email-builder/property-editors/divider-editor.d.ts +7 -0
- package/dist/email-builder/property-editors/divider-editor.js +10 -0
- package/dist/email-builder/property-editors/footer-editor.d.ts +7 -0
- package/dist/email-builder/property-editors/footer-editor.js +6 -0
- package/dist/email-builder/property-editors/heading-editor.d.ts +7 -0
- package/dist/email-builder/property-editors/heading-editor.js +16 -0
- package/dist/email-builder/property-editors/image-editor.d.ts +8 -0
- package/dist/email-builder/property-editors/image-editor.js +17 -0
- package/dist/email-builder/property-editors/social-editor.d.ts +7 -0
- package/dist/email-builder/property-editors/social-editor.js +18 -0
- package/dist/email-builder/property-editors/spacer-editor.d.ts +7 -0
- package/dist/email-builder/property-editors/spacer-editor.js +6 -0
- package/dist/email-builder/property-editors/text-editor.d.ts +13 -0
- package/dist/email-builder/property-editors/text-editor.js +8 -0
- package/dist/email-builder/property-inspector.d.ts +11 -0
- package/dist/email-builder/property-inspector.js +42 -0
- package/dist/email-builder/public.d.ts +1 -0
- package/dist/email-builder/public.js +3 -0
- package/dist/email-builder/render-to-email-html.d.ts +11 -0
- package/dist/email-builder/render-to-email-html.js +220 -0
- package/dist/email-builder/starter-shell.d.ts +3 -0
- package/dist/email-builder/starter-shell.js +21 -0
- package/dist/email-builder/types.d.ts +182 -0
- package/dist/email-builder/types.js +41 -0
- package/dist/email-builder/view-controls.d.ts +10 -0
- package/dist/email-builder/view-controls.js +12 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/lib/format-time.js +2 -3
- package/dist/marketing/index.d.ts +10 -1
- package/dist/marketing/index.js +9 -0
- package/dist/marketing/marketing-bento-card.d.ts +2 -0
- package/dist/marketing/marketing-bento-card.js +24 -0
- package/dist/marketing/marketing-bento-grid.d.ts +2 -0
- package/dist/marketing/marketing-bento-grid.js +12 -0
- package/dist/marketing/marketing-faq.d.ts +2 -0
- package/dist/marketing/marketing-faq.js +12 -0
- package/dist/marketing/marketing-footer.d.ts +2 -0
- package/dist/marketing/marketing-footer.js +5 -0
- package/dist/marketing/marketing-header-logo.d.ts +10 -0
- package/dist/marketing/marketing-header-logo.js +6 -0
- package/dist/marketing/marketing-header.d.ts +2 -0
- package/dist/marketing/marketing-header.js +26 -0
- package/dist/marketing/marketing-nav-item.d.ts +4 -0
- package/dist/marketing/marketing-nav-item.js +10 -0
- package/dist/marketing/marketing-shell.d.ts +2 -0
- package/dist/marketing/marketing-shell.js +5 -0
- package/dist/marketing/marketing-trust-bar.d.ts +2 -0
- package/dist/marketing/marketing-trust-bar.js +5 -0
- package/dist/marketing/public.d.ts +1 -1
- package/dist/marketing/types.d.ts +99 -0
- package/dist/post-preview/index.d.ts +4 -0
- package/dist/post-preview/index.js +7 -0
- package/dist/post-preview/internal/avatar.d.ts +12 -0
- package/dist/post-preview/internal/avatar.js +21 -0
- package/dist/post-preview/internal/format-content.d.ts +12 -0
- package/dist/post-preview/internal/format-content.js +32 -0
- package/dist/post-preview/internal/platform-meta.d.ts +10 -0
- package/dist/post-preview/internal/platform-meta.js +18 -0
- package/dist/post-preview/internal/textarea.d.ts +8 -0
- package/dist/post-preview/internal/textarea.js +12 -0
- package/dist/post-preview/internal/use-swipe.d.ts +17 -0
- package/dist/post-preview/internal/use-swipe.js +29 -0
- package/dist/post-preview/platforms/bluesky.d.ts +15 -0
- package/dist/post-preview/platforms/bluesky.js +21 -0
- package/dist/post-preview/platforms/discord.d.ts +44 -0
- package/dist/post-preview/platforms/discord.js +34 -0
- package/dist/post-preview/platforms/facebook.d.ts +23 -0
- package/dist/post-preview/platforms/facebook.js +26 -0
- package/dist/post-preview/platforms/generic.d.ts +22 -0
- package/dist/post-preview/platforms/generic.js +30 -0
- package/dist/post-preview/platforms/google-business.d.ts +18 -0
- package/dist/post-preview/platforms/google-business.js +24 -0
- package/dist/post-preview/platforms/index.d.ts +24 -0
- package/dist/post-preview/platforms/index.js +13 -0
- package/dist/post-preview/platforms/instagram.d.ts +31 -0
- package/dist/post-preview/platforms/instagram.js +104 -0
- package/dist/post-preview/platforms/linkedin.d.ts +52 -0
- package/dist/post-preview/platforms/linkedin.js +140 -0
- package/dist/post-preview/platforms/telegram.d.ts +46 -0
- package/dist/post-preview/platforms/telegram.js +44 -0
- package/dist/post-preview/platforms/threads.d.ts +19 -0
- package/dist/post-preview/platforms/threads.js +26 -0
- package/dist/post-preview/platforms/tiktok.d.ts +18 -0
- package/dist/post-preview/platforms/tiktok.js +25 -0
- package/dist/post-preview/platforms/twitter.d.ts +40 -0
- package/dist/post-preview/platforms/twitter.js +137 -0
- package/dist/post-preview/platforms/youtube.d.ts +17 -0
- package/dist/post-preview/platforms/youtube.js +23 -0
- package/dist/post-preview/post-preview.d.ts +29 -0
- package/dist/post-preview/post-preview.js +70 -0
- package/dist/post-preview/public.d.ts +1 -0
- package/dist/post-preview/public.js +6 -0
- package/dist/post-preview/types.d.ts +82 -0
- package/dist/post-preview/types.js +1 -0
- package/dist/primitives/filter-rail.js +17 -2
- package/dist/shell/command-palette.js +2 -0
- package/dist/shell/drag-mode-banner.js +4 -0
- package/dist/shell/extras/shell-scrollable-content.js +2 -2
- package/dist/shell/extras/workbench-layout.js +24 -13
- package/dist/shell/internal/mobile-bottom-nav.js +1 -0
- package/dist/shell/internal/mobile-drawers.js +5 -0
- package/dist/shell/rail-drop-slot.js +20 -3
- package/dist/shell/rail-drop-zones.js +2 -0
- package/dist/shell/right-panel.js +10 -1
- package/dist/shell/shell-header.js +7 -1
- package/dist/shell/theme-next-themes.js +7 -2
- package/dist/shell/theme.js +7 -1
- package/dist/shell/use-shell-viewport.js +2 -0
- package/dist/timeline/lane-timeline.js +1 -1
- package/dist/timeline/scrub-bar.js +1 -1
- package/dist/timeline/timeline-tape.js +8 -5
- package/dist/voice/voice-orb-scene.js +4 -4
- package/dist/voice/voice-status-pill.js +8 -7
- package/dist/workflow-builder/edges/default-edge.d.ts +10 -0
- package/dist/workflow-builder/edges/default-edge.js +21 -0
- package/dist/workflow-builder/edges/index.d.ts +3 -0
- package/dist/workflow-builder/edges/index.js +5 -0
- package/dist/workflow-builder/index.d.ts +5 -0
- package/dist/workflow-builder/index.js +12 -0
- package/dist/workflow-builder/internal/trigger-icons.d.ts +4 -0
- package/dist/workflow-builder/internal/trigger-icons.js +43 -0
- package/dist/workflow-builder/internal/trigger-sentence.d.ts +14 -0
- package/dist/workflow-builder/internal/trigger-sentence.js +50 -0
- package/dist/workflow-builder/nodes/action-node.d.ts +3 -0
- package/dist/workflow-builder/nodes/action-node.js +7 -0
- package/dist/workflow-builder/nodes/base-node.d.ts +20 -0
- package/dist/workflow-builder/nodes/base-node.js +18 -0
- package/dist/workflow-builder/nodes/condition-node.d.ts +3 -0
- package/dist/workflow-builder/nodes/condition-node.js +11 -0
- package/dist/workflow-builder/nodes/delay-node.d.ts +3 -0
- package/dist/workflow-builder/nodes/delay-node.js +7 -0
- package/dist/workflow-builder/nodes/end-node.d.ts +3 -0
- package/dist/workflow-builder/nodes/end-node.js +7 -0
- package/dist/workflow-builder/nodes/index.d.ts +13 -0
- package/dist/workflow-builder/nodes/index.js +22 -0
- package/dist/workflow-builder/nodes/trigger-node.d.ts +3 -0
- package/dist/workflow-builder/nodes/trigger-node.js +8 -0
- package/dist/workflow-builder/public.d.ts +1 -0
- package/dist/workflow-builder/public.js +4 -0
- package/dist/workflow-builder/types.d.ts +140 -0
- package/dist/workflow-builder/types.js +18 -0
- package/dist/workflow-builder/workflow-builder.d.ts +10 -0
- package/dist/workflow-builder/workflow-builder.js +22 -0
- package/dist/workflow-builder/workflow-canvas.d.ts +26 -0
- package/dist/workflow-builder/workflow-canvas.js +29 -0
- package/dist/workflow-builder/workflow-card-compact.d.ts +2 -0
- package/dist/workflow-builder/workflow-card-compact.js +22 -0
- package/dist/workflow-builder/workflow-card.d.ts +2 -0
- package/dist/workflow-builder/workflow-card.js +44 -0
- package/dist/workflow-builder/workflow-header.d.ts +2 -0
- package/dist/workflow-builder/workflow-header.js +32 -0
- package/dist/workflow-builder/workflow-toolbox.d.ts +2 -0
- package/dist/workflow-builder/workflow-toolbox.js +19 -0
- package/package.json +72 -50
- package/dist/styles/theme.test.ts +0 -41
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type Connection, type EdgeChange, type NodeChange, type ReactFlowProps } from '@xyflow/react';
|
|
2
|
+
import '@xyflow/react/dist/style.css';
|
|
3
|
+
import type { WorkflowEdge, WorkflowNode } from './types.js';
|
|
4
|
+
export interface WorkflowCanvasProps {
|
|
5
|
+
nodes: WorkflowNode[];
|
|
6
|
+
edges: WorkflowEdge[];
|
|
7
|
+
onNodesChange: (changes: NodeChange[]) => void;
|
|
8
|
+
onEdgesChange: (changes: EdgeChange[]) => void;
|
|
9
|
+
onConnect: (connection: Connection) => void;
|
|
10
|
+
onNodeClick?: (node: WorkflowNode) => void;
|
|
11
|
+
onPaneClick?: () => void;
|
|
12
|
+
onSelectionChange?: (selection: {
|
|
13
|
+
nodes: WorkflowNode[];
|
|
14
|
+
edges: WorkflowEdge[];
|
|
15
|
+
}) => void;
|
|
16
|
+
readOnly?: boolean;
|
|
17
|
+
customNodeTypes?: ReactFlowProps['nodeTypes'];
|
|
18
|
+
customEdgeTypes?: ReactFlowProps['edgeTypes'];
|
|
19
|
+
className?: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* The bare React Flow canvas, with sensible defaults wired in. No header / no
|
|
23
|
+
* toolbox — compose with `WorkflowBuilder` for the full surface, or use this
|
|
24
|
+
* alone when embedding in a custom layout.
|
|
25
|
+
*/
|
|
26
|
+
export declare function WorkflowCanvas({ nodes, edges, onNodesChange, onEdgesChange, onConnect, onNodeClick, onPaneClick, onSelectionChange, readOnly, customNodeTypes, customEdgeTypes, className, }: WorkflowCanvasProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { Background, BackgroundVariant, Controls, ReactFlow, } from '@xyflow/react';
|
|
4
|
+
import '@xyflow/react/dist/style.css';
|
|
5
|
+
import { useCallback } from 'react';
|
|
6
|
+
import { cn } from '../lib/utils.js';
|
|
7
|
+
import { workflowEdgeTypes } from './edges/index.js';
|
|
8
|
+
import { workflowNodeTypes } from './nodes/index.js';
|
|
9
|
+
/**
|
|
10
|
+
* The bare React Flow canvas, with sensible defaults wired in. No header / no
|
|
11
|
+
* toolbox — compose with `WorkflowBuilder` for the full surface, or use this
|
|
12
|
+
* alone when embedding in a custom layout.
|
|
13
|
+
*/
|
|
14
|
+
export function WorkflowCanvas({ nodes, edges, onNodesChange, onEdgesChange, onConnect, onNodeClick, onPaneClick, onSelectionChange, readOnly = false, customNodeTypes, customEdgeTypes, className, }) {
|
|
15
|
+
const handleNodeClick = useCallback(
|
|
16
|
+
/* v8 ignore next 3 — React Flow only fires this in a real browser canvas */
|
|
17
|
+
(_e, node) => {
|
|
18
|
+
onNodeClick?.(node);
|
|
19
|
+
}, [onNodeClick]);
|
|
20
|
+
const handleSelectionChange = useCallback(
|
|
21
|
+
/* v8 ignore next 4 — React Flow only fires this in a real browser canvas */
|
|
22
|
+
(params) => {
|
|
23
|
+
onSelectionChange?.({
|
|
24
|
+
nodes: params.nodes,
|
|
25
|
+
edges: params.edges,
|
|
26
|
+
});
|
|
27
|
+
}, [onSelectionChange]);
|
|
28
|
+
return (_jsx("div", { "data-slot": "workflow-canvas", className: cn('@container relative h-full w-full bg-muted/40', className), children: _jsxs(ReactFlow, { nodes: nodes, edges: edges, onNodesChange: readOnly ? undefined : onNodesChange, onEdgesChange: readOnly ? undefined : onEdgesChange, onConnect: readOnly ? undefined : onConnect, onNodeClick: onNodeClick ? handleNodeClick : undefined, onPaneClick: onPaneClick, onSelectionChange: onSelectionChange ? handleSelectionChange : undefined, nodeTypes: customNodeTypes ?? workflowNodeTypes, edgeTypes: customEdgeTypes ?? workflowEdgeTypes, fitView: true, fitViewOptions: { padding: 0.3, maxZoom: 1.1 }, nodesDraggable: !readOnly, nodesConnectable: !readOnly, elementsSelectable: !readOnly, panOnScroll: true, proOptions: { hideAttribution: true }, children: [_jsx(Background, { variant: BackgroundVariant.Dots, gap: 20, size: 1, color: "var(--color-border)" }), _jsx(Controls, { showInteractive: false, className: "!bg-background !border-border !shadow-sm [&>button]:!bg-background [&>button]:!border-border [&>button]:!text-foreground [&>button:hover]:!bg-muted" })] }) }));
|
|
29
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { Pause, Play, Zap } from 'lucide-react';
|
|
4
|
+
import { cn } from '../lib/utils.js';
|
|
5
|
+
const STATUS_CLASSES = {
|
|
6
|
+
draft: 'bg-muted text-muted-foreground',
|
|
7
|
+
active: 'bg-success-100 text-success-700 dark:bg-success-900/30 dark:text-success-400',
|
|
8
|
+
paused: 'bg-warning-100 text-warning-700 dark:bg-warning-900/30 dark:text-warning-400',
|
|
9
|
+
};
|
|
10
|
+
const STATUS_ICONS = {
|
|
11
|
+
draft: null,
|
|
12
|
+
active: _jsx(Play, { className: "h-3 w-3", "aria-hidden": true }),
|
|
13
|
+
paused: _jsx(Pause, { className: "h-3 w-3", "aria-hidden": true }),
|
|
14
|
+
};
|
|
15
|
+
export function WorkflowCardCompact({ workflow, onClick, className }) {
|
|
16
|
+
return (_jsxs("div", { "data-slot": "workflow-card-compact", "data-status": workflow.status, className: cn('cursor-pointer space-y-2 rounded-md border border-border bg-card p-3 transition-colors hover:bg-accent/50', className), onClick: onClick, onKeyDown: (e) => {
|
|
17
|
+
if (onClick && (e.key === 'Enter' || e.key === ' ')) {
|
|
18
|
+
e.preventDefault();
|
|
19
|
+
onClick();
|
|
20
|
+
}
|
|
21
|
+
}, role: onClick ? 'button' : undefined, tabIndex: onClick ? 0 : undefined, children: [_jsx("div", { className: "truncate font-medium text-foreground text-sm", children: workflow.name }), workflow.description ? (_jsx("p", { className: "line-clamp-2 text-muted-foreground text-xs", children: workflow.description })) : null, _jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsxs("span", { className: cn('inline-flex items-center gap-1 rounded-full px-2 py-0.5 font-medium text-xs', STATUS_CLASSES[workflow.status]), children: [STATUS_ICONS[workflow.status], _jsx("span", { className: "capitalize", children: workflow.status })] }), workflow.triggerLabel ? (_jsxs("span", { className: "inline-flex items-center gap-1 text-muted-foreground text-xs", children: [_jsx(Zap, { className: "h-3 w-3", "aria-hidden": true }), workflow.triggerLabel] })) : null] })] }));
|
|
22
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { Pause, Play, Zap } from 'lucide-react';
|
|
4
|
+
import { cn } from '../lib/utils.js';
|
|
5
|
+
const STATUS_CLASSES = {
|
|
6
|
+
draft: 'bg-muted text-muted-foreground',
|
|
7
|
+
active: 'bg-success-100 text-success-700 dark:bg-success-900/30 dark:text-success-400',
|
|
8
|
+
paused: 'bg-warning-100 text-warning-700 dark:bg-warning-900/30 dark:text-warning-400',
|
|
9
|
+
};
|
|
10
|
+
function formatRelative(ts) {
|
|
11
|
+
const diff = Date.now() - ts;
|
|
12
|
+
const seconds = Math.round(diff / 1000);
|
|
13
|
+
if (seconds < 60)
|
|
14
|
+
return 'just now';
|
|
15
|
+
const minutes = Math.round(seconds / 60);
|
|
16
|
+
if (minutes < 60)
|
|
17
|
+
return `${minutes}m ago`;
|
|
18
|
+
const hours = Math.round(minutes / 60);
|
|
19
|
+
if (hours < 24)
|
|
20
|
+
return `${hours}h ago`;
|
|
21
|
+
const days = Math.round(hours / 24);
|
|
22
|
+
return `${days}d ago`;
|
|
23
|
+
}
|
|
24
|
+
function getInitials(value) {
|
|
25
|
+
return value
|
|
26
|
+
.split(' ')
|
|
27
|
+
.map((part) => part[0] ?? '')
|
|
28
|
+
.join('')
|
|
29
|
+
.toUpperCase()
|
|
30
|
+
.slice(0, 2);
|
|
31
|
+
}
|
|
32
|
+
const STATUS_ICONS = {
|
|
33
|
+
draft: null,
|
|
34
|
+
active: _jsx(Play, { className: "h-3 w-3", "aria-hidden": true }),
|
|
35
|
+
paused: _jsx(Pause, { className: "h-3 w-3", "aria-hidden": true }),
|
|
36
|
+
};
|
|
37
|
+
export function WorkflowCard({ workflow, onClick, className }) {
|
|
38
|
+
return (_jsxs("div", { "data-slot": "workflow-card", "data-status": workflow.status, className: cn('group cursor-pointer rounded-lg border border-border bg-card p-4 shadow-sm transition-all hover:shadow-md', className), onClick: onClick, onKeyDown: (e) => {
|
|
39
|
+
if (onClick && (e.key === 'Enter' || e.key === ' ')) {
|
|
40
|
+
e.preventDefault();
|
|
41
|
+
onClick();
|
|
42
|
+
}
|
|
43
|
+
}, role: onClick ? 'button' : undefined, tabIndex: onClick ? 0 : undefined, children: [_jsx("div", { className: "mb-3 flex items-start justify-between gap-3", children: _jsxs("div", { className: "min-w-0 flex-1 space-y-1", children: [_jsx("h3", { className: "truncate font-semibold text-base text-foreground", children: workflow.name }), workflow.description ? (_jsx("p", { className: "line-clamp-2 text-muted-foreground text-sm", children: workflow.description })) : null] }) }), _jsxs("div", { className: "space-y-3", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsxs("span", { className: cn('inline-flex items-center gap-1 rounded-full px-2 py-0.5 font-medium text-xs', STATUS_CLASSES[workflow.status]), children: [STATUS_ICONS[workflow.status], _jsx("span", { className: "capitalize", children: workflow.status })] }), workflow.triggerLabel ? (_jsxs("span", { className: "inline-flex items-center gap-1 text-muted-foreground text-sm", children: [_jsx(Zap, { className: "h-3.5 w-3.5", "aria-hidden": true }), workflow.triggerLabel] })) : null] }), workflow.meta?.length ? (_jsx("dl", { className: "flex flex-wrap items-center gap-x-4 gap-y-1 text-muted-foreground text-sm", children: workflow.meta.map((m) => (_jsxs("div", { className: "flex items-center gap-1", children: [_jsxs("dt", { className: "font-medium", children: [m.label, ":"] }), _jsx("dd", { className: "tabular-nums", children: m.value })] }, m.label))) })) : null, workflow.creatorName || workflow.createdAt ? (_jsxs("div", { className: "flex items-center gap-2 text-muted-foreground text-xs", children: [workflow.creatorName ? (_jsxs("span", { className: "inline-flex items-center gap-1.5", children: [workflow.creatorAvatarUrl ? (_jsx("img", { src: workflow.creatorAvatarUrl, alt: "", className: "h-5 w-5 rounded-full" })) : (_jsx("span", { className: "inline-flex h-5 w-5 items-center justify-center rounded-full bg-muted font-medium text-[10px]", children: getInitials(workflow.creatorName) })), _jsx("span", { className: "truncate", children: workflow.creatorName })] })) : null, workflow.createdAt ? _jsx("span", { children: formatRelative(workflow.createdAt) }) : null] })) : null] })] }));
|
|
44
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { ArrowLeft, Pause, Play, Save } from 'lucide-react';
|
|
4
|
+
import { useRef, useState } from 'react';
|
|
5
|
+
import { cn } from '../lib/utils.js';
|
|
6
|
+
import { defaultWorkflowBuilderLabels, } from './types.js';
|
|
7
|
+
const STATUS_CLASSES = {
|
|
8
|
+
draft: 'bg-muted text-muted-foreground',
|
|
9
|
+
active: 'bg-success-100 text-success-700 dark:bg-success-900/30 dark:text-success-400',
|
|
10
|
+
paused: 'bg-warning-100 text-warning-700 dark:bg-warning-900/30 dark:text-warning-400',
|
|
11
|
+
};
|
|
12
|
+
const STATUS_TEXT = {
|
|
13
|
+
draft: 'Draft',
|
|
14
|
+
active: 'Active',
|
|
15
|
+
paused: 'Paused',
|
|
16
|
+
};
|
|
17
|
+
export function WorkflowHeader({ name, onNameChange, status = 'draft', onSave, onPublish, onPause, onBack, isSaving = false, readOnly = false, labels, className, }) {
|
|
18
|
+
const resolvedLabels = { ...defaultWorkflowBuilderLabels, ...(labels ?? {}) };
|
|
19
|
+
const [isEditing, setIsEditing] = useState(false);
|
|
20
|
+
const inputRef = useRef(null);
|
|
21
|
+
const handleNameClick = () => {
|
|
22
|
+
/* v8 ignore next — button is disabled when readOnly or no handler; browser blocks the click */
|
|
23
|
+
if (readOnly || !onNameChange)
|
|
24
|
+
return;
|
|
25
|
+
setIsEditing(true);
|
|
26
|
+
setTimeout(() => inputRef.current?.select(), 0);
|
|
27
|
+
};
|
|
28
|
+
return (_jsxs("header", { "data-slot": "workflow-header", className: cn('flex h-14 items-center justify-between border-border border-b bg-background px-4', className), children: [_jsxs("div", { className: "flex min-w-0 items-center gap-3", children: [onBack ? (_jsx("button", { type: "button", onClick: onBack, "aria-label": "Back", className: "inline-flex h-11 w-11 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-accent hover:text-foreground", children: _jsx(ArrowLeft, { className: "h-4 w-4", "aria-hidden": true }) })) : null, isEditing && onNameChange ? (_jsx("input", { ref: inputRef, value: name, onChange: (e) => onNameChange(e.target.value), onBlur: () => setIsEditing(false), onKeyDown: (e) => {
|
|
29
|
+
if (e.key === 'Enter' || e.key === 'Escape')
|
|
30
|
+
setIsEditing(false);
|
|
31
|
+
}, className: "h-9 w-64 rounded-md border border-border bg-background px-2 font-semibold text-foreground text-sm" })) : (_jsx("button", { type: "button", onClick: handleNameClick, disabled: readOnly || !onNameChange, className: "rounded-md px-2 py-1 font-semibold text-foreground text-sm transition-colors hover:bg-accent disabled:cursor-default disabled:hover:bg-transparent", children: name || 'Untitled workflow' })), _jsx("span", { "data-slot": "workflow-status-badge", className: cn('inline-flex items-center rounded-full px-2 py-0.5 font-medium text-xs', STATUS_CLASSES[status]), children: STATUS_TEXT[status] })] }), !readOnly ? (_jsxs("div", { className: "flex items-center gap-2", children: [(status === 'draft' || status === 'paused') && onPublish ? (_jsxs("button", { type: "button", onClick: onPublish, className: "inline-flex h-9 min-h-9 items-center gap-1.5 rounded-md border border-border bg-background px-3 font-medium text-sm transition-colors hover:bg-accent", children: [_jsx(Play, { className: "h-3.5 w-3.5", "aria-hidden": true }), resolvedLabels.publishAction] })) : null, status === 'active' && onPause ? (_jsxs("button", { type: "button", onClick: onPause, className: "inline-flex h-9 min-h-9 items-center gap-1.5 rounded-md border border-border bg-background px-3 font-medium text-sm transition-colors hover:bg-accent", children: [_jsx(Pause, { className: "h-3.5 w-3.5", "aria-hidden": true }), resolvedLabels.pauseAction] })) : null, onSave ? (_jsxs("button", { type: "button", onClick: onSave, disabled: isSaving, className: "inline-flex h-9 min-h-9 items-center gap-1.5 rounded-md bg-primary px-3 font-medium text-primary-foreground text-sm transition-colors hover:bg-primary/90 disabled:opacity-50", children: [_jsx(Save, { className: "h-3.5 w-3.5", "aria-hidden": true }), isSaving ? resolvedLabels.saving : resolvedLabels.saveAction] })) : null] })) : null] }));
|
|
32
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { cn } from '../lib/utils.js';
|
|
4
|
+
import { renderWorkflowIcon } from './internal/trigger-icons.js';
|
|
5
|
+
import { defaultWorkflowBuilderLabels, } from './types.js';
|
|
6
|
+
function defaultItems(labels) {
|
|
7
|
+
return [
|
|
8
|
+
{ kind: 'trigger', label: labels.addTrigger, iconName: 'zap' },
|
|
9
|
+
{ kind: 'action', label: labels.addAction, iconName: 'send' },
|
|
10
|
+
{ kind: 'condition', label: labels.addCondition, iconName: 'git-branch' },
|
|
11
|
+
{ kind: 'delay', label: labels.addDelay, iconName: 'clock' },
|
|
12
|
+
{ kind: 'end', label: labels.addEnd, iconName: 'flag' },
|
|
13
|
+
];
|
|
14
|
+
}
|
|
15
|
+
export function WorkflowToolbox({ items, onAddNode, readOnly = false, labels, className, }) {
|
|
16
|
+
const resolvedLabels = { ...defaultWorkflowBuilderLabels, ...(labels ?? {}) };
|
|
17
|
+
const resolvedItems = items ?? defaultItems(resolvedLabels);
|
|
18
|
+
return (_jsxs("aside", { "data-slot": "workflow-toolbox", className: cn('flex h-full w-full flex-col border-border border-r bg-background', className), children: [_jsx("div", { className: "border-border border-b px-4 py-3", children: _jsx("h2", { className: "font-semibold text-foreground text-sm", children: resolvedLabels.toolboxTitle }) }), _jsx("div", { className: "flex-1 overflow-y-auto px-3 py-3", children: readOnly ? (_jsx("p", { className: "px-1 py-2 text-muted-foreground text-xs", children: resolvedLabels.toolboxReadOnlyHint })) : (_jsxs(_Fragment, { children: [_jsx("p", { className: "mb-2 px-1 text-muted-foreground text-xs", children: resolvedLabels.toolboxHint }), _jsx("ul", { className: "space-y-1.5", children: resolvedItems.map((item) => (_jsx("li", { children: _jsxs("button", { type: "button", "data-slot": "workflow-toolbox-item", "data-kind": item.kind, onClick: () => onAddNode?.(item.kind), className: "flex min-h-11 w-full items-center gap-2.5 rounded-md px-2 py-2.5 text-left text-sm transition-colors hover:bg-accent/60 focus-visible:bg-accent/80 focus-visible:outline-none", children: [_jsx("span", { className: "flex-shrink-0 text-muted-foreground", children: renderWorkflowIcon(item.kind, item.iconName, 'h-4 w-4') }), _jsx("span", { className: "flex-1 font-medium", children: item.label })] }) }, item.kind))) })] })) })] }));
|
|
19
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@medalsocial/meda",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "Shared Meda UI shell and runtime package.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -55,6 +55,14 @@
|
|
|
55
55
|
"types": "./dist/kanban/index.d.ts",
|
|
56
56
|
"import": "./dist/kanban/index.js"
|
|
57
57
|
},
|
|
58
|
+
"./calendar": {
|
|
59
|
+
"types": "./dist/calendar/index.d.ts",
|
|
60
|
+
"import": "./dist/calendar/index.js"
|
|
61
|
+
},
|
|
62
|
+
"./workflow-builder": {
|
|
63
|
+
"types": "./dist/workflow-builder/index.d.ts",
|
|
64
|
+
"import": "./dist/workflow-builder/index.js"
|
|
65
|
+
},
|
|
58
66
|
"./list": {
|
|
59
67
|
"types": "./dist/list/index.d.ts",
|
|
60
68
|
"import": "./dist/list/index.js"
|
|
@@ -67,10 +75,18 @@
|
|
|
67
75
|
"types": "./dist/chat/index.d.ts",
|
|
68
76
|
"default": "./dist/chat/index.js"
|
|
69
77
|
},
|
|
78
|
+
"./email-builder": {
|
|
79
|
+
"types": "./dist/email-builder/index.d.ts",
|
|
80
|
+
"default": "./dist/email-builder/index.js"
|
|
81
|
+
},
|
|
70
82
|
"./panel": {
|
|
71
83
|
"types": "./dist/panel/index.d.ts",
|
|
72
84
|
"default": "./dist/panel/index.js"
|
|
73
85
|
},
|
|
86
|
+
"./post-preview": {
|
|
87
|
+
"types": "./dist/post-preview/index.d.ts",
|
|
88
|
+
"default": "./dist/post-preview/index.js"
|
|
89
|
+
},
|
|
74
90
|
"./styles": {
|
|
75
91
|
"default": "./dist/styles/theme.css"
|
|
76
92
|
},
|
|
@@ -105,6 +121,7 @@
|
|
|
105
121
|
"@dnd-kit/sortable": "^10.0.0",
|
|
106
122
|
"@dnd-kit/utilities": "^3.2.2",
|
|
107
123
|
"@react-three/fiber": "^9.0.0",
|
|
124
|
+
"@xyflow/react": "^12.0.0",
|
|
108
125
|
"lucide-react": "^1.8.0",
|
|
109
126
|
"next-themes": "^0.4.0",
|
|
110
127
|
"react": ">=19",
|
|
@@ -123,62 +140,66 @@
|
|
|
123
140
|
"@react-three/fiber": {
|
|
124
141
|
"optional": true
|
|
125
142
|
},
|
|
143
|
+
"@xyflow/react": {
|
|
144
|
+
"optional": false
|
|
145
|
+
},
|
|
126
146
|
"next-themes": {
|
|
127
147
|
"optional": true
|
|
128
148
|
}
|
|
129
149
|
},
|
|
130
150
|
"dependencies": {
|
|
131
|
-
"@base-ui/react": "
|
|
132
|
-
"@fontsource-variable/geist": "
|
|
133
|
-
"@fontsource-variable/geist-mono": "
|
|
134
|
-
"class-variance-authority": "
|
|
135
|
-
"clsx": "
|
|
136
|
-
"cmdk": "
|
|
137
|
-
"react-resizable-panels": "
|
|
138
|
-
"tailwind-merge": "
|
|
139
|
-
"three": "
|
|
140
|
-
"vaul": "
|
|
151
|
+
"@base-ui/react": "1.4.1",
|
|
152
|
+
"@fontsource-variable/geist": "5.2.8",
|
|
153
|
+
"@fontsource-variable/geist-mono": "5.2.7",
|
|
154
|
+
"class-variance-authority": "0.7.1",
|
|
155
|
+
"clsx": "2.1.1",
|
|
156
|
+
"cmdk": "1.1.1",
|
|
157
|
+
"react-resizable-panels": "4.11.0",
|
|
158
|
+
"tailwind-merge": "3.5.0",
|
|
159
|
+
"three": "0.184.0",
|
|
160
|
+
"vaul": "1.1.2"
|
|
141
161
|
},
|
|
142
162
|
"devDependencies": {
|
|
143
|
-
"@biomejs/biome": "
|
|
144
|
-
"@changesets/changelog-github": "
|
|
145
|
-
"@changesets/cli": "
|
|
146
|
-
"@dnd-kit/core": "
|
|
147
|
-
"@dnd-kit/sortable": "
|
|
148
|
-
"@dnd-kit/utilities": "
|
|
149
|
-
"@react-three/
|
|
150
|
-
"@
|
|
151
|
-
"@
|
|
152
|
-
"@storybook/addon-
|
|
153
|
-
"@storybook/addon-
|
|
154
|
-
"@storybook/addon-
|
|
155
|
-
"@storybook/addon-
|
|
156
|
-
"@storybook/
|
|
157
|
-
"@
|
|
158
|
-
"@
|
|
159
|
-
"@testing-library/
|
|
160
|
-
"@
|
|
161
|
-
"@types/react": "
|
|
162
|
-
"@types/
|
|
163
|
-
"@
|
|
164
|
-
"@
|
|
165
|
-
"@vitest/
|
|
166
|
-
"@vitest/coverage-v8": "4.1.
|
|
167
|
-
"
|
|
168
|
-
"
|
|
169
|
-
"
|
|
170
|
-
"
|
|
171
|
-
"
|
|
172
|
-
"
|
|
173
|
-
"react
|
|
174
|
-
"
|
|
175
|
-
"
|
|
176
|
-
"
|
|
177
|
-
"
|
|
178
|
-
"
|
|
179
|
-
"
|
|
180
|
-
"vitest
|
|
181
|
-
"
|
|
163
|
+
"@biomejs/biome": "2.4.14",
|
|
164
|
+
"@changesets/changelog-github": "0.6.0",
|
|
165
|
+
"@changesets/cli": "2.31.0",
|
|
166
|
+
"@dnd-kit/core": "6.3.1",
|
|
167
|
+
"@dnd-kit/sortable": "10.0.0",
|
|
168
|
+
"@dnd-kit/utilities": "3.2.2",
|
|
169
|
+
"@react-three/fiber": "9.6.1",
|
|
170
|
+
"@size-limit/preset-small-lib": "12.1.0",
|
|
171
|
+
"@storybook/addon-a11y": "10.3.6",
|
|
172
|
+
"@storybook/addon-docs": "10.3.6",
|
|
173
|
+
"@storybook/addon-mcp": "0.6.0",
|
|
174
|
+
"@storybook/addon-themes": "10.3.6",
|
|
175
|
+
"@storybook/addon-vitest": "10.3.6",
|
|
176
|
+
"@storybook/react-vite": "10.3.6",
|
|
177
|
+
"@tailwindcss/vite": "4.2.4",
|
|
178
|
+
"@testing-library/jest-dom": "6.9.1",
|
|
179
|
+
"@testing-library/react": "16.3.2",
|
|
180
|
+
"@types/react": "19.2.14",
|
|
181
|
+
"@types/react-dom": "19.2.3",
|
|
182
|
+
"@types/three": "0.184.0",
|
|
183
|
+
"@vitejs/plugin-react": "6.0.1",
|
|
184
|
+
"@vitest/browser-playwright": "4.1.5",
|
|
185
|
+
"@vitest/coverage-istanbul": "4.1.5",
|
|
186
|
+
"@vitest/coverage-v8": "4.1.5",
|
|
187
|
+
"@xyflow/react": "12.10.2",
|
|
188
|
+
"chromatic": "16.6.3",
|
|
189
|
+
"husky": "9.1.7",
|
|
190
|
+
"jsdom": "29.1.1",
|
|
191
|
+
"next-themes": "0.4.6",
|
|
192
|
+
"playwright": "1.59.1",
|
|
193
|
+
"react": "19.2.5",
|
|
194
|
+
"react-dom": "19.2.5",
|
|
195
|
+
"size-limit": "12.1.0",
|
|
196
|
+
"storybook": "10.3.6",
|
|
197
|
+
"tailwindcss": "4.2.4",
|
|
198
|
+
"typescript": "~6.0.3",
|
|
199
|
+
"vite": "8.0.10",
|
|
200
|
+
"vitest": "4.1.5",
|
|
201
|
+
"vitest-axe": "0.1.0",
|
|
202
|
+
"wrangler": "4.87.0"
|
|
182
203
|
},
|
|
183
204
|
"scripts": {
|
|
184
205
|
"build": "pnpm exec tsc -p tsconfig.build.json && node ./scripts/build.mjs",
|
|
@@ -193,6 +214,7 @@
|
|
|
193
214
|
"worker:deploy": "pnpm worker:build && wrangler deploy",
|
|
194
215
|
"test": "vitest run --environment jsdom",
|
|
195
216
|
"test:run": "vitest run --environment jsdom",
|
|
217
|
+
"test:coverage": "vitest run --environment jsdom --project unit --coverage",
|
|
196
218
|
"test:integration": "vitest run --config vitest.config.integration.ts",
|
|
197
219
|
"typecheck": "tsc --noEmit",
|
|
198
220
|
"storybook": "storybook dev -p 6006 --no-open",
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest';
|
|
2
|
-
|
|
3
|
-
// Read theme.css via Node's runtime APIs without pulling in @types/node.
|
|
4
|
-
// Declared locally so the package-level tsconfig (which doesn't include
|
|
5
|
-
// node typings) still typechecks cleanly under jsdom Vitest runs.
|
|
6
|
-
declare const require: (id: string) => unknown;
|
|
7
|
-
declare const __dirname: string;
|
|
8
|
-
|
|
9
|
-
const fs = require('node:fs') as { readFileSync(p: string, enc: string): string };
|
|
10
|
-
const path = require('node:path') as { join(...parts: string[]): string };
|
|
11
|
-
const themeCss = fs.readFileSync(path.join(__dirname, 'theme.css'), 'utf8');
|
|
12
|
-
|
|
13
|
-
describe('theme.css', () => {
|
|
14
|
-
// Tailwind v4 only generates utility classes for class names it sees in
|
|
15
|
-
// scanned files. Consumer apps don't reference every utility used by meda
|
|
16
|
-
// components (e.g. `h-full`, `mt-auto`, `py-3.5`, `bg-shell-rail` on
|
|
17
|
-
// IconRail), so without an @source directive pointing at meda's compiled
|
|
18
|
-
// dist files, those classes silently disappear and component layouts
|
|
19
|
-
// collapse — most visibly, the IconRail's utility items fail to pin to
|
|
20
|
-
// the bottom of the viewport because `mt-auto` never gets generated.
|
|
21
|
-
//
|
|
22
|
-
// The directive is resolved relative to this CSS file at build time. Since
|
|
23
|
-
// src/styles/theme.css is copied verbatim to dist/styles/theme.css by the
|
|
24
|
-
// build script, `../**/*.js` from the dist location scans every emitted
|
|
25
|
-
// component module — exactly the surface consumers import from.
|
|
26
|
-
it('declares an @source directive that scans meda component output', () => {
|
|
27
|
-
expect(themeCss).toMatch(/@source\s+["']\.\.\/\*\*\/\*\.js["']/);
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
it('declares dedicated auth gradient tokens for consumer overrides', () => {
|
|
31
|
-
expect(themeCss).toContain('--auth-gradient-primary: var(--color-brand-500);');
|
|
32
|
-
expect(themeCss).toContain('--auth-gradient-secondary: var(--color-brand-700);');
|
|
33
|
-
expect(themeCss).toContain('--auth-gradient-base: var(--color-brand-800);');
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
it('neutralizes vaul drawer layer hints after mobile drawers are open', () => {
|
|
37
|
-
expect(themeCss).toMatch(
|
|
38
|
-
/\[data-vaul-drawer\]\[data-state=["']open["']\]\s*\{[^}]*will-change:\s*auto;/s
|
|
39
|
-
);
|
|
40
|
-
});
|
|
41
|
-
});
|