@star-ai/star-ui 0.0.4 → 0.0.5

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.
@@ -1,10 +1,153 @@
1
1
 
2
2
  // Button 组件入口文件
3
- import StarButton from './Button.vue'
3
+ const StarButton = {
4
+ name: 'StarButton',
5
+
6
+ // 组件属性定义
7
+ props: {
8
+ // 按钮类型
9
+ type: {
10
+ type: String,
11
+ default: 'default',
12
+ validator: (value) => {
13
+ return ['default', 'primary', 'success', 'warning', 'error', 'info'].includes(value)
14
+ }
15
+ },
16
+
17
+ // 按钮大小
18
+ size: {
19
+ type: String,
20
+ default: 'medium',
21
+ validator: (value) => {
22
+ return ['mini', 'small', 'medium', 'large'].includes(value)
23
+ }
24
+ },
25
+
26
+ // 是否禁用
27
+ disabled: {
28
+ type: Boolean,
29
+ default: false
30
+ },
31
+
32
+ // 是否加载中
33
+ loading: {
34
+ type: Boolean,
35
+ default: false
36
+ },
37
+
38
+ // 是否为朴素按钮
39
+ plain: {
40
+ type: Boolean,
41
+ default: false
42
+ },
43
+
44
+ // 是否为块级按钮
45
+ block: {
46
+ type: Boolean,
47
+ default: false
48
+ },
49
+
50
+ // 左侧图标
51
+ icon: {
52
+ type: String,
53
+ default: ''
54
+ },
55
+
56
+ // 右侧图标
57
+ rightIcon: {
58
+ type: String,
59
+ default: ''
60
+ },
61
+
62
+ // 自定义样式
63
+ customStyle: {
64
+ type: Object,
65
+ default: () => ({})
66
+ },
67
+
68
+ // 点击防抖时间(毫秒)
69
+ debounce: {
70
+ type: Number,
71
+ default: 0
72
+ }
73
+ },
74
+
75
+ data() {
76
+ return {
77
+ canClick: true
78
+ }
79
+ },
80
+
81
+ methods: {
82
+ handleClick(event) {
83
+ // 防抖处理
84
+ if (!this.canClick) return
85
+
86
+ if (this.debounce > 0) {
87
+ this.canClick = false
88
+ setTimeout(() => {
89
+ this.canClick = true
90
+ }, this.debounce)
91
+ }
92
+
93
+ // 触发点击事件
94
+ if (!this.disabled && !this.loading) {
95
+ this.$emit('click', event)
96
+ }
97
+ }
98
+ }
99
+ }
100
+
101
+ // 添加模板
102
+ StarButton.template = `<view
103
+ class="star-button"
104
+ :class="[
105
+ `star-button--${type}`,
106
+ `star-button--${size}`,
107
+ {
108
+ 'star-button--disabled': disabled,
109
+ 'star-button--loading': loading,
110
+ 'star-button--block': block,
111
+ 'star-button--plain': plain
112
+ }
113
+ ]"
114
+ :style="[customStyle]"
115
+ @click="handleClick"
116
+ >
117
+ <!-- 加载状态 -->
118
+ <view v-if="loading" class="star-button__loading">
119
+ <view class="star-button__loading-spinner"></view>
120
+ </view>
121
+
122
+ <!-- 图标 -->
123
+ <text
124
+ v-if="icon && !loading"
125
+ class="star-button__icon"
126
+ :class="icon"
127
+ ></text>
128
+
129
+ <!-- 文字内容 -->
130
+ <text class="star-button__text">
131
+ <slot></slot>
132
+ </text>
133
+
134
+ <!-- 右侧图标 -->
135
+ <text
136
+ v-if="rightIcon && !loading"
137
+ class="star-button__right-icon"
138
+ :class="rightIcon"
139
+ ></text>
140
+ </view>`
4
141
 
5
142
  StarButton.install = function(Vue) {
6
143
  Vue.component(StarButton.name, StarButton)
7
144
  }
8
145
 
