@easy-editor/materials-dashboard-image 0.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.
Files changed (45) hide show
  1. package/.vite/plugins/vite-plugin-external-deps.ts +224 -0
  2. package/.vite/plugins/vite-plugin-material-dev.ts +218 -0
  3. package/CHANGELOG.md +7 -0
  4. package/LICENSE +9 -0
  5. package/dist/component.esm.js +105 -0
  6. package/dist/component.esm.js.map +1 -0
  7. package/dist/component.js +114 -0
  8. package/dist/component.js.map +1 -0
  9. package/dist/component.min.js +2 -0
  10. package/dist/component.min.js.map +1 -0
  11. package/dist/index.cjs +427 -0
  12. package/dist/index.cjs.map +1 -0
  13. package/dist/index.esm.js +424 -0
  14. package/dist/index.esm.js.map +1 -0
  15. package/dist/index.js +432 -0
  16. package/dist/index.js.map +1 -0
  17. package/dist/index.min.js +2 -0
  18. package/dist/index.min.js.map +1 -0
  19. package/dist/meta.esm.js +323 -0
  20. package/dist/meta.esm.js.map +1 -0
  21. package/dist/meta.js +334 -0
  22. package/dist/meta.js.map +1 -0
  23. package/dist/meta.min.js +2 -0
  24. package/dist/meta.min.js.map +1 -0
  25. package/dist/src/component.d.ts +31 -0
  26. package/dist/src/configure.d.ts +7 -0
  27. package/dist/src/constants.d.ts +16 -0
  28. package/dist/src/index.d.ts +6 -0
  29. package/dist/src/meta.d.ts +7 -0
  30. package/dist/src/snippets.d.ts +7 -0
  31. package/package.json +67 -0
  32. package/rollup.config.js +222 -0
  33. package/src/assets/default.png +0 -0
  34. package/src/component.module.css +122 -0
  35. package/src/component.tsx +99 -0
  36. package/src/configure.ts +285 -0
  37. package/src/constants.ts +18 -0
  38. package/src/index.tsx +7 -0
  39. package/src/meta.ts +28 -0
  40. package/src/snippets.ts +49 -0
  41. package/src/type.d.ts +13 -0
  42. package/tsconfig.build.json +12 -0
  43. package/tsconfig.json +9 -0
  44. package/tsconfig.test.json +7 -0
  45. package/vite.config.ts +54 -0
