UNPKG

ano-ui

Version:

<p align="center"> <img src="https://github.com/ano-ui/ano-ui/raw/main/public/logo.svg" style="width:100px;" /> <h1 align="center">Ano-UI (WIP)</h1> <p align="center">An UniApp UI components with UnoCSS.</p> </p> <p align="center"> <a href="https://www.np

1,256 lines (1,199 loc) 33.6 kB
export * from '@ano-ui/preset'; import { getCurrentInstance, onMounted, computed, inject, ref, watch, provide, useSlots } from 'vue'; const UPDATE_MODEL_EVENT = "update:modelValue"; const UPDATE_SHOW_EVENT = "update:show"; const CHANGE_EVENT = "change"; const INPUT_EVENT = "input"; const CLICK_EVENT = "click"; const OPEN_EVENT = "open"; const CLOSE_EVENT = "close"; const OPENED_EVENT = "opened"; const CLOSED_EVENT = "closed"; const FOCUS_EVENT = "focus"; const BLUR_EVENT = "blur"; const CONFIRM_EVENT = "confirm"; const CLEAR_EVENT = "clear"; const CANCEL_EVENT = "cancel"; const useCustomClassProp = { type: [String, Object, Array], default: "" }; const useCustomStyleProp = { type: [String, Object, Array], default: "" }; const useVariantProp = { type: String, default: "solid" }; const sizeList = ["mini", "small", "normal", "large"]; const useSizeProp = { type: String, validator: (value) => sizeList.includes(value), default: "normal" }; const typeList = ["default", "primary", "success", "info", "warning", "danger"]; const useTypeProp = { type: String, validator: (value) => typeList.includes(value), default: "default" }; const directionList = ["vertical", "horizontal"]; const useDirectionProp = { type: String, validator: (value) => directionList.includes(value), default: "vertical" }; const positionList = ["top", "bottom", "left", "right", "center"]; const PositionProp = { type: String, validator: (value) => positionList.includes(value), default: "center" }; const toString = Object.prototype.toString; function is(val, type) { return toString.call(val) === `[object ${type}]`; } function isDef(val) { return typeof val !== "undefined"; } function isUnDef(val) { return !isDef(val); } function isObject(val) { return val !== null && is(val, "Object"); } function isEmpty(val) { if (isArray(val) || isString(val)) return val.length === 0; if (val instanceof Map || val instanceof Set) return val.size === 0; if (isObject(val)) return Object.keys(val).length === 0; return false; } function isDate(val) { return is(val, "Date"); } function isNull(val) { return val === null; } function isNullAndUnDef(val) { return isUnDef(val) && isNull(val); } function isNullOrUnDef(val) { return isUnDef(val) || isNull(val); } function isNumber(val) { return is(val, "Number"); } function isPromise(val) { return is(val, "Promise") && isObject(val) && isFunction(val.then) && isFunction(val.catch); } function isString(val) { return is(val, "String"); } function isFunction(val) { return typeof val === "function"; } function isBoolean(val) { return is(val, "Boolean"); } function isRegExp(val) { return is(val, "RegExp"); } function isArray(val) { return val && Array.isArray(val); } function isWindow(val) { return typeof window !== "undefined" && is(val, "Window"); } function isElement(val) { return isObject(val) && !!val.tagName; } function isMap(val) { return is(val, "Map"); } function isUrl(path) { const reg = /^http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?/; return reg.test(path); } const unknownProp = null; const numericProp = [Number, String]; const truthProp = { type: Boolean, default: true }; function makeRequiredProp(type) { return { type, required: true }; } function makeArrayProp(defaultVal = []) { return { type: Array, default: () => defaultVal }; } function makeNumberProp(defaultVal) { return { type: Number, default: defaultVal }; } function makeNumericProp(defaultVal) { return { type: numericProp, default: defaultVal }; } function makeStringProp(defaultVal) { return { type: String, default: defaultVal }; } function createDeferred() { let resolve = noop; let reject = noop; const promise = new Promise((_resolve, _reject) => { resolve = _resolve; reject = _reject; }); promise.resolve = resolve; promise.reject = reject; return promise; } function toArray(value) { if (!value) return []; return Array.isArray(value) ? value : [value]; } function guid() { const s4 = () => Math.floor((1 + Math.random()) * 65536).toString(16).slice(1); return `${s4() + s4()}`; } function delay(ms) { const promise = createDeferred(); setTimeout(promise.resolve, ms); return promise; } function noop() { } function createQuerySelector(type, mode = "select") { const ready = createDeferred(); const instance = getCurrentInstance(); function query(selector, fields = {}) { const promise = createDeferred(); function resolve(value) { const result = toArray(value); const resolved = mode === "select" ? result[0] : result; result.length ? promise.resolve(resolved) : promise.reject(); } ready.then(() => { const query2 = uni.createSelectorQuery().in(instance)[mode](selector); if (type === "fields") query2.fields(fields, resolve).exec(); else query2[type](resolve).exec(); }); return promise; } onMounted(ready.resolve); return query; } function useQuerySelector(...args) { return createQuerySelector(args[0], "select"); } function useQuerySelectorAll(...args) { return createQuerySelector(args[0], "selectAll"); } const avatarGroupProps = { customClass: useCustomClassProp, customStyle: useCustomStyleProp, max: Number, options: makeArrayProp() }; const avatarGroupEmits = { [CLICK_EVENT]: (evt) => evt instanceof Object }; function useAvatarGroup(props, emit) { const className = computed(() => []); const clickHandler = (evt) => { emit(CLICK_EVENT, evt); }; const spliceOptions = computed(() => { const options = props.options || []; return props.max ? options.slice(0, props.max - 1) : options; }); const reset = computed(() => { const length = (props.options || []).length; return length - (props.max || 0) + 1; }); const lt = computed(() => { const length = (props.options || []).length; return length > (props.max || 0); }); return { className, spliceOptions, reset, lt, clickHandler }; } const useAvatarSizeProp = useSizeProp; const avatarProps = { customClass: useCustomClassProp, customStyle: useCustomStyleProp, size: useAvatarSizeProp, src: String, fit: makeStringProp("cover") }; const avatarEmits = { [CLICK_EVENT]: (evt) => evt instanceof Object }; const sizeClasses = { mini: "w-8", small: "w-10", normal: "w-12", large: "w-14" }; function useAvatar(props, emit) { const classes = computed(() => { const sizeClass = sizeClasses[props.size]; return sizeClass ? [sizeClass] : []; }); function clickHandler(evt) { emit(CLICK_EVENT, evt); } const mode = computed(() => { const modes = { fill: "aspectFit", cover: "aspectFill", contain: "scaleToFill" }; return modes[props.fit]; }); return { classes, clickHandler, mode }; } const useButtonTypeProp = useTypeProp; const useButtonSizeProp = useSizeProp; const buttonProps = { customClass: useCustomClassProp, customStyle: useCustomStyleProp, type: useButtonTypeProp, size: useButtonSizeProp, variant: useVariantProp, disabled: Boolean, icon: String, openType: String, block: Boolean, loading: Boolean }; const buttonEmits = { [CLICK_EVENT]: (evt) => evt instanceof Object }; function useButton(props, emit) { const disabled = computed(() => props.disabled || props.loading); function clickHandler(evt) { if (disabled.value) return; emit(CLICK_EVENT, evt); } const classes = computed(() => [ `a-${props.type}`, props.type === "default" && "a-type-default", `a-button-${props.size}`, `a-${props.variant}`, props.block ? "w-full flex" : "inline-flex", disabled.value ? "op-50" : "" ]); return { disabled, classes, clickHandler }; } const cellProps = { customClass: useCustomClassProp, customStyle: useCustomStyleProp, title: String, value: String, label: String, icon: String, arrow: { type: [Boolean, String] }, center: Boolean, clickable: Boolean, disabled: Boolean, titleClass: useCustomClassProp, titleStyle: useCustomStyleProp, valueClass: useCustomClassProp, valueStyle: useCustomStyleProp, labelClass: useCustomClassProp, labelStyle: useCustomStyleProp }; const cellEmits = { [CLICK_EVENT]: (evt) => evt instanceof Object }; const checkboxGroupKey = Symbol("checkboxGroupKey"); const radioGroupKey = Symbol("radioGroupKey"); const cellGroupKey = Symbol("cellGroupKey"); const collapseContextKey = Symbol("collapseContextKey"); function useCell(props, emit) { const cellGroup = inject(cellGroupKey, void 0); const arrow = computed(() => cellGroup?.arrow || props.arrow); const clickable = computed(() => cellGroup?.clickable || props.clickable); const classes = computed(() => { const _classes = []; if (arrow.value || clickable.value) _classes.push("a-active-h5"); return _classes; }); function clickHandler(evt) { emit(CLICK_EVENT, evt); } return { arrow, clickable, classes, clickHandler }; } const popupProps = { customClass: useCustomClassProp, customStyle: useCustomStyleProp, show: Boolean, position: PositionProp, duration: makeNumberProp(200) }; const popupEmits = { [UPDATE_SHOW_EVENT]: (value) => isBoolean(value), [OPEN_EVENT]: () => true, [CLOSE_EVENT]: () => true, [OPENED_EVENT]: () => true, [CLOSED_EVENT]: () => true }; function usePopup(props, emit) { const show = ref(props.show || false); const showValue = computed({ get: () => props.show || show.value, set(val) { if (val) emit(OPEN_EVENT); else emit(CLOSE_EVENT); show.value = val; emit(UPDATE_SHOW_EVENT, val); } }); const classes = computed(() => { const { position } = props; return [ position === "center" && "left-50% top-50% translate--50%", position === "top" && "top-0 left-0 right-0", position === "bottom" && "bottom-0 left-0 right-0", position === "left" && "left-0 top-0 bottom-0", position === "right" && "right-0 top-0 bottom-0" ]; }); return { showValue, classes }; } const toastProps = { customClass: useCustomClassProp, customStyle: useCustomStyleProp }; const toastEmits = { [CLOSE_EVENT]: () => true }; function useToast(props, emit) { let timer; const visible = ref(false); const state = ref(); function close() { clearTimeout(timer); visible.value = false; emit(CLOSE_EVENT); } function show(options = {}) { const { position = "default", message = "", duration = 2e3, type } = options; visible.value = true; state.value = { type, position, message, duration }; clearTimeout(timer); if (state.value.duration !== false) timer = setTimeout(close, state.value.duration); } const classes = computed(() => { return [ state.value?.position === "default" && "left-50% top-50% translate--50%", state.value?.position === "top" && "left-50% top-20% translate--50%", state.value?.position === "bottom" && "left-50% top-80% translate--50%" ]; }); return { state, show, close, visible, classes }; } const useCheckboxTypeProp = useTypeProp; const useCheckboxSizeProp = useSizeProp; const checkboxProps = { customClass: useCustomClassProp, customStyle: useCustomStyleProp, type: useCheckboxTypeProp, size: useCheckboxSizeProp, variant: useVariantProp, disabled: Boolean, modelValue: { type: [Number, String, Boolean], default: void 0 }, value: { type: [String, Number, Boolean], default: "" }, label: String, icon: String, customIcon: Boolean, labelDisabled: Boolean }; const checkboxEmits = { [UPDATE_MODEL_EVENT]: (val) => isString(val) || isNumber(val) || isBoolean(val), [CHANGE_EVENT]: (val) => isString(val) || isNumber(val) || isBoolean(val) }; function useCheckbox(props, emit) { const checkboxGroup = inject(checkboxGroupKey, void 0); const isGroup = computed(() => !!checkboxGroup); const size = computed(() => checkboxGroup?.size ?? props.size); const min = computed(() => checkboxGroup?.min); const max = computed(() => checkboxGroup?.max); const modelValue = computed(() => isGroup.value ? checkboxGroup.modelValue : props.modelValue); const disabled = computed(() => { if (!isGroup.value) return props.disabled; const { disabled: disabled2, min: min2, max: max2 } = checkboxGroup; if (disabled2) return true; if (isGroup.value && isArray(modelValue.value)) { if (min2 !== -1 && modelValue.value.length === min2) return modelValue.value.includes(props.value); if (max2 !== -1 && modelValue.value.length === max2) return !modelValue.value.includes(props.value); } return false; }); const labelDisabled = computed(() => props.labelDisabled || (checkboxGroup?.labelDisabled ?? false)); const checked = computed(() => { if (isGroup.value) { const value = checkboxGroup.modelValue; return Array.isArray(value) ? value.includes(props.value) : value === props.value; } else { return props.modelValue; } }); const toggle = (e) => { e.stopPropagation(); if (isGroup.value && isArray(modelValue.value)) { const newValue = [...modelValue.value]; newValue.includes(props.value) ? newValue.splice(newValue.indexOf(props.value), 1) : newValue.push(props.value); checkboxGroup.changeEvent(newValue); } else { emit && emit(UPDATE_MODEL_EVENT, !props.modelValue); } emit && emit(CHANGE_EVENT, !props.modelValue); }; const iconClickHandler = (e) => { if (disabled.value) return; toggle(e); }; const labelClickHandler = (e) => { if (labelDisabled.value || disabled.value) return; toggle(e); }; return { checkboxGroup, isGroup, size, min, max, disabled, modelValue, checked, iconClickHandler, labelClickHandler, toggle }; } const useCheckboxGroupDirectionProp = useDirectionProp; const checkboxGroupProps = { customClass: useCustomClassProp, customStyle: useCustomStyleProp, modelValue: makeArrayProp(), size: useCheckboxSizeProp, direction: useCheckboxGroupDirectionProp, min: makeNumberProp(-1), max: makeNumberProp(-1), disabled: Boolean, labelDisabled: Boolean }; const checkboxGroupEmits = { [UPDATE_MODEL_EVENT]: (val) => isArray(val), [CHANGE_EVENT]: (val) => isArray(val) }; const useFieldTypeProp = { type: String, validator: (value) => ["text", "number", "digit", "password", "textarea"].includes(value), default: "text" }; const useFieldLabelAlignProp = { type: String, validator: (value) => ["left", "right", "top", "center"].includes(value), default: "left" }; const useFieldInputAlignProp = { type: String, validator: (value) => ["left", "right"].includes(value), default: "left" }; const fieldProps = { customClass: useCustomClassProp, customStyle: useCustomStyleProp, type: useFieldTypeProp, label: String, labelAlign: useFieldLabelAlignProp, inputAlign: useFieldInputAlignProp, disabled: Boolean, focus: Boolean, icon: String, suffixIcon: String, showClear: Boolean, placeholder: String, modelValue: String, maxlength: makeNumberProp(-1), showWordLimit: Boolean }; const fieldEmits = { [UPDATE_MODEL_EVENT]: (value) => isString(value), [CLICK_EVENT]: (evt) => evt instanceof Object, [FOCUS_EVENT]: () => true, [BLUR_EVENT]: () => true, [INPUT_EVENT]: (value) => isString(value), [CHANGE_EVENT]: (value) => isString(value), [CLEAR_EVENT]: () => true }; function useField(props, emit) { const disabled = computed(() => props.disabled ?? false); const modelValue = computed(() => props.modelValue || ""); const placeholderText = computed(() => props.placeholder || ""); const isClick = ref(false); const showPasswordText = ref(false); const focus = computed(() => props.focus && !props.disabled || isClick.value); const clickHandler = (evt) => { evt.stopPropagation(); if (!props.disabled) isClick.value = true; }; const focusHandler = () => { if (!props.disabled) emit(FOCUS_EVENT); }; const blurHandler = () => { isClick.value = false; emit(BLUR_EVENT); }; const inputHandler = (e) => { const _e = e; emit(UPDATE_MODEL_EVENT, _e.detail.value); emit(INPUT_EVENT, _e.detail.value); emit(CHANGE_EVENT, _e.detail.value); }; const clearHandler = () => { emit(UPDATE_MODEL_EVENT, ""); emit(INPUT_EVENT, ""); emit(CHANGE_EVENT, ""); emit(CLEAR_EVENT); }; return { disabled, modelValue, placeholderText, isClick, showPasswordText, focus, focusHandler, clickHandler, blurHandler, inputHandler, clearHandler }; } const useRadioTypeProp = useTypeProp; const useRadioSizeProp = useSizeProp; const radioProps = { customClass: useCustomClassProp, customStyle: useCustomStyleProp, type: useRadioTypeProp, size: useRadioSizeProp, variant: useVariantProp, disabled: Boolean, modelValue: { type: [String, Number, Boolean], default: "" }, value: { type: [String, Number, Boolean], default: "" }, label: String, icon: String, customIcon: Boolean }; const radioEmits = { [UPDATE_MODEL_EVENT]: (val) => isString(val) || isNumber(val) || isBoolean(val), [CHANGE_EVENT]: (val) => isString(val) || isNumber(val) || isBoolean(val) }; function useRadio(props, emit) { const radioGroup = inject(radioGroupKey, void 0); const isGroup = computed(() => !!radioGroup); const size = computed(() => radioGroup?.size ?? props.size); const disabled = computed(() => radioGroup?.disabled ? radioGroup?.disabled : props.disabled); const modelValue = computed(() => isGroup.value ? radioGroup.modelValue : props.modelValue); const checked = computed(() => isGroup.value ? radioGroup.modelValue === props.value : props.modelValue); const toggle = (e) => { e.stopPropagation(); if (disabled.value) return; const newValue = typeof modelValue.value === "string" ? props.value : !modelValue.value; if (isGroup.value) radioGroup.changeEvent(newValue); else if (!checked.value) emit && emit(UPDATE_MODEL_EVENT, newValue); else return; emit && emit(CHANGE_EVENT, newValue); }; return { radioGroup, isGroup, size, disabled, modelValue, checked, toggle }; } const useRadioGroupDirectionProp = useDirectionProp; const radioGroupProps = { customClass: useCustomClassProp, customStyle: useCustomStyleProp, modelValue: { type: [String, Number, Boolean], default: "" }, size: useRadioSizeProp, direction: useRadioGroupDirectionProp, min: makeNumberProp(-1), max: makeNumberProp(-1), disabled: Boolean }; const radioGroupEmits = radioEmits; const useSwitchTypeProp = useTypeProp; const useSwitchSizeProp = useSizeProp; const switchProps = { customClass: useCustomClassProp, customStyle: useCustomStyleProp, type: useSwitchTypeProp, size: useSwitchSizeProp, variant: useVariantProp, disabled: Boolean, modelValue: { type: [String, Number, Boolean], default: false }, activeValue: { type: [String, Number, Boolean], default: true }, activeLabel: String, inactiveValue: { type: [String, Number, Boolean], default: false }, inactiveLabel: String, showIcon: truthProp, icon: String, loading: Boolean, customIcon: Boolean }; const switchEmits = { [UPDATE_MODEL_EVENT]: (val) => isString(val) || isNumber(val) || isBoolean(val), [CHANGE_EVENT]: (val) => isString(val) || isNumber(val) || isBoolean(val) }; function useSwitch(props, emit) { const disabled = computed(() => props.disabled || props.loading); const modelValue = computed(() => props.modelValue); const checked = computed(() => props.modelValue === props.activeValue); function toggle(evt) { evt.stopPropagation(); if (disabled.value) return; const newValue = modelValue.value === props.activeValue ? props.inactiveValue : props.activeValue; emit(UPDATE_MODEL_EVENT, newValue); emit(CHANGE_EVENT, newValue); } const dotTranslateClasses = computed(() => { if (props.size === "mini") return "translate-x-4.5"; if (props.size === "small") return "translate-x-5.5"; if (props.size === "large") return "translate-x-7.5"; return "translate-x-6.5"; }); return { disabled, modelValue, checked, dotTranslateClasses, toggle }; } const actionSheetProps = { customClass: useCustomClassProp, customStyle: useCustomStyleProp, show: Boolean, actions: makeArrayProp(), title: String, cancelText: String, description: String, closeable: truthProp, duration: makeNumberProp(300), round: truthProp }; const actionSheetEmits = { [UPDATE_SHOW_EVENT]: (value) => isBoolean(value), [OPEN_EVENT]: () => true, [CLOSE_EVENT]: () => true, [OPENED_EVENT]: () => true, [CLOSED_EVENT]: () => true, [CANCEL_EVENT]: () => true }; function useActionSheet(props, emit) { const show = ref(props.show || false); const showValue = computed({ get: () => props.show || show.value, set(val) { if (val) emit(OPEN_EVENT); else emit(CLOSE_EVENT); show.value = val; emit(UPDATE_SHOW_EVENT, val); } }); const cancelHandler = () => { showValue.value = false; emit(CANCEL_EVENT); }; return { showValue, cancelHandler }; } const dialogProps = { customClass: useCustomClassProp, customStyle: useCustomStyleProp, show: Boolean, title: String, message: String, showConfirmButton: truthProp, showCancelButton: Boolean, confirmButtonText: String, cancelButtonText: String }; const dialogEmits = { [CONFIRM_EVENT]: () => true, [CANCEL_EVENT]: () => true }; function useDialog(props, emit) { const show = ref(props.show || false); const showValue = computed(() => props.show || show.value); const dialogStatus = ref({}); const showDialog = (options) => { dialogStatus.value = { title: options.title ?? props.title, message: options.message ?? props.message, showConfirmButton: options.showConfirmButton ?? props.showConfirmButton, showCancelButton: options.showCancelButton ?? props.showCancelButton, confirmButtonText: options.confirmButtonText ?? props.confirmButtonText, cancelButtonText: options.cancelButtonText ?? props.cancelButtonText }; show.value = true; }; const onConfirm = () => { show.value = false; emit(CONFIRM_EVENT); }; const onCancel = () => { show.value = false; emit(CANCEL_EVENT); }; return { showValue, dialogStatus, showDialog, onConfirm, onCancel }; } const notifyPositionList = ["default", "top", "top-left", "top-right", "bottom", "bottom-left", "bottom-right"]; const useNotifyTypeProp = useTypeProp; const useNotifyPositionProp = { type: String, validator: (value) => notifyPositionList.includes(value), default: "default" }; const notifyProps = { customClass: useCustomClassProp, customStyle: useCustomStyleProp, type: useNotifyTypeProp, position: useNotifyPositionProp, message: String, duration: makeNumberProp(300), showIcon: Boolean, customIcon: Boolean, showClose: Boolean }; const notifyEmits = { [CLOSE_EVENT]: () => true }; function useNotify(props, emit) { const timer = ref(); const visible = ref(false); const state = ref({}); function close() { if (timer.value) clearTimeout(timer.value); visible.value = false; emit(CLOSE_EVENT); } function show(options = {}) { state.value = { type: options.type ?? "primary", position: options.position ?? props.position, message: options.message ?? props.message, duration: options.duration ?? props.duration, showIcon: options.showIcon ?? props.showIcon, customIcon: options.customIcon ?? props.customIcon, showClose: options.showClose ?? props.showClose }; visible.value = true; if (timer.value) clearTimeout(timer.value); timer.value = setTimeout(close, state.value.duration); } const classes = computed(() => { return [ state.value?.position === "default" && "top-0 left-0 right-0", state.value?.position === "top" && "top-0 left-5 right-5 pt-5", state.value?.position === "top-left" && "top-0 left-0 pt-5 pl-5", state.value?.position === "top-right" && "top-0 right-0 pt-5 pr-5", state.value?.position === "bottom" && "!top-auto bottom-0 left-5 right-5 mb-safe pb-5", state.value?.position === "bottom-left" && "!top-auto bottom-5 left-5 mb-safe pl-5", state.value?.position === "bottom-right" && "!top-auto bottom-5 right-5 mb-safe pr-5" ]; }); return { visible, state, classes, show, close }; } const overlayProps = { customClass: useCustomClassProp, customStyle: useCustomStyleProp, show: Boolean, duration: makeNumberProp(200) }; const overlayEmits = { [CLICK_EVENT]: (evt) => evt instanceof Object }; function useOverlay(props, emit) { const showValue = computed(() => props.show || false); const clickHandler = (evt) => { emit(CLICK_EVENT, evt); }; return { showValue, clickHandler }; } const collapseProps = { customClass: useCustomClassProp, customStyle: useCustomStyleProp, modelValue: { type: [String, Number, Array] }, accordion: Boolean }; const collapseEmits = { [UPDATE_MODEL_EVENT]: (val) => isString(val) || isNumber(val) || isArray(val), [CHANGE_EVENT]: (val) => isString(val) || isNumber(val) || isArray(val) }; function useCollapse(props, emit) { const activeNames = ref(toArray(props.modelValue)); function setActiveNames(_activeNames) { activeNames.value = _activeNames; const value = props.accordion ? activeNames.value[0] : activeNames.value; emit(UPDATE_MODEL_EVENT, value); emit(CHANGE_EVENT, value); } function handleItemClick(name) { if (props.accordion) { setActiveNames([activeNames.value[0] === name ? "" : name]); } else { const _activeNames = [...activeNames.value]; const index = _activeNames.indexOf(name); if (index > -1) _activeNames.splice(index, 1); else _activeNames.push(name); setActiveNames(_activeNames); } } watch( () => props.modelValue, () => activeNames.value = toArray(props.modelValue), { deep: true } ); provide(collapseContextKey, { activeNames, handleItemClick }); return { activeNames, setActiveNames }; } const noticeBarProps = { customClass: useCustomClassProp, customStyle: useCustomStyleProp, type: useTypeProp, variant: useVariantProp, show: truthProp, loop: Boolean, icon: String, showClose: Boolean }; const noticeBarEmits = { [CLOSE_EVENT]: () => true }; function useNoticeBar(props, emit) { const handleClose = () => { emit(CLOSE_EVENT); }; return { handleClose }; } const useTagTypeProp = useTypeProp; const useTagSizeProp = useSizeProp; const tagProps = { customClass: useCustomClassProp, customStyle: useCustomStyleProp, type: useTagTypeProp, size: useTagSizeProp, variant: useVariantProp, label: String, disabled: Boolean, show: truthProp, closable: Boolean, icon: String, iconOnly: Boolean }; const tagEmits = { [CLICK_EVENT]: (evt) => evt instanceof Object, [CLOSE_EVENT]: (evt) => evt instanceof Object }; function useTag(props, emit) { const disabled = computed(() => props.disabled); function clickHandler(evt) { if (disabled.value) return; emit(CLICK_EVENT, evt); } function closeHandler(evt) { if (props.disabled) return; emit(CLOSE_EVENT, evt); } const classes = computed(() => [ `a-${props.type}`, props.type === "default" && "a-type-default", `a-tag-${props.size}`, `a-${props.variant}`, { "!p-0.5 aspect-square": props.iconOnly }, { "op-50": disabled.value } ]); return { disabled, classes, clickHandler, closeHandler }; } const useBadgeProp = useTypeProp; const useBadgeOffsetProp = { type: Array }; const badgeProps = { customClass: useCustomClassProp, customStyle: useCustomStyleProp, type: useBadgeProp, color: String, dot: Boolean, offset: useBadgeOffsetProp, showZero: truthProp, max: Number, value: numericProp, processing: Boolean }; const tabBarItemEmits = { [CLICK_EVENT]: (evt) => evt instanceof Object, [UPDATE_MODEL_EVENT]: (val) => isString(val) || isNumber(val), [CHANGE_EVENT]: (val) => isString(val) || isNumber(val) }; const tabBarProps = { customClass: useCustomClassProp, customStyle: useCustomStyleProp, modelValue: makeNumericProp("") }; const tabBarEmits = tabBarItemEmits; const navBarProps = { customClass: useCustomClassProp, customStyle: useCustomStyleProp, title: String, height: numericProp, fixed: Boolean, zIndex: numericProp, border: truthProp, leftText: String, rightText: String, leftArrow: Boolean, placeholder: Boolean, clickable: truthProp }; const navBarEmits = { clickLeft: (evt) => evt instanceof Object, clickRight: (evt) => evt instanceof Object }; function useNavBar(props, emit) { const systemInfo = uni.getSystemInfoSync(); const navBarRef = ref(); const statusBarHeight = systemInfo.statusBarHeight ?? 0; const navBarHeight = computed(() => { const propsHeight = Number(props.height); let defaultHeight = 44; if (props.fixed) { const menuButtonInfo = uni.getMenuButtonBoundingClientRect(); const menuHeight = menuButtonInfo.height; const menuTop = menuButtonInfo.top; defaultHeight = (menuTop - statusBarHeight) * 2 + menuHeight; } return propsHeight || defaultHeight; }); const className = computed(() => { const { fixed, border } = props; return [ { "a-nav-bar-fixed": fixed, "a-hairline-bottom": border } ]; }); const clickableClassName = computed(() => { const { clickable } = props; let className2 = ""; className2 = clickable ? "cursor-pointer a-nav-bar-clickable-hover-h5" : ""; return className2; }); const navBarStyle = computed(() => { return props.fixed ? { paddingTop: `${statusBarHeight}px` } : {}; }); const navBarContentStyle = computed(() => { return { height: `${navBarHeight.value}px` }; }); const placeholderStyle = computed(() => { return { width: "100%", height: `${navBarHeight.value + statusBarHeight}px` }; }); const zIndexStyle = computed(() => { return props.zIndex ? { zIndex: Number(props.zIndex) } : {}; }); const slots = useSlots(); const hasLeft = computed(() => props.leftArrow || props.leftText || slots.left); const hasRight = computed(() => props.rightText || slots.right); const clickLeftHandler = (evt) => { emit("clickLeft", evt); }; const clickRightHandler = (evt) => { emit("clickRight", evt); }; return { navBarRef, hasLeft, hasRight, className, clickableClassName, zIndexStyle, placeholderStyle, navBarStyle, navBarContentStyle, navBarHeight, statusBarHeight, clickLeftHandler, clickRightHandler }; } function AnoResolver() { return { type: "component", resolve: (name) => { if (name.match(/^A[A-Z]/)) return { name, from: `ano-ui/components/${name}/${name}.vue` }; } }; } export { AnoResolver, PositionProp, actionSheetEmits, actionSheetProps, avatarEmits, avatarGroupEmits, avatarGroupProps, avatarProps, badgeProps, buttonEmits, buttonProps, cellEmits, cellGroupKey, cellProps, checkboxEmits, checkboxGroupEmits, checkboxGroupKey, checkboxGroupProps, checkboxProps, collapseContextKey, collapseEmits, collapseProps, createDeferred, delay, dialogEmits, dialogProps, fieldEmits, fieldProps, guid, is, isArray, isBoolean, isDate, isDef, isElement, isEmpty, isFunction, isMap, isNull, isNullAndUnDef, isNullOrUnDef, isNumber, isObject, isPromise, isRegExp, isString, isUnDef, isUrl, isWindow, makeArrayProp, makeNumberProp, makeNumericProp, makeRequiredProp, makeStringProp, navBarEmits, navBarProps, noop, noticeBarEmits, noticeBarProps, notifyEmits, notifyPositionList, notifyProps, numericProp, overlayEmits, overlayProps, popupEmits, popupProps, radioEmits, radioGroupEmits, radioGroupKey, radioGroupProps, radioProps, switchEmits, switchProps, tabBarEmits, tabBarProps, tagEmits, tagProps, toArray, toastEmits, toastProps, truthProp, unknownProp, useActionSheet, useAvatar, useAvatarGroup, useAvatarSizeProp, useBadgeOffsetProp, useBadgeProp, useButton, useButtonSizeProp, useButtonTypeProp, useCell, useCheckbox, useCheckboxGroupDirectionProp, useCheckboxSizeProp, useCheckboxTypeProp, useCollapse, useCustomClassProp, useCustomStyleProp, useDialog, useDirectionProp, useField, useFieldInputAlignProp, useFieldLabelAlignProp, useFieldTypeProp, useNavBar, useNoticeBar, useNotify, useNotifyPositionProp, useNotifyTypeProp, useOverlay, usePopup, useQuerySelector, useQuerySelectorAll, useRadio, useRadioGroupDirectionProp, useRadioSizeProp, useRadioTypeProp, useSizeProp, useSwitch, useSwitchSizeProp, useSwitchTypeProp, useTag, useTagSizeProp, useTagTypeProp, useToast, useTypeProp, useVariantProp };