{"version":3,"file":"tabs.mjs","sources":["../../../../../../packages/components/tabs/src/tabs.tsx"],"sourcesContent":["import {\n  defineComponent,\n  getCurrentInstance,\n  nextTick,\n  provide,\n  ref,\n  renderSlot,\n  shallowReactive,\n  shallowRef,\n  watch,\n} from 'vue'\nimport {\n  buildProps,\n  definePropType,\n  isNumber,\n  isString,\n  isUndefined,\n} from '@bigin/utils'\nimport { EVENT_CODE, UPDATE_MODEL_EVENT } from '@bigin/constants'\nimport BButton from '@bigin/components/button'\nimport { ControlPlus } from '@bigin/icons-vue'\nimport { tabsRootContextKey } from '@bigin/tokens'\nimport { useNamespace } from '@bigin/hooks'\nimport TabNav from './tab-nav'\nimport { getOrderedPanes } from './utils/pane'\n\nimport type { TabNavInstance } from './tab-nav'\nimport type { TabsPaneContext } from '@bigin/tokens'\n\nimport type { ExtractPropTypes } from 'vue'\nimport type { Awaitable } from '@bigin/utils'\n\nexport type TabPanelName = string | number\n\nexport const tabsProps = buildProps({\n  type: {\n    type: String,\n    values: ['separator', 'segment', 'large-segment', ''],\n    default: '',\n  },\n  activeName: {\n    type: [String, Number],\n  },\n  closable: Boolean,\n  addable: Boolean,\n  modelValue: {\n    type: [String, Number],\n  },\n  editable: Boolean,\n  tabPosition: {\n    type: String,\n    values: ['top', 'right', 'bottom', 'left'],\n    default: 'top',\n  },\n  beforeLeave: {\n    type: definePropType<\n      (\n        newName: TabPanelName,\n        oldName: TabPanelName\n      ) => Awaitable<void | boolean>\n    >(Function),\n    default: () => true,\n  },\n  stretch: Boolean,\n  paneless: Boolean,\n  center: Boolean,\n} as const)\nexport type TabsProps = ExtractPropTypes<typeof tabsProps>\n\nconst isPanelName = (value: unknown): value is string | number =>\n  isString(value) || isNumber(value)\n\nexport const tabsEmits = {\n  [UPDATE_MODEL_EVENT]: (name: TabPanelName) => isPanelName(name),\n  tabClick: (pane: TabsPaneContext, ev: Event) => ev instanceof Event,\n  tabChange: (name: TabPanelName) => isPanelName(name),\n  edit: (paneName: TabPanelName | undefined, action: 'remove' | 'add') =>\n    ['remove', 'add'].includes(action),\n  tabRemove: (name: TabPanelName) => isPanelName(name),\n  tabAdd: () => true,\n}\nexport type TabsEmits = typeof tabsEmits\n\nexport type TabsPanes = Record<number, TabsPaneContext>\n\nexport default defineComponent({\n  name: 'BTabs',\n\n  props: tabsProps,\n  emits: tabsEmits,\n\n  setup(props, { emit, slots, expose }) {\n    const vm = getCurrentInstance()!\n\n    const ns = useNamespace('tabs')\n\n    const nav$ = ref<TabNavInstance>()\n    const panes = shallowReactive<TabsPanes>({})\n    const orderedPanes = shallowRef<TabsPaneContext[]>([])\n    const currentName = ref<TabPanelName>(\n      props.modelValue ?? props.activeName ?? '0'\n    )\n\n    const changeCurrentName = (value: TabPanelName) => {\n      currentName.value = value\n      emit(UPDATE_MODEL_EVENT, value)\n      emit('tabChange', value)\n    }\n\n    const setCurrentName = async (value?: TabPanelName) => {\n      // should do nothing.\n      if (currentName.value === value || isUndefined(value)) return\n\n      try {\n        const canLeave = await props.beforeLeave?.(value, currentName.value)\n        if (canLeave !== false) {\n          changeCurrentName(value)\n\n          // call exposed function, Vue doesn't support expose in typescript yet.\n          // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n          // @ts-expect-error\n          nav$.value?.removeFocus?.()\n        }\n      } catch {}\n    }\n\n    const handleTabClick = (\n      tab: TabsPaneContext,\n      tabName: TabPanelName,\n      event: Event\n    ) => {\n      if (tab.props.disabled) return\n      setCurrentName(tabName)\n      emit('tabClick', tab, event)\n    }\n\n    const handleTabRemove = (pane: TabsPaneContext, ev: Event) => {\n      if (pane.props.disabled || isUndefined(pane.props.name)) return\n      ev.stopPropagation()\n      emit('edit', pane.props.name, 'remove')\n      emit('tabRemove', pane.props.name)\n    }\n\n    const handleTabAdd = () => {\n      emit('edit', undefined, 'add')\n      emit('tabAdd')\n    }\n\n    watch(\n      () => props.activeName,\n      (modelValue) => setCurrentName(modelValue)\n    )\n\n    watch(\n      () => props.modelValue,\n      (modelValue) => setCurrentName(modelValue)\n    )\n\n    watch(currentName, async () => {\n      await nextTick()\n      // call exposed function, Vue doesn't support expose in typescript yet.\n      // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n      // @ts-expect-error\n      nav$.value?.scrollToActiveTab()\n    })\n\n    {\n      const registerPane = (pane: TabsPaneContext) => {\n        panes[pane.uid] = pane\n        orderedPanes.value = getOrderedPanes(vm, panes)\n      }\n\n      const unregisterPane = (uid: number) => {\n        delete panes[uid]\n        orderedPanes.value = getOrderedPanes(vm, panes)\n      }\n\n      provide(tabsRootContextKey, {\n        props,\n        currentName,\n        registerPane,\n        unregisterPane,\n      })\n    }\n\n    expose({\n      currentName,\n    })\n\n    return () => {\n      const newButton =\n        props.editable || props.addable ? (\n          <span\n            class={ns.e('new-tab')}\n            tabindex=\"0\"\n            onClick={handleTabAdd}\n            onKeydown={(ev: KeyboardEvent) => {\n              if (ev.code === EVENT_CODE.enter) handleTabAdd()\n            }}\n          >\n            <BButton\n              class={ns.is('icon-plus')}\n              icon={ControlPlus}\n              xsmall\n              ghost\n            />\n          </span>\n        ) : null\n\n      const header = (\n        <div class={[ns.e('header'), ns.is(props.tabPosition)]}>\n          {newButton}\n          <TabNav\n            ref={nav$}\n            currentName={currentName.value}\n            editable={props.editable}\n            type={props.type}\n            panes={orderedPanes.value}\n            stretch={props.stretch}\n            center={props.center}\n            onTabClick={handleTabClick}\n            onTabRemove={handleTabRemove}\n          />\n        </div>\n      )\n\n      const panels = (\n        <div class={ns.e('content')}>{renderSlot(slots, 'default')}</div>\n      )\n\n      return (\n        <div\n          class={[\n            ns.b(),\n            ns.m(props.tabPosition),\n            ns.is('paneless', props.paneless),\n            {\n              [ns.m(props.type)]: props.type.length,\n            },\n          ]}\n          data-test-name={'tabs'}\n        >\n          {...props.tabPosition !== 'bottom'\n            ? [header, panels]\n            : [panels, header]}\n        </div>\n      )\n    }\n  },\n})\n"],"names":["tabsProps","buildProps","type","String","values","default","activeName","Number","closable","Boolean","addable","modelValue","editable","tabPosition","beforeLeave","definePropType","Function","stretch","paneless","center","isPanelName","value","isString","isNumber","tabsEmits","UPDATE_MODEL_EVENT","name","tabClick","pane","ev","Event","tabChange","edit","paneName","action","includes","tabRemove","tabAdd","defineComponent","props","emits","setup","emit","slots","expose","vm","getCurrentInstance","ns","useNamespace","nav$","ref","panes","shallowReactive","orderedPanes","shallowRef","currentName","changeCurrentName","setCurrentName","isUndefined","canLeave","removeFocus","handleTabClick","tab","tabName","event","disabled","handleTabRemove","stopPropagation","handleTabAdd","undefined","watch","nextTick","scrollToActiveTab","registerPane","uid","getOrderedPanes","unregisterPane","provide","tabsRootContextKey","newButton","_createVNode","e","code","EVENT_CODE","enter","is","ControlPlus","header","panels","renderSlot","b","m","length"],"mappings":"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"}