{"version":3,"file":"overflow.mjs","sources":["../../../components/overflow/overflow.tsx"],"sourcesContent":["import { ResizeObserver } from '@/components/resize-observer'\r\n\r\nimport {\r\n  Fragment,\r\n  computed,\r\n  createTextVNode,\r\n  defineComponent,\r\n  nextTick,\r\n  onMounted,\r\n  ref,\r\n  watch,\r\n} from 'vue'\r\n\r\nimport { emitEvent, useNameHelper, useProps } from '@vexip-ui/config'\r\nimport { isDefined } from '@vexip-ui/utils'\r\nimport { overflowProps } from './props'\r\n\r\nconst TEXT_VNODE = createTextVNode('').type\r\n\r\nexport default defineComponent({\r\n  name: 'Overflow',\r\n  inheritAttrs: false,\r\n  props: overflowProps,\r\n  emits: [],\r\n  setup(_props, { attrs, slots, expose }) {\r\n    const props = useProps('overflow', _props, {\r\n      items: {\r\n        default: null,\r\n        static: true,\r\n      },\r\n      tag: 'div',\r\n      attrFlag: false,\r\n      static: false,\r\n      maxCount: 0,\r\n    })\r\n\r\n    const nh = useNameHelper('overflow')\r\n    const restCount = ref(0)\r\n\r\n    const wrapper = ref<HTMLElement>()\r\n    const counter = ref<HTMLElement>()\r\n    const suffix = ref<HTMLElement>()\r\n\r\n    const className = computed(() => {\r\n      return [\r\n        nh.b(),\r\n        nh.bs('vars'),\r\n        {\r\n          [nh.bm('inherit')]: props.inherit,\r\n          [nh.bm('manual')]: props.maxCount > 0,\r\n        },\r\n      ]\r\n    })\r\n    const hiddenFlag = computed(() => {\r\n      return props.attrFlag ? (props.attrFlag === true ? 'hidden' : props.attrFlag) : false\r\n    })\r\n\r\n    watch([() => props.items?.length, () => props.maxCount], () => {\r\n      nextTick(refresh)\r\n    })\r\n\r\n    expose({ refresh })\r\n\r\n    onMounted(refresh)\r\n\r\n    function toggleDisplay(el: HTMLElement, show: boolean) {\r\n      if (hiddenFlag.value) {\r\n        show ? el.removeAttribute(hiddenFlag.value) : el.setAttribute(hiddenFlag.value, '')\r\n      } else {\r\n        if (show) {\r\n          el.style.display = ''\r\n        } else {\r\n          el.style.display = 'none'\r\n        }\r\n      }\r\n    }\r\n\r\n    function computeHorizontalMargin(el: HTMLElement) {\r\n      const style = getComputedStyle(el)\r\n      const marginLeft = parseFloat(style.marginLeft) || 0\r\n      const marginRight = parseFloat(style.marginRight) || 0\r\n\r\n      return marginLeft + marginRight\r\n    }\r\n\r\n    function computeHorizontalPadding(elOrStyle: HTMLElement | CSSStyleDeclaration) {\r\n      const style = elOrStyle instanceof Element ? getComputedStyle(elOrStyle) : elOrStyle\r\n      const paddingLeft = parseFloat(style.paddingLeft) || 0\r\n      const paddingRight = parseFloat(style.paddingRight) || 0\r\n\r\n      return paddingLeft + paddingRight\r\n    }\r\n\r\n    function computeOuterWidth(el: HTMLElement) {\r\n      return el.offsetWidth + computeHorizontalMargin(el)\r\n    }\r\n\r\n    let lastOverflow = false\r\n    let lastRestCount = restCount.value\r\n\r\n    function refresh() {\r\n      const counterEl = counter.value\r\n\r\n      if (!wrapper.value || !counterEl) return\r\n\r\n      toggleDisplay(counterEl, true)\r\n\r\n      const children = wrapper.value.children\r\n      const childCount = children.length\r\n\r\n      let overflow = false\r\n\r\n      if (props.maxCount > 0) {\r\n        for (let i = 0, len = childCount - 1; i < len; ++i) {\r\n          const child = children[i] as HTMLElement\r\n\r\n          child.style.display = i < props.maxCount ? '' : 'none'\r\n        }\r\n\r\n        if (props.maxCount > childCount - 1) {\r\n          toggleDisplay(counterEl, false)\r\n\r\n          restCount.value = 0\r\n        } else {\r\n          restCount.value = childCount - 1 - props.maxCount - (slots.suffix ? 1 : 0)\r\n          overflow = restCount.value > 0\r\n        }\r\n\r\n        postRefresh(overflow)\r\n        return\r\n      }\r\n\r\n      const suffixEl = suffix.value\r\n      const style = getComputedStyle(wrapper.value)\r\n      const wrapperWidth = wrapper.value.offsetWidth - computeHorizontalPadding(style)\r\n      const gap = parseFloat(style.columnGap) || 0\r\n      const childWidths: number[] = []\r\n\r\n      let totalWidth = suffixEl ? suffixEl.offsetWidth + computeHorizontalMargin(suffixEl) + gap : 0\r\n\r\n      const counterMargin = computeHorizontalMargin(counterEl)\r\n      const length = childCount - (suffixEl ? 2 : 1)\r\n\r\n      for (let i = 0; i < length; ++i) {\r\n        if (i < 0) continue\r\n\r\n        const child = children[i] as HTMLElement\r\n\r\n        if (overflow) {\r\n          toggleDisplay(child, false)\r\n          continue\r\n        } else {\r\n          toggleDisplay(child, true)\r\n        }\r\n\r\n        const childWidth = computeOuterWidth(child) + gap\r\n\r\n        totalWidth += childWidth\r\n        childWidths[i] = childWidth\r\n\r\n        if (totalWidth > wrapperWidth) {\r\n          for (let j = i; j >= 0; --j) {\r\n            restCount.value = length - j\r\n            totalWidth -= childWidths[j]\r\n\r\n            if (totalWidth + counterEl.offsetWidth + counterMargin <= wrapperWidth || !j) {\r\n              overflow = true\r\n              i = j - 1\r\n\r\n              if (suffixEl) {\r\n                suffixEl.style.maxWidth =\r\n                  i === -1 ? `${wrapperWidth - counterEl.offsetWidth}px` : ''\r\n              }\r\n\r\n              break\r\n            }\r\n          }\r\n        }\r\n      }\r\n\r\n      postRefresh(overflow)\r\n    }\r\n\r\n    function postRefresh(overflow: boolean) {\r\n      if (lastRestCount !== restCount.value) {\r\n        lastRestCount = restCount.value\r\n        emitEvent(props.onRestChange, restCount.value)\r\n      }\r\n\r\n      counter.value && toggleDisplay(counter.value, overflow)\r\n\r\n      if (overflow !== lastOverflow) {\r\n        lastOverflow = overflow\r\n        emitEvent(props.onToggle, overflow)\r\n      }\r\n    }\r\n\r\n    function syncCounterRef(el?: HTMLElement | null) {\r\n      if (el) {\r\n        counter.value = el.nextElementSibling as HTMLElement | undefined\r\n      } else {\r\n        counter.value = undefined\r\n      }\r\n    }\r\n\r\n    return () => {\r\n      const CustomTag = (props.tag || 'div') as any\r\n      const itemSlot = slots.default\r\n      const staticItem = props.static\r\n      const counterVNode = slots.counter?.({ count: restCount.value })[0] || null\r\n\r\n      const renderCounter = () =>\r\n        counterVNode?.type === TEXT_VNODE ? <span>{counterVNode}</span> : counterVNode\r\n      const render = () => (\r\n        <CustomTag {...attrs} ref={wrapper} class={className.value}>\r\n          {itemSlot && isDefined(props.items)\r\n            ? props.items.map((item, index) => {\r\n              const vnode = itemSlot({ item, index })[0]\r\n\r\n              if (staticItem) {\r\n                vnode.key = index\r\n\r\n                return vnode\r\n              }\r\n\r\n              return (\r\n                <ResizeObserver key={index} onResize={refresh}>\r\n                  {() => vnode}\r\n                </ResizeObserver>\r\n              )\r\n            })\r\n            : itemSlot?.()}\r\n          {counterVNode ? (\r\n            <Fragment ref={syncCounterRef as any}>{renderCounter()}</Fragment>\r\n          ) : (\r\n            <span ref={counter} style={{ display: 'inline-block' }}></span>\r\n          )}\r\n          {slots.suffix ? (\r\n            <ResizeObserver onResize={refresh}>\r\n              <div ref={suffix} class={nh.be('suffix')}>\r\n                {slots.suffix()}\r\n              </div>\r\n            </ResizeObserver>\r\n          ) : null}\r\n        </CustomTag>\r\n      )\r\n\r\n      if (import.meta.env.MODE === 'test') {\r\n        // It is difficult to test ResizeObserver in vitest, so directly rendering all items\r\n        return render()\r\n      }\r\n\r\n      return <ResizeObserver onResize={refresh}>{render()}</ResizeObserver>\r\n    }\r\n  },\r\n})\r\n"],"names":["_isSlot","s","Object","prototype","toString","call","_isVNode","TEXT_VNODE","createTextVNode","type","defineComponent","name","inheritAttrs","props","overflowProps","emits","setup","_props","attrs","slots","expose","useProps","items","default","static","tag","attrFlag","maxCount","nh","useNameHelper","restCount","ref","wrapper","counter","suffix","className","computed","b","bs","bm","inherit","hiddenFlag","watch","length","nextTick","refresh","onMounted","toggleDisplay","el","show","value","removeAttribute","setAttribute","style","display","computeHorizontalMargin","getComputedStyle","marginLeft","parseFloat","marginRight","computeHorizontalPadding","elOrStyle","Element","paddingLeft","paddingRight","computeOuterWidth","offsetWidth","lastOverflow","lastRestCount","counterEl","children","childCount","overflow","i","len","child","postRefresh","suffixEl","wrapperWidth","gap","columnGap","childWidths","totalWidth","counterMargin","childWidth","j","maxWidth","onRestChange","onToggle","syncCounterRef","nextElementSibling","undefined","_slot","CustomTag","itemSlot","staticItem","counterVNode","count","renderCounter","_createVNode","ResizeObserver","_mergeProps","isDefined","map","item","index","vnode","key","_Fragment","be"],"mappings":"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"}