magnaui 0.2.0 → 0.3.1

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 (43) hide show
  1. package/README.md +52 -10
  2. package/dist/components/magna/brand-logo.d.ts +12 -0
  3. package/dist/components/magna/brand-logo.js +9 -0
  4. package/dist/components/magna/index.d.ts +2 -0
  5. package/dist/components/magna/index.js +1 -0
  6. package/dist/components/magna/navigation.d.ts +10 -3
  7. package/dist/components/magna/navigation.js +2 -2
  8. package/dist/components/ui/activity-feed.d.ts +1 -1
  9. package/dist/components/ui/button.d.ts +2 -1
  10. package/dist/components/ui/button.js +6 -2
  11. package/dist/components/ui/combobox.d.ts +25 -0
  12. package/dist/components/ui/combobox.js +72 -0
  13. package/dist/components/ui/compact-button.d.ts +2 -1
  14. package/dist/components/ui/compact-button.js +6 -2
  15. package/dist/components/ui/content-card.js +2 -2
  16. package/dist/components/ui/highlight.d.ts +15 -0
  17. package/dist/components/ui/highlight.js +20 -0
  18. package/dist/components/ui/hit-area.d.ts +6 -0
  19. package/dist/components/ui/hit-area.js +2 -0
  20. package/dist/components/ui/modal.d.ts +14 -0
  21. package/dist/components/ui/modal.js +19 -3
  22. package/dist/components/ui/panel.d.ts +10 -0
  23. package/dist/components/ui/panel.js +12 -0
  24. package/dist/components/ui/progress-bar.d.ts +4 -2
  25. package/dist/components/ui/progress-bar.js +13 -9
  26. package/dist/components/ui/progress-circle.d.ts +2 -1
  27. package/dist/components/ui/progress-circle.js +4 -3
  28. package/dist/components/ui/quote.d.ts +6 -0
  29. package/dist/components/ui/quote.js +14 -0
  30. package/dist/components/ui/resizable.d.ts +53 -0
  31. package/dist/components/ui/resizable.js +201 -0
  32. package/dist/components/ui/skeleton.d.ts +10 -0
  33. package/dist/components/ui/skeleton.js +12 -0
  34. package/dist/components/ui/status-modal.d.ts +1 -0
  35. package/dist/components/ui/table.d.ts +4 -1
  36. package/dist/components/ui/table.js +9 -2
  37. package/dist/core.d.ts +99 -0
  38. package/dist/core.js +97 -0
  39. package/dist/magna-classes.js +1 -1
  40. package/dist/magnaui.d.ts +4 -80
  41. package/dist/magnaui.js +4 -78
  42. package/dist/styles.css +3 -3
  43. package/package.json +90 -22
package/README.md CHANGED
@@ -2,14 +2,16 @@
2
2
 
3
3
  React components, theme tokens, and original Magna artwork for authorized Magna AI applications.
4
4
 
5
- MagnaUI `0.2.0` includes AI conversation components, React 18.3 and React 19 support, RTL direction support, and isolated styles for Tailwind 4 applications.
5
+ MagnaUI `0.3.1` includes AI conversation components, React 18.3 and React 19 support, RTL direction support, and isolated styles for Tailwind 4 applications.
6
6
 
7
7
  **Usage terms:** Public package visibility permits downloading the distribution; it does not grant an open-source license to Magna-owned materials. Use is restricted to the owner and expressly authorized users under `LICENSE` in the installed package. Third-party materials retain their own terms in `THIRD_PARTY_NOTICES.md`.
8
8
 
9
+ Internal teams may use MagnaUI in Magna AI projects covered by the owner’s authorization. Keep that approval with your project records; public npm access or organization membership alone does not extend permission to unrelated projects.
10
+
9
11
  ## Install
10
12
 
11
13
  ```sh
12
- npm install magnaui@^0.2.0
14
+ npm install magnaui@^0.3.1
13
15
  ```
14
16
 
15
17
  Use matching `react` and `react-dom` versions: `^18.3.1` or `^19.0.0`. Next.js 15 applications can keep React 19. The package ships ESM JavaScript, TypeScript declarations, compiled CSS, fonts, and artwork. Use Next.js, Vite, or another modern bundler that supports CSS Modules and static package assets. Next.js itself is not a library dependency.
@@ -26,7 +28,7 @@ No Tailwind plugin, `@source` scan, or Tailwind 3 configuration is required for
26
28
  ```tsx
27
29
  'use client';
28
30
 
29
- import { Button, Checkbox, MagnaLogo } from 'magnaui';
31
+ import { Button, Checkbox, MagnaLogo } from 'magnaui/core';
30
32
 
31
33
  export function Workspace() {
32
34
  return (
@@ -47,25 +49,65 @@ For a narrower import, component modules also have subpaths:
47
49
 
48
50
  ```tsx
49
51
  import * as Button from 'magnaui/ui/button';