9
- export default StarButton
10
- export { StarButton }
146
+ // CommonJS 导出
147
+ module.exports = StarButton
148
+ module.exports.default = StarButton
149
+
150
+ // 浏览器全局变量导出
151
+ if (typeof window !== 'undefined') {
152
+ window.StarButton = StarButton
153
+ }
@@ -1,10 +1,264 @@
1
1
 
2
2
  // Input 组件入口文件
3
- import StarInput from './Input.vue'
3
+ const StarInput = {
4
+ name: 'StarInput',
5
+
6
+ props: {
7
+ // 输入框类型
8
+ type: {
9
+ type: String,
10
+ default: 'text'
11
+ },
12
+
13
+ // 绑定值
14
+ value: {
15
+ type: [String, Number],
16
+ default: ''
17
+ },
18
+
19
+ // 原生属性
20
+ placeholder: {
21
+ type: String,
22
+ default: ''
23
+ },
24
+
25
+ disabled: {
26
+ type: Boolean,
27
+ default: false
28
+ },
29
+
30
+ maxlength: {
31
+ type: [String, Number],
32
+ default: 140
33
+ },
34
+
35
+ focus: {
36
+ type: Boolean,
37
+ default: false
38
+ },
39
+
40
+ confirmType: {
41
+ type: String,
42
+ default: 'done'
43
+ },
44
+
45
+ placeholderStyle: {
46
+ type: String,
47
+ default: ''
48
+ },
49
+
50
+ placeholderClass: {
51
+ type: String,
52
+ default: ''
53
+ },
54
+
55
+ cursorSpacing: {
56
+ type: [String, Number],
57
+ default: 0
58
+ },
59
+
60
+ // 自定义属性
61
+ size: {
62
+ type: String,
63
+ default: 'medium',
64
+ validator: (value) => ['mini', 'small', 'medium', 'large'].includes(value)
65
+ },
66
+
67
+ clearable: {
68
+ type: Boolean,
69
+ default: false
70
+ },
71
+
72
+ showPassword: {
73
+ type: Boolean,
74
+ default: false
75
+ },
76
+
77
+ prefixIcon: {
78
+ type: String,
79
+ default: ''
80
+ },
81
+
82
+ suffixIcon: {
83
+ type: String,
84
+ default: ''
85
+ },
86
+
87
+ prepend: {
88
+ type: String,
89
+ default: ''
90
+ },
91
+
92
+ append: {
93
+ type: String,
94
+ default: ''
95
+ },
96
+
97
+ readonly: {
98
+ type: Boolean,
99
+ default: false
100
+ }
101
+ },
102
+
103
+ data() {
104
+ return {
105
+ currentValue: this.value,
106
+ isFocused: false,
107
+ passwordVisible: false
108
+ }
109
+ },
110
+
111
+ computed: {
112
+ inputClasses() {
113
+ return [
114
+ `star-input--${this.size}`,
115
+ {
116
+ 'star-input--disabled': this.disabled,
117
+ 'star-input--focused': this.isFocused,
118
+ 'star-input--with-prepend': this.prepend || this.$slots.prepend,
119
+ 'star-input--with-append': this.append || this.$slots.append,
120
+ 'star-input--readonly': this.readonly
121
+ }
122
+ ]
123
+ }
124
+ },
125
+
126
+ watch: {
127
+ value(newVal) {
128
+ this.currentValue = newVal
129
+ }
130
+ },
131
+
132
+ methods: {
133
+ handleInput(event) {
134
+ const value = event.detail.value
135
+ this.currentValue = value
136
+ this.$emit('input', value)
137
+ this.$emit('change', value)
138
+ },
139
+
140
+ handleFocus(event) {
141
+ this.isFocused = true
142
+ this.$emit('focus', event)
143
+ },
144
+
145
+ handleBlur(event) {
146
+ this.isFocused = false
147
+ this.$emit('blur', event)
148
+ },
149
+
150
+ handleConfirm(event) {
151
+ this.$emit('confirm', event)
152
+ },
153
+
154
+ handleKeyboardHeightChange(event) {
155
+ this.$emit('keyboardheightchange', event)
156
+ },
157
+
158
+ handleClear() {
159
+ this.currentValue = ''
160
+ this.$emit('input', '')
161
+ this.$emit('change', '')
162
+ this.$emit('clear')
163
+ },
164
+
165
+ togglePasswordVisible() {
166
+ this.passwordVisible = !this.passwordVisible
167
+ },
168
+
169
+ handlePrefixIconClick() {
170
+ this.$emit('click-prefix')
171
+ },
172
+
173
+ handleSuffixIconClick() {
174
+ this.$emit('click-suffix')
175
+ }
176
+ }
177
+ }
178
+
179
+ // 添加模板
180
+ StarInput.template = `<view class="star-input" :class="inputClasses">
181
+ <!-- 前置内容 -->
182
+ <view v-if="$slots.prepend || prepend" class="star-input__prepend">
183
+ <slot name="prepend">
184
+ <text v-if="prepend" class="star-input__prepend-text">{{ prepend }}</text>
185
+ </slot>
186
+ </view>
187
+
188
+ <!-- 输入框主体 -->
189
+ <view class="star-input__wrapper">
190
+ <!-- 前置图标 -->
191
+ <text
192
+ v-if="prefixIcon"
193
+ class="star-input__prefix-icon"
194
+ :class="prefixIcon"
195
+ @click="handlePrefixIconClick"
196
+ ></text>
197
+
198
+ <!-- 输入框 -->
199
+ <input
200
+ class="star-input__inner"
201
+ :type="showPassword ? (passwordVisible ? 'text' : 'password') : type"
202
+ :value="currentValue"
203
+ :placeholder="placeholder"
204
+ :disabled="disabled"
205
+ :maxlength="maxlength"
206
+ :focus="focus"
207
+ :confirm-type="confirmType"
208
+ :placeholder-style="placeholderStyle"
209
+ :placeholder-class="placeholderClass"
210
+ :cursor-spacing="cursorSpacing"
211
+ @input="handleInput"
212
+ @focus="handleFocus"
213
+ @blur="handleBlur"
214
+ @confirm="handleConfirm"
215
+ @keyboardheightchange="handleKeyboardHeightChange"
216
+ />
217
+
218
+ <!-- 清除按钮 -->
219
+ <view
220
+ v-if="clearable && currentValue && !disabled"
221
+ class="star-input__clear"
222
+ @click="handleClear"
223
+ >
224
+ <text class="star-icon-close"></text>
225
+ </view>
226
+
227
+ <!-- 密码可见切换按钮 -->
228
+ <view
229
+ v-if="showPassword && currentValue"
230
+ class="star-input__password-toggle"
231
+ @click="togglePasswordVisible"
232
+ >
233
+ <text :class="passwordVisible ? 'star-icon-eye-open' : 'star-icon-eye-close'"></text>
234
+ </view>
235
+
236
+ <!-- 后置图标 -->
237
+ <text
238
+ v-if="suffixIcon"
239
+ class="star-input__suffix-icon"
240
+ :class="suffixIcon"
241
+ @click="handleSuffixIconClick"
242
+ ></text>
243
+ </view>
244
+
245
+ <!-- 后置内容 -->
246
+ <view v-if="$slots.append || append" class="star-input__append">
247
+ <slot name="append">
248
+ <text v-if="append" class="star-input__append-text">{{ append }}</text>
249
+ </slot>
250
+ </view>
251
+ </view>`
4
252
 
