import { ref, watch, reactive, defineComponent, createVNode as _createVNode, vShow as _vShow, withDirectives as _withDirectives } from "vue"; import { isDef, createNamespace, makeNumericProp } from "../utils/index.mjs"; import { raf, useRect, doubleRaf, useEventListener, onMountedOrActivated } from "@vant/use"; import { useExpose } from "../composables/use-expose.mjs"; import { onPopupReopen } from "../composables/on-popup-reopen.mjs"; import { Icon } from "../icon/index.mjs"; const [name, bem] = createNamespace("notice-bar"); const noticeBarProps = { text: String, mode: String, color: String, delay: makeNumericProp(1), speed: makeNumericProp(60), leftIcon: String, wrapable: Boolean, background: String, scrollable: { type: Boolean, default: null } }; var stdin_default = defineComponent({ name, props: noticeBarProps, emits: ["close", "replay"], setup(props, { emit, slots }) { let wrapWidth = 0; let contentWidth = 0; let startTimer; const wrapRef = ref(); const contentRef = ref(); const state = reactive({ show: true, offset: 0, duration: 0 }); const renderLeftIcon = () => { if (slots["left-icon"]) { return slots["left-icon"](); } if (props.leftIcon) { return _createVNode(Icon, { "class": bem("left-icon"), "name": props.leftIcon }, null); } }; const getRightIconName = () => { if (props.mode === "closeable") { return "cross"; } if (props.mode === "link") { return "arrow"; } }; const onClickRightIcon = (event) => { if (props.mode === "closeable") { state.show = false; emit("close", event); } }; const renderRightIcon = () => { if (slots["right-icon"]) { return slots["right-icon"](); } const name2 = getRightIconName(); if (name2) { return _createVNode(Icon, { "name": name2, "class": bem("right-icon"), "onClick": onClickRightIcon }, null); } }; const onTransitionEnd = () => { state.offset = wrapWidth; state.duration = 0; raf(() => { doubleRaf(() => { state.offset = -contentWidth; state.duration = (contentWidth + wrapWidth) / +props.speed; emit("replay"); }); }); }; const renderMarquee = () => { const ellipsis = props.scrollable === false && !props.wrapable; const style = { transform: state.offset ? `translateX(${state.offset}px)` : "", transitionDuration: `${state.duration}s` }; return _createVNode("div", { "ref": wrapRef, "role": "marquee", "class": bem("wrap") }, [_createVNode("div", { "ref": contentRef, "style": style, "class": [bem("content"), { "van-ellipsis": ellipsis }], "onTransitionend": onTransitionEnd }, [slots.default ? slots.default() : props.text])]); }; const reset = () => { const { delay, speed, scrollable } = props; const ms = isDef(delay) ? +delay * 1e3 : 0; wrapWidth = 0; contentWidth = 0; state.offset = 0; state.duration = 0; clearTimeout(startTimer); startTimer = setTimeout(() => { if (!wrapRef.value || !contentRef.value || scrollable === false) { return; } const wrapRefWidth = useRect(wrapRef).width; const contentRefWidth = useRect(contentRef).width; if (scrollable || contentRefWidth > wrapRefWidth) { doubleRaf(() => { wrapWidth = wrapRefWidth; contentWidth = contentRefWidth; state.offset = -contentWidth; state.duration = contentWidth / +speed; }); } }, ms); }; onPopupReopen(reset); onMountedOrActivated(reset); useEventListener("pageshow", reset); useExpose({ reset }); watch(() => [props.text, props.scrollable], reset); return () => { const { color, wrapable, background } = props; return _withDirectives(_createVNode("div", { "role": "alert", "class": bem({ wrapable }), "style": { color, background } }, [renderLeftIcon(), renderMarquee(), renderRightIcon()]), [[_vShow, state.show]]); }; } }); export { stdin_default as default, noticeBarProps };