gnui 1.2.20 → 1.2.21

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 (79) hide show
  1. package/@types/gnui.d.ts +8 -0
  2. package/dist/js/gnui.esm.js +528 -149
  3. package/dist/js/gnui.js +528 -149
  4. package/dist/js/gnui.min.js +6 -6
  5. package/dist/styles/default.css +144 -0
  6. package/dist/styles/gpi.css +144 -0
  7. package/dist/styles/green24.css +145 -1
  8. package/dist/styles/insights.css +144 -0
  9. package/dist/styles/nac.css +144 -0
  10. package/dist/styles/ztnac.css +145 -1
  11. package/package.json +7 -2
  12. package/styleguide/assets/components.js +155 -9
  13. package/styleguide/assets/js/gnui.js +528 -149
  14. package/styleguide/assets/js/gnui.min.js +6 -6
  15. package/styleguide/assets/styles/default.css +144 -0
  16. package/styleguide/assets/styles/gpi.css +144 -0
  17. package/styleguide/assets/styles/green24.css +145 -1
  18. package/styleguide/assets/styles/insights.css +144 -0
  19. package/styleguide/assets/styles/nac.css +144 -0
  20. package/styleguide/assets/styles/ztnac.css +145 -1
  21. package/styleguide/category/COLOR/index.html +1 -1
  22. package/styleguide/category/COMPONENT/Alert(js)/index.html +1 -1
  23. package/styleguide/category/COMPONENT/Bignumber/index.html +1 -1
  24. package/styleguide/category/COMPONENT/Breadcrumb/index.html +1 -1
  25. package/styleguide/category/COMPONENT/Calendar(js)/index.html +1 -1
  26. package/styleguide/category/COMPONENT/Card/index.html +1 -1
  27. package/styleguide/category/COMPONENT/Chart(js)/index.html +1 -1
  28. package/styleguide/category/COMPONENT/Datagrid(js)/index.html +109 -11
  29. package/styleguide/category/COMPONENT/Datalist(js)/index.html +1 -1
  30. package/styleguide/category/COMPONENT/Growl(js)/index.html +1 -1
  31. package/styleguide/category/COMPONENT/JsonView(js)/index.html +1 -1
  32. package/styleguide/category/COMPONENT/Loader(js)/index.html +1 -1
  33. package/styleguide/category/COMPONENT/MenuButton(js)/index.html +1 -1
  34. package/styleguide/category/COMPONENT/Message(js)/index.html +1 -1
  35. package/styleguide/category/COMPONENT/Modal(js)/index.html +31 -1
  36. package/styleguide/category/COMPONENT/Pagination(js)/index.html +1 -1
  37. package/styleguide/category/COMPONENT/Panel/index.html +1 -1
  38. package/styleguide/category/COMPONENT/Progressbar(js)/index.html +1 -1
  39. package/styleguide/category/COMPONENT/Tab(js)/index.html +1 -1
  40. package/styleguide/category/COMPONENT/Tagcloud(js)/index.html +1 -1
  41. package/styleguide/category/COMPONENT/Tooltip(js)/index.html +1 -1
  42. package/styleguide/category/COMPONENT/Tree(js)/index.html +83 -19
  43. package/styleguide/category/CONTROLS/Button(js)/index.html +1 -1
  44. package/styleguide/category/CONTROLS/Checkbox/index.html +1 -1
  45. package/styleguide/category/CONTROLS/Colorpicker(js)/index.html +1 -1
  46. package/styleguide/category/CONTROLS/Datepicker(js)/index.html +1 -1
  47. package/styleguide/category/CONTROLS/Dropdown(js)/index.html +1 -1
  48. package/styleguide/category/CONTROLS/File/index.html +1 -1
  49. package/styleguide/category/CONTROLS/Form/Control/index.html +1 -1
  50. package/styleguide/category/CONTROLS/Form/Field/index.html +53 -1
  51. package/styleguide/category/CONTROLS/Form/Plain/index.html +1 -1
  52. package/styleguide/category/CONTROLS/Input/index.html +1 -1
  53. package/styleguide/category/CONTROLS/MultiText(js)/index.html +32 -1
  54. package/styleguide/category/CONTROLS/Picklist(js)/index.html +1 -1
  55. package/styleguide/category/CONTROLS/Radio/index.html +1 -1
  56. package/styleguide/category/CONTROLS/Select/index.html +1 -1
  57. package/styleguide/category/CONTROLS/SelectButton(js)/index.html +1 -1
  58. package/styleguide/category/CONTROLS/Slider/index.html +1 -1
  59. package/styleguide/category/CONTROLS/SortableList(js)/index.html +1 -1
  60. package/styleguide/category/CONTROLS/Switch(js)/index.html +1 -1
  61. package/styleguide/category/CONTROLS/SyntaxInput(js)/index.html +1 -1
  62. package/styleguide/category/CONTROLS/Textarea/index.html +1 -1
  63. package/styleguide/category/CONTROLS/Time(js)/index.html +1 -1
  64. package/styleguide/category/ELEMENTS/Box/index.html +1 -1
  65. package/styleguide/category/ELEMENTS/Icon/index.html +1 -1
  66. package/styleguide/category/ELEMENTS/Image/index.html +1 -1
  67. package/styleguide/category/ELEMENTS/List/index.html +1 -1
  68. package/styleguide/category/ELEMENTS/Table/index.html +1 -1
  69. package/styleguide/category/ELEMENTS/Tag/index.html +1 -1
  70. package/styleguide/category/ELEMENTS/Title/index.html +1 -1
  71. package/styleguide/category/LAYOUT/Container/index.html +1 -1
  72. package/styleguide/category/LAYOUT/Grid/index.html +1 -1
  73. package/styleguide/category/LAYOUT/Splitter(js)/index.html +1 -1
  74. package/styleguide/category/UTILITY/index.html +9 -2
  75. package/styleguide/category/Utils/index.html +1 -1
  76. package/styleguide/color.html +1 -1
  77. package/styleguide/index.html +1 -1
  78. package/styleguide/tag/javascript/index.html +252 -29
  79. package/styleguide/tag/v.0.1.0/index.html +312 -30
