nucleus-core-ts 0.9.879 → 0.9.880

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/dist/.build-ok CHANGED
@@ -1 +1 @@
1
- 0.9.879
1
+ 0.9.880
@@ -3,6 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { useState } from 'react';
4
4
  import { cn } from '../../../utils/cn';
5
5
  import { useChat } from '../hooks/useChat';
6
+ import { DEFAULT_CHAT_LABELS } from '../labels';
6
7
  import { chatPanelTheme } from '../theme';
7
8
  import { ConversationList } from './ConversationList';
8
9
  import { MessageComposer } from './MessageComposer';
@@ -10,6 +11,10 @@ import { MessageThread } from './MessageThread';
10
11
  import { NewConversationModal } from './NewConversationModal';
11
12
  export function ChatPanel(props) {
12
13
  const theme = chatPanelTheme;
14
+ const say = {
15
+ ...DEFAULT_CHAT_LABELS,
16
+ ...props.labels
17
+ };
13
18
  const chat = useChat(props);
14
19
  const { store } = chat;
15
20
  const [pickerOpen, setPickerOpen] = useState(false);
@@ -66,7 +71,7 @@ export function ChatPanel(props) {
66
71
  type: "button",
67
72
  className: theme.sidebar.newButton,
68
73
  onClick: handleNewConversation,
69
- "aria-label": "New conversation",
74
+ "aria-label": say.newConversation,
70
75
  children: /*#__PURE__*/ _jsxs("svg", {
71
76
  className: "h-4 w-4",
72
77
  fill: "none",
@@ -88,6 +93,7 @@ export function ChatPanel(props) {
88
93
  ]
89
94
  }),
90
95
  /*#__PURE__*/ _jsx(ConversationList, {
96
+ labels: props.labels,
91
97
  conversations: store.conversations,
92
98
  activeId: store.activeConversationId,
93
99
  currentUserId: props.currentUserId,
@@ -103,6 +109,7 @@ export function ChatPanel(props) {
103
109
  className: "flex min-h-0 flex-1 flex-col",
104
110
  children: [
105
111
  /*#__PURE__*/ _jsx(MessageThread, {
112
+ labels: props.labels,
106
113
  conversation: active,
107
114
  messages: store.messages,
108
115
  currentUserId: props.currentUserId,
@@ -127,6 +134,7 @@ export function ChatPanel(props) {
127
134
  onStartDirect: handleStartDirect
128
135
  }),
129
136
  active && /*#__PURE__*/ _jsx(MessageComposer, {
137
+ labels: props.labels,
130
138
  theme: theme,
131
139
  value: store.composerText,
132
140
  disabled: store.isSending,
@@ -1,7 +1,9 @@
1
+ import { type ChatPanelLabels } from '../labels';
1
2
  import type { ReactElement } from 'react';
2
3
  import type { ChatPanelTheme } from '../theme';
3
4
  import type { ChatConversationDTO } from '../types';
4
5
  type ConversationListProps = {
6
+ labels?: Partial<ChatPanelLabels>;
5
7
  conversations: ChatConversationDTO[];
6
8
  activeId: string | null;
7
9
  currentUserId: string;
@@ -11,5 +13,5 @@ type ConversationListProps = {
11
13
  resolveUserName?: (userId: string) => string | undefined;
12
14
  resolveUserAvatar?: (userId: string) => string | undefined;
13
15
  };
14
- export declare function ConversationList({ conversations, activeId, currentUserId, isLoading, theme, onSelect, resolveUserName, resolveUserAvatar, }: ConversationListProps): ReactElement;
16
+ export declare function ConversationList({ conversations, activeId, currentUserId, isLoading, theme, onSelect, resolveUserName, resolveUserAvatar, labels, }: ConversationListProps): ReactElement;
15
17
  export {};
@@ -1,18 +1,23 @@
1
- 'use client';
2
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { DEFAULT_CHAT_LABELS } from '../labels';
3
+ 'use client';
3
4
  import { cn } from '../../../utils/cn';
4
5
  import { conversationTitle, formatRelativeTime, initialsOf, otherParticipantId } from '../helpers';
5
- export function ConversationList({ conversations, activeId, currentUserId, isLoading, theme, onSelect, resolveUserName, resolveUserAvatar }) {
6
+ export function ConversationList({ conversations, activeId, currentUserId, isLoading, theme, onSelect, resolveUserName, resolveUserAvatar, labels }) {
7
+ const say = {
8
+ ...DEFAULT_CHAT_LABELS,
9
+ ...labels
10
+ };
6
11
  if (isLoading && conversations.length === 0) {
7
12
  return /*#__PURE__*/ _jsx("div", {
8
13
  className: theme.sidebar.empty,
9
- children: "Loading conversations..."
14
+ children: say.loadingConversations
10
15
  });
11
16
  }
12
17
  if (conversations.length === 0) {
13
18
  return /*#__PURE__*/ _jsx("div", {
14
19
  className: theme.sidebar.empty,
15
- children: "No conversations yet"
20
+ children: say.noConversations
16
21
  });
17
22
  }
18
23
  return /*#__PURE__*/ _jsx("div", {
@@ -1,6 +1,8 @@
1
+ import { type ChatPanelLabels } from '../labels';
1
2
  import type { ReactElement } from 'react';
2
3
  import type { ChatPanelTheme } from '../theme';
3
4
  type MessageComposerProps = {
5
+ labels?: Partial<ChatPanelLabels>;
4
6
  theme: ChatPanelTheme;
5
7
  value: string;
6
8
  disabled: boolean;
@@ -9,5 +11,5 @@ type MessageComposerProps = {
9
11
  onSendText: () => void;
10
12
  onSendFiles: (files: File[], text: string) => void;
11
13
  };
12
- export declare function MessageComposer({ theme, value, disabled, uploadEnabled, onChange, onSendText, onSendFiles, }: MessageComposerProps): ReactElement;
14
+ export declare function MessageComposer({ theme, value, disabled, uploadEnabled, onChange, onSendText, onSendFiles, labels, }: MessageComposerProps): ReactElement;
13
15
  export {};
@@ -1,7 +1,12 @@
1
- 'use client';
2
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { DEFAULT_CHAT_LABELS } from '../labels';
3
+ 'use client';
3
4
  import { useRef, useState } from 'react';
4
- export function MessageComposer({ theme, value, disabled, uploadEnabled, onChange, onSendText, onSendFiles }) {
5
+ export function MessageComposer({ theme, value, disabled, uploadEnabled, onChange, onSendText, onSendFiles, labels }) {
6
+ const say = {
7
+ ...DEFAULT_CHAT_LABELS,
8
+ ...labels
9
+ };
5
10
  const fileInputRef = useRef(null);
6
11
  const [pendingFiles, setPendingFiles] = useState([]);
7
12
  const submit = ()=>{
@@ -41,7 +46,7 @@ export function MessageComposer({ theme, value, disabled, uploadEnabled, onChang
41
46
  /*#__PURE__*/ _jsx("button", {
42
47
  type: "button",
43
48
  onClick: ()=>removeFile(index),
44
- "aria-label": "Remove file",
49
+ "aria-label": say.removeFile,
45
50
  children: "×"
46
51
  })
47
52
  ]
@@ -56,7 +61,7 @@ export function MessageComposer({ theme, value, disabled, uploadEnabled, onChang
56
61
  type: "button",
57
62
  className: theme.composer.attachButton,
58
63
  onClick: ()=>fileInputRef.current?.click(),
59
- "aria-label": "Attach files",
64
+ "aria-label": say.attachFiles,
60
65
  children: /*#__PURE__*/ _jsxs("svg", {
61
66
  className: "h-5 w-5",
62
67
  fill: "none",
@@ -64,7 +69,7 @@ export function MessageComposer({ theme, value, disabled, uploadEnabled, onChang
64
69
  stroke: "currentColor",
65
70
  children: [
66
71
  /*#__PURE__*/ _jsx("title", {
67
- children: "Attach"
72
+ children: say.attach
68
73
  }),
69
74
  /*#__PURE__*/ _jsx("path", {
70
75
  strokeLinecap: "round",
@@ -86,7 +91,7 @@ export function MessageComposer({ theme, value, disabled, uploadEnabled, onChang
86
91
  }),
87
92
  /*#__PURE__*/ _jsx("textarea", {
88
93
  className: theme.composer.input,
89
- placeholder: "Write a message...",
94
+ placeholder: say.writeMessage,
90
95
  rows: 1,
91
96
  value: value,
92
97
  disabled: disabled,
@@ -1,7 +1,9 @@
1
+ import { type ChatPanelLabels } from '../labels';
1
2
  import type { ReactElement } from 'react';
2
3
  import type { ChatPanelTheme } from '../theme';
3
4
  import type { ChatConversationDTO, ChatMessageDTO, TypingIndicator } from '../types';
4
5
  type MessageThreadProps = {
6
+ labels?: Partial<ChatPanelLabels>;
5
7
  conversation: ChatConversationDTO | null;
6
8
  messages: ChatMessageDTO[];
7
9
  currentUserId: string;
@@ -12,5 +14,5 @@ type MessageThreadProps = {
12
14
  onLoadOlder: () => void;
13
15
  resolveUserName?: (userId: string) => string | undefined;
14
16
  };
15
- export declare function MessageThread({ conversation, messages, currentUserId, typing, hasMore, isLoading, theme, onLoadOlder, resolveUserName, }: MessageThreadProps): ReactElement;
17
+ export declare function MessageThread({ conversation, messages, currentUserId, typing, hasMore, isLoading, theme, onLoadOlder, resolveUserName, labels, }: MessageThreadProps): ReactElement;
16
18
  export {};
@@ -1,5 +1,6 @@
1
- 'use client';
2
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { DEFAULT_CHAT_LABELS } from '../labels';
3
+ 'use client';
3
4
  import { useEffect, useRef } from 'react';
4
5
  import { cn } from '../../../utils/cn';
5
6
  import { conversationTitle, formatClockTime } from '../helpers';
@@ -20,7 +21,11 @@ function Attachments({ message, theme }) {
20
21
  }, attachment.id))
21
22
  });
22
23
  }
23
- export function MessageThread({ conversation, messages, currentUserId, typing, hasMore, isLoading, theme, onLoadOlder, resolveUserName }) {
24
+ export function MessageThread({ conversation, messages, currentUserId, typing, hasMore, isLoading, theme, onLoadOlder, resolveUserName, labels }) {
25
+ const say = {
26
+ ...DEFAULT_CHAT_LABELS,
27
+ ...labels
28
+ };
24
29
  const scrollRef = useRef(null);
25
30
  useEffect(()=>{
26
31
  const el = scrollRef.current;
@@ -32,7 +37,7 @@ export function MessageThread({ conversation, messages, currentUserId, typing, h
32
37
  if (!conversation) {
33
38
  return /*#__PURE__*/ _jsx("div", {
34
39
  className: theme.thread.placeholder,
35
- children: "Select a conversation to start chatting"
40
+ children: say.selectConversation
36
41
  });
37
42
  }
38
43
  const title = conversationTitle(conversation, currentUserId, resolveUserName);
@@ -75,7 +80,7 @@ export function MessageThread({ conversation, messages, currentUserId, typing, h
75
80
  }),
76
81
  messages.length === 0 && !isLoading ? /*#__PURE__*/ _jsx("div", {
77
82
  className: theme.thread.empty,
78
- children: "No messages yet — say hello"
83
+ children: say.noMessages
79
84
  }) : messages.map((message)=>{
80
85
  const own = message.senderId === currentUserId;
81
86
  return /*#__PURE__*/ _jsx("div", {
@@ -89,7 +94,7 @@ export function MessageThread({ conversation, messages, currentUserId, typing, h
89
94
  }),
90
95
  message.deletedAt ? /*#__PURE__*/ _jsx("span", {
91
96
  className: theme.message.deleted,
92
- children: "This message was deleted"
97
+ children: say.deletedMessage
93
98
  }) : /*#__PURE__*/ _jsxs(_Fragment, {
94
99
  children: [
95
100
  message.content && /*#__PURE__*/ _jsx("span", {
@@ -4,6 +4,7 @@ export { MessageComposer } from './components/MessageComposer';
4
4
  export { MessageThread } from './components/MessageThread';
5
5
  export { NewConversationModal } from './components/NewConversationModal';
6
6
  export { type UseChatReturn, useChat } from './hooks/useChat';
7
+ export { type ChatPanelLabels, DEFAULT_CHAT_LABELS } from './labels';
7
8
  export { useChatStore } from './store';
8
9
  export { type ChatPanelTheme, chatPanelTheme, extendChatPanelTheme } from './theme';
9
10
  export type { ChatAttachmentDTO, ChatConversationDTO, ChatDirectoryUser, ChatMessageDTO, ChatPanelActions, ChatPanelProps, ChatPanelState, ChatParticipantDTO, TypingIndicator, } from './types';
@@ -4,5 +4,6 @@ export { MessageComposer } from './components/MessageComposer';
4
4
  export { MessageThread } from './components/MessageThread';
5
5
  export { NewConversationModal } from './components/NewConversationModal';
6
6
  export { useChat } from './hooks/useChat';
7
+ export { DEFAULT_CHAT_LABELS } from './labels';
7
8
  export { useChatStore } from './store';
8
9
  export { chatPanelTheme, extendChatPanelTheme } from './theme';
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Every word the chat says, so a portal can say them in its own language.
3
+ *
4
+ * The panel wrote them in English inside the components, and the one label the
5
+ * consumer COULD pass — `title` — was the tell: an intranet in Turkish set the
6
+ * heading to "Sohbetler" and the panel underneath it still said "No
7
+ * conversations yet" and "Select a conversation to start chatting". Two
8
+ * sentences of English on the one screen in the product where people talk to
9
+ * each other.
10
+ *
11
+ * Defaults stay English, so nothing that does not pass labels changes.
12
+ */
13
+ export type ChatPanelLabels = {
14
+ /** While the conversation list is still arriving. */
15
+ loadingConversations: string;
16
+ /** The list, with nothing in it. */
17
+ noConversations: string;
18
+ /** No conversation chosen yet. */
19
+ selectConversation: string;
20
+ /** A conversation with no messages in it. */
21
+ noMessages: string;
22
+ /** A message somebody removed. */
23
+ deletedMessage: string;
24
+ /** The composer's own placeholder. */
25
+ writeMessage: string;
26
+ attach: string;
27
+ attachFiles: string;
28
+ removeFile: string;
29
+ newConversation: string;
30
+ close: string;
31
+ };
32
+ export declare const DEFAULT_CHAT_LABELS: ChatPanelLabels;
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Every word the chat says, so a portal can say them in its own language.
3
+ *
4
+ * The panel wrote them in English inside the components, and the one label the
5
+ * consumer COULD pass — `title` — was the tell: an intranet in Turkish set the
6
+ * heading to "Sohbetler" and the panel underneath it still said "No
7
+ * conversations yet" and "Select a conversation to start chatting". Two
8
+ * sentences of English on the one screen in the product where people talk to
9
+ * each other.
10
+ *
11
+ * Defaults stay English, so nothing that does not pass labels changes.
12
+ */ export const DEFAULT_CHAT_LABELS = {
13
+ loadingConversations: 'Loading conversations...',
14
+ noConversations: 'No conversations yet',
15
+ selectConversation: 'Select a conversation to start chatting',
16
+ noMessages: 'No messages yet — say hello',
17
+ deletedMessage: 'This message was deleted',
18
+ writeMessage: 'Write a message...',
19
+ attach: 'Attach',
20
+ attachFiles: 'Attach files',
21
+ removeFile: 'Remove file',
22
+ newConversation: 'New conversation',
23
+ close: 'Close'
24
+ };
@@ -1,4 +1,5 @@
1
1
  import type { ChatActionResponse, ChatConversationDTO, ChatConversationListResponse, ChatConversationResponse, ChatCreateConversationPayload, ChatMessageDTO, ChatMessageListResponse, ChatMessageResponse, ChatReadResponse, ChatSendMessagePayload } from '../../../../src/Client/ApiCaller/types';
2
+ import type { ChatPanelLabels } from '../labels';
2
3
  export type { ChatAttachmentDTO, ChatConversationDTO, ChatMessageDTO, ChatParticipantDTO, } from '../../../../src/Client/ApiCaller/types';
3
4
  /** Mirrors the useServerAction shape exposed by the generated API hook. */
4
5
  export type GenericAction<TPayload = unknown, TData = unknown, TError = unknown> = {
@@ -75,6 +76,8 @@ export type ChatPanelProps = {
75
76
  /** Enable the file-attachment composer button (requires backend CDN). */
76
77
  uploadEnabled?: boolean;
77
78
  title?: string;
79
+ /** Every word the panel says, so a portal can say them in its own language. */
80
+ labels?: Partial<ChatPanelLabels>;
78
81
  className?: string;
79
82
  /** Resolve a display name for a user id (sender labels, conversation titles). */
80
83
  resolveUserName?: (userId: string) => string | undefined;
@@ -8,8 +8,8 @@ export type { CaptchaAction, CaptchaChallenge, CaptchaConfig, CaptchaDifficulty,
8
8
  export { Captcha, captchaTheme } from './components/Captcha';
9
9
  export type { ChangePasswordAction, ChangePasswordFormProps, ChangePasswordHeaderProps, ChangePasswordPageConfig, ChangePasswordStep, } from './components/ChangePasswordPage';
10
10
  export { ChangePasswordPage, useChangePasswordStore, } from './components/ChangePasswordPage';
11
- export type { ChatDirectoryUser, ChatPanelActions, ChatPanelProps, ChatPanelState, ChatPanelTheme, TypingIndicator as ChatTypingIndicator, UseChatReturn, } from './components/ChatPanel';
12
- export { ChatPanel, chatPanelTheme, extendChatPanelTheme, NewConversationModal, useChat, useChatStore, } from './components/ChatPanel';
11
+ export type { ChatDirectoryUser, ChatPanelActions, ChatPanelLabels, ChatPanelProps, ChatPanelState, ChatPanelTheme, TypingIndicator as ChatTypingIndicator, UseChatReturn, } from './components/ChatPanel';
12
+ export { ChatPanel, chatPanelTheme, DEFAULT_CHAT_LABELS, extendChatPanelTheme, NewConversationModal, useChat, useChatStore, } from './components/ChatPanel';
13
13
  export { Checkbox } from './components/Checkbox';
14
14
  export { DataTable } from './components/DataTable';
15
15
  export { DatePicker } from './components/DatePicker';
package/dist/fe/index.js CHANGED
@@ -7,7 +7,7 @@ export { Button } from './components/Button';
7
7
  export { Captcha, captchaTheme } from './components/Captcha';
8
8
  export { ChangePasswordPage, useChangePasswordStore } from './components/ChangePasswordPage';
9
9
  // Chat
10
- export { ChatPanel, chatPanelTheme, extendChatPanelTheme, NewConversationModal, useChat, useChatStore } from './components/ChatPanel';
10
+ export { ChatPanel, chatPanelTheme, DEFAULT_CHAT_LABELS, extendChatPanelTheme, NewConversationModal, useChat, useChatStore } from './components/ChatPanel';
11
11
  export { Checkbox } from './components/Checkbox';
12
12
  export { DataTable } from './components/DataTable';
13
13
  export { DatePicker } from './components/DatePicker';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nucleus-core-ts",
3
- "version": "0.9.879",
3
+ "version": "0.9.880",
4
4
  "description": "Production-ready, enterprise-grade TypeScript framework for building multi-tenant APIs",
5
5
  "author": "Hidayet Can Özcan <hidayetcan@gmail.com>",
6
6
  "license": "SEE LICENSE IN LICENSE",