@medalsocial/meda 0.2.0 → 1.0.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/README.md +26 -0
- package/dist/brand/index.d.ts +2 -0
- package/dist/brand/index.js +1 -0
- package/dist/brand/medal-social-mark.d.ts +7 -0
- package/dist/brand/medal-social-mark.js +6 -0
- package/dist/brand/public.d.ts +2 -0
- package/dist/brand/public.js +1 -0
- package/dist/chat/index.d.ts +11 -0
- package/dist/chat/index.js +5 -0
- package/dist/chat/latency-badge.d.ts +7 -0
- package/dist/chat/latency-badge.js +23 -0
- package/dist/chat/latency-breakdown.d.ts +8 -0
- package/dist/chat/latency-breakdown.js +9 -0
- package/dist/chat/public.d.ts +1 -0
- package/dist/chat/public.js +1 -0
- package/dist/chat/tool-call-block.d.ts +6 -0
- package/dist/chat/tool-call-block.js +19 -0
- package/dist/chat/transcript-stream.d.ts +10 -0
- package/dist/chat/transcript-stream.js +40 -0
- package/dist/chat/turn-card.d.ts +10 -0
- package/dist/chat/turn-card.js +25 -0
- package/dist/chat/types.d.ts +36 -0
- package/dist/chat/types.js +1 -0
- package/dist/components/ui/command.d.ts +19 -0
- package/dist/components/ui/command.js +37 -0
- package/dist/components/ui/dialog.d.ts +26 -0
- package/dist/components/ui/dialog.js +39 -0
- package/dist/components/ui/drawer.d.ts +16 -0
- package/dist/components/ui/drawer.js +35 -0
- package/dist/components/ui/dropdown-menu.d.ts +32 -0
- package/dist/components/ui/dropdown-menu.js +68 -0
- package/dist/components/ui/tooltip.d.ts +6 -0
- package/dist/components/ui/tooltip.js +17 -0
- package/dist/index.d.ts +6 -1
- package/dist/index.js +6 -1
- package/dist/lib/format-time.d.ts +9 -0
- package/dist/lib/format-time.js +34 -0
- package/dist/lib/utils.d.ts +2 -0
- package/dist/lib/utils.js +5 -0
- package/dist/marketing/index.d.ts +5 -0
- package/dist/marketing/index.js +4 -0
- package/dist/marketing/marketing-callout.d.ts +2 -0
- package/dist/marketing/marketing-callout.js +8 -0
- package/dist/marketing/marketing-contact.d.ts +2 -0
- package/dist/marketing/marketing-contact.js +19 -0
- package/dist/marketing/marketing-cta-list.d.ts +2 -0
- package/dist/marketing/marketing-cta-list.js +21 -0
- package/dist/marketing/marketing-lead-magnet.d.ts +2 -0
- package/dist/marketing/marketing-lead-magnet.js +9 -0
- package/dist/marketing/public.d.ts +1 -0
- package/dist/marketing/public.js +1 -0
- package/dist/marketing/types.d.ts +67 -0
- package/dist/marketing/types.js +1 -0
- package/dist/marketing/utils.d.ts +2 -0
- package/dist/marketing/utils.js +6 -0
- package/dist/panel/index.d.ts +6 -0
- package/dist/panel/index.js +3 -0
- package/dist/panel/inspector-field.d.ts +9 -0
- package/dist/panel/inspector-field.js +4 -0
- package/dist/panel/inspector-json.d.ts +7 -0
- package/dist/panel/inspector-json.js +75 -0
- package/dist/panel/inspector.d.ts +7 -0
- package/dist/panel/inspector.js +12 -0
- package/dist/panel/public.d.ts +1 -0
- package/dist/panel/public.js +1 -0
- package/dist/panel/types.d.ts +6 -0
- package/dist/panel/types.js +1 -0
- package/dist/shell/app-shell.d.ts +9 -0
- package/dist/shell/app-shell.js +11 -0
- package/dist/shell/command-palette.d.ts +23 -0
- package/dist/shell/command-palette.js +138 -0
- package/dist/shell/context-rail.d.ts +31 -0
- package/dist/shell/context-rail.js +81 -0
- package/dist/shell/extras/index.d.ts +4 -0
- package/dist/shell/extras/index.js +4 -0
- package/dist/shell/extras/shell-desktop-panel-dock.d.ts +14 -0
- package/dist/shell/extras/shell-desktop-panel-dock.js +43 -0
- package/dist/shell/extras/shell-scrollable-content.d.ts +9 -0
- package/dist/shell/extras/shell-scrollable-content.js +7 -0
- package/dist/shell/extras/shell-tab-bar.d.ts +18 -0
- package/dist/shell/extras/shell-tab-bar.js +27 -0
- package/dist/shell/extras/types.d.ts +64 -0
- package/dist/shell/extras/types.js +2 -0
- package/dist/shell/extras/workbench-layout.d.ts +10 -0
- package/dist/shell/extras/workbench-layout.js +29 -0
- package/dist/shell/icon-rail.d.ts +29 -0
- package/dist/shell/icon-rail.js +38 -0
- package/dist/shell/index.d.ts +24 -15
- package/dist/shell/index.js +35 -15
- package/dist/shell/layout-state.d.ts +32 -0
- package/dist/shell/layout-state.js +98 -0
- package/dist/shell/mobile/mobile-bottom-nav.d.ts +15 -0
- package/dist/shell/mobile/mobile-bottom-nav.js +76 -0
- package/dist/shell/mobile/mobile-drawers.d.ts +20 -0
- package/dist/shell/mobile/mobile-drawers.js +62 -0
- package/dist/shell/mobile/mobile-header.d.ts +23 -0
- package/dist/shell/mobile/mobile-header.js +22 -0
- package/dist/shell/motion.d.ts +22 -0
- package/dist/shell/motion.js +19 -0
- package/dist/shell/public.d.ts +16 -2
- package/dist/shell/public.js +20 -1
- package/dist/shell/resizable-shell.d.ts +45 -0
- package/dist/shell/resizable-shell.js +15 -0
- package/dist/shell/right-panel.d.ts +15 -0
- package/dist/shell/right-panel.js +126 -0
- package/dist/shell/shell-auth-frame.d.ts +22 -0
- package/dist/shell/shell-auth-frame.js +60 -0
- package/dist/shell/shell-header.d.ts +10 -9
- package/dist/shell/shell-header.js +57 -14
- package/dist/shell/shell-layout-utils.d.ts +2 -2
- package/dist/shell/shell-main.d.ts +8 -0
- package/dist/shell/shell-main.js +11 -0
- package/dist/shell/shell-provider.d.ts +65 -0
- package/dist/shell/shell-provider.js +152 -0
- package/dist/shell/shell-route-utils.d.ts +1 -1
- package/dist/shell/theme-next-themes.d.ts +4 -0
- package/dist/shell/theme-next-themes.js +24 -0
- package/dist/shell/theme.d.ts +9 -0
- package/dist/shell/theme.js +58 -0
- package/dist/shell/types.d.ts +41 -41
- package/dist/shell/types.js +1 -0
- package/dist/shell/use-shell-viewport.d.ts +2 -0
- package/dist/shell/use-shell-viewport.js +40 -0
- package/dist/shell/utils.d.ts +1 -1
- package/dist/styles/globals.css +26 -0
- package/dist/styles/theme.css +147 -0
- package/dist/styles/tokens.css +338 -0
- package/dist/timeline/date-switcher.d.ts +11 -0
- package/dist/timeline/date-switcher.js +64 -0
- package/dist/timeline/event-card.d.ts +9 -0
- package/dist/timeline/event-card.js +18 -0
- package/dist/timeline/index.d.ts +13 -0
- package/dist/timeline/index.js +6 -0
- package/dist/timeline/live-indicator.d.ts +7 -0
- package/dist/timeline/live-indicator.js +7 -0
- package/dist/timeline/public.d.ts +1 -0
- package/dist/timeline/public.js +1 -0
- package/dist/timeline/scrub-bar.d.ts +14 -0
- package/dist/timeline/scrub-bar.js +43 -0
- package/dist/timeline/timeline-rail.d.ts +19 -0
- package/dist/timeline/timeline-rail.js +66 -0
- package/dist/timeline/timeline-tape.d.ts +19 -0
- package/dist/timeline/timeline-tape.js +65 -0
- package/dist/timeline/types.d.ts +40 -0
- package/dist/timeline/types.js +1 -0
- package/dist/voice/voice-level.js +3 -1
- package/dist/voice/voice-orb-scene.js +1 -0
- package/dist/voice/voice-orb.js +9 -11
- package/dist/voice/voice-status-pill.js +4 -9
- package/package.json +67 -7
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { formatClock } from '../lib/format-time.js';
|
|
4
|
+
import { cn } from '../lib/utils.js';
|
|
5
|
+
import { EventCard } from './event-card.js';
|
|
6
|
+
const DEFAULT_PX_PER_SEC = 1.2;
|
|
7
|
+
const DEFAULT_FUTURE_PAD_SEC = 300;
|
|
8
|
+
const DEFAULT_PAST_SPAN_SEC = 6 * 60 * 60;
|
|
9
|
+
/** Convert a unix-ms instant to canvas y (px). y=0 at canvas top. */
|
|
10
|
+
function instantToY(instantMs, nowMs, pxPerSec, futurePadSec) {
|
|
11
|
+
const secsAfterNow = (instantMs - nowMs) / 1000;
|
|
12
|
+
// future is above now → smaller y. past is below now → larger y.
|
|
13
|
+
return (futurePadSec - secsAfterNow) * pxPerSec;
|
|
14
|
+
}
|
|
15
|
+
export function TimelineTape({ now, events, pxPerSec = DEFAULT_PX_PER_SEC, futurePadSec = DEFAULT_FUTURE_PAD_SEC, pastSpanSec = DEFAULT_PAST_SPAN_SEC, tz, onSelect, className, }) {
|
|
16
|
+
const nowMs = now.getTime();
|
|
17
|
+
const totalSec = futurePadSec + pastSpanSec;
|
|
18
|
+
const canvasHeight = totalSec * pxPerSec;
|
|
19
|
+
const nowY = instantToY(nowMs, nowMs, pxPerSec, futurePadSec);
|
|
20
|
+
// Compute tick positions at minute boundaries. Start from the future edge, go down.
|
|
21
|
+
const ticks = [];
|
|
22
|
+
const futureEdgeMs = nowMs + futurePadSec * 1000;
|
|
23
|
+
const pastEdgeMs = nowMs - pastSpanSec * 1000;
|
|
24
|
+
const firstTick = new Date(futureEdgeMs);
|
|
25
|
+
firstTick.setSeconds(0, 0);
|
|
26
|
+
for (let t = firstTick.getTime(); t >= pastEdgeMs; t -= 60_000) {
|
|
27
|
+
const y = instantToY(t, nowMs, pxPerSec, futurePadSec);
|
|
28
|
+
if (y < 0 || y > canvasHeight)
|
|
29
|
+
continue;
|
|
30
|
+
ticks.push({
|
|
31
|
+
y,
|
|
32
|
+
label: formatClock(new Date(t), { tz, withSeconds: false }),
|
|
33
|
+
major: true,
|
|
34
|
+
});
|
|
35
|
+
// 5 sub-ticks every 10s under each major
|
|
36
|
+
for (let sub = 1; sub <= 5; sub++) {
|
|
37
|
+
const subT = t - sub * 10_000;
|
|
38
|
+
if (subT < pastEdgeMs)
|
|
39
|
+
break;
|
|
40
|
+
const subY = instantToY(subT, nowMs, pxPerSec, futurePadSec);
|
|
41
|
+
ticks.push({ y: subY, label: '', major: false });
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
// Build tape segments + cards
|
|
45
|
+
const segments = events
|
|
46
|
+
.filter((e) => e.kind === 'session' || e.kind === 'error')
|
|
47
|
+
.map((e) => {
|
|
48
|
+
const startY = instantToY(e.startedAt, nowMs, pxPerSec, futurePadSec);
|
|
49
|
+
const endInstant = e.endedAt ?? (e.isLive ? nowMs : e.startedAt + 1000);
|
|
50
|
+
const endY = instantToY(endInstant, nowMs, pxPerSec, futurePadSec);
|
|
51
|
+
// "Top" of the segment is the more recent (smaller y).
|
|
52
|
+
const top = Math.min(startY, endY);
|
|
53
|
+
const height = Math.max(2, Math.abs(endY - startY));
|
|
54
|
+
return { event: e, top, height };
|
|
55
|
+
});
|
|
56
|
+
return (_jsxs("div", { className: cn('relative ml-3.5 mr-3', className), style: { height: `${canvasHeight}px` }, "data-canvas-height": canvasHeight, children: [ticks.map((t) => t.major ? (_jsxs("div", { children: [_jsx("span", { className: "absolute left-0 w-[30px] -translate-y-[7px] text-right text-[11px] font-medium tabular-nums text-muted-foreground", style: { top: `${t.y}px` }, children: t.label }), _jsx("span", { className: "absolute h-px w-2 bg-border", style: { left: 32, top: `${t.y}px` } })] }, `maj-${t.y}`)) : (_jsx("span", { className: "absolute h-px w-1.5 bg-border/40", style: { left: 35, top: `${t.y}px` } }, `min-${t.y}`))), segments.map(({ event, top, height }) => (_jsx("span", { "aria-hidden": "true", "data-tape-segment-id": event.id, "data-tape-segment-live": String(event.isLive ?? false), className: cn('absolute w-1 rounded-sm', event.isLive
|
|
57
|
+
? 'bg-success-600 shadow-[0_0_12px_rgba(16,185,129,0.5)]'
|
|
58
|
+
: event.kind === 'error'
|
|
59
|
+
? 'bg-destructive'
|
|
60
|
+
: 'bg-info-500 shadow-[0_0_8px_rgba(56,189,248,0.35)]'), style: { left: 44, top: `${top}px`, height: `${height}px` } }, `seg-${event.id}`))), events.map((event) => {
|
|
61
|
+
const startY = instantToY(event.startedAt, nowMs, pxPerSec, futurePadSec);
|
|
62
|
+
const isSubEvent = event.kind === 'sub-event';
|
|
63
|
+
return (_jsx("div", { "data-event-id": event.id, className: "absolute", style: { top: `${startY}px`, left: 56, right: 0 }, children: _jsx(EventCard, { event: event, size: isSubEvent ? 'tiny' : 'default', onSelect: onSelect }) }, event.id));
|
|
64
|
+
}), _jsx("span", { "aria-hidden": "true", "data-now-y": nowY, className: "absolute", style: { top: `${nowY}px`, left: 0, width: 0, height: 0 } })] }));
|
|
65
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
/** What kind of timeline entry this is. */
|
|
3
|
+
export type TimelineEventKind = 'session' | 'sub-event' | 'scheduled' | 'error';
|
|
4
|
+
/**
|
|
5
|
+
* Generic timeline entry. Apps map their domain (a phone call, a chat session, a workflow run)
|
|
6
|
+
* onto this shape and pass an array to <TimelineRail/>.
|
|
7
|
+
*/
|
|
8
|
+
export interface TimelineEvent {
|
|
9
|
+
/** Stable identifier across re-renders. */
|
|
10
|
+
id: string;
|
|
11
|
+
/** Unix ms — when the event began. */
|
|
12
|
+
startedAt: number;
|
|
13
|
+
/** Unix ms — when the event ended. Omit for live or instantaneous events. */
|
|
14
|
+
endedAt?: number;
|
|
15
|
+
/** Coarse category — drives default styling. */
|
|
16
|
+
kind: TimelineEventKind;
|
|
17
|
+
/** Optional narrower tag for app-specific styling, e.g. "tool-call", "barge-in". */
|
|
18
|
+
variant?: string;
|
|
19
|
+
/** Card primary line content (typically a name). */
|
|
20
|
+
primary?: ReactNode;
|
|
21
|
+
/** Card secondary line content (typically meta — counts, cost). */
|
|
22
|
+
secondary?: ReactNode;
|
|
23
|
+
/** Highlight as currently selected. */
|
|
24
|
+
selected?: boolean;
|
|
25
|
+
/** Render with the live treatment (green pulse, etc). */
|
|
26
|
+
isLive?: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Optional override for the tape segment color expressed as a CSS color value.
|
|
29
|
+
* Defaults derived from kind + isLive + variant.
|
|
30
|
+
*/
|
|
31
|
+
fillColor?: string;
|
|
32
|
+
}
|
|
33
|
+
/** Marks rendered along the per-conversation <ScrubBar/>. */
|
|
34
|
+
export interface ScrubMark {
|
|
35
|
+
id: string;
|
|
36
|
+
/** Position along the bar, 0..100. */
|
|
37
|
+
positionPct: number;
|
|
38
|
+
kind: 'turn' | 'tool' | 'barge' | 'error';
|
|
39
|
+
label?: string;
|
|
40
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
'use client';
|
|
1
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
3
|
import * as React from 'react';
|
|
4
|
+
import { cn } from '../lib/utils.js';
|
|
3
5
|
const BAR_COUNT = 9;
|
|
4
6
|
export function VoiceLevel({ level, variant = 'bars', width = 140, height = 48, className, }) {
|
|
5
7
|
const historyRef = React.useRef(Array(BAR_COUNT).fill(0));
|
|
@@ -14,7 +16,7 @@ export function VoiceLevel({ level, variant = 'bars', width = 140, height = 48,
|
|
|
14
16
|
force((v) => v + 1);
|
|
15
17
|
}, [level, variant]);
|
|
16
18
|
if (variant === 'bars') {
|
|
17
|
-
return (_jsx("div", { role: "presentation", className:
|
|
19
|
+
return (_jsx("div", { role: "presentation", className: cn('flex items-end gap-1', className), style: { width, height }, children: historyRef.current.map((v, i) => (_jsx("span", { className: "flex-1 rounded-sm bg-primary", style: { height: `${15 + v * 85}%`, opacity: 0.4 + v * 0.6 } }, i))) }));
|
|
18
20
|
}
|
|
19
21
|
if (variant === 'ring') {
|
|
20
22
|
const r = Math.min(width, height) / 2 - 4;
|
package/dist/voice/voice-orb.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
'use client';
|
|
1
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
3
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
4
|
import { Canvas } from '@react-three/fiber';
|
|
4
5
|
import * as React from 'react';
|
|
6
|
+
import { cn } from '../lib/utils.js';
|
|
5
7
|
import { Scene } from './voice-orb-scene.js';
|
|
6
8
|
// Note: CSS for `.meda-voice-orb` is shipped via @medalsocial/meda/styles.css
|
|
7
9
|
// (re-exported from globals.css). We avoid a JS-side CSS import here so
|
|
@@ -9,7 +11,11 @@ import { Scene } from './voice-orb-scene.js';
|
|
|
9
11
|
// ---------------------------------------------------------------------------
|
|
10
12
|
// Theming helpers
|
|
11
13
|
// ---------------------------------------------------------------------------
|
|
12
|
-
|
|
14
|
+
// Fallback colors used only if CSS custom properties fail to resolve.
|
|
15
|
+
// Both values are from the canonical brand ramp (.lib.pen):
|
|
16
|
+
// brand-400 (#9A6AC2) and brand-500 (#7E3FAC).
|
|
17
|
+
// Runtime path reads --primary and --accent first.
|
|
18
|
+
const FALLBACK_COLOR = '#9A6AC2'; // brand-400
|
|
13
19
|
function hslToHex(h, s, l) {
|
|
14
20
|
const sl = s / 100;
|
|
15
21
|
const ll = l / 100;
|
|
@@ -70,7 +76,7 @@ function readMedaColors(el) {
|
|
|
70
76
|
const colorB = accent ? parseColor(accent) : colorA;
|
|
71
77
|
return [colorA, colorB];
|
|
72
78
|
}
|
|
73
|
-
const DEFAULT_COLORS = ['#9A6AC2', '#
|
|
79
|
+
const DEFAULT_COLORS = ['#9A6AC2', '#7E3FAC']; // brand-400 → brand-500
|
|
74
80
|
// ---------------------------------------------------------------------------
|
|
75
81
|
// Component
|
|
76
82
|
// ---------------------------------------------------------------------------
|
|
@@ -111,13 +117,5 @@ export const VoiceOrb = React.forwardRef(function VoiceOrb({ pressed, level = 0,
|
|
|
111
117
|
height: size,
|
|
112
118
|
...style,
|
|
113
119
|
};
|
|
114
|
-
return (_jsx("button", { ref: buttonRef, type: "button", "aria-pressed": pressed, "aria-label": label, disabled: disabled, "data-phase": phase, "data-pressed": pressed, className: [
|
|
115
|
-
'meda-voice-orb',
|
|
116
|
-
'relative inline-flex items-center justify-center rounded-full',
|
|
117
|
-
'select-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',
|
|
118
|
-
'transition-transform duration-200 ease-out',
|
|
119
|
-
disabled ? 'cursor-not-allowed opacity-60' : 'cursor-pointer',
|
|
120
|
-
pressed ? 'scale-[0.97]' : 'scale-100',
|
|
121
|
-
className ?? '',
|
|
122
|
-
].join(' '), style: btnStyle, ...rest, children: _jsx(Canvas, { gl: { alpha: true, antialias: true, premultipliedAlpha: true }, style: { pointerEvents: 'none' }, children: _jsx(Scene, { level: level, outputLevel: outputLevel, phase: phase, colors: resolvedColors, reducedMotion: reducedMotion, pressed: pressed, variant: variant }) }) }));
|
|
120
|
+
return (_jsx("button", { ref: buttonRef, type: "button", "aria-pressed": pressed, "aria-label": label, disabled: disabled, "data-phase": phase, "data-pressed": pressed, className: cn('meda-voice-orb', 'relative inline-flex items-center justify-center rounded-full', 'select-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring', 'transition-transform duration-200 ease-out', disabled ? 'cursor-not-allowed opacity-60' : 'cursor-pointer', pressed ? 'scale-[0.97]' : 'scale-100', className), style: btnStyle, ...rest, children: _jsx(Canvas, { gl: { alpha: true, antialias: true, premultipliedAlpha: true }, style: { pointerEvents: 'none' }, children: _jsx(Scene, { level: level, outputLevel: outputLevel, phase: phase, colors: resolvedColors, reducedMotion: reducedMotion, pressed: pressed, variant: variant }) }) }));
|
|
123
121
|
});
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
'use client';
|
|
1
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { cn } from '../lib/utils.js';
|
|
2
4
|
const PHASE_LABEL = {
|
|
3
5
|
idle: 'Idle',
|
|
4
6
|
listening: 'Listening',
|
|
@@ -10,17 +12,10 @@ export function VoiceStatusPill({ phase, thinkingForMs, className }) {
|
|
|
10
12
|
const tone = phase === 'listening'
|
|
11
13
|
? 'bg-primary text-primary-foreground'
|
|
12
14
|
: phase === 'speaking'
|
|
13
|
-
? 'bg-
|
|
15
|
+
? 'bg-success text-success-foreground'
|
|
14
16
|
: phase === 'error'
|
|
15
17
|
? 'bg-destructive text-destructive-foreground'
|
|
16
18
|
: 'bg-muted text-muted-foreground';
|
|
17
19
|
const seconds = thinkingForMs ? (thinkingForMs / 1000).toFixed(1) : null;
|
|
18
|
-
return (_jsxs("span", { role: "status", "data-phase": phase, className: [
|
|
19
|
-
'inline-flex items-center gap-1.5 rounded-full px-3 py-1 text-xs font-medium',
|
|
20
|
-
tone,
|
|
21
|
-
className ?? '',
|
|
22
|
-
].join(' '), children: [_jsx("span", { className: [
|
|
23
|
-
'size-1.5 rounded-full bg-current',
|
|
24
|
-
phase === 'thinking' ? 'animate-pulse' : '',
|
|
25
|
-
].join(' ') }), PHASE_LABEL[phase], phase === 'thinking' && seconds && _jsxs("span", { className: "opacity-70", children: ["\u00B7 ", seconds, "s"] })] }));
|
|
20
|
+
return (_jsxs("span", { role: "status", "data-phase": phase, className: cn('inline-flex items-center gap-1.5 rounded-full px-3 py-1 text-xs font-medium', tone, className), children: [_jsx("span", { className: cn('size-1.5 rounded-full bg-current', phase === 'thinking' && 'animate-pulse') }), PHASE_LABEL[phase], phase === 'thinking' && seconds && _jsxs("span", { children: ["\u00B7 ", seconds, "s"] })] }));
|
|
26
21
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@medalsocial/meda",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "Shared Meda UI shell and runtime package.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -24,6 +24,10 @@
|
|
|
24
24
|
"types": "./dist/index.d.ts",
|
|
25
25
|
"default": "./dist/index.js"
|
|
26
26
|
},
|
|
27
|
+
"./brand": {
|
|
28
|
+
"types": "./dist/brand/index.d.ts",
|
|
29
|
+
"default": "./dist/brand/index.js"
|
|
30
|
+
},
|
|
27
31
|
"./shell": {
|
|
28
32
|
"types": "./dist/shell/index.d.ts",
|
|
29
33
|
"default": "./dist/shell/index.js"
|
|
@@ -32,19 +36,52 @@
|
|
|
32
36
|
"types": "./dist/voice/index.d.ts",
|
|
33
37
|
"default": "./dist/voice/index.js"
|
|
34
38
|
},
|
|
35
|
-
"./
|
|
39
|
+
"./timeline": {
|
|
40
|
+
"types": "./dist/timeline/index.d.ts",
|
|
41
|
+
"default": "./dist/timeline/index.js"
|
|
42
|
+
},
|
|
43
|
+
"./marketing": {
|
|
44
|
+
"types": "./dist/marketing/index.d.ts",
|
|
45
|
+
"default": "./dist/marketing/index.js"
|
|
46
|
+
},
|
|
47
|
+
"./chat": {
|
|
48
|
+
"types": "./dist/chat/index.d.ts",
|
|
49
|
+
"default": "./dist/chat/index.js"
|
|
50
|
+
},
|
|
51
|
+
"./panel": {
|
|
52
|
+
"types": "./dist/panel/index.d.ts",
|
|
53
|
+
"default": "./dist/panel/index.js"
|
|
54
|
+
},
|
|
55
|
+
"./styles": {
|
|
56
|
+
"default": "./dist/styles/theme.css"
|
|
57
|
+
},
|
|
58
|
+
"./styles.css": {
|
|
59
|
+
"default": "./dist/styles/theme.css"
|
|
60
|
+
},
|
|
61
|
+
"./styles/tokens": {
|
|
62
|
+
"default": "./dist/styles/tokens.css"
|
|
63
|
+
}
|
|
36
64
|
},
|
|
65
|
+
"sideEffects": [
|
|
66
|
+
"**/*.css",
|
|
67
|
+
"./dist/styles/*.css"
|
|
68
|
+
],
|
|
37
69
|
"publishConfig": {
|
|
38
70
|
"access": "public"
|
|
39
71
|
},
|
|
40
72
|
"peerDependencies": {
|
|
41
73
|
"@react-three/fiber": "^9.0.0",
|
|
74
|
+
"lucide-react": "^1.8.0",
|
|
75
|
+
"next-themes": "^0.4.0",
|
|
42
76
|
"react": ">=19",
|
|
43
77
|
"react-dom": ">=19"
|
|
44
78
|
},
|
|
45
79
|
"peerDependenciesMeta": {
|
|
46
80
|
"@react-three/fiber": {
|
|
47
81
|
"optional": true
|
|
82
|
+
},
|
|
83
|
+
"next-themes": {
|
|
84
|
+
"optional": true
|
|
48
85
|
}
|
|
49
86
|
},
|
|
50
87
|
"dependencies": {
|
|
@@ -54,7 +91,6 @@
|
|
|
54
91
|
"class-variance-authority": "^0.7.1",
|
|
55
92
|
"clsx": "^2.1.1",
|
|
56
93
|
"cmdk": "^1.1.1",
|
|
57
|
-
"lucide-react": "^1.8.0",
|
|
58
94
|
"react-resizable-panels": "^4.10.0",
|
|
59
95
|
"tailwind-merge": "^3.5.0",
|
|
60
96
|
"three": "^0.170.0",
|
|
@@ -66,21 +102,36 @@
|
|
|
66
102
|
"@changesets/cli": "^2.29.0",
|
|
67
103
|
"@react-three/drei": "^10.7.7",
|
|
68
104
|
"@react-three/fiber": "^9.6.0",
|
|
105
|
+
"@size-limit/preset-small-lib": "^12.1.0",
|
|
106
|
+
"@storybook/addon-a11y": "^10.3.5",
|
|
107
|
+
"@storybook/addon-docs": "10.3.5",
|
|
108
|
+
"@storybook/addon-mcp": "^0.6.0",
|
|
109
|
+
"@storybook/addon-themes": "^10.3.5",
|
|
110
|
+
"@storybook/addon-vitest": "^10.3.5",
|
|
111
|
+
"@storybook/react-vite": "^10.3.5",
|
|
69
112
|
"@tailwindcss/vite": "^4.2.4",
|
|
70
|
-
"@types/three": "^0.184.0",
|
|
71
113
|
"@testing-library/jest-dom": "^6.9.1",
|
|
72
114
|
"@testing-library/react": "^16.3.2",
|
|
73
115
|
"@types/react": "^19.2.14",
|
|
74
116
|
"@types/react-dom": "^19.2.3",
|
|
117
|
+
"@types/three": "^0.184.0",
|
|
75
118
|
"@vitejs/plugin-react": "^6.0.1",
|
|
119
|
+
"@vitest/browser-playwright": "4.1.4",
|
|
120
|
+
"@vitest/coverage-v8": "4.1.4",
|
|
121
|
+
"chromatic": "^16.6.0",
|
|
76
122
|
"husky": "^9.1.7",
|
|
77
123
|
"jsdom": "^29.0.2",
|
|
124
|
+
"next-themes": "^0.4.0",
|
|
125
|
+
"playwright": "^1.59.1",
|
|
78
126
|
"react": "^19.2.4",
|
|
79
127
|
"react-dom": "^19.2.4",
|
|
128
|
+
"size-limit": "^12.1.0",
|
|
129
|
+
"storybook": "^10.3.5",
|
|
80
130
|
"tailwindcss": "^4.2.4",
|
|
81
131
|
"typescript": "~6.0.2",
|
|
82
132
|
"vite": "^8.0.4",
|
|
83
133
|
"vitest": "^4.1.4",
|
|
134
|
+
"vitest-axe": "^0.1.0",
|
|
84
135
|
"wrangler": "^4.0.0"
|
|
85
136
|
},
|
|
86
137
|
"scripts": {
|
|
@@ -90,14 +141,23 @@
|
|
|
90
141
|
"format": "biome format --write .",
|
|
91
142
|
"demo:dev": "vite --config vite.config.demo.ts",
|
|
92
143
|
"demo:build": "vite build --config vite.config.demo.ts",
|
|
93
|
-
"worker:build": "pnpm demo:build && node ./scripts/copy-registry-to-dist.mjs",
|
|
94
|
-
"worker:dev": "pnpm
|
|
144
|
+
"worker:build": "pnpm demo:build && pnpm storybook:build && node ./scripts/copy-registry-to-dist.mjs",
|
|
145
|
+
"worker:build:dev": "pnpm demo:build && node ./scripts/copy-registry-to-dist.mjs --skip-storybook",
|
|
146
|
+
"worker:dev": "pnpm worker:build:dev && wrangler dev",
|
|
95
147
|
"worker:deploy": "pnpm worker:build && wrangler deploy",
|
|
96
148
|
"test": "vitest run --environment jsdom",
|
|
97
149
|
"test:run": "vitest run --environment jsdom",
|
|
150
|
+
"test:integration": "vitest run --config vitest.config.integration.ts",
|
|
98
151
|
"typecheck": "tsc --noEmit",
|
|
152
|
+
"storybook": "storybook dev -p 6006 --no-open",
|
|
153
|
+
"storybook:build": "storybook build -o storybook-static",
|
|
154
|
+
"chromatic": "chromatic --build-script-name=storybook:build --exit-zero-on-changes",
|
|
155
|
+
"size-limit": "size-limit",
|
|
156
|
+
"size-limit:why": "size-limit --why",
|
|
99
157
|
"version": "changeset version",
|
|
100
158
|
"release": "pnpm build && changeset publish",
|
|
101
|
-
"registry:validate": "node ./registry/scripts/validate-registry.mjs"
|
|
159
|
+
"registry:validate": "node ./registry/scripts/validate-registry.mjs",
|
|
160
|
+
"lint:tokens": "node scripts/lint-tokens.mjs",
|
|
161
|
+
"quality": "pnpm lint && pnpm typecheck && pnpm lint:tokens && pnpm test"
|
|
102
162
|
}
|
|
103
163
|
}
|