@exakt/ui 0.0.12 → 0.0.14
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/dist/module.json +1 -1
- package/dist/runtime/components/e/chat-bubble.vue +200 -0
- package/dist/runtime/components/e/chat-renderer.vue +85 -0
- package/dist/runtime/components/e/dropdown.vue +32 -16
- package/dist/runtime/components/e/iconButton.vue +2 -1
- package/dist/runtime/components/e/input/text.vue +3 -1
- package/dist/runtime/css/util.scss +17 -1
- package/dist/runtime/plugin.mjs +11 -0
- package/package.json +4 -3
package/dist/module.json
CHANGED
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div
|
|
3
|
+
class="bubble"
|
|
4
|
+
:class="bubbleClasses"
|
|
5
|
+
>
|
|
6
|
+
<div
|
|
7
|
+
class="content"
|
|
8
|
+
:style="{textAlign}"
|
|
9
|
+
>
|
|
10
|
+
<slot />
|
|
11
|
+
</div>
|
|
12
|
+
<div
|
|
13
|
+
v-if="!hideStatus"
|
|
14
|
+
class="status text-secondary"
|
|
15
|
+
>
|
|
16
|
+
<slot name="status" />
|
|
17
|
+
</div>
|
|
18
|
+
</div>
|
|
19
|
+
</template>
|
|
20
|
+
<script lang="ts" setup>
|
|
21
|
+
import { computed } from "#imports";
|
|
22
|
+
// Define props for the position and color of the bubble
|
|
23
|
+
const props = withDefaults(
|
|
24
|
+
defineProps<{
|
|
25
|
+
posx?:
|
|
26
|
+
"left" | "right" | "center";
|
|
27
|
+
posy?: "top" | "bottom";
|
|
28
|
+
textAlign?: "left" | "right" | "center";
|
|
29
|
+
color?: string;
|
|
30
|
+
liveTyping?: boolean;
|
|
31
|
+
pointer?: boolean;
|
|
32
|
+
hideStatus?: boolean;
|
|
33
|
+
}>(),
|
|
34
|
+
{
|
|
35
|
+
posx: "left",
|
|
36
|
+
posy: "bottom",
|
|
37
|
+
color: "turquoise",
|
|
38
|
+
liveTyping: false,
|
|
39
|
+
pointer: true
|
|
40
|
+
}
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
const bubbleClasses = computed(() => {
|
|
44
|
+
const classes = [props.posx, props.posy];
|
|
45
|
+
if (props.liveTyping) {
|
|
46
|
+
classes.push("live-typing");
|
|
47
|
+
}
|
|
48
|
+
if (props.pointer === false) {
|
|
49
|
+
classes.push("no-pointer");
|
|
50
|
+
}
|
|
51
|
+
return classes;
|
|
52
|
+
});
|
|
53
|
+
</script>
|
|
54
|
+
|
|
55
|
+
<style scoped lang="scss">
|
|
56
|
+
$bottom-triangle-height: 0.3rem;
|
|
57
|
+
|
|
58
|
+
.bubble {
|
|
59
|
+
--current-color: var(--e-color-elev);
|
|
60
|
+
--text-color: var(--e-color-dark);
|
|
61
|
+
position: relative;
|
|
62
|
+
font-family: sans-serif;
|
|
63
|
+
width: fit-content;
|
|
64
|
+
min-width: 0;
|
|
65
|
+
overflow-wrap: break-word;
|
|
66
|
+
padding: var(--e-core-padding-x);
|
|
67
|
+
background: var(--current-color);
|
|
68
|
+
//outline: 0.07rem solid var(--e-color-elev-2);
|
|
69
|
+
|
|
70
|
+
border-radius: 1rem;
|
|
71
|
+
color: rgb(var(--text-color));
|
|
72
|
+
margin-top: 0px;
|
|
73
|
+
max-width: 50%;
|
|
74
|
+
min-width: 10rem;
|
|
75
|
+
transition: transform 0.15s ease-in-out;
|
|
76
|
+
|
|
77
|
+
&:active {
|
|
78
|
+
transform: scale(0.95);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.overline {
|
|
82
|
+
font-weight: bold;
|
|
83
|
+
text-align: left;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.status {
|
|
87
|
+
text-align: right;
|
|
88
|
+
margin-top: 0.5rem;
|
|
89
|
+
display: flex;
|
|
90
|
+
justify-content: flex-end;
|
|
91
|
+
align-items: center;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
&:before {
|
|
95
|
+
content: "";
|
|
96
|
+
width: 0px;
|
|
97
|
+
height: 0px;
|
|
98
|
+
position: absolute;
|
|
99
|
+
animation: anim2 2s ease-in-out infinite;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
&.no-pointer {
|
|
103
|
+
&:before {
|
|
104
|
+
display: none;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
margin-bottom: 0.5rem !important;
|
|
108
|
+
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
&.right {
|
|
112
|
+
&:before {
|
|
113
|
+
left: unset;
|
|
114
|
+
right: calc($bottom-triangle-height * 2);
|
|
115
|
+
border-right: calc($bottom-triangle-height * 2) solid var(--current-color);
|
|
116
|
+
border-left: $bottom-triangle-height solid transparent;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
align-self: flex-end;
|
|
120
|
+
animation: enter-right 0.3s ease-in-out;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
&.center{
|
|
124
|
+
align-self: center;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
&.left {
|
|
128
|
+
&:before {
|
|
129
|
+
left: calc($bottom-triangle-height * 2);
|
|
130
|
+
border-left: calc($bottom-triangle-height * 2) solid var(--current-color);
|
|
131
|
+
border-right: $bottom-triangle-height solid transparent;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
animation: enter-left 0.3s ease-in-out;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
&.live-typing {
|
|
138
|
+
.content {
|
|
139
|
+
animation: live-typing 5s linear infinite;
|
|
140
|
+
background-clip: text;
|
|
141
|
+
background: linear-gradient(to right,
|
|
142
|
+
rgba(var(--text-color), 1) 20%,
|
|
143
|
+
rgba(var(--text-color), 0.5) 40%,
|
|
144
|
+
rgba(var(--text-color), 0.5) 60%,
|
|
145
|
+
rgba(var(--text-color), 1) 80%);
|
|
146
|
+
-webkit-background-clip: text;
|
|
147
|
+
|
|
148
|
+
background-size: 200% auto;
|
|
149
|
+
color: transparent;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
.bottom {
|
|
155
|
+
margin-bottom: $bottom-triangle-height * 4;
|
|
156
|
+
|
|
157
|
+
&:before {
|
|
158
|
+
border-top: $bottom-triangle-height solid var(--current-color);
|
|
159
|
+
border-bottom: calc($bottom-triangle-height * 2) solid transparent;
|
|
160
|
+
left: calc($bottom-triangle-height * 2);
|
|
161
|
+
bottom: calc(-2.5 * $bottom-triangle-height);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
.top {
|
|
166
|
+
margin-top: $bottom-triangle-height * 4;
|
|
167
|
+
|
|
168
|
+
&:before {
|
|
169
|
+
top: calc(-2.5 * $bottom-triangle-height);
|
|
170
|
+
border-bottom: $bottom-triangle-height solid var(--current-color);
|
|
171
|
+
border-top: calc($bottom-triangle-height * 2) solid transparent;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
@keyframes enter-left {
|
|
176
|
+
from {
|
|
177
|
+
transform: scale(0.8) translateX(-30%) translateY(20%);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
to {
|
|
181
|
+
transform: scale(1) translateX(0%) translateY(0%);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
@keyframes enter-right {
|
|
186
|
+
from {
|
|
187
|
+
transform: scale(0.8) translateX(30%) translateY(20%);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
to {
|
|
191
|
+
transform: scale(1) translateX(0%) translateY(0%);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
@keyframes live-typing {
|
|
196
|
+
to {
|
|
197
|
+
background-position: -200% center;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
</style>
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="d-flex flex-column">
|
|
3
|
+
<e-dropdown
|
|
4
|
+
:items="items"
|
|
5
|
+
width="13rem"
|
|
6
|
+
:visible="status.dropdown.visible"
|
|
7
|
+
fixed
|
|
8
|
+
:position="{ x: status.dropdown.x, y: status.dropdown.y }"
|
|
9
|
+
@update:visible="status.dropdown.visible = $event"
|
|
10
|
+
/>
|
|
11
|
+
|
|
12
|
+
<slot
|
|
13
|
+
v-for="m in computedMessages"
|
|
14
|
+
:key="m.id"
|
|
15
|
+
v-bind="m"
|
|
16
|
+
:name="(m.status === 'system') ? 'system' : 'default'"
|
|
17
|
+
@click.right.prevent="openDropdown"
|
|
18
|
+
/>
|
|
19
|
+
</div>
|
|
20
|
+
</template>
|
|
21
|
+
<script setup lang="ts">
|
|
22
|
+
import { mdiDelete, mdiFlag, mdiMinusCircle } from "@mdi/js";
|
|
23
|
+
import { reactive, computed } from "#imports";
|
|
24
|
+
|
|
25
|
+
const status = reactive({ dropdown: { visible: false, x: 0, y: 0 } });
|
|
26
|
+
const items = [{ icon: mdiDelete, name: "Delete" }, { icon: mdiMinusCircle, name: "Delete just for me" }, { icon: mdiFlag, name: "Dox" }];
|
|
27
|
+
|
|
28
|
+
const openDropdown = ({ clientX, clientY }: MouseEvent) => {
|
|
29
|
+
status.dropdown.visible = true;
|
|
30
|
+
status.dropdown.x = clientX;
|
|
31
|
+
status.dropdown.y = clientY;
|
|
32
|
+
|
|
33
|
+
}
|
|
34
|
+
type MessageArray = {
|
|
35
|
+
liveTyping?: boolean;
|
|
36
|
+
pointer?: boolean;
|
|
37
|
+
id: string;
|
|
38
|
+
text: string;
|
|
39
|
+
date?: Date;
|
|
40
|
+
status: "sending" | "sent" | "read" | "received" | "system";
|
|
41
|
+
[key: string]: any;
|
|
42
|
+
}[]
|
|
43
|
+
const props = defineProps<{
|
|
44
|
+
messages: MessageArray
|
|
45
|
+
}>()
|
|
46
|
+
|
|
47
|
+
const computedMessages = computed(() => {
|
|
48
|
+
const newMessages = <MessageArray>[];
|
|
49
|
+
const msgs = props.messages;
|
|
50
|
+
const entries = props.messages.entries();
|
|
51
|
+
for (const [i, m] of entries ) {
|
|
52
|
+
if ((msgs[i + 1] != undefined) && (msgs[i + 1].status === msgs[i].status)) {
|
|
53
|
+
m.pointer = false;
|
|
54
|
+
const nextDate = msgs[i + 1].date;
|
|
55
|
+
const thisDate = msgs[i].date;
|
|
56
|
+
if (nextDate && thisDate && nextDate.getMinutes() == thisDate.getMinutes() && nextDate.getHours() == thisDate.getHours() && msgs[i + 1].status == msgs[i].status) {
|
|
57
|
+
m.hideStatus = true
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
} else {
|
|
61
|
+
m.pointer = true
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
switch (m.status) {
|
|
65
|
+
case "system":
|
|
66
|
+
m.hideStatus = true;
|
|
67
|
+
m.pointer = false;
|
|
68
|
+
m.posx = "center";
|
|
69
|
+
m.textAlign = "center";
|
|
70
|
+
break;
|
|
71
|
+
case "received":
|
|
72
|
+
m.posx = "left";
|
|
73
|
+
break;
|
|
74
|
+
default:
|
|
75
|
+
m.posx = "right";
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
newMessages.push(m);
|
|
80
|
+
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return newMessages
|
|
84
|
+
})
|
|
85
|
+
</script>
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
v-if="visibleComputed"
|
|
14
14
|
ref="list"
|
|
15
15
|
class="list rounded"
|
|
16
|
+
:style="{position:(fixed?'fixed':undefined)}"
|
|
16
17
|
>
|
|
17
18
|
<component
|
|
18
19
|
:is="item.href ? 'a' : 'div'"
|
|
@@ -49,7 +50,7 @@
|
|
|
49
50
|
</template>
|
|
50
51
|
<script setup lang="ts">
|
|
51
52
|
import { computed, ref, reactive, watch/*, nextTick*/ } from "#imports";
|
|
52
|
-
import _ from "lodash";
|
|
53
|
+
import * as _ from "lodash";
|
|
53
54
|
|
|
54
55
|
interface DropdownItem {
|
|
55
56
|
name: string;
|
|
@@ -68,6 +69,8 @@ const props = withDefaults(
|
|
|
68
69
|
items: DropdownItem[];
|
|
69
70
|
visible?: boolean | null;
|
|
70
71
|
paddingY?: string;
|
|
72
|
+
position?: { x: number, y: number }
|
|
73
|
+
fixed?:boolean;
|
|
71
74
|
}>(),
|
|
72
75
|
{ center: false, visible: null, paddingY: "", modelValue: undefined }
|
|
73
76
|
);
|
|
@@ -111,24 +114,36 @@ function computeWidth(input: string | number) {
|
|
|
111
114
|
}
|
|
112
115
|
|
|
113
116
|
const updatePosition = async () => {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
!activator.value ||
|
|
117
|
-
!activator.value.firstElementChild
|
|
118
|
-
) {
|
|
117
|
+
|
|
118
|
+
if (!visibleComputed.value) {
|
|
119
119
|
window.removeEventListener("resize", debouncedUpdatePosition);
|
|
120
120
|
return;
|
|
121
121
|
}
|
|
122
|
-
const activatorRect = activator.value.getBoundingClientRect();
|
|
123
122
|
|
|
124
|
-
if (
|
|
125
|
-
|
|
123
|
+
if (activator.value) {
|
|
124
|
+
const activatorRect = activator.value.getBoundingClientRect();
|
|
125
|
+
|
|
126
|
+
if (props.width === "100%") {
|
|
127
|
+
state.width = activatorRect.width;
|
|
128
|
+
} else {
|
|
129
|
+
state.width = computeWidth(props.width);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
state.y = activatorRect.height;
|
|
133
|
+
state.x = 0;
|
|
134
|
+
|
|
126
135
|
} else {
|
|
127
136
|
state.width = computeWidth(props.width);
|
|
128
|
-
}
|
|
129
137
|
|
|
130
|
-
|
|
138
|
+
|
|
139
|
+
}
|
|
140
|
+
if (props.position) {
|
|
141
|
+
state.x = props.position.x;
|
|
142
|
+
state.y = props.position.y;
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
131
145
|
state.x = 0;
|
|
146
|
+
state.y = 0;
|
|
132
147
|
|
|
133
148
|
/* await nextTick();
|
|
134
149
|
if (!list.value) return;
|
|
@@ -172,11 +187,12 @@ const onActivatorClick = () => {
|
|
|
172
187
|
.t-dropdown {
|
|
173
188
|
position: relative;
|
|
174
189
|
}
|
|
190
|
+
|
|
175
191
|
.list {
|
|
176
192
|
position: absolute;
|
|
177
|
-
left: v-bind('state.x + "px"');
|
|
178
|
-
top: v-bind('state.y + "px"');
|
|
179
|
-
width: v-bind('state.width+"px"');
|
|
193
|
+
left: v-bind('(state.x) + "px"');
|
|
194
|
+
top: v-bind('(state.y) + "px"');
|
|
195
|
+
width: v-bind('state.width + "px"');
|
|
180
196
|
display: flex;
|
|
181
197
|
|
|
182
198
|
background-color: var(--e-color-elev-2);
|
|
@@ -199,8 +215,8 @@ const onActivatorClick = () => {
|
|
|
199
215
|
&:hover {
|
|
200
216
|
background-color: rgba(var(--e-color-dark-rgb), 0.2);
|
|
201
217
|
}
|
|
202
|
-
|
|
203
|
-
}
|
|
218
|
+
|
|
219
|
+
&:focus {}
|
|
204
220
|
|
|
205
221
|
&.active {
|
|
206
222
|
background-color: rgba(var(--e-color-primary-rgb), 0.2);
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
class="a-btn"
|
|
4
4
|
:loading="loading"
|
|
5
5
|
:solid="false"
|
|
6
|
+
:type="type"
|
|
6
7
|
background="transparent"
|
|
7
8
|
>
|
|
8
9
|
<e-icon
|
|
@@ -13,7 +14,7 @@
|
|
|
13
14
|
</template>
|
|
14
15
|
<script setup lang="ts">
|
|
15
16
|
withDefaults(
|
|
16
|
-
defineProps<{ icon: string; size?: string; loading?: boolean }>(),
|
|
17
|
+
defineProps<{ icon: string; size?: string; loading?: boolean, type?: "button" | "submit" | "reset" }>(),
|
|
17
18
|
{ size: "21" }
|
|
18
19
|
);
|
|
19
20
|
</script>
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
<div
|
|
4
4
|
class="wrapper fullwidth"
|
|
5
5
|
:style="inputState.overtakeStyle"
|
|
6
|
-
:class="{ rounded: solid, solid }"
|
|
6
|
+
:class="{ rounded: rounded==undefined?solid:rounded, solid }"
|
|
7
7
|
@click="focus"
|
|
8
8
|
>
|
|
9
9
|
<e-icon
|
|
@@ -82,6 +82,7 @@ const props = withDefaults(
|
|
|
82
82
|
label: string;
|
|
83
83
|
modelValue?: string;
|
|
84
84
|
solid?: boolean;
|
|
85
|
+
rounded?: boolean;
|
|
85
86
|
type?: string;
|
|
86
87
|
autocomplete?: string;
|
|
87
88
|
disabled?: boolean;
|
|
@@ -98,6 +99,7 @@ const props = withDefaults(
|
|
|
98
99
|
modelValue: "",
|
|
99
100
|
autocomplete: "off",
|
|
100
101
|
height: "unset",
|
|
102
|
+
rounded:undefined,
|
|
101
103
|
}
|
|
102
104
|
);
|
|
103
105
|
|
|
@@ -151,7 +151,10 @@ body {
|
|
|
151
151
|
.text-center {
|
|
152
152
|
text-align: center;
|
|
153
153
|
}
|
|
154
|
-
|
|
154
|
+
.text-secondary{
|
|
155
|
+
opacity: 0.8;
|
|
156
|
+
font-size: small;
|
|
157
|
+
}
|
|
155
158
|
.e-blur {
|
|
156
159
|
background-color: rgba(0, 0, 0, 0.9);
|
|
157
160
|
}
|
|
@@ -175,3 +178,16 @@ label {
|
|
|
175
178
|
text-decoration: none !important;
|
|
176
179
|
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
|
177
180
|
}
|
|
181
|
+
|
|
182
|
+
.slide-up-enter-active,
|
|
183
|
+
.slide-up-leave-active {
|
|
184
|
+
transition: all 0.5s ease-in-out;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
.slide-up-enter-from {
|
|
188
|
+
transform: translateY(100%);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
.slide-up-leave-to {
|
|
192
|
+
transform: translateY(-100%);
|
|
193
|
+
}
|
package/dist/runtime/plugin.mjs
CHANGED
|
@@ -14,6 +14,17 @@ export default defineNuxtPlugin(() => {
|
|
|
14
14
|
return result.concat(suffix ? "-".concat(suffix) : "", ")");
|
|
15
15
|
}
|
|
16
16
|
return p;
|
|
17
|
+
},
|
|
18
|
+
makeid: (length) => {
|
|
19
|
+
let result = "";
|
|
20
|
+
const characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
|
21
|
+
const charactersLength = characters.length;
|
|
22
|
+
let counter = 0;
|
|
23
|
+
while (counter < length) {
|
|
24
|
+
result += characters.charAt(Math.floor(Math.random() * charactersLength));
|
|
25
|
+
counter += 1;
|
|
26
|
+
}
|
|
27
|
+
return result;
|
|
17
28
|
}
|
|
18
29
|
}
|
|
19
30
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@exakt/ui",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.14",
|
|
4
4
|
"description": "A UI library for Nuxt.js",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -42,8 +42,9 @@
|
|
|
42
42
|
"@types/node": "^20.2.4",
|
|
43
43
|
"changelogen": "^0.5.1",
|
|
44
44
|
"eslint": "^8.35.0",
|
|
45
|
+
"eslint-plugin-unused-imports": "^3.0.0",
|
|
45
46
|
"mkdist": "^1.2.0",
|
|
46
|
-
"nuxt": "^3.
|
|
47
|
+
"nuxt": "^3.7.1",
|
|
47
48
|
"vitest": "^0.29.2"
|
|
48
49
|
},
|
|
49
50
|
"directories": {
|
|
@@ -69,4 +70,4 @@
|
|
|
69
70
|
},
|
|
70
71
|
"homepage": "https://github.com/wd-4000/exakt#readme",
|
|
71
72
|
"packageManager": "yarn@3.5.1"
|
|
72
|
-
}
|
|
73
|
+
}
|