@firerian/fireui 1.0.1 → 1.0.2

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.
@@ -340,6 +340,24 @@ declare const _default_2: __VLS_WithTemplateSlots_2<typeof __VLS_component_2, __
340
340
 
341
341
  declare const _default_3: __VLS_WithTemplateSlots_3<typeof __VLS_component_3, __VLS_TemplateResult_3["slots"]>;
342
342
 
343
+ declare const _default_4: DefineComponent<RichTextProps, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {} & {
344
+ change: (value: string) => any;
345
+ "update:modelValue": (value: string) => any;
346
+ ready: (quill: any) => any;
347
+ "image-upload": (file: File, callback: (url: string) => void) => any;
348
+ }, string, PublicProps, Readonly<RichTextProps> & Readonly<{
349
+ onChange?: ((value: string) => any) | undefined;
350
+ "onUpdate:modelValue"?: ((value: string) => any) | undefined;
351
+ onReady?: ((quill: any) => any) | undefined;
352
+ "onImage-upload"?: ((file: File, callback: (url: string) => void) => any) | undefined;
353
+ }>, {
354
+ disabled: boolean;
355
+ height: string | number;
356
+ placeholder: string;
357
+ modelValue: string;
358
+ toolbar: any[];
359
+ }, {}, {}, {}, string, ComponentProvideOptions, false, {}, HTMLDivElement>;
360
+
343
361
  export declare const FButton: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
344
362
 
345
363
  export declare const FireAside: {
@@ -676,6 +694,10 @@ style?: string | object;
676
694
  install: (app: App) => void;
677
695
  };
678
696
 
