@v1nt1248/3nclient-lib 0.1.66 → 0.1.68

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.66",
5
+ "version": "0.1.68",
6
6
  "description": "Library for 3NWeb clients",
7
7
  "type": "module",
8
8
  "files": [
@@ -5,7 +5,6 @@ export type Ui3nDialogEvent = 'open' | 'before-close' | 'close' | 'confirm' | 'c
5
5
 
6
6
  export interface Ui3nDialogProps {
7
7
  id?: string;
8
- teleport?: string;
9
8
  title?: string;
10
9
  width?: string | number;
11
10
  draggable?: boolean;
@@ -25,6 +24,7 @@ export interface Ui3nDialogProps {
25
24
  confirmButtonBackground?: string;
26
25
  cancelButtonBackground?: string;
27
26
  closeOnClickOverlay?: boolean;
27
+ closeOnEsc?: boolean;
28
28
  }
29
29
 
30
30
  export interface Ui3nDialogComponentProps<T extends Component> {
@@ -85,6 +85,16 @@
85
85
  }
86
86
  }
87
87
 
88
+ function onKeydown(event: KeyboardEvent) {
89
+ const { code } = event;
90
+ console.log('onKeydown: ', code, props.dialogProps?.closeOnEsc);
91
+ if (code === 'Escape' && props.dialogProps?.closeOnEsc) {
92
+ event.preventDefault();
93
+ event.stopPropagation();
94
+ startEmit('cancel');
95
+ }
96
+ }
97
+
88
98
  function startEmit(event: Ui3nDialogEvent, ev?: Event) {
89
99
  if (event === 'click-overlay') {
90
100
  emits(event);
@@ -195,11 +205,15 @@
195
205
  :style="cssStyle"
196
206
  v-on="
197
207
  dialogProps?.draggable
198
- ? { dragstart: onDragstart, mousedown: onMousedown, mouseup: onMouseup, mousemove: onMousemove }
199
- : {}
208
+ ? {
209
+ dragstart: onDragstart,
210
+ mousedown: onMousedown,
211
+ mouseup: onMouseup,
212
+ mousemove: onMousemove,
213
+ keydown: onKeydown
214
+ }
215
+ : { keydown: onKeydown }
200
216
  "
201
- @keydown.esc.stop="startEmit('cancel')"
202
- @keydown.enter.stop="isValid && startEmit('confirm')"
203
217
  >
204
218
  <div
205
219
  v-if="currentDialogProps.title"
@@ -61,6 +61,10 @@
61
61
  }
62
62
 
63
63
  function turnOnEditMode() {
64
+ if (props.disabled) {
65
+ return;
66
+ }
67
+
64
68
  inEdit.value = true;
65
69
  initialValue.value = value.value;
66
70
 
@@ -80,6 +84,10 @@
80
84
  }
81
85
 
82
86
  function done() {
87
+ if (props.disabled) {
88
+ return;
89
+ }
90
+
83
91
  if (props.disallowEmptyValue && !isValid.value) {
84
92
  return;
85
93
  }
@@ -93,6 +101,10 @@
93
101
  }
94
102
 
95
103
  function cancel() {
104
+ if (props.disabled) {
105
+ return;
106
+ }
107
+
96
108
  if (value.value !== initialValue.value) {
97
109
  value.value = initialValue.value;
98
110
  emits('update:modelValue', value.value);
@@ -102,6 +114,10 @@
102
114
  }
103
115
 
104
116
  function onClickOutside() {
117
+ if (props.disabled) {
118
+ return;
119
+ }
120
+
105
121
  if (inEdit.value) {
106
122
  emits('focusout');
107
123
  done();
@@ -121,7 +137,7 @@
121
137
  watch(
122
138
  () => inEdit.value,
123
139
  val => {
124
- emits('toggle:editMode', val);
140
+ !props.disabled && emits('toggle:editMode', val);
125
141
  },
126
142
  );
127
143
  </script>
@@ -129,7 +145,7 @@
129
145
  <template>
130
146
  <div
131
147
  v-ui3n-click-outside="onClickOutside"
132
- :class="$style.ui3nEditable"
148
+ :class="[$style.ui3nEditable, disabled && $style.ui3nEditableDisabled]"
133
149
  @focusin="emits('focusin', $event);"
134
150
  >
135
151
  <template v-if="inEdit">
@@ -148,11 +164,19 @@
148
164
  @keydown.esc="cancel"
149
165
  />
150
166
 
151
- <div v-ui3n-ripple :class="[$style.btn, $style.doneBtn]" @click.stop.prevent="done">
167
+ <div
168
+ v-ui3n-ripple
169
+ :class="[$style.btn, $style.doneBtn, disabled && $style.btnDisabled]"
170
+ @click.stop.prevent="done"
171
+ >
152
172
  <ui3n-icon icon="round-done" size="12" color="var(--color-icon-table-accent-default)" />
153
173
  </div>
154
174
 
155
- <div v-ui3n-ripple :class="[$style.btn, $style.cancelBtn]" @click.stop.prevent="cancel">
175
+ <div
176
+ v-ui3n-ripple
177
+ :class="[$style.btn, $style.cancelBtn, disabled && $style.btnDisabled]"
178
+ @click.stop.prevent="cancel"
179
+ >
156
180
  <ui3n-icon icon="round-close" size="12" color="var(--color-icon-table-secondary-default)" />
157
181
  </div>
158
182
  </template>
@@ -192,6 +216,11 @@
192
216
  overflow: hidden;
193
217
  }
194
218
 
219
+ .ui3nEditableDisabled {
220
+ cursor: default;
221
+ pointer-events: none;
222
+ }
223
+
195
224
  .content {
196
225
  position: relative;
197
226
  height: var(--ui3n-editable-height);
@@ -300,4 +329,10 @@
300
329
  opacity: 1;
301
330
  }
302
331
  }
332
+
333
+ .btnDisabled {
334
+ cursor: default;
335
+ pointer-events: none;
336
+ opacity: 0.75;
337
+ }
303
338
  </style>
@@ -1,71 +1,75 @@
1
1
  <script lang="ts" setup>
2
- import { ref, watch } from 'vue';
3
- import { autoUpdate, flip, useFloating, offset, shift } from '@floating-ui/vue';
4
- import { default as vClickOutside } from '../../directives/ui3n-click-outside';
5
- import type { Ui3nMenuEmits, Ui3nMenuProps, Ui3nMenuSlots } from './types';
2
+ import { ref, watch } from 'vue';
3
+ import { autoUpdate, flip, useFloating, offset, shift } from '@floating-ui/vue';
4
+ import { default as vClickOutside } from '../../directives/ui3n-click-outside';
5
+ import type { Ui3nMenuEmits, Ui3nMenuProps, Ui3nMenuSlots } from './types';
6
6
 
7
- const props = withDefaults(defineProps<Ui3nMenuProps>(), {
8
- positionStrategy: 'absolute',
9
- offsetX: 0,
10
- offsetY: 0,
11
- closeOnClick: true,
12
- closeOnClickOutside: true,
13
- disabled: false,
14
- });
15
- const emits = defineEmits<Ui3nMenuEmits>();
16
- defineSlots<Ui3nMenuSlots>();
7
+ const props = withDefaults(defineProps<Ui3nMenuProps>(), {
8
+ positionStrategy: 'absolute',
9
+ offsetX: 0,
10
+ offsetY: 0,
11
+ closeOnClick: true,
12
+ closeOnClickOutside: true,
13
+ disabled: false,
14
+ });
15
+ const emits = defineEmits<Ui3nMenuEmits>();
16
+ defineSlots<Ui3nMenuSlots>();
17
17
 
18
- const menuElement = ref<HTMLDivElement | null>(null);
19
- const menuTriggerElement = ref<HTMLDivElement | null>(null);
20
- const menuContentElement = ref<HTMLDivElement | null>(null);
21
- const isShow = ref(false);
18
+ const menuElement = ref<HTMLDivElement | null>(null);
19
+ const menuTriggerElement = ref<HTMLDivElement | null>(null);
20
+ const menuContentElement = ref<HTMLDivElement | null>(null);
21
+ const isShow = ref(false);
22
22
 
23
- const { floatingStyles, isPositioned } = useFloating(
24
- menuTriggerElement,
25
- menuContentElement,
26
- {
27
- placement: 'bottom-start',
28
- strategy: props.positionStrategy,
29
- middleware: [
30
- offset({
31
- mainAxis: props.offsetY,
32
- crossAxis: props.offsetX + 2,
33
- }),
34
- flip({
35
- fallbackAxisSideDirection: 'end',
36
- flipAlignment: false,
37
- fallbackPlacements: ['bottom-end'],
38
- }),
39
- shift(),
40
- ],
41
- whileElementsMounted: props.positionStrategy === 'fixed' ? autoUpdate : undefined,
42
- },
43
- );
23
+ const { floatingStyles, isPositioned } = useFloating(
24
+ menuTriggerElement,
25
+ menuContentElement,
26
+ {
27
+ placement: 'bottom-start',
28
+ strategy: props.positionStrategy,
29
+ middleware: [
30
+ offset({
31
+ mainAxis: props.offsetY,
32
+ crossAxis: props.offsetX + 2,
33
+ }),
34
+ flip({
35
+ fallbackAxisSideDirection: 'end',
36
+ flipAlignment: false,
37
+ fallbackPlacements: ['bottom-end'],
38
+ }),
39
+ shift(),
40
+ ],
41
+ whileElementsMounted: props.positionStrategy === 'fixed' ? autoUpdate : undefined,
42
+ },
43
+ );
44
44
 
45
- function toggleMenu() {
46
- isShow.value = !isShow.value;
47
- isShow.value ? emits('open') : emits('close');
48
- }
45
+ function toggleMenu() {
46
+ if (props.disabled) {
47
+ return;
48
+ }
49
49
 
50
- function onContentClick() {
51
- isShow.value = false;
52
- emits('close');
53
- }
50
+ isShow.value = !isShow.value;
51
+ isShow.value ? emits('open') : emits('close');
52
+ }
54
53
 
55
- function onClickOutside() {
56
- emits('click-outside');
57
- if (props.closeOnClickOutside) {
54
+ function onContentClick() {
58
55
  isShow.value = false;
59
56
  emits('close');
60
57
  }
61
- }
62
58
 
63
- watch(
64
- isPositioned,
65
- (val) => {
66
- val ? emits('opened') : emits('closed');
67
- },
68
- );
59
+ function onClickOutside() {
60
+ emits('click-outside');
61
+ if (props.closeOnClickOutside) {
62
+ isShow.value = false;
63
+ emits('close');
64
+ }
65
+ }
66
+
67
+ watch(
68
+ isPositioned,
69
+ val => {
70
+ val ? emits('opened') : emits('closed');
71
+ },
72
+ );
69
73
  </script>
70
74
 
71
75
  <template>
@@ -92,26 +96,26 @@ watch(
92
96
  </template>
93
97
 
94
98
  <style lang="scss" module>
95
- @use '../../assets/styles/mixins' as mixins;
99
+ @use '../../assets/styles/mixins' as mixins;
96
100
 
97
- .ui3nMenu {
98
- --ui3n-menu-content-bg: var(--color-bg-control-secondary-default);
101
+ .ui3nMenu {
102
+ --ui3n-menu-content-bg: var(--color-bg-control-secondary-default);
99
103
 
100
- position: relative;
101
- max-width: max-content;
102
- overflow: visible;
103
- }
104
+ position: relative;
105
+ max-width: max-content;
106
+ overflow: visible;
107
+ }
104
108
 
105
- .ui3nMenuTrigger {
106
- position: relative;
107
- max-width: max-content;
108
- }
109
+ .ui3nMenuTrigger {
110
+ position: relative;
111
+ max-width: max-content;
112
+ }
109
113
 
110
- .ui3nMenuContent {
111
- position: absolute;
112
- border-radius: 4px;
113
- background-color: var(--ui3n-menu-content-bg);
114
- z-index: 1000;
115
- @include mixins.elevation(3);
116
- }
114
+ .ui3nMenuContent {
115
+ position: absolute;
116
+ border-radius: 4px;
117
+ background-color: var(--ui3n-menu-content-bg);
118
+ z-index: 1000;
119
+ @include mixins.elevation(3);
120
+ }
117
121
  </style>