@intentface/chat 0.1.0 → 0.1.2
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/README.md +6 -6
- package/dist/chip-markdown.js +3 -1
- package/dist/composer/prefix-detection.js +14 -5
- package/dist/internal/render/getReactElementRef.js +1 -1
- package/dist/internal/render/mergeProps.d.ts +1 -1
- package/dist/internal/render/mergeProps.js +1 -1
- package/dist/internal/render/types.d.ts +1 -1
- package/dist/internal/render/useMergedRefs.js +1 -1
- package/dist/internal/render/useRender.d.ts +3 -3
- package/dist/internal/render/useRender.js +1 -1
- package/dist/internal/render/useRenderElement.d.ts +3 -3
- package/dist/internal/render/useRenderElement.js +9 -9
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# @intentface/chat
|
|
2
2
|
|
|
3
3
|
Headless chat UI primitives for React — the behavior, state, and wire formats
|
|
4
|
-
for building AI chat interfaces, with no styling of their own.
|
|
5
|
-
the shadcn-style styled layer from the [docs](https://intentface.dev/docs), or
|
|
6
|
-
bring your own.
|
|
4
|
+
for building AI chat interfaces, with no styling of their own.
|
|
7
5
|
|
|
8
|
-
This is the Base UI model applied to chat: **
|
|
9
|
-
|
|
6
|
+
This is the Base UI model applied to chat: **the package owns behavior, you own
|
|
7
|
+
every class.** There is no pre-styled `@intentface/chat` package. The demos on
|
|
8
|
+
each [docs](https://intentface.dev/docs) page show how the parts fit together
|
|
9
|
+
and are meant to be copied and restyled.
|
|
10
10
|
|
|
11
11
|
## Status
|
|
12
12
|
|
|
@@ -100,7 +100,7 @@ directive and import fine anywhere.
|
|
|
100
100
|
|
|
101
101
|
## Docs
|
|
102
102
|
|
|
103
|
-
Full guides, live
|
|
103
|
+
Full guides, live demos, and the API reference at
|
|
104
104
|
[intentface.dev/docs](https://intentface.dev/docs).
|
|
105
105
|
|
|
106
106
|
## License
|
package/dist/chip-markdown.js
CHANGED
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
// token, so a rendered message reconstructs the chip from its own text
|
|
4
4
|
// alone — no sidecar metadata array. Presentation that's derivable at render
|
|
5
5
|
// time (e.g. a per-prefix variant) is the renderer's job, not wire data.
|
|
6
|
-
|
|
6
|
+
// Every class excludes "[" so no group can consume past the next one — without
|
|
7
|
+
// that this backtracks quadratically, and message text is untrusted.
|
|
8
|
+
export const CHIP_REF_PATTERN = /\[([^[\]]+)\]\(chip:([^[:)]+):([^[)?]+)(?:\?([^[)]*))?\)/g;
|
|
7
9
|
export const escapeMarkdownLink = (input) => input.replace(/[[\]()\\]/g, (match) => `\\${match}`);
|
|
8
10
|
// Tolerate legacy/un-encoded values — a stray "%" would otherwise throw and
|
|
9
11
|
// take the whole message render down with it.
|
|
@@ -2,6 +2,11 @@
|
|
|
2
2
|
// active-token state shape and the pure scan that derives it from the text
|
|
3
3
|
// around the caret. Sticky range tracking and dismissal memory live one layer
|
|
4
4
|
// up, in trigger-tracker.ts.
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
6
|
+
// Types & constants
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
// Non-global: `.test` on a global regex advances lastIndex between calls.
|
|
9
|
+
const WHITESPACE = /\s/;
|
|
5
10
|
export const CLOSED_COMMAND_STATE = {
|
|
6
11
|
isOpen: false,
|
|
7
12
|
trigger: null,
|
|
@@ -34,16 +39,20 @@ export const detectActivePrefix = (args) => {
|
|
|
34
39
|
// taken from both sides of the caret so it stays whole as the caret moves
|
|
35
40
|
// within it. Text chars map 1:1 to positions and an atomic chip can never
|
|
36
41
|
// sit inside a run, so the run length is the position delta on each side.
|
|
37
|
-
|
|
42
|
+
// Scanned backwards, not /\S*$/ — that backtracks quadratically when the
|
|
43
|
+
// text ends in whitespace, on a path that runs per keystroke.
|
|
44
|
+
let runStart = textBeforeCursor.length;
|
|
45
|
+
while (runStart > 0 && !WHITESPACE.test(textBeforeCursor[runStart - 1]))
|
|
46
|
+
runStart--;
|
|
47
|
+
const leftRun = textBeforeCursor.slice(runStart);
|
|
48
|
+
// Start-anchored, so this one cannot backtrack.
|
|
38
49
|
const rightRun = textAfterCursor.match(/^\S*/)?.[0] ?? "";
|
|
39
50
|
const runText = leftRun + rightRun;
|
|
40
51
|
if (!runText.startsWith(entry.prefix))
|
|
41
52
|
continue;
|
|
42
53
|
// The prefix must sit at a word boundary: line start or after whitespace.
|
|
43
|
-
const charBeforeRun = textBeforeCursor
|
|
44
|
-
|
|
45
|
-
.at(-1);
|
|
46
|
-
if (charBeforeRun !== undefined && !/\s/.test(charBeforeRun))
|
|
54
|
+
const charBeforeRun = runStart > 0 ? textBeforeCursor[runStart - 1] : undefined;
|
|
55
|
+
if (charBeforeRun !== undefined && !WHITESPACE.test(charBeforeRun))
|
|
47
56
|
continue;
|
|
48
57
|
return {
|
|
49
58
|
isOpen: true,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Vendored from @base-ui/utils v1.6.0 (MIT) — packages/utils/src/getReactElementRef.ts
|
|
2
2
|
// https://github.com/mui/base-ui — exact copy.
|
|
3
3
|
import * as React from 'react';
|
|
4
|
-
import { isReactVersionAtLeast } from './reactVersion';
|
|
4
|
+
import { isReactVersionAtLeast } from './reactVersion.js';
|
|
5
5
|
/**
|
|
6
6
|
* Extracts the `ref` from a React element, handling different React versions.
|
|
7
7
|
*/
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import type { BaseUIEvent, WithBaseUIEvent } from './types';
|
|
2
|
+
import type { BaseUIEvent, WithBaseUIEvent } from './types.js';
|
|
3
3
|
type ElementType = React.ElementType;
|
|
4
4
|
type PropsOf<T extends React.ElementType> = WithBaseUIEvent<React.ComponentPropsWithRef<T>>;
|
|
5
5
|
type InputProps<T extends React.ElementType> = PropsOf<T> | ((otherProps: PropsOf<T>) => PropsOf<T>) | undefined;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Vendored from @base-ui/react v1.6.0 (MIT) — packages/react/src/merge-props/mergeProps.ts
|
|
2
2
|
// https://github.com/mui/base-ui — exact copy; only import specifiers rewired.
|
|
3
3
|
import * as React from 'react';
|
|
4
|
-
import { mergeObjects } from './mergeObjects';
|
|
4
|
+
import { mergeObjects } from './mergeObjects.js';
|
|
5
5
|
const EMPTY_PROPS = {};
|
|
6
6
|
export function mergeProps(a, b, c, d, e) {
|
|
7
7
|
if (!c && !d && !e && !a) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type * as React from 'react';
|
|
2
|
-
import type { BaseUIEvent, ComponentRenderFn, HTMLProps } from './baseTypes';
|
|
2
|
+
import type { BaseUIEvent, ComponentRenderFn, HTMLProps } from './baseTypes.js';
|
|
3
3
|
export type { HTMLProps, BaseUIEvent, ComponentRenderFn };
|
|
4
4
|
export type MaybeBaseUIEvent<E extends React.SyntheticEvent<Element, Event>> = E & Partial<Pick<BaseUIEvent<E>, 'preventBaseUIHandler' | 'baseUIHandlerPrevented'>>;
|
|
5
5
|
export interface FloatingUIOpenChangeDetails {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Vendored from @base-ui/utils v1.6.0 (MIT) — packages/utils/src/useMergedRefs.ts
|
|
2
2
|
// https://github.com/mui/base-ui — exact copy.
|
|
3
3
|
import * as React from 'react';
|
|
4
|
-
import { useRefWithInit } from './useRefWithInit';
|
|
4
|
+
import { useRefWithInit } from './useRefWithInit.js';
|
|
5
5
|
export function useMergedRefs(a, b, c, d) {
|
|
6
6
|
const forkRef = useRefWithInit((createForkRef)).current;
|
|
7
7
|
if (didChange(forkRef, a, b, c, d)) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import type { ComponentRenderFn } from './types';
|
|
3
|
-
import type { HTMLProps } from './types';
|
|
4
|
-
import type { StateAttributesMapping } from './getStateAttributesProps';
|
|
2
|
+
import type { ComponentRenderFn } from './types.js';
|
|
3
|
+
import type { HTMLProps } from './types.js';
|
|
4
|
+
import type { StateAttributesMapping } from './getStateAttributesProps.js';
|
|
5
5
|
/**
|
|
6
6
|
* Renders a Base UI element.
|
|
7
7
|
*
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Vendored from @base-ui/react v1.6.0 (MIT) — packages/react/src/use-render/useRender.ts
|
|
2
2
|
// https://github.com/mui/base-ui — exact copy; only import specifiers rewired.
|
|
3
3
|
import * as React from 'react';
|
|
4
|
-
import { useRenderElement } from './useRenderElement';
|
|
4
|
+
import { useRenderElement } from './useRenderElement.js';
|
|
5
5
|
/**
|
|
6
6
|
* Renders a Base UI element.
|
|
7
7
|
*
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import type { ComponentRenderFn, HTMLProps } from './types';
|
|
3
|
-
import type { WithDataAttributes } from './baseTypes';
|
|
4
|
-
import { type StateAttributesMapping } from './getStateAttributesProps';
|
|
2
|
+
import type { ComponentRenderFn, HTMLProps } from './types.js';
|
|
3
|
+
import type { WithDataAttributes } from './baseTypes.js';
|
|
4
|
+
import { type StateAttributesMapping } from './getStateAttributesProps.js';
|
|
5
5
|
type IntrinsicTagName = keyof React.JSX.IntrinsicElements;
|
|
6
6
|
/**
|
|
7
7
|
* Renders a Base UI element.
|
|
@@ -3,15 +3,15 @@ import { createElement as _createElement } from "react";
|
|
|
3
3
|
// https://github.com/mui/base-ui — import specifiers rewired; one local departure:
|
|
4
4
|
// the `props` config accepts bespoke data-* part attributes (WithDataAttributes).
|
|
5
5
|
import * as React from 'react';
|
|
6
|
-
import { useMergedRefs, useMergedRefsN } from './useMergedRefs';
|
|
7
|
-
import { getReactElementRef } from './getReactElementRef';
|
|
8
|
-
import { mergeObjects } from './mergeObjects';
|
|
9
|
-
import { warn } from './warn';
|
|
10
|
-
import { EMPTY_OBJECT } from './empty';
|
|
11
|
-
import { getStateAttributesProps } from './getStateAttributesProps';
|
|
12
|
-
import { resolveClassName } from './resolveClassName';
|
|
13
|
-
import { resolveStyle } from './resolveStyle';
|
|
14
|
-
import { mergeProps, mergePropsN, mergeClassNames } from './mergeProps';
|
|
6
|
+
import { useMergedRefs, useMergedRefsN } from './useMergedRefs.js';
|
|
7
|
+
import { getReactElementRef } from './getReactElementRef.js';
|
|
8
|
+
import { mergeObjects } from './mergeObjects.js';
|
|
9
|
+
import { warn } from './warn.js';
|
|
10
|
+
import { EMPTY_OBJECT } from './empty.js';
|
|
11
|
+
import { getStateAttributesProps } from './getStateAttributesProps.js';
|
|
12
|
+
import { resolveClassName } from './resolveClassName.js';
|
|
13
|
+
import { resolveStyle } from './resolveStyle.js';
|
|
14
|
+
import { mergeProps, mergePropsN, mergeClassNames } from './mergeProps.js';
|
|
15
15
|
/**
|
|
16
16
|
* Renders a Base UI element.
|
|
17
17
|
*
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@intentface/chat",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Headless chat UI primitives — unstyled compound components, hooks, and wire formats for building AI chat interfaces.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -77,7 +77,7 @@
|
|
|
77
77
|
}
|
|
78
78
|
},
|
|
79
79
|
"scripts": {
|
|
80
|
-
"build": "rm -rf dist && tsc -p tsconfig.build.json && node scripts/add-dist-extensions.mjs",
|
|
80
|
+
"build": "rm -rf dist && tsc -p tsconfig.build.json && node scripts/add-dist-extensions.mjs && node scripts/smoke-dist.mjs",
|
|
81
81
|
"test": "bun test",
|
|
82
82
|
"typecheck": "tsc --noEmit",
|
|
83
83
|
"prepack": "bun run build && node scripts/swap-exports.mjs pre",
|