commit
797b4a66f1
|
@ -6,104 +6,107 @@ import { useClear } from './composition/use-clear';
|
|||
import { useTextBox } from './composition/use-text-box';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'FButtonEdit',
|
||||
props: buttonEditProps,
|
||||
emits: [
|
||||
'updateExtendInfo',
|
||||
'clear',
|
||||
'change',
|
||||
'click',
|
||||
'clickButton',
|
||||
'blur',
|
||||
'focus',
|
||||
'mouseEnterIcon',
|
||||
'mouseLeaveIcon',
|
||||
'keyup',
|
||||
'keydown',
|
||||
'inputClick',
|
||||
'input',
|
||||
'update:modelValue',
|
||||
],
|
||||
setup(props: ButtonEditProps, context: SetupContext) {
|
||||
const modelValue = ref(props.modelValue);
|
||||
const { buttonClass, onClickButton, onMouseEnterButton, onMouseLeaveButton } = useButton(props, context);
|
||||
const displayText = ref('');
|
||||
const {
|
||||
hasFocusedTextBox,
|
||||
isTextBoxReadonly,
|
||||
textBoxClass,
|
||||
textBoxPlaceholder,
|
||||
textBoxTitle,
|
||||
onBlurTextBox,
|
||||
onClickTextBox,
|
||||
onFocusTextBox,
|
||||
onInput,
|
||||
onKeyDownTextBox,
|
||||
onKeyUpTextBox,
|
||||
onMouseDownTextBox,
|
||||
onTextBoxValueChange,
|
||||
} = useTextBox(props, context, modelValue, displayText);
|
||||
name: 'FButtonEdit',
|
||||
props: buttonEditProps,
|
||||
emits: [
|
||||
'updateExtendInfo',
|
||||
'clear',
|
||||
'change',
|
||||
'click',
|
||||
'clickButton',
|
||||
'blur',
|
||||
'focus',
|
||||
'mouseEnterIcon',
|
||||
'mouseLeaveIcon',
|
||||
'keyup',
|
||||
'keydown',
|
||||
'inputClick',
|
||||
'input',
|
||||
'update:modelValue',
|
||||
],
|
||||
setup(props: ButtonEditProps, context: SetupContext) {
|
||||
const modelValue = ref(props.modelValue);
|
||||
const { buttonClass, onClickButton, onMouseEnterButton, onMouseLeaveButton } = useButton(props, context);
|
||||
const displayText = ref('');
|
||||
const {
|
||||
hasFocusedTextBox,
|
||||
isTextBoxReadonly,
|
||||
textBoxClass,
|
||||
textBoxPlaceholder,
|
||||
textBoxTitle,
|
||||
onBlurTextBox,
|
||||
onClickTextBox,
|
||||
onFocusTextBox,
|
||||
onInput,
|
||||
onKeyDownTextBox,
|
||||
onKeyUpTextBox,
|
||||
onMouseDownTextBox,
|
||||
onTextBoxValueChange,
|
||||
} = useTextBox(props, context, modelValue, displayText);
|
||||
|
||||
const { enableClearButton, showClearButton, onClearValue, onMouseEnterTextBox, onMouseLeaveTextBox } = useClear(
|
||||
props,
|
||||
context,
|
||||
modelValue,
|
||||
hasFocusedTextBox,
|
||||
displayText
|
||||
);
|
||||
const { enableClearButton, showClearButton, onClearValue, onMouseEnterTextBox, onMouseLeaveTextBox } = useClear(
|
||||
props,
|
||||
context,
|
||||
modelValue,
|
||||
hasFocusedTextBox,
|
||||
displayText
|
||||
);
|
||||
|
||||
const inputGroupClass = computed(() => ({
|
||||
'input-group': true,
|
||||
'f-state-disable': props.disable,
|
||||
'f-state-editable': props.editable && !props.disable && !props.readonly,
|
||||
'f-state-readonly': props.readonly && !props.disable,
|
||||
'f-state-focus': hasFocusedTextBox,
|
||||
}));
|
||||
const inputGroupClass = computed(() => ({
|
||||
'input-group': true,
|
||||
'f-state-disable': props.disable,
|
||||
'f-state-editable': props.editable && !props.disable && !props.readonly,
|
||||
'f-state-readonly': props.readonly && !props.disable,
|
||||
'f-state-focus': hasFocusedTextBox,
|
||||
}));
|
||||
|
||||
return () => {
|
||||
return (
|
||||
<div class="f-cmp-inputgroup" id={props.id}>
|
||||
<div class={[props.customClass, inputGroupClass.value]} onMouseenter={onMouseEnterTextBox} onMouseleave={onMouseLeaveTextBox}>
|
||||
<input
|
||||
name="input-group-value"
|
||||
autocomplete={'' + props.autoComplete}
|
||||
class={textBoxClass.value}
|
||||
disabled={props.disable}
|
||||
maxlength={props.maxLength}
|
||||
minlength={props.minLength}
|
||||
placeholder={textBoxPlaceholder.value}
|
||||
readonly={isTextBoxReadonly.value}
|
||||
tabindex={props.tabIndex}
|
||||
title={textBoxTitle.value}
|
||||
type={props.inputType}
|
||||
value={modelValue.value}
|
||||
onBlur={onBlurTextBox}
|
||||
onChange={onTextBoxValueChange}
|
||||
onClick={onClickTextBox}
|
||||
onFocus={onFocusTextBox}
|
||||
onInput={onInput}
|
||||
onKeydown={onKeyDownTextBox}
|
||||
onKeyup={onKeyUpTextBox}
|
||||
onMousedown={onMouseDownTextBox}
|
||||
/>
|
||||
<div class={buttonClass.value}>
|
||||
{enableClearButton.value && (
|
||||
<span class="input-group-text input-group-clear" v-show={showClearButton.value} onClick={onClearValue}>
|
||||
<i class="f-icon modal_close"></i>
|
||||
</span>
|
||||
)}
|
||||
{props.buttonContent && (
|
||||
<span
|
||||
class="input-group-text input-group-append-button"
|
||||
onClick={onClickButton}
|
||||
onMouseenter={onMouseEnterButton}
|
||||
onMouseleave={onMouseLeaveButton}
|
||||
v-html={props.buttonContent}></span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
},
|
||||
return () => {
|
||||
return (
|
||||
<div class="f-cmp-inputgroup" id={props.id}>
|
||||
<div
|
||||
class={[props.customClass, inputGroupClass.value]}
|
||||
onMouseenter={onMouseEnterTextBox}
|
||||
onMouseleave={onMouseLeaveTextBox}>
|
||||
<input
|
||||
name="input-group-value"
|
||||
autocomplete={'' + props.autoComplete}
|
||||
class={textBoxClass.value}
|
||||
disabled={props.disable}
|
||||
maxlength={props.maxLength}
|
||||
minlength={props.minLength}
|
||||
placeholder={textBoxPlaceholder.value}
|
||||
readonly={isTextBoxReadonly.value}
|
||||
tabindex={props.tabIndex}
|
||||
title={textBoxTitle.value}
|
||||
type={props.inputType}
|
||||
value={modelValue.value}
|
||||
onBlur={onBlurTextBox}
|
||||
onChange={onTextBoxValueChange}
|
||||
onClick={onClickTextBox}
|
||||
onFocus={onFocusTextBox}
|
||||
onInput={onInput}
|
||||
onKeydown={onKeyDownTextBox}
|
||||
onKeyup={onKeyUpTextBox}
|
||||
onMousedown={onMouseDownTextBox}
|
||||
/>
|
||||
<div class={buttonClass.value}>
|
||||
{enableClearButton.value && (
|
||||
<span class="input-group-text input-group-clear" v-show={showClearButton.value} onClick={onClearValue}>
|
||||
<i class="f-icon modal_close"></i>
|
||||
</span>
|
||||
)}
|
||||
{props.buttonContent && (
|
||||
<span
|
||||
class="input-group-text input-group-append-button"
|
||||
onClick={onClickButton}
|
||||
onMouseenter={onMouseEnterButton}
|
||||
onMouseleave={onMouseLeaveButton}
|
||||
v-html={props.buttonContent}></span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
},
|
||||
});
|
||||
|
|
|
@ -3,79 +3,79 @@ import { ExtractPropTypes, PropType } from 'vue';
|
|||
type TextAlignment = 'left' | 'center' | 'right';
|
||||
|
||||
export const buttonEditProps = {
|
||||
/**
|
||||
* 组件标识
|
||||
*/
|
||||
id: String,
|
||||
/**
|
||||
* 扩展按钮显示内容,这是一段现在扩展按钮中的html标签
|
||||
*/
|
||||
buttonContent: { type: String, default: '<i class="f-icon f-icon-lookup"></i>' },
|
||||
/**
|
||||
* 启用输入框自动完成功能
|
||||
*/
|
||||
autoComplete: { type: Boolean, default: false },
|
||||
/**
|
||||
* 组件自定义样式
|
||||
*/
|
||||
customClass: { type: String, default: '' },
|
||||
/**
|
||||
* 禁用组件,既不允许在输入框中录入,也不允许点击扩展按钮。
|
||||
*/
|
||||
disable: { type: Boolean, default: false },
|
||||
/**
|
||||
* 允许在输入框中录入文本。
|
||||
*/
|
||||
editable: { type: Boolean, default: true },
|
||||
/**
|
||||
* 显示清空文本按钮
|
||||
*/
|
||||
enableClear: { type: Boolean, default: false },
|
||||
/**
|
||||
* 组件值
|
||||
*/
|
||||
modelValue:{type:String,default:''},
|
||||
/**
|
||||
* 将组件设置为只读,既不允许在输入框中录入,也不允许点击扩展按钮,但是允许复制输入框中的内容。
|
||||
*/
|
||||
readonly: { type: Boolean, default: false },
|
||||
/**
|
||||
* 文本对齐方式
|
||||
*/
|
||||
textAlign: { type: String as PropType<TextAlignment>, default: 'left' },
|
||||
/**
|
||||
* 禁用组件时,是否显示扩展按钮
|
||||
*/
|
||||
showButtonWhenDisabled: { type: Boolean, default: false },
|
||||
/**
|
||||
* 组件标识
|
||||
*/
|
||||
id: String,
|
||||
/**
|
||||
* 扩展按钮显示内容,这是一段现在扩展按钮中的html标签
|
||||
*/
|
||||
buttonContent: { type: String, default: '<i class="f-icon f-icon-lookup"></i>' },
|
||||
/**
|
||||
* 启用输入框自动完成功能
|
||||
*/
|
||||
autoComplete: { type: Boolean, default: false },
|
||||
/**
|
||||
* 组件自定义样式
|
||||
*/
|
||||
customClass: { type: String, default: '' },
|
||||
/**
|
||||
* 禁用组件,既不允许在输入框中录入,也不允许点击扩展按钮。
|
||||
*/
|
||||
disable: { type: Boolean, default: false },
|
||||
/**
|
||||
* 允许在输入框中录入文本。
|
||||
*/
|
||||
editable: { type: Boolean, default: true },
|
||||
/**
|
||||
* 显示清空文本按钮
|
||||
*/
|
||||
enableClear: { type: Boolean, default: false },
|
||||
/**
|
||||
* 组件值
|
||||
*/
|
||||
modelValue: { type: String, default: '' },
|
||||
/**
|
||||
* 将组件设置为只读,既不允许在输入框中录入,也不允许点击扩展按钮,但是允许复制输入框中的内容。
|
||||
*/
|
||||
readonly: { type: Boolean, default: false },
|
||||
/**
|
||||
* 文本对齐方式
|
||||
*/
|
||||
textAlign: { type: String as PropType<TextAlignment>, default: 'left' },
|
||||
/**
|
||||
* 禁用组件时,是否显示扩展按钮
|
||||
*/
|
||||
showButtonWhenDisabled: { type: Boolean, default: false },
|
||||
|
||||
/**
|
||||
* 显示输入框的标签
|
||||
*/
|
||||
enableTitle: { type: Boolean, default: false },
|
||||
/**
|
||||
* 输入框类型
|
||||
*/
|
||||
inputType: { type: String, default: 'text' },
|
||||
/**
|
||||
* 显示输入框提示信息
|
||||
*/
|
||||
forcePlaceholder: { type: Boolean, default: false },
|
||||
/**
|
||||
* 输入框提示文本
|
||||
*/
|
||||
placeholder: { type: String, default: '' },
|
||||
/**
|
||||
* 输入框最小长度
|
||||
*/
|
||||
minLength: Number,
|
||||
/**
|
||||
* 输入框最大长度
|
||||
*/
|
||||
maxLength: Number,
|
||||
/**
|
||||
* 输入框Tab键索引
|
||||
*/
|
||||
tabIndex: Number,
|
||||
/**
|
||||
* 显示输入框的标签
|
||||
*/
|
||||
enableTitle: { type: Boolean, default: false },
|
||||
/**
|
||||
* 输入框类型
|
||||
*/
|
||||
inputType: { type: String, default: 'text' },
|
||||
/**
|
||||
* 显示输入框提示信息
|
||||
*/
|
||||
forcePlaceholder: { type: Boolean, default: false },
|
||||
/**
|
||||
* 输入框提示文本
|
||||
*/
|
||||
placeholder: { type: String, default: '' },
|
||||
/**
|
||||
* 输入框最小长度
|
||||
*/
|
||||
minLength: Number,
|
||||
/**
|
||||
* 输入框最大长度
|
||||
*/
|
||||
maxLength: Number,
|
||||
/**
|
||||
* 输入框Tab键索引
|
||||
*/
|
||||
tabIndex: Number,
|
||||
};
|
||||
|
||||
export type ButtonEditProps = ExtractPropTypes<typeof buttonEditProps>;
|
||||
|
|
|
@ -3,37 +3,37 @@ import { computed, SetupContext } from 'vue';
|
|||
import { ButtonEditProps } from '../button-edit.props';
|
||||
|
||||
export function useButton(props: ButtonEditProps, context: SetupContext): UseButton {
|
||||
const buttonClass = computed(() => ({
|
||||
'input-group-append': true,
|
||||
'append-force-show': props.showButtonWhenDisabled && (props.readonly || props.disable),
|
||||
}));
|
||||
const buttonClass = computed(() => ({
|
||||
'input-group-append': true,
|
||||
'append-force-show': props.showButtonWhenDisabled && (props.readonly || props.disable),
|
||||
}));
|
||||
|
||||
const canClickAppendButton = computed(() => props.showButtonWhenDisabled || ((!props.editable || !props.readonly) && !props.disable));
|
||||
const canClickAppendButton = computed(() => props.showButtonWhenDisabled || ((!props.editable || !props.readonly) && !props.disable));
|
||||
|
||||
function onClickButton($event: Event) {
|
||||
if (canClickAppendButton.value) {
|
||||
context.emit('clickButton', { origin: $event, value: props.modelValue });
|
||||
function onClickButton($event: Event) {
|
||||
if (canClickAppendButton.value) {
|
||||
context.emit('clickButton', { origin: $event, value: props.modelValue });
|
||||
}
|
||||
$event.stopPropagation();
|
||||
}
|
||||
$event.stopPropagation();
|
||||
}
|
||||
|
||||
function onMouseEnterButton($event: MouseEvent) {
|
||||
context.emit('mouseEnterIcon', $event);
|
||||
}
|
||||
function onMouseEnterButton($event: MouseEvent) {
|
||||
context.emit('mouseEnterIcon', $event);
|
||||
}
|
||||
|
||||
function onMouseLeaveButton($event: MouseEvent) {
|
||||
context.emit('mouseLeaveIcon', $event);
|
||||
}
|
||||
function onMouseLeaveButton($event: MouseEvent) {
|
||||
context.emit('mouseLeaveIcon', $event);
|
||||
}
|
||||
|
||||
function onMouseOverButton() {
|
||||
context.emit('mouseOverButton');
|
||||
}
|
||||
function onMouseOverButton() {
|
||||
context.emit('mouseOverButton');
|
||||
}
|
||||
|
||||
return {
|
||||
buttonClass,
|
||||
onClickButton,
|
||||
onMouseEnterButton,
|
||||
onMouseLeaveButton,
|
||||
onMouseOverButton,
|
||||
};
|
||||
return {
|
||||
buttonClass,
|
||||
onClickButton,
|
||||
onMouseEnterButton,
|
||||
onMouseLeaveButton,
|
||||
onMouseOverButton,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -4,64 +4,64 @@ import { UseClear } from './types';
|
|||
import { useTextBox } from './use-text-box';
|
||||
|
||||
export function useClear(
|
||||
props: ButtonEditProps,
|
||||
context: SetupContext,
|
||||
modelValue: Ref<string>,
|
||||
hasFocusedTextBox: ComputedRef<boolean>,
|
||||
displayText: Ref<string>
|
||||
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 showClearButton = ref(false);
|
||||
const enableClearButton = computed(() => props.enableClear && !props.readonly && !props.disable);
|
||||
const { changeTextBoxValue } = useTextBox(props, context, modelValue, displayText);
|
||||
|
||||
function toggleClearIcon(isShow: boolean) {
|
||||
showClearButton.value = isShow;
|
||||
}
|
||||
function toggleClearIcon(isShow: boolean) {
|
||||
showClearButton.value = isShow;
|
||||
}
|
||||
|
||||
watch(displayText, () => {
|
||||
if (hasFocusedTextBox.value) {
|
||||
toggleClearIcon(!!displayText.value);
|
||||
} else {
|
||||
toggleClearIcon(false);
|
||||
}
|
||||
});
|
||||
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);
|
||||
toggleClearIcon(!showClearButton.value);
|
||||
context.emit('clear');
|
||||
function onClearValue($event: Event) {
|
||||
const flag1 = !props.readonly && !props.disable && props.editable;
|
||||
const flag2 = !props.editable;
|
||||
$event.stopPropagation();
|
||||
if (flag1 || flag2) {
|
||||
changeTextBoxValue('', false);
|
||||
toggleClearIcon(!showClearButton.value);
|
||||
context.emit('clear');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function onMouseEnterTextBox($event: Event) {
|
||||
if (!enableClearButton.value) {
|
||||
return;
|
||||
function onMouseEnterTextBox($event: Event) {
|
||||
if (!enableClearButton.value) {
|
||||
return;
|
||||
}
|
||||
if (!modelValue.value) {
|
||||
toggleClearIcon(false);
|
||||
return;
|
||||
}
|
||||
if ((!props.editable || !props.readonly) && !props.disable) {
|
||||
toggleClearIcon(true);
|
||||
}
|
||||
}
|
||||
if (!modelValue.value) {
|
||||
toggleClearIcon(false);
|
||||
return;
|
||||
}
|
||||
if ((!props.editable || !props.readonly) && !props.disable) {
|
||||
toggleClearIcon(true);
|
||||
}
|
||||
}
|
||||
|
||||
function onMouseLeaveTextBox($event: Event) {
|
||||
if (!enableClearButton.value) {
|
||||
return;
|
||||
function onMouseLeaveTextBox($event: Event) {
|
||||
if (!enableClearButton.value) {
|
||||
return;
|
||||
}
|
||||
toggleClearIcon(false);
|
||||
}
|
||||
toggleClearIcon(false);
|
||||
}
|
||||
|
||||
return {
|
||||
enableClearButton,
|
||||
showClearButton,
|
||||
onClearValue,
|
||||
onMouseEnterTextBox,
|
||||
onMouseLeaveTextBox,
|
||||
};
|
||||
return {
|
||||
enableClearButton,
|
||||
showClearButton,
|
||||
onClearValue,
|
||||
onMouseEnterTextBox,
|
||||
onMouseLeaveTextBox,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,59 +1,118 @@
|
|||
import { computed, defineComponent, SetupContext } from 'vue';
|
||||
import { NotifyData } from '../notify.props';
|
||||
import { computed, defineComponent, ref, SetupContext, watch } from 'vue';
|
||||
import { NotifyButton, NotifyData } from '../notify.props';
|
||||
import { ToastProps, toastProps } from './toast.props';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'Toast',
|
||||
props: toastProps,
|
||||
emits: [],
|
||||
setup: (props: ToastProps, context: SetupContext) => {
|
||||
const toastClass = computed(() => ({
|
||||
toast: true,
|
||||
}));
|
||||
name: 'Toast',
|
||||
props: toastProps,
|
||||
emits: ['close', 'click'],
|
||||
setup: (props: ToastProps, context: SetupContext) => {
|
||||
const animateIn = ref(props.animate);
|
||||
const animateEnd = 'fadeOut';
|
||||
const toast = computed(() => {
|
||||
return props.options as NotifyData;
|
||||
});
|
||||
const showingToast = ref(false);
|
||||
|
||||
const toast = computed(() => {
|
||||
return {} as NotifyData;
|
||||
});
|
||||
const toastClass = computed(() => {
|
||||
const classObject = {
|
||||
animated: showingToast.value,
|
||||
toast: true,
|
||||
};
|
||||
classObject[props.animate] = false;
|
||||
classObject[animateEnd] = showingToast.value;
|
||||
classObject[toast.value.type] = true;
|
||||
if (toast.value.theme) {
|
||||
classObject[toast.value.theme] = true;
|
||||
}
|
||||
return classObject;
|
||||
});
|
||||
|
||||
const toastIconClass = computed(() => ({
|
||||
'f-icon': true,
|
||||
}));
|
||||
const toastIconClass = computed(() => {
|
||||
const hasSpecialToastType = toast.value && toast.value.type;
|
||||
const iconType = hasSpecialToastType ? toast.value.type.replace('toasty-type-', '') : 'default';
|
||||
const iconTypeName = `f-icon-${iconType}`;
|
||||
const classObject = { 'f-icon': true };
|
||||
classObject[iconTypeName] = true;
|
||||
return classObject;
|
||||
});
|
||||
|
||||
const shouldShowTips = computed(() => toast.value.title || toast.value.msg);
|
||||
const shouldShowTips = computed(() => toast.value.title || toast.value.msg);
|
||||
|
||||
const shouldShowTitle = computed(() => toast.value.title && toast.value.msg);
|
||||
const shouldShowTitle = computed(() => toast.value.title && toast.value.msg);
|
||||
|
||||
const shouldShowCloseButton = computed(() => {
|
||||
return true;
|
||||
});
|
||||
const shouldShowCloseButton = computed(() => {
|
||||
return true;
|
||||
});
|
||||
|
||||
function onCloseToast($event: Event) {}
|
||||
const shouldShowButtonsInTitle = computed(() => !!toast.value.buttons || !!context.slots.default);
|
||||
|
||||
return () => {
|
||||
return (
|
||||
<div class={toastClass}>
|
||||
{shouldShowCloseButton.value && (
|
||||
<button class="toast-close f-btn-icon f-bare" onClick={onCloseToast}>
|
||||
<span class="f-icon modal_close"></span>
|
||||
</button>
|
||||
)}
|
||||
{shouldShowTips.value && (
|
||||
<section class="modal-tips">
|
||||
<div class="float-left modal-tips-iconwrap">
|
||||
<span class={toastIconClass}></span>
|
||||
</div>
|
||||
<div class="modal-tips-content">
|
||||
{shouldShowTitle.value && (
|
||||
<>
|
||||
<h5 class="toast-title modal-tips-title" v-html={toast.value.title}></h5>
|
||||
<p class="toast-msg" v-html={toast.value.msg}></p>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
},
|
||||
function onCloseToast($event: Event) {
|
||||
$event.stopPropagation();
|
||||
$event.preventDefault();
|
||||
showingToast.value = false;
|
||||
setTimeout(() => {
|
||||
context.emit('close', toast.value);
|
||||
}, 200);
|
||||
}
|
||||
|
||||
function onClickButton($event: Event, notifyButton: NotifyButton) {}
|
||||
|
||||
function getNotifyButtonClass(notifyButton: NotifyButton) {
|
||||
return `f-preten-link ${notifyButton.customClass ? notifyButton.customClass : ''}`;
|
||||
}
|
||||
|
||||
watch(animateIn, () => {
|
||||
const animateInClass = animateIn.value || 'bounceInRight';
|
||||
const animateOutClass = 'fadeOut';
|
||||
});
|
||||
|
||||
const renderNotifyButtons = () => {
|
||||
return (
|
||||
<>
|
||||
<div class="after-toast-msg text-right">
|
||||
{!context.slots.default &&
|
||||
toast.value.buttons?.map((notifyButton: NotifyButton) => {
|
||||
return (
|
||||
<span
|
||||
class={getNotifyButtonClass(notifyButton)}
|
||||
onClick={($event) => onClickButton($event, notifyButton)}>
|
||||
{notifyButton.text}
|
||||
</span>
|
||||
);
|
||||
})}
|
||||
{context.slots.default && context.slots.default()}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
return () => {
|
||||
return (
|
||||
<div class={toastClass}>
|
||||
{shouldShowCloseButton.value && (
|
||||
<button class="toast-close f-btn-icon f-bare" onClick={onCloseToast}>
|
||||
<span class="f-icon modal_close"></span>
|
||||
</button>
|
||||
)}
|
||||
{shouldShowTips.value && (
|
||||
<section class="modal-tips">
|
||||
<div class="float-left modal-tips-iconwrap">
|
||||
<span class={toastIconClass}></span>
|
||||
</div>
|
||||
<div class="modal-tips-content">
|
||||
{shouldShowTitle.value && (
|
||||
<>
|
||||
<h5 class="toast-title modal-tips-title" v-html={toast.value.title}></h5>
|
||||
<p class="toast-msg" v-html={toast.value.msg}></p>
|
||||
{shouldShowButtonsInTitle.value && renderNotifyButtons()}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
},
|
||||
});
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import { ExtractPropTypes, PropType } from 'vue';
|
||||
import { ToastyAnimate } from '../notify.props';
|
||||
import { NotifyData, ToastyAnimate } from '../notify.props';
|
||||
|
||||
export const toastProps = {
|
||||
animate: { type: String as PropType<ToastyAnimate>, default: 'fadeIn' },
|
||||
animate: { type: String as PropType<ToastyAnimate>, default: 'fadeIn' },
|
||||
options: { type: Object as PropType<NotifyData> },
|
||||
};
|
||||
|
||||
export type ToastProps = ExtractPropTypes<typeof toastProps>;
|
||||
|
|
|
@ -1,35 +1,37 @@
|
|||
import { computed, defineComponent, SetupContext } from 'vue';
|
||||
import { computed, defineComponent, ref, SetupContext } from 'vue';
|
||||
import { NotifyContainerComponent } from './notify-container.component';
|
||||
import { NotifyData, NotifyProps, notifyProps } from './notify.props';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'Notify',
|
||||
props: notifyProps,
|
||||
emits: [],
|
||||
setup(props: NotifyProps, context: SetupContext) {
|
||||
const notifyClass = computed(() => ({
|
||||
'farris-notify': true,
|
||||
}));
|
||||
name: 'Notify',
|
||||
props: notifyProps,
|
||||
emits: [],
|
||||
setup(props: NotifyProps, context: SetupContext) {
|
||||
const notifyClass = computed(() => ({
|
||||
'farris-notify': true,
|
||||
}));
|
||||
|
||||
const notifyStyle = computed(() => ({
|
||||
left: '',
|
||||
right: '',
|
||||
top: '',
|
||||
bottom: '',
|
||||
}));
|
||||
const notifyStyle = computed(() => ({
|
||||
left: '',
|
||||
right: '',
|
||||
top: '',
|
||||
bottom: '',
|
||||
}));
|
||||
|
||||
const toasts = computed(() => {
|
||||
return props.toasts ? props.toasts : [];
|
||||
});
|
||||
const toasts = computed(() => {
|
||||
return props.toasts ? props.toasts : [];
|
||||
});
|
||||
|
||||
return () => {
|
||||
return (
|
||||
<div id={props.id} class={notifyClass.value} style={notifyStyle.value}>
|
||||
{toasts.value.map((toastData: NotifyData) => {
|
||||
return <f-toast v-model={toastData} animate={props.animate} onClose={} onClick={}></f-toast>;
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
},
|
||||
|
||||
|
||||
return () => {
|
||||
return (
|
||||
<div id={props.id} class={notifyClass.value} style={notifyStyle.value}>
|
||||
{toasts.value.map((toastData: NotifyData) => {
|
||||
return <f-toast v-model={toastData} animate={props.animate} onClose={} onClick={}></f-toast>;
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
},
|
||||
});
|
||||
|
|
|
@ -1,44 +1,45 @@
|
|||
import { NotifyData } from './notify.props';
|
||||
import { ExtractPropTypes, PropType } from 'vue';
|
||||
|
||||
export type NotifyPosition = 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left' | 'top-center' | 'bottom-center' | 'center-center';
|
||||
|
||||
export type ToastyAnimate =
|
||||
| 'bounceInRight'
|
||||
| 'bounceInLeft'
|
||||
| 'bounceInRight'
|
||||
| 'bounceInLeft'
|
||||
| 'bounceInDown'
|
||||
| 'bounceInUp'
|
||||
| 'bounceIn'
|
||||
| 'fadeIn';
|
||||
| 'bounceInRight'
|
||||
| 'bounceInLeft'
|
||||
| 'bounceInRight'
|
||||
| 'bounceInLeft'
|
||||
| 'bounceInDown'
|
||||
| 'bounceInUp'
|
||||
| 'bounceIn'
|
||||
| 'fadeIn';
|
||||
|
||||
export interface NotifyButton {
|
||||
customClass?: string;
|
||||
text: string;
|
||||
disable?: boolean;
|
||||
onClick?: ($event: Event, component: any) => any;
|
||||
customClass?: string;
|
||||
text: string;
|
||||
disable?: boolean;
|
||||
onClick?: ($event: Event, component: any) => any;
|
||||
}
|
||||
|
||||
export interface NotifyData {
|
||||
type: string;
|
||||
title?: string;
|
||||
msg?: string;
|
||||
/** 按钮列表模板 */
|
||||
buttons?: Array<NotifyButton>;
|
||||
showClose?: boolean;
|
||||
theme?: string;
|
||||
timeout?: number;
|
||||
onAdd?: () => void;
|
||||
onRemove?: () => void;
|
||||
id?: number | string;
|
||||
type: string;
|
||||
title?: string;
|
||||
msg?: string;
|
||||
/** 按钮列表模板 */
|
||||
buttons?: Array<NotifyButton>;
|
||||
showClose?: boolean;
|
||||
theme?: string;
|
||||
timeout?: number;
|
||||
onAdd?: () => void;
|
||||
onRemove?: () => void;
|
||||
id?: number | string;
|
||||
}
|
||||
|
||||
// export interface NotifyData extends NotifyOptions {}
|
||||
|
||||
export const notifyProps = {
|
||||
id: { type: String },
|
||||
animate: { type: String as PropType<ToastyAnimate>, default: 'fadeIn' },
|
||||
position: { type: String as PropType<NotifyPosition>, default: 'toasty-position-top-center' },
|
||||
toasts: { type: Array<NotifyData> },
|
||||
id: { type: String },
|
||||
animate: { type: String as PropType<ToastyAnimate>, default: 'fadeIn' },
|
||||
position: { type: String as PropType<NotifyPosition>, default: 'toasty-position-top-center' },
|
||||
toasts: { type: Array<NotifyData> },
|
||||
};
|
||||
export type NotifyProps = ExtractPropTypes<typeof notifyProps>;
|
||||
|
|
Loading…
Reference in New Issue