5
253
  StarInput.install = function(Vue) {
6
254
  Vue.component(StarInput.name, StarInput)
7
255
  }
8
256
 
9
- export default StarInput
10
- export { StarInput }
257
+ // CommonJS 导出
258
+ module.exports = StarInput
259
+ module.exports.default = StarInput
260
+
261
+ // 浏览器全局变量导出
262
+ if (typeof window !== 'undefined') {
263
+ window.StarInput = StarInput
264
+ }
package/lib/index.js CHANGED
@@ -1,10 +1,9 @@
1
-
2
1
  // star-ui 组件库主入口文件
3
- import packageJson from '../package.json'
2
+ const packageJson = require('../package.json')
4
3
 
5
4
  // 导入所有组件
6
- import StarButton from './components/Button/index.js'
7
- import StarInput from './components/Input/index.js'
5
+ const StarButton = require('./components/Button/index.js').default
6
+ const StarInput = require('./components/Input/index.js').default
8
7
 
9
8
  // 组件列表
10
9
  const components = [
@@ -46,25 +45,18 @@ const StarUI = {
46
45
  StarInput
47
46
  }
48
47
 
49
- // 导出模块
50
- if (typeof module !== 'undefined' && module.exports) {
51
- // CommonJS 导出
52
- module.exports = StarUI
53
- module.exports.default = StarUI
54
- // 为每个组件添加单独的导出(支持按需导入)
55
- components.forEach(component => {
56
- if (component.name) {
57
- module.exports[component.name] = component
58
- }
59
- })
60
- } else if (typeof define === 'function' && define.amd) {
61
- // AMD 导出
62
- define(() => StarUI)
63
- } else if (typeof window !== 'undefined') {
64
- // 浏览器全局变量导出
65
- window.StarUI = StarUI
66
- }
48
+ // CommonJS 导出
49
+ module.exports = StarUI
50
+ module.exports.default = StarUI
51
+
52
+ // 为每个组件添加单独的导出(支持按需导入)
53
+ components.forEach(component => {
54
+ if (component.name) {
55
+ module.exports[component.name] = component
56
+ }
57
+ })
67
58
 
68
- // ES模块导出
69
- export default StarUI
70
- export { StarButton, StarInput }
59
+ // 浏览器全局变量导出
60
+ if (typeof window !== 'undefined') {
61
+ window.StarUI = StarUI
62
+ }
package/lib/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@star-ai/star-ui",
3
- "version": "0.0.3",
3
+ "version": "0.0.4",
4
4
  "description": "基于Uniapp的Vue2组件库",
5
5
  "main": "index.js",
6
6
  "files": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@star-ai/star-ui",
3
- "version": "0.0.4",
3
+ "version": "0.0.5",
4
4
  "description": "基于Uniapp的Vue2组件库",
5
5
  "main": "lib/index.js",
6
6
  "module": "lib/index.js",
@@ -1,325 +0,0 @@
1
- <template>
2
- <view
3
- class="star-button"
4
- :class="[
5
- `star-button--${type}`,
6
- `star-button--${size}`,
7
- {
8
- 'star-button--disabled': disabled,
9
- 'star-button--loading': loading,
10
- 'star-button--block': block,
11
- 'star-button--plain': plain
12
- }
13
- ]"
14
- :style="[customStyle]"
15
- @click="handleClick"
16
- >
17
- <!-- 加载状态 -->
18
- <view v-if="loading" class="star-button__loading">
19
- <view class="star-button__loading-spinner"></view>
20
- </view>
21
-
22
- <!-- 图标 -->
23
- <text
24
- v-if="icon && !loading"
25
- class="star-button__icon"
26
- :class="icon"
27
- ></text>
28
-
29
- <!-- 文字内容 -->
30
- <text class="star-button__text">
31
- <slot></slot>
32
- </text>
33
-
34
- <!-- 右侧图标 -->
35
- <text
36
- v-if="rightIcon && !loading"
37
- class="star-button__right-icon"
38
- :class="rightIcon"
39
- ></text>
40
- </view>
41
- </template>
42
-
43
- <script>
44
- export default {
45
- name: 'StarButton',
46
-
47
- // 组件属性定义
48
- props: {
49
- // 按钮类型
50
- type: {
51
- type: String,
52
- default: 'default',
53
- validator: (value) => {
54
- return ['default', 'primary', 'success', 'warning', 'error', 'info'].includes(value)
55
- }
56
- },
57
-
58
- // 按钮大小
59
- size: {
60
- type: String,
61
- default: 'medium',
62
- validator: (value) => {
63
- return ['mini', 'small', 'medium', 'large'].includes(value)
64
- }
65
- },
66
-
67
- // 是否禁用
68
- disabled: {
69
- type: Boolean,
70
- default: false
71
- },
72
-
73
- // 是否加载中
74
- loading: {
75
- type: Boolean,
76
- default: false
77
- },
78
-
79
- // 是否为朴素按钮
80
- plain: {
81
- type: Boolean,
82
- default: false
83
- },
84
-
85
- // 是否为块级按钮
86
- block: {
87
- type: Boolean,
88
- default: false
89
- },
90
-
91
- // 左侧图标
92
- icon: {
93
- type: String,
94
- default: ''
95
- },
96
-
97
- // 右侧图标
98
- rightIcon: {
99
- type: String,
100
- default: ''
101
- },
102
-
103
- // 自定义样式
104
- customStyle: {
105
- type: Object,
106
- default: () => ({})
107
- },
108
-
109
- // 点击防抖时间(毫秒)
110
- debounce: {
111
- type: Number,
112
- default: 0
113
- }
114
- },
115
-
116
- data() {
117
- return {
118
- canClick: true
119
- }
120
- },
121
-
122
- methods: {
123
- handleClick(event) {
124
- // 防抖处理
125
- if (!this.canClick) return
126
-
127
- if (this.debounce > 0) {
128
- this.canClick = false
129
- setTimeout(() => {
130
- this.canClick = true
131
- }, this.debounce)
132
- }
133
-
134
- // 触发点击事件
135
- if (!this.disabled && !this.loading) {
136
- this.$emit('click', event)
137
- }
138
- }
139
- }
140
- }
141
- </script>
142
-
143
- <style lang="scss" scoped>
144
- // 引入样式变量
145
- @import "../../styles/variables.scss";
146
-
147
- .star-button {
148
- display: inline-flex;
149
- align-items: center;
150
- justify-content: center;
151
- position: relative;
152
- box-sizing: border-box;
153
- padding: 0 16px;
154
- height: 44px;
155
- line-height: 44px;
156
- border-radius: $border-radius-base;
157
- font-size: $font-size-base;
158
- font-weight: 500;
159
- text-align: center;
160
- vertical-align: middle;
161
- transition: all 0.3s;
162
- cursor: pointer;
163
- user-select: none;
164
-
165
- // 块级按钮
166
- &--block {
167
- display: flex;
168
- width: 100%;
169
- }
170
-
171
- // 禁用状态
172
- &--disabled {
173
- opacity: 0.6;
174
- cursor: not-allowed;
175
- }
176
-
177
- // 大小
178
- &--mini {
179
- padding: 0 8px;
180
- height: 24px;
181
- line-height: 24px;
182
- font-size: $font-size-sm;
183
- border-radius: $border-radius-sm;
184
- }
185
-
186
- &--small {
187
- padding: 0 12px;
188
- height: 32px;
189
- line-height: 32px;
190
- font-size: $font-size-sm;
191
- border-radius: $border-radius-sm;
192
- }
193
-
194
- &--large {
195
- padding: 0 20px;
196
- height: 48px;
197
- line-height: 48px;
198
- font-size: $font-size-lg;
199
- border-radius: $border-radius-lg;
200
- }
201
-
202
- // 类型 - 默认
203
- &--default {
204
- color: $text-color;
205
- background-color: $bg-color;
206
- border: 1px solid $border-color;
207
-
208
- &:not(.star-button--disabled):not(.star-button--loading):active {
209
- background-color: darken($bg-color, 5%);
210
- }
211
- }
212
-
213
- // 类型 - 主要
214
- &--primary {
215
- color: $white;
216
- background-color: $primary-color;
217
- border: 1px solid $primary-color;
218
-
219
- &.star-button--plain {
220
- color: $primary-color;
221
- background-color: transparent;
222
- }
223
-
224
- &:not(.star-button--disabled):not(.star-button--loading):active {
225
- background-color: darken($primary-color, 10%);
226
- border-color: darken($primary-color, 10%);
227
- }
228
- }
229
-
230
- // 类型 - 成功
231
- &--success {
232
- color: $white;
233
- background-color: $success-color;
234
- border: 1px solid $success-color;
235
-
236
- &.star-button--plain {
237
- color: $success-color;
238
- background-color: transparent;
239
- }
240
- }
241
-
242
- // 类型 - 警告
243
- &--warning {
244
- color: $white;
245
- background-color: $warning-color;
246
- border: 1px solid $warning-color;
247
-
248
- &.star-button--plain {
249
- color: $warning-color;
250
- background-color: transparent;
251
- }
252
- }
253
-
254
- // 类型 - 错误
255
- &--error {
256
- color: $white;
257
- background-color: $error-color;
258
- border: 1px solid $error-color;
259
-
260
- &.star-button--plain {
261
- color: $error-color;
262
- background-color: transparent;
263
- }
264
- }
265
-
266
- // 类型 - 信息
267
- &--info {
268
- color: $white;
269
- background-color: $info-color;
270
- border: 1px solid $info-color;
271
-
272
- &.star-button--plain {
273
- color: $info-color;
274
- background-color: transparent;
275
- }
276
- }
277
-
278
- // 加载中
279
- &--loading {
280
- cursor: not-allowed;
281
- }
282
-
283
- // 图标
284
- &__icon,
285
- &__right-icon {
286
- font-family: "star-icon-font" !important; // 使用你自己的图标字体
287
- margin-right: 4px;
288
- font-size: inherit;
289
- }
290
-
291
- &__right-icon {
292
- margin-right: 0;
293
- margin-left: 4px;
294
- }
295
-
296
- &__text {
297
- display: inline-block;
298
- vertical-align: middle;
299
- }
300
-
301
- // 加载动画
302
- &__loading {
303
- margin-right: 4px;
304
- }
305
-
306
- &__loading-spinner {
307
- display: inline-block;
308
- width: 14px;
309
- height: 14px;
310
- border: 2px solid;
311
- border-color: currentColor transparent transparent transparent;
312
- border-radius: 50%;
313
- animation: star-button-spin 1s linear infinite;
314
- }
315
- }
316
-
317
- @keyframes star-button-spin {
318
- 0% {
319
- transform: rotate(0deg);
320
- }
321
- 100% {
322
- transform: rotate(360deg);
323
- }
324
- }
325
- </style>
@@ -1,404 +0,0 @@
1
- <template>
2
- <view class="star-input" :class="inputClasses">
3
- <!-- 前置内容 -->
4
- <view v-if="$slots.prepend || prepend" class="star-input__prepend">
5
- <slot name="prepend">
6
- <text v-if="prepend" class="star-input__prepend-text">{{ prepend }}</text>
7
- </slot>
8
- </view>
9
-
10
- <!-- 输入框主体 -->
11
- <view class="star-input__wrapper">
12
- <!-- 前置图标 -->
13
- <text
14
- v-if="prefixIcon"
15
- class="star-input__prefix-icon"
16
- :class="prefixIcon"
17
- @click="handlePrefixIconClick"
18
- ></text>
19
-
20
- <!-- 输入框 -->
21
- <input
22
- class="star-input__inner"
23
- :type="showPassword ? (passwordVisible ? 'text' : 'password') : type"
24
- :value="currentValue"
25
- :placeholder="placeholder"
26
- :disabled="disabled"
27
- :maxlength="maxlength"
28
- :focus="focus"
29
- :confirm-type="confirmType"
30
- :placeholder-style="placeholderStyle"
31
- :placeholder-class="placeholderClass"
32
- :cursor-spacing="cursorSpacing"
33
- @input="handleInput"
34
- @focus="handleFocus"
35
- @blur="handleBlur"
36
- @confirm="handleConfirm"
37
- @keyboardheightchange="handleKeyboardHeightChange"
38
- />
39
-
40
- <!-- 清除按钮 -->
41
- <view
42
- v-if="clearable && currentValue && !disabled"
43
- class="star-input__clear"
44
- @click="handleClear"
45
- >
46
- <text class="star-icon-close"></text>
47
- </view>
48
-
49
- <!-- 密码可见切换按钮 -->
50
- <view
51
- v-if="showPassword && currentValue"
52
- class="star-input__password-toggle"
53
- @click="togglePasswordVisible"
54
- >
55
- <text :class="passwordVisible ? 'star-icon-eye-open' : 'star-icon-eye-close'"></text>
56
- </view>
57
-
58
- <!-- 后置图标 -->
59
- <text
60
- v-if="suffixIcon"
61
- class="star-input__suffix-icon"
62
- :class="suffixIcon"
63
- @click="handleSuffixIconClick"
64
- ></text>
65
- </view>
66
-
67
- <!-- 后置内容 -->
68
- <view v-if="$slots.append || append" class="star-input__append">
69
- <slot name="append">
70
- <text v-if="append" class="star-input__append-text">{{ append }}</text>
71
- </slot>
72
- </view>
73
- </view>
74
- </template>
75
-
76
- <script>
77
- export default {
78
- name: 'StarInput',
79
-
80
- props: {
81
- // 输入框类型
82
- type: {
83
- type: String,
84
- default: 'text'
85
- },
86
-
87
- // 绑定值
88
- value: {
89
- type: [String, Number],
90
- default: ''
91
- },
92
-
93
- // 原生属性
94
- placeholder: {
95
- type: String,
96
- default: ''
97
- },
98
-
99
- disabled: {
100
- type: Boolean,
101
- default: false
102
- },
103
-
104
- maxlength: {
105
- type: [String, Number],
106
- default: 140
107
- },
108
-
109
- focus: {
110
- type: Boolean,
111
- default: false
112
- },
113
-
114
- confirmType: {
115
- type: String,
116
- default: 'done'
117
- },
118
-
119
- placeholderStyle: {
120
- type: String,
121
- default: ''
122
- },
123
-
124
- placeholderClass: {
125
- type: String,
126
- default: ''
127
- },
128
-
129
- cursorSpacing: {
130
- type: [String, Number],
131
- default: 0
132
- },
133
-
134
- // 自定义属性
135
- size: {
136
- type: String,
137
- default: 'medium',
138
- validator: (value) => ['mini', 'small', 'medium', 'large'].includes(value)
139
- },
140
-
141
- clearable: {
142
- type: Boolean,
143
- default: false
144
- },
145
-
146
- showPassword: {
147
- type: Boolean,
148
- default: false
149
- },
150
-
151
- prefixIcon: {
152
- type: String,
153
- default: ''
154
- },
155
-
156
- suffixIcon: {
157
- type: String,
158
- default: ''
159
- },
160
-
161
- prepend: {
162
- type: String,
163
- default: ''
164
- },
165
-
166
- append: {
167
- type: String,
168
- default: ''
169
- },
170
-
171
- readonly: {
172
- type: Boolean,
173
- default: false
174
- }
175
- },
176
-
177
- data() {
178
- return {
179
- currentValue: this.value,
180
- isFocused: false,
181
- passwordVisible: false
182
- }
183
- },
184
-
185
- computed: {
186
- inputClasses() {
187
- return [
188
- `star-input--${this.size}`,
189
- {
190
- 'star-input--disabled': this.disabled,
191
- 'star-input--focused': this.isFocused,
192
- 'star-input--with-prepend': this.prepend || this.$slots.prepend,
193
- 'star-input--with-append': this.append || this.$slots.append,
194
- 'star-input--readonly': this.readonly
195
- }
196
- ]
197
- }
198
- },
199
-
200
- watch: {
201
- value(newVal) {
202
- this.currentValue = newVal
203
- }
204
- },
205
-
206
- methods: {
207
- handleInput(event) {
208
- const value = event.detail.value
209
- this.currentValue = value
210
- this.$emit('input', value)
211
- this.$emit('change', value)
212
- },
213
-
214
- handleFocus(event) {
215
- this.isFocused = true
216
- this.$emit('focus', event)
217
- },
218
-
219
- handleBlur(event) {
220
- this.isFocused = false
221
- this.$emit('blur', event)
222
- },
223
-
224
- handleConfirm(event) {
225
- this.$emit('confirm', event)
226
- },
227
-
228
- handleKeyboardHeightChange(event) {
229
- this.$emit('keyboardheightchange', event)
230
- },
231
-
232
- handleClear() {
233
- this.currentValue = ''
234
- this.$emit('input', '')
235
- this.$emit('change', '')
236
- this.$emit('clear')
237
- },
238
-
239
- togglePasswordVisible() {
240
- this.passwordVisible = !this.passwordVisible
241
- },
242
-
243
- handlePrefixIconClick() {
244
- this.$emit('click-prefix')
245
- },
246
-
247
- handleSuffixIconClick() {
248
- this.$emit('click-suffix')
249
- }
250
- }
251
- }
252
- </script>
253
-
254
- <style lang="scss" scoped>
255
- @import "../../styles/variables.scss";
256
-
257
- .star-input {
258
- display: inline-flex;
259
- width: 100%;
260
- font-size: $font-size-base;
261
- line-height: normal;
262
-
263
- &__prepend,
264
- &__append {
265
- display: flex;
266
- align-items: center;
267
- justify-content: center;
268
- padding: 0 12px;
269
- background-color: $bg-color-grey;
270
- border: 1px solid $border-color;
271
- white-space: nowrap;
272
-
273
- &-text {
274
- color: $text-color-secondary;
275
- }
276
- }
277
-
278
- &__prepend {
279
- border-right: 0;
280
- border-radius: $border-radius-base 0 0 $border-radius-base;
281
- }
282
-
283
- &__append {
284
- border-left: 0;
285
- border-radius: 0 $border-radius-base $border-radius-base 0;
286
- }
287
-
288
- &__wrapper {
289
- display: flex;
290
- align-items: center;
291
- flex: 1;
292
- position: relative;
293
- padding: 0 12px;
294
- border: 1px solid $border-color;
295
- border-radius: $border-radius-base;
296
- background-color: $bg-color;
297
- transition: border-color 0.3s;
298
-
299
- .star-input--with-prepend & {
300
- border-top-left-radius: 0;
301
- border-bottom-left-radius: 0;
302
- border-left: 0;
303
- }
304
-
305
- .star-input--with-append & {
306
- border-top-right-radius: 0;
307
- border-bottom-right-radius: 0;
308
- border-right: 0;
309
- }
310
- }
311
-
312
- &--focused &__wrapper {
313
- border-color: $primary-color;
314
- }
315
-
316
- &--disabled &__wrapper {
317
- background-color: $bg-color-grey;
318
- cursor: not-allowed;
319
- }
320
-
321
- &__inner {
322
- flex: 1;
323
- width: 100%;
324
- height: 100%;
325
- padding: 0;
326
- border: none;
327
- outline: none;
328
- background: transparent;
329
- font-size: inherit;
330
- color: $text-color;
331
-
332
- .star-input--disabled & {
333
- color: $text-color-disabled;
334
- cursor: not-allowed;
335
- }
336
-
337
- &::placeholder {
338
- color: $text-color-light;
339
- }
340
- }
341
-
342
- &__prefix-icon,
343
- &__suffix-icon {
344
- font-family: "star-icon-font" !important;
345
- color: $text-color-light;
346
- font-size: 18px;
347
- cursor: pointer;
348
- transition: color 0.3s;
349
-
350
- &:hover {
351
- color: $text-color;
352
- }
353
- }
354
-
355
- &__prefix-icon {
356
- margin-right: 8px;
357
- }
358
-
359
- &__suffix-icon {
360
- margin-left: 8px;
361
- }
362
-
363
- &__clear,
364
- &__password-toggle {
365
- display: flex;
366
- align-items: center;
367
- justify-content: center;
368
- width: 20px;
369
- height: 20px;
370
- margin-left: 8px;
371
- color: $text-color-light;
372
- cursor: pointer;
373
- transition: color 0.3s;
374
-
375
- &:hover {
376
- color: $text-color;
377
- }
378
-
379
- .star-icon-close,
380
- .star-icon-eye-open,
381
- .star-icon-eye-close {
382
- font-family: "star-icon-font" !important;
383
- font-size: 16px;
384
- }
385
- }
386
-
387
- // 尺寸
388
- &--mini &__wrapper {
389
- height: 24px;
390
- }
391
-
392
- &--small &__wrapper {
393
- height: 32px;
394
- }
395
-
396
- &--medium &__wrapper {
397
- height: 40px;
398
- }
399
-
400
- &--large &__wrapper {
401
- height: 48px;
402
- }
403
- }
404
- </style>