gnui 1.2.19 → 1.2.20

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.
Files changed (78) hide show
  1. package/dist/js/gnui.esm.js +339 -134
  2. package/dist/js/gnui.js +339 -134
  3. package/dist/js/gnui.min.js +6 -6
  4. package/dist/styles/default.css +10600 -20758
  5. package/dist/styles/gpi.css +10630 -20788
  6. package/dist/styles/green24.css +11263 -21435
  7. package/dist/styles/insights.css +10616 -20775
  8. package/dist/styles/nac.css +10628 -20795
  9. package/dist/styles/ztnac.css +11263 -21436
  10. package/package.json +3 -2
  11. package/styleguide/assets/components.js +58 -3
  12. package/styleguide/assets/js/gnui.js +339 -134
  13. package/styleguide/assets/js/gnui.min.js +6 -6
  14. package/styleguide/assets/styles/default.css +10600 -20758
  15. package/styleguide/assets/styles/gpi.css +10630 -20788
  16. package/styleguide/assets/styles/green24.css +11263 -21435
  17. package/styleguide/assets/styles/insights.css +10616 -20775
  18. package/styleguide/assets/styles/nac.css +10628 -20795
  19. package/styleguide/assets/styles/ztnac.css +11263 -21436
  20. package/styleguide/category/COLOR/index.html +1 -1
  21. package/styleguide/category/COMPONENT/Alert(js)/index.html +1 -1
  22. package/styleguide/category/COMPONENT/Bignumber/index.html +1 -1
  23. package/styleguide/category/COMPONENT/Breadcrumb/index.html +1 -1
  24. package/styleguide/category/COMPONENT/Calendar(js)/index.html +1 -1
  25. package/styleguide/category/COMPONENT/Card/index.html +1 -1
  26. package/styleguide/category/COMPONENT/Chart(js)/index.html +1 -1
  27. package/styleguide/category/COMPONENT/Datagrid(js)/index.html +1 -1
  28. package/styleguide/category/COMPONENT/Datalist(js)/index.html +1 -1
  29. package/styleguide/category/COMPONENT/Growl(js)/index.html +1 -1
  30. package/styleguide/category/COMPONENT/JsonView(js)/index.html +1 -1
  31. package/styleguide/category/COMPONENT/Loader(js)/index.html +1 -1
  32. package/styleguide/category/COMPONENT/MenuButton(js)/index.html +169 -21
  33. package/styleguide/category/COMPONENT/Message(js)/index.html +1 -1
  34. package/styleguide/category/COMPONENT/Modal(js)/index.html +1 -1
  35. package/styleguide/category/COMPONENT/Pagination(js)/index.html +1 -1
  36. package/styleguide/category/COMPONENT/Panel/index.html +1 -1
  37. package/styleguide/category/COMPONENT/Progressbar(js)/index.html +1 -1
  38. package/styleguide/category/COMPONENT/Tab(js)/index.html +1 -1
  39. package/styleguide/category/COMPONENT/Tagcloud(js)/index.html +1 -1
  40. package/styleguide/category/COMPONENT/Tooltip(js)/index.html +1 -1
  41. package/styleguide/category/COMPONENT/Tree(js)/index.html +16 -1
  42. package/styleguide/category/CONTROLS/Button(js)/index.html +1 -1
  43. package/styleguide/category/CONTROLS/Checkbox/index.html +1 -1
  44. package/styleguide/category/CONTROLS/Colorpicker(js)/index.html +1 -1
  45. package/styleguide/category/CONTROLS/Datepicker(js)/index.html +1 -1
  46. package/styleguide/category/CONTROLS/Dropdown(js)/index.html +67 -10
  47. package/styleguide/category/CONTROLS/File/index.html +1 -1
  48. package/styleguide/category/CONTROLS/Form/Control/index.html +1 -1
  49. package/styleguide/category/CONTROLS/Form/Field/index.html +2 -2
  50. package/styleguide/category/CONTROLS/Form/Plain/index.html +2 -2
  51. package/styleguide/category/CONTROLS/Input/index.html +1 -1
  52. package/styleguide/category/CONTROLS/MultiText(js)/index.html +1 -1
  53. package/styleguide/category/CONTROLS/Picklist(js)/index.html +67 -13
  54. package/styleguide/category/CONTROLS/Radio/index.html +1 -1
  55. package/styleguide/category/CONTROLS/Select/index.html +1 -1
  56. package/styleguide/category/CONTROLS/SelectButton(js)/index.html +2 -2
  57. package/styleguide/category/CONTROLS/Slider/index.html +1 -1
  58. package/styleguide/category/CONTROLS/SortableList(js)/index.html +2 -2
  59. package/styleguide/category/CONTROLS/Switch(js)/index.html +1 -1
  60. package/styleguide/category/CONTROLS/SyntaxInput(js)/index.html +1 -1
  61. package/styleguide/category/CONTROLS/Textarea/index.html +2 -2
  62. package/styleguide/category/CONTROLS/Time(js)/index.html +2 -2
  63. package/styleguide/category/ELEMENTS/Box/index.html +1 -1
  64. package/styleguide/category/ELEMENTS/Icon/index.html +1 -1
  65. package/styleguide/category/ELEMENTS/Image/index.html +1 -1
  66. package/styleguide/category/ELEMENTS/List/index.html +1 -1
  67. package/styleguide/category/ELEMENTS/Table/index.html +1 -1
  68. package/styleguide/category/ELEMENTS/Tag/index.html +1 -1
  69. package/styleguide/category/ELEMENTS/Title/index.html +1 -1
  70. package/styleguide/category/LAYOUT/Container/index.html +1 -1
  71. package/styleguide/category/LAYOUT/Grid/index.html +1 -1
  72. package/styleguide/category/LAYOUT/Splitter(js)/index.html +1 -1
  73. package/styleguide/category/UTILITY/index.html +1 -1
  74. package/styleguide/category/Utils/index.html +1 -1
  75. package/styleguide/color.html +1 -1
  76. package/styleguide/index.html +1 -1
  77. package/styleguide/tag/javascript/index.html +4446 -4172
  78. package/styleguide/tag/v.0.1.0/index.html +5259 -4985
package/dist/js/gnui.js CHANGED
@@ -16876,65 +16876,65 @@
16876
16876
  return GNCoreEventManager.instance;
16877
16877
  }
16878
16878
  // life cycle event add
