@v1nt1248/3nclient-lib 0.1.50 → 0.1.52

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/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@v1nt1248/3nclient-lib",
3
3
  "license": "AGPL-3.0-or-later",
4
4
  "author": "v1nt1248",
5
- "version": "0.1.50",
5
+ "version": "0.1.52",
6
6
  "description": "Library for 3NWeb clients",
7
7
  "type": "module",
8
8
  "files": [
@@ -1,173 +1,179 @@
1
1
  <script lang="ts" setup generic="T extends Component">
2
- import { type Component, computed, nextTick, onMounted, ref } from 'vue';
3
- import Ui3nButton from '../ui3n-button/ui3n-button.vue';
4
- import type { Ui3nDialogEvent, Ui3nDialogComponentProps, Ui3nDialogComponentEmits } from './types';
5
- import { ExtractComponentProps } from '@/components/types';
6
-
7
- const props = defineProps<Ui3nDialogComponentProps<T>>();
8
- const emits = defineEmits<Ui3nDialogComponentEmits>();
9
-
10
- const currentDialogProps = computed(() => ({
11
- teleport: props.dialogProps?.teleport || 'body',
12
- title: props.dialogProps?.title || '',
13
- width: props.dialogProps?.width || 380,
14
- cssClass: props.dialogProps?.cssClass || [],
15
- cssStyle: props.dialogProps?.cssStyle || {},
16
- contentCssClass: props.dialogProps?.contentCssClass || [],
17
- contentCssStyle: props.dialogProps?.contentCssStyle || {},
18
- confirmButton: props.dialogProps?.confirmButton || true,
19
- cancelButton: props.dialogProps?.cancelButton || true,
20
- confirmButtonText: props.dialogProps?.confirmButtonText || 'Done',
21
- cancelButtonText: props.dialogProps?.cancelButtonText || 'Cancel',
22
- confirmButtonColor: props.dialogProps?.confirmButtonColor || 'var(--color-text-button-primary-default)',
23
- cancelButtonColor: props.dialogProps?.cancelButtonColor || 'var(--color-text-button-secondary-default)',
24
- confirmButtonBackground: props.dialogProps?.confirmButtonBackground || 'var(--color-bg-button-primary-default)',
25
- cancelButtonBackground: props.dialogProps?.cancelButtonBackground || 'var(--color-bg-button-secondary-default)',
26
- closeOnClickOverlay: props.dialogProps?.closeOnClickOverlay || true,
27
- }));
28
-
29
- const show = ref(true);
30
- const data = ref<unknown>(null);
31
- const isValid = ref(true);
32
- const dialogOverlayElement = ref<HTMLElement | null>(null);
33
- const dialogElement = ref<HTMLDivElement | null>(null);
34
- const isMousedown = ref(false);
35
- const dragData = ref({
36
- initialLeft: 0,
37
- initialTop: 0,
38
- left: 0,
39
- top: 0,
40
- shiftX: 0,
41
- shiftY: 0,
42
- });
43
-
44
- const cssStyle = computed(() => ({
45
- ...currentDialogProps.value.cssStyle,
46
- width: `${currentDialogProps.value.width}px`,
47
- ...(props.dialogProps?.draggable && {
48
- left: `${dragData.value.left}px`,
49
- top: `${dragData.value.top}px`,
50
- }),
51
- }));
52
-
53
- function selectData(value: unknown) {
54
- data.value = value;
55
- if (
56
- !currentDialogProps.value.confirmButton &&
57
- !currentDialogProps.value.cancelButton &&
58
- props.dialogProps?.onConfirm
59
- ) {
60
- props.dialogProps?.onConfirm(data.value);
61
- closeDialog();
2
+ import { type Component, computed, nextTick, onMounted, ref } from 'vue';
3
+ import omit from 'lodash/omit';
4
+ import Ui3nButton from '../ui3n-button/ui3n-button.vue';
5
+ import type { Ui3nDialogEvent, Ui3nDialogComponentProps, Ui3nDialogComponentEmits } from './types';
6
+ import { ExtractComponentProps } from '@/components/types';
7
+ import { determineWindowWidth } from './util';
8
+
9
+ const props = defineProps<Ui3nDialogComponentProps<T>>();
10
+ const emits = defineEmits<Ui3nDialogComponentEmits>();
11
+
12
+ const currentDialogProps = computed(() => ({
13
+ teleport: props.dialogProps?.teleport || 'body',
14
+ title: props.dialogProps?.title || '',
15
+ cssClass: props.dialogProps?.cssClass || [],
16
+ cssStyle: props.dialogProps?.cssStyle || {},
17
+ contentCssClass: props.dialogProps?.contentCssClass || [],
18
+ contentCssStyle: props.dialogProps?.contentCssStyle || {},
19
+ width: props.dialogProps?.width
20
+ ? props.dialogProps?.width
21
+ : props.dialogProps?.cssStyle?.width
22
+ ? props.dialogProps?.cssStyle?.width
23
+ : 380,
24
+ confirmButton: props.dialogProps?.confirmButton !== false,
25
+ cancelButton: props.dialogProps?.cancelButton !== false,
26
+ confirmButtonText: props.dialogProps?.confirmButtonText || 'Done',
27
+ cancelButtonText: props.dialogProps?.cancelButtonText || 'Cancel',
28
+ confirmButtonColor: props.dialogProps?.confirmButtonColor || 'var(--color-text-button-primary-default)',
29
+ cancelButtonColor: props.dialogProps?.cancelButtonColor || 'var(--color-text-button-secondary-default)',
30
+ confirmButtonBackground: props.dialogProps?.confirmButtonBackground || 'var(--color-bg-button-primary-default)',
31
+ cancelButtonBackground: props.dialogProps?.cancelButtonBackground || 'var(--color-bg-button-secondary-default)',
32
+ closeOnClickOverlay: props.dialogProps?.closeOnClickOverlay !== false,
33
+ }));
34
+
35
+ const show = ref(true);
36
+ const data = ref<unknown>(null);
37
+ const isValid = ref(true);
38
+ const dialogOverlayElement = ref<HTMLElement | null>(null);
39
+ const dialogElement = ref<HTMLDivElement | null>(null);
40
+ const isMousedown = ref(false);
41
+ const dragData = ref({
42
+ initialLeft: 0,
43
+ initialTop: 0,
44
+ left: 0,
45
+ top: 0,
46
+ shiftX: 0,
47
+ shiftY: 0,
48
+ });
49
+
50
+ const cssStyle = computed(() => ({
51
+ width: determineWindowWidth({ width: currentDialogProps.value.width, style: currentDialogProps.value.cssStyle }),
52
+ ...omit(currentDialogProps.value.cssStyle, 'width'),
53
+ ...(props.dialogProps?.draggable && {
54
+ left: `${dragData.value.left}px`,
55
+ top: `${dragData.value.top}px`,
56
+ }),
57
+ }));
58
+
59
+ function selectData(value: unknown) {
60
+ data.value = value;
61
+ if (
62
+ !currentDialogProps.value.confirmButton &&
63
+ !currentDialogProps.value.cancelButton &&
64
+ props.dialogProps?.onConfirm
65
+ ) {
66
+ props.dialogProps?.onConfirm(data.value);
67
+ closeDialog();
68
+ }
62
69
  }
63
- }
64
70
 
65
- function validate(value: boolean) {
66
- isValid.value = value;
67
- }
68
-
69
- function closeDialog(arg?: { ev?: Event; withAction?: boolean }) {
70
- const { ev, withAction = true } = arg || {};
71
- if (ev) {
72
- ev.stopImmediatePropagation();
73
- ev.preventDefault();
71
+ function validate(value: boolean) {
72
+ isValid.value = value;
74
73
  }
75
- show.value = false;
76
- props.dialogProps?.onClose && props.dialogProps.onClose();
77
- if (withAction) {
78
- emits('close');
74
+
75
+ function closeDialog(arg?: { ev?: Event; withAction?: boolean }) {
76
+ const { ev, withAction = true } = arg || {};
77
+ if (ev) {
78
+ ev.stopImmediatePropagation();
79
+ ev.preventDefault();
80
+ }
81
+ show.value = false;
82
+ props.dialogProps?.onClose && props.dialogProps.onClose();
83
+ if (withAction) {
84
+ emits('close');
85
+ }
79
86
  }
80
- }
81
87
 
82
- function startEmit(event: Ui3nDialogEvent, ev?: Event) {
83
- if (event === 'click-overlay') {
84
- emits(event);
85
- currentDialogProps.value.closeOnClickOverlay && closeDialog({ ev });
86
- return;
88
+ function startEmit(event: Ui3nDialogEvent, ev?: Event) {
89
+ if (event === 'click-overlay') {
90
+ emits(event);
91
+ currentDialogProps.value.closeOnClickOverlay && closeDialog({ ev });
92
+ return;
93
+ }
94
+
95
+ if (event === 'confirm') {
96
+ props.dialogProps?.onConfirm && props.dialogProps.onConfirm(data.value);
97
+ closeDialog();
98
+ }
99
+
100
+ if (event === 'cancel') {
101
+ props.dialogProps?.onCancel && props.dialogProps.onCancel(data.value);
102
+ closeDialog();
103
+ }
104
+
105
+ if (data.value) {
106
+ // @ts-ignore
107
+ emits(event, data.value);
108
+ } else {
109
+ // @ts-ignore
110
+ emits(event);
111
+ }
87
112
  }
88
113
 
89
- if (event === 'confirm') {
90
- props.dialogProps?.onConfirm && props.dialogProps.onConfirm(data.value);
91
- closeDialog();
114
+ function handleEvent(event: Event, eventName: Ui3nDialogEvent) {
115
+ event.stopImmediatePropagation();
116
+ event.preventDefault();
117
+ startEmit(eventName);
92
118
  }
93
119
 
94
- if (event === 'cancel') {
95
- props.dialogProps?.onCancel && props.dialogProps.onCancel(data.value);
96
- closeDialog();
120
+ /* drag */
121
+ function onDragstart() {
122
+ return false;
97
123
  }
98
124
 
99
- if (data.value) {
100
- // @ts-ignore
101
- emits(event, data.value);
102
- } else {
103
- // @ts-ignore
104
- emits(event);
125
+ function onMouseup() {
126
+ isMousedown.value = false;
127
+ dragData.value.shiftX = 0;
128
+ dragData.value.shiftY = 0;
129
+ return false;
105
130
  }
106
- }
107
-
108
- function handleEvent(event: Event, eventName: Ui3nDialogEvent) {
109
- event.stopImmediatePropagation();
110
- event.preventDefault();
111
- startEmit(eventName);
112
- }
113
-
114
- /* drag */
115
- function onDragstart() {
116
- return false;
117
- }
118
-
119
- function onMouseup() {
120
- isMousedown.value = false;
121
- dragData.value.shiftX = 0;
122
- dragData.value.shiftY = 0;
123
- return false;
124
- }
125
-
126
- function onMousedown(ev: MouseEvent) {
127
- isMousedown.value = true;
128
- const dialogElementRect = dialogElement.value!.getBoundingClientRect();
129
- dragData.value.shiftX = ev.clientX - dialogElementRect.left;
130
- dragData.value.shiftY = ev.clientY - dialogElementRect.top;
131
- }
132
-
133
- function onMousemove(ev: MouseEvent) {
134
- if (!isMousedown.value) {
135
- return;
131
+
132
+ function onMousedown(ev: MouseEvent) {
133
+ isMousedown.value = true;
134
+ const dialogElementRect = dialogElement.value!.getBoundingClientRect();
135
+ dragData.value.shiftX = ev.clientX - dialogElementRect.left;
136
+ dragData.value.shiftY = ev.clientY - dialogElementRect.top;
136
137
  }
137
- dragData.value.left = ev.clientX - dragData.value.shiftX - dragData.value.initialLeft;
138
- dragData.value.top = ev.clientY - dragData.value.shiftY - dragData.value.initialTop;
139
- }
140
-
141
- onMounted(() => {
142
- if (dialogElement.value) {
143
- dialogElement.value.style.setProperty(
144
- '--dialog-confirm-button-color',
145
- currentDialogProps.value.confirmButtonColor!,
146
- );
147
- dialogElement.value.style.setProperty(
148
- '--dialog-cancel-button-color',
149
- currentDialogProps.value.cancelButtonColor!,
150
- );
151
- dialogElement.value.style.setProperty(
152
- '--dialog-confirm-background-color',
153
- currentDialogProps.value.confirmButtonBackground!,
154
- );
155
- dialogElement.value.style.setProperty(
156
- '--dialog-cancel-background-color',
157
- currentDialogProps.value.cancelButtonBackground!,
158
- );
159
-
160
- nextTick(() => {
161
- dialogElement.value!.focus();
162
-
163
- setTimeout(() => {
164
- const dialogClientRect = dialogElement.value!.getBoundingClientRect();
165
- dragData.value.initialLeft = dialogClientRect.left;
166
- dragData.value.initialTop = dialogClientRect.top;
167
- }, 100);
168
- });
138
+
139
+ function onMousemove(ev: MouseEvent) {
140
+ if (!isMousedown.value) {
141
+ return;
142
+ }
143
+ dragData.value.left = ev.clientX - dragData.value.shiftX - dragData.value.initialLeft;
144
+ dragData.value.top = ev.clientY - dragData.value.shiftY - dragData.value.initialTop;
169
145
  }
170
- });
146
+
147
+ onMounted(() => {
148
+ if (dialogElement.value) {
149
+ dialogElement.value.style.setProperty(
150
+ '--dialog-confirm-button-color',
151
+ currentDialogProps.value.confirmButtonColor!,
152
+ );
153
+ dialogElement.value.style.setProperty(
154
+ '--dialog-cancel-button-color',
155
+ currentDialogProps.value.cancelButtonColor!,
156
+ );
157
+ dialogElement.value.style.setProperty(
158
+ '--dialog-confirm-background-color',
159
+ currentDialogProps.value.confirmButtonBackground!,
160
+ );
161
+ dialogElement.value.style.setProperty(
162
+ '--dialog-cancel-background-color',
163
+ currentDialogProps.value.cancelButtonBackground!,
164
+ );
165
+
166
+ nextTick(() => {
167
+ dialogElement.value!.focus();
168
+
169
+ setTimeout(() => {
170
+ const dialogClientRect = dialogElement.value!.getBoundingClientRect();
171
+ dragData.value.initialLeft = dialogClientRect.left;
172
+ dragData.value.initialTop = dialogClientRect.top;
173
+ }, 100);
174
+ });
175
+ }
176
+ });
171
177
  </script>
172
178
 
173
179
  <template>
@@ -187,9 +193,11 @@ onMounted(() => {
187
193
  ...currentDialogProps.cssClass!,
188
194
  ]"
189
195
  :style="cssStyle"
190
- v-on="dialogProps?.draggable
196
+ v-on="
197
+ dialogProps?.draggable
191
198
  ? { dragstart: onDragstart, mousedown: onMousedown, mouseup: onMouseup, mousemove: onMousemove }
192
- : {}"
199
+ : {}
200
+ "
193
201
  @keydown.esc.stop="startEmit('cancel')"
194
202
  @keydown.enter.stop="isValid && startEmit('confirm')"
195
203
  >
@@ -234,7 +242,7 @@ onMounted(() => {
234
242
  v-if="currentDialogProps.confirmButton || currentDialogProps.cancelButton"
235
243
  :class="[
236
244
  $style.actions,
237
- currentDialogProps.confirmButton && currentDialogProps.cancelButton && $style.bothBtns
245
+ currentDialogProps.confirmButton && currentDialogProps.cancelButton && $style.bothBtns,
238
246
  ]"
239
247
  @click.stop
240
248
  >
@@ -263,87 +271,87 @@ onMounted(() => {
263
271
  </template>
264
272
 
265
273
  <style lang="scss" module>
266
- @use '../../assets/styles/mixins' as mixins;
267
-
268
- .overlay {
269
- position: fixed;
270
- z-index: 1000;
271
- inset: 0;
272
- display: flex;
273
- justify-content: center;
274
- align-items: center;
275
- background-color: rgba(0, 0, 0, 0.4);
276
- }
277
-
278
- .dialog {
279
- --dialog-border-radius: 8px;
280
- --dialog-title-padding: 16px 32px 16px 16px;
281
- --dialog-title-font-size: 14px;
282
- --dialog-actions-padding: 16px;
283
- --dialog-confirm-button-color: var(--color-text-button-primary-default);
284
- --dialog-cancel-button-color: var(--color-text-button-secondary-default);
285
- --dialog-confirm-background-color: var(--color-bg-button-primary-default);
286
- --dialog-cancel-background-color: var(--color-bg-button-secondary-default);
287
-
288
- position: relative;
289
- display: flex;
290
- flex-direction: column;
291
- height: auto;
292
- max-height: 95%;
293
- background-color: var(--color-bg-block-primary-default);
294
- border-radius: var(--dialog-border-radius);
295
- outline: none;
296
-
297
- @include mixins.elevation();
298
-
299
- &.draggable {
300
- cursor: move;
274
+ @use '../../assets/styles/mixins' as mixins;
275
+
276
+ .overlay {
277
+ position: fixed;
278
+ z-index: 1000;
279
+ inset: 0;
280
+ display: flex;
281
+ justify-content: center;
282
+ align-items: center;
283
+ background-color: rgba(0, 0, 0, 0.4);
284
+ }
285
+
286
+ .dialog {
287
+ --dialog-border-radius: 8px;
288
+ --dialog-title-padding: 16px 32px 16px 16px;
289
+ --dialog-title-font-size: 14px;
290
+ --dialog-actions-padding: 16px;
291
+ --dialog-confirm-button-color: var(--color-text-button-primary-default);
292
+ --dialog-cancel-button-color: var(--color-text-button-secondary-default);
293
+ --dialog-confirm-background-color: var(--color-bg-button-primary-default);
294
+ --dialog-cancel-background-color: var(--color-bg-button-secondary-default);
295
+
296
+ position: relative;
297
+ display: flex;
298
+ flex-direction: column;
299
+ height: auto;
300
+ max-height: 95%;
301
+ background-color: var(--color-bg-block-primary-default);
302
+ border-radius: var(--dialog-border-radius);
303
+ outline: none;
304
+
305
+ @include mixins.elevation();
306
+
307
+ &.draggable {
308
+ cursor: move;
309
+ }
310
+ }
311
+
312
+ .title {
313
+ position: relative;
314
+ width: 100%;
315
+ height: calc(var(--spacing-m) * 3);
316
+ display: flex;
317
+ justify-content: flex-start;
318
+ align-items: center;
319
+ padding: var(--dialog-title-padding);
320
+ font-size: var(--dialog-title-font-size);
321
+ font-weight: 600;
322
+ line-height: 1.2;
323
+ color: var(--color-text-control-primary-default);
324
+ border-bottom: 1px solid var(--color-border-block-primary-default);
325
+ @include mixins.text-overflow-ellipsis();
326
+ }
327
+
328
+ .dragHandleIcon {
329
+ position: absolute;
330
+ left: 0;
331
+ top: 16px;
332
+ }
333
+
334
+ .closeBtn {
335
+ position: absolute;
336
+ right: 4px;
337
+ top: 12px;
338
+ z-index: 5;
339
+ }
340
+
341
+ .content {
342
+ flex-grow: 2;
343
+ overflow-y: auto;
344
+ }
345
+
346
+ .actions {
347
+ padding: var(--dialog-actions-padding);
348
+ display: flex;
349
+ justify-content: flex-end;
350
+ align-items: center;
351
+ gap: var(--spacing-s);
352
+ }
353
+
354
+ .bothBtns {
355
+ margin-left: var(--spacing-s);
301
356
  }
302
- }
303
-
304
- .title {
305
- position: relative;
306
- width: 100%;
307
- height: calc(var(--spacing-m) * 3);
308
- display: flex;
309
- justify-content: flex-start;
310
- align-items: center;
311
- padding: var(--dialog-title-padding);
312
- font-size: var(--dialog-title-font-size);
313
- font-weight: 600;
314
- line-height: 1.2;
315
- color: var(--color-text-control-primary-default);
316
- border-bottom: 1px solid var(--color-border-block-primary-default);
317
- @include mixins.text-overflow-ellipsis();
318
- }
319
-
320
- .dragHandleIcon {
321
- position: absolute;
322
- left: 0;
323
- top: 16px;
324
- }
325
-
326
- .closeBtn {
327
- position: absolute;
328
- right: 4px;
329
- top: 12px;
330
- z-index: 5;
331
- }
332
-
333
- .content {
334
- flex-grow: 2;
335
- overflow-y: auto;
336
- }
337
-
338
- .actions {
339
- padding: var(--dialog-actions-padding);
340
- display: flex;
341
- justify-content: flex-end;
342
- align-items: center;
343
- gap: var(--spacing-s);
344
- }
345
-
346
- .bothBtns {
347
- margin-left: var(--spacing-s);
348
- }
349
357
  </style>
@@ -0,0 +1,24 @@
1
+ export function determineWindowWidth({
2
+ width,
3
+ style,
4
+ defaultValue = 380,
5
+ }: {
6
+ width?: string | number;
7
+ style?: Record<string, string>;
8
+ defaultValue?: number;
9
+ }): string {
10
+ if (width) {
11
+ const widthAsNumber = Number(width);
12
+ if (Number.isNaN(widthAsNumber)) {
13
+ return width as string;
14
+ }
15
+
16
+ return `${widthAsNumber}px`;
17
+ }
18
+
19
+ if (style?.width) {
20
+ return style.width as string;
21
+ }
22
+
23
+ return `${defaultValue}px`;
24
+ }
@@ -47,7 +47,7 @@
47
47
  }
48
48
 
49
49
  ev.stopImmediatePropagation();
50
- fileInput.value!.click();
50
+ fileInput.value?.click();
51
51
  }
52
52
 
53
53
  function validateFileSize(file: File) {
@@ -136,8 +136,8 @@
136
136
  }
137
137
 
138
138
  function onChange() {
139
- processFiles([...fileInput.value!.files!]);
140
- fileInput.value!.value = '';
139
+ fileInput.value && fileInput.value.files && processFiles([...fileInput.value.files]);
140
+ fileInput.value && (fileInput.value!.value = '');
141
141
  }
142
142
  </script>
143
143