unika-components 1.1.21 → 1.1.22

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.
@@ -28603,6 +28603,14 @@
28603
28603
  const inputValue = vue.ref('');
28604
28604
  const hasError = vue.ref(false);
28605
28605
  const isTouched = vue.ref(false);
28606
+ const inputRef = vue.ref(null);
28607
+ const instanceId = vue.ref(`input-${Math.random().toString(36).substr(2, 9)}`);
28608
+ const inputId = vue.computed(() => `form-input-${props.element.id || instanceId.value}`);
28609
+ // 检测移动设备
28610
+ const isMobile = vue.ref(false);
28611
+ const checkIfMobile = () => {
28612
+ isMobile.value = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
28613
+ };
28606
28614
  // 根据inputType确定验证类型
28607
28615
  const validatorType = vue.computed(() => {
28608
28616
  switch (props.element.inputType) {
@@ -28640,12 +28648,68 @@
28640
28648
  isTouched.value = true;
28641
28649
  validate();
28642
28650
  };
28651
+ // 处理输入框聚焦时的滚动问题
28652
+ const handleFocus = () => {
28653
+ if (props.isPlatform || !isMobile.value || !inputRef.value)
28654
+ return;
28655
+ setTimeout(() => {
28656
+ const inputEl = inputRef.value;
28657
+ if (!inputEl)
28658
+ return;
28659
+ // 对于Android设备,需要额外处理
28660
+ if (/Android/i.test(navigator.userAgent)) {
28661
+ const scrollContainer = inputEl.closest('.scroll-long');
28662
+ if (scrollContainer) {
28663
+ const inputRect = inputEl.getBoundingClientRect();
28664
+ const scrollTop = window.scrollY || document.documentElement.scrollTop;
28665
+ const targetPosition = inputRect.top + scrollTop - (window.innerHeight / 3);
28666
+ window.scrollTo({
28667
+ top: targetPosition,
28668
+ behavior: 'smooth'
28669
+ });
28670
+ }
28671
+ }
28672
+ else {
28673
+ // iOS和其他设备
28674
+ const wrapper = inputEl.closest('.input-wrapper');
28675
+ if (wrapper) {
28676
+ wrapper.scrollIntoView({
28677
+ block: 'center',
28678
+ behavior: 'smooth'
28679
+ });
28680
+ }
28681
+ }
28682
+ }, 300);
28683
+ };
28684
+ // 处理Android键盘收起
28685
+ const handleAndroidBlur = () => {
28686
+ if (/Android/i.test(navigator.userAgent)) {
28687
+ setTimeout(() => {
28688
+ window.scrollTo(0, 0);
28689
+ }, 200);
28690
+ }
28691
+ };
28643
28692
  // 值变化时验证(如果已经触摸过)
28644
28693
  vue.watch(inputValue, () => {
28645
28694
  if (isTouched.value) {
28646
28695
  validate();
28647
28696
  }
28648
28697
  });
28698
+ // 初始化
28699
+ vue.onMounted(() => {
28700
+ checkIfMobile();
28701
+ if (inputRef.value) {
28702
+ inputRef.value.addEventListener('focus', handleFocus);
28703
+ inputRef.value.addEventListener('blur', handleAndroidBlur);
28704
+ }
28705
+ });
28706
+ // 清理
28707
+ vue.onBeforeUnmount(() => {
28708
+ if (inputRef.value) {
28709
+ inputRef.value.removeEventListener('focus', handleFocus);
28710
+ inputRef.value.removeEventListener('blur', handleAndroidBlur);
28711
+ }
28712
+ });
28649
28713
  // 样式计算
28650
28714
  const required = vue.computed(() => props.element.properties.required || false);
28651
28715
  const title = vue.computed(() => props.element.title || '');
@@ -28658,6 +28722,13 @@
28658
28722
  transform: `rotate(${props.element.css.transform || 0}deg)`,
28659
28723
  opacity: props.element.css.opacity || 1
28660
28724
  }));
