u
This commit is contained in:
1 parent
494f1ad01f
commit
0ab2796dd4
21 files changed
+1583
-472
No files matched your search
@@ -11,6 +11,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@alova/adapter-axios": "^2.0.16",
|
||||
"@expo/html-elements": "0.12.5",
|
||||
"@gluestack-ui/core": "^3.0.12",
|
||||
"@gluestack-ui/utils": "^3.0.11",
|
||||
"@gluestack/ui-next-adapter": "^3.0.3",
|
||||
@@ -44,6 +45,7 @@
|
||||
"react-native-modal": "14.0.0-rc.1",
|
||||
"react-native-pager-view": "6.9.1",
|
||||
"react-native-popup-menu": "^0.18.0",
|
||||
"react-native-qrcode-svg": "^6.3.20",
|
||||
"react-native-reanimated": "~4.1.3",
|
||||
"react-native-safe-area-context": "~5.6.1",
|
||||
"react-native-screens": "~4.16.0",
|
||||
|
||||
+127
-8
@@ -11,6 +11,9 @@ importers:
|
||||
'@alova/adapter-axios':
|
||||
specifier: ^2.0.16
|
||||
version: 2.0.16(alova@3.3.4)(axios@1.13.2)
|
||||
'@expo/html-elements':
|
||||
specifier: 0.12.5
|
||||
version: 0.12.5
|
||||
'@gluestack-ui/core':
|
||||
specifier: ^3.0.12
|
||||
version: 3.0.12(@gluestack-ui/utils@3.0.12(react-dom@19.1.0(react@19.1.0))(react-native-web@0.21.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)(tailwindcss@3.4.18(yaml@2.8.1)))(react-native-safe-area-context@5.6.2(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native-svg@15.12.1(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native-web@0.21.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)
|
||||
@@ -110,6 +113,9 @@ importers:
|
||||
react-native-popup-menu:
|
||||
specifier: ^0.18.0
|
||||
version: 0.18.0
|
||||
react-native-qrcode-svg:
|
||||
specifier: ^6.3.20
|
||||
version: 6.3.20(react-native-svg@15.12.1(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)
|
||||
react-native-reanimated:
|
||||
specifier: ~4.1.3
|
||||
version: 4.1.5(@babel/core@7.28.5)(react-native-worklets@0.5.1(@babel/core@7.28.5)(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)
|
||||
@@ -875,6 +881,9 @@ packages:
|
||||
resolution: {integrity: sha512-8YPJpEYlmV171fi+t+cSLMX1nC5ngY9j2FiN70dHldLpd6Ct6ouGhk96svJ4BQZwsqwII2pokwzrDAwqo4Z0FQ==}
|
||||
hasBin: true
|
||||
|
||||
'@expo/html-elements@0.12.5':
|
||||
resolution: {integrity: sha512-28KWO88YKykKU7ke5sEQs5TivFRMs1Aktz13xxgqAf5rTgb+lka0VKVt3W2fG7ksbUQ407rtUqz7SEAq298NvQ==}
|
||||
|
||||
'@expo/image-utils@0.8.7':
|
||||
resolution: {integrity: sha512-SXOww4Wq3RVXLyOaXiCCuQFguCDh8mmaHBv54h/R29wGl4jRY8GEyQEx8SypV/iHt1FbzsU/X3Qbcd9afm2W2w==}
|
||||
|
||||
@@ -2631,6 +2640,9 @@ packages:
|
||||
client-only@0.0.1:
|
||||
resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==}
|
||||
|
||||
cliui@6.0.0:
|
||||
resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==}
|
||||
|
||||
cliui@8.0.1:
|
||||
resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
|
||||
engines: {node: '>=12'}
|
||||
@@ -2814,6 +2826,10 @@ packages:
|
||||
supports-color:
|
||||
optional: true
|
||||
|
||||
decamelize@1.2.0:
|
||||
resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
decimal.js@10.6.0:
|
||||
resolution: {integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==}
|
||||
|
||||
@@ -2884,6 +2900,9 @@ packages:
|
||||
resolution: {integrity: sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==}
|
||||
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
|
||||
|
||||
dijkstrajs@1.0.3:
|
||||
resolution: {integrity: sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==}
|
||||
|
||||
dlv@1.1.3:
|
||||
resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==}
|
||||
|
||||
@@ -3911,56 +3930,48 @@ packages:
|
||||
engines: {node: '>= 12.0.0'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
lightningcss-linux-arm64-gnu@1.30.2:
|
||||
resolution: {integrity: sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A==}
|
||||
engines: {node: '>= 12.0.0'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
lightningcss-linux-arm64-musl@1.27.0:
|
||||
resolution: {integrity: sha512-rCGBm2ax7kQ9pBSeITfCW9XSVF69VX+fm5DIpvDZQl4NnQoMQyRwhZQm9pd59m8leZ1IesRqWk2v/DntMo26lg==}
|
||||
engines: {node: '>= 12.0.0'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
lightningcss-linux-arm64-musl@1.30.2:
|
||||
resolution: {integrity: sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==}
|
||||
engines: {node: '>= 12.0.0'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
lightningcss-linux-x64-gnu@1.27.0:
|
||||
resolution: {integrity: sha512-Dk/jovSI7qqhJDiUibvaikNKI2x6kWPN79AQiD/E/KeQWMjdGe9kw51RAgoWFDi0coP4jinaH14Nrt/J8z3U4A==}
|
||||
engines: {node: '>= 12.0.0'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
lightningcss-linux-x64-gnu@1.30.2:
|
||||
resolution: {integrity: sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==}
|
||||
engines: {node: '>= 12.0.0'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
lightningcss-linux-x64-musl@1.27.0:
|
||||
resolution: {integrity: sha512-QKjTxXm8A9s6v9Tg3Fk0gscCQA1t/HMoF7Woy1u68wCk5kS4fR+q3vXa1p3++REW784cRAtkYKrPy6JKibrEZA==}
|
||||
engines: {node: '>= 12.0.0'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
lightningcss-linux-x64-musl@1.30.2:
|
||||
resolution: {integrity: sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==}
|
||||
engines: {node: '>= 12.0.0'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
lightningcss-win32-arm64-msvc@1.27.0:
|
||||
resolution: {integrity: sha512-/wXegPS1hnhkeG4OXQKEMQeJd48RDC3qdh+OA8pCuOPCyvnm/yEayrJdJVqzBsqpy1aJklRCVxscpFur80o6iQ==}
|
||||
@@ -4665,6 +4676,10 @@ packages:
|
||||
resolution: {integrity: sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==}
|
||||
engines: {node: '>=4.0.0'}
|
||||
|
||||
pngjs@5.0.0:
|
||||
resolution: {integrity: sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==}
|
||||
engines: {node: '>=10.13.0'}
|
||||
|
||||
pnpm-workspace-yaml@1.3.0:
|
||||
resolution: {integrity: sha512-Krb5q8Totd5mVuLx7we+EFHq/AfxA75nbfTm25Q1pIf606+RlaKUG+PXH8SDihfe5b5k4H09gE+sL47L1t5lbw==}
|
||||
|
||||
@@ -4763,6 +4778,11 @@ packages:
|
||||
resolution: {integrity: sha512-Uu7ii+FQy4Qf82G4xu7ShHhjhGahEpCWc3x8UavY3CTcWV+ufmmCtwkr7ZKsX42jdL0kr1B5FKUeqJvAn51jzQ==}
|
||||
hasBin: true
|
||||
|
||||
qrcode@1.5.4:
|
||||
resolution: {integrity: sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg==}
|
||||
engines: {node: '>=10.13.0'}
|
||||
hasBin: true
|
||||
|
||||
quansync@0.2.11:
|
||||
resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==}
|
||||
|
||||
@@ -4885,6 +4905,13 @@ packages:
|
||||
react-native-popup-menu@0.18.0:
|
||||
resolution: {integrity: sha512-XD3gyp/hwL5YWw2J034DerfvbJ6S2YHqAzvqAFRU+UGnFD4JyTqggfm4UyynBD26O1PDoRb45Loil+NZCGfCnA==}
|
||||
|
||||
react-native-qrcode-svg@6.3.20:
|
||||
resolution: {integrity: sha512-GDP7T3DDEHUo53xmDyWWXXm3MhWRp0YayqVMum98JYfm0DW2rEbz1GIj+XLaA0QX443G0nURyzPnuQJeHjuvjA==}
|
||||
peerDependencies:
|
||||
react: '*'
|
||||
react-native: '>=0.63.4'
|
||||
react-native-svg: '>=14.0.0'
|
||||
|
||||
react-native-reanimated@4.1.5:
|
||||
resolution: {integrity: sha512-UA6VUbxwhRjEw2gSNrvhkusUq3upfD3Cv+AnB07V+kC8kpvwRVI+ivwY95ePbWNFkFpP+Y2Sdw1WHpHWEV+P2Q==}
|
||||
peerDependencies:
|
||||
@@ -5040,6 +5067,9 @@ packages:
|
||||
resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
require-main-filename@2.0.0:
|
||||
resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==}
|
||||
|
||||
requireg@0.2.2:
|
||||
resolution: {integrity: sha512-nYzyjnFcPNGR3lx9lwPPPnuQxv6JWEZd2Ci0u9opN7N5zUEPIhY/GbL3vMGOr2UXwEg9WwSyV9X9Y/kLFgPsOg==}
|
||||
engines: {node: '>= 4.0.0'}
|
||||
@@ -5148,6 +5178,9 @@ packages:
|
||||
server-only@0.0.1:
|
||||
resolution: {integrity: sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA==}
|
||||
|
||||
set-blocking@2.0.0:
|
||||
resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==}
|
||||
|
||||
setimmediate@1.0.5:
|
||||
resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==}
|
||||
|
||||
@@ -5375,6 +5408,10 @@ packages:
|
||||
resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
text-encoding@0.7.0:
|
||||
resolution: {integrity: sha512-oJQ3f1hrOnbRLOcwKz0Liq2IcrvDeZRHXhd9RgLrsT+DjWY/nty1Hi7v3dtkaEYbPYe0mUoOfzRrMwfXXwgPUA==}
|
||||
deprecated: no longer maintained
|
||||
|
||||
thenify-all@1.6.0:
|
||||
resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==}
|
||||
engines: {node: '>=0.8'}
|
||||
@@ -5609,6 +5646,9 @@ packages:
|
||||
whatwg-url@5.0.0:
|
||||
resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==}
|
||||
|
||||
which-module@2.0.1:
|
||||
resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==}
|
||||
|
||||
which@2.0.2:
|
||||
resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
|
||||
engines: {node: '>= 8'}
|
||||
@@ -5621,6 +5661,10 @@ packages:
|
||||
resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
wrap-ansi@6.2.0:
|
||||
resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
wrap-ansi@7.0.0:
|
||||
resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
|
||||
engines: {node: '>=10'}
|
||||
@@ -5695,6 +5739,9 @@ packages:
|
||||
resolution: {integrity: sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==}
|
||||
engines: {node: '>=8.0'}
|
||||
|
||||
y18n@4.0.3:
|
||||
resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==}
|
||||
|
||||
y18n@5.0.8:
|
||||
resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
|
||||
engines: {node: '>=10'}
|
||||
@@ -5715,10 +5762,18 @@ packages:
|
||||
engines: {node: '>= 14.6'}
|
||||
hasBin: true
|
||||
|
||||
yargs-parser@18.1.3:
|
||||
resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
yargs-parser@21.1.1:
|
||||
resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
yargs@15.4.1:
|
||||
resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
yargs@17.7.2:
|
||||
resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==}
|
||||
engines: {node: '>=12'}
|
||||
@@ -6698,6 +6753,8 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@expo/html-elements@0.12.5': {}
|
||||
|
||||
'@expo/image-utils@0.8.7':
|
||||
dependencies:
|
||||
'@expo/spawn-async': 1.7.2
|
||||
@@ -9139,6 +9196,12 @@ snapshots:
|
||||
|
||||
client-only@0.0.1: {}
|
||||
|
||||
cliui@6.0.0:
|
||||
dependencies:
|
||||
string-width: 4.2.3
|
||||
strip-ansi: 6.0.1
|
||||
wrap-ansi: 6.2.0
|
||||
|
||||
cliui@8.0.1:
|
||||
dependencies:
|
||||
string-width: 4.2.3
|
||||
@@ -9310,6 +9373,8 @@ snapshots:
|
||||
dependencies:
|
||||
ms: 2.1.3
|
||||
|
||||
decamelize@1.2.0: {}
|
||||
|
||||
decimal.js@10.6.0: {}
|
||||
|
||||
decode-named-character-reference@1.2.0:
|
||||
@@ -9358,6 +9423,8 @@ snapshots:
|
||||
|
||||
diff-sequences@27.5.1: {}
|
||||
|
||||
dijkstrajs@1.0.3: {}
|
||||
|
||||
dlv@1.1.3: {}
|
||||
|
||||
dom-helpers@6.0.1:
|
||||
@@ -11581,6 +11648,8 @@ snapshots:
|
||||
|
||||
pngjs@3.4.0: {}
|
||||
|
||||
pngjs@5.0.0: {}
|
||||
|
||||
pnpm-workspace-yaml@1.3.0:
|
||||
dependencies:
|
||||
yaml: 2.8.1
|
||||
@@ -11668,6 +11737,12 @@ snapshots:
|
||||
|
||||
qrcode-terminal@0.11.0: {}
|
||||
|
||||
qrcode@1.5.4:
|
||||
dependencies:
|
||||
dijkstrajs: 1.0.3
|
||||
pngjs: 5.0.0
|
||||
yargs: 15.4.1
|
||||
|
||||
quansync@0.2.11: {}
|
||||
|
||||
query-string@7.1.3:
|
||||
@@ -11841,6 +11916,15 @@ snapshots:
|
||||
|
||||
react-native-popup-menu@0.18.0: {}
|
||||
|
||||
react-native-qrcode-svg@6.3.20(react-native-svg@15.12.1(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0):
|
||||
dependencies:
|
||||
prop-types: 15.8.1
|
||||
qrcode: 1.5.4
|
||||
react: 19.1.0
|
||||
react-native: 0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0)
|
||||
react-native-svg: 15.12.1(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)
|
||||
text-encoding: 0.7.0
|
||||
|
||||
react-native-reanimated@4.1.5(@babel/core@7.28.5)(react-native-worklets@0.5.1(@babel/core@7.28.5)(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.28.5)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0):
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
@@ -12080,6 +12164,8 @@ snapshots:
|
||||
|
||||
require-from-string@2.0.2: {}
|
||||
|
||||
require-main-filename@2.0.0: {}
|
||||
|
||||
requireg@0.2.2:
|
||||
dependencies:
|
||||
nested-error-stacks: 2.0.1
|
||||
@@ -12198,6 +12284,8 @@ snapshots:
|
||||
|
||||
server-only@0.0.1: {}
|
||||
|
||||
set-blocking@2.0.0: {}
|
||||
|
||||
setimmediate@1.0.5: {}
|
||||
|
||||
setprototypeof@1.2.0: {}
|
||||
@@ -12427,6 +12515,8 @@ snapshots:
|
||||
glob: 7.2.3
|
||||
minimatch: 3.1.2
|
||||
|
||||
text-encoding@0.7.0: {}
|
||||
|
||||
thenify-all@1.6.0:
|
||||
dependencies:
|
||||
thenify: 3.3.1
|
||||
@@ -12629,6 +12719,8 @@ snapshots:
|
||||
tr46: 0.0.3
|
||||
webidl-conversions: 3.0.1
|
||||
|
||||
which-module@2.0.1: {}
|
||||
|
||||
which@2.0.2:
|
||||
dependencies:
|
||||
isexe: 2.0.0
|
||||
@@ -12637,6 +12729,12 @@ snapshots:
|
||||
|
||||
word-wrap@1.2.5: {}
|
||||
|
||||
wrap-ansi@6.2.0:
|
||||
dependencies:
|
||||
ansi-styles: 4.3.0
|
||||
string-width: 4.2.3
|
||||
strip-ansi: 6.0.1
|
||||
|
||||
wrap-ansi@7.0.0:
|
||||
dependencies:
|
||||
ansi-styles: 4.3.0
|
||||
@@ -12685,6 +12783,8 @@ snapshots:
|
||||
|
||||
xmlbuilder@15.1.1: {}
|
||||
|
||||
y18n@4.0.3: {}
|
||||
|
||||
y18n@5.0.8: {}
|
||||
|
||||
yallist@3.1.1: {}
|
||||
@@ -12698,8 +12798,27 @@ snapshots:
|
||||
|
||||
yaml@2.8.1: {}
|
||||
|
||||
yargs-parser@18.1.3:
|
||||
dependencies:
|
||||
camelcase: 5.3.1
|
||||
decamelize: 1.2.0
|
||||
|
||||
yargs-parser@21.1.1: {}
|
||||
|
||||
yargs@15.4.1:
|
||||
dependencies:
|
||||
cliui: 6.0.0
|
||||
decamelize: 1.2.0
|
||||
find-up: 4.1.0
|
||||
get-caller-file: 2.0.5
|
||||
require-directory: 2.1.1
|
||||
require-main-filename: 2.0.0
|
||||
set-blocking: 2.0.0
|
||||
string-width: 4.2.3
|
||||
which-module: 2.0.1
|
||||
y18n: 4.0.3
|
||||
yargs-parser: 18.1.3
|
||||
|
||||
yargs@17.7.2:
|
||||
dependencies:
|
||||
cliui: 8.0.1
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { MoneyRecordGroup, MoneyRecordItem } from '@/types/money/record'
|
||||
import React, { useCallback, useState } from 'react'
|
||||
import { RefreshControl, SectionList, Text, TouchableHighlight, View } from 'react-native'
|
||||
import { RefreshControl, SectionList, Text, TouchableHighlight, Vibration, View } from 'react-native'
|
||||
import {
|
||||
Menu,
|
||||
MenuOption,
|
||||
@@ -120,7 +120,6 @@ export default function StaticTransactions({
|
||||
|
||||
renderItem={({ item, index }) => {
|
||||
const category = moneyCategoryStore.getCategoryById(item.category_id)
|
||||
|
||||
return (
|
||||
<Menu
|
||||
renderer={renderers.Popover}
|
||||
@@ -135,7 +134,12 @@ export default function StaticTransactions({
|
||||
onOpen={() => setSelectedId(item.id)}
|
||||
onClose={() => setSelectedId(null)}
|
||||
>
|
||||
<MenuTrigger triggerOnLongPress>
|
||||
<MenuTrigger
|
||||
triggerOnLongPress
|
||||
onPress={() => {
|
||||
Vibration.vibrate(50)
|
||||
}}
|
||||
>
|
||||
<View
|
||||
className="flex-row items-center gap-4 py-2 px-5"
|
||||
style={{
|
||||
@@ -179,7 +183,6 @@ export default function StaticTransactions({
|
||||
},
|
||||
}}
|
||||
>
|
||||
|
||||
<MenuOption
|
||||
customStyles={{
|
||||
OptionTouchableComponent: TouchableHighlight,
|
||||
|
||||
@@ -1,12 +1,34 @@
|
||||
import type { AFormRef } from '@/components/common/ao'
|
||||
import { SquareUserRound } from 'lucide-react-native'
|
||||
import * as React from 'react'
|
||||
import { useRef, useState } from 'react'
|
||||
import { Text, View } from 'react-native'
|
||||
import { AButton, AForm, AFormItem, AInput, ASegmentedTabs, ATab, LucideIcon } from '@/components/common/ao'
|
||||
import { FlatList, Pressable, TouchableOpacity, View } from 'react-native'
|
||||
import QRCode from 'react-native-qrcode-svg'
|
||||
import { AButton, ADivider, AForm, AFormItem, AInput, LucideIcon } from '@/components/common/ao'
|
||||
import CustomHeader from '@/components/custom/Header'
|
||||
import { Badge, BadgeIcon, BadgeText } from '@/components/ui/badge'
|
||||
import { Divider } from '@/components/ui/divider'
|
||||
import {
|
||||
Accordion,
|
||||
AccordionContent,
|
||||
AccordionHeader,
|
||||
AccordionIcon,
|
||||
AccordionItem,
|
||||
AccordionTitleText,
|
||||
AccordionTrigger,
|
||||
} from '@/components/ui/accordion'
|
||||
import {
|
||||
Avatar,
|
||||
AvatarBadge,
|
||||
AvatarFallbackText,
|
||||
AvatarImage,
|
||||
} from '@/components/ui/avatar'
|
||||
import { Badge, BadgeText } from '@/components/ui/badge'
|
||||
|
||||
import { Heading } from '@/components/ui/heading'
|
||||
import { HStack } from '@/components/ui/hstack'
|
||||
import { ChevronDownIcon, ChevronUpIcon } from '@/components/ui/icon'
|
||||
import { Link, LinkText } from '@/components/ui/link'
|
||||
import { Menu, MenuItem, MenuItemLabel } from '@/components/ui/menu'
|
||||
import { Text } from '@/components/ui/text'
|
||||
import { VStack } from '@/components/ui/vstack'
|
||||
|
||||
export default function PagerWithTab() {
|
||||
const formRef = useRef<AFormRef>(null)
|
||||
@@ -14,9 +36,11 @@ export default function PagerWithTab() {
|
||||
code: '',
|
||||
})
|
||||
|
||||
const [accordion, setAccordion] = useState(['a'])
|
||||
|
||||
function EnterSapce() {
|
||||
return (
|
||||
<View>
|
||||
<View className="px-4 items-center">
|
||||
<AForm ref={formRef} form={form}>
|
||||
<AFormItem
|
||||
name="username"
|
||||
@@ -26,7 +50,7 @@ export default function PagerWithTab() {
|
||||
</AFormItem>
|
||||
</AForm>
|
||||
|
||||
<AButton>加入空间</AButton>
|
||||
<AButton className="w-full">加入空间</AButton>
|
||||
<View
|
||||
className="flex-row items-center w-full"
|
||||
style={{
|
||||
@@ -35,19 +59,27 @@ export default function PagerWithTab() {
|
||||
}}
|
||||
>
|
||||
<View className="flex-1">
|
||||
<Divider />
|
||||
<ADivider />
|
||||
</View>
|
||||
<Text className="mx-3 text-gray-500 text-sm">或</Text>
|
||||
<View className="flex-1">
|
||||
<Divider />
|
||||
<ADivider />
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<AButton variant="outline">扫码加入</AButton>
|
||||
<AButton variant="outline" className="w-full">扫码加入</AButton>
|
||||
|
||||
<Link className="mt-4">
|
||||
<LinkText>返回</LinkText>
|
||||
</Link>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
const members = [
|
||||
{ id: 1, name: '张三' },
|
||||
{ id: 2, name: '李四' },
|
||||
{ id: 3, name: '王五' },
|
||||
]
|
||||
|
||||
return (
|
||||
<View className="flex-1">
|
||||
@@ -79,24 +111,65 @@ export default function PagerWithTab() {
|
||||
<AButton variant="outline">加入已有空间</AButton>
|
||||
</View> */}
|
||||
|
||||
<View className="p-4">
|
||||
<View>
|
||||
<View className="flex flex-row items-center justify-between">
|
||||
<Text className="font-semibold text-lg">邀请好友加入</Text>
|
||||
</View>
|
||||
|
||||
<View
|
||||
className="flex-row items-center justify-between px-2 py-2 mt-4 border-round"
|
||||
style={{
|
||||
backgroundColor: '#f8f9fa',
|
||||
{/* <View className="px-4 flex-1">
|
||||
<Accordion
|
||||
size="md"
|
||||
variant="unfilled"
|
||||
type="multiple"
|
||||
isCollapsible={true}
|
||||
isDisabled={false}
|
||||
value={accordion}
|
||||
onValueChange={(value) => {
|
||||
setAccordion(value)
|
||||
}}
|
||||
>
|
||||
<AccordionItem value="a">
|
||||
<AccordionHeader>
|
||||
<AccordionTrigger
|
||||
style={{
|
||||
paddingLeft: 0,
|
||||
paddingRight: 0,
|
||||
}}
|
||||
>
|
||||
{({ isExpanded }: { isExpanded: boolean }) => {
|
||||
return (
|
||||
<>
|
||||
<AccordionTitleText className="font-semibold text-lg">
|
||||
我的邀请码
|
||||
</AccordionTitleText>
|
||||
{isExpanded
|
||||
? (
|
||||
<AccordionIcon as={ChevronUpIcon} className="ml-3" />
|
||||
)
|
||||
: (
|
||||
<AccordionIcon as={ChevronDownIcon} className="ml-3" />
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}}
|
||||
</AccordionTrigger>
|
||||
</AccordionHeader>
|
||||
<AccordionContent style={{
|
||||
marginBottom: 0,
|
||||
paddingBottom: 0,
|
||||
}}
|
||||
>
|
||||
<Text>123456</Text>
|
||||
<AButton size="xs">复制代码</AButton>
|
||||
</View>
|
||||
</View>
|
||||
>
|
||||
<TouchableOpacity className="flex-row items-center justify-center ">
|
||||
<Text className="font-bold text-3xl tracking-[4px] mr-3">123456</Text>
|
||||
<LucideIcon icon="Copy" size={16} color="blue" clickable={false} />
|
||||
</TouchableOpacity>
|
||||
|
||||
<View className="mt-8">
|
||||
<View className="items-center justify-center">
|
||||
<ADivider direction="horizontal" text="扫描二维码" />
|
||||
<QRCode
|
||||
size={120}
|
||||
value="http://awesome.link.qr"
|
||||
/>
|
||||
</View>
|
||||
</AccordionContent>
|
||||
</AccordionItem>
|
||||
</Accordion>
|
||||
<View className="mt-4 flex-1">
|
||||
<View className="flex flex-row items-center justify-between">
|
||||
<Text className="font-semibold text-lg">空间成员</Text>
|
||||
<Badge size="lg" variant="solid" action="muted">
|
||||
@@ -104,12 +177,65 @@ export default function PagerWithTab() {
|
||||
</Badge>
|
||||
</View>
|
||||
|
||||
<View className="mt-2">
|
||||
<Text>列表</Text>
|
||||
<View>
|
||||
<FlatList
|
||||
data={members}
|
||||
keyExtractor={item => item.id.toString()}
|
||||
renderItem={({ item }) => (
|
||||
<TouchableOpacity>
|
||||
<HStack space="md" className="my-2 items-center">
|
||||
<Avatar className="bg-indigo-600">
|
||||
<AvatarFallbackText className="text-white text-lg">
|
||||
{item.name}
|
||||
</AvatarFallbackText>
|
||||
<AvatarBadge />
|
||||
</Avatar>
|
||||
<VStack>
|
||||
<HStack space="sm">
|
||||
<Heading size="sm">{item.name}</Heading>
|
||||
<Badge size="sm" variant="solid" action="muted">
|
||||
<BadgeText>管理员</BadgeText>
|
||||
</Badge>
|
||||
</HStack>
|
||||
<Text size="sm">Marketing Coordinator</Text>
|
||||
</VStack>
|
||||
|
||||
<View className="ml-auto">
|
||||
<Menu
|
||||
placement="top"
|
||||
offset={5}
|
||||
trigger={triggerProps => (
|
||||
<Pressable
|
||||
{...triggerProps}
|
||||
style={{
|
||||
padding: 8,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
}}
|
||||
>
|
||||
<LucideIcon icon="EllipsisVertical" size={20} clickable={false} />
|
||||
</Pressable>
|
||||
)}
|
||||
>
|
||||
<MenuItem key="Add account" textValue="Add account">
|
||||
<MenuItemLabel size="sm">添加为管理员</MenuItemLabel>
|
||||
</MenuItem>
|
||||
<MenuItem key="Community" textValue="Community">
|
||||
<MenuItemLabel size="sm">移出空间</MenuItemLabel>
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
</View>
|
||||
</HStack>
|
||||
</TouchableOpacity>
|
||||
)}
|
||||
/>
|
||||
</View>
|
||||
<AButton size="sm" className="mb-8 mt-4">退出该空间</AButton>
|
||||
</View>
|
||||
|
||||
</View>
|
||||
</View> */}
|
||||
|
||||
<EnterSapce />
|
||||
</View>
|
||||
</View>
|
||||
)
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
import type { ViewStyle } from 'react-native'
|
||||
import React from 'react'
|
||||
import { Text, View } from 'react-native'
|
||||
|
||||
interface DividerProps {
|
||||
direction?: 'horizontal' | 'vertical'
|
||||
text?: string | React.ReactNode
|
||||
textPosition?: 'left' | 'center' | 'right'
|
||||
style?: ViewStyle
|
||||
className?: string
|
||||
}
|
||||
|
||||
export default function Divider({
|
||||
direction = 'horizontal',
|
||||
text,
|
||||
textPosition = 'center',
|
||||
style,
|
||||
className,
|
||||
}: DividerProps) {
|
||||
const isString = typeof text === 'string'
|
||||
|
||||
// 垂直分割线
|
||||
if (direction === 'vertical') {
|
||||
return (
|
||||
<View
|
||||
style={style}
|
||||
className={`w-px bg-gray-300 mx-2 h-4 ${className ?? ''}`}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
// 水平,无文字
|
||||
if (!text) {
|
||||
return (
|
||||
<View
|
||||
style={style}
|
||||
className={`h-px bg-gray-300 my-2 w-full ${className ?? ''}`}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
// 水平 + 文本
|
||||
return (
|
||||
<View
|
||||
style={style}
|
||||
className={`flex-row items-center my-2 ${className ?? ''}`}
|
||||
>
|
||||
{/* 左线 */}
|
||||
<View
|
||||
className={`h-px bg-gray-300 ${
|
||||
textPosition === 'left' ? 'w-2' : 'flex-1'
|
||||
}`}
|
||||
/>
|
||||
|
||||
{/* 文本(字符串 → 自动包裹 Text;node → 直接渲染) */}
|
||||
<View className="mx-3">
|
||||
{isString
|
||||
? (
|
||||
<Text className="text-gray-500 text-sm">{text}</Text>
|
||||
)
|
||||
: (
|
||||
text
|
||||
)}
|
||||
</View>
|
||||
|
||||
{/* 右线 */}
|
||||
<View
|
||||
className={`h-px bg-gray-300 ${
|
||||
textPosition === 'right' ? 'w-2' : 'flex-1'
|
||||
}`}
|
||||
/>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
@@ -2,6 +2,7 @@ import Button from './Button'
|
||||
import { Cell, CellGroup } from './Cell'
|
||||
import Checkbox from './Checkbox'
|
||||
import DatePicker from './DatePicker'
|
||||
import Divider from './Divider'
|
||||
import Form, { FormRef } from './Form'
|
||||
import FormItem from './FormItem'
|
||||
import Input from './Input'
|
||||
@@ -16,6 +17,7 @@ export {
|
||||
CellGroup as ACellGroup,
|
||||
Checkbox as ACheckbox,
|
||||
DatePicker as ADatePicker,
|
||||
Divider as ADivider,
|
||||
Form as AForm,
|
||||
FormItem as AFormItem,
|
||||
FormRef as AFormRef,
|
||||
|
||||
@@ -0,0 +1,331 @@
|
||||
'use client';
|
||||
import React from 'react';
|
||||
import { createAccordion } from '@gluestack-ui/core/accordion/creator';
|
||||
import { View, Pressable, Text, Platform, TextProps } from 'react-native';
|
||||
import { tva } from '@gluestack-ui/utils/nativewind-utils';
|
||||
import type { VariantProps } from '@gluestack-ui/utils/nativewind-utils';
|
||||
import {
|
||||
withStyleContext,
|
||||
useStyleContext,
|
||||
} from '@gluestack-ui/utils/nativewind-utils';
|
||||
import { H3 } from '@expo/html-elements';
|
||||
import { cssInterop } from 'nativewind';
|
||||
import { PrimitiveIcon, UIIcon } from '@gluestack-ui/core/icon/creator';
|
||||
|
||||
const SCOPE = 'ACCORDION';
|
||||
/** Styles */
|
||||
|
||||
const accordionStyle = tva({
|
||||
base: 'w-full',
|
||||
variants: {
|
||||
variant: {
|
||||
filled: 'bg-white shadow-hard-2',
|
||||
unfilled: '',
|
||||
},
|
||||
size: {
|
||||
sm: '',
|
||||
md: '',
|
||||
lg: '',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const accordionItemStyle = tva({
|
||||
base: '',
|
||||
parentVariants: {
|
||||
variant: {
|
||||
filled: 'bg-background-0',
|
||||
unfilled: 'bg-transparent',
|
||||
},
|
||||
},
|
||||
});
|
||||
const accordionTitleTextStyle = tva({
|
||||
base: 'text-typography-900 font-bold flex-1 text-left',
|
||||
parentVariants: {
|
||||
size: {
|
||||
sm: 'text-sm',
|
||||
md: 'text-base',
|
||||
lg: 'text-lg',
|
||||
},
|
||||
},
|
||||
});
|
||||
const accordionIconStyle = tva({
|
||||
base: 'text-typography-900 fill-none',
|
||||
parentVariants: {
|
||||
size: {
|
||||
'2xs': 'h-3 w-3',
|
||||
'xs': 'h-3.5 w-3.5',
|
||||
'sm': 'h-4 w-4',
|
||||
'md': 'h-[18px] w-[18px]',
|
||||
'lg': 'h-5 w-5',
|
||||
'xl': 'h-6 w-6',
|
||||
},
|
||||
},
|
||||
});
|
||||
const accordionContentTextStyle = tva({
|
||||
base: 'text-typography-700 font-normal',
|
||||
parentVariants: {
|
||||
size: {
|
||||
sm: 'text-sm',
|
||||
md: 'text-base',
|
||||
lg: 'text-lg',
|
||||
},
|
||||
},
|
||||
});
|
||||
const accordionHeaderStyle = tva({
|
||||
base: 'mx-0 my-0',
|
||||
});
|
||||
const accordionContentStyle = tva({
|
||||
base: 'pt-1 pb-3 px-4',
|
||||
});
|
||||
const accordionTriggerStyle = tva({
|
||||
base: 'w-full flex-row justify-between items-center web:outline-none focus:outline-none data-[disabled=true]:opacity-40 data-[disabled=true]:cursor-not-allowed data-[focus-visible=true]:bg-background-50 py-3 px-4',
|
||||
});
|
||||
|
||||
const Root = withStyleContext(View, SCOPE);
|
||||
|
||||
const Header = (
|
||||
Platform.OS === 'web' ? H3 : View
|
||||
) as React.ComponentType<TextProps>;
|
||||
|
||||
/** Creator */
|
||||
const UIAccordion = createAccordion({
|
||||
Root: Root,
|
||||
Item: View,
|
||||
Header: Header,
|
||||
Trigger: Pressable,
|
||||
Icon: UIIcon,
|
||||
TitleText: Text,
|
||||
ContentText: Text,
|
||||
Content: View,
|
||||
});
|
||||
|
||||
cssInterop(PrimitiveIcon, {
|
||||
className: {
|
||||
target: 'style',
|
||||
nativeStyleToProp: {
|
||||
height: true,
|
||||
width: true,
|
||||
fill: true,
|
||||
color: 'classNameColor',
|
||||
stroke: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
cssInterop(H3, {
|
||||
className: {
|
||||
target: 'style',
|
||||
},
|
||||
});
|
||||
|
||||
type IAccordionProps = React.ComponentPropsWithoutRef<typeof UIAccordion> &
|
||||
VariantProps<typeof accordionStyle>;
|
||||
|
||||
type IAccordionItemProps = React.ComponentPropsWithoutRef<
|
||||
typeof UIAccordion.Item
|
||||
> &
|
||||
VariantProps<typeof accordionItemStyle>;
|
||||
|
||||
type IAccordionContentProps = React.ComponentPropsWithoutRef<
|
||||
typeof UIAccordion.Content
|
||||
> &
|
||||
VariantProps<typeof accordionContentStyle>;
|
||||
|
||||
type IAccordionContentTextProps = React.ComponentPropsWithoutRef<
|
||||
typeof UIAccordion.ContentText
|
||||
> &
|
||||
VariantProps<typeof accordionContentTextStyle>;
|
||||
|
||||
type IAccordionIconProps = VariantProps<typeof accordionIconStyle> &
|
||||
React.ComponentPropsWithoutRef<typeof UIAccordion.Icon> & {
|
||||
as?: React.ElementType;
|
||||
height?: number;
|
||||
width?: number;
|
||||
};
|
||||
|
||||
type IAccordionHeaderProps = React.ComponentPropsWithoutRef<
|
||||
typeof UIAccordion.Header
|
||||
> &
|
||||
VariantProps<typeof accordionHeaderStyle>;
|
||||
|
||||
type IAccordionTriggerProps = React.ComponentPropsWithoutRef<
|
||||
typeof UIAccordion.Trigger
|
||||
> &
|
||||
VariantProps<typeof accordionTriggerStyle>;
|
||||
|
||||
type IAccordionTitleTextProps = React.ComponentPropsWithoutRef<
|
||||
typeof UIAccordion.TitleText
|
||||
> &
|
||||
VariantProps<typeof accordionTitleTextStyle>;
|
||||
|
||||
/** Components */
|
||||
|
||||
const Accordion = React.forwardRef<
|
||||
React.ComponentRef<typeof UIAccordion>,
|
||||
IAccordionProps
|
||||
>(({ className, variant = 'filled', size = 'md', ...props }, ref) => {
|
||||
return (
|
||||
<UIAccordion
|
||||
ref={ref}
|
||||
{...props}
|
||||
className={accordionStyle({ variant, class: className })}
|
||||
context={{ variant, size }}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
const AccordionItem = React.forwardRef<
|
||||
React.ComponentRef<typeof UIAccordion.Item>,
|
||||
IAccordionItemProps
|
||||
>(({ className, ...props }, ref) => {
|
||||
const { variant } = useStyleContext(SCOPE);
|
||||
return (
|
||||
<UIAccordion.Item
|
||||
ref={ref}
|
||||
{...props}
|
||||
className={accordionItemStyle({
|
||||
parentVariants: { variant },
|
||||
class: className,
|
||||
})}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
const AccordionContent = React.forwardRef<
|
||||
React.ComponentRef<typeof UIAccordion.Content>,
|
||||
IAccordionContentProps
|
||||
>(function AccordionContent({ className, ...props }, ref) {
|
||||
return (
|
||||
<UIAccordion.Content
|
||||
ref={ref}
|
||||
{...props}
|
||||
className={accordionContentStyle({
|
||||
class: className,
|
||||
})}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
const AccordionContentText = React.forwardRef<
|
||||
React.ComponentRef<typeof UIAccordion.ContentText>,
|
||||
IAccordionContentTextProps
|
||||
>(function AccordionContentText({ className, ...props }, ref) {
|
||||
const { size } = useStyleContext(SCOPE);
|
||||
return (
|
||||
<UIAccordion.ContentText
|
||||
ref={ref}
|
||||
{...props}
|
||||
className={accordionContentTextStyle({
|
||||
parentVariants: { size },
|
||||
class: className,
|
||||
})}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
const AccordionIcon = React.forwardRef<
|
||||
React.ComponentRef<typeof UIAccordion.Icon>,
|
||||
IAccordionIconProps
|
||||
>(function AccordionIcon({ size, className, ...props }, ref) {
|
||||
const { size: parentSize } = useStyleContext(SCOPE);
|
||||
|
||||
if (typeof size === 'number') {
|
||||
return (
|
||||
<UIAccordion.Icon
|
||||
ref={ref}
|
||||
{...props}
|
||||
className={accordionIconStyle({ class: className })}
|
||||
size={size}
|
||||
/>
|
||||
);
|
||||
} else if (
|
||||
(props.height !== undefined || props.width !== undefined) &&
|
||||
size === undefined
|
||||
) {
|
||||
return (
|
||||
<UIAccordion.Icon
|
||||
ref={ref}
|
||||
{...props}
|
||||
className={accordionIconStyle({ class: className })}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<UIAccordion.Icon
|
||||
ref={ref}
|
||||
{...props}
|
||||
className={accordionIconStyle({
|
||||
size,
|
||||
class: className,
|
||||
parentVariants: { size: parentSize },
|
||||
})}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
const AccordionHeader = React.forwardRef<
|
||||
React.ComponentRef<typeof UIAccordion.Header>,
|
||||
IAccordionHeaderProps
|
||||
>(function AccordionHeader({ className, ...props }, ref) {
|
||||
return (
|
||||
<UIAccordion.Header
|
||||
ref={ref}
|
||||
{...props}
|
||||
className={accordionHeaderStyle({
|
||||
class: className,
|
||||
})}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
const AccordionTrigger = React.forwardRef<
|
||||
React.ComponentRef<typeof UIAccordion.Trigger>,
|
||||
IAccordionTriggerProps
|
||||
>(function AccordionTrigger({ className, ...props }, ref) {
|
||||
return (
|
||||
<UIAccordion.Trigger
|
||||
ref={ref}
|
||||
{...props}
|
||||
className={accordionTriggerStyle({
|
||||
class: className,
|
||||
})}
|
||||
/>
|
||||
);
|
||||
});
|
||||
const AccordionTitleText = React.forwardRef<
|
||||
React.ComponentRef<typeof UIAccordion.TitleText>,
|
||||
IAccordionTitleTextProps
|
||||
>(function AccordionTitleText({ className, ...props }, ref) {
|
||||
const { size } = useStyleContext(SCOPE);
|
||||
return (
|
||||
<UIAccordion.TitleText
|
||||
ref={ref}
|
||||
{...props}
|
||||
className={accordionTitleTextStyle({
|
||||
parentVariants: { size },
|
||||
class: className,
|
||||
})}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
Accordion.displayName = 'Accordion';
|
||||
AccordionItem.displayName = 'AccordionItem';
|
||||
AccordionHeader.displayName = 'AccordionHeader';
|
||||
AccordionTrigger.displayName = 'AccordionTrigger';
|
||||
AccordionTitleText.displayName = 'AccordionTitleText';
|
||||
AccordionContentText.displayName = 'AccordionContentText';
|
||||
AccordionIcon.displayName = 'AccordionIcon';
|
||||
AccordionContent.displayName = 'AccordionContent';
|
||||
|
||||
export {
|
||||
Accordion,
|
||||
AccordionItem,
|
||||
AccordionHeader,
|
||||
AccordionTrigger,
|
||||
AccordionTitleText,
|
||||
AccordionContentText,
|
||||
AccordionIcon,
|
||||
AccordionContent,
|
||||
};
|
||||
@@ -0,0 +1,220 @@
|
||||
import React, { forwardRef, memo } from 'react';
|
||||
import { H1, H2, H3, H4, H5, H6 } from '@expo/html-elements';
|
||||
import { headingStyle } from './styles';
|
||||
import type { VariantProps } from '@gluestack-ui/utils/nativewind-utils';
|
||||
import { cssInterop } from 'nativewind';
|
||||
|
||||
type IHeadingProps = VariantProps<typeof headingStyle> &
|
||||
React.ComponentPropsWithoutRef<typeof H1> & {
|
||||
as?: React.ElementType;
|
||||
};
|
||||
|
||||
cssInterop(H1, { className: 'style' });
|
||||
cssInterop(H2, { className: 'style' });
|
||||
cssInterop(H3, { className: 'style' });
|
||||
cssInterop(H4, { className: 'style' });
|
||||
cssInterop(H5, { className: 'style' });
|
||||
cssInterop(H6, { className: 'style' });
|
||||
|
||||
const MappedHeading = memo(
|
||||
forwardRef<React.ComponentRef<typeof H1>, IHeadingProps>(
|
||||
function MappedHeading(
|
||||
{
|
||||
size,
|
||||
className,
|
||||
isTruncated,
|
||||
bold,
|
||||
underline,
|
||||
strikeThrough,
|
||||
sub,
|
||||
italic,
|
||||
highlight,
|
||||
...props
|
||||
},
|
||||
ref
|
||||
) {
|
||||
switch (size) {
|
||||
case '5xl':
|
||||
case '4xl':
|
||||
case '3xl':
|
||||
return (
|
||||
<H1
|
||||
className={headingStyle({
|
||||
size,
|
||||
isTruncated: isTruncated as boolean,
|
||||
bold: bold as boolean,
|
||||
underline: underline as boolean,
|
||||
strikeThrough: strikeThrough as boolean,
|
||||
sub: sub as boolean,
|
||||
italic: italic as boolean,
|
||||
highlight: highlight as boolean,
|
||||
class: className,
|
||||
})}
|
||||
{...props}
|
||||
// @ts-expect-error : type issue
|
||||
ref={ref}
|
||||
/>
|
||||
);
|
||||
case '2xl':
|
||||
return (
|
||||
<H2
|
||||
className={headingStyle({
|
||||
size,
|
||||
isTruncated: isTruncated as boolean,
|
||||
bold: bold as boolean,
|
||||
underline: underline as boolean,
|
||||
strikeThrough: strikeThrough as boolean,
|
||||
sub: sub as boolean,
|
||||
italic: italic as boolean,
|
||||
highlight: highlight as boolean,
|
||||
class: className,
|
||||
})}
|
||||
{...props}
|
||||
// @ts-expect-error : type issue
|
||||
ref={ref}
|
||||
/>
|
||||
);
|
||||
case 'xl':
|
||||
return (
|
||||
<H3
|
||||
className={headingStyle({
|
||||
size,
|
||||
isTruncated: isTruncated as boolean,
|
||||
bold: bold as boolean,
|
||||
underline: underline as boolean,
|
||||
strikeThrough: strikeThrough as boolean,
|
||||
sub: sub as boolean,
|
||||
italic: italic as boolean,
|
||||
highlight: highlight as boolean,
|
||||
class: className,
|
||||
})}
|
||||
{...props}
|
||||
// @ts-expect-error : type issue
|
||||
ref={ref}
|
||||
/>
|
||||
);
|
||||
case 'lg':
|
||||
return (
|
||||
<H4
|
||||
className={headingStyle({
|
||||
size,
|
||||
isTruncated: isTruncated as boolean,
|
||||
bold: bold as boolean,
|
||||
underline: underline as boolean,
|
||||
strikeThrough: strikeThrough as boolean,
|
||||
sub: sub as boolean,
|
||||
italic: italic as boolean,
|
||||
highlight: highlight as boolean,
|
||||
class: className,
|
||||
})}
|
||||
{...props}
|
||||
// @ts-expect-error : type issue
|
||||
ref={ref}
|
||||
/>
|
||||
);
|
||||
case 'md':
|
||||
return (
|
||||
<H5
|
||||
className={headingStyle({
|
||||
size,
|
||||
isTruncated: isTruncated as boolean,
|
||||
bold: bold as boolean,
|
||||
underline: underline as boolean,
|
||||
strikeThrough: strikeThrough as boolean,
|
||||
sub: sub as boolean,
|
||||
italic: italic as boolean,
|
||||
highlight: highlight as boolean,
|
||||
class: className,
|
||||
})}
|
||||
{...props}
|
||||
// @ts-expect-error : type issue
|
||||
ref={ref}
|
||||
/>
|
||||
);
|
||||
case 'sm':
|
||||
case 'xs':
|
||||
return (
|
||||
<H6
|
||||
className={headingStyle({
|
||||
size,
|
||||
isTruncated: isTruncated as boolean,
|
||||
bold: bold as boolean,
|
||||
underline: underline as boolean,
|
||||
strikeThrough: strikeThrough as boolean,
|
||||
sub: sub as boolean,
|
||||
italic: italic as boolean,
|
||||
highlight: highlight as boolean,
|
||||
class: className,
|
||||
})}
|
||||
{...props}
|
||||
// @ts-expect-error : type issue
|
||||
ref={ref}
|
||||
/>
|
||||
);
|
||||
default:
|
||||
return (
|
||||
<H4
|
||||
className={headingStyle({
|
||||
size,
|
||||
isTruncated: isTruncated as boolean,
|
||||
bold: bold as boolean,
|
||||
underline: underline as boolean,
|
||||
strikeThrough: strikeThrough as boolean,
|
||||
sub: sub as boolean,
|
||||
italic: italic as boolean,
|
||||
highlight: highlight as boolean,
|
||||
class: className,
|
||||
})}
|
||||
{...props}
|
||||
// @ts-expect-error : type issue
|
||||
ref={ref}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
const Heading = memo(
|
||||
forwardRef<React.ComponentRef<typeof H1>, IHeadingProps>(function Heading(
|
||||
{ className, size = 'lg', as: AsComp, ...props },
|
||||
ref
|
||||
) {
|
||||
const {
|
||||
isTruncated,
|
||||
bold,
|
||||
underline,
|
||||
strikeThrough,
|
||||
sub,
|
||||
italic,
|
||||
highlight,
|
||||
} = props;
|
||||
|
||||
if (AsComp) {
|
||||
return (
|
||||
<AsComp
|
||||
className={headingStyle({
|
||||
size,
|
||||
isTruncated: isTruncated as boolean,
|
||||
bold: bold as boolean,
|
||||
underline: underline as boolean,
|
||||
strikeThrough: strikeThrough as boolean,
|
||||
sub: sub as boolean,
|
||||
italic: italic as boolean,
|
||||
highlight: highlight as boolean,
|
||||
class: className,
|
||||
})}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<MappedHeading className={className} size={size} ref={ref} {...props} />
|
||||
);
|
||||
})
|
||||
);
|
||||
|
||||
Heading.displayName = 'Heading';
|
||||
|
||||
export { Heading };
|
||||
@@ -0,0 +1,202 @@
|
||||
import React, { forwardRef, memo } from 'react';
|
||||
import { headingStyle } from './styles';
|
||||
import type { VariantProps } from '@gluestack-ui/utils/nativewind-utils';
|
||||
type IHeadingProps = VariantProps<typeof headingStyle> &
|
||||
React.ComponentPropsWithoutRef<'h1'> & {
|
||||
as?: React.ElementType;
|
||||
};
|
||||
|
||||
const MappedHeading = memo(
|
||||
forwardRef<HTMLHeadingElement, IHeadingProps>(function MappedHeading(
|
||||
{
|
||||
size,
|
||||
className,
|
||||
isTruncated,
|
||||
bold,
|
||||
underline,
|
||||
strikeThrough,
|
||||
sub,
|
||||
italic,
|
||||
highlight,
|
||||
...props
|
||||
},
|
||||
ref
|
||||
) {
|
||||
switch (size) {
|
||||
case '5xl':
|
||||
case '4xl':
|
||||
case '3xl':
|
||||
return (
|
||||
<h1
|
||||
className={headingStyle({
|
||||
size,
|
||||
isTruncated: isTruncated as boolean,
|
||||
bold: bold as boolean,
|
||||
underline: underline as boolean,
|
||||
strikeThrough: strikeThrough as boolean,
|
||||
sub: sub as boolean,
|
||||
italic: italic as boolean,
|
||||
highlight: highlight as boolean,
|
||||
class: className,
|
||||
})}
|
||||
{...props}
|
||||
ref={ref}
|
||||
/>
|
||||
);
|
||||
case '2xl':
|
||||
return (
|
||||
<h2
|
||||
className={headingStyle({
|
||||
size,
|
||||
isTruncated: isTruncated as boolean,
|
||||
bold: bold as boolean,
|
||||
underline: underline as boolean,
|
||||
strikeThrough: strikeThrough as boolean,
|
||||
sub: sub as boolean,
|
||||
italic: italic as boolean,
|
||||
highlight: highlight as boolean,
|
||||
class: className,
|
||||
})}
|
||||
{...props}
|
||||
ref={ref}
|
||||
/>
|
||||
);
|
||||
case 'xl':
|
||||
return (
|
||||
<h3
|
||||
className={headingStyle({
|
||||
size,
|
||||
isTruncated: isTruncated as boolean,
|
||||
bold: bold as boolean,
|
||||
underline: underline as boolean,
|
||||
strikeThrough: strikeThrough as boolean,
|
||||
sub: sub as boolean,
|
||||
italic: italic as boolean,
|
||||
highlight: highlight as boolean,
|
||||
class: className,
|
||||
})}
|
||||
{...props}
|
||||
ref={ref}
|
||||
/>
|
||||
);
|
||||
case 'lg':
|
||||
return (
|
||||
<h4
|
||||
className={headingStyle({
|
||||
size,
|
||||
isTruncated: isTruncated as boolean,
|
||||
bold: bold as boolean,
|
||||
underline: underline as boolean,
|
||||
strikeThrough: strikeThrough as boolean,
|
||||
sub: sub as boolean,
|
||||
italic: italic as boolean,
|
||||
highlight: highlight as boolean,
|
||||
class: className,
|
||||
})}
|
||||
{...props}
|
||||
ref={ref}
|
||||
/>
|
||||
);
|
||||
case 'md':
|
||||
return (
|
||||
<h5
|
||||
className={headingStyle({
|
||||
size,
|
||||
isTruncated: isTruncated as boolean,
|
||||
bold: bold as boolean,
|
||||
underline: underline as boolean,
|
||||
strikeThrough: strikeThrough as boolean,
|
||||
sub: sub as boolean,
|
||||
italic: italic as boolean,
|
||||
highlight: highlight as boolean,
|
||||
class: className,
|
||||
})}
|
||||
{...props}
|
||||
ref={ref}
|
||||
/>
|
||||
);
|
||||
case 'sm':
|
||||
case 'xs':
|
||||
return (
|
||||
<h6
|
||||
className={headingStyle({
|
||||
size,
|
||||
isTruncated: isTruncated as boolean,
|
||||
bold: bold as boolean,
|
||||
underline: underline as boolean,
|
||||
strikeThrough: strikeThrough as boolean,
|
||||
sub: sub as boolean,
|
||||
italic: italic as boolean,
|
||||
highlight: highlight as boolean,
|
||||
class: className,
|
||||
})}
|
||||
{...props}
|
||||
ref={ref}
|
||||
/>
|
||||
);
|
||||
default:
|
||||
return (
|
||||
<h4
|
||||
className={headingStyle({
|
||||
size,
|
||||
isTruncated: isTruncated as boolean,
|
||||
bold: bold as boolean,
|
||||
underline: underline as boolean,
|
||||
strikeThrough: strikeThrough as boolean,
|
||||
sub: sub as boolean,
|
||||
italic: italic as boolean,
|
||||
highlight: highlight as boolean,
|
||||
class: className,
|
||||
})}
|
||||
{...props}
|
||||
ref={ref}
|
||||
/>
|
||||
);
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
const Heading = memo(
|
||||
forwardRef<HTMLHeadingElement, IHeadingProps>(function Heading(
|
||||
{ className, size = 'lg', as: AsComp, ...props },
|
||||
ref
|
||||
) {
|
||||
const {
|
||||
isTruncated,
|
||||
bold,
|
||||
underline,
|
||||
strikeThrough,
|
||||
sub,
|
||||
italic,
|
||||
highlight,
|
||||
} = props;
|
||||
|
||||
if (AsComp) {
|
||||
return (
|
||||
<AsComp
|
||||
className={headingStyle({
|
||||
size,
|
||||
isTruncated: isTruncated as boolean,
|
||||
bold: bold as boolean,
|
||||
underline: underline as boolean,
|
||||
strikeThrough: strikeThrough as boolean,
|
||||
sub: sub as boolean,
|
||||
italic: italic as boolean,
|
||||
highlight: highlight as boolean,
|
||||
class: className,
|
||||
})}
|
||||
{...props}
|
||||
ref={ref}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<MappedHeading className={className} size={size} ref={ref} {...props} />
|
||||
);
|
||||
})
|
||||
);
|
||||
|
||||
Heading.displayName = 'Heading';
|
||||
|
||||
export { Heading };
|
||||
@@ -0,0 +1,43 @@
|
||||
import { tva } from '@gluestack-ui/utils/nativewind-utils';
|
||||
import { isWeb } from '@gluestack-ui/utils/nativewind-utils';
|
||||
const baseStyle = isWeb
|
||||
? 'font-sans tracking-sm bg-transparent border-0 box-border display-inline list-none margin-0 padding-0 position-relative text-start no-underline whitespace-pre-wrap word-wrap-break-word'
|
||||
: '';
|
||||
|
||||
export const headingStyle = tva({
|
||||
base: `text-typography-900 font-bold font-heading tracking-sm my-0 ${baseStyle}`,
|
||||
variants: {
|
||||
isTruncated: {
|
||||
true: 'truncate',
|
||||
},
|
||||
bold: {
|
||||
true: 'font-bold',
|
||||
},
|
||||
underline: {
|
||||
true: 'underline',
|
||||
},
|
||||
strikeThrough: {
|
||||
true: 'line-through',
|
||||
},
|
||||
sub: {
|
||||
true: 'text-xs',
|
||||
},
|
||||
italic: {
|
||||
true: 'italic',
|
||||
},
|
||||
highlight: {
|
||||
true: 'bg-yellow-500',
|
||||
},
|
||||
size: {
|
||||
'5xl': 'text-6xl',
|
||||
'4xl': 'text-5xl',
|
||||
'3xl': 'text-4xl',
|
||||
'2xl': 'text-3xl',
|
||||
'xl': 'text-2xl',
|
||||
'lg': 'text-xl',
|
||||
'md': 'text-lg',
|
||||
'sm': 'text-base',
|
||||
'xs': 'text-sm',
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,27 @@
|
||||
import React from 'react';
|
||||
import type { VariantProps } from '@gluestack-ui/utils/nativewind-utils';
|
||||
import { View } from 'react-native';
|
||||
import type { ViewProps } from 'react-native';
|
||||
import { hstackStyle } from './styles';
|
||||
|
||||
type IHStackProps = ViewProps & VariantProps<typeof hstackStyle>;
|
||||
|
||||
const HStack = React.forwardRef<React.ComponentRef<typeof View>, IHStackProps>(
|
||||
function HStack({ className, space, reversed, ...props }, ref) {
|
||||
return (
|
||||
<View
|
||||
className={hstackStyle({
|
||||
space,
|
||||
reversed: reversed as boolean,
|
||||
class: className,
|
||||
})}
|
||||
{...props}
|
||||
ref={ref}
|
||||
/>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
HStack.displayName = 'HStack';
|
||||
|
||||
export { HStack };
|
||||
@@ -0,0 +1,26 @@
|
||||
import React from 'react';
|
||||
import type { VariantProps } from '@gluestack-ui/utils/nativewind-utils';
|
||||
import { hstackStyle } from './styles';
|
||||
|
||||
type IHStackProps = React.ComponentPropsWithoutRef<'div'> &
|
||||
VariantProps<typeof hstackStyle>;
|
||||
|
||||
const HStack = React.forwardRef<React.ComponentRef<'div'>, IHStackProps>(
|
||||
function HStack({ className, space, reversed, ...props }, ref) {
|
||||
return (
|
||||
<div
|
||||
className={hstackStyle({
|
||||
space,
|
||||
reversed: reversed as boolean,
|
||||
class: className,
|
||||
})}
|
||||
{...props}
|
||||
ref={ref}
|
||||
/>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
HStack.displayName = 'HStack';
|
||||
|
||||
export { HStack };
|
||||
@@ -0,0 +1,25 @@
|
||||
import { isWeb } from '@gluestack-ui/utils/nativewind-utils';
|
||||
import { tva } from '@gluestack-ui/utils/nativewind-utils';
|
||||
|
||||
const baseStyle = isWeb
|
||||
? 'flex relative z-0 box-border border-0 list-none min-w-0 min-h-0 bg-transparent items-stretch m-0 p-0 text-decoration-none'
|
||||
: '';
|
||||
|
||||
export const hstackStyle = tva({
|
||||
base: `flex-row ${baseStyle}`,
|
||||
variants: {
|
||||
space: {
|
||||
'xs': 'gap-1',
|
||||
'sm': 'gap-2',
|
||||
'md': 'gap-3',
|
||||
'lg': 'gap-4',
|
||||
'xl': 'gap-5',
|
||||
'2xl': 'gap-6',
|
||||
'3xl': 'gap-7',
|
||||
'4xl': 'gap-8',
|
||||
},
|
||||
reversed: {
|
||||
true: 'flex-row-reverse',
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,48 @@
|
||||
import React from 'react';
|
||||
|
||||
import type { VariantProps } from '@gluestack-ui/utils/nativewind-utils';
|
||||
import { Text as RNText } from 'react-native';
|
||||
import { textStyle } from './styles';
|
||||
|
||||
type ITextProps = React.ComponentProps<typeof RNText> &
|
||||
VariantProps<typeof textStyle>;
|
||||
|
||||
const Text = React.forwardRef<React.ComponentRef<typeof RNText>, ITextProps>(
|
||||
function Text(
|
||||
{
|
||||
className,
|
||||
isTruncated,
|
||||
bold,
|
||||
underline,
|
||||
strikeThrough,
|
||||
size = 'md',
|
||||
sub,
|
||||
italic,
|
||||
highlight,
|
||||
...props
|
||||
},
|
||||
ref
|
||||
) {
|
||||
return (
|
||||
<RNText
|
||||
className={textStyle({
|
||||
isTruncated: isTruncated as boolean,
|
||||
bold: bold as boolean,
|
||||
underline: underline as boolean,
|
||||
strikeThrough: strikeThrough as boolean,
|
||||
size,
|
||||
sub: sub as boolean,
|
||||
italic: italic as boolean,
|
||||
highlight: highlight as boolean,
|
||||
class: className,
|
||||
})}
|
||||
{...props}
|
||||
ref={ref}
|
||||
/>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
Text.displayName = 'Text';
|
||||
|
||||
export { Text };
|
||||
@@ -0,0 +1,45 @@
|
||||
import React from 'react';
|
||||
import type { VariantProps } from '@gluestack-ui/utils/nativewind-utils';
|
||||
import { textStyle } from './styles';
|
||||
|
||||
type ITextProps = React.ComponentProps<'span'> & VariantProps<typeof textStyle>;
|
||||
|
||||
const Text = React.forwardRef<React.ComponentRef<'span'>, ITextProps>(
|
||||
function Text(
|
||||
{
|
||||
className,
|
||||
isTruncated,
|
||||
bold,
|
||||
underline,
|
||||
strikeThrough,
|
||||
size = 'md',
|
||||
sub,
|
||||
italic,
|
||||
highlight,
|
||||
...props
|
||||
}: { className?: string } & ITextProps,
|
||||
ref
|
||||
) {
|
||||
return (
|
||||
<span
|
||||
className={textStyle({
|
||||
isTruncated: isTruncated as boolean,
|
||||
bold: bold as boolean,
|
||||
underline: underline as boolean,
|
||||
strikeThrough: strikeThrough as boolean,
|
||||
size,
|
||||
sub: sub as boolean,
|
||||
italic: italic as boolean,
|
||||
highlight: highlight as boolean,
|
||||
class: className,
|
||||
})}
|
||||
{...props}
|
||||
ref={ref}
|
||||
/>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
Text.displayName = 'Text';
|
||||
|
||||
export { Text };
|
||||
@@ -0,0 +1,47 @@
|
||||
import { tva } from '@gluestack-ui/utils/nativewind-utils';
|
||||
import { isWeb } from '@gluestack-ui/utils/nativewind-utils';
|
||||
|
||||
const baseStyle = isWeb
|
||||
? 'font-sans tracking-sm my-0 bg-transparent border-0 box-border display-inline list-none margin-0 padding-0 position-relative text-start no-underline whitespace-pre-wrap word-wrap-break-word'
|
||||
: '';
|
||||
|
||||
export const textStyle = tva({
|
||||
base: `text-typography-700 font-body ${baseStyle}`,
|
||||
|
||||
variants: {
|
||||
isTruncated: {
|
||||
true: 'web:truncate',
|
||||
},
|
||||
bold: {
|
||||
true: 'font-bold',
|
||||
},
|
||||
underline: {
|
||||
true: 'underline',
|
||||
},
|
||||
strikeThrough: {
|
||||
true: 'line-through',
|
||||
},
|
||||
size: {
|
||||
'2xs': 'text-2xs',
|
||||
'xs': 'text-xs',
|
||||
'sm': 'text-sm',
|
||||
'md': 'text-base',
|
||||
'lg': 'text-lg',
|
||||
'xl': 'text-xl',
|
||||
'2xl': 'text-2xl',
|
||||
'3xl': 'text-3xl',
|
||||
'4xl': 'text-4xl',
|
||||
'5xl': 'text-5xl',
|
||||
'6xl': 'text-6xl',
|
||||
},
|
||||
sub: {
|
||||
true: 'text-xs',
|
||||
},
|
||||
italic: {
|
||||
true: 'italic',
|
||||
},
|
||||
highlight: {
|
||||
true: 'bg-yellow-500',
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,28 @@
|
||||
import React from 'react';
|
||||
import type { VariantProps } from '@gluestack-ui/utils/nativewind-utils';
|
||||
import { View } from 'react-native';
|
||||
|
||||
import { vstackStyle } from './styles';
|
||||
|
||||
type IVStackProps = React.ComponentProps<typeof View> &
|
||||
VariantProps<typeof vstackStyle>;
|
||||
|
||||
const VStack = React.forwardRef<React.ComponentRef<typeof View>, IVStackProps>(
|
||||
function VStack({ className, space, reversed, ...props }, ref) {
|
||||
return (
|
||||
<View
|
||||
className={vstackStyle({
|
||||
space,
|
||||
reversed: reversed as boolean,
|
||||
class: className,
|
||||
})}
|
||||
{...props}
|
||||
ref={ref}
|
||||
/>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
VStack.displayName = 'VStack';
|
||||
|
||||
export { VStack };
|
||||
@@ -0,0 +1,27 @@
|
||||
import React from 'react';
|
||||
import type { VariantProps } from '@gluestack-ui/utils/nativewind-utils';
|
||||
|
||||
import { vstackStyle } from './styles';
|
||||
|
||||
type IVStackProps = React.ComponentProps<'div'> &
|
||||
VariantProps<typeof vstackStyle>;
|
||||
|
||||
const VStack = React.forwardRef<React.ComponentRef<'div'>, IVStackProps>(
|
||||
function VStack({ className, space, reversed, ...props }, ref) {
|
||||
return (
|
||||
<div
|
||||
className={vstackStyle({
|
||||
space,
|
||||
reversed: reversed as boolean,
|
||||
class: className,
|
||||
})}
|
||||
{...props}
|
||||
ref={ref}
|
||||
/>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
VStack.displayName = 'VStack';
|
||||
|
||||
export { VStack };
|
||||
@@ -0,0 +1,25 @@
|
||||
import { isWeb } from '@gluestack-ui/utils/nativewind-utils';
|
||||
import { tva } from '@gluestack-ui/utils/nativewind-utils';
|
||||
|
||||
const baseStyle = isWeb
|
||||
? 'flex flex-col relative z-0 box-border border-0 list-none min-w-0 min-h-0 bg-transparent items-stretch m-0 p-0 text-decoration-none'
|
||||
: '';
|
||||
|
||||
export const vstackStyle = tva({
|
||||
base: `flex-col ${baseStyle}`,
|
||||
variants: {
|
||||
space: {
|
||||
'xs': 'gap-1',
|
||||
'sm': 'gap-2',
|
||||
'md': 'gap-3',
|
||||
'lg': 'gap-4',
|
||||
'xl': 'gap-5',
|
||||
'2xl': 'gap-6',
|
||||
'3xl': 'gap-7',
|
||||
'4xl': 'gap-8',
|
||||
},
|
||||
reversed: {
|
||||
true: 'flex-col-reverse',
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -32,8 +32,8 @@ function isWhiteListed(url: string) {
|
||||
}
|
||||
|
||||
const alovaInstance = createAlova({
|
||||
// baseURL: 'http://192.168.5.6:8086/app',
|
||||
baseURL: 'http://192.168.1.136:8086/app',
|
||||
baseURL: 'http://192.168.5.6:8086/app',
|
||||
// baseURL: 'http://192.168.1.136:8086/app',
|
||||
requestAdapter: axiosRequestAdapter(),
|
||||
timeout: 5000,
|
||||
cacheFor: null,
|
||||
|
||||
@@ -1,457 +1,148 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<html lang="zh">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>查询进度步骤条 - 精确对齐版本</title>
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
font-family: 'Segoe UI', 'Microsoft YaHei', sans-serif;
|
||||
}
|
||||
|
||||
body {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-height: 100vh;
|
||||
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
|
||||
padding: 40px 20px;
|
||||
}
|
||||
|
||||
.g3-main-content-indicator{
|
||||
display: block;
|
||||
}
|
||||
<meta charset="UTF-8" />
|
||||
<title>高级邀请页面</title>
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: "Inter", sans-serif;
|
||||
background: #f3f4f7;
|
||||
}
|
||||
|
||||
.g3-main-content-indicator-title {
|
||||
font-size: 22px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 15px;
|
||||
color: #1a2980;
|
||||
}
|
||||
/* 顶部渐变 Header */
|
||||
.header {
|
||||
width: 100%;
|
||||
padding: 40px 24px;
|
||||
background: linear-gradient(135deg, #4d8dff, #6fa5ff);
|
||||
color: white;
|
||||
font-size: 26px;
|
||||
font-weight: 600;
|
||||
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.progress-steps {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
position: relative;
|
||||
margin: 60px 0px;
|
||||
counter-reset: step;
|
||||
}
|
||||
/* 内容卡片 */
|
||||
.container {
|
||||
margin-top: -32px;
|
||||
padding: 0 24px 40px;
|
||||
}
|
||||
|
||||
.step {
|
||||
position: relative;
|
||||
z-index: 3;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
flex: 1;
|
||||
}
|
||||
.card {
|
||||
background: white;
|
||||
padding: 24px;
|
||||
border-radius: 20px;
|
||||
box-shadow: 0 6px 20px rgba(0,0,0,0.06);
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.step-connector {
|
||||
position: absolute;
|
||||
top: 28px;
|
||||
height: 4px;
|
||||
background-color: #e0e0e0;
|
||||
z-index: 1;
|
||||
}
|
||||
.title-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.step-progress {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100%;
|
||||
width: 0;
|
||||
background: #4b6cb7;
|
||||
transition: width 0.8s ease, background-color 0.8s ease;
|
||||
z-index: 2;
|
||||
}
|
||||
.title {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.step-progress.success {
|
||||
background: linear-gradient(to right, #4CAF50, #2E7D32);
|
||||
}
|
||||
.invite-code {
|
||||
font-size: 40px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 4px;
|
||||
color: #333;
|
||||
text-align: center;
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
.step-progress.failed {
|
||||
background: linear-gradient(to right, #f44336, #c62828);
|
||||
}
|
||||
.copy-btn {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-top: 8px;
|
||||
font-size: 14px;
|
||||
color: #4d8dff;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.step-icon {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
border-radius: 50%;
|
||||
background: #e0e0e0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
color: #999;
|
||||
font-weight: bold;
|
||||
border: 4px solid white;
|
||||
box-shadow: 0 0 0 3px #e0e0e0;
|
||||
transition: all 0.5s ease;
|
||||
position: relative;
|
||||
z-index: 4;
|
||||
font-size: 24px;
|
||||
}
|
||||
/* 二维码卡片设计 */
|
||||
.qr-card {
|
||||
background: white;
|
||||
padding: 20px;
|
||||
border-radius: 20px;
|
||||
text-align: center;
|
||||
box-shadow: 0 4px 14px rgba(0,0,0,0.05);
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.step.active .step-icon {
|
||||
background: #4b6cb7;
|
||||
color: white;
|
||||
box-shadow: 0 0 0 3px #b8c6f0;
|
||||
animation: pulse 1.5s infinite;
|
||||
}
|
||||
.qr-img {
|
||||
width: 190px;
|
||||
height: 190px;
|
||||
border-radius: 12px;
|
||||
border: 1px solid #eee;
|
||||
}
|
||||
|
||||
.step.completed .step-icon {
|
||||
background: #4CAF50;
|
||||
color: white;
|
||||
box-shadow: 0 0 0 3px #a5d6a7;
|
||||
}
|
||||
.badge {
|
||||
background: #eef1ff;
|
||||
padding: 6px 14px;
|
||||
border-radius: 14px;
|
||||
font-size: 14px;
|
||||
color: #4d5bff;
|
||||
}
|
||||
|
||||
.step.failed .step-icon {
|
||||
background: #f44336;
|
||||
color: white;
|
||||
box-shadow: 0 0 0 3px #ffcdd2;
|
||||
}
|
||||
.member-item {
|
||||
padding: 14px 0;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.step.completed .step-icon::after {
|
||||
content: '✓';
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.step.failed .step-icon::after {
|
||||
content: '✕';
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.step-label {
|
||||
margin-top: 10px;
|
||||
text-align: center;
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
font-weight: 500;
|
||||
max-width: 100px;
|
||||
}
|
||||
|
||||
.step.active .step-label {
|
||||
color: #4b6cb7;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.step.completed .step-label {
|
||||
color: #4CAF50;
|
||||
}
|
||||
|
||||
.step.failed .step-label {
|
||||
color: #f44336;
|
||||
font-weight: 600;
|
||||
}
|
||||
.progress-info {
|
||||
background: #f8f9fa;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
margin-top: 20px;
|
||||
text-align: center;
|
||||
border-left: 4px solid #4b6cb7;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.progress-info.failed {
|
||||
border-left-color: #f44336;
|
||||
}
|
||||
|
||||
.progress-info.success {
|
||||
border-left-color: #4CAF50;
|
||||
}
|
||||
|
||||
.progress-status {
|
||||
font-size: 16px;
|
||||
color: #333;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.progress-details {
|
||||
font-size: 18px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.progress-time {
|
||||
display: inline-block;
|
||||
background: #e3f2fd;
|
||||
padding: 3px 8px;
|
||||
border-radius: 4px;
|
||||
font-size: 16px;
|
||||
color: #1565c0;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
</style>
|
||||
.member-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="statusIndicator" class="g3-main-content-indicator">
|
||||
<div class="g3-main-content-indicator-title">查询状态</div>
|
||||
<div class="progress-steps">
|
||||
<!-- 步骤1 -->
|
||||
<div class="step active" id="step1">
|
||||
<div class="step-icon">1</div>
|
||||
<div class="step-label">验证查询条件</div>
|
||||
</div>
|
||||
|
||||
<!-- 步骤2 -->
|
||||
<div class="step" id="step2">
|
||||
<div class="step-icon">2</div>
|
||||
<div class="step-label">发出请求</div>
|
||||
</div>
|
||||
<!-- Header -->
|
||||
<div class="header">邀请好友加入空间</div>
|
||||
|
||||
<!-- 步骤3 -->
|
||||
<div class="step" id="step3">
|
||||
<div class="step-icon">3</div>
|
||||
<div class="step-label">等待响应</div>
|
||||
</div>
|
||||
<!-- 内容 -->
|
||||
<div class="container">
|
||||
|
||||
<!-- 步骤4 -->
|
||||
<div class="step" id="step4">
|
||||
<div class="step-icon">4</div>
|
||||
<div class="step-label">查询成功</div>
|
||||
</div>
|
||||
|
||||
<!-- 连接线1-2 -->
|
||||
<div class="step-connector" id="connector1" style="left: 12.5%; width: 25%;">
|
||||
<div class="step-progress" id="progress1"></div>
|
||||
</div>
|
||||
|
||||
<!-- 连接线2-3 -->
|
||||
<div class="step-connector" id="connector2" style="left: 37.5%; width: 25%;">
|
||||
<div class="step-progress" id="progress2"></div>
|
||||
</div>
|
||||
|
||||
<!-- 连接线3-4 -->
|
||||
<div class="step-connector" id="connector3" style="left: 62.5%; width: 25%;">
|
||||
<div class="step-progress" id="progress3"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="progress-info" id="progressInfo">
|
||||
<div class="progress-details" id="progressDetails">
|
||||
检查查询参数的有效性,确保数据请求符合系统要求。
|
||||
<div class="progress-time">已用时间: <span id="timeElapsed">0分00秒</span></div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 邀请码卡片 -->
|
||||
<div class="card">
|
||||
<div class="title-row">
|
||||
<div class="title">我的邀请码</div>
|
||||
</div>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const steps = document.querySelectorAll('.step');
|
||||
const stepProgresses = document.querySelectorAll('.step-progress');
|
||||
const connectors = document.querySelectorAll('.step-connector');
|
||||
const progressInfoElement = document.getElementById('progressInfo');
|
||||
const progressDetails = document.getElementById('progressDetails');
|
||||
const timeElapsed = document.getElementById('timeElapsed');
|
||||
|
||||
let currentStep = 1;
|
||||
let isRunning = false;
|
||||
let hasFailed = false;
|
||||
let timerInterval;
|
||||
let seconds = 0;
|
||||
let stepStatus = [null, 'active', null, null, null];
|
||||
<div class="invite-code">123456</div>
|
||||
<div class="copy-btn">点击复制邀请码</div>
|
||||
</div>
|
||||
|
||||
<!-- 二维码卡片 -->
|
||||
<div class="qr-card">
|
||||
<img
|
||||
src="https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=demo"
|
||||
class="qr-img"
|
||||
alt="二维码"
|
||||
/>
|
||||
<p style="margin-top: 12px; color: #666; font-size: 14px;">
|
||||
扫码加入我的共享空间
|
||||
</p>
|
||||
</div>
|
||||
|
||||
// 计算连接线位置
|
||||
function calculateConnectorPositions() {
|
||||
const stepWidth = 100 / steps.length; // 每个步骤占据的宽度百分比
|
||||
<!-- 成员卡片 -->
|
||||
<div class="card">
|
||||
<div class="title-row">
|
||||
<div class="title">空间成员</div>
|
||||
<div class="badge">3 人</div>
|
||||
</div>
|
||||
|
||||
connectors.forEach((connector, index) => {
|
||||
// 计算连接线的起始位置和宽度
|
||||
const left = (index + 0.5) * stepWidth; // 从第一个步骤的中心开始
|
||||
const width = stepWidth; // 连接线宽度等于步骤宽度
|
||||
<div class="member-item">成员 A</div>
|
||||
<div class="member-item">成员 B</div>
|
||||
<div class="member-item">成员 C</div>
|
||||
</div>
|
||||
|
||||
connector.style.left = left + `%`;
|
||||
connector.style.width = width + `%`;
|
||||
});
|
||||
}
|
||||
</div>
|
||||
|
||||
// 更新步骤状态
|
||||
function updateSteps() {
|
||||
steps.forEach((step, index) => {
|
||||
step.classList.remove('active', 'completed', 'failed');
|
||||
|
||||
if (index + 1 < currentStep) {
|
||||
step.classList.add('completed');
|
||||
} else if (index + 1 === currentStep) {
|
||||
if (currentStep > steps.length) {
|
||||
// 如果所有步骤已完成,最后一个步骤显示为完成状态
|
||||
step.classList.add('completed');
|
||||
} else {
|
||||
step.classList.add('active');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 更新进度条
|
||||
function updateProgressBars() {
|
||||
// 重置所有进度条
|
||||
stepProgresses.forEach((progress, index) => {
|
||||
progress.style.width = '0';
|
||||
progress.classList.remove('success', 'failed');
|
||||
});
|
||||
|
||||
// 设置已完成的进度条
|
||||
for (let i = 1; i < currentStep; i++) {
|
||||
if (i <= stepProgresses.length) {
|
||||
const progress = document.getElementById(`progress` + i);
|
||||
if (progress) {
|
||||
progress.style.width = '100%';
|
||||
// 根据步骤状态设置颜色
|
||||
if (stepStatus[i] === 'completed') {
|
||||
progress.classList.add('success');
|
||||
} else if (stepStatus[i] === 'failed') {
|
||||
progress.classList.add('failed');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 标记步骤失败
|
||||
function markStepFailed(stepIndex, error) {
|
||||
stepStatus[stepIndex] = 'failed';
|
||||
hasFailed = true;
|
||||
|
||||
steps[stepIndex - 1].classList.remove('active', 'completed');
|
||||
steps[stepIndex - 1].classList.add('failed');
|
||||
|
||||
// 标记前一个连接线为失败
|
||||
if (stepIndex > 1) {
|
||||
const prevProgress = document.getElementById("progress" + (stepIndex - 1));
|
||||
if (prevProgress) {
|
||||
prevProgress.classList.add('failed');
|
||||
}
|
||||
}
|
||||
|
||||
progressInfoElement.classList.add('failed');
|
||||
|
||||
isRunning = false;
|
||||
stopTimer();
|
||||
|
||||
updateProgressBars();
|
||||
}
|
||||
|
||||
// 标记步骤成功
|
||||
function markStepCompleted(stepIndex) {
|
||||
stepStatus[stepIndex] = 'completed';
|
||||
updateSteps();
|
||||
|
||||
// 标记前一个连接线为成功
|
||||
if (stepIndex > 1) {
|
||||
const prevProgress = document.getElementById("progress" + (stepIndex - 1));
|
||||
if (prevProgress) {
|
||||
prevProgress.classList.add('success');
|
||||
}
|
||||
}
|
||||
|
||||
updateProgressBars();
|
||||
}
|
||||
|
||||
// 标记所有步骤完成
|
||||
function markAllStepsCompleted() {
|
||||
for (let i = 1; i <= steps.length; i++) {
|
||||
stepStatus[i] = 'completed';
|
||||
}
|
||||
updateSteps();
|
||||
updateProgressBars();
|
||||
}
|
||||
|
||||
// 更新状态信息
|
||||
function updateStatus() {
|
||||
const statusTexts = [
|
||||
'',
|
||||
'正在验证查询条件...',
|
||||
'正在向服务器发出请求...',
|
||||
'正在等待服务器响应...',
|
||||
'查询成功,正在处理结果...'
|
||||
];
|
||||
|
||||
const detailTexts = [
|
||||
'',
|
||||
'检查查询参数的有效性,确保数据请求符合系统要求。',
|
||||
'将查询请求发送到远程服务器,建立数据连接。',
|
||||
'等待服务器处理查询请求并返回结果。',
|
||||
'处理查询结果并准备返回,即将完成整个过程。'
|
||||
];
|
||||
|
||||
progressDetails.innerHTML = detailTexts[currentStep] +
|
||||
'<div class="progress-time">已用时间: <span id="timeElapsed">'
|
||||
+ formatTime(seconds) +
|
||||
'</span></div>';
|
||||
|
||||
progressInfoElement.classList.remove('failed');
|
||||
}
|
||||
|
||||
// 格式化时间显示
|
||||
function formatTime(totalSeconds) {
|
||||
const minutes = Math.floor(totalSeconds / 60);
|
||||
const seconds = totalSeconds % 60;
|
||||
return minutes + "分" + seconds.toString().padStart(2, "0") + "秒";
|
||||
}
|
||||
|
||||
// 开始计时器
|
||||
function startTimer() {
|
||||
seconds = 0;
|
||||
timerInterval = setInterval(() => {
|
||||
seconds++;
|
||||
timeElapsed.textContent = formatTime(seconds);
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
// 停止计时器
|
||||
function stopTimer() {
|
||||
clearInterval(timerInterval);
|
||||
}
|
||||
|
||||
// 初始化
|
||||
updateSteps();
|
||||
updateProgressBars();
|
||||
updateStatus();
|
||||
function runStep() {
|
||||
if (currentStep > steps.length) {
|
||||
// 查询完成
|
||||
isRunning = false;
|
||||
stopTimer();
|
||||
markAllStepsCompleted();
|
||||
progressDetails.innerHTML =
|
||||
'数据查询已成功完成,结果已准备就绪。' +
|
||||
'<div class="progress-time">总用时: <span id="timeElapsed">'
|
||||
+ formatTime(seconds) +
|
||||
'</span></div>';
|
||||
return;
|
||||
}
|
||||
|
||||
updateStatus();
|
||||
updateSteps();
|
||||
updateProgressBars();
|
||||
|
||||
const stepWillFail = Math.random() < 0.2;
|
||||
const duration = [0,1000,1000,1000,1000][currentStep];
|
||||
|
||||
setTimeout(() => {
|
||||
if (stepWillFail && !hasFailed) {
|
||||
markStepFailed(currentStep, "模拟失败");
|
||||
hasFailed = true;
|
||||
return;
|
||||
}
|
||||
|
||||
markStepCompleted(currentStep);
|
||||
currentStep++;
|
||||
runStep(); // ✅ 递归调用下一步
|
||||
}, duration);
|
||||
}
|
||||
|
||||
runStep();
|
||||
|
||||
|
||||
})
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in new issue
Block a user