697
+ export declare const FireRichText: typeof _default_4 & {
698
+ install: (app: App) => void;
699
+ };
700
+
679
701
  export declare const FireRow: {
680
702
  new (...args: any[]): CreateComponentPublicInstanceWithMixins<Readonly<RowProps_2> & Readonly<{}>, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {}, PublicProps, {
681
703
  gutter: number | [number, number];
@@ -1240,6 +1262,37 @@ declare interface ResponsiveProps_2 {
1240
1262
  offset?: number;
1241
1263
  }
1242
1264
 
1265
+ declare interface RichTextProps {
1266
+ /**
1267
+ * 绑定的值
1268
+ */
1269
+ modelValue?: string;
1270
+ /**
1271
+ * 编辑器高度
1272
+ */
1273
+ height?: string | number;
1274
+ /**
1275
+ * 是否禁用
1276
+ */
1277
+ disabled?: boolean;
1278
+ /**
1279
+ * 占位文本
1280
+ */
1281
+ placeholder?: string;
1282
+ /**
1283
+ * 自定义工具栏配置
1284
+ */
1285
+ toolbar?: any[];
1286
+ /**
1287
+ * 自定义类名
1288
+ */
1289
+ class?: string;
1290
+ /**
1291
+ * 自定义样式
1292
+ */
1293
+ style?: string | object;
1294
+ }
1295
+
1243
1296
  export declare interface RowProps {
1244
1297
  /**
1245
1298
  * 栅格间距
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@firerian/fireui",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "type": "module",
5
5
  "description": "A modern Vue 3 UI component library",
6
6
  "main": "./dist/fireui.cjs",
@@ -74,8 +74,10 @@
74
74
  },
75
75
  "dependencies": {
76
76
  "@floating-ui/vue": "^1.1.10",
77
+ "@vueup/vue-quill": "^1.2.0",
77
78
  "async-validator": "^4.2.5",
78
- "lucide-vue-next": "^0.454.0"
79
+ "lucide-vue-next": "^0.454.0",
80
+ "quill": "^2.0.3"
79
81
  },
80
82
  "devDependencies": {
81
83
  "@eslint/js": "^9.13.0",
@@ -34,3 +34,7 @@ export type { FormProps, FormEmits, FormInstance, FormItemProps, FormItemEmits,
34
34
  // Table 组件
35
35
  export { FireTable, FireTableColumn } from './table'
36
36
  export type { TableProps, TableEmits, TableInstance, TableColumnProps, TableColumnSlots } from '../types/table'
37
+
38
+ // RichText 组件
39
+ export { FireRichText } from './rich-text'
40
+ export type { RichTextProps, RichTextEmits } from './rich-text/types'
@@ -0,0 +1,8 @@
1
+ import RichText from './rich-text.vue'
2
+ import { withInstall } from '../../utils'
3
+ import type { App } from 'vue'
4
+
5
+ const FireRichText = withInstall(RichText as any) as typeof RichText & { install: (app: App) => void }
6
+
7
+ export { FireRichText }
8
+ export default FireRichText
@@ -0,0 +1,205 @@
1
+ <template>
2
+ <div
3
+ :class="[
4
+ ns.b.value,
5
+ {
6
+ [ns.m('disabled')]: disabled
7
+ }
8
+ ]"
9
+ :style="{
10
+ ...(typeof props.style === 'object' ? props.style : {}),
11
+ height
12
+ }"
13
+ >
14
+ <QuillEditor
15
+ v-model:content="localValue"
16
+ :disabled="disabled"
17
+ :placeholder="placeholder"
18
+ :toolbar="toolbar"
19
+ @ready="handleReady"
20
+ @update:content="handleUpdate"
21
+ @text-change="handleTextChange"
22
+ @image-upload="handleImageUpload"
23
+ />
24
+ </div>
25
+ </template>
26
+
27
+ <script setup lang="ts">
28
+ import { ref, computed, watch } from 'vue'
29
+ import { QuillEditor } from '@vueup/vue-quill'
30
+ import 'quill/dist/quill.snow.css'
31
+ import { useNamespace } from '../../utils'
32
+ import type { RichTextProps, RichTextEmits } from './types'
33
+
34
+ const ns = useNamespace('rich-text')
35
+
36
+ const props = withDefaults(defineProps<RichTextProps>(), {
37
+ modelValue: '',
38
+ height: '300px',
39
+ disabled: false,
40
+ placeholder: '请输入内容...',
41
+ toolbar: () => [
42
+ ['bold', 'italic', 'underline', 'strike'],
43
+ ['blockquote', 'code-block'],
44
+ [{ 'header': 1 }, { 'header': 2 }],
45
+ [{ 'list': 'ordered' }, { 'list': 'bullet' }],
46
+ [{ 'script': 'sub' }, { 'script': 'super' }],
47
+ [{ 'indent': '-1' }, { 'indent': '+1' }],
48
+ [{ 'direction': 'rtl' }],
49
+ [{ 'size': ['small', false, 'large', 'huge'] }],
50
+ [{ 'header': [1, 2, 3, 4, 5, 6, false] }],
51
+ [{ 'color': [] }, { 'background': [] }],
52
+ [{ 'font': [] }],
53
+ [{ 'align': [] }],
54
+ ['clean'],
55
+ ['link', 'image', 'video']
56
+ ]
57
+ })
58
+
59
+ const emit = defineEmits<RichTextEmits>()
60
+
61
+ const localValue = ref(props.modelValue)
62
+
63
+ const height = computed(() => {
64
+ return typeof props.height === 'number' ? `${props.height}px` : props.height
65
+ })
66
+
67
+
68
+
69
+ watch(
70
+ () => props.modelValue,
71
+ (newValue) => {
72
+ if (newValue !== localValue.value) {
73
+ localValue.value = newValue
74
+ }
75
+ }
76
+ )
77
+
78
+ const handleReady = (quill: any) => {
79
+ emit('ready', quill)
80
+ }
81
+
82
+ const handleUpdate = (value: string) => {
83
+ emit('update:modelValue', value)
84
+ emit('change', value)
85
+ }
86
+
87
+ const handleTextChange = (_delta: any, _oldDelta: any, source: any) => {
88
+ if (source === 'user') {
89
+ emit('change', localValue.value)
90
+ }
91
+ }
92
+
93
+ const handleImageUpload = (file: File, callback: (url: string) => void) => {
94
+ emit('image-upload', file, callback)
95
+ }
96
+ </script>
97
+
98
+ <style scoped lang="scss">
99
+ @import '../../styles/variables.scss';
100
+
101
+ .#{$namespace}-rich-text {
102
+ border: 1px solid $border-color;
103
+ border-radius: $border-radius-base;
104
+ transition: all 0.2s ease;
105
+
106
+ &:hover {
107
+ border-color: $primary-color;
108
+ }
109
+
110
+ &--disabled {
111
+ background-color: $disabled-bg;
112
+ border-color: $border-color;
113
+ cursor: not-allowed;
114
+
115
+ .ql-container {
116
+ background-color: $disabled-bg;
117
+ cursor: not-allowed;
118
+ }
119
+ }
120
+
121
+ .ql-container {
122
+ font-size: 14px;
123
+ }
124
+
125
+ .ql-editor {
126
+ min-height: calc(100% - 42px);
127
+ line-height: 1.5;
128
+ }
129
+
130
+ .ql-toolbar.ql-snow {
131
+ border-bottom: 1px solid $border-color;
132
+ }
133
+
134
+ .ql-snow .ql-picker-label {
135
+ color: $text-color;
136
+ }
137
+
138
+ .ql-snow .ql-picker-options {
139
+ color: $text-color;
140
+ background-color: #fff;
141
+ }
142
+
143
+ .ql-snow .ql-picker-item:hover {
144
+ background-color: $primary-color-light;
145
+ }
146
+
147
+ .ql-snow .ql-picker-item.ql-selected {
148
+ color: $primary-color;
149
+ }
150
+
151
+ .ql-snow .ql-button:hover {
152
+ color: $primary-color;
153
+ }
154
+
155
+ .ql-snow .ql-active {
156
+ color: $primary-color;
157
+ }
158
+
159
+ .ql-snow .ql-tooltip {
160
+ background-color: #fff;
161
+ border: 1px solid $border-color;
162
+ border-radius: $border-radius-base;
163
+ box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
164
+ }
165
+
166
+ .ql-snow .ql-tooltip input[type=text] {
167
+ border: 1px solid $border-color;
168
+ border-radius: $border-radius-base;
169
+ }
170
+
171
+ .ql-snow .ql-tooltip input[type=text]:focus {
172
+ border-color: $primary-color;
173
+ box-shadow: 0 0 0 2px rgba($primary-color, 0.2);
174
+ }
175
+
176
+ .ql-snow .ql-tooltip button {
177
+ background-color: $primary-color;
178
+ color: #fff;
179
+ border: none;
180
+ border-radius: $border-radius-base;
181
+ padding: 4px 8px;
182
+ cursor: pointer;
183
+
184
+ &:hover {
185
+ background-color: $primary-color-dark;
186
+ }
187
+ }
188
+
189
+ .ql-snow .ql-tooltip button.ql-action {
190
+ background-color: $success-color;
191
+
192
+ &:hover {
193
+ background-color: $success-color-dark;
194
+ }
195
+ }
196
+
197
+ .ql-snow .ql-tooltip button.ql-remove {
198
+ background-color: $danger-color;
199
+
200
+ &:hover {
201
+ background-color: $danger-color-dark;
202
+ }
203
+ }
204
+ }
205
+ </style>
@@ -0,0 +1,52 @@
1
+ // 简化 Quill 类型定义
2
+ type QuillType = any
3
+
4
+ export interface RichTextProps {
5
+ /**
6
+ * 绑定的值
7
+ */
8
+ modelValue?: string
9
+ /**
10
+ * 编辑器高度
11
+ */
12
+ height?: string | number
13
+ /**
14
+ * 是否禁用
15
+ */
16
+ disabled?: boolean
17
+ /**
18
+ * 占位文本
19
+ */
20
+ placeholder?: string
21
+ /**
22
+ * 自定义工具栏配置
23
+ */
24
+ toolbar?: any[]
25
+ /**
26
+ * 自定义类名
27
+ */
28
+ class?: string
29
+ /**
30
+ * 自定义样式
31
+ */
32
+ style?: string | object
33
+ }
34
+
35
+ export interface RichTextEmits {
36
+ /**
37
+ * 值变化事件
38
+ */
39
+ (e: 'update:modelValue', value: string): void
40
+ /**
41
+ * 编辑器初始化完成事件
42
+ */
43
+ (e: 'ready', quill: QuillType): void
44
+ /**
45
+ * 内容变化事件
46
+ */
47
+ (e: 'change', value: string): void
48
+ /**
49
+ * 图片上传事件
50
+ */
51
+ (e: 'image-upload', file: File, callback: (url: string) => void): void
52
+ }
package/src/index.ts CHANGED
@@ -17,10 +17,10 @@
17
17
  */
18
18
 
19
19
  import type { App, Plugin, Component } from 'vue'
20
- import { FButton, FireRow, FireCol, FireContainer, FireHeader, FireAside, FireMain, FireFooter, FireTooltip, FireTips, FireInput, FireForm, FireFormItem, FireTable, FireTableColumn } from './components'
20
+ import { FButton, FireRow, FireCol, FireContainer, FireHeader, FireAside, FireMain, FireFooter, FireTooltip, FireTips, FireInput, FireForm, FireFormItem, FireTable, FireTableColumn, FireRichText } from './components'
21
21
 
22
22
  // 所有组件列表
23
- const components = [FButton, FireRow, FireCol, FireContainer, FireHeader, FireAside, FireMain, FireFooter, FireTooltip, FireTips, FireInput, FireForm, FireFormItem, FireTable, FireTableColumn]
23
+ const components = [FButton, FireRow, FireCol, FireContainer, FireHeader, FireAside, FireMain, FireFooter, FireTooltip, FireTips, FireInput, FireForm, FireFormItem, FireTable, FireTableColumn, FireRichText]
24
24
 
25
25
  /**
26
26
  * 安装函数 - 自动注册所有组件
@@ -35,7 +35,7 @@ const install = (app: App): void => {
35
35
  }
36
36
 
37
37
  // 导出所有组件
38
- export { FButton, FireRow, FireCol, FireContainer, FireHeader, FireAside, FireMain, FireFooter, FireTooltip, FireTips, FireInput, FireForm, FireFormItem, FireTable, FireTableColumn }
38
+ export { FButton, FireRow, FireCol, FireContainer, FireHeader, FireAside, FireMain, FireFooter, FireTooltip, FireTips, FireInput, FireForm, FireFormItem, FireTable, FireTableColumn, FireRichText }
39
39
 
40
40
  // 导出组件库插件
41
41
  export default {
@@ -4,9 +4,13 @@ $namespace: fire;
4
4
  // 颜色变量
5
5
  $primary-color: #3b82f6;
6
6
  $primary-color-hover: #2563eb;
7
+ $primary-color-light: rgba(59, 130, 246, 0.1);
8
+ $primary-color-dark: #1d4ed8;
7
9
  $success-color: #22c55e;
8
- $warning-color: #f59e0b;
10
+ $success-color-dark: #16a34a;
9
11
  $danger-color: #ef4444;
12
+ $danger-color-dark: #dc2626;
13
+ $warning-color: #f59e0b;
10
14
  $info-color: #6b7280;
11
15
 
12
16
  // 字体