laif-ds 1.1.4 → 1.2.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/dist/CHANGELOG.md +13 -0
- package/dist/_virtual/prism-cpp.js +3 -0
- package/dist/_virtual/prism-cpp2.js +5 -0
- package/dist/_virtual/prism-java.js +3 -0
- package/dist/_virtual/prism-java2.js +5 -0
- package/dist/_virtual/prism-python.js +3 -0
- package/dist/_virtual/prism-python2.js +5 -0
- package/dist/_virtual/prism-rust.js +3 -0
- package/dist/_virtual/prism-rust2.js +5 -0
- package/dist/_virtual/prism-typescript.js +3 -0
- package/dist/_virtual/prism-typescript2.js +5 -0
- package/dist/_virtual/prism.js +3 -0
- package/dist/_virtual/prism2.js +5 -0
- package/dist/agent-docs/adoption-report.json +26 -24
- package/dist/agent-docs/components/AppEditor.md +4 -0
- package/dist/agent-docs/components/FilePreview.md +24 -0
- package/dist/agent-docs/manifest.json +12 -8
- package/dist/components/editor/plugins/paste-markdown-plugin.js +75 -0
- package/dist/components/ui/app-editor.js +128 -116
- package/dist/components/ui/file-preview/index.js +262 -218
- package/dist/index.d.ts +12 -0
- package/dist/node_modules/@lexical/code-prism/dist/LexicalCodePrism.prod.js +27 -0
- package/dist/node_modules/@lexical/markdown/dist/LexicalMarkdown.prod.js +114 -109
- package/dist/node_modules/prismjs/components/prism-c.js +77 -0
- package/dist/node_modules/prismjs/components/prism-clike.js +32 -0
- package/dist/node_modules/prismjs/components/prism-cpp.js +93 -0
- package/dist/node_modules/prismjs/components/prism-css.js +56 -0
- package/dist/node_modules/prismjs/components/prism-java.js +122 -0
- package/dist/node_modules/prismjs/components/prism-javascript.js +138 -0
- package/dist/node_modules/prismjs/components/prism-markdown.js +301 -0
- package/dist/node_modules/prismjs/components/prism-markup.js +174 -0
- package/dist/node_modules/prismjs/components/prism-objectivec.js +11 -0
- package/dist/node_modules/prismjs/components/prism-powershell.js +56 -0
- package/dist/node_modules/prismjs/components/prism-python.js +69 -0
- package/dist/node_modules/prismjs/components/prism-rust.js +124 -0
- package/dist/node_modules/prismjs/components/prism-sql.js +34 -0
- package/dist/node_modules/prismjs/components/prism-swift.js +114 -0
- package/dist/node_modules/prismjs/components/prism-typescript.js +53 -0
- package/dist/node_modules/prismjs/prism.js +1165 -0
- package/package.json +1 -1
package/dist/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,19 @@ All notable technical changes to the laif-ds core will be documented in this fil
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [laif-ds@1.2.0]
|
|
9
|
+
|
|
10
|
+
### 🚀 Added
|
|
11
|
+
|
|
12
|
+
- **AppEditor**: Pasting plain text containing Markdown now converts it into formatted content (headings, links, code blocks, etc.), matching the formatting already applied to `defaultValue`; plain text without Markdown, HTML, and Lexical clipboard pastes keep their previous behavior
|
|
13
|
+
|
|
14
|
+
## [laif-ds@1.1.5]
|
|
15
|
+
|
|
16
|
+
### 🚀 Added
|
|
17
|
+
|
|
18
|
+
- **FilePreview**: Added a `loading` prop that replaces the thumbnail with a same-size spinner, sets `aria-busy`, and disables container activation and the action menu, while keeping the inline remove button active so an in-progress upload can still be cancelled
|
|
19
|
+
- **FilePreview**: Image thumbnails now show a spinner until the image has loaded, then fade in
|
|
20
|
+
|
|
8
21
|
## [laif-ds@1.1.4]
|
|
9
22
|
|
|
10
23
|
### 🚀 Added
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": "1.0.0",
|
|
3
|
-
"generatedAt": "2026-10-
|
|
3
|
+
"generatedAt": "2026-10-26T17:03:35.397Z",
|
|
4
4
|
"package": {
|
|
5
5
|
"name": "laif-ds",
|
|
6
|
-
"version": "1.
|
|
6
|
+
"version": "1.2.0"
|
|
7
7
|
},
|
|
8
8
|
"summary": {
|
|
9
|
-
"scannedFiles":
|
|
9
|
+
"scannedFiles": 505,
|
|
10
10
|
"deprecatedComponentsCount": 5,
|
|
11
11
|
"deprecatedComponentsUsedCount": 3,
|
|
12
12
|
"componentsWithoutExamplesCount": 5,
|
|
@@ -489,8 +489,9 @@
|
|
|
489
489
|
},
|
|
490
490
|
{
|
|
491
491
|
"className": "text-muted-foreground text-sm",
|
|
492
|
-
"occurrences":
|
|
492
|
+
"occurrences": 29,
|
|
493
493
|
"files": [
|
|
494
|
+
"src/components/stories/app-editor.stories.tsx",
|
|
494
495
|
"src/components/stories/app-form.stories.tsx",
|
|
495
496
|
"src/components/stories/app-stepper.stories.tsx",
|
|
496
497
|
"src/components/stories/app-time-picker.stories.tsx",
|
|
@@ -520,20 +521,12 @@
|
|
|
520
521
|
"src/components/ui/secure-pdf-viewer.tsx"
|
|
521
522
|
]
|
|
522
523
|
},
|
|
523
|
-
{
|
|
524
|
-
"className": "bg-muted rounded-md p-4",
|
|
525
|
-
"occurrences": 20,
|
|
526
|
-
"files": [
|
|
527
|
-
"src/components/stories/card.stories.tsx",
|
|
528
|
-
"src/components/stories/data-table-no-utils-example.stories.tsx",
|
|
529
|
-
"src/components/stories/data-table-utils-example.stories.tsx"
|
|
530
|
-
]
|
|
531
|
-
},
|
|
532
524
|
{
|
|
533
525
|
"className": "flex items-center justify-between",
|
|
534
|
-
"occurrences":
|
|
526
|
+
"occurrences": 20,
|
|
535
527
|
"files": [
|
|
536
528
|
"src/components/stories/app-card.stories.tsx",
|
|
529
|
+
"src/components/stories/app-editor.stories.tsx",
|
|
537
530
|
"src/components/stories/data-table-utils-example.stories.tsx",
|
|
538
531
|
"src/components/stories/sidebar.stories.tsx",
|
|
539
532
|
"src/components/stories/switch.stories.tsx",
|
|
@@ -543,6 +536,15 @@
|
|
|
543
536
|
"src/components/ui/tables/data-cross-table/editable-input.tsx"
|
|
544
537
|
]
|
|
545
538
|
},
|
|
539
|
+
{
|
|
540
|
+
"className": "bg-muted rounded-md p-4",
|
|
541
|
+
"occurrences": 20,
|
|
542
|
+
"files": [
|
|
543
|
+
"src/components/stories/card.stories.tsx",
|
|
544
|
+
"src/components/stories/data-table-no-utils-example.stories.tsx",
|
|
545
|
+
"src/components/stories/data-table-utils-example.stories.tsx"
|
|
546
|
+
]
|
|
547
|
+
},
|
|
546
548
|
{
|
|
547
549
|
"className": "mb-2 text-lg font-medium",
|
|
548
550
|
"occurrences": 19,
|
|
@@ -647,6 +649,16 @@
|
|
|
647
649
|
"src/components/stories/tabs.stories.tsx"
|
|
648
650
|
]
|
|
649
651
|
},
|
|
652
|
+
{
|
|
653
|
+
"className": "flex flex-wrap gap-2",
|
|
654
|
+
"occurrences": 8,
|
|
655
|
+
"files": [
|
|
656
|
+
"src/components/stories/app-card.stories.tsx",
|
|
657
|
+
"src/components/stories/app-data-grid-filtri-custom.stories.tsx",
|
|
658
|
+
"src/components/stories/file-preview.stories.tsx",
|
|
659
|
+
"src/components/stories/toaster.stories.tsx"
|
|
660
|
+
]
|
|
661
|
+
},
|
|
650
662
|
{
|
|
651
663
|
"className": "text-muted-foreground text-xs",
|
|
652
664
|
"occurrences": 8,
|
|
@@ -711,16 +723,6 @@
|
|
|
711
723
|
"src/components/ui/weekly-calendar/appointment-card.tsx"
|
|
712
724
|
]
|
|
713
725
|
},
|
|
714
|
-
{
|
|
715
|
-
"className": "flex flex-wrap gap-2",
|
|
716
|
-
"occurrences": 6,
|
|
717
|
-
"files": [
|
|
718
|
-
"src/components/stories/app-card.stories.tsx",
|
|
719
|
-
"src/components/stories/app-data-grid-filtri-custom.stories.tsx",
|
|
720
|
-
"src/components/stories/file-preview.stories.tsx",
|
|
721
|
-
"src/components/stories/toaster.stories.tsx"
|
|
722
|
-
]
|
|
723
|
-
},
|
|
724
726
|
{
|
|
725
727
|
"className": "text-lg font-semibold",
|
|
726
728
|
"occurrences": 6,
|
|
@@ -60,6 +60,10 @@ type MentionItem = {
|
|
|
60
60
|
- **Editing**: Autosave via `onValueChange`. Keyboard navigation and selection per Lexical defaults.
|
|
61
61
|
- **Markdown Features**: Full support for headings, lists, quotes, links, inline code, bold, italic, strikethrough, and custom underline syntax.
|
|
62
62
|
- **Links**: `[text](url)` in `defaultValue` renders as a link and is emitted back unchanged; links pasted as HTML are kept as links. Enable the `link` toolbar for a user-facing button; to insert a link programmatically (e.g. a "quick insert" action outside the editor) call `ref.current.insertLink(url, text)`. Give the triggering button `onMouseDown={(e) => e.preventDefault()}` so the editor keeps its caret.
|
|
63
|
+
- **Paste from Markdown** (when `onlyMarkdown=true`): pasting **plain text that contains Markdown** (headings, `**bold**`, `*italic*`, `` `code` ``, bulleted/numbered lists, quotes, fenced code, `[links](url)`, `<u>underline</u>`) converts it with the same transformers as `defaultValue` — formatted nodes, no leftover markers, no empty paragraphs from blank lines. A single line pasted mid-paragraph merges inline. Everything else keeps the default Lexical paste:
|
|
64
|
+
- plain text with no Markdown construct (look-alikes such as `5 * 3`, `file_name_v2`, `#hashtag` are not treated as Markdown);
|
|
65
|
+
- any clipboard carrying `text/html` (web pages, Word, Outlook) or Lexical's own format — even when its plain-text flavour looks like Markdown. Copying Markdown source from an editor that also writes HTML (e.g. VS Code) therefore pastes as-is.
|
|
66
|
+
- The paste is a single undo step.
|
|
63
67
|
- **Mentions** (opt-in via `mentions`):
|
|
64
68
|
- `mentions` is either a ready `MentionItem[]` or a **loader function** `() => MentionItem[] | Promise<MentionItem[]>`. The loader is called **once, the first time the menu opens**, so a large list is never preloaded on mount; while it resolves the menu shows a `Loading…` row, and on failure a `Couldn't load mentions` row (re-opening the menu retries). The resolved list is then filtered client-side like the array form.
|
|
65
69
|
- With the **loader form**, `meta.mentions` cannot reconcile against a synchronous source list, so its emitted items carry `id`/`label`/`value` from the chip but **not `sublabel`** (which is menu-only metadata). The array form preserves `sublabel`.
|
|
@@ -18,6 +18,7 @@ Compact file chip with name, format/size info, optional remove button, and optio
|
|
|
18
18
|
| `onDownload` | `(url: string) => void \| Promise<void>` | `undefined` | Called when user clicks Download from the action menu. |
|
|
19
19
|
| `showActionMenu` | `boolean` | `false` | Show overflow menu (Preview/Download/Delete if provided). |
|
|
20
20
|
| `showThumbnail` | `boolean` | `true` | Controls whether a thumbnail/text preview is rendered when available. |
|
|
21
|
+
| `loading` | `boolean` | `false` | Shows a spinner in place of the thumbnail; disables container click and the action menu (e.g. uploads). |
|
|
21
22
|
| `variant` | `"default" \| "outline" \| "ghost"` | `"default"` | Visual style of the chip container. |
|
|
22
23
|
| `size` | `"default" \| "sm"` | `"default"` | Visual size of the chip container and its internal elements. |
|
|
23
24
|
| `className` | `string` | `""` | Additional classes for the wrapper. |
|
|
@@ -42,6 +43,11 @@ Compact file chip with name, format/size info, optional remove button, and optio
|
|
|
42
43
|
- **Thumbnails**:
|
|
43
44
|
- Images: if `showThumbnail` is `false`, an icon is shown instead of the image.
|
|
44
45
|
- Text: if `showThumbnail` is `false` (or a preview can't be extracted), an icon is shown instead of the text snippet.
|
|
46
|
+
- **Loading**:
|
|
47
|
+
- `loading` replaces the thumbnail with a spinner of the same size (the chip does not change size) and sets `aria-busy` on the container.
|
|
48
|
+
- While loading, container click/keyboard activation and the action menu trigger are disabled; the inline remove button stays active, so removing the file can cancel an upload.
|
|
49
|
+
- Image thumbnails show the same spinner automatically until the image has loaded, then fade the image in; if it fails to load, the format icon is shown.
|
|
50
|
+
- When `onClick`, `onPreview` or the inline `onRemove` return a Promise, the chip shows the same loading state until it settles and ignores repeated activations; the remove button is disabled meanwhile. Action-menu items keep their own per-item spinner.
|
|
45
51
|
|
|
46
52
|
---
|
|
47
53
|
|
|
@@ -110,6 +116,24 @@ export function WithMenu() {
|
|
|
110
116
|
}
|
|
111
117
|
```
|
|
112
118
|
|
|
119
|
+
### Upload in Progress
|
|
120
|
+
|
|
121
|
+
```tsx
|
|
122
|
+
import { FilePreview } from "laif-ds";
|
|
123
|
+
|
|
124
|
+
export function UploadingPreview({
|
|
125
|
+
file,
|
|
126
|
+
isUploading,
|
|
127
|
+
onCancel,
|
|
128
|
+
}: {
|
|
129
|
+
file: File;
|
|
130
|
+
isUploading: boolean;
|
|
131
|
+
onCancel: () => void;
|
|
132
|
+
}) {
|
|
133
|
+
return <FilePreview file={file} loading={isUploading} onRemove={onCancel} />;
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
|
|
113
137
|
### With Custom Click Handler
|
|
114
138
|
|
|
115
139
|
```tsx
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": "1.1.0",
|
|
3
|
-
"generatedAt": "2026-10-
|
|
3
|
+
"generatedAt": "2026-10-26T17:03:34.845Z",
|
|
4
4
|
"package": {
|
|
5
5
|
"name": "laif-ds",
|
|
6
|
-
"version": "1.
|
|
6
|
+
"version": "1.2.0"
|
|
7
7
|
},
|
|
8
8
|
"stats": {
|
|
9
9
|
"documentedComponentCount": 97,
|
|
@@ -3280,6 +3280,7 @@
|
|
|
3280
3280
|
"Image",
|
|
3281
3281
|
"With Remove Button",
|
|
3282
3282
|
"With Action Menu",
|
|
3283
|
+
"Upload in Progress",
|
|
3283
3284
|
"With Custom Click Handler"
|
|
3284
3285
|
],
|
|
3285
3286
|
"controlledPattern": "not-specified",
|
|
@@ -3287,17 +3288,20 @@
|
|
|
3287
3288
|
},
|
|
3288
3289
|
"metadata": {
|
|
3289
3290
|
"props": {
|
|
3290
|
-
"totalProps":
|
|
3291
|
+
"totalProps": 12,
|
|
3291
3292
|
"requiredPropsCount": 0,
|
|
3292
|
-
"typedPropsCount":
|
|
3293
|
-
"describedPropsCount":
|
|
3293
|
+
"typedPropsCount": 12,
|
|
3294
|
+
"describedPropsCount": 12
|
|
3294
3295
|
},
|
|
3295
3296
|
"accessibility": {
|
|
3296
3297
|
"hasCoverage": true
|
|
3297
3298
|
},
|
|
3298
3299
|
"states": {
|
|
3299
|
-
"coveredStates": [
|
|
3300
|
-
|
|
3300
|
+
"coveredStates": [
|
|
3301
|
+
"disabled",
|
|
3302
|
+
"loading"
|
|
3303
|
+
],
|
|
3304
|
+
"coveredStateCount": 2
|
|
3301
3305
|
}
|
|
3302
3306
|
},
|
|
3303
3307
|
"aiReadiness": {
|
|
@@ -6552,5 +6556,5 @@
|
|
|
6552
6556
|
]
|
|
6553
6557
|
}
|
|
6554
6558
|
],
|
|
6555
|
-
"checksum": "
|
|
6559
|
+
"checksum": "0ae7e68a8339e77f0a232184ea036347a3ae7c383c803d1c7215951e7eaadd49"
|
|
6556
6560
|
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { $generateNodesFromMarkdownString as f } from "../../../node_modules/@lexical/markdown/dist/LexicalMarkdown.prod.js";
|
|
3
|
+
import { useLexicalComposerContext as c } from "../../../node_modules/@lexical/react/dist/LexicalComposerContext.prod.js";
|
|
4
|
+
import { PASTE_COMMAND as _, $isRangeSelection as l, $getSelection as m, PASTE_TAG as d, COMMAND_PRIORITY_LOW as p } from "../../../node_modules/lexical/dist/Lexical.prod.js";
|
|
5
|
+
import { useEffect as S } from "react";
|
|
6
|
+
const w = [
|
|
7
|
+
/^#{1,6}\s+\S/m,
|
|
8
|
+
// # heading
|
|
9
|
+
/^\s*[-*+]\s+\S/m,
|
|
10
|
+
// - bulleted list
|
|
11
|
+
/^\s*\d+[.)]\s+\S/m,
|
|
12
|
+
// 1. numbered list
|
|
13
|
+
/^>\s?\S/m,
|
|
14
|
+
// > quote
|
|
15
|
+
/^```/m,
|
|
16
|
+
// fenced code block
|
|
17
|
+
/\*\*[^*\s](?:[^*\n]*[^*\s])?\*\*/,
|
|
18
|
+
// **bold**
|
|
19
|
+
/(^|[^\w])__[^_\s](?:[^_\n]*[^_\s])?__(?!\w)/m,
|
|
20
|
+
// __bold__
|
|
21
|
+
/(^|[^\w*])\*[^*\s](?:[^*\n]*[^*\s])?\*(?![\w*])/m,
|
|
22
|
+
// *italic*
|
|
23
|
+
/(^|[^\w])_[^_\s](?:[^_\n]*[^_\s])?_(?!\w)/m,
|
|
24
|
+
// _italic_
|
|
25
|
+
/~~[^~\s](?:[^~\n]*[^~\s])?~~/,
|
|
26
|
+
// ~~strikethrough~~
|
|
27
|
+
/`[^`\n]+`/,
|
|
28
|
+
// `inline code`
|
|
29
|
+
/\[[^\]\n]+\]\([^)\s]+\)/,
|
|
30
|
+
// [link](url)
|
|
31
|
+
/<u>[^<\n]+<\/u>/
|
|
32
|
+
// <u>underline</u> (AppEditor's extended syntax)
|
|
33
|
+
];
|
|
34
|
+
function g(e) {
|
|
35
|
+
return w.some((t) => t.test(e));
|
|
36
|
+
}
|
|
37
|
+
function k({
|
|
38
|
+
transformers: e,
|
|
39
|
+
preprocess: t
|
|
40
|
+
}) {
|
|
41
|
+
const [n] = c();
|
|
42
|
+
return S(
|
|
43
|
+
() => n.registerCommand(
|
|
44
|
+
_,
|
|
45
|
+
(r) => {
|
|
46
|
+
if (!(r instanceof ClipboardEvent)) return !1;
|
|
47
|
+
const o = r.clipboardData;
|
|
48
|
+
if (!o) return !1;
|
|
49
|
+
const a = Array.from(o.types);
|
|
50
|
+
if (a.includes("text/html") || a.includes("application/x-lexical-editor"))
|
|
51
|
+
return !1;
|
|
52
|
+
const s = o.getData("text/plain");
|
|
53
|
+
return !s || !g(s) || !l(m()) ? !1 : (r.preventDefault(), n.update(
|
|
54
|
+
() => {
|
|
55
|
+
const i = m();
|
|
56
|
+
if (!l(i)) return;
|
|
57
|
+
const u = t ? t(s) : s;
|
|
58
|
+
i.insertNodes(
|
|
59
|
+
f(u, e)
|
|
60
|
+
);
|
|
61
|
+
},
|
|
62
|
+
// Same tag as Lexical's own paste: its own undo entry.
|
|
63
|
+
{ tag: d }
|
|
64
|
+
), !0);
|
|
65
|
+
},
|
|
66
|
+
// Above RichTextPlugin's COMMAND_PRIORITY_EDITOR, so it runs first.
|
|
67
|
+
p
|
|
68
|
+
),
|
|
69
|
+
[n, e, t]
|
|
70
|
+
), null;
|
|
71
|
+
}
|
|
72
|
+
export {
|
|
73
|
+
k as PasteMarkdownPlugin,
|
|
74
|
+
g as looksLikeMarkdown
|
|
75
|
+
};
|