@intentface/ui 0.0.0 → 0.7.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/LICENSE +21 -0
- package/README.md +145 -2
- package/dist/ask-user/ask-user.d.ts +104 -0
- package/dist/ask-user/ask-user.js +245 -0
- package/dist/ask-user/index.d.ts +3 -0
- package/dist/ask-user/index.js +3 -0
- package/dist/ask-user/index.parts.d.ts +1 -0
- package/dist/ask-user/index.parts.js +5 -0
- package/dist/attachments/attachments.d.ts +73 -0
- package/dist/attachments/attachments.js +121 -0
- package/dist/attachments/index.d.ts +3 -0
- package/dist/attachments/index.js +3 -0
- package/dist/attachments/index.parts.d.ts +1 -0
- package/dist/attachments/index.parts.js +5 -0
- package/dist/chip/chip.d.ts +45 -0
- package/dist/chip/chip.js +43 -0
- package/dist/chip/index.d.ts +2 -0
- package/dist/chip/index.js +2 -0
- package/dist/chip/index.parts.d.ts +1 -0
- package/dist/chip/index.parts.js +5 -0
- package/dist/chip-markdown.d.ts +25 -0
- package/dist/chip-markdown.js +54 -0
- package/dist/composer/actions.d.ts +35 -0
- package/dist/composer/actions.js +76 -0
- package/dist/composer/ask-user-machine.d.ts +52 -0
- package/dist/composer/ask-user-machine.js +164 -0
- package/dist/composer/attachments-machine.d.ts +34 -0
- package/dist/composer/attachments-machine.js +91 -0
- package/dist/composer/attachments.d.ts +16 -0
- package/dist/composer/attachments.js +32 -0
- package/dist/composer/command-list.d.ts +49 -0
- package/dist/composer/command-list.js +360 -0
- package/dist/composer/commands.d.ts +28 -0
- package/dist/composer/commands.js +56 -0
- package/dist/composer/container.d.ts +3 -0
- package/dist/composer/container.js +32 -0
- package/dist/composer/controller.d.ts +3 -0
- package/dist/composer/controller.js +6 -0
- package/dist/composer/editor-dom.d.ts +57 -0
- package/dist/composer/editor-dom.js +517 -0
- package/dist/composer/fuzzy.d.ts +4 -0
- package/dist/composer/fuzzy.js +49 -0
- package/dist/composer/index.d.ts +25 -0
- package/dist/composer/index.js +13 -0
- package/dist/composer/index.parts.d.ts +11 -0
- package/dist/composer/index.parts.js +15 -0
- package/dist/composer/internals.d.ts +30 -0
- package/dist/composer/internals.js +102 -0
- package/dist/composer/keyboard.d.ts +61 -0
- package/dist/composer/keyboard.js +75 -0
- package/dist/composer/panel.d.ts +28 -0
- package/dist/composer/panel.js +76 -0
- package/dist/composer/placeholder.d.ts +10 -0
- package/dist/composer/placeholder.js +8 -0
- package/dist/composer/popover.d.ts +12 -0
- package/dist/composer/popover.js +62 -0
- package/dist/composer/prefix-detection.d.ts +23 -0
- package/dist/composer/prefix-detection.js +67 -0
- package/dist/composer/root.d.ts +21 -0
- package/dist/composer/root.js +124 -0
- package/dist/composer/segments.d.ts +108 -0
- package/dist/composer/segments.js +366 -0
- package/dist/composer/store.d.ts +98 -0
- package/dist/composer/store.js +457 -0
- package/dist/composer/textarea.d.ts +39 -0
- package/dist/composer/textarea.js +64 -0
- package/dist/composer/trigger-tracker.d.ts +12 -0
- package/dist/composer/trigger-tracker.js +90 -0
- package/dist/composer/types.d.ts +127 -0
- package/dist/composer/types.js +4 -0
- package/dist/composer/use-composer-editor.d.ts +43 -0
- package/dist/composer/use-composer-editor.js +653 -0
- package/dist/generative/catalog.d.ts +177 -0
- package/dist/generative/catalog.js +20 -0
- package/dist/generative/index.d.ts +26 -0
- package/dist/generative/index.js +20 -0
- package/dist/generative/json-schema.d.ts +45 -0
- package/dist/generative/json-schema.js +216 -0
- package/dist/generative/markdown.d.ts +21 -0
- package/dist/generative/markdown.js +76 -0
- package/dist/generative/tree.d.ts +56 -0
- package/dist/generative/tree.js +365 -0
- package/dist/generative/use-tree.d.ts +12 -0
- package/dist/generative/use-tree.js +64 -0
- package/dist/internal/change-event-details.d.ts +12 -0
- package/dist/internal/change-event-details.js +16 -0
- package/dist/internal/collapsible.d.ts +22 -0
- package/dist/internal/collapsible.js +94 -0
- package/dist/internal/collection.d.ts +32 -0
- package/dist/internal/collection.js +72 -0
- package/dist/internal/iso-layout-effect.d.ts +2 -0
- package/dist/internal/iso-layout-effect.js +6 -0
- package/dist/internal/portal.d.ts +6 -0
- package/dist/internal/portal.js +18 -0
- package/dist/internal/primitive-props.d.ts +4 -0
- package/dist/internal/primitive-props.js +3 -0
- package/dist/internal/render/baseTypes.d.ts +18 -0
- package/dist/internal/render/baseTypes.js +4 -0
- package/dist/internal/render/empty.d.ts +3 -0
- package/dist/internal/render/empty.js +5 -0
- package/dist/internal/render/getReactElementRef.d.ts +5 -0
- package/dist/internal/render/getReactElementRef.js +15 -0
- package/dist/internal/render/getStateAttributesProps.d.ts +4 -0
- package/dist/internal/render/getStateAttributesProps.js +23 -0
- package/dist/internal/render/mergeObjects.d.ts +1 -0
- package/dist/internal/render/mergeObjects.js +14 -0
- package/dist/internal/render/mergeProps.d.ts +55 -0
- package/dist/internal/render/mergeProps.js +183 -0
- package/dist/internal/render/positioning.d.ts +33 -0
- package/dist/internal/render/positioning.js +112 -0
- package/dist/internal/render/reactVersion.d.ts +3 -0
- package/dist/internal/render/reactVersion.js +7 -0
- package/dist/internal/render/resolveClassName.d.ts +8 -0
- package/dist/internal/render/resolveClassName.js +12 -0
- package/dist/internal/render/resolveStyle.d.ts +8 -0
- package/dist/internal/render/resolveStyle.js +12 -0
- package/dist/internal/render/transition.d.ts +47 -0
- package/dist/internal/render/transition.js +259 -0
- package/dist/internal/render/types.d.ts +74 -0
- package/dist/internal/render/types.js +3 -0
- package/dist/internal/render/useMergedRefs.d.ts +21 -0
- package/dist/internal/render/useMergedRefs.js +102 -0
- package/dist/internal/render/useRefWithInit.d.ts +10 -0
- package/dist/internal/render/useRefWithInit.js +12 -0
- package/dist/internal/render/useRender.d.ts +71 -0
- package/dist/internal/render/useRender.js +12 -0
- package/dist/internal/render/useRenderElement.d.ts +62 -0
- package/dist/internal/render/useRenderElement.js +157 -0
- package/dist/internal/render/warn.d.ts +1 -0
- package/dist/internal/render/warn.js +15 -0
- package/dist/internal/safe-polygon.d.ts +21 -0
- package/dist/internal/safe-polygon.js +179 -0
- package/dist/internal/scroll-into-view-within.d.ts +1 -0
- package/dist/internal/scroll-into-view-within.js +26 -0
- package/dist/internal/standard-schema.d.ts +38 -0
- package/dist/internal/standard-schema.js +4 -0
- package/dist/internal/state-mappings.d.ts +8 -0
- package/dist/internal/state-mappings.js +17 -0
- package/dist/internal/use-controlled.d.ts +19 -0
- package/dist/internal/use-controlled.js +33 -0
- package/dist/message/index.d.ts +3 -0
- package/dist/message/index.js +3 -0
- package/dist/message/index.parts.d.ts +1 -0
- package/dist/message/index.parts.js +5 -0
- package/dist/message/message.d.ts +58 -0
- package/dist/message/message.js +93 -0
- package/dist/message-utils.d.ts +55 -0
- package/dist/message-utils.js +79 -0
- package/dist/nav/index.d.ts +4 -0
- package/dist/nav/index.js +5 -0
- package/dist/nav/index.parts.d.ts +3 -0
- package/dist/nav/index.parts.js +7 -0
- package/dist/nav/nav.d.ts +152 -0
- package/dist/nav/nav.js +660 -0
- package/dist/nav/store.d.ts +50 -0
- package/dist/nav/store.js +95 -0
- package/dist/reasoning/index.d.ts +3 -0
- package/dist/reasoning/index.js +3 -0
- package/dist/reasoning/index.parts.d.ts +1 -0
- package/dist/reasoning/index.parts.js +5 -0
- package/dist/reasoning/reasoning.d.ts +38 -0
- package/dist/reasoning/reasoning.js +67 -0
- package/dist/shell/index.d.ts +5 -0
- package/dist/shell/index.js +5 -0
- package/dist/shell/index.parts.d.ts +3 -0
- package/dist/shell/index.parts.js +7 -0
- package/dist/shell/shell.d.ts +108 -0
- package/dist/shell/shell.js +390 -0
- package/dist/shell/store.d.ts +112 -0
- package/dist/shell/store.js +134 -0
- package/dist/steps/index.d.ts +2 -0
- package/dist/steps/index.js +2 -0
- package/dist/steps/index.parts.d.ts +1 -0
- package/dist/steps/index.parts.js +5 -0
- package/dist/steps/steps.d.ts +90 -0
- package/dist/steps/steps.js +116 -0
- package/dist/tabs/anchored.d.ts +59 -0
- package/dist/tabs/anchored.js +109 -0
- package/dist/tabs/hover.d.ts +33 -0
- package/dist/tabs/hover.js +169 -0
- package/dist/tabs/index.d.ts +5 -0
- package/dist/tabs/index.js +4 -0
- package/dist/tabs/index.parts.d.ts +4 -0
- package/dist/tabs/index.parts.js +8 -0
- package/dist/tabs/store.d.ts +131 -0
- package/dist/tabs/store.js +248 -0
- package/dist/tabs/tabs.d.ts +217 -0
- package/dist/tabs/tabs.js +458 -0
- package/dist/thread/geometry.d.ts +23 -0
- package/dist/thread/geometry.js +48 -0
- package/dist/thread/index.d.ts +4 -0
- package/dist/thread/index.js +3 -0
- package/dist/thread/index.parts.d.ts +1 -0
- package/dist/thread/index.parts.js +5 -0
- package/dist/thread/stores.d.ts +21 -0
- package/dist/thread/stores.js +63 -0
- package/dist/thread/thread.d.ts +57 -0
- package/dist/thread/thread.js +663 -0
- package/dist/types.d.ts +58 -0
- package/dist/types.js +17 -0
- package/package.json +120 -4
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { type RefObject } from "react";
|
|
2
|
+
export type NavState = {
|
|
3
|
+
/** Which groups are open, by value. */
|
|
4
|
+
expanded: ReadonlySet<string>;
|
|
5
|
+
toggle: (value: string) => void;
|
|
6
|
+
setOpen: (value: string, open: boolean) => void;
|
|
7
|
+
setExpanded: (expanded: Iterable<string>) => void;
|
|
8
|
+
};
|
|
9
|
+
export type NavStore = {
|
|
10
|
+
subscribe: (listener: () => void) => () => void;
|
|
11
|
+
getSnapshot: () => NavState;
|
|
12
|
+
/**
|
|
13
|
+
* Adopt state the Root owns rather than the store.
|
|
14
|
+
*
|
|
15
|
+
* Silent by default, because the seeding call happens *during render* and a
|
|
16
|
+
* handle you created yourself may already have subscribers — notifying there
|
|
17
|
+
* would update a mounted component mid-render. Pass `notify` from a layout
|
|
18
|
+
* effect, where it is safe and necessary: without it a memoised subtree never
|
|
19
|
+
* re-renders and so never learns a controlled value changed.
|
|
20
|
+
*/
|
|
21
|
+
hydrate: (state: {
|
|
22
|
+
expanded?: string[];
|
|
23
|
+
}, options?: {
|
|
24
|
+
notify?: boolean;
|
|
25
|
+
}) => void;
|
|
26
|
+
controlledRef: RefObject<boolean>;
|
|
27
|
+
onExpandedChangeRef: RefObject<((expanded: string[]) => void) | null>;
|
|
28
|
+
/** Route a change through the controlled/uncontrolled decision and persistence. */
|
|
29
|
+
commitExpanded: (expanded: ReadonlySet<string>) => void;
|
|
30
|
+
/** The Root's element. Keyboard navigation reads row order off the DOM. */
|
|
31
|
+
rootRef: RefObject<HTMLElement | null>;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* A plain closure store read through `useSyncExternalStore` — not React state
|
|
35
|
+
* and not Zustand. Takes no arguments: everything configurable arrives from
|
|
36
|
+
* `Nav.Root` as props, so a handle created at module scope cannot disagree
|
|
37
|
+
* with the tree that later adopts it.
|
|
38
|
+
*/
|
|
39
|
+
export declare const createNavStore: () => NavStore;
|
|
40
|
+
export declare const NavStoreContext: import("react").Context<NavStore | null>;
|
|
41
|
+
/** Internal: parts resolve the store their Nav.Root provided. */
|
|
42
|
+
export declare const useNavContextStore: () => NavStore;
|
|
43
|
+
/** Subscribe to an explicit `Nav.createStore()` handle, from outside the tree. */
|
|
44
|
+
export declare const useNavStore: <Selected = NavState>(store: NavStore, selector?: (nav: NavState) => Selected) => Selected;
|
|
45
|
+
/**
|
|
46
|
+
* Subscribe from inside the tree. Select a primitive — a boolean, an id — so
|
|
47
|
+
* the subscription can settle; a selector building a fresh Set on every call
|
|
48
|
+
* never will.
|
|
49
|
+
*/
|
|
50
|
+
export declare const useNav: <Selected = NavState>(selector?: (nav: NavState) => Selected) => Selected;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { createContext, use, useSyncExternalStore } from "react";
|
|
3
|
+
const sameSet = (a, b) => a.size === b.size && [...a].every((value) => b.has(value));
|
|
4
|
+
/**
|
|
5
|
+
* A plain closure store read through `useSyncExternalStore` — not React state
|
|
6
|
+
* and not Zustand. Takes no arguments: everything configurable arrives from
|
|
7
|
+
* `Nav.Root` as props, so a handle created at module scope cannot disagree
|
|
8
|
+
* with the tree that later adopts it.
|
|
9
|
+
*/
|
|
10
|
+
export const createNavStore = () => {
|
|
11
|
+
const listeners = new Set();
|
|
12
|
+
const notify = () => {
|
|
13
|
+
for (const listener of listeners)
|
|
14
|
+
listener();
|
|
15
|
+
};
|
|
16
|
+
const controlledRef = { current: false };
|
|
17
|
+
const onExpandedChangeRef = { current: null };
|
|
18
|
+
const rootRef = { current: null };
|
|
19
|
+
let snapshot;
|
|
20
|
+
const commitExpanded = (expanded) => {
|
|
21
|
+
if (sameSet(snapshot.expanded, expanded))
|
|
22
|
+
return;
|
|
23
|
+
const list = [...expanded];
|
|
24
|
+
onExpandedChangeRef.current?.(list);
|
|
25
|
+
// A controlled Root owns the value: it comes back as a prop or it does not
|
|
26
|
+
// change at all. Writing it here too would let the two disagree.
|
|
27
|
+
if (!controlledRef.current) {
|
|
28
|
+
snapshot = { ...snapshot, expanded };
|
|
29
|
+
notify();
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
const setOpen = (value, open) => {
|
|
33
|
+
const next = new Set(snapshot.expanded);
|
|
34
|
+
if (open)
|
|
35
|
+
next.add(value);
|
|
36
|
+
else
|
|
37
|
+
next.delete(value);
|
|
38
|
+
commitExpanded(next);
|
|
39
|
+
};
|
|
40
|
+
snapshot = {
|
|
41
|
+
expanded: new Set(),
|
|
42
|
+
toggle: (value) => setOpen(value, !snapshot.expanded.has(value)),
|
|
43
|
+
setOpen,
|
|
44
|
+
setExpanded: (expanded) => commitExpanded(new Set(expanded)),
|
|
45
|
+
};
|
|
46
|
+
return {
|
|
47
|
+
subscribe: (listener) => {
|
|
48
|
+
listeners.add(listener);
|
|
49
|
+
return () => {
|
|
50
|
+
listeners.delete(listener);
|
|
51
|
+
};
|
|
52
|
+
},
|
|
53
|
+
getSnapshot: () => snapshot,
|
|
54
|
+
hydrate: ({ expanded }, { notify: shouldNotify = false } = {}) => {
|
|
55
|
+
if (!expanded)
|
|
56
|
+
return;
|
|
57
|
+
const next = new Set(expanded);
|
|
58
|
+
if (shouldNotify && sameSet(snapshot.expanded, next))
|
|
59
|
+
return;
|
|
60
|
+
snapshot = { ...snapshot, expanded: next };
|
|
61
|
+
if (shouldNotify)
|
|
62
|
+
notify();
|
|
63
|
+
},
|
|
64
|
+
controlledRef,
|
|
65
|
+
onExpandedChangeRef,
|
|
66
|
+
commitExpanded,
|
|
67
|
+
rootRef,
|
|
68
|
+
};
|
|
69
|
+
};
|
|
70
|
+
// ---------------------------------------------------------------------------
|
|
71
|
+
// Instance resolution — the nearest Nav.Root, explicitly.
|
|
72
|
+
// ---------------------------------------------------------------------------
|
|
73
|
+
export const NavStoreContext = createContext(null);
|
|
74
|
+
/** Internal: parts resolve the store their Nav.Root provided. */
|
|
75
|
+
export const useNavContextStore = () => {
|
|
76
|
+
const store = use(NavStoreContext);
|
|
77
|
+
if (!store)
|
|
78
|
+
throw new Error("Nav parts must be used within <Nav.Root>");
|
|
79
|
+
return store;
|
|
80
|
+
};
|
|
81
|
+
/** Subscribe to an explicit `Nav.createStore()` handle, from outside the tree. */
|
|
82
|
+
export const useNavStore = (store, selector) => {
|
|
83
|
+
const getValue = () => {
|
|
84
|
+
const state = store.getSnapshot();
|
|
85
|
+
// Safe: without a selector, Selected defaults to NavState.
|
|
86
|
+
return selector ? selector(state) : state;
|
|
87
|
+
};
|
|
88
|
+
return useSyncExternalStore(store.subscribe, getValue, getValue);
|
|
89
|
+
};
|
|
90
|
+
/**
|
|
91
|
+
* Subscribe from inside the tree. Select a primitive — a boolean, an id — so
|
|
92
|
+
* the subscription can settle; a selector building a fresh Set on every call
|
|
93
|
+
* never will.
|
|
94
|
+
*/
|
|
95
|
+
export const useNav = (selector) => useNavStore(useNavContextStore(), selector);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { ReasoningContent as Content, ReasoningRoot as Root, ReasoningTrigger as Trigger, } from "./reasoning.js";
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
// Part names for the `Reasoning` namespace. Deliberately carries no
|
|
2
|
+
// "use client" directive: this module and index.ts must stay server-resolvable
|
|
3
|
+
// so a React Server Component can reach Reasoning.Root and its siblings
|
|
4
|
+
// through them. The directive lives one level down, on reasoning.tsx.
|
|
5
|
+
export { ReasoningContent as Content, ReasoningRoot as Root, ReasoningTrigger as Trigger, } from "./reasoning.js";
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { type ComponentProps } from "react";
|
|
2
|
+
import { Collapsible } from "../internal/collapsible.js";
|
|
3
|
+
type ReasoningContextValue = {
|
|
4
|
+
isStreaming: boolean;
|
|
5
|
+
isOpen: boolean;
|
|
6
|
+
setIsOpen: (open: boolean) => void;
|
|
7
|
+
duration: number | undefined;
|
|
8
|
+
};
|
|
9
|
+
export declare const useReasoning: () => ReasoningContextValue;
|
|
10
|
+
export type ReasoningRootProps = Omit<ComponentProps<typeof Collapsible>, "onOpenChange"> & {
|
|
11
|
+
isStreaming?: boolean;
|
|
12
|
+
duration?: number;
|
|
13
|
+
onOpenChange?: (open: boolean) => void;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* The disclosure root. Tracks how long `isStreaming` stayed true and hands the
|
|
17
|
+
* elapsed seconds back through `useReasoning`, so a label can change without
|
|
18
|
+
* the consumer timing anything.
|
|
19
|
+
* Renders a `<div>` element.
|
|
20
|
+
*/
|
|
21
|
+
export declare const ReasoningRoot: import("react").MemoExoticComponent<({ isStreaming, open: controlledOpen, defaultOpen, onOpenChange, duration: durationProp, children, ...props }: ReasoningRootProps) => import("react").JSX.Element>;
|
|
22
|
+
export type ReasoningTriggerProps = ComponentProps<typeof Collapsible.Trigger>;
|
|
23
|
+
/**
|
|
24
|
+
* The toggle. Ships no copy: supply the label as children, and read
|
|
25
|
+
* `isStreaming` and `duration` from `useReasoning` if it should change while
|
|
26
|
+
* the model is thinking.
|
|
27
|
+
* Renders a `<button>` element.
|
|
28
|
+
*/
|
|
29
|
+
export declare const ReasoningTrigger: (props: ReasoningTriggerProps) => import("react").JSX.Element;
|
|
30
|
+
export type ReasoningContentProps = ComponentProps<typeof Collapsible.Panel>;
|
|
31
|
+
/**
|
|
32
|
+
* The collapsible panel. Publishes its measured height while a transition runs
|
|
33
|
+
* and releases it once settled open, so a panel that is open keeps growing as
|
|
34
|
+
* text streams in.
|
|
35
|
+
* Renders a `<div>` element.
|
|
36
|
+
*/
|
|
37
|
+
export declare const ReasoningContent: (props: ReasoningContentProps) => import("react").JSX.Element;
|
|
38
|
+
export {};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
// Headless reasoning disclosure. Owns the open state and the streaming
|
|
4
|
+
// duration tracking; exposes them via useReasoning() so the styled layer can
|
|
5
|
+
// render its own trigger label (shimmer, crossfade) and markdown content.
|
|
6
|
+
import { createContext, memo, use, useCallback, useEffect, useMemo, useRef, useState, } from "react";
|
|
7
|
+
import { Collapsible } from "../internal/collapsible.js";
|
|
8
|
+
const MS_IN_S = 1000;
|
|
9
|
+
const ReasoningContext = createContext(null);
|
|
10
|
+
export const useReasoning = () => {
|
|
11
|
+
const context = use(ReasoningContext);
|
|
12
|
+
if (!context) {
|
|
13
|
+
throw new Error("Reasoning components must be used within Reasoning");
|
|
14
|
+
}
|
|
15
|
+
return context;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* The disclosure root. Tracks how long `isStreaming` stayed true and hands the
|
|
19
|
+
* elapsed seconds back through `useReasoning`, so a label can change without
|
|
20
|
+
* the consumer timing anything.
|
|
21
|
+
* Renders a `<div>` element.
|
|
22
|
+
*/
|
|
23
|
+
export const ReasoningRoot = memo(({ isStreaming = false, open: controlledOpen, defaultOpen, onOpenChange, duration: durationProp, children, ...props }) => {
|
|
24
|
+
const resolvedDefaultOpen = defaultOpen ?? false;
|
|
25
|
+
const [internalOpen, setInternalOpen] = useState(resolvedDefaultOpen);
|
|
26
|
+
const isControlled = controlledOpen !== undefined;
|
|
27
|
+
const isOpen = isControlled ? controlledOpen : internalOpen;
|
|
28
|
+
const [duration, setDuration] = useState(durationProp);
|
|
29
|
+
const hasEverStreamedRef = useRef(isStreaming);
|
|
30
|
+
const startTimeRef = useRef(null);
|
|
31
|
+
const setIsOpen = useCallback((value) => {
|
|
32
|
+
if (!isControlled) {
|
|
33
|
+
setInternalOpen(value);
|
|
34
|
+
}
|
|
35
|
+
onOpenChange?.(value);
|
|
36
|
+
}, [isControlled, onOpenChange]);
|
|
37
|
+
// Track when streaming starts and compute duration
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
if (isStreaming) {
|
|
40
|
+
hasEverStreamedRef.current = true;
|
|
41
|
+
if (startTimeRef.current === null) {
|
|
42
|
+
startTimeRef.current = Date.now();
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
else if (startTimeRef.current !== null) {
|
|
46
|
+
setDuration(Math.ceil((Date.now() - startTimeRef.current) / MS_IN_S));
|
|
47
|
+
startTimeRef.current = null;
|
|
48
|
+
}
|
|
49
|
+
}, [isStreaming]);
|
|
50
|
+
const contextValue = useMemo(() => ({ duration, isOpen, isStreaming, setIsOpen }), [duration, isOpen, isStreaming, setIsOpen]);
|
|
51
|
+
return (_jsx(ReasoningContext, { value: contextValue, children: _jsx(Collapsible, { open: isOpen, onOpenChange: (open) => setIsOpen(open), "aria-busy": isStreaming || undefined, "data-reasoning": "", "data-streaming": isStreaming ? "" : undefined, ...props, children: children }) }));
|
|
52
|
+
});
|
|
53
|
+
ReasoningRoot.displayName = "Reasoning";
|
|
54
|
+
/**
|
|
55
|
+
* The toggle. Ships no copy: supply the label as children, and read
|
|
56
|
+
* `isStreaming` and `duration` from `useReasoning` if it should change while
|
|
57
|
+
* the model is thinking.
|
|
58
|
+
* Renders a `<button>` element.
|
|
59
|
+
*/
|
|
60
|
+
export const ReasoningTrigger = (props) => (_jsx(Collapsible.Trigger, { "data-reasoning-trigger": "", ...props }));
|
|
61
|
+
/**
|
|
62
|
+
* The collapsible panel. Publishes its measured height while a transition runs
|
|
63
|
+
* and releases it once settled open, so a panel that is open keeps growing as
|
|
64
|
+
* text streams in.
|
|
65
|
+
* Renders a `<div>` element.
|
|
66
|
+
*/
|
|
67
|
+
export const ReasoningContent = (props) => (_jsx(Collapsible.Panel, { "data-reasoning-content": "", ...props }));
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export * as Shell from "./index.parts.js";
|
|
2
|
+
export type { ShellGripProps, ShellHotspotProps, ShellPartState, ShellRootProps, ShellSidebarProps, ShellSidebarState, ShellTriggerProps, ShellViewportProps, } from "./shell.js";
|
|
3
|
+
export { SHELL_SIDEBAR_WIDTH_VAR } from "./shell.js";
|
|
4
|
+
export type { ShellState, ShellStore } from "./store.js";
|
|
5
|
+
export { useShell, useShellStore } from "./store.js";
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
// Public surface of @intentface/ui/shell: the `Shell` namespace plus the store. No "use client" directive here — see
|
|
2
|
+
// index.parts.ts.
|
|
3
|
+
export * as Shell from "./index.parts.js";
|
|
4
|
+
export { SHELL_SIDEBAR_WIDTH_VAR } from "./shell.js";
|
|
5
|
+
export { useShell, useShellStore } from "./store.js";
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { ShellGrip as Grip, ShellHotspot as Hotspot, ShellRoot as Root, ShellSidebar as Sidebar, ShellTrigger as Trigger, ShellViewport as Viewport, } from "./shell.js";
|
|
2
|
+
/** Create a standalone store handle: `<Shell.Root store={…}>` plus `useShellStore(store, selector)` for reading it from outside the tree. */
|
|
3
|
+
export { createShellStore as createStore } from "./store.js";
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// Part names for the `Shell` namespace. Deliberately carries no "use client"
|
|
2
|
+
// directive: this module and index.ts must stay server-resolvable so a React
|
|
3
|
+
// Server Component can reach Shell.Root and its siblings through them. Each
|
|
4
|
+
// part module carries the directive itself.
|
|
5
|
+
export { ShellGrip as Grip, ShellHotspot as Hotspot, ShellRoot as Root, ShellSidebar as Sidebar, ShellTrigger as Trigger, ShellViewport as Viewport, } from "./shell.js";
|
|
6
|
+
/** Create a standalone store handle: `<Shell.Root store={…}>` plus `useShellStore(store, selector)` for reading it from outside the tree. */
|
|
7
|
+
export { createShellStore as createStore } from "./store.js";
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
import type { PrimitiveProps } from "../internal/primitive-props.js";
|
|
3
|
+
import type { ShellStore } from "./store.js";
|
|
4
|
+
/**
|
|
5
|
+
* The shell: a sidebar that collapses, floats out on hover, and can be dragged
|
|
6
|
+
* wider, next to the viewport it shares the screen with.
|
|
7
|
+
*
|
|
8
|
+
* The package ships no CSS. Parts publish their state as `data-*` attributes
|
|
9
|
+
* and the sidebar's measured width as a custom property; sizing, collapsing
|
|
10
|
+
* geometry and transitions are all yours. In particular **the sidebar's width
|
|
11
|
+
* and the range it may be dragged through are CSS**:
|
|
12
|
+
*
|
|
13
|
+
* [data-shell-sidebar] {
|
|
14
|
+
* width: var(--shell-sidebar-width, 240px);
|
|
15
|
+
* min-width: 200px;
|
|
16
|
+
* max-width: 400px;
|
|
17
|
+
* }
|
|
18
|
+
*
|
|
19
|
+
* The drag writes that custom property, the browser clamps it against your
|
|
20
|
+
* `min-width` / `max-width`, and the sidebar reports back whatever the browser
|
|
21
|
+
* settled on. Nothing here second-guesses your stylesheet.
|
|
22
|
+
*
|
|
23
|
+
* No global key binding either. `Shell.Trigger` is the click affordance; a
|
|
24
|
+
* Cmd/Ctrl+B — or whatever your app's shortcut registry says — is four lines
|
|
25
|
+
* around `useShell((shell) => shell.toggle)`, and a package has no business
|
|
26
|
+
* claiming a window-level `keydown` for a key it cannot know is free.
|
|
27
|
+
*/
|
|
28
|
+
/** Written by the grip; read by your `width`. */
|
|
29
|
+
export declare const SHELL_SIDEBAR_WIDTH_VAR = "--shell-sidebar-width";
|
|
30
|
+
export type ShellPartState = {
|
|
31
|
+
state: "expanded" | "collapsed";
|
|
32
|
+
hotspot: boolean;
|
|
33
|
+
resizing: boolean;
|
|
34
|
+
};
|
|
35
|
+
export type ShellSidebarState = ShellPartState & {
|
|
36
|
+
side: "left" | "right";
|
|
37
|
+
};
|
|
38
|
+
export type ShellRootProps = PrimitiveProps<"div", ShellPartState> & {
|
|
39
|
+
/**
|
|
40
|
+
* Where the sidebar starts when nothing controls it. Read it from the
|
|
41
|
+
* request on the server, if you persist it, so the first paint is already
|
|
42
|
+
* right rather than snapping a frame later. Nothing here reads storage —
|
|
43
|
+
* see `onOpenChange` for the other half.
|
|
44
|
+
*/
|
|
45
|
+
defaultOpen?: boolean;
|
|
46
|
+
open?: boolean;
|
|
47
|
+
onOpenChange?: (open: boolean) => void;
|
|
48
|
+
/**
|
|
49
|
+
* An explicit `Shell.createStore()` handle, for when the state has to be
|
|
50
|
+
* reachable from outside this tree. Must be stable for the Root's lifetime.
|
|
51
|
+
*/
|
|
52
|
+
store?: ShellStore;
|
|
53
|
+
children?: ReactNode;
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* The provider and container. Holds the store every other part reads, so
|
|
57
|
+
* `defaultOpen` and the width must arrive here rather than on a child.
|
|
58
|
+
* Renders a `<div>` element.
|
|
59
|
+
*/
|
|
60
|
+
export declare const ShellRoot: ({ defaultOpen, open, onOpenChange, store: storeProp, className, render, style, ...elementProps }: ShellRootProps) => import("react").JSX.Element;
|
|
61
|
+
export type ShellSidebarProps = PrimitiveProps<"div", ShellSidebarState> & {
|
|
62
|
+
side?: "left" | "right";
|
|
63
|
+
/**
|
|
64
|
+
* The panel's settled width, in pixels — fired once a drag ends, never per
|
|
65
|
+
* frame, and whenever anything else resizes it. Persist it if you want it
|
|
66
|
+
* remembered, and restore it as the custom property rather than as a prop:
|
|
67
|
+
* the width is CSS's, and this is only the measurement coming back.
|
|
68
|
+
*/
|
|
69
|
+
onResize?: (width: number) => void;
|
|
70
|
+
};
|
|
71
|
+
/**
|
|
72
|
+
* The panel, and the element whose width is measured and reported back.
|
|
73
|
+
* Carries the `id` the trigger's `aria-controls` points at.
|
|
74
|
+
* Renders a `<div>` element.
|
|
75
|
+
*/
|
|
76
|
+
export declare const ShellSidebar: ({ side, onResize, className, render, style, ...elementProps }: ShellSidebarProps) => import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
|
|
77
|
+
export type ShellViewportProps = PrimitiveProps<"div", ShellPartState>;
|
|
78
|
+
/**
|
|
79
|
+
* The content area beside the sidebar. Carries the same state attributes as
|
|
80
|
+
* the root, so it can react to the sidebar without a group selector.
|
|
81
|
+
* Renders a `<div>` element.
|
|
82
|
+
*/
|
|
83
|
+
export declare const ShellViewport: ({ className, render, style, ...elementProps }: ShellViewportProps) => import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
|
|
84
|
+
export type ShellHotspotProps = PrimitiveProps<"div", ShellPartState>;
|
|
85
|
+
/**
|
|
86
|
+
* The strip along the screen edge that floats a collapsed sidebar out on
|
|
87
|
+
* hover. Give it a width and a position in CSS. Omitting it is how you opt out
|
|
88
|
+
* of hotspot entirely — there is no prop to turn it off, because not rendering it
|
|
89
|
+
* already says that.
|
|
90
|
+
*/
|
|
91
|
+
export declare const ShellHotspot: ({ className, render, style, ...elementProps }: ShellHotspotProps) => import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
|
|
92
|
+
export type ShellTriggerProps = PrimitiveProps<"button", ShellPartState>;
|
|
93
|
+
/**
|
|
94
|
+
* Toggles the sidebar, and pins a floated-out one open rather than closing it.
|
|
95
|
+
* Ships no copy — supply the label as children.
|
|
96
|
+
* Renders a `<button>` element.
|
|
97
|
+
*/
|
|
98
|
+
export declare const ShellTrigger: ({ className, render, style, ...elementProps }: ShellTriggerProps) => import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
|
|
99
|
+
export type ShellGripProps = PrimitiveProps<"div", ShellPartState> & {
|
|
100
|
+
/** Pixels moved per arrow-key press. */
|
|
101
|
+
step?: number;
|
|
102
|
+
};
|
|
103
|
+
/**
|
|
104
|
+
* The drag affordance. Give it a width and a cursor in CSS; the drag range
|
|
105
|
+
* comes from the sidebar's own `min-width` and `max-width`.
|
|
106
|
+
* Renders a `<div>` element with `role="separator"`.
|
|
107
|
+
*/
|
|
108
|
+
export declare const ShellGrip: ({ step, className, render, style, ...elementProps }: ShellGripProps) => import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
|