@v1nt1248/3nclient-lib 0.1.67 → 0.1.69

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.67",
5
+ "version": "0.1.69",
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> {
@@ -10,7 +10,6 @@
10
10
  const emits = defineEmits<Ui3nDialogComponentEmits>();
11
11
 
12
12
  const currentDialogProps = computed(() => ({
13
- teleport: props.dialogProps?.teleport || 'body',
14
13
  title: props.dialogProps?.title || '',
15
14
  cssClass: props.dialogProps?.cssClass || [],
16
15
  cssStyle: props.dialogProps?.cssStyle || {},
@@ -85,6 +84,16 @@
85
84
  }
86
85
  }
87
86
 
87
+ function onKeydown(event: KeyboardEvent) {
88
+ const { code } = event;
89
+ console.log('onKeydown: ', code, props.dialogProps?.closeOnEsc);
90
+ if (code === 'Escape' && props.dialogProps?.closeOnEsc) {
91
+ event.preventDefault();
92
+ event.stopPropagation();
93
+ startEmit('cancel');
94
+ }
95
+ }
96
+
88
97
  function startEmit(event: Ui3nDialogEvent, ev?: Event) {
89
98
  if (event === 'click-overlay') {
90
99
  emits(event);
@@ -195,11 +204,15 @@
195
204
  :style="cssStyle"
196
205
  v-on="
197
206
  dialogProps?.draggable
198
- ? { dragstart: onDragstart, mousedown: onMousedown, mouseup: onMouseup, mousemove: onMousemove }
199
- : {}
207
+ ? {
208
+ dragstart: onDragstart,
209
+ mousedown: onMousedown,
210
+ mouseup: onMouseup,
211
+ mousemove: onMousemove,
212
+ keydown: onKeydown
213
+ }
214
+ : { keydown: onKeydown }
200
215
  "
201
- @keydown.esc.stop="startEmit('cancel')"
202
- @keydown.enter.stop="isValid && startEmit('confirm')"
203
216
  >
204
217
  <div
205
218
  v-if="currentDialogProps.title"
@@ -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>
@@ -43,12 +43,12 @@ export interface Ui3nTableProps<T extends Ui3nTableBodyBaseItem> {
43
43
 
44
44
  export interface Ui3nTableEmits<T extends Ui3nTableBodyBaseItem> {
45
45
  (ev: 'change:sort', val: Ui3nTableSort<T>): void;
46
-
47
46
  (ev: 'select:row', val: T[]): void;
48
47
  }
49
48
 
50
- export type Ui3nTableNoDataSlot = {
49
+ export type Ui3nTableOtherSlots = {
51
50
  'no-data': () => VNode;
51
+ 'unused-place': () => VNode;
52
52
  };
53
53
 
54
54
  export type Ui3nTableGroupActionsSlot<T extends Ui3nTableBodyBaseItem> = {
@@ -86,7 +86,7 @@ export type Ui3nTableBodyRowCellSlot<T extends Ui3nTableBodyBaseItem, K extends
86
86
  [p in `row-cell-${K}`]: (scope: Ui3nTableBodyRowCellSlotScope<T, K>) => VNode;
87
87
  };
88
88
 
89
- export type Ui3nTableSlots<T extends Ui3nTableBodyBaseItem, K extends string & keyof T> = Ui3nTableNoDataSlot &
89
+ export type Ui3nTableSlots<T extends Ui3nTableBodyBaseItem, K extends string & keyof T> = Ui3nTableOtherSlots &
90
90
  Ui3nTableGroupActionsSlot<T> &
91
91
  Ui3nTableHeaderCellSlot<T, K> &
92
92
  Ui3nTableBodyRowSlot<T> &
@@ -105,7 +105,7 @@
105
105
  </template>
106
106
  </div>
107
107
 
108
- <!-- table body -->
108
+ <!-- table: body -->
109
109
  <div :class="$style.body">
110
110
  <template v-if="config?.showNoDataMessage && !size(body.content)">
111
111
  <slot name="no-data">
@@ -177,6 +177,11 @@
177
177
  </template>
178
178
  </template>
179
179
  </div>
180
+
181
+ <!-- table: unused space-->
182
+ <div :class="$style.unusedPlace">
183
+ <slot name="unused-place" />
184
+ </div>
180
185
  </div>
181
186
  </template>
182
187
 
@@ -200,6 +205,10 @@
200
205
  height: 100%;
201
206
  background-color: transparent;
202
207
  overflow-y: auto;
208
+ display: flex;
209
+ flex-direction: column;
210
+ justify-content: flex-start;
211
+ align-items: stretch;
203
212
  }
204
213
 
205
214
  .header {
@@ -360,4 +369,8 @@
360
369
  font-weight: 600;
361
370
  color: var(--ui3n-table-nodata-color);
362
371
  }
372
+
373
+ .unusedPlace {
374
+ flex-grow: 1;
375
+ }
363
376
  </style>