@lark-apaas/coding-template-nestjs-react-fullstack 0.1.36-alpha.20260901072249 → 0.1.36-alpha.20260902024923

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.
Files changed (31) hide show
  1. package/package.json +1 -1
  2. package/template/client/src/components/ui/markdown.tsx +43 -0
  3. package/template/client/src/index.css +0 -1
  4. package/template/nest-cli.json +10 -9
  5. package/template/package-lock.json +9641 -18288
  6. package/template/package.json +4 -67
  7. package/template/client/src/components/business-ui/tiptap-editor/README.md +0 -324
  8. package/template/client/src/components/business-ui/tiptap-editor/components/attachment-toolbar-button.tsx +0 -74
  9. package/template/client/src/components/business-ui/tiptap-editor/components/blockquote-toolbar-button.tsx +0 -41
  10. package/template/client/src/components/business-ui/tiptap-editor/components/code-block-toolbar-button.tsx +0 -41
  11. package/template/client/src/components/business-ui/tiptap-editor/components/color-highlight-toolbar-button.tsx +0 -141
  12. package/template/client/src/components/business-ui/tiptap-editor/components/heading-toolbar-button.tsx +0 -99
  13. package/template/client/src/components/business-ui/tiptap-editor/components/horizontal-rule-toolbar-button.tsx +0 -39
  14. package/template/client/src/components/business-ui/tiptap-editor/components/image-upload-toolbar-button.tsx +0 -65
  15. package/template/client/src/components/business-ui/tiptap-editor/components/link-edit-form.tsx +0 -127
  16. package/template/client/src/components/business-ui/tiptap-editor/components/link-hover-toolbar.tsx +0 -380
  17. package/template/client/src/components/business-ui/tiptap-editor/components/link-toolbar-button.tsx +0 -96
  18. package/template/client/src/components/business-ui/tiptap-editor/components/list-toolbar-button.tsx +0 -75
  19. package/template/client/src/components/business-ui/tiptap-editor/components/mark-toolbar-button.tsx +0 -118
  20. package/template/client/src/components/business-ui/tiptap-editor/components/text-align-toolbar-button.tsx +0 -84
  21. package/template/client/src/components/business-ui/tiptap-editor/components/undo-redo-toolbar-button.tsx +0 -54
  22. package/template/client/src/components/business-ui/tiptap-editor/extensions/attachment.tsx +0 -539
  23. package/template/client/src/components/business-ui/tiptap-editor/extensions/code-block-shiki.tsx +0 -236
  24. package/template/client/src/components/business-ui/tiptap-editor/extensions/complete-kit.ts +0 -260
  25. package/template/client/src/components/business-ui/tiptap-editor/extensions/image.tsx +0 -456
  26. package/template/client/src/components/business-ui/tiptap-editor/hooks/use-tiptap-editor.ts +0 -47
  27. package/template/client/src/components/business-ui/tiptap-editor/index.ts +0 -38
  28. package/template/client/src/components/business-ui/tiptap-editor/tiptap-editor-complete.tsx +0 -112
  29. package/template/client/src/components/business-ui/tiptap-editor/tiptap-editor.tsx +0 -169
  30. package/template/client/src/components/ui/streamdown.tsx +0 -186
  31. package/template/client/src/lib/shiki.ts +0 -92
@@ -1,169 +0,0 @@
1
- 'use client';
2
-
3
- import * as React from 'react';
4
- import {
5
- EditorContent,
6
- EditorContext,
7
- useCurrentEditor,
8
- useEditor,
9
- type EditorContentProps,
10
- type Extensions,
11
- } from '@tiptap/react';
12
- import { Slot } from 'radix-ui';
13
-
14
- import { LinkHoverToolbar } from '@/components/business-ui/tiptap-editor/components/link-hover-toolbar';
15
- import { CompleteKit } from '@/components/business-ui/tiptap-editor/extensions/complete-kit';
16
- import { cn } from '@/lib/utils';
17
- import { Separator } from '@/components/ui/separator';
18
-
19
- export interface TiptapEditorProps extends React.ComponentProps<'div'> {
20
- /** 受控 value (HTML)。 */
21
- value?: string;
22
- /** 默认值 (HTML)。 */
23
- defaultValue?: string;
24
- /** 当编辑器更新时,触发并传递最新的 HTML。 */
25
- onValueChange?: (value: string) => void;
26
- children?: React.ReactNode;
27
- className?: string;
28
- /**
29
- * 自定义 Tiptap 扩展。
30
- * @default [CompleteKit]
31
- */
32
- extensions?: Extensions;
33
- /** 是否为只读模式。 */
34
- readOnly?: boolean;
35
- asChild?: boolean;
36
- }
37
-
38
- const defaultExtensions = [CompleteKit];
39
-
40
- export function TiptapEditor({
41
- value,
42
- defaultValue,
43
- onValueChange,
44
- children,
45
- className,
46
- extensions = defaultExtensions,
47
- readOnly = false,
48
- asChild = false,
49
- autoFocus = false,
50
- 'aria-disabled': ariaDisabled,
51
- ...props
52
- }: TiptapEditorProps) {
53
- const Comp = asChild ? Slot.Root : 'div';
54
-
55
- const initialContent = value !== undefined ? value : defaultValue;
56
- const editable = !readOnly && !ariaDisabled;
57
-
58
- const editor = useEditor({
59
- autofocus: autoFocus,
60
- editable,
61
- editorProps: {
62
- attributes: {
63
- class: cn('prose max-w-none flex-1 px-3 py-2 dark:prose-invert'),
64
- },
65
- },
66
- immediatelyRender: false,
67
- content: initialContent,
68
- onUpdate: ({ editor }) => {
69
- onValueChange?.(editor.getHTML());
70
- },
71
- extensions,
72
- });
73
-
74
- const valueRef = React.useRef(value);
75
- React.useEffect(() => {
76
- if (!editor || value === undefined) return;
77
- valueRef.current = value;
78
-
79
- // Tiptap 内部会使用 flushSync,因此我们将内容更新延迟到微任务队列
80
- queueMicrotask(() => {
81
- const current = editor.getHTML();
82
- if (valueRef.current !== current) {
83
- editor.commands.setContent(value);
84
- }
85
- });
86
- }, [value, editor]);
87
-
88
- React.useEffect(() => {
89
- if (!editor) return;
90
- editor.setEditable(editable);
91
- }, [editor, editable]);
92
-
93
- const contextValue = React.useMemo(() => ({ editor }), [editor]);
94
-
95
- return (
96
- <EditorContext value={contextValue}>
97
- <Comp
98
- aria-disabled={ariaDisabled}
99
- className={cn(
100
- "relative flex w-full flex-col rounded-md border ring-offset-background focus-within:border-ring focus-within:ring-[3px] focus-within:ring-ring/20 focus-within:outline-hidden hover:border-ring aria-disabled:cursor-not-allowed aria-disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 **:data-[type='taskList']:list-none **:data-[type='taskList']:p-0 [&_[data-type='taskList']>li]:flex [&_[data-type='taskList']>li]:items-start [&_[data-type='taskList']>li]:gap-2 [&_[data-type='taskList']>li>div]:min-w-0 [&_[data-type='taskList']>li>div]:flex-1 [&_[data-type='taskList']>li>div>p]:m-0 [&_[data-type='taskList']>li>label]:mt-0.5 [&_[data-type='taskList']>li>label]:shrink-0 **:[a]:cursor-pointer",
101
- className,
102
- )}
103
- data-slot="tiptap-editor"
104
- {...props}
105
- >
106
- {children}
107
- <LinkHoverToolbar />
108
- </Comp>
109
- </EditorContext>
110
- );
111
- }
112
-
113
- export function TiptapEditorContent({
114
- className,
115
- ...props
116
- }: Omit<EditorContentProps, 'editor'>) {
117
- const { editor } = useCurrentEditor();
118
-
119
- return (
120
- <EditorContent
121
- editor={editor}
122
- className={cn(
123
- 'flex flex-1 flex-col overflow-y-auto outline-hidden',
124
- className,
125
- )}
126
- data-slot="tiptap-editor-content"
127
- {...props}
128
- />
129
- );
130
- }
131
-
132
- export function TiptapEditorToolbar({
133
- className,
134
- children,
135
- asChild,
136
- ...props
137
- }: React.ComponentProps<'div'> & { asChild?: boolean }) {
138
- const Comp = asChild ? Slot.Root : 'div';
139
-
140
- return (
141
- <Comp
142
- className={cn(
143
- 'flex flex-wrap items-center gap-x-1 gap-y-2 p-1.5',
144
- className,
145
- )}
146
- data-slot="tiptap-editor-toolbar"
147
- {...props}
148
- >
149
- {children}
150
- </Comp>
151
- );
152
- }
153
-
154
- export function TiptapEditorToolbarSeparator({
155
- className,
156
- ...props
157
- }: React.ComponentProps<typeof Separator>) {
158
- return (
159
- <Separator
160
- orientation="vertical"
161
- className={cn(
162
- 'mx-0.5 h-4 w-px bg-border data-[orientation=vertical]:h-4',
163
- className,
164
- )}
165
- data-slot="tiptap-editor-toolbar-separator"
166
- {...props}
167
- />
168
- );
169
- }
@@ -1,186 +0,0 @@
1
- 'use client';
2
-
3
- import * as React from 'react';
4
- import { Streamdown as StreamdownPrimitive } from 'streamdown';
5
-
6
- import { cn } from '@/lib/utils';
7
- import { omit } from 'es-toolkit';
8
-
9
- const defaultComponents: NonNullable<
10
- React.ComponentProps<typeof StreamdownPrimitive>['components']
11
- > = {
12
- ol: ({ className, ...props }) => (
13
- <ol
14
- className={cn(className)}
15
- data-streamdown="ordered-list"
16
- {...omit(props, ['node'])}
17
- />
18
- ),
19
- li: ({ className, ...props }) => (
20
- <li
21
- className={cn(className)}
22
- data-streamdown="list-item"
23
- {...omit(props, ['node'])}
24
- />
25
- ),
26
- ul: ({ className, ...props }) => (
27
- <ul
28
- className={cn(className)}
29
- data-streamdown="unordered-list"
30
- {...omit(props, ['node'])}
31
- />
32
- ),
33
- hr: ({ className, ...props }) => (
34
- <hr
35
- className={cn(className)}
36
- data-streamdown="horizontal-rule"
37
- {...omit(props, ['node'])}
38
- />
39
- ),
40
- strong: ({ className, ...props }) => (
41
- <strong
42
- className={cn(className)}
43
- data-streamdown="strong"
44
- {...omit(props, ['node'])}
45
- />
46
- ),
47
- a: ({ className, href, ...props }) => {
48
- const isIncomplete = href === 'streamdown:incomplete-link';
49
-
50
- return (
51
- <a
52
- className={cn(className)}
53
- data-incomplete={isIncomplete}
54
- data-streamdown="link"
55
- href={href}
56
- rel={props.rel ?? 'noreferrer'}
57
- target={props.target ?? '_blank'}
58
- {...omit(props, ['node'])}
59
- />
60
- );
61
- },
62
- h1: ({ className, ...props }) => (
63
- <h1
64
- className={cn(className)}
65
- data-streamdown="heading-1"
66
- {...omit(props, ['node'])}
67
- />
68
- ),
69
- h2: ({ className, ...props }) => (
70
- <h2
71
- className={cn(className)}
72
- data-streamdown="heading-2"
73
- {...omit(props, ['node'])}
74
- />
75
- ),
76
- h3: ({ className, ...props }) => (
77
- <h3
78
- className={cn(className)}
79
- data-streamdown="heading-3"
80
- {...omit(props, ['node'])}
81
- />
82
- ),
83
- h4: ({ className, ...props }) => (
84
- <h4
85
- className={cn(className)}
86
- data-streamdown="heading-4"
87
- {...omit(props, ['node'])}
88
- />
89
- ),
90
- h5: ({ className, ...props }) => (
91
- <h5
92
- className={cn(className)}
93
- data-streamdown="heading-5"
94
- {...omit(props, ['node'])}
95
- />
96
- ),
97
- h6: ({ className, ...props }) => (
98
- <h6
99
- className={cn(className)}
100
- data-streamdown="heading-6"
101
- {...omit(props, ['node'])}
102
- />
103
- ),
104
- table: ({ className, ...props }) => (
105
- <table
106
- className={cn(className)}
107
- data-streamdown="table-wrapper"
108
- {...omit(props, ['node'])}
109
- />
110
- ),
111
- thead: ({ className, ...props }) => (
112
- <thead
113
- className={cn(className)}
114
- data-streamdown="table-header"
115
- {...omit(props, ['node'])}
116
- />
117
- ),
118
- tbody: ({ className, ...props }) => (
119
- <tbody
120
- className={cn(className)}
121
- data-streamdown="table-body"
122
- {...omit(props, ['node'])}
123
- />
124
- ),
125
- tr: ({ className, ...props }) => (
126
- <tr
127
- className={cn(className)}
128
- data-streamdown="table-row"
129
- {...omit(props, ['node'])}
130
- />
131
- ),
132
- th: ({ className, ...props }) => (
133
- <th
134
- className={cn(className)}
135
- data-streamdown="table-header-cell"
136
- {...omit(props, ['node'])}
137
- />
138
- ),
139
- td: ({ className, ...props }) => (
140
- <td
141
- className={cn(className)}
142
- data-streamdown="table-cell"
143
- {...omit(props, ['node'])}
144
- />
145
- ),
146
- blockquote: ({ className, ...props }) => (
147
- <blockquote
148
- className={cn(className)}
149
- data-streamdown="blockquote"
150
- {...omit(props, ['node'])}
151
- />
152
- ),
153
- sup: ({ className, ...props }) => (
154
- <sup className={cn(className)} {...omit(props, ['node'])} />
155
- ),
156
- sub: ({ className, ...props }) => (
157
- <sub className={cn(className)} {...omit(props, ['node'])} />
158
- ),
159
- p: ({ className, ...props }) => (
160
- <p className={cn(className)} {...omit(props, ['node'])} />
161
- ),
162
- section: ({ className, ...props }) => (
163
- <section className={cn(className)} {...omit(props, ['node'])} />
164
- ),
165
- img: ({ className, alt, ...props }) => (
166
- <img className={cn(className)} alt={alt ?? ''} {...omit(props, ['node'])} />
167
- ),
168
- pre: ({ children }) => <div className="not-prose">{children}</div>,
169
- };
170
-
171
- export function Streamdown({
172
- className,
173
- components,
174
- ...props
175
- }: React.ComponentProps<typeof StreamdownPrimitive>) {
176
- return (
177
- <StreamdownPrimitive
178
- className={cn(
179
- 'prose max-w-none dark:prose-invert',
180
- className,
181
- )}
182
- components={{ ...defaultComponents, ...components }}
183
- {...props}
184
- />
185
- );
186
- }
@@ -1,92 +0,0 @@
1
- import {
2
- createBundledHighlighter,
3
- createSingletonShorthands,
4
- } from 'shiki/core';
5
- import { createJavaScriptRegexEngine } from 'shiki/engine/javascript';
6
- import type {
7
- DynamicImportLanguageRegistration,
8
- DynamicImportThemeRegistration,
9
- HighlighterGeneric,
10
- } from 'shiki/types';
11
-
12
- type BundledLanguage =
13
- | 'typescript'
14
- | 'ts'
15
- | 'cts'
16
- | 'mts'
17
- | 'javascript'
18
- | 'js'
19
- | 'cjs'
20
- | 'mjs'
21
- | 'jsx'
22
- | 'tsx'
23
- | 'html'
24
- | 'css'
25
- | 'json'
26
- | 'jsonc'
27
- | 'json5'
28
- | 'markdown'
29
- | 'md';
30
- type BundledTheme = 'github-light' | 'github-dark';
31
- type Highlighter = HighlighterGeneric<BundledLanguage, BundledTheme>;
32
-
33
- const bundledLanguages = {
34
- typescript: () => import('@shikijs/langs/typescript'),
35
- ts: () => import('@shikijs/langs/typescript'),
36
- cts: () => import('@shikijs/langs/typescript'),
37
- mts: () => import('@shikijs/langs/typescript'),
38
- javascript: () => import('@shikijs/langs/javascript'),
39
- js: () => import('@shikijs/langs/javascript'),
40
- cjs: () => import('@shikijs/langs/javascript'),
41
- mjs: () => import('@shikijs/langs/javascript'),
42
- jsx: () => import('@shikijs/langs/jsx'),
43
- tsx: () => import('@shikijs/langs/tsx'),
44
- html: () => import('@shikijs/langs/html'),
45
- css: () => import('@shikijs/langs/css'),
46
- json: () => import('@shikijs/langs/json'),
47
- jsonc: () => import('@shikijs/langs/jsonc'),
48
- json5: () => import('@shikijs/langs/json5'),
49
- markdown: () => import('@shikijs/langs/markdown'),
50
- md: () => import('@shikijs/langs/markdown'),
51
- } as Record<BundledLanguage, DynamicImportLanguageRegistration>;
52
-
53
- const bundledThemes = {
54
- 'github-light': () => import('@shikijs/themes/github-light'),
55
- 'github-dark': () => import('@shikijs/themes/github-dark'),
56
- } as Record<BundledTheme, DynamicImportThemeRegistration>;
57
-
58
- const createHighlighter = /* @__PURE__ */ createBundledHighlighter<
59
- BundledLanguage,
60
- BundledTheme
61
- >({
62
- langs: bundledLanguages,
63
- themes: bundledThemes,
64
- engine: () => createJavaScriptRegexEngine(),
65
- });
66
-
67
- const {
68
- codeToHtml,
69
- codeToHast,
70
- codeToTokensBase,
71
- codeToTokens,
72
- codeToTokensWithThemes,
73
- getSingletonHighlighter,
74
- getLastGrammarState,
75
- } = /* @__PURE__ */ createSingletonShorthands<BundledLanguage, BundledTheme>(
76
- createHighlighter,
77
- );
78
-
79
- export {
80
- bundledLanguages,
81
- bundledThemes,
82
- codeToHast,
83
- codeToHtml,
84
- codeToTokens,
85
- codeToTokensBase,
86
- codeToTokensWithThemes,
87
- createHighlighter,
88
- getLastGrammarState,
89
- getSingletonHighlighter,
90
- };
91
-
92
- export type { BundledLanguage, BundledTheme, Highlighter };