hw-cus-ui 1.0.22 → 1.0.24

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.
@@ -0,0 +1,195 @@
1
+ <template>
2
+ <view class="draggable-popup-mask">
3
+ <view
4
+ class="draggable-popup-container"
5
+ :style="{
6
+ top: popupTop + 'px',
7
+ position: isDrag ? 'fixed' : 'initial',
8
+ borderTopLeftRadius: isDrag ? '20rpx' : '0',
9
+ borderTopRightRadius: isDrag ? '20rpx' : '0'
10
+ }"
11
+ >
12
+ <view
13
+ v-if="isDrag"
14
+ class="draggable-popup-handle"
15
+ @touchstart="handleTouchStart"
16
+ @touchmove="handleTouchMove"
17
+ @touchend="handleTouchEnd"
18
+ @touchcancel="handleTouchEnd"
19
+ >
20
+ <view class="draggable-popup-handle-line"></view>
21
+ </view>
22
+ <view class="draggable-popup-content" :style="{ height: isDrag ? contentPopupTop + 'px' : 'auto' }">
23
+ <slot></slot>
24
+ </view>
25
+ </view>
26
+ </view>
27
+ </template>
28
+
29
+ <script>
30
+ import { useDebounceFn } from '@vueuse/core';
31
+ export default {
32
+ name: 'DraggableBottomPopup',
33
+ props: {
34
+ heightCalc: {
35
+ type: String,
36
+ default: '0.4'
37
+ },
38
+ isDrag: {
39
+ type: Boolean,
40
+ default: () => true
41
+ }
42
+ },
43
+ data() {
44
+ return {
45
+ startY: 0,
46
+ startTop: 0,
47
+ popupTop: 0,
48
+ windowHeight: 0,
49
+ contentPopupTop: 0,
50
+ isMoving: false,
51
+ containerHeight: 0, // 容器高度
52
+ updateContentPopupTop: null // 防抖函数
53
+ };
54
+ },
55
+
56
+ mounted() {
57
+ this.getWindowInfo();
58
+ this.initPopupPosition();
59
+ // 初始化防抖函数
60
+ this.updateContentPopupTop = useDebounceFn(() => {
61
+ this.contentPopupTop = this.windowHeight - this.popupTop - 25;
62
+ }, 300);
63
+ },
64
+ methods: {
65
+ getWindowInfo() {
66
+ const systemInfo = uni.getSystemInfoSync();
67
+ this.windowHeight = systemInfo.windowHeight;
68
+ // 初始位置在屏幕外,隐藏状态
69
+ this.popupTop = this.windowHeight;
70
+ },
71
+
72
+ initPopupPosition() {
73
+ this.$nextTick(() => {
74
+ // 获取内容高度
75
+ const query = uni.createSelectorQuery().in(this);
76
+ query
77
+ .select('.draggable-popup-container')
78
+ .boundingClientRect((data) => {
79
+ if (data) {
80
+ this.containerHeight = data.height;
81
+ // 默认显示屏幕高度的60%
82
+ this.popupTop = this.windowHeight * this.heightCalc;
83
+ this.contentPopupTop = this.windowHeight - this.popupTop - 25;
84
+ this.changeTop();
85
+ }
86
+ })
87
+ .exec();
88
+ });
89
+ },
90
+
91
+ handleTouchStart(e) {
92
+ this.isMoving = true;
93
+ this.startY = e.touches[0].clientY;
94
+ this.startTop = this.popupTop;
95
+ },
96
+
97
+ handleTouchMove(e) {
98
+ if (!this.isMoving) return;
99
+
100
+ const moveY = e.touches[0].clientY - this.startY;
101
+ let newTop = this.startTop + moveY;
102
+
103
+ // 限制拖动范围,但允许拖出屏幕一定距离
104
+ const maxDragDistance = 100; // 最大可拖出屏幕的距离
105
+
106
+ if (newTop < -maxDragDistance) {
107
+ newTop = -maxDragDistance;
108
+ }
109
+
110
+ // 保留一部分在屏幕内,方便拖回
111
+ if (this.containerHeight > 0) {
112
+ const maxTop = this.windowHeight - 50; // 至少保留50px在屏幕内
113
+ if (newTop > maxTop) {
114
+ newTop = maxTop;
115
+ }
116
+ }
117
+ this.popupTop = newTop;
118
+ this.changeTop();
119
+ // 调用防抖函数而不是创建它
120
+ this.updateContentPopupTop();
121
+ },
122
+
123
+ handleTouchEnd(e) {
124
+ if (!this.isMoving) return;
125
+ this.isMoving = false;
126
+
127
+ // 修改:拖动结束后停留在当前位置,不自动展开或收起
128
+ // 只要确保popupTop在有效范围内即可
129
+
130
+ if (this.popupTop < 0) {
131
+ this.popupTop = 110;
132
+ this.contentPopupTop = this.windowHeight - this.popupTop - 25;
133
+ } else if (this.popupTop > this.windowHeight) {
134
+ this.popupTop = this.windowHeight - 60;
135
+ this.contentPopupTop = this.windowHeight - this.popupTop - 25;
136
+ } else if (this.popupTop < 110) {
137
+ this.popupTop = 110;
138
+ this.contentPopupTop = this.windowHeight - this.popupTop - 25;
139
+ }
140
+ this.changeTop();
141
+ },
142
+ changeTop() {
143
+ this.$emit('changeTop', this.popupTop);
144
+ }
145
+ }
146
+ };
147
+ </script>
148
+
149
+ <style lang="scss" scoped>
150
+ /* .draggable-popup-mask {
151
+ position: fixed;
152
+ top: 0;
153
+ left: 0;
154
+ right: 0;
155
+ bottom: 0;
156
+ background-color: rgba(0, 0, 0, 0.4);
157
+ z-index: 98;
158
+ } */
159
+
160
+ .draggable-popup-container {
161
+ position: fixed;
162
+ left: 0;
163
+ right: 0;
164
+ bottom: 0;
165
+ background-color: #ffffff;
166
+ border-top-left-radius: 20rpx;
167
+ border-top-right-radius: 20rpx;
168
+ transition: top 0.1s ease; /* 减少过渡时间使拖动更流畅 */
169
+ z-index: 99;
170
+ display: flex;
171
+ flex-direction: column;
172
+ overflow: auto;
173
+ }
174
+
175
+ .draggable-popup-handle {
176
+ display: flex;
177
+ justify-content: center;
178
+ align-items: center;
179
+ padding: 20rpx 0;
180
+ cursor: move;
181
+ }
182
+
183
+ .draggable-popup-handle-line {
184
+ width: 60rpx;
185
+ height: 8rpx;
186
+ border-radius: 4rpx;
187
+ background-color: rgba(23, 26, 29, 0.24);
188
+ }
189
+
190
+ .draggable-popup-content {
191
+ overflow: auto;
192
+ position: relative;
193
+ z-index: 100;
194
+ }
195
+ </style>
@@ -0,0 +1,10 @@
1
+ // index.ts
2
+ import type { App } from 'vue';
3
+ import DraggableBottomPopup from './DraggableBottomPopup.vue';
4
+
5
+ // 使用install方法,在app.use挂载
6
+ DraggableBottomPopup.install = (app: App) => {
7
+ app.component(DraggableBottomPopup.__name as string, DraggableBottomPopup); //注册组件
8
+ };
9
+
10
+ export default DraggableBottomPopup;
@@ -0,0 +1,16 @@
1
+ <template>
2
+ <div class="btn">我的按钮</div>
3
+ </template>
4
+
5
+ <script setup lang="ts">
6
+
7
+ </script>
8
+
9
+ <style scoped>
10
+ .btn {
11
+ width: 100px;
12
+ height: 100px;
13
+ background-color: red;
14
+ color: #ffffff;
15
+ }
16
+ </style>
package/HwBtn/index.ts ADDED
@@ -0,0 +1,10 @@
1
+ // index.ts
2
+ import type { App } from 'vue'
3
+ import HwBtn from "./HwBtn.vue"
4
+
5
+ // 使用install方法,在app.use挂载
6
+ HwBtn.install = (app: App) => {
7
+ app.component(HwBtn.__name as string, HwBtn) //注册组件
8
+ }
9
+
10
+ export default HwBtn
package/index.d.ts ADDED
@@ -0,0 +1,11 @@
1
+ import { App } from 'vue';
2
+ import { HwBtn } from './HwBtn';
3
+ import { DraggableBottomPopup } from './DraggableBottomPopup';
4
+
5
+ export { HwBtn, DraggableBottomPopup };
6
+
7
+ export declare const hwCusUi: {
8
+ install: (app: App) => void;
9
+ };
10
+
11
+ export default hwCusUi;
package/index.ts ADDED
@@ -0,0 +1,21 @@
1
+ // index.ts
2
+ import type { App } from 'vue';
3
+ import HwBtn from './HwBtn';
4
+ import DraggableBottomPopup from './DraggableBottomPopup';
5
+
6
+ // 所有组件列表
7
+ const components = [HwBtn, DraggableBottomPopup];
8
+
9
+ // 定义 install 方法
10
+ const install = (app: App): void => {
11
+ // 遍历注册所有组件
12
+ components.forEach((component) => app.component(component.__name as string, component));
13
+ };
14
+
15
+ export { HwBtn, DraggableBottomPopup };
16
+
17
+ const hwCusUi = {
18
+ install
19
+ };
20
+
21
+ export default hwCusUi;
package/package.json CHANGED
@@ -1,45 +1,14 @@
1
- {
2
- "name": "hw-cus-ui",
3
- "version": "1.0.22",
4
- "type": "module",
5
- "main": "./dist/hw-cus-ui.umd.cjs",
6
- "module": "./dist/hw-cus-ui.es.cjs",
7
- "types": "./dist/types/index.d.ts",
8
- "exports": {
9
- ".": {
10
- "import": "./dist/hw-cus-ui.es.cjs",
11
- "require": "./dist/hw-cus-ui.umd.cjs",
12
- "types": "./dist/types/index.d.ts"
13
- }
14
- },
15
- "files": [
16
- "dist"
17
- ],
18
- "scripts": {
19
- "dev": "vite",
20
- "build": "vue-tsc -b && vite build && vue-tsc -p tsconfig.types.json",
21
- "preview": "vite preview",
22
- "lib": "vue-tsc -b && vite build --mode lib"
23
- },
24
- "dependencies": {
25
- "vue": "^3.5.24"
26
- },
27
- "devDependencies": {
28
- "@types/node": "^24.10.1",
29
- "@vitejs/plugin-vue": "^6.0.1",
30
- "@vue/tsconfig": "^0.8.1",
31
- "typescript": "~5.9.3",
32
- "vite": "npm:rolldown-vite@7.2.5",
33
- "vue-tsc": "^3.1.4"
34
- },
35
- "resolutions": {
36
- "vite": "npm:rolldown-vite@7.2.5"
37
- },
38
- "peerDependencies": {
39
- "vue": "^3.5.24"
40
- },
41
- "description": "一个基于 Vue 3 的组件库,包含常用的UI组件。",
42
- "keywords": [],
43
- "author": "",
44
- "license": "ISC"
45
- }
1
+ {
2
+ "name": "hw-cus-ui",
3
+ "version": "1.0.24",
4
+ "description": "",
5
+ "main": "index.ts",
6
+ "scripts": {
7
+ "test": "echo \"Error: no test specified\" && exit 1"
8
+ },
9
+ "keywords": [],
10
+ "author": "",
11
+ "license": "ISC",
12
+ "type": "commonjs",
13
+ "types": "./index.d.ts"
14
+ }
package/README.md DELETED
@@ -1,70 +0,0 @@
1
- # hw-cus-ui
2
-
3
- 一个基于 Vue 3 的组件库,包含常用的UI组件。
4
-
5
- ## 安装
6
-
7
- ```bash
8
- npm install @yourname/hw-cus-ui
9
- ```
10
-
11
- ## 使用
12
-
13
- ### 全局注册
14
-
15
- ```ts
16
- import { createApp } from 'vue'
17
- import App from './App.vue'
18
- import hwCusUi from '@yourname/hw-cus-ui'
19
- import '@yourname/hw-cus-ui/dist/hw-cus-ui.css'
20
-
21
- const app = createApp(App)
22
-
23
- app.use(hwCusUi)
24
- app.mount('#app')
25
- ```
26
-
27
- ### 按需引入
28
-
29
- ```ts
30
- import { createApp } from 'vue'
31
- import App from './App.vue'
32
- import { HwBtn } from 'hw-cus-ui'
33
- import '@yourname/hw-cus-ui/dist/hw-cus-ui.css'
34
-
35
- const app = createApp(App)
36
-
37
- app.component('HwBtn', HwBtn)
38
- app.mount('#app')
39
- ```
40
-
41
- ## 组件列表
42
-
43
- - HwBtn (按钮组件)
44
-
45
- ## 开发
46
-
47
- ```bash
48
- # 安装依赖
49
- npm install
50
-
51
- # 启动开发服务器
52
- npm run dev
53
-
54
- # 构建组件库
55
- npm run build
56
- ```
57
-
58
- ## 发布到npm
59
-
60
- 在发布前,请注意:
61
-
62
- 1. 将 package.json 中的 `@yourname/hw-cus-ui` 替换为你的实际npm用户名
63
- 2. 登录npm账户: `npm login`
64
- 3. 确保版本号更新
65
- 4. 运行构建命令: `npm run build`
66
- 5. 发布: `npm publish`
67
-
68
- ## License
69
-
70
- MIT
@@ -1,2 +0,0 @@
1
- .btn[data-v-6693a7d0]{color:#fff;background-color:red;width:100px;height:100px}
2
- /*$vite$:1*/
@@ -1,17 +0,0 @@
1
- import { createElementBlock, openBlock } from "vue";
2
- var __plugin_vue_export_helper_default = (e, s) => {
3
- let c = e.__vccOpts || e;
4
- for (let [e, l] of s) c[e] = l;
5
- return c;
6
- }, _sfc_main = {}, _hoisted_1 = { class: "btn" };
7
- function _sfc_render(c, l) {
8
- return openBlock(), createElementBlock("div", _hoisted_1, "我的按钮");
9
- }
10
- var HwBtn_default$1 = /* @__PURE__ */ __plugin_vue_export_helper_default(_sfc_main, [["render", _sfc_render], ["__scopeId", "data-v-6693a7d0"]]);
11
- HwBtn_default$1.install = (e) => {
12
- e.component(HwBtn_default$1.__name, HwBtn_default$1);
13
- };
14
- var HwBtn_default = HwBtn_default$1, components = [HwBtn_default], components_default = { install: (e) => {
15
- components.forEach((s) => e.component(s.__name, s));
16
- } };
17
- export { HwBtn_default as HwBtn, components_default as default };
@@ -1 +0,0 @@
1
- (function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports,require(`vue`)):typeof define==`function`&&define.amd?define([`exports`,`vue`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.hwCusUi={},e.Vue))})(this,function(e,t){Object.defineProperty(e,`__esModule`,{value:!0});var n=(e,t)=>{let n=e.__vccOpts||e;for(let[e,r]of t)n[e]=r;return n},r={},i={class:`btn`};function a(e,n){return(0,t.openBlock)(),(0,t.createElementBlock)(`div`,i,`我的按钮`)}var o=n(r,[[`render`,a],[`__scopeId`,`data-v-6693a7d0`]]);o.install=e=>{e.component(o.__name,o)};var s=o,c=[s];e.HwBtn=s,e.default={install:e=>{c.forEach(t=>e.component(t.__name,t))}}});
@@ -1,3 +0,0 @@
1
- declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
2
- declare const _default: typeof __VLS_export;
3
- export default _default;
@@ -1,2 +0,0 @@
1
- import HwBtn from "./HwBtn.vue";
2
- export default HwBtn;
@@ -1,7 +0,0 @@
1
- import type { App } from 'vue';
2
- import HwBtn from './HwBtn';
3
- export { HwBtn, };
4
- declare const hwCusUi: {
5
- install: (app: App) => void;
6
- };
7
- export default hwCusUi;
@@ -1,3 +0,0 @@
1
- import hwCusUi from './components';
2
- export * from './components';
3
- export { hwCusUi };
package/dist/vite.svg DELETED
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>