@atelier-ui/react 0.0.24 → 0.0.26
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 +17 -0
- package/package.json +1 -1
- package/src/index.d.ts +1 -0
- package/src/index.d.ts.map +1 -1
- package/src/index.js +1 -0
- package/src/index.js.map +1 -1
- package/src/lib/chat/llm-chat.d.ts +79 -0
- package/src/lib/chat/llm-chat.d.ts.map +1 -0
- package/src/lib/chat/llm-chat.js +147 -0
- package/src/lib/chat/llm-chat.js.map +1 -0
- package/src/lib/spec.d.ts +20 -1
- package/src/lib/spec.d.ts.map +1 -1
- package/src/lib/spec.js.map +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,20 @@
|
|
|
1
|
+
## 0.0.26 (2026-04-25)
|
|
2
|
+
|
|
3
|
+
### 🚀 Features
|
|
4
|
+
|
|
5
|
+
- **chat:** add LlmChat component for React ([5b04778](https://github.com/DominikPieper/atelier-ui/commit/5b04778))
|
|
6
|
+
- **chat:** add LlmChat component for Angular ([48392af](https://github.com/DominikPieper/atelier-ui/commit/48392af))
|
|
7
|
+
- **button:** add danger variant ([bcdb114](https://github.com/DominikPieper/atelier-ui/commit/bcdb114))
|
|
8
|
+
|
|
9
|
+
### ❤️ Thank You
|
|
10
|
+
|
|
11
|
+
- Claude Opus 4.7 (1M context)
|
|
12
|
+
- Dominik Pieper
|
|
13
|
+
|
|
14
|
+
## 0.0.25 (2026-04-24)
|
|
15
|
+
|
|
16
|
+
This was a version bump only for react to align it with other projects, there were no code changes.
|
|
17
|
+
|
|
1
18
|
## 0.0.24 (2026-04-24)
|
|
2
19
|
|
|
3
20
|
This was a version bump only for react to align it with other projects, there were no code changes.
|
package/package.json
CHANGED
package/src/index.d.ts
CHANGED
package/src/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../libs/react/src/index.ts"],"names":[],"mappings":"AAAA,cAAc,+BAA+B,CAAC;AAC9C,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC;AACtC,cAAc,mCAAmC,CAAC;AAClD,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,iCAAiC,CAAC;AAChD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,mCAAmC,CAAC;AAClD,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,uBAAuB,CAAC;AACtC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,yBAAyB,CAAC;AACxC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,iCAAiC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../libs/react/src/index.ts"],"names":[],"mappings":"AAAA,cAAc,+BAA+B,CAAC;AAC9C,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC;AACtC,cAAc,mCAAmC,CAAC;AAClD,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,iCAAiC,CAAC;AAChD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,mCAAmC,CAAC;AAClD,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,uBAAuB,CAAC;AACtC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,yBAAyB,CAAC;AACxC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,iCAAiC,CAAC;AAChD,cAAc,qBAAqB,CAAC"}
|
package/src/index.js
CHANGED
package/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../libs/react/src/index.ts"],"names":[],"mappings":"AAAA,cAAc,+BAA+B,CAAC;AAC9C,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC;AACtC,cAAc,mCAAmC,CAAC;AAClD,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,iCAAiC,CAAC;AAChD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,mCAAmC,CAAC;AAClD,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,uBAAuB,CAAC;AACtC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,yBAAyB,CAAC;AACxC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,iCAAiC,CAAC","sourcesContent":["export * from './lib/accordion/llm-accordion';\nexport * from './lib/alert/llm-alert';\nexport * from './lib/avatar/llm-avatar';\nexport * from './lib/badge/llm-badge';\nexport * from './lib/breadcrumbs/llm-breadcrumbs';\nexport * from './lib/button/llm-button';\nexport * from './lib/card/llm-card';\nexport * from './lib/checkbox/llm-checkbox';\nexport * from './lib/dialog/llm-dialog';\nexport * from './lib/drawer/llm-drawer';\nexport * from './lib/input/llm-input';\nexport * from './lib/menu/llm-menu';\nexport * from './lib/pagination/llm-pagination';\nexport * from './lib/progress/llm-progress';\nexport * from './lib/radio-group/llm-radio-group';\nexport * from './lib/radio/llm-radio';\nexport * from './lib/select/llm-select';\nexport * from './lib/combobox/llm-combobox';\nexport * from './lib/skeleton/llm-skeleton';\nexport * from './lib/table/llm-table';\nexport * from './lib/tabs/llm-tabs';\nexport * from './lib/textarea/llm-textarea';\nexport * from './lib/toast/llm-toast';\nexport * from './lib/stepper/llm-stepper';\nexport * from './lib/toggle/llm-toggle';\nexport * from './lib/tooltip/llm-tooltip';\nexport * from './lib/code-block/llm-code-block';\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../libs/react/src/index.ts"],"names":[],"mappings":"AAAA,cAAc,+BAA+B,CAAC;AAC9C,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC;AACtC,cAAc,mCAAmC,CAAC;AAClD,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,iCAAiC,CAAC;AAChD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,mCAAmC,CAAC;AAClD,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,uBAAuB,CAAC;AACtC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,yBAAyB,CAAC;AACxC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,iCAAiC,CAAC;AAChD,cAAc,qBAAqB,CAAC","sourcesContent":["export * from './lib/accordion/llm-accordion';\nexport * from './lib/alert/llm-alert';\nexport * from './lib/avatar/llm-avatar';\nexport * from './lib/badge/llm-badge';\nexport * from './lib/breadcrumbs/llm-breadcrumbs';\nexport * from './lib/button/llm-button';\nexport * from './lib/card/llm-card';\nexport * from './lib/checkbox/llm-checkbox';\nexport * from './lib/dialog/llm-dialog';\nexport * from './lib/drawer/llm-drawer';\nexport * from './lib/input/llm-input';\nexport * from './lib/menu/llm-menu';\nexport * from './lib/pagination/llm-pagination';\nexport * from './lib/progress/llm-progress';\nexport * from './lib/radio-group/llm-radio-group';\nexport * from './lib/radio/llm-radio';\nexport * from './lib/select/llm-select';\nexport * from './lib/combobox/llm-combobox';\nexport * from './lib/skeleton/llm-skeleton';\nexport * from './lib/table/llm-table';\nexport * from './lib/tabs/llm-tabs';\nexport * from './lib/textarea/llm-textarea';\nexport * from './lib/toast/llm-toast';\nexport * from './lib/stepper/llm-stepper';\nexport * from './lib/toggle/llm-toggle';\nexport * from './lib/tooltip/llm-tooltip';\nexport * from './lib/code-block/llm-code-block';\nexport * from './lib/chat/llm-chat';\n"]}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { HTMLAttributes, ReactNode, TextareaHTMLAttributes } from 'react';
|
|
2
|
+
import type { LlmChatMessageRole, LlmChatStatus, LlmChatVariant } from '../spec';
|
|
3
|
+
import './llm-chat.css';
|
|
4
|
+
/**
|
|
5
|
+
* Properties for the LlmChat component.
|
|
6
|
+
*/
|
|
7
|
+
export interface LlmChatProps {
|
|
8
|
+
/** Layout variant. */
|
|
9
|
+
variant?: LlmChatVariant;
|
|
10
|
+
/** Connection / response status. */
|
|
11
|
+
status?: LlmChatStatus;
|
|
12
|
+
/** Whether the chat is open (drawer / popup variants). */
|
|
13
|
+
open?: boolean;
|
|
14
|
+
/** Callback when open state should change. */
|
|
15
|
+
onOpenChange?: (open: boolean) => void;
|
|
16
|
+
children?: ReactNode;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* AI assistant surface. Three layout variants share the same content slots:
|
|
20
|
+
* `drawer` (slide-in panel), `popup` (floating bubble + window), `inline`
|
|
21
|
+
* (embedded card). Compose with `LlmChatHeader`, `LlmChatMessages`,
|
|
22
|
+
* `LlmChatMessage`, `LlmChatTyping`, `LlmChatSuggestion`, `LlmChatInput`.
|
|
23
|
+
*/
|
|
24
|
+
export declare function LlmChat({ variant, status, open, onOpenChange, children, }: LlmChatProps): import("react/jsx-runtime").JSX.Element;
|
|
25
|
+
/**
|
|
26
|
+
* Header slot for `LlmChat`. Holds the title block; the close button
|
|
27
|
+
* is rendered automatically (hidden on the inline variant via CSS).
|
|
28
|
+
*/
|
|
29
|
+
export declare function LlmChatHeader({ children, className, ...rest }: HTMLAttributes<HTMLDivElement>): import("react/jsx-runtime").JSX.Element;
|
|
30
|
+
/**
|
|
31
|
+
* Scrollable message list. Project `LlmChatMessage`, `LlmChatTyping`, or
|
|
32
|
+
* `LlmChatSuggestion` children inside.
|
|
33
|
+
*/
|
|
34
|
+
export declare function LlmChatMessages({ children, className, ...rest }: HTMLAttributes<HTMLDivElement>): import("react/jsx-runtime").JSX.Element;
|
|
35
|
+
/**
|
|
36
|
+
* A single chat message. Role drives bubble alignment and color.
|
|
37
|
+
*/
|
|
38
|
+
export interface LlmChatMessageProps extends HTMLAttributes<HTMLDivElement> {
|
|
39
|
+
/** Sender of the message. */
|
|
40
|
+
role?: LlmChatMessageRole;
|
|
41
|
+
/** Marks the message as failed (red dashed border). */
|
|
42
|
+
failed?: boolean;
|
|
43
|
+
}
|
|
44
|
+
export declare function LlmChatMessage({ role, failed, children, className, ...rest }: LlmChatMessageProps): import("react/jsx-runtime").JSX.Element;
|
|
45
|
+
/**
|
|
46
|
+
* Typing indicator (three animated dots). Render at the end of the
|
|
47
|
+
* message list while the assistant is streaming.
|
|
48
|
+
*/
|
|
49
|
+
export declare function LlmChatTyping({ className, ...rest }: HTMLAttributes<HTMLDivElement>): import("react/jsx-runtime").JSX.Element;
|
|
50
|
+
/**
|
|
51
|
+
* Tappable suggestion chip used in the empty state to seed a conversation.
|
|
52
|
+
*/
|
|
53
|
+
export interface LlmChatSuggestionProps {
|
|
54
|
+
/** Primary label of the suggestion. */
|
|
55
|
+
label: string;
|
|
56
|
+
/** Optional secondary hint text. */
|
|
57
|
+
hint?: string;
|
|
58
|
+
/** Fires the label string when activated. */
|
|
59
|
+
onSelected?: (label: string) => void;
|
|
60
|
+
className?: string;
|
|
61
|
+
}
|
|
62
|
+
export declare function LlmChatSuggestion({ label, hint, onSelected, className, }: LlmChatSuggestionProps): import("react/jsx-runtime").JSX.Element;
|
|
63
|
+
/**
|
|
64
|
+
* Composable input footer for `LlmChat`. Wraps a textarea and emits
|
|
65
|
+
* `onSend` (or `onStop` when the chat status is `'streaming'`).
|
|
66
|
+
*
|
|
67
|
+
* The action button automatically switches between primary "Send" and
|
|
68
|
+
* danger "Stop" based on the parent chat's status.
|
|
69
|
+
*/
|
|
70
|
+
export interface LlmChatInputProps extends Omit<TextareaHTMLAttributes<HTMLTextAreaElement>, 'onChange'> {
|
|
71
|
+
value?: string;
|
|
72
|
+
onValueChange?: (value: string) => void;
|
|
73
|
+
onSend?: (text: string) => void;
|
|
74
|
+
onStop?: () => void;
|
|
75
|
+
/** Accessible label for the input field. */
|
|
76
|
+
ariaLabel?: string;
|
|
77
|
+
}
|
|
78
|
+
export declare function LlmChatInput({ value, onValueChange, onSend, onStop, placeholder, ariaLabel, ...rest }: LlmChatInputProps): import("react/jsx-runtime").JSX.Element;
|
|
79
|
+
//# sourceMappingURL=llm-chat.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llm-chat.d.ts","sourceRoot":"","sources":["../../../../../../libs/react/src/lib/chat/llm-chat.tsx"],"names":[],"mappings":"AAAA,OAAO,EAEL,cAAc,EAGd,SAAS,EACT,sBAAsB,EAOvB,MAAM,OAAO,CAAC;AACf,OAAO,KAAK,EACV,kBAAkB,EAClB,aAAa,EACb,cAAc,EACf,MAAM,SAAS,CAAC;AACjB,OAAO,gBAAgB,CAAC;AAgBxB;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,sBAAsB;IACtB,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,oCAAoC;IACpC,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,0DAA0D;IAC1D,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,8CAA8C;IAC9C,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,EACtB,OAAkB,EAClB,MAAe,EACf,IAAY,EACZ,YAAY,EACZ,QAAQ,GACT,EAAE,YAAY,2CA2Gd;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,EAC5B,QAAQ,EACR,SAAS,EACT,GAAG,IAAI,EACR,EAAE,cAAc,CAAC,cAAc,CAAC,2CAiChC;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,EAC9B,QAAQ,EACR,SAAS,EACT,GAAG,IAAI,EACR,EAAE,cAAc,CAAC,cAAc,CAAC,2CAShC;AAED;;GAEG;AACH,MAAM,WAAW,mBAAoB,SAAQ,cAAc,CAAC,cAAc,CAAC;IACzE,6BAA6B;IAC7B,IAAI,CAAC,EAAE,kBAAkB,CAAC;IAC1B,uDAAuD;IACvD,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,wBAAgB,cAAc,CAAC,EAC7B,IAAkB,EAClB,MAAc,EACd,QAAQ,EACR,SAAS,EACT,GAAG,IAAI,EACR,EAAE,mBAAmB,2CAcrB;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,EAC5B,SAAS,EACT,GAAG,IAAI,EACR,EAAE,cAAc,CAAC,cAAc,CAAC,2CAchC;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,uCAAuC;IACvC,KAAK,EAAE,MAAM,CAAC;IACd,oCAAoC;IACpC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,6CAA6C;IAC7C,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,iBAAiB,CAAC,EAChC,KAAK,EACL,IAAI,EACJ,UAAU,EACV,SAAS,GACV,EAAE,sBAAsB,2CAexB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,iBACf,SAAQ,IAAI,CAAC,sBAAsB,CAAC,mBAAmB,CAAC,EAAE,UAAU,CAAC;IACrE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,4CAA4C;IAC5C,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,YAAY,CAAC,EAC3B,KAAK,EACL,aAAa,EACb,MAAM,EACN,MAAM,EACN,WAAW,EACX,SAAuC,EACvC,GAAG,IAAI,EACR,EAAE,iBAAiB,2CAuEnB"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { createContext, useContext, useEffect, useId, useRef, useState, } from 'react';
|
|
3
|
+
import './llm-chat.css';
|
|
4
|
+
const ChatContext = createContext({
|
|
5
|
+
headerId: '',
|
|
6
|
+
status: 'idle',
|
|
7
|
+
close: () => undefined,
|
|
8
|
+
toggle: () => undefined,
|
|
9
|
+
});
|
|
10
|
+
/**
|
|
11
|
+
* AI assistant surface. Three layout variants share the same content slots:
|
|
12
|
+
* `drawer` (slide-in panel), `popup` (floating bubble + window), `inline`
|
|
13
|
+
* (embedded card). Compose with `LlmChatHeader`, `LlmChatMessages`,
|
|
14
|
+
* `LlmChatMessage`, `LlmChatTyping`, `LlmChatSuggestion`, `LlmChatInput`.
|
|
15
|
+
*/
|
|
16
|
+
export function LlmChat({ variant = 'drawer', status = 'idle', open = false, onOpenChange, children, }) {
|
|
17
|
+
const dialogRef = useRef(null);
|
|
18
|
+
const headerId = useId();
|
|
19
|
+
const triggerElRef = useRef(null);
|
|
20
|
+
useEffect(() => {
|
|
21
|
+
if (variant !== 'drawer')
|
|
22
|
+
return;
|
|
23
|
+
const dialog = dialogRef.current;
|
|
24
|
+
if (!dialog)
|
|
25
|
+
return;
|
|
26
|
+
if (open) {
|
|
27
|
+
triggerElRef.current = document.activeElement;
|
|
28
|
+
if (!dialog.open)
|
|
29
|
+
dialog.showModal();
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
if (dialog.open)
|
|
33
|
+
dialog.close();
|
|
34
|
+
triggerElRef.current?.focus();
|
|
35
|
+
triggerElRef.current = null;
|
|
36
|
+
}
|
|
37
|
+
}, [open, variant]);
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
if (variant !== 'drawer')
|
|
40
|
+
return;
|
|
41
|
+
const dialog = dialogRef.current;
|
|
42
|
+
if (!dialog)
|
|
43
|
+
return;
|
|
44
|
+
const onClose = () => onOpenChange?.(false);
|
|
45
|
+
const onCancel = (e) => {
|
|
46
|
+
e.preventDefault();
|
|
47
|
+
onOpenChange?.(false);
|
|
48
|
+
};
|
|
49
|
+
dialog.addEventListener('close', onClose);
|
|
50
|
+
dialog.addEventListener('cancel', onCancel);
|
|
51
|
+
return () => {
|
|
52
|
+
dialog.removeEventListener('close', onClose);
|
|
53
|
+
dialog.removeEventListener('cancel', onCancel);
|
|
54
|
+
};
|
|
55
|
+
}, [onOpenChange, variant]);
|
|
56
|
+
const handleBackdropClick = (e) => {
|
|
57
|
+
if (e.target === dialogRef.current)
|
|
58
|
+
onOpenChange?.(false);
|
|
59
|
+
};
|
|
60
|
+
const hostClass = [
|
|
61
|
+
'llm-chat',
|
|
62
|
+
`variant-${variant}`,
|
|
63
|
+
`status-${status}`,
|
|
64
|
+
open && 'is-open',
|
|
65
|
+
]
|
|
66
|
+
.filter(Boolean)
|
|
67
|
+
.join(' ');
|
|
68
|
+
const ctx = {
|
|
69
|
+
headerId,
|
|
70
|
+
status,
|
|
71
|
+
close: () => onOpenChange?.(false),
|
|
72
|
+
toggle: () => onOpenChange?.(!open),
|
|
73
|
+
};
|
|
74
|
+
return (_jsx(ChatContext.Provider, { value: ctx, children: _jsxs("div", { className: hostClass, children: [variant === 'drawer' && (_jsx("dialog", { ref: dialogRef, "aria-labelledby": headerId, "aria-modal": "true", onClick: handleBackdropClick, children: _jsx("div", { className: "surface drawer-surface", onClick: (e) => e.stopPropagation(), children: children }) })), variant === 'popup' && (_jsxs(_Fragment, { children: [open && (_jsx("div", { className: "surface popup-surface", role: "dialog", "aria-labelledby": headerId, children: children })), _jsx("button", { type: "button", className: "fab-bubble", "aria-label": open ? 'Close AI assistant' : 'Open AI assistant', "aria-expanded": open, onClick: () => onOpenChange?.(!open), children: _jsx("span", { "aria-hidden": "true", children: "AI" }) })] })), variant === 'inline' && (_jsx("section", { className: "surface inline-surface", "aria-labelledby": headerId, children: children }))] }) }));
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Header slot for `LlmChat`. Holds the title block; the close button
|
|
78
|
+
* is rendered automatically (hidden on the inline variant via CSS).
|
|
79
|
+
*/
|
|
80
|
+
export function LlmChatHeader({ children, className, ...rest }) {
|
|
81
|
+
const ctx = useContext(ChatContext);
|
|
82
|
+
return (_jsxs("div", { id: ctx.headerId, className: ['llm-chat-header', className].filter(Boolean).join(' '), ...rest, children: [_jsx("div", { className: "title-block", children: children }), _jsx("button", { type: "button", className: "close-btn", "aria-label": "Close chat", onClick: ctx.close, children: _jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [_jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }), _jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })] }) })] }));
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Scrollable message list. Project `LlmChatMessage`, `LlmChatTyping`, or
|
|
86
|
+
* `LlmChatSuggestion` children inside.
|
|
87
|
+
*/
|
|
88
|
+
export function LlmChatMessages({ children, className, ...rest }) {
|
|
89
|
+
return (_jsx("div", { className: ['llm-chat-messages', className].filter(Boolean).join(' '), ...rest, children: children }));
|
|
90
|
+
}
|
|
91
|
+
export function LlmChatMessage({ role = 'assistant', failed = false, children, className, ...rest }) {
|
|
92
|
+
const classes = [
|
|
93
|
+
'llm-chat-message',
|
|
94
|
+
`role-${role}`,
|
|
95
|
+
failed && 'is-failed',
|
|
96
|
+
className,
|
|
97
|
+
]
|
|
98
|
+
.filter(Boolean)
|
|
99
|
+
.join(' ');
|
|
100
|
+
return (_jsx("div", { role: "listitem", className: classes, ...rest, children: children }));
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Typing indicator (three animated dots). Render at the end of the
|
|
104
|
+
* message list while the assistant is streaming.
|
|
105
|
+
*/
|
|
106
|
+
export function LlmChatTyping({ className, ...rest }) {
|
|
107
|
+
return (_jsxs("div", { role: "status", "aria-live": "polite", className: ['llm-chat-typing', className].filter(Boolean).join(' '), ...rest, children: [_jsx("span", { className: "dot" }), _jsx("span", { className: "dot" }), _jsx("span", { className: "dot" }), _jsx("span", { className: "sr-only", children: "Assistant is typing" })] }));
|
|
108
|
+
}
|
|
109
|
+
export function LlmChatSuggestion({ label, hint, onSelected, className, }) {
|
|
110
|
+
return (_jsx("div", { className: ['llm-chat-suggestion', className].filter(Boolean).join(' '), children: _jsxs("button", { type: "button", className: "chip", onClick: () => onSelected?.(label), children: [_jsx("span", { className: "chip-label", children: label }), hint && _jsx("span", { className: "chip-hint", children: hint })] }) }));
|
|
111
|
+
}
|
|
112
|
+
export function LlmChatInput({ value, onValueChange, onSend, onStop, placeholder, ariaLabel = 'Message your AI assistant', ...rest }) {
|
|
113
|
+
const ctx = useContext(ChatContext);
|
|
114
|
+
const isStreaming = ctx.status === 'streaming';
|
|
115
|
+
const [internal, setInternal] = useState('');
|
|
116
|
+
const isControlled = value !== undefined;
|
|
117
|
+
const current = isControlled ? value : internal;
|
|
118
|
+
const setCurrent = (next) => {
|
|
119
|
+
if (!isControlled)
|
|
120
|
+
setInternal(next);
|
|
121
|
+
onValueChange?.(next);
|
|
122
|
+
};
|
|
123
|
+
const effectivePlaceholder = placeholder ??
|
|
124
|
+
(isStreaming
|
|
125
|
+
? 'Waiting for response…'
|
|
126
|
+
: ctx.status === 'error'
|
|
127
|
+
? 'Try again…'
|
|
128
|
+
: 'Message your AI assistant…');
|
|
129
|
+
const emitSend = () => {
|
|
130
|
+
const text = current.trim();
|
|
131
|
+
if (!text || isStreaming)
|
|
132
|
+
return;
|
|
133
|
+
onSend?.(text);
|
|
134
|
+
setCurrent('');
|
|
135
|
+
};
|
|
136
|
+
const handleChange = (e) => {
|
|
137
|
+
setCurrent(e.target.value);
|
|
138
|
+
};
|
|
139
|
+
const handleKeyDown = (e) => {
|
|
140
|
+
if (e.key === 'Enter' && !e.shiftKey) {
|
|
141
|
+
e.preventDefault();
|
|
142
|
+
emitSend();
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
return (_jsxs("div", { className: "llm-chat-input", children: [_jsx("textarea", { className: "field", rows: 1, value: current, placeholder: effectivePlaceholder, disabled: isStreaming, "aria-label": ariaLabel, onChange: handleChange, onKeyDown: handleKeyDown, ...rest }), isStreaming ? (_jsx("button", { type: "button", className: "action-btn variant-danger size-md", onClick: onStop, children: "Stop" })) : (_jsx("button", { type: "button", className: "action-btn variant-primary size-md", disabled: !current.trim(), onClick: emitSend, children: "Send" }))] }));
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=llm-chat.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llm-chat.js","sourceRoot":"","sources":["../../../../../../libs/react/src/lib/chat/llm-chat.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n ChangeEvent,\n HTMLAttributes,\n KeyboardEvent,\n MouseEvent,\n ReactNode,\n TextareaHTMLAttributes,\n createContext,\n useContext,\n useEffect,\n useId,\n useRef,\n useState,\n} from 'react';\nimport type {\n LlmChatMessageRole,\n LlmChatStatus,\n LlmChatVariant,\n} from '../spec';\nimport './llm-chat.css';\n\ninterface ChatContextValue {\n headerId: string;\n status: LlmChatStatus;\n close: () => void;\n toggle: () => void;\n}\n\nconst ChatContext = createContext<ChatContextValue>({\n headerId: '',\n status: 'idle',\n close: () => undefined,\n toggle: () => undefined,\n});\n\n/**\n * Properties for the LlmChat component.\n */\nexport interface LlmChatProps {\n /** Layout variant. */\n variant?: LlmChatVariant;\n /** Connection / response status. */\n status?: LlmChatStatus;\n /** Whether the chat is open (drawer / popup variants). */\n open?: boolean;\n /** Callback when open state should change. */\n onOpenChange?: (open: boolean) => void;\n children?: ReactNode;\n}\n\n/**\n * AI assistant surface. Three layout variants share the same content slots:\n * `drawer` (slide-in panel), `popup` (floating bubble + window), `inline`\n * (embedded card). Compose with `LlmChatHeader`, `LlmChatMessages`,\n * `LlmChatMessage`, `LlmChatTyping`, `LlmChatSuggestion`, `LlmChatInput`.\n */\nexport function LlmChat({\n variant = 'drawer',\n status = 'idle',\n open = false,\n onOpenChange,\n children,\n}: LlmChatProps) {\n const dialogRef = useRef<HTMLDialogElement>(null);\n const headerId = useId();\n const triggerElRef = useRef<Element | null>(null);\n\n useEffect(() => {\n if (variant !== 'drawer') return;\n const dialog = dialogRef.current;\n if (!dialog) return;\n if (open) {\n triggerElRef.current = document.activeElement;\n if (!dialog.open) dialog.showModal();\n } else {\n if (dialog.open) dialog.close();\n (triggerElRef.current as HTMLElement | null)?.focus();\n triggerElRef.current = null;\n }\n }, [open, variant]);\n\n useEffect(() => {\n if (variant !== 'drawer') return;\n const dialog = dialogRef.current;\n if (!dialog) return;\n const onClose = () => onOpenChange?.(false);\n const onCancel = (e: Event) => {\n e.preventDefault();\n onOpenChange?.(false);\n };\n dialog.addEventListener('close', onClose);\n dialog.addEventListener('cancel', onCancel);\n return () => {\n dialog.removeEventListener('close', onClose);\n dialog.removeEventListener('cancel', onCancel);\n };\n }, [onOpenChange, variant]);\n\n const handleBackdropClick = (e: MouseEvent<HTMLDialogElement>) => {\n if (e.target === dialogRef.current) onOpenChange?.(false);\n };\n\n const hostClass = [\n 'llm-chat',\n `variant-${variant}`,\n `status-${status}`,\n open && 'is-open',\n ]\n .filter(Boolean)\n .join(' ');\n\n const ctx: ChatContextValue = {\n headerId,\n status,\n close: () => onOpenChange?.(false),\n toggle: () => onOpenChange?.(!open),\n };\n\n return (\n <ChatContext.Provider value={ctx}>\n <div className={hostClass}>\n {variant === 'drawer' && (\n <dialog\n ref={dialogRef}\n aria-labelledby={headerId}\n aria-modal=\"true\"\n onClick={handleBackdropClick}\n >\n <div\n className=\"surface drawer-surface\"\n onClick={(e) => e.stopPropagation()}\n >\n {children}\n </div>\n </dialog>\n )}\n {variant === 'popup' && (\n <>\n {open && (\n <div\n className=\"surface popup-surface\"\n role=\"dialog\"\n aria-labelledby={headerId}\n >\n {children}\n </div>\n )}\n <button\n type=\"button\"\n className=\"fab-bubble\"\n aria-label={open ? 'Close AI assistant' : 'Open AI assistant'}\n aria-expanded={open}\n onClick={() => onOpenChange?.(!open)}\n >\n <span aria-hidden=\"true\">AI</span>\n </button>\n </>\n )}\n {variant === 'inline' && (\n <section\n className=\"surface inline-surface\"\n aria-labelledby={headerId}\n >\n {children}\n </section>\n )}\n </div>\n </ChatContext.Provider>\n );\n}\n\n/**\n * Header slot for `LlmChat`. Holds the title block; the close button\n * is rendered automatically (hidden on the inline variant via CSS).\n */\nexport function LlmChatHeader({\n children,\n className,\n ...rest\n}: HTMLAttributes<HTMLDivElement>) {\n const ctx = useContext(ChatContext);\n return (\n <div\n id={ctx.headerId}\n className={['llm-chat-header', className].filter(Boolean).join(' ')}\n {...rest}\n >\n <div className=\"title-block\">{children}</div>\n <button\n type=\"button\"\n className=\"close-btn\"\n aria-label=\"Close chat\"\n onClick={ctx.close}\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n </button>\n </div>\n );\n}\n\n/**\n * Scrollable message list. Project `LlmChatMessage`, `LlmChatTyping`, or\n * `LlmChatSuggestion` children inside.\n */\nexport function LlmChatMessages({\n children,\n className,\n ...rest\n}: HTMLAttributes<HTMLDivElement>) {\n return (\n <div\n className={['llm-chat-messages', className].filter(Boolean).join(' ')}\n {...rest}\n >\n {children}\n </div>\n );\n}\n\n/**\n * A single chat message. Role drives bubble alignment and color.\n */\nexport interface LlmChatMessageProps extends HTMLAttributes<HTMLDivElement> {\n /** Sender of the message. */\n role?: LlmChatMessageRole;\n /** Marks the message as failed (red dashed border). */\n failed?: boolean;\n}\n\nexport function LlmChatMessage({\n role = 'assistant',\n failed = false,\n children,\n className,\n ...rest\n}: LlmChatMessageProps) {\n const classes = [\n 'llm-chat-message',\n `role-${role}`,\n failed && 'is-failed',\n className,\n ]\n .filter(Boolean)\n .join(' ');\n return (\n <div role=\"listitem\" className={classes} {...rest}>\n {children}\n </div>\n );\n}\n\n/**\n * Typing indicator (three animated dots). Render at the end of the\n * message list while the assistant is streaming.\n */\nexport function LlmChatTyping({\n className,\n ...rest\n}: HTMLAttributes<HTMLDivElement>) {\n return (\n <div\n role=\"status\"\n aria-live=\"polite\"\n className={['llm-chat-typing', className].filter(Boolean).join(' ')}\n {...rest}\n >\n <span className=\"dot\" />\n <span className=\"dot\" />\n <span className=\"dot\" />\n <span className=\"sr-only\">Assistant is typing</span>\n </div>\n );\n}\n\n/**\n * Tappable suggestion chip used in the empty state to seed a conversation.\n */\nexport interface LlmChatSuggestionProps {\n /** Primary label of the suggestion. */\n label: string;\n /** Optional secondary hint text. */\n hint?: string;\n /** Fires the label string when activated. */\n onSelected?: (label: string) => void;\n className?: string;\n}\n\nexport function LlmChatSuggestion({\n label,\n hint,\n onSelected,\n className,\n}: LlmChatSuggestionProps) {\n return (\n <div\n className={['llm-chat-suggestion', className].filter(Boolean).join(' ')}\n >\n <button\n type=\"button\"\n className=\"chip\"\n onClick={() => onSelected?.(label)}\n >\n <span className=\"chip-label\">{label}</span>\n {hint && <span className=\"chip-hint\">{hint}</span>}\n </button>\n </div>\n );\n}\n\n/**\n * Composable input footer for `LlmChat`. Wraps a textarea and emits\n * `onSend` (or `onStop` when the chat status is `'streaming'`).\n *\n * The action button automatically switches between primary \"Send\" and\n * danger \"Stop\" based on the parent chat's status.\n */\nexport interface LlmChatInputProps\n extends Omit<TextareaHTMLAttributes<HTMLTextAreaElement>, 'onChange'> {\n value?: string;\n onValueChange?: (value: string) => void;\n onSend?: (text: string) => void;\n onStop?: () => void;\n /** Accessible label for the input field. */\n ariaLabel?: string;\n}\n\nexport function LlmChatInput({\n value,\n onValueChange,\n onSend,\n onStop,\n placeholder,\n ariaLabel = 'Message your AI assistant',\n ...rest\n}: LlmChatInputProps) {\n const ctx = useContext(ChatContext);\n const isStreaming = ctx.status === 'streaming';\n const [internal, setInternal] = useState('');\n const isControlled = value !== undefined;\n const current = isControlled ? value : internal;\n\n const setCurrent = (next: string) => {\n if (!isControlled) setInternal(next);\n onValueChange?.(next);\n };\n\n const effectivePlaceholder =\n placeholder ??\n (isStreaming\n ? 'Waiting for response…'\n : ctx.status === 'error'\n ? 'Try again…'\n : 'Message your AI assistant…');\n\n const emitSend = () => {\n const text = current.trim();\n if (!text || isStreaming) return;\n onSend?.(text);\n setCurrent('');\n };\n\n const handleChange = (e: ChangeEvent<HTMLTextAreaElement>) => {\n setCurrent(e.target.value);\n };\n\n const handleKeyDown = (e: KeyboardEvent<HTMLTextAreaElement>) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault();\n emitSend();\n }\n };\n\n return (\n <div className=\"llm-chat-input\">\n <textarea\n className=\"field\"\n rows={1}\n value={current}\n placeholder={effectivePlaceholder}\n disabled={isStreaming}\n aria-label={ariaLabel}\n onChange={handleChange}\n onKeyDown={handleKeyDown}\n {...rest}\n />\n {isStreaming ? (\n <button\n type=\"button\"\n className=\"action-btn variant-danger size-md\"\n onClick={onStop}\n >\n Stop\n </button>\n ) : (\n <button\n type=\"button\"\n className=\"action-btn variant-primary size-md\"\n disabled={!current.trim()}\n onClick={emitSend}\n >\n Send\n </button>\n )}\n </div>\n );\n}\n"]}
|
package/src/lib/spec.d.ts
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* Angular: use the union types as `input<T>()` type parameters.
|
|
9
9
|
* React: extend the spec interface from the framework-specific props interface.
|
|
10
10
|
*/
|
|
11
|
-
export type LlmButtonVariant = 'primary' | 'secondary' | 'outline';
|
|
11
|
+
export type LlmButtonVariant = 'primary' | 'secondary' | 'outline' | 'danger';
|
|
12
12
|
export type LlmButtonSize = 'sm' | 'md' | 'lg';
|
|
13
13
|
export interface LlmButtonSpec {
|
|
14
14
|
variant?: LlmButtonVariant;
|
|
@@ -225,4 +225,23 @@ export interface LlmThSpec {
|
|
|
225
225
|
export interface LlmTdSpec {
|
|
226
226
|
align?: LlmTableAlign;
|
|
227
227
|
}
|
|
228
|
+
export type LlmChatVariant = 'drawer' | 'popup' | 'inline';
|
|
229
|
+
export type LlmChatStatus = 'idle' | 'streaming' | 'error';
|
|
230
|
+
export type LlmChatMessageRole = 'user' | 'assistant' | 'system';
|
|
231
|
+
export interface LlmChatMessageSpec {
|
|
232
|
+
id: string;
|
|
233
|
+
role: LlmChatMessageRole;
|
|
234
|
+
content: string;
|
|
235
|
+
failed?: boolean;
|
|
236
|
+
}
|
|
237
|
+
export interface LlmChatSuggestionSpec {
|
|
238
|
+
id: string;
|
|
239
|
+
label: string;
|
|
240
|
+
hint?: string;
|
|
241
|
+
}
|
|
242
|
+
export interface LlmChatSpec {
|
|
243
|
+
variant?: LlmChatVariant;
|
|
244
|
+
status?: LlmChatStatus;
|
|
245
|
+
open?: boolean;
|
|
246
|
+
}
|
|
228
247
|
//# sourceMappingURL=spec.d.ts.map
|
package/src/lib/spec.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spec.d.ts","sourceRoot":"","sources":["../../../../../libs/react/src/lib/spec.ts"],"names":[],"mappings":"AAIA;;;;;;;;;GASG;AAKH,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,WAAW,GAAG,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"spec.d.ts","sourceRoot":"","sources":["../../../../../libs/react/src/lib/spec.ts"],"names":[],"mappings":"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"}
|
package/src/lib/spec.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spec.js","sourceRoot":"","sources":["../../../../../libs/react/src/lib/spec.ts"],"names":[],"mappings":"AAAA,iEAAiE;AACjE,4EAA4E;AAC5E,4EAA4E","sourcesContent":["// AUTO-GENERATED from libs/spec/src/index.ts — do not edit here.\n// Run `node tools/scripts/sync-spec.mjs` after editing the source of truth.\n// The framework libs inline these types so @atelier-ui/spec stays internal.\n\n/**\n * @atelier-ui/spec\n *\n * Framework-agnostic TypeScript interfaces defining the public API contract\n * for every llm-components component. Both the Angular and React libraries\n * import from here so the compiler enforces parity.\n *\n * Angular: use the union types as `input<T>()` type parameters.\n * React: extend the spec interface from the framework-specific props interface.\n */\n\n// ---------------------------------------------------------------------------\n// Button\n// ---------------------------------------------------------------------------\nexport type LlmButtonVariant = 'primary' | 'secondary' | 'outline';\nexport type LlmButtonSize = 'sm' | 'md' | 'lg';\nexport interface LlmButtonSpec {\n variant?: LlmButtonVariant;\n size?: LlmButtonSize;\n disabled?: boolean;\n loading?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Badge\n// ---------------------------------------------------------------------------\nexport type LlmBadgeVariant = 'default' | 'success' | 'warning' | 'danger' | 'info';\nexport type LlmBadgeSize = 'sm' | 'md';\nexport interface LlmBadgeSpec {\n variant?: LlmBadgeVariant;\n size?: LlmBadgeSize;\n}\n\n// ---------------------------------------------------------------------------\n// Avatar / AvatarGroup\n// ---------------------------------------------------------------------------\nexport type LlmAvatarSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';\nexport type LlmAvatarShape = 'circle' | 'square';\nexport type LlmAvatarStatus = 'online' | 'offline' | 'away' | 'busy' | '';\nexport interface LlmAvatarSpec {\n src?: string;\n alt?: string;\n name?: string;\n size?: LlmAvatarSize;\n shape?: LlmAvatarShape;\n status?: LlmAvatarStatus;\n}\nexport interface LlmAvatarGroupSpec {\n max?: number;\n size?: LlmAvatarSize;\n}\n\n// ---------------------------------------------------------------------------\n// Card\n// ---------------------------------------------------------------------------\nexport type LlmCardVariant = 'elevated' | 'outlined' | 'flat';\nexport type LlmCardPadding = 'none' | 'sm' | 'md' | 'lg';\nexport interface LlmCardSpec {\n variant?: LlmCardVariant;\n padding?: LlmCardPadding;\n}\n\n// ---------------------------------------------------------------------------\n// Input / Textarea (shared form field props)\n// ---------------------------------------------------------------------------\n// `any` is intentional here: downstream form-field interfaces narrow `value`\n// to the concrete primitive they accept (string, number, boolean, Date, …).\n// Using `unknown` would force every downstream consumer to redeclare the\n// property, defeating the purpose of the shared spec.\n/* eslint-disable @typescript-eslint/no-explicit-any */\nexport interface LlmFormFieldSpec {\n value?: any;\n onValueChange?: (value: any) => void;\n disabled?: boolean;\n readonly?: boolean;\n invalid?: boolean;\n required?: boolean;\n name?: string;\n}\n/* eslint-enable @typescript-eslint/no-explicit-any */\n\nexport type LlmInputType = 'text' | 'email' | 'password' | 'number' | 'tel' | 'url';\nexport interface LlmInputSpec extends LlmFormFieldSpec {\n type?: LlmInputType;\n placeholder?: string;\n}\n\nexport interface LlmTextareaSpec extends LlmFormFieldSpec {\n rows?: number;\n placeholder?: string;\n autoResize?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Checkbox / Toggle\n// ---------------------------------------------------------------------------\nexport interface LlmCheckboxSpec extends LlmFormFieldSpec {\n checked?: boolean;\n onCheckedChange?: (checked: boolean) => void;\n indeterminate?: boolean;\n}\n\nexport interface LlmToggleSpec extends LlmFormFieldSpec {\n checked?: boolean;\n onCheckedChange?: (checked: boolean) => void;\n}\n\n// ---------------------------------------------------------------------------\n// Radio / RadioGroup\n// ---------------------------------------------------------------------------\nexport interface LlmRadioSpec {\n radioValue: string;\n disabled?: boolean;\n}\n\nexport interface LlmRadioGroupSpec extends LlmFormFieldSpec {\n value?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Select / Option\n// ---------------------------------------------------------------------------\nexport interface LlmSelectSpec extends LlmFormFieldSpec {\n placeholder?: string;\n}\n\nexport interface LlmOptionSpec {\n optionValue: string;\n disabled?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Stepper\n// ---------------------------------------------------------------------------\nexport interface LlmStepperSpec {\n activeStep?: number;\n orientation?: 'horizontal' | 'vertical';\n linear?: boolean;\n}\n\nexport interface LlmStepSpec {\n label: string;\n description?: string;\n completed?: boolean;\n error?: boolean;\n optional?: boolean;\n disabled?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Combobox\n// ---------------------------------------------------------------------------\nexport interface LlmComboboxOption {\n value: string;\n label: string;\n disabled?: boolean;\n}\n\nexport interface LlmComboboxSpec extends LlmFormFieldSpec {\n options?: LlmComboboxOption[];\n placeholder?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Alert\n// ---------------------------------------------------------------------------\nexport type LlmAlertVariant = 'info' | 'success' | 'warning' | 'danger';\nexport interface LlmAlertSpec {\n variant?: LlmAlertVariant;\n dismissible?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Dialog\n// ---------------------------------------------------------------------------\nexport type LlmDialogSize = 'sm' | 'md' | 'lg' | 'xl' | 'full';\nexport interface LlmDialogSpec {\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n closeOnBackdrop?: boolean;\n size?: LlmDialogSize;\n}\n\n// ---------------------------------------------------------------------------\n// TabGroup / Tab\n// ---------------------------------------------------------------------------\nexport type LlmTabGroupVariant = 'default' | 'pills';\nexport interface LlmTabGroupSpec {\n selectedIndex?: number;\n onSelectedIndexChange?: (index: number) => void;\n variant?: LlmTabGroupVariant;\n}\n\nexport interface LlmTabSpec {\n label: string;\n disabled?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// AccordionGroup / AccordionItem\n// ---------------------------------------------------------------------------\nexport type LlmAccordionGroupVariant = 'default' | 'bordered' | 'separated';\nexport interface LlmAccordionGroupSpec {\n multi?: boolean;\n variant?: LlmAccordionGroupVariant;\n}\n\nexport interface LlmAccordionItemSpec {\n expanded?: boolean;\n onExpandedChange?: (expanded: boolean) => void;\n disabled?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Menu / MenuItem\n// ---------------------------------------------------------------------------\nexport type LlmMenuVariant = 'default' | 'compact';\nexport interface LlmMenuSpec {\n variant?: LlmMenuVariant;\n}\n\nexport interface LlmMenuItemSpec {\n disabled?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Tooltip\n// ---------------------------------------------------------------------------\nexport type LlmTooltipPosition = 'above' | 'below' | 'left' | 'right';\nexport interface LlmTooltipSpec {\n llmTooltip: string;\n llmTooltipPosition?: LlmTooltipPosition;\n llmTooltipDisabled?: boolean;\n llmTooltipShowDelay?: number;\n llmTooltipHideDelay?: number;\n}\n\n// ---------------------------------------------------------------------------\n// Toast\n// ---------------------------------------------------------------------------\nexport type LlmToastVariant = 'default' | 'success' | 'warning' | 'danger' | 'info';\nexport type LlmToastContainerPosition =\n | 'top-right'\n | 'top-center'\n | 'bottom-right'\n | 'bottom-center';\nexport interface LlmToastOptions {\n variant?: LlmToastVariant;\n duration?: number;\n dismissible?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Skeleton\n// ---------------------------------------------------------------------------\nexport type LlmSkeletonVariant = 'text' | 'circular' | 'rectangular';\nexport interface LlmSkeletonSpec {\n variant?: LlmSkeletonVariant;\n width?: string;\n height?: string;\n animated?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Breadcrumbs / BreadcrumbItem\n// ---------------------------------------------------------------------------\nexport interface LlmBreadcrumbsSpec {\n separator?: string;\n}\n\nexport interface LlmBreadcrumbItemSpec {\n href?: string;\n current?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Pagination\n// ---------------------------------------------------------------------------\nexport interface LlmPaginationSpec {\n page?: number;\n pageCount?: number;\n siblingCount?: number;\n showFirstLast?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Progress\n// ---------------------------------------------------------------------------\nexport type LlmProgressVariant = 'default' | 'success' | 'warning' | 'danger';\nexport type LlmProgressSize = 'sm' | 'md' | 'lg';\nexport interface LlmProgressSpec {\n value?: number;\n max?: number;\n variant?: LlmProgressVariant;\n size?: LlmProgressSize;\n indeterminate?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Drawer\n// ---------------------------------------------------------------------------\nexport type LlmDrawerPosition = 'left' | 'right' | 'top' | 'bottom';\nexport type LlmDrawerSize = 'sm' | 'md' | 'lg' | 'full';\nexport interface LlmDrawerSpec {\n open?: boolean;\n position?: LlmDrawerPosition;\n size?: LlmDrawerSize;\n closeOnBackdrop?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Table\n// ---------------------------------------------------------------------------\nexport type LlmTableVariant = 'default' | 'striped' | 'bordered';\nexport type LlmTableSize = 'sm' | 'md' | 'lg';\nexport type LlmSortDirection = 'asc' | 'desc' | null;\nexport type LlmTableAlign = 'start' | 'center' | 'end';\n\nexport interface LlmTableSpec {\n variant?: LlmTableVariant;\n size?: LlmTableSize;\n stickyHeader?: boolean;\n}\n\nexport interface LlmTbodySpec {\n empty?: boolean;\n colSpan?: number;\n}\n\nexport interface LlmTrSpec {\n selected?: boolean;\n selectable?: boolean;\n rowId?: string;\n}\n\nexport interface LlmThSpec {\n sortable?: boolean;\n sortDirection?: LlmSortDirection;\n align?: LlmTableAlign;\n width?: string;\n}\n\nexport interface LlmTdSpec {\n align?: LlmTableAlign;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"spec.js","sourceRoot":"","sources":["../../../../../libs/react/src/lib/spec.ts"],"names":[],"mappings":"AAAA,iEAAiE;AACjE,4EAA4E;AAC5E,4EAA4E","sourcesContent":["// AUTO-GENERATED from libs/spec/src/index.ts — do not edit here.\n// Run `node tools/scripts/sync-spec.mjs` after editing the source of truth.\n// The framework libs inline these types so @atelier-ui/spec stays internal.\n\n/**\n * @atelier-ui/spec\n *\n * Framework-agnostic TypeScript interfaces defining the public API contract\n * for every llm-components component. Both the Angular and React libraries\n * import from here so the compiler enforces parity.\n *\n * Angular: use the union types as `input<T>()` type parameters.\n * React: extend the spec interface from the framework-specific props interface.\n */\n\n// ---------------------------------------------------------------------------\n// Button\n// ---------------------------------------------------------------------------\nexport type LlmButtonVariant = 'primary' | 'secondary' | 'outline' | 'danger';\nexport type LlmButtonSize = 'sm' | 'md' | 'lg';\nexport interface LlmButtonSpec {\n variant?: LlmButtonVariant;\n size?: LlmButtonSize;\n disabled?: boolean;\n loading?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Badge\n// ---------------------------------------------------------------------------\nexport type LlmBadgeVariant = 'default' | 'success' | 'warning' | 'danger' | 'info';\nexport type LlmBadgeSize = 'sm' | 'md';\nexport interface LlmBadgeSpec {\n variant?: LlmBadgeVariant;\n size?: LlmBadgeSize;\n}\n\n// ---------------------------------------------------------------------------\n// Avatar / AvatarGroup\n// ---------------------------------------------------------------------------\nexport type LlmAvatarSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';\nexport type LlmAvatarShape = 'circle' | 'square';\nexport type LlmAvatarStatus = 'online' | 'offline' | 'away' | 'busy' | '';\nexport interface LlmAvatarSpec {\n src?: string;\n alt?: string;\n name?: string;\n size?: LlmAvatarSize;\n shape?: LlmAvatarShape;\n status?: LlmAvatarStatus;\n}\nexport interface LlmAvatarGroupSpec {\n max?: number;\n size?: LlmAvatarSize;\n}\n\n// ---------------------------------------------------------------------------\n// Card\n// ---------------------------------------------------------------------------\nexport type LlmCardVariant = 'elevated' | 'outlined' | 'flat';\nexport type LlmCardPadding = 'none' | 'sm' | 'md' | 'lg';\nexport interface LlmCardSpec {\n variant?: LlmCardVariant;\n padding?: LlmCardPadding;\n}\n\n// ---------------------------------------------------------------------------\n// Input / Textarea (shared form field props)\n// ---------------------------------------------------------------------------\n// `any` is intentional here: downstream form-field interfaces narrow `value`\n// to the concrete primitive they accept (string, number, boolean, Date, …).\n// Using `unknown` would force every downstream consumer to redeclare the\n// property, defeating the purpose of the shared spec.\n/* eslint-disable @typescript-eslint/no-explicit-any */\nexport interface LlmFormFieldSpec {\n value?: any;\n onValueChange?: (value: any) => void;\n disabled?: boolean;\n readonly?: boolean;\n invalid?: boolean;\n required?: boolean;\n name?: string;\n}\n/* eslint-enable @typescript-eslint/no-explicit-any */\n\nexport type LlmInputType = 'text' | 'email' | 'password' | 'number' | 'tel' | 'url';\nexport interface LlmInputSpec extends LlmFormFieldSpec {\n type?: LlmInputType;\n placeholder?: string;\n}\n\nexport interface LlmTextareaSpec extends LlmFormFieldSpec {\n rows?: number;\n placeholder?: string;\n autoResize?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Checkbox / Toggle\n// ---------------------------------------------------------------------------\nexport interface LlmCheckboxSpec extends LlmFormFieldSpec {\n checked?: boolean;\n onCheckedChange?: (checked: boolean) => void;\n indeterminate?: boolean;\n}\n\nexport interface LlmToggleSpec extends LlmFormFieldSpec {\n checked?: boolean;\n onCheckedChange?: (checked: boolean) => void;\n}\n\n// ---------------------------------------------------------------------------\n// Radio / RadioGroup\n// ---------------------------------------------------------------------------\nexport interface LlmRadioSpec {\n radioValue: string;\n disabled?: boolean;\n}\n\nexport interface LlmRadioGroupSpec extends LlmFormFieldSpec {\n value?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Select / Option\n// ---------------------------------------------------------------------------\nexport interface LlmSelectSpec extends LlmFormFieldSpec {\n placeholder?: string;\n}\n\nexport interface LlmOptionSpec {\n optionValue: string;\n disabled?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Stepper\n// ---------------------------------------------------------------------------\nexport interface LlmStepperSpec {\n activeStep?: number;\n orientation?: 'horizontal' | 'vertical';\n linear?: boolean;\n}\n\nexport interface LlmStepSpec {\n label: string;\n description?: string;\n completed?: boolean;\n error?: boolean;\n optional?: boolean;\n disabled?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Combobox\n// ---------------------------------------------------------------------------\nexport interface LlmComboboxOption {\n value: string;\n label: string;\n disabled?: boolean;\n}\n\nexport interface LlmComboboxSpec extends LlmFormFieldSpec {\n options?: LlmComboboxOption[];\n placeholder?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Alert\n// ---------------------------------------------------------------------------\nexport type LlmAlertVariant = 'info' | 'success' | 'warning' | 'danger';\nexport interface LlmAlertSpec {\n variant?: LlmAlertVariant;\n dismissible?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Dialog\n// ---------------------------------------------------------------------------\nexport type LlmDialogSize = 'sm' | 'md' | 'lg' | 'xl' | 'full';\nexport interface LlmDialogSpec {\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n closeOnBackdrop?: boolean;\n size?: LlmDialogSize;\n}\n\n// ---------------------------------------------------------------------------\n// TabGroup / Tab\n// ---------------------------------------------------------------------------\nexport type LlmTabGroupVariant = 'default' | 'pills';\nexport interface LlmTabGroupSpec {\n selectedIndex?: number;\n onSelectedIndexChange?: (index: number) => void;\n variant?: LlmTabGroupVariant;\n}\n\nexport interface LlmTabSpec {\n label: string;\n disabled?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// AccordionGroup / AccordionItem\n// ---------------------------------------------------------------------------\nexport type LlmAccordionGroupVariant = 'default' | 'bordered' | 'separated';\nexport interface LlmAccordionGroupSpec {\n multi?: boolean;\n variant?: LlmAccordionGroupVariant;\n}\n\nexport interface LlmAccordionItemSpec {\n expanded?: boolean;\n onExpandedChange?: (expanded: boolean) => void;\n disabled?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Menu / MenuItem\n// ---------------------------------------------------------------------------\nexport type LlmMenuVariant = 'default' | 'compact';\nexport interface LlmMenuSpec {\n variant?: LlmMenuVariant;\n}\n\nexport interface LlmMenuItemSpec {\n disabled?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Tooltip\n// ---------------------------------------------------------------------------\nexport type LlmTooltipPosition = 'above' | 'below' | 'left' | 'right';\nexport interface LlmTooltipSpec {\n llmTooltip: string;\n llmTooltipPosition?: LlmTooltipPosition;\n llmTooltipDisabled?: boolean;\n llmTooltipShowDelay?: number;\n llmTooltipHideDelay?: number;\n}\n\n// ---------------------------------------------------------------------------\n// Toast\n// ---------------------------------------------------------------------------\nexport type LlmToastVariant = 'default' | 'success' | 'warning' | 'danger' | 'info';\nexport type LlmToastContainerPosition =\n | 'top-right'\n | 'top-center'\n | 'bottom-right'\n | 'bottom-center';\nexport interface LlmToastOptions {\n variant?: LlmToastVariant;\n duration?: number;\n dismissible?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Skeleton\n// ---------------------------------------------------------------------------\nexport type LlmSkeletonVariant = 'text' | 'circular' | 'rectangular';\nexport interface LlmSkeletonSpec {\n variant?: LlmSkeletonVariant;\n width?: string;\n height?: string;\n animated?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Breadcrumbs / BreadcrumbItem\n// ---------------------------------------------------------------------------\nexport interface LlmBreadcrumbsSpec {\n separator?: string;\n}\n\nexport interface LlmBreadcrumbItemSpec {\n href?: string;\n current?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Pagination\n// ---------------------------------------------------------------------------\nexport interface LlmPaginationSpec {\n page?: number;\n pageCount?: number;\n siblingCount?: number;\n showFirstLast?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Progress\n// ---------------------------------------------------------------------------\nexport type LlmProgressVariant = 'default' | 'success' | 'warning' | 'danger';\nexport type LlmProgressSize = 'sm' | 'md' | 'lg';\nexport interface LlmProgressSpec {\n value?: number;\n max?: number;\n variant?: LlmProgressVariant;\n size?: LlmProgressSize;\n indeterminate?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Drawer\n// ---------------------------------------------------------------------------\nexport type LlmDrawerPosition = 'left' | 'right' | 'top' | 'bottom';\nexport type LlmDrawerSize = 'sm' | 'md' | 'lg' | 'full';\nexport interface LlmDrawerSpec {\n open?: boolean;\n position?: LlmDrawerPosition;\n size?: LlmDrawerSize;\n closeOnBackdrop?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Table\n// ---------------------------------------------------------------------------\nexport type LlmTableVariant = 'default' | 'striped' | 'bordered';\nexport type LlmTableSize = 'sm' | 'md' | 'lg';\nexport type LlmSortDirection = 'asc' | 'desc' | null;\nexport type LlmTableAlign = 'start' | 'center' | 'end';\n\nexport interface LlmTableSpec {\n variant?: LlmTableVariant;\n size?: LlmTableSize;\n stickyHeader?: boolean;\n}\n\nexport interface LlmTbodySpec {\n empty?: boolean;\n colSpan?: number;\n}\n\nexport interface LlmTrSpec {\n selected?: boolean;\n selectable?: boolean;\n rowId?: string;\n}\n\nexport interface LlmThSpec {\n sortable?: boolean;\n sortDirection?: LlmSortDirection;\n align?: LlmTableAlign;\n width?: string;\n}\n\nexport interface LlmTdSpec {\n align?: LlmTableAlign;\n}\n\n// ---------------------------------------------------------------------------\n// Chat (AI surface)\n// ---------------------------------------------------------------------------\nexport type LlmChatVariant = 'drawer' | 'popup' | 'inline';\nexport type LlmChatStatus = 'idle' | 'streaming' | 'error';\nexport type LlmChatMessageRole = 'user' | 'assistant' | 'system';\n\nexport interface LlmChatMessageSpec {\n id: string;\n role: LlmChatMessageRole;\n content: string;\n failed?: boolean;\n}\n\nexport interface LlmChatSuggestionSpec {\n id: string;\n label: string;\n hint?: string;\n}\n\nexport interface LlmChatSpec {\n variant?: LlmChatVariant;\n status?: LlmChatStatus;\n open?: boolean;\n}\n"]}
|