50
- import { MagnaLogo } from 'magnaui/magna';
51
- import { BorderBeam } from 'magnaui/interactions';
52
+ import { MagnaLogo } from 'magnaui/magna/logo';
53
+ import { BorderBeam } from 'magnaui/interactions/border-beam';
54
+ ```
55
+
56
+ ## Optional editor and effects
57
+
58
+ Starting in 0.3.0, editor and animation engines are optional peers. A basic install does not download Tiptap, Three.js, or the effects packages. Use `magnaui/core` for base UI, branding, providers, and AI message components, or `magnaui/ui/*` and `magnaui/magna/*` for individual modules.
59
+
60
+ ```tsx
61
+ import { Button, DirectionProvider, MagnaLogo } from 'magnaui/core';
62
+ import { ChatMessage } from 'magnaui/magna/chat-message';
63
+ ```
64
+
65
+ Install only the engines required by the feature you import:
66
+
67
+ | Feature/subpath | Additional packages |
68
+ | --- | --- |
69
+ | `magnaui/ui/rich-editor` | All Tiptap packages in the command below |
70
+ | `magnaui/magna/chat-composer` | `border-beam@1.4.1 voice-glow@0.2.1` |
71
+ | `magnaui/magna/chat-activity` | `thinking-orbs@0.3.2` |
72
+ | `magnaui/interactions/border-beam` | `border-beam@1.4.1` |
73
+ | `magnaui/interactions/thinking-orb` | `thinking-orbs@0.3.2` |
74
+ | `magnaui/interactions/bot-avatar` | `bot-avatars@0.1.1` |
75
+ | `magnaui/interactions/liquid` | `liquid-gooey@0.2.2` |
76
+ | `magnaui/interactions/voice-beam` | `voice-glow@0.2.1` |
77
+ | `magnaui/interactions/metal-fx` | `metal-fx@2.0.11` |
78
+ | `magnaui/interactions/image-generation` | `img-fx@0.5.1 three@0.149.0` |
79
+
80
+ ```sh
81
+ # Rich editor
82
+ npm install @tiptap/core@3.31.3 @tiptap/extension-bubble-menu@3.31.3 @tiptap/extension-floating-menu@3.31.3 @tiptap/extension-text-align@3.31.3 @tiptap/extension-text-style@3.31.3 @tiptap/extension-underline@3.31.3 @tiptap/pm@3.31.3 @tiptap/react@3.31.3 @tiptap/starter-kit@3.31.3
83
+
84
+ # Animated chat composer and activity
85
+ npm install border-beam@1.4.1 voice-glow@0.2.1 thinking-orbs@0.3.2
86
+ ```
87
+
88
+ The existing full `magnaui`, `magnaui/magna`, and `magnaui/interactions` barrels retain their exports. Full-root examples in this guide require all optional engines because bundlers and TypeScript can traverse re-exports even when only one symbol is imported. To preserve an existing full-root application, install all engines once:
89
+
90
+ ```sh
91
+ npm install @tiptap/core@3.31.3 @tiptap/extension-bubble-menu@3.31.3 @tiptap/extension-floating-menu@3.31.3 @tiptap/extension-text-align@3.31.3 @tiptap/extension-text-style@3.31.3 @tiptap/extension-underline@3.31.3 @tiptap/pm@3.31.3 @tiptap/react@3.31.3 @tiptap/starter-kit@3.31.3 border-beam@1.4.1 bot-avatars@0.1.1 img-fx@0.5.1 liquid-gooey@0.2.2 metal-fx@2.0.11 thinking-orbs@0.3.2 three@0.149.0 voice-glow@0.2.1
52
92
  ```
53
93
 
94
+ For a smaller installation, switch ordinary UI imports to `magnaui/core` and feature imports to the individual subpaths above. Setting `interactions={false}` hides effects but does not change a module's dependency requirements. All component designs and existing prop defaults are preserved.
95
+
54
96
  ## Included components
55
97
 
56
- MagnaUI `0.2.0` includes **68 base component families**, **10 Magna workspace components**, **7 interaction adapters**, and **7 AI conversation components**, with their public component parts and types.
98
+ MagnaUI `0.3.1` includes base component families, Magna workspace components, interaction adapters, and AI conversation components, with their public component parts and types.
57
99
 
58
100
  | Group | Public component families |
59
101
  | ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
60
102
  | Actions | `Button`, `ButtonGroup`, `CompactButton`, `FancyButton`, `LinkButton`, `SocialButton` |
61
- | Forms and input | `Checkbox`, `ColorPicker`, `CounterInput`, `DatePicker`, `DigitInput`, `FileUpload`, `Filter`, `Hint`, `InlineInput`, `Input`, `Label`, `PasswordStrength`, `Radio`, `Rating`, `RichEditor`, `Select`, `Slider`, `Switch`, `TagInput`, `Textarea`, `TimePicker` |
103
+ | Forms and input | `Checkbox`, `Combobox`, `ColorPicker`, `CounterInput`, `DatePicker`, `DigitInput`, `FileUpload`, `Filter`, `Hint`, `InlineInput`, `Input`, `Label`, `PasswordStrength`, `Radio`, `Rating`, `RichEditor`, `Select`, `Slider`, `Switch`, `TagInput`, `Textarea`, `TimePicker` |
62
104
  | Navigation | `Accordion`, `Breadcrumb`, `CommandMenu`, `DotStepper`, `HorizontalStepper`, `Pagination`, `SegmentedControl`, `TabMenuHorizontal`, `TabMenuVertical`, `VerticalStepper` |
63
- | Feedback | `Alert`, `Banner`, `Notification`, `NotificationFeed`, `ProgressBar`, `ProgressCircle`, `StatusBadge`, `Tooltip` |
105
+ | Feedback | `Alert`, `Banner`, `Notification`, `NotificationFeed`, `ProgressBar`, `ProgressCircle`, `Skeleton`, `StatusBadge`, `Tooltip` |
64
106
  | Overlays | `Drawer`, `Dropdown`, `Modal`, `Popover`, `StatusModal` |
65
- | Data and content | `ActivityFeed`, `ChartLegend`, `ContentCard`, `ContentLabel`, `Divider`, `Kbd`, `ScrollArea`, `Table`, `Tag` |
107
+ | Data and content | `ActivityFeed`, `ChartLegend`, `ContentCard`, `ContentLabel`, `Divider`, `Highlight`, `Kbd`, `Panel`, `Quote`, `Resizable`, `ScrollArea`, `Table`, `Tag` |
66
108
  | Identity and icons | `Avatar`, `AvatarEmptyIcons`, `AvatarGroup`, `AvatarGroupCompact`, `Badge`, `FileFormatIcon`, `KeyIcon`, `PaymentIcon`, `RatingIcons` |
67
109
 
68
- - **Magna workspace:** `AppIcon`, `AppLauncher`, `MagnaLogo`, `ChatComposer`, `ChatActivity`, `DesktopButton`, `DesktopSwitch`, `FileTile`, `MagnaNavigation`, and `ProjectContext`.
110
+ - **Magna workspace:** `AppIcon`, `AppLauncher`, `BrandLogo`, `MagnaLogo`, `ChatComposer`, `ChatActivity`, `DesktopButton`, `DesktopSwitch`, `FileTile`, `MagnaNavigation`, and `ProjectContext`.
69
111
  - **AI conversations:** `ChatMessage`, `ChatConversation`, `ChatAttachment`, `ChatReasoning`, `ChatToolCall`, `ChatSources`, and `ChatSuggestions`.
70
112
  - **Interactions:** `BorderBeam`, `ThinkingOrb`, `BotAvatar`, `Liquid`, `VoiceBeam`, `MetalFx`, and `ImageGeneration`.
71
113
  - **Providers and helpers:** `ThemeProvider`, `useTheme`, `ThemeSwitch`, `TooltipProvider`, `NotificationProvider`, `notification`, `useNotification`, `useTabObserver`, `DirectionProvider`, `useDirection`, `createMagnaTheme`, and application, navigation, and logo metadata.
@@ -0,0 +1,12 @@
1
+ import type { ComponentPropsWithoutRef } from "react";
2
+ export type BrandLogoProps = Omit<ComponentPropsWithoutRef<'span'>, 'children'> & {
3
+ src: string;
4
+ darkSrc?: string;
5
+ /** Organisation name, or an empty string when the enclosing link names it. */
6
+ alt: string;
7
+ width?: number;
8
+ height?: number;
9
+ imageClassName?: string;
10
+ };
11
+ /** Tenant artwork for a header or navigation rail, with one accessible name. */
12
+ export declare function BrandLogo({ src, darkSrc, alt, width, height, className, imageClassName, style, ...props }: BrandLogoProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,9 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { magnaClasses as __magnaClasses_1 } from "../../magna-classes.js";
3
+ import { cn } from "../../utils/cn.js";
4
+ /** Tenant artwork for a header or navigation rail, with one accessible name. */
5
+ export function BrandLogo({ src, darkSrc, alt, width = 32, height = 32, className, imageClassName, style, ...props }) {
6
+ return (_jsxs("span", { ...props, role: alt ? 'img' : undefined, "aria-label": alt || undefined, "aria-hidden": alt ? undefined : true, className: __magnaClasses_1(__magnaClasses_1(cn('inline-flex shrink-0 items-center justify-center', className), className), className), style: { width, height, ...style }, "data-magnaui": '', children: [_jsx("img", { src: src, alt: '', width: width, height: height, className: __magnaClasses_1(__magnaClasses_1(cn('h-full w-full object-contain', darkSrc ? 'block dark:hidden' : 'block', imageClassName), imageClassName), imageClassName), "data-magnaui": '' }), darkSrc && (
7
+ // eslint-disable-next-line @next/next/no-img-element
8
+ _jsx("img", { src: darkSrc, alt: '', width: width, height: height, className: __magnaClasses_1(__magnaClasses_1(cn('hidden h-full w-full object-contain dark:block', imageClassName), imageClassName), imageClassName), "data-magnaui": '' }))] }));
9
+ }
@@ -13,3 +13,5 @@ export { ChatMessage, type ChatMessageProps } from "./chat-message.js";
13
13
  export { ChatAttachment, type ChatAttachmentProps } from "./chat-attachment.js";
14
14
  export { ChatConversation, type ChatConversationProps, } from "./chat-conversation.js";
15
15
  export { ChatReasoning, ChatToolCall, ChatSources, ChatSuggestions, type ChatReasoningProps, type ChatToolCallProps, type ChatToolCallStatus, type ChatSourcesProps, type ChatSource, type ChatSuggestionsProps, } from "./chat-response.js";
16
+ export { BrandLogo, type BrandLogoProps } from "./brand-logo.js";
17
+ export type { MagnaNavigationProps } from "./navigation.js";
@@ -13,3 +13,4 @@ export { ChatMessage } from "./chat-message.js";
13
13
  export { ChatAttachment } from "./chat-attachment.js";
14
14
  export { ChatConversation, } from "./chat-conversation.js";
15
15
  export { ChatReasoning, ChatToolCall, ChatSources, ChatSuggestions, } from "./chat-response.js";
16
+ export { BrandLogo } from "./brand-logo.js";
@@ -5,11 +5,18 @@ export interface MagnaNavItem {
5
5
  icon: 'chat' | 'apps' | 'folder' | 'store' | 'book' | 'notifications';
6
6
  }
7
7
  export declare const defaultNavItems: MagnaNavItem[];
8
- /** Figma Sidebar 199714:167527 and Magan bar 199714:167174. */
9
- export declare function MagnaNavigation({ orientation, items, active, className, footer, }: {
8
+ export type MagnaNavigationProps = {
10
9
  orientation?: 'vertical' | 'horizontal';
11
10
  items?: MagnaNavItem[];
12
11
  active?: string;
13
12
  className?: string;
14
13
  footer?: React.ReactNode;
15
- }): import("react/jsx-runtime").JSX.Element;
14
+ /** Logo artwork placed inside the home link; defaults to the Magna glyph. */
15
+ brand?: React.ReactNode;
16
+ brandHref?: string;
17
+ brandLabel?: string;
18
+ brandClassName?: string;
19
+ navigationLabel?: string;
20
+ };
21
+ /** Figma Sidebar 199714:167527 and Magan bar 199714:167174. */
22
+ export declare function MagnaNavigation({ orientation, items, active, className, footer, brand, brandHref, brandLabel, brandClassName, navigationLabel, }: MagnaNavigationProps): import("react/jsx-runtime").JSX.Element;
@@ -11,7 +11,7 @@ export const defaultNavItems = [
11
11
  { label: 'Store', href: '#components', icon: 'store' },
12
12
  ];
13
13
  /** Figma Sidebar 199714:167527 and Magan bar 199714:167174. */
14
- export function MagnaNavigation({ orientation = 'vertical', items = defaultNavItems, active, className, footer, }) {
14
+ export function MagnaNavigation({ orientation = 'vertical', items = defaultNavItems, active, className, footer, brand, brandHref = '#top', brandLabel = 'MagnaUI home', brandClassName, navigationLabel = 'Magna navigation', }) {
15
15
  const vertical = orientation === 'vertical';
16
- return (_jsxs("nav", { "aria-label": 'Magna navigation', className: __magnaClasses_1(__magnaClasses_1(cn('flex shrink-0 gap-5 bg-bg-white-0 p-5', vertical ? 'w-[74px] flex-col' : 'min-h-[74px] w-full items-center', className), className), className), "data-magnaui": '', children: [_jsx("a", { href: '#top', "aria-label": 'MagnaUI home', className: __magnaClasses_1('flex size-[34px] shrink-0 items-center justify-center rounded-lg focus-visible:outline focus-visible:outline-2 focus-visible:outline-primary-base'), "data-magnaui": '', children: _jsx(MagnaLogo, { variant: 'glyph', className: __magnaClasses_1('size-6'), "data-magnaui": '' }) }), _jsx("div", { className: __magnaClasses_1(__magnaClasses_1(cn('shrink-0 bg-stroke-soft-200', vertical ? 'h-px w-full' : 'h-6 w-px'))), "data-magnaui": '' }), _jsx("div", { className: __magnaClasses_1(__magnaClasses_1(cn('flex flex-1 gap-3', vertical ? 'flex-col' : 'min-w-0 overflow-x-auto py-1'))), "data-magnaui": '', children: items.map((item) => (_jsx("a", { href: item.href, "aria-label": item.label, title: item.label, "aria-current": active === item.label ? 'page' : undefined, className: __magnaClasses_1(__magnaClasses_1(cn('flex size-[34px] shrink-0 items-center justify-center rounded-lg hover:bg-bg-weak-50 focus-visible:outline focus-visible:outline-2 focus-visible:outline-primary-base', active === item.label && 'bg-bg-soft-200'))), "data-magnaui": '', children: _jsx("img", { src: __resolveMagnaAsset_1(`/magna/icons/${item.icon}.svg`), width: 22, height: 22, alt: '', className: __magnaClasses_1('size-[22px] dark:invert'), "data-magnaui": '' }) }, item.label))) }), footer] }));
16
+ return (_jsxs("nav", { "aria-label": navigationLabel, className: __magnaClasses_1(__magnaClasses_1(cn('flex shrink-0 gap-5 bg-bg-white-0 p-5', vertical ? 'w-[74px] flex-col' : 'min-h-[74px] w-full items-center', className), className), className), "data-magnaui": '', children: [_jsx("a", { href: brandHref, "aria-label": brandLabel, className: __magnaClasses_1(__magnaClasses_1(cn('flex size-[34px] shrink-0 items-center justify-center rounded-lg focus-visible:outline focus-visible:outline-2 focus-visible:outline-primary-base', brandClassName), brandClassName), brandClassName), "data-magnaui": '', children: brand ?? _jsx(MagnaLogo, { variant: 'glyph', className: __magnaClasses_1('size-6'), "data-magnaui": '' }) }), _jsx("div", { className: __magnaClasses_1(__magnaClasses_1(cn('shrink-0 bg-stroke-soft-200', vertical ? 'h-px w-full' : 'h-6 w-px'))), "data-magnaui": '' }), _jsx("div", { className: __magnaClasses_1(__magnaClasses_1(cn('flex flex-1 gap-3', vertical ? 'flex-col' : 'min-w-0 overflow-x-auto py-1'))), "data-magnaui": '', children: items.map((item) => (_jsx("a", { href: item.href, "aria-label": item.label, title: item.label, "aria-current": active === item.label ? 'page' : undefined, className: __magnaClasses_1(__magnaClasses_1(cn('flex size-[34px] shrink-0 items-center justify-center rounded-lg hover:bg-bg-weak-50 focus-visible:outline focus-visible:outline-2 focus-visible:outline-primary-base', active === item.label && 'bg-bg-soft-200'))), "data-magnaui": '', children: _jsx("img", { src: __resolveMagnaAsset_1(`/magna/icons/${item.icon}.svg`), width: 22, height: 22, alt: '', className: __magnaClasses_1('size-[22px] dark:invert'), "data-magnaui": '' }) }, item.label))) }), footer] }));
17
17
  }
@@ -36,7 +36,7 @@ export declare const SelectedFilter: React.ForwardRefExoticComponent<Omit<Omit<R
36
36
  size: "medium" | "small" | "xsmall" | "xxsmall";
37
37
  }> & {
38
38
  asChild?: boolean;
39
- } & React.RefAttributes<HTMLButtonElement>, "ref">, "onChange"> & {
39
+ } & import("./hit-area.js").HitAreaProps & React.RefAttributes<HTMLButtonElement>, "ref">, "onChange"> & {
40
40
  pressed?: boolean;
41
41
  defaultPressed?: boolean;
42
42
  onPressedChange?: (pressed: boolean) => void;
@@ -1,5 +1,6 @@
1
1
  import * as React from "react";
2
2
  import type { PolymorphicComponentProps } from "../../utils/polymorphic.js";
3
+ import { type HitAreaProps } from "./hit-area.js";
3
4
  type Appearance = {
4
5
  variant: 'primary' | 'neutral' | 'error';
5
6
  mode: 'filled' | 'stroke' | 'lighter' | 'ghost';
@@ -14,7 +15,7 @@ export declare const buttonVariants: (options?: Partial<Appearance> & {
14
15
  }) | undefined) => string>;
15
16
  export declare const Root: React.ForwardRefExoticComponent<React.ButtonHTMLAttributes<HTMLButtonElement> & Partial<Appearance> & {
16
17
  asChild?: boolean;
17
- } & React.RefAttributes<HTMLButtonElement>>;
18
+ } & HitAreaProps & React.RefAttributes<HTMLButtonElement>>;
18
19
  export declare function Icon<T extends React.ElementType = 'div'>({ as, className, variant, mode, size, ...props }: PolymorphicComponentProps<T, Partial<Appearance>>): import("react/jsx-runtime").JSX.Element;
19
20
  export declare namespace Icon {
20
21
  var displayName: string;
@@ -4,6 +4,8 @@ import { magnaRecipe as __magnaRecipe_1, magnaClasses as __magnaClasses_1 } from
4
4
  import * as React from "react";
5
5
  import { Slot } from "@radix-ui/react-slot";
6
6
  import { mergeOptions, slotRecipe } from "./magna-recipe.js";
7
+ import { touchHitArea } from "./hit-area.js";
8
+ import { cn } from "../../utils/cn.js";
7
9
  const appearance = React.createContext({});
8
10
  const dimensions = {
9
11
  medium: 'h-10 px-3.5 gap-3',
@@ -45,10 +47,12 @@ export const buttonVariants = __magnaRecipe_1(slotRecipe({ variant: 'primary', m
45
47
  ],
46
48
  icon: 'flex shrink-0 justify-center items-center size-5 -mx-1',
47
49
  })));
48
- export const Root = React.forwardRef(function Button({ variant, mode, size, asChild, className, children, ...props }, ref) {
50
+ export const Root = React.forwardRef(function Button({ variant, mode, size, asChild, hitArea = 'visual', className, children, ...props }, ref) {
49
51
  const options = { variant, mode, size };
50
52
  const Element = asChild ? Slot : 'button';
51
- return (_jsx(appearance.Provider, { value: options, children: _jsx(Element, { ref: ref, className: __magnaClasses_1(buttonVariants(options).root({ className }), className), ...props, "data-magnaui": '', children: children }) }));
53
+ return (_jsx(appearance.Provider, { value: options, children: _jsx(Element, { ref: ref, className: __magnaClasses_1(buttonVariants(options).root({
54
+ className: __magnaClasses_1(cn(hitArea === 'touch' && touchHitArea, className), className),
55
+ }), className), ...props, "data-magnaui": '', children: children }) }));
52
56
  });
53
57
  Root.displayName = 'ButtonRoot';
54
58
  export function Icon({ as, className, variant, mode, size, ...props }) {
@@ -0,0 +1,25 @@
1
+ import * as React from "react";
2
+ import * as Aria from "react-aria-components";
3
+ import { type Direction } from "./direction-provider.js";
4
+ export type ComboboxProps<T extends object> = Aria.ComboBoxProps<T> & {
5
+ dir?: Direction;
6
+ lang?: string;
7
+ };
8
+ /** An editable, non-modal select. React Aria owns filtering and active-descendant navigation. */
9
+ export declare function Root<T extends object>({ className, dir, lang, allowsEmptyCollection, ...props }: ComboboxProps<T>): import("react/jsx-runtime").JSX.Element;
10
+ export declare const Label: React.ForwardRefExoticComponent<Aria.LabelProps & React.RefAttributes<HTMLLabelElement>>;
11
+ export declare const Control: React.ForwardRefExoticComponent<Aria.GroupProps & React.RefAttributes<HTMLDivElement>>;
12
+ export declare const Input: React.ForwardRefExoticComponent<Aria.InputProps & React.RefAttributes<HTMLInputElement>>;
13
+ export declare const Trigger: React.ForwardRefExoticComponent<Aria.ButtonProps & React.RefAttributes<HTMLButtonElement>>;
14
+ export type ContentProps = Aria.PopoverProps & {
15
+ lang?: string;
16
+ };
17
+ export declare const Content: React.ForwardRefExoticComponent<Aria.PopoverProps & {
18
+ lang?: string;
19
+ } & React.RefAttributes<HTMLElement>>;
20
+ export declare function List<T extends object>({ className, ...props }: Aria.ListBoxProps<T>): import("react/jsx-runtime").JSX.Element;
21
+ export declare function Item<T extends object>({ className, children, textValue, ...props }: Aria.ListBoxItemProps<T>): import("react/jsx-runtime").JSX.Element;
22
+ /** Supply through List.renderEmptyState so empty text is not treated as an option. */
23
+ export declare function Empty({ className, ...props }: React.HTMLAttributes<HTMLDivElement>): import("react/jsx-runtime").JSX.Element;
24
+ export declare const Description: React.ForwardRefExoticComponent<Aria.TextProps & React.RefAttributes<HTMLElement>>;
25
+ export declare const Error: React.ForwardRefExoticComponent<Aria.FieldErrorProps & React.RefAttributes<HTMLElement>>;
@@ -0,0 +1,72 @@
1
+ 'use client';
2
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { magnaClasses as __magnaClasses_1 } from "../../magna-classes.js";
4
+ import * as React from "react";
5
+ import * as Aria from "react-aria-components";
6
+ import { RiArrowDownSLine, RiCheckLine } from "@remixicon/react";
7
+ import { cn } from "../../utils/cn.js";
8
+ import { DirectionProvider, useDirection, useDirectionAttributes, } from "./direction-provider.js";
9
+ // Resolve render-prop classes once. The named local also lets the package
10
+ // compiler preserve caller Tailwind classes rather than namespace them.
11
+ function classes(base, extra) {
12
+ return (state) => {
13
+ const className = typeof extra === 'function' ? extra(state) : extra;
14
+ return __magnaClasses_1(cn(base, className), className);
15
+ };
16
+ }
17
+ /** An editable, non-modal select. React Aria owns filtering and active-descendant navigation. */
18
+ export function Root({ className, dir, lang, allowsEmptyCollection = true, ...props }) {
19
+ const direction = useDirection(dir);
20
+ const attributes = useDirectionAttributes(direction, lang);
21
+ return (_jsx(DirectionProvider, { dir: direction, lang: attributes.lang, className: __magnaClasses_1('contents'), "data-magnaui": '', children: _jsx(Aria.ComboBox, { ...props, allowsEmptyCollection: allowsEmptyCollection, className: __magnaClasses_1(classes('flex min-w-0 flex-col gap-1.5', className), className), "data-magnaui": '' }) }));
22
+ }
23
+ export const Label = React.forwardRef(function Label({ className, ...props }, ref) {
24
+ return (_jsx(Aria.Label, { ...props, ref: ref, className: __magnaClasses_1(__magnaClasses_1(cn('text-start text-label-sm text-text-strong-950', className), className), className), "data-magnaui": '' }));
25
+ });
26
+ export const Control = React.forwardRef(function Control({ className, ...props }, ref) {
27
+ return (_jsx(Aria.Group, { role: 'presentation', ...props, ref: ref, className: __magnaClasses_1(classes('flex min-w-0 items-center gap-1 rounded-full bg-bg-white-0 pe-2 ps-3 shadow-regular-xs ring-1 ring-inset ring-stroke-soft-200 transition-colors data-[disabled]:bg-bg-weak-50 data-[hovered]:bg-bg-weak-50 data-[disabled]:shadow-none data-[focus-within]:shadow-button-important-focus data-[disabled]:ring-transparent data-[focus-within]:ring-stroke-strong-950 data-[invalid]:ring-error-base', className), className), "data-magnaui": '' }));
28
+ });
29
+ export const Input = React.forwardRef(function Input({ className, onKeyDown, ...props }, ref) {
30
+ return (_jsx(Aria.Input, { ...props, ref: ref, onKeyDown: (event) => {
31
+ onKeyDown?.(event);
32
+ if (event.altKey ||
33
+ event.ctrlKey ||
34
+ event.metaKey ||
35
+ event.shiftKey ||
36
+ event.nativeEvent.isComposing ||
37
+ event.currentTarget.readOnly)
38
+ return;
39
+ const expanded = event.currentTarget.getAttribute('aria-expanded') === 'true';
40
+ // Some React Aria versions leave the native default unhandled when
41
+ // navigation reaches a collection boundary. Keep those keys in the
42
+ // list instead of scrolling the page and dismissing the suggestions.
43
+ if (event.key === 'ArrowDown' ||
44
+ event.key === 'ArrowUp' ||
45
+ (expanded &&
46
+ ['Home', 'End', 'PageUp', 'PageDown'].includes(event.key)))
47
+ event.preventDefault();
48
+ }, className: __magnaClasses_1(classes('h-10 min-w-0 flex-1 bg-transparent text-start text-paragraph-sm text-text-strong-950 outline-none placeholder:text-text-soft-400 disabled:text-text-disabled-300', className), className), "data-magnaui": '' }));
49
+ });
50
+ export const Trigger = React.forwardRef(function Trigger({ className, children, ...props }, ref) {
51
+ return (_jsx(Aria.Button, { ...props, ref: ref, className: __magnaClasses_1(classes('flex size-7 shrink-0 items-center justify-center rounded-full text-text-sub-600 outline-none data-[hovered]:bg-bg-soft-200 data-[disabled]:text-text-disabled-300 data-[focus-visible]:ring-2 data-[focus-visible]:ring-primary-base', className), className), "data-magnaui": '', children: children ?? _jsx(RiArrowDownSLine, { className: __magnaClasses_1('size-5'), "aria-hidden": 'true', "data-magnaui": '' }) }));
52
+ });
53
+ export const Content = React.forwardRef(function Content({ className, lang, children, offset = 6, ...props }, ref) {
54
+ const attributes = useDirectionAttributes(undefined, lang);
55
+ return (_jsx(Aria.Popover, { ...props, ref: ref, offset: offset, isNonModal: true, className: __magnaClasses_1(classes('z-50 min-w-[--trigger-width] max-w-[calc(100vw-24px)] overflow-hidden rounded-2xl bg-bg-white-0 p-1 shadow-regular-md outline-none ring-1 ring-inset ring-stroke-soft-200', className), className), "data-magnaui": '', children: (state) => (_jsx("div", { ...attributes, "data-magnaui": '', children: typeof children === 'function' ? children(state) : children })) }));
56
+ });
57
+ export function List({ className, ...props }) {
58
+ return (_jsx(Aria.ListBox, { ...props, className: __magnaClasses_1(classes('max-h-[min(320px,var(--available-height))] min-w-40 overflow-y-auto overscroll-contain p-1 outline-none', className), className), "data-magnaui": '' }));
59
+ }
60
+ export function Item({ className, children, textValue, ...props }) {
61
+ return (_jsx(Aria.ListBoxItem, { ...props, textValue: textValue ?? (typeof children === 'string' ? children : undefined), className: __magnaClasses_1(classes('flex min-h-9 cursor-default select-none items-center gap-2 rounded-lg px-2 py-1.5 text-start text-paragraph-sm text-text-strong-950 outline-none data-[focused]:bg-bg-weak-50 data-[selected]:bg-primary-alpha-10 data-[disabled]:text-text-disabled-300 data-[disabled]:opacity-60', className), className), "data-magnaui": '', children: (state) => (_jsxs(_Fragment, { children: [_jsx("span", { className: __magnaClasses_1('min-w-0 flex-1'), "data-magnaui": '', children: typeof children === 'function' ? children(state) : children }), state.isSelected && (_jsx(RiCheckLine, { className: __magnaClasses_1('size-4 shrink-0 text-primary-base'), "aria-hidden": 'true', "data-magnaui": '' }))] })) }));
62
+ }
63
+ /** Supply through List.renderEmptyState so empty text is not treated as an option. */
64
+ export function Empty({ className, ...props }) {
65
+ return (_jsx("div", { ...props, className: __magnaClasses_1(__magnaClasses_1(cn('px-3 py-4 text-center text-paragraph-sm text-text-soft-400', className), className), className), "data-magnaui": '' }));
66
+ }
67
+ export const Description = React.forwardRef(function Description({ className, ...props }, ref) {
68
+ return (_jsx(Aria.Text, { ...props, ref: ref, slot: 'description', className: __magnaClasses_1(__magnaClasses_1(cn('text-start text-paragraph-xs text-text-sub-600', className), className), className), "data-magnaui": '' }));
69
+ });
70
+ export const Error = React.forwardRef(function Error({ className, ...props }, ref) {
71
+ return (_jsx(Aria.FieldError, { ...props, ref: ref, className: __magnaClasses_1(classes('text-start text-paragraph-xs text-error-base', className), className), "data-magnaui": '' }));
72
+ });
@@ -1,5 +1,6 @@
1
1
  import * as React from "react";
2
2
  import type { PolymorphicComponentProps } from "../../utils/polymorphic.js";
3
+ import { type HitAreaProps } from "./hit-area.js";
3
4
  type Appearance = {
4
5
  variant: 'stroke' | 'ghost' | 'white' | 'modifiable';
5
6
  size: 'large' | 'medium';
@@ -14,7 +15,7 @@ export declare const compactButtonVariants: (options?: Partial<Appearance> & {
14
15
  }) | undefined) => string>;
15
16
  export declare const Root: React.ForwardRefExoticComponent<React.ButtonHTMLAttributes<HTMLButtonElement> & Partial<Appearance> & {
16
17
  asChild?: boolean;
17
- } & React.RefAttributes<HTMLButtonElement>>;
18
+ } & HitAreaProps & React.RefAttributes<HTMLButtonElement>>;
18
19
  export declare function Icon<T extends React.ElementType = 'div'>({ as, variant, size, className, ...props }: PolymorphicComponentProps<T, Partial<Omit<Appearance, 'fullRadius'>>>): import("react/jsx-runtime").JSX.Element;
19
20
  export declare namespace Icon {
20
21
  var displayName: string;
@@ -4,6 +4,8 @@ import { magnaRecipe as __magnaRecipe_1, magnaClasses as __magnaClasses_1 } from
4
4
  import * as React from "react";
5
5
  import { Slot } from "@radix-ui/react-slot";
6
6
  import { mergeOptions, slotRecipe } from "./magna-recipe.js";
7
+ import { touchHitArea } from "./hit-area.js";
8
+ import { cn } from "../../utils/cn.js";
7
9
  const appearance = React.createContext({});
8
10
  const surfaces = {
9
11
  stroke: 'border border-stroke-soft-200 bg-bg-white-0 shadow-regular-xs hover:border-transparent hover:shadow-none focus-visible:border-transparent focus-visible:shadow-none',
@@ -23,10 +25,12 @@ export const compactButtonVariants = __magnaRecipe_1(slotRecipe({ variant: 'stro
23
25
  ],
24
26
  icon: size === 'large' ? 'size-5' : 'size-[18px]',
25
27
  })));
26
- export const Root = React.forwardRef(function CompactButton({ variant, size, fullRadius, asChild, className, children, ...props }, ref) {
28
+ export const Root = React.forwardRef(function CompactButton({ variant, size, fullRadius, asChild, hitArea = 'visual', className, children, ...props }, ref) {
27
29
  const options = { variant, size, fullRadius };
28
30
  const Element = asChild ? Slot : 'button';
29
- return (_jsx(appearance.Provider, { value: options, children: _jsx(Element, { ref: ref, className: __magnaClasses_1(compactButtonVariants(options).root({ className }), className), ...props, "data-magnaui": '', children: children }) }));
31
+ return (_jsx(appearance.Provider, { value: options, children: _jsx(Element, { ref: ref, className: __magnaClasses_1(compactButtonVariants(options).root({
32
+ className: __magnaClasses_1(cn(hitArea === 'touch' && touchHitArea, className), className),
33
+ }), className), ...props, "data-magnaui": '', children: children }) }));
30
34
  });
31
35
  Root.displayName = 'CompactButtonRoot';
32
36
  export function Icon({ as, variant, size, className, ...props }) {
@@ -7,6 +7,6 @@ import * as CompactButton from "./compact-button.js";
7
7
  import * as KeyIcon from "./key-icon.js";
8
8
  import { DisplayAsset } from "./display-asset.js";
9
9
  import { displayAssets } from "./display-assets.js";
10
- export const Root = React.forwardRef(function ContentCard({ title, sublabel, description, badge, leading, variant = 'basic', onDismiss, dismissLabel = 'Dismiss card', className, ...props }, ref) {
11
- return (_jsxs("div", { ref: ref, ...props, className: __magnaClasses_1(__magnaClasses_1(cn('flex w-[360px] max-w-full items-center gap-3.5 rounded-xl bg-bg-white-0 p-4 shadow-regular-xs ring-1 ring-inset ring-stroke-soft-200', className), className), className), "data-magnaui": '', children: [variant !== 'basic' && (leading || variant === 'icon') && (_jsx("span", { className: __magnaClasses_1(__magnaClasses_1(cn('flex shrink-0 items-center justify-center', variant === 'provider' ? 'h-6 w-8' : 'size-10', variant === 'avatar' && 'overflow-hidden rounded-full'))), "data-magnaui": '', children: leading ?? _jsx(KeyIcon.Root, { size: 40 }) })), _jsxs("div", { className: __magnaClasses_1('min-w-0 flex-1 space-y-1'), "data-magnaui": '', children: [_jsxs("div", { className: __magnaClasses_1('flex flex-wrap items-center gap-1'), "data-magnaui": '', children: [_jsx("span", { className: __magnaClasses_1('text-label-sm text-text-strong-950'), "data-magnaui": '', children: title }), sublabel && (_jsx("span", { className: __magnaClasses_1('text-paragraph-xs text-text-sub-600'), "data-magnaui": '', children: sublabel })), badge] }), description && (_jsx("p", { className: __magnaClasses_1('text-paragraph-xs text-text-sub-600'), "data-magnaui": '', children: description }))] }), onDismiss && (_jsx(CompactButton.Root, { type: 'button', variant: 'ghost', size: 'medium', "aria-label": dismissLabel, onClick: onDismiss, children: _jsx(DisplayAsset, { src: displayAssets.contentClose }) }))] }));
10
+ export const Root = React.forwardRef(function ContentCard({ title, sublabel, description, children, badge, leading, variant = 'basic', onDismiss, dismissLabel = 'Dismiss card', className, ...props }, ref) {
11
+ return (_jsxs("div", { ref: ref, ...props, className: __magnaClasses_1(__magnaClasses_1(cn('flex w-[360px] max-w-full items-center gap-3.5 rounded-xl bg-bg-white-0 p-4 shadow-regular-xs ring-1 ring-inset ring-stroke-soft-200', className), className), className), "data-magnaui": '', children: [variant !== 'basic' && (leading || variant === 'icon') && (_jsx("span", { className: __magnaClasses_1(__magnaClasses_1(cn('flex shrink-0 items-center justify-center', variant === 'provider' ? 'h-6 w-8' : 'size-10', variant === 'avatar' && 'overflow-hidden rounded-full'))), "data-magnaui": '', children: leading ?? _jsx(KeyIcon.Root, { size: 40 }) })), _jsxs("div", { className: __magnaClasses_1('min-w-0 flex-1 space-y-1'), "data-magnaui": '', children: [_jsxs("div", { className: __magnaClasses_1('flex flex-wrap items-center gap-1'), "data-magnaui": '', children: [_jsx("span", { className: __magnaClasses_1('text-label-sm text-text-strong-950'), "data-magnaui": '', children: title }), sublabel && (_jsx("span", { className: __magnaClasses_1('text-paragraph-xs text-text-sub-600'), "data-magnaui": '', children: sublabel })), badge] }), description && (_jsx("p", { className: __magnaClasses_1('text-paragraph-xs text-text-sub-600'), "data-magnaui": '', children: description })), children] }), onDismiss && (_jsx(CompactButton.Root, { type: 'button', variant: 'ghost', size: 'medium', "aria-label": dismissLabel, onClick: onDismiss, children: _jsx(DisplayAsset, { src: displayAssets.contentClose }) }))] }));
12
12
  });
@@ -0,0 +1,15 @@
1
+ import * as React from "react";
2
+ export type HighlightProps = React.HTMLAttributes<HTMLElement> & {
3
+ tone?: 'primary' | 'warning' | 'neutral';
4
+ };
5
+ /** Semantic highlighted text; content remains text rather than injected HTML. */
6
+ export declare function Root({ tone, className, ...props }: HighlightProps): import("react/jsx-runtime").JSX.Element;
7
+ export type HighlightTextProps = Omit<React.HTMLAttributes<HTMLSpanElement>, 'children'> & {
8
+ children: string;
9
+ match: string | readonly string[];
10
+ caseSensitive?: boolean;
11
+ tone?: HighlightProps['tone'];
12
+ markClassName?: string;
13
+ };
14
+ /** Highlight literal search terms, longest first; punctuation is never a regular expression. */
15
+ export declare function Text({ children, match, caseSensitive, tone, markClassName, ...props }: HighlightTextProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,20 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { magnaClasses as __magnaClasses_1 } from "../../magna-classes.js";
3
+ import { cn } from "../../utils/cn.js";
4
+ /** Semantic highlighted text; content remains text rather than injected HTML. */
5
+ export function Root({ tone = 'primary', className, ...props }) {
6
+ return (_jsx("mark", { ...props, className: __magnaClasses_1(__magnaClasses_1(cn('rounded-sm px-0.5 text-inherit [box-decoration-break:clone]', tone === 'primary' && 'bg-primary-alpha-24', tone === 'warning' && 'bg-warning-light', tone === 'neutral' && 'bg-bg-soft-200', className), className), className), "data-magnaui": '' }));
7
+ }
8
+ /** Highlight literal search terms, longest first; punctuation is never a regular expression. */
9
+ export function Text({ children, match, caseSensitive = false, tone, markClassName, ...props }) {
10
+ const terms = [...new Set(typeof match === 'string' ? [match] : match)]
11
+ .filter(Boolean)
12
+ .sort((a, b) => b.length - a.length);
13
+ const pattern = terms
14
+ .map((term) => term.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'))
15
+ .join('|');
16
+ const parts = pattern
17
+ ? children.split(new RegExp(`(${pattern})`, caseSensitive ? 'gu' : 'giu'))
18
+ : [children];
19
+ return (_jsx("span", { ...props, "data-magnaui": '', children: parts.map((part, index) => index % 2 ? (_jsx(Root, { tone: tone, className: __magnaClasses_1(markClassName, markClassName), "data-magnaui": '', children: part }, index)) : (part)) }));
20
+ }
@@ -0,0 +1,6 @@
1
+ /** Extend the existing control's hit box without adding a tab stop or changing layout. */
2
+ export declare const touchHitArea = "after:absolute after:left-1/2 after:top-1/2 after:h-full after:w-full after:min-h-[44px] after:min-w-[44px] after:-translate-x-1/2 after:-translate-y-1/2 after:content-['']";
3
+ export type HitAreaProps = {
4
+ /** Touch adds a 44 px minimum hit area. Leave space around adjacent controls. */
5
+ hitArea?: 'visual' | 'touch';
6
+ };
@@ -0,0 +1,2 @@
1
+ /** Extend the existing control's hit box without adding a tab stop or changing layout. */
2
+ export const touchHitArea = "after:absolute after:left-1/2 after:top-1/2 after:h-full after:w-full after:min-h-[44px] after:min-w-[44px] after:-translate-x-1/2 after:-translate-y-1/2 after:content-['']";
@@ -5,10 +5,24 @@ export declare const Root: React.FC<Dialog.DialogProps>;
5
5
  export declare const Trigger: React.ForwardRefExoticComponent<Dialog.DialogTriggerProps & React.RefAttributes<HTMLButtonElement>>;
6
6
  export declare const Close: React.ForwardRefExoticComponent<Dialog.DialogCloseProps & React.RefAttributes<HTMLButtonElement>>;
7
7
  export declare const Portal: React.FC<Dialog.DialogPortalProps>;
8
+ export type ModalSize = 'small' | 'medium' | 'large' | 'xlarge' | 'full';
9
+ export declare const modalContentVariants: (options?: Partial<{
10
+ size: ModalSize;
11
+ }> & {
12
+ class?: import("tailwind-merge").ClassNameValue;
13
+ className?: import("tailwind-merge").ClassNameValue;
14
+ }) => Record<"root", (overrides?: (Partial<{
15
+ size: ModalSize;
16
+ }> & {
17
+ class?: import("tailwind-merge").ClassNameValue;
18
+ className?: import("tailwind-merge").ClassNameValue;
19
+ }) | undefined) => string>;
8
20
  export declare const Overlay: React.ForwardRefExoticComponent<Omit<Dialog.DialogOverlayProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
9
21
  export declare const Content: React.ForwardRefExoticComponent<Omit<Dialog.DialogContentProps & React.RefAttributes<HTMLDivElement>, "ref"> & {
10
22
  overlayClassName?: string;
11
23
  showClose?: boolean;
24
+ /** Small preserves the original 400 px maximum. All sizes fit the viewport. */
25
+ size?: ModalSize;
12
26
  } & React.RefAttributes<HTMLDivElement>>;
13
27
  export declare const Title: React.ForwardRefExoticComponent<Omit<Dialog.DialogTitleProps & React.RefAttributes<HTMLHeadingElement>, "ref"> & React.RefAttributes<HTMLHeadingElement>>;
14
28
  export declare const Description: React.ForwardRefExoticComponent<Omit<Dialog.DialogDescriptionProps & React.RefAttributes<HTMLParagraphElement>, "ref"> & React.RefAttributes<HTMLParagraphElement>>;
@@ -1,6 +1,6 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
- import { magnaClasses as __magnaClasses_1 } from "../../magna-classes.js";
3
+ import { magnaRecipe as __magnaRecipe_1, magnaClasses as __magnaClasses_1 } from "../../magna-classes.js";
4
4
  import * as React from "react";
5
5
  import * as Dialog from "@radix-ui/react-dialog";
6
6
  import { Slottable } from "@radix-ui/react-slot";
@@ -8,17 +8,33 @@ import { RiCloseLine } from "@remixicon/react";
8
8
  import * as CompactButton from "./compact-button.js";
9
9
  import { cn } from "../../utils/cn.js";
10
10
  import { useDirectionAttributes } from "./direction-provider.js";
11
+ import { slotRecipe } from "./magna-recipe.js";
11
12
  export const Root = Dialog.Root;
12
13
  export const Trigger = Dialog.Trigger;
13
14
  export const Close = Dialog.Close;
14
15
  export const Portal = Dialog.Portal;
15
16
  const fade = 'data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=closed]:animate-out data-[state=closed]:fade-out-0';
17
+ const widths = {
18
+ small: 'max-w-[400px]',
19
+ medium: 'max-w-[560px]',
20
+ large: 'max-w-[720px]',
21
+ xlarge: 'max-w-[960px]',
22
+ full: 'max-w-none',
23
+ };
24
+ export const modalContentVariants = __magnaRecipe_1(slotRecipe({ size: 'small' }, ({ size }) => ({
25
+ root: [
26
+ 'relative w-full rounded-20 bg-bg-white-0 shadow-regular-md outline-none',
27
+ widths[size],
28
+ fade,
29
+ 'data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95',
30
+ ],
31
+ })));
16
32
  export const Overlay = React.forwardRef(function Overlay({ className, ...props }, ref) {
17
33
  return (_jsx(Dialog.Overlay, { ...props, ref: ref, className: __magnaClasses_1(__magnaClasses_1(cn('fixed inset-0 z-50 flex flex-col items-center justify-center overflow-y-auto bg-overlay p-4 backdrop-blur-[10px]', fade, className), className), className), "data-magnaui": '' }));
18
34
  });
19
- export const Content = React.forwardRef(function Content({ children, className, overlayClassName, showClose = true, ...props }, ref) {
35
+ export const Content = React.forwardRef(function Content({ children, className, overlayClassName, showClose = true, size = 'small', ...props }, ref) {
20
36
  const direction = useDirectionAttributes(props.dir, props.lang);
21
- return (_jsx(Portal, { children: _jsx(Overlay, { className: __magnaClasses_1(overlayClassName, overlayClassName), "data-magnaui": '', children: _jsxs(Dialog.Content, { ...props, ...direction, ref: ref, className: __magnaClasses_1(__magnaClasses_1(cn('relative w-full max-w-[400px] rounded-20 bg-bg-white-0 shadow-regular-md outline-none', fade, 'data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95', className), className), className), "data-magnaui": '', children: [_jsx(Slottable, { children: children }), showClose && (_jsx(Close, { asChild: true, children: _jsx(CompactButton.Root, { "aria-label": 'Close dialog', size: 'large', variant: 'ghost', className: __magnaClasses_1('absolute end-4 top-4'), "data-magnaui": '', children: _jsx(CompactButton.Icon, { as: RiCloseLine }) }) }))] }) }) }));
37
+ return (_jsx(Portal, { children: _jsx(Overlay, { className: __magnaClasses_1(overlayClassName, overlayClassName), "data-magnaui": '', children: _jsxs(Dialog.Content, { ...props, ...direction, ref: ref, className: __magnaClasses_1(modalContentVariants({ size }).root({ className }), className), "data-magnaui": '', children: [_jsx(Slottable, { children: children }), showClose && (_jsx(Close, { asChild: true, children: _jsx(CompactButton.Root, { "aria-label": 'Close dialog', size: 'large', variant: 'ghost', className: __magnaClasses_1('absolute end-4 top-4'), "data-magnaui": '', children: _jsx(CompactButton.Icon, { as: RiCloseLine }) }) }))] }) }) }));
22
38
  });
23
39
  export const Title = React.forwardRef(function Title({ className, ...props }, ref) {
24
40
  return (_jsx(Dialog.Title, { ...props, ref: ref, className: __magnaClasses_1(__magnaClasses_1(cn('text-label-sm text-text-strong-950', className), className), className), "data-magnaui": '' }));
@@ -0,0 +1,10 @@
1
+ import * as React from "react";
2
+ export type PanelProps = React.HTMLAttributes<HTMLDivElement> & {
3
+ /** Apply the surface to a single semantic child, such as a section or form. */
4
+ asChild?: boolean;
5
+ };
6
+ /** A neutral Magna surface for forms, tables, and other block content. */
7
+ export declare const Root: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & {
8
+ /** Apply the surface to a single semantic child, such as a section or form. */
9
+ asChild?: boolean;
10
+ } & React.RefAttributes<HTMLDivElement>>;
@@ -0,0 +1,12 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { magnaClasses as __magnaClasses_1 } from "../../magna-classes.js";
4
+ import * as React from "react";
5
+ import { Slot } from "@radix-ui/react-slot";
6
+ import { cn } from "../../utils/cn.js";
7
+ /** A neutral Magna surface for forms, tables, and other block content. */
8
+ export const Root = React.forwardRef(function Panel({ asChild, className, ...props }, ref) {
9
+ const Element = asChild ? Slot : 'div';
10
+ return (_jsx(Element, { ...props, ref: ref, className: __magnaClasses_1(__magnaClasses_1(cn('min-w-0 rounded-xl bg-bg-white-0 p-4 shadow-regular-xs ring-1 ring-inset ring-stroke-soft-200', className), className), className), "data-magnaui": '' }));
11
+ });
12
+ Root.displayName = 'PanelRoot';
@@ -1,6 +1,8 @@
1
1
  import * as React from "react";
2
2
  type Appearance = {
3
3
  color: 'blue' | 'red' | 'orange' | 'green';
4
+ /** Unknown completion. A null value also selects this state. */
5
+ indeterminate: boolean;
4
6
  };
5
7
  export declare const progressBarVariants: (options?: Partial<Appearance> & {
6
8
  class?: import("tailwind-merge").ClassNameValue;
@@ -10,7 +12,7 @@ export declare const progressBarVariants: (options?: Partial<Appearance> & {
10
12
  className?: import("tailwind-merge").ClassNameValue;
11
13
  }) | undefined) => string>;
12
14
  export declare const Root: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & Partial<Appearance> & {
13
- value?: number;
15
+ value?: number | null;
14
16
  max?: number;
15
17
  } & React.RefAttributes<HTMLDivElement>>;
16
18
  export type LabelProps = React.ComponentPropsWithoutRef<typeof Root> & {
@@ -22,7 +24,7 @@ export type LabelProps = React.ComponentPropsWithoutRef<typeof Root> & {
22
24
  showPercentage?: boolean;
23
25
  };
24
26
  export declare const Label: React.ForwardRefExoticComponent<Omit<React.HTMLAttributes<HTMLDivElement> & Partial<Appearance> & {
25
- value?: number;
27
+ value?: number | null;
26
28
  max?: number;
27
29
  } & React.RefAttributes<HTMLDivElement>, "ref"> & {
28
30
  label: React.ReactNode;