@neuronection/assistant-ui 0.29.1 → 0.31.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,36 @@
1
1
  # @neuronection/assistant-ui
2
2
 
3
+ ## 0.31.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`f25f3ef`](https://github.com/neuronection/assistant-ui/commit/f25f3ef0d22d72fb09918af1e050ffe28d53e71a) Thanks [@constLiakos](https://github.com/constLiakos)! - ProviderForm gains a controlled preset-catalog select (`presets`,
8
+ `presetKey`, `onPresetChange`, `presetLabel`, `customPresetLabel` +
9
+ `ProviderPresetOption` and `CUSTOM_PRESET_KEY` exports) so both family apps
10
+ render the same provider catalog picker; the catalog data itself stays
11
+ app-side (ADR-006). New `@neuronection/assistant-ui/countries` subpath
12
+ exports the shared ISO country list (`COUNTRIES`, `CountryOption`,
13
+ `getCountryFlag`) for data-residency pickers.
14
+
15
+ ## 0.30.0
16
+
17
+ ### Minor Changes
18
+
19
+ - [`815aecb`](https://github.com/neuronection/assistant-ui/commit/815aecbbbde173d2b569a2552d1773d7eaca84c2) Thanks [@constLiakos](https://github.com/constLiakos)! - ChatComposer: the input row now exposes styling hooks —
20
+ `data-as="chat-composer-row"` plus a `data-multiline` attribute that is
21
+ present whenever the auto-growing textarea renders more than one line
22
+ (measured in the same layout pass as the auto-grow height). Layout stays
23
+ unchanged by default; apps opt in via the hook (first consumer:
24
+ desktop-assistant wraps the toolbars into a footer row under the
25
+ full-width textarea once a draft is multiline).
26
+
27
+ - [`068b817`](https://github.com/neuronection/assistant-ui/commit/068b8174e2701a20d9b4beae411127cbaf0f826c) Thanks [@constLiakos](https://github.com/constLiakos)! - ChatLauncher: new `showClose` prop (default `true`). Set it to `false`
28
+ when the panel body renders its own header actions — the overlaid
29
+ close button pinned to the panel's top-right corner intercepted clicks
30
+ meant for top-right header buttons (career's bubble panel: the
31
+ "New chat" action was unclickable with a mouse). Compose the close
32
+ into the header actions via `onOpenChange(false)` instead.
33
+
3
34
  ## 0.29.1
4
35
 
5
36
  ### Patch Changes
package/README.md CHANGED
@@ -91,7 +91,7 @@ Visual reference: [gallery](https://neuronection.github.io/assistant-ui/).
91
91
  | [`chat-core`](./docs/components/chat-core.md) | `useChatStream` (transport-injected live-turn state machine), `liveTurnReducer`, `ChatMessageView`, family `ChatStreamEvent` vocabulary, branch-tree utils (`buildBranchTree`, `walkActivePath`, `variantInfo`) | [stories](https://neuronection.github.io/assistant-ui/?story=chat-core--chat-core-story) |
92
92
  | [`chat-markdown`](./docs/components/chat-markdown.md) | `MarkdownSurface` (read-only streaming markdown: GFM + KaTeX + lazy mermaid + copyable code blocks; no raw HTML) · `MarkdownCodeBlock` · `MermaidDiagram` | [stories](https://neuronection.github.io/assistant-ui/?story=chat-markdown--default) |
93
93
  | [`chat-message`](./docs/components/chat-message.md) / [`chat-reasoning`](./docs/components/chat-reasoning.md) / [`chat-tool-card`](./docs/components/chat-tool-card.md) / [`chat-turn-status`](./docs/components/chat-turn-status.md) | `ChatMessage` (bubble: actions row, variant switcher, edit-and-resend, error/interrupted states) · `ChatReasoning` (collapsible thinking block) · `ChatToolCard` (tool observation: status, duration, args/result, app-provided result views via `renderResult`) · `ChatTurnStatus` (live pre-text turn status: dots, phase label, elapsed timer) | [stories](https://neuronection.github.io/assistant-ui/?story=chat-message--assistant) |
94
- | [`chat-composer`](./docs/components/chat-composer.md) | `ChatComposer` — auto-growing IME-safe input with send/stop states, toolbar/attachment/suggestion slots, drag-drop + paste wiring | [stories](https://neuronection.github.io/assistant-ui/?story=chat-composer--default) |
94
+ | [`chat-composer`](./docs/components/chat-composer.md) | `ChatComposer` — auto-growing IME-safe input with send/stop states, toolbar/attachment/suggestion slots, drag-drop + paste wiring, `data-multiline` row styling hook | [stories](https://neuronection.github.io/assistant-ui/?story=chat-composer--default) |
95
95
  | [`chat-transcript`](./docs/components/chat-transcript.md) / [`chat-branch-tree`](./docs/components/chat-branch-tree.md) / [`chat-session-list`](./docs/components/chat-session-list.md) | `ChatTranscript` (log semantics, polite announcements, stick-to-bottom + jump pill, optional virtualization) · `ChatBranchTree` (OpenWebUI-style branch rail, keyboard tree nav) · `ChatSessionList` (fuzzy search, date groups, row actions) | [stories](https://neuronection.github.io/assistant-ui/?story=chat-surfaces--transcript) |
96
96
  | [`chat-panel`](./docs/components/chat-panel.md) / [`chat-drawer`](./docs/components/chat-drawer.md) / [`chat-launcher`](./docs/components/chat-launcher.md) | the three chat surfaces from one assembly — `ChatPanel` host (`page` \| `sidebar` \| `bubble`) · `ChatDrawer` (resizable sidepanel on Radix Dialog, keyboard resize) · `ChatLauncher` (floating bubble → anchored panel, badge) | [stories](https://neuronection.github.io/assistant-ui/?story=chat-surfaces--transcript) |
97
97
  | [`chat-tools-catalog`](./docs/components/chat-tools-catalog.md) | `ChatToolsCatalog` — searchable disclosure catalog of the tools an assistant can use (name, title, scope, arguments, example, response); fetching stays app-side | [stories](https://neuronection.github.io/assistant-ui/?story=chat-tools-catalog--default) |
@@ -1,3 +1,3 @@
1
- export { ChatComposer } from './chunk-743FJDRA.js';
1
+ export { ChatComposer } from './chunk-IN6ORI3V.js';
2
2
  //# sourceMappingURL=chat-composer.js.map
3
3
  //# sourceMappingURL=chat-composer.js.map
@@ -14,6 +14,14 @@ interface ChatLauncherProps {
14
14
  closeIcon?: LucideIcon;
15
15
  /** Unread / activity badge. */
16
16
  badge?: number | string;
17
+ /**
18
+ * Render the floating close button pinned to the panel's top-right
19
+ * corner (default). Turn this off when the panel body renders its own
20
+ * header actions — an overlaid close intercepts clicks meant for
21
+ * top-right header buttons; compose the close into those actions
22
+ * (calling `onOpenChange(false)`) instead.
23
+ */
24
+ showClose?: boolean;
17
25
  container?: HTMLElement | null;
18
26
  panelClassName?: string;
19
27
  className?: string;
@@ -1,3 +1,3 @@
1
- export { ChatLauncher } from './chunk-RPLEI6LQ.js';
1
+ export { ChatLauncher } from './chunk-OUJJLZ6C.js';
2
2
  //# sourceMappingURL=chat-launcher.js.map
3
3
  //# sourceMappingURL=chat-launcher.js.map
@@ -4,6 +4,7 @@ import * as React from 'react';
4
4
  import { KeyRound, House, Building2 } from 'lucide-react';
5
5
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
6
6
 
7
+ var CUSTOM_PRESET_KEY = "custom";
7
8
  var ProviderForm = React.forwardRef(
8
9
  function ProviderForm2({
9
10
  name,
@@ -20,6 +21,11 @@ var ProviderForm = React.forwardRef(
20
21
  apiKeyLabel = "API key",
21
22
  apiKeyHelp,
22
23
  hasStoredKey = false,
24
+ presets,
25
+ presetKey = "",
26
+ onPresetChange,
27
+ presetLabel = "Provider",
28
+ customPresetLabel = "Custom\u2026",
23
29
  showLocationKind = false,
24
30
  locationKind = "cloud",
25
31
  onLocationKindChange,
@@ -47,6 +53,21 @@ var ProviderForm = React.forwardRef(
47
53
  className: cn("flex w-full flex-col gap-4", className),
48
54
  ...props,
49
55
  children: [
56
+ presets && presets.length > 0 && onPresetChange ? /* @__PURE__ */ jsxs("label", { className: "block space-y-1 text-sm", children: [
57
+ /* @__PURE__ */ jsx("span", { className: "text-sm font-medium text-[var(--as-fg)]", children: presetLabel }),
58
+ /* @__PURE__ */ jsxs(
59
+ "select",
60
+ {
61
+ value: presetKey,
62
+ onChange: (event) => onPresetChange(event.target.value),
63
+ className: "w-full rounded-[var(--as-radius)] border border-[var(--as-border)] bg-[var(--as-surface)] px-3 py-2 text-sm text-[var(--as-fg)]",
64
+ children: [
65
+ presets.map((preset) => /* @__PURE__ */ jsx("option", { value: preset.key, children: preset.name }, preset.key)),
66
+ /* @__PURE__ */ jsx("option", { value: CUSTOM_PRESET_KEY, children: customPresetLabel })
67
+ ]
68
+ }
69
+ )
70
+ ] }) : null,
50
71
  /* @__PURE__ */ jsx(
51
72
  Input,
52
73
  {
@@ -140,6 +161,6 @@ var ProviderForm = React.forwardRef(
140
161
  }
141
162
  );
142
163
 
143
- export { ProviderForm };
144
- //# sourceMappingURL=chunk-4WDXLXHL.js.map
145
- //# sourceMappingURL=chunk-4WDXLXHL.js.map
164
+ export { CUSTOM_PRESET_KEY, ProviderForm };
165
+ //# sourceMappingURL=chunk-HT5633F3.js.map
166
+ //# sourceMappingURL=chunk-HT5633F3.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/provider-form/ProviderForm.tsx"],"names":["ProviderForm"],"mappings":"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","file":"chunk-HT5633F3.js","sourcesContent":["import * as React from 'react'\nimport { Building2, House, KeyRound } from 'lucide-react'\nimport { cn } from '../../lib/utils'\nimport { Input } from '../input/Input'\n\n/** One entry of the app's provider catalog (ADR-006: the catalog lives in\n * the app/backend — the form only renders the picker and reports the key). */\nexport interface ProviderPresetOption {\n key: string\n name: string\n /** Local/on-premise preset — apps may default the hosting toggle from it. */\n local?: boolean\n}\n\n/** Reserved key of the built-in \"custom\" preset entry (never a catalog key). */\nexport const CUSTOM_PRESET_KEY = 'custom'\n\nexport interface ProviderFormProps extends React.ComponentProps<'div'> {\n name: string\n onNameChange: (value: string) => void\n baseUrl: string\n onBaseUrlChange: (value: string) => void\n apiKey: string\n onApiKeyChange: (value: string) => void\n namePlaceholder?: string\n baseUrlPlaceholder?: string\n nameLabel?: string\n baseUrlLabel?: string\n /** Hide the base URL field for provider types that have a fixed endpoint. */\n hideBaseUrl?: boolean\n apiKeyLabel?: string\n /** Optional preset catalog select — render only when `presets` is non-empty. */\n presets?: ProviderPresetOption[]\n presetKey?: string\n onPresetChange?: (key: string) => void\n presetLabel?: string\n customPresetLabel?: string\n /** Optional Local/Cloud toggle — render only when `showLocationKind`. */\n showLocationKind?: boolean\n locationKind?: 'local' | 'cloud'\n onLocationKindChange?: (kind: 'local' | 'cloud') => void\n locationLabel?: string\n localLabel?: string\n cloudLabel?: string\n /** Optional country select — render only when `showCountry`. */\n showCountry?: boolean\n country?: string\n onCountryChange?: (country: string) => void\n countryLabel?: string\n countryOptions?: { value: string; label: string }[]\n countryPlaceholder?: string\n /** Hint under the key field; apps mention keyring storage here. */\n apiKeyHelp?: string\n /** The provider already stores a key (write-only field shows no value). */\n hasStoredKey?: boolean\n storedKeyLabel?: string\n keyPlaceholder?: string\n error?: string\n children?: React.ReactNode\n}\n\n/**\n * Standard provider credential fields: name, base URL and a **write-only**\n * masked API key (`onChange` only — the library never renders a stored key;\n * keyring/storage is the app's business, ADR-006).\n */\nexport const ProviderForm = React.forwardRef<HTMLDivElement, ProviderFormProps>(\n function ProviderForm(\n {\n name,\n onNameChange,\n baseUrl,\n onBaseUrlChange,\n apiKey,\n onApiKeyChange,\n namePlaceholder = 'Provider name',\n baseUrlPlaceholder = 'https://api.example.com/v1',\n nameLabel = 'Name',\n baseUrlLabel = 'API base URL',\n hideBaseUrl = false,\n apiKeyLabel = 'API key',\n apiKeyHelp,\n hasStoredKey = false,\n presets,\n presetKey = '',\n onPresetChange,\n presetLabel = 'Provider',\n customPresetLabel = 'Custom…',\n showLocationKind = false,\n locationKind = 'cloud',\n onLocationKindChange,\n locationLabel = 'Hosting',\n localLabel = 'Local / on-premise',\n cloudLabel = 'Cloud',\n showCountry = false,\n country,\n onCountryChange,\n countryLabel = 'Country',\n countryOptions = [],\n countryPlaceholder = 'Select a country…',\n storedKeyLabel = 'Stored — leave empty to keep',\n keyPlaceholder = 'sk-…',\n error,\n children,\n className,\n ...props\n },\n ref,\n ) {\n return (\n <div\n ref={ref}\n data-as=\"provider-form\"\n className={cn('flex w-full flex-col gap-4', className)}\n {...props}\n >\n {presets && presets.length > 0 && onPresetChange ? (\n <label className=\"block space-y-1 text-sm\">\n <span className=\"text-sm font-medium text-[var(--as-fg)]\">{presetLabel}</span>\n <select\n value={presetKey}\n onChange={(event) => onPresetChange(event.target.value)}\n className=\"w-full rounded-[var(--as-radius)] border border-[var(--as-border)] bg-[var(--as-surface)] px-3 py-2 text-sm text-[var(--as-fg)]\"\n >\n {presets.map((preset) => (\n <option key={preset.key} value={preset.key}>\n {preset.name}\n </option>\n ))}\n <option value={CUSTOM_PRESET_KEY}>{customPresetLabel}</option>\n </select>\n </label>\n ) : null}\n <Input\n label={nameLabel}\n value={name}\n onChange={(event) => onNameChange(event.target.value)}\n placeholder={namePlaceholder}\n />\n {hideBaseUrl ? null : (\n <Input\n label={baseUrlLabel}\n value={baseUrl}\n onChange={(event) => onBaseUrlChange(event.target.value)}\n placeholder={baseUrlPlaceholder}\n className=\"font-mono\"\n />\n )}\n <Input\n label={\n hasStoredKey ? (\n <>\n {apiKeyLabel}{' '}\n <span className=\"font-normal text-[var(--as-muted-fg)]\">\n ({storedKeyLabel})\n </span>\n </>\n ) : (\n apiKeyLabel\n )\n }\n type=\"password\"\n value={apiKey}\n onChange={(event) => onApiKeyChange(event.target.value)}\n placeholder={hasStoredKey ? '•••' : keyPlaceholder}\n autoComplete=\"new-password\"\n hint={\n apiKeyHelp ? (\n <span className=\"inline-flex items-center gap-1\">\n <KeyRound className=\"size-3\" aria-hidden />\n {apiKeyHelp}\n </span>\n ) : undefined\n }\n />\n {showLocationKind && onLocationKindChange ? (\n <div className=\"space-y-1\">\n <span className=\"text-sm font-medium text-[var(--as-fg)]\">{locationLabel}</span>\n <div className=\"flex gap-2\" role=\"group\" aria-label={locationLabel}>\n {(\n [\n { kind: 'local' as const, label: localLabel, Icon: House },\n { kind: 'cloud' as const, label: cloudLabel, Icon: Building2 },\n ]\n ).map(({ kind, label, Icon }) => {\n const on = locationKind === kind\n return (\n <button\n key={kind}\n type=\"button\"\n data-as-location={kind}\n aria-pressed={on}\n onClick={() => onLocationKindChange(kind)}\n className={cn(\n 'flex flex-1 cursor-pointer items-center justify-center gap-1.5 rounded-[var(--as-radius)] border px-3 py-2 text-xs font-semibold transition-all',\n 'focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-[var(--as-focus-ring)]',\n on\n ? 'border-[var(--as-primary)]/30 bg-[var(--as-primary)]/10 text-[var(--as-primary)] shadow-[var(--as-shadow-1)]'\n : 'border-[var(--as-border)] bg-[var(--as-surface)] text-[var(--as-muted-fg)] hover:border-[var(--as-muted-fg)]/40',\n )}\n >\n <Icon className=\"size-3.5\" aria-hidden />\n {label}\n </button>\n )\n })}\n </div>\n </div>\n ) : null}\n {showCountry && onCountryChange ? (\n <label className=\"block space-y-1 text-sm\">\n <span className=\"text-sm font-medium text-[var(--as-fg)]\">{countryLabel}</span>\n <select\n value={country ?? ''}\n onChange={(event) => onCountryChange(event.target.value)}\n className=\"w-full rounded-[var(--as-radius)] border border-[var(--as-border)] bg-[var(--as-surface)] px-3 py-2 text-sm text-[var(--as-fg)]\"\n >\n <option value=\"\">{countryPlaceholder}</option>\n {countryOptions.map((option) => (\n <option key={option.value} value={option.value}>\n {option.label}\n </option>\n ))}\n </select>\n </label>\n ) : null}\n {children}\n {error ? (\n <p role=\"alert\" className=\"text-sm font-medium text-[var(--as-danger)]\">\n {error}\n </p>\n ) : null}\n </div>\n )\n },\n)\n"]}
@@ -29,6 +29,7 @@ var ChatComposer = React.forwardRef(
29
29
  }, ref) {
30
30
  const internalTextareaRef = React.useRef(null);
31
31
  const [dragging, setDragging] = React.useState(false);
32
+ const [multiline, setMultiline] = React.useState(false);
32
33
  const dragDepth = React.useRef(0);
33
34
  const setTextarea = (element) => {
34
35
  internalTextareaRef.current = element;
@@ -47,6 +48,10 @@ var ChatComposer = React.forwardRef(
47
48
  const cap = maxRows * 22;
48
49
  element.style.height = element.scrollHeight > 0 ? `${Math.min(element.scrollHeight, cap)}px` : "auto";
49
50
  element.style.overflowY = element.scrollHeight > cap ? "auto" : "hidden";
51
+ const style = window.getComputedStyle(element);
52
+ const lineHeight = Number.parseFloat(style.lineHeight) || 22;
53
+ const verticalPadding = (Number.parseFloat(style.paddingTop) || 0) + (Number.parseFloat(style.paddingBottom) || 0);
54
+ setMultiline(element.scrollHeight > lineHeight + verticalPadding + 1);
50
55
  }, [value, maxRows]);
51
56
  const submit = () => {
52
57
  if (disabled || sending) {
@@ -124,6 +129,8 @@ var ChatComposer = React.forwardRef(
124
129
  /* @__PURE__ */ jsxs(
125
130
  "div",
126
131
  {
132
+ "data-as": "chat-composer-row",
133
+ "data-multiline": multiline || void 0,
127
134
  "data-dragging": dragging || void 0,
128
135
  className: cn(
129
136
  "flex items-end gap-1.5 rounded-[var(--as-radius-lg)] border border-[var(--as-border)] bg-[var(--as-surface)] px-2 py-1.5 transition-colors focus-within:border-[var(--as-primary)]",
@@ -180,5 +187,5 @@ var ChatComposer = React.forwardRef(
180
187
  );
181
188
 
182
189
  export { ChatComposer };
183
- //# sourceMappingURL=chunk-743FJDRA.js.map
184
- //# sourceMappingURL=chunk-743FJDRA.js.map
190
+ //# sourceMappingURL=chunk-IN6ORI3V.js.map
191
+ //# sourceMappingURL=chunk-IN6ORI3V.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/chat-composer/ChatComposer.tsx"],"names":["ChatComposer"],"mappings":"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","file":"chunk-IN6ORI3V.js","sourcesContent":["import * as React from 'react'\nimport { ArrowUp, Square } from 'lucide-react'\nimport type { LucideIcon } from 'lucide-react'\n\nimport { cn } from '../../lib/utils'\n\nexport interface ChatComposerLabels {\n send: string\n stop: string\n placeholder: string\n ariaLabel: string\n dropFiles: string\n}\n\nexport interface ChatComposerIcons {\n send: LucideIcon\n stop: LucideIcon\n}\n\nexport interface ChatComposerProps {\n value: string\n onValueChange: (value: string) => void\n /** Enter / Send — IME-safe (composition and keyCode 229 are ignored). */\n onSubmit: () => void\n /** A turn is in flight — renders the stop control when `onStop` is provided. */\n sending?: boolean\n onStop?: () => void\n disabled?: boolean\n placeholder?: string\n ariaLabel?: string\n /** Auto-grow cap before the textarea scrolls. Default 8. */\n maxRows?: number\n /** Leading slot inside the input row (attach menu, equation, draw…). */\n toolbarStart?: React.ReactNode\n /** Trailing slot inside the input row (dictation, tools…). */\n toolbarEnd?: React.ReactNode\n /** Attachment rail above the input (usually `FileQueue` / chips). */\n attachments?: React.ReactNode\n /** Suggestion chips / context strip above everything. */\n suggestions?: React.ReactNode\n /** Drag-drop + paste wiring for file attachments. */\n onAttachFiles?: (files: File[]) => void\n labels?: Partial<ChatComposerLabels>\n icons?: Partial<ChatComposerIcons>\n textareaRef?: React.Ref<HTMLTextAreaElement>\n className?: string\n}\n\nfunction isIMEComposition(event: React.KeyboardEvent<HTMLTextAreaElement>): boolean {\n return event.nativeEvent.isComposing || event.keyCode === 229\n}\n\n/**\n * The family chat input: auto-growing IME-safe textarea, send/stop\n * states, attachment/dictation/toolbar slots, drag-drop + paste file\n * wiring. Presentational + controlled; transports stay app-side.\n */\nexport const ChatComposer = React.forwardRef<HTMLFormElement, ChatComposerProps>(\n function ChatComposer(\n {\n value,\n onValueChange,\n onSubmit,\n sending = false,\n onStop,\n disabled = false,\n placeholder,\n ariaLabel,\n maxRows = 8,\n toolbarStart,\n toolbarEnd,\n attachments,\n suggestions,\n onAttachFiles,\n labels,\n icons,\n textareaRef,\n className,\n },\n ref,\n ) {\n const internalTextareaRef = React.useRef<HTMLTextAreaElement | null>(null)\n const [dragging, setDragging] = React.useState(false)\n const [multiline, setMultiline] = React.useState(false)\n const dragDepth = React.useRef(0)\n\n const setTextarea = (element: HTMLTextAreaElement | null) => {\n internalTextareaRef.current = element\n if (typeof textareaRef === 'function') {\n textareaRef(element)\n } else if (textareaRef && typeof textareaRef === 'object') {\n ;(textareaRef as React.MutableRefObject<HTMLTextAreaElement | null>).current = element\n }\n }\n\n React.useLayoutEffect(() => {\n const element = internalTextareaRef.current\n if (element === null) {\n return\n }\n element.style.height = 'auto'\n const cap = maxRows * 22\n element.style.height = element.scrollHeight > 0 ? `${Math.min(element.scrollHeight, cap)}px` : 'auto'\n element.style.overflowY = element.scrollHeight > cap ? 'auto' : 'hidden'\n const style = window.getComputedStyle(element)\n const lineHeight = Number.parseFloat(style.lineHeight) || 22\n const verticalPadding =\n (Number.parseFloat(style.paddingTop) || 0) + (Number.parseFloat(style.paddingBottom) || 0)\n setMultiline(element.scrollHeight > lineHeight + verticalPadding + 1)\n }, [value, maxRows])\n\n const submit = () => {\n if (disabled || sending) {\n return\n }\n onSubmit()\n }\n\n const onKeyDown: React.KeyboardEventHandler<HTMLTextAreaElement> = (event) => {\n if (event.key !== 'Enter' || event.shiftKey) {\n return\n }\n if (isIMEComposition(event)) {\n return\n }\n event.preventDefault()\n submit()\n }\n\n const emitFiles = (fileList: FileList | null | undefined) => {\n const files = fileList ? Array.from(fileList) : []\n if (files.length > 0) {\n onAttachFiles?.(files)\n }\n }\n\n const dragCounterHandlers = {\n onDragEnter: (event: React.DragEvent) => {\n if (onAttachFiles === undefined || !event.dataTransfer.types.includes('Files')) {\n return\n }\n event.preventDefault()\n dragDepth.current += 1\n setDragging(true)\n },\n onDragOver: (event: React.DragEvent) => {\n if (onAttachFiles === undefined || !event.dataTransfer.types.includes('Files')) {\n return\n }\n event.preventDefault()\n },\n onDragLeave: () => {\n if (dragDepth.current > 0) {\n dragDepth.current -= 1\n if (dragDepth.current === 0) {\n setDragging(false)\n }\n }\n },\n onDrop: (event: React.DragEvent) => {\n if (onAttachFiles === undefined) {\n return\n }\n event.preventDefault()\n dragDepth.current = 0\n setDragging(false)\n emitFiles(event.dataTransfer.files)\n },\n }\n\n const SendIcon = icons?.send ?? ArrowUp\n const StopIcon = icons?.stop ?? Square\n const showStop = sending && onStop !== undefined\n\n return (\n <form\n ref={ref}\n data-as=\"chat-composer\"\n data-sending={sending}\n onSubmit={(event) => {\n event.preventDefault()\n submit()\n }}\n className={cn('flex w-full flex-col gap-2', className)}\n {...dragCounterHandlers}\n >\n {suggestions ? <div className=\"flex flex-wrap gap-1.5\">{suggestions}</div> : null}\n {attachments ? <div className=\"flex flex-wrap gap-1.5\">{attachments}</div> : null}\n <div\n data-as=\"chat-composer-row\"\n data-multiline={multiline || undefined}\n data-dragging={dragging || undefined}\n className={cn(\n 'flex items-end gap-1.5 rounded-[var(--as-radius-lg)] border border-[var(--as-border)] bg-[var(--as-surface)] px-2 py-1.5 transition-colors focus-within:border-[var(--as-primary)]',\n dragging && 'border-dashed border-[var(--as-primary)] bg-[var(--as-primary)]/5',\n disabled && 'opacity-50',\n )}\n >\n {toolbarStart ? <div className=\"flex shrink-0 items-center gap-0.5 pb-0.5\">{toolbarStart}</div> : null}\n <textarea\n ref={setTextarea}\n value={value}\n rows={1}\n disabled={disabled}\n placeholder={placeholder ?? labels?.placeholder ?? 'Send a message…'}\n aria-label={ariaLabel ?? labels?.ariaLabel ?? 'Message'}\n onChange={(event) => onValueChange(event.target.value)}\n onKeyDown={onKeyDown}\n onPaste={(event) => emitFiles(event.clipboardData.files)}\n className=\"max-h-40 min-h-[1.5rem] w-full flex-1 resize-none bg-transparent px-1 py-1 text-sm leading-relaxed text-[var(--as-fg)] placeholder:text-[var(--as-muted-fg)] focus-visible:outline-none disabled:cursor-not-allowed\"\n />\n {toolbarEnd ? <div className=\"flex shrink-0 items-center gap-0.5 pb-0.5\">{toolbarEnd}</div> : null}\n {showStop ? (\n <button\n type=\"button\"\n aria-label={labels?.stop ?? 'Stop generating'}\n title={labels?.stop ?? 'Stop generating'}\n onClick={onStop}\n className=\"mb-0.5 flex size-7 shrink-0 items-center justify-center rounded-full border border-[var(--as-border)] bg-[var(--as-surface-raised)] text-[var(--as-fg)] transition-colors hover:bg-[var(--as-secondary)] focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-[var(--as-focus-ring)]\"\n >\n <StopIcon className=\"size-3.5\" aria-hidden />\n </button>\n ) : (\n <button\n type=\"submit\"\n aria-label={labels?.send ?? 'Send message'}\n title={labels?.send ?? 'Send message'}\n disabled={disabled || value.trim() === '' || sending}\n className=\"mb-0.5 flex size-7 shrink-0 items-center justify-center rounded-full bg-[var(--as-primary)] text-[var(--as-primary-fg)] transition-opacity hover:opacity-90 disabled:pointer-events-none disabled:opacity-30 focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-[var(--as-focus-ring)]\"\n >\n <SendIcon className=\"size-4\" aria-hidden />\n </button>\n )}\n </div>\n {dragging && onAttachFiles ? (\n <p className=\"text-xs text-[var(--as-muted-fg)]\" role=\"status\">\n {labels?.dropFiles ?? 'Drop files to attach'}\n </p>\n ) : null}\n </form>\n )\n },\n)\n"]}
@@ -16,6 +16,7 @@ var ChatLauncher = React.forwardRef(
16
16
  icon: Icon = MessageCircle,
17
17
  closeIcon: CloseIcon = X,
18
18
  badge,
19
+ showClose = true,
19
20
  container,
20
21
  panelClassName,
21
22
  className
@@ -58,7 +59,7 @@ var ChatLauncher = React.forwardRef(
58
59
  "aria-label": label,
59
60
  children: [
60
61
  panel,
61
- /* @__PURE__ */ jsx(
62
+ showClose ? /* @__PURE__ */ jsx(
62
63
  "button",
63
64
  {
64
65
  type: "button",
@@ -67,7 +68,7 @@ var ChatLauncher = React.forwardRef(
67
68
  className: "absolute right-2 top-2 z-10 rounded-[var(--as-radius-sm)] p-1 text-[var(--as-muted-fg)] transition-colors hover:bg-[var(--as-secondary)] hover:text-[var(--as-fg)] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--as-focus-ring)]",
68
69
  children: /* @__PURE__ */ jsx(CloseIcon, { "aria-hidden": true, className: "size-4" })
69
70
  }
70
- )
71
+ ) : null
71
72
  ]
72
73
  }
73
74
  ) }) : null,
@@ -98,5 +99,5 @@ var ChatLauncher = React.forwardRef(
98
99
  );
99
100
 
100
101
  export { ChatLauncher };
101
- //# sourceMappingURL=chunk-RPLEI6LQ.js.map
102
- //# sourceMappingURL=chunk-RPLEI6LQ.js.map
102
+ //# sourceMappingURL=chunk-OUJJLZ6C.js.map
103
+ //# sourceMappingURL=chunk-OUJJLZ6C.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/chat-launcher/ChatLauncher.tsx"],"names":["ChatLauncher"],"mappings":";;;;;;AAsCO,IAAM,YAAA,GAAqB,KAAA,CAAA,UAAA;AAAA,EAChC,SAASA,aAAAA,CACP;AAAA,IACE,KAAA;AAAA,IACA,IAAA,EAAM,QAAA;AAAA,IACN,WAAA,GAAc,KAAA;AAAA,IACd,YAAA;AAAA,IACA,QAAA,GAAW,cAAA;AAAA,IACX,KAAA,GAAQ,MAAA;AAAA,IACR,UAAA,GAAa,YAAA;AAAA,IACb,MAAM,IAAA,GAAO,aAAA;AAAA,IACb,WAAW,SAAA,GAAY,CAAA;AAAA,IACvB,KAAA;AAAA,IACA,SAAA,GAAY,IAAA;AAAA,IACZ,SAAA;AAAA,IACA,cAAA;AAAA,IACA;AAAA,KAEF,GAAA,EACA;AACA,IAAA,MAAM,CAAC,gBAAA,EAAkB,mBAAmB,CAAA,GAAU,eAAS,WAAW,CAAA;AAC1E,IAAA,MAAM,eAAe,QAAA,KAAa,MAAA;AAClC,IAAA,MAAM,IAAA,GAAO,eAAe,QAAA,GAAW,gBAAA;AACvC,IAAA,MAAM,QAAA,GAAiB,aAA8B,IAAI,CAAA;AAEzD,IAAA,MAAM,OAAA,GAAU,CAAC,IAAA,KAAkB;AACjC,MAAA,IAAI,CAAC,YAAA,EAAc;AACjB,QAAA,mBAAA,CAAoB,IAAI,CAAA;AAAA,MAC1B;AACA,MAAA,YAAA,GAAe,IAAI,CAAA;AAAA,IACrB,CAAA;AAEA,IAAM,gBAAU,MAAM;AACpB,MAAA,IAAI,CAAC,IAAA,EAAM;AACT,QAAA;AAAA,MACF;AACA,MAAA,MAAM,SAAA,GAAY,CAAC,KAAA,KAAyB;AAC1C,QAAA,IAAI,KAAA,CAAM,QAAQ,QAAA,IAAY,QAAA,CAAS,SAAS,QAAA,CAAS,QAAA,CAAS,aAAa,CAAA,EAAG;AAChF,UAAA,OAAA,CAAQ,KAAK,CAAA;AAAA,QACf;AAAA,MACF,CAAA;AACA,MAAA,QAAA,CAAS,gBAAA,CAAiB,WAAW,SAAS,CAAA;AAC9C,MAAA,OAAO,MAAM,QAAA,CAAS,mBAAA,CAAoB,SAAA,EAAW,SAAS,CAAA;AAAA,IAChE,CAAC,CAAA;AAED,IAAA,MAAM,SAAA,GAAY,KAAA,KAAU,MAAA,IAAa,KAAA,KAAU,KAAK,KAAA,KAAU,EAAA;AAElE,IAAA,uBACE,IAAA,CAAA,QAAA,EAAA,EACG,QAAA,EAAA;AAAA,MAAA,IAAA,mBACC,GAAA,CAAC,UAAO,SAAA,EACN,QAAA,kBAAA,IAAA;AAAA,QAAC,KAAA;AAAA,QAAA;AAAA,UACC,GAAA,EAAK,QAAA;AAAA,UACL,SAAA,EAAQ,qBAAA;AAAA,UACR,SAAA,EAAW,EAAA;AAAA,YACT,yRAAA;AAAA,YACA,QAAA,KAAa,iBAAiB,SAAA,GAAY,QAAA;AAAA,YAC1C;AAAA,WACF;AAAA,UACA,IAAA,EAAK,eAAA;AAAA,UACL,YAAA,EAAY,KAAA;AAAA,UAEX,QAAA,EAAA;AAAA,YAAA,KAAA;AAAA,YACA,SAAA,mBACC,GAAA;AAAA,cAAC,QAAA;AAAA,cAAA;AAAA,gBACC,IAAA,EAAK,QAAA;AAAA,gBACL,YAAA,EAAY,UAAA;AAAA,gBACZ,OAAA,EAAS,MAAM,OAAA,CAAQ,KAAK,CAAA;AAAA,gBAC5B,SAAA,EAAU,wQAAA;AAAA,gBAEV,QAAA,kBAAA,GAAA,CAAC,SAAA,EAAA,EAAU,aAAA,EAAW,IAAA,EAAC,WAAU,QAAA,EAAS;AAAA;AAAA,aAC5C,GACE;AAAA;AAAA;AAAA,SAER,CAAA,GACE,IAAA;AAAA,sBACJ,IAAA;AAAA,QAAC,QAAA;AAAA,QAAA;AAAA,UACC,GAAA;AAAA,UACA,IAAA,EAAK,QAAA;AAAA,UACL,eAAA,EAAe,IAAA;AAAA,UACf,YAAA,EAAY,OAAO,UAAA,GAAa,KAAA;AAAA,UAChC,KAAA,EAAO,OAAO,UAAA,GAAa,KAAA;AAAA,UAC3B,OAAA,EAAS,MAAM,OAAA,CAAQ,CAAC,IAAI,CAAA;AAAA,UAC5B,SAAA,EAAQ,eAAA;AAAA,UACR,aAAW,IAAA,IAAQ,MAAA;AAAA,UACnB,SAAA,EAAW,EAAA;AAAA,YACT,sTAAA;AAAA,YACA,QAAA,KAAa,iBAAiB,SAAA,GAAY,QAAA;AAAA,YAC1C;AAAA,WACF;AAAA,UAEA,QAAA,EAAA;AAAA,4BAAA,GAAA,CAAC,IAAA,EAAA,EAAK,SAAA,EAAU,QAAA,EAAS,aAAA,EAAW,IAAA,EAAC,CAAA;AAAA,YACpC,4BACC,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,4MAAA,EACb,iBACH,CAAA,GACE;AAAA;AAAA;AAAA;AACN,KAAA,EACF,CAAA;AAAA,EAEJ;AACF","file":"chunk-OUJJLZ6C.js","sourcesContent":["import * as React from 'react'\nimport { MessageCircle, X } from 'lucide-react'\nimport type { LucideIcon } from 'lucide-react'\n\nimport { cn } from '../../lib/utils'\nimport { Portal } from '../portal/Portal'\n\nexport interface ChatLauncherProps {\n /** The anchored panel body — usually `ChatPanel variant=\"bubble\"`. */\n panel: React.ReactNode\n open?: boolean\n defaultOpen?: boolean\n onOpenChange?: (open: boolean) => void\n position?: 'bottom-right' | 'bottom-left'\n label?: string\n closeLabel?: string\n icon?: LucideIcon\n closeIcon?: LucideIcon\n /** Unread / activity badge. */\n badge?: number | string\n /**\n * Render the floating close button pinned to the panel's top-right\n * corner (default). Turn this off when the panel body renders its own\n * header actions — an overlaid close intercepts clicks meant for\n * top-right header buttons; compose the close into those actions\n * (calling `onOpenChange(false)`) instead.\n */\n showClose?: boolean\n container?: HTMLElement | null\n panelClassName?: string\n className?: string\n}\n\n/**\n * The floating chat bubble (career's `ChatWidget` launcher,\n * family-standard): fixed launcher button opening an anchored, non-modal\n * panel. `aria-expanded` wiring, Escape closes while focus is inside.\n */\nexport const ChatLauncher = React.forwardRef<HTMLButtonElement, ChatLauncherProps>(\n function ChatLauncher(\n {\n panel,\n open: openProp,\n defaultOpen = false,\n onOpenChange,\n position = 'bottom-right',\n label = 'Chat',\n closeLabel = 'Close chat',\n icon: Icon = MessageCircle,\n closeIcon: CloseIcon = X,\n badge,\n showClose = true,\n container,\n panelClassName,\n className,\n },\n ref,\n ) {\n const [uncontrolledOpen, setUncontrolledOpen] = React.useState(defaultOpen)\n const isControlled = openProp !== undefined\n const open = isControlled ? openProp : uncontrolledOpen\n const panelRef = React.useRef<HTMLDivElement | null>(null)\n\n const setOpen = (next: boolean) => {\n if (!isControlled) {\n setUncontrolledOpen(next)\n }\n onOpenChange?.(next)\n }\n\n React.useEffect(() => {\n if (!open) {\n return\n }\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape' && panelRef.current?.contains(document.activeElement)) {\n setOpen(false)\n }\n }\n document.addEventListener('keydown', onKeyDown)\n return () => document.removeEventListener('keydown', onKeyDown)\n })\n\n const showBadge = badge !== undefined && badge !== 0 && badge !== ''\n\n return (\n <>\n {open ? (\n <Portal container={container}>\n <div\n ref={panelRef}\n data-as=\"chat-launcher-panel\"\n className={cn(\n 'as-anim-pop fixed bottom-20 z-[var(--as-z-modal)] flex h-[min(36rem,calc(100dvh-11rem))] w-[min(26rem,calc(100vw-2rem))] flex-col overflow-hidden rounded-[var(--as-radius-lg)] border border-[var(--as-border)] bg-[var(--as-surface)] text-[var(--as-fg)] shadow-[var(--as-shadow-3)]',\n position === 'bottom-right' ? 'right-4' : 'left-4',\n panelClassName,\n )}\n role=\"complementary\"\n aria-label={label}\n >\n {panel}\n {showClose ? (\n <button\n type=\"button\"\n aria-label={closeLabel}\n onClick={() => setOpen(false)}\n className=\"absolute right-2 top-2 z-10 rounded-[var(--as-radius-sm)] p-1 text-[var(--as-muted-fg)] transition-colors hover:bg-[var(--as-secondary)] hover:text-[var(--as-fg)] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--as-focus-ring)]\"\n >\n <CloseIcon aria-hidden className=\"size-4\" />\n </button>\n ) : null}\n </div>\n </Portal>\n ) : null}\n <button\n ref={ref}\n type=\"button\"\n aria-expanded={open}\n aria-label={open ? closeLabel : label}\n title={open ? closeLabel : label}\n onClick={() => setOpen(!open)}\n data-as=\"chat-launcher\"\n data-open={open || undefined}\n className={cn(\n 'fixed bottom-4 z-[var(--as-z-popover)] flex size-12 items-center justify-center rounded-full bg-[var(--as-primary)] text-[var(--as-primary-fg)] shadow-[var(--as-shadow-2)] transition-transform hover:scale-105 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--as-focus-ring)]',\n position === 'bottom-right' ? 'right-4' : 'left-4',\n className,\n )}\n >\n <Icon className=\"size-5\" aria-hidden />\n {showBadge ? (\n <span className=\"absolute -right-0.5 -top-0.5 flex h-5 min-w-5 items-center justify-center rounded-full border-2 border-[var(--as-surface)] bg-[var(--as-danger)] px-1 text-[10px] font-semibold text-[var(--as-danger-fg)]\">\n {badge}\n </span>\n ) : null}\n </button>\n </>\n )\n },\n)\n"]}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Shared country catalog (ISO 3166-1 alpha-2 + English name + flag emoji)
3
+ * for provider-data-residency pickers. Data-only export (ADR-006) — apps
4
+ * render labels/translations as they see fit. Consumed via the
5
+ * `@neuronection/assistant-ui/countries` subpath.
6
+ */
7
+ interface CountryOption {
8
+ code: string;
9
+ name: string;
10
+ flag: string;
11
+ }
12
+ declare const COUNTRIES: CountryOption[];
13
+ declare const getCountryFlag: (code?: string) => string;
14
+
15
+ export { COUNTRIES, type CountryOption, getCountryFlag };
@@ -0,0 +1,124 @@
1
+ // src/lib/countries.ts
2
+ var COUNTRIES = [
3
+ { code: "AF", name: "Afghanistan", flag: "\u{1F1E6}\u{1F1EB}" },
4
+ { code: "AL", name: "Albania", flag: "\u{1F1E6}\u{1F1F1}" },
5
+ { code: "DZ", name: "Algeria", flag: "\u{1F1E9}\u{1F1FF}" },
6
+ { code: "AD", name: "Andorra", flag: "\u{1F1E6}\u{1F1E9}" },
7
+ { code: "AO", name: "Angola", flag: "\u{1F1E6}\u{1F1F4}" },
8
+ { code: "AR", name: "Argentina", flag: "\u{1F1E6}\u{1F1F7}" },
9
+ { code: "AM", name: "Armenia", flag: "\u{1F1E6}\u{1F1F2}" },
10
+ { code: "AU", name: "Australia", flag: "\u{1F1E6}\u{1F1FA}" },
11
+ { code: "AT", name: "Austria", flag: "\u{1F1E6}\u{1F1F9}" },
12
+ { code: "AZ", name: "Azerbaijan", flag: "\u{1F1E6}\u{1F1FF}" },
13
+ { code: "BS", name: "Bahamas", flag: "\u{1F1E7}\u{1F1F8}" },
14
+ { code: "BH", name: "Bahrain", flag: "\u{1F1E7}\u{1F1ED}" },
15
+ { code: "BD", name: "Bangladesh", flag: "\u{1F1E7}\u{1F1E9}" },
16
+ { code: "BE", name: "Belgium", flag: "\u{1F1E7}\u{1F1EA}" },
17
+ { code: "BZ", name: "Belize", flag: "\u{1F1E7}\u{1F1FF}" },
18
+ { code: "BJ", name: "Benin", flag: "\u{1F1E7}\u{1F1EF}" },
19
+ { code: "BT", name: "Bhutan", flag: "\u{1F1E7}\u{1F1F9}" },
20
+ { code: "BO", name: "Bolivia", flag: "\u{1F1E7}\u{1F1F4}" },
21
+ { code: "BA", name: "Bosnia and Herzegovina", flag: "\u{1F1E7}\u{1F1E6}" },
22
+ { code: "BW", name: "Botswana", flag: "\u{1F1E7}\u{1F1FC}" },
23
+ { code: "BR", name: "Brazil", flag: "\u{1F1E7}\u{1F1F7}" },
24
+ { code: "BG", name: "Bulgaria", flag: "\u{1F1E7}\u{1F1EC}" },
25
+ { code: "BF", name: "Burkina Faso", flag: "\u{1F1E7}\u{1F1EB}" },
26
+ { code: "KH", name: "Cambodia", flag: "\u{1F1F0}\u{1F1ED}" },
27
+ { code: "CM", name: "Cameroon", flag: "\u{1F1E8}\u{1F1F2}" },
28
+ { code: "CA", name: "Canada", flag: "\u{1F1E8}\u{1F1E6}" },
29
+ { code: "CL", name: "Chile", flag: "\u{1F1E8}\u{1F1F1}" },
30
+ { code: "CN", name: "China", flag: "\u{1F1E8}\u{1F1F3}" },
31
+ { code: "CO", name: "Colombia", flag: "\u{1F1E8}\u{1F1F4}" },
32
+ { code: "CR", name: "Costa Rica", flag: "\u{1F1E8}\u{1F1F7}" },
33
+ { code: "HR", name: "Croatia", flag: "\u{1F1ED}\u{1F1F7}" },
34
+ { code: "CU", name: "Cuba", flag: "\u{1F1E8}\u{1F1FA}" },
35
+ { code: "CY", name: "Cyprus", flag: "\u{1F1E8}\u{1F1FE}" },
36
+ { code: "CZ", name: "Czech Republic", flag: "\u{1F1E8}\u{1F1FF}" },
37
+ { code: "DK", name: "Denmark", flag: "\u{1F1E9}\u{1F1F0}" },
38
+ { code: "DO", name: "Dominican Republic", flag: "\u{1F1E9}\u{1F1F4}" },
39
+ { code: "EC", name: "Ecuador", flag: "\u{1F1EA}\u{1F1E8}" },
40
+ { code: "EG", name: "Egypt", flag: "\u{1F1EA}\u{1F1EC}" },
41
+ { code: "SV", name: "El Salvador", flag: "\u{1F1F8}\u{1F1FB}" },
42
+ { code: "EE", name: "Estonia", flag: "\u{1F1EA}\u{1F1EA}" },
43
+ { code: "ET", name: "Ethiopia", flag: "\u{1F1EA}\u{1F1F9}" },
44
+ { code: "FJ", name: "Fiji", flag: "\u{1F1EB}\u{1F1EF}" },
45
+ { code: "FI", name: "Finland", flag: "\u{1F1EB}\u{1F1EE}" },
46
+ { code: "FR", name: "France", flag: "\u{1F1EB}\u{1F1F7}" },
47
+ { code: "GE", name: "Georgia", flag: "\u{1F1EC}\u{1F1EA}" },
48
+ { code: "DE", name: "Germany", flag: "\u{1F1E9}\u{1F1EA}" },
49
+ { code: "GH", name: "Ghana", flag: "\u{1F1EC}\u{1F1ED}" },
50
+ { code: "GR", name: "Greece", flag: "\u{1F1EC}\u{1F1F7}" },
51
+ { code: "GT", name: "Guatemala", flag: "\u{1F1EC}\u{1F1F9}" },
52
+ { code: "HN", name: "Honduras", flag: "\u{1F1ED}\u{1F1F3}" },
53
+ { code: "HU", name: "Hungary", flag: "\u{1F1ED}\u{1F1FA}" },
54
+ { code: "IS", name: "Iceland", flag: "\u{1F1EE}\u{1F1F8}" },
55
+ { code: "IN", name: "India", flag: "\u{1F1EE}\u{1F1F3}" },
56
+ { code: "ID", name: "Indonesia", flag: "\u{1F1EE}\u{1F1E9}" },
57
+ { code: "IR", name: "Iran", flag: "\u{1F1EE}\u{1F1F7}" },
58
+ { code: "IQ", name: "Iraq", flag: "\u{1F1EE}\u{1F1F6}" },
59
+ { code: "IE", name: "Ireland", flag: "\u{1F1EE}\u{1F1EA}" },
60
+ { code: "IL", name: "Israel", flag: "\u{1F1EE}\u{1F1F1}" },
61
+ { code: "IT", name: "Italy", flag: "\u{1F1EE}\u{1F1F9}" },
62
+ { code: "JM", name: "Jamaica", flag: "\u{1F1EF}\u{1F1F2}" },
63
+ { code: "JP", name: "Japan", flag: "\u{1F1EF}\u{1F1F5}" },
64
+ { code: "JO", name: "Jordan", flag: "\u{1F1EF}\u{1F1F4}" },
65
+ { code: "KZ", name: "Kazakhstan", flag: "\u{1F1F0}\u{1F1FF}" },
66
+ { code: "KE", name: "Kenya", flag: "\u{1F1F0}\u{1F1EA}" },
67
+ { code: "KR", name: "Korea (South)", flag: "\u{1F1F0}\u{1F1F7}" },
68
+ { code: "KW", name: "Kuwait", flag: "\u{1F1F0}\u{1F1FC}" },
69
+ { code: "LV", name: "Latvia", flag: "\u{1F1F1}\u{1F1FB}" },
70
+ { code: "LB", name: "Lebanon", flag: "\u{1F1F1}\u{1F1E7}" },
71
+ { code: "LY", name: "Libya", flag: "\u{1F1F1}\u{1F1FE}" },
72
+ { code: "LT", name: "Lithuania", flag: "\u{1F1F1}\u{1F1F9}" },
73
+ { code: "LU", name: "Luxembourg", flag: "\u{1F1F1}\u{1F1FA}" },
74
+ { code: "MY", name: "Malaysia", flag: "\u{1F1F2}\u{1F1FE}" },
75
+ { code: "MT", name: "Malta", flag: "\u{1F1F2}\u{1F1F9}" },
76
+ { code: "MX", name: "Mexico", flag: "\u{1F1F2}\u{1F1FD}" },
77
+ { code: "MC", name: "Monaco", flag: "\u{1F1F2}\u{1F1E8}" },
78
+ { code: "ME", name: "Montenegro", flag: "\u{1F1F2}\u{1F1EA}" },
79
+ { code: "MA", name: "Morocco", flag: "\u{1F1F2}\u{1F1E6}" },
80
+ { code: "NL", name: "Netherlands", flag: "\u{1F1F3}\u{1F1F1}" },
81
+ { code: "NZ", name: "New Zealand", flag: "\u{1F1F3}\u{1F1FF}" },
82
+ { code: "NG", name: "Nigeria", flag: "\u{1F1F3}\u{1F1EC}" },
83
+ { code: "NO", name: "Norway", flag: "\u{1F1F3}\u{1F1F4}" },
84
+ { code: "PK", name: "Pakistan", flag: "\u{1F1F5}\u{1F1F0}" },
85
+ { code: "PA", name: "Panama", flag: "\u{1F1F5}\u{1F1E6}" },
86
+ { code: "PY", name: "Paraguay", flag: "\u{1F1F5}\u{1F1FE}" },
87
+ { code: "PE", name: "Peru", flag: "\u{1F1F5}\u{1F1EA}" },
88
+ { code: "PH", name: "Philippines", flag: "\u{1F1F5}\u{1F1ED}" },
89
+ { code: "PL", name: "Poland", flag: "\u{1F1F5}\u{1F1F1}" },
90
+ { code: "PT", name: "Portugal", flag: "\u{1F1F5}\u{1F1F9}" },
91
+ { code: "QA", name: "Qatar", flag: "\u{1F1F6}\u{1F1E6}" },
92
+ { code: "RO", name: "Romania", flag: "\u{1F1F7}\u{1F1F4}" },
93
+ { code: "RU", name: "Russia", flag: "\u{1F1F7}\u{1F1FA}" },
94
+ { code: "SA", name: "Saudi Arabia", flag: "\u{1F1F8}\u{1F1E6}" },
95
+ { code: "RS", name: "Serbia", flag: "\u{1F1F7}\u{1F1F8}" },
96
+ { code: "SG", name: "Singapore", flag: "\u{1F1F8}\u{1F1EC}" },
97
+ { code: "SK", name: "Slovakia", flag: "\u{1F1F8}\u{1F1F0}" },
98
+ { code: "SI", name: "Slovenia", flag: "\u{1F1F8}\u{1F1EE}" },
99
+ { code: "ZA", name: "South Africa", flag: "\u{1F1FF}\u{1F1E6}" },
100
+ { code: "ES", name: "Spain", flag: "\u{1F1EA}\u{1F1F8}" },
101
+ { code: "SE", name: "Sweden", flag: "\u{1F1F8}\u{1F1EA}" },
102
+ { code: "CH", name: "Switzerland", flag: "\u{1F1E8}\u{1F1ED}" },
103
+ { code: "TW", name: "Taiwan", flag: "\u{1F1F9}\u{1F1FC}" },
104
+ { code: "TH", name: "Thailand", flag: "\u{1F1F9}\u{1F1ED}" },
105
+ { code: "TN", name: "Tunisia", flag: "\u{1F1F9}\u{1F1F3}" },
106
+ { code: "TR", name: "Turkey", flag: "\u{1F1F9}\u{1F1F7}" },
107
+ { code: "UA", name: "Ukraine", flag: "\u{1F1FA}\u{1F1E6}" },
108
+ { code: "AE", name: "UAE", flag: "\u{1F1E6}\u{1F1EA}" },
109
+ { code: "UK", name: "United Kingdom", flag: "\u{1F1EC}\u{1F1E7}" },
110
+ { code: "US", name: "United States", flag: "\u{1F1FA}\u{1F1F8}" },
111
+ { code: "UY", name: "Uruguay", flag: "\u{1F1FA}\u{1F1FE}" },
112
+ { code: "UZ", name: "Uzbekistan", flag: "\u{1F1FA}\u{1F1FF}" },
113
+ { code: "VE", name: "Venezuela", flag: "\u{1F1FB}\u{1F1EA}" },
114
+ { code: "VN", name: "Vietnam", flag: "\u{1F1FB}\u{1F1F3}" }
115
+ ];
116
+ var getCountryFlag = (code) => {
117
+ if (!code) return "";
118
+ const country = COUNTRIES.find((c) => c.code === code);
119
+ return country ? country.flag : code;
120
+ };
121
+
122
+ export { COUNTRIES, getCountryFlag };
123
+ //# sourceMappingURL=countries.js.map
124
+ //# sourceMappingURL=countries.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/countries.ts"],"names":[],"mappings":"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","file":"countries.js","sourcesContent":["/**\n * Shared country catalog (ISO 3166-1 alpha-2 + English name + flag emoji)\n * for provider-data-residency pickers. Data-only export (ADR-006) — apps\n * render labels/translations as they see fit. Consumed via the\n * `@neuronection/assistant-ui/countries` subpath.\n */\n\nexport interface CountryOption {\n code: string\n name: string\n flag: string\n}\n\nexport const COUNTRIES: CountryOption[] = [\n { code: 'AF', name: 'Afghanistan', flag: '🇦🇫' },\n { code: 'AL', name: 'Albania', flag: '🇦🇱' },\n { code: 'DZ', name: 'Algeria', flag: '🇩🇿' },\n { code: 'AD', name: 'Andorra', flag: '🇦🇩' },\n { code: 'AO', name: 'Angola', flag: '🇦🇴' },\n { code: 'AR', name: 'Argentina', flag: '🇦🇷' },\n { code: 'AM', name: 'Armenia', flag: '🇦🇲' },\n { code: 'AU', name: 'Australia', flag: '🇦🇺' },\n { code: 'AT', name: 'Austria', flag: '🇦🇹' },\n { code: 'AZ', name: 'Azerbaijan', flag: '🇦🇿' },\n { code: 'BS', name: 'Bahamas', flag: '🇧🇸' },\n { code: 'BH', name: 'Bahrain', flag: '🇧🇭' },\n { code: 'BD', name: 'Bangladesh', flag: '🇧🇩' },\n { code: 'BE', name: 'Belgium', flag: '🇧🇪' },\n { code: 'BZ', name: 'Belize', flag: '🇧🇿' },\n { code: 'BJ', name: 'Benin', flag: '🇧🇯' },\n { code: 'BT', name: 'Bhutan', flag: '🇧🇹' },\n { code: 'BO', name: 'Bolivia', flag: '🇧🇴' },\n { code: 'BA', name: 'Bosnia and Herzegovina', flag: '🇧🇦' },\n { code: 'BW', name: 'Botswana', flag: '🇧🇼' },\n { code: 'BR', name: 'Brazil', flag: '🇧🇷' },\n { code: 'BG', name: 'Bulgaria', flag: '🇧🇬' },\n { code: 'BF', name: 'Burkina Faso', flag: '🇧🇫' },\n { code: 'KH', name: 'Cambodia', flag: '🇰🇭' },\n { code: 'CM', name: 'Cameroon', flag: '🇨🇲' },\n { code: 'CA', name: 'Canada', flag: '🇨🇦' },\n { code: 'CL', name: 'Chile', flag: '🇨🇱' },\n { code: 'CN', name: 'China', flag: '🇨🇳' },\n { code: 'CO', name: 'Colombia', flag: '🇨🇴' },\n { code: 'CR', name: 'Costa Rica', flag: '🇨🇷' },\n { code: 'HR', name: 'Croatia', flag: '🇭🇷' },\n { code: 'CU', name: 'Cuba', flag: '🇨🇺' },\n { code: 'CY', name: 'Cyprus', flag: '🇨🇾' },\n { code: 'CZ', name: 'Czech Republic', flag: '🇨🇿' },\n { code: 'DK', name: 'Denmark', flag: '🇩🇰' },\n { code: 'DO', name: 'Dominican Republic', flag: '🇩🇴' },\n { code: 'EC', name: 'Ecuador', flag: '🇪🇨' },\n { code: 'EG', name: 'Egypt', flag: '🇪🇬' },\n { code: 'SV', name: 'El Salvador', flag: '🇸🇻' },\n { code: 'EE', name: 'Estonia', flag: '🇪🇪' },\n { code: 'ET', name: 'Ethiopia', flag: '🇪🇹' },\n { code: 'FJ', name: 'Fiji', flag: '🇫🇯' },\n { code: 'FI', name: 'Finland', flag: '🇫🇮' },\n { code: 'FR', name: 'France', flag: '🇫🇷' },\n { code: 'GE', name: 'Georgia', flag: '🇬🇪' },\n { code: 'DE', name: 'Germany', flag: '🇩🇪' },\n { code: 'GH', name: 'Ghana', flag: '🇬🇭' },\n { code: 'GR', name: 'Greece', flag: '🇬🇷' },\n { code: 'GT', name: 'Guatemala', flag: '🇬🇹' },\n { code: 'HN', name: 'Honduras', flag: '🇭🇳' },\n { code: 'HU', name: 'Hungary', flag: '🇭🇺' },\n { code: 'IS', name: 'Iceland', flag: '🇮🇸' },\n { code: 'IN', name: 'India', flag: '🇮🇳' },\n { code: 'ID', name: 'Indonesia', flag: '🇮🇩' },\n { code: 'IR', name: 'Iran', flag: '🇮🇷' },\n { code: 'IQ', name: 'Iraq', flag: '🇮🇶' },\n { code: 'IE', name: 'Ireland', flag: '🇮🇪' },\n { code: 'IL', name: 'Israel', flag: '🇮🇱' },\n { code: 'IT', name: 'Italy', flag: '🇮🇹' },\n { code: 'JM', name: 'Jamaica', flag: '🇯🇲' },\n { code: 'JP', name: 'Japan', flag: '🇯🇵' },\n { code: 'JO', name: 'Jordan', flag: '🇯🇴' },\n { code: 'KZ', name: 'Kazakhstan', flag: '🇰🇿' },\n { code: 'KE', name: 'Kenya', flag: '🇰🇪' },\n { code: 'KR', name: 'Korea (South)', flag: '🇰🇷' },\n { code: 'KW', name: 'Kuwait', flag: '🇰🇼' },\n { code: 'LV', name: 'Latvia', flag: '🇱🇻' },\n { code: 'LB', name: 'Lebanon', flag: '🇱🇧' },\n { code: 'LY', name: 'Libya', flag: '🇱🇾' },\n { code: 'LT', name: 'Lithuania', flag: '🇱🇹' },\n { code: 'LU', name: 'Luxembourg', flag: '🇱🇺' },\n { code: 'MY', name: 'Malaysia', flag: '🇲🇾' },\n { code: 'MT', name: 'Malta', flag: '🇲🇹' },\n { code: 'MX', name: 'Mexico', flag: '🇲🇽' },\n { code: 'MC', name: 'Monaco', flag: '🇲🇨' },\n { code: 'ME', name: 'Montenegro', flag: '🇲🇪' },\n { code: 'MA', name: 'Morocco', flag: '🇲🇦' },\n { code: 'NL', name: 'Netherlands', flag: '🇳🇱' },\n { code: 'NZ', name: 'New Zealand', flag: '🇳🇿' },\n { code: 'NG', name: 'Nigeria', flag: '🇳🇬' },\n { code: 'NO', name: 'Norway', flag: '🇳🇴' },\n { code: 'PK', name: 'Pakistan', flag: '🇵🇰' },\n { code: 'PA', name: 'Panama', flag: '🇵🇦' },\n { code: 'PY', name: 'Paraguay', flag: '🇵🇾' },\n { code: 'PE', name: 'Peru', flag: '🇵🇪' },\n { code: 'PH', name: 'Philippines', flag: '🇵🇭' },\n { code: 'PL', name: 'Poland', flag: '🇵🇱' },\n { code: 'PT', name: 'Portugal', flag: '🇵🇹' },\n { code: 'QA', name: 'Qatar', flag: '🇶🇦' },\n { code: 'RO', name: 'Romania', flag: '🇷🇴' },\n { code: 'RU', name: 'Russia', flag: '🇷🇺' },\n { code: 'SA', name: 'Saudi Arabia', flag: '🇸🇦' },\n { code: 'RS', name: 'Serbia', flag: '🇷🇸' },\n { code: 'SG', name: 'Singapore', flag: '🇸🇬' },\n { code: 'SK', name: 'Slovakia', flag: '🇸🇰' },\n { code: 'SI', name: 'Slovenia', flag: '🇸🇮' },\n { code: 'ZA', name: 'South Africa', flag: '🇿🇦' },\n { code: 'ES', name: 'Spain', flag: '🇪🇸' },\n { code: 'SE', name: 'Sweden', flag: '🇸🇪' },\n { code: 'CH', name: 'Switzerland', flag: '🇨🇭' },\n { code: 'TW', name: 'Taiwan', flag: '🇹🇼' },\n { code: 'TH', name: 'Thailand', flag: '🇹🇭' },\n { code: 'TN', name: 'Tunisia', flag: '🇹🇳' },\n { code: 'TR', name: 'Turkey', flag: '🇹🇷' },\n { code: 'UA', name: 'Ukraine', flag: '🇺🇦' },\n { code: 'AE', name: 'UAE', flag: '🇦🇪' },\n { code: 'UK', name: 'United Kingdom', flag: '🇬🇧' },\n { code: 'US', name: 'United States', flag: '🇺🇸' },\n { code: 'UY', name: 'Uruguay', flag: '🇺🇾' },\n { code: 'UZ', name: 'Uzbekistan', flag: '🇺🇿' },\n { code: 'VE', name: 'Venezuela', flag: '🇻🇪' },\n { code: 'VN', name: 'Vietnam', flag: '🇻🇳' },\n]\n\nexport const getCountryFlag = (code?: string): string => {\n if (!code) return ''\n const country = COUNTRIES.find(c => c.code === code)\n return country ? country.flag : code\n}\n"]}
package/dist/index.d.ts CHANGED
@@ -377,7 +377,7 @@ interface FlowStatusCardProps {
377
377
  declare const FlowStatusCard: React.ForwardRefExoticComponent<FlowStatusCardProps & React.RefAttributes<HTMLDivElement>>;
378
378
 
379
379
  declare const badgeVariants: (props?: ({
380
- variant?: "default" | "warning" | "success" | "danger" | "secondary" | "outline" | "ai" | null | undefined;
380
+ variant?: "ai" | "default" | "warning" | "success" | "danger" | "secondary" | "outline" | null | undefined;
381
381
  } & class_variance_authority_types.ClassProp) | undefined) => string;
382
382
  interface BadgeProps extends React.ComponentProps<'span'>, VariantProps<typeof badgeVariants> {
383
383
  }
@@ -438,6 +438,16 @@ interface ConnectionTestRowProps {
438
438
  */
439
439
  declare const ConnectionTestRow: React.ForwardRefExoticComponent<ConnectionTestRowProps & React.RefAttributes<HTMLDivElement>>;
440
440
 
441
+ /** One entry of the app's provider catalog (ADR-006: the catalog lives in
442
+ * the app/backend — the form only renders the picker and reports the key). */
443
+ interface ProviderPresetOption {
444
+ key: string;
445
+ name: string;
446
+ /** Local/on-premise preset — apps may default the hosting toggle from it. */
447
+ local?: boolean;
448
+ }
449
+ /** Reserved key of the built-in "custom" preset entry (never a catalog key). */
450
+ declare const CUSTOM_PRESET_KEY = "custom";
441
451
  interface ProviderFormProps extends React.ComponentProps<'div'> {
442
452
  name: string;
443
453
  onNameChange: (value: string) => void;
@@ -452,6 +462,12 @@ interface ProviderFormProps extends React.ComponentProps<'div'> {
452
462
  /** Hide the base URL field for provider types that have a fixed endpoint. */
453
463
  hideBaseUrl?: boolean;
454
464
  apiKeyLabel?: string;
465
+ /** Optional preset catalog select — render only when `presets` is non-empty. */
466
+ presets?: ProviderPresetOption[];
467
+ presetKey?: string;
468
+ onPresetChange?: (key: string) => void;
469
+ presetLabel?: string;
470
+ customPresetLabel?: string;
455
471
  /** Optional Local/Cloud toggle — render only when `showLocationKind`. */
456
472
  showLocationKind?: boolean;
457
473
  locationKind?: 'local' | 'cloud';
@@ -2539,6 +2555,14 @@ interface ChatLauncherProps {
2539
2555
  closeIcon?: LucideIcon;
2540
2556
  /** Unread / activity badge. */
2541
2557
  badge?: number | string;
2558
+ /**
2559
+ * Render the floating close button pinned to the panel's top-right
2560
+ * corner (default). Turn this off when the panel body renders its own
2561
+ * header actions — an overlaid close intercepts clicks meant for
2562
+ * top-right header buttons; compose the close into those actions
2563
+ * (calling `onOpenChange(false)`) instead.
2564
+ */
2565
+ showClose?: boolean;
2542
2566
  container?: HTMLElement | null;
2543
2567
  panelClassName?: string;
2544
2568
  className?: string;
@@ -2550,4 +2574,4 @@ interface ChatLauncherProps {
2550
2574
  */
2551
2575
  declare const ChatLauncher: React.ForwardRefExoticComponent<ChatLauncherProps & React.RefAttributes<HTMLButtonElement>>;
2552
2576
 
2553
- export { AboutCard, type AboutCardProps, type AboutCreator, AboutFooterLine, type AboutFooterLineProps, type AboutLicense, type AboutLinkItem, AboutLinkList, type AboutLinkListProps, AboutNote, type AboutNoteContent, type AboutNoteProps, AboutPanel, type AboutPanelProps, type AboutSponsorContent, ActionMenu, type ActionMenuItem, type ActionMenuProps, type AiAction, AiActionsDropdown, type AiActionsDropdownProps, AiButton, type AiButtonProps, AiMagicFill, type AiMagicFillProps, type AiTextTransformEventHandlers, type AiTextTransformStatus, type AiTextTransformTransport, Badge, type BadgeProps, type BranchNode, type BranchNodeInput, type BranchTree, type BreadcrumbItem, type BreadcrumbLinkProps, Breadcrumbs, type BreadcrumbsProps, Button, type ButtonProps, CapabilityChips, type CapabilityChipsProps, type CapabilityDescriptor, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, CareerMark, type ChatAttachmentView, ChatBranchTree, type ChatBranchTreeIcons, type ChatBranchTreeLabels, type ChatBranchTreeNode, type ChatBranchTreeProps, ChatComposer, type ChatComposerIcons, type ChatComposerLabels, type ChatComposerProps, ChatDrawer, type ChatDrawerProps, type ChatError, type ChatExportMessage, type ChatExportOptions, ChatHistoryButton, type ChatHistoryButtonLabels, type ChatHistoryButtonProps, ChatLauncher, type ChatLauncherProps, ChatMessage, type ChatMessageAction, type ChatMessageActions, ChatMessageEditor, type ChatMessageEditorLabels, type ChatMessageEditorProps, type ChatMessageLabels, type ChatMessageProps, type ChatMessageStatus, type ChatMessageVariants, type ChatMessageView, ChatPanel, type ChatPanelProps, type ChatPanelVariant, ChatReasoning, type ChatReasoningLabels, type ChatReasoningProps, type ChatRole, ChatSessionList, type ChatSessionListIcons, type ChatSessionListLabels, type ChatSessionListProps, type ChatSessionView, type ChatStreamEvent, type ChatStreamTransport, ChatToolCard, type ChatToolCardLabels, type ChatToolCardProps, type ChatToolCatalogArgument, type ChatToolCatalogEntry, ChatToolsCatalog, type ChatToolsCatalogLabels, type ChatToolsCatalogProps, ChatTraceMeta, type ChatTraceMetaProps, ChatTraceTimeline, type ChatTraceTimelineEntry, type ChatTraceTimelineLabels, type ChatTraceTimelineProps, type ChatTraceTimelineTrace, ChatTranscript, type ChatTranscriptLabels, type ChatTranscriptProps, ChatTurnStatus, type ChatTurnStatusLabels, type ChatTurnStatusProps, CheckIndicator, type CheckIndicatorProps, ChipInput, type ChipInputProps, ChipList, type ChipListProps, type ChipVariant, Combobox, ComboboxMulti, type ComboboxMultiProps, type ComboboxOption, type ComboboxProps, ConfirmationModal, type ConfirmationModalProps, ConnectionTestRow, type ConnectionTestRowProps, type ConnectionTestStatus, ContextMenu, type ContextMenuItem, type ContextMenuProps, CopyButton, type CopyButtonProps, DatePicker, type DatePickerProps, DictationButton, type DictationButtonProps, type DictationError, type DictationResult, type DictationStatus, DictationStrip, type DictationStripLabels, type DictationStripProps, type DiffCell, type DiffRow, type DiffSegment, EmptyState, type EmptyStateProps, ErrorBanner, type ErrorBannerProps, ExpandableSearch, type ExpandableSearchProps, type FamilyApp, FamilyBadge, type FamilyBadgeProps, type FamilyCreator, type FamilyMember, FieldLabel, type FieldLabelProps, FileCard, type FileCardProps, type FileCardStatus, FileQueue, type FileQueueItem, type FileQueueProps, type FlowError, FlowStatusCard, type FlowStatusCardProps, type FlowStep, type FlowStepInfo, type FlowStepStatus, FormModal, type FormModalProps, HealthMark, InfoButton, type InfoButtonProps, InfoTooltip, type InfoTooltipProps, Input, type InputProps, type LineDiffOptions, type LineDiffResult, type LiveNodeState, type LiveToolCall, type LiveTurnAction, type LiveTurnState, type LiveTurnStatus, type LogoProps, type LogoTheme, MarkdownCodeBlock, type MarkdownCodeBlockLabels, type MarkdownCodeBlockProps, type MarkdownComponents, MarkdownSurface, type MarkdownSurfaceProps, MarqueeBand, type MarqueePhase, type MarqueeSelection, MarqueeSurface, type MarqueeSurfaceProps, Menu, MenuCheckboxItem, type MenuCheckboxItemProps, MenuContent, MenuGroup, MenuItem, type MenuItemProps, MenuLabel, MenuSeparator, MenuTrigger, MermaidDiagram, type MermaidDiagramProps, MessageVariantSwitcher, type MessageVariantSwitcherLabels, type MessageVariantSwitcherProps, Modal, ModalClose, ModalContent, type ModalContentProps, ModalDescription, ModalFooter, ModalHeader, ModalTitle, ModalTrigger, ModelPicker, type ModelPickerModel, type ModelPickerProps, type ModelPickerProvider, ModelRegistry, type ModelRegistryDraft, type ModelRegistryModel, type ModelRegistryPatch, type ModelRegistryProps, type ModelRegistryProvider, type ModelRegistryRemoteModel, type ModelRegistryRemoteState, type NavChild, type NavItem, NeuronectionMark, NeuronectionWordmark, type NeuronectionWordmarkProps, PanelModal, type PanelModalProps, Popover, PopoverAnchor, PopoverButton, type PopoverButtonProps, PopoverClose, PopoverContent, PopoverTrigger, Portal, type PortalProps, ProviderForm, type ProviderFormProps, RangeBar, type RangeBarProps, type Rect, RichTextEditor, type RichTextEditorIcons, type RichTextEditorLabels, type RichTextEditorProps, type RichTextToolbarGroup, ScaleSlider, type ScaleSliderProps, SearchInput, type SearchInputProps, SelectionBar, type SelectionBarProps, type SettingsNavItem, SettingsShell, type SettingsShellProps, SidebarNav, type SidebarNavLabels, type SidebarNavProps, Spinner, type SpinnerProps, SponsorCard, type SponsorCardProps, type SponsorChannel, Stepper, type StepperProps, type StepperStep, StudyMark, Table, type TableProps, TaskAssignmentPicker, type TaskAssignmentPickerProps, type TaskAssignmentSection, type TaskAssignmentTask, TechChips, type TechChipsProps, TextDiffView, type TextDiffViewLabels, type TextDiffViewProps, ThemeScope, type ThemeScopeProps, ThemeTokens, TimeList, type TimeListProps, TimePicker, TimePickerContent, type TimePickerContentProps, type TimePickerProps, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, UndoNotice, type UndoNoticeProps, UploadDropzone, type UploadDropzoneProps, type UseAiTextTransformOptions, type UseChatStreamOptions, type UseChatStreamResult, type UseDictationOptions, type UseMarqueeOptions, UserMenu, type UserMenuItem, type UserMenuProps, ViewToggle, type ViewToggleProps, type ViewToggleView, Wizard, type WizardContext, type WizardProps, type WizardStep, activePathSet, badgeVariants, buildBranchTree, buildChatMarkdown, buttonVariants, chatExportFileName, cn, computeLineDiff, downloadChatMarkdown, formatBytes, hitTestIds, initialLiveTurnState, linearTree, liveTurnReducer, marqueeRect, modalContentVariants, rectsIntersect, scaleColorForValue, useAiTextTransform, useChatStream, useDictation, useLogoId, useMarquee, variantInfo, walkActivePath, wordSegments };
2577
+ export { AboutCard, type AboutCardProps, type AboutCreator, AboutFooterLine, type AboutFooterLineProps, type AboutLicense, type AboutLinkItem, AboutLinkList, type AboutLinkListProps, AboutNote, type AboutNoteContent, type AboutNoteProps, AboutPanel, type AboutPanelProps, type AboutSponsorContent, ActionMenu, type ActionMenuItem, type ActionMenuProps, type AiAction, AiActionsDropdown, type AiActionsDropdownProps, AiButton, type AiButtonProps, AiMagicFill, type AiMagicFillProps, type AiTextTransformEventHandlers, type AiTextTransformStatus, type AiTextTransformTransport, Badge, type BadgeProps, type BranchNode, type BranchNodeInput, type BranchTree, type BreadcrumbItem, type BreadcrumbLinkProps, Breadcrumbs, type BreadcrumbsProps, Button, type ButtonProps, CUSTOM_PRESET_KEY, CapabilityChips, type CapabilityChipsProps, type CapabilityDescriptor, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, CareerMark, type ChatAttachmentView, ChatBranchTree, type ChatBranchTreeIcons, type ChatBranchTreeLabels, type ChatBranchTreeNode, type ChatBranchTreeProps, ChatComposer, type ChatComposerIcons, type ChatComposerLabels, type ChatComposerProps, ChatDrawer, type ChatDrawerProps, type ChatError, type ChatExportMessage, type ChatExportOptions, ChatHistoryButton, type ChatHistoryButtonLabels, type ChatHistoryButtonProps, ChatLauncher, type ChatLauncherProps, ChatMessage, type ChatMessageAction, type ChatMessageActions, ChatMessageEditor, type ChatMessageEditorLabels, type ChatMessageEditorProps, type ChatMessageLabels, type ChatMessageProps, type ChatMessageStatus, type ChatMessageVariants, type ChatMessageView, ChatPanel, type ChatPanelProps, type ChatPanelVariant, ChatReasoning, type ChatReasoningLabels, type ChatReasoningProps, type ChatRole, ChatSessionList, type ChatSessionListIcons, type ChatSessionListLabels, type ChatSessionListProps, type ChatSessionView, type ChatStreamEvent, type ChatStreamTransport, ChatToolCard, type ChatToolCardLabels, type ChatToolCardProps, type ChatToolCatalogArgument, type ChatToolCatalogEntry, ChatToolsCatalog, type ChatToolsCatalogLabels, type ChatToolsCatalogProps, ChatTraceMeta, type ChatTraceMetaProps, ChatTraceTimeline, type ChatTraceTimelineEntry, type ChatTraceTimelineLabels, type ChatTraceTimelineProps, type ChatTraceTimelineTrace, ChatTranscript, type ChatTranscriptLabels, type ChatTranscriptProps, ChatTurnStatus, type ChatTurnStatusLabels, type ChatTurnStatusProps, CheckIndicator, type CheckIndicatorProps, ChipInput, type ChipInputProps, ChipList, type ChipListProps, type ChipVariant, Combobox, ComboboxMulti, type ComboboxMultiProps, type ComboboxOption, type ComboboxProps, ConfirmationModal, type ConfirmationModalProps, ConnectionTestRow, type ConnectionTestRowProps, type ConnectionTestStatus, ContextMenu, type ContextMenuItem, type ContextMenuProps, CopyButton, type CopyButtonProps, DatePicker, type DatePickerProps, DictationButton, type DictationButtonProps, type DictationError, type DictationResult, type DictationStatus, DictationStrip, type DictationStripLabels, type DictationStripProps, type DiffCell, type DiffRow, type DiffSegment, EmptyState, type EmptyStateProps, ErrorBanner, type ErrorBannerProps, ExpandableSearch, type ExpandableSearchProps, type FamilyApp, FamilyBadge, type FamilyBadgeProps, type FamilyCreator, type FamilyMember, FieldLabel, type FieldLabelProps, FileCard, type FileCardProps, type FileCardStatus, FileQueue, type FileQueueItem, type FileQueueProps, type FlowError, FlowStatusCard, type FlowStatusCardProps, type FlowStep, type FlowStepInfo, type FlowStepStatus, FormModal, type FormModalProps, HealthMark, InfoButton, type InfoButtonProps, InfoTooltip, type InfoTooltipProps, Input, type InputProps, type LineDiffOptions, type LineDiffResult, type LiveNodeState, type LiveToolCall, type LiveTurnAction, type LiveTurnState, type LiveTurnStatus, type LogoProps, type LogoTheme, MarkdownCodeBlock, type MarkdownCodeBlockLabels, type MarkdownCodeBlockProps, type MarkdownComponents, MarkdownSurface, type MarkdownSurfaceProps, MarqueeBand, type MarqueePhase, type MarqueeSelection, MarqueeSurface, type MarqueeSurfaceProps, Menu, MenuCheckboxItem, type MenuCheckboxItemProps, MenuContent, MenuGroup, MenuItem, type MenuItemProps, MenuLabel, MenuSeparator, MenuTrigger, MermaidDiagram, type MermaidDiagramProps, MessageVariantSwitcher, type MessageVariantSwitcherLabels, type MessageVariantSwitcherProps, Modal, ModalClose, ModalContent, type ModalContentProps, ModalDescription, ModalFooter, ModalHeader, ModalTitle, ModalTrigger, ModelPicker, type ModelPickerModel, type ModelPickerProps, type ModelPickerProvider, ModelRegistry, type ModelRegistryDraft, type ModelRegistryModel, type ModelRegistryPatch, type ModelRegistryProps, type ModelRegistryProvider, type ModelRegistryRemoteModel, type ModelRegistryRemoteState, type NavChild, type NavItem, NeuronectionMark, NeuronectionWordmark, type NeuronectionWordmarkProps, PanelModal, type PanelModalProps, Popover, PopoverAnchor, PopoverButton, type PopoverButtonProps, PopoverClose, PopoverContent, PopoverTrigger, Portal, type PortalProps, ProviderForm, type ProviderFormProps, type ProviderPresetOption, RangeBar, type RangeBarProps, type Rect, RichTextEditor, type RichTextEditorIcons, type RichTextEditorLabels, type RichTextEditorProps, type RichTextToolbarGroup, ScaleSlider, type ScaleSliderProps, SearchInput, type SearchInputProps, SelectionBar, type SelectionBarProps, type SettingsNavItem, SettingsShell, type SettingsShellProps, SidebarNav, type SidebarNavLabels, type SidebarNavProps, Spinner, type SpinnerProps, SponsorCard, type SponsorCardProps, type SponsorChannel, Stepper, type StepperProps, type StepperStep, StudyMark, Table, type TableProps, TaskAssignmentPicker, type TaskAssignmentPickerProps, type TaskAssignmentSection, type TaskAssignmentTask, TechChips, type TechChipsProps, TextDiffView, type TextDiffViewLabels, type TextDiffViewProps, ThemeScope, type ThemeScopeProps, ThemeTokens, TimeList, type TimeListProps, TimePicker, TimePickerContent, type TimePickerContentProps, type TimePickerProps, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, UndoNotice, type UndoNoticeProps, UploadDropzone, type UploadDropzoneProps, type UseAiTextTransformOptions, type UseChatStreamOptions, type UseChatStreamResult, type UseDictationOptions, type UseMarqueeOptions, UserMenu, type UserMenuItem, type UserMenuProps, ViewToggle, type ViewToggleProps, type ViewToggleView, Wizard, type WizardContext, type WizardProps, type WizardStep, activePathSet, badgeVariants, buildBranchTree, buildChatMarkdown, buttonVariants, chatExportFileName, cn, computeLineDiff, downloadChatMarkdown, formatBytes, hitTestIds, initialLiveTurnState, linearTree, liveTurnReducer, marqueeRect, modalContentVariants, rectsIntersect, scaleColorForValue, useAiTextTransform, useChatStream, useDictation, useLogoId, useMarquee, variantInfo, walkActivePath, wordSegments };
package/dist/index.js CHANGED
@@ -1,5 +1,7 @@
1
+ export { UndoNotice } from './chunk-OUHUVACM.js';
1
2
  export { ViewToggle } from './chunk-MXOBOS4Y.js';
2
3
  export { Stepper, Wizard } from './chunk-YMCMUAIF.js';
4
+ export { TaskAssignmentPicker } from './chunk-Q5THPPNL.js';
3
5
  export { SettingsShell } from './chunk-ZK2V2LPA.js';
4
6
  export { SidebarNav } from './chunk-SW3YNICQ.js';
5
7
  export { UserMenu } from './chunk-535TM7SK.js';
@@ -7,16 +9,14 @@ export { ThemeScope } from './chunk-TGU3PKNM.js';
7
9
  export { TimeList } from './chunk-GVOC3ARM.js';
8
10
  export { TimePicker, TimePickerContent } from './chunk-CR42EAF4.js';
9
11
  export { InfoTooltip, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from './chunk-34NO2UOB.js';
10
- export { UndoNotice } from './chunk-OUHUVACM.js';
11
12
  export { SearchInput } from './chunk-H5U4KNXF.js';
12
13
  export { ModelRegistry } from './chunk-BHHDCY2B.js';
13
14
  export { CapabilityChips } from './chunk-G3DWN2DJ.js';
14
15
  export { SelectionBar } from './chunk-HSUCCANX.js';
15
16
  export { Table } from './chunk-5LRRVD27.js';
16
- export { TaskAssignmentPicker } from './chunk-Q5THPPNL.js';
17
17
  export { ModelPicker } from './chunk-S4WHBQJ2.js';
18
18
  export { PanelModal } from './chunk-G6557MEN.js';
19
- export { ProviderForm } from './chunk-4WDXLXHL.js';
19
+ export { CUSTOM_PRESET_KEY, ProviderForm } from './chunk-HT5633F3.js';
20
20
  export { RangeBar } from './chunk-PFAH25VU.js';
21
21
  export { ScaleSlider, scaleColorForValue } from './chunk-PSFJN7WH.js';
22
22
  export { RichTextEditor } from './chunk-AY77TWLT.js';
@@ -56,9 +56,9 @@ export { ChatTurnStatus } from './chunk-P75QKU5J.js';
56
56
  export { buildChatMarkdown, chatExportFileName, downloadChatMarkdown } from './chunk-DRJGZ5TB.js';
57
57
  export { initialLiveTurnState, liveTurnReducer, useChatStream } from './chunk-6GNLY2EB.js';
58
58
  export { activePathSet, buildBranchTree, linearTree, variantInfo, walkActivePath } from './chunk-Z4IBQ53C.js';
59
- export { ChatLauncher } from './chunk-RPLEI6LQ.js';
59
+ export { ChatLauncher } from './chunk-OUJJLZ6C.js';
60
60
  export { Portal } from './chunk-XZWLTTHA.js';
61
- export { ChatComposer } from './chunk-743FJDRA.js';
61
+ export { ChatComposer } from './chunk-IN6ORI3V.js';
62
62
  export { ChatPanel } from './chunk-MVT4F6TA.js';
63
63
  export { ChatTranscript } from './chunk-FS7M7PNS.js';
64
64
  export { ChatMessage, ChatMessageEditor, MessageVariantSwitcher } from './chunk-FGYGWZ6S.js';
@@ -1,5 +1,15 @@
1
1
  import * as React from 'react';
2
2
 
3
+ /** One entry of the app's provider catalog (ADR-006: the catalog lives in
4
+ * the app/backend — the form only renders the picker and reports the key). */
5
+ interface ProviderPresetOption {
6
+ key: string;
7
+ name: string;
8
+ /** Local/on-premise preset — apps may default the hosting toggle from it. */
9
+ local?: boolean;
10
+ }
11
+ /** Reserved key of the built-in "custom" preset entry (never a catalog key). */
12
+ declare const CUSTOM_PRESET_KEY = "custom";
3
13
  interface ProviderFormProps extends React.ComponentProps<'div'> {
4
14
  name: string;
5
15
  onNameChange: (value: string) => void;
@@ -14,6 +24,12 @@ interface ProviderFormProps extends React.ComponentProps<'div'> {
14
24
  /** Hide the base URL field for provider types that have a fixed endpoint. */
15
25
  hideBaseUrl?: boolean;
16
26
  apiKeyLabel?: string;
27
+ /** Optional preset catalog select — render only when `presets` is non-empty. */
28
+ presets?: ProviderPresetOption[];
29
+ presetKey?: string;
30
+ onPresetChange?: (key: string) => void;
31
+ presetLabel?: string;
32
+ customPresetLabel?: string;
17
33
  /** Optional Local/Cloud toggle — render only when `showLocationKind`. */
18
34
  showLocationKind?: boolean;
19
35
  locationKind?: 'local' | 'cloud';
@@ -47,4 +63,4 @@ interface ProviderFormProps extends React.ComponentProps<'div'> {
47
63
  */
48
64
  declare const ProviderForm: React.ForwardRefExoticComponent<Omit<ProviderFormProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
49
65
 
50
- export { ProviderForm, type ProviderFormProps };
66
+ export { CUSTOM_PRESET_KEY, ProviderForm, type ProviderFormProps, type ProviderPresetOption };
@@ -1,3 +1,3 @@
1
- export { ProviderForm } from './chunk-4WDXLXHL.js';
1
+ export { CUSTOM_PRESET_KEY, ProviderForm } from './chunk-HT5633F3.js';
2
2
  //# sourceMappingURL=provider-form.js.map
3
3
  //# sourceMappingURL=provider-form.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neuronection/assistant-ui",
3
- "version": "0.29.1",
3
+ "version": "0.31.0",
4
4
  "description": "Shared React component library for the Assistant family (career-, study-, health-assistant). Family look by default, app-flavored via CSS-variable tokens.",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -341,6 +341,10 @@
341
341
  "./fuzzy": {
342
342
  "types": "./dist/fuzzy.d.ts",
343
343
  "import": "./dist/fuzzy.js"
344
+ },
345
+ "./countries": {
346
+ "types": "./dist/countries.d.ts",
347
+ "import": "./dist/countries.js"
344
348
  }
345
349
  },
346
350
  "peerDependencies": {
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/provider-form/ProviderForm.tsx"],"names":["ProviderForm"],"mappings":"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","file":"chunk-4WDXLXHL.js","sourcesContent":["import * as React from 'react'\nimport { Building2, House, KeyRound } from 'lucide-react'\nimport { cn } from '../../lib/utils'\nimport { Input } from '../input/Input'\n\nexport interface ProviderFormProps extends React.ComponentProps<'div'> {\n name: string\n onNameChange: (value: string) => void\n baseUrl: string\n onBaseUrlChange: (value: string) => void\n apiKey: string\n onApiKeyChange: (value: string) => void\n namePlaceholder?: string\n baseUrlPlaceholder?: string\n nameLabel?: string\n baseUrlLabel?: string\n /** Hide the base URL field for provider types that have a fixed endpoint. */\n hideBaseUrl?: boolean\n apiKeyLabel?: string\n /** Optional Local/Cloud toggle — render only when `showLocationKind`. */\n showLocationKind?: boolean\n locationKind?: 'local' | 'cloud'\n onLocationKindChange?: (kind: 'local' | 'cloud') => void\n locationLabel?: string\n localLabel?: string\n cloudLabel?: string\n /** Optional country select — render only when `showCountry`. */\n showCountry?: boolean\n country?: string\n onCountryChange?: (country: string) => void\n countryLabel?: string\n countryOptions?: { value: string; label: string }[]\n countryPlaceholder?: string\n /** Hint under the key field; apps mention keyring storage here. */\n apiKeyHelp?: string\n /** The provider already stores a key (write-only field shows no value). */\n hasStoredKey?: boolean\n storedKeyLabel?: string\n keyPlaceholder?: string\n error?: string\n children?: React.ReactNode\n}\n\n/**\n * Standard provider credential fields: name, base URL and a **write-only**\n * masked API key (`onChange` only — the library never renders a stored key;\n * keyring/storage is the app's business, ADR-006).\n */\nexport const ProviderForm = React.forwardRef<HTMLDivElement, ProviderFormProps>(\n function ProviderForm(\n {\n name,\n onNameChange,\n baseUrl,\n onBaseUrlChange,\n apiKey,\n onApiKeyChange,\n namePlaceholder = 'Provider name',\n baseUrlPlaceholder = 'https://api.example.com/v1',\n nameLabel = 'Name',\n baseUrlLabel = 'API base URL',\n hideBaseUrl = false,\n apiKeyLabel = 'API key',\n apiKeyHelp,\n hasStoredKey = false,\n showLocationKind = false,\n locationKind = 'cloud',\n onLocationKindChange,\n locationLabel = 'Hosting',\n localLabel = 'Local / on-premise',\n cloudLabel = 'Cloud',\n showCountry = false,\n country,\n onCountryChange,\n countryLabel = 'Country',\n countryOptions = [],\n countryPlaceholder = 'Select a country…',\n storedKeyLabel = 'Stored — leave empty to keep',\n keyPlaceholder = 'sk-…',\n error,\n children,\n className,\n ...props\n },\n ref,\n ) {\n return (\n <div\n ref={ref}\n data-as=\"provider-form\"\n className={cn('flex w-full flex-col gap-4', className)}\n {...props}\n >\n <Input\n label={nameLabel}\n value={name}\n onChange={(event) => onNameChange(event.target.value)}\n placeholder={namePlaceholder}\n />\n {hideBaseUrl ? null : (\n <Input\n label={baseUrlLabel}\n value={baseUrl}\n onChange={(event) => onBaseUrlChange(event.target.value)}\n placeholder={baseUrlPlaceholder}\n className=\"font-mono\"\n />\n )}\n <Input\n label={\n hasStoredKey ? (\n <>\n {apiKeyLabel}{' '}\n <span className=\"font-normal text-[var(--as-muted-fg)]\">\n ({storedKeyLabel})\n </span>\n </>\n ) : (\n apiKeyLabel\n )\n }\n type=\"password\"\n value={apiKey}\n onChange={(event) => onApiKeyChange(event.target.value)}\n placeholder={hasStoredKey ? '•••' : keyPlaceholder}\n autoComplete=\"new-password\"\n hint={\n apiKeyHelp ? (\n <span className=\"inline-flex items-center gap-1\">\n <KeyRound className=\"size-3\" aria-hidden />\n {apiKeyHelp}\n </span>\n ) : undefined\n }\n />\n {showLocationKind && onLocationKindChange ? (\n <div className=\"space-y-1\">\n <span className=\"text-sm font-medium text-[var(--as-fg)]\">{locationLabel}</span>\n <div className=\"flex gap-2\" role=\"group\" aria-label={locationLabel}>\n {(\n [\n { kind: 'local' as const, label: localLabel, Icon: House },\n { kind: 'cloud' as const, label: cloudLabel, Icon: Building2 },\n ]\n ).map(({ kind, label, Icon }) => {\n const on = locationKind === kind\n return (\n <button\n key={kind}\n type=\"button\"\n data-as-location={kind}\n aria-pressed={on}\n onClick={() => onLocationKindChange(kind)}\n className={cn(\n 'flex flex-1 cursor-pointer items-center justify-center gap-1.5 rounded-[var(--as-radius)] border px-3 py-2 text-xs font-semibold transition-all',\n 'focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-[var(--as-focus-ring)]',\n on\n ? 'border-[var(--as-primary)]/30 bg-[var(--as-primary)]/10 text-[var(--as-primary)] shadow-[var(--as-shadow-1)]'\n : 'border-[var(--as-border)] bg-[var(--as-surface)] text-[var(--as-muted-fg)] hover:border-[var(--as-muted-fg)]/40',\n )}\n >\n <Icon className=\"size-3.5\" aria-hidden />\n {label}\n </button>\n )\n })}\n </div>\n </div>\n ) : null}\n {showCountry && onCountryChange ? (\n <label className=\"block space-y-1 text-sm\">\n <span className=\"text-sm font-medium text-[var(--as-fg)]\">{countryLabel}</span>\n <select\n value={country ?? ''}\n onChange={(event) => onCountryChange(event.target.value)}\n className=\"w-full rounded-[var(--as-radius)] border border-[var(--as-border)] bg-[var(--as-surface)] px-3 py-2 text-sm text-[var(--as-fg)]\"\n >\n <option value=\"\">{countryPlaceholder}</option>\n {countryOptions.map((option) => (\n <option key={option.value} value={option.value}>\n {option.label}\n </option>\n ))}\n </select>\n </label>\n ) : null}\n {children}\n {error ? (\n <p role=\"alert\" className=\"text-sm font-medium text-[var(--as-danger)]\">\n {error}\n </p>\n ) : null}\n </div>\n )\n },\n)\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/chat-composer/ChatComposer.tsx"],"names":["ChatComposer"],"mappings":"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","file":"chunk-743FJDRA.js","sourcesContent":["import * as React from 'react'\nimport { ArrowUp, Square } from 'lucide-react'\nimport type { LucideIcon } from 'lucide-react'\n\nimport { cn } from '../../lib/utils'\n\nexport interface ChatComposerLabels {\n send: string\n stop: string\n placeholder: string\n ariaLabel: string\n dropFiles: string\n}\n\nexport interface ChatComposerIcons {\n send: LucideIcon\n stop: LucideIcon\n}\n\nexport interface ChatComposerProps {\n value: string\n onValueChange: (value: string) => void\n /** Enter / Send — IME-safe (composition and keyCode 229 are ignored). */\n onSubmit: () => void\n /** A turn is in flight — renders the stop control when `onStop` is provided. */\n sending?: boolean\n onStop?: () => void\n disabled?: boolean\n placeholder?: string\n ariaLabel?: string\n /** Auto-grow cap before the textarea scrolls. Default 8. */\n maxRows?: number\n /** Leading slot inside the input row (attach menu, equation, draw…). */\n toolbarStart?: React.ReactNode\n /** Trailing slot inside the input row (dictation, tools…). */\n toolbarEnd?: React.ReactNode\n /** Attachment rail above the input (usually `FileQueue` / chips). */\n attachments?: React.ReactNode\n /** Suggestion chips / context strip above everything. */\n suggestions?: React.ReactNode\n /** Drag-drop + paste wiring for file attachments. */\n onAttachFiles?: (files: File[]) => void\n labels?: Partial<ChatComposerLabels>\n icons?: Partial<ChatComposerIcons>\n textareaRef?: React.Ref<HTMLTextAreaElement>\n className?: string\n}\n\nfunction isIMEComposition(event: React.KeyboardEvent<HTMLTextAreaElement>): boolean {\n return event.nativeEvent.isComposing || event.keyCode === 229\n}\n\n/**\n * The family chat input: auto-growing IME-safe textarea, send/stop\n * states, attachment/dictation/toolbar slots, drag-drop + paste file\n * wiring. Presentational + controlled; transports stay app-side.\n */\nexport const ChatComposer = React.forwardRef<HTMLFormElement, ChatComposerProps>(\n function ChatComposer(\n {\n value,\n onValueChange,\n onSubmit,\n sending = false,\n onStop,\n disabled = false,\n placeholder,\n ariaLabel,\n maxRows = 8,\n toolbarStart,\n toolbarEnd,\n attachments,\n suggestions,\n onAttachFiles,\n labels,\n icons,\n textareaRef,\n className,\n },\n ref,\n ) {\n const internalTextareaRef = React.useRef<HTMLTextAreaElement | null>(null)\n const [dragging, setDragging] = React.useState(false)\n const dragDepth = React.useRef(0)\n\n const setTextarea = (element: HTMLTextAreaElement | null) => {\n internalTextareaRef.current = element\n if (typeof textareaRef === 'function') {\n textareaRef(element)\n } else if (textareaRef && typeof textareaRef === 'object') {\n ;(textareaRef as React.MutableRefObject<HTMLTextAreaElement | null>).current = element\n }\n }\n\n React.useLayoutEffect(() => {\n const element = internalTextareaRef.current\n if (element === null) {\n return\n }\n element.style.height = 'auto'\n const cap = maxRows * 22\n element.style.height = element.scrollHeight > 0 ? `${Math.min(element.scrollHeight, cap)}px` : 'auto'\n element.style.overflowY = element.scrollHeight > cap ? 'auto' : 'hidden'\n }, [value, maxRows])\n\n const submit = () => {\n if (disabled || sending) {\n return\n }\n onSubmit()\n }\n\n const onKeyDown: React.KeyboardEventHandler<HTMLTextAreaElement> = (event) => {\n if (event.key !== 'Enter' || event.shiftKey) {\n return\n }\n if (isIMEComposition(event)) {\n return\n }\n event.preventDefault()\n submit()\n }\n\n const emitFiles = (fileList: FileList | null | undefined) => {\n const files = fileList ? Array.from(fileList) : []\n if (files.length > 0) {\n onAttachFiles?.(files)\n }\n }\n\n const dragCounterHandlers = {\n onDragEnter: (event: React.DragEvent) => {\n if (onAttachFiles === undefined || !event.dataTransfer.types.includes('Files')) {\n return\n }\n event.preventDefault()\n dragDepth.current += 1\n setDragging(true)\n },\n onDragOver: (event: React.DragEvent) => {\n if (onAttachFiles === undefined || !event.dataTransfer.types.includes('Files')) {\n return\n }\n event.preventDefault()\n },\n onDragLeave: () => {\n if (dragDepth.current > 0) {\n dragDepth.current -= 1\n if (dragDepth.current === 0) {\n setDragging(false)\n }\n }\n },\n onDrop: (event: React.DragEvent) => {\n if (onAttachFiles === undefined) {\n return\n }\n event.preventDefault()\n dragDepth.current = 0\n setDragging(false)\n emitFiles(event.dataTransfer.files)\n },\n }\n\n const SendIcon = icons?.send ?? ArrowUp\n const StopIcon = icons?.stop ?? Square\n const showStop = sending && onStop !== undefined\n\n return (\n <form\n ref={ref}\n data-as=\"chat-composer\"\n data-sending={sending}\n onSubmit={(event) => {\n event.preventDefault()\n submit()\n }}\n className={cn('flex w-full flex-col gap-2', className)}\n {...dragCounterHandlers}\n >\n {suggestions ? <div className=\"flex flex-wrap gap-1.5\">{suggestions}</div> : null}\n {attachments ? <div className=\"flex flex-wrap gap-1.5\">{attachments}</div> : null}\n <div\n data-dragging={dragging || undefined}\n className={cn(\n 'flex items-end gap-1.5 rounded-[var(--as-radius-lg)] border border-[var(--as-border)] bg-[var(--as-surface)] px-2 py-1.5 transition-colors focus-within:border-[var(--as-primary)]',\n dragging && 'border-dashed border-[var(--as-primary)] bg-[var(--as-primary)]/5',\n disabled && 'opacity-50',\n )}\n >\n {toolbarStart ? <div className=\"flex shrink-0 items-center gap-0.5 pb-0.5\">{toolbarStart}</div> : null}\n <textarea\n ref={setTextarea}\n value={value}\n rows={1}\n disabled={disabled}\n placeholder={placeholder ?? labels?.placeholder ?? 'Send a message…'}\n aria-label={ariaLabel ?? labels?.ariaLabel ?? 'Message'}\n onChange={(event) => onValueChange(event.target.value)}\n onKeyDown={onKeyDown}\n onPaste={(event) => emitFiles(event.clipboardData.files)}\n className=\"max-h-40 min-h-[1.5rem] w-full flex-1 resize-none bg-transparent px-1 py-1 text-sm leading-relaxed text-[var(--as-fg)] placeholder:text-[var(--as-muted-fg)] focus-visible:outline-none disabled:cursor-not-allowed\"\n />\n {toolbarEnd ? <div className=\"flex shrink-0 items-center gap-0.5 pb-0.5\">{toolbarEnd}</div> : null}\n {showStop ? (\n <button\n type=\"button\"\n aria-label={labels?.stop ?? 'Stop generating'}\n title={labels?.stop ?? 'Stop generating'}\n onClick={onStop}\n className=\"mb-0.5 flex size-7 shrink-0 items-center justify-center rounded-full border border-[var(--as-border)] bg-[var(--as-surface-raised)] text-[var(--as-fg)] transition-colors hover:bg-[var(--as-secondary)] focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-[var(--as-focus-ring)]\"\n >\n <StopIcon className=\"size-3.5\" aria-hidden />\n </button>\n ) : (\n <button\n type=\"submit\"\n aria-label={labels?.send ?? 'Send message'}\n title={labels?.send ?? 'Send message'}\n disabled={disabled || value.trim() === '' || sending}\n className=\"mb-0.5 flex size-7 shrink-0 items-center justify-center rounded-full bg-[var(--as-primary)] text-[var(--as-primary-fg)] transition-opacity hover:opacity-90 disabled:pointer-events-none disabled:opacity-30 focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-[var(--as-focus-ring)]\"\n >\n <SendIcon className=\"size-4\" aria-hidden />\n </button>\n )}\n </div>\n {dragging && onAttachFiles ? (\n <p className=\"text-xs text-[var(--as-muted-fg)]\" role=\"status\">\n {labels?.dropFiles ?? 'Drop files to attach'}\n </p>\n ) : null}\n </form>\n )\n },\n)\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/chat-launcher/ChatLauncher.tsx"],"names":["ChatLauncher"],"mappings":"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","file":"chunk-RPLEI6LQ.js","sourcesContent":["import * as React from 'react'\nimport { MessageCircle, X } from 'lucide-react'\nimport type { LucideIcon } from 'lucide-react'\n\nimport { cn } from '../../lib/utils'\nimport { Portal } from '../portal/Portal'\n\nexport interface ChatLauncherProps {\n /** The anchored panel body — usually `ChatPanel variant=\"bubble\"`. */\n panel: React.ReactNode\n open?: boolean\n defaultOpen?: boolean\n onOpenChange?: (open: boolean) => void\n position?: 'bottom-right' | 'bottom-left'\n label?: string\n closeLabel?: string\n icon?: LucideIcon\n closeIcon?: LucideIcon\n /** Unread / activity badge. */\n badge?: number | string\n container?: HTMLElement | null\n panelClassName?: string\n className?: string\n}\n\n/**\n * The floating chat bubble (career's `ChatWidget` launcher,\n * family-standard): fixed launcher button opening an anchored, non-modal\n * panel. `aria-expanded` wiring, Escape closes while focus is inside.\n */\nexport const ChatLauncher = React.forwardRef<HTMLButtonElement, ChatLauncherProps>(\n function ChatLauncher(\n {\n panel,\n open: openProp,\n defaultOpen = false,\n onOpenChange,\n position = 'bottom-right',\n label = 'Chat',\n closeLabel = 'Close chat',\n icon: Icon = MessageCircle,\n closeIcon: CloseIcon = X,\n badge,\n container,\n panelClassName,\n className,\n },\n ref,\n ) {\n const [uncontrolledOpen, setUncontrolledOpen] = React.useState(defaultOpen)\n const isControlled = openProp !== undefined\n const open = isControlled ? openProp : uncontrolledOpen\n const panelRef = React.useRef<HTMLDivElement | null>(null)\n\n const setOpen = (next: boolean) => {\n if (!isControlled) {\n setUncontrolledOpen(next)\n }\n onOpenChange?.(next)\n }\n\n React.useEffect(() => {\n if (!open) {\n return\n }\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape' && panelRef.current?.contains(document.activeElement)) {\n setOpen(false)\n }\n }\n document.addEventListener('keydown', onKeyDown)\n return () => document.removeEventListener('keydown', onKeyDown)\n })\n\n const showBadge = badge !== undefined && badge !== 0 && badge !== ''\n\n return (\n <>\n {open ? (\n <Portal container={container}>\n <div\n ref={panelRef}\n data-as=\"chat-launcher-panel\"\n className={cn(\n 'as-anim-pop fixed bottom-20 z-[var(--as-z-modal)] flex h-[min(36rem,calc(100dvh-11rem))] w-[min(26rem,calc(100vw-2rem))] flex-col overflow-hidden rounded-[var(--as-radius-lg)] border border-[var(--as-border)] bg-[var(--as-surface)] text-[var(--as-fg)] shadow-[var(--as-shadow-3)]',\n position === 'bottom-right' ? 'right-4' : 'left-4',\n panelClassName,\n )}\n role=\"complementary\"\n aria-label={label}\n >\n {panel}\n <button\n type=\"button\"\n aria-label={closeLabel}\n onClick={() => setOpen(false)}\n className=\"absolute right-2 top-2 z-10 rounded-[var(--as-radius-sm)] p-1 text-[var(--as-muted-fg)] transition-colors hover:bg-[var(--as-secondary)] hover:text-[var(--as-fg)] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--as-focus-ring)]\"\n >\n <CloseIcon aria-hidden className=\"size-4\" />\n </button>\n </div>\n </Portal>\n ) : null}\n <button\n ref={ref}\n type=\"button\"\n aria-expanded={open}\n aria-label={open ? closeLabel : label}\n title={open ? closeLabel : label}\n onClick={() => setOpen(!open)}\n data-as=\"chat-launcher\"\n data-open={open || undefined}\n className={cn(\n 'fixed bottom-4 z-[var(--as-z-popover)] flex size-12 items-center justify-center rounded-full bg-[var(--as-primary)] text-[var(--as-primary-fg)] shadow-[var(--as-shadow-2)] transition-transform hover:scale-105 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--as-focus-ring)]',\n position === 'bottom-right' ? 'right-4' : 'left-4',\n className,\n )}\n >\n <Icon className=\"size-5\" aria-hidden />\n {showBadge ? (\n <span className=\"absolute -right-0.5 -top-0.5 flex h-5 min-w-5 items-center justify-center rounded-full border-2 border-[var(--as-surface)] bg-[var(--as-danger)] px-1 text-[10px] font-semibold text-[var(--as-danger-fg)]\">\n {badge}\n </span>\n ) : null}\n </button>\n </>\n )\n },\n)\n"]}