@scx-js/scx-ui 0.0.1

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.
@@ -0,0 +1,28 @@
1
+ <template>
2
+ <transition :name="'scx-panel-t_'+transitionType">
3
+ <div v-show="modelValue" class="scx-panel">
4
+ <slot/>
5
+ </div>
6
+ </transition>
7
+ </template>
8
+
9
+ <script>
10
+ import "./index.css";
11
+
12
+ export default {
13
+ name: "scx-panel",
14
+ props: {
15
+ modelValue: {
16
+ type: Boolean,
17
+ default: false
18
+ },
19
+ transitionType: {
20
+ type: String,
21
+ default: "left-top"
22
+ }
23
+ },
24
+ setup(props, context) {
25
+
26
+ }
27
+ };
28
+ </script>
@@ -0,0 +1,36 @@
1
+ .scx-panel-item {
2
+ flex-shrink: 0;
3
+ height: 40px;
4
+ display: flex;
5
+ border-radius: 2px;
6
+ align-items: center;
7
+ cursor: pointer;
8
+ border: 2px solid var(--scx-panel-item_border-color);
9
+ box-sizing: border-box;
10
+ padding-left: 5px;
11
+ padding-right: 5px;
12
+ transition: all ease 100ms;
13
+ background: var(--scx-panel-item_bg);
14
+ }
15
+
16
+ .scx-panel-item:hover,
17
+ .scx-panel-item.active {
18
+ background: var(--scx-panel-item_hover-bg);
19
+ border: 2px solid var(--scx-panel-item_hover-border-color);
20
+ color: var(--scx-panel-item_hover-color);
21
+ }
22
+
23
+ .scx-panel-item > svg {
24
+ flex-shrink: 0;
25
+ margin-left: 10px;
26
+ margin-right: 10px;
27
+ fill: currentColor;
28
+ }
29
+
30
+ .scx-panel-item > span {
31
+ font-weight: 600;
32
+ padding-right: 5px;
33
+ white-space: nowrap;
34
+ overflow: hidden;
35
+ text-overflow: ellipsis;
36
+ }
@@ -0,0 +1,22 @@
1
+ <template>
2
+ <div :class="{active}" class="scx-panel-item">
3
+ <slot/>
4
+ </div>
5
+ </template>
6
+
7
+ <script>
8
+ import "./scx-panel-item.css";
9
+
10
+ export default {
11
+ name: "scx-panel-item",
12
+ props: {
13
+ active: {
14
+ type: Boolean,
15
+ default: false
16
+ }
17
+ },
18
+ setup() {
19
+
20
+ }
21
+ };
22
+ </script>
@@ -0,0 +1,33 @@
1
+ .scx-progress {
2
+ display: flex;
3
+ height: 1rem;
4
+ overflow: hidden;
5
+ font-size: .75rem;
6
+ background-color: #c0c0c0;
7
+ border-radius: .25rem;
8
+ }
9
+
10
+ .scx-progress-bar {
11
+ display: flex;
12
+ flex-direction: column;
13
+ justify-content: center;
14
+ color: #fff;
15
+ text-align: right;
16
+ white-space: nowrap;
17
+ background-color: #0d6efd;
18
+ transition: width .6s ease;
19
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
20
+ background-size: 1rem 1rem;
21
+ animation: 1s linear infinite scx-progress-bar-stripes;
22
+ }
23
+
24
+ .scx-progress-bar-text {
25
+ font-weight: 600;
26
+ margin: 0 5px;
27
+ }
28
+
29
+ @keyframes scx-progress-bar-stripes {
30
+ 0% {
31
+ background-position-x: 1rem;
32
+ }
33
+ }
@@ -0,0 +1,29 @@
1
+ <template>
2
+ <div class="scx-progress">
3
+ <div :style="{width: modelValue+'%',backgroundColor:color}" class="scx-progress-bar">
4
+ <div class="scx-progress-bar-text">{{ modelValue }} %</div>
5
+ </div>
6
+ </div>
7
+ </template>
8
+
9
+ <script>
10
+ import "./index.css";
11
+
12
+ export default {
13
+ name: "scx-progress",
14
+ props: {
15
+ modelValue: {
16
+ type: Number,
17
+ default: 0
18
+ },
19
+ color: {
20
+ type: String,
21
+ default: ""
22
+ }
23
+ }
24
+ };
25
+ </script>
26
+
27
+ <style scoped>
28
+
29
+ </style>
@@ -0,0 +1,109 @@
1
+ .scx-switch + .scx-switch {
2
+ margin: 2px;
3
+ }
4
+
5
+ .scx-switch {
6
+ height: 22px;
7
+ width: 44px;
8
+ border: none;
9
+ background: rgba(0, 0, 0, .25);
10
+ border-radius: 11px;
11
+ position: relative;
12
+ vertical-align: middle;
13
+ transition: background-color 150ms, box-shadow 150ms;
14
+ cursor: pointer;
15
+ padding: 0;
16
+ }
17
+
18
+ .scx-switch:hover {
19
+ box-shadow: 0 0 0 0.1rem var(--scx-text-placeholder-color);
20
+ }
21
+
22
+ .scx-switch > .scx-switch-icon {
23
+ box-shadow: rgba(0, 35, 11, 0.2) 0 2px 4px 0;
24
+ position: absolute;
25
+ top: 2px;
26
+ left: 2px;
27
+ height: 18px;
28
+ width: 18px;
29
+ background: white;
30
+ border-radius: 9px;
31
+ transition: left 150ms ease-in-out, width 200ms ease-in-out, margin-left 200ms ease-in-out;
32
+ display: flex;
33
+ justify-content: center;
34
+ align-items: center;
35
+ z-index: 1;
36
+ }
37
+
38
+ .scx-switch.scx-switch-checked {
39
+ background: var(--scx-theme);
40
+ }
41
+
42
+ .scx-switch.scx-switch-checked > .scx-switch-icon {
43
+ left: calc(100% - 18px - 2px);
44
+ }
45
+
46
+ .scx-switch.scx-switch-checked:active > .scx-switch-icon {
47
+ width: 22px;
48
+ margin-left: -4px;
49
+ }
50
+
51
+ .scx-switch:active > .scx-switch-icon {
52
+ width: 22px;
53
+ margin-left: 0;
54
+ }
55
+
56
+ .scx-switch > .scx-switch-label {
57
+ position: absolute;
58
+ top: 2px;
59
+ display: flex;
60
+ align-items: center;
61
+ right: 8px;
62
+ }
63
+
64
+ .scx-switch.scx-switch-checked > .scx-switch-label {
65
+ left: 8px;
66
+ }
67
+
68
+ .scx-switch:focus {
69
+ outline: none;
70
+ }
71
+
72
+ .scx-switch[disabled] {
73
+ cursor: not-allowed;
74
+ opacity: 0.4;
75
+ }
76
+
77
+ .scx-switch.scx-switch-checked:active {
78
+ animation: scx-switch-close-tips 1500ms infinite linear;
79
+ }
80
+
81
+ .scx-switch:active {
82
+ animation: scx-switch-open-tips 1500ms infinite linear;
83
+ }
84
+
85
+ @keyframes scx-switch-close-tips {
86
+ 0% {
87
+ box-shadow: 0 0 0 0.1rem rgba(99, 172, 255, 0.5);
88
+ }
89
+ 50% {
90
+
91
+ box-shadow: 0 0 0 0.2rem rgba(255, 38, 103, 0.5)
92
+ }
93
+ 100% {
94
+ box-shadow: 0 0 0 0.1rem rgba(99, 172, 255, 0.5);
95
+ }
96
+ }
97
+
98
+ @keyframes scx-switch-open-tips {
99
+ 0% {
100
+ box-shadow: 0 0 0 0.1rem rgba(99, 172, 255, 0.5);
101
+ }
102
+ 50% {
103
+
104
+ box-shadow: 0 0 0 0.2rem rgba(17, 141, 47, 0.5);
105
+ }
106
+ 100% {
107
+ box-shadow: 0 0 0 0.1rem rgba(99, 172, 255, 0.5);
108
+ }
109
+ }
@@ -0,0 +1,31 @@
1
+ <template>
2
+ <button :class="{'scx-switch-checked': modelValue}" class="scx-switch" type="button" @click="changeSwitchState">
3
+ <span class="scx-switch-icon">
4
+ <slot name="icon"/>
5
+ </span>
6
+ <span class="scx-switch-label">
7
+ <slot name="label"/>
8
+ </span>
9
+ </button>
10
+ </template>
11
+ <script>
12
+ import "./index.css";
13
+
14
+ export default {
15
+ name: "scx-switch",
16
+ props: {
17
+ modelValue: Boolean,
18
+ default: false
19
+ },
20
+ emits: ["update:modelValue", "change"],
21
+ setup(props, context) {
22
+ function changeSwitchState() {
23
+ const val = !props.modelValue;
24
+ context.emit("update:modelValue", val);
25
+ context.emit("change", val);
26
+ }
27
+
28
+ return {changeSwitchState};
29
+ }
30
+ };
31
+ </script>
@@ -0,0 +1,177 @@
1
+ class UploadInfo {
2
+
3
+ /**
4
+ * a
5
+ * @type {string}
6
+ */
7
+ fileName = "";
8
+
9
+ /**
10
+ * a
11
+ * @type {string}
12
+ */
13
+ previewURL = null;
14
+
15
+ /**
16
+ *
17
+ * @type {string}
18
+ */
19
+ downloadURL = null;
20
+
21
+ /**
22
+ *
23
+ * @type {number}
24
+ */
25
+ progressValue = 0;
26
+
27
+ /**
28
+ * a
29
+ * @type {string}
30
+ */
31
+ progressState = "";
32
+
33
+ /**
34
+ * a
35
+ * @type {boolean}
36
+ */
37
+ progressVisible = false;
38
+
39
+ /**
40
+ *
41
+ * @type {File}
42
+ */
43
+ file = null;
44
+
45
+ /**
46
+ * a
47
+ * @type {string}
48
+ */
49
+ fileID = "";
50
+
51
+ /**
52
+ * 上传时间
53
+ * @type {null}
54
+ */
55
+ uploadTime = null;
56
+
57
+ /**
58
+ * 文件大小
59
+ * @type {null}
60
+ */
61
+ fileSizeDisplay = null;
62
+
63
+ /**
64
+ * 文件实际大小
65
+ * @type {null}
66
+ */
67
+ fileSize = null;
68
+
69
+ /**
70
+ * 文件 fssObjectID
71
+ * @type {null}
72
+ */
73
+ fssObjectID = null;
74
+
75
+ reset() {
76
+ this.fileName = null;
77
+ this.previewURL = null;
78
+ this.downloadURL = null;
79
+ this.uploadTime = null;
80
+ this.fileSizeDisplay = null;
81
+ this.fileSize = null;
82
+ this.fssObjectID = null;
83
+ return this;
84
+ }
85
+
86
+ fill(rawOptions) {
87
+ const {
88
+ fileName,
89
+ previewURL,
90
+ downloadURL,
91
+ uploadTime,
92
+ fileSizeDisplay,
93
+ fileSize,
94
+ fssObjectID,
95
+ } = rawOptions;
96
+ this.fileName = fileName;
97
+ this.previewURL = previewURL;
98
+ this.downloadURL = downloadURL;
99
+ this.uploadTime = uploadTime;
100
+ this.fileSizeDisplay = fileSizeDisplay;
101
+ this.fileSize = fileSize;
102
+ this.fssObjectID = fssObjectID;
103
+ return this;
104
+ }
105
+
106
+ copy() {
107
+ return new UploadInfo().fill(this);
108
+ }
109
+
110
+ }
111
+
112
+ class ScxFSSHelper {
113
+
114
+ /**
115
+ * @type ScxFSS
116
+ */
117
+ scxFSS;
118
+
119
+ constructor(scxFSS) {
120
+ this.scxFSS = scxFSS;
121
+ }
122
+
123
+ /**
124
+ * 默认的 scx-fss 的 fileInfoHandler
125
+ *
126
+ * @param fileID
127
+ * @returns {Promise<{fileName: string}|{[p: string]: *}>}
128
+ */
129
+ fileInfoHandler(fileID) {
130
+ const previewURL = this.scxFSS.joinImageURL(fileID, {
131
+ w: 150,
132
+ h: 150,
133
+ });
134
+ const downloadURL = this.scxFSS.joinDownloadURL(fileID);
135
+ return new Promise((resolve, reject) => {
136
+ this.scxFSS.info(fileID).then(item => {
137
+ if (item) {
138
+ resolve({
139
+ ...item,
140
+ previewURL,
141
+ downloadURL,
142
+ });
143
+ } else {
144
+ resolve({fileName: "文件无法读取 !!! id : " + fileID});
145
+ }
146
+ }).catch(e => reject(e));
147
+ });
148
+ }
149
+
150
+ /**
151
+ * 默认的 scx-fss 的上传 handler
152
+ * @param needUploadFile
153
+ * @param progress
154
+ * @returns {Promise<unknown>}
155
+ */
156
+ uploadHandler(needUploadFile, progress) {
157
+ const onProgress = (state, value) => {
158
+ // todo 这里没有使用 ScxFSS.CHECKING() 而是直接引入字符串的原因
159
+ // todo 请参照 https://github.com/vitejs/vite/issues/7775
160
+ //前 50% 是校验 md5 后 50% 才是真正的文件上传
161
+ if (state === "checking") {
162
+ progress(value * 0.5, "校验中");
163
+ } else if (state === "uploading") {
164
+ progress(50 + value * 0.5, "上传中");
165
+ }
166
+ };
167
+ return new Promise((resolve, reject) => {
168
+ this.scxFSS.upload(needUploadFile, onProgress).then(d => {
169
+ resolve(d.item.fssObjectID);
170
+ }).catch(e => reject(e));
171
+ });
172
+ }
173
+
174
+ }
175
+
176
+ export {UploadInfo, ScxFSSHelper};
177
+
@@ -0,0 +1,204 @@
1
+ /* 主区域 */
2
+ .scx-upload {
3
+ background: var(--scx-overlay-bg);
4
+ border: 3px dashed var(--scx-text-placeholder-color);
5
+ border-radius: 6px;
6
+ position: relative;
7
+ overflow: hidden;
8
+ width: 150px;
9
+ height: 150px;
10
+ transition: border 200ms;
11
+ }
12
+
13
+ /* border 变化 */
14
+ .scx-upload:hover {
15
+ border-color: var(--scx-theme);
16
+ }
17
+
18
+ /* 预览区域 */
19
+ .scx-upload > .preview {
20
+ height: 100%;
21
+ width: 100%;
22
+ display: flex;
23
+ justify-content: center;
24
+ align-items: center;
25
+ }
26
+
27
+ /* 预览图片 */
28
+ .scx-upload .preview-image {
29
+ min-height: 50%;
30
+ min-width: 50%;
31
+ height: 100%;
32
+ width: 100%;
33
+ }
34
+
35
+ /* 预览文字 */
36
+ .scx-upload .preview-text {
37
+ font-size: 15px;
38
+ width: 100%;
39
+ height: 100%;
40
+ display: flex;
41
+ overflow: auto;
42
+ }
43
+
44
+ .scx-upload .preview-text > div {
45
+ /**
46
+ 这里并没有在 .scx-upload .preview-text 中使用
47
+ justify-content: center;
48
+ align-items: center;
49
+ 来进行居中 而是在子元素(也就是当前注释)中使用
50
+ margin: auto;
51
+ 请参阅
52
+ https://stackoverflow.com/questions/33454533/cant-scroll-to-top-of-flex-item-that-is-overflowing-container
53
+ */
54
+ margin: auto;
55
+ word-break: break-all;
56
+ }
57
+
58
+ /* 预览中操作 */
59
+ .scx-upload .operation {
60
+ position: absolute;
61
+ bottom: 0;
62
+ width: 100%;
63
+ height: 30px;
64
+ display: flex;
65
+ }
66
+
67
+ /*操作项子元素*/
68
+ .scx-upload .operation > div,
69
+ .scx-upload .operation > a {
70
+ display: flex;
71
+ justify-content: center;
72
+ align-items: center;
73
+ height: 100%;
74
+ flex-grow: 1;
75
+ flex-shrink: 1;
76
+ flex-basis: 0;
77
+ opacity: 50%;
78
+ transition: 200ms ease-in-out opacity;
79
+ cursor: pointer;
80
+ color: white;
81
+ font-weight: 600;
82
+ text-decoration: unset;
83
+ }
84
+
85
+ .scx-upload .operation > div:hover,
86
+ .scx-upload .operation > a:hover {
87
+ opacity: 100%;
88
+ }
89
+
90
+ .scx-upload .item-download {
91
+ background: #44be16;
92
+ }
93
+
94
+ .scx-upload .item-replace {
95
+ background: #29aaf5;
96
+ }
97
+
98
+ .scx-upload .item-delete {
99
+ background: #f44336;
100
+ }
101
+
102
+ /* 没有预览时 */
103
+ .scx-upload > .no-preview {
104
+ height: 100%;
105
+ width: 100%;
106
+ display: flex;
107
+ justify-content: center;
108
+ align-items: center;
109
+ cursor: pointer;
110
+ flex-direction: column;
111
+ row-gap: 10px;
112
+ }
113
+
114
+ /* 图标 */
115
+ .scx-upload > .no-preview > .scx-icon {
116
+ fill: var(--scx-text-placeholder-color);
117
+ height: 40px;
118
+ width: 40px;
119
+ pointer-events: none;
120
+ flex-shrink: 0;
121
+ }
122
+
123
+ /* 提示拖拽文字 */
124
+ .scx-upload > .no-preview > span {
125
+ font-weight: 600;
126
+ font-size: 20px;
127
+ color: var(--scx-text-placeholder-color);
128
+ pointer-events: none;
129
+ flex-shrink: 0;
130
+ }
131
+
132
+ /* 拖动时蓝色背景 */
133
+ .scx-upload > .no-preview.dragover::after {
134
+ content: " ";
135
+ width: 100%;
136
+ height: 100%;
137
+ background: var(--scx-theme-bg);
138
+ position: absolute;
139
+ top: 0;
140
+ left: 0;
141
+ pointer-events: none;
142
+ }
143
+
144
+ .scx-upload > .progress-preview {
145
+ position: absolute;
146
+ top: 0;
147
+ left: 0;
148
+ height: 100%;
149
+ width: 100%;
150
+ }
151
+
152
+ /* 进度条 */
153
+ .scx-upload > .progress {
154
+ height: 100%;
155
+ width: 100%;
156
+ position: absolute;
157
+ top: 0;
158
+ left: 0;
159
+ background: rgba(50, 50, 50, 40%);
160
+ backdrop-filter: blur(2px);
161
+ color: white;
162
+ display: flex;
163
+ flex-direction: column;
164
+ justify-content: space-between;
165
+ }
166
+
167
+ .scx-upload .temp-file-name {
168
+ height: 100%;
169
+ width: 100%;
170
+ display: flex;
171
+ overflow: auto;
172
+ }
173
+
174
+ .scx-upload .temp-file-name > div {
175
+ /**
176
+ 参照 44 行
177
+ */
178
+ margin: auto;
179
+ word-break: break-all;
180
+ }
181
+
182
+ .scx-upload .progress-state {
183
+ width: 100%;
184
+ display: flex;
185
+ justify-content: center;
186
+ align-items: center;
187
+ flex-direction: column;
188
+ font-weight: 600;
189
+ flex-shrink: 0;
190
+ padding: 5px;
191
+ box-sizing: border-box;
192
+ row-gap: 5px;
193
+ }
194
+
195
+ .scx-upload .progress-state > .progress-state-text {
196
+ flex-shrink: 0;
197
+ font-weight: 600;
198
+ font-size: 14px;
199
+ }
200
+
201
+ .scx-upload .progress-state > .scx-progress {
202
+ width: 100%;
203
+ }
204
+