@medalsocial/meda 0.3.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.
Files changed (112) hide show
  1. package/README.md +26 -0
  2. package/dist/brand/index.d.ts +2 -0
  3. package/dist/brand/index.js +1 -0
  4. package/dist/brand/medal-social-mark.d.ts +7 -0
  5. package/dist/brand/medal-social-mark.js +6 -0
  6. package/dist/brand/public.d.ts +2 -0
  7. package/dist/brand/public.js +1 -0
  8. package/dist/chat/latency-badge.js +6 -2
  9. package/dist/chat/tool-call-block.js +1 -1
  10. package/dist/chat/turn-card.js +3 -1
  11. package/dist/components/ui/command.d.ts +19 -0
  12. package/dist/components/ui/command.js +37 -0
  13. package/dist/components/ui/dialog.d.ts +26 -0
  14. package/dist/components/ui/dialog.js +39 -0
  15. package/dist/components/ui/drawer.d.ts +16 -0
  16. package/dist/components/ui/drawer.js +35 -0
  17. package/dist/components/ui/dropdown-menu.d.ts +32 -0
  18. package/dist/components/ui/dropdown-menu.js +68 -0
  19. package/dist/components/ui/tooltip.d.ts +6 -0
  20. package/dist/components/ui/tooltip.js +17 -0
  21. package/dist/index.d.ts +3 -1
  22. package/dist/index.js +3 -1
  23. package/dist/lib/utils.d.ts +2 -0
  24. package/dist/lib/utils.js +5 -0
  25. package/dist/marketing/index.d.ts +5 -0
  26. package/dist/marketing/index.js +4 -0
  27. package/dist/marketing/marketing-callout.d.ts +2 -0
  28. package/dist/marketing/marketing-callout.js +8 -0
  29. package/dist/marketing/marketing-contact.d.ts +2 -0
  30. package/dist/marketing/marketing-contact.js +19 -0
  31. package/dist/marketing/marketing-cta-list.d.ts +2 -0
  32. package/dist/marketing/marketing-cta-list.js +21 -0
  33. package/dist/marketing/marketing-lead-magnet.d.ts +2 -0
  34. package/dist/marketing/marketing-lead-magnet.js +9 -0
  35. package/dist/marketing/public.d.ts +1 -0
  36. package/dist/marketing/public.js +1 -0
  37. package/dist/marketing/types.d.ts +67 -0
  38. package/dist/marketing/types.js +1 -0
  39. package/dist/marketing/utils.d.ts +2 -0
  40. package/dist/marketing/utils.js +6 -0
  41. package/dist/panel/inspector-json.js +5 -3
  42. package/dist/shell/app-shell.d.ts +9 -0
  43. package/dist/shell/app-shell.js +11 -0
  44. package/dist/shell/command-palette.d.ts +23 -0
  45. package/dist/shell/command-palette.js +138 -0
  46. package/dist/shell/context-rail.d.ts +31 -0
  47. package/dist/shell/context-rail.js +81 -0
  48. package/dist/shell/extras/index.d.ts +4 -0
  49. package/dist/shell/extras/index.js +4 -0
  50. package/dist/shell/extras/shell-desktop-panel-dock.d.ts +14 -0
  51. package/dist/shell/extras/shell-desktop-panel-dock.js +43 -0
  52. package/dist/shell/extras/shell-scrollable-content.d.ts +9 -0
  53. package/dist/shell/extras/shell-scrollable-content.js +7 -0
  54. package/dist/shell/extras/shell-tab-bar.d.ts +18 -0
  55. package/dist/shell/extras/shell-tab-bar.js +27 -0
  56. package/dist/shell/extras/types.d.ts +64 -0
  57. package/dist/shell/extras/types.js +2 -0
  58. package/dist/shell/extras/workbench-layout.d.ts +10 -0
  59. package/dist/shell/extras/workbench-layout.js +29 -0
  60. package/dist/shell/icon-rail.d.ts +29 -0
  61. package/dist/shell/icon-rail.js +38 -0
  62. package/dist/shell/index.d.ts +24 -15
  63. package/dist/shell/index.js +35 -15
  64. package/dist/shell/layout-state.d.ts +32 -0
  65. package/dist/shell/layout-state.js +98 -0
  66. package/dist/shell/mobile/mobile-bottom-nav.d.ts +15 -0
  67. package/dist/shell/mobile/mobile-bottom-nav.js +76 -0
  68. package/dist/shell/mobile/mobile-drawers.d.ts +20 -0
  69. package/dist/shell/mobile/mobile-drawers.js +62 -0
  70. package/dist/shell/mobile/mobile-header.d.ts +23 -0
  71. package/dist/shell/mobile/mobile-header.js +22 -0
  72. package/dist/shell/motion.d.ts +22 -0
  73. package/dist/shell/motion.js +19 -0
  74. package/dist/shell/public.d.ts +16 -2
  75. package/dist/shell/public.js +20 -1
  76. package/dist/shell/resizable-shell.d.ts +45 -0
  77. package/dist/shell/resizable-shell.js +15 -0
  78. package/dist/shell/right-panel.d.ts +15 -0
  79. package/dist/shell/right-panel.js +126 -0
  80. package/dist/shell/shell-auth-frame.d.ts +22 -0
  81. package/dist/shell/shell-auth-frame.js +60 -0
  82. package/dist/shell/shell-header.d.ts +10 -9
  83. package/dist/shell/shell-header.js +57 -14
  84. package/dist/shell/shell-layout-utils.d.ts +2 -2
  85. package/dist/shell/shell-main.d.ts +8 -0
  86. package/dist/shell/shell-main.js +11 -0
  87. package/dist/shell/shell-provider.d.ts +65 -0
  88. package/dist/shell/shell-provider.js +152 -0
  89. package/dist/shell/shell-route-utils.d.ts +1 -1
  90. package/dist/shell/theme-next-themes.d.ts +4 -0
  91. package/dist/shell/theme-next-themes.js +24 -0
  92. package/dist/shell/theme.d.ts +9 -0
  93. package/dist/shell/theme.js +58 -0
  94. package/dist/shell/types.d.ts +41 -41
  95. package/dist/shell/types.js +1 -0
  96. package/dist/shell/use-shell-viewport.d.ts +2 -0
  97. package/dist/shell/use-shell-viewport.js +40 -0
  98. package/dist/shell/utils.d.ts +1 -1
  99. package/dist/styles/globals.css +26 -0
  100. package/dist/styles/theme.css +147 -0
  101. package/dist/styles/tokens.css +338 -0
  102. package/dist/timeline/date-switcher.js +3 -1
  103. package/dist/timeline/event-card.js +5 -13
  104. package/dist/timeline/live-indicator.js +3 -1
  105. package/dist/timeline/scrub-bar.js +8 -9
  106. package/dist/timeline/timeline-rail.js +6 -4
  107. package/dist/timeline/timeline-tape.js +7 -8
  108. package/dist/voice/voice-level.js +3 -1
  109. package/dist/voice/voice-orb-scene.js +1 -0
  110. package/dist/voice/voice-orb.js +9 -11
  111. package/dist/voice/voice-status-pill.js +4 -9
  112. package/package.json +53 -6
