mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-29 21:06:33 +08:00
93 lines
2.1 KiB
JavaScript
93 lines
2.1 KiB
JavaScript
import { ref } from 'vue';
|
|
import { createNamespace } from '../utils';
|
|
import { useTouch } from '../composition/use-touch';
|
|
import Loading from '../loading';
|
|
import { DeleteIcon, CollapseIcon } from './Icon';
|
|
|
|
const [createComponent, bem] = createNamespace('key');
|
|
|
|
export default createComponent({
|
|
props: {
|
|
type: String,
|
|
text: [Number, String],
|
|
color: String,
|
|
wider: Boolean,
|
|
large: Boolean,
|
|
loading: Boolean,
|
|
},
|
|
|
|
emits: ['press'],
|
|
|
|
setup(props, { emit, slots }) {
|
|
const active = ref(false);
|
|
const touch = useTouch();
|
|
|
|
const onTouchStart = (event) => {
|
|
touch.start(event);
|
|
active.value = true;
|
|
};
|
|
|
|
const onTouchMove = (event) => {
|
|
touch.move(event);
|
|
|
|
if (touch.direction.value) {
|
|
active.value = false;
|
|
}
|
|
};
|
|
|
|
const onTouchEnd = (event) => {
|
|
if (active.value) {
|
|
// eliminate tap delay on safari
|
|
// see: https://github.com/youzan/vant/issues/6836
|
|
if (!slots.default) {
|
|
event.preventDefault();
|
|
}
|
|
active.value = false;
|
|
emit('press', props.text, props.type);
|
|
}
|
|
};
|
|
|
|
const renderContent = () => {
|
|
if (props.loading) {
|
|
return <Loading class={bem('loading-icon')} />;
|
|
}
|
|
|
|
const text = slots.default ? slots.default() : props.text;
|
|
|
|
switch (props.type) {
|
|
case 'delete':
|
|
return text || <DeleteIcon class={bem('delete-icon')} />;
|
|
case 'extra':
|
|
return text || <CollapseIcon class={bem('collapse-icon')} />;
|
|
default:
|
|
return text;
|
|
}
|
|
};
|
|
|
|
return () => (
|
|
<div
|
|
class={bem('wrapper', { wider: props.wider })}
|
|
onTouchstart={onTouchStart}
|
|
onTouchmove={onTouchMove}
|
|
onTouchend={onTouchEnd}
|
|
onTouchcancel={onTouchEnd}
|
|
>
|
|
<div
|
|
role="button"
|
|
tabindex="0"
|
|
class={bem([
|
|
props.color,
|
|
{
|
|
large: props.large,
|
|
active: active.value,
|
|
delete: props.type === 'delete',
|
|
},
|
|
])}
|
|
>
|
|
{renderContent()}
|
|
</div>
|
|
</div>
|
|
);
|
|
},
|
|
});
|