28725
+ const shadowStyle = vue.computed(() => {
28726
+ const shadow = props.element.properties;
28727
+ if (shadow.shadowSize <= 0)
28728
+ return 'none';
28729
+ // Use px2rem for shadow values and remove props.unit (which does not exist)
28730
+ return `${px2rem(shadow.shadowX, props.isPlatform)} ${px2rem(shadow.shadowY, props.isPlatform)} ${px2rem(shadow.shadowBlur, props.isPlatform)} ${shadow.shadowColor}`;
28731
+ });
28661
28732
  const wrapperStyles = vue.computed(() => ({
28662
28733
  backgroundColor: props.element.css.backgroundColor || '#fff',
28663
28734
  borderRadius: px2rem(props.element.css.borderRadius || 2, props.isPlatform),
@@ -28680,7 +28751,11 @@
28680
28751
  containerStyles,
28681
28752
  wrapperStyles,
28682
28753
  inputStyles,
28683
- handleBlur
28754
+ shadowStyle,
28755
+ handleBlur,
28756
+ inputRef,
28757
+ instanceId,
28758
+ inputId
28684
28759
  };
28685
28760
  }
28686
28761
  });
@@ -28689,12 +28764,12 @@
28689
28764
  key: 0,
28690
28765
  class: "required-marker"
28691
28766
  };
28692
- const _hoisted_2$7 = ["type", "placeholder"];
28767
+ const _hoisted_2$7 = ["id", "type", "placeholder", "data-instance-id"];
28693
28768
 
