feature: suport show clear button when input text

This commit is contained in:
Sagi 2022-09-17 19:39:24 +08:00
parent db564e36ff
commit 83565d319d
4 changed files with 69 additions and 48 deletions

View File

@ -1,4 +1,4 @@
import { defineComponent, computed, toRefs, ref } from 'vue';
import { defineComponent, computed, toRefs, ref, reactive } from 'vue';
import type { SetupContext } from 'vue';
import { buttonEditProps, ButtonEditProps } from './button-edit.props';
import { useButton } from './composition/use-button';
@ -29,9 +29,7 @@ export default defineComponent({
const modelValue = ref(props.modelValue);
const { buttonClass, onClickButton, onMouseEnterButton, onMouseLeaveButton } = useButton(props, context);
const { showClearButton, onClearValue, onMouseEnterTextBox, onMouseLeaveTextBox } = useClear(props, context, modelValue);
const displayText = ref('');
const {
hasFocusedTextBox,
isTextBoxReadonly,
@ -46,7 +44,15 @@ export default defineComponent({
onKeyUpTextBox,
onMouseDownTextBox,
onTextBoxValueChange,
} = useTextBox(props, context, modelValue);
} = useTextBox(props, context, modelValue, displayText);
const { enableClearButton, showClearButton, onClearValue, onMouseEnterTextBox, onMouseLeaveTextBox } = useClear(
props,
context,
modelValue,
hasFocusedTextBox,
displayText
);
const inputGroupClass = computed(() => ({
'input-group': true,
@ -56,6 +62,8 @@ export default defineComponent({
'f-state-focus': hasFocusedTextBox,
}));
const displayClearButton = computed(() => (showClearButton ? '' : 'display: "none";'));
return () => {
return (
<div class="f-cmp-inputgroup" id={props.id}>
@ -83,8 +91,8 @@ export default defineComponent({
onMousedown={onMouseDownTextBox}
/>
<div class={buttonClass.value}>
{showClearButton.value && (
<span class="input-group-text input-group-clear" onClick={onClearValue}>
{enableClearButton.value && (
<span class="input-group-text input-group-clear" v-show={showClearButton.value} onClick={onClearValue}>
<i class="f-icon modal_close"></i>
</span>
)}

View File

@ -1,4 +1,4 @@
import { ComputedRef } from 'vue';
import { ComputedRef, Ref } from 'vue';
export interface UseButton {
/**
@ -24,10 +24,14 @@ export interface UseButton {
}
export interface UseClear {
/**
*
*/
enableClearButton: ComputedRef<boolean>;
/**
*
*/
showClearButton: ComputedRef<boolean>;
showClearButton: Ref<boolean>;
/**
*
*/

View File

@ -1,60 +1,64 @@
import { computed, Ref, ref, SetupContext } from 'vue';
import { computed, ComputedRef, Ref, ref, SetupContext, watch } from 'vue';
import { ButtonEditProps } from '../button-edit.props';
import { UseClear } from './types';
import { useTextBox } from './use-text-box';
export function useClear(props: ButtonEditProps, context: SetupContext, modelValue: Ref<string>): UseClear {
const hasShownClearButton = ref(false);
const showClearButton = computed(() => props.enableClear && !props.readonly && !props.disable);
export function useClear(
props: ButtonEditProps,
context: SetupContext,
modelValue: Ref<string>,
hasFocusedTextBox: ComputedRef<boolean>,
displayText: Ref<string>
): UseClear {
const showClearButton = ref(false);
const enableClearButton = computed(() => props.enableClear && !props.readonly && !props.disable);
const { changeTextBoxValue } = useTextBox(props, context, modelValue, displayText);
const { changeTextBoxValue } = useTextBox(props, context, modelValue);
function toggleClearIcon($event: any, isShow = false) {
const display = isShow ? '' : 'none';
const clearIcon = $event.target.querySelector('.input-group-clear');
if (clearIcon) {
clearIcon.style.display = display;
}
function toggleClearIcon(isShow: boolean) {
showClearButton.value = isShow;
}
watch(displayText, () => {
if (hasFocusedTextBox.value) {
toggleClearIcon(!!displayText.value);
} else {
toggleClearIcon(false);
}
});
function onClearValue($event: Event) {
const flag1 = !props.readonly && !props.disable && props.editable;
const flag2 = !props.editable;
$event.stopPropagation();
if (flag1 || flag2) {
changeTextBoxValue('', false);
hasShownClearButton.value = false;
toggleClearIcon(!showClearButton.value);
context.emit('clear');
}
}
function onMouseEnterTextBox($event: Event) {
if (!showClearButton.value) {
if (!enableClearButton.value) {
return;
}
if (modelValue.value) {
if (!props.editable) {
if (!props.disable) {
hasShownClearButton.value = true;
}
} else if (!props.readonly && !props.disable) {
hasShownClearButton.value = true;
}
if (!modelValue.value) {
toggleClearIcon(false);
return;
}
if (hasShownClearButton.value) {
toggleClearIcon($event, true);
if ((!props.editable || !props.readonly) && !props.disable) {
toggleClearIcon(true);
}
}
function onMouseLeaveTextBox($event: Event) {
if (!showClearButton.value) {
if (!enableClearButton.value) {
return;
}
hasShownClearButton.value = false;
toggleClearIcon($event, false);
toggleClearIcon(false);
}
return {
enableClearButton,
showClearButton,
onClearValue,
onMouseEnterTextBox,

View File

@ -1,8 +1,8 @@
import { computed, Ref, SetupContext, watch } from 'vue';
import { computed, ref, Ref, SetupContext, watch } from 'vue';
import { ButtonEditProps } from '../button-edit.props';
import { UseTextBox } from './types';
export function useTextBox(props: ButtonEditProps, context: SetupContext, modelValue: Ref<string>): UseTextBox {
export function useTextBox(props: ButtonEditProps, context: SetupContext, modelValue: Ref<string>, displayText: Ref<string>): UseTextBox {
const textBoxTitle = computed(() => (props.enableTitle ? modelValue.value : ''));
const textBoxPlaceholder = computed(() => ((props.disable || props.readonly) && !props.forcePlaceholder ? '' : props.placeholder));
@ -21,6 +21,15 @@ export function useTextBox(props: ButtonEditProps, context: SetupContext, modelV
'f-utils-fill': true,
}));
function changeTextBoxValue(newValue: string, showEmitChangeEmit = true) {
if (modelValue.value !== newValue) {
modelValue.value = newValue;
if (showEmitChangeEmit) {
context.emit('change', newValue);
}
}
}
watch(
() => props.modelValue,
(value: string) => context.emit('change', value)
@ -48,7 +57,12 @@ export function useTextBox(props: ButtonEditProps, context: SetupContext, modelV
function onInput($event: Event) {
context.emit('input', ($event.target as HTMLInputElement).value);
context.emit('update:modelValue', ($event.target as HTMLInputElement).value);
const newValue = ($event.target as HTMLInputElement).value;
displayText.value = newValue;
if (modelValue.value !== newValue) {
changeTextBoxValue(newValue, false);
context.emit('update:modelValue', ($event.target as HTMLInputElement).value);
}
}
function onMouseDownTextBox($event: MouseEvent) {
@ -67,15 +81,6 @@ export function useTextBox(props: ButtonEditProps, context: SetupContext, modelV
context.emit('keyup', $event);
}
function changeTextBoxValue(newValue: string, showEmitChangeEmit = true) {
if (modelValue.value !== newValue) {
modelValue.value = newValue;
if (showEmitChangeEmit) {
context.emit('change', newValue);
}
}
}
function onTextBoxValueChange($event: Event) {
const newValue = ($event.target as HTMLInputElement).value;
changeTextBoxValue(newValue);