diff --git a/packages/ui-vue/components/button-edit/src/composition/types.ts b/packages/ui-vue/components/button-edit/src/composition/types.ts index a041ade..b120936 100644 --- a/packages/ui-vue/components/button-edit/src/composition/types.ts +++ b/packages/ui-vue/components/button-edit/src/composition/types.ts @@ -1,106 +1,106 @@ import { ComputedRef, Ref } from 'vue'; export interface UseButton { - /** - * 附加按钮的Class - */ - buttonClass: ComputedRef>; - /** - * 点击附加按钮事件响应函数 - */ - onClickButton: ($event: Event) => void; - /** - * 鼠标移入附加按钮事件响应函数 - */ - onMouseEnterButton: ($event: MouseEvent) => void; - /** - * 鼠标移出附加按钮事件响应函数 - */ - onMouseLeaveButton: ($event: MouseEvent) => void; - /** - * 鼠标滑过附加按钮事件响应函数 - */ - onMouseOverButton: () => void; + /** + * 附加按钮的Class + */ + buttonClass: ComputedRef>; + /** + * 点击附加按钮事件响应函数 + */ + onClickButton: ($event: Event) => void; + /** + * 鼠标移入附加按钮事件响应函数 + */ + onMouseEnterButton: ($event: MouseEvent) => void; + /** + * 鼠标移出附加按钮事件响应函数 + */ + onMouseLeaveButton: ($event: MouseEvent) => void; + /** + * 鼠标滑过附加按钮事件响应函数 + */ + onMouseOverButton: () => void; } export interface UseClear { - /** - * 启用清空按钮 - */ - enableClearButton: ComputedRef; - /** - * 显示清空按钮 - */ - showClearButton: Ref; - /** - * 清空输入框值事件响应函数 - */ - onClearValue: ($event: Event) => void; - /** - * 鼠标进入输入框事件响应函数 - */ - onMouseEnterTextBox: ($event: MouseEvent) => void; - /** - * 鼠标移出输入框事件响应函数 - */ - onMouseLeaveTextBox: ($event: MouseEvent) => void; + /** + * 启用清空按钮 + */ + enableClearButton: ComputedRef; + /** + * 显示清空按钮 + */ + showClearButton: Ref; + /** + * 清空输入框值事件响应函数 + */ + onClearValue: ($event: Event) => void; + /** + * 鼠标进入输入框事件响应函数 + */ + onMouseEnterTextBox: ($event: MouseEvent) => void; + /** + * 鼠标移出输入框事件响应函数 + */ + onMouseLeaveTextBox: ($event: MouseEvent) => void; } export interface UseTextBox { - /** - * 输入框是否获得焦点 - */ - hasFocusedTextBox: ComputedRef; - /** - * 输入框是否处于只读状态 - */ - isTextBoxReadonly: ComputedRef; - /** - * 输入框Class - */ - textBoxClass: ComputedRef>; - /** - * 输入框提示语 - */ - textBoxPlaceholder: ComputedRef; - /** - * 输入框提示标签 - */ - textBoxTitle: ComputedRef; - /** - * 更新输入框的值并触发change事件 - */ - changeTextBoxValue: (newValue: string, showEmitChangeEmit: boolean) => void; - /** - * 输入框失去焦点事件响应函数 - */ - onBlurTextBox: ($event: Event) => void; - /** - * 鼠标点击输入框事件响应函数 - */ - onClickTextBox: ($event: Event) => void; - /** - * 输入框获得焦点事件响应函数 - */ - onFocusTextBox: ($event: Event) => void; - /** - * 输入框值变化事件 - */ - onInput: ($event: Event) => void; - /** - * 鼠标点击输入框事件响应函数 - */ - onMouseDownTextBox: ($event: MouseEvent) => void; - /** - * 键盘在输入框按下事件 - */ - onKeyDownTextBox: ($event: Event) => void; - /** - * 键盘在输入框抬起事件 - */ - onKeyUpTextBox: ($event: Event) => void; - /** - * 输入框值变化事件响应函数 - */ - onTextBoxValueChange: ($event: Event) => void; + /** + * 输入框是否获得焦点 + */ + hasFocusedTextBox: ComputedRef; + /** + * 输入框是否处于只读状态 + */ + isTextBoxReadonly: ComputedRef; + /** + * 输入框Class + */ + textBoxClass: ComputedRef>; + /** + * 输入框提示语 + */ + textBoxPlaceholder: ComputedRef; + /** + * 输入框提示标签 + */ + textBoxTitle: ComputedRef; + /** + * 更新输入框的值并触发change事件 + */ + changeTextBoxValue: (newValue: string, showEmitChangeEmit: boolean) => void; + /** + * 输入框失去焦点事件响应函数 + */ + onBlurTextBox: ($event: Event) => void; + /** + * 鼠标点击输入框事件响应函数 + */ + onClickTextBox: ($event: Event) => void; + /** + * 输入框获得焦点事件响应函数 + */ + onFocusTextBox: ($event: Event) => void; + /** + * 输入框值变化事件 + */ + onInput: ($event: Event) => void; + /** + * 鼠标点击输入框事件响应函数 + */ + onMouseDownTextBox: ($event: MouseEvent) => void; + /** + * 键盘在输入框按下事件 + */ + onKeyDownTextBox: ($event: Event) => void; + /** + * 键盘在输入框抬起事件 + */ + onKeyUpTextBox: ($event: Event) => void; + /** + * 输入框值变化事件响应函数 + */ + onTextBoxValueChange: ($event: Event) => void; } diff --git a/packages/ui-vue/components/notify/src/components/toast.component.tsx b/packages/ui-vue/components/notify/src/components/toast.component.tsx index 4c49082..33b5836 100644 --- a/packages/ui-vue/components/notify/src/components/toast.component.tsx +++ b/packages/ui-vue/components/notify/src/components/toast.component.tsx @@ -2,6 +2,8 @@ import { computed, defineComponent, ref, SetupContext, watch } from 'vue'; import { NotifyButton, NotifyData } from '../notify.props'; import { ToastProps, toastProps } from './toast.props'; +import './toast.css'; + export default defineComponent({ name: 'Toast', props: toastProps, @@ -41,6 +43,8 @@ export default defineComponent({ const shouldShowTitle = computed(() => toast.value.title && toast.value.msg); + const shouldShowMessageOnly = computed(() => !toast.value.title && toast.value.msg); + const shouldShowCloseButton = computed(() => { return true; }); @@ -108,6 +112,15 @@ export default defineComponent({ {shouldShowButtonsInTitle.value && renderNotifyButtons()} )} + {shouldShowMessageOnly.value && + (toast.value.buttons ? ( +
+ +
{renderNotifyButtons()}
+
+ ) : ( + + ))} )} diff --git a/packages/ui-vue/components/notify/src/components/toast.css b/packages/ui-vue/components/notify/src/components/toast.css new file mode 100644 index 0000000..fa9de4e --- /dev/null +++ b/packages/ui-vue/components/notify/src/components/toast.css @@ -0,0 +1,63 @@ +.toast-title-beforeshow { + opacity: 0; +} +@-webkit-keyframes farrisMoveUpIn { + 0% { + transform: translateY(-100%); + transform-origin: 0 0; + opacity: 0; + } + + 100% { + transform: translateY(0); + transform-origin: 0 0; + opacity: 1; + } +} +@keyframes farrisMoveUpIn { + 0% { + transform: translateY(-100%); + transform-origin: 0 0; + opacity: 0; + } + + 100% { + transform: translateY(0); + transform-origin: 0 0; + opacity: 1; + } +} +@-webkit-keyframes farrisMoveUpOut { + 0% { + transform: translateY(0); + transform-origin: 0 0; + opacity: 1; + } + + 100% { + transform: translateY(-100%); + transform-origin: 0 0; + opacity: 0; + } +} +@keyframes farrisMoveUpOut { + 0% { + transform: translateY(0); + transform-origin: 0 0; + opacity: 1; + } + + 100% { + transform: translateY(-100%); + transform-origin: 0 0; + opacity: 0; + } +} +.toast.fadeIn { + -webkit-animation: farrisMoveUpIn 0.2s linear; + animation: farrisMoveUpIn 0.2s linear; +} +.toast.fadeOut { + -webkit-animation: farrisMoveUpOut 0.2s linear; + animation: farrisMoveUpOut 0.2s linear; +} diff --git a/packages/ui-vue/components/notify/src/notify-container.component.tsx b/packages/ui-vue/components/notify/src/notify-container.component.tsx deleted file mode 100644 index 3094c98..0000000 --- a/packages/ui-vue/components/notify/src/notify-container.component.tsx +++ /dev/null @@ -1,222 +0,0 @@ -import { Component, Input, ViewChildren, QueryList, AfterContentChecked, OnInit, Output, EventEmitter, NgZone, HostListener } from '@angular/core'; -import { NotifyConfig, NotifyData } from './notifiy.options'; -import { isFunction } from 'lodash-es'; -import { NotifyComponent } from './notify.component'; - -@Component({ - selector: 'farris-notify-container', - template: ` -
- -
- ` -}) -export class NotifyContainerComponent implements OnInit, AfterContentChecked { - - static POSITIONS: Array = ['bottom-right', 'bottom-left', - 'top-right', 'top-left', 'top-center', 'bottom-center', 'center-center']; - - static ANIMATES: Array = ['bounceInRight', 'bounceInLeft', - 'bounceInRight', 'bounceInLeft', 'bounceInDown', 'bounceInUp', 'bounceIn']; - - private _position = ''; - style = { - 'left': '', - 'right': '', - 'top': '', - 'bottom': '' - }; - notifyDistance = { - 'left': 12, - 'right': 12, - 'top': 136, - 'bottom': 12 - }; - - animateCls = 'fadeIn'; - - config: NotifyConfig; - - id = ''; - - @ViewChildren(NotifyComponent) notifyCmpList: QueryList; - - - @Output() empty = new EventEmitter(); - - @Input() set position(value: string) { - if (value) { - let notFound = true; - for (let i = 0; i < NotifyContainerComponent.POSITIONS.length; i++) { - if (NotifyContainerComponent.POSITIONS[i] === value) { - notFound = false; - break; - } - } - - if (notFound) { - value = this.config.position; - } - } else { - value = this.config.position; - } - - // console.log(this.config); - - - // if (value === 'center-center') { - // this.animateCls = 'bounceIn'; - // } else { - const i = NotifyContainerComponent.POSITIONS.indexOf(value); - //this.animateCls = NotifyContainerComponent.ANIMATES[i]; - this.animateCls = 'fadeIn'; - //} - - this._position = 'toasty-position-' + value; - - if (this.config.left) { - this.notifyDistance.left = this.config.left; - } - if (this.config.right) { - this.notifyDistance.right = this.config.right; - } - if (this.config.top) { - this.notifyDistance.top = this.config.top; - } - if (this.config.bottom) { - this.notifyDistance.bottom = this.config.bottom; - } - this.initstyle(); - if (value === 'top-left') { - this.style.left = `${this.notifyDistance.left}px`; - this.style.top = `${this.notifyDistance.top}px`; - } - else if (value === 'top-center') { - this.style.top = `${this.notifyDistance.top}px`; - } - else if (value === 'top-right') { - this.style.right = `${this.notifyDistance.right}px`; - this.style.top = `${this.notifyDistance.top}px`; - } - else if (value === 'bottom-left') { - this.style.left = `${this.notifyDistance.left}px`; - this.style.bottom = `${this.notifyDistance.bottom}px`; - } - else if (value === 'bottom-center') { - this.style.bottom = `${this.notifyDistance.bottom}px`; - } - else if (value === 'bottom-right') { - this.style.right = `${this.notifyDistance.right}px`; - this.style.bottom = `${this.notifyDistance.bottom}px`; - } - - } - - get position() { - if (this._position) { - return this._position; - } else { - return 'toasty-position-top-center'; - } - } - - initstyle() { - this.style = { - 'left': '', - 'right': '', - 'top': '', - 'bottom': '' - }; - } - - - toasts: Array = []; - - constructor(private ngZone: NgZone) { } - - ngOnInit() {} - - @HostListener('click', ['$event']) - onContainerClick($event: MouseEvent) { - $event.stopPropagation(); - return false; - } - - ngAfterContentChecked() { - if (this.notifyCmpList && this.notifyCmpList.length) { - this.notifyCmpList.forEach(cmp => { - cmp.close.subscribe(() => { - this.clear(cmp.toast.id); - }); - }); - } - } - - closeToast(toast: NotifyData) { - this.clear(toast.id); - } - - add(notify: NotifyData) { - if (this.toasts.length >= this.config.limit) { - this.toasts.shift(); - } - - this.toasts.push(notify); - - if (notify.timeout) { - this._setTimeout(notify); - } - } - - clear(id: number | string) { - if (id) { - this.toasts.forEach((value: any, key: number) => { - if (value.id === id) { - if (value.onRemove && isFunction(value.onRemove)) { - value.onRemove.call(this, value); - } - - this.toasts.splice(key, 1); - } - }); - - if (this.toasts.length === 0) { - this.empty.emit(); - } - - } else { - throw new Error('Please provide id of Toast to close'); - } - } - - clearAll() { - this.toasts.forEach((value: any, key: number) => { - if (value.onRemove && isFunction(value.onRemove)) { - value.onRemove.call(this, value); - } - }); - this.toasts = []; - this.empty.emit(); - } - - private findNotifyComponent(id: number | string) { - return this.notifyCmpList.find(item => item.toast.id === id); - } - - private _setTimeout(notify: NotifyData) { - // this.ngZone.runOutsideAngular(() => { - window.setTimeout(() => { - // this.clear(notify.id); - const cmp = this.findNotifyComponent(notify.id); - if (cmp) { - cmp.state = true; - cmp.inCls[cmp.animateCls] = false; - } - }, notify.timeout); - // }); - } - btnClickHander(ev, notify: NotifyData) { - const cmp = this.findNotifyComponent(notify.id); - ev.callback(ev['ev'], cmp); - } -} diff --git a/packages/ui-vue/components/notify/src/notify.component.ts b/packages/ui-vue/components/notify/src/notify.component.ts deleted file mode 100644 index c3818e2..0000000 --- a/packages/ui-vue/components/notify/src/notify.component.ts +++ /dev/null @@ -1,223 +0,0 @@ -import { - Component, - OnInit, - OnChanges, - Input, - Output, - EventEmitter, - ViewChild, - ElementRef, - SimpleChanges, - NgZone, - TemplateRef -} from '@angular/core'; -import { NotifyData,NotifyButton } from './notifiy.options'; - -@Component({ - selector: 'farris-notify', - template: ` -
- - -
- - - - {{ btn.text }} - - - `, - styles: [ - ` - .toast-title-beforeshow{ - opacity:0; - } - @-webkit-keyframes farrisMoveUpIn { - 0% { - transform: translateY(-100%); - transform-origin: 0 0; - opacity: 0 - } - - 100% { - transform: translateY(0); - transform-origin: 0 0; - opacity: 1 - } - } - @keyframes farrisMoveUpIn { - 0% { - transform: translateY(-100%); - transform-origin: 0 0; - opacity: 0 - } - - 100% { - transform: translateY(0); - transform-origin: 0 0; - opacity: 1 - } - } - @-webkit-keyframes farrisMoveUpOut { - 0% { - transform: translateY(0); - transform-origin: 0 0; - opacity: 1 - } - - 100% { - transform: translateY(-100%); - transform-origin: 0 0; - opacity: 0 - } - } - @keyframes farrisMoveUpOut { - 0% { - transform: translateY(0); - transform-origin: 0 0; - opacity: 1 - } - - 100% { - transform: translateY(-100%); - transform-origin: 0 0; - opacity: 0 - } - } - .toast.fadeIn { - -webkit-animation: farrisMoveUpIn 0.2s linear; - animation: farrisMoveUpIn 0.2s linear; - } - .toast.fadeOut { - -webkit-animation: farrisMoveUpOut 0.2s linear; - animation: farrisMoveUpOut 0.2s linear; - } - ` - ] -}) -export class NotifyComponent implements OnInit, OnChanges { - @Input() toast: NotifyData; - @Output() close = new EventEmitter(); - @Output() btnClick = new EventEmitter(); - @ViewChild('notifyDiv') notifyDiv: ElementRef; - - _state = false; - @Input() animateCls: string; - outCls = ''; - inCls = {}; - - get state() { - return this._state; - } - - set state(value) { - this._state = value; - if (value) { - this.inCls[this.animateCls] = false; - this.inCls['animated'] = value; - this.inCls[this.outCls] = value; - // this.ngZone.runOutsideAngular(() => { - setTimeout(() => { - this.close.next(this.toast); - }, 200); - // }); - } - } - - constructor(private ngZone: NgZone) { } - - ngOnInit() { - if (this.toast.buttons) { - this.ngZone.runOutsideAngular(() => { - setTimeout(() => { - let closeEl = this.notifyDiv.nativeElement.querySelector('.toast-close'); - let contentEl =this.notifyDiv.nativeElement.querySelector('.toast-title-btns-wrapper'); - if(closeEl['clientHeight']+10 ({ 'farris-notify': true, })); + const defaultNotifyDistance = { + left: 12, + right: 12, + top: 136, + bottom: 12, + }; + + const toasts = ref(props.toasts || []); + const notifyStyle = computed(() => ({ - left: '', - right: '', - top: '', - bottom: '', + left: props.position.indexOf('left') > -1 ? `${props.left ? props.left : defaultNotifyDistance.left}px` : '', + right: props.position.indexOf('right') > -1 ? `${props.right ? props.right : defaultNotifyDistance.right}px` : '', + top: props.position.indexOf('top') > -1 ? `${props.top ? props.top : defaultNotifyDistance.top}px` : '', + bottom: props.position.indexOf('bottom') > -1 ? `${props.bottom ? props.bottom : defaultNotifyDistance.bottom}px` : '', })); - const toasts = computed(() => { - return props.toasts ? props.toasts : []; - }); + function closeToast(toast: NotifyData) {} + function addToast(toast: NotifyData) { + if (toasts.value.length >= props.limit) { + toasts.value.shift(); + } + toasts.value.push(toast); + // if (props.timeout) { + // this._setTimeout(notify); + // } + } + function invokeToastOnRemoveCallback(toast: NotifyData) { + if (toast && toast.onRemove && isFunction(toast.onRemove)) { + toast.onRemove.call(this, toast); + } + } + + function clear(id: number | string) { + const targetToastIndex = toasts.value.findIndex((toast: NotifyData) => toast.id === id); + if (targetToastIndex > -1) { + const targetToast = toasts.value[targetToastIndex]; + invokeToastOnRemoveCallback(targetToast); + toasts.value.splice(targetToastIndex, 1); + } + } + + function clearAll() { + toasts.value.forEach((toast: NotifyData) => invokeToastOnRemoveCallback(toast)); + toasts.value.length = 0; + context.emit('empty'); + } + + context.expose({ addToast, clear, clearAll, closeToast }); + + function onClose($event: Event, toast: NotifyData) { + closeToast(toast); + } + function onClick($event: Event) {} return () => { return (
{toasts.value.map((toastData: NotifyData) => { - return ; + return ( + onClose($event, toastData)} + onClick={onClick}> + ); })}
); diff --git a/packages/ui-vue/components/notify/src/notify.props.ts b/packages/ui-vue/components/notify/src/notify.props.ts index 60bc455..63aed85 100644 --- a/packages/ui-vue/components/notify/src/notify.props.ts +++ b/packages/ui-vue/components/notify/src/notify.props.ts @@ -1,4 +1,3 @@ -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'; @@ -13,6 +12,8 @@ export type ToastyAnimate = | 'bounceIn' | 'fadeIn'; +export type NotifyTheme = 'default' | 'material' | 'bootstrap'; + export interface NotifyButton { customClass?: string; text: string; @@ -37,9 +38,18 @@ export interface NotifyData { // export interface NotifyData extends NotifyOptions {} export const notifyProps = { + limit: { type: Number, default: 5 }, + showCloseButton: { type: Boolean, default: true }, + position: { type: String as PropType, default: 'top-center' }, + timeout: { type: Number, default: 3000 }, + theme: { type: String as PropType, default: 'bootstrap' }, + left: { type: Number }, + right: { type: Number }, + top: { type: Number }, + bottom: { type: Number }, id: { type: String }, animate: { type: String as PropType, default: 'fadeIn' }, - position: { type: String as PropType, default: 'toasty-position-top-center' }, toasts: { type: Array }, + options: { type: Object as PropType }, }; export type NotifyProps = ExtractPropTypes; diff --git a/packages/ui-vue/components/popover/src/popover.component.tsx b/packages/ui-vue/components/popover/src/popover.component.tsx index 2735fd0..41ed995 100644 --- a/packages/ui-vue/components/popover/src/popover.component.tsx +++ b/packages/ui-vue/components/popover/src/popover.component.tsx @@ -18,7 +18,7 @@ export default defineComponent({ <>
{shouldShowTitle.value &&

{props.title}

} -
+
{context.slots.default && context.slots?.default()}
); }; diff --git a/packages/ui-vue/components/popover/src/popover.props.ts b/packages/ui-vue/components/popover/src/popover.props.ts index f114678..f048f7f 100644 --- a/packages/ui-vue/components/popover/src/popover.props.ts +++ b/packages/ui-vue/components/popover/src/popover.props.ts @@ -1,7 +1,10 @@ -import { ExtractPropTypes } from 'vue'; +import { ExtractPropTypes, PropType } from 'vue'; + +export type PopoverPosition = 'top' | 'bottom' | 'left' | 'right' | 'auto'; export const popoverProps = { title: { type: String }, + position: { type: String as PropType, default: 'top' }, }; export type PopoverProps = ExtractPropTypes;