@@ -34549,7 +34549,7 @@ class Chart extends GNCoreInstance {
34549
34549
  const newOptions = merge(this.chartDefault, merge(chartOptions, typesDefault[this.$options.type] || {}));
34550
34550
  if (!newOptions.theme) {
34551
34551
  newOptions.theme = {
34552
- palette: 'palette4'
34552
+ palette: 'palette1'
34553
34553
  };
34554
34554
  }
34555
34555
  this.$options.chart = new ApexCharts$1(this.$el, newOptions);
@@ -37219,6 +37219,13 @@ class DataGrid extends GNCoreInstance {
37219
37219
  this.$event(this, 'onSort', column);
37220
37220
  },
37221
37221
  renderHeader: (columns, isReset = false) => {
37222
+ if (this._isHorizontalState()) {
37223
+ return (createElement$1("div", { className: "gn-datagrid-header-row is-horizontal" },
37224
+ createElement$1("div", { className: "gn-datagrid-header-cell is-horizontal" }, this.$options.hasCheck && (createElement$1("label", { className: "gn-checkbox is-no-padding", style: { width: '20px' } },
37225
+ createElement$1("input", { type: "checkbox", className: "is-allChecker", id: this._uid + '-rows-check', "on-click": (e) => {
37226
+ this._hidden.checkAll.call(this, e);
37227
+ }, disabled: this.$options.disabled }))))));
37228
+ }
37222
37229
  this._setColumnsTemplate(isReset);
37223
37230
  return (createElement$1("div", { className: "gn-datagrid-header-row", style: {
37224
37231
  'grid-template-columns': this._columnsTemplate.join(' ')
@@ -37259,15 +37266,24 @@ class DataGrid extends GNCoreInstance {
37259
37266
  },
37260
37267
  renderBody: (data, columns) => {
37261
37268
  // 헤더가 숨겨진 경우에도 body 렌더 전에 템플릿 폭을 준비한다
37262
- if (!this._columnsTemplate || !this._columnsTemplate.length) {
37269
+ if (!this._isHorizontalState() && (!this._columnsTemplate || !this._columnsTemplate.length)) {
37263
37270
  this._setColumnsTemplate();
37264
37271
  }
37265
37272
  rowIdx$1 = 0;
37266
- return (createElement$1("div", { className: "gn-datagrid-body", style: {
37273
+ return (createElement$1("div", { className: 'gn-datagrid-body' + (this._isHorizontalState() ? ' is-horizontal' : ''), style: {
37274
+ 'grid-template-columns': this._isHorizontalState()
37275
+ ? this._orientationState.columns === 'auto-fit'
37276
+ ? `repeat(auto-fit, minmax(${this._orientationState.minWidth}, 1fr))`
37277
+ : `repeat(${this._orientationState.columns}, minmax(0, 1fr))`
37278
+ : '',
37279
+ gap: this._isHorizontalState() ? this._orientationState.gap : '',
37267
37280
  maxHeight: this.$options.bodyHeight ? this.$options.bodyHeight : 'auto'
37268
37281
  } }, (data === null || data === void 0 ? void 0 : data.length) ? this._hidden.renderRows(data, columns) : this._hidden.renderNodata()));
37269
37282
  },
37270
37283
  renderRows: (rows, columns, depth = 0, isOpen = false) => {
37284
+ if (this._isHorizontalState()) {
37285
+ return rows.map((row) => this._hidden.renderRow(row, columns, 0, false, false));
37286
+ }
37271
37287
  return rows.map((row) => {
37272
37288
  return row[this.$options.childField] && isArray$1(row[this.$options.childField])
37273
37289
  ? [this._hidden.renderRow(row, columns, depth, true, isOpen), this._hidden.renderRows(row[this.$options.childField], columns, depth + 1, row.isOpened)]
@@ -37276,6 +37292,23 @@ class DataGrid extends GNCoreInstance {
37276
37292
  },
37277
37293
  renderRow: (row, columns, depth = 0, hasChild, isOpened, isCheck = false) => {
37278
37294
  const _index = rowIdx$1++;
37295
+ const getHorizontalRowClass = () => {
37296
+ if (!this._isHorizontalState() || this._orientationState.columns === 'auto-fit') {
37297
+ return '';
37298
+ }
37299
+ const classes = ['is-horizontal'];
37300
+ if (_index % this._orientationState.columns === 0) {
37301
+ classes.push('is-horizontal-first-col');
37302
+ }
37303
+ if ((_index + 1) % this._orientationState.columns === 0 || _index === this.$options.data.length - 1) {
37304
+ classes.push('is-horizontal-last-col');
37305
+ }
37306
+ if (_index < this._orientationState.columns) {
37307
+ classes.push('is-horizontal-first-row');
37308
+ }
37309
+ return ' ' + classes.join(' ');
37310
+ };
37311
+ const horizontalClass = getHorizontalRowClass();
37279
37312
  if (row.isChecked) {
37280
37313
  isCheck = true;
37281
37314
  }
@@ -37285,76 +37318,114 @@ class DataGrid extends GNCoreInstance {
37285
37318
  }, "on-dblclick": (e) => {
37286
37319
  var _a;
37287
37320
  ((_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);
37288
- }, className: 'gn-datagrid-body-row' + (hasChild ? ' has-child' : '') + (row.isOpened ? '' : ' is-collapsed') + (depth > 0 && !isOpened ? ' is-hidden' : '') + (row.color ? ` ${row.color}` : ''), style: {
37289
- 'grid-template-columns': this._columnsTemplate.join(' ')
37290
- }, id: this._uid + '-row-' + _index, "data-depth": depth }, columns.map((col, idx) => {
37291
- const cellStyle = {};
37292
- if (col.bodyStyle || col.style) {
37293
- each(col.bodyStyle || col.style, (value, key) => {
37294
- if (key !== 'width') {
37295
- cellStyle[key] = value;
37296
- }
37297
- });
37298
- }
37299
- if (idx === 0 && depth !== 0) {
37300
- cellStyle.paddingLeft = depth * 15 + 10 + 'px';
37301
- }
37302
- if (isIE) {
37303
- cellStyle.display = 'inline-block';
37304
- }
37305
- if (col.key === 'btnOrder') {
37306
- cellStyle.display = 'flex';
37307
- cellStyle.padding = '0';
37308
- cellStyle['justify-content'] = 'space-evenly';
37309
- cellStyle['align-items'] = 'center';
37310
- return (createElement$1("div", { className: 'gn-datagrid-body-cell btn-container ' + (col.key ? col.key : ''), style: cellStyle, "on-click": (e) => {
37311
- this._hidden.stopRowSelectEvent(e);
37312
- } },
37313
- createElement$1("span", { className: 'gn-icon btn-order ' + (_index == 0 ? 'is-cancel' : 'is-info'), "on-click": () => {
37314
- !this.$options.disabled && this._hidden.moveRowUp.call(this, _index);
37315
- } },
37316
- createElement$1("i", { className: "fas fa-arrow-circle-up" })),
37317
- createElement$1("span", { className: 'gn-icon btn-order ' + (_index == this.$options.data.length - 1 ? 'is-cancel' : 'is-info'), "on-click": () => {
37318
- !this.$options.disabled && this._hidden.moveRowDown.call(this, _index);
37321
+ }, className: 'gn-datagrid-body-row' +
37322
+ (hasChild ? ' has-child' : '') +
37323
+ (row.isOpened ? '' : ' is-collapsed') +
37324
+ (depth > 0 && !isOpened ? ' is-hidden' : '') +
37325
+ (row.color ? ` ${row.color}` : '') +
37326
+ horizontalClass, style: {
37327
+ 'grid-template-columns': this._isHorizontalState() ? '' : this._columnsTemplate.join(' ')
37328
+ }, id: this._uid + '-row-' + _index, "data-depth": depth },
37329
+ this._isHorizontalState() && this._hidden.renderHorizontalCardHeader(row, _index, hasChild, isCheck),
37330
+ columns.map((col, idx) => {
37331
+ const cellStyle = {};
37332
+ if (col.bodyStyle || col.style) {
37333
+ each(col.bodyStyle || col.style, (value, key) => {
37334
+ if (key !== 'width') {
37335
+ cellStyle[key] = value;
37336
+ }
37337
+ });
37338
+ }
37339
+ if (idx === 0 && depth !== 0) {
37340
+ cellStyle.paddingLeft = depth * 15 + 10 + 'px';
37341
+ }
37342
+ if (isIE) {
37343
+ cellStyle.display = 'inline-block';
37344
+ }
37345
+ if (col.key === 'btnOrder') {
37346
+ cellStyle.display = 'flex';
37347
+ cellStyle.padding = '0';
37348
+ cellStyle['justify-content'] = 'space-evenly';
37349
+ cellStyle['align-items'] = 'center';
37350
+ return (createElement$1("div", { className: 'gn-datagrid-body-cell btn-container ' + (col.key ? col.key : '') + (this._isHorizontalState() ? ' is-horizontal' : ''), style: cellStyle, "data-key": col.key, "on-click": (e) => {
37351
+ this._hidden.stopRowSelectEvent(e);
37319
37352
  } },
37320
- createElement$1("i", { className: "fas fa-arrow-circle-down" }))));
37321
- }
37322
- if (col.key === 'btnDelete') {
37323
- cellStyle.display = 'flex';
37324
- cellStyle['justify-content'] = 'center';
37325
- cellStyle['align-items'] = 'center';
37326
- return (createElement$1("div", { className: 'gn-datagrid-body-cell btn-container ' + (col.key ? col.key : ''), style: cellStyle, "on-click": (e) => {
37327
- this._hidden.stopRowSelectEvent(e);
37328
- } },
37329
- createElement$1("span", { className: "gn-icon is-small is-mono", "on-click": () => {
37330
- !this.$options.disabled && this._hidden.deleteRow.call(this, _index);
37353
+ createElement$1("span", { className: 'gn-icon btn-order ' + (_index == 0 ? 'is-cancel' : 'is-info'), "on-click": () => {
37354
+ !this.$options.disabled && this._hidden.moveRowUp.call(this, _index);
37355
+ } },
37356
+ createElement$1("i", { className: "fas fa-arrow-circle-up" })),
37357
+ createElement$1("span", { className: 'gn-icon btn-order ' + (_index == this.$options.data.length - 1 ? 'is-cancel' : 'is-info'), "on-click": () => {
37358
+ !this.$options.disabled && this._hidden.moveRowDown.call(this, _index);
37359
+ } },
37360
+ createElement$1("i", { className: "fas fa-arrow-circle-down" }))));
37361
+ }
37362
+ if (col.key === 'btnDelete') {
37363
+ cellStyle.display = 'flex';
37364
+ cellStyle['justify-content'] = 'center';
37365
+ cellStyle['align-items'] = 'center';
37366
+ return (createElement$1("div", { className: 'gn-datagrid-body-cell btn-container ' + (col.key ? col.key : '') + (this._isHorizontalState() ? ' is-horizontal' : ''), style: cellStyle, "data-key": col.key, "on-click": (e) => {
37367
+ this._hidden.stopRowSelectEvent(e);
37331
37368
  } },
37332
- createElement$1("i", { className: "fas fa-trash" }))));
37333
- }
37334
- return (createElement$1("div", { className: 'gn-datagrid-body-cell ' +
37335
- (col.bodyClass ? col.bodyClass : col.className ? col.className : '') +
37336
- (isFunction(col.onSelect) ? ' is-selectable' : '') +
37337
- (col.isHidden ? ' is-unvisible' : ''), "data-key": col.key, style: cellStyle, "on-click": (e) => {
37338
- col.onSelect && !this.$options.disabled && this._hidden.selectCell.call(this, col, row, _index, e);
37339
- }, "on-mouseenter": (e) => {
37340
- col.onHover && !this.$options.disabled && this._hidden.hoverCell.call(this, col, row, _index, e);
37341
- }, "on-mouseleave": (e) => {
37342
- col.offHover && this._hidden.blurCell.call(this, col, row, _index, e);
37343
- }, 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)));
37344
- })));
37345
- },
37346
- renderCell: (row, col, idx, hasChild, isCheck, _index) => {
37369
+ createElement$1("span", { className: "gn-icon is-small is-mono", "on-click": () => {
37370
+ !this.$options.disabled && this._hidden.deleteRow.call(this, _index);
37371
+ } },
37372
+ createElement$1("i", { className: "fas fa-trash" }))));
37373
+ }
37374
+ return (createElement$1("div", { className: 'gn-datagrid-body-cell ' +
37375
+ (col.bodyClass ? col.bodyClass : col.className ? col.className : '') +
37376
+ (isFunction(col.onSelect) ? ' is-selectable' : '') +
37377
+ (col.isHidden ? ' is-unvisible' : '') +
37378
+ (this._isHorizontalState() ? ' is-horizontal' : ''), "data-key": col.key, style: cellStyle, "on-click": (e) => {
37379
+ col.onSelect && !this.$options.disabled && this._hidden.selectCell.call(this, col, row, _index, e);
37380
+ }, "on-mouseenter": (e) => {
37381
+ col.onHover && !this.$options.disabled && this._hidden.hoverCell.call(this, col, row, _index, e);
37382
+ }, "on-mouseleave": (e) => {
37383
+ col.offHover && this._hidden.blurCell.call(this, col, row, _index, e);
37384
+ }, 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)));
37385
+ })));
37386
+ },
37387
+ renderHorizontalCellLabel: (col) => {
37388
+ if (this._isSystemAddedColumn(col.key)) {
37389
+ return null;
37390
+ }
37391
+ return createElement$1("span", { className: "gn-datagrid-cell-label" }, col.label);
37392
+ },
37393
+ renderHorizontalCardHeader: (row, index, hasChild, isCheck) => {
37394
+ const hasHeader = this.$options.hasCheck || (this.$options.hasDelete && !this.$options.readonly);
37395
+ const showCheck = this.$options.hasCheck && row.noCheck !== true && row.noCheck !== 'true';
37396
+ const showDelete = this.$options.hasDelete && !this.$options.readonly;
37397
+ if (!hasHeader) {
37398
+ return null;
37399
+ }
37400
+ return (createElement$1("div", { className: "gn-datagrid-card-header" },
37401
+ createElement$1("div", { className: "gn-datagrid-card-header-left" }, showCheck && (createElement$1("label", { className: "gn-checkbox is-no-padding", style: { width: '20px' } },
37402
+ createElement$1("input", { type: "checkbox", id: this._uid + '-row-check-' + index, className: "is-rowChecker", "on-click": (e) => {
37403
+ this._hidden.check.call(this, row, e);
37404
+ }, defaultChecked: isCheck, disabled: this.$options.disabled || row.disabled })))),
37405
+ createElement$1("div", { className: "gn-datagrid-card-header-right" }, showDelete && (createElement$1("span", { className: "gn-icon is-small is-mono", "on-click": (e) => {
37406
+ this._hidden.stopRowSelectEvent(e);
37407
+ !this.$options.disabled && this._hidden.deleteRow.call(this, index);
37408
+ } },
37409
+ createElement$1("i", { className: "fas fa-trash" }))))));
37410
+ },
37411
+ renderCellValue: (row, col, idx, hasChild, isCheck, _index) => {
37347
37412
  return [
37348
- idx === 0 && hasChild ? (createElement$1("span", { className: "is-toggler", "on-click": (e) => {
37413
+ idx === 0 && hasChild && !this._isHorizontalState() ? (createElement$1("span", { className: "is-toggler", "on-click": (e) => {
37349
37414
  !this.$options.disabled && this._hidden.toggle.call(this, row, e);
37350
37415
  } })) : (''),
37351
- idx === 0 && this.$options.hasCheck && row.noCheck !== true && row.noCheck !== 'true' ? (createElement$1("label", { className: "gn-checkbox is-no-padding", style: { width: '20px' } },
37416
+ idx === 0 && this.$options.hasCheck && row.noCheck !== true && row.noCheck !== 'true' && !this._isHorizontalState() ? (createElement$1("label", { className: "gn-checkbox is-no-padding", style: { width: '20px' } },
37352
37417
  createElement$1("input", { type: "checkbox", id: this._uid + '-row-check-' + _index, className: "is-rowChecker", "on-click": (e) => {
37353
37418
  this._hidden.check.call(this, row, e);
37354
37419
  }, defaultChecked: isCheck, disabled: this.$options.disabled || row.disabled }))) : (''),
37355
37420
  col.template ? createElement$1("span", { className: "gn-datagrid-cell", innerHTML: col.template(col.key, row, col) }) : row[col.key] !== undefined ? row[col.key] : ''
37356
37421
  ];
37357
37422
  },
37423
+ renderCell: (row, col, idx, hasChild, isCheck, _index) => {
37424
+ if (this._isHorizontalState()) {
37425
+ return [this._hidden.renderHorizontalCellLabel(col), createElement$1("div", { className: "gn-datagrid-cell-value" }, this._hidden.renderCellValue(row, col, idx, hasChild, isCheck, _index))];
37426
+ }
37427
+ return this._hidden.renderCellValue(row, col, idx, hasChild, isCheck, _index);
37428
+ },
37358
37429
  renderNodata: () => {
37359
37430
  return (createElement$1("div", { className: "gn-datagrid-body-row is-nodata" },
37360
37431
  createElement$1("div", { className: "gn-datagrid-body-cell has-text-center" }, this.$options.textSets.noData)));
@@ -37440,7 +37511,10 @@ class DataGrid extends GNCoreInstance {
37440
37511
  });
37441
37512
  this.$event(this, 'onCheckAll', e.target.checked);
37442
37513
  },
37443
- showDetail(index, headerKeys, rawDataKeys) {
37514
+ showDetail: (index, headerKeys, rawDataKeys) => {
37515
+ if (this._isHorizontalState()) {
37516
+ return;
37517
+ }
37444
37518
  const rows = findAll(`.gn-datagrid-body > .gn-datagrid-body-row`, this.$el);
37445
37519
  const row = rows[+index];
37446
37520
  if (next(row) && hasClass(next(row), 'gn-datagrid-body-row-detail')) {
@@ -37527,6 +37601,7 @@ class DataGrid extends GNCoreInstance {
37527
37601
  },
37528
37602
  reRender: ({ headers, data, hasCheck }) => {
37529
37603
  return new Promise(resolve => {
37604
+ this._refreshOrientationState(this.$options);
37530
37605
  if (hasCheck === undefined) {
37531
37606
  hasCheck = this.$options.hasCheck;
37532
37607
  }
@@ -37735,8 +37810,8 @@ class DataGrid extends GNCoreInstance {
37735
37810
  visibles.forEach((visible, index) => {
37736
37811
  const colNumber = index + 1;
37737
37812
  !visible
37738
- ? addClass(findAll('.gn-datagrid-body-cell:nth-child(' + colNumber + ')', this.$el), 'is-unvisible')
37739
- : removeClass(findAll('.gn-datagrid-body-cell:nth-child(' + colNumber + ')', this.$el), 'is-unvisible');
37813
+ ? addClass(findAll(`.gn-datagrid-body-cell[data-key="${this.$options.headers[index].key}"]`, this.$el), 'is-unvisible')
37814
+ : removeClass(findAll(`.gn-datagrid-body-cell[data-key="${this.$options.headers[index].key}"]`, this.$el), 'is-unvisible');
37740
37815
  !visible
37741
37816
  ? addClass(findAll('.gn-datagrid-header-cell:nth-child(' + colNumber + ')', this.$el), 'is-unvisible')
37742
37817
  : removeClass(findAll('.gn-datagrid-header-cell:nth-child(' + colNumber + ')', this.$el), 'is-unvisible');
@@ -37781,6 +37856,13 @@ class DataGrid extends GNCoreInstance {
37781
37856
  removeClass(this.$el, 'is-disabled');
37782
37857
  }
37783
37858
  };
37859
+ this._orientationState = {
37860
+ orientation: 'vertical',
37861
+ columns: 1,
37862
+ gap: 0,
37863
+ minWidth: 240,
37864
+ hasGap: false
37865
+ };
37784
37866
  this.config = {
37785
37867
  width: '100%',
37786
37868
  hasCheck: false,
@@ -37795,6 +37877,7 @@ class DataGrid extends GNCoreInstance {
37795
37877
  deleteLabel: '',
37796
37878
  deleteConfirmMessage: ''
37797
37879
  },
37880
+ orientation: 'vertical',
37798
37881
  childField: 'child',
37799
37882
  checkCapturing: true,
37800
37883
  sort: {
@@ -37815,10 +37898,10 @@ class DataGrid extends GNCoreInstance {
37815
37898
  onDelete: true
37816
37899
  };
37817
37900
  this.methods = {
37818
- reRender(options) {
37901
+ reRender: (options) => {
37819
37902
  return this._hidden.reRender(options);
37820
37903
  },
37821
- resetData(data) {
37904
+ resetData: (data) => {
37822
37905
  if (isFunction(data)) {
37823
37906
  this.$options.asyncData = data;
37824
37907
  data = [];
@@ -37827,45 +37910,60 @@ class DataGrid extends GNCoreInstance {
37827
37910
  }
37828
37911
  return this._hidden.resetData(arrClone(data));
37829
37912
  },
37830
- addChild(index, data) {
37913
+ addChild: (index, data) => {
37914
+ if (this._isHorizontalState()) {
37915
+ return;
37916
+ }
37831
37917
  this._hidden.addChild(index, arrClone(data));
37832
37918
  },
37833
- addRow(data) {
37919
+ addRow: (data) => {
37920
+ if (this._isHorizontalState()) {
37921
+ return;
37922
+ }
37834
37923
  this._hidden.addChild(null, arrClone(data));
37835
37924
  this.$options.data = this.$options.data.concat(data);
37836
37925
  },
37837
- expand(index) {
37926
+ expand: (index) => {
37927
+ if (this._isHorizontalState()) {
37928
+ return;
37929
+ }
37838
37930
  this._hidden.expand(index);
37839
37931
  },
37840
- collapse(index) {
37932
+ collapse: (index) => {
37933
+ if (this._isHorizontalState()) {
37934
+ return;
37935
+ }
37841
37936
  this._hidden.collapse(index);
37842
37937
  },
37843
- getChecked() {
37938
+ getChecked: () => {
37844
37939
  return this._hidden.getChecked();
37845
37940
  },
37846
- hideCols(keys) {
37941
+ hideCols: (keys) => {
37847
37942
  this._hidden.hideCols(keys);
37848
37943
  },
37849
- showCols(keys) {
37944
+ showCols: (keys) => {
37850
37945
  this._hidden.showCols(keys);
37851
37946
  },
37852
- showAll() {
37947
+ showAll: () => {
37853
37948
  this._hidden.showAll();
37854
37949
  },
37855
- showDetail(index, headerKeys, rawDataKeys) {
37950
+ showDetail: (index, headerKeys, rawDataKeys) => {
37951
+ if (this._isHorizontalState()) {
37952
+ return;
37953
+ }
37856
37954
  this._hidden.showDetail.call(this, index, headerKeys, rawDataKeys);
37857
37955
  },
37858
- selectRow(index, rowData) {
37956
+ selectRow: (index, rowData) => {
37859
37957
  let row = rowData;
37860
37958
  if (!row) {
37861
37959
  row = this.$options.data[index];
37862
37960
  }
37863
37961
  !this.$options.disable && this._hidden.selectRow(row, index);
37864
37962
  },
37865
- disable() {
37963
+ disable: () => {
37866
37964
  this._hidden.disable();
37867
37965
  },
37868
- enable() {
37966
+ enable: () => {
37869
37967
  this._hidden.enable();
37870
37968
  }
37871
37969
  };
@@ -37918,6 +38016,34 @@ class DataGrid extends GNCoreInstance {
37918
38016
  });
37919
38017
  }
37920
38018
  }
38019
+ // 렌더에서 바로 쓸 수 있는 orientation 상태를 만든다.
38020
+ _resolveOrientationState(config = this.$options) {
38021
+ var _a, _b, _c, _d, _e;
38022
+ const orientation = (config === null || config === void 0 ? void 0 : config.orientation) === 'horizontal' ? 'horizontal' : 'vertical';
38023
+ const optionColumns = (_a = config === null || config === void 0 ? void 0 : config.orientationOptions) === null || _a === void 0 ? void 0 : _a.columns;
38024
+ const columns = optionColumns === 'auto-fit' ? optionColumns : Number.isInteger(Number(optionColumns)) && Number(optionColumns) > 0 ? Number(optionColumns) : 1;
38025
+ const optionGap = (_c = (_b = config === null || config === void 0 ? void 0 : config.orientationOptions) === null || _b === void 0 ? void 0 : _b.gap) !== null && _c !== void 0 ? _c : 0;
38026
+ const isZeroLikeGap = optionGap === 0 || optionGap === '0' || optionGap === '0px' || optionGap === '';
38027
+ const gap = columns === 'auto-fit' && isZeroLikeGap ? '5px' : isZeroLikeGap ? 0 : typeof optionGap === 'number' ? optionGap + 'px' : optionGap;
38028
+ const rawMinWidth = (_e = (_d = config.orientationOptions) === null || _d === void 0 ? void 0 : _d.minWidth) !== null && _e !== void 0 ? _e : 240;
38029
+ const minWidth = typeof rawMinWidth === 'number' ? rawMinWidth + 'px' : rawMinWidth;
38030
+ return {
38031
+ orientation,
38032
+ columns,
38033
+ gap,
38034
+ minWidth,
38035
+ hasGap: gap !== 0
38036
+ };
38037
+ }
38038
+ // 실제 옵션이 갱신될 때 내부 orientation 상태를 새로 계산한다.
38039
+ _refreshOrientationState(config = this.$options) {
38040
+ this._orientationState = this._resolveOrientationState(config);
38041
+ return this._orientationState;
38042
+ }
38043
+ // 내부 렌더 분기에서는 orientationState만 기준으로 사용한다.
38044
+ _isHorizontalState() {
38045
+ return this._orientationState.orientation === 'horizontal';
38046
+ }
37921
38047
  _isSystemAddedColumn(key) {
37922
38048
  return ['btnOrder', 'btnDelete'].includes(key);
37923
38049
  }
@@ -37925,6 +38051,10 @@ class DataGrid extends GNCoreInstance {
37925
38051
  _prepareHeaders(headers = []) {
37926
38052
  const hasOrderColumn = headers.some((header) => header.key === 'btnOrder');
37927
38053
  const hasDeleteColumn = headers.some((header) => header.key === 'btnDelete');
38054
+ const horizontal = this._isHorizontalState();
38055
+ if (horizontal) {
38056
+ headers = headers.map((header) => (Object.assign(Object.assign({}, header), { sortable: false, draggable: false })));
38057
+ }
37928
38058
  if (this.$options.hasOrder && !this.$options.readonly && !hasOrderColumn) {
37929
38059
  headers.push({
37930
38060
  label: this.$options.textSets.orderLabel,
@@ -37934,7 +38064,7 @@ class DataGrid extends GNCoreInstance {
37934
38064
  }
37935
38065
  });
37936
38066
  }
37937
- if (this.$options.hasDelete && !this.$options.readonly && !hasDeleteColumn) {
38067
+ if (this.$options.hasDelete && !this.$options.readonly && !hasDeleteColumn && !horizontal) {
37938
38068
  headers.push({
37939
38069
  label: this.$options.textSets.deleteLabel,
37940
38070
  key: 'btnDelete',
@@ -37947,9 +38077,14 @@ class DataGrid extends GNCoreInstance {
37947
38077
  return headers;
37948
38078
  }
37949
38079
  template(config) {
38080
+ const resolvedConfig = Object.assign(Object.assign({}, this.$options), config);
38081
+ this._refreshOrientationState(resolvedConfig);
38082
+ const contentsMarginTop = this.$options.bodyTopMargin ? this.$options.bodyTopMargin : this._isHorizontalState() && this._orientationState.hasGap ? String(this._orientationState.gap) : '0';
37950
38083
  const styles = {};
37951
38084
  const headers = this._prepareHeaders(config.headers);
37952
38085
  return (createElement$1("div", { id: this._uid, className: 'gn-datagrid' +
38086
+ (this._isHorizontalState() ? ' is-horizontal' : '') +
38087
+ (this._isHorizontalState() && this._orientationState.hasGap ? ' has-horizontal-gap' : '') +
37953
38088
  (config.style ? ' is-' + config.style : '') +
37954
38089
  (config.isEllipsis ? ' is-ellipsis' : '') +
37955
38090
  (config.bodyHeight ? ' has-fixed-body' : '') +
@@ -37959,7 +38094,7 @@ class DataGrid extends GNCoreInstance {
37959
38094
  (config.data.some((d) => isArray$1(d[this.$options.childField])) ? ' has-left-padding' : '') +
37960
38095
  (config.disabled ? ' is-disabled' : ''), style: styles },
37961
38096
  config.hasHeader && createElement$1("div", { className: "gn-datagrid-header" }, this._hidden.renderHeader(headers)),
37962
- createElement$1("div", { className: "gn-datagrid-contents", style: { marginTop: this.$options.bodyTopMargin ? this.$options.bodyTopMargin : '0', marginBottom: this.$options.bodyBottomMargin ? this.$options.bodyBottomMargin : '0' } }, this._hidden.renderBody(arrClone(config.data), headers)),
38097
+ createElement$1("div", { className: "gn-datagrid-contents", style: { marginTop: contentsMarginTop, marginBottom: this.$options.bodyBottomMargin ? this.$options.bodyBottomMargin : '0' } }, this._hidden.renderBody(arrClone(config.data), headers)),
37963
38098
  config.paginator /* 페이지네이터 옵션 확인 */ && createElement$1("div", { className: "gn-datagrid-footer" })));
37964
38099
  }
37965
38100
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
@@ -37976,7 +38111,12 @@ class DataGrid extends GNCoreInstance {
37976
38111
  }
37977
38112
  }
37978
38113
  completed() {
37979
- if (this.$options.fixHeader && this.$options.hasHeader) {
38114
+ const isHorizontal = this._isHorizontalState();
38115
+ const isVertical = !isHorizontal;
38116
+ const usesFixedHeader = this.$options.fixHeader && this.$options.hasHeader;
38117
+ const needsBlankHeader = usesFixedHeader || this.$options.bodyHeight;
38118
+ isHorizontal ? addClass(this.$el, 'is-horizontal') : removeClass(this.$el, 'is-horizontal');
38119
+ if (usesFixedHeader && isVertical) {
37980
38120
  const body = find('.gn-datagrid-contents', this.$el);
37981
38121
  const header = find('.gn-datagrid-header', this.$el);
37982
38122
  if (header) {
@@ -37989,7 +38129,7 @@ class DataGrid extends GNCoreInstance {
37989
38129
  css$1(body, 'margin-bottom', this.$options.bodyBottomMargin);
37990
38130
  }
37991
38131
  }
37992
- if ((this.$options.fixHeader && this.$options.hasHeader) || this.$options.bodyHeight) {
38132
+ if (isVertical && needsBlankHeader) {
37993
38133
  this._hidden.setBlankHeader();
37994
38134
  on(window, 'resize', this._hidden.setBlankHeader);
37995
38135
  }
@@ -38467,6 +38607,10 @@ class Modal extends GNCoreInstance {
38467
38607
  focus: () => {
38468
38608
  const modal = find('.modal-content', this.$el);
38469
38609
  modal.focus();
38610
+ },
38611
+ extra: (actionKey) => {
38612
+ // notify page about which extra button clicked
38613
+ this.$event(this, 'onExtra', actionKey);
38470
38614
  }
38471
38615
  };
38472
38616
  this.config = {
@@ -38484,6 +38628,7 @@ class Modal extends GNCoreInstance {
38484
38628
  hasClose: true,
38485
38629
  hasConfirm: false,
38486
38630
  hasCancel: false,
38631
+ extraButtons: [],
38487
38632
  isModal: true,
38488
38633
  minimized: false,
38489
38634
  resizable: false,
@@ -38494,7 +38639,8 @@ class Modal extends GNCoreInstance {
38494
38639
  this.events = {
38495
38640
  onClose: true,
38496
38641
  onConfirm: true,
38497
- onOpen: true
38642
+ onOpen: true,
38643
+ onExtra: true
38498
38644
  };
38499
38645
  this.methods = {
38500
38646
  close() {
@@ -38536,7 +38682,10 @@ class Modal extends GNCoreInstance {
38536
38682
  createElement$1("i", { className: "fas fa-times" })))))),
38537
38683
  createElement$1("div", { className: "modal-body", style: styles },
38538
38684
  createElement$1("div", { className: "modal-body-content", style: contStyles })),
38539
- (config.hasConfirm || config.hasCancel) /* 확인/취소 옵션 확인 */ && (createElement$1("div", { className: "modal-footer has-text-center" },
38685
+ (config.hasConfirm || config.hasCancel || (Array.isArray(config.extraButtons) && config.extraButtons.length > 0)) /* 확인/취소/추가버튼 옵션 확인 */ && (createElement$1("div", { className: "modal-footer has-text-center" },
38686
+ Array.isArray(config.extraButtons) &&
38687
+ config.extraButtons.length > 0 &&
38688
+ config.extraButtons.map((btn) => (createElement$1("button", { type: "button", className: 'gn-button ' + (btn.className ? btn.className : 'is-mono'), "on-click": this._hidden.extra.bind(this, btn.key || btn.label) }, btn.label || btn.key))),
38540
38689
  config.hasConfirm && (createElement$1("button", { type: "button", className: 'gn-button' + ` is-${config.sizeSets.confirm}`, id: this._uid + '_confirm', "on-click": this._hidden.confirm }, config.textSets.confirm)),
38541
38690
  config.hasCancel && (createElement$1("button", { type: "button", className: 'gn-button btnCloseModal is-cancel' + ` is-${config.sizeSets.cancel}`, id: this._uid + '_cancel', "on-click": this._hidden.close }, config.textSets.cancel)))))));
38542
38691
  }
@@ -39575,15 +39724,124 @@ class Tab extends GNCoreInstance {
39575
39724
  }
39576
39725
 
39577
39726
  class MultiTextArea extends GNCoreInstance {
39727
+ _isMaxLengthMessageEnabled() {
39728
+ return !!(this.$options.maxlength && this.$options.useMaxLengthMessage);
39729
+ }
39730
+ _getTotalLength(valueSet) {
39731
+ return this.$options.lang.reduce((sum, currentLang) => {
39732
+ const currentValue = valueSet[currentLang] || '';
39733
+ return sum + currentValue.length;
39734
+ }, 0);
39735
+ }
39736
+ _getTotalLengthWithoutLang(valueSet, excludeLang) {
39737
+ return this.$options.lang.reduce((sum, currentLang) => {
39738
+ if (currentLang === excludeLang) {
39739
+ return sum;
39740
+ }
39741
+ const currentValue = valueSet[currentLang] || '';
39742
+ return sum + currentValue.length;
39743
+ }, 0);
39744
+ }
39745
+ _getRemainMessage(remain) {
39746
+ var _a, _b;
39747
+ const template = ((_b = (_a = this.$options) === null || _a === void 0 ? void 0 : _a.textSets) === null || _b === void 0 ? void 0 : _b.maxLengthMessage) || '{{maxlength}}자 입력 가능합니다.';
39748
+ return template.replace(/\{\{\s*maxlength\s*\}\}/g, String(remain));
39749
+ }
39578
39750
  constructor(name, selector, options = {}) {
39579
39751
  super(name, selector, options);
39580
39752
  this._hidden = {
39753
+ beforeInput: (e) => {
39754
+ var _a, _b;
39755
+ if (!this.$options.maxlength || !this._isMaxLengthMessageEnabled()) {
39756
+ return;
39757
+ }
39758
+ const target = e.target;
39759
+ const lang = data(target, 'data-lang');
39760
+ if (!lang) {
39761
+ return;
39762
+ }
39763
+ if (e.inputType && e.inputType.startsWith('delete')) {
39764
+ return;
39765
+ }
39766
+ const currentValue = val(target) || '';
39767
+ const selectionStart = typeof target.selectionStart === 'number' ? target.selectionStart : currentValue.length;
39768
+ const selectionEnd = typeof target.selectionEnd === 'number' ? target.selectionEnd : currentValue.length;
39769
+ const selectedLength = Math.max(0, selectionEnd - selectionStart);
39770
+ let insertValue = e.data || '';
39771
+ if (e.inputType === 'insertLineBreak' || e.inputType === 'insertParagraph') {
39772
+ insertValue = '\n';
39773
+ }
39774
+ if (e.inputType === 'insertFromPaste' && !insertValue) {
39775
+ const pastedText = (_b = (_a = e.dataTransfer) === null || _a === void 0 ? void 0 : _a.getData) === null || _b === void 0 ? void 0 : _b.call(_a, 'text/plain');
39776
+ insertValue = typeof pastedText === 'string' ? pastedText : '';
39777
+ }
39778
+ // 현재 언어를 제외한 나머지 언어들의 총 입력 길이를 기준으로 남은 입력 가능 길이를 계산한다.
39779
+ const totalLengthWithoutCurrent = this._getTotalLengthWithoutLang(this.$options.value, lang);
39780
+ const allowedLengthForCurrent = Math.max(0, this.$options.maxlength - totalLengthWithoutCurrent);
39781
+ const remainingForInsert = this.$options.maxlength - totalLengthWithoutCurrent - (currentValue.length - selectedLength);
39782
+ // paste는 "붙여넣기 내용 우선 반영 + 전체 결과의 뒤를 자르기" 정책을 적용한다.
39783
+ if (e.inputType === 'insertFromPaste') {
39784
+ if (remainingForInsert <= 0) {
39785
+ e.preventDefault();
39786
+ return;
39787
+ }
39788
+ const before = currentValue.slice(0, selectionStart);
39789
+ const after = currentValue.slice(selectionEnd);
39790
+ const nextValue = `${before}${insertValue}${after}`;
39791
+ if (nextValue.length <= allowedLengthForCurrent) {
39792
+ return;
39793
+ }
39794
+ e.preventDefault();
39795
+ const clamped = nextValue.slice(0, allowedLengthForCurrent);
39796
+ val(target, clamped);
39797
+ const nextCaret = Math.min((before + insertValue).length, clamped.length);
39798
+ target.setSelectionRange(nextCaret, nextCaret);
39799
+ trigger(target, 'input');
39800
+ return;
39801
+ }
39802
+ if (remainingForInsert >= insertValue.length) {
39803
+ return;
39804
+ }
39805
+ if (remainingForInsert <= 0) {
39806
+ e.preventDefault();
39807
+ return;
39808
+ }
39809
+ // 붙여넣기/다중 입력이 한도를 넘는 경우 허용 가능한 길이만 잘라서 반영한다.
39810
+ e.preventDefault();
39811
+ const partial = insertValue.slice(0, remainingForInsert);
39812
+ target.setRangeText(partial, selectionStart, selectionEnd, 'end');
39813
+ trigger(target, 'input');
39814
+ },
39581
39815
  change: (e) => {
39582
39816
  const target = e.target;
39583
39817
  const lang = data(target, 'data-lang');
39584
- this.$options.value[lang] = val(target);
39585
- if (this.$options.maxlength) {
39586
- text$1(this.$options.delegates[lang], this.$options.value[lang].length);
39818
+ if (!lang) {
39819
+ return;
39820
+ }
39821
+ this.$options.value[lang] = val(target) || '';
39822
+ if (this.$options.maxlength && this._isMaxLengthMessageEnabled()) {
39823
+ // 총합 maxlength를 넘지 않도록 현재 언어 값만 상한선까지 보정한다.
39824
+ const totalLengthWithoutCurrent = this._getTotalLengthWithoutLang(this.$options.value, lang);
39825
+ const allowedLength = Math.max(0, this.$options.maxlength - totalLengthWithoutCurrent);
39826
+ const clampedValue = this.$options.value[lang].slice(0, allowedLength);
39827
+ if (clampedValue !== this.$options.value[lang]) {
39828
+ this.$options.value[lang] = clampedValue;
39829
+ val(target, clampedValue);
39830
+ }
39831
+ }
39832
+ if (this.$options.maxlength && this.$options.delegates[lang]) {
39833
+ const hasMaxLengthMessage = this._isMaxLengthMessageEnabled();
39834
+ if (hasMaxLengthMessage) {
39835
+ // 메시지 모드에서는 모든 탭에 동일한 "남은 글자 수" 안내를 동기화한다.
39836
+ const totalLength = this._getTotalLength(this.$options.value);
39837
+ const textValue = this._getRemainMessage(this.$options.maxlength - totalLength);
39838
+ this.$options.lang.forEach((targetLang) => {
39839
+ text$1(this.$options.delegates[targetLang], textValue);
39840
+ });
39841
+ }
39842
+ else {
39843
+ text$1(this.$options.delegates[lang], this.$options.value[lang].length);
39844
+ }
39587
39845
  }
39588
39846
  this.$event(this, 'onChange', this.$options.value);
39589
39847
  },
@@ -39600,7 +39858,7 @@ class MultiTextArea extends GNCoreInstance {
39600
39858
  }
39601
39859
  const textInput = find(`[data-lang=${lang}]`, this.$el);
39602
39860
  val(textInput, value[lang]);
39603
- trigger(textInput, 'keyup');
39861
+ trigger(textInput, 'input');
39604
39862
  });
39605
39863
  },
39606
39864
  disable: () => {
@@ -39619,6 +39877,10 @@ class MultiTextArea extends GNCoreInstance {
39619
39877
  this.config = {
39620
39878
  lang: ['en', 'ko'],
39621
39879
  value: {},
39880
+ useMaxLengthMessage: false,
39881
+ textSets: {
39882
+ maxLengthMessage: '{{maxlength}}자 입력 가능합니다.'
39883
+ },
39622
39884
  delegates: {}
39623
39885
  };
39624
39886
  this.events = {
@@ -39643,6 +39905,12 @@ class MultiTextArea extends GNCoreInstance {
39643
39905
  }
39644
39906
  template(config) {
39645
39907
  const styles = {};
39908
+ const totalLength = config.lang.reduce((sum, currentLang) => {
39909
+ const currentValue = config.value && config.value[currentLang] ? config.value[currentLang] : '';
39910
+ return sum + currentValue.length;
39911
+ }, 0);
39912
+ const hasMaxLengthMessage = this._isMaxLengthMessageEnabled();
39913
+ const remainMessage = config.maxlength ? this._getRemainMessage(config.maxlength - totalLength) : '';
39646
39914
  if (config.width) {
39647
39915
  styles.width = getUnit('width', config.width);
39648
39916
  }
@@ -39651,11 +39919,14 @@ class MultiTextArea extends GNCoreInstance {
39651
39919
  createElement$1("ul", null, config.lang.map((l, index) => (createElement$1("li", { className: index === 0 ? 'is-active' : '' },
39652
39920
  createElement$1("a", { href: '#' + this._uid + '-' + l }, l)))))),
39653
39921
  createElement$1("div", { id: this._uid + '_content' }, config.lang.map((l) => (createElement$1("div", { id: this._uid + '-' + l },
39654
- createElement$1("textarea", { className: "gn-textarea", "data-lang": l, rows: config.rows ? config.rows : '', maxLength: config.maxlength ? config.maxlength : 524288, "on-keyup": this._hidden.change, disabled: config.disabled, readOnly: config.readonly }, config.value ? config.value[l] : ''),
39655
- config.maxlength && (createElement$1("p", { className: "has-text-right has-text-size6" },
39656
- createElement$1("span", { className: "charLen", "data-lang": l }, config.value && config.value[l] ? config.value[l].length : 0),
39657
- "/",
39658
- config.maxlength))))))));
39922
+ createElement$1("textarea", { className: "gn-textarea", "data-lang": l, rows: config.rows ? config.rows : '', maxLength: config.maxlength ? config.maxlength : 524288, "on-beforeinput": this._hidden.beforeInput, "on-input": this._hidden.change, disabled: config.disabled, readOnly: config.readonly }, config.value ? config.value[l] : ''),
39923
+ config.maxlength && (createElement$1("div", { className: "has-text-size6" },
39924
+ !hasMaxLengthMessage && (createElement$1("p", null,
39925
+ createElement$1("span", { className: "charLen", "data-lang": l }, config.value && config.value[l] ? config.value[l].length : 0),
39926
+ "/",
39927
+ config.maxlength)),
39928
+ hasMaxLengthMessage && (createElement$1("p", null,
39929
+ createElement$1("span", { className: "charLen", "data-lang": l }, remainMessage)))))))))));
39659
39930
  }
39660
39931
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
39661
39932
  $render(config) {
@@ -40946,41 +41217,56 @@ class Tagcloud extends GNCoreInstance {
40946
41217
  class Tree extends GNCoreInstance {
40947
41218
  constructor(name, selector, options = {}) {
40948
41219
  super(name, selector, options);
41220
+ this._checkerIdSeq = 0;
40949
41221
  this._hidden = {
40950
41222
  select: (item, e) => {
40951
41223
  if (item.disabled) {
40952
41224
  return;
40953
41225
  }
41226
+ if (hasClass(this.$el, 'is-disabled')) {
41227
+ return;
41228
+ }
40954
41229
  let target = e.target;
40955
- // 트리 아이콘을 클릭한 경우, 텍스트로 타겟 변경
40956
41230
  if (this.$options.showIcon && target.tagName === 'I') {
40957
41231
  target = parent(target);
40958
41232
  }
40959
- if (!this.$options.multiple) {
41233
+ if (this.$options.hasCheck) {
41234
+ // hasCheck 시: 노드 클릭으로 체크박스 토글, is-active 미적용
41235
+ const itemEl = hasClass(target, 'tree-item') ? target : parents(target, '.tree-item')[0];
41236
+ if (!itemEl)
41237
+ return;
41238
+ const checker = find('.is-checker', itemEl);
41239
+ if (!checker)
41240
+ return;
41241
+ // 라벨 또는 input 직접 클릭 시 여기서 토글하지 않음 → input 클릭 핸들러만 한 번 실행되게 함 (이중 토글·이중 onCheck 방지)
41242
+ const labelTarget = parents(e.target, 'label')[0];
41243
+ if (e.target === checker || (labelTarget && checker.id && labelTarget.getAttribute('for') === checker.id)) {
41244
+ return;
41245
+ }
41246
+ checker.checked = !checker.checked;
41247
+ this._hidden.check.call(this, item, { target: checker, stopPropagation: () => { } });
41248
+ }
41249
+ else {
41250
+ // hasCheck 미사용 시: 노드 클릭 시 is-active 적용, onSelect 발생
40960
41251
  removeClass(findAll('.tree-item', this.$el), 'is-active');
40961
41252
  addClass(target, 'is-active');
40962
41253
  this.$event(this, 'onSelect', item, e);
40963
41254
  }
40964
- else {
40965
- toggleClass(target, 'is-active');
40966
- if (hasClass(target, 'is-active')) {
40967
- this.$event(this, 'onSelect', item, e);
40968
- }
40969
- }
40970
41255
  },
40971
41256
  addChild: (index, addData) => {
40972
41257
  const itemEl = findAll('.tree-item', this.$el)[index];
40973
41258
  const itemData = this._hidden.findData(index);
41259
+ const nextChildren = this._hidden.setPaths(addData.slice(), itemData.path);
40974
41260
  if (!itemData[this.$options.childField]) {
40975
41261
  itemData[this.$options.childField] = [];
40976
41262
  }
40977
- itemData[this.$options.childField] = itemData[this.$options.childField].concat(addData);
41263
+ itemData[this.$options.childField] = itemData[this.$options.childField].concat(nextChildren);
40978
41264
  const appendTarget = siblings(itemEl, 'ul').pop();
40979
41265
  if (!appendTarget) {
40980
41266
  this.$template.reRender(parent(itemEl), this._hidden.renderItem(itemData));
40981
41267
  }
40982
41268
  else {
40983
- addData.forEach((item) => {
41269
+ nextChildren.forEach((item) => {
40984
41270
  const newItem = document.createElement('li');
40985
41271
  append(appendTarget, newItem);
40986
41272
  this.$template.reRender(newItem, this._hidden.renderItem(item));
@@ -41011,38 +41297,59 @@ class Tree extends GNCoreInstance {
41011
41297
  },
41012
41298
  check: (item, e) => {
41013
41299
  const target = e.target;
41014
- e.stopPropagation();
41015
- findAll('.is-checker', parents(target, 'li')[0]).forEach((c) => {
41016
- c.checked = target.checked;
41017
- });
41018
- if (this.$options.checkPath) {
41019
- parents(target, 'ul')
41020
- .map((list) => siblings(list, '.tree-item').pop())
41021
- .filter((item) => item)
41022
- .forEach((item) => {
41023
- const parentChecker = find('.is-checker', item);
41024
- if (!parentChecker) {
41025
- return;
41026
- }
41027
- const parentLi = parents(item, 'li')[0];
41028
- if (!parentLi) {
41029
- return;
41030
- }
41031
- // 자식 중 하나라도 체크면 부모 체크, 전부 해제되면 부모도 해제
41032
- const descendantCheckers = findAll('.is-checker', parentLi).filter((checker) => checker !== parentChecker);
41033
- if (!descendantCheckers.length) {
41034
- return;
41035
- }
41036
- parentChecker.checked = descendantCheckers.some((checker) => checker.checked);
41037
- });
41300
+ if (hasClass(this.$el, 'is-disabled') || item.disabled) {
41301
+ if (typeof e.preventDefault === 'function')
41302
+ e.preventDefault();
41303
+ target.checked = !target.checked; // 브라우저가 이미 토글했으므로 원래대로 되돌림
41304
+ return;
41038
41305
  }
41306
+ if (typeof e.stopPropagation === 'function')
41307
+ e.stopPropagation();
41308
+ this._hidden.applyCheckedState(target, target.checked);
41039
41309
  this.$event(this, 'onCheck', item, target.checked, this._hidden.getItemIndex(target), e);
41040
41310
  },
41041
41311
  checkAll: (isChecked) => {
41312
+ if (this.$options.disabled) {
41313
+ return;
41314
+ }
41042
41315
  findAll('.is-checker', this.$el).forEach((c) => {
41316
+ if (c.disabled) {
41317
+ return;
41318
+ }
41043
41319
  c.checked = isChecked;
41044
41320
  });
41045
41321
  },
41322
+ setChecked: (targets, checked) => {
41323
+ if (!this.$options.hasCheck || this.$options.disabled) {
41324
+ return;
41325
+ }
41326
+ const normalizedTargets = Array.isArray(targets) ? targets : [targets];
41327
+ const targetSet = new Set(normalizedTargets);
41328
+ findAll('.tree-item', this.$el).forEach((itemEl, index) => {
41329
+ const itemData = this._hidden.findData(index);
41330
+ const itemValue = itemData === null || itemData === void 0 ? void 0 : itemData.value;
41331
+ if (itemValue === undefined || itemValue === null || itemValue === '') {
41332
+ return;
41333
+ }
41334
+ if (!targetSet.has(String(itemValue))) {
41335
+ return;
41336
+ }
41337
+ const checker = find('.is-checker', itemEl);
41338
+ if (!checker) {
41339
+ return;
41340
+ }
41341
+ if (checker.disabled || (itemData === null || itemData === void 0 ? void 0 : itemData.disabled)) {
41342
+ return;
41343
+ }
41344
+ checker.checked = checked;
41345
+ this._hidden.applyCheckedState(checker, checked);
41346
+ });
41347
+ },
41348
+ setCheckersDisabled: (disabled) => {
41349
+ findAll('.is-checker', this.$el).forEach((el) => {
41350
+ el.disabled = disabled;
41351
+ });
41352
+ },
41046
41353
  getChecked: (withStatus = false) => {
41047
41354
  if (!this.$options.hasCheck) {
41048
41355
  return [];
@@ -41066,14 +41373,53 @@ class Tree extends GNCoreInstance {
41066
41373
  findData.__status.isOpened = hasClass(target, 'is-open');
41067
41374
  findData.__status.isChecked = find('.is-checker', target).checked;
41068
41375
  findData.__status.isSelected = hasClass(target, 'is-active');
41069
- findData.__status.hasChildren = isArray$1(findData.child);
41376
+ findData.__status.hasChildren = isArray$1(findData[this.$options.childField]);
41070
41377
  }
41071
41378
  return findData;
41072
41379
  });
41073
41380
  },
41074
41381
  getItemIndex: (item) => {
41382
+ const itemEl = hasClass(item, 'tree-item') ? item : parents(item, '.tree-item')[0];
41383
+ if (!itemEl) {
41384
+ return -1;
41385
+ }
41075
41386
  const itemList = findAll('.tree-item', this.$el);
41076
- return itemList.findIndex((el) => el == item);
41387
+ return itemList.findIndex((el) => el == itemEl);
41388
+ },
41389
+ applyCheckedState: (checker, checked) => {
41390
+ const listItem = parents(checker, 'li')[0];
41391
+ if (!listItem) {
41392
+ return;
41393
+ }
41394
+ if (this.$options.checkChild !== false) {
41395
+ findAll('.is-checker', listItem).forEach((childChecker) => {
41396
+ if (childChecker.disabled) {
41397
+ return;
41398
+ }
41399
+ childChecker.checked = checked;
41400
+ });
41401
+ }
41402
+ if (!this.$options.checkPath) {
41403
+ return;
41404
+ }
41405
+ parents(checker, 'ul')
41406
+ .map((list) => siblings(list, '.tree-item').pop())
41407
+ .filter((item) => item)
41408
+ .forEach((item) => {
41409
+ const parentChecker = find('.is-checker', item);
41410
+ if (!parentChecker) {
41411
+ return;
41412
+ }
41413
+ const parentLi = parents(item, 'li')[0];
41414
+ if (!parentLi) {
41415
+ return;
41416
+ }
41417
+ const descendantCheckers = findAll('.is-checker', parentLi).filter((candidate) => candidate !== parentChecker);
41418
+ if (!descendantCheckers.length) {
41419
+ return;
41420
+ }
41421
+ parentChecker.checked = descendantCheckers.some((candidate) => candidate.checked);
41422
+ });
41077
41423
  },
41078
41424
  getPathArray(path) {
41079
41425
  const pathParts = path.split('/');
@@ -41152,34 +41498,46 @@ class Tree extends GNCoreInstance {
41152
41498
  }
41153
41499
  this.$event(this, 'onToggle', item, hasClass(target, 'is-open') ? 'expanded' : 'collapsed', this._hidden.getItemIndex(target), e);
41154
41500
  },
41155
- renderTree: (data) => {
41156
- return (createElement$1("ul", null, data.map((item) => {
41157
- return this._hidden.renderItem(item);
41501
+ renderTree: (data, keyPath = '') => {
41502
+ return (createElement$1("ul", null, data.map((item, idx) => {
41503
+ const itemKeyPath = keyPath ? `${keyPath}-${idx}` : `${idx}`;
41504
+ return this._hidden.renderItem(item, itemKeyPath);
41158
41505
  })));
41159
41506
  },
41160
- renderItem: (item) => {
41507
+ renderItem: (item, keyPath) => {
41161
41508
  var _a;
41509
+ const resolvedKeyPath = keyPath !== null && keyPath !== void 0 ? keyPath : `seq-${this._checkerIdSeq++}`;
41510
+ const checkerId = `${this._uid}-chk-${resolvedKeyPath}`;
41162
41511
  return (createElement$1("li", null,
41163
- createElement$1("div", { className: ['tree-item', item[this.$options.childField] ? 'has-child' : '', item.opened ? 'is-open' : '', item.actived ? ' is-active' : '', item.disabled ? 'is-disabled' : ''].join(' '), "on-click": this._hidden.select.bind(this, item), "data-path": (_a = item.path) !== null && _a !== void 0 ? _a : '', title: item.text },
41512
+ createElement$1("div", { className: [
41513
+ 'tree-item',
41514
+ item[this.$options.childField] ? 'has-child' : '',
41515
+ item.opened ? 'is-open' : '',
41516
+ !this.$options.hasCheck && item.actived ? ' is-active' : '',
41517
+ item.disabled ? 'is-disabled' : ''
41518
+ ].join(' '), "on-click": this._hidden.select.bind(this, item), "data-path": (_a = item.path) !== null && _a !== void 0 ? _a : '', title: item.text },
41164
41519
  // has child field - arrow toggle
41165
41520
  item[this.$options.childField] ? (createElement$1("div", { className: "is-toggler", "on-click": (e) => {
41166
41521
  this._hidden.toggle.call(this, item, e);
41167
41522
  } })) : (''),
41168
41523
  // has checkbox
41169
- this.$options.hasCheck && item.noCheck !== true && item.noCheck !== 'true' ? (createElement$1("label", { className: "gn-checkbox is-no-padding", style: { width: '20px' } },
41170
- createElement$1("input", { type: "checkbox", className: "is-checker", "on-click": (e) => {
41524
+ this.$options.hasCheck && item.noCheck !== true && item.noCheck !== 'true' ? (createElement$1("div", { className: "gn-checks is-small is-no-padding" },
41525
+ createElement$1("input", { type: "checkbox", className: "is-checker", id: checkerId, disabled: !!this.$options.disabled || !!item.disabled, "on-click": (e) => {
41171
41526
  this._hidden.check.call(this, item, e);
41172
- }, defaultChecked: !!item.selected }))) : (''),
41527
+ }, defaultChecked: !!item.selected }),
41528
+ createElement$1("label", { for: checkerId }, item.text))) : (''),
41173
41529
  // show icon
41174
41530
  this.$options.showIcon && !item.hideIcon ? (item.icon ? (createElement$1("span", { innerHTML: item.icon })) : (createElement$1("i", { style: { marginRight: '5px' }, className: 'far fa-' + (item.opened ? 'folder-open' : 'folder') }))) : (''),
41175
- item.text),
41176
- item[this.$options.childField] && this._hidden.renderTree(item[this.$options.childField])));
41531
+ !(this.$options.hasCheck && item.noCheck !== true && item.noCheck !== 'true') && item.text),
41532
+ item[this.$options.childField] && this._hidden.renderTree(item[this.$options.childField], resolvedKeyPath)));
41177
41533
  },
41178
- setPaths(data, basePath = '') {
41534
+ setPaths: (data, basePath = '') => {
41179
41535
  return data.map(item => {
41180
- const itemPath = basePath ? `${basePath}/${item.text}` : item.text;
41181
- const childPath = item.child ? this.setPaths(item.child, itemPath) : null;
41182
- return Object.assign(Object.assign({}, item), { path: itemPath, child: childPath });
41536
+ const itemKey = (item === null || item === void 0 ? void 0 : item.value) !== undefined && (item === null || item === void 0 ? void 0 : item.value) !== null && (item === null || item === void 0 ? void 0 : item.value) !== '' ? String(item.value) : item.text;
41537
+ const itemPath = basePath ? `${basePath}/${itemKey}` : itemKey;
41538
+ const children = item[this.$options.childField];
41539
+ const childPath = children ? this._hidden.setPaths(children, itemPath) : null;
41540
+ return Object.assign(Object.assign({}, item), { path: itemPath, [this.$options.childField]: childPath });
41183
41541
  });
41184
41542
  }
41185
41543
  };
@@ -41190,10 +41548,11 @@ class Tree extends GNCoreInstance {
41190
41548
  data: [],
41191
41549
  childField: 'child',
41192
41550
  hasCheck: false,
41193
- multiple: false,
41551
+ checkChild: true,
41194
41552
  checkPath: false,
41195
41553
  showIcon: false,
41196
- hideIcon: false
41554
+ hideIcon: false,
41555
+ disabled: false
41197
41556
  };
41198
41557
  this.events = {
41199
41558
  onSelect: true,
@@ -41218,15 +41577,20 @@ class Tree extends GNCoreInstance {
41218
41577
  this._hidden.collapseAll();
41219
41578
  },
41220
41579
  checkAll() {
41221
- if (!this.$options.hasCheck)
41580
+ if (!this.$options.hasCheck || this.$options.disabled)
41222
41581
  return;
41223
41582
  this._hidden.checkAll(true);
41224
41583
  },
41225
41584
  uncheckAll() {
41226
- if (!this.$options.hasCheck)
41585
+ if (!this.$options.hasCheck || this.$options.disabled)
41227
41586
  return;
41228
41587
  this._hidden.checkAll(false);
41229
41588
  },
41589
+ setChecked(targets, checked) {
41590
+ if (this.$options.disabled)
41591
+ return;
41592
+ this._hidden.setChecked(targets, checked);
41593
+ },
41230
41594
  getChecked(withStatus = false) {
41231
41595
  return this._hidden.getChecked(withStatus);
41232
41596
  },
@@ -41238,14 +41602,29 @@ class Tree extends GNCoreInstance {
41238
41602
  },
41239
41603
  filter(keyword) {
41240
41604
  return this._hidden.filter(keyword);
41605
+ },
41606
+ disable() {
41607
+ this.$options.disabled = true;
41608
+ addClass(this.$el, 'is-disabled');
41609
+ this._hidden.setCheckersDisabled(true);
41610
+ },
41611
+ enable() {
41612
+ this.$options.disabled = false;
41613
+ removeClass(this.$el, 'is-disabled');
41614
+ this._hidden.setCheckersDisabled(false);
41241
41615
  }
41242
41616
  };
41617
+ // multiple → hasCheck 치환(동일 기능으로 지원 X)
41618
+ if (options && options.multiple) {
41619
+ options.hasCheck = true;
41620
+ delete options.multiple;
41621
+ }
41243
41622
  this.$init(this, options);
41244
41623
  }
41245
41624
  template(config) {
41246
41625
  config.data = this._hidden.setPaths(config.data);
41247
41626
  const styles = {};
41248
- return (createElement$1("div", { id: this._uid, className: 'gn-tree' + (config.color ? ' is-' + config.color : '') + (config.type ? ' is-' + config.type : '') + (config.size ? ' is-' + config.size : ''), style: styles },
41627
+ return (createElement$1("div", { id: this._uid, className: 'gn-tree' + (config.color ? ' is-' + config.color : '') + (config.type ? ' is-' + config.type : '') + (config.size ? ' is-' + config.size : '') + (config.disabled ? ' is-disabled' : ''), style: styles },
41249
41628
  config.textSets.title && createElement$1("p", { className: "tree-label", innerHTML: config.textSets.title }),
41250
41629
  this._hidden.renderTree(config.data)));
41251
41630
  }