28694
28769
  function render$9(_ctx, _cache, $props, $setup, $data, $options) {
28695
28770
  return (vue.openBlock(), vue.createElementBlock("div", {
28696
28771
  class: "ele-form form-input eles",
28697
- style: vue.normalizeStyle(_ctx.containerStyles)
28772
+ style: vue.normalizeStyle({..._ctx.containerStyles, boxShadow: _ctx.shadowStyle})
28698
28773
  }, [
28699
28774
  vue.createElementVNode("div", {
28700
28775
  class: "input-wrapper",
@@ -28707,12 +28782,15 @@
28707
28782
  ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_1$7, "*"))
28708
28783
  : vue.createCommentVNode("v-if", true),
28709
28784
  vue.withDirectives(vue.createElementVNode("input", {
28785
+ id: _ctx.inputId,
28710
28786
  type: _ctx.inputType,
28711
28787
  placeholder: _ctx.title,
28712
28788
  "onUpdate:modelValue": _cache[0] || (_cache[0] = $event => ((_ctx.inputValue) = $event)),
28713
28789
  style: vue.normalizeStyle(_ctx.inputStyles),
28714
28790
  onBlur: _cache[1] || (_cache[1] = (...args) => (_ctx.handleBlur && _ctx.handleBlur(...args))),
28715
- class: "dynamic-placeholder-input"
28791
+ class: "dynamic-placeholder-input",
28792
+ ref: "inputRef",
28793
+ "data-instance-id": _ctx.instanceId
28716
28794
  }, null, 44 /* STYLE, PROPS, NEED_HYDRATION */, _hoisted_2$7), [
28717
28795
  [vue.vModelDynamic, _ctx.inputValue]
28718
28796
  ])
@@ -28721,6 +28799,7 @@
28721
28799
  }
28722
28800
 
28723
28801
  script$d.render = render$9;
28802
+ script$d.__scopeId = "data-v-af046be2";
28724
28803
  script$d.__file = "src/components/UniFormInput/UniFormInput.vue";
28725
28804
 
28726
28805
  var script$c = vue.defineComponent({
@@ -29383,7 +29462,6 @@
29383
29462
  }
29384
29463
 
29385
29464
  script$8.render = render$4;
29386
- script$8.__scopeId = "data-v-2d16d26f";
29387
29465
  script$8.__file = "src/components/UniFormContainer/UniFormContainer.vue";
29388
29466
 
29389
29467
  var script$7 = /*#__PURE__*/ vue.defineComponent({
@@ -29999,6 +30077,8 @@
29999
30077
  const direction = vue.ref('up');
30000
30078
  const autoPlayTimer = vue.ref(null);
30001
30079
  const isAutoPlaying = vue.ref(false);
30080
+ const isMobile = vue.ref(false);
30081
+ const isKeyboardActive = vue.ref(false);
30002
30082
  const workData = vue.computed(() => props.workData || { pages: [], global: {} });
30003
30083
  const personalData = vue.computed(() => workData.value.personalData || {});
30004
30084
  const global = vue.computed(() => workData.value.global || {});
@@ -30006,6 +30086,10 @@
30006
30086
  const musicStatus = vue.ref(false);
30007
30087
  const musicPlayer = vue.ref();
30008
30088
  const { attemptAutoplay, playOnInteraction, pauseNonGlobalMusic, getCurrentMusicState } = useMusicManager();
30089
+ // 检测移动设备
30090
+ const checkIfMobile = () => {
30091
+ isMobile.value = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
30092
+ };
30009
30093
  // 处理首次交互
30010
30094
  const handleFirstInteraction = () => {
30011
30095
  const currentState = getCurrentMusicState();
@@ -30068,7 +30152,40 @@
30068
30152
  vue.watch(currentPageId, () => {
30069
30153
  startAutoPlay();
30070
30154
  });
30155
+ // 处理移动端键盘事件
30156
+ const handleMobileResize = () => {
30157
+ const activeElement = document.activeElement;
30158
+ if (activeElement && (activeElement.tagName === 'INPUT' || activeElement.tagName === 'TEXTAREA')) {
30159
+ setTimeout(() => {
30160
+ activeElement.scrollIntoView({
30161
+ block: 'center',
30162
+ behavior: 'smooth'
30163
+ });
30164
+ }, 100);
30165
+ }
30166
+ };
30167
+ const handleFocusIn = (e) => {
30168
+ const target = e.target;
30169
+ if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA') {
30170
+ isKeyboardActive.value = true;
30171
+ if (isAutoPlaying.value) {
30172
+ clearAutoPlayTimer();
30173
+ }
30174
+ }
30175
+ };
30176
+ const handleFocusOut = (e) => {
30177
+ const target = e.target;
30178
+ if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA') {
30179
+ isKeyboardActive.value = false;
30180
+ if (/Android/i.test(navigator.userAgent)) {
30181
+ setTimeout(() => {
30182
+ window.scrollTo(0, 0);
30183
+ }, 200);
30184
+ }
30185
+ }
30186
+ };
30071
30187
  vue.onMounted(() => {
30188
+ checkIfMobile();
30072
30189
  startAutoPlay();
30073
30190
  if (global.value.music.url) {
30074
30191
  setTimeout(() => {
@@ -30080,9 +30197,19 @@
30080
30197
  handleFirstInteraction();
30081
30198
  }, 1000);
30082
30199
  }
30200
+ if (isMobile.value) {
30201
+ window.addEventListener('resize', handleMobileResize);
30202
+ document.body.addEventListener('focusin', handleFocusIn);
30203
+ document.body.addEventListener('focusout', handleFocusOut);
30204
+ }
30083
30205
  });
30084
30206
  vue.onBeforeUnmount(() => {
30085
30207
  clearAutoPlayTimer();
30208
+ if (isMobile.value) {
30209
+ window.removeEventListener('resize', handleMobileResize);
30210
+ document.body.removeEventListener('focusin', handleFocusIn);
30211
+ document.body.removeEventListener('focusout', handleFocusOut);
30212
+ }
30086
30213
  });
30087
30214
  const { handleTouchStart, handleTouchMove, handleTouchEnd, handleMouseDown, handleMouseMove, handleMouseUp } = useTouchHandler(pages, currentPageId, direction, isLoopEnabled, () => {
30088
30215
  handleFirstInteraction();
@@ -30187,6 +30314,7 @@
30187
30314
  showPopup,
30188
30315
  direction,
30189
30316
  musicPlayer,
30317
+ isKeyboardActive,
30190
30318
  handleFirstInteraction,
30191
30319
  playMusic,
30192
30320
  px2rem,
@@ -30230,7 +30358,8 @@
30230
30358
  onMousemove: _cache[4] || (_cache[4] = (...args) => (_ctx.handleMouseMove && _ctx.handleMouseMove(...args))),
30231
30359
  onMouseup: _cache[5] || (_cache[5] = (...args) => (_ctx.handleMouseUp && _ctx.handleMouseUp(...args))),
30232
30360
  onMouseleave: _cache[6] || (_cache[6] = (...args) => (_ctx.handleMouseUp && _ctx.handleMouseUp(...args))),
30233
- style: vue.normalizeStyle(_ctx.containerStyle)
30361
+ style: vue.normalizeStyle(_ctx.containerStyle),
30362
+ class: vue.normalizeClass({ 'keyboard-active': _ctx.isKeyboardActive })
30234
30363
  }, [
30235
30364
  vue.createCommentVNode(" 背景音乐 "),
30236
30365
  (_ctx.global && _ctx.global.music && _ctx.global.music.url)
@@ -30284,29 +30413,41 @@
30284
30413
  }, {
30285
30414
  default: vue.withCtx(() => [
30286
30415
  (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(page.elements, (element) => {
30287
- return (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(_ctx.getComponentName(element.type)), {
30288
- key: element.id,
30289
- element: element,
30290
- isPlatform: _ctx.isPlatform,
30291
- global: _ctx.global,
30292
- env: _ctx.env,
30293
- personalData: _ctx.personalData,
30294
- onTrigger: _ctx.handleElementTrigger
30295
- }, null, 40 /* PROPS, NEED_HYDRATION */, ["element", "isPlatform", "global", "env", "personalData", "onTrigger"]))
30416
+ return (vue.openBlock(), vue.createElementBlock(vue.Fragment, {
30417
+ key: element.id
30418
+ }, [
30419
+ (element.type !== 'group')
30420
+ ? (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(_ctx.getComponentName(element.type)), {
30421
+ key: 0,
30422
+ element: element,
30423
+ isPlatform: _ctx.isPlatform,
30424
+ global: _ctx.global,
30425
+ env: _ctx.env,
30426
+ personalData: _ctx.personalData,
30427
+ onTrigger: _ctx.handleElementTrigger
30428
+ }, null, 40 /* PROPS, NEED_HYDRATION */, ["element", "isPlatform", "global", "env", "personalData", "onTrigger"]))
30429
+ : vue.createCommentVNode("v-if", true)
30430
+ ], 64 /* STABLE_FRAGMENT */))
30296
30431
  }), 128 /* KEYED_FRAGMENT */))
30297
30432
  ]),
30298
30433
  _: 2 /* DYNAMIC */
30299
30434
  }, 1032 /* PROPS, DYNAMIC_SLOTS */, ["onSubmit"]))
30300
30435
  : (vue.openBlock(true), vue.createElementBlock(vue.Fragment, { key: 1 }, vue.renderList(page.elements, (element) => {
30301
- return (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(_ctx.getComponentName(element.type)), {
30302
- key: element.id,
30303
- element: element,
30304
- global: _ctx.global,
30305
- env: _ctx.env,
30306
- isPlatform: _ctx.isPlatform,
30307
- personalData: _ctx.personalData,
30308
- onTrigger: _ctx.handleElementTrigger
30309
- }, null, 40 /* PROPS, NEED_HYDRATION */, ["element", "global", "env", "isPlatform", "personalData", "onTrigger"]))
30436
+ return (vue.openBlock(), vue.createElementBlock(vue.Fragment, {
30437
+ key: element.id
30438
+ }, [
30439
+ (element.type !== 'group')
30440
+ ? (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(_ctx.getComponentName(element.type)), {
30441
+ key: 0,
30442
+ element: element,
30443
+ global: _ctx.global,
30444
+ env: _ctx.env,
30445
+ isPlatform: _ctx.isPlatform,
30446
+ personalData: _ctx.personalData,
30447
+ onTrigger: _ctx.handleElementTrigger
30448
+ }, null, 40 /* PROPS, NEED_HYDRATION */, ["element", "global", "env", "isPlatform", "personalData", "onTrigger"]))
30449
+ : vue.createCommentVNode("v-if", true)
30450
+ ], 64 /* STABLE_FRAGMENT */))
30310
30451
  }), 128 /* KEYED_FRAGMENT */))
