quasar-ui-sellmate-ui-kit 3.14.9 → 3.14.10

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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "quasar-ui-sellmate-ui-kit",
3
- "version": "3.14.9",
3
+ "version": "3.14.10",
4
4
  "author": "Sellmate Dev Team <dev@sellmate.co.kr>",
5
5
  "description": "Sellmate UI Kit",
6
6
  "license": "MIT",
@@ -13,13 +13,13 @@
13
13
  :class="{
14
14
  's-select-table': $attrs.selection && $attrs.selection !== 'none',
15
15
  'resizable-table': resizable,
16
- 'sticky-column-table': stickyColumn.isStickyLeft || stickyColumn.isStickyRight,
16
+ 'sticky-column-table': stickyColumn.leftStickyCount > 0 || stickyColumn.rightStickyCount > 0,
17
17
  'sticky-resizable-table': stickyResizable,
18
18
  'sticky-header': stickyHeader,
19
19
  'before-search': !rows.length,
20
20
  's-table__hover': !noHover,
21
- 'sticky-left-table': stickyColumn.isStickyLeft,
22
- 'sticky-right-table': stickyColumn.isStickyRight,
21
+ 'sticky-left-table': stickyColumn.leftStickyCount > 0,
22
+ 'sticky-right-table': stickyColumn.rightStickyCount > 0,
23
23
  }"
24
24
  @selection="updateSelected"
25
25
  ref="sTableRef"
@@ -44,24 +44,7 @@
44
44
  </template>
45
45
 
46
46
  <template v-for="(column, index) in columns" :key="index" #[`body-cell-${column.name}`]="props">
47
- <q-td
48
- v-if="navigator"
49
- :class="{
50
- focused: isFocused(props),
51
- 'text-center': props.col.align === 'center',
52
- 'text-right': props.col.align === 'right',
53
- [typeof props.col.classes === 'function'
54
- ? props.col.classes(props.row)
55
- : props.col.classes]: true,
56
- [typeof props.row.class === 'function'
57
- ? props.row.class(props.row)
58
- : typeof props.row.class === 'string'
59
- ? props.row.class
60
- : '']: true,
61
- }"
62
- :style="props.col.style"
63
- @click.stop="focusCell(props)"
64
- >
47
+ <q-td v-if="navigator" :props="props" @click.stop="focusCell(props)">
65
48
  <slot :name="`body-cell-${column.name}-content`" v-bind="props">
66
49
  <s-input
67
50
  ref="inputRef"
@@ -82,24 +65,7 @@
82
65
  </span>
83
66
  </slot>
84
67
  </q-td>
85
- <q-td
86
- v-else
87
- v-bind="props"
88
- auto-width
89
- :class="{
90
- 'text-center': props.col.align === 'center',
91
- 'text-right': props.col.align === 'right',
92
- [typeof props.col.classes === 'function'
93
- ? props.col.classes(props.row)
94
- : props.col.classes]: true,
95
- [typeof props.row.class === 'function'
96
- ? props.row.class(props.row)
97
- : typeof props.row.class === 'string'
98
- ? props.row.class
99
- : '']: true,
100
- }"
101
- :style="props.col.style"
102
- >
68
+ <q-td v-else :props="props" auto-width>
103
69
  <slot :name="`body-cell-${column.name}-content`" v-bind="props">
104
70
  {{ props.value }}
105
71
  </slot>
@@ -169,8 +135,6 @@
169
135
  stickyColumn: {
170
136
  type: Object,
171
137
  default: () => ({
172
- isStickyLeft: false,
173
- isStickyRight: false,
174
138
  leftStickyCount: 0,
175
139
  rightStickyCount: 0,
176
140
  }),
@@ -303,8 +267,8 @@
303
267
  }
304
268
 
305
269
  const { count, direction: stickyDirection } = props.stickyColumn;
