bge-ui 1.8.8 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -6656,43 +6656,124 @@ const _sfc_main$u = /* @__PURE__ */ defineComponent({
6656
6656
  __name: "index",
6657
6657
  props: {
6658
6658
  type: {
6659
+ type: String,
6659
6660
  default: "bordered",
6660
- value: ["bordered", "pills", "pills-elevated"]
6661
+ validator: (value) => ["bordered", "pills", "pills-elevated"].includes(value)
6661
6662
  },
6662
6663
  modelValue: {
6663
6664
  type: String,
6664
6665
  default: ""
6665
6666
  },
6666
6667
  size: {
6668
+ type: String,
6667
6669
  default: "default",
6668
- value: ["default", "large", "mini"]
6670
+ validator: (value) => ["default", "large", "mini"].includes(value)
6669
6671
  }
6670
6672
  },
6671
6673
  emits: ["update:modelValue"],
6672
6674
  setup(__props, { emit: __emit }) {
6675
+ const isBrowser = typeof window !== "undefined" && typeof document !== "undefined";
6673
6676
  const props = __props;
6674
6677
  const emits = __emit;
6675
6678
  const panes = ref([]);
6679
+ const barStyle = ref();
6680
+ const navOffset = ref(0);
6681
+ const scrollable = ref(false);
6682
+ const tabsRef = ref(null);
6683
+ const navScrollRef = ref(null);
6676
6684
  function addPane(pane) {
6677
6685
  panes.value.push(pane);
6678
6686
  }
6679
- watch(() => props.modelValue, () => {
6680
- setTimeout(() => {
6681
- update();
6682
- }, 100);
6683
- });
6684
6687
  function changeValue(value) {
6685
6688
  emits("update:modelValue", value);
6686
- setTimeout(() => {
6689
+ nextTick(() => {
6687
6690
  update();
6688
- }, 100);
6691
+ });
6689
6692
  }
6693
+ watch(() => props.modelValue, () => {
6694
+ nextTick(() => {
6695
+ update();
6696
+ });
6697
+ });
6698
+ provide(tabsKey$1, {
6699
+ addPane,
6700
+ changeValue
6701
+ });
6702
+ const getBarStyle = () => {
6703
+ let offset2 = 0;
6704
+ let tabSize = 0;
6705
+ const sizeName = "width";
6706
+ if (isBrowser) {
6707
+ panes.value.forEach((tab, index2) => {
6708
+ const $el = tab.ref;
6709
+ if (!$el)
6710
+ return false;
6711
+ if ($el.clientWidth === 0 && index2 === 0) {
6712
+ nextTick(() => {
6713
+ update();
6714
+ });
6715
+ return false;
6716
+ }
6717
+ if (tab.value !== props.modelValue) {
6718
+ tab.setActive(false);
6719
+ return true;
6720
+ }
6721
+ tab.setActive(true);
6722
+ offset2 = $el["offsetLeft"];
6723
+ tabSize = $el["clientWidth"];
6724
+ return false;
6725
+ });
6726
+ } else {
6727
+ panes.value.forEach((tab) => {
6728
+ if (tab.value === props.modelValue) {
6729
+ tab.setActive(true);
6730
+ } else {
6731
+ tab.setActive(false);
6732
+ }
6733
+ });
6734
+ }
6735
+ return {
6736
+ [sizeName]: `${tabSize}px`,
6737
+ transform: `translateX(${offset2}px)`
6738
+ };
6739
+ };
6740
+ const getNavOffset = () => {
6741
+ if (!isBrowser)
6742
+ return;
6743
+ const navScrollElement = navScrollRef.value;
6744
+ if (!navScrollElement)
6745
+ return;
6746
+ panes.value.forEach((tab, index2) => {
6747
+ const $el = tab.ref;
6748
+ if (!$el)
6749
+ return false;
6750
+ if (tab.value === props.modelValue) {
6751
+ const currentOffset = navOffset.value;
6752
+ let newOffset = currentOffset;
6753
+ const activeTabBounding = $el.getBoundingClientRect();
6754
+ const navScrollBounding = navScrollElement.getBoundingClientRect();
6755
+ const maxOffset = navScrollBounding.width;
6756
+ if (activeTabBounding.left < navScrollBounding.left) {
6757
+ newOffset = currentOffset - (navScrollBounding.left - activeTabBounding.left);
6758
+ }
6759
+ if (activeTabBounding.right > navScrollBounding.right) {
6760
+ newOffset = currentOffset + activeTabBounding.right - navScrollBounding.right;
6761
+ }
6762
+ newOffset = Math.max(newOffset, 0);
6763
+ navOffset.value = Math.min(newOffset, maxOffset);
6764
+ }
6765
+ return false;
6766
+ });
6767
+ };
6690
6768
  const scrollPrev = () => {
6691
- if (!navScrollRef.value)
6769
+ if (!isBrowser)
6770
+ return;
6771
+ const navScrollElement = navScrollRef.value;
6772
+ if (!navScrollElement)
6692
6773
  return;
6693
6774
  let newOffset;
6694
6775
  const currentOffset = navOffset.value;
6695
- const navScrollBounding = navScrollRef.value.getBoundingClientRect();
6776
+ const navScrollBounding = navScrollElement.getBoundingClientRect();
6696
6777
  const maxOffset = navScrollBounding.width;
6697
6778
  panes.value.some((tab, index2) => {
6698
6779
  const $el = tab.ref;
@@ -6700,13 +6781,16 @@ const _sfc_main$u = /* @__PURE__ */ defineComponent({
6700
6781
  return false;
6701
6782
  const activeTabBounding = $el.getBoundingClientRect();
6702
6783
  if (activeTabBounding.left >= navScrollBounding.left && index2 > 0) {
6703
- const tabBounding = panes.value[index2 - 1].ref.getBoundingClientRect();
6704
- if (index2 - 1 === 0) {
6705
- newOffset = -navScrollBounding.left;
6784
+ const prevTab = panes.value[index2 - 1];
6785
+ if (prevTab && prevTab.ref) {
6786
+ const tabBounding = prevTab.ref.getBoundingClientRect();
6787
+ if (index2 - 1 === 0) {
6788
+ newOffset = -navScrollBounding.left;
6789
+ return true;
6790
+ }
6791
+ newOffset = currentOffset - (navScrollBounding.left - tabBounding.left);
6706
6792
  return true;
6707
6793
  }
6708
- newOffset = currentOffset - (navScrollBounding.left - tabBounding.left);
6709
- return true;
6710
6794
  }
6711
6795
  });
6712
6796
  if (newOffset) {
@@ -6715,11 +6799,14 @@ const _sfc_main$u = /* @__PURE__ */ defineComponent({
6715
6799
  }
6716
6800
  };
6717
6801
  const scrollNext = () => {
6718
- if (!navScrollRef.value)
6802
+ if (!isBrowser)
6803
+ return;
6804
+ const navScrollElement = navScrollRef.value;
6805
+ if (!navScrollElement)
6719
6806
  return;
6720
6807
  let newOffset;
6721
6808
  const currentOffset = navOffset.value;
6722
- const navScrollBounding = navScrollRef.value.getBoundingClientRect();
6809
+ const navScrollBounding = navScrollElement.getBoundingClientRect();
6723
6810
  const maxOffset = navScrollBounding.width;
6724
6811
  panes.value.some((tab, index2) => {
6725
6812
  const $el = tab.ref;
@@ -6736,90 +6823,37 @@ const _sfc_main$u = /* @__PURE__ */ defineComponent({
6736
6823
  navOffset.value = Math.min(newOffset, maxOffset);
6737
6824
  }
6738
6825
  };
6739
- provide(tabsKey$1, {
6740
- addPane,
6741
- changeValue
6742
- });
6743
- const barStyle = ref();
6744
- const navOffset = ref(0);
6745
- const scrollable = ref(false);
6746
- const getBarStyle = () => {
6747
- let offset2 = 0;
6748
- let tabSize = 0;
6749
- const sizeName = "width";
6750
- panes.value.forEach((tab, index2) => {
6751
- const $el = tab.ref;
6752
- if (!$el)
6753
- return false;
6754
- if ($el.clientWidth === 0 && index2 === 0) {
6755
- setTimeout(() => {
6756
- update();
6757
- }, 100);
6758
- return false;
6759
- }
6760
- if (tab.value !== props.modelValue) {
6761
- tab.setActive(false);
6762
- return true;
6763
- }
6764
- tab.setActive(true);
6765
- offset2 = $el["offsetLeft"];
6766
- tabSize = $el["clientWidth"];
6767
- return false;
6768
- });
6769
- return {
6770
- [sizeName]: `${tabSize}px`,
6771
- transform: `translateX(${offset2}px)`
6772
- };
6773
- };
6774
- const navScrollRef = ref();
6775
- const getNavOffset = () => {
6776
- if (!navScrollRef.value)
6777
- return;
6778
- panes.value.forEach((tab, index2) => {
6779
- const $el = tab.ref;
6780
- if (!$el)
6781
- return false;
6782
- if (tab.value === props.modelValue) {
6783
- const currentOffset = navOffset.value;
6784
- let newOffset = currentOffset;
6785
- const activeTabBounding = $el.getBoundingClientRect();
6786
- const navScrollBounding = navScrollRef.value.getBoundingClientRect();
6787
- const maxOffset = navScrollBounding.width;
6788
- if (activeTabBounding.left < navScrollBounding.left) {
6789
- newOffset = currentOffset - (navScrollBounding.left - activeTabBounding.left);
6790
- }
6791
- if (activeTabBounding.right > navScrollBounding.right) {
6792
- newOffset = currentOffset + activeTabBounding.right - navScrollBounding.right;
6793
- }
6794
- newOffset = Math.max(newOffset, 0);
6795
- navOffset.value = Math.min(newOffset, maxOffset);
6796
- }
6797
- return false;
6798
- });
6799
- };
6800
6826
  const panesStyle = computed(() => {
6801
6827
  return {
6802
6828
  transform: `translateX(-${navOffset.value}px)`
6803
6829
  };
6804
6830
  });
6805
6831
  const update = () => {
6806
- if (panes.value.length > 0 && navScrollRef.value) {
6807
- const right2 = panes.value[panes.value.length - 1].ref.getBoundingClientRect().right;
6808
- const left2 = panes.value[0].ref.getBoundingClientRect().left;
6809
- const navScrollBounding = navScrollRef.value.getBoundingClientRect();
6810
- if (left2 < navScrollBounding.left) {
6811
- scrollable.value = true;
6812
- } else if (right2 > navScrollBounding.right) {
6813
- scrollable.value = true;
6814
- } else {
6815
- scrollable.value = false;
6832
+ if (isBrowser) {
6833
+ const navScrollElement = navScrollRef.value;
6834
+ if (panes.value.length > 0 && navScrollElement) {
6835
+ const lastPane = panes.value[panes.value.length - 1];
6836
+ const firstPane = panes.value[0];
6837
+ if (lastPane && lastPane.ref && firstPane && firstPane.ref) {
6838
+ const right2 = lastPane.ref.getBoundingClientRect().right;
6839
+ const left2 = firstPane.ref.getBoundingClientRect().left;
6840
+ const navScrollBounding = navScrollElement.getBoundingClientRect();
6841
+ if (left2 < navScrollBounding.left) {
6842
+ scrollable.value = true;
6843
+ } else if (right2 > navScrollBounding.right) {
6844
+ scrollable.value = true;
6845
+ } else {
6846
+ scrollable.value = false;
6847
+ }
6848
+ }
6816
6849
  }
6817
6850
  }
6818
6851
  barStyle.value = getBarStyle();
6819
6852
  getNavOffset();
6820
6853
  };
6821
- const tabsRef = ref();
6822
- useResizeObserver(tabsRef, update);
6854
+ if (isBrowser) {
6855
+ useResizeObserver(tabsRef, update);
6856
+ }
6823
6857
  onMounted(() => {
6824
6858
  update();
6825
6859
  });
@@ -1,30 +1,34 @@
1
1
  declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<{
2
2
  type: {
3
+ type: StringConstructor;
3
4
  default: string;
4
- value: string[];
5
+ validator: (value: string) => boolean;
5
6
  };
6
7
  modelValue: {
7
8
  type: StringConstructor;
8
9
  default: string;
9
10
  };
10
11
  size: {
12
+ type: StringConstructor;
11
13
  default: string;
12
- value: string[];
14
+ validator: (value: string) => boolean;
13
15
  };
14
16
  }, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
15
17
  "update:modelValue": (...args: any[]) => void;
16
18
  }, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{
17
19
  type: {
20
+ type: StringConstructor;
18
21
  default: string;
19
- value: string[];
22
+ validator: (value: string) => boolean;
20
23
  };
21
24
  modelValue: {
22
25
  type: StringConstructor;
23
26
  default: string;
24
27
  };
25
28
  size: {
29
+ type: StringConstructor;
26
30
  default: string;
27
- value: string[];
31
+ validator: (value: string) => boolean;
28
32
  };
29
33
  }>> & {
30
34
  "onUpdate:modelValue"?: ((...args: any[]) => any) | undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bge-ui",
3
- "version": "1.8.8",
3
+ "version": "1.9.0",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "main": "./src/index.ts",
@@ -12,130 +12,110 @@
12
12
  </template>
13
13
  <script setup lang="ts">
14
14
  import { useResizeObserver } from "@vueuse/core"
15
- import { provide, ref, onMounted, watch, computed, onBeforeUnmount } from "vue"
15
+ import { provide, ref, onMounted, watch, computed, nextTick } from "vue"
16
+
17
+ // 检测是否在浏览器环境中
18
+ const isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined'
16
19
  defineOptions({
17
20
  name: "Tabs",
18
21
  })
19
22
 
20
23
  const props = defineProps({
21
24
  type: {
25
+ type: String,
22
26
  default: 'bordered',
23
- value: ['bordered', 'pills', 'pills-elevated']
27
+ validator: (value: string) => ['bordered', 'pills', 'pills-elevated'].includes(value)
24
28
  },
25
29
  modelValue: {
26
30
  type: String,
27
31
  default: '',
28
32
  },
29
33
  size: {
34
+ type: String,
30
35
  default: 'default',
31
- value: ['default', 'large', 'mini']
36
+ validator: (value: string) => ['default', 'large', 'mini'].includes(value)
32
37
  }
33
38
  })
34
39
 
35
40
  const emits = defineEmits(['update:modelValue'])
36
41
 
37
- const panes = ref<any>([])
42
+ // 类型定义
43
+ interface TabPane {
44
+ ref: HTMLElement | null
45
+ value: string
46
+ setActive: (active: boolean) => void
47
+ }
48
+
49
+ // 状态管理
50
+ const panes = ref<TabPane[]>([])
51
+ const barStyle = ref<{ width: string; transform: string } | undefined>()
52
+ const navOffset = ref(0)
53
+ const scrollable = ref(false)
54
+
55
+ // 引用
56
+ const tabsRef = ref<HTMLElement | null>(null)
57
+ const navScrollRef = ref<HTMLElement | null>(null)
38
58
 
39
- function addPane(pane: any) {
59
+ // 方法
60
+ function addPane(pane: TabPane) {
40
61
  panes.value.push(pane)
41
62
  }
42
63
 
43
- watch(() => props.modelValue, () => {
44
- setTimeout(() => {
45
- update()
46
- }, 100)
47
- })
48
-
49
64
  function changeValue(value: string) {
50
65
  emits('update:modelValue', value)
51
- setTimeout(() => {
66
+ nextTick(() => {
52
67
  update()
53
- }, 100)
54
- }
55
-
56
- const scrollPrev = () => {
57
- if (!navScrollRef.value) return
58
- let newOffset
59
- const currentOffset = navOffset.value
60
- const navScrollBounding = navScrollRef.value.getBoundingClientRect()
61
- const maxOffset = navScrollBounding.width
62
- panes.value.some((tab: any, index: number) => {
63
- const $el = tab.ref as HTMLElement
64
- if (!$el) return false
65
- const activeTabBounding = $el.getBoundingClientRect()
66
- if (activeTabBounding.left >= navScrollBounding.left && index > 0) {
67
- const tabBounding = panes.value[index - 1].ref.getBoundingClientRect()
68
- if (index - 1 === 0) {
69
- newOffset = -navScrollBounding.left
70
- return true
71
- }
72
- newOffset =
73
- currentOffset - (navScrollBounding.left - tabBounding.left)
74
- return true
75
- }
76
68
  })
77
- if (newOffset) {
78
- newOffset = Math.max(newOffset, 0)
79
- navOffset.value = Math.min(newOffset, maxOffset)
80
- }
81
69
  }
82
70
 
83
- const scrollNext = () => {
84
- if (!navScrollRef.value) return
85
- let newOffset
86
- const currentOffset = navOffset.value
87
- const navScrollBounding = navScrollRef.value.getBoundingClientRect()
88
- const maxOffset = navScrollBounding.width
89
- panes.value.some((tab: any, index: number) => {
90
- const $el = tab.ref as HTMLElement
91
- if (!$el) return false
92
- const activeTabBounding = $el.getBoundingClientRect()
93
- if (activeTabBounding.right > navScrollBounding.right) {
94
- newOffset =
95
- currentOffset + activeTabBounding.right - navScrollBounding.right
96
- return true
97
- }
71
+ watch(() => props.modelValue, () => {
72
+ nextTick(() => {
73
+ update()
98
74
  })
99
- if (newOffset) {
100
- newOffset = Math.max(newOffset, 0)
101
- navOffset.value = Math.min(newOffset, maxOffset)
102
- }
103
- }
75
+ })
104
76
 
105
77
  const tabsKey = 'bge-tabs-context'
106
78
  provide(tabsKey, {
107
79
  addPane,
108
80
  changeValue
109
81
  })
110
- const barStyle = ref<any>()
111
- const navOffset = ref(0)
112
- const scrollable = ref(false)
113
82
 
114
- const getBarStyle: any = () => {
83
+ const getBarStyle = (): { width: string; transform: string } => {
115
84
  let offset = 0
116
85
  let tabSize = 0
117
86
 
118
87
  const sizeName = 'width'
119
88
 
120
- panes.value.forEach((tab: any, index: number) => {
121
- const $el = tab.ref as HTMLElement
122
- if (!$el) return false
123
- if ($el.clientWidth === 0 && index === 0) {
124
- setTimeout(() => {
125
- update()
126
- }, 100)
127
- return false
128
- }
129
- if (tab.value !== props.modelValue) {
130
- tab.setActive(false)
131
- return true
132
- }
89
+ if (isBrowser) {
90
+ panes.value.forEach((tab: TabPane, index: number) => {
91
+ const $el = tab.ref
92
+ if (!$el) return false
93
+ if ($el.clientWidth === 0 && index === 0) {
94
+ nextTick(() => {
95
+ update()
96
+ })
97
+ return false
98
+ }
99
+ if (tab.value !== props.modelValue) {
100
+ tab.setActive(false)
101
+ return true
102
+ }
133
103
 
134
- tab.setActive(true)
135
- offset = $el['offsetLeft']
136
- tabSize = $el['clientWidth']
137
- return false
138
- })
104
+ tab.setActive(true)
105
+ offset = $el['offsetLeft']
106
+ tabSize = $el['clientWidth']
107
+ return false
108
+ })
109
+ } else {
110
+ // 服务端渲染时,为活动标签设置默认样式
111
+ panes.value.forEach((tab: TabPane) => {
112
+ if (tab.value === props.modelValue) {
113
+ tab.setActive(true)
114
+ } else {
115
+ tab.setActive(false)
116
+ }
117
+ })
118
+ }
139
119
 
140
120
  return {
141
121
  [sizeName]: `${tabSize}px`,
@@ -143,17 +123,18 @@ const getBarStyle: any = () => {
143
123
  }
144
124
  }
145
125
 
146
- const navScrollRef = ref()
147
- const getNavOffset: any = () => {
148
- if (!navScrollRef.value) return
149
- panes.value.forEach((tab: any, index: number) => {
150
- const $el = tab.ref as HTMLElement
126
+ const getNavOffset = () => {
127
+ if (!isBrowser) return
128
+ const navScrollElement = navScrollRef.value
129
+ if (!navScrollElement) return
130
+ panes.value.forEach((tab: TabPane, index: number) => {
131
+ const $el = tab.ref
151
132
  if (!$el) return false
152
133
  if (tab.value === props.modelValue) {
153
134
  const currentOffset = navOffset.value
154
135
  let newOffset = currentOffset
155
136
  const activeTabBounding = $el.getBoundingClientRect()
156
- const navScrollBounding = navScrollRef.value.getBoundingClientRect()
137
+ const navScrollBounding = navScrollElement.getBoundingClientRect()
157
138
  const maxOffset = navScrollBounding.width
158
139
  if (activeTabBounding.left < navScrollBounding.left) {
159
140
  newOffset =
@@ -169,29 +150,97 @@ const getNavOffset: any = () => {
169
150
  return false
170
151
  })
171
152
  }
153
+
154
+ const scrollPrev = () => {
155
+ if (!isBrowser) return
156
+ const navScrollElement = navScrollRef.value
157
+ if (!navScrollElement) return
158
+ let newOffset
159
+ const currentOffset = navOffset.value
160
+ const navScrollBounding = navScrollElement.getBoundingClientRect()
161
+ const maxOffset = navScrollBounding.width
162
+ panes.value.some((tab: TabPane, index: number) => {
163
+ const $el = tab.ref
164
+ if (!$el) return false
165
+ const activeTabBounding = $el.getBoundingClientRect()
166
+ if (activeTabBounding.left >= navScrollBounding.left && index > 0) {
167
+ const prevTab = panes.value[index - 1]
168
+ if (prevTab && prevTab.ref) {
169
+ const tabBounding = prevTab.ref.getBoundingClientRect()
170
+ if (index - 1 === 0) {
171
+ newOffset = -navScrollBounding.left
172
+ return true
173
+ }
174
+ newOffset =
175
+ currentOffset - (navScrollBounding.left - tabBounding.left)
176
+ return true
177
+ }
178
+ }
179
+ })
180
+ if (newOffset) {
181
+ newOffset = Math.max(newOffset, 0)
182
+ navOffset.value = Math.min(newOffset, maxOffset)
183
+ }
184
+ }
185
+
186
+ const scrollNext = () => {
187
+ if (!isBrowser) return
188
+ const navScrollElement = navScrollRef.value
189
+ if (!navScrollElement) return
190
+ let newOffset
191
+ const currentOffset = navOffset.value
192
+ const navScrollBounding = navScrollElement.getBoundingClientRect()
193
+ const maxOffset = navScrollBounding.width
194
+ panes.value.some((tab: TabPane, index: number) => {
195
+ const $el = tab.ref
196
+ if (!$el) return false
197
+ const activeTabBounding = $el.getBoundingClientRect()
198
+ if (activeTabBounding.right > navScrollBounding.right) {
199
+ newOffset =
200
+ currentOffset + activeTabBounding.right - navScrollBounding.right
201
+ return true
202
+ }
203
+ })
204
+ if (newOffset) {
205
+ newOffset = Math.max(newOffset, 0)
206
+ navOffset.value = Math.min(newOffset, maxOffset)
207
+ }
208
+ }
209
+
172
210
  const panesStyle = computed(() => {
173
211
  return {
174
212
  transform: `translateX(-${navOffset.value}px)`,
175
213
  }
176
214
  })
215
+
177
216
  const update = () => {
178
- if (panes.value.length > 0 && navScrollRef.value) {
179
- const right = panes.value[panes.value.length - 1].ref.getBoundingClientRect().right
180
- const left = panes.value[0].ref.getBoundingClientRect().left
181
- const navScrollBounding = navScrollRef.value.getBoundingClientRect()
182
- if (left < navScrollBounding.left) {
183
- scrollable.value = true
184
- } else if (right > navScrollBounding.right) {
185
- scrollable.value = true
186
- } else {
187
- scrollable.value = false
217
+ if (isBrowser) {
218
+ const navScrollElement = navScrollRef.value
219
+ if (panes.value.length > 0 && navScrollElement) {
220
+ const lastPane = panes.value[panes.value.length - 1]
221
+ const firstPane = panes.value[0]
222
+ if (lastPane && lastPane.ref && firstPane && firstPane.ref) {
223
+ const right = lastPane.ref.getBoundingClientRect().right
224
+ const left = firstPane.ref.getBoundingClientRect().left
225
+ const navScrollBounding = navScrollElement.getBoundingClientRect()
226
+ if (left < navScrollBounding.left) {
227
+ scrollable.value = true
228
+ } else if (right > navScrollBounding.right) {
229
+ scrollable.value = true
230
+ } else {
231
+ scrollable.value = false
232
+ }
233
+ }
188
234
  }
189
235
  }
190
236
  barStyle.value = getBarStyle()
191
237
  getNavOffset()
192
238
  }
193
- const tabsRef = ref()
194
- useResizeObserver(tabsRef, update)
239
+
240
+ // 仅在浏览器环境中使用 ResizeObserver
241
+ if (isBrowser) {
242
+ useResizeObserver(tabsRef, update)
243
+ }
195
244
 
196
245
  onMounted(() => {
197
246
  update()