@@ -0,0 +1,99 @@
1
+ /**
2
+ * Image Component
3
+ * 图片/图标/边框装饰组件
4
+ */
5
+
6
+ import type { CSSProperties, Ref } from 'react'
7
+ import { cn } from '@easy-editor/materials-shared'
8
+ import styles from './component.module.css'
9
+
10
+ export type ObjectFit = 'cover' | 'contain' | 'fill' | 'none'
11
+ export type BorderStyle = 'none' | 'neon' | 'gradient' | 'tech'
12
+ export type DisplayMode = 'image' | 'icon'
13
+
14
+ export interface ImageProps {
15
+ ref?: Ref<HTMLDivElement>
16
+ /** 图片地址 */
17
+ src?: string
18
+ /** 图片描述 */
19
+ alt?: string
20
+ /** 图片填充方式 */
21
+ objectFit?: ObjectFit
22
+ /** 圆角 */
23
+ borderRadius?: number
24
+ /** 边框样式 */
25
+ borderStyle?: BorderStyle
26
+ /** 边框颜色(霓虹/科技感边框) */
27
+ borderColor?: string
28
+ /** 阴影 */
29
+ shadow?: boolean
30
+ /** 阴影颜色 */
31
+ shadowColor?: string
32
+ /** 外部样式 */
33
+ style?: CSSProperties
34
+ }
35
+
36
+ const DEFAULT_IMAGE =
37
+ 'data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgNzAgNjAiIHdpZHRoPSI3MCIgaGVpZ2h0PSI2MCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4NCiAgPGRlZnMgaWQ9IlN2Z2pzRGVmczEwMDEiPjwvZGVmcz4NCiAgPGcNCiAgICB0cmFuc2Zvcm09Im1hdHJpeCgwLjYwNDgwNDY3OTI2Mjc2NTIsMCwwLDAuNjA0ODA0Njc5MjYyNzY1MiwtMC4wMDAwMTg0MDMxMDAyOTc2NjgwNzYsLTAuMDAwNDk0ODEwODgwODczMjQ1OSkiDQogICAgZmlsbD0iI2ZmZiINCiAgPg0KICAgIDxwYXRoDQogICAgICB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciDQogICAgICBkPSJNOTUuMTA4LDg0LjEyNWMtMC40ODQsMC0wLjk1NS0wLjI1Mi0xLjIxNi0wLjcwMUw2NS44NDksMzQuNzljLTAuMzg2LTAuNjcxLTAuMTU1LTEuNTI4LDAuNTE2LTEuOTE3ICBjMC42NzMtMC4zODYsMS41MjctMC4xNTYsMS45MTYsMC41MTVsMjguMDQzLDQ4LjYzNGMwLjM4NiwwLjY3LDAuMTU2LDEuNTI3LTAuNTE1LDEuOTE2Qzk1LjU4Nyw4NC4wNjQsOTUuMzQ2LDg0LjEyNSw5NS4xMDgsODQuMTI1ICB6Ig0KICAgID48L3BhdGg+DQogICAgPHBhdGgNCiAgICAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyINCiAgICAgIGQ9Ik03Ni45MzgsODQuMTI1SDEuNDAzYy0wLjUwMSwwLTAuOTY0LTAuMjY2LTEuMjEzLTAuNzAxYy0wLjI1Mi0wLjQzMy0wLjI1Mi0wLjk2Ny0wLjAwMy0xLjQwMUw0Ny4wMTEsMC43MTYgIGMwLjI1MS0wLjQzMywwLjcxNC0wLjcwMSwxLjIxNS0wLjcwMWgxOS4yM2MwLjc3NSwwLDEuNDAyLDAuNjI3LDEuNDAyLDEuNDAyYzAsMC43NzQtMC42MjcsMS40MDEtMS40MDIsMS40MDFINDkuMDM3TDMuODI4LDgxLjMyMSAgaDczLjExYzAuNzc0LDAsMS40MDEsMC42MjcsMS40MDEsMS40MDFDNzguMzM5LDgzLjQ5OCw3Ny43MTIsODQuMTI1LDc2LjkzOCw4NC4xMjV6Ig0KICAgID48L3BhdGg+DQogICAgPHBhdGggeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBkPSJNNDguODkyLDM0LjA4OSI+PC9wYXRoPg0KICAgIDxwYXRoDQogICAgICB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciDQogICAgICBkPSJNNzYuOTM4LDg0LjEyNUgxLjQwM2MtMC43NzUsMC0xLjQwMi0wLjYyNy0xLjQwMi0xLjQwMmMwLTAuNzc0LDAuNjI3LTEuNDAxLDEuNDAyLTEuNDAxaDczLjEwOUw1Ni43NjYsNTAuNTU0ICBjLTAuMzg2LTAuNjctMC4xNTYtMS41MjcsMC41MTUtMS45MTZjMC42NzEtMC4zODYsMS41MjgtMC4xNTYsMS45MTcsMC41MTVsMTguOTU2LDMyLjg3YzAuMjQ5LDAuNDM1LDAuMjQ5LDAuOTY5LTAuMDAzLDEuNDAxICBDNzcuOTAxLDgzLjg1Niw3Ny40MzksODQuMTI1LDc2LjkzOCw4NC4xMjV6Ig0KICAgID48L3BhdGg+DQogICAgPHBhdGgNCiAgICAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyINCiAgICAgIGQ9Ik0yOC43MDcsMTAwLjAwMUgxMC43NmMtMC43NzUsMC0xLjQwMi0wLjYyNy0xLjQwMi0xLjQwMWMwLTAuNzc1LDAuNjI3LTEuNDAyLDEuNDAyLTEuNDAyaDE3Ljk0NiAgYzAuNzc0LDAsMS40MDEsMC42MjcsMS40MDEsMS40MDJDMzAuMTA4LDk5LjM3NCwyOS40ODEsMTAwLjAwMSwyOC43MDcsMTAwLjAwMXoiDQogICAgPjwvcGF0aD4NCiAgICA8cGF0aA0KICAgICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIg0KICAgICAgZD0iTTc2LjkzOCw4NC4xMjVIMS40MDNjLTAuNTAxLDAtMC45NjQtMC4yNjktMS4yMTMtMC43MDFjLTAuMjUyLTAuNDMzLTAuMjUyLTAuOTY3LTAuMDAzLTEuNDAxbDE4Ljk1NC0zMi44NyAgYzAuMzg5LTAuNjcxLDEuMjQtMC45MDEsMS45MTctMC41MTVjMC42NzEsMC4zODksMC45MDEsMS4yNDYsMC41MTUsMS45MTZMMy44MjgsODEuMzIxaDczLjExYzAuNzc0LDAsMS40MDEsMC42MjcsMS40MDEsMS40MDEgIEM3OC4zMzksODMuNDk4LDc3LjcxMiw4NC4xMjUsNzYuOTM4LDg0LjEyNXoiDQogICAgPjwvcGF0aD4NCiAgICA8cGF0aA0KICAgICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIg0KICAgICAgZD0iTTEwNC4yMzYsMTAwLjAwMUgyOC43MDdjLTAuNzc1LDAtMS40MDItMC42MjctMS40MDItMS40MDFjMC0wLjc3NSwwLjYyNy0xLjQwMiwxLjQwMi0xLjQwMmg3My4xMDRMODQuMDY3LDY2LjQzNCAgYy0wLjM4Ni0wLjY3MS0wLjE1Ni0xLjUyOCwwLjUxNS0xLjkxN2MwLjY3MS0wLjM4MywxLjUyNy0wLjE1OCwxLjkxNiwwLjUxNWwxOC45NTQsMzIuODY3YzAuMjQ5LDAuNDM2LDAuMjQ5LDAuOTY5LTAuMDAzLDEuNDAxICBDMTA1LjIsOTkuNzMyLDEwNC43MzcsMTAwLjAwMSwxMDQuMjM2LDEwMC4wMDF6Ig0KICAgID48L3BhdGg+DQogICAgPHBhdGgNCiAgICAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyINCiAgICAgIGQ9Ik03Ni45MzgsODQuMTI1SDIwLjYzM2MtMC43NzUsMC0xLjQwMi0wLjYyNy0xLjQwMi0xLjQwMmMwLTAuNzc0LDAuNjI3LTEuNDAxLDEuNDAyLTEuNDAxaDU2LjMwNSAgYzAuNzc0LDAsMS40MDEsMC42MjcsMS40MDEsMS40MDFDNzguMzM5LDgzLjQ5OCw3Ny43MTIsODQuMTI1LDc2LjkzOCw4NC4xMjV6Ig0KICAgID48L3BhdGg+DQogICAgPHBhdGgNCiAgICAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyINCiAgICAgIGQ9Ik02Ny40MzIsNjcuNjQ0aC0zNy4zNGMtMC41MDEsMC0wLjk2NC0wLjI2Ni0xLjIxMy0wLjcwMWMtMC4yNTItMC40MzMtMC4yNTItMC45NjctMC4wMDMtMS40MDFsMzcuMzQtNjQuODM5ICBjMC4zODYtMC42NzEsMS4yNC0wLjkwMSwxLjkxNy0wLjUxNWMwLjY3LDAuMzg2LDAuOSwxLjI0MywwLjUxNSwxLjkxN0wzMi41MTcsNjQuODRoMzQuOTE1YzAuNzc0LDAsMS40MDEsMC42MjcsMS40MDEsMS40MDEgIEM2OC44MzMsNjcuMDE3LDY4LjIwNyw2Ny42NDQsNjcuNDMyLDY3LjY0NHoiDQogICAgPjwvcGF0aD4NCiAgICA8cGF0aA0KICAgICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIg0KICAgICAgZD0iTTY3LjQzMiw2Ny42NDRINDguNTQ0Yy0wLjUwMSwwLTAuOTY0LTAuMjY2LTEuMjEzLTAuNzAxYy0wLjI1Mi0wLjQzMy0wLjI1Mi0wLjk2Ny0wLjAwMy0xLjQwMWwxOC41MTktMzIuMTU1ICBjMC4zODktMC42NzEsMS4yNC0wLjkwMSwxLjkxNi0wLjUxNWMwLjY3MSwwLjM4NiwwLjksMS4yNDMsMC41MTUsMS45MTdMNTAuOTcsNjQuODRoMTYuNDYyYzAuNzc0LDAsMS40MDEsMC42MjcsMS40MDEsMS40MDEgIEM2OC44MzMsNjcuMDE3LDY4LjIwNyw2Ny42NDQsNjcuNDMyLDY3LjY0NHoiDQogICAgPjwvcGF0aD4NCiAgICA8cGF0aA0KICAgICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIg0KICAgICAgZD0iTTEwLjc2LDEwMC4wMDFjLTAuNDc5LDAtMC45NDctMC4yNDYtMS4yMDgtMC42OUwwLjE5NSw4My40MzVjLTAuMzk0LTAuNjY4LTAuMTcyLTEuNTI0LDAuNDk2LTEuOTE5ICBjMC42NjUtMC4zOTIsMS41MjUtMC4xNzMsMS45MTksMC40OTVsOS4zNTgsMTUuODc3YzAuMzk0LDAuNjY4LDAuMTcyLDEuNTI3LTAuNDk2LDEuOTE5ICBDMTEuMjQ4LDk5LjkzOCwxMS4wMDQsMTAwLjAwMSwxMC43NiwxMDAuMDAxeiINCiAgICA+PC9wYXRoPg0KICAgIDxwYXRoDQogICAgICB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciDQogICAgICBkPSJNMTA0LjIzNiwxMDAuMDAxYy0wLjI2LDAtMC41MjEtMC4wNzEtMC43NTMtMC4yMTljLTAuNjUxLTAuNDE2LTAuODQ2LTEuMjgxLTAuNDMtMS45MzZsOS42NDUtMTUuMTU5TDY3LjQ1Nyw0LjIyMyAgTDMxLjMzMiw2Ni45NTZjLTAuMzkyLDAuNjcxLTEuMjQzLDAuODk2LTEuOTE3LDAuNTE1Yy0wLjY3MS0wLjM4Ni0wLjkwMS0xLjI0My0wLjUxNS0xLjkxNmwzNy4zNC02NC44MzkgIGMwLjUwNC0wLjg2NSwxLjkyOC0wLjg2NSwyLjQzMiwwbDQ2Ljg4MSw4MS4zMDdjMC4yNjEsMC40NTEsMC4yNDcsMS4wMTMtMC4wMzIsMS40NTNsLTEwLjEwMywxNS44NzYgIEMxMDUuMTUsOTkuNzcxLDEwNC42OTksMTAwLjAwMSwxMDQuMjM2LDEwMC4wMDF6Ig0KICAgID48L3BhdGg+DQogIDwvZz4NCjwvc3ZnPg0K'
38
+
39
+ const getObjectFitClass = (fit: ObjectFit): string => {
40
+ switch (fit) {
41
+ case 'cover':
42
+ return styles.imageCover
43
+ case 'contain':
44
+ return styles.imageContain
45
+ case 'fill':
46
+ return styles.imageFill
47
+ default:
48
+ return ''
49
+ }
50
+ }
51
+
52
+ const getBorderClass = (borderStyle: BorderStyle): string => {
53
+ switch (borderStyle) {
54
+ case 'neon':
55
+ return styles.borderNeon
56
+ case 'gradient':
57
+ return styles.borderGradient
58
+ case 'tech':
59
+ return styles.borderTech
60
+ default:
61
+ return ''
62
+ }
63
+ }
64
+
65
+ export const Image: React.FC<ImageProps> = ({
66
+ ref,
67
+ src = DEFAULT_IMAGE,
68
+ alt = '',
69
+ objectFit = 'cover',
70
+ borderRadius = 0,
71
+ borderStyle = 'none',
72
+ borderColor = '#00d4ff',
73
+ shadow = false,
74
+ shadowColor = 'rgba(0, 212, 255, 0.3)',
75
+ style: externalStyle,
76
+ }) => {
77
+ const containerStyle: CSSProperties = {
78
+ borderRadius,
79
+ color: borderColor,
80
+ boxShadow: shadow ? `0 4px 20px ${shadowColor}` : undefined,
81
+ ...externalStyle,
82
+ } as CSSProperties
83
+
84
+ // 图片模式
85
+ return (
86
+ <div className={cn(styles.container, getBorderClass(borderStyle))} ref={ref} style={containerStyle}>
87
+ <img
88
+ alt={alt}
89
+ className={cn(styles.image, getObjectFitClass(objectFit))}
90
+ draggable={false}
91
+ height='100%'
92
+ src={src}
93
+ width='100%'
94
+ />
95
+ </div>
96
+ )
97
+ }
98
+
99
+ export default Image
@@ -0,0 +1,285 @@
1
+ /**
2
+ * Image Configure
3
+ * 图片组件配置
4
+ */
5
+
6
+ import type { Configure } from '@easy-editor/core'
7
+ import type { UploadValue } from '@easy-editor/materials-shared'
8
+
9
+ export const configure: Configure = {
10
+ props: [
11
+ {
12
+ type: 'group',
13
+ title: '属性',
14
+ setter: 'TabSetter',
15
+ items: [
16
+ {
17
+ type: 'group',
18
+ key: 'config',
19
+ title: '配置',
20
+ setter: {
21
+ componentName: 'CollapseSetter',
22
+ props: {
23
+ icon: false,
24
+ },
25
+ },
26
+ items: [
27
+ // 基础配置
28
+ {
29
+ name: 'id',
30
+ title: 'ID',
31
+ setter: 'NodeIdSetter',
32
+ extraProps: {
33
+ // @ts-expect-error label is not a valid extra prop
34
+ label: false,
35
+ },
36
+ },
37
+ {
38
+ name: 'title',
39
+ title: '标题',
40
+ setter: 'StringSetter',
41
+ extraProps: {
42
+ getValue(target) {
43
+ return target.getExtraPropValue('title')
44
+ },
45
+ setValue(target, value) {
46
+ target.setExtraPropValue('title', value)
47
+ },
48
+ },
49
+ },
50
+ {
51
+ type: 'group',
52
+ title: '基础属性',
53
+ setter: {
54
+ componentName: 'CollapseSetter',
55
+ props: {
56
+ icon: false,
57
+ },
58
+ },
59
+ items: [
60
+ {
61
+ name: 'rect',
62
+ title: '位置尺寸',
63
+ setter: 'RectSetter',
64
+ extraProps: {
65
+ getValue(target) {
66
+ return target.getExtraPropValue('$dashboard.rect')
67
+ },
68
+ setValue(target, value) {
69
+ target.setExtraPropValue('$dashboard.rect', value)
70
+ },
71
+ },
72
+ },
73
+ ],
74
+ },
75
+ // 组件配置
76
+ {
77
+ type: 'group',
78
+ title: '内容',
79
+ setter: {
80
+ componentName: 'CollapseSetter',
81
+ props: {
82
+ icon: false,
83
+ },
84
+ },
85
+ items: [
86
+ {
87
+ name: '__upload',
88
+ title: '上传',
89
+ setter: {
90
+ componentName: 'UploadSetter',
91
+ props: {
92
+ accept: '.jpg,.jpeg,.png,.gif,.svg',
93
+ },
94
+ },
95
+ extraProps: {
96
+ setValue(target, value: UploadValue) {
97
+ if (value) {
98
+ const { base64, raw } = value
99
+ if (base64) {
100
+ target.parent.setPropValue('src', base64)
101
+ }
102
+ if (raw?.width) {
103
+ target.parent.setExtraPropValue('$dashboard.rect.width', raw.width)
104
+ }
105
+ if (raw?.height) {
106
+ target.parent.setExtraPropValue('$dashboard.rect.height', raw.height)
107
+ }
108
+ } else {
109
+ target.parent.clearPropValue('src')
110
+ }
111
+ },
112
+ },
113
+ },
114
+ {
115
+ name: 'src',
116
+ title: '图片地址',
117
+ setter: 'StringSetter',
118
+ },
119
+ {
120
+ name: 'alt',
121
+ title: '替代文本',
122
+ setter: 'StringSetter',
123
+ },
124
+ ],
125
+ },
126
+ {
127
+ type: 'group',
128
+ title: '加载',
129
+ setter: {
130
+ componentName: 'CollapseSetter',
131
+ props: {
132
+ icon: false,
133
+ },
134
+ },
135
+ items: [
136
+ {
137
+ name: 'lazyLoad',
138
+ title: '懒加载',
139
+ setter: 'SwitchSetter',
140
+ extraProps: {
141
+ defaultValue: false,
142
+ },
143
+ },
144
+ {
145
+ name: 'lazyLoadThreshold',
146
+ title: '懒加载阈值',
147
+ setter: {
148
+ componentName: 'SliderSetter',
149
+ props: {
150
+ min: 0,
151
+ max: 500,
152
+ step: 50,
153
+ suffix: 'px',
154
+ },
155
+ },
156
+ extraProps: {
157
+ defaultValue: 100,
158
+ },
159
+ },
160
+ {
161
+ name: 'placeholder',
162
+ title: '占位图',
163
+ setter: 'StringSetter',
164
+ },
165
+ ],
166
+ },
167
+ {
168
+ type: 'group',
169
+ title: '样式',
170
+ setter: {
171
+ componentName: 'CollapseSetter',
172
+ props: {
173
+ icon: false,
174
+ },
175
+ },
176
+ items: [
177
+ {
178
+ name: 'objectFit',
179
+ title: '填充方式',
180
+ setter: {
181
+ componentName: 'SelectSetter',
182
+ props: {
183
+ options: [
184
+ { label: '覆盖', value: 'cover' },
185
+ { label: '包含', value: 'contain' },
186
+ { label: '填充', value: 'fill' },
187
+ { label: '无', value: 'none' },
188
+ ],
189
+ },
190
+ },
191
+ extraProps: {
192
+ defaultValue: 'cover',
193
+ },
194
+ },
195
+ {
196
+ name: 'borderRadius',
197
+ title: '圆角',
198
+ setter: 'NumberSetter',
199
+ extraProps: {
200
+ defaultValue: 0,
201
+ },
202
+ },
203
+ {
204
+ name: 'borderStyle',
205
+ title: '边框样式',
206
+ setter: {
207
+ componentName: 'SelectSetter',
208
+ props: {
209
+ options: [
210
+ { label: '无', value: 'none' },
211
+ { label: '霓虹', value: 'neon' },
212
+ { label: '渐变', value: 'gradient' },
213
+ { label: '科技感', value: 'tech' },
214
+ ],
215
+ },
216
+ },
217
+ extraProps: {
218
+ defaultValue: 'none',
219
+ },
220
+ },
221
+ {
222
+ name: 'borderColor',
223
+ title: '边框颜色',
224
+ setter: 'ColorSetter',
225
+ extraProps: {
226
+ defaultValue: '#00d4ff',
227
+ },
228
+ },
229
+ {
230
+ name: 'shadow',
231
+ title: '启用阴影',
232
+ setter: 'SwitchSetter',
233
+ extraProps: {
234
+ defaultValue: false,
235
+ },
236
+ },
237
+ {
238
+ name: 'shadowColor',
239
+ title: '阴影颜色',
240
+ setter: 'ColorSetter',
241
+ extraProps: {
242
+ defaultValue: 'rgba(0, 212, 255, 0.3)',
243
+ },
244
+ },
245
+ ],
246
+ },
247
+ ],
248
+ },
249
+ {
250
+ type: 'group',
251
+ key: 'data',
252
+ title: '数据',
253
+ items: [
254
+ {
255
+ name: 'dataBinding',
256
+ title: '数据绑定',
257
+ setter: 'DataBindingSetter',
258
+ },
259
+ ],
260
+ },
261
+ {
262
+ type: 'group',
263
+ key: 'advanced',
264
+ title: '高级',
265
+ items: [
266
+ {
267
+ name: 'condition',
268
+ title: '显隐控制',
269
+ setter: 'SwitchSetter',
270
+ extraProps: {
271
+ defaultValue: true,
272
+ supportVariable: true,
273
+ },
274
+ },
275
+ ],
276
+ },
277
+ ],
278
+ },
279
+ ],
280
+ component: {},
281
+ supports: {},
282
+ advanced: {},
283
+ }
284
+
285
+ export default configure
@@ -0,0 +1,18 @@
1
+ /**
2
+ * 物料常量配置
3
+ * 统一管理全局变量名等配置,确保 meta.ts 和 rollup.config.js 使用相同的值
4
+ */
5
+
6
+ /**
7
+ * UMD 全局变量基础名称
8
+ * 用于构建:
9
+ * - 元数据:${GLOBAL_NAME}Meta (例如: EasyEditorMaterialsImageMeta)
10
+ * - 组件:${GLOBAL_NAME}Component (例如: EasyEditorMaterialsImageComponent)
11
+ * - 完整构建:${GLOBAL_NAME} (例如: EasyEditorMaterialsImage)
12
+ */
13
+ export const COMPONENT_NAME = 'EasyEditorMaterialsImage'
14
+
15
+ /**
16
+ * 包名
17
+ */
18
+ export const PACKAGE_NAME = '@easy-editor/materials-dashboard-image'
package/src/index.tsx ADDED
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Image Entry
3
+ * 图片组件入口
4
+ */
5
+
6
+ export { Image as component } from './component'
7
+ export { default as meta } from './meta'
package/src/meta.ts ADDED
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Image Meta
3
+ * 图片组件元数据
4
+ */
5
+
6
+ import type { ComponentMetadata } from '@easy-editor/core'
7
+ import { MaterialGroup } from '@easy-editor/materials-shared'
8
+ import { COMPONENT_NAME, PACKAGE_NAME } from './constants'
9
+ import configure from './configure'
10
+ import snippets from './snippets'
11
+ import pkg from '../package.json'
12
+
13
+ export const meta: ComponentMetadata = {
14
+ componentName: COMPONENT_NAME,
15
+ title: '图片',
16
+ group: MaterialGroup.MEDIA,
17
+ devMode: 'proCode',
18
+ npm: {
19
+ package: PACKAGE_NAME,
20
+ version: pkg.version,
21
+ globalName: COMPONENT_NAME,
22
+ componentName: COMPONENT_NAME,
23
+ },
24
+ snippets,
25
+ configure,
26
+ }
27
+
28
+ export default meta
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Image Snippets
3
+ * 图片组件代码片段
4
+ */
5
+
6
+ import type { Snippet } from '@easy-editor/core'
7
+ import { COMPONENT_NAME } from './constants'
8
+
9
+ export const snippets: Snippet[] = [
10
+ {
11
+ title: '普通图片',
12
+ screenshot: '',
13
+ schema: {
14
+ componentName: COMPONENT_NAME,
15
+ props: {
16
+ alt: '图片',
17
+ objectFit: 'contain',
18
+ borderRadius: 0,
19
+ },
20
+ $dashboard: {
21
+ rect: {
22
+ width: 200,
23
+ height: 180,
24
+ },
25
+ },
26
+ },
27
+ },
28
+ {
29
+ title: '圆角图片',
30
+ screenshot: '',
31
+ schema: {
32
+ componentName: COMPONENT_NAME,
33
+ props: {
34
+ alt: '圆角图片',
35
+ objectFit: 'contain',
36
+ borderRadius: 100,
37
+ borderStyle: 'tech',
38
+ },
39
+ $dashboard: {
40
+ rect: {
41
+ width: 200,
42
+ height: 200,
43
+ },
44
+ },
45
+ },
46
+ },
47
+ ]
48
+
49
+ export default snippets
package/src/type.d.ts ADDED
@@ -0,0 +1,13 @@
1
+ /**
2
+ * CSS Modules Type Declarations
3
+ */
4
+
5
+ declare module '*.module.css' {
6
+ const classes: { readonly [key: string]: string }
7
+ export default classes
8
+ }
9
+
10
+ declare module '*.png' {
11
+ const classes: string
12
+ export default classes
13
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "extends": "../../../../tsconfig.json",
3
+ "compilerOptions": {
4
+ "jsx": "react-jsx",
5
+ "strictPropertyInitialization": false,
6
+ "outDir": "./dist",
7
+ "skipLibCheck": true,
8
+ "esModuleInterop": true,
9
+ "allowSyntheticDefaultImports": true
10
+ },
11
+ "include": ["./src"]
12
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,9 @@
1
+ {
2
+ "compilerOptions": {
3
+ "jsx": "react-jsx",
4
+ "esModuleInterop": true,
5
+ "allowSyntheticDefaultImports": true
6
+ },
7
+ "extends": "./tsconfig.build.json",
8
+ "include": ["./src", "./test"]
9
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "extends": "./tsconfig.build.json",
3
+ "compilerOptions": {
4
+ "noEmit": true
5
+ },
6
+ "include": ["./src"]
7
+ }
package/vite.config.ts ADDED
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Vite Configuration for Material Development
3
+ * 物料开发 Vite 配置
4
+ */
5
+
6
+ import { defineConfig } from 'vite'
7
+ import react from '@vitejs/plugin-react'
8
+ import { materialDevPlugin } from './.vite/plugins/vite-plugin-material-dev'
9
+ import { externalDeps } from './.vite/plugins/vite-plugin-external-deps'
10
+
11
+ export default defineConfig({
12
+ plugins: [
13
+ react(),
14
+ // 外部化 React/ReactDOM,使用父应用提供的实例
15
+ externalDeps({
16
+ externals: ['react', 'react-dom', 'react/jsx-runtime', '@easy-editor/core'],
17
+ globals: {
18
+ react: 'React',
19
+ 'react-dom': 'ReactDOM',
20
+ 'react/jsx-runtime': 'jsxRuntime',
21
+ '@easy-editor/core': 'EasyEditorCore',
22
+ },
23
+ }),
24
+ materialDevPlugin({
25
+ entry: '/src/index.tsx',
26
+ }),
27
+ ],
28
+ server: {
29
+ port: 5001,
30
+ host: 'localhost',
31
+ cors: true,
32
+ hmr: {
33
+ port: 5001,
34
+ },
35
+ },
36
+ build: {
37
+ target: 'esnext',
38
+ rollupOptions: {
39
+ // 确保生产构建也外部化这些依赖
40
+ external: ['react', 'react-dom', 'react/jsx-runtime', '@easy-editor/core'],
41
+ output: {
42
+ globals: {
43
+ react: 'React',
44
+ 'react-dom': 'ReactDOM',
45
+ 'react/jsx-runtime': 'jsxRuntime',
46
+ '@easy-editor/core': 'EasyEditorCore',
47
+ },
48
+ },
49
+ },
50
+ },
51
+ resolve: {
52
+ dedupe: ['react', 'react-dom'],
53
+ },
54
+ })