@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,68 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { Menu as MenuPrimitive } from '@base-ui/react/menu';
|
|
4
|
+
import { CheckIcon, ChevronRightIcon } from 'lucide-react';
|
|
5
|
+
import { cn } from '../../lib/utils.js';
|
|
6
|
+
function DropdownMenu({ ...props }) {
|
|
7
|
+
return _jsx(MenuPrimitive.Root, { "data-slot": "dropdown-menu", ...props });
|
|
8
|
+
}
|
|
9
|
+
function DropdownMenuPortal({ ...props }) {
|
|
10
|
+
return _jsx(MenuPrimitive.Portal, { "data-slot": "dropdown-menu-portal", ...props });
|
|
11
|
+
}
|
|
12
|
+
function DropdownMenuTrigger({ render, children, ...props }) {
|
|
13
|
+
// Function render is passed through directly to Base UI
|
|
14
|
+
if (typeof render === 'function') {
|
|
15
|
+
return (_jsx(MenuPrimitive.Trigger, { "data-slot": "dropdown-menu-trigger", render: render, ...props, children: children }));
|
|
16
|
+
}
|
|
17
|
+
if (render) {
|
|
18
|
+
return (_jsx(MenuPrimitive.Trigger, { "data-slot": "dropdown-menu-trigger", render: render, ...props, children: children }));
|
|
19
|
+
}
|
|
20
|
+
return (_jsx(MenuPrimitive.Trigger, { "data-slot": "dropdown-menu-trigger", ...props, children: children }));
|
|
21
|
+
}
|
|
22
|
+
function DropdownMenuContent({ align = 'start', alignOffset = 0, side = 'bottom', sideOffset = 4, className, ...props }) {
|
|
23
|
+
return (_jsx(MenuPrimitive.Portal, { children: _jsx(MenuPrimitive.Positioner, { className: "isolate z-50 outline-none", align: align, alignOffset: alignOffset, side: side, sideOffset: sideOffset, children: _jsx(MenuPrimitive.Popup, { "data-slot": "dropdown-menu-content", className: cn('data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-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-[side=inline-start]:slide-in-from-right-2 data-[side=inline-end]:slide-in-from-left-2 z-50 max-h-(--available-height) w-(--anchor-width) min-w-32 origin-(--transform-origin) overflow-y-auto overflow-x-hidden rounded-lg bg-popover p-1 text-popover-foreground shadow-md outline-none ring-1 ring-foreground/10 duration-100 data-closed:animate-out data-open:animate-in data-closed:overflow-hidden', className), ...props }) }) }));
|
|
24
|
+
}
|
|
25
|
+
function DropdownMenuGroup({ ...props }) {
|
|
26
|
+
return _jsx(MenuPrimitive.Group, { "data-slot": "dropdown-menu-group", ...props });
|
|
27
|
+
}
|
|
28
|
+
function DropdownMenuLabel({ className, inset, ...props }) {
|
|
29
|
+
return (_jsx(MenuPrimitive.GroupLabel, { "data-slot": "dropdown-menu-label", "data-inset": inset, className: cn('px-1.5 py-1 font-medium text-muted-foreground text-xs data-[inset]:pl-8', className), ...props }));
|
|
30
|
+
}
|
|
31
|
+
function DropdownMenuItem({ className, inset, variant = 'default', render, onClick, onSelect, children, ...props }) {
|
|
32
|
+
const handleClick = onClick || onSelect
|
|
33
|
+
? (event) => {
|
|
34
|
+
onSelect?.(event);
|
|
35
|
+
onClick?.(event);
|
|
36
|
+
}
|
|
37
|
+
: undefined;
|
|
38
|
+
const itemClassName = cn("focus:bg-accent focus:text-accent-foreground focus:*:[svg]:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:*:[svg]:text-destructive data-[variant=destructive]:focus:bg-destructive data-[variant=destructive]:focus:text-destructive-foreground data-[variant=destructive]:focus:*:[svg]:text-destructive-foreground gap-1.5 rounded-md px-1.5 py-1 text-sm [&_svg:not([class*='size-'])]:size-4 group/dropdown-menu-item relative flex cursor-default items-center outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0", className);
|
|
39
|
+
if (render) {
|
|
40
|
+
return (_jsx(MenuPrimitive.Item, { "data-slot": "dropdown-menu-item", "data-inset": inset, "data-variant": variant, className: itemClassName, render: render, onClick: handleClick, ...props, children: children }));
|
|
41
|
+
}
|
|
42
|
+
return (_jsx(MenuPrimitive.Item, { "data-slot": "dropdown-menu-item", "data-inset": inset, "data-variant": variant, className: itemClassName, onClick: handleClick, ...props, children: children }));
|
|
43
|
+
}
|
|
44
|
+
function DropdownMenuSub({ ...props }) {
|
|
45
|
+
return _jsx(MenuPrimitive.SubmenuRoot, { "data-slot": "dropdown-menu-sub", ...props });
|
|
46
|
+
}
|
|
47
|
+
function DropdownMenuSubTrigger({ className, inset, children, ...props }) {
|
|
48
|
+
return (_jsxs(MenuPrimitive.SubmenuTrigger, { "data-slot": "dropdown-menu-sub-trigger", "data-inset": inset, className: cn("flex cursor-default select-none items-center gap-1.5 rounded-md px-1.5 py-1 text-sm outline-hidden focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-open:bg-accent data-[inset]:pl-8 data-open:text-accent-foreground [&>[data-chevron]]:transition-transform [&>[data-chevron]]:duration-200 data-open:[&>[data-chevron]]:rotate-90 [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0", className), ...props, children: [children, _jsx(ChevronRightIcon, { "data-chevron": "", className: "ml-auto" })] }));
|
|
49
|
+
}
|
|
50
|
+
function DropdownMenuSubContent({ align = 'start', alignOffset = -3, side = 'right', sideOffset = 0, className, ...props }) {
|
|
51
|
+
return (_jsx(DropdownMenuContent, { "data-slot": "dropdown-menu-sub-content", className: cn('data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-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 w-auto min-w-[96px] rounded-md bg-popover p-1 text-popover-foreground shadow-lg ring-1 ring-foreground/10 duration-100 data-closed:animate-out data-open:animate-in', className), align: align, alignOffset: alignOffset, side: side, sideOffset: sideOffset, ...props }));
|
|
52
|
+
}
|
|
53
|
+
function DropdownMenuCheckboxItem({ className, children, checked, ...props }) {
|
|
54
|
+
return (_jsxs(MenuPrimitive.CheckboxItem, { "data-slot": "dropdown-menu-checkbox-item", className: cn("relative flex cursor-default select-none items-center gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0", className), checked: checked, ...props, children: [_jsx("span", { className: "pointer-events-none pointer-events-none absolute right-2 flex items-center justify-center", "data-slot": "dropdown-menu-checkbox-item-indicator", children: _jsx(MenuPrimitive.CheckboxItemIndicator, { children: _jsx(CheckIcon, {}) }) }), children] }));
|
|
55
|
+
}
|
|
56
|
+
function DropdownMenuRadioGroup({ ...props }) {
|
|
57
|
+
return _jsx(MenuPrimitive.RadioGroup, { "data-slot": "dropdown-menu-radio-group", ...props });
|
|
58
|
+
}
|
|
59
|
+
function DropdownMenuRadioItem({ className, children, ...props }) {
|
|
60
|
+
return (_jsxs(MenuPrimitive.RadioItem, { "data-slot": "dropdown-menu-radio-item", className: cn("relative flex cursor-default select-none items-center gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0", className), ...props, children: [_jsx("span", { className: "pointer-events-none pointer-events-none absolute right-2 flex items-center justify-center", "data-slot": "dropdown-menu-radio-item-indicator", children: _jsx(MenuPrimitive.RadioItemIndicator, { children: _jsx(CheckIcon, {}) }) }), children] }));
|
|
61
|
+
}
|
|
62
|
+
function DropdownMenuSeparator({ className, ...props }) {
|
|
63
|
+
return (_jsx(MenuPrimitive.Separator, { "data-slot": "dropdown-menu-separator", className: cn('-mx-1 my-1 h-px bg-border', className), ...props }));
|
|
64
|
+
}
|
|
65
|
+
function DropdownMenuShortcut({ className, ...props }) {
|
|
66
|
+
return (_jsx("span", { "data-slot": "dropdown-menu-shortcut", className: cn('ml-auto text-muted-foreground text-xs tracking-widest group-focus/dropdown-menu-item:text-accent-foreground', className), ...props }));
|
|
67
|
+
}
|
|
68
|
+
export { DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { Tooltip as TooltipPrimitive } from '@base-ui/react/tooltip';
|
|
2
|
+
declare function TooltipProvider({ delay, ...props }: TooltipPrimitive.Provider.Props): import("react/jsx-runtime").JSX.Element;
|
|
3
|
+
declare function Tooltip({ ...props }: TooltipPrimitive.Root.Props): import("react/jsx-runtime").JSX.Element;
|
|
4
|
+
declare function TooltipTrigger({ ...props }: TooltipPrimitive.Trigger.Props): import("react/jsx-runtime").JSX.Element;
|
|
5
|
+
declare function TooltipContent({ className, side, sideOffset, align, alignOffset, children, ...props }: TooltipPrimitive.Popup.Props & Pick<TooltipPrimitive.Positioner.Props, 'align' | 'alignOffset' | 'side' | 'sideOffset'>): import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
export { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { Tooltip as TooltipPrimitive } from '@base-ui/react/tooltip';
|
|
4
|
+
import { cn } from '../../lib/utils.js';
|
|
5
|
+
function TooltipProvider({ delay = 0, ...props }) {
|
|
6
|
+
return _jsx(TooltipPrimitive.Provider, { "data-slot": "tooltip-provider", delay: delay, ...props });
|
|
7
|
+
}
|
|
8
|
+
function Tooltip({ ...props }) {
|
|
9
|
+
return _jsx(TooltipPrimitive.Root, { "data-slot": "tooltip", ...props });
|
|
10
|
+
}
|
|
11
|
+
function TooltipTrigger({ ...props }) {
|
|
12
|
+
return _jsx(TooltipPrimitive.Trigger, { "data-slot": "tooltip-trigger", ...props });
|
|
13
|
+
}
|
|
14
|
+
function TooltipContent({ className, side = 'top', sideOffset = 4, align = 'center', alignOffset = 0, children, ...props }) {
|
|
15
|
+
return (_jsx(TooltipPrimitive.Portal, { children: _jsx(TooltipPrimitive.Positioner, { align: align, alignOffset: alignOffset, side: side, sideOffset: sideOffset, className: "isolate z-50", children: _jsxs(TooltipPrimitive.Popup, { "data-slot": "tooltip-content", className: cn('data-open:fade-in-0 data-open:zoom-in-95 data-closed:fade-out-0 data-closed:zoom-out-95', 'data-[side=bottom]:slide-in-from-top-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-[side=inline-start]:slide-in-from-right-2 data-[side=inline-end]:slide-in-from-left-2', 'z-50 w-fit max-w-xs origin-(--transform-origin) rounded-md', 'bg-foreground px-3 py-1.5 text-background text-xs', 'data-closed:animate-out data-open:animate-in', 'dark:bg-card dark:text-foreground dark:ring-1 dark:ring-border', className), role: "tooltip", ...props, children: [children, _jsx(TooltipPrimitive.Arrow, { className: cn('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=top]:-bottom-2.5', 'data-[side=left]:-right-1 data-[side=right]:-left-1', 'data-[side=inline-start]:-right-1 data-[side=inline-end]:-left-1', 'data-[side=inline-end]:top-1/2! data-[side=inline-start]:top-1/2!', 'data-[side=left]:top-1/2! data-[side=right]:top-1/2!', 'data-[side=inline-end]:-translate-y-1/2 data-[side=inline-start]:-translate-y-1/2', 'data-[side=left]:-translate-y-1/2 data-[side=right]:-translate-y-1/2', 'dark:bg-card dark:fill-card') })] }) }) }));
|
|
16
|
+
}
|
|
17
|
+
export { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger };
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -1 +1,6 @@
|
|
|
1
|
-
export * from './
|
|
1
|
+
export * from './brand/public.js';
|
|
2
|
+
export * from './chat/public.js';
|
|
3
|
+
export * from './marketing/public.js';
|
|
4
|
+
export * from './panel/public.js';
|
|
5
|
+
export * from './shell/index.js'; // v2 surface
|
|
6
|
+
export * from './timeline/public.js';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface FormatClockOptions {
|
|
2
|
+
/** IANA timezone, e.g. "Europe/Stockholm". Defaults to local tz. */
|
|
3
|
+
tz?: string;
|
|
4
|
+
/** Include seconds (default true). */
|
|
5
|
+
withSeconds?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare function formatClock(date: Date, opts?: FormatClockOptions): string;
|
|
8
|
+
export declare function formatDuration(ms: number): string;
|
|
9
|
+
export declare function formatRelativeOffset(ms: number): string;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export function formatClock(date, opts = {}) {
|
|
2
|
+
const { tz, withSeconds = true } = opts;
|
|
3
|
+
const fmt = new Intl.DateTimeFormat('en-GB', {
|
|
4
|
+
hour: '2-digit',
|
|
5
|
+
minute: '2-digit',
|
|
6
|
+
second: withSeconds ? '2-digit' : undefined,
|
|
7
|
+
hour12: false,
|
|
8
|
+
timeZone: tz,
|
|
9
|
+
});
|
|
10
|
+
return fmt.format(date);
|
|
11
|
+
}
|
|
12
|
+
export function formatDuration(ms) {
|
|
13
|
+
if (ms < 0)
|
|
14
|
+
ms = 0;
|
|
15
|
+
const totalSec = Math.floor(ms / 1000);
|
|
16
|
+
const h = Math.floor(totalSec / 3600);
|
|
17
|
+
const m = Math.floor((totalSec % 3600) / 60);
|
|
18
|
+
const s = totalSec % 60;
|
|
19
|
+
if (h > 0)
|
|
20
|
+
return `${h}h ${m}m`;
|
|
21
|
+
if (m > 0)
|
|
22
|
+
return `${m}m ${s}s`;
|
|
23
|
+
return `${s}s`;
|
|
24
|
+
}
|
|
25
|
+
export function formatRelativeOffset(ms) {
|
|
26
|
+
const sign = ms < 0 ? '-' : '+';
|
|
27
|
+
const abs = Math.abs(ms);
|
|
28
|
+
const totalSec = Math.floor(abs / 1000);
|
|
29
|
+
const m = Math.floor(totalSec / 60);
|
|
30
|
+
const s = totalSec % 60;
|
|
31
|
+
if (m === 0)
|
|
32
|
+
return `${sign}${s}s`;
|
|
33
|
+
return `${sign}${m}m ${s}s`;
|
|
34
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { MarketingCallout } from './marketing-callout.js';
|
|
2
|
+
export { MarketingContact } from './marketing-contact.js';
|
|
3
|
+
export { MarketingCtaList } from './marketing-cta-list.js';
|
|
4
|
+
export { MarketingLeadMagnet } from './marketing-lead-magnet.js';
|
|
5
|
+
export type { MarketingAlign, MarketingCalloutProps, MarketingCalloutVariant, MarketingContactPerson, MarketingContactProps, MarketingCta, MarketingCtaListProps, MarketingCtaVariant, MarketingLeadMagnetProps, MarketingLeadMagnetVariant, MarketingOffice, } from './types.js';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { MarketingCtaList } from './marketing-cta-list.js';
|
|
4
|
+
import { cx } from './utils.js';
|
|
5
|
+
export function MarketingCallout({ eyebrow, title, description, children, ctas, variant = 'band', align = 'center', className, }) {
|
|
6
|
+
const isCard = variant === 'card';
|
|
7
|
+
return (_jsx("section", { className: cx('relative overflow-hidden border border-border bg-card text-card-foreground', isCard ? 'rounded-lg px-6 py-8 shadow-sm' : 'px-6 py-14 sm:px-8 sm:py-16', className), children: _jsxs("div", { className: cx('mx-auto flex max-w-4xl flex-col gap-5', align === 'center' ? 'items-center text-center' : 'items-start text-left'), children: [eyebrow && _jsx("p", { className: "text-sm font-semibold text-primary", children: eyebrow }), _jsx("h2", { className: "max-w-3xl text-3xl font-bold leading-tight text-foreground sm:text-4xl", children: title }), description && (_jsx("p", { className: "max-w-2xl text-base leading-7 text-muted-foreground sm:text-lg", children: description })), children && (_jsx("div", { className: "max-w-2xl text-base leading-7 text-muted-foreground", children: children })), _jsx(MarketingCtaList, { ctas: ctas, align: align, className: "mt-1" })] }) }));
|
|
8
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { Clock, Mail, MapPin, Phone, Smartphone } from 'lucide-react';
|
|
4
|
+
import { cx, toTelHref } from './utils.js';
|
|
5
|
+
function InfoRow({ icon: Icon, label, children }) {
|
|
6
|
+
return (_jsxs("div", { className: "flex items-start gap-3", children: [_jsx("span", { className: "mt-0.5 inline-flex size-9 shrink-0 items-center justify-center rounded-md bg-primary/10 text-primary", children: _jsx(Icon, { className: "size-4", "aria-hidden": true }) }), _jsxs("div", { className: "min-w-0", children: [_jsx("p", { className: "mb-1 text-sm font-semibold text-foreground", children: label }), _jsx("div", { className: "text-sm leading-6 text-muted-foreground", children: children })] })] }));
|
|
7
|
+
}
|
|
8
|
+
function DetailCard({ title, children }) {
|
|
9
|
+
return (_jsxs("section", { className: "rounded-lg border border-border bg-card p-6 text-card-foreground shadow-sm", children: [title && _jsx("h3", { className: "mb-5 text-lg font-semibold text-foreground", children: title }), children] }));
|
|
10
|
+
}
|
|
11
|
+
function OfficeInfo({ office }) {
|
|
12
|
+
return (_jsx(DetailCard, { title: office.title ?? 'Office', children: _jsxs("div", { className: "space-y-5", children: [office.address && (_jsx(InfoRow, { icon: MapPin, label: "Address", children: office.address })), office.email && (_jsx(InfoRow, { icon: Mail, label: "Email", children: _jsx("a", { className: "hover:text-foreground", href: `mailto:${office.email}`, children: office.email }) })), office.phone && (_jsx(InfoRow, { icon: Phone, label: "Phone", children: _jsx("a", { className: "hover:text-foreground", href: toTelHref(office.phone), children: office.phone }) })), office.hours && (_jsx(InfoRow, { icon: Clock, label: "Opening hours", children: office.hours }))] }) }));
|
|
13
|
+
}
|
|
14
|
+
function ContactPerson({ person }) {
|
|
15
|
+
return (_jsx(DetailCard, { title: person.title ?? 'Direct contact', children: _jsxs("div", { className: "flex flex-col gap-5 sm:flex-row", children: [person.image && _jsx("div", { className: "shrink-0 overflow-hidden rounded-lg", children: person.image }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("h4", { className: "text-lg font-semibold text-foreground", children: person.name }), person.role && _jsx("p", { className: "mt-1 text-sm font-semibold text-primary", children: person.role }), person.description && (_jsx("p", { className: "mt-3 text-sm leading-6 text-muted-foreground", children: person.description })), (person.email || person.phone) && (_jsxs("div", { className: "mt-4 space-y-2 text-sm text-muted-foreground", children: [person.email && (_jsxs("a", { className: "flex items-center gap-2 hover:text-foreground", href: `mailto:${person.email}`, children: [_jsx(Mail, { className: "size-4", "aria-hidden": true }), person.email] })), person.phone && (_jsxs("a", { className: "flex items-center gap-2 hover:text-foreground", href: toTelHref(person.phone), children: [_jsx(Smartphone, { className: "size-4", "aria-hidden": true }), person.phone] }))] }))] })] }) }));
|
|
16
|
+
}
|
|
17
|
+
export function MarketingContact({ intro, form, office, contactPerson, compact = false, className, }) {
|
|
18
|
+
return (_jsx("section", { className: cx('bg-background px-6 py-12 text-foreground sm:px-8', className), children: _jsxs("div", { className: "mx-auto max-w-6xl", children: [intro && (_jsx("div", { className: cx('mx-auto max-w-3xl text-center', compact ? 'mb-8' : 'mb-12'), children: _jsx("div", { className: "text-base leading-7 text-muted-foreground sm:text-lg", children: intro }) })), _jsxs("div", { className: cx('grid items-start gap-6', compact ? 'grid-cols-1' : 'lg:grid-cols-[minmax(0,1fr)_420px]'), children: [_jsx("div", { className: "rounded-lg border border-border bg-card p-6 shadow-sm", children: form }), (office || contactPerson) && (_jsxs("div", { className: "space-y-6", children: [office && _jsx(OfficeInfo, { office: office }), contactPerson && _jsx(ContactPerson, { person: contactPerson })] }))] })] }) }));
|
|
19
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { cx } from './utils.js';
|
|
4
|
+
const baseCtaClass = 'inline-flex min-h-10 items-center justify-center rounded-md px-4 py-2 text-sm font-semibold transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background';
|
|
5
|
+
const ctaVariantClass = {
|
|
6
|
+
primary: 'bg-primary text-primary-foreground hover:opacity-90',
|
|
7
|
+
secondary: 'border border-border bg-transparent text-foreground hover:bg-surface-highlight hover:text-foreground',
|
|
8
|
+
};
|
|
9
|
+
export function MarketingCtaList({ ctas, align = 'center', className }) {
|
|
10
|
+
if (!ctas?.length)
|
|
11
|
+
return null;
|
|
12
|
+
return (_jsx("div", { className: cx('flex flex-wrap gap-3', align === 'center' ? 'justify-center' : 'justify-start', className), children: ctas.map((cta, index) => {
|
|
13
|
+
const variant = cta.variant ?? (index === 0 ? 'primary' : 'secondary');
|
|
14
|
+
const className = cx(baseCtaClass, ctaVariantClass[variant]);
|
|
15
|
+
const key = typeof cta.label === 'string' ? `${cta.label}-${index}` : `marketing-cta-${index}`;
|
|
16
|
+
if (cta.href) {
|
|
17
|
+
return (_jsx("a", { href: cta.href, "aria-label": cta.ariaLabel, className: className, target: cta.target, rel: cta.rel, children: cta.label }, key));
|
|
18
|
+
}
|
|
19
|
+
return (_jsx("button", { type: "button", "aria-label": cta.ariaLabel, className: className, onClick: cta.onClick, children: cta.label }, key));
|
|
20
|
+
}) }));
|
|
21
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import type { MarketingLeadMagnetProps } from './types.js';
|
|
2
|
+
export declare function MarketingLeadMagnet({ title, description, benefits, image, buttonText, formTitle, form, variant, open, defaultOpen, onOpenChange, className, }: MarketingLeadMagnetProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { Dialog } from '@base-ui/react/dialog';
|
|
4
|
+
import { CheckCircle2, X } from 'lucide-react';
|
|
5
|
+
import { cx } from './utils.js';
|
|
6
|
+
export function MarketingLeadMagnet({ title, description, benefits = [], image, buttonText = 'Download now', formTitle = 'Get the resource', form, variant = 'featured', open, defaultOpen, onOpenChange, className, }) {
|
|
7
|
+
const isSidebar = variant === 'sidebar';
|
|
8
|
+
return (_jsx("section", { className: cx('overflow-hidden rounded-lg border border-border bg-card text-card-foreground shadow-sm', isSidebar ? 'p-6' : 'p-6 sm:p-8 lg:p-10', className), children: _jsxs("div", { className: cx('grid gap-8', isSidebar ? 'grid-cols-1' : 'lg:grid-cols-[0.8fr_1fr]'), children: [!isSidebar && image && _jsx("div", { className: "overflow-hidden rounded-lg bg-muted", children: image }), _jsxs("div", { className: "flex min-w-0 flex-col items-start justify-center", children: [_jsx("h2", { className: "text-2xl font-bold leading-tight text-foreground sm:text-3xl", children: title }), description && (_jsx("p", { className: "mt-3 text-base leading-7 text-muted-foreground", children: description })), benefits.length > 0 && (_jsx("ul", { className: "mt-5 space-y-3", children: benefits.map((benefit, index) => (_jsxs("li", { className: "flex items-start gap-3 text-sm leading-6 text-muted-foreground", children: [_jsx(CheckCircle2, { className: "mt-0.5 size-4 shrink-0 text-primary", "aria-hidden": true }), _jsx("span", { children: benefit })] }, typeof benefit === 'string' ? `${benefit}-${index}` : `benefit-${index}`))) })), _jsxs(Dialog.Root, { open: open, defaultOpen: defaultOpen, onOpenChange: (nextOpen) => onOpenChange?.(nextOpen), children: [_jsx(Dialog.Trigger, { className: "mt-6 inline-flex min-h-10 items-center justify-center rounded-md bg-primary px-4 py-2 text-sm font-semibold text-primary-foreground transition-colors hover:opacity-90 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background", children: buttonText }), _jsxs(Dialog.Portal, { children: [_jsx(Dialog.Backdrop, { className: "fixed inset-0 z-modal bg-background/80 backdrop-blur-sm" }), _jsxs(Dialog.Popup, { className: "fixed left-1/2 top-1/2 z-modal w-[calc(100vw-2rem)] max-w-lg -translate-x-1/2 -translate-y-1/2 overflow-hidden rounded-lg border border-border bg-card text-card-foreground shadow-lg focus-visible:outline-none", children: [_jsxs("div", { className: "flex items-start justify-between gap-4 border-b border-border px-6 py-5", children: [_jsx(Dialog.Title, { className: "text-lg font-semibold text-foreground", children: formTitle }), _jsxs(Dialog.Close, { className: "inline-flex size-8 shrink-0 items-center justify-center rounded-md text-muted-foreground hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", children: [_jsx("span", { className: "sr-only", children: "Close" }), _jsx(X, { className: "size-4", "aria-hidden": true })] })] }), _jsx("div", { className: "p-6", children: form })] })] })] })] })] }) }));
|
|
9
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type { MarketingCalloutProps, MarketingContactPerson, MarketingContactProps, MarketingCta, MarketingLeadMagnetProps, MarketingOffice, } from './types.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { MouseEventHandler, ReactNode } from 'react';
|
|
2
|
+
export type MarketingCtaVariant = 'primary' | 'secondary';
|
|
3
|
+
export type MarketingAlign = 'start' | 'center';
|
|
4
|
+
export interface MarketingCta {
|
|
5
|
+
label: ReactNode;
|
|
6
|
+
href?: string;
|
|
7
|
+
onClick?: MouseEventHandler<HTMLButtonElement>;
|
|
8
|
+
variant?: MarketingCtaVariant;
|
|
9
|
+
ariaLabel?: string;
|
|
10
|
+
target?: string;
|
|
11
|
+
rel?: string;
|
|
12
|
+
}
|
|
13
|
+
export interface MarketingCtaListProps {
|
|
14
|
+
ctas?: MarketingCta[];
|
|
15
|
+
align?: MarketingAlign;
|
|
16
|
+
className?: string;
|
|
17
|
+
}
|
|
18
|
+
export type MarketingCalloutVariant = 'band' | 'card';
|
|
19
|
+
export interface MarketingCalloutProps {
|
|
20
|
+
eyebrow?: ReactNode;
|
|
21
|
+
title: ReactNode;
|
|
22
|
+
description?: ReactNode;
|
|
23
|
+
children?: ReactNode;
|
|
24
|
+
ctas?: MarketingCta[];
|
|
25
|
+
variant?: MarketingCalloutVariant;
|
|
26
|
+
align?: MarketingAlign;
|
|
27
|
+
className?: string;
|
|
28
|
+
}
|
|
29
|
+
export interface MarketingOffice {
|
|
30
|
+
title?: ReactNode;
|
|
31
|
+
address?: ReactNode;
|
|
32
|
+
email?: string;
|
|
33
|
+
phone?: string;
|
|
34
|
+
hours?: ReactNode;
|
|
35
|
+
}
|
|
36
|
+
export interface MarketingContactPerson {
|
|
37
|
+
title?: ReactNode;
|
|
38
|
+
name: ReactNode;
|
|
39
|
+
role?: ReactNode;
|
|
40
|
+
description?: ReactNode;
|
|
41
|
+
image?: ReactNode;
|
|
42
|
+
email?: string;
|
|
43
|
+
phone?: string;
|
|
44
|
+
}
|
|
45
|
+
export interface MarketingContactProps {
|
|
46
|
+
intro?: ReactNode;
|
|
47
|
+
form: ReactNode;
|
|
48
|
+
office?: MarketingOffice;
|
|
49
|
+
contactPerson?: MarketingContactPerson;
|
|
50
|
+
compact?: boolean;
|
|
51
|
+
className?: string;
|
|
52
|
+
}
|
|
53
|
+
export type MarketingLeadMagnetVariant = 'featured' | 'sidebar';
|
|
54
|
+
export interface MarketingLeadMagnetProps {
|
|
55
|
+
title: ReactNode;
|
|
56
|
+
description?: ReactNode;
|
|
57
|
+
benefits?: ReactNode[];
|
|
58
|
+
image?: ReactNode;
|
|
59
|
+
buttonText?: ReactNode;
|
|
60
|
+
formTitle?: ReactNode;
|
|
61
|
+
form?: ReactNode;
|
|
62
|
+
variant?: MarketingLeadMagnetVariant;
|
|
63
|
+
open?: boolean;
|
|
64
|
+
defaultOpen?: boolean;
|
|
65
|
+
onOpenChange?: (open: boolean) => void;
|
|
66
|
+
className?: string;
|
|
67
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export type { InspectorProps } from './inspector.js';
|
|
2
|
+
export { Inspector } from './inspector.js';
|
|
3
|
+
export type { InspectorFieldProps } from './inspector-field.js';
|
|
4
|
+
export { InspectorField } from './inspector-field.js';
|
|
5
|
+
export type { InspectorJSONProps } from './inspector-json.js';
|
|
6
|
+
export { InspectorJSON } from './inspector-json.js';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
export interface InspectorFieldProps {
|
|
3
|
+
label: string;
|
|
4
|
+
value: ReactNode;
|
|
5
|
+
/** Optional smaller hint after the value, e.g. provider info. */
|
|
6
|
+
hint?: ReactNode;
|
|
7
|
+
className?: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function InspectorField({ label, value, hint, className }: InspectorFieldProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
export function InspectorField({ label, value, hint, className }) {
|
|
3
|
+
return (_jsxs("div", { className: ['border-b border-border py-3 last:border-b-0', className ?? ''].join(' '), children: [_jsx("div", { className: "mb-1.5 text-[10px] font-semibold uppercase tracking-wider text-muted-foreground", children: label }), _jsxs("div", { className: "text-[13px] tabular-nums text-foreground", children: [value, hint != null && _jsxs("span", { className: "text-[12px] text-muted-foreground", children: [" ", hint] })] })] }));
|
|
4
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
function tokenize(value, level, key, indent, seen) {
|
|
3
|
+
const out = [];
|
|
4
|
+
const pad = ' '.repeat(level * indent);
|
|
5
|
+
if (key !== null) {
|
|
6
|
+
out.push({ kind: 'punct', text: pad });
|
|
7
|
+
out.push({ kind: 'key', text: `"${key}"` });
|
|
8
|
+
out.push({ kind: 'punct', text: ': ' });
|
|
9
|
+
}
|
|
10
|
+
else {
|
|
11
|
+
out.push({ kind: 'punct', text: pad });
|
|
12
|
+
}
|
|
13
|
+
if (value === null) {
|
|
14
|
+
out.push({ kind: 'literal', text: 'null' });
|
|
15
|
+
}
|
|
16
|
+
else if (typeof value === 'string') {
|
|
17
|
+
out.push({ kind: 'string', text: JSON.stringify(value) });
|
|
18
|
+
}
|
|
19
|
+
else if (typeof value === 'number') {
|
|
20
|
+
out.push({ kind: 'number', text: String(value) });
|
|
21
|
+
}
|
|
22
|
+
else if (typeof value === 'boolean') {
|
|
23
|
+
out.push({ kind: 'literal', text: String(value) });
|
|
24
|
+
}
|
|
25
|
+
else if (Array.isArray(value)) {
|
|
26
|
+
if (seen.has(value)) {
|
|
27
|
+
out.push({ kind: 'literal', text: '"[Circular]"' });
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
seen.add(value);
|
|
31
|
+
out.push({ kind: 'punct', text: '[\n' });
|
|
32
|
+
value.forEach((v, i) => {
|
|
33
|
+
out.push(...tokenize(v, level + 1, null, indent, seen));
|
|
34
|
+
out.push({ kind: 'punct', text: i < value.length - 1 ? ',\n' : '\n' });
|
|
35
|
+
});
|
|
36
|
+
out.push({ kind: 'punct', text: `${pad}]` });
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
else if (typeof value === 'object') {
|
|
40
|
+
const obj = value;
|
|
41
|
+
if (seen.has(obj)) {
|
|
42
|
+
out.push({ kind: 'literal', text: '"[Circular]"' });
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
seen.add(obj);
|
|
46
|
+
out.push({ kind: 'punct', text: '{\n' });
|
|
47
|
+
const entries = Object.entries(obj);
|
|
48
|
+
entries.forEach(([k, v], i) => {
|
|
49
|
+
out.push(...tokenize(v, level + 1, k, indent, seen));
|
|
50
|
+
out.push({ kind: 'punct', text: i < entries.length - 1 ? ',\n' : '\n' });
|
|
51
|
+
});
|
|
52
|
+
out.push({ kind: 'punct', text: `${pad}}` });
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
out.push({ kind: 'literal', text: String(value) });
|
|
57
|
+
}
|
|
58
|
+
return out;
|
|
59
|
+
}
|
|
60
|
+
// 700-shade variants for syntax tokens so 11px monospace text clears
|
|
61
|
+
// WCAG AA (4.5:1) against the inspector's near-white background.
|
|
62
|
+
const KIND_CLASS = {
|
|
63
|
+
punct: 'text-muted-foreground',
|
|
64
|
+
key: 'text-primary',
|
|
65
|
+
string: 'text-emerald-700',
|
|
66
|
+
number: 'text-amber-700',
|
|
67
|
+
literal: 'text-amber-700',
|
|
68
|
+
};
|
|
69
|
+
export function InspectorJSON({ data, indent = 2, className }) {
|
|
70
|
+
const tokens = tokenize(data, 0, null, indent, new WeakSet());
|
|
71
|
+
return (_jsx("pre", { className: [
|
|
72
|
+
'mt-1.5 overflow-x-auto rounded-md border border-border bg-background p-2.5 font-mono text-[11px] leading-relaxed text-foreground',
|
|
73
|
+
className ?? '',
|
|
74
|
+
].join(' '), children: tokens.map((t, i) => (_jsx("span", { className: KIND_CLASS[t.kind], children: t.text }, i))) }));
|
|
75
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { InspectorTab } from './types.js';
|
|
2
|
+
export interface InspectorProps {
|
|
3
|
+
tabs: InspectorTab[];
|
|
4
|
+
defaultTab?: string;
|
|
5
|
+
className?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function Inspector({ tabs, defaultTab, className }: InspectorProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
export function Inspector({ tabs, defaultTab, className }) {
|
|
4
|
+
const [active, setActive] = useState(defaultTab ?? tabs[0]?.id ?? '');
|
|
5
|
+
const current = tabs.find((t) => t.id === active) ?? tabs[0];
|
|
6
|
+
return (_jsxs("aside", { className: ['flex h-full flex-col border-l border-border bg-card', className ?? ''].join(' '), children: [_jsx("div", { role: "tablist", className: "flex gap-0.5 border-b border-border px-3.5", children: tabs.map((t) => (_jsx("button", { type: "button", role: "tab", "aria-selected": t.id === active, onClick: () => setActive(t.id), className: [
|
|
7
|
+
'border-b-2 px-2.5 py-3 text-xs',
|
|
8
|
+
t.id === active
|
|
9
|
+
? 'border-primary text-foreground'
|
|
10
|
+
: 'border-transparent text-muted-foreground hover:text-foreground',
|
|
11
|
+
].join(' '), children: t.label }, t.id))) }), _jsx("div", { className: "flex-1 overflow-y-auto px-4 pb-8 pt-4", children: current?.content })] }));
|
|
12
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type { InspectorTab } from './types.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
export declare function AppShell({ children, className }: {
|
|
3
|
+
children: ReactNode;
|
|
4
|
+
className?: string;
|
|
5
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
export declare function AppShellBody({ children, className }: {
|
|
7
|
+
children: ReactNode;
|
|
8
|
+
className?: string;
|
|
9
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { cn } from '../lib/utils.js';
|
|
4
|
+
import { useMedaShell } from './shell-provider.js';
|
|
5
|
+
export function AppShell({ children, className }) {
|
|
6
|
+
const { workspace, activeAppId } = useMedaShell();
|
|
7
|
+
return (_jsx("div", { "data-meda-app": activeAppId, "data-meda-workspace": workspace.id, className: cn('h-screen overflow-hidden bg-background text-foreground', className), children: children }));
|
|
8
|
+
}
|
|
9
|
+
export function AppShellBody({ children, className }) {
|
|
10
|
+
return (_jsx("div", { className: cn('relative flex h-[calc(100vh-var(--shell-header-height))] overflow-hidden', className), children: children }));
|
|
11
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import type { CommandDefinition } from './types.js';
|
|
3
|
+
export interface CommandGroupDefinition {
|
|
4
|
+
id: string;
|
|
5
|
+
label: string;
|
|
6
|
+
/** Lower value = rendered earlier. Default: 100. */
|
|
7
|
+
priority?: number;
|
|
8
|
+
}
|
|
9
|
+
interface CommandRegistry {
|
|
10
|
+
register: (commands: CommandDefinition[]) => void;
|
|
11
|
+
unregister: (ids: string[]) => void;
|
|
12
|
+
registerGroup: (group: CommandGroupDefinition) => void;
|
|
13
|
+
unregisterGroup: (id: string) => void;
|
|
14
|
+
}
|
|
15
|
+
export declare const CommandRegistryContext: import("react").Context<CommandRegistry | null>;
|
|
16
|
+
export declare function matchesHotkey(e: KeyboardEvent, spec: string): boolean;
|
|
17
|
+
export interface CommandPaletteProps {
|
|
18
|
+
children?: ReactNode;
|
|
19
|
+
}
|
|
20
|
+
export declare function CommandPalette({ children }: CommandPaletteProps): import("react/jsx-runtime").JSX.Element;
|
|
21
|
+
export declare function useCommands(commands: CommandDefinition[]): void;
|
|
22
|
+
export declare function useCommandGroup(group: CommandGroupDefinition): void;
|
|
23
|
+
export {};
|