16879
- stateAdd(uid, name, handler) {
16880
- return this.add(undefined, uid, name, handler);
16879
+ stateAdd(cid, name, handler) {
16880
+ return this.add(undefined, cid, name, handler);
16881
16881
  }
16882
- add(target, uid, name, handler) {
16883
- if (!this._eventMap[uid]) {
16884
- this._eventMap[uid] = []; // 해당 uid에 대한 이벤트가 없는 경우 초기화
16882
+ add(target, cid, name, handler) {
16883
+ if (!this._eventMap[cid]) {
16884
+ this._eventMap[cid] = []; // 해당 cid에 대한 이벤트가 없는 경우 초기화
16885
16885
  }
16886
- const eid = this._getEventId(uid); // eventID 생성
16887
- this._eventMap[uid].push(target
16886
+ const eid = this._getEventId(cid); // eventID 생성
16887
+ this._eventMap[cid].push(target
16888
16888
  ? {
16889
16889
  target,
16890
16890
  eid,
16891
- uid,
16891
+ cid,
16892
16892
  name,
16893
16893
  handler
16894
16894
  }
16895
16895
  : {
16896
16896
  eid,
16897
- uid,
16897
+ cid,
16898
16898
  name,
16899
16899
  handler
16900
16900
  });
16901
16901
  target && on(target, name, handler); // 이벤트 바인딩
16902
16902
  return eid;
16903
16903
  }
16904
- remove(uid, name) {
16905
- const _events = this._getEvent(uid, name);
16904
+ remove(cid, name) {
16905
+ const _events = this._getEvent(cid, name);
16906
16906
  // 이벤트 해제
16907
16907
  if (_events.length) {
16908
16908
  _events.forEach((_event) => {
16909
16909
  off(_event.target, _event.name, _event.handler);
16910
16910
  // eventMap에서 해당 이벤트 삭제
16911
- this._eventMap[uid].some(event => event.eid === _event.eid) &&
16912
- this._eventMap[uid].splice(this._eventMap[uid].findIndex(event => event.eid === _event.eid), 1);
16911
+ this._eventMap[cid].some(event => event.eid === _event.eid) &&
16912
+ this._eventMap[cid].splice(this._eventMap[cid].findIndex(event => event.eid === _event.eid), 1);
16913
16913
  });
16914
- // uid에 대한 이벤트가 남아있지 않은 경우 uid 키 삭제
16915
- if (!this._eventMap[uid].length) {
16916
- delete this._eventMap[uid];
16914
+ // cid에 대한 이벤트가 남아있지 않은 경우 cid 키 삭제
16915
+ if (!this._eventMap[cid].length) {
16916
+ delete this._eventMap[cid];
16917
16917
  }
16918
16918
  }
16919
16919
  }
16920
- removeAll(uid) {
16921
- if (!this._eventMap[uid]) {
16920
+ removeAll(cid) {
16921
+ if (!this._eventMap[cid]) {
16922
16922
  return;
16923
16923
  }
16924
16924
  // 이벤트 해제
16925
- this._eventMap[uid].forEach(event => {
16925
+ this._eventMap[cid].forEach(event => {
16926
16926
  if (event.target) {
16927
16927
  off(event.target, event.name, event.handler);
16928
16928
  }
16929
16929
  });
16930
16930
  // 이벤트 삭제
16931
- delete this._eventMap[uid];
16931
+ delete this._eventMap[cid];
16932
16932
  }
16933
16933
  /**
16934
16934
  * lifeCycle 핸들러 실행
16935
16935
  */
16936
- cyclepatch(uid, name, params) {
16937
- const _events = this._getEvent(uid, name);
16936
+ cyclepatch(cid, name, params) {
16937
+ const _events = this._getEvent(cid, name);
16938
16938
  if (_events.length) {
16939
16939
  _events.forEach((_event) => {
16940
16940
  const _tagret = _event.target || this;
@@ -16949,8 +16949,8 @@
16949
16949
  * - 모든 핸들러를 순차 실행한 뒤, 하나라도 `false` 를 반환한 경우 `true`(cancelled)를 반환한다.
16950
16950
  * (첫 false 에서 중단하지 않고, 나머지 핸들러도 계속 실행한다)
16951
16951
  */
16952
- async dispatch(uid, name, params) {
16953
- const _events = this._getEvent(uid, name);
16952
+ async dispatch(cid, name, params) {
16953
+ const _events = this._getEvent(cid, name);
16954
16954
  let cancelled = false;
16955
16955
  if (_events.length) {
16956
16956
  for (const _event of _events) {
@@ -16964,17 +16964,17 @@
16964
16964
  }
16965
16965
  return cancelled;
16966
16966
  }
16967
- _getEvent(uid, name) {
16967
+ _getEvent(cid, name) {
16968
16968
  // parameters에 해당하는 이벤트 반환
16969
- return this._eventMap[uid]
16970
- ? this._eventMap[uid].filter(event => {
16969
+ return this._eventMap[cid]
16970
+ ? this._eventMap[cid].filter(event => {
16971
16971
  return event.name === name;
16972
16972
  }) || []
16973
16973
  : [];
16974
16974
  }
16975
- _getEventId(uid) {
16975
+ _getEventId(cid) {
16976
16976
  // event ID 생성
16977
- return `ev_${uid}${this._eventMap[uid].length}`;
16977
+ return `ev_${cid}${this._eventMap[cid].length}`;
16978
16978
  }
16979
16979
  }
16980
16980
 
@@ -17018,12 +17018,12 @@
17018
17018
  }
17019
17019
  // 최초 생성 후 state에 등록 - created
17020
17020
  _addComponent(component) {
17021
- const uid = component._uid;
17022
- if (uid) {
17023
- this._componentMap[uid] = {
17021
+ const cid = component._cid;
17022
+ if (cid) {
17023
+ this._componentMap[cid] = {
17024
17024
  component: component,
17025
17025
  selector: component.$selector,
17026
- uid: uid,
17026
+ cid: cid,
17027
17027
  status: 'created'
17028
17028
  };
17029
17029
  }
@@ -17038,13 +17038,28 @@
17038
17038
  if (!_selector) {
17039
17039
  return undefined;
17040
17040
  }
17041
- Object.values(this._componentMap).forEach(n => {
17042
- // 동일한 selector 인지 비교
17043
- if (isEquals(n.uid, _selector) || isEquals(_selector.id, n.uid)) {
17041
+ // 1) cid 직접 조회 (string selector 인 경우)
17042
+ if (typeof selector === 'string' && this._componentMap[selector]) {
17043
+ _findComponent = this._componentMap[selector].component;
17044
+ _findComponent._status = this._componentMap[selector].status;
17045
+ return _findComponent;
17046
+ }
17047
+ // 2) data-component-id 기반 조회
17048
+ const dataCid = (_selector === null || _selector === void 0 ? void 0 : _selector.getAttribute) && _selector.getAttribute('data-component-id');
17049
+ if (dataCid && this._componentMap[dataCid]) {
17050
+ _findComponent = this._componentMap[dataCid].component;
17051
+ _findComponent._status = this._componentMap[dataCid].status;
17052
+ return _findComponent;
17053
+ }
17054
+ // 3) selector/element 비교 fallback
17055
+ Object.values(this._componentMap).some(n => {
17056
+ var _a;
17057
+ if (isEquals(n.selector, _selector) || isEquals((_a = n.component) === null || _a === void 0 ? void 0 : _a.$el, _selector)) {
17044
17058
  _findComponent = n.component;
17045
17059
  _findComponent._status = n.status;
17046
- return false;
17060
+ return true;
17047
17061
  }
17062
+ return false;
17048
17063
  });
17049
17064
  return _findComponent;
17050
17065
  }
@@ -17058,7 +17073,7 @@
17058
17073
  // 동일한 selector 인지 비교해서 동일한 component의 selector이면 제거 처리
17059
17074
  if (isEquals(n.selector, _selector)) {
17060
17075
  // componentMap에서 완전히 제거
17061
- delete this._componentMap[n.uid];
17076
+ delete this._componentMap[n.cid];
17062
17077
  // 컴포넌트 내부 참조도 제거 (메모리 누수 방지)
17063
17078
  if (n.component) {
17064
17079
  n.component = null;
@@ -17067,32 +17082,32 @@
17067
17082
  }
17068
17083
  });
17069
17084
  }
17070
- // 등록된 컴포넌트 제거 (uid 기반 - 더 효율적)
17071
- _removeComponentByUid(uid) {
17072
- if (!uid || !this._componentMap[uid]) {
17085
+ // 등록된 컴포넌트 제거 (cid 기반)
17086
+ _removeComponentByCid(cid) {
17087
+ if (!cid || !this._componentMap[cid]) {
17073
17088
  return;
17074
17089
  }
17075
17090
  // 컴포넌트 내부 참조 제거 (메모리 누수 방지)
17076
- const componentInfo = this._componentMap[uid];
17091
+ const componentInfo = this._componentMap[cid];
17077
17092
  if (componentInfo.component) {
17078
17093
  componentInfo.component = null;
17079
17094
  }
17080
17095
  componentInfo.selector = null;
17081
17096
  // componentMap에서 완전히 제거
17082
- delete this._componentMap[uid];
17097
+ delete this._componentMap[cid];
17083
17098
  }
17084
17099
  // 컴포넌트 life cycle에 따른 eventManager dispatch
17085
- _detectedCycle(uid, name) {
17100
+ _detectedCycle(cid, name) {
17086
17101
  // component 마지막 status 업데이트
17087
- if (this._componentMap[uid]) {
17088
- this._componentMap[uid].status = name;
17102
+ if (this._componentMap[cid]) {
17103
+ this._componentMap[cid].status = name;
17089
17104
  }
17090
- // event manager를 이용해 해당 uid 이벤트 dispatch
17105
+ // event manager를 이용해 해당 cid 이벤트 dispatch
17091
17106
  const eventManager = GNCoreEventManager.getInstance();
17092
17107
  // 호출 후
17093
- eventManager.cyclepatch(uid, name, '');
17108
+ eventManager.cyclepatch(cid, name, '');
17094
17109
  // 이벤트 해제 - life cycle 은 컴포넌트 별로 한번씩만 존재하므로..
17095
- eventManager.remove(uid, name);
17110
+ eventManager.remove(cid, name);
17096
17111
  }
17097
17112
  // document DOM observer 실행
17098
17113
  // - DOM 변환 이벤트 감지해서 removedNodes 가 생기면 해당 node와 일치하는 component를 찾아 제거한다.
@@ -17117,18 +17132,18 @@
17117
17132
  if (isElement$2(rm) && attr(rm, 'data-gnui')) {
17118
17133
  remove($('#' + attr(rm, 'data-gnui')));
17119
17134
  }
17120
- const childComponents = $$('[data-gn-uid]', rm);
17135
+ const childComponents = $$('[data-component-id]', rm);
17121
17136
  each(childComponents, (childComponent) => {
17122
17137
  if (isElement$2(childComponent)) {
17123
17138
  const findComponent = closerThis._getComponent($(childComponent));
17124
- if (findComponent && findComponent._uid && findComponent.$el && findComponent.$name !== 'modal') {
17125
- // $destroy 내부에서 removeAll과 _removeComponentByUid를 처리하므로 직접 호출만
17139
+ if (findComponent && findComponent._cid && findComponent.$el && findComponent.$name !== 'modal') {
17140
+ // $destroy 내부에서 removeAll과 _removeComponentByCid를 처리하므로 직접 호출만
17126
17141
  findComponent.$destroy(findComponent, false);
17127
17142
  }
17128
17143
  }
17129
17144
  });
17130
17145
  const findComponent = closerThis._getComponent($(rm));
17131
- if (findComponent && findComponent._uid && !((_a = findComponent.$el) === null || _a === void 0 ? void 0 : _a.parentNode) && findComponent.$name !== 'modal') {
17146
+ if (findComponent && findComponent._cid && !((_a = findComponent.$el) === null || _a === void 0 ? void 0 : _a.parentNode) && findComponent.$name !== 'modal') {
17132
17147
  findComponent.$destroy(findComponent, false);
17133
17148
  }
17134
17149
  });
@@ -17161,6 +17176,7 @@
17161
17176
  return generateUUID();
17162
17177
  };
17163
17178
  this._uid = ((_a = this.$options) === null || _a === void 0 ? void 0 : _a.id) || ((_b = this.$selector) === null || _b === void 0 ? void 0 : _b.id) || `${GN_CONSTANT.PREFIX}${uuid()}`;
17179
+ this._cid = `${GN_CONSTANT.PREFIX}${uuid()}`;
17164
17180
  }
17165
17181
  $reset() { }
17166
17182
  $init(component, options) {
@@ -17171,14 +17187,14 @@
17171
17187
  // component.$options.states => 사용자가 정의한 lifecycle callback handler
17172
17188
  this.$stateBind(component);
17173
17189
  // stateManager를 통해 beforeMount 상태 dispatch
17174
- stateManager._detectedCycle(component._uid, 'beforeMount');
17190
+ stateManager._detectedCycle(component._cid, 'beforeMount');
17175
17191
  this.$mount(component, this.$selector);
17176
17192
  this.$render(component.$options);
17177
17193
  // stateManager를 통해 beforeBind 상태 dispatch
17178
- stateManager._detectedCycle(component._uid, 'beforeBind');
17194
+ stateManager._detectedCycle(component._cid, 'beforeBind');
17179
17195
  this.$bind(component);
17180
17196
  // stateManager를 통해 completed 상태 dispatch
17181
- stateManager._detectedCycle(component._uid, 'completed');
17197
+ stateManager._detectedCycle(component._cid, 'completed');
17182
17198
  }
17183
17199
  $create(component, options) {
17184
17200
  // extend options
@@ -17240,7 +17256,7 @@
17240
17256
  const eventManager = GNCoreEventManager.getInstance();
17241
17257
  // lifecycle 관련 이벤트 add to eventManager
17242
17258
  GN_CONSTANT.LIFE_CYCLE.forEach((ev) => {
17243
- eventManager.stateAdd(component._uid, ev, (...args) => {
17259
+ eventManager.stateAdd(component._cid, ev, (...args) => {
17244
17260
  // 해당 life cycle 상태에 해당하는 함수가 각 컴포넌트 내부에 정의되어 있으면 호출한다.
17245
17261
  if (isFunction(component[ev])) {
17246
17262
  component[ev](args);
@@ -17285,13 +17301,17 @@
17285
17301
  if (tmpRole) {
17286
17302
  attr(this.$el, 'role', tmpRole);
17287
17303
  }
17288
- attr(this.$el, 'data-gn-uid', this._uid);
17304
+ attr(this.$el, 'data-component-id', this._cid);
17289
17305
  // inherit selector class
17290
17306
  selector.className && addClass(this.$el, selector.className);
17291
17307
  }
17292
17308
  else {
17293
17309
  this.$el = $(this.$selector);
17294
17310
  }
17311
+ // 항상 컴포넌트 cid를 DOM에 표시 (기존 DOM 사용 시에도)
17312
+ if (this.$el) {
17313
+ attr(this.$el, 'data-component-id', this._cid);
17314
+ }
17295
17315
  // delegates 바인딩
17296
17316
  each(this.$options.delegates, (val, key) => {
17297
17317
  if (isString(val)) {
@@ -17311,11 +17331,11 @@
17311
17331
  const eventManager = GNCoreEventManager.getInstance();
17312
17332
  each(events, (event, name) => {
17313
17333
  if (isFunction(event)) {
17314
- eventManager.add(this.$el, this._uid, event.name || name, event);
17334
+ eventManager.add(this.$el, this._cid, event.name || name, event);
17315
17335
  }
17316
17336
  else if (isPlainObject$1(event)) {
17317
17337
  const delegate = isFunction(event.delegate) ? event.delegate() : event.delegate;
17318
- eventManager.add(delegate, this._uid, event.name, event.handler);
17338
+ eventManager.add(delegate, this._cid, event.name, event.handler);
17319
17339
  }
17320
17340
  });
17321
17341
  }
@@ -17334,13 +17354,13 @@
17334
17354
  */
17335
17355
  async $event(component, name, ...params) {
17336
17356
  const eventManager = GNCoreEventManager.getInstance();
17337
- return eventManager.dispatch(component._uid, name, params);
17357
+ return eventManager.dispatch(component._cid, name, params);
17338
17358
  }
17339
17359
  $destroy(component = this, removeEl = true) {
17340
17360
  var _a;
17341
17361
  const stateManager = GNUIState.getInstance();
17342
17362
  // state manager 를 통해 destroy 상태 dispatch
17343
- stateManager._detectedCycle(component._uid, 'destroy');
17363
+ stateManager._detectedCycle(component._cid, 'destroy');
17344
17364
  // remove DOM (by removeEl)
17345
17365
  if (removeEl) {
17346
17366
  style(component.$el, 'display', 'none');
@@ -17350,11 +17370,11 @@
17350
17370
  component.$options._destroy();
17351
17371
  }
17352
17372
  // state manager 를 통해 destroy 상태 dispatch
17353
- stateManager._detectedCycle(component._uid, 'destroyed');
17373
+ stateManager._detectedCycle(component._cid, 'destroyed');
17354
17374
  // event manager 에서 등록 해제
17355
- GNCoreEventManager.getInstance().removeAll(component._uid);
17356
- // state manager에서 component 제거 (uid 기반으로 효율적 제거)
17357
- stateManager._removeComponentByUid(component._uid);
17375
+ GNCoreEventManager.getInstance().removeAll(component._cid);
17376
+ // state manager에서 component 제거 (cid 기반)
17377
+ stateManager._removeComponentByCid(component._cid);
17358
17378
  // 메모리 누수 방지: component의 모든 hasOwnProperty 제거
17359
17379
  // config, events, methods, _hidden 등 동적으로 추가된 속성 포함
17360
17380
  Object.keys(component).forEach((key) => {
@@ -33311,7 +33331,10 @@
33311
33331
  text: ''
33312
33332
  };
33313
33333
  }
33314
- this.$event(this, 'onChange', option.value, option.text, this.$options.value);
33334
+ // 기존 의미 유지: 클릭된 옵션 기준으로 value/text 전달
33335
+ const value = !isArray$1(option.value) ? String(option.value) : '';
33336
+ const text = option.text || (isArray$1(option === null || option === void 0 ? void 0 : option.cols) ? option.cols : value);
33337
+ this.$event(this, 'onChange', value, text, this.$options.value);
33315
33338
  },
33316
33339
  toggle: () => {
33317
33340
  if (this.$options.disabled) {
@@ -33407,18 +33430,33 @@
33407
33430
  const target = e instanceof Event ? $(e.currentTarget) : find(`[data-value=${option.value}]`, this.$el);
33408
33431
  e instanceof Event && e.stopPropagation();
33409
33432
  // toggle 처리
33433
+ const checkbox = find('input[type=checkbox]', target);
33410
33434
  if (hasClass(target, 'is-active')) {
33411
33435
  removeClass(target, 'is-active');
33412
- find('input[type=checkbox]', target).checked = false;
33436
+ if (checkbox) {
33437
+ checkbox.checked = false;
33438
+ }
33413
33439
  }
33414
33440
  else {
33415
33441
  addClass(target, 'is-active');
33416
- find('input[type=checkbox]', target).checked = true;
33442
+ if (checkbox) {
33443
+ checkbox.checked = true;
33444
+ }
33417
33445
  }
33418
33446
  const selected = findAll('.dropdown-item.is-active', this.$el).map((item) => data(item, 'data-value'));
33419
- this.$options.value = this.$options.data.filter((opt) => selected.includes(opt.value));
33447
+ this.$options.value = this.$options.data.filter((opt) => {
33448
+ // value가 배열이 아닌 경우에만 비교
33449
+ return !isArray$1(opt.value) && selected.includes(opt.value);
33450
+ });
33420
33451
  // text 표시
33421
- const selectText = this.$options.value.map((v) => v.text).join(',');
33452
+ // Implements [US-Rev-014] cols가 있는 경우 첫 번째 컬럼 값을 표시
33453
+ const selectText = this.$options.value.map((v) => {
33454
+ if (isArray$1(v === null || v === void 0 ? void 0 : v.cols)) {
33455
+ return v.cols[0];
33456
+ }
33457
+ // value가 배열이 아닌 경우에만 사용
33458
+ return v.text || (!isArray$1(v.value) ? String(v.value) : '');
33459
+ }).join(',');
33422
33460
  text$1(find('.dropdown-text', this.$el), selectText.length ? escapeEntity(selectText) : this.$options.textSets && this.$options.textSets.selectText ? this.$options.textSets.selectText : '');
33423
33461
  this._hidden.change(option);
33424
33462
  }
@@ -33440,9 +33478,21 @@
33440
33478
  }
33441
33479
  // text 표시
33442
33480
  const selectText = find('.dropdown-text', this.$el);
33443
- text$1(selectText, escapeEntity(option.text));
33481
+ // Implements [US-Rev-014] cols가 있는 경우 첫 번째 컬럼 값을 표시
33482
+ let displayText;
33483
+ if (isArray$1(option === null || option === void 0 ? void 0 : option.cols)) {
33484
+ displayText = option.cols[0];
33485
+ }
33486
+ else {
33487
+ // value가 배열이 아닌 경우에만 사용
33488
+ displayText = option.text || (!isArray$1(option.value) ? String(option.value) : '');
33489
+ }
33490
+ text$1(selectText, escapeEntity(displayText));
33444
33491
  // select 선택값 변경
33445
- targetSelect.value = option.value;
33492
+ // value 배열이 아닌 경우에만 설정
33493
+ if (!isArray$1(option.value)) {
33494
+ targetSelect.value = option.value;
33495
+ }
33446
33496
  trigger(targetSelect, 'change');
33447
33497
  this.$options.value = option;
33448
33498
  this._hidden.change(option);
@@ -33499,21 +33549,76 @@
33499
33549
  return;
33500
33550
  }
33501
33551
  findAll('.dropdown-item', this.$el).forEach((option) => {
33502
- if (!includes(data(option, 'value').toUpperCase(), q.toUpperCase()) && !includes(text$1(find('.dropdown-text', option)).toUpperCase(), q.toUpperCase())) {
33552
+ const itemValue = data(option, 'value');
33553
+ // value가 배열이 아닌 항목만 검색 대상으로 처리
33554
+ const rowData = this.$options.flatData.find((item) => {
33555
+ // value가 배열이 아닌 경우에만 비교
33556
+ return !isArray$1(item.value) && String(item.value) === itemValue;
33557
+ });
33558
+ let match = false;
33559
+ // Implements [US-Rev-014] 다중 컬럼 모드: cols 배열의 값들을 검색
33560
+ if (isArray$1(rowData === null || rowData === void 0 ? void 0 : rowData.cols)) {
33561
+ match = rowData.cols.some((colValue) => {
33562
+ return includes(String(colValue).toUpperCase(), q.toUpperCase());
33563
+ });
33564
+ // value 필드도 검색 대상에 포함 (배열이 아닌 경우에만)
33565
+ if (!match && rowData.value && !isArray$1(rowData.value)) {
33566
+ match = includes(String(rowData.value).toUpperCase(), q.toUpperCase());
33567
+ }
33568
+ }
33569
+ else if (rowData) {
33570
+ // 단일 컬럼 모드: text 또는 value 필드 검색
33571
+ const textValue = rowData.text || (!isArray$1(rowData.value) ? String(rowData.value) : '');
33572
+ const valueStr = !isArray$1(rowData.value) ? String(rowData.value) : '';
33573
+ match = includes(valueStr.toUpperCase(), q.toUpperCase()) || includes(textValue.toUpperCase(), q.toUpperCase());
33574
+ }
33575
+ else {
33576
+ // rowData를 찾지 못한 경우 (그룹화된 항목 등), DOM에서 직접 검색
33577
+ const textValue = text$1(find('.dropdown-text', option));
33578
+ match = includes(itemValue.toUpperCase(), q.toUpperCase()) || includes(textValue.toUpperCase(), q.toUpperCase());
33579
+ }
33580
+ if (!match) {
33503
33581
  css$1(option, 'display', 'none');
33504
33582
  }
33505
33583
  });
33506
33584
  },
33507
33585
  renderLabel: () => {
33508
- const _labelText = this.$options.value
33509
- ? isArray$1(this.$options.value)
33510
- ? this.$options.value.map((v) => v.text).join(',')
33511
- : this.$options.value.text
33512
- : this.$options.textSets && this.$options.textSets.selectText
33513
- ? this.$options.textSets.selectText
33514
- : this.$options.flatData.length
33515
- ? this.$options.flatData[0].text
33516
- : '';
33586
+ // Implements [US-Rev-014] cols가 있는 경우 첫 번째 컬럼 값을 표시
33587
+ let _labelText = '';
33588
+ if (this.$options.value) {
33589
+ if (isArray$1(this.$options.value)) {
33590
+ _labelText = this.$options.value.map((v) => {
33591
+ if (isArray$1(v === null || v === void 0 ? void 0 : v.cols)) {
33592
+ return v.cols[0];
33593
+ }
33594
+ // value가 배열이 아닌 경우에만 사용
33595
+ return v.text || (!isArray$1(v.value) ? String(v.value) : '');
33596
+ }).join(',');
33597
+ }
33598
+ else {
33599
+ const value = this.$options.value;
33600
+ if (isArray$1(value === null || value === void 0 ? void 0 : value.cols)) {
33601
+ _labelText = value.cols[0];
33602
+ }
33603
+ else {
33604
+ // value가 배열이 아닌 경우에만 사용
33605
+ _labelText = value.text || (!isArray$1(value.value) ? String(value.value) : '');
33606
+ }
33607
+ }
33608
+ }
33609
+ else if (this.$options.textSets && this.$options.textSets.selectText) {
33610
+ _labelText = this.$options.textSets.selectText;
33611
+ }
33612
+ else if (this.$options.flatData.length) {
33613
+ const firstItem = this.$options.flatData[0];
33614
+ if (isArray$1(firstItem === null || firstItem === void 0 ? void 0 : firstItem.cols)) {
33615
+ _labelText = firstItem.cols[0];
33616
+ }
33617
+ else {
33618
+ // value가 배열이 아닌 경우에만 사용
33619
+ _labelText = firstItem.text || (!isArray$1(firstItem.value) ? String(firstItem.value) : '');
33620
+ }
33621
+ }
33517
33622
  return createElement$1("span", { className: "dropdown-text" }, escapeEntity(_labelText));
33518
33623
  },
33519
33624
  renderSub: (data) => {
@@ -33523,24 +33628,43 @@
33523
33628
  if (this.$options.type === 'opened' && !items.length) {
33524
33629
  return createElement$1("div", { className: 'dropdown-nodata' }, this.$options.textSets.noData);
33525
33630
  }
33526
- return (createElement$1("ul", null, items.map((option, index) => (createElement$1("li", { id: this._uid + '_opt_' + index, className: 'dropdown-item' +
33527
- (option.text ? '' : ' is-unselectable') +
33528
- (this.$options.value &&
33529
- (isArray$1(this.$options.value) ? this.$options.value.find((v) => v.value === option.value) : option.value === this.$options.value.value)
33530
- ? ' is-active'
33531
- : '') +
33532
- (this.$options.multiple ? ' has-checkbox' : ''), "on-click": isArray$1(option.value) || !option.text ? null : this._hidden.select.bind(this, option), "data-value": isArray$1(option.value) ? '' : option.value, title: option.text ? escapeEntity(option.text) : '' },
33533
- createElement$1("span", { className: "dropdown-text", innerHTML: option.html ? option.html : '' },
33534
- option.html ? ('') : this.$options.multiple ? (createElement$1("div", { className: "gn-checks is-small is-no-padding" },
33535
- createElement$1("input", { type: "checkbox", id: this._uid + '_chk_' + index, defaultChecked: this.$options.value &&
33536
- (isArray$1(this.$options.value) ? this.$options.value.find((v) => v.value === option.value) : option.value === this.$options.value.value), disabled: this.$options.disabled }),
33537
- createElement$1("label", { for: this._uid + '_chk_' + index }, escapeEntity(option.text)))) : option.icon ? (createElement$1("span", null,
33538
- createElement$1("span", { className: 'gn-icon' + (this.$options.size ? ' is-' + this.$options.size : '') },
33539
- createElement$1("i", { className: (this.isBrandIcon(option.icon) ? 'fab' : 'fa') + ` fa-${option.icon}` })),
33540
- escapeEntity(option.text))) : (escapeEntity(option.text)),
33541
- isArray$1(option.value) && (createElement$1("span", { className: "gn-icon is-small submenu-icon" },
33542
- createElement$1("i", { className: "fas fa-angle-right" })))),
33543
- isArray$1(option.value) && this._hidden.renderSub(option.value))))));
33631
+ const hasCols = items.some((item) => !(item === null || item === void 0 ? void 0 : item.html) && isArray$1(item === null || item === void 0 ? void 0 : item.cols));
33632
+ return (createElement$1("ul", { className: hasCols ? 'is-cols' : '' }, items.map((option, index) => {
33633
+ const hasHtml = !!option.html;
33634
+ const hasColsData = isArray$1(option === null || option === void 0 ? void 0 : option.cols);
33635
+ const renderAsCols = !hasHtml && hasColsData;
33636
+ // html이 있으면 text가 있는 항목만 선택 가능
33637
+ // cols가 있으면 번째 컬럼을 displayText로 사용 (value 비어도 선택 가능)
33638
+ const displayText = hasHtml
33639
+ ? (option.text || '')
33640
+ : renderAsCols
33641
+ ? (option.cols && option.cols.length ? String(option.cols[0]) : '')
33642
+ : (option.text || (!isArray$1(option.value) ? String(option.value) : ''));
33643
+ return (createElement$1("li", { key: index, id: this._uid + '_opt_' + index, className: 'dropdown-item' +
33644
+ (renderAsCols ? ' dropdown-row' : '') +
33645
+ (displayText ? '' : ' is-unselectable') +
33646
+ (this.$options.value &&
33647
+ (isArray$1(this.$options.value) ? this.$options.value.find((v) => v.value === option.value) : option.value === this.$options.value.value)
33648
+ ? ' is-active'
33649
+ : '') +
33650
+ (this.$options.multiple ? ' has-checkbox' : ''), "on-click": isArray$1(option.value) || !displayText ? null : this._hidden.select.bind(this, option), "data-value": isArray$1(option.value) ? '' : option.value, title: displayText ? escapeEntity(String(displayText)) : '' },
33651
+ createElement$1("span", { className: "dropdown-text", innerHTML: option.html ? option.html : '' },
33652
+ option.html ? ('') : renderAsCols ? (createElement$1("div", { className: "gn-checks dropdown-cols" },
33653
+ this.$options.multiple && (createElement$1("div", { className: "is-small is-no-padding" },
33654
+ createElement$1("input", { type: "checkbox", id: this._uid + '_chk_' + index, defaultChecked: this.$options.value &&
33655
+ (isArray$1(this.$options.value) ? this.$options.value.find((v) => v.value === option.value) : option.value === this.$options.value.value), disabled: this.$options.disabled }),
33656
+ createElement$1("label", { for: this._uid + '_chk_' + index }))),
33657
+ option.cols.map((col, colIndex) => (createElement$1("span", { key: colIndex, className: "dropdown-col" }, escapeEntity(col)))))) : this.$options.multiple ? (createElement$1("div", { className: "gn-checks is-small is-no-padding" },
33658
+ createElement$1("input", { type: "checkbox", id: this._uid + '_chk_' + index, defaultChecked: this.$options.value &&
33659
+ (isArray$1(this.$options.value) ? this.$options.value.find((v) => v.value === option.value) : option.value === this.$options.value.value), disabled: this.$options.disabled }),
33660
+ createElement$1("label", { for: this._uid + '_chk_' + index }, escapeEntity(option.text || (!isArray$1(option.value) ? String(option.value) : ''))))) : option.icon ? (createElement$1("span", null,
33661
+ createElement$1("span", { className: 'gn-icon' + (this.$options.size ? ' is-' + this.$options.size : '') },
33662
+ createElement$1("i", { className: (this.isBrandIcon(option.icon) ? 'fab' : 'fa') + ` fa-${option.icon}` })),
33663
+ escapeEntity(option.text || (!isArray$1(option.value) ? String(option.value) : '')))) : (escapeEntity(option.text || (!isArray$1(option.value) ? String(option.value) : ''))),
33664
+ isArray$1(option.value) && (createElement$1("span", { className: "gn-icon is-small submenu-icon" },
33665
+ createElement$1("i", { className: "fas fa-angle-right" })))),
33666
+ isArray$1(option.value) && this._hidden.renderSub(option.value)));
33667
+ })));
33544
33668
  },
33545
33669
  flatData: () => {
33546
33670
  // data 검색 편의성을 위해 depth를 없앤 flatdata 생성
@@ -33578,11 +33702,17 @@
33578
33702
  : [String(this.$options.value)]; // 기타: 숫자 등
33579
33703
  this.$options.value = this.$options.flatData.filter((opt) => {
33580
33704
  const optValue = typeof opt.value === 'string' ? opt.value : String(opt.value);
33581
- return values.includes(optValue) && opt.text;
33705
+ // Implements [US-Rev-014] cols가 있으면 text 없어도 선택 가능
33706
+ return values.includes(optValue) && (opt.text || isArray$1(opt === null || opt === void 0 ? void 0 : opt.cols) || (!isArray$1(opt.value)));
33582
33707
  });
33583
33708
  }
33584
33709
  else {
33585
- this.$options.value = this.$options.flatData.find((opt) => opt.value + '' === this.$options.value + '' && opt.text);
33710
+ // Implements [US-Rev-014] cols가 있으면 text 없어도 선택 가능
33711
+ this.$options.value = this.$options.flatData.find((opt) => {
33712
+ const optValue = !isArray$1(opt.value) ? String(opt.value) : '';
33713
+ const compareValue = String(this.$options.value);
33714
+ return optValue === compareValue && (opt.text || isArray$1(opt === null || opt === void 0 ? void 0 : opt.cols) || optValue);
33715
+ });
33586
33716
  }
33587
33717
  }
33588
33718
  },
@@ -37156,9 +37286,11 @@
37156
37286
  isCheck = true;
37157
37287
  }
37158
37288
  return (createElement$1("div", { "on-click": (e) => {
37159
- !this.$options.disabled && this._hidden.selectRow.call(this, row, _index, e);
37289
+ var _a;
37290
+ ((_a = this === null || this === void 0 ? void 0 : this.$options) === null || _a === void 0 ? void 0 : _a.onSelect) && !this.$options.disabled && this._hidden.selectRow.call(this, row, _index, e);
37160
37291
  }, "on-dblclick": (e) => {
37161
- !this.$options.disabled && this._hidden.doubleSelect.call(this, row, _index, e);
37292
+ var _a;
37293
+ ((_a = this === null || this === void 0 ? void 0 : this.$options) === null || _a === void 0 ? void 0 : _a.onDoubleClick) && !this.$options.disabled && this._hidden.doubleSelect.call(this, row, _index, e);
37162
37294
  }, className: 'gn-datagrid-body-row' + (hasChild ? ' has-child' : '') + (row.isOpened ? '' : ' is-collapsed') + (depth > 0 && !isOpened ? ' is-hidden' : '') + (row.color ? ` ${row.color}` : ''), style: {
37163
37295
  'grid-template-columns': this._columnsTemplate.join(' ')
37164
37296
  }, id: this._uid + '-row-' + _index, "data-depth": depth }, columns.map((col, idx) => {
@@ -37209,11 +37341,11 @@
37209
37341
  (col.bodyClass ? col.bodyClass : col.className ? col.className : '') +
37210
37342
  (isFunction(col.onSelect) ? ' is-selectable' : '') +
37211
37343
  (col.isHidden ? ' is-unvisible' : ''), "data-key": col.key, style: cellStyle, "on-click": (e) => {
37212
- !this.$options.disabled && this._hidden.selectCell.call(this, col, row, _index, e);
37344
+ col.onSelect && !this.$options.disabled && this._hidden.selectCell.call(this, col, row, _index, e);
37213
37345
  }, "on-mouseenter": (e) => {
37214
- !this.$options.disabled && this._hidden.hoverCell.call(this, col, row, _index, e);
37346
+ col.onHover && !this.$options.disabled && this._hidden.hoverCell.call(this, col, row, _index, e);
37215
37347
  }, "on-mouseleave": (e) => {
37216
- this._hidden.blurCell.call(this, col, row, _index, e);
37348
+ col.offHover && this._hidden.blurCell.call(this, col, row, _index, e);
37217
37349
  }, title: col.tipField && row[col.tipField] ? row[col.tipField] : !col.template && row[col.key] ? row[col.key] : '' }, this._hidden.renderCell(row, col, idx, hasChild, isCheck, _index)));
37218
37350
  })));
37219
37351
  },
@@ -37899,7 +38031,7 @@
37899
38031
  color: (this.$options.readonly ? 'info' : 'cancel')
37900
38032
  };
37901
38033
  return (createElement$1("div", { "on-dblclick": (e) => {
37902
- this._hidden.doubleSelect.call(this, row, _index, e);
38034
+ this.$options.onDoubleClick && this._hidden.doubleSelect.call(this, row, _index, e);
37903
38035
  }, id: this._uid + '-row-' + _index, className: 'gn-datalist-body-row' + (hasChild ? ' has-child' : '') + (row.isOpened ? '' : ' is-collapsed') + (row.isSelectedRow ? ' is-active' : '') + (depth > 0 && !isOpened ? ' is-hidden' : ''), "data-depth": depth, style: { cursor: this.$options.onSelect ? 'pointer' : 'default' } },
37904
38036
  createElement$1("ol", { className: 'gn-datalist-ol-container' }, columns.map((col, idx) => {
37905
38037
  const cellStyle = {};
@@ -37928,9 +38060,9 @@
37928
38060
  (col.bodyClass ? col.bodyClass : col.className ? col.className : '') +
37929
38061
  (isFunction(col.onSelect) ? ' is-selectable' : '') +
37930
38062
  (col.isHidden ? ' is-unvisible' : ''), style: cellStyle, "on-mouseenter": (e) => {
37931
- this._hidden.hoverCell.call(this, col, row, _index, e);
38063
+ col.onHover && this._hidden.hoverCell.call(this, col, row, _index, e);
37932
38064
  }, "on-mouseleave": (e) => {
37933
- this._hidden.blurCell.call(this, col, row, _index, e);
38065
+ col.offHover && this._hidden.blurCell.call(this, col, row, _index, e);
37934
38066
  }, title: !col.template && row[col.key] ? row[col.key] : '' }, this._hidden.renderCell(row, col, idx, hasChild)))));
37935
38067
  })),
37936
38068
  createElement$1("div", { id: this._uid + '-btn-' + index, className: "gn-datalist-btn-container" },
@@ -39205,6 +39337,7 @@
39205
39337
 
39206
39338
  class MenuButton extends GNCoreInstance {
39207
39339
  constructor(name, selector, options = {}) {
39340
+ var _a, _b, _c, _d;
39208
39341
  super(name, selector, options);
39209
39342
  this._hidden = {
39210
39343
  open: () => {
@@ -39216,7 +39349,9 @@
39216
39349
  removeClass(this.$el, 'is-open');
39217
39350
  },
39218
39351
  select: (menu, e) => {
39219
- this.$event(this, 'onSelect', menu.value, menu.text, menu, e);
39352
+ // cols만 있고 text 없는 경우 cols[0]을 text로 사용 (호환성 유지)
39353
+ const menuText = menu.text || (isArray$1(menu === null || menu === void 0 ? void 0 : menu.cols) ? menu.cols[0] : menu.value || '');
39354
+ this.$event(this, 'onSelect', menu.value, menuText, menu, e);
39220
39355
  this._hidden.close();
39221
39356
  },
39222
39357
  changeText: (buttonText) => {
@@ -39251,12 +39386,16 @@
39251
39386
  // 부모 경로를 포함한 고유한 ID 생성
39252
39387
  const currentPath = parentPath ? `${parentPath}-${index}` : `${index}`;
39253
39388
  const uniqueId = `${this._uid}-${currentPath}`;
39389
+ const hasColsData = isArray$1(menu === null || menu === void 0 ? void 0 : menu.cols);
39390
+ const renderAsCols = !hasHtml && hasColsData;
39391
+ const canSelect = !hasHtml || !!menu.text;
39254
39392
  return (createElement$1("li", { id: uniqueId, className: 'menuButton-menu' +
39255
39393
  (this.$options.align ? ' has-text-' + this.$options.align : '') +
39256
39394
  (canRenderChild ? ' has-submenu' : '') +
39257
39395
  (depth > 0 ? ' is-submenu-item' : '') +
39258
39396
  (isDisabled ? ' is-disabled' : '') +
39259
- (isActived ? ' is-actived' : ''), "on-click": (e) => {
39397
+ (isActived ? ' is-actived' : '') +
39398
+ (renderAsCols ? ' has-cols' : ''), "on-click": (e) => {
39260
39399
  // disabled 상태이거나 자식 메뉴가 있는 경우 클릭 이벤트 처리하지 않음
39261
39400
  if (isDisabled) {
39262
39401
  e.stopPropagation();
@@ -39265,12 +39404,16 @@
39265
39404
  }
39266
39405
  // 자식 메뉴가 없는 경우에만 select 이벤트 발생
39267
39406
  if (!canRenderChild) {
39407
+ if (!canSelect) {
39408
+ e.stopPropagation();
39409
+ return;
39410
+ }
39268
39411
  e.stopPropagation();
39269
39412
  this._hidden.select.call(this, menu, e);
39270
39413
  }
39271
39414
  }, innerHTML: hasHtml ? menu.html : '' },
39272
- hasHtml ? ('') : (createElement$1("span", { className: "menuButton-menu-content" },
39273
- createElement$1("span", { className: "menuButton-menu-text" }, menu.text),
39415
+ hasHtml ? ('') : renderAsCols ? (createElement$1("div", { className: "menubutton-cols" }, menu.cols.map((col, colIndex) => (createElement$1("span", { key: colIndex, className: "menubutton-col" }, escapeEntity(col)))))) : (createElement$1("span", { className: "menuButton-menu-content" },
39416
+ createElement$1("span", { className: "menuButton-menu-text" }, menu.text || menu.value || ''),
39274
39417
  canRenderChild && (createElement$1("span", { className: "menuButton-menu-arrow" },
39275
39418
  createElement$1("i", { className: "fas fa-caret-right" }))))),
39276
39419
  canRenderChild && this._hidden.renderMenus.call(this, menu.child, depth + 1, currentPath)));
@@ -39282,9 +39425,11 @@
39282
39425
  };
39283
39426
  this.config = {
39284
39427
  textSets: {
39285
- buttonText: this.$selector.textContent
39428
+ buttonText: ((_a = this.$selector) === null || _a === void 0 ? void 0 : _a.cols)
39429
+ ? (isArray$1(this.$selector.cols) ? this.$selector.cols.join(', ') : String(this.$selector.cols))
39430
+ : (((_b = this.$selector) === null || _b === void 0 ? void 0 : _b.textContent) || ((_c = this.$selector) === null || _c === void 0 ? void 0 : _c.text) || '')
39286
39431
  },
39287
- name: this.$selector.name,
39432
+ name: (_d = this.$selector) === null || _d === void 0 ? void 0 : _d.name,
39288
39433
  data: [],
39289
39434
  align: 'left'
39290
39435
  };
@@ -39562,9 +39707,27 @@
39562
39707
  return;
39563
39708
  }
39564
39709
  findAll(`.picklist-${obj} .dropdown-item`, this.$el).forEach((option) => {
39565
- if (!includes(data(option, 'value').toUpperCase(), q.toUpperCase()) && !includes(text$1(find('.dropdown-text', option)).toUpperCase(), q.toUpperCase())) {
39710
+ const itemValue = data(option, 'value');
39711
+ const rowData = this.$options.data[obj].find((item) => item.value === itemValue);
39712
+ let match = false;
39713
+ // Implements [US-Rev-023] 다중 컬럼 모드: cols 배열의 값들을 검색
39714
+ if (isArray$1(rowData === null || rowData === void 0 ? void 0 : rowData.cols)) {
39715
+ match = rowData.cols.some((colValue) => {
39716
+ return includes(String(colValue).toUpperCase(), q.toUpperCase());
39717
+ });
39718
+ // value 필드도 검색 대상에 포함
39719
+ if (!match && rowData.value) {
39720
+ match = includes(String(rowData.value).toUpperCase(), q.toUpperCase());
39721
+ }
39722
+ }
39723
+ else {
39724
+ // 단일 컬럼 모드: text 또는 value 필드 검색
39725
+ const textValue = text$1(find('.dropdown-text', option));
39726
+ match = includes(data(option, 'value').toUpperCase(), q.toUpperCase()) || includes(textValue.toUpperCase(), q.toUpperCase());
39727
+ }
39728
+ if (!match) {
39566
39729
  css$1(option, 'display', 'none');
39567
- this.$options.data[`filtered-${obj}`] = this.$options.data[`filtered-${obj}`].filter((e) => e.value !== option.dataset.value);
39730
+ this.$options.data[`filtered-${obj}`] = this.$options.data[`filtered-${obj}`].filter((e) => e.value !== itemValue);
39568
39731
  }
39569
39732
  });
39570
39733
  },
@@ -39673,9 +39836,20 @@
39673
39836
  isArray$1(addArr) &&
39674
39837
  addArr.forEach((option) => {
39675
39838
  const _index = source.findIndex((select) => {
39676
- return option.value === select.value && option.text === select.text;
39839
+ const valueMatch = option.value === select.value;
39840
+ if (isArray$1(option === null || option === void 0 ? void 0 : option.cols)) {
39841
+ if (!isArray$1(select === null || select === void 0 ? void 0 : select.cols) || select.cols.length !== option.cols.length) {
39842
+ return false;
39843
+ }
39844
+ const colsMatch = option.cols.every((col, idx) => col === select.cols[idx]);
39845
+ return valueMatch && colsMatch;
39846
+ }
39847
+ return valueMatch && option.text === select.text;
39677
39848
  });
39678
- target.push(source.splice(_index, 1).pop());
39849
+ // 매칭 실패 시 (_index === -1) 마지막 항목이 제거되는 것을 방지
39850
+ if (_index >= 0) {
39851
+ target.push(source.splice(_index, 1).pop());
39852
+ }
39679
39853
  });
39680
39854
  },
39681
39855
  reRender: (obj) => {
@@ -39685,21 +39859,32 @@
39685
39859
  },
39686
39860
  renderSub: (item) => {
39687
39861
  const items = this.$options.data[item] || [];
39688
- return (createElement$1("ul", null, items.map((option, index) => {
39862
+ const hasColsForList = items.some((item) => !(item === null || item === void 0 ? void 0 : item.html) && isArray$1(item === null || item === void 0 ? void 0 : item.cols));
39863
+ return (createElement$1("ul", { className: hasColsForList ? 'is-cols' : '' }, items.map((option, index) => {
39689
39864
  var _a;
39690
- return (createElement$1("li", { id: this._uid + '_opt_' + index, className: 'dropdown-item' + (option.selected ? ' is-active' : ''), "data-value": option.value, "on-click": !option.text ? null : this._hidden.toggle.bind(this), "on-dblclick": !option.text
39865
+ const hasHtml = !!option.html;
39866
+ const hasColsData = isArray$1(option === null || option === void 0 ? void 0 : option.cols);
39867
+ const renderAsCols = !hasHtml && hasColsData;
39868
+ // html이 있으면 text가 있는 항목만 선택 가능
39869
+ // cols가 있으면 첫 번째 컬럼을 displayText로 사용 (value가 비어도 선택 가능)
39870
+ const displayText = hasHtml
39871
+ ? (option.text || '')
39872
+ : renderAsCols
39873
+ ? (option.cols && option.cols.length ? String(option.cols[0]) : '')
39874
+ : (option.text || option.value);
39875
+ return (createElement$1("li", { key: index, id: this._uid + '_opt_' + index, className: 'dropdown-item' + (renderAsCols ? ' picklist-row' : '') + (option.selected ? ' is-active' : ''), "data-value": option.value, "on-click": !displayText ? null : this._hidden.toggle.bind(this), "on-dblclick": !displayText
39691
39876
  ? null
39692
39877
  : this._hidden.move.bind(this, item === 'source' ? 'add' : 'remove', [
39693
39878
  {
39694
39879
  value: option.value,
39695
- text: option.text,
39880
+ text: renderAsCols ? undefined : option.text,
39881
+ cols: hasColsData ? option.cols : undefined,
39696
39882
  html: (_a = option.html) !== null && _a !== void 0 ? _a : null
39697
39883
  }
39698
- ]) },
39699
- createElement$1("span", { className: "dropdown-text", innerHTML: option.html ? option.html : '' }, option.html ? ('') : option.icon ? (createElement$1("span", null,
39700
- createElement$1("span", { className: 'gn-icon' + (this.$options.size ? ' is-' + this.$options.size : '') },
39701
- createElement$1("i", { className: (this.isBrandIcon(option.icon) ? 'fab' : 'fa') + ` fa-${option.icon}` })),
39702
- escapeEntity(option.text))) : (escapeEntity(option.text)))));
39884
+ ]) }, hasHtml ? (createElement$1("span", { className: "dropdown-text", innerHTML: option.html })) : renderAsCols ? (createElement$1("div", { className: "picklist-cols" }, option.cols.map((col, colIndex) => (createElement$1("span", { key: colIndex, className: "picklist-col" }, escapeEntity(col)))))) : (createElement$1("span", { className: "dropdown-text" }, option.icon ? (createElement$1("span", null,
39885
+ createElement$1("span", { className: 'gn-icon' + (this.$options.size ? ' is-' + this.$options.size : '') },
39886
+ createElement$1("i", { className: (this.isBrandIcon(option.icon) ? 'fab' : 'fa') + ` fa-${option.icon}` })),
39887
+ escapeEntity(option.text || option.value))) : (escapeEntity(option.text || option.value))))));
39703
39888
  })));
39704
39889
  },
39705
39890
  getSelection: (target) => {
@@ -40836,19 +41021,32 @@
40836
41021
  findAll('.is-checker', parents(target, 'li')[0]).forEach((c) => {
40837
41022
  c.checked = target.checked;
40838
41023
  });
40839
- if (this.$options.checkPath && target.checked) {
41024
+ if (this.$options.checkPath) {
40840
41025
  parents(target, 'ul')
40841
41026
  .map((list) => siblings(list, '.tree-item').pop())
40842
41027
  .filter((item) => item)
40843
41028
  .forEach((item) => {
40844
- find('.is-checker', item).checked = true;
41029
+ const parentChecker = find('.is-checker', item);
41030
+ if (!parentChecker) {
41031
+ return;
41032
+ }
41033
+ const parentLi = parents(item, 'li')[0];
41034
+ if (!parentLi) {
41035
+ return;
41036
+ }
41037
+ // 자식 중 하나라도 체크면 부모 체크, 전부 해제되면 부모도 해제
41038
+ const descendantCheckers = findAll('.is-checker', parentLi).filter((checker) => checker !== parentChecker);
41039
+ if (!descendantCheckers.length) {
41040
+ return;
41041
+ }
41042
+ parentChecker.checked = descendantCheckers.some((checker) => checker.checked);
40845
41043
  });
40846
41044
  }
40847
41045
  this.$event(this, 'onCheck', item, target.checked, this._hidden.getItemIndex(target), e);
40848
41046
  },
40849
- checkAll: () => {
41047
+ checkAll: (isChecked) => {
40850
41048
  findAll('.is-checker', this.$el).forEach((c) => {
40851
- c.checked = true;
41049
+ c.checked = isChecked;
40852
41050
  });
40853
41051
  },
40854
41052
  getChecked: (withStatus = false) => {
@@ -41026,7 +41224,14 @@
41026
41224
  this._hidden.collapseAll();
41027
41225
  },
41028
41226
  checkAll() {
41029
- this._hidden.checkAll();
41227
+ if (!this.$options.hasCheck)
41228
+ return;
41229
+ this._hidden.checkAll(true);
41230
+ },
41231
+ uncheckAll() {
41232
+ if (!this.$options.hasCheck)
41233
+ return;
41234
+ this._hidden.checkAll(false);
41030
41235
  },
41031
41236
  getChecked(withStatus = false) {
41032
41237
  return this._hidden.getChecked(withStatus);