@cloudron/pankow 4.3.4 → 4.3.5
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/components/Button.vue +7 -0
- package/components/CheckBox.vue +4 -1
- package/index.js +2 -0
- package/package.json +6 -6
- package/plugin.js +2 -0
- package/style.css +31 -0
- package/text-overflow.js +120 -0
- package/types/index.d.ts +2 -1
- package/types/text-overflow.d.ts +19 -0
package/components/Button.vue
CHANGED
|
@@ -77,6 +77,7 @@ function onClick(event) {
|
|
|
77
77
|
align-items: center;
|
|
78
78
|
justify-content: center;
|
|
79
79
|
display: inline-flex;
|
|
80
|
+
line-height: 1.2;
|
|
80
81
|
cursor: pointer;
|
|
81
82
|
border: 1px solid transparent;
|
|
82
83
|
transition: background 250ms, border-color 250ms;
|
|
@@ -101,6 +102,12 @@ a.pankow-button:visited {
|
|
|
101
102
|
margin-right: 7px;
|
|
102
103
|
}
|
|
103
104
|
|
|
105
|
+
.pankow-button [class^="fa-"],
|
|
106
|
+
.pankow-button [class*=" fa-"],
|
|
107
|
+
.pankow-button .fa {
|
|
108
|
+
line-height: inherit;
|
|
109
|
+
}
|
|
110
|
+
|
|
104
111
|
.pankow-button-icon-right-with-text {
|
|
105
112
|
padding-left: 7px;
|
|
106
113
|
}
|
package/components/CheckBox.vue
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
|
|
3
3
|
import { uuidv4 } from '../utils.js';
|
|
4
|
+
import textOverflow from '../text-overflow.js';
|
|
4
5
|
|
|
5
6
|
const props = defineProps({
|
|
6
7
|
label: String,
|
|
@@ -13,13 +14,15 @@ const model = defineModel({ type: Boolean });
|
|
|
13
14
|
|
|
14
15
|
const internalId = uuidv4();
|
|
15
16
|
|
|
17
|
+
const vTextOverflow = textOverflow;
|
|
18
|
+
|
|
16
19
|
</script>
|
|
17
20
|
|
|
18
21
|
<template>
|
|
19
22
|
<span class="pankow-checkbox">
|
|
20
23
|
<input :id="id || internalId" class="pankow-checkbox-input" type="checkbox" v-model="model" :disabled="disabled" :required="$attrs['required']" @input="$emit('update:modelValue', $event.target.checked)"/>
|
|
21
24
|
<slot>
|
|
22
|
-
<label :for="id || internalId" class="pankow-checkbox-input-label">
|
|
25
|
+
<label :for="id || internalId" class="pankow-checkbox-input-label" v-text-overflow>
|
|
23
26
|
{{ label }}
|
|
24
27
|
<sup v-if="helpUrl"><a :href="helpUrl" target="_blank" tabindex="-1"><i class="fa fa-question-circle"></i></a></sup>
|
|
25
28
|
</label>
|
package/index.js
CHANGED
|
@@ -59,6 +59,7 @@ import gestures from './gestures.js';
|
|
|
59
59
|
import utils from './utils.js';
|
|
60
60
|
import tooltip from './tooltip.js';
|
|
61
61
|
import fallbackImage from './fallbackImage.js';
|
|
62
|
+
import textOverflow from './text-overflow.js';
|
|
62
63
|
|
|
63
64
|
export {
|
|
64
65
|
BottomBar,
|
|
@@ -111,6 +112,7 @@ export {
|
|
|
111
112
|
gestures,
|
|
112
113
|
tooltip,
|
|
113
114
|
fallbackImage,
|
|
115
|
+
textOverflow,
|
|
114
116
|
utils,
|
|
115
117
|
};
|
|
116
118
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cloudron/pankow",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "4.3.
|
|
4
|
+
"version": "4.3.5",
|
|
5
5
|
"description": "Vue 3 UI component library for Cloudron apps",
|
|
6
6
|
"main": "index.js",
|
|
7
7
|
"types": "types/index.d.ts",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"license": "ISC",
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"@fontsource/inter": "^5.2.8",
|
|
41
|
-
"@fortawesome/fontawesome-free": "^7.3.
|
|
41
|
+
"@fortawesome/fontawesome-free": "^7.3.1",
|
|
42
42
|
"filesize": "^11.0.22",
|
|
43
43
|
"monaco-editor": "^0.55.1",
|
|
44
44
|
"online-3d-viewer": "^0.18.0"
|
|
@@ -48,13 +48,13 @@
|
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
50
|
"@highlightjs/vue-plugin": "^2.1.0",
|
|
51
|
-
"@unhead/vue": "^
|
|
51
|
+
"@unhead/vue": "^3.1.8",
|
|
52
52
|
"@vitejs/plugin-vue": "^6.0.8",
|
|
53
53
|
"highlight.js": "^11.11.1",
|
|
54
54
|
"typescript": "^7.0.2",
|
|
55
|
-
"vite": "^8.1.
|
|
55
|
+
"vite": "^8.1.5",
|
|
56
56
|
"vite-ssg": "^28.3.0",
|
|
57
|
-
"vue": "^3.5.
|
|
58
|
-
"vue-router": "^5.
|
|
57
|
+
"vue": "^3.5.40",
|
|
58
|
+
"vue-router": "^5.2.0"
|
|
59
59
|
}
|
|
60
60
|
}
|
package/plugin.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createApp } from 'vue';
|
|
2
2
|
import tooltip from './tooltip.js';
|
|
3
3
|
import fallbackImage from './fallbackImage.js';
|
|
4
|
+
import textOverflow from './text-overflow.js';
|
|
4
5
|
import fetcher from './fetcher.js';
|
|
5
6
|
import { setNotifyPosition } from './notifyState.js';
|
|
6
7
|
import Notification from './components/Notification.vue';
|
|
@@ -11,6 +12,7 @@ export default {
|
|
|
11
12
|
install(app, options = {}) {
|
|
12
13
|
app.directive('tooltip', tooltip);
|
|
13
14
|
app.directive('fallback-image', fallbackImage);
|
|
15
|
+
app.directive('text-overflow', textOverflow);
|
|
14
16
|
|
|
15
17
|
if (options.fetcher) {
|
|
16
18
|
if (options.fetcher.credentials !== undefined) {
|
package/style.css
CHANGED
|
@@ -34,6 +34,8 @@
|
|
|
34
34
|
--pankow-tooltip-background-color: #333;
|
|
35
35
|
--pankow-tooltip-text-color: white;
|
|
36
36
|
|
|
37
|
+
--pankow-color-border: #ddd;
|
|
38
|
+
|
|
37
39
|
--pankow-color-primary: #1a76bf;
|
|
38
40
|
--pankow-color-primary-hover: #0d89ec;
|
|
39
41
|
--pankow-color-primary-active: #0b7ad1;
|
|
@@ -111,6 +113,8 @@ input {
|
|
|
111
113
|
--pankow-color-background: #1b1e21;
|
|
112
114
|
--pankow-color-background-hover: #1f2326;
|
|
113
115
|
|
|
116
|
+
--pankow-color-border: #495057;
|
|
117
|
+
|
|
114
118
|
--pankow-dialog-background-color: #32383e;
|
|
115
119
|
--pankow-dialog-backdrop-color: rgba(0,0,0,.7);
|
|
116
120
|
}
|
|
@@ -211,6 +215,33 @@ textarea[disabled]:hover {
|
|
|
211
215
|
text-align: center;
|
|
212
216
|
}
|
|
213
217
|
|
|
218
|
+
.pankow-text-overflow-tooltip {
|
|
219
|
+
position: fixed;
|
|
220
|
+
background: var(--pankow-color-background);
|
|
221
|
+
border: 1px solid var(--pankow-color-border);
|
|
222
|
+
border-radius: var(--pankow-border-radius);
|
|
223
|
+
padding: 8px 12px;
|
|
224
|
+
font-size: 13px;
|
|
225
|
+
z-index: 10000;
|
|
226
|
+
max-width: 400px;
|
|
227
|
+
white-space: normal;
|
|
228
|
+
word-break: break-word;
|
|
229
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
|
230
|
+
pointer-events: none;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
@media (prefers-color-scheme: dark) {
|
|
234
|
+
.pankow-text-overflow-tooltip {
|
|
235
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
@media (hover: none) and (pointer: coarse) {
|
|
240
|
+
.pankow-text-overflow-tooltip {
|
|
241
|
+
display: none !important;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
214
245
|
.has-error {
|
|
215
246
|
color: var(--pankow-color-danger);
|
|
216
247
|
}
|
package/text-overflow.js
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TextOverflow Directive
|
|
3
|
+
*
|
|
4
|
+
* Shows a cursor-following tooltip overlay only when the element's text content
|
|
5
|
+
* is actually clipped (scrollWidth > clientWidth).
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* ```
|
|
9
|
+
* import textOverflow from 'pankow/text-overflow';
|
|
10
|
+
* app.directive('text-overflow', textOverflow);
|
|
11
|
+
* // <div v-text-overflow>{{ longText }}</div>
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
const tooltips = {};
|
|
16
|
+
let id = 0;
|
|
17
|
+
|
|
18
|
+
function createOverlay() {
|
|
19
|
+
const el = document.createElement('div');
|
|
20
|
+
el.classList.add('pankow-text-overflow-tooltip');
|
|
21
|
+
el.style.display = 'none';
|
|
22
|
+
document.body.appendChild(el);
|
|
23
|
+
return el;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function isOverflowing(el) {
|
|
27
|
+
return el.scrollWidth > el.clientWidth;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Vue directive `mounted` hook.
|
|
32
|
+
* @param {HTMLElement} el
|
|
33
|
+
* @param {import('vue').DirectiveBinding} binding
|
|
34
|
+
* @param {import('vue').VNode} vnode
|
|
35
|
+
*/
|
|
36
|
+
function mounted(el, binding, vnode) {
|
|
37
|
+
el.__pankow_to_id = id++;
|
|
38
|
+
|
|
39
|
+
tooltips[el.__pankow_to_id] = {
|
|
40
|
+
overlay: null,
|
|
41
|
+
text: el.textContent || '',
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
el.addEventListener('mouseenter', onMouseEnter);
|
|
45
|
+
el.addEventListener('mouseleave', onMouseLeave);
|
|
46
|
+
el.addEventListener('mousemove', onMouseMove);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Vue directive `updated` hook.
|
|
51
|
+
* @param {HTMLElement} el
|
|
52
|
+
* @param {import('vue').DirectiveBinding} binding
|
|
53
|
+
* @param {import('vue').VNode} vnode
|
|
54
|
+
*/
|
|
55
|
+
function updated(el, binding, vnode) {
|
|
56
|
+
const state = tooltips[el.__pankow_to_id];
|
|
57
|
+
if (state) state.text = el.textContent || '';
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Vue directive `beforeUnmount` hook.
|
|
62
|
+
* @param {HTMLElement} el
|
|
63
|
+
* @param {import('vue').DirectiveBinding} binding
|
|
64
|
+
* @param {import('vue').VNode} vnode
|
|
65
|
+
*/
|
|
66
|
+
function beforeUnmount(el, binding, vnode) {
|
|
67
|
+
el.removeEventListener('mouseenter', onMouseEnter);
|
|
68
|
+
el.removeEventListener('mouseleave', onMouseLeave);
|
|
69
|
+
el.removeEventListener('mousemove', onMouseMove);
|
|
70
|
+
|
|
71
|
+
const state = tooltips[el.__pankow_to_id];
|
|
72
|
+
if (state) {
|
|
73
|
+
if (state.overlay) state.overlay.remove();
|
|
74
|
+
delete tooltips[el.__pankow_to_id];
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function onMouseEnter(event) {
|
|
79
|
+
const el = event.currentTarget;
|
|
80
|
+
if (!isOverflowing(el)) return;
|
|
81
|
+
|
|
82
|
+
const state = tooltips[el.__pankow_to_id];
|
|
83
|
+
if (!state) return;
|
|
84
|
+
|
|
85
|
+
if (!state.overlay) state.overlay = createOverlay();
|
|
86
|
+
state.overlay.textContent = state.text;
|
|
87
|
+
state.overlay.style.display = 'block';
|
|
88
|
+
updatePosition(event, state);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function onMouseLeave(event) {
|
|
92
|
+
const el = event.currentTarget;
|
|
93
|
+
const state = tooltips[el.__pankow_to_id];
|
|
94
|
+
if (!state || !state.overlay) return;
|
|
95
|
+
state.overlay.style.display = 'none';
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function onMouseMove(event) {
|
|
99
|
+
const el = event.currentTarget;
|
|
100
|
+
const state = tooltips[el.__pankow_to_id];
|
|
101
|
+
updatePosition(event, state);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function updatePosition(event, state) {
|
|
105
|
+
if (!state || !state.overlay) return;
|
|
106
|
+
state.overlay.style.left = (event.clientX + 10) + 'px';
|
|
107
|
+
state.overlay.style.top = (event.clientY + 20) + 'px';
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Vue directive for text-overflow tooltips. Register via `app.directive('text-overflow', textOverflow)`.
|
|
112
|
+
* @type {import('vue').Directive}
|
|
113
|
+
*/
|
|
114
|
+
const textOverflow = {
|
|
115
|
+
mounted,
|
|
116
|
+
updated,
|
|
117
|
+
beforeUnmount
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
export default textOverflow;
|
package/types/index.d.ts
CHANGED
|
@@ -53,7 +53,8 @@ import gestures from './gestures.js';
|
|
|
53
53
|
import utils from './utils.js';
|
|
54
54
|
import tooltip from './tooltip.js';
|
|
55
55
|
import fallbackImage from './fallbackImage.js';
|
|
56
|
-
|
|
56
|
+
import textOverflow from './text-overflow.js';
|
|
57
|
+
export { BottomBar, BreadCrumb, Button, ButtonGroup, ClipboardAction, ClipboardButton, CheckBox, DateTimeInput, Dialog, DirectoryView, EmailInput, FileUploader, FormGroup, InputGroup, Icon, ListItem, InputDialog, LoginView, MainLayout, MaskedInput, Menu, MenuItem, SingleSelect, MultiSelect, Notification, NumberInput, OfflineBanner, PasswordInput, Popover, ProgressBar, RadioButton, SaveIndicator, SectionItem, SideBar, SplitLayout, Spinner, Switch, TableView, TableViewActionBar, TabView, TagInput, TextInput, TextInputRaw, TopBar, TreeView, fetcher, gestures, tooltip, fallbackImage, textOverflow, utils, };
|
|
57
58
|
export { CheckBox as Checkbox };
|
|
58
59
|
export { RadioButton as Radiobutton };
|
|
59
60
|
export { BreadCrumb as Breadcrumb };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TextOverflow Directive
|
|
3
|
+
*
|
|
4
|
+
* Shows a cursor-following tooltip overlay only when the element's text content
|
|
5
|
+
* is actually clipped (scrollWidth > clientWidth).
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* ```
|
|
9
|
+
* import textOverflow from 'pankow/text-overflow';
|
|
10
|
+
* app.directive('text-overflow', textOverflow);
|
|
11
|
+
* // <div v-text-overflow>{{ longText }}</div>
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Vue directive for text-overflow tooltips. Register via `app.directive('text-overflow', textOverflow)`.
|
|
16
|
+
* @type {import('vue').Directive}
|
|
17
|
+
*/
|
|
18
|
+
declare const textOverflow: import('vue').Directive;
|
|
19
|
+
export default textOverflow;
|