package/README.md CHANGED
@@ -52,6 +52,7 @@ See the [demo app](./demo) for a live playground.
52
52
 
53
53
  - `@medalsocial/meda` — curated public API (components + helpers)
54
54
  - `@medalsocial/meda/shell` — shell-only subpath
55
+ - `@medalsocial/meda/marketing` — marketing sections and campaign blocks
55
56
  - `@medalsocial/meda/styles.css` — design tokens + base styles
56
57
 
57
58
  ## Alternative: shadcn registry
@@ -73,10 +74,35 @@ The registry index is at `https://meda.medalsocial.com/registry.json`. Source JS
73
74
  pnpm install
74
75
  pnpm build # compile dist/
75
76
  pnpm test # vitest (jsdom)
77
+ pnpm typecheck
78
+ pnpm lint
76
79
  pnpm registry:validate
77
80
  pnpm demo:dev # run the playground locally
81
+ pnpm storybook # http://localhost:6006
82
+ pnpm storybook:build # storybook-static/
83
+ pnpm size-limit # bundle-size gate
78
84
  ```
79
85
 
86
+ ## Storybook + Chromatic
87
+
88
+ Stories are colocated as `Component.stories.tsx` next to each primitive. Build
89
+ the static bundle with:
90
+
91
+ ```bash
92
+ pnpm storybook:build
93
+ ```
94
+
95
+ Visual review runs via **Chromatic**. The `Chromatic` GitHub workflow publishes
96
+ Storybook on pushes and pull requests targeting `dev` or `prod`, using the
97
+ repository secret `CHROMATIC_PROJECT_TOKEN`.
98
+
99
+ ```bash
100
+ pnpm chromatic
101
+ ```
102
+
103
+ Chromatic handles UI diffs and review state, so visual snapshot baselines are
104
+ not committed to this repository.
105
+
80
106
  ## Release
81
107
 
82
108
  Changesets + GitHub Actions (OIDC trusted publishing). Add a changeset with `pnpm changeset`, merge to the release branch, and the `Release` workflow handles npm publish with provenance.
@@ -0,0 +1,2 @@
1
+ export type { MedalSocialMarkProps } from './medal-social-mark.js';
2
+ export { MedalSocialMark } from './medal-social-mark.js';
@@ -0,0 +1 @@
1
+ export { MedalSocialMark } from './medal-social-mark.js';
@@ -0,0 +1,7 @@
1
+ import type { SVGProps } from 'react';
2
+ export interface MedalSocialMarkProps extends SVGProps<SVGSVGElement> {
3
+ title?: string;
4
+ backgroundColor?: string;
5
+ markColor?: string;
6
+ }
7
+ export declare function MedalSocialMark({ title, backgroundColor, markColor, role, focusable, 'aria-hidden': ariaHidden, ...props }: MedalSocialMarkProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,6 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ export function MedalSocialMark({ title, backgroundColor = 'hsl(0, 0%, 10%)', markColor = 'hsl(0, 0%, 90%)', role, focusable = 'false', 'aria-hidden': ariaHidden, ...props }) {
3
+ const accessibleTitle = title?.trim();
4
+ const hasAccessibleName = Boolean(accessibleTitle || props['aria-label'] || props['aria-labelledby']);
5
+ return (_jsxs("svg", { ...props, viewBox: "0 0 48 48", fill: "none", role: hasAccessibleName ? (role ?? 'img') : role, "aria-hidden": hasAccessibleName ? ariaHidden : (ariaHidden ?? true), focusable: focusable, children: [_jsx("title", { children: accessibleTitle || 'Medal Social' }), _jsx("circle", { cx: "24", cy: "24", r: "23", fill: backgroundColor }), _jsx("path", { d: "M8 24L24 8L40 24L24 40L8 24Z", stroke: markColor, strokeWidth: "1.3", fill: "none" }), _jsx("circle", { cx: "24", cy: "8.5", r: "2.5", fill: markColor }), _jsx("circle", { cx: "39.5", cy: "24", r: "2.5", fill: markColor }), _jsx("circle", { cx: "24", cy: "39.5", r: "2.5", fill: markColor }), _jsx("circle", { cx: "8.5", cy: "24", r: "2.5", fill: markColor }), _jsx("g", { transform: "translate(12, 12) scale(1)", children: _jsx("path", { d: "M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z", fill: "none", stroke: markColor, strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round" }) })] }));
6
+ }
@@ -0,0 +1,2 @@
1
+ export type { MedalSocialMarkProps } from './medal-social-mark.js';
2
+ export { MedalSocialMark } from './medal-social-mark.js';
@@ -0,0 +1 @@
1
+ export { MedalSocialMark } from './medal-social-mark.js';
@@ -1,8 +1,12 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ // Tones use 700-shade variants so 11px badge text clears WCAG AA (4.5:1)
3
+ // against the white/card background. The 400/500 shades chosen for visual
4
+ // consistency with the colored bar segments don't satisfy contrast at this
5
+ // size, so the *bar* keeps the lighter shade and the *label* uses the darker.
2
6
  const KIND = {
3
- stt: { label: 'STT', tone: 'text-sky-400' },
7
+ stt: { label: 'STT', tone: 'text-sky-700' },
4
8
  claude: { label: 'Claude', tone: 'text-primary' },
5
- tts: { label: 'TTS', tone: 'text-emerald-500' },
9
+ tts: { label: 'TTS', tone: 'text-emerald-700' },
6
10
  };
7
11
  function fmt(ms) {
8
12
  if (ms >= 1000)
@@ -15,5 +15,5 @@ export function ToolCallBlock({ call, className }) {
15
15
  return (_jsxs("div", { className: [
16
16
  'mt-3 rounded-md border border-border border-l-2 border-l-amber-500 bg-card p-3 font-mono text-xs',
17
17
  className ?? '',
18
- ].join(' '), children: [_jsxs("div", { className: "mb-1.5 flex items-center gap-2 text-[11px]", children: [_jsx(Zap, { className: "size-3 text-amber-500" }), _jsx("strong", { className: "font-semibold text-foreground", children: call.name }), call.latencyMs != null && (_jsxs("span", { className: "ml-auto tabular-nums text-muted-foreground", children: [call.latencyMs, "ms"] }))] }), _jsxs("div", { className: "text-muted-foreground", children: [Object.entries(call.args && typeof call.args === 'object' ? call.args : {}).map(([k, v], i) => (_jsxs("span", { children: [i > 0 && ', ', _jsx("span", { className: "text-primary", children: k }), ": ", '', _jsx("span", { className: "text-emerald-500", children: safeStringify(v) })] }, k))), call.resultSummary && (_jsxs("span", { className: "text-muted-foreground", children: [" \u2192 ", call.resultSummary] }))] })] }));
18
+ ].join(' '), children: [_jsxs("div", { className: "mb-1.5 flex items-center gap-2 text-[11px]", children: [_jsx(Zap, { className: "size-3 text-amber-500" }), _jsx("strong", { className: "font-semibold text-foreground", children: call.name }), call.latencyMs != null && (_jsxs("span", { className: "ml-auto tabular-nums text-muted-foreground", children: [call.latencyMs, "ms"] }))] }), _jsxs("div", { className: "text-muted-foreground", children: [Object.entries(call.args && typeof call.args === 'object' ? call.args : {}).map(([k, v], i) => (_jsxs("span", { children: [i > 0 && ', ', _jsx("span", { className: "text-primary", children: k }), ": ", '', _jsx("span", { className: "text-emerald-700", children: safeStringify(v) })] }, k))), call.resultSummary && (_jsxs("span", { className: "text-muted-foreground", children: [" \u2192 ", call.resultSummary] }))] })] }));
19
19
  }
@@ -11,10 +11,12 @@ const SPEAKER_LABEL = {
11
11
  export function TurnCard({ turn, startedAtRef, tz, onPlay, className }) {
12
12
  const label = turn.speakerLabel ?? SPEAKER_LABEL[turn.speaker];
13
13
  const offset = turn.startedAt - startedAtRef;
14
+ // amber-700 (not -500) for the 11px system speaker label so it clears
15
+ // WCAG AA (4.5:1) against the card background.
14
16
  const speakerColor = turn.speaker === 'assistant'
15
17
  ? 'text-primary'
16
18
  : turn.speaker === 'system'
17
- ? 'text-amber-500'
19
+ ? 'text-amber-700'
18
20
  : 'text-foreground';
19
21
  return (_jsxs("div", { className: [
20
22
  'grid grid-cols-[64px_1fr] gap-5 border-b border-border py-4 last:border-b-0',
@@ -0,0 +1,19 @@
1
+ import { Command as CommandPrimitive } from 'cmdk';
2
+ import type * as React from 'react';
3
+ import { Dialog } from './dialog.js';
4
+ declare function Command({ className, ...props }: React.ComponentProps<typeof CommandPrimitive>): import("react/jsx-runtime").JSX.Element;
5
+ declare function CommandDialog({ title, description, children, className, showCloseButton, ...props }: Omit<React.ComponentProps<typeof Dialog>, 'children'> & {
6
+ title?: string;
7
+ description?: string;
8
+ className?: string;
9
+ showCloseButton?: boolean;
10
+ children: React.ReactNode;
11
+ }): import("react/jsx-runtime").JSX.Element;
12
+ declare function CommandInput({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Input>): import("react/jsx-runtime").JSX.Element;
13
+ declare function CommandList({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.List>): import("react/jsx-runtime").JSX.Element;
14
+ declare function CommandEmpty({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Empty>): import("react/jsx-runtime").JSX.Element;
15
+ declare function CommandGroup({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Group>): import("react/jsx-runtime").JSX.Element;
16
+ declare function CommandSeparator({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Separator>): import("react/jsx-runtime").JSX.Element;
17
+ declare function CommandItem({ className, children, ...props }: React.ComponentProps<typeof CommandPrimitive.Item>): import("react/jsx-runtime").JSX.Element;
18
+ declare function CommandShortcut({ className, ...props }: React.ComponentProps<'span'>): import("react/jsx-runtime").JSX.Element;
19
+ export { Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, };
@@ -0,0 +1,37 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { Command as CommandPrimitive } from 'cmdk';
4
+ import { SearchIcon } from 'lucide-react';
5
+ import { cn } from '../../lib/utils.js';
6
+ import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from './dialog.js';
7
+ function Command({ className, ...props }) {
8
+ return (_jsx(CommandPrimitive, { "data-slot": "command", className: cn('flex size-full flex-col overflow-hidden bg-popover text-popover-foreground', className), ...props }));
9
+ }
10
+ function CommandDialog({ title = 'Command Palette', description = 'Search for a command to run...', children, className, showCloseButton = false, ...props }) {
11
+ return (_jsxs(Dialog, { ...props, children: [_jsxs(DialogHeader, { className: "sr-only", children: [_jsx(DialogTitle, { children: title }), _jsx(DialogDescription, { children: description })] }), _jsx(DialogContent, { className: cn('top-[38%] overflow-hidden rounded-xl! p-0 sm:max-w-2xl', className), showCloseButton: showCloseButton, children: children })] }));
12
+ }
13
+ function CommandInput({ className, ...props }) {
14
+ return (_jsxs("div", { "data-slot": "command-input-wrapper", className: "flex items-center gap-3 border-b px-4 py-3", children: [_jsx(SearchIcon, { className: "size-5 shrink-0 text-muted-foreground/60" }), _jsx(CommandPrimitive.Input, { "data-slot": "command-input", className: cn('flex-1 bg-transparent text-base outline-none placeholder:text-muted-foreground/60 disabled:cursor-not-allowed disabled:opacity-50', className), ...props })] }));
15
+ }
16
+ function CommandList({ className, ...props }) {
17
+ return (_jsx(CommandPrimitive.List, { "data-slot": "command-list", className: cn('no-scrollbar max-h-[400px] scroll-py-1 overflow-y-auto overflow-x-hidden p-2 outline-none', className), ...props }));
18
+ }
19
+ function CommandEmpty({ className, ...props }) {
20
+ return (_jsx(CommandPrimitive.Empty, { "data-slot": "command-empty", className: cn('py-6 text-center text-sm', className), ...props }));
21
+ }
22
+ function CommandGroup({ className, ...props }) {
23
+ return (_jsx(CommandPrimitive.Group, { "data-slot": "command-group", className: cn(
24
+ // group heading uses solid muted-foreground (not /70) so 12px
25
+ // labels meet WCAG AA contrast on the popover background.
26
+ 'overflow-hidden text-foreground [&:first-child_[cmdk-group-heading]]:pt-1 [&_[cmdk-group-heading]]:px-3 [&_[cmdk-group-heading]]:pt-4 [&_[cmdk-group-heading]]:pb-1 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group-heading]]:text-xs', className), ...props }));
27
+ }
28
+ function CommandSeparator({ className, ...props }) {
29
+ return (_jsx(CommandPrimitive.Separator, { "data-slot": "command-separator", className: cn('-mx-1 h-px bg-border', className), ...props }));
30
+ }
31
+ function CommandItem({ className, children, ...props }) {
32
+ return (_jsx(CommandPrimitive.Item, { "data-slot": "command-item", className: cn("group/command-item relative flex cursor-default select-none items-center gap-3 rounded-lg px-3 py-2 text-sm outline-hidden data-[disabled=true]:pointer-events-none data-selected:bg-accent data-selected:text-accent-foreground data-[disabled=true]:opacity-50 [&_svg:not([class*='size-'])]:size-5 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg]:text-muted-foreground data-selected:[&_svg]:text-accent-foreground", className), ...props, children: children }));
33
+ }
34
+ function CommandShortcut({ className, ...props }) {
35
+ return (_jsx("span", { "data-slot": "command-shortcut", className: cn('ml-auto text-muted-foreground text-xs tracking-widest group-data-selected/command-item:text-foreground', className), ...props }));
36
+ }
37
+ export { Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, };
@@ -0,0 +1,26 @@
1
+ import { Dialog as DialogPrimitive } from '@base-ui/react/dialog';
2
+ import type * as React from 'react';
3
+ interface DialogProps extends DialogPrimitive.Root.Props {
4
+ /**
5
+ * When false, prevents closing via backdrop/outside clicks.
6
+ * Escape key and X button still work (WCAG compliance).
7
+ * @default true
8
+ */
9
+ dismissible?: boolean;
10
+ }
11
+ declare function Dialog({ dismissible, ...props }: DialogProps): import("react/jsx-runtime").JSX.Element;
12
+ interface DialogTriggerProps extends Omit<React.ComponentPropsWithoutRef<typeof DialogPrimitive.Trigger>, 'render'> {
13
+ render?: React.ReactElement;
14
+ }
15
+ declare function DialogTrigger({ render, children, ...props }: DialogTriggerProps): import("react/jsx-runtime").JSX.Element;
16
+ declare function DialogPortal({ ...props }: DialogPrimitive.Portal.Props): import("react/jsx-runtime").JSX.Element;
17
+ declare function DialogClose({ ...props }: DialogPrimitive.Close.Props): import("react/jsx-runtime").JSX.Element;
18
+ declare function DialogOverlay({ className, ...props }: DialogPrimitive.Backdrop.Props): import("react/jsx-runtime").JSX.Element;
19
+ declare function DialogContent({ className, children, showCloseButton, ...props }: DialogPrimitive.Popup.Props & {
20
+ showCloseButton?: boolean;
21
+ }): import("react/jsx-runtime").JSX.Element;
22
+ declare function DialogHeader({ className, ...props }: React.ComponentProps<'div'>): import("react/jsx-runtime").JSX.Element;
23
+ declare function DialogFooter({ className, children, ...props }: React.ComponentProps<'div'>): import("react/jsx-runtime").JSX.Element;
24
+ declare function DialogTitle({ className, ...props }: DialogPrimitive.Title.Props): import("react/jsx-runtime").JSX.Element;
25
+ declare function DialogDescription({ className, ...props }: DialogPrimitive.Description.Props): import("react/jsx-runtime").JSX.Element;
26
+ export { Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, };
@@ -0,0 +1,39 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { Dialog as DialogPrimitive } from '@base-ui/react/dialog';
4
+ import { XIcon } from 'lucide-react';
5
+ import { cn } from '../../lib/utils.js';
6
+ function Dialog({ dismissible = true, ...props }) {
7
+ return (_jsx(DialogPrimitive.Root, { "data-slot": "dialog", disablePointerDismissal: !dismissible, ...props }));
8
+ }
9
+ function DialogTrigger({ render, children, ...props }) {
10
+ if (render) {
11
+ return (_jsx(DialogPrimitive.Trigger, { "data-slot": "dialog-trigger", render: render, ...props, children: children }));
12
+ }
13
+ return (_jsx(DialogPrimitive.Trigger, { "data-slot": "dialog-trigger", ...props, children: children }));
14
+ }
15
+ function DialogPortal({ ...props }) {
16
+ return _jsx(DialogPrimitive.Portal, { "data-slot": "dialog-portal", ...props });
17
+ }
18
+ function DialogClose({ ...props }) {
19
+ return _jsx(DialogPrimitive.Close, { "data-slot": "dialog-close", ...props });
20
+ }
21
+ function DialogOverlay({ className, ...props }) {
22
+ return (_jsx(DialogPrimitive.Backdrop, { "data-slot": "dialog-overlay", className: cn('data-closed:fade-out-0 data-open:fade-in-0 fixed inset-0 isolate z-50 bg-black/20 duration-100 data-closed:animate-out data-open:animate-in motion-reduce:duration-0 supports-backdrop-filter:backdrop-blur-xs dark:bg-black/40', className), ...props }));
23
+ }
24
+ function DialogContent({ className, children, showCloseButton = true, ...props }) {
25
+ return (_jsxs(DialogPortal, { children: [_jsx(DialogOverlay, {}), _jsxs(DialogPrimitive.Popup, { "data-slot": "dialog-content", className: cn('data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 fixed top-1/2 left-1/2 z-50 grid w-full max-w-[calc(100%-2rem)] -translate-x-1/2 -translate-y-1/2 gap-4 rounded-lg bg-background p-4 text-sm outline-none ring-1 ring-foreground/10 duration-100 data-closed:animate-out data-open:animate-in motion-reduce:duration-0 sm:max-w-sm overscroll-behavior-y-contain dark:ring-border', className), ...props, children: [children, showCloseButton && (_jsxs(DialogPrimitive.Close, { "data-slot": "dialog-close", className: "absolute top-2 right-2 inline-flex size-8 items-center justify-center rounded-md text-muted-foreground hover:bg-accent hover:text-accent-foreground", children: [_jsx(XIcon, { size: 16 }), _jsx("span", { className: "sr-only", children: "Close" })] }))] })] }));
26
+ }
27
+ function DialogHeader({ className, ...props }) {
28
+ return (_jsx("div", { "data-slot": "dialog-header", className: cn('flex flex-col gap-2', className), ...props }));
29
+ }
30
+ function DialogFooter({ className, children, ...props }) {
31
+ return (_jsx("div", { "data-slot": "dialog-footer", className: cn('-mx-4 -mb-4 flex flex-col-reverse gap-2 rounded-b-xl border-t bg-muted/50 p-4 sm:flex-row sm:justify-end dark:bg-muted/70', className), ...props, children: children }));
32
+ }
33
+ function DialogTitle({ className, ...props }) {
34
+ return (_jsx(DialogPrimitive.Title, { "data-slot": "dialog-title", className: cn('font-semibold text-base leading-snug tracking-tight', className), ...props }));
35
+ }
36
+ function DialogDescription({ className, ...props }) {
37
+ return (_jsx(DialogPrimitive.Description, { "data-slot": "dialog-description", className: cn('text-muted-foreground text-sm *:[a]:underline *:[a]:underline-offset-3 *:[a]:hover:text-foreground', className), ...props }));
38
+ }
39
+ export { Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, };
@@ -0,0 +1,16 @@
1
+ import type * as React from 'react';
2
+ import { Drawer as DrawerPrimitive } from 'vaul';
3
+ declare function Drawer({ ...props }: React.ComponentProps<typeof DrawerPrimitive.Root>): import("react/jsx-runtime").JSX.Element;
4
+ declare function DrawerTrigger({ ...props }: React.ComponentProps<typeof DrawerPrimitive.Trigger>): import("react/jsx-runtime").JSX.Element;
5
+ declare function DrawerPortal({ ...props }: React.ComponentProps<typeof DrawerPrimitive.Portal>): import("react/jsx-runtime").JSX.Element;
6
+ declare function DrawerClose({ ...props }: React.ComponentProps<typeof DrawerPrimitive.Close>): import("react/jsx-runtime").JSX.Element;
7
+ declare function DrawerOverlay({ className, ...props }: React.ComponentProps<typeof DrawerPrimitive.Overlay>): import("react/jsx-runtime").JSX.Element;
8
+ declare function DrawerContent({ className, children, showOverlay, overlayClassName, ...props }: React.ComponentProps<typeof DrawerPrimitive.Content> & {
9
+ showOverlay?: boolean;
10
+ overlayClassName?: string;
11
+ }): import("react/jsx-runtime").JSX.Element;
12
+ declare function DrawerHeader({ className, ...props }: React.ComponentProps<'div'>): import("react/jsx-runtime").JSX.Element;
13
+ declare function DrawerFooter({ className, ...props }: React.ComponentProps<'div'>): import("react/jsx-runtime").JSX.Element;
14
+ declare function DrawerTitle({ className, ...props }: React.ComponentProps<typeof DrawerPrimitive.Title>): import("react/jsx-runtime").JSX.Element;
15
+ declare function DrawerDescription({ className, ...props }: React.ComponentProps<typeof DrawerPrimitive.Description>): import("react/jsx-runtime").JSX.Element;
16
+ export { Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, };
@@ -0,0 +1,35 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { Drawer as DrawerPrimitive } from 'vaul';
4
+ import { cn } from '../../lib/utils.js';
5
+ function Drawer({ ...props }) {
6
+ return _jsx(DrawerPrimitive.Root, { "data-slot": "drawer", ...props });
7
+ }
8
+ function DrawerTrigger({ ...props }) {
9
+ return _jsx(DrawerPrimitive.Trigger, { "data-slot": "drawer-trigger", ...props });
10
+ }
11
+ function DrawerPortal({ ...props }) {
12
+ return _jsx(DrawerPrimitive.Portal, { "data-slot": "drawer-portal", ...props });
13
+ }
14
+ function DrawerClose({ ...props }) {
15
+ return _jsx(DrawerPrimitive.Close, { "data-slot": "drawer-close", ...props });
16
+ }
17
+ function DrawerOverlay({ className, ...props }) {
18
+ return (_jsx(DrawerPrimitive.Overlay, { "data-slot": "drawer-overlay", className: cn('data-closed:fade-out-0 data-open:fade-in-0 fixed inset-0 z-50 bg-black/10 data-closed:animate-out data-open:animate-in supports-backdrop-filter:backdrop-blur-xs dark:bg-black/40', className), ...props }));
19
+ }
20
+ function DrawerContent({ className, children, showOverlay = true, overlayClassName, ...props }) {
21
+ return (_jsxs(DrawerPortal, { "data-slot": "drawer-portal", children: [showOverlay ? _jsx(DrawerOverlay, { className: overlayClassName }) : null, _jsxs(DrawerPrimitive.Content, { "data-slot": "drawer-content", className: cn('group/drawer-content fixed z-50 flex h-auto flex-col bg-card text-sm data-[vaul-drawer-direction=bottom]:inset-x-0 data-[vaul-drawer-direction=top]:inset-x-0 data-[vaul-drawer-direction=left]:inset-y-0 data-[vaul-drawer-direction=right]:inset-y-0 data-[vaul-drawer-direction=top]:top-0 data-[vaul-drawer-direction=right]:right-0 data-[vaul-drawer-direction=bottom]:bottom-0 data-[vaul-drawer-direction=left]:left-0 data-[vaul-drawer-direction=bottom]:mt-24 data-[vaul-drawer-direction=top]:mb-24 data-[vaul-drawer-direction=bottom]:max-h-[80vh] data-[vaul-drawer-direction=top]:max-h-[80vh] data-[vaul-drawer-direction=left]:w-3/4 data-[vaul-drawer-direction=right]:w-3/4 data-[vaul-drawer-direction=bottom]:rounded-t-xl data-[vaul-drawer-direction=left]:rounded-r-xl data-[vaul-drawer-direction=top]:rounded-b-xl data-[vaul-drawer-direction=right]:rounded-l-xl data-[vaul-drawer-direction=bottom]:border-t data-[vaul-drawer-direction=left]:border-r data-[vaul-drawer-direction=top]:border-b data-[vaul-drawer-direction=right]:border-l border-border data-[vaul-drawer-direction=left]:sm:max-w-sm data-[vaul-drawer-direction=right]:sm:max-w-sm', className), ...props, children: [_jsx("div", { className: "mx-auto mt-4 hidden h-1 w-[100px] shrink-0 rounded-full bg-muted group-data-[vaul-drawer-direction=bottom]/drawer-content:block" }), children] })] }));
22
+ }
23
+ function DrawerHeader({ className, ...props }) {
24
+ return (_jsx("div", { "data-slot": "drawer-header", className: cn('flex flex-col gap-0.5 p-4 group-data-[vaul-drawer-direction=bottom]/drawer-content:text-center group-data-[vaul-drawer-direction=top]/drawer-content:text-center md:gap-0.5 md:text-left', className), ...props }));
25
+ }
26
+ function DrawerFooter({ className, ...props }) {
27
+ return (_jsx("div", { "data-slot": "drawer-footer", className: cn('mt-auto flex flex-col gap-2 p-4', className), ...props }));
28
+ }
29
+ function DrawerTitle({ className, ...props }) {
30
+ return (_jsx(DrawerPrimitive.Title, { "data-slot": "drawer-title", className: cn('font-semibold text-base text-foreground leading-snug tracking-tight', className), ...props }));
31
+ }
32
+ function DrawerDescription({ className, ...props }) {
33
+ return (_jsx(DrawerPrimitive.Description, { "data-slot": "drawer-description", className: cn('text-muted-foreground text-sm', className), ...props }));
34
+ }
35
+ export { Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, };
@@ -0,0 +1,32 @@
1
+ import { Menu as MenuPrimitive } from '@base-ui/react/menu';
2
+ import type * as React from 'react';
3
+ declare function DropdownMenu({ ...props }: MenuPrimitive.Root.Props): import("react/jsx-runtime").JSX.Element;
4
+ declare function DropdownMenuPortal({ ...props }: MenuPrimitive.Portal.Props): import("react/jsx-runtime").JSX.Element;
5
+ interface DropdownMenuTriggerProps extends Omit<MenuPrimitive.Trigger.Props, 'render'> {
6
+ render?: React.ReactElement | MenuPrimitive.Trigger.Props['render'];
7
+ }
8
+ declare function DropdownMenuTrigger({ render, children, ...props }: DropdownMenuTriggerProps): import("react/jsx-runtime").JSX.Element;
9
+ declare function DropdownMenuContent({ align, alignOffset, side, sideOffset, className, ...props }: MenuPrimitive.Popup.Props & Pick<MenuPrimitive.Positioner.Props, 'align' | 'alignOffset' | 'side' | 'sideOffset'>): import("react/jsx-runtime").JSX.Element;
10
+ declare function DropdownMenuGroup({ ...props }: MenuPrimitive.Group.Props): import("react/jsx-runtime").JSX.Element;
11
+ declare function DropdownMenuLabel({ className, inset, ...props }: MenuPrimitive.GroupLabel.Props & {
12
+ inset?: boolean;
13
+ }): import("react/jsx-runtime").JSX.Element;
14
+ interface MenuItemProps extends Omit<MenuPrimitive.Item.Props, 'render' | 'onClick' | 'onSelect'> {
15
+ inset?: boolean;
16
+ variant?: 'default' | 'destructive';
17
+ render?: React.ReactElement;
18
+ onClick?: MenuPrimitive.Item.Props['onClick'];
19
+ onSelect?: MenuPrimitive.Item.Props['onClick'];
20
+ }
21
+ declare function DropdownMenuItem({ className, inset, variant, render, onClick, onSelect, children, ...props }: MenuItemProps): import("react/jsx-runtime").JSX.Element;
22
+ declare function DropdownMenuSub({ ...props }: MenuPrimitive.SubmenuRoot.Props): import("react/jsx-runtime").JSX.Element;
23
+ declare function DropdownMenuSubTrigger({ className, inset, children, ...props }: MenuPrimitive.SubmenuTrigger.Props & {
24
+ inset?: boolean;
25
+ }): import("react/jsx-runtime").JSX.Element;
26
+ declare function DropdownMenuSubContent({ align, alignOffset, side, sideOffset, className, ...props }: React.ComponentProps<typeof DropdownMenuContent>): import("react/jsx-runtime").JSX.Element;
27
+ declare function DropdownMenuCheckboxItem({ className, children, checked, ...props }: MenuPrimitive.CheckboxItem.Props): import("react/jsx-runtime").JSX.Element;
28
+ declare function DropdownMenuRadioGroup({ ...props }: MenuPrimitive.RadioGroup.Props): import("react/jsx-runtime").JSX.Element;
29
+ declare function DropdownMenuRadioItem({ className, children, ...props }: MenuPrimitive.RadioItem.Props): import("react/jsx-runtime").JSX.Element;
30
+ declare function DropdownMenuSeparator({ className, ...props }: MenuPrimitive.Separator.Props): import("react/jsx-runtime").JSX.Element;
31
+ declare function DropdownMenuShortcut({ className, ...props }: React.ComponentProps<'span'>): import("react/jsx-runtime").JSX.Element;
32
+ export { DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, type MenuItemProps, };
@@ -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
@@ -1,4 +1,6 @@
1
+ export * from './brand/public.js';
1
2
  export * from './chat/public.js';
3
+ export * from './marketing/public.js';
2
4
  export * from './panel/public.js';
3
- export * from './shell/public.js';
5
+ export * from './shell/index.js';
4
6
  export * from './timeline/public.js';
package/dist/index.js CHANGED
@@ -1,4 +1,6 @@
1
+ export * from './brand/public.js';
1
2
  export * from './chat/public.js';
3
+ export * from './marketing/public.js';
2
4
  export * from './panel/public.js';
3
- export * from './shell/public.js';
5
+ export * from './shell/index.js'; // v2 surface
4
6
  export * from './timeline/public.js';
@@ -0,0 +1,2 @@
1
+ import { type ClassValue } from 'clsx';
2
+ export declare function cn(...inputs: ClassValue[]): string;
@@ -0,0 +1,5 @@
1
+ import { clsx } from 'clsx';
2
+ import { twMerge } from 'tailwind-merge';
3
+ export function cn(...inputs) {
4
+ return twMerge(clsx(inputs));
5
+ }
@@ -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,4 @@
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';
@@ -0,0 +1,2 @@
1
+ import type { MarketingCalloutProps } from './types.js';
2
+ export declare function MarketingCallout({ eyebrow, title, description, children, ctas, variant, align, className, }: MarketingCalloutProps): import("react/jsx-runtime").JSX.Element;
@@ -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,2 @@
1
+ import type { MarketingContactProps } from './types.js';
2
+ export declare function MarketingContact({ intro, form, office, contactPerson, compact, className, }: MarketingContactProps): import("react/jsx-runtime").JSX.Element;
@@ -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,2 @@
1
+ import type { MarketingCtaListProps } from './types.js';
2
+ export declare function MarketingCtaList({ ctas, align, className }: MarketingCtaListProps): import("react/jsx-runtime").JSX.Element | null;
@@ -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 {};