vue-modaller 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +21 -0
- package/README.md +201 -0
- package/dist/index.d.ts +49 -0
- package/dist/logo.webp +0 -0
- package/dist/style.css +1 -0
- package/dist/vite.svg +1 -0
- package/dist/vue-modaller.js +301 -0
- package/dist/vue-modaller.umd.cjs +1 -0
- package/package.json +91 -0
package/LICENSE.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 I. Kaan Yilmaz
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
# VueModaller
|
|
2
|
+
|
|
3
|
+
A flexible and powerful modal system for Vue 3 applications with TypeScript support, featuring draggable modals, side panels, and smooth animations.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
✨ **Multiple Modal Types**
|
|
8
|
+
- Standard modals
|
|
9
|
+
- Side panels
|
|
10
|
+
- Panel modals
|
|
11
|
+
- Draggable modals (Instagram-style)
|
|
12
|
+
|
|
13
|
+
🎨 **Customizable**
|
|
14
|
+
- CSS variables for easy theming
|
|
15
|
+
- BEM methodology for styling
|
|
16
|
+
- Configurable animations
|
|
17
|
+
- Custom handle styles for draggable modals
|
|
18
|
+
|
|
19
|
+
🚀 **Developer Experience**
|
|
20
|
+
- TypeScript support
|
|
21
|
+
- Vue 3 Composition API
|
|
22
|
+
- Easy to use composable
|
|
23
|
+
- Global component registration
|
|
24
|
+
|
|
25
|
+
📱 **Mobile-Friendly**
|
|
26
|
+
- Touch gesture support
|
|
27
|
+
- Smooth animations
|
|
28
|
+
- Responsive design
|
|
29
|
+
|
|
30
|
+
## Installation
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npm install vue-modaller
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Quick Start
|
|
37
|
+
|
|
38
|
+
### 1. Install the plugin
|
|
39
|
+
|
|
40
|
+
```javascript
|
|
41
|
+
import { createApp } from 'vue'
|
|
42
|
+
import VueModaller from 'vue-modaller'
|
|
43
|
+
import App from './App.vue'
|
|
44
|
+
|
|
45
|
+
const app = createApp(App)
|
|
46
|
+
app.use(VueModaller)
|
|
47
|
+
app.mount('#app')
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### 2. Add ModalRoot to your app
|
|
51
|
+
|
|
52
|
+
```vue
|
|
53
|
+
<template>
|
|
54
|
+
<div id="app">
|
|
55
|
+
<!-- Your app content -->
|
|
56
|
+
<ModalRoot />
|
|
57
|
+
</div>
|
|
58
|
+
</template>
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### 3. Use the useModal composable
|
|
62
|
+
|
|
63
|
+
```vue
|
|
64
|
+
<script setup>
|
|
65
|
+
import { useModal } from 'vue-modaller'
|
|
66
|
+
import MyModalContent from './MyModalContent.vue'
|
|
67
|
+
|
|
68
|
+
const openModal = async () => {
|
|
69
|
+
const result = await useModal(MyModalContent, {
|
|
70
|
+
title: 'My Modal',
|
|
71
|
+
config: {
|
|
72
|
+
type: 'modal', // 'modal' | 'side' | 'panel' | 'draggable'
|
|
73
|
+
blur: true,
|
|
74
|
+
closeable: true
|
|
75
|
+
},
|
|
76
|
+
props: {
|
|
77
|
+
message: 'Hello from modal!'
|
|
78
|
+
}
|
|
79
|
+
})
|
|
80
|
+
console.log('Modal result:', result)
|
|
81
|
+
}
|
|
82
|
+
</script>
|
|
83
|
+
|
|
84
|
+
<template>
|
|
85
|
+
<button @click="openModal">Open Modal</button>
|
|
86
|
+
</template>
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Modal Types
|
|
90
|
+
|
|
91
|
+
### Standard Modal
|
|
92
|
+
```javascript
|
|
93
|
+
const result = await useModal(Component, {
|
|
94
|
+
config: {
|
|
95
|
+
type: 'modal',
|
|
96
|
+
width: 500,
|
|
97
|
+
blur: true,
|
|
98
|
+
closeable: true
|
|
99
|
+
}
|
|
100
|
+
})
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Side Panel
|
|
104
|
+
```javascript
|
|
105
|
+
const result = await useModal(Component, {
|
|
106
|
+
config: {
|
|
107
|
+
type: 'side',
|
|
108
|
+
blur: true,
|
|
109
|
+
closeable: true
|
|
110
|
+
}
|
|
111
|
+
})
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Draggable Modal (Instagram-style)
|
|
115
|
+
```javascript
|
|
116
|
+
const result = await useModal(Component, {
|
|
117
|
+
config: {
|
|
118
|
+
type: 'draggable',
|
|
119
|
+
blur: true,
|
|
120
|
+
closeable: true,
|
|
121
|
+
draggableConfig: {
|
|
122
|
+
initialPosition: 'half', // 'full' | 'half'
|
|
123
|
+
handle: {
|
|
124
|
+
color: '#ddd',
|
|
125
|
+
hoverColor: '#bbb',
|
|
126
|
+
activeColor: '#999'
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
})
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Configuration Options
|
|
134
|
+
|
|
135
|
+
```typescript
|
|
136
|
+
interface ModalConfig {
|
|
137
|
+
type?: 'modal' | 'side' | 'panel' | 'draggable'
|
|
138
|
+
width?: number
|
|
139
|
+
height?: number | string
|
|
140
|
+
blur?: boolean
|
|
141
|
+
closeable?: boolean
|
|
142
|
+
corner?: string
|
|
143
|
+
margin?: number
|
|
144
|
+
padding?: number
|
|
145
|
+
background?: string
|
|
146
|
+
anim?: boolean
|
|
147
|
+
draggableConfig?: {
|
|
148
|
+
initialPosition?: 'full' | 'half'
|
|
149
|
+
hideHandle?: boolean
|
|
150
|
+
handle?: {
|
|
151
|
+
color?: string
|
|
152
|
+
hoverColor?: string
|
|
153
|
+
activeColor?: string
|
|
154
|
+
height?: string
|
|
155
|
+
width?: string
|
|
156
|
+
radius?: string
|
|
157
|
+
marginTop?: string
|
|
158
|
+
marginBottom?: string
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## API
|
|
165
|
+
|
|
166
|
+
### useModal(component, options)
|
|
167
|
+
|
|
168
|
+
Opens a modal and returns a promise that resolves with the modal result.
|
|
169
|
+
|
|
170
|
+
**Parameters:**
|
|
171
|
+
- `component`: Vue component to render in the modal
|
|
172
|
+
- `options`: Modal configuration object
|
|
173
|
+
|
|
174
|
+
**Returns:** `Promise<any>` - Resolves when modal is closed
|
|
175
|
+
|
|
176
|
+
### ModalRoot
|
|
177
|
+
|
|
178
|
+
Global component that manages modal rendering. Must be added to your app template.
|
|
179
|
+
|
|
180
|
+
## Styling
|
|
181
|
+
|
|
182
|
+
VueModaller uses CSS variables for easy customization:
|
|
183
|
+
|
|
184
|
+
```css
|
|
185
|
+
:root {
|
|
186
|
+
--modal-backdrop-color: rgba(0, 0, 0, 0.5);
|
|
187
|
+
--modal-background-color: #ffffff;
|
|
188
|
+
--modal-border-radius: 0.75rem;
|
|
189
|
+
--modal-shadow: 0 10px 25px rgba(0, 0, 0, 0.15);
|
|
190
|
+
--modal-draggable-handle-color: #ddd;
|
|
191
|
+
/* ... more variables */
|
|
192
|
+
}
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
## License
|
|
196
|
+
|
|
197
|
+
MIT
|
|
198
|
+
|
|
199
|
+
## Contributing
|
|
200
|
+
|
|
201
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { App } from 'vue'
|
|
2
|
+
|
|
3
|
+
export interface DraggableConfig {
|
|
4
|
+
initialPosition?: 'full' | 'half'
|
|
5
|
+
hideHandle?: boolean
|
|
6
|
+
handle?: {
|
|
7
|
+
color?: string
|
|
8
|
+
hoverColor?: string
|
|
9
|
+
activeColor?: string
|
|
10
|
+
height?: string
|
|
11
|
+
width?: string
|
|
12
|
+
radius?: string
|
|
13
|
+
marginTop?: string
|
|
14
|
+
marginBottom?: string
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface ModalConfig {
|
|
19
|
+
type?: 'modal' | 'side' | 'panel' | 'draggable'
|
|
20
|
+
width?: number
|
|
21
|
+
height?: number | string
|
|
22
|
+
blur?: boolean
|
|
23
|
+
closeable?: boolean
|
|
24
|
+
corner?: string
|
|
25
|
+
margin?: number
|
|
26
|
+
padding?: number
|
|
27
|
+
background?: string
|
|
28
|
+
anim?: boolean
|
|
29
|
+
draggableConfig?: DraggableConfig
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface modalOptionsType {
|
|
33
|
+
title?: string
|
|
34
|
+
config?: ModalConfig & { open?: boolean }
|
|
35
|
+
props?: Record<string, any>
|
|
36
|
+
slots?: Record<string, any>
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
declare const VueModaller: {
|
|
40
|
+
install(app: App, options?: any): void
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function useModal(
|
|
44
|
+
component: any,
|
|
45
|
+
options?: modalOptionsType
|
|
46
|
+
): Promise<any>
|
|
47
|
+
|
|
48
|
+
export { VueModaller as default }
|
|
49
|
+
export * from './components'
|
package/dist/logo.webp
ADDED
|
Binary file
|
package/dist/style.css
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
:root{--white: #fff;--blue-500: #3b82f6;--blue-600: #2563eb;--gray-500: #6b7280;--gray-600: #4b5563;--dark: #1f2937;--border-gray: #e0e0e0;--modal-backdrop: rgba(0, 0, 0, .2);--modal-border-radius: .75rem;--modal-padding: 1rem;--modal-shadow: 0 4px 6px -1px rgba(0, 0, 0, .1), 0 2px 4px -1px rgba(0, 0, 0, .06);--modal-z-index: 9999;--modal-content-z-index: 99;--modal-draggable-handle-color: #ccc;--modal-draggable-handle-hover-color: #999;--modal-draggable-handle-active-color: #666;--modal-draggable-handle-height: 5px;--modal-draggable-handle-width: 45px;--modal-draggable-handle-radius: 4px;--modal-draggable-handle-margin-top: 10px;--modal-draggable-handle-margin-bottom: 10px}.__modal-wrapper{position:fixed;width:100%;height:100%;z-index:var(--modal-z-index);top:0;left:0}.__modal-wrapper--centered{display:flex;justify-content:center;align-items:center}.__modal-wrapper--side{display:flex;justify-content:flex-end;align-items:flex-end;top:0;right:0}.__modal-backdrop{position:absolute;width:100%;height:100%;background-color:var(--modal-backdrop);cursor:pointer;top:0;right:0;bottom:0;left:0}.__modal-backdrop--blur{-webkit-backdrop-filter:blur(2.5px);backdrop-filter:blur(2.5px)}.__modal-content{padding:var(--modal-padding);box-shadow:var(--modal-shadow);z-index:var(--modal-content-z-index);width:100%;pointer-events:auto;overflow-y:auto;background-color:var(--white)}.__modal-content--standard{max-width:100%;margin-top:5rem;margin-bottom:5rem}.__modal-content--side{height:100%;max-width:25rem}@media (min-width: 1024px){.__modal-content--side{max-width:30rem}}.__modal-content--panel{width:100%;max-height:50vh;border-radius:1rem 1rem 0 0;margin:0}.__modal-wrapper--dragable,.__modal-wrapper--draggable{display:flex;justify-content:center;align-items:flex-end;top:0;left:0}.__modal-content--dragable.dragging{transition:none}.__modal-content--draggable{width:100%;height:100vh;max-height:100vh;border-radius:18px 18px 0 0;margin:0;transition:transform .25s cubic-bezier(.25,.1,.25,1);position:absolute;bottom:0;touch-action:none;overflow:hidden;box-shadow:0 -4px 12px #00000040}.__modal-content--draggable.__modal-content--dragging{transition:none}.__modal-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:.75rem}.__modal-header__title{color:var(--dark);font-weight:600}.__modal-header__title--standard{font-size:1.25rem;line-height:1.75rem}.__modal-header__title--side{font-size:1.5rem;line-height:2rem}.__modal-header__close-btn{cursor:pointer;width:2.5rem;height:2.5rem;display:flex;justify-content:center;align-items:center;border:1px solid var(--border-gray);border-radius:9999px;background-color:transparent;font-size:1.25rem;color:var(--dark)}.__modal-header__close-btn:hover{background-color:#f3f4f6}@media (min-width: 768px){.__modal-body{padding:0}}.__modal-drag-handle{cursor:grab;background:var(--modal-draggable-handle-color);height:var(--modal-draggable-handle-height);width:var(--modal-draggable-handle-width);border-radius:var(--modal-draggable-handle-radius);margin-top:var(--modal-draggable-handle-margin-top);margin-bottom:var(--modal-draggable-handle-margin-bottom);margin-left:auto;margin-right:auto;transition:background-color .2s}.__modal-drag-handle:hover{background:var(--modal-draggable-handle-hover-color)}.__modal-drag-handle:active{cursor:grabbing;background:var(--modal-draggable-handle-active-color)}.__hidden{display:none}:root{--draggable-slidein-y: 0px}@-webkit-keyframes zoomIn{0%{opacity:0;-webkit-transform:translateY(16px) scale(.95);transform:translateY(16px) scale(.95)}to{opacity:1;-webkit-transform:translateY(0) scale(1);transform:translateY(0) scale(1)}}@keyframes zoomIn{0%{opacity:0;-webkit-transform:translateY(16px) scale(.95);transform:translateY(16px) scale(.95)}to{opacity:1;-webkit-transform:translateY(0) scale(1);transform:translateY(0) scale(1)}}.zoomIn{-webkit-animation-name:zoomIn;animation-name:zoomIn;animation-duration:.3s;animation-timing-function:ease-out;animation-fill-mode:both}@-webkit-keyframes zoomOut{0%{opacity:1;-webkit-transform:translateY(0) scale(1);transform:translateY(0) scale(1)}to{opacity:0;-webkit-transform:translateY(16px) scale(.95);transform:translateY(16px) scale(.95)}}@keyframes zoomOut{0%{opacity:1;-webkit-transform:translateY(0) scale(1);transform:translateY(0) scale(1)}to{opacity:0;-webkit-transform:translateY(16px) scale(.95);transform:translateY(16px) scale(.95)}}.zoomOut{-webkit-animation-name:zoomOut;animation-name:zoomOut;animation-duration:.2s;animation-timing-function:ease-in;animation-fill-mode:both}@-webkit-keyframes slideOutRight{0%{-webkit-transform:translate3d(0,0,0);transform:translateZ(0)}to{visibility:hidden;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}@keyframes slideOutRight{0%{-webkit-transform:translate3d(0,0,0);transform:translateZ(0)}to{visibility:hidden;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}.slideOutRight{-webkit-animation-name:slideOutRight;animation-name:slideOutRight;animation-duration:.2s;animation-timing-function:ease-in;animation-fill-mode:both}@-webkit-keyframes slideInRight{0%{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0);visibility:visible}to{-webkit-transform:translate3d(0,0,0);transform:translateZ(0)}}@keyframes slideInRight{0%{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0);visibility:visible}to{-webkit-transform:translate3d(0,0,0);transform:translateZ(0)}}.slideInRight{-webkit-animation-name:slideInRight;animation-name:slideInRight;animation-duration:.3s;animation-timing-function:ease-out;animation-fill-mode:both}@-webkit-keyframes slideInBottom{0%{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0);visibility:visible}to{-webkit-transform:translate3d(0,0,0);transform:translateZ(0)}}@keyframes slideInBottom{0%{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0);visibility:visible}to{-webkit-transform:translate3d(0,0,0);transform:translateZ(0)}}.slideInBottom{-webkit-animation-name:slideInBottom;animation-name:slideInBottom;animation-duration:.3s;animation-timing-function:ease-out;animation-fill-mode:backwards}@-webkit-keyframes slideOutBottom{0%{-webkit-transform:translate3d(0,0,0);transform:translateZ(0)}to{visibility:hidden;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}@keyframes slideOutBottom{0%{-webkit-transform:translate3d(0,0,0);transform:translateZ(0)}to{visibility:hidden;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}.slideOutBottom{-webkit-animation-name:slideOutBottom;animation-name:slideOutBottom;animation-duration:.2s;animation-timing-function:ease-in;animation-fill-mode:backwards}@-webkit-keyframes slideInUp{0%{-webkit-transform:translate3d(0,50%,0);transform:translate3d(0,50%,0);visibility:visible}to{-webkit-transform:translate3d(0,0,0);transform:translateZ(0)}}@keyframes slideInUp{0%{-webkit-transform:translateY(50%);transform:translateY(50%);visibility:visible}to{-webkit-transform:translate3d(0,0,0);transform:translateZ(0)}}@keyframes slideInUp{0%{-webkit-transform:translateY(100%);transform:translateY(100%);visibility:visible}to{-webkit-transform:translateY(50%);transform:translateY(50%)}}.slideInUp{-webkit-animation-name:slideInUp;animation-name:slideInUp;animation-duration:.3s;animation-timing-function:ease-out;animation-fill-mode:both}@-webkit-keyframes slideOutDown{0%{-webkit-transform:translateY(0);transform:translateY(0)}to{visibility:hidden;-webkit-transform:translateY(50%);transform:translateY(50%)}}@keyframes slideOutDown{0%{-webkit-transform:translateY(50%);transform:translateY(50%)}to{visibility:hidden;-webkit-transform:translateY(0%);transform:translateY(0)}}.slideOutDown{-webkit-animation-name:slideOutDown;animation-name:slideOutDown;animation-duration:.2s;animation-timing-function:ease-in;animation-fill-mode:forwards}.__modal-content--draggable{height:100vh;border-radius:18px 18px 0 0;box-shadow:0 -4px 12px #00000040;touch-action:none;overflow:hidden;transform-origin:bottom}.__modal-content--dragging,.__modal-content--animating{transition:none!important;animation:none!important;-webkit-user-select:none;user-select:none}.__modal-wrapper--draggable{display:flex;justify-content:center;align-items:flex-end}.blur-bg{-webkit-backdrop-filter:blur(2.5px);backdrop-filter:blur(2.5px)}
|
package/dist/vite.svg
ADDED
|
@@ -0,0 +1 @@
|
|
|
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>
|
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
import { ref as h, onMounted as $e, onUnmounted as He, defineComponent as Le, computed as K, createElementBlock as G, createCommentVNode as _e, openBlock as O, normalizeClass as U, createElementVNode as Y, normalizeStyle as ye, unref as C, renderSlot as we, markRaw as Be, toRaw as De, createBlock as p, Teleport as Ae, Fragment as Se, renderList as Me, createSlots as Te, withCtx as J, resolveDynamicComponent as ke, mergeProps as Ee, toDisplayString as Fe } from "vue";
|
|
2
|
+
const xe = {
|
|
3
|
+
initialPosition: "half",
|
|
4
|
+
hideHandle: !1,
|
|
5
|
+
handle: {
|
|
6
|
+
color: "#ccc",
|
|
7
|
+
height: "5px",
|
|
8
|
+
width: "45px",
|
|
9
|
+
hoverColor: "#999",
|
|
10
|
+
activeColor: "#666"
|
|
11
|
+
}
|
|
12
|
+
}, ze = (l = xe, e) => {
|
|
13
|
+
const g = h(!1), a = h(0), y = h(!1), c = h(!1);
|
|
14
|
+
let u = 0, _ = 0, P = !1, $ = 0, o = { full: 0, half: 0, closed: 0 }, T = 0, L = 0, B = 0, k = 0;
|
|
15
|
+
const x = h(null), D = () => {
|
|
16
|
+
$ = window.innerHeight, o = {
|
|
17
|
+
full: 0,
|
|
18
|
+
half: $ * 0.4,
|
|
19
|
+
closed: $
|
|
20
|
+
}, a.value = o.closed, T = o.closed;
|
|
21
|
+
}, w = (f, i = 300) => new Promise((b) => {
|
|
22
|
+
if (c.value) return b();
|
|
23
|
+
c.value = !0;
|
|
24
|
+
const m = a.value, M = f - m, s = performance.now(), A = (S) => {
|
|
25
|
+
const F = S - s, j = Math.min(F / i, 1), q = 1 - Math.pow(1 - j, 3);
|
|
26
|
+
a.value = m + M * q, j < 1 ? requestAnimationFrame(A) : (c.value = !1, T = a.value, b());
|
|
27
|
+
};
|
|
28
|
+
requestAnimationFrame(A);
|
|
29
|
+
}), H = async () => {
|
|
30
|
+
await w(o[l.initialPosition], 400);
|
|
31
|
+
}, E = async () => {
|
|
32
|
+
await w(o.closed, 300), e && setTimeout(() => e(), 50);
|
|
33
|
+
}, n = (f) => {
|
|
34
|
+
var b, m;
|
|
35
|
+
if (c.value) return;
|
|
36
|
+
y.value = !0, P = !0;
|
|
37
|
+
const i = f;
|
|
38
|
+
u = i instanceof PointerEvent ? i.clientY : ((m = (b = i.touches) == null ? void 0 : b[0]) == null ? void 0 : m.clientY) || 0, k = u, B = Date.now(), document.addEventListener("pointermove", t), document.addEventListener("pointerup", r), document.addEventListener("touchmove", t, { passive: !1 }), document.addEventListener("touchend", r);
|
|
39
|
+
}, t = (f) => {
|
|
40
|
+
var S, F;
|
|
41
|
+
if (!P || c.value) return;
|
|
42
|
+
const i = f;
|
|
43
|
+
_ = i instanceof PointerEvent ? i.clientY : ((F = (S = i.touches) == null ? void 0 : S[0]) == null ? void 0 : F.clientY) || 0;
|
|
44
|
+
const b = _ - u, m = T + b, M = Date.now(), s = _ - k, A = M - B;
|
|
45
|
+
L = s / A, k = _, B = M, m < o.full ? a.value = o.full : m > o.closed ? a.value = o.closed : a.value = m;
|
|
46
|
+
}, r = async () => {
|
|
47
|
+
y.value = !1, P = !1, document.removeEventListener("pointermove", t), document.removeEventListener("pointerup", r), document.removeEventListener("touchmove", t), document.removeEventListener("touchend", r);
|
|
48
|
+
const f = a.value, i = Math.abs(f - o.full), b = Math.abs(f - o.half), m = Math.abs(f - o.closed), M = Math.min(i, b, m);
|
|
49
|
+
let s = o.half;
|
|
50
|
+
L > 0.5 ? T === o.full ? s = o.half : s = o.closed : L < -0.5 || M === i ? s = o.full : M === b ? s = o.half : s = o.closed, s === o.closed ? await E() : await w(s, 250);
|
|
51
|
+
}, v = () => {
|
|
52
|
+
E();
|
|
53
|
+
};
|
|
54
|
+
return $e(() => {
|
|
55
|
+
D();
|
|
56
|
+
}), He(() => {
|
|
57
|
+
document.removeEventListener("pointermove", t), document.removeEventListener("pointerup", r), document.removeEventListener("touchmove", t), document.removeEventListener("touchend", r);
|
|
58
|
+
}), {
|
|
59
|
+
open: g,
|
|
60
|
+
translateY: a,
|
|
61
|
+
isDragging: y,
|
|
62
|
+
isAnimating: c,
|
|
63
|
+
panel: x,
|
|
64
|
+
openPanel: H,
|
|
65
|
+
closePanel: E,
|
|
66
|
+
startDrag: n,
|
|
67
|
+
handleBackdropClick: v,
|
|
68
|
+
initPositions: D,
|
|
69
|
+
animateToPosition: w
|
|
70
|
+
};
|
|
71
|
+
}, Ve = { class: "__modal-body" }, We = { class: "__modal-header" }, je = /* @__PURE__ */ Le({
|
|
72
|
+
__name: "modal",
|
|
73
|
+
props: {
|
|
74
|
+
config: Object,
|
|
75
|
+
modalKeyIndex: Number
|
|
76
|
+
},
|
|
77
|
+
emits: ["close"],
|
|
78
|
+
setup(l, { emit: e }) {
|
|
79
|
+
var H, E;
|
|
80
|
+
const g = e, a = l, y = () => {
|
|
81
|
+
var n;
|
|
82
|
+
((n = a.config) == null ? void 0 : n.type) === "draggable" ? $() : g("close");
|
|
83
|
+
}, { isDragging: c, translateY: u, startDrag: _, openPanel: P, closePanel: $, isAnimating: o } = ze((H = a.config) == null ? void 0 : H.draggableConfig, () => {
|
|
84
|
+
g("close");
|
|
85
|
+
}), T = () => {
|
|
86
|
+
var n, t;
|
|
87
|
+
(n = a.config) != null && n.closeable && (console.log("Modal closed from outside", (t = a.config) == null ? void 0 : t.closeable), y());
|
|
88
|
+
}, L = K(() => {
|
|
89
|
+
var n, t, r;
|
|
90
|
+
return ((n = a.config) == null ? void 0 : n.type) == "side" ? "100%" : (t = a.config) != null && t.width ? `${(r = a.config) == null ? void 0 : r.width}px` : "480px";
|
|
91
|
+
}), B = K(() => {
|
|
92
|
+
var n, t, r, v;
|
|
93
|
+
return (n = a.config) != null && n.height && a.config.type !== "draggable" ? typeof ((t = a.config) == null ? void 0 : t.height) == "number" ? `${(r = a.config) == null ? void 0 : r.height}px` : (v = a.config) == null ? void 0 : v.height : "100%";
|
|
94
|
+
});
|
|
95
|
+
let k = h({
|
|
96
|
+
modal: { cls: "is-modal", anim_in: "zoomIn", anim_out: "zoomOut", style: `padding: ${(E = a.config) == null ? void 0 : E.padding}px;` },
|
|
97
|
+
panel: { cls: "is-panel", anim_in: "slideInBottom", anim_out: "slideOutBottom", style: "padding: 0" },
|
|
98
|
+
draggable: { cls: "is-draggable", anim_in: "", anim_out: "", style: "padding: 0" },
|
|
99
|
+
side: { cls: "is-side", anim_in: "slideInRight", anim_out: "slideOutRight", style: "padding: 0" }
|
|
100
|
+
});
|
|
101
|
+
const x = K(() => {
|
|
102
|
+
var n, t, r;
|
|
103
|
+
return (n = a.config) != null && n.anim ? k.value[((t = a.config) == null ? void 0 : t.type) || "modal"].anim_in : k.value[((r = a.config) == null ? void 0 : r.type) || "modal"].anim_out;
|
|
104
|
+
}), D = K(() => {
|
|
105
|
+
var r, v, f, i;
|
|
106
|
+
let n = "__modal-wrapper--centered", t = "__modal-content __modal-content--standard";
|
|
107
|
+
return ((r = a.config) == null ? void 0 : r.type) == "modal" ? (n = "__modal-wrapper--centered", t = "__modal-content __modal-content--standard") : ((v = a.config) == null ? void 0 : v.type) == "side" ? (n = "__modal-wrapper--side", t = "__modal-content __modal-content--side") : ((f = a.config) == null ? void 0 : f.type) == "panel" ? (n = "__modal-wrapper--panel", t = "__modal-content __modal-content--panel") : ((i = a.config) == null ? void 0 : i.type) == "draggable" && (n = "__modal-wrapper--draggable", t = `__modal-content __modal-content--draggable ${c.value ? "__modal-content--dragging" : ""} ${o.value ? "__modal-content--animating" : ""}`), {
|
|
108
|
+
mainModalWrapperClass: n,
|
|
109
|
+
mainModalClass: t
|
|
110
|
+
};
|
|
111
|
+
}), w = h(!1);
|
|
112
|
+
return $e(() => {
|
|
113
|
+
setTimeout(() => {
|
|
114
|
+
var n;
|
|
115
|
+
w.value = !0, ((n = a.config) == null ? void 0 : n.type) === "draggable" && (P(), console.log("opened draggable with animation"));
|
|
116
|
+
}, 100);
|
|
117
|
+
}), (n, t) => {
|
|
118
|
+
var r, v, f, i, b, m, M, s, A, S, F, j, q, X, Z, I, N, ee, ae, le, ne, te, oe, re, ce, de, ie, ge, ue, fe, se, me, he, ve, be, Ce;
|
|
119
|
+
return (r = l.config) != null && r.open ? (O(), G("div", {
|
|
120
|
+
key: 0,
|
|
121
|
+
class: U(["__modal-wrapper", D.value.mainModalWrapperClass])
|
|
122
|
+
}, [
|
|
123
|
+
Y("div", {
|
|
124
|
+
class: U(["__modal-backdrop", (v = l.config) != null && v.blur ? "__modal-backdrop--blur" : ""]),
|
|
125
|
+
onClick: T
|
|
126
|
+
}, null, 2),
|
|
127
|
+
w.value ? (O(), G("div", {
|
|
128
|
+
key: 0,
|
|
129
|
+
ref: "modalElement",
|
|
130
|
+
class: U([D.value.mainModalClass, (f = l.config) != null && f.background ? `bg-${(i = l.config) == null ? void 0 : i.background}` : "__modal-content", x.value]),
|
|
131
|
+
onPointerdown: t[0] || (t[0] = //@ts-ignore
|
|
132
|
+
(...Re) => C(_) && C(_)(...Re)),
|
|
133
|
+
style: ye({
|
|
134
|
+
width: L.value,
|
|
135
|
+
maxHeight: B.value,
|
|
136
|
+
borderRadius: `${((b = l.config) == null ? void 0 : b.type) !== "side" && ((m = l.config) == null ? void 0 : m.type) !== "panel" && ((M = l.config) == null ? void 0 : M.type) !== "draggable" ? ((s = l.config) == null ? void 0 : s.corner) ?? "0.75rem" : "0"}`,
|
|
137
|
+
marginTop: `${(A = l.config) != null && A.margin && l.config.type == "side" ? `${l.config.margin}px` : "0"}`,
|
|
138
|
+
transform: `translateY(${C(u)}px)`
|
|
139
|
+
})
|
|
140
|
+
}, [
|
|
141
|
+
Y("div", Ve, [
|
|
142
|
+
Y("div", {
|
|
143
|
+
class: U(["__modal-drag-handle", { __hidden: ((F = (S = l.config) == null ? void 0 : S.draggableConfig) == null ? void 0 : F.hideHandle) && ((j = l.config) == null ? void 0 : j.type) !== "draggable" }]),
|
|
144
|
+
style: ye({
|
|
145
|
+
"--modal-draggable-handle-color": (Z = (X = (q = l.config) == null ? void 0 : q.draggableConfig) == null ? void 0 : X.handle) == null ? void 0 : Z.color,
|
|
146
|
+
"--modal-draggable-handle-hover-color": (ee = (N = (I = l.config) == null ? void 0 : I.draggableConfig) == null ? void 0 : N.handle) == null ? void 0 : ee.hoverColor,
|
|
147
|
+
"--modal-draggable-handle-active-color": (ne = (le = (ae = l.config) == null ? void 0 : ae.draggableConfig) == null ? void 0 : le.handle) == null ? void 0 : ne.activeColor,
|
|
148
|
+
"--modal-draggable-handle-height": ((re = (oe = (te = l.config) == null ? void 0 : te.draggableConfig) == null ? void 0 : oe.handle) == null ? void 0 : re.height) || "5px",
|
|
149
|
+
"--modal-draggable-handle-width": ((ie = (de = (ce = l.config) == null ? void 0 : ce.draggableConfig) == null ? void 0 : de.handle) == null ? void 0 : ie.width) || "45px",
|
|
150
|
+
"--modal-draggable-handle-radius": ((fe = (ue = (ge = l.config) == null ? void 0 : ge.draggableConfig) == null ? void 0 : ue.handle) == null ? void 0 : fe.radius) || "4px",
|
|
151
|
+
"--modal-draggable-handle-margin-top": ((he = (me = (se = l.config) == null ? void 0 : se.draggableConfig) == null ? void 0 : me.handle) == null ? void 0 : he.marginTop) || "10px",
|
|
152
|
+
"--modal-draggable-handle-margin-bottom": ((Ce = (be = (ve = l.config) == null ? void 0 : ve.draggableConfig) == null ? void 0 : be.handle) == null ? void 0 : Ce.marginBottom) || "10px"
|
|
153
|
+
})
|
|
154
|
+
}, null, 6),
|
|
155
|
+
Y("div", We, [
|
|
156
|
+
we(n.$slots, "header")
|
|
157
|
+
]),
|
|
158
|
+
Y("div", null, [
|
|
159
|
+
we(n.$slots, "default")
|
|
160
|
+
])
|
|
161
|
+
])
|
|
162
|
+
], 38)) : _e("", !0)
|
|
163
|
+
], 2)) : _e("", !0);
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
}), Oe = h(!1), R = h([]), z = h([]), Ye = h(""), d = h([]), V = h([]), W = h([]), Je = (l, e) => new Promise(
|
|
167
|
+
(g) => {
|
|
168
|
+
var c, u, _, P, $, o, T, L, B, k, x, D, w, H, E, n, t, r;
|
|
169
|
+
Oe.value = !0;
|
|
170
|
+
const a = Be(De(l));
|
|
171
|
+
R.value.length > 0 ? R.value.push(a) : R.value = [a], Ye.value = (e == null ? void 0 : e.title) || "";
|
|
172
|
+
const y = {
|
|
173
|
+
width: (e == null ? void 0 : e.config.width) || 450,
|
|
174
|
+
background: (e == null ? void 0 : e.config.background) || "white",
|
|
175
|
+
padding: (e == null ? void 0 : e.config.padding) || "20px",
|
|
176
|
+
closeable: (e == null ? void 0 : e.config.closeable) ?? !0,
|
|
177
|
+
blur: (e == null ? void 0 : e.config.blur) ?? !0,
|
|
178
|
+
corner: (e == null ? void 0 : e.config.corner) ?? "10px",
|
|
179
|
+
type: (e == null ? void 0 : e.config.type) || "modal",
|
|
180
|
+
open: !0,
|
|
181
|
+
anim: !0,
|
|
182
|
+
title: (e == null ? void 0 : e.config.title) || "",
|
|
183
|
+
margin: (e == null ? void 0 : e.config.margin) || 0,
|
|
184
|
+
height: (e == null ? void 0 : e.config.height) || 0,
|
|
185
|
+
mobileType: (e == null ? void 0 : e.config.mobileType) || "modal",
|
|
186
|
+
draggableConfig: {
|
|
187
|
+
initialPosition: ((c = e == null ? void 0 : e.config.draggableConfig) == null ? void 0 : c.initialPosition) || "half",
|
|
188
|
+
hideHandle: ((u = e == null ? void 0 : e.config.draggableConfig) == null ? void 0 : u.hideHandle) || !1,
|
|
189
|
+
handle: {
|
|
190
|
+
color: ((P = (_ = e == null ? void 0 : e.config.draggableConfig) == null ? void 0 : _.handle) == null ? void 0 : P.color) || "#ccc",
|
|
191
|
+
height: ((o = ($ = e == null ? void 0 : e.config.draggableConfig) == null ? void 0 : $.handle) == null ? void 0 : o.height) || "5px",
|
|
192
|
+
width: ((L = (T = e == null ? void 0 : e.config.draggableConfig) == null ? void 0 : T.handle) == null ? void 0 : L.width) || "45px",
|
|
193
|
+
radius: ((k = (B = e == null ? void 0 : e.config.draggableConfig) == null ? void 0 : B.handle) == null ? void 0 : k.radius) || "4px",
|
|
194
|
+
marginTop: ((D = (x = e == null ? void 0 : e.config.draggableConfig) == null ? void 0 : x.handle) == null ? void 0 : D.marginTop) || "10px",
|
|
195
|
+
marginBottom: ((H = (w = e == null ? void 0 : e.config.draggableConfig) == null ? void 0 : w.handle) == null ? void 0 : H.marginBottom) || "10px",
|
|
196
|
+
hoverColor: ((n = (E = e == null ? void 0 : e.config.draggableConfig) == null ? void 0 : E.handle) == null ? void 0 : n.hoverColor) || "#999",
|
|
197
|
+
activeColor: ((r = (t = e == null ? void 0 : e.config.draggableConfig) == null ? void 0 : t.handle) == null ? void 0 : r.activeColor) || "#666"
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
console.log("configToBeUsed in useModal:", y), d.value.push(y), V.value.push({
|
|
202
|
+
...e == null ? void 0 : e.props,
|
|
203
|
+
onClose: (v) => {
|
|
204
|
+
g(v), Q(
|
|
205
|
+
v,
|
|
206
|
+
d.value.length - 1
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
}), W.value.push((e == null ? void 0 : e.slots) || {}), e != null && e.config.onClosed ? z.value.push(e.config.onClosed) : z.value.push(() => {
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
), Q = (l, e) => (d.value[e] ? d.value[e].anim = !1 : d.value[d.value.length - 1].anim = !1, setTimeout(() => {
|
|
213
|
+
if (e === d.value.length - 1) {
|
|
214
|
+
const g = d.value[d.value.length - 1];
|
|
215
|
+
g ? (g.open = !1, R.value.pop(), d.value.pop(), V.value.pop(), W.value.pop()) : (d.value = [], R.value = [], V.value = [], W.value = []);
|
|
216
|
+
} else
|
|
217
|
+
d.value[e] && (d.value[e].open = !1, R.value.splice(e, 1), d.value.splice(e, 1), V.value.splice(e, 1), W.value.splice(e, 1));
|
|
218
|
+
try {
|
|
219
|
+
z.value[e] && typeof z.value[e] == "function" && (z.value[e](l), z.value.splice(e, 1));
|
|
220
|
+
} catch (g) {
|
|
221
|
+
throw console.log(g), new Error("Error in your onClosed function");
|
|
222
|
+
}
|
|
223
|
+
}, 500), l), Ue = (l) => {
|
|
224
|
+
setTimeout(() => (Oe.value = !1, R.value = [], Ye.value = "", d.value = [], V.value = [], W.value = [], l), 300);
|
|
225
|
+
}, qe = ["onClick"], Ke = /* @__PURE__ */ Le({
|
|
226
|
+
__name: "modalRoot",
|
|
227
|
+
setup(l) {
|
|
228
|
+
const e = (g, a) => {
|
|
229
|
+
Q(g, a);
|
|
230
|
+
};
|
|
231
|
+
return (g, a) => (O(), G("div", null, [
|
|
232
|
+
(O(), p(Ae, { to: "body" }, [
|
|
233
|
+
(O(!0), G(Se, null, Me(C(R), (y, c) => (O(), p(je, {
|
|
234
|
+
onClose: (u) => e(u, c),
|
|
235
|
+
key: c,
|
|
236
|
+
config: C(d)[c],
|
|
237
|
+
"modal-key-index": c
|
|
238
|
+
}, Te({
|
|
239
|
+
default: J(() => [
|
|
240
|
+
(O(), p(ke(y), Ee({
|
|
241
|
+
data: C(d),
|
|
242
|
+
onClose: (u) => C(Q)(u, c)
|
|
243
|
+
}, { ref_for: !0 }, C(V)[c], { onCloseAll: C(Ue) }), Te({ _: 2 }, [
|
|
244
|
+
Me(C(W)[c], (u, _) => ({
|
|
245
|
+
name: _,
|
|
246
|
+
fn: J(() => [
|
|
247
|
+
(O(), p(ke(Be(De(u.component))), Ee({ ref_for: !0 }, u.props), null, 16))
|
|
248
|
+
])
|
|
249
|
+
}))
|
|
250
|
+
]), 1040, ["data", "onClose", "onCloseAll"]))
|
|
251
|
+
]),
|
|
252
|
+
_: 2
|
|
253
|
+
}, [
|
|
254
|
+
C(d)[c].title ? {
|
|
255
|
+
name: "header",
|
|
256
|
+
fn: J(() => [
|
|
257
|
+
Y("h3", {
|
|
258
|
+
class: U(["__modal-header__title", C(d)[c].type == "modal" ? "__modal-header__title--standard" : "__modal-header__title--side"])
|
|
259
|
+
}, Fe(C(d)[c].title), 3),
|
|
260
|
+
Y("button", {
|
|
261
|
+
type: "button",
|
|
262
|
+
class: "__modal-header__close-btn",
|
|
263
|
+
onClick: (u) => e(u, c)
|
|
264
|
+
}, [...a[0] || (a[0] = [
|
|
265
|
+
Y("span", null, "×", -1)
|
|
266
|
+
])], 8, qe)
|
|
267
|
+
]),
|
|
268
|
+
key: "0"
|
|
269
|
+
} : void 0
|
|
270
|
+
]), 1032, ["onClose", "config", "modal-key-index"]))), 128))
|
|
271
|
+
]))
|
|
272
|
+
]));
|
|
273
|
+
}
|
|
274
|
+
}), Pe = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
275
|
+
__proto__: null,
|
|
276
|
+
ModalRoot: Ke
|
|
277
|
+
}, Symbol.toStringTag, { value: "Module" })), pe = {
|
|
278
|
+
install(l, e) {
|
|
279
|
+
console.log("Installing VueModaller plugin with options:", e);
|
|
280
|
+
for (const g in Pe)
|
|
281
|
+
l.component(g, Pe[g]);
|
|
282
|
+
}
|
|
283
|
+
}, Qe = (l) => (e) => {
|
|
284
|
+
pe.install(e, l);
|
|
285
|
+
};
|
|
286
|
+
export {
|
|
287
|
+
Ke as ModalRoot,
|
|
288
|
+
pe as VueModaller,
|
|
289
|
+
Ue as closeAllModal,
|
|
290
|
+
Q as closeModal,
|
|
291
|
+
R as compRef,
|
|
292
|
+
Qe as createPlugin,
|
|
293
|
+
pe as default,
|
|
294
|
+
Oe as modalOpen,
|
|
295
|
+
d as modalOptions,
|
|
296
|
+
V as modalProps,
|
|
297
|
+
W as modalSlots,
|
|
298
|
+
Ye as modalTitle,
|
|
299
|
+
z as onClosedFunctions,
|
|
300
|
+
Je as useModal
|
|
301
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(function(g,l){typeof exports=="object"&&typeof module<"u"?l(exports,require("vue")):typeof define=="function"&&define.amd?define(["exports","vue"],l):(g=typeof globalThis<"u"?globalThis:g||self,l(g.VueModaller={},g.Vue))})(this,function(g,l){"use strict";const _e={initialPosition:"half",hideHandle:!1,handle:{color:"#ccc",height:"5px",width:"45px",hoverColor:"#999",activeColor:"#666"}},ye=(n=_e,e)=>{const s=l.ref(!1),a=l.ref(0),w=l.ref(!1),d=l.ref(!1);let m=0,y=0,P=!1,O=0,r={full:0,half:0,closed:0},E=0,V=0,L=0,T=0;const H=l.ref(null),$=()=>{O=window.innerHeight,r={full:0,half:O*.4,closed:O},a.value=r.closed,E=r.closed},v=(u,f=300)=>new Promise(_=>{if(d.value)return _();d.value=!0;const b=a.value,k=u-b,h=performance.now(),Y=p=>{const A=p-h,F=Math.min(A/f,1),W=1-Math.pow(1-F,3);a.value=b+k*W,F<1?requestAnimationFrame(Y):(d.value=!1,E=a.value,_())};requestAnimationFrame(Y)}),z=async()=>{await v(r[n.initialPosition],400)},B=async()=>{await v(r.closed,300),e&&setTimeout(()=>e(),50)},t=u=>{var _,b;if(d.value)return;w.value=!0,P=!0;const f=u;m=f instanceof PointerEvent?f.clientY:((b=(_=f.touches)==null?void 0:_[0])==null?void 0:b.clientY)||0,T=m,L=Date.now(),document.addEventListener("pointermove",o),document.addEventListener("pointerup",c),document.addEventListener("touchmove",o,{passive:!1}),document.addEventListener("touchend",c)},o=u=>{var p,A;if(!P||d.value)return;const f=u;y=f instanceof PointerEvent?f.clientY:((A=(p=f.touches)==null?void 0:p[0])==null?void 0:A.clientY)||0;const _=y-m,b=E+_,k=Date.now(),h=y-T,Y=k-L;V=h/Y,T=y,L=k,b<r.full?a.value=r.full:b>r.closed?a.value=r.closed:a.value=b},c=async()=>{w.value=!1,P=!1,document.removeEventListener("pointermove",o),document.removeEventListener("pointerup",c),document.removeEventListener("touchmove",o),document.removeEventListener("touchend",c);const u=a.value,f=Math.abs(u-r.full),_=Math.abs(u-r.half),b=Math.abs(u-r.closed),k=Math.min(f,_,b);let h=r.half;V>.5?E===r.full?h=r.half:h=r.closed:V<-.5||k===f?h=r.full:k===_?h=r.half:h=r.closed,h===r.closed?await B():await v(h,250)},C=()=>{B()};return l.onMounted(()=>{$()}),l.onUnmounted(()=>{document.removeEventListener("pointermove",o),document.removeEventListener("pointerup",c),document.removeEventListener("touchmove",o),document.removeEventListener("touchend",c)}),{open:s,translateY:a,isDragging:w,isAnimating:d,panel:H,openPanel:z,closePanel:B,startDrag:t,handleBackdropClick:C,initPositions:$,animateToPosition:v}},we={class:"__modal-body"},ve={class:"__modal-header"},ke=l.defineComponent({__name:"modal",props:{config:Object,modalKeyIndex:Number},emits:["close"],setup(n,{emit:e}){var z,B;const s=e,a=n,w=()=>{var t;((t=a.config)==null?void 0:t.type)==="draggable"?O():s("close")},{isDragging:d,translateY:m,startDrag:y,openPanel:P,closePanel:O,isAnimating:r}=ye((z=a.config)==null?void 0:z.draggableConfig,()=>{s("close")}),E=()=>{var t,o;(t=a.config)!=null&&t.closeable&&(console.log("Modal closed from outside",(o=a.config)==null?void 0:o.closeable),w())},V=l.computed(()=>{var t,o,c;return((t=a.config)==null?void 0:t.type)=="side"?"100%":(o=a.config)!=null&&o.width?`${(c=a.config)==null?void 0:c.width}px`:"480px"}),L=l.computed(()=>{var t,o,c,C;return(t=a.config)!=null&&t.height&&a.config.type!=="draggable"?typeof((o=a.config)==null?void 0:o.height)=="number"?`${(c=a.config)==null?void 0:c.height}px`:(C=a.config)==null?void 0:C.height:"100%"});let T=l.ref({modal:{cls:"is-modal",anim_in:"zoomIn",anim_out:"zoomOut",style:`padding: ${(B=a.config)==null?void 0:B.padding}px;`},panel:{cls:"is-panel",anim_in:"slideInBottom",anim_out:"slideOutBottom",style:"padding: 0"},draggable:{cls:"is-draggable",anim_in:"",anim_out:"",style:"padding: 0"},side:{cls:"is-side",anim_in:"slideInRight",anim_out:"slideOutRight",style:"padding: 0"}});const H=l.computed(()=>{var t,o,c;return(t=a.config)!=null&&t.anim?T.value[((o=a.config)==null?void 0:o.type)||"modal"].anim_in:T.value[((c=a.config)==null?void 0:c.type)||"modal"].anim_out}),$=l.computed(()=>{var c,C,u,f;let t="__modal-wrapper--centered",o="__modal-content __modal-content--standard";return((c=a.config)==null?void 0:c.type)=="modal"?(t="__modal-wrapper--centered",o="__modal-content __modal-content--standard"):((C=a.config)==null?void 0:C.type)=="side"?(t="__modal-wrapper--side",o="__modal-content __modal-content--side"):((u=a.config)==null?void 0:u.type)=="panel"?(t="__modal-wrapper--panel",o="__modal-content __modal-content--panel"):((f=a.config)==null?void 0:f.type)=="draggable"&&(t="__modal-wrapper--draggable",o=`__modal-content __modal-content--draggable ${d.value?"__modal-content--dragging":""} ${r.value?"__modal-content--animating":""}`),{mainModalWrapperClass:t,mainModalClass:o}}),v=l.ref(!1);return l.onMounted(()=>{setTimeout(()=>{var t;v.value=!0,((t=a.config)==null?void 0:t.type)==="draggable"&&(P(),console.log("opened draggable with animation"))},100)}),(t,o)=>{var c,C,u,f,_,b,k,h,Y,p,A,F,W,X,Z,N,x,I,ee,le,ae,ne,te,oe,re,ce,de,ie,ge,fe,se,me,ue,he,be,Ce;return(c=n.config)!=null&&c.open?(l.openBlock(),l.createElementBlock("div",{key:0,class:l.normalizeClass(["__modal-wrapper",$.value.mainModalWrapperClass])},[l.createElementVNode("div",{class:l.normalizeClass(["__modal-backdrop",(C=n.config)!=null&&C.blur?"__modal-backdrop--blur":""]),onClick:E},null,2),v.value?(l.openBlock(),l.createElementBlock("div",{key:0,ref:"modalElement",class:l.normalizeClass([$.value.mainModalClass,(u=n.config)!=null&&u.background?`bg-${(f=n.config)==null?void 0:f.background}`:"__modal-content",H.value]),onPointerdown:o[0]||(o[0]=(...Be)=>l.unref(y)&&l.unref(y)(...Be)),style:l.normalizeStyle({width:V.value,maxHeight:L.value,borderRadius:`${((_=n.config)==null?void 0:_.type)!=="side"&&((b=n.config)==null?void 0:b.type)!=="panel"&&((k=n.config)==null?void 0:k.type)!=="draggable"?((h=n.config)==null?void 0:h.corner)??"0.75rem":"0"}`,marginTop:`${(Y=n.config)!=null&&Y.margin&&n.config.type=="side"?`${n.config.margin}px`:"0"}`,transform:`translateY(${l.unref(m)}px)`})},[l.createElementVNode("div",we,[l.createElementVNode("div",{class:l.normalizeClass(["__modal-drag-handle",{__hidden:((A=(p=n.config)==null?void 0:p.draggableConfig)==null?void 0:A.hideHandle)&&((F=n.config)==null?void 0:F.type)!=="draggable"}]),style:l.normalizeStyle({"--modal-draggable-handle-color":(Z=(X=(W=n.config)==null?void 0:W.draggableConfig)==null?void 0:X.handle)==null?void 0:Z.color,"--modal-draggable-handle-hover-color":(I=(x=(N=n.config)==null?void 0:N.draggableConfig)==null?void 0:x.handle)==null?void 0:I.hoverColor,"--modal-draggable-handle-active-color":(ae=(le=(ee=n.config)==null?void 0:ee.draggableConfig)==null?void 0:le.handle)==null?void 0:ae.activeColor,"--modal-draggable-handle-height":((oe=(te=(ne=n.config)==null?void 0:ne.draggableConfig)==null?void 0:te.handle)==null?void 0:oe.height)||"5px","--modal-draggable-handle-width":((de=(ce=(re=n.config)==null?void 0:re.draggableConfig)==null?void 0:ce.handle)==null?void 0:de.width)||"45px","--modal-draggable-handle-radius":((fe=(ge=(ie=n.config)==null?void 0:ie.draggableConfig)==null?void 0:ge.handle)==null?void 0:fe.radius)||"4px","--modal-draggable-handle-margin-top":((ue=(me=(se=n.config)==null?void 0:se.draggableConfig)==null?void 0:me.handle)==null?void 0:ue.marginTop)||"10px","--modal-draggable-handle-margin-bottom":((Ce=(be=(he=n.config)==null?void 0:he.draggableConfig)==null?void 0:be.handle)==null?void 0:Ce.marginBottom)||"10px"})},null,6),l.createElementVNode("div",ve,[l.renderSlot(t.$slots,"header")]),l.createElementVNode("div",null,[l.renderSlot(t.$slots,"default")])])],38)):l.createCommentVNode("",!0)],2)):l.createCommentVNode("",!0)}}}),q=l.ref(!1),M=l.ref([]),D=l.ref([]),U=l.ref(""),i=l.ref([]),S=l.ref([]),R=l.ref([]),Me=(n,e)=>new Promise(s=>{var d,m,y,P,O,r,E,V,L,T,H,$,v,z,B,t,o,c;q.value=!0;const a=l.markRaw(l.toRaw(n));M.value.length>0?M.value.push(a):M.value=[a],U.value=(e==null?void 0:e.title)||"";const w={width:(e==null?void 0:e.config.width)||450,background:(e==null?void 0:e.config.background)||"white",padding:(e==null?void 0:e.config.padding)||"20px",closeable:(e==null?void 0:e.config.closeable)??!0,blur:(e==null?void 0:e.config.blur)??!0,corner:(e==null?void 0:e.config.corner)??"10px",type:(e==null?void 0:e.config.type)||"modal",open:!0,anim:!0,title:(e==null?void 0:e.config.title)||"",margin:(e==null?void 0:e.config.margin)||0,height:(e==null?void 0:e.config.height)||0,mobileType:(e==null?void 0:e.config.mobileType)||"modal",draggableConfig:{initialPosition:((d=e==null?void 0:e.config.draggableConfig)==null?void 0:d.initialPosition)||"half",hideHandle:((m=e==null?void 0:e.config.draggableConfig)==null?void 0:m.hideHandle)||!1,handle:{color:((P=(y=e==null?void 0:e.config.draggableConfig)==null?void 0:y.handle)==null?void 0:P.color)||"#ccc",height:((r=(O=e==null?void 0:e.config.draggableConfig)==null?void 0:O.handle)==null?void 0:r.height)||"5px",width:((V=(E=e==null?void 0:e.config.draggableConfig)==null?void 0:E.handle)==null?void 0:V.width)||"45px",radius:((T=(L=e==null?void 0:e.config.draggableConfig)==null?void 0:L.handle)==null?void 0:T.radius)||"4px",marginTop:(($=(H=e==null?void 0:e.config.draggableConfig)==null?void 0:H.handle)==null?void 0:$.marginTop)||"10px",marginBottom:((z=(v=e==null?void 0:e.config.draggableConfig)==null?void 0:v.handle)==null?void 0:z.marginBottom)||"10px",hoverColor:((t=(B=e==null?void 0:e.config.draggableConfig)==null?void 0:B.handle)==null?void 0:t.hoverColor)||"#999",activeColor:((c=(o=e==null?void 0:e.config.draggableConfig)==null?void 0:o.handle)==null?void 0:c.activeColor)||"#666"}}};console.log("configToBeUsed in useModal:",w),i.value.push(w),S.value.push({...e==null?void 0:e.props,onClose:C=>{s(C),j(C,i.value.length-1)}}),R.value.push((e==null?void 0:e.slots)||{}),e!=null&&e.config.onClosed?D.value.push(e.config.onClosed):D.value.push(()=>{})}),j=(n,e)=>(i.value[e]?i.value[e].anim=!1:i.value[i.value.length-1].anim=!1,setTimeout(()=>{if(e===i.value.length-1){const s=i.value[i.value.length-1];s?(s.open=!1,M.value.pop(),i.value.pop(),S.value.pop(),R.value.pop()):(i.value=[],M.value=[],S.value=[],R.value=[])}else i.value[e]&&(i.value[e].open=!1,M.value.splice(e,1),i.value.splice(e,1),S.value.splice(e,1),R.value.splice(e,1));try{D.value[e]&&typeof D.value[e]=="function"&&(D.value[e](n),D.value.splice(e,1))}catch(s){throw console.log(s),new Error("Error in your onClosed function")}},500),n),G=n=>{setTimeout(()=>(q.value=!1,M.value=[],U.value="",i.value=[],S.value=[],R.value=[],n),300)},Ee=["onClick"],J=l.defineComponent({__name:"modalRoot",setup(n){const e=(s,a)=>{j(s,a)};return(s,a)=>(l.openBlock(),l.createElementBlock("div",null,[(l.openBlock(),l.createBlock(l.Teleport,{to:"body"},[(l.openBlock(!0),l.createElementBlock(l.Fragment,null,l.renderList(l.unref(M),(w,d)=>(l.openBlock(),l.createBlock(ke,{onClose:m=>e(m,d),key:d,config:l.unref(i)[d],"modal-key-index":d},l.createSlots({default:l.withCtx(()=>[(l.openBlock(),l.createBlock(l.resolveDynamicComponent(w),l.mergeProps({data:l.unref(i),onClose:m=>l.unref(j)(m,d)},{ref_for:!0},l.unref(S)[d],{onCloseAll:l.unref(G)}),l.createSlots({_:2},[l.renderList(l.unref(R)[d],(m,y)=>({name:y,fn:l.withCtx(()=>[(l.openBlock(),l.createBlock(l.resolveDynamicComponent(l.markRaw(l.toRaw(m.component))),l.mergeProps({ref_for:!0},m.props),null,16))])}))]),1040,["data","onClose","onCloseAll"]))]),_:2},[l.unref(i)[d].title?{name:"header",fn:l.withCtx(()=>[l.createElementVNode("h3",{class:l.normalizeClass(["__modal-header__title",l.unref(i)[d].type=="modal"?"__modal-header__title--standard":"__modal-header__title--side"])},l.toDisplayString(l.unref(i)[d].title),3),l.createElementVNode("button",{type:"button",class:"__modal-header__close-btn",onClick:m=>e(m,d)},[...a[0]||(a[0]=[l.createElementVNode("span",null,"×",-1)])],8,Ee)]),key:"0"}:void 0]),1032,["onClose","config","modal-key-index"]))),128))]))]))}}),Q=Object.freeze(Object.defineProperty({__proto__:null,ModalRoot:J},Symbol.toStringTag,{value:"Module"})),K={install(n,e){console.log("Installing VueModaller plugin with options:",e);for(const s in Q)n.component(s,Q[s])}},Te=n=>e=>{K.install(e,n)};g.ModalRoot=J,g.VueModaller=K,g.closeAllModal=G,g.closeModal=j,g.compRef=M,g.createPlugin=Te,g.default=K,g.modalOpen=q,g.modalOptions=i,g.modalProps=S,g.modalSlots=R,g.modalTitle=U,g.onClosedFunctions=D,g.useModal=Me,Object.defineProperties(g,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
|
package/package.json
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "vue-modaller",
|
|
3
|
+
"author": "Classydev (https://github.com/classyrazy)",
|
|
4
|
+
"version": "1.0.0",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"description": "A flexible and powerful modal system for Vue 3 applications with TypeScript support, featuring draggable modals, side panels, and smooth animations",
|
|
7
|
+
"private": false,
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/classyrazy/vue-modaller.git"
|
|
11
|
+
},
|
|
12
|
+
"type": "module",
|
|
13
|
+
"contributors": [
|
|
14
|
+
{
|
|
15
|
+
"name": "Classydev",
|
|
16
|
+
"email": "o.abdulrazaq.a@gmail.com"
|
|
17
|
+
}
|
|
18
|
+
],
|
|
19
|
+
"keywords": [
|
|
20
|
+
"vue",
|
|
21
|
+
"vue3",
|
|
22
|
+
"modal",
|
|
23
|
+
"dialog",
|
|
24
|
+
"popup",
|
|
25
|
+
"overlay",
|
|
26
|
+
"draggable",
|
|
27
|
+
"side-panel",
|
|
28
|
+
"typescript",
|
|
29
|
+
"composable",
|
|
30
|
+
"plugin",
|
|
31
|
+
"animations",
|
|
32
|
+
"instagram-style",
|
|
33
|
+
"draggable-modals",
|
|
34
|
+
"vue-modals",
|
|
35
|
+
"vue-dialogs",
|
|
36
|
+
"vue-popups",
|
|
37
|
+
"vue-overlays",
|
|
38
|
+
"vue-modaller"
|
|
39
|
+
],
|
|
40
|
+
"homepage": "https://classyrazy.github.io/vue-modaller/",
|
|
41
|
+
"bugs": {
|
|
42
|
+
"url": "https://github.com/classyrazy/vue-modaller/issues"
|
|
43
|
+
},
|
|
44
|
+
"files": [
|
|
45
|
+
"dist"
|
|
46
|
+
],
|
|
47
|
+
"main": "./dist/vue-modaller.umd.cjs",
|
|
48
|
+
"module": "./dist/vue-modaller.js",
|
|
49
|
+
"exports": {
|
|
50
|
+
".": {
|
|
51
|
+
"import": "./dist/vue-modaller.js",
|
|
52
|
+
"require": "./dist/vue-modaller.umd.cjs",
|
|
53
|
+
"types": "./dist/index.d.ts"
|
|
54
|
+
},
|
|
55
|
+
"./style.css": "./dist/style.css"
|
|
56
|
+
},
|
|
57
|
+
"types": "./dist/index.d.ts",
|
|
58
|
+
"scripts": {
|
|
59
|
+
"dev": "vite",
|
|
60
|
+
"build": "npm run test && vite build --mode production && npm run generate:types && npm run build:pages",
|
|
61
|
+
"build:lib": "npm run test && vite build --mode production && npm run generate:types",
|
|
62
|
+
"clean": "rm -rf ./dist && rm -rf ./live-demo && rm -rf ./coverage",
|
|
63
|
+
"coverage:web": "http-server ./coverage",
|
|
64
|
+
"generate:types": "vue-tsc -p tsconfig-build.json --declaration --emitDeclarationOnly true --outdir ./dist",
|
|
65
|
+
"changeset": "changeset",
|
|
66
|
+
"test": "vitest run",
|
|
67
|
+
"test:watch": "vitest",
|
|
68
|
+
"test:coverage": "vitest run --coverage",
|
|
69
|
+
"build:pages": "npm run docs:build && npm run build:live-demo",
|
|
70
|
+
"build:live-demo": "vite build --mode live-demo --outDir ./docs/.vitepress/dist/live-demo",
|
|
71
|
+
"docs:dev": "vitepress dev docs",
|
|
72
|
+
"docs:build": "vitepress build docs",
|
|
73
|
+
"docs:preview": "vitepress preview docs"
|
|
74
|
+
},
|
|
75
|
+
"dependencies": {
|
|
76
|
+
"@tailwindcss/vite": "^4.1.16",
|
|
77
|
+
"@vitejs/plugin-vue": "^4.5.0",
|
|
78
|
+
"vue": "^3.3.8"
|
|
79
|
+
},
|
|
80
|
+
"devDependencies": {
|
|
81
|
+
"@changesets/cli": "^2.26.2",
|
|
82
|
+
"@types/node": "^20.9.4",
|
|
83
|
+
"@vitest/coverage-v8": "^0.34.6",
|
|
84
|
+
"tailwindcss": "^4.1.16",
|
|
85
|
+
"typescript": "^5.2.2",
|
|
86
|
+
"vite": "^5.0.0",
|
|
87
|
+
"vitepress": "^1.0.0-rc.24",
|
|
88
|
+
"vitest": "^0.34.6",
|
|
89
|
+
"vue-tsc": "^1.8.22"
|
|
90
|
+
}
|
|
91
|
+
}
|