306
- const { isStickyLeft, isStickyRight } = props.stickyColumn;
307
- if (isStickyLeft || isStickyRight) {
270
+ const { leftStickyCount, rightStickyCount } = props.stickyColumn;
271
+ if (leftStickyCount > 0 || rightStickyCount > 0) {
308
272
  addStickyColumn(sTableRef, props.stickyColumn);
309
273
  observeScrollForStickyShadow(tableElement());
310
274
  }
@@ -1,3 +1,8 @@
1
+ const MIN_COL_WIDTH = 40; // 최소 너비 제한
2
+ const HANDLE_WIDTH = 4; // 리사이즈 핸들의 너비
3
+ const HANDLE_HEIGHT = 16; // 리사이즈 핸들의 높이
4
+ const HANDLE_Z_INDEX = 2; // 리사이즈 핸들의 z-index
5
+
1
6
  function createDiv(val) {
2
7
  // 기존의 resizable div 코드
3
8
  const div = document.createElement('div');
@@ -5,23 +10,22 @@ function createDiv(val) {
5
10
  div.style.top = '10px';
6
11
  if (val === 'right') div.style.right = 0;
7
12
  if (val === 'left') div.style.left = 0;
8
- div.style.width = '4px';
13
+ div.style.width = `${HANDLE_WIDTH}px`;
9
14
  div.style.position = 'absolute';
10
15
  div.style.cursor = 'col-resize';
11
- div.style.backgroundColor = 'none';
16
+ div.style.backgroundColor = 'transparent';
12
17
  div.style.border = '1px solid #CCCCCC';
13
18
  div.style.borderTop = 'none';
14
19
  div.style.borderBottom = 'none';
15
- div.style.zIndex = 2;
20
+ div.style.zIndex = HANDLE_Z_INDEX;
16
21
  div.style.userSelect = 'none';
17
- div.style.height = '16px';
22
+ div.style.height = `${HANDLE_HEIGHT}px`;
18
23
  return div;
19
24
  }
20
25
 
21
- // TODO: 전역이 아니라 컴포넌트 단위로 제한된 최소 너비를 설정할 수 있도록 개선
22
- let restrictedMinWidth;
23
-
24
26
  function detectStickyWidth(tableElement, isStickyLeft) {
27
+ if (!tableElement) return;
28
+
25
29
  const tableRow = Array.from(tableElement.getElementsByTagName('tr'));
26
30
  const theadRow = tableRow[0];
27
31
  const stickyTh = Array.from(theadRow.querySelectorAll('.sticky-cell'));
@@ -46,182 +50,145 @@ function detectStickyWidth(tableElement, isStickyLeft) {
46
50
  });
47
51
  }
48
52
 
49
- // Helper function to measure text width
50
- function getTextWidth(text, style) {
51
- const canvas = getTextWidth.canvas || (getTextWidth.canvas = document.createElement('canvas'));
52
- const context = canvas.getContext('2d');
53
- const font = style.font || `${style.fontWeight} ${style.fontSize} ${style.fontFamily}`;
54
- context.font = font;
55
- return context.measureText(text).width;
56
- }
57
-
58
- function setListeners(div, position, useSticky, restrictedColClass = '') {
59
- // resizable 속성을 사용할 때에 이벤트
60
- let curCol;
61
- let pageX;
62
- let curColWidth;
63
-
64
- const onMouseMove = e => {
65
- if (!curCol) return false;
66
-
67
- const isRestricted = curCol.classList.contains(restrictedColClass);
68
-
69
- const diffX = e.pageX - pageX;
70
- let calcWidth = '';
71
-
72
- const isStickyLeft = position === 'right';
73
-
74
- if (isStickyLeft) {
75
- if (isRestricted && curColWidth + diffX <= restrictedMinWidth) {
76
- calcWidth = restrictedMinWidth; // 제한된 컬럼은 최소 너비로 설정
77
- } else {
78
- calcWidth = curColWidth + diffX;
53
+ export function useResizable() {
54
+ function setListeners(div, position, useSticky) {
55
+ // resizable 속성을 사용할 때에 이벤트
56
+ let curCol;
57
+ let pageX;
58
+ let curColWidth;
59
+
60
+ const onMouseMove = e => {
61
+ if (!curCol) return false;
62
+
63
+ const diffX = e.pageX - pageX;
64
+ const isStickyLeft = position === 'right';
65
+ let calcWidth = isStickyLeft ? curColWidth + diffX : curColWidth - diffX;
66
+
67
+ const computedStyles = window.getComputedStyle(curCol);
68
+ const min = parseInt(computedStyles.minWidth || `${MIN_COL_WIDTH}`, 10);
69
+ const max = parseInt(
70
+ computedStyles.maxWidth === 'none' ? '9999' : computedStyles.maxWidth || '9999',
71
+ 10,
72
+ );
73
+ calcWidth = Math.max(min, Math.min(calcWidth, max));
74
+ curCol.style.width = `${calcWidth}px`;
75
+
76
+ if (useSticky && curCol) {
77
+ const table = curCol.closest('table').parentElement;
78
+ detectStickyWidth(table, position === 'right');
79
79
  }
80
- } else {
81
- calcWidth = curColWidth - diffX;
82
- }
83
-
84
- if (calcWidth < 40) {
85
- calcWidth = 40; // 최소 너비 제한
86
- }
87
80
 
88
- curCol.style.width = `${calcWidth}px`;
89
- curCol.style.minWidth = `${calcWidth}px`;
90
- curCol.style.maxWidth = `${calcWidth}px`;
91
-
92
- if (useSticky && curCol) {
93
- const table = curCol.closest('table').parentElement;
94
- detectStickyWidth(table, position === 'right');
95
- }
96
-
97
- return true;
98
- };
99
-
100
- const onMouseUp = () => {
101
- curCol = undefined;
102
- pageX = undefined;
103
- curColWidth = undefined;
104
- document.removeEventListener('mousemove', onMouseMove);
105
- document.removeEventListener('mouseup', onMouseUp);
106
- };
81
+ return true;
82
+ };
83
+
84
+ const onMouseUp = () => {
85
+ curCol = undefined;
86
+ pageX = undefined;
87
+ curColWidth = undefined;
88
+ document.removeEventListener('mousemove', onMouseMove);
89
+ document.removeEventListener('mouseup', onMouseUp);
90
+ };
91
+
92
+ const onMouseDown = e => {
93
+ curCol = e.target.parentElement;
94
+ pageX = e.pageX;
95
+ curColWidth = curCol.offsetWidth;
96
+ document.addEventListener('mousemove', onMouseMove, { passive: true });
97
+ document.addEventListener('mouseup', onMouseUp, { passive: true });
98
+ };
99
+
100
+ div.addEventListener('mousedown', onMouseDown, { passive: true });
101
+ }
107
102
 
108
- const onMouseDown = e => {
109
- curCol = e.target.parentElement;
110
- pageX = e.pageX;
111
- curColWidth = curCol.offsetWidth;
112
- document.addEventListener('mousemove', onMouseMove, { passive: true });
113
- document.addEventListener('mouseup', onMouseUp, { passive: true });
114
- };
103
+ function appendResizableDiv(col, direction, useSticky) {
104
+ const div = createDiv(direction);
105
+ col.appendChild(div);
106
+ setListeners(div, direction, useSticky);
107
+ }
115
108
 
116
- div.addEventListener('mousedown', onMouseDown, { passive: true });
117
- }
109
+ function getTableCols(tableEl) {
110
+ if (!tableEl) return [];
111
+ const tableElement = tableEl.getElementsByTagName('table')[0];
112
+ if (!tableElement) return [];
113
+ const firstRow = tableElement.getElementsByTagName('tr')[0];
114
+ return firstRow ? Array.from(firstRow.children) : [];
115
+ }
118
116
 
119
- function appendResizableDiv(col, direction, useSticky, restrictedColClass = '') {
120
- const div = createDiv(direction);
121
- col.appendChild(div);
122
- setListeners(div, direction, useSticky, restrictedColClass);
123
- }
117
+ function applyStickyToColumn(tableEl, colIdx, isLeft, offsetPx) {
118
+ const rows = Array.from(tableEl.querySelectorAll('tr'));
124
119
 
125
- function getTableCols(tableEl) {
126
- const tableElement = tableEl.getElementsByTagName('table')[0];
127
- const firstRow = tableElement.getElementsByTagName('tr')[0];
128
- return firstRow ? Array.from(firstRow.children) : [];
129
- }
120
+ rows.forEach(row => {
121
+ const cells = Array.from(row.children);
122
+ const targetCell = cells[colIdx];
123
+ if (!targetCell) return;
130
124
 
131
- function addResizable(tableRef, stickyColumnsConfig = {}) {
132
- const cols = getTableCols(tableRef.value.$el);
125
+ targetCell.classList.add('sticky-cell');
126
+ targetCell.classList.add(isLeft ? 'left' : 'right');
127
+ targetCell.style.position = 'sticky';
128
+ targetCell.style[isLeft ? 'left' : 'right'] = offsetPx;
129
+ });
130
+ }
133
131
 
134
- const leftStickyCount = stickyColumnsConfig.leftStickyCount || 0;
135
- const rightStickyCount = stickyColumnsConfig.rightStickyCount || 0;
132
+ function addResizable(tableRef, stickyColumnsConfig = {}) {
133
+ const cols = getTableCols(tableRef.value.$el);
134
+ const leftStickyCount = stickyColumnsConfig.leftStickyCount || 0;
135
+ const rightStickyCount = stickyColumnsConfig.rightStickyCount || 0;
136
136
 
137
- cols.forEach((col, colIdx) => {
138
- const isLastCol = colIdx >= cols.length - 1;
139
- const isFirstCol = colIdx === 0;
140
- const isSelectTable = tableRef.value.$el.classList.contains('s-select-table');
137
+ cols.forEach((col, colIdx) => {
138
+ const isFirstCol = colIdx === 0;
139
+ const isSelectTable = tableRef.value.$el.classList.contains('s-select-table');
141
140
 
142
- // 🔑 스티키 컬럼이라면 리사이즈 핸들 생성 금지
143
- const isLeftSticky = colIdx < leftStickyCount;
144
- const isRightSticky = colIdx >= cols.length - rightStickyCount;
141
+ // 🔑 스티키 컬럼이라면 리사이즈 핸들 생성 금지
142
+ const isLeftSticky = colIdx < leftStickyCount;
143
+ const isRightSticky = colIdx >= cols.length - rightStickyCount;
145
144
 
146
- if (isLeftSticky || isRightSticky) {
147
- return; // 스티키 컬럼이면 appendResizableDiv 호출하지 않음
148
- }
145
+ // 스티키 컬럼이면 appendResizableDiv 호출하지 않음
146
+ if (isLeftSticky || isRightSticky) return;
149
147
 
150
- // 나머지 컬럼만 리사이즈 핸들 생성
151
- if (isSelectTable) {
152
- if (!isFirstCol && !isLastCol) {
148
+ // 나머지 컬럼만 리사이즈 핸들 생성
149
+ if (isSelectTable) {
150
+ if (!isFirstCol) {
151
+ appendResizableDiv(col, 'right', false);
152
+ }
153
+ } else {
153
154
  appendResizableDiv(col, 'right', false);
154
155
  }
155
- } else if (!isLastCol) {
156
- appendResizableDiv(col, 'right', false);
157
- }
158
- });
159
- }
160
-
161
- function applyStickyToColumn(tableEl, colIdx, isLeft, offsetPx) {
162
- const rows = Array.from(tableEl.querySelectorAll('tr'));
163
-
164
- rows.forEach(row => {
165
- const cells = Array.from(row.children);
166
- const targetCell = cells[colIdx];
167
- if (!targetCell) return;
168
-
169
- targetCell.classList.add('sticky-cell');
170
- targetCell.classList.add(isLeft ? 'left' : 'right');
171
- targetCell.classList.add(`sticky-col-${colIdx}`);
172
-
173
- targetCell.style.position = 'sticky';
174
-
175
- if (isLeft) {
176
- targetCell.style.left = offsetPx;
177
- } else {
178
- targetCell.style.right = offsetPx;
179
- }
180
- });
181
- }
182
-
183
- function addStickyColumn(tableRef, stickyColumnsConfig) {
184
- const { isStickyLeft, isStickyRight, leftStickyCount, rightStickyCount } = stickyColumnsConfig;
156
+ });
157
+ }
185
158
 
186
- const cols = getTableCols(tableRef.value.$el);
187
- const isSelectTable = tableRef.value.$el.classList.contains('s-select-table');
188
- const restrictedColClass = `sticky-col-${isSelectTable ? leftStickyCount : leftStickyCount - 1}`;
159
+ function addStickyColumn(tableRef, stickyColumnsConfig) {
160
+ const { leftStickyCount, rightStickyCount } = stickyColumnsConfig;
189
161
 
190
- // Left Sticky Columns
191
- if (isStickyLeft && leftStickyCount > 0) {
192
- // let i = isSelectTable ? 1 : 0; // Select Table일 경우 첫번째 컬럼은 스티키가 아님
193
- const count = isSelectTable ? leftStickyCount + 1 : leftStickyCount; // Select Table일 경우 +1
162
+ const cols = getTableCols(tableRef.value.$el);
163
+ const isSelectTable = tableRef.value.$el.classList.contains('s-select-table');
194
164
 
195
- for (let i = 0; i < count; i++) {
196
- applyStickyToColumn(tableRef.value.$el, i, true, '0px');
197
- if (isSelectTable && i > 0) {
198
- appendResizableDiv(cols[i], 'right', true, restrictedColClass); // 오른쪽에 리사이즈 핸들 추가
199
- if (i === count - 1) {
200
- restrictedMinWidth = cols[i].style.width.replace('px', ''); // 마지막 스티키 컬럼의 최소 너비 저장
201
- }
202
- } else {
203
- appendResizableDiv(cols[i], 'right', true, restrictedColClass); // 오른쪽에 리사이즈 핸들 추가
204
- if (i === count - 1) {
205
- restrictedMinWidth = cols[i].style.width.replace('px', ''); // 마지막 스티키 컬럼의 최소 너비 저장
165
+ // Left Sticky Columns
166
+ if (leftStickyCount > 0) {
167
+ // let i = isSelectTable ? 1 : 0; // Select Table일 경우 첫번째 컬럼은 스티키가 아님
168
+ const count = isSelectTable ? leftStickyCount + 1 : leftStickyCount; // Select Table일 경우 +1
169
+
170
+ for (let i = 0; i < count; i++) {
171
+ applyStickyToColumn(tableRef.value.$el, i, true, '0px');
172
+ if (isSelectTable && i > 0) {
173
+ appendResizableDiv(cols[i], 'right', true); // 오른쪽에 리사이즈 핸들 추가
174
+ } else {
175
+ appendResizableDiv(cols[i], 'right', true); // 오른쪽에 리사이즈 핸들 추가
206
176
  }
207
177
  }
178
+
179
+ detectStickyWidth(tableRef.value.$el, true); // 좌측 스티키 너비 재계산
208
180
  }
209
181
 
210
- detectStickyWidth(tableRef.value.$el, true); // 좌측 스티키 너비 재계산
211
- }
182
+ // Right Sticky Columns
183
+ if (rightStickyCount > 0) {
184
+ for (let i = cols.length - rightStickyCount; i < cols.length; i++) {
185
+ applyStickyToColumn(tableRef.value.$el, i, false, '0px');
186
+ appendResizableDiv(cols[i], 'left', true); // 왼쪽에 리사이즈 핸들 추가 (우측 스티키)
187
+ }
212
188
 
213
- // Right Sticky Columns
214
- if (isStickyRight && rightStickyCount > 0) {
215
- for (let i = cols.length - rightStickyCount; i < cols.length; i++) {
216
- applyStickyToColumn(tableRef.value.$el, i, false, '0px');
217
- appendResizableDiv(cols[i], 'left', true); // 왼쪽에 리사이즈 핸들 추가 (우측 스티키)
189
+ detectStickyWidth(tableRef.value.$el, false); // 우측 스티키 너비 재계산
218
190
  }
219
-
220
- detectStickyWidth(tableRef.value.$el, false); // 우측 스티키 너비 재계산
221
191
  }
222
- }
223
-
224
- export function useResizable() {
225
192
  return {
226
193
  addResizable,
227
194
  addStickyColumn,