aeon-ui-engine 1.1.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +35 -0
- package/CONSUMER.md +45 -0
- package/package.json +1 -1
- package/packages/core/dist/index.d.ts +88 -8
- package/packages/core/dist/index.js +123 -0
- package/packages/core/src/anatomy.ts +38 -0
- package/packages/core/src/brand-theme.ts +183 -0
- package/packages/core/src/index.ts +1 -0
- package/packages/panda/aeon.css +1 -0
- package/packages/panda/src/theme/consumer-shell.css +250 -0
- package/packages/panda/src/theme/electron.css +114 -0
- package/packages/primitives/dist/chunk-4NOKRUSG.js +81 -0
- package/packages/primitives/dist/index.d.ts +1 -0
- package/packages/primitives/dist/index.js +16 -6
- package/packages/primitives/dist/machines/app-nav.d.ts +96 -0
- package/packages/primitives/dist/machines/app-nav.js +12 -0
- package/packages/primitives/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
- package/packages/primitives/src/__tests__/app-nav.test.ts +30 -0
- package/packages/primitives/src/index.ts +1 -0
- package/packages/primitives/src/machines/app-nav.ts +107 -0
- package/packages/react/dist/index.d.ts +135 -3
- package/packages/react/dist/index.js +1126 -720
- package/packages/react/src/app-nav/index.tsx +249 -0
- package/packages/react/src/avatar/index.tsx +4 -1
- package/packages/react/src/hooks/use-fit-text.ts +59 -0
- package/packages/react/src/index.ts +4 -0
- package/packages/react/src/prompt/index.tsx +161 -0
- package/packages/react/src/status-banner/index.tsx +84 -0
- package/packages/ui/src/app-nav.tsx +2 -0
- package/packages/ui/src/index.ts +4 -0
- package/packages/ui/src/prompt.tsx +29 -0
- package/packages/ui/src/status-banner.tsx +1 -0
- package/scripts/vite-aliases.mjs +8 -0
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { assign, setup } from 'xstate'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Section + detail stack navigation — the pattern every multi-panel product
|
|
5
|
+
* reinvented (wallet sections, settings drill-in, list→detail).
|
|
6
|
+
*
|
|
7
|
+
* Not product-specific: `section` is a string id; `stack` is opaque child records.
|
|
8
|
+
*/
|
|
9
|
+
export type AppNavChild = {
|
|
10
|
+
id: string
|
|
11
|
+
/** Free-form type tag (e.g. "detail", "compose", "settings"). */
|
|
12
|
+
type: string
|
|
13
|
+
/** Optional payload for the view layer. */
|
|
14
|
+
data?: unknown
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface AppNavContext {
|
|
18
|
+
section: string
|
|
19
|
+
stack: AppNavChild[]
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export type AppNavEvent =
|
|
23
|
+
| { type: 'SET_SECTION'; section: string }
|
|
24
|
+
| { type: 'PUSH'; child: AppNavChild }
|
|
25
|
+
| { type: 'REPLACE'; child: AppNavChild }
|
|
26
|
+
| { type: 'POP' }
|
|
27
|
+
| { type: 'POP_TO'; id: string }
|
|
28
|
+
| { type: 'CLEAR' }
|
|
29
|
+
| { type: 'RESET'; section: string }
|
|
30
|
+
|
|
31
|
+
export function appNavDepth(ctx: AppNavContext): number {
|
|
32
|
+
return ctx.stack.length
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function appNavChild(ctx: AppNavContext): AppNavChild | null {
|
|
36
|
+
return ctx.stack.length ? ctx.stack[ctx.stack.length - 1]! : null
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** Projected state for data-aeon-state: `section` or `section/childType`. */
|
|
40
|
+
export function appNavStateAttr(ctx: AppNavContext): string {
|
|
41
|
+
const child = appNavChild(ctx)
|
|
42
|
+
return child ? `${ctx.section}/${child.type}` : ctx.section
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export const appNavMachine = setup({
|
|
46
|
+
types: {
|
|
47
|
+
context: {} as AppNavContext,
|
|
48
|
+
events: {} as AppNavEvent,
|
|
49
|
+
input: {} as Partial<AppNavContext> & { section?: string },
|
|
50
|
+
},
|
|
51
|
+
actions: {
|
|
52
|
+
setSection: assign({
|
|
53
|
+
section: ({ event }) => (event.type === 'SET_SECTION' ? event.section : ''),
|
|
54
|
+
stack: [],
|
|
55
|
+
}),
|
|
56
|
+
push: assign({
|
|
57
|
+
stack: ({ context, event }) =>
|
|
58
|
+
event.type === 'PUSH' ? [...context.stack, event.child] : context.stack,
|
|
59
|
+
}),
|
|
60
|
+
replace: assign({
|
|
61
|
+
stack: ({ context, event }) => {
|
|
62
|
+
if (event.type !== 'REPLACE') return context.stack
|
|
63
|
+
if (!context.stack.length) return [event.child]
|
|
64
|
+
return [...context.stack.slice(0, -1), event.child]
|
|
65
|
+
},
|
|
66
|
+
}),
|
|
67
|
+
pop: assign({
|
|
68
|
+
stack: ({ context }) => context.stack.slice(0, -1),
|
|
69
|
+
}),
|
|
70
|
+
popTo: assign({
|
|
71
|
+
stack: ({ context, event }) => {
|
|
72
|
+
if (event.type !== 'POP_TO') return context.stack
|
|
73
|
+
const idx = context.stack.findIndex((c) => c.id === event.id)
|
|
74
|
+
if (idx < 0) return context.stack
|
|
75
|
+
return context.stack.slice(0, idx + 1)
|
|
76
|
+
},
|
|
77
|
+
}),
|
|
78
|
+
clear: assign({ stack: [] }),
|
|
79
|
+
reset: assign({
|
|
80
|
+
section: ({ event }) => (event.type === 'RESET' ? event.section : ''),
|
|
81
|
+
stack: [],
|
|
82
|
+
}),
|
|
83
|
+
},
|
|
84
|
+
guards: {
|
|
85
|
+
canPop: ({ context }) => context.stack.length > 0,
|
|
86
|
+
},
|
|
87
|
+
}).createMachine({
|
|
88
|
+
id: 'appNav',
|
|
89
|
+
context: ({ input }) => ({
|
|
90
|
+
section: input?.section ?? 'home',
|
|
91
|
+
stack: input?.stack ?? [],
|
|
92
|
+
}),
|
|
93
|
+
initial: 'ready',
|
|
94
|
+
states: {
|
|
95
|
+
ready: {
|
|
96
|
+
on: {
|
|
97
|
+
SET_SECTION: { actions: 'setSection' },
|
|
98
|
+
PUSH: { actions: 'push' },
|
|
99
|
+
REPLACE: { actions: 'replace' },
|
|
100
|
+
POP: { guard: 'canPop', actions: 'pop' },
|
|
101
|
+
POP_TO: { actions: 'popTo' },
|
|
102
|
+
CLEAR: { actions: 'clear' },
|
|
103
|
+
RESET: { actions: 'reset' },
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
})
|
|
@@ -3,8 +3,8 @@ import { ButtonHTMLAttributes, ReactNode, HTMLAttributes, InputHTMLAttributes, L
|
|
|
3
3
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
4
4
|
import * as xstate from 'xstate';
|
|
5
5
|
import { AnyStateMachine } from 'xstate';
|
|
6
|
-
import { AsyncContext, ContentRegionState, StickyBarState } from '@aeon-ui/primitives';
|
|
7
|
-
export { createAsyncMachine, fieldMachine } from '@aeon-ui/primitives';
|
|
6
|
+
import { AsyncContext, ContentRegionState, AppNavChild, StickyBarState } from '@aeon-ui/primitives';
|
|
7
|
+
export { AppNavChild, AppNavContext, createAsyncMachine, fieldMachine } from '@aeon-ui/primitives';
|
|
8
8
|
import { useMachine } from '@xstate/react';
|
|
9
9
|
import { fieldFace, AeonColorMode, ResponsiveLayoutSpec, LayoutMode, LayoutCompositionSpec } from '@aeon-ui/core';
|
|
10
10
|
export { AeonColorMode as AeonMode } from '@aeon-ui/core';
|
|
@@ -81,6 +81,51 @@ declare const Dialog: {
|
|
|
81
81
|
CloseTrigger: react.ForwardRefExoticComponent<ButtonHTMLAttributes<HTMLButtonElement> & react.RefAttributes<HTMLButtonElement>>;
|
|
82
82
|
};
|
|
83
83
|
|
|
84
|
+
type PromptStatus = 'pending' | 'confirming' | 'dismissed' | 'confirmed';
|
|
85
|
+
interface PromptRootProps {
|
|
86
|
+
open?: boolean;
|
|
87
|
+
defaultOpen?: boolean;
|
|
88
|
+
onOpenChange?: (open: boolean) => void;
|
|
89
|
+
/** Projected onto data-aeon-state (default: pending when open). */
|
|
90
|
+
status?: PromptStatus;
|
|
91
|
+
children?: ReactNode;
|
|
92
|
+
className?: string;
|
|
93
|
+
}
|
|
94
|
+
declare const Prompt: {
|
|
95
|
+
Root: react.ForwardRefExoticComponent<PromptRootProps & react.RefAttributes<HTMLDivElement>>;
|
|
96
|
+
Trigger: react.ForwardRefExoticComponent<ButtonHTMLAttributes<HTMLButtonElement> & react.RefAttributes<HTMLButtonElement>>;
|
|
97
|
+
Portal: react.ForwardRefExoticComponent<DialogPortalProps & react.RefAttributes<HTMLDivElement>>;
|
|
98
|
+
Backdrop: react.ForwardRefExoticComponent<HTMLAttributes<HTMLDivElement> & react.RefAttributes<HTMLDivElement>>;
|
|
99
|
+
Positioner: react.ForwardRefExoticComponent<HTMLAttributes<HTMLDivElement> & react.RefAttributes<HTMLDivElement>>;
|
|
100
|
+
Content: react.ForwardRefExoticComponent<HTMLAttributes<HTMLDivElement> & react.RefAttributes<HTMLDivElement>>;
|
|
101
|
+
Title: react.ForwardRefExoticComponent<HTMLAttributes<HTMLHeadingElement> & react.RefAttributes<HTMLHeadingElement>>;
|
|
102
|
+
Description: react.ForwardRefExoticComponent<HTMLAttributes<HTMLParagraphElement> & react.RefAttributes<HTMLParagraphElement>>;
|
|
103
|
+
CloseTrigger: react.ForwardRefExoticComponent<ButtonHTMLAttributes<HTMLButtonElement> & react.RefAttributes<HTMLButtonElement>>;
|
|
104
|
+
Eyebrow: react.ForwardRefExoticComponent<HTMLAttributes<HTMLParagraphElement> & react.RefAttributes<HTMLParagraphElement>>;
|
|
105
|
+
Meta: react.ForwardRefExoticComponent<HTMLAttributes<HTMLDListElement> & react.RefAttributes<HTMLDListElement>>;
|
|
106
|
+
Amount: react.ForwardRefExoticComponent<HTMLAttributes<HTMLDivElement> & react.RefAttributes<HTMLDivElement>>;
|
|
107
|
+
Actions: react.ForwardRefExoticComponent<HTMLAttributes<HTMLDivElement> & react.RefAttributes<HTMLDivElement>>;
|
|
108
|
+
Primary: react.ForwardRefExoticComponent<ButtonHTMLAttributes<HTMLButtonElement> & react.RefAttributes<HTMLButtonElement>>;
|
|
109
|
+
Secondary: react.ForwardRefExoticComponent<ButtonHTMLAttributes<HTMLButtonElement> & react.RefAttributes<HTMLButtonElement>>;
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
type StatusBannerTone = 'info' | 'success' | 'warning' | 'danger';
|
|
113
|
+
interface StatusBannerRootProps extends HTMLAttributes<HTMLDivElement> {
|
|
114
|
+
tone?: StatusBannerTone;
|
|
115
|
+
/** Machine-ish status string projected to data-aeon-state (e.g. ready, downloading). */
|
|
116
|
+
status?: string;
|
|
117
|
+
children?: ReactNode;
|
|
118
|
+
}
|
|
119
|
+
/** Non-blocking top-of-app notice (updates, sync, offline). */
|
|
120
|
+
declare const StatusBanner: {
|
|
121
|
+
Root: react.ForwardRefExoticComponent<StatusBannerRootProps & react.RefAttributes<HTMLDivElement>>;
|
|
122
|
+
Copy: react.ForwardRefExoticComponent<HTMLAttributes<HTMLDivElement> & react.RefAttributes<HTMLDivElement>>;
|
|
123
|
+
Title: react.ForwardRefExoticComponent<HTMLAttributes<HTMLElement> & react.RefAttributes<HTMLElement>>;
|
|
124
|
+
Body: react.ForwardRefExoticComponent<HTMLAttributes<HTMLSpanElement> & react.RefAttributes<HTMLSpanElement>>;
|
|
125
|
+
Actions: react.ForwardRefExoticComponent<HTMLAttributes<HTMLDivElement> & react.RefAttributes<HTMLDivElement>>;
|
|
126
|
+
Action: react.ForwardRefExoticComponent<ButtonHTMLAttributes<HTMLButtonElement> & react.RefAttributes<HTMLButtonElement>>;
|
|
127
|
+
};
|
|
128
|
+
|
|
84
129
|
interface TabsRootProps {
|
|
85
130
|
value?: string;
|
|
86
131
|
defaultValue?: string;
|
|
@@ -861,6 +906,81 @@ declare const AppShell: {
|
|
|
861
906
|
Scrim: react.ForwardRefExoticComponent<HTMLAttributes<HTMLDivElement> & react.RefAttributes<HTMLDivElement>>;
|
|
862
907
|
};
|
|
863
908
|
|
|
909
|
+
interface AppNavContextValue {
|
|
910
|
+
section: string;
|
|
911
|
+
stack: AppNavChild[];
|
|
912
|
+
child: AppNavChild | null;
|
|
913
|
+
stateAttr: string;
|
|
914
|
+
send: ReturnType<typeof useAeonMachine<typeof appNavMachine>>[1];
|
|
915
|
+
setSection: (section: string) => void;
|
|
916
|
+
push: (child: AppNavChild) => void;
|
|
917
|
+
replace: (child: AppNavChild) => void;
|
|
918
|
+
pop: () => void;
|
|
919
|
+
popTo: (id: string) => void;
|
|
920
|
+
clear: () => void;
|
|
921
|
+
}
|
|
922
|
+
declare function useAppNav(): AppNavContextValue;
|
|
923
|
+
/** Use the machine without the compound tree. */
|
|
924
|
+
declare function useAppNavMachine(input?: {
|
|
925
|
+
section?: string;
|
|
926
|
+
stack?: AppNavChild[];
|
|
927
|
+
}): {
|
|
928
|
+
section: string;
|
|
929
|
+
stack: AppNavChild[];
|
|
930
|
+
child: AppNavChild | null;
|
|
931
|
+
stateAttr: string;
|
|
932
|
+
send: (event: {
|
|
933
|
+
type: "SET_SECTION";
|
|
934
|
+
section: string;
|
|
935
|
+
} | {
|
|
936
|
+
type: "PUSH";
|
|
937
|
+
child: AppNavChild;
|
|
938
|
+
} | {
|
|
939
|
+
type: "REPLACE";
|
|
940
|
+
child: AppNavChild;
|
|
941
|
+
} | {
|
|
942
|
+
type: "POP";
|
|
943
|
+
} | {
|
|
944
|
+
type: "POP_TO";
|
|
945
|
+
id: string;
|
|
946
|
+
} | {
|
|
947
|
+
type: "CLEAR";
|
|
948
|
+
} | {
|
|
949
|
+
type: "RESET";
|
|
950
|
+
section: string;
|
|
951
|
+
}) => void;
|
|
952
|
+
setSection: (next: string) => void;
|
|
953
|
+
push: (next: AppNavChild) => void;
|
|
954
|
+
replace: (next: AppNavChild) => void;
|
|
955
|
+
pop: () => void;
|
|
956
|
+
popTo: (id: string) => void;
|
|
957
|
+
clear: () => void;
|
|
958
|
+
reset: (next: string) => void;
|
|
959
|
+
};
|
|
960
|
+
interface AppNavRootProps extends HTMLAttributes<HTMLDivElement> {
|
|
961
|
+
defaultSection?: string;
|
|
962
|
+
children?: ReactNode;
|
|
963
|
+
}
|
|
964
|
+
interface AppNavSectionProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
|
965
|
+
value: string;
|
|
966
|
+
}
|
|
967
|
+
interface AppNavBreadcrumbProps extends HTMLAttributes<HTMLElement> {
|
|
968
|
+
/** Labels for section + each stack entry (length = 1 + stack.length). */
|
|
969
|
+
labels?: string[];
|
|
970
|
+
}
|
|
971
|
+
/**
|
|
972
|
+
* AppNav — section rail + detail stack.
|
|
973
|
+
* Machine: SET_SECTION / PUSH / POP / CLEAR. UI = f(section, stack).
|
|
974
|
+
*/
|
|
975
|
+
declare const AppNav: {
|
|
976
|
+
Root: react.ForwardRefExoticComponent<AppNavRootProps & react.RefAttributes<HTMLDivElement>>;
|
|
977
|
+
Rail: react.ForwardRefExoticComponent<HTMLAttributes<HTMLElement> & react.RefAttributes<HTMLElement>>;
|
|
978
|
+
Section: react.ForwardRefExoticComponent<AppNavSectionProps & react.RefAttributes<HTMLButtonElement>>;
|
|
979
|
+
Stage: react.ForwardRefExoticComponent<HTMLAttributes<HTMLDivElement> & react.RefAttributes<HTMLDivElement>>;
|
|
980
|
+
Breadcrumb: react.ForwardRefExoticComponent<AppNavBreadcrumbProps & react.RefAttributes<HTMLElement>>;
|
|
981
|
+
Back: react.ForwardRefExoticComponent<ButtonHTMLAttributes<HTMLButtonElement> & react.RefAttributes<HTMLButtonElement>>;
|
|
982
|
+
};
|
|
983
|
+
|
|
864
984
|
interface ContentContextValue {
|
|
865
985
|
state: ContentRegionState;
|
|
866
986
|
error: string | null;
|
|
@@ -948,4 +1068,16 @@ declare function useLayoutMode(spec: ResponsiveLayoutSpec): {
|
|
|
948
1068
|
composition: LayoutCompositionSpec;
|
|
949
1069
|
};
|
|
950
1070
|
|
|
951
|
-
|
|
1071
|
+
type FitTextOptions = {
|
|
1072
|
+
maxPx?: number;
|
|
1073
|
+
minPx?: number;
|
|
1074
|
+
/** Re-run when this value changes (e.g. display string). */
|
|
1075
|
+
watch?: unknown;
|
|
1076
|
+
};
|
|
1077
|
+
/**
|
|
1078
|
+
* Shrink font-size (then scale) so `contentRef` fits inside `slotRef`
|
|
1079
|
+
* without expanding parent layout. Universal for balance rows, titles, tickers.
|
|
1080
|
+
*/
|
|
1081
|
+
declare function useFitText(slotRef: RefObject<HTMLElement | null>, contentRef: RefObject<HTMLElement | null>, opts?: FitTextOptions): void;
|
|
1082
|
+
|
|
1083
|
+
export { Accordion, type AccordionItemContentProps, type AccordionItemProps, type AccordionItemTriggerProps, type AccordionRootProps, AppNav, type AppNavBreadcrumbProps, type AppNavRootProps, type AppNavSectionProps, AppShell, type AppShellRootProps, Async, AsyncActions, AsyncProvider, AsyncReadout, AsyncRoot, AsyncTrack, Avatar, type AvatarRootProps, type AvatarStatus, Bar, type BarRootProps, Button, type ButtonRootProps, type ButtonStatus, Checkbox, type CheckboxRootProps, Combobox, type ComboboxItemProps, type ComboboxRootProps, Composer, type ComposerRootProps, type ComposerState, Content, type ContentRootProps, Conversation, type ConversationItemProps, type ConversationItemState, type ConversationRootProps, Dialog, type DialogPortalProps, type DialogRootProps, Entry, type EntryListProps, type EntryRootProps, type EntryState, Field, type FieldControlProps, type FieldRootProps, type FieldTextareaProps, Identity, type IdentityRootProps, ListRow, type ListRowRootProps, Menu, type MenuItemProps, type MenuPositionerProps, type MenuRootProps, MetricStrip, type MetricStripRootProps, Nav, type NavItemProps, type NavRootProps, Panel, type PanelContentProps, type PanelGroupProps, type PanelLabelProps, type PanelRootProps, type PanelTriggerProps, PinInput, type PinInputInputProps, type PinInputRootProps, Popover, type PopoverPositionerProps, type PopoverRootProps, type PresenceState, ProfileHeader, type ProfileHeaderRootProps, Progress, type ProgressRootProps, Prompt, type PromptRootProps, type PromptStatus, RadioGroup, type RadioGroupItemProps, type RadioGroupRootProps, Scroll, type ScrollRootProps, type ScrollViewportProps, Select, type SelectContentProps, type SelectItemProps, type SelectPositionerProps, type SelectRootProps, Separator, type SeparatorRootProps, Slider, type SliderRootProps, StatusBanner, type StatusBannerRootProps, type StatusBannerTone, StickyBar, type StickyBarRootProps, Switch, type SwitchRootProps, Tabs, type TabsContentProps, type TabsRootProps, type TabsTriggerProps, ThemeSwitcher, type ThemeSwitcherModeBtnProps, type ThemeSwitcherModesProps, type ThemeSwitcherRootProps, type ThemeSwitcherThemeSelectProps, Thread, type ThreadItemProps, type ThreadMessageState, type ThreadRootProps, Toast, ToastItem, type ToastPlacement, type ToastProviderProps, type ToastPublishOptions, type ToastRecord, type ToastRootProps, type ToastStore, type ToastViewportProps, Tooltip, type TooltipPositionerProps, type TooltipRootProps, asyncStatusToContentState, useAeonMachine, useAppNav, useAppNavMachine, useAppShellContext, useAsyncContext, useContentContext, useFieldContext, useFitText, useLayoutMode, useScrollContext, useScrollState, useStickyBarContext, useToast, useToastStore };
|