aeon-ui-engine 1.9.0 → 1.10.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.
- package/CHANGELOG.md +13 -0
- package/README.md +33 -0
- package/package.json +1 -1
- package/packages/core/vitest.config.ts +1 -0
- package/packages/primitives/dist/chunk-H5XJGZHT.js +493 -0
- package/packages/primitives/dist/index.d.ts +1 -0
- package/packages/primitives/dist/index.js +23 -1
- package/packages/primitives/dist/machines/app-nav.d.ts +3 -3
- package/packages/primitives/dist/machines/store.d.ts +286 -0
- package/packages/primitives/dist/machines/store.js +25 -0
- package/packages/primitives/dist/machines/tabs.d.ts +2 -2
- package/packages/primitives/src/index.ts +1 -0
- package/packages/primitives/src/machines/store.ts +712 -0
- package/packages/primitives/vitest.config.ts +1 -0
- package/packages/react/dist/index.d.ts +11 -2
- package/packages/react/dist/index.js +31 -2
- package/packages/react/src/hooks/use-aeon-store.ts +50 -0
- package/packages/react/src/index.ts +1 -0
- package/packages/react/vitest.config.ts +1 -0
- package/packages/tree/vitest.config.ts +1 -0
|
@@ -4,7 +4,7 @@ import * as xstate from 'xstate';
|
|
|
4
4
|
import { AnyStateMachine } from 'xstate';
|
|
5
5
|
import { useMachine } from '@xstate/react';
|
|
6
6
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
7
|
-
import { AsyncContext, ContentRegionState, AppNavChild, StickyBarState } from '@aeon-ui/primitives';
|
|
7
|
+
import { AsyncContext, ContentRegionState, AppNavChild, StickyBarState, AnySlices, AeonStore, QueryOf, QueryResult, EntityOf, StoreState } from '@aeon-ui/primitives';
|
|
8
8
|
export { AppNavChild, AppNavContext, createAsyncMachine, fieldMachine } from '@aeon-ui/primitives';
|
|
9
9
|
import { fieldFace, ListWindowAxis, ListWindow, AeonColorMode, ResponsiveLayoutSpec, LayoutMode, LayoutCompositionSpec } from '@aeon-ui/core';
|
|
10
10
|
export { AeonColorMode as AeonMode } from '@aeon-ui/core';
|
|
@@ -1282,6 +1282,15 @@ declare const StickyBar: {
|
|
|
1282
1282
|
Seam: react.ForwardRefExoticComponent<HTMLAttributes<HTMLDivElement> & react.RefAttributes<HTMLDivElement>>;
|
|
1283
1283
|
};
|
|
1284
1284
|
|
|
1285
|
+
/**
|
|
1286
|
+
* Reads a slice of an Aeon store. Re-renders only when the selected value
|
|
1287
|
+
* changes under `equals` (shallow by default), so a component that selects
|
|
1288
|
+
* one entity ignores writes to every other.
|
|
1289
|
+
*/
|
|
1290
|
+
declare function useAeonSelector<S extends AnySlices, T>(store: AeonStore<S>, selector: (state: StoreState<S>) => T, equals?: (a: T, b: T) => boolean): T;
|
|
1291
|
+
/** Fetches a query while mounted and returns its result; the entities stay in the store. */
|
|
1292
|
+
declare function useAeonQuery<S extends AnySlices, N extends keyof S & string>(store: AeonStore<S>, slice: N, query: QueryOf<S[N]>): QueryResult<EntityOf<S[N]>>;
|
|
1293
|
+
|
|
1285
1294
|
declare function useLayoutMode(spec: ResponsiveLayoutSpec): {
|
|
1286
1295
|
mode: LayoutMode;
|
|
1287
1296
|
composition: LayoutCompositionSpec;
|
|
@@ -1307,4 +1316,4 @@ declare const Slot: react.ForwardRefExoticComponent<HTMLAttributes<HTMLElement>
|
|
|
1307
1316
|
children?: ReactNode;
|
|
1308
1317
|
} & react.RefAttributes<HTMLElement>>;
|
|
1309
1318
|
|
|
1310
|
-
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, Clipboard, type ClipboardIndicatorProps, type ClipboardRootProps, Combobox, type ComboboxItemProps, type ComboboxRootProps, Composer, type ComposerInputProps, 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, FileUpload, type FileUploadRootProps, 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, Prose, type ProseRootProps, RadioGroup, type RadioGroupItemProps, type RadioGroupRootProps, RangeSlider, type RangeSliderRootProps, type RangeSliderThumbProps, Scroll, type ScrollRootProps, type ScrollViewportProps, SegmentGroup, type SegmentGroupItemProps, type SegmentGroupRootProps, Select, type SelectContentProps, type SelectItemProps, type SelectPositionerProps, type SelectRootProps, Separator, type SeparatorRootProps, Slider, type SliderContextValue, type SliderRootProps, Slot, StatusBanner, type StatusBannerRootProps, type StatusBannerTone, StickyBar, type StickyBarRootProps, Switch, type SwitchRootProps, Tabs, type TabsContentProps, type TabsRootProps, type TabsTriggerProps, Textarea, type TextareaRootProps, ThemeSwitcher, type ThemeSwitcherModeBtnProps, type ThemeSwitcherModesProps, type ThemeSwitcherRootProps, type ThemeSwitcherThemeSelectProps, Thread, type ThreadItemFace, 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, type UseWindowedRangeOptions, asyncStatusToContentState, rowLimits, useAeonMachine, useAppNav, useAppNavMachine, useAppShellContext, useAsyncContext, useAutoGrow, useClipboardStatus, useContentContext, useFieldContext, useFileUploadCtx as useFileUpload, useFitText, useLayoutMode, useScrollContext, useScrollState, useSliderContext, useStickyBarContext, useToast, useToastStore, useWindowedRange };
|
|
1319
|
+
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, Clipboard, type ClipboardIndicatorProps, type ClipboardRootProps, Combobox, type ComboboxItemProps, type ComboboxRootProps, Composer, type ComposerInputProps, 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, FileUpload, type FileUploadRootProps, 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, Prose, type ProseRootProps, RadioGroup, type RadioGroupItemProps, type RadioGroupRootProps, RangeSlider, type RangeSliderRootProps, type RangeSliderThumbProps, Scroll, type ScrollRootProps, type ScrollViewportProps, SegmentGroup, type SegmentGroupItemProps, type SegmentGroupRootProps, Select, type SelectContentProps, type SelectItemProps, type SelectPositionerProps, type SelectRootProps, Separator, type SeparatorRootProps, Slider, type SliderContextValue, type SliderRootProps, Slot, StatusBanner, type StatusBannerRootProps, type StatusBannerTone, StickyBar, type StickyBarRootProps, Switch, type SwitchRootProps, Tabs, type TabsContentProps, type TabsRootProps, type TabsTriggerProps, Textarea, type TextareaRootProps, ThemeSwitcher, type ThemeSwitcherModeBtnProps, type ThemeSwitcherModesProps, type ThemeSwitcherRootProps, type ThemeSwitcherThemeSelectProps, Thread, type ThreadItemFace, 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, type UseWindowedRangeOptions, asyncStatusToContentState, rowLimits, useAeonMachine, useAeonQuery, useAeonSelector, useAppNav, useAppNavMachine, useAppShellContext, useAsyncContext, useAutoGrow, useClipboardStatus, useContentContext, useFieldContext, useFileUploadCtx as useFileUpload, useFitText, useLayoutMode, useScrollContext, useScrollState, useSliderContext, useStickyBarContext, useToast, useToastStore, useWindowedRange };
|
|
@@ -6218,13 +6218,40 @@ var StickyBar = {
|
|
|
6218
6218
|
Seam
|
|
6219
6219
|
};
|
|
6220
6220
|
|
|
6221
|
+
// src/hooks/use-aeon-store.ts
|
|
6222
|
+
import { useEffect as useEffect27, useRef as useRef15, useSyncExternalStore } from "react";
|
|
6223
|
+
import {
|
|
6224
|
+
shallowEqual
|
|
6225
|
+
} from "@aeon-ui/primitives";
|
|
6226
|
+
function useAeonSelector(store, selector, equals = shallowEqual) {
|
|
6227
|
+
const held = useRef15(null);
|
|
6228
|
+
const getSelection = () => {
|
|
6229
|
+
const state = store.getSnapshot();
|
|
6230
|
+
const last = held.current;
|
|
6231
|
+
if (last && last.state === state && last.selector === selector) return last.value;
|
|
6232
|
+
const next = selector(state);
|
|
6233
|
+
const value = last && equals(last.value, next) ? last.value : next;
|
|
6234
|
+
held.current = { state, selector, value };
|
|
6235
|
+
return value;
|
|
6236
|
+
};
|
|
6237
|
+
return useSyncExternalStore(store.subscribe, getSelection, getSelection);
|
|
6238
|
+
}
|
|
6239
|
+
function useAeonQuery(store, slice, query) {
|
|
6240
|
+
const key = typeof query === "string" ? query : JSON.stringify(query);
|
|
6241
|
+
useEffect27(() => {
|
|
6242
|
+
store.send({ type: "QUERY.FETCH", slice, query });
|
|
6243
|
+
}, [store, slice, key]);
|
|
6244
|
+
const read = () => store.query(slice, query);
|
|
6245
|
+
return useSyncExternalStore(store.subscribe, read, read);
|
|
6246
|
+
}
|
|
6247
|
+
|
|
6221
6248
|
// src/hooks/use-layout-mode.ts
|
|
6222
6249
|
import { getCompactMq, layoutCompositionForMode, matchLayoutMode } from "@aeon-ui/core";
|
|
6223
|
-
import { useEffect as
|
|
6250
|
+
import { useEffect as useEffect28, useMemo as useMemo32, useState as useState14 } from "react";
|
|
6224
6251
|
function useLayoutMode(spec) {
|
|
6225
6252
|
const mq = useMemo32(() => getCompactMq(spec), [spec.compactMq]);
|
|
6226
6253
|
const [mode, setMode] = useState14(() => matchLayoutMode(spec, mq));
|
|
6227
|
-
|
|
6254
|
+
useEffect28(() => {
|
|
6228
6255
|
const sync = () => setMode(matchLayoutMode(spec, mq));
|
|
6229
6256
|
sync();
|
|
6230
6257
|
mq.addEventListener("change", sync);
|
|
@@ -6330,6 +6357,8 @@ export {
|
|
|
6330
6357
|
fieldMachine,
|
|
6331
6358
|
rowLimits,
|
|
6332
6359
|
useAeonMachine,
|
|
6360
|
+
useAeonQuery,
|
|
6361
|
+
useAeonSelector,
|
|
6333
6362
|
useAppNav,
|
|
6334
6363
|
useAppNavMachine,
|
|
6335
6364
|
useAppShellContext,
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { useEffect, useRef, useSyncExternalStore } from 'react'
|
|
2
|
+
import {
|
|
3
|
+
shallowEqual,
|
|
4
|
+
type AeonStore,
|
|
5
|
+
type AnySlices,
|
|
6
|
+
type EntityOf,
|
|
7
|
+
type QueryOf,
|
|
8
|
+
type QueryResult,
|
|
9
|
+
type StoreEvent,
|
|
10
|
+
type StoreState,
|
|
11
|
+
} from '@aeon-ui/primitives'
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Reads a slice of an Aeon store. Re-renders only when the selected value
|
|
15
|
+
* changes under `equals` (shallow by default), so a component that selects
|
|
16
|
+
* one entity ignores writes to every other.
|
|
17
|
+
*/
|
|
18
|
+
export function useAeonSelector<S extends AnySlices, T>(
|
|
19
|
+
store: AeonStore<S>,
|
|
20
|
+
selector: (state: StoreState<S>) => T,
|
|
21
|
+
equals: (a: T, b: T) => boolean = shallowEqual,
|
|
22
|
+
): T {
|
|
23
|
+
const held = useRef<{ state: StoreState<S>; selector: (state: StoreState<S>) => T; value: T } | null>(null)
|
|
24
|
+
const getSelection = () => {
|
|
25
|
+
const state = store.getSnapshot()
|
|
26
|
+
const last = held.current
|
|
27
|
+
if (last && last.state === state && last.selector === selector) return last.value
|
|
28
|
+
const next = selector(state)
|
|
29
|
+
const value = last && equals(last.value, next) ? last.value : next
|
|
30
|
+
held.current = { state, selector, value }
|
|
31
|
+
return value
|
|
32
|
+
}
|
|
33
|
+
return useSyncExternalStore(store.subscribe, getSelection, getSelection)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** Fetches a query while mounted and returns its result; the entities stay in the store. */
|
|
37
|
+
export function useAeonQuery<S extends AnySlices, N extends keyof S & string>(
|
|
38
|
+
store: AeonStore<S>,
|
|
39
|
+
slice: N,
|
|
40
|
+
query: QueryOf<S[N]>,
|
|
41
|
+
): QueryResult<EntityOf<S[N]>> {
|
|
42
|
+
const key = typeof query === 'string' ? query : JSON.stringify(query)
|
|
43
|
+
useEffect(() => {
|
|
44
|
+
store.send({ type: 'QUERY.FETCH', slice, query } as StoreEvent<S>)
|
|
45
|
+
// `key` stands for `query`, which callers often rebuild each render.
|
|
46
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
47
|
+
}, [store, slice, key])
|
|
48
|
+
const read = () => store.query(slice, query)
|
|
49
|
+
return useSyncExternalStore(store.subscribe, read, read)
|
|
50
|
+
}
|
|
@@ -44,6 +44,7 @@ export * from './content/index.js'
|
|
|
44
44
|
export * from './nav/index.js'
|
|
45
45
|
export * from './sticky-bar/index.js'
|
|
46
46
|
export { useAeonMachine } from './hooks/use-aeon-machine.js'
|
|
47
|
+
export { useAeonQuery, useAeonSelector } from './hooks/use-aeon-store.js'
|
|
47
48
|
export { useLayoutMode } from './hooks/use-layout-mode.js'
|
|
48
49
|
export { useFitText } from './hooks/use-fit-text.js'
|
|
49
50
|
export { Slot } from './utils/slot.js'
|