@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 CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "exakt-ui",
3
3
  "configKey": "exakt",
4
- "version": "0.0.12"
4
+ "version": "0.0.14"
5
5
  }
@@ -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
- if (
115
- !visibleComputed.value ||
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 (props.width === "100%") {
125
- state.width = activatorRect.width;
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
- state.y = activatorRect.height;
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
- &:focus {
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
+ }
@@ -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.12",
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.4.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
+ }