@homecode/ui 5.20.20 → 5.20.21
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/esm/index.js +1 -1
- package/dist/esm/src/components/FormattedText/FormattedText.js +31 -5
- package/dist/esm/src/components/FormattedText/FormattedText.styl.js +2 -2
- package/dist/esm/src/components/PromptComposer/promptComposerPlaceholder.js +10 -0
- package/dist/esm/src/components/PromptComposer/usePromptComposerEditor.js +2 -1
- package/dist/esm/types/src/components/FormattedText/FormattedText.d.ts +2 -1
- package/dist/esm/types/src/components/FormattedText/FormattedText.types.d.ts +10 -0
- package/dist/esm/types/src/components/FormattedText/index.d.ts +2 -2
- package/dist/esm/types/src/components/PromptComposer/promptComposerPlaceholder.d.ts +9 -0
- package/dist/esm/types/src/components/PromptComposer/promptComposerPlaceholder.test.d.ts +1 -0
- package/package.json +1 -1
package/dist/esm/index.js
CHANGED
|
@@ -24,7 +24,7 @@ export { Flex } from './src/components/Flex/Flex.js';
|
|
|
24
24
|
export { FoldedLine } from './src/components/FoldedLine/FoldedLine.js';
|
|
25
25
|
export { FoldedLineAction, FoldedLineActionsProvider, useFoldedLineActionsRegister } from './src/components/FoldedLine/FoldedLineActionsContext.js';
|
|
26
26
|
export { Form } from './src/components/Form/Form.js';
|
|
27
|
-
export { FormattedText } from './src/components/FormattedText/FormattedText.js';
|
|
27
|
+
export { FormattedText, findJsonEndExclusive } from './src/components/FormattedText/FormattedText.js';
|
|
28
28
|
export { Gap } from './src/components/Gap/Gap.js';
|
|
29
29
|
export { Gallery, normalizeGalleryItem } from './src/components/Gallery/Gallery.js';
|
|
30
30
|
export { GridLayout } from './src/components/GridLayout/GridLayout.js';
|
|
@@ -108,7 +108,24 @@ function applyInjectors(text, injectors) {
|
|
|
108
108
|
});
|
|
109
109
|
return result;
|
|
110
110
|
}
|
|
111
|
-
function FormattedText({ text, className, onButtonClick, }) {
|
|
111
|
+
function FormattedText({ text, className, onButtonClick, quotes, injectors, breaks = true, }) {
|
|
112
|
+
// Without `<br>`s the text keeps its own newlines (pre-wrap), so a block, such
|
|
113
|
+
// as a table, swallows the blank lines after it instead of showing them.
|
|
114
|
+
const blankLinesAfter = (content, from) => breaks ? 0 : content.slice(from).match(/^\s*/)[0].length;
|
|
115
|
+
/** A run of `> ` lines, grayed with a bar down its left side. */
|
|
116
|
+
const injectQuote = (content) => {
|
|
117
|
+
const matches = content.match(/(?:^|\n)(>[^\n]*(?:\n>[^\n]*)*)(?:\n|$)/);
|
|
118
|
+
if (!matches)
|
|
119
|
+
return null;
|
|
120
|
+
const lines = matches[1]
|
|
121
|
+
.split('\n')
|
|
122
|
+
.map(line => line.replace(/^>[ \t]?/, ''));
|
|
123
|
+
return {
|
|
124
|
+
elem: (jsx("div", { className: S.quote, "data-quote": true, children: lines.join('\n') })),
|
|
125
|
+
index: matches.index,
|
|
126
|
+
length: matches[0].length,
|
|
127
|
+
};
|
|
128
|
+
};
|
|
112
129
|
const injectLines = (content) => {
|
|
113
130
|
const matches = content.match(/(^|\n)---[ \t]*(?:\n|$)/);
|
|
114
131
|
if (!matches)
|
|
@@ -266,6 +283,7 @@ function FormattedText({ text, className, onButtonClick, }) {
|
|
|
266
283
|
const headingTags = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'];
|
|
267
284
|
const processCellContent = (value, depth = 0) => applyInjectors(value, [
|
|
268
285
|
injectCodeBlock,
|
|
286
|
+
...(injectors ?? []),
|
|
269
287
|
injectPrettyJson,
|
|
270
288
|
...(depth === 0
|
|
271
289
|
? [
|
|
@@ -291,7 +309,10 @@ function FormattedText({ text, className, onButtonClick, }) {
|
|
|
291
309
|
injectButtons,
|
|
292
310
|
]);
|
|
293
311
|
const injectHeading = (content) => {
|
|
294
|
-
|
|
312
|
+
// Without `<br>`s the text keeps its own newlines (pre-wrap), so a heading,
|
|
313
|
+
// which is a block, swallows the blank lines around it instead of leaving
|
|
314
|
+
// an extra empty line.
|
|
315
|
+
const matches = content.match(breaks ? /(^|\n)(#{1,6})\s+([^\n]+)/ : /(^|\n+)(#{1,6})[ \t]+([^\n]+)\n*/);
|
|
295
316
|
if (!matches)
|
|
296
317
|
return null;
|
|
297
318
|
const Tag = headingTags[Math.min(matches[2].length, 6) - 1];
|
|
@@ -350,13 +371,18 @@ function FormattedText({ text, className, onButtonClick, }) {
|
|
|
350
371
|
return {
|
|
351
372
|
elem: (jsx(Table, { size: "s", variant: "plain", columns: columns, data: tableData, className: S.table })),
|
|
352
373
|
index: matches.index + (matches[1]?.length || 0),
|
|
353
|
-
length: matches[0].length -
|
|
374
|
+
length: matches[0].length -
|
|
375
|
+
(matches[1]?.length || 0) +
|
|
376
|
+
blankLinesAfter(content, matches.index + matches[0].length),
|
|
354
377
|
};
|
|
355
378
|
};
|
|
356
379
|
return (jsx("div", { className: className, children: applyInjectors(text, [
|
|
357
380
|
injectTables,
|
|
358
381
|
injectCodeBlock,
|
|
382
|
+
...(injectors ?? []),
|
|
359
383
|
injectPrettyJson,
|
|
384
|
+
// After code, so a `> ` line inside a code block stays code.
|
|
385
|
+
...(quotes ? [injectQuote] : []),
|
|
360
386
|
injectHeading,
|
|
361
387
|
injectLines,
|
|
362
388
|
injectLinks,
|
|
@@ -365,8 +391,8 @@ function FormattedText({ text, className, onButtonClick, }) {
|
|
|
365
391
|
injectBullet,
|
|
366
392
|
injectNumbered,
|
|
367
393
|
injectButtons,
|
|
368
|
-
injectBreaks,
|
|
394
|
+
...(breaks ? [injectBreaks] : []),
|
|
369
395
|
]) }));
|
|
370
396
|
}
|
|
371
397
|
|
|
372
|
-
export { FormattedText, hrefForFormattedLink };
|
|
398
|
+
export { FormattedText, findJsonEndExclusive, hrefForFormattedLink };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
var css_248z = ".FormattedText_bullet__vbqlq{display:inline-block;margin-bottom:2px;margin-left:var(--p-2);margin-right:2px}.FormattedText_bullet__vbqlq:before{background-color:var(--accent-color);border-radius:50%;content:\"\";display:block;height:6px;margin:0 4px;width:6px}.FormattedText_numberedIndex__rZ6Kt{font-feature-settings:\"tnum\";color:var(--accent-color);display:inline-block;font-variant-numeric:tabular-nums;margin-left:var(--p-2);margin-right:6px;min-width:1.25em}.FormattedText_line__c2bmE{background-color:var(--accent-color-alpha-200);border-radius:2px;height:2px;margin:var(--p-2) 0;width:100%}.FormattedText_codeBlock__Xrbvn,.FormattedText_codeInline__jCbNL{background-color:var(--decent-color-alpha-400);border-radius:var(--p-2);box-shadow:0 1px 1px var(--accent-color-alpha-50),inset 0 1px 1px var(--decent-color-alpha-500);font-family:monospace;-webkit-user-select:text;-moz-user-select:text;user-select:text}.FormattedText_codeInline__jCbNL{border-radius:3px;display:inline;font-size:90%;padding:0 4px}.FormattedText_codeBlock__Xrbvn,.FormattedText_jsonPre__qOGmo{display:block;font-size:90%;margin:var(--p-2) 0;overflow-x:auto;padding:var(--p-2);white-space:pre-wrap}.FormattedText_jsonPre__qOGmo{background-color:var(--decent-color-alpha-300);border-radius:var(--p-2);box-shadow:0 1px 1px var(--accent-color-alpha-50),inset 0 1px 1px var(--accent-color-alpha-50);font-family:monospace;max-width:100%;-webkit-user-select:text;-moz-user-select:text;user-select:text}.FormattedText_table__ipMMS{margin-bottom:10px}";
|
|
2
|
-
var S = {"bullet":"FormattedText_bullet__vbqlq","numberedIndex":"FormattedText_numberedIndex__rZ6Kt","line":"FormattedText_line__c2bmE","codeInline":"FormattedText_codeInline__jCbNL","codeBlock":"FormattedText_codeBlock__Xrbvn","jsonPre":"FormattedText_jsonPre__qOGmo","table":"FormattedText_table__ipMMS"};
|
|
1
|
+
var css_248z = ".FormattedText_bullet__vbqlq{display:inline-block;margin-bottom:2px;margin-left:var(--p-2);margin-right:2px}.FormattedText_bullet__vbqlq:before{background-color:var(--accent-color);border-radius:50%;content:\"\";display:block;height:6px;margin:0 4px;width:6px}.FormattedText_numberedIndex__rZ6Kt{font-feature-settings:\"tnum\";color:var(--accent-color);display:inline-block;font-variant-numeric:tabular-nums;margin-left:var(--p-2);margin-right:6px;min-width:1.25em}.FormattedText_quote__BBm-M{color:var(--accent-color-alpha-600);font-size:85%;margin:0 0 var(--p-1);padding:2px 0 2px calc(4px + var(--p-2));position:relative;white-space:pre-wrap}.FormattedText_quote__BBm-M:before{background-color:var(--accent-color);border-radius:2px;bottom:2px;content:\"\";left:2px;opacity:.3;position:absolute;top:2px;width:4px}.FormattedText_line__c2bmE{background-color:var(--accent-color-alpha-200);border-radius:2px;height:2px;margin:var(--p-2) 0;width:100%}.FormattedText_codeBlock__Xrbvn,.FormattedText_codeInline__jCbNL{background-color:var(--decent-color-alpha-400);border-radius:var(--p-2);box-shadow:0 1px 1px var(--accent-color-alpha-50),inset 0 1px 1px var(--decent-color-alpha-500);font-family:monospace;-webkit-user-select:text;-moz-user-select:text;user-select:text}.FormattedText_codeInline__jCbNL{border-radius:3px;display:inline;font-size:90%;padding:0 4px}.FormattedText_codeBlock__Xrbvn,.FormattedText_jsonPre__qOGmo{display:block;font-size:90%;margin:var(--p-2) 0;overflow-x:auto;padding:var(--p-2);white-space:pre-wrap}.FormattedText_jsonPre__qOGmo{background-color:var(--decent-color-alpha-300);border-radius:var(--p-2);box-shadow:0 1px 1px var(--accent-color-alpha-50),inset 0 1px 1px var(--accent-color-alpha-50);font-family:monospace;max-width:100%;-webkit-user-select:text;-moz-user-select:text;user-select:text}.FormattedText_table__ipMMS{margin-bottom:10px}";
|
|
2
|
+
var S = {"bullet":"FormattedText_bullet__vbqlq","numberedIndex":"FormattedText_numberedIndex__rZ6Kt","quote":"FormattedText_quote__BBm-M","line":"FormattedText_line__c2bmE","codeInline":"FormattedText_codeInline__jCbNL","codeBlock":"FormattedText_codeBlock__Xrbvn","jsonPre":"FormattedText_jsonPre__qOGmo","table":"FormattedText_table__ipMMS"};
|
|
3
3
|
if (typeof document !== 'undefined') {
|
|
4
4
|
var __uilibHead = document.head || document.getElementsByTagName('head')[0];
|
|
5
5
|
if (__uilibHead) {
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Placeholder text for the composer's empty paragraphs. Only a wholly empty
|
|
3
|
+
* composer shows it: a quote or list with an empty line after it already is
|
|
4
|
+
* content, so it keeps no hint.
|
|
5
|
+
*/
|
|
6
|
+
function promptComposerPlaceholder(text) {
|
|
7
|
+
return ({ editor }) => (editor.isEmpty ? text : '');
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export { promptComposerPlaceholder };
|
|
@@ -3,6 +3,7 @@ import { Placeholder } from '@tiptap/extensions';
|
|
|
3
3
|
import { useEditor } from '@tiptap/react';
|
|
4
4
|
import StarterKit from '@tiptap/starter-kit';
|
|
5
5
|
import S from './PromptComposer.styl.js';
|
|
6
|
+
import { promptComposerPlaceholder } from './promptComposerPlaceholder.js';
|
|
6
7
|
import { createPromptBlocksExtension, isInPromptBlock } from '../../tiptap/prompt-blocks/createPromptBlocksExtension.js';
|
|
7
8
|
import { promptBlocksDoc } from '../../tiptap/prompt-blocks/promptBlocksText.js';
|
|
8
9
|
import { createLinkHighlightExtension } from '../../tiptap/link-highlight/createLinkHighlightExtension.js';
|
|
@@ -110,7 +111,7 @@ function usePromptComposerEditor({ disabled, placeholder, slashCommandItems, sla
|
|
|
110
111
|
}),
|
|
111
112
|
NonInclusiveLink,
|
|
112
113
|
Placeholder.configure({
|
|
113
|
-
placeholder: placeholderText,
|
|
114
|
+
placeholder: promptComposerPlaceholder(placeholderText),
|
|
114
115
|
showOnlyWhenEditable: true,
|
|
115
116
|
emptyNodeClass: S.promptComposerEmptyNode,
|
|
116
117
|
}),
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { FormattedTextProps } from './FormattedText.types';
|
|
3
3
|
export declare function hrefForFormattedLink(url: string): string;
|
|
4
|
-
export declare function
|
|
4
|
+
export declare function findJsonEndExclusive(content: string, start: number): number;
|
|
5
|
+
export declare function FormattedText({ text, className, onButtonClick, quotes, injectors, breaks, }: FormattedTextProps): React.JSX.Element;
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
import type React from 'react';
|
|
2
|
+
export type InjectionResult = {
|
|
3
|
+
elem: React.ReactNode;
|
|
4
|
+
index: number;
|
|
5
|
+
length: number;
|
|
6
|
+
} | null;
|
|
7
|
+
export type Injector = (content: string) => InjectionResult;
|
|
1
8
|
export type FormattedTextProps = {
|
|
2
9
|
text: string;
|
|
3
10
|
className?: string;
|
|
@@ -5,4 +12,7 @@ export type FormattedTextProps = {
|
|
|
5
12
|
text: string;
|
|
6
13
|
[name: string]: string;
|
|
7
14
|
}) => void;
|
|
15
|
+
quotes?: boolean;
|
|
16
|
+
injectors?: Injector[];
|
|
17
|
+
breaks?: boolean;
|
|
8
18
|
};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { FormattedText } from './FormattedText';
|
|
2
|
-
export type { FormattedTextProps } from './FormattedText.types';
|
|
1
|
+
export { FormattedText, findJsonEndExclusive } from './FormattedText';
|
|
2
|
+
export type { FormattedTextProps, InjectionResult, Injector, } from './FormattedText.types';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Editor } from '@tiptap/core';
|
|
2
|
+
/**
|
|
3
|
+
* Placeholder text for the composer's empty paragraphs. Only a wholly empty
|
|
4
|
+
* composer shows it: a quote or list with an empty line after it already is
|
|
5
|
+
* content, so it keeps no hint.
|
|
6
|
+
*/
|
|
7
|
+
export declare function promptComposerPlaceholder(text: string): ({ editor }: {
|
|
8
|
+
editor: Editor;
|
|
9
|
+
}) => string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|