@lettuceai/crisp 1.0.0 → 1.1.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.
@@ -1,6 +1,6 @@
1
- /** "Just now", "4 min ago", "Yesterday", "3 wk ago" — how a list says when. */
2
- export declare function relativeTime(when: Date | number, now?: Date | number): string;
3
- /** 950 → "950", 1 240 → "1.2k", 18 300 → "18k", 2 140 000 → "2.1M". */
4
- export declare function compactNumber(n: number): string;
5
- /** 1 536 000 → "1.5 MB". */
6
- export declare function fileSize(bytes: number): string;
1
+ /** "Just now", "4 min ago", "Yesterday", "3 wk ago" — how a list says when. Other locales follow `Intl.RelativeTimeFormat`. */
2
+ export declare function relativeTime(when: Date | number, now?: Date | number, locale?: string): string;
3
+ /** 950 → "950", 1 240 → "1.2k", 18 300 → "18k", 2 140 000 → "2.1M". Other locales follow compact `Intl.NumberFormat`. */
4
+ export declare function compactNumber(n: number, locale?: string): string;
5
+ /** 1 536 000 → "1.5 MB". Other locales use `Intl.NumberFormat` with byte units. */
6
+ export declare function fileSize(bytes: number, locale?: string): string;
@@ -0,0 +1,10 @@
1
+ import type { Ref, RefCallback } from "react";
2
+ /**
3
+ * Combines multiple React refs (callback or RefObject) into a single callback ref.
4
+ * Safely handles null and undefined refs.
5
+ */
6
+ export declare function mergeRefs<T>(...refs: (Ref<T> | undefined | null)[]): RefCallback<T>;
7
+ /**
8
+ * Extracts the ref from a React element across React 18 (element.ref) and React 19 (element.props.ref).
9
+ */
10
+ export declare function getElementRef<T>(element: unknown): Ref<T> | undefined;
@@ -0,0 +1,221 @@
1
+ import { type ReactNode } from "react";
2
+ /** Every string crisp renders on its own: aria-labels, default prop text and status lines. */
3
+ export interface CrispStrings {
4
+ actionBarBack: string;
5
+ alertDismiss: string;
6
+ alertShowDetails: string;
7
+ alertHideDetails: string;
8
+ appBarBack: string;
9
+ appBarSearch: string;
10
+ appBarClearSearch: string;
11
+ appBarCloseSearch: string;
12
+ audioItemPlay: (title: string) => string;
13
+ audioItemPause: (title: string) => string;
14
+ audioItemSeek: (title: string) => string;
15
+ avatarGroupPeople: (count: number) => string;
16
+ avatarPickerRemove: string;
17
+ avatarPickerTitle: string;
18
+ avatarPickerDescription: string;
19
+ avatarPickerCancel: string;
20
+ avatarPickerUse: string;
21
+ avatarPickerZoom: string;
22
+ bannerDismiss: string;
23
+ breadcrumbLabel: string;
24
+ breadcrumbMore: (count: number) => string;
25
+ carouselPosition: (index: number, count: number) => string;
26
+ carouselGoTo: (index: number) => string;
27
+ carouselPrevious: string;
28
+ carouselNext: string;
29
+ chipRemove: string;
30
+ citationSource: (title: string) => string;
31
+ citationVisit: string;
32
+ colorPickerCurrent: (value: string) => string;
33
+ colorPickerPick: string;
34
+ colorPickerHex: string;
35
+ comboboxPlaceholder: string;
36
+ comboboxSearch: string;
37
+ comboboxEmpty: string;
38
+ comboboxClear: string;
39
+ commandPaletteLabel: string;
40
+ commandPalettePlaceholder: string;
41
+ commandPaletteEmpty: string;
42
+ commandPaletteEscape: string;
43
+ composerPlaceholder: string;
44
+ composerMessage: string;
45
+ composerAttachment: string;
46
+ composerFile: string;
47
+ composerAttachmentRemove: (name: string | undefined) => string;
48
+ composerAddAttachment: string;
49
+ composerCancelRecording: string;
50
+ composerRecordVoice: string;
51
+ composerStopAndTranscribe: string;
52
+ composerTranscribing: string;
53
+ composerRecording: (elapsed: string) => string;
54
+ composerStop: string;
55
+ composerSend: string;
56
+ composerSending: string;
57
+ composerContinue: string;
58
+ composerSendAsSystem: string;
59
+ confirmTitle: string;
60
+ confirmCancel: string;
61
+ confirmConfirm: string;
62
+ confirmUndone: string;
63
+ copyButtonCopy: string;
64
+ copyButtonCopied: string;
65
+ datePickerPlaceholder: string;
66
+ datePickerPreviousMonth: string;
67
+ datePickerNextMonth: string;
68
+ datePickerTime: string;
69
+ dialogClose: string;
70
+ diffBefore: string;
71
+ diffAfter: string;
72
+ diffChanges: string;
73
+ downloadFailed: string;
74
+ downloadWaiting: string;
75
+ downloadVerifying: string;
76
+ downloadPaused: string;
77
+ downloadProgress: (done: string, total: string) => string;
78
+ downloadSpeed: (rate: string) => string;
79
+ downloadLeftSeconds: (seconds: number) => string;
80
+ downloadLeftMinutes: (minutes: number) => string;
81
+ downloadLeftHours: (hours: string) => string;
82
+ downloadPause: (name: string) => string;
83
+ downloadResume: (name: string) => string;
84
+ downloadRetry: (name: string) => string;
85
+ downloadCancel: (name: string) => string;
86
+ downloadFileCount: (count: number) => string;
87
+ downloadShowFiles: (count: number) => string;
88
+ downloadHideFiles: string;
89
+ downloadFailedCount: (failed: number, total: number) => string;
90
+ downloadFilesDone: (done: number, total: number) => string;
91
+ downloadFailedBadge: (count: number) => string;
92
+ dropzoneOver: string;
93
+ dropzoneIdle: string;
94
+ errorStateTitle: string;
95
+ errorStateRetry: string;
96
+ feedbackGood: string;
97
+ feedbackBad: string;
98
+ feedbackCopy: string;
99
+ feedbackCopied: string;
100
+ feedbackRetry: string;
101
+ formSave: string;
102
+ formCancel: string;
103
+ formUnsaved: string;
104
+ formDiscardTitle: string;
105
+ formDiscardMessage: string;
106
+ formDiscardConfirm: string;
107
+ formDiscardCancel: string;
108
+ imageViewerZoomIn: string;
109
+ imageViewerZoomOut: string;
110
+ imageViewerClose: string;
111
+ imageViewerPrevious: string;
112
+ imageViewerNext: string;
113
+ infiniteScrollLoading: string;
114
+ loadingState: string;
115
+ messageScene: string;
116
+ messageSystem: string;
117
+ messagePinned: string;
118
+ messageMenuTitle: string;
119
+ messageReasoning: string;
120
+ messageTyping: string;
121
+ modelSelectPlaceholder: string;
122
+ modelSelectTitle: string;
123
+ modelSelectDefault: string;
124
+ modelSelectVision: string;
125
+ modelSelectAudio: string;
126
+ navPrimary: string;
127
+ navCreate: string;
128
+ navCollapse: string;
129
+ navCollapseSidebar: string;
130
+ navExpandSidebar: string;
131
+ numberInputDecrease: string;
132
+ numberInputIncrease: string;
133
+ otpDigit: (index: number, total: number) => string;
134
+ paginationLabel: string;
135
+ paginationPrevious: string;
136
+ paginationNext: string;
137
+ paginationPage: (page: number) => string;
138
+ partitionBarFree: string;
139
+ promptSuggestionsTitle: string;
140
+ reorderableHandle: (index: number, count: number) => string;
141
+ resizableResize: string;
142
+ searchFieldPlaceholder: string;
143
+ searchFieldClear: string;
144
+ secretInputPaste: string;
145
+ secretInputClear: string;
146
+ secretInputShow: string;
147
+ secretInputHide: string;
148
+ secretInputChecking: string;
149
+ secretInputConnected: string;
150
+ selectMenuPlaceholder: string;
151
+ selectMenuClear: string;
152
+ selectMenuEmpty: string;
153
+ selectMenuSelected: (count: number) => string;
154
+ shelfBack: string;
155
+ shelfForward: string;
156
+ sheetClose: string;
157
+ splitButtonMore: string;
158
+ stepperProgress: (step: number, total: number) => string;
159
+ stepperBackTo: (label: string) => string;
160
+ tableEmpty: string;
161
+ tagInputPlaceholder: string;
162
+ tagInputRemove: (tag: string) => string;
163
+ tagInputLimit: (max: number) => string;
164
+ themeEditorPreset: string;
165
+ themeEditorCustom: string;
166
+ themeEditorDensity: string;
167
+ themeEditorDensityDefault: string;
168
+ themeEditorDensityCompact: string;
169
+ themeEditorRadius: string;
170
+ themeEditorRadiusSharp: string;
171
+ themeEditorRadiusDefault: string;
172
+ themeEditorRadiusRound: string;
173
+ themeEditorReset: string;
174
+ themeEditorDerived: string;
175
+ themeEditorDerivedHint: string;
176
+ themeEditorBody: string;
177
+ themeEditorMuted: string;
178
+ themeEditorAccent: string;
179
+ themeEditorContrast: (label: string, ratio: string, need: number) => string;
180
+ themeEditorSurface: string;
181
+ themeEditorSurfaceHint: string;
182
+ themeEditorForeground: string;
183
+ themeEditorForegroundHint: string;
184
+ themeEditorAccentHint: string;
185
+ themeEditorDanger: string;
186
+ themeEditorDangerHint: string;
187
+ themeEditorWarning: string;
188
+ themeEditorWarningHint: string;
189
+ themeEditorInfo: string;
190
+ themeEditorInfoHint: string;
191
+ themeEditorSecondary: string;
192
+ themeEditorSecondaryHint: string;
193
+ titleBarMinimize: string;
194
+ titleBarMaximize: string;
195
+ titleBarClose: string;
196
+ toastDismiss: string;
197
+ tourLabel: string;
198
+ tourSkip: string;
199
+ tourFinish: string;
200
+ tourBack: string;
201
+ tourNext: string;
202
+ treeCollapse: string;
203
+ treeExpand: string;
204
+ }
205
+ export declare const englishStrings: CrispStrings;
206
+ interface CrispStringsValue {
207
+ strings: CrispStrings;
208
+ locale: string;
209
+ }
210
+ export interface CrispStringsProviderProps {
211
+ /** Only the strings you translate; the rest stay English. */
212
+ strings?: Partial<CrispStrings>;
213
+ /** A BCP 47 tag used by every `Intl` call and the format helpers. Default "en". */
214
+ locale?: string;
215
+ children: ReactNode;
216
+ }
217
+ /** Translates crisp's built-in text. Without it every component renders English and formats for "en". */
218
+ export declare function CrispStringsProvider({ strings, locale, children }: CrispStringsProviderProps): import("react").JSX.Element;
219
+ /** The active strings and locale, for components that render their own text with crisp's. */
220
+ export declare function useCrispStrings(): CrispStringsValue;
221
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lettuceai/crisp",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "React components, design tokens and motion for LettuceAI.",
5
5
  "keywords": [
6
6
  "react",
@@ -47,6 +47,7 @@
47
47
  "build": "vite build && tsc -p tsconfig.build.json",
48
48
  "typecheck": "tsc -p tsconfig.json --noEmit",
49
49
  "lint": "oxlint src",
50
+ "test": "bun test",
50
51
  "prepublishOnly": "bun run build"
51
52
  },
52
53
  "peerDependencies": {
@@ -66,6 +67,7 @@
66
67
  "tailwind-merge": "^3.6.0"
67
68
  },
68
69
  "devDependencies": {
70
+ "@types/bun": "^1.4.3",
69
71
  "@types/react": "^19.2.18",
70
72
  "@types/react-dom": "^19.2.4",
71
73
  "@vitejs/plugin-react": "^6.1.0",