30311
30452
  ])
30312
30453
  ])
@@ -30321,7 +30462,7 @@
30321
30462
  ], 2 /* CLASS */),
30322
30463
  vue.createVNode(_component_UniBarrage, { global: _ctx.global }, null, 8 /* PROPS */, ["global"]),
30323
30464
  vue.createVNode(_component_UniMenu, { global: _ctx.global }, null, 8 /* PROPS */, ["global"])
30324
- ], 36 /* STYLE, NEED_HYDRATION */))
30465
+ ], 38 /* CLASS, STYLE, NEED_HYDRATION */))
30325
30466
  }
30326
30467
 
30327
30468
  script$2.render = render$2;
@@ -30782,29 +30923,41 @@
30782
30923
  }, {
30783
30924
  default: vue.withCtx(() => [
30784
30925
  (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(_ctx.page.elements, (element) => {
30785
- return (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(_ctx.getComponentName(element.type)), {
30786
- key: element.id,
30787
- element: element,
30788
- isPlatform: _ctx.isPlatform,
30789
- global: _ctx.global,
30790
- env: _ctx.env,
30791
- personalData: _ctx.personalData,
30792
- onTrigger: _ctx.handleElementTrigger
30793
- }, null, 40 /* PROPS, NEED_HYDRATION */, ["element", "isPlatform", "global", "env", "personalData", "onTrigger"]))
30926
+ return (vue.openBlock(), vue.createElementBlock(vue.Fragment, {
30927
+ key: element.id
30928
+ }, [
30929
+ (element.type !== 'group')
30930
+ ? (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(_ctx.getComponentName(element.type)), {
30931
+ key: 0,
30932
+ element: element,
30933
+ isPlatform: _ctx.isPlatform,
30934
+ global: _ctx.global,
30935
+ env: _ctx.env,
30936
+ personalData: _ctx.personalData,
30937
+ onTrigger: _ctx.handleElementTrigger
30938
+ }, null, 40 /* PROPS, NEED_HYDRATION */, ["element", "isPlatform", "global", "env", "personalData", "onTrigger"]))
30939
+ : vue.createCommentVNode("v-if", true)
30940
+ ], 64 /* STABLE_FRAGMENT */))
30794
30941
  }), 128 /* KEYED_FRAGMENT */))
30795
30942
  ]),
30796
30943
  _: 1 /* STABLE */
30797
30944
  }, 8 /* PROPS */, ["onSubmit"]))
30798
30945
  : (vue.openBlock(true), vue.createElementBlock(vue.Fragment, { key: 1 }, vue.renderList(_ctx.page.elements, (element) => {
30799
- return (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(_ctx.getComponentName(element.type)), {
30800
- key: element.id,
30801
- element: element,
30802
- global: _ctx.global,
30803
- env: _ctx.env,
30804
- isPlatform: _ctx.isPlatform,
30805
- personalData: _ctx.personalData,
30806
- onTrigger: _ctx.handleElementTrigger
30807
- }, null, 40 /* PROPS, NEED_HYDRATION */, ["element", "global", "env", "isPlatform", "personalData", "onTrigger"]))
30946
+ return (vue.openBlock(), vue.createElementBlock(vue.Fragment, {
30947
+ key: element.id
30948
+ }, [
30949
+ (element.type !== 'group')
30950
+ ? (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(_ctx.getComponentName(element.type)), {
30951
+ key: 0,
30952
+ element: element,
30953
+ global: _ctx.global,
30954
+ env: _ctx.env,
30955
+ isPlatform: _ctx.isPlatform,
30956
+ personalData: _ctx.personalData,
30957
+ onTrigger: _ctx.handleElementTrigger
30958
+ }, null, 40 /* PROPS, NEED_HYDRATION */, ["element", "global", "env", "isPlatform", "personalData", "onTrigger"]))
30959
+ : vue.createCommentVNode("v-if", true)
30960
+ ], 64 /* STABLE_FRAGMENT */))
30808
30961
  }), 128 /* KEYED_FRAGMENT */))
30809
30962
  ])
30810
30963
  ], 36 /* STYLE, NEED_HYDRATION */)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "unika-components",
3
- "version": "1.1.21",
3
+ "version": "1.1.22",
4
4
  "private": false,
5
5
  "main": "dist/unika-components.umd.js",
6
6
  "module": "dist/unika-components.esm.js",