@neatui/nuxt 1.5.5 → 1.6.0

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,224 +0,0 @@
1
- <template>
2
- <div :ui-form="`@a type:select sz:${sz}`" ui-tips="@a co:well" :ui-tips-view="state.show">
3
- <IFollowView>
4
- <Input v-bind="$props" :clearable="false" readonly v-model="state.value" @click="toggle">
5
- <template #suffix><i ui-form-select=""></i></template>
6
- </Input>
7
- <template #tips>
8
- <div ui-calendar="@a" class="w-ll">
9
- <div ui-calendar-head="">
10
- <div ui-flex="row lm" class="nx-ss-sub">
11
- <span class="fw-auto">{{ curr.y }}-{{ curr.m }}</span>
12
- </div>
13
- <div ui-flex="row rm">
14
- <button class="fs-xs mr-ss" ui-btn="@a main s">使用</button>
15
- </div>
16
- </div>
17
- <ul ui-calendar-week="">
18
- <li><span>日</span></li>
19
- <li><span>一</span></li>
20
- <li><span>二</span></li>
21
- <li><span>三</span></li>
22
- <li><span>四</span></li>
23
- <li><span>五</span></li>
24
- <li><span>六</span></li>
25
- </ul>
26
- <div>
27
- <ul ui-calendar-days="">
28
- <li
29
- v-for="(item, idx) in curr.days"
30
- :key="idx"
31
- :class="`${item.isToday ? 'today' : item.isLastMonth || item.isNextMonth ? 'o-sl' : item.isHoliday ? 'co-risk' : ''} ${
32
- state.selected && state.selected === item.date ? 'active' : ''
33
- }`"
34
- >
35
- <div v-if="item.day" @click="change(item)" class="pr">
36
- <span>{{ item.day }}</span>
37
- <sup style="font-size: 0.6em; margin-top: -0.3em; position: absolute; left: 100%; top: 0" v-if="item.holiday" class="lh-ss">休</sup>
38
- </div>
39
- </li>
40
- </ul>
41
- </div>
42
- <div ui-calendar-foot="">
43
- <div ui-flex="row lm">
44
- <div ui-calendar-prev-year="" @click="prev('y')"></div>
45
- <div ui-calendar-prev="" @click="prev('m')"></div>
46
- </div>
47
- <div ui-flex="row cm" class="nx-ss-sub">
48
- <ul class="fs-xs n-sm-sub" ui-flex="row lm">
49
- <li ui-btn="@a s none">年</li>
50
- <li ui-btn="@a s none">月</li>
51
- <li ui-btn="@a s none">日</li>
52
- <li ui-btn="@a s none">时</li>
53
- </ul>
54
- </div>
55
- <div ui-flex="row rm">
56
- <div ui-calendar-next="" @click="next('m')"></div>
57
- <div ui-calendar-next-year="" @click="next('y')"></div>
58
- </div>
59
- </div>
60
- </div>
61
- </template>
62
- </IFollowView>
63
- </div>
64
- </template>
65
- <script setup lang="ts">
66
- import { computed, reactive, toRefs } from 'vue';
67
- import { idate } from '@fekit/utils';
68
- import { Input } from '../form';
69
- import { IFollowView } from '../basic';
70
-
71
- // 创建日期
72
- const cDate = (date: any = null) => {
73
- const _date = new Date(date);
74
- return date && _date instanceof Date && !isNaN(_date.getTime()) ? _date : new Date();
75
- };
76
- // 个位补零
77
- const numfill = (num: string | number = '') => {
78
- return Number(num) < 10 ? `0${num}` : num;
79
- };
80
- // 外部入参
81
- const props = defineProps({
82
- theme: { type: String, default: '@a' },
83
- sz: { type: String, default: 'm' },
84
- co: { type: String, default: '' },
85
- block: { type: Boolean, default: true },
86
- // 提示文案
87
- tips: {
88
- type: String,
89
- default: ''
90
- },
91
- // 提示文案
92
- placeholder: {
93
- type: String,
94
- default: ''
95
- },
96
- // 格式
97
- format: {
98
- type: String,
99
- default: ''
100
- },
101
- // 值
102
- value: {
103
- type: [String, Number],
104
- default: ''
105
- },
106
- // 节假日
107
- holiday: {
108
- type: Object,
109
- default: () => ({})
110
- },
111
- // 校验规则
112
- rules: {
113
- type: Array,
114
- default: () => []
115
- },
116
- // 是否是示校验图标
117
- verify: {
118
- type: Boolean,
119
- default: false
120
- }
121
- });
122
-
123
- // 内部数据
124
- const state: any = reactive({
125
- view: 1,
126
- show: 0,
127
- pos: 'bl',
128
- selected: '',
129
- date: props.value,
130
- curr: computed(() => {
131
- const date = cDate(state.date);
132
- const calendar = [];
133
- // 年
134
- const y: any = date.getFullYear();
135
- // 月
136
- const m: any = date.getMonth() + 1;
137
- // 日
138
- const d: any = date.getDate();
139
- // 本月第一天星期几
140
- const w = new Date(`${y}-${m}-1`).getDay();
141
- // 当前月份一共几天
142
- const days = new Date(y, m, 0).getDate();
143
-
144
- // 当前
145
- const curr = new Date();
146
- const curr_y = curr.getFullYear();
147
- const curr_m = curr.getMonth() + 1;
148
- const curr_d = curr.getDate();
149
-
150
- // 上月
151
- const last = new Date(y, m - 1, 0);
152
- const last_y = last.getFullYear();
153
- const last_m = last.getMonth() + 1;
154
-
155
- // 下月
156
- const next = new Date(y, m + 1, 0);
157
- const next_y = next.getFullYear();
158
- const next_m = next.getMonth() + 1;
159
- let prevdays = last.getDate();
160
-
161
- for (let i = 0; i < w; i++) {
162
- calendar.unshift({
163
- date: `${last_y}-${numfill(last_m)}-${prevdays}`,
164
- day: prevdays,
165
- isLastMonth: 1
166
- });
167
- prevdays = prevdays - 1;
168
- }
169
- for (let i = 1; i <= days; i++) {
170
- const _i = numfill(i);
171
- calendar.push({
172
- date: `${y}-${numfill(m)}-${_i}`,
173
- day: _i,
174
- isToday: curr_y === y && curr_m === m && curr_d === i,
175
- isHoliday: props.holiday[`${y}-${numfill(m)}-${_i}`]?.name ? 1 : 0,
176
- holiday: props.holiday[`${y}-${numfill(m)}-${_i}`]?.name
177
- });
178
- }
179
- for (let i = 1; calendar.length < 42; i++) {
180
- const _i = numfill(i);
181
- calendar.push({
182
- date: `${next_y}-${numfill(next_m)}-${_i}`,
183
- day: _i,
184
- isNextMonth: 1
185
- });
186
- }
187
- return { days: calendar, y, m, d };
188
- }),
189
- value: computed(() => {
190
- return props.format ? idate(state.selected || props.value).format(props.format) : state.selected || props.value;
191
- })
192
- });
193
- const { curr = {} }: any = toRefs(state);
194
-
195
- const toggle = () => {
196
- state.show = state.show ? 0 : 1;
197
- };
198
- const upload = (a: any = 'm', b: any = 1) => {
199
- const date = cDate(state.date);
200
- if (a === 'm') {
201
- date.setMonth(date.getMonth() + b);
202
- } else {
203
- date.setFullYear(date.getFullYear() + b);
204
- }
205
- return date.toISOString().substring(0, 10);
206
- };
207
-
208
- // 日期前翻
209
- const prev = (type: any = 'm') => {
210
- state.date = upload(type, -1);
211
- };
212
- // 日期后翻
213
- const next = (type: any = 'm') => {
214
- state.date = upload(type, 1);
215
- };
216
-
217
- // 向外通信
218
- const emits = defineEmits(['change']);
219
- const change = (item: any) => {
220
- state.selected = item.date;
221
- state.date = item.date;
222
- emits('change', item.date);
223
- };
224
- </script>
@@ -1,230 +0,0 @@
1
- <template>
2
- <div
3
- :ui-form="`${theme} sz:${sz} ${state.error.co} type:input ${block ? ' :block' : ''} ${disabled ? 'disabled' : ''} ${readonly ? 'readonly' : ''}`"
4
- @click="emits('click', $event)"
5
- >
6
- <div :ui-form-tips="state.error.ontips">{{ state.error.tips }}</div>
7
- <div ui-form-prefix="">
8
- <template v-for="(item, idx) in prefix" :key="idx">
9
- <div v-html="isObject(item) ? item.html : item"></div>
10
- </template>
11
- <slot name="prefix"></slot>
12
- </div>
13
- <slot>
14
- <input
15
- v-model="state.value"
16
- :type="type"
17
- :placeholder="placeholder"
18
- :readonly="readonly || disabled"
19
- autocomplete="new-password"
20
- @focus="emits('focus', $event, state)"
21
- @input="input($event)"
22
- @change="emits('change', $event, state)"
23
- @blur="blur($event)"
24
- />
25
- </slot>
26
- <div ui-form-suffix="">
27
- <i ui-form-clean="" v-if="clearable && state.value && !readonly && !disabled" @click.stop="clear"></i>
28
- <slot name="suffix"></slot>
29
- <template v-for="(item, idx) in suffix" :key="idx">
30
- <div v-html="isObject(item) ? item.html : item"></div>
31
- </template>
32
- </div>
33
- <i v-if="ready && verify" :ui-form-verify="verify"></i>
34
- </div>
35
- </template>
36
-
37
- <script setup lang="ts">
38
- import { reactive, watch } from 'vue';
39
- import { isObject } from '@fekit/utils';
40
-
41
- const emits = defineEmits(['update:modelValue', 'click', 'blur', 'focus', 'change', 'input', 'clear']);
42
-
43
- /**
44
- * 入参说明
45
- *
46
- * modelValue 值
47
- * theme 主题
48
- * sz 尺寸
49
- * co 颜色
50
- * block 撑满
51
- * ready 准备就绪
52
- * type 类型
53
- * tips 提示文案
54
- * placeholder 内容占位
55
- * maxlength 最大长度
56
- * minlength 最小长度
57
- * disabled 是否禁用
58
- * readonly 是否只读
59
- * clearable 是否显示清除按钮
60
- * rules 校验规则
61
- * verify 是否是示校验图标
62
- * prefix 前缀内容
63
- * suffix 后缀内容
64
- * interacted 用户是否交互
65
- */
66
-
67
- // 类型
68
- interface Props {
69
- modelValue?: string | number;
70
- placeholder?: string;
71
- rules?: Array<object>;
72
- theme?: string;
73
- sz?: '' | 'xs' | 's' | 'm' | 'l' | 'xl';
74
- co?: string;
75
- block?: boolean;
76
- ready?: boolean;
77
- type?: string;
78
- tips?: string;
79
- maxlength?: null | number;
80
- minlength?: null | number;
81
- disabled?: boolean;
82
- readonly?: boolean;
83
- clearable?: boolean;
84
- verify?: boolean;
85
- prefix?: Array<any>;
86
- suffix?: Array<any>;
87
- interacted?: boolean;
88
- }
89
- const props: any = withDefaults(defineProps<Props>(), {
90
- modelValue: '',
91
- placeholder: '',
92
- rules: () => [],
93
- theme: '@a',
94
- sz: '',
95
- co: '',
96
- block: true,
97
- ready: false,
98
- type: 'text',
99
- tips: '',
100
- maxlength: null,
101
- minlength: null,
102
- disabled: false,
103
- readonly: false,
104
- clearable: true,
105
- verify: false,
106
- prefix: () => [],
107
- suffix: () => [],
108
- interacted: false
109
- });
110
-
111
- const state: any = reactive({
112
- // 用户是否交互
113
- interacted: false,
114
- // 值
115
- value: props.modelValue,
116
- // 错误
117
- error: {}
118
- });
119
- // 外部传入交互标识,主要用于外部没有输入但点击了提交
120
- watch(
121
- () => props.interacted,
122
- (interacted: any) => {
123
- if (interacted) {
124
- state.interacted = interacted;
125
- }
126
- },
127
- { deep: true, immediate: true }
128
- );
129
-
130
- // 监听异步数据
131
- watch(
132
- () => props.modelValue,
133
- (value: any) => {
134
- if (state.value !== value) {
135
- state.value = value;
136
- }
137
- },
138
- { deep: true, immediate: true }
139
- );
140
- watch(
141
- () => state.value,
142
- (value: any) => {
143
- emits('update:modelValue', value);
144
- },
145
- { deep: true, immediate: true }
146
- );
147
-
148
- // 校验
149
- watch(
150
- [() => state.interacted, () => state.value],
151
- async () => {
152
- if (state.interacted) {
153
- // 提示文案
154
- let tips = '';
155
- // 错误类型
156
- let type = '';
157
- // 验证结果
158
- let verify = '';
159
-
160
- if (props.modelValue) {
161
- // 有值
162
- let hasError = false;
163
- // 遍历校验规则
164
- for (const rule of props.rules) {
165
- if (rule && rule.validator) {
166
- const yes = !(await rule.validator(props.modelValue));
167
- if (yes) {
168
- tips = rule.msg;
169
- type = rule.type;
170
- hasError = true;
171
- break;
172
- }
173
- }
174
- }
175
- verify = hasError ? 'no' : 'ok';
176
- } else {
177
- // 无值
178
- let hasError = false;
179
- // 遍历校验规则
180
- for (const rule of props.rules) {
181
- if (rule) {
182
- tips = rule.msg;
183
- type = rule.type;
184
- if (rule.required) {
185
- hasError = true;
186
- break;
187
- }
188
- }
189
- }
190
- verify = hasError ? 'no' : '';
191
- }
192
- if (verify !== 'no' && props.tips) {
193
- tips = props.tips;
194
- }
195
- // 是否显示提示
196
- const ontips = (verify === 'no' && tips) || props.tips ? 'show' : '';
197
- // 状态颜色
198
- const co = verify === 'no' ? 'co:' + type : props.co ? 'co:' + props.co : '';
199
- state.error = { tips, ontips, verify, co };
200
- } else {
201
- state.error = { tips: props.tips, ontips: props.tips ? 'show' : '', verify: '', co: '' };
202
- }
203
- },
204
- { deep: true, immediate: true }
205
- );
206
-
207
- // 清空
208
- function clear() {
209
- emits('update:modelValue', '');
210
- emits('clear');
211
- }
212
- // 输入
213
- const input = (e: any) => {
214
- if (!state.interacted) {
215
- setTimeout(() => {
216
- state.interacted = true;
217
- }, 50);
218
- }
219
- emits('input', e, state);
220
- };
221
- // 失焦
222
- const blur = (e: any) => {
223
- if (!state.interacted) {
224
- setTimeout(() => {
225
- state.interacted = true;
226
- }, 50);
227
- }
228
- emits('blur', e, state);
229
- };
230
- </script>
@@ -1,144 +0,0 @@
1
- <template>
2
- <div :ui-form="`@a type:select ${sz ? 'sz:' + sz : ''}`">
3
- <IFollowView ref="ifollow" tipBoxClass="ny-sm nx-no" tipBoxStyle="min-width: 100%">
4
- <slot>
5
- <Input v-bind="$props" :clearable="false" readonly v-model="state.value" :interacted="interacted">
6
- <template #suffix><i ui-form-select=""></i></template>
7
- </Input>
8
- </slot>
9
- <template #tips>
10
- <ul v-if="props.options?.length" ui-scroll=":y s" class="nx-sm lh-ml" style="min-width: 100%; max-height: 15em">
11
- <template v-for="(item, idx) of props.options" :key="idx">
12
- <li v-if="item.disable" class="ux-hover nx-sm r-ss o-ms">
13
- <label style="pointer-events: none" ui-form="@a type:checkbox :block">
14
- <input type="checkbox" :name="state.name" :checked="modelValue?.some((i: any) => `${i}` === `${item.value}`)" />
15
- <del class="ml-sm">{{ item.label || item }}</del>
16
- </label>
17
- </li>
18
- <li v-else class="ux-hover nx-sm r-ss" @click.stop="select(item.value)">
19
- <label style="pointer-events: none" ui-form="@a type:checkbox :block">
20
- <input type="checkbox" :name="state.name" :checked="modelValue?.some((i: any) => `${i}` === `${item.value}`)" />
21
- <span class="ml-sm">{{ item.label || item }}</span>
22
- </label>
23
- </li>
24
- </template>
25
- </ul>
26
- <div v-else class="w-full ny-ms" ui-flex="col cm" v-html="spare"></div>
27
- <ul class="nx-sm lh-ml" v-if="tools">
28
- <li class="my-ss"><div class="o-mm" ui-line="@a"></div></li>
29
- <li ui-flex="row xm">
30
- <div class="ux-hover nx-sm r-ss nowrap co-main" @click.stop="allselect()">
31
- <label style="pointer-events: none" ui-form="@a type:checkbox :block">
32
- <input type="checkbox" :name="state.name" :checked="state.all" />
33
- <span class="ml-sm">全选({{ props.options?.length || 0 }})</span>
34
- </label>
35
- </div>
36
- <div>
37
- <button v-show="state.has" class="co-risk" ui-btn="@a none s" @click="remove">清空</button>
38
- </div>
39
- </li>
40
- </ul>
41
- </template>
42
- </IFollowView>
43
- </div>
44
- </template>
45
-
46
- <script setup lang="ts">
47
- import { reactive, ref, computed, watch } from 'vue';
48
- import { Input } from '../form';
49
- import { IFollowView } from '../basic';
50
- const ifollow: any = ref(null);
51
-
52
- const emits = defineEmits(['update:modelValue']);
53
- const props: any = defineProps({
54
- // 用户是否交互
55
- interacted: {
56
- type: Boolean,
57
- default: false
58
- },
59
- theme: { type: String, default: '@a' },
60
- sz: { type: String, default: '' },
61
- co: { type: String, default: '' },
62
- block: { type: Boolean, default: true },
63
- // 提示文案
64
- tips: {
65
- type: String,
66
- default: ''
67
- },
68
- placeholder: {
69
- type: String,
70
- default: ''
71
- },
72
- modelValue: {
73
- type: Array as () => any[],
74
- default: () => []
75
- },
76
- options: {
77
- type: Array as () => any[],
78
- default: () => []
79
- },
80
- // 校验规则
81
- rules: {
82
- type: Array,
83
- default: () => []
84
- },
85
- // 是否是示校验图标
86
- verify: {
87
- type: Boolean,
88
- default: false
89
- },
90
- tools: {
91
- type: Boolean,
92
- default: true
93
- },
94
- spare: {
95
- type: String,
96
- default: '当前没有可选项'
97
- }
98
- });
99
-
100
- const state: any = reactive({
101
- name: computed(() => {
102
- return Array.from({ length: 8 }, () => String.fromCharCode(97 + Math.floor(Math.random() * 26))).join('');
103
- }),
104
- show: 0,
105
- value: '',
106
- all: computed(() => {
107
- return props.options?.every((item: any) => props.modelValue?.some((i: any) => `${i}` === `${item.value}`));
108
- }),
109
- has: computed(() => {
110
- return props.options?.some((item: any) => props.modelValue?.some((i: any) => `${i}` === `${item.value}`));
111
- })
112
- });
113
-
114
- // 监听外部数据
115
- watch(
116
- () => props.modelValue,
117
- (v: any = []) => {
118
- const selectd: any = props.options?.filter((item: any) => v?.some((i: any) => `${i}` === `${item.value}`))?.map((item: any) => item.label) || [];
119
- state.value = selectd.join(' Ι ') || '';
120
- },
121
- { deep: true, immediate: true }
122
- );
123
-
124
- // 更新
125
- const change = (item: any) => {
126
- emits('update:modelValue', item);
127
- };
128
- // 选中
129
- const select = (item: any) => {
130
- const s = [...props.modelValue];
131
- s?.indexOf(item) !== -1 ? s?.splice(s?.indexOf(item), 1) : s?.push(item);
132
- change(s);
133
- };
134
- // 全选
135
- const allselect = () => {
136
- const s = state.all ? [] : props.options?.map((item: any) => item.value);
137
- change(s);
138
- };
139
- // 清除
140
- const remove = () => {
141
- change([]);
142
- ifollow.value.cancel();
143
- };
144
- </script>