pimelon-ui 0.1.111 → 0.1.113
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pimelon-ui",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.113",
|
|
4
4
|
"description": "A set of components and utilities for rapid UI development",
|
|
5
5
|
"main": "./src/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
"@popperjs/core": "^2.11.2",
|
|
31
31
|
"@tailwindcss/forms": "^0.5.3",
|
|
32
32
|
"@tailwindcss/typography": "^0.5.16",
|
|
33
|
+
"@tiptap/extension-code-block-lowlight": "^2.11.5",
|
|
33
34
|
"@tiptap/extension-color": "^2.0.3",
|
|
34
35
|
"@tiptap/extension-highlight": "^2.0.3",
|
|
35
36
|
"@tiptap/extension-image": "^2.0.3",
|
|
@@ -52,6 +53,7 @@
|
|
|
52
53
|
"feather-icons": "^4.28.0",
|
|
53
54
|
"husky": "^9.1.7",
|
|
54
55
|
"idb-keyval": "^6.2.0",
|
|
56
|
+
"lowlight": "^3.3.0",
|
|
55
57
|
"ora": "5.4.1",
|
|
56
58
|
"prettier": "^3.3.2",
|
|
57
59
|
"radix-vue": "^1.5.3",
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<node-view-wrapper>
|
|
3
|
+
<div class="code-block-container">
|
|
4
|
+
<select
|
|
5
|
+
class="language-selector form-select"
|
|
6
|
+
contenteditable="false"
|
|
7
|
+
v-model="selectedLanguage"
|
|
8
|
+
>
|
|
9
|
+
<option :value="null">auto</option>
|
|
10
|
+
<option disabled>—</option>
|
|
11
|
+
<option
|
|
12
|
+
v-for="(language, index) in languages"
|
|
13
|
+
:value="language.value"
|
|
14
|
+
:key="language.value"
|
|
15
|
+
>
|
|
16
|
+
{{ language.label }}
|
|
17
|
+
</option>
|
|
18
|
+
</select>
|
|
19
|
+
<pre><code><node-view-content /></code></pre>
|
|
20
|
+
</div>
|
|
21
|
+
</node-view-wrapper>
|
|
22
|
+
</template>
|
|
23
|
+
|
|
24
|
+
<script>
|
|
25
|
+
import { NodeViewContent, nodeViewProps, NodeViewWrapper } from '@tiptap/vue-3'
|
|
26
|
+
|
|
27
|
+
export default {
|
|
28
|
+
components: {
|
|
29
|
+
NodeViewWrapper,
|
|
30
|
+
NodeViewContent,
|
|
31
|
+
},
|
|
32
|
+
props: nodeViewProps,
|
|
33
|
+
computed: {
|
|
34
|
+
selectedLanguage: {
|
|
35
|
+
get() {
|
|
36
|
+
return this.node.attrs.language
|
|
37
|
+
},
|
|
38
|
+
set(language) {
|
|
39
|
+
this.updateAttributes({ language })
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
languages() {
|
|
43
|
+
let supportedLanguages = this.extension.options.lowlight.listLanguages()
|
|
44
|
+
return supportedLanguages
|
|
45
|
+
.map((language) => {
|
|
46
|
+
return {
|
|
47
|
+
label: language,
|
|
48
|
+
value: language,
|
|
49
|
+
}
|
|
50
|
+
})
|
|
51
|
+
.concat([{ label: 'html', value: 'xml' }])
|
|
52
|
+
.sort((a, b) => a.label.localeCompare(b.label))
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
}
|
|
56
|
+
</script>
|
|
57
|
+
|
|
58
|
+
<style>
|
|
59
|
+
/* CodeBlock styles */
|
|
60
|
+
.code-block {
|
|
61
|
+
position: relative;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.code-block-container {
|
|
65
|
+
position: relative;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.language-selector {
|
|
69
|
+
position: absolute;
|
|
70
|
+
top: 0.25rem;
|
|
71
|
+
right: 0.25rem;
|
|
72
|
+
padding-top: 0;
|
|
73
|
+
padding-bottom: 0;
|
|
74
|
+
opacity: 0;
|
|
75
|
+
z-index: 10;
|
|
76
|
+
transition-property: opacity;
|
|
77
|
+
transition-duration: 0.2s;
|
|
78
|
+
transition-timing-function: ease-in-out;
|
|
79
|
+
transition-delay: 0s;
|
|
80
|
+
pointer-events: none;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.code-block-container:hover .language-selector {
|
|
84
|
+
opacity: 1;
|
|
85
|
+
transition-delay: 0s;
|
|
86
|
+
pointer-events: auto;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.language-selector:focus-within {
|
|
90
|
+
opacity: 1;
|
|
91
|
+
transition-delay: 0s;
|
|
92
|
+
pointer-events: auto;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/* When mouse leaves the code block, delay the hiding */
|
|
96
|
+
.code-block-container:not(:hover) .language-selector:not(:focus-within) {
|
|
97
|
+
transition-delay: 1.5s;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.ProseMirror pre {
|
|
101
|
+
background: #0d0d0d;
|
|
102
|
+
color: #fff;
|
|
103
|
+
font-family: ui-monospace, Menlo, Monaco, 'Cascadia Mono', 'Segoe UI Mono',
|
|
104
|
+
'Roboto Mono', 'Oxygen Mono', 'Ubuntu Mono', 'Source Code Pro', 'Fira Mono',
|
|
105
|
+
'Droid Sans Mono', 'Consolas', 'Courier New', monospace;
|
|
106
|
+
padding: 0.75rem 1rem;
|
|
107
|
+
border-radius: 0.75rem;
|
|
108
|
+
caret-color: #fff;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.ProseMirror pre code {
|
|
112
|
+
color: inherit;
|
|
113
|
+
padding: 0;
|
|
114
|
+
background: none;
|
|
115
|
+
font-size: 12px;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
.ProseMirror pre .hljs-comment,
|
|
119
|
+
.ProseMirror pre .hljs-quote {
|
|
120
|
+
color: #999;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
.ProseMirror pre .hljs-variable,
|
|
124
|
+
.ProseMirror pre .hljs-template-variable,
|
|
125
|
+
.ProseMirror pre .hljs-attribute,
|
|
126
|
+
.ProseMirror pre .hljs-tag,
|
|
127
|
+
.ProseMirror pre .hljs-name,
|
|
128
|
+
.ProseMirror pre .hljs-regexp,
|
|
129
|
+
.ProseMirror pre .hljs-link,
|
|
130
|
+
.ProseMirror pre .hljs-selector-id,
|
|
131
|
+
.ProseMirror pre .hljs-selector-class {
|
|
132
|
+
color: #f2777a;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
.ProseMirror pre .hljs-number,
|
|
136
|
+
.ProseMirror pre .hljs-meta,
|
|
137
|
+
.ProseMirror pre .hljs-built_in,
|
|
138
|
+
.ProseMirror pre .hljs-builtin-name,
|
|
139
|
+
.ProseMirror pre .hljs-literal,
|
|
140
|
+
.ProseMirror pre .hljs-type,
|
|
141
|
+
.ProseMirror pre .hljs-params {
|
|
142
|
+
color: #f99157;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
.ProseMirror pre .hljs-string,
|
|
146
|
+
.ProseMirror pre .hljs-symbol,
|
|
147
|
+
.ProseMirror pre .hljs-bullet {
|
|
148
|
+
color: #99cc99;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
.ProseMirror pre .hljs-title,
|
|
152
|
+
.ProseMirror pre .hljs-section {
|
|
153
|
+
color: #ffcc66;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
.ProseMirror pre .hljs-keyword,
|
|
157
|
+
.ProseMirror pre .hljs-selector-tag {
|
|
158
|
+
color: #6196cc;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
.ProseMirror pre .hljs-emphasis {
|
|
162
|
+
font-style: italic;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
.ProseMirror pre .hljs-strong {
|
|
166
|
+
font-weight: 700;
|
|
167
|
+
}
|
|
168
|
+
</style>
|
|
@@ -5,7 +5,24 @@ import TextEditor from './TextEditor.vue'
|
|
|
5
5
|
import TextEditorFixedMenu from './TextEditorFixedMenu.vue'
|
|
6
6
|
import { Button } from '../Button'
|
|
7
7
|
|
|
8
|
-
const value = ref(
|
|
8
|
+
const value = ref(`
|
|
9
|
+
<div>
|
|
10
|
+
<h2>Heading 2</h2>
|
|
11
|
+
<p>
|
|
12
|
+
This is a paragraph with <strong>bold</strong> and <em>italic</em> text.
|
|
13
|
+
</p>
|
|
14
|
+
<ul>
|
|
15
|
+
<li>Item 1</li>
|
|
16
|
+
<li>Item 2</li>
|
|
17
|
+
</ul>
|
|
18
|
+
<p>
|
|
19
|
+
<a href="https://devel.monakerp.com">Melon</a>
|
|
20
|
+
</p>
|
|
21
|
+
<pre><code class="language-javascript">import { Button } from 'pimelon-ui'
|
|
22
|
+
const value = ref(true);</code>
|
|
23
|
+
</pre>
|
|
24
|
+
</div>
|
|
25
|
+
`)
|
|
9
26
|
const customValue = ref('')
|
|
10
27
|
const customButtons = [
|
|
11
28
|
'Paragraph',
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
<script>
|
|
18
18
|
import { normalizeClass } from 'vue'
|
|
19
19
|
import { computed } from '@vue/reactivity'
|
|
20
|
-
import { Editor, EditorContent } from '@tiptap/vue-3'
|
|
20
|
+
import { Editor, EditorContent, VueNodeViewRenderer } from '@tiptap/vue-3'
|
|
21
21
|
import StarterKit from '@tiptap/starter-kit'
|
|
22
22
|
import Placeholder from '@tiptap/extension-placeholder'
|
|
23
23
|
import TextAlign from '@tiptap/extension-text-align'
|
|
@@ -32,6 +32,9 @@ import Typography from '@tiptap/extension-typography'
|
|
|
32
32
|
import TextStyle from '@tiptap/extension-text-style'
|
|
33
33
|
import Highlight from '@tiptap/extension-highlight'
|
|
34
34
|
import { Color } from '@tiptap/extension-color'
|
|
35
|
+
import { common, createLowlight } from 'lowlight'
|
|
36
|
+
import CodeBlockLowlight from '@tiptap/extension-code-block-lowlight'
|
|
37
|
+
import CodeBlockComponent from './CodeBlockComponent.vue'
|
|
35
38
|
import configureMention from './mention'
|
|
36
39
|
import TextEditorFixedMenu from './TextEditorFixedMenu.vue'
|
|
37
40
|
import TextEditorBubbleMenu from './TextEditorBubbleMenu.vue'
|
|
@@ -40,6 +43,8 @@ import EmojiExtension from './emoji-extension'
|
|
|
40
43
|
import { detectMarkdown, markdownToHTML } from '../../utils/markdown'
|
|
41
44
|
import { DOMParser } from 'prosemirror-model'
|
|
42
45
|
|
|
46
|
+
const lowlight = createLowlight(common)
|
|
47
|
+
|
|
43
48
|
export default {
|
|
44
49
|
name: 'TextEditor',
|
|
45
50
|
inheritAttrs: false,
|
|
@@ -136,6 +141,7 @@ export default {
|
|
|
136
141
|
extensions: [
|
|
137
142
|
StarterKit.configure({
|
|
138
143
|
...this.starterkitOptions,
|
|
144
|
+
codeBlock: false,
|
|
139
145
|
}),
|
|
140
146
|
Table.configure({
|
|
141
147
|
resizable: true,
|
|
@@ -150,6 +156,11 @@ export default {
|
|
|
150
156
|
TextStyle,
|
|
151
157
|
Color,
|
|
152
158
|
Highlight.configure({ multicolor: true }),
|
|
159
|
+
CodeBlockLowlight.extend({
|
|
160
|
+
addNodeView() {
|
|
161
|
+
return VueNodeViewRenderer(CodeBlockComponent)
|
|
162
|
+
},
|
|
163
|
+
}).configure({ lowlight }),
|
|
153
164
|
Image,
|
|
154
165
|
Video,
|
|
155
166
|
Link.configure({
|
|
@@ -8,6 +8,9 @@ interface UploadOptions {
|
|
|
8
8
|
method?: string
|
|
9
9
|
type?: string
|
|
10
10
|
upload_endpoint?: string
|
|
11
|
+
optimize?: boolean
|
|
12
|
+
max_width?: number
|
|
13
|
+
max_height?: number
|
|
11
14
|
}
|
|
12
15
|
|
|
13
16
|
type EventListenerOption = 'start' | 'progress' | 'finish' | 'error'
|
|
@@ -129,6 +132,16 @@ class FileUploadHandler {
|
|
|
129
132
|
form_data.append('type', options.type)
|
|
130
133
|
}
|
|
131
134
|
|
|
135
|
+
if (options.optimize) {
|
|
136
|
+
form_data.append('optimize', '1')
|
|
137
|
+
if (options.max_width) {
|
|
138
|
+
form_data.append('max_width', options.max_width.toString())
|
|
139
|
+
}
|
|
140
|
+
if (options.max_height) {
|
|
141
|
+
form_data.append('max_height', options.max_height.toString())
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
132
145
|
xhr.send(form_data)
|
|
133
146
|
})
|
|
134
147
|
}
|