@operato/data-grist 0.2.41 → 0.2.45

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 (50) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/custom-elements.json +186 -14
  3. package/demo/index.html +79 -39
  4. package/dist/src/data-grid/data-grid-header.d.ts +1 -1
  5. package/dist/src/data-grid/data-grid-header.js +39 -9
  6. package/dist/src/data-grid/data-grid-header.js.map +1 -1
  7. package/dist/src/data-grist.d.ts +2 -1
  8. package/dist/src/data-grist.js +6 -3
  9. package/dist/src/data-grist.js.map +1 -1
  10. package/dist/src/filters/filter-checkbox.d.ts +2 -0
  11. package/dist/src/filters/filter-checkbox.js +30 -0
  12. package/dist/src/filters/filter-checkbox.js.map +1 -0
  13. package/dist/src/filters/filter-input.d.ts +2 -0
  14. package/dist/src/filters/filter-input.js +7 -0
  15. package/dist/src/filters/filter-input.js.map +1 -0
  16. package/dist/src/filters/filter-range-date.d.ts +2 -0
  17. package/dist/src/filters/filter-range-date.js +10 -0
  18. package/dist/src/filters/filter-range-date.js.map +1 -0
  19. package/dist/src/filters/filter-range-number.d.ts +2 -0
  20. package/dist/src/filters/filter-range-number.js +9 -0
  21. package/dist/src/filters/filter-range-number.js.map +1 -0
  22. package/dist/src/filters/filter-select.d.ts +2 -0
  23. package/dist/src/filters/filter-select.js +9 -0
  24. package/dist/src/filters/filter-select.js.map +1 -0
  25. package/dist/src/filters/filter-styles.d.ts +1 -0
  26. package/dist/src/filters/filter-styles.js +40 -0
  27. package/dist/src/filters/filter-styles.js.map +1 -0
  28. package/dist/src/filters/index.d.ts +5 -1
  29. package/dist/src/filters/index.js +5 -1
  30. package/dist/src/filters/index.js.map +1 -1
  31. package/dist/src/filters/registry.js +26 -23
  32. package/dist/src/filters/registry.js.map +1 -1
  33. package/dist/src/types.d.ts +4 -4
  34. package/dist/src/types.js.map +1 -1
  35. package/dist/tsconfig.tsbuildinfo +1 -1
  36. package/package.json +7 -7
  37. package/src/data-grid/data-grid-header.ts +42 -10
  38. package/src/data-grist.ts +7 -4
  39. package/src/filters/filter-checkbox.ts +35 -0
  40. package/src/filters/filter-input.ts +10 -0
  41. package/src/filters/filter-range-date.ts +13 -0
  42. package/src/filters/filter-range-number.ts +12 -0
  43. package/src/filters/filter-select.ts +11 -0
  44. package/src/filters/filter-styles.ts +40 -0
  45. package/src/filters/index.ts +5 -1
  46. package/src/filters/registry.ts +26 -23
  47. package/src/types.ts +4 -5
  48. package/themes/grist-theme.css +3 -0
  49. package/yarn-error.log +3149 -2371
  50. package/src/filters/list-select.ts +0 -14
package/CHANGELOG.md CHANGED
@@ -3,6 +3,49 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ### [0.2.45](https://github.com/hatiolab/operato/compare/v0.2.44...v0.2.45) (2021-12-11)
7
+
8
+
9
+ ### :bug: Bug Fix
10
+
11
+ * data-grid filter popup title ([5c75c24](https://github.com/hatiolab/operato/commit/5c75c24a563dddccfdceb52ce9db3393ce13b0df))
12
+ * filter style ([6f5789d](https://github.com/hatiolab/operato/commit/6f5789d9594eacb005203ae0f916993d107322c2))
13
+
14
+
15
+
16
+ ### [0.2.44](https://github.com/hatiolab/operato/compare/v0.2.43...v0.2.44) (2021-12-09)
17
+
18
+
19
+ ### :bug: Bug Fix
20
+
21
+ * filter style ([2d39b59](https://github.com/hatiolab/operato/commit/2d39b59e2068483c64bb4adee450603d8fe29031))
22
+ * filter style ([65eb5ec](https://github.com/hatiolab/operato/commit/65eb5ec87645719b6b797d6592a9436a6cffe569))
23
+
24
+
25
+
26
+ ### [0.2.43](https://github.com/hatiolab/operato/compare/v0.2.42...v0.2.43) (2021-12-08)
27
+
28
+
29
+ ### :rocket: New Features
30
+
31
+ * filter option for data-grist ([619aa04](https://github.com/hatiolab/operato/commit/619aa049799a0afde566a56ea77d291013946a41))
32
+
33
+
34
+ ### :bug: Bug Fix
35
+
36
+ * filter styling structure ([222b138](https://github.com/hatiolab/operato/commit/222b1387de24ed7b8c28faa44570670a22de4eb5))
37
+
38
+
39
+
40
+ ### [0.2.42](https://github.com/hatiolab/operato/compare/v0.2.41...v0.2.42) (2021-12-07)
41
+
42
+
43
+ ### :rocket: New Features
44
+
45
+ * add ox-input-barcode and export sorters property for grist ([0659d20](https://github.com/hatiolab/operato/commit/0659d20fcbfb48b0790ee57154c9108491566509))
46
+
47
+
48
+
6
49
  ### [0.2.41](https://github.com/hatiolab/operato/compare/v0.2.40...v0.2.41) (2021-12-07)
7
50
 
8
51
 
@@ -224,6 +224,13 @@
224
224
  }
225
225
  ]
226
226
  },
227
+ {
228
+ "kind": "field",
229
+ "name": "sorters",
230
+ "type": {
231
+ "text": "SortersConfig | undefined"
232
+ }
233
+ },
227
234
  {
228
235
  "kind": "field",
229
236
  "name": "dirtyData",
@@ -9797,34 +9804,67 @@
9797
9804
  },
9798
9805
  {
9799
9806
  "kind": "javascript-module",
9800
- "path": "src/filters/index.ts",
9801
- "declarations": [],
9807
+ "path": "src/filters/filter-checkbox.ts",
9808
+ "declarations": [
9809
+ {
9810
+ "kind": "function",
9811
+ "name": "FilterCheckbox",
9812
+ "parameters": [
9813
+ {
9814
+ "name": "column"
9815
+ },
9816
+ {
9817
+ "name": "owner"
9818
+ }
9819
+ ]
9820
+ }
9821
+ ],
9802
9822
  "exports": [
9803
9823
  {
9804
9824
  "kind": "js",
9805
- "name": "*",
9825
+ "name": "FilterCheckbox",
9806
9826
  "declaration": {
9807
- "name": "*",
9808
- "package": "./registry"
9827
+ "name": "FilterCheckbox",
9828
+ "module": "src/filters/filter-checkbox.ts"
9809
9829
  }
9810
- },
9830
+ }
9831
+ ]
9832
+ },
9833
+ {
9834
+ "kind": "javascript-module",
9835
+ "path": "src/filters/filter-input.ts",
9836
+ "declarations": [
9837
+ {
9838
+ "kind": "function",
9839
+ "name": "FilterInput",
9840
+ "parameters": [
9841
+ {
9842
+ "name": "column"
9843
+ },
9844
+ {
9845
+ "name": "owner"
9846
+ }
9847
+ ]
9848
+ }
9849
+ ],
9850
+ "exports": [
9811
9851
  {
9812
9852
  "kind": "js",
9813
- "name": "*",
9853
+ "name": "FilterInput",
9814
9854
  "declaration": {
9815
- "name": "*",
9816
- "package": "./list-select"
9855
+ "name": "FilterInput",
9856
+ "module": "src/filters/filter-input.ts"
9817
9857
  }
9818
9858
  }
9819
9859
  ]
9820
9860
  },
9821
9861
  {
9822
9862
  "kind": "javascript-module",
9823
- "path": "src/filters/list-select.ts",
9863
+ "path": "src/filters/filter-range-date.ts",
9824
9864
  "declarations": [
9825
9865
  {
9826
9866
  "kind": "function",
9827
- "name": "ListSelect",
9867
+ "name": "FilterRangeDate",
9828
9868
  "parameters": [
9829
9869
  {
9830
9870
  "name": "column"
@@ -9838,10 +9878,142 @@
9838
9878
  "exports": [
9839
9879
  {
9840
9880
  "kind": "js",
9841
- "name": "ListSelect",
9881
+ "name": "FilterRangeDate",
9842
9882
  "declaration": {
9843
- "name": "ListSelect",
9844
- "module": "src/filters/list-select.ts"
9883
+ "name": "FilterRangeDate",
9884
+ "module": "src/filters/filter-range-date.ts"
9885
+ }
9886
+ }
9887
+ ]
9888
+ },
9889
+ {
9890
+ "kind": "javascript-module",
9891
+ "path": "src/filters/filter-range-number.ts",
9892
+ "declarations": [
9893
+ {
9894
+ "kind": "function",
9895
+ "name": "FilterRangeNumber",
9896
+ "parameters": [
9897
+ {
9898
+ "name": "column"
9899
+ },
9900
+ {
9901
+ "name": "owner"
9902
+ }
9903
+ ]
9904
+ }
9905
+ ],
9906
+ "exports": [
9907
+ {
9908
+ "kind": "js",
9909
+ "name": "FilterRangeNumber",
9910
+ "declaration": {
9911
+ "name": "FilterRangeNumber",
9912
+ "module": "src/filters/filter-range-number.ts"
9913
+ }
9914
+ }
9915
+ ]
9916
+ },
9917
+ {
9918
+ "kind": "javascript-module",
9919
+ "path": "src/filters/filter-select.ts",
9920
+ "declarations": [
9921
+ {
9922
+ "kind": "function",
9923
+ "name": "FilterSelect",
9924
+ "parameters": [
9925
+ {
9926
+ "name": "column"
9927
+ },
9928
+ {
9929
+ "name": "owner"
9930
+ }
9931
+ ]
9932
+ }
9933
+ ],
9934
+ "exports": [
9935
+ {
9936
+ "kind": "js",
9937
+ "name": "FilterSelect",
9938
+ "declaration": {
9939
+ "name": "FilterSelect",
9940
+ "module": "src/filters/filter-select.ts"
9941
+ }
9942
+ }
9943
+ ]
9944
+ },
9945
+ {
9946
+ "kind": "javascript-module",
9947
+ "path": "src/filters/filter-styles.ts",
9948
+ "declarations": [
9949
+ {
9950
+ "kind": "variable",
9951
+ "name": "FilterStyles",
9952
+ "default": "css`\n :host {\n --ox-input-placeholder-color: var(--primary-color);\n\n --ox-input-padding: var(--padding-narrow) var(--padding-default);\n --ox-input-border: 1px solid rgba(0, 0, 0, 0.2);\n --ox-input-border-radius: var(--border-radius);\n --ox-input-font: normal 14px var(--theme-font);\n --ox-input-color: var(--primary-text-color);\n }\n\n [filter] input::placeholder {\n color: var(--ox-input-placeholder-color);\n opacity: 0.7;\n }\n [filter] input {\n margin: 0 10px 5px 10px;\n padding: var(--ox-input-padding);\n border: var(--ox-input-border);\n border-radius: var(--ox-input-border-radius);\n font: var(--ox-input-font);\n color: var(--ox-input-color, #3a5877);\n }\n [filter] input[type='number'] {\n padding-right: var(--padding-narrow);\n max-width: 100px;\n }\n [filter] input[type='datetime-local'] {\n padding-right: var(--padding-narrow);\n max-width: 170px;\n }\n [filter] input[name='from'] {\n margin: 0 0 5px 10px;\n }\n [filter] input[name='to'] {\n margin: 0 10px 5px 0;\n }\n`"
9953
+ }
9954
+ ],
9955
+ "exports": [
9956
+ {
9957
+ "kind": "js",
9958
+ "name": "FilterStyles",
9959
+ "declaration": {
9960
+ "name": "FilterStyles",
9961
+ "module": "src/filters/filter-styles.ts"
9962
+ }
9963
+ }
9964
+ ]
9965
+ },
9966
+ {
9967
+ "kind": "javascript-module",
9968
+ "path": "src/filters/index.ts",
9969
+ "declarations": [],
9970
+ "exports": [
9971
+ {
9972
+ "kind": "js",
9973
+ "name": "*",
9974
+ "declaration": {
9975
+ "name": "*",
9976
+ "package": "./registry"
9977
+ }
9978
+ },
9979
+ {
9980
+ "kind": "js",
9981
+ "name": "*",
9982
+ "declaration": {
9983
+ "name": "*",
9984
+ "package": "./filter-select"
9985
+ }
9986
+ },
9987
+ {
9988
+ "kind": "js",
9989
+ "name": "*",
9990
+ "declaration": {
9991
+ "name": "*",
9992
+ "package": "./filter-input"
9993
+ }
9994
+ },
9995
+ {
9996
+ "kind": "js",
9997
+ "name": "*",
9998
+ "declaration": {
9999
+ "name": "*",
10000
+ "package": "./filter-checkbox"
10001
+ }
10002
+ },
10003
+ {
10004
+ "kind": "js",
10005
+ "name": "*",
10006
+ "declaration": {
10007
+ "name": "*",
10008
+ "package": "./filter-range-date"
10009
+ }
10010
+ },
10011
+ {
10012
+ "kind": "js",
10013
+ "name": "*",
10014
+ "declaration": {
10015
+ "name": "*",
10016
+ "package": "./filter-range-number"
9845
10017
  }
9846
10018
  }
9847
10019
  ]
package/demo/index.html CHANGED
@@ -158,6 +158,9 @@
158
158
  // target: '_blank'
159
159
  }
160
160
  },
161
+ filter: {
162
+ type: 'text'
163
+ },
161
164
  sortable: true,
162
165
  width: 120
163
166
  },
@@ -184,6 +187,7 @@
184
187
  record: {
185
188
  editable: true
186
189
  },
190
+ filter: true,
187
191
  sortable: true,
188
192
  width: 130,
189
193
  validation: function (after, before, record, column) {
@@ -208,6 +212,7 @@
208
212
  record: {
209
213
  editable: true
210
214
  },
215
+ filter: true,
211
216
  handlers: {
212
217
  dblclick: () => {
213
218
  const grist = document.querySelector('ox-grist')
@@ -227,8 +232,7 @@
227
232
  editable: true
228
233
  },
229
234
  filter: {
230
- type: 'code',
231
- options: ['admin', 'worker', 'tester']
235
+ options: ['admin', 'worker', 'tester', 'xyz', 'VERY LONG OPTION - ABCDEFG']
232
236
  },
233
237
  sortable: true,
234
238
  width: 120
@@ -251,6 +255,7 @@
251
255
  align: 'right',
252
256
  editable: true
253
257
  },
258
+ filter: true,
254
259
  sortable: true,
255
260
  width: 50
256
261
  },
@@ -267,6 +272,9 @@
267
272
  record: {
268
273
  editable: true
269
274
  },
275
+ filter: {
276
+ type: 'datetime'
277
+ },
270
278
  sortable: true,
271
279
  width: 180
272
280
  },
@@ -329,32 +337,62 @@
329
337
 
330
338
  #headroom {
331
339
  display: flex;
332
- flex-direction: column;
333
- background-color: var(--primary-color);
334
- height: 200px;
340
+ flex-direction: row;
335
341
  align-items: center;
336
- justify-content: center;
337
- color: var(--theme-white-color);
342
+ padding: var(--padding-default) var(--padding-wide);
343
+ border-top: 2px solid rgba(0, 0, 0, 0.2);
344
+ background-color: var(--main-section-background-color);
338
345
  }
339
346
 
340
347
  #modes > * {
341
348
  padding: var(--padding-narrow);
342
- font-size: 1.5em;
343
- opacity: 0.7;
349
+ font-size: 1em;
350
+ opacity: 0.5;
351
+ color: var(--primary-text-color);
352
+ cursor: pointer;
344
353
  }
345
354
 
346
355
  #modes > mwc-icon[active] {
347
- border: 1px solid var(--status-warning-color);
348
356
  border-radius: 9px;
349
- background-color: rgba(0, 0, 0, 0.3);
357
+ background-color: rgba(var(--primary-color-rgb), 0.05);
350
358
  opacity: 1;
359
+ color: var(--secondary-text-color);
360
+ cursor: default;
351
361
  }
352
362
 
353
363
  #filters {
354
- position: absolute;
355
- left: 10px;
356
- bottom: 10px;
357
- width: calc(100% - 20px);
364
+ flex: 1;
365
+ }
366
+
367
+ #tailer {
368
+ display: flex;
369
+ flex-direction: row;
370
+ margin: 0 var(--margin-default);
371
+ }
372
+ #tailer a {
373
+ padding: 0 var(--padding-narrow) 0 var(--padding-default);
374
+ margin: 0 var(--margin-narrow);
375
+ border-left: 1px solid rgba(0, 0, 0, 0.1);
376
+ font-size: var(--fontsize-default);
377
+ color: var(--primary-color);
378
+ }
379
+
380
+ #add button {
381
+ background-color: var(--status-success-color);
382
+ border: 0;
383
+ border-radius: 50%;
384
+ padding: 5px;
385
+ width: 36px;
386
+ height: 36px;
387
+ cursor: pointer;
388
+ }
389
+ #add button:hover {
390
+ background-color: var(--focus-background-color);
391
+ box-shadow: var(--box-shadow);
392
+ }
393
+ #add button mwc-icon {
394
+ font-size: 2em;
395
+ color: var(--theme-white-color);
358
396
  }
359
397
  `
360
398
  ]
@@ -382,30 +420,6 @@
382
420
  ></ox-grist-search-form>
383
421
  <ox-grist .config=${config} .mode=${mode} auto-fetch .fetchHandler=${fetchHandler}>
384
422
  <div slot="headroom" id="headroom">
385
- <h1>HEAD ROOM AREA</h1>
386
- <div id="modes">
387
- <mwc-icon @click=${() => (this.mode = 'GRID')} ?active=${mode == 'GRID'}>view_list</mwc-icon>
388
- <mwc-icon @click=${() => (this.mode = 'LIST')} ?active=${mode == 'LIST'}>menu</mwc-icon>
389
- <mwc-icon @click=${() => (this.mode = 'CARD')} ?active=${mode == 'CARD'}>apps</mwc-icon>
390
- </div>
391
- <div id="tailer">
392
- <a href="./report-test.html">Report Test</a>|
393
- <a
394
- href="#"
395
- @click=${() => {
396
- this.renderRoot.querySelector('ox-grist').reset()
397
- }}
398
- >Reset</a
399
- >|
400
- <a
401
- href="#"
402
- @click=${() => {
403
- this.renderRoot.querySelector('ox-grist').fetch(true)
404
- }}
405
- >Fetch</a
406
- >
407
- </div>
408
-
409
423
  <div id="filters">
410
424
  <mwc-icon
411
425
  @click=${e => {
@@ -461,6 +475,32 @@
461
475
  </div>
462
476
  </ox-popup-list>
463
477
  </div>
478
+ <div id="modes">
479
+ <mwc-icon @click=${() => (this.mode = 'GRID')} ?active=${mode == 'GRID'}>view_list</mwc-icon>
480
+ <mwc-icon @click=${() => (this.mode = 'LIST')} ?active=${mode == 'LIST'}>menu</mwc-icon>
481
+ <mwc-icon @click=${() => (this.mode = 'CARD')} ?active=${mode == 'CARD'}>apps</mwc-icon>
482
+ </div>
483
+
484
+ <div id="tailer">
485
+ <a href="./report-test.html">Report Test</a>
486
+ <a
487
+ href="#"
488
+ @click=${() => {
489
+ this.renderRoot.querySelector('ox-grist').reset()
490
+ }}
491
+ >Reset</a
492
+ >
493
+ <a
494
+ href="#"
495
+ @click=${() => {
496
+ this.renderRoot.querySelector('ox-grist').fetch(true)
497
+ }}
498
+ >Fetch</a
499
+ >
500
+ </div>
501
+ <div id="add">
502
+ <button><mwc-icon>add</mwc-icon></button>
503
+ </div>
464
504
  </div>
465
505
  </ox-grist>
466
506
  `
@@ -1,8 +1,8 @@
1
1
  import '@operato/popup';
2
2
  import '@operato/input';
3
3
  import '@material/mwc-icon';
4
- import { ColumnConfig, GristConfig, GristData } from '../types';
5
4
  import { LitElement, PropertyValues } from 'lit';
5
+ import { ColumnConfig, GristConfig, GristData } from '../types';
6
6
  export declare class DataGridHeader extends LitElement {
7
7
  static styles: import("lit").CSSResult[];
8
8
  config: GristConfig;
@@ -2,11 +2,12 @@ import { __decorate } from "tslib";
2
2
  import '@operato/popup';
3
3
  import '@operato/input';
4
4
  import '@material/mwc-icon';
5
- import { LitElement, css, html } from 'lit';
6
- import { ZERO_COLUMNS, ZERO_CONFIG, ZERO_DATA } from '../configure/zero-config';
5
+ import { css, html, LitElement } from 'lit';
7
6
  import { customElement, property, state } from 'lit/decorators.js';
8
- import { getRenderer } from '../filters/registry';
9
7
  import throttle from 'lodash-es/throttle';
8
+ import { ZERO_COLUMNS, ZERO_CONFIG, ZERO_DATA } from '../configure/zero-config';
9
+ import { FilterStyles } from '../filters/filter-styles';
10
+ import { getRenderer } from '../filters/registry';
10
11
  let DataGridHeader = class DataGridHeader extends LitElement {
11
12
  constructor() {
12
13
  super(...arguments);
@@ -71,13 +72,13 @@ let DataGridHeader = class DataGridHeader extends LitElement {
71
72
  }
72
73
  }
73
74
  _renderFilterHeader(column) {
74
- var _a;
75
75
  var filter = column.filter;
76
+ const type = typeof filter === 'boolean' ? column.type : (filter === null || filter === void 0 ? void 0 : filter.type) || column.type;
76
77
  return html `
77
78
  <mwc-icon
78
79
  @click=${(e) => {
79
80
  const parent = e.target.closest('[column]');
80
- const popup = parent.querySelector('[popup]');
81
+ const popup = parent.querySelector('ox-popup, ox-popup-list');
81
82
  // const popup = (e.target as HTMLElement).nextSibling as OxPopupList | null
82
83
  // absolute position인 popup의 위치 부모는 grist 이므로,
83
84
  // data-grid-header 의 포지션 부모(grist)의 위치로부터 계산해야함.
@@ -92,7 +93,15 @@ let DataGridHeader = class DataGridHeader extends LitElement {
92
93
  >filter_alt</mwc-icon
93
94
  >
94
95
 
95
- ${getRenderer(((_a = column.filter) === null || _a === void 0 ? void 0 : _a.type) || column.type)(column, this)}
96
+ ${type === 'select'
97
+ ? html `<ox-popup-list multiple attr-selected="checked"
98
+ ><div filter-title><mwc-icon>filter_alt</mwc-icon> filter by <strong>${column.name}</strong></div>
99
+ ${getRenderer(type)(column, this)}</ox-popup-list
100
+ >`
101
+ : html ` <ox-popup
102
+ ><div filter-title><mwc-icon>filter_alt</mwc-icon> filter by <strong>${column.name}</strong></div>
103
+ ${getRenderer(type)(column, this)}</ox-popup
104
+ >`}
96
105
  `;
97
106
  }
98
107
  updated(changes) {
@@ -173,6 +182,7 @@ let DataGridHeader = class DataGridHeader extends LitElement {
173
182
  }
174
183
  };
175
184
  DataGridHeader.styles = [
185
+ FilterStyles,
176
186
  css `
177
187
  :host {
178
188
  display: grid;
@@ -181,7 +191,7 @@ DataGridHeader.styles = [
181
191
  overflow: hidden;
182
192
  }
183
193
 
184
- div {
194
+ :scope > div {
185
195
  display: flex;
186
196
 
187
197
  white-space: nowrap;
@@ -222,11 +232,15 @@ DataGridHeader.styles = [
222
232
  padding: 0;
223
233
  border: 0;
224
234
  }
225
- span[sorter] mwc-icon,
226
- span[filter] mwc-icon {
235
+ span[sorter] mwc-icon {
227
236
  font-size: var(--grid-header-sorter-size);
228
237
  }
229
238
 
239
+ span[filter] > mwc-icon {
240
+ font-size: var(--fontsize-default);
241
+ line-height: 20px;
242
+ }
243
+
230
244
  span[splitter] {
231
245
  cursor: col-resize;
232
246
  border-right: var(--grid-header-splitter-border);
@@ -239,6 +253,22 @@ DataGridHeader.styles = [
239
253
  margin: 3px 0 0 0;
240
254
  zoom: var(--grist-input-zoom);
241
255
  }
256
+ [filter-title] {
257
+ color: var(--grid-header-filter-title-color);
258
+ font: var(--grid-header-filter-title-font);
259
+ text-transform: capitalize;
260
+ }
261
+ [filter-title] * {
262
+ vertical-align: middle;
263
+ }
264
+ [filter-title] mwc-icon {
265
+ opacity: 0.7;
266
+ color: var(--grid-header-filter-title-icon-color);
267
+ }
268
+ [filter] input[type='checkbox'] {
269
+ margin-left: 10px;
270
+ margin-bottom: 5px;
271
+ }
242
272
 
243
273
  @media print {
244
274
  :host {
@@ -1 +1 @@
1
- {"version":3,"file":"data-grid-header.js","sourceRoot":"","sources":["../../../src/data-grid/data-grid-header.ts"],"names":[],"mappings":"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","sourcesContent":["import '@operato/popup'\nimport '@operato/input'\nimport '@material/mwc-icon'\n\nimport { ColumnConfig, GristConfig, GristData, SortersConfig } from '../types'\nimport { LitElement, PropertyValues, css, html } from 'lit'\nimport { OxPopup, OxPopupList } from '@operato/popup'\nimport { ZERO_COLUMNS, ZERO_CONFIG, ZERO_DATA } from '../configure/zero-config'\nimport { customElement, property, state } from 'lit/decorators.js'\n\nimport { getRenderer } from '../filters/registry'\nimport throttle from 'lodash-es/throttle'\n\n@customElement('ox-grid-header')\nexport class DataGridHeader extends LitElement {\n static styles = [\n css`\n :host {\n display: grid;\n grid-template-columns: var(--grid-template-columns);\n\n overflow: hidden;\n }\n\n div {\n display: flex;\n\n white-space: nowrap;\n overflow: hidden;\n background-color: var(--grid-header-background-color);\n border-top: var(--grid-header-top-border);\n border-bottom: var(--grid-header-bottom-border);\n padding: var(--grid-header-padding);\n\n text-overflow: ellipsis;\n font: var(--grid-header-font);\n color: var(--grid-header-color);\n }\n\n div[gutter] {\n padding: var(--padding-default) 0 var(--padding-narrow) 0;\n text-align: center;\n }\n\n span {\n display: block;\n white-space: nowrap;\n overflow: hidden;\n }\n\n span[for-title] {\n flex: 1;\n text-overflow: ellipsis;\n line-height: 1.6;\n text-transform: capitalize;\n }\n span[for-title] mwc-icon {\n font-size: var(--grid-record-fontsize);\n }\n\n span[sorter],\n span[filter] {\n padding: 0;\n border: 0;\n }\n span[sorter] mwc-icon,\n span[filter] mwc-icon {\n font-size: var(--grid-header-sorter-size);\n }\n\n span[splitter] {\n cursor: col-resize;\n border-right: var(--grid-header-splitter-border);\n }\n span[splitter]:hover {\n border-right: var(--grid-header-splitter-border-hover);\n }\n input[type='checkbox'],\n input[type='radio'] {\n margin: 3px 0 0 0;\n zoom: var(--grist-input-zoom);\n }\n\n @media print {\n :host {\n grid-template-columns: var(--grid-template-print-columns);\n }\n }\n `\n ]\n\n @property({ type: Object }) config: GristConfig = ZERO_CONFIG\n @property({ type: Array }) columns: ColumnConfig[] = ZERO_COLUMNS\n @property({ type: Object }) data: GristData = ZERO_DATA\n\n @state() private _sorters: SortersConfig = []\n private _lastAccVal?: number\n private _throttledNotifier?: any\n\n render() {\n var columns = this.columns || []\n\n return html`\n ${columns.map((column, idx) =>\n !column.hidden\n ? html`\n <div ?gutter=${column.type == 'gutter'} column>\n <span for-title @click=${(e: MouseEvent) => this._changeSort(column)}\n >${this._renderHeader(column)}\n </span>\n\n ${column.sortable\n ? html`\n <span sorter @click=${(e: MouseEvent) => this._changeSort(column)}>\n ${this._renderSortHeader(column)}\n </span>\n `\n : undefined}\n ${column.filter ? html` <span filter> ${this._renderFilterHeader(column)} </span> ` : undefined}\n ${column.resizable !== false\n ? html`\n <span splitter draggable=\"false\" @mousedown=${(e: MouseEvent) => this._mousedown(e, idx)}\n >&nbsp;</span\n >\n `\n : undefined}\n </div>\n `\n : undefined\n )}\n\n <div column></div>\n `\n }\n\n _renderHeader(column: ColumnConfig) {\n var { renderer } = column.header || {}\n var title = renderer.call(this, column)\n\n return html` ${title} `\n }\n\n _renderSortHeader(column: ColumnConfig) {\n var sorters = this._sorters\n\n var sorter = sorters.find(sorter => column.type !== 'gutter' && column.name == sorter.name)\n if (!sorter) {\n return html``\n }\n\n if (sorters.length > 1) {\n var rank = sorters.indexOf(sorter) + 1\n return sorter.desc\n ? html` <mwc-icon>keyboard_arrow_up</mwc-icon><sub>${rank}</sub> `\n : html` <mwc-icon>keyboard_arrow_down</mwc-icon><sub>${rank}</sub> `\n } else {\n return sorter.desc\n ? html` <mwc-icon>keyboard_arrow_up</mwc-icon> `\n : html` <mwc-icon>keyboard_arrow_down</mwc-icon> `\n }\n }\n\n _renderFilterHeader(column: ColumnConfig) {\n var filter = column.filter\n\n return html`\n <mwc-icon\n @click=${(e: Event) => {\n const parent = (e.target as HTMLElement).closest('[column]') as HTMLElement\n const popup = parent.querySelector('[popup]') as OxPopup | null\n // const popup = (e.target as HTMLElement).nextSibling as OxPopupList | null\n\n // absolute position인 popup의 위치 부모는 grist 이므로,\n // data-grid-header 의 포지션 부모(grist)의 위치로부터 계산해야함.\n // this의 position을 relative로 하지 못하는 이유 : ox-popup-list가 grid body에 덮히기 때문.\n const top = parent.offsetTop + parent.offsetHeight\n const right = this.clientWidth - (parent.offsetLeft + parent.offsetWidth - this.scrollLeft)\n\n popup?.open({\n right,\n top\n })\n }}\n >filter_alt</mwc-icon\n >\n\n ${getRenderer(column.filter?.type || column.type)(column, this)}\n `\n }\n\n updated(changes: PropertyValues<this>) {\n if (changes.has('config')) {\n this._sorters = this.config.sorters || []\n }\n }\n\n _changeSort(column: ColumnConfig) {\n if (!column.sortable) {\n return\n }\n\n var sorters = [...this._sorters]\n\n var idx = sorters.findIndex(sorter => sorter.name == column.name)\n if (idx !== -1) {\n let sorter = sorters[idx]\n if (sorter.desc) {\n sorters.splice(idx, 1)\n } else {\n sorter.desc = true\n }\n } else {\n var sorter = {\n name: column.name\n }\n\n sorters.push(sorter)\n }\n\n this._sorters = sorters\n\n this.dispatchEvent(\n new CustomEvent('sorters-change', {\n bubbles: true,\n composed: true,\n detail: this._sorters\n })\n )\n }\n\n _accumalate(x: number) {\n this._lastAccVal = (this._lastAccVal ?? 0) + x\n return this._lastAccVal\n }\n\n _notifyWidthChange(idx: number, width: number) {\n if (!this._throttledNotifier) {\n this._throttledNotifier = throttle((idx: number, width: number) => {\n this.dispatchEvent(\n new CustomEvent('column-width-change', {\n bubbles: true,\n composed: true,\n detail: {\n idx,\n width\n }\n })\n )\n\n this._lastAccVal = 0\n }, 100)\n }\n\n this._throttledNotifier(idx, width)\n }\n\n _mousedown(e: MouseEvent, idx: number) {\n e.stopPropagation()\n e.preventDefault()\n\n var mousemoveHandler = ((e: MouseEvent) => {\n e.stopPropagation()\n e.preventDefault()\n let column = this.columns[idx]\n\n let width = Math.max(0, Number(column.width) + this._accumalate(e.movementX))\n if (width == 0) {\n /* CLARIFY-ME 왜 마지막 이벤트의 offsetX로 음수 값이 오는가 */\n return\n }\n\n this._notifyWidthChange(idx, width)\n }).bind(this)\n\n var mouseupHandler = ((e: MouseEvent) => {\n document.removeEventListener('mousemove', mousemoveHandler)\n document.removeEventListener('mouseup', mouseupHandler)\n\n mousemoveHandler(e)\n }).bind(this)\n\n document.addEventListener('mousemove', mousemoveHandler)\n document.addEventListener('mouseup', mouseupHandler)\n }\n}\n"]}
1
+ {"version":3,"file":"data-grid-header.js","sourceRoot":"","sources":["../../../src/data-grid/data-grid-header.ts"],"names":[],"mappings":";AAAA,OAAO,gBAAgB,CAAA;AACvB,OAAO,gBAAgB,CAAA;AACvB,OAAO,oBAAoB,CAAA;AAE3B,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,EAAkB,MAAM,KAAK,CAAA;AAC3D,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAClE,OAAO,QAAQ,MAAM,oBAAoB,CAAA;AAIzC,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AAC/E,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AAIjD,IAAa,cAAc,GAA3B,MAAa,cAAe,SAAQ,UAAU;IAA9C;;QAkG8B,WAAM,GAAgB,WAAW,CAAA;QAClC,YAAO,GAAmB,YAAY,CAAA;QACrC,SAAI,GAAc,SAAS,CAAA;QAEtC,aAAQ,GAAkB,EAAE,CAAA;IAsM/C,CAAC;IAlMC,MAAM;QACJ,IAAI,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,EAAE,CAAA;QAEhC,OAAO,IAAI,CAAA;QACP,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE,CAC5B,CAAC,MAAM,CAAC,MAAM;YACZ,CAAC,CAAC,IAAI,CAAA;6BACa,MAAM,CAAC,IAAI,IAAI,QAAQ;yCACX,CAAC,CAAa,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC;qBAC/D,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC;;;kBAG7B,MAAM,CAAC,QAAQ;gBACf,CAAC,CAAC,IAAI,CAAA;4CACoB,CAAC,CAAa,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC;0BAC7D,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC;;qBAEnC;gBACH,CAAC,CAAC,SAAS;kBACX,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAA,kBAAkB,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS;kBAC7F,MAAM,CAAC,SAAS,KAAK,KAAK;gBAC1B,CAAC,CAAC,IAAI,CAAA;oEAC4C,CAAC,CAAa,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,EAAE,GAAG,CAAC;;;qBAGzF;gBACH,CAAC,CAAC,SAAS;;aAEhB;YACH,CAAC,CAAC,SAAS,CACd;;;KAGF,CAAA;IACH,CAAC;IAED,aAAa,CAAC,MAAoB;QAChC,IAAI,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC,MAAM,IAAI,EAAE,CAAA;QACtC,IAAI,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;QAEvC,OAAO,IAAI,CAAA,IAAI,KAAK,GAAG,CAAA;IACzB,CAAC;IAED,iBAAiB,CAAC,MAAoB;QACpC,IAAI,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAA;QAE3B,IAAI,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,CAAA;QAC3F,IAAI,CAAC,MAAM,EAAE;YACX,OAAO,IAAI,CAAA,EAAE,CAAA;SACd;QAED,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE;YACtB,IAAI,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;YACtC,OAAO,MAAM,CAAC,IAAI;gBAChB,CAAC,CAAC,IAAI,CAAA,+CAA+C,IAAI,SAAS;gBAClE,CAAC,CAAC,IAAI,CAAA,iDAAiD,IAAI,SAAS,CAAA;SACvE;aAAM;YACL,OAAO,MAAM,CAAC,IAAI;gBAChB,CAAC,CAAC,IAAI,CAAA,0CAA0C;gBAChD,CAAC,CAAC,IAAI,CAAA,4CAA4C,CAAA;SACrD;IACH,CAAC;IAED,mBAAmB,CAAC,MAAoB;QACtC,IAAI,MAAM,GAAG,MAAM,CAAC,MAAM,CAAA;QAC1B,MAAM,IAAI,GAAG,OAAO,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,IAAI,KAAI,MAAM,CAAC,IAAI,CAAA;QAEpF,OAAO,IAAI,CAAA;;iBAEE,CAAC,CAAQ,EAAE,EAAE;YACpB,MAAM,MAAM,GAAI,CAAC,CAAC,MAAsB,CAAC,OAAO,CAAC,UAAU,CAAgB,CAAA;YAC3E,MAAM,KAAK,GAAG,MAAM,CAAC,aAAa,CAAC,yBAAyB,CAAmB,CAAA;YAC/E,4EAA4E;YAE5E,8CAA8C;YAC9C,iDAAiD;YACjD,0EAA0E;YAC1E,MAAM,GAAG,GAAG,MAAM,CAAC,SAAS,GAAG,MAAM,CAAC,YAAY,CAAA;YAClD,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,GAAG,CAAC,MAAM,CAAC,UAAU,GAAG,MAAM,CAAC,WAAW,GAAG,IAAI,CAAC,UAAU,CAAC,CAAA;YAE3F,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,IAAI,CAAC;gBACV,KAAK;gBACL,GAAG;aACJ,CAAC,CAAA;QACJ,CAAC;;;;QAID,IAAI,KAAK,QAAQ;YACjB,CAAC,CAAC,IAAI,CAAA;mFACqE,MAAM,CAAC,IAAI;cAChF,WAAW,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,IAAI,CAAC;YACjC;YACJ,CAAC,CAAC,IAAI,CAAA;mFACqE,MAAM,CAAC,IAAI;cAChF,WAAW,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,IAAI,CAAC;YACjC;KACP,CAAA;IACH,CAAC;IAED,OAAO,CAAC,OAA6B;QACnC,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE;YACzB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAA;SAC1C;IACH,CAAC;IAED,WAAW,CAAC,MAAoB;QAC9B,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE;YACpB,OAAM;SACP;QAED,IAAI,OAAO,GAAG,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAA;QAEhC,IAAI,GAAG,GAAG,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,CAAA;QACjE,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE;YACd,IAAI,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAA;YACzB,IAAI,MAAM,CAAC,IAAI,EAAE;gBACf,OAAO,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAA;aACvB;iBAAM;gBACL,MAAM,CAAC,IAAI,GAAG,IAAI,CAAA;aACnB;SACF;aAAM;YACL,IAAI,MAAM,GAAG;gBACX,IAAI,EAAE,MAAM,CAAC,IAAI;aAClB,CAAA;YAED,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;SACrB;QAED,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAA;QAEvB,IAAI,CAAC,aAAa,CAChB,IAAI,WAAW,CAAC,gBAAgB,EAAE;YAChC,OAAO,EAAE,IAAI;YACb,QAAQ,EAAE,IAAI;YACd,MAAM,EAAE,IAAI,CAAC,QAAQ;SACtB,CAAC,CACH,CAAA;IACH,CAAC;IAED,WAAW,CAAC,CAAS;;QACnB,IAAI,CAAC,WAAW,GAAG,CAAC,MAAA,IAAI,CAAC,WAAW,mCAAI,CAAC,CAAC,GAAG,CAAC,CAAA;QAC9C,OAAO,IAAI,CAAC,WAAW,CAAA;IACzB,CAAC;IAED,kBAAkB,CAAC,GAAW,EAAE,KAAa;QAC3C,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE;YAC5B,IAAI,CAAC,kBAAkB,GAAG,QAAQ,CAAC,CAAC,GAAW,EAAE,KAAa,EAAE,EAAE;gBAChE,IAAI,CAAC,aAAa,CAChB,IAAI,WAAW,CAAC,qBAAqB,EAAE;oBACrC,OAAO,EAAE,IAAI;oBACb,QAAQ,EAAE,IAAI;oBACd,MAAM,EAAE;wBACN,GAAG;wBACH,KAAK;qBACN;iBACF,CAAC,CACH,CAAA;gBAED,IAAI,CAAC,WAAW,GAAG,CAAC,CAAA;YACtB,CAAC,EAAE,GAAG,CAAC,CAAA;SACR;QAED,IAAI,CAAC,kBAAkB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;IACrC,CAAC;IAED,UAAU,CAAC,CAAa,EAAE,GAAW;QACnC,CAAC,CAAC,eAAe,EAAE,CAAA;QACnB,CAAC,CAAC,cAAc,EAAE,CAAA;QAElB,IAAI,gBAAgB,GAAG,CAAC,CAAC,CAAa,EAAE,EAAE;YACxC,CAAC,CAAC,eAAe,EAAE,CAAA;YACnB,CAAC,CAAC,cAAc,EAAE,CAAA;YAClB,IAAI,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;YAE9B,IAAI,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAA;YAC7E,IAAI,KAAK,IAAI,CAAC,EAAE;gBACd,8CAA8C;gBAC9C,OAAM;aACP;YAED,IAAI,CAAC,kBAAkB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;QACrC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAEb,IAAI,cAAc,GAAG,CAAC,CAAC,CAAa,EAAE,EAAE;YACtC,QAAQ,CAAC,mBAAmB,CAAC,WAAW,EAAE,gBAAgB,CAAC,CAAA;YAC3D,QAAQ,CAAC,mBAAmB,CAAC,SAAS,EAAE,cAAc,CAAC,CAAA;YAEvD,gBAAgB,CAAC,CAAC,CAAC,CAAA;QACrB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAEb,QAAQ,CAAC,gBAAgB,CAAC,WAAW,EAAE,gBAAgB,CAAC,CAAA;QACxD,QAAQ,CAAC,gBAAgB,CAAC,SAAS,EAAE,cAAc,CAAC,CAAA;IACtD,CAAC;CACF,CAAA;AA3SQ,qBAAM,GAAG;IACd,YAAY;IACZ,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA4FF;CACF,CAAA;AAE2B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;8CAAkC;AAClC;IAA1B,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;+CAAuC;AACrC;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;4CAA4B;AAE9C;IAAR,KAAK,EAAE;gDAAqC;AAtGlC,cAAc;IAD1B,aAAa,CAAC,gBAAgB,CAAC;GACnB,cAAc,CA4S1B;SA5SY,cAAc","sourcesContent":["import '@operato/popup'\nimport '@operato/input'\nimport '@material/mwc-icon'\n\nimport { css, html, LitElement, PropertyValues } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport throttle from 'lodash-es/throttle'\n\nimport { OxPopup } from '@operato/popup'\n\nimport { ZERO_COLUMNS, ZERO_CONFIG, ZERO_DATA } from '../configure/zero-config'\nimport { FilterStyles } from '../filters/filter-styles'\nimport { getRenderer } from '../filters/registry'\nimport { ColumnConfig, GristConfig, GristData, SortersConfig } from '../types'\n\n@customElement('ox-grid-header')\nexport class DataGridHeader extends LitElement {\n static styles = [\n FilterStyles,\n css`\n :host {\n display: grid;\n grid-template-columns: var(--grid-template-columns);\n\n overflow: hidden;\n }\n\n :scope > div {\n display: flex;\n\n white-space: nowrap;\n overflow: hidden;\n background-color: var(--grid-header-background-color);\n border-top: var(--grid-header-top-border);\n border-bottom: var(--grid-header-bottom-border);\n padding: var(--grid-header-padding);\n\n text-overflow: ellipsis;\n font: var(--grid-header-font);\n color: var(--grid-header-color);\n }\n\n div[gutter] {\n padding: var(--padding-default) 0 var(--padding-narrow) 0;\n text-align: center;\n }\n\n span {\n display: block;\n white-space: nowrap;\n overflow: hidden;\n }\n\n span[for-title] {\n flex: 1;\n text-overflow: ellipsis;\n line-height: 1.6;\n text-transform: capitalize;\n }\n span[for-title] mwc-icon {\n font-size: var(--grid-record-fontsize);\n }\n\n span[sorter],\n span[filter] {\n padding: 0;\n border: 0;\n }\n span[sorter] mwc-icon {\n font-size: var(--grid-header-sorter-size);\n }\n\n span[filter] > mwc-icon {\n font-size: var(--fontsize-default);\n line-height: 20px;\n }\n\n span[splitter] {\n cursor: col-resize;\n border-right: var(--grid-header-splitter-border);\n }\n span[splitter]:hover {\n border-right: var(--grid-header-splitter-border-hover);\n }\n input[type='checkbox'],\n input[type='radio'] {\n margin: 3px 0 0 0;\n zoom: var(--grist-input-zoom);\n }\n [filter-title] {\n color: var(--grid-header-filter-title-color);\n font: var(--grid-header-filter-title-font);\n text-transform: capitalize;\n }\n [filter-title] * {\n vertical-align: middle;\n }\n [filter-title] mwc-icon {\n opacity: 0.7;\n color: var(--grid-header-filter-title-icon-color);\n }\n [filter] input[type='checkbox'] {\n margin-left: 10px;\n margin-bottom: 5px;\n }\n\n @media print {\n :host {\n grid-template-columns: var(--grid-template-print-columns);\n }\n }\n `\n ]\n\n @property({ type: Object }) config: GristConfig = ZERO_CONFIG\n @property({ type: Array }) columns: ColumnConfig[] = ZERO_COLUMNS\n @property({ type: Object }) data: GristData = ZERO_DATA\n\n @state() private _sorters: SortersConfig = []\n private _lastAccVal?: number\n private _throttledNotifier?: any\n\n render() {\n var columns = this.columns || []\n\n return html`\n ${columns.map((column, idx) =>\n !column.hidden\n ? html`\n <div ?gutter=${column.type == 'gutter'} column>\n <span for-title @click=${(e: MouseEvent) => this._changeSort(column)}\n >${this._renderHeader(column)}\n </span>\n\n ${column.sortable\n ? html`\n <span sorter @click=${(e: MouseEvent) => this._changeSort(column)}>\n ${this._renderSortHeader(column)}\n </span>\n `\n : undefined}\n ${column.filter ? html` <span filter> ${this._renderFilterHeader(column)} </span> ` : undefined}\n ${column.resizable !== false\n ? html`\n <span splitter draggable=\"false\" @mousedown=${(e: MouseEvent) => this._mousedown(e, idx)}\n >&nbsp;</span\n >\n `\n : undefined}\n </div>\n `\n : undefined\n )}\n\n <div column></div>\n `\n }\n\n _renderHeader(column: ColumnConfig) {\n var { renderer } = column.header || {}\n var title = renderer.call(this, column)\n\n return html` ${title} `\n }\n\n _renderSortHeader(column: ColumnConfig) {\n var sorters = this._sorters\n\n var sorter = sorters.find(sorter => column.type !== 'gutter' && column.name == sorter.name)\n if (!sorter) {\n return html``\n }\n\n if (sorters.length > 1) {\n var rank = sorters.indexOf(sorter) + 1\n return sorter.desc\n ? html` <mwc-icon>keyboard_arrow_up</mwc-icon><sub>${rank}</sub> `\n : html` <mwc-icon>keyboard_arrow_down</mwc-icon><sub>${rank}</sub> `\n } else {\n return sorter.desc\n ? html` <mwc-icon>keyboard_arrow_up</mwc-icon> `\n : html` <mwc-icon>keyboard_arrow_down</mwc-icon> `\n }\n }\n\n _renderFilterHeader(column: ColumnConfig) {\n var filter = column.filter\n const type = typeof filter === 'boolean' ? column.type : filter?.type || column.type\n\n return html`\n <mwc-icon\n @click=${(e: Event) => {\n const parent = (e.target as HTMLElement).closest('[column]') as HTMLElement\n const popup = parent.querySelector('ox-popup, ox-popup-list') as OxPopup | null\n // const popup = (e.target as HTMLElement).nextSibling as OxPopupList | null\n\n // absolute position인 popup의 위치 부모는 grist 이므로,\n // data-grid-header 의 포지션 부모(grist)의 위치로부터 계산해야함.\n // this의 position을 relative로 하지 못하는 이유 : ox-popup-list가 grid body에 덮히기 때문.\n const top = parent.offsetTop + parent.offsetHeight\n const right = this.clientWidth - (parent.offsetLeft + parent.offsetWidth - this.scrollLeft)\n\n popup?.open({\n right,\n top\n })\n }}\n >filter_alt</mwc-icon\n >\n\n ${type === 'select'\n ? html`<ox-popup-list multiple attr-selected=\"checked\"\n ><div filter-title><mwc-icon>filter_alt</mwc-icon> filter by <strong>${column.name}</strong></div>\n ${getRenderer(type)(column, this)}</ox-popup-list\n >`\n : html` <ox-popup\n ><div filter-title><mwc-icon>filter_alt</mwc-icon> filter by <strong>${column.name}</strong></div>\n ${getRenderer(type)(column, this)}</ox-popup\n >`}\n `\n }\n\n updated(changes: PropertyValues<this>) {\n if (changes.has('config')) {\n this._sorters = this.config.sorters || []\n }\n }\n\n _changeSort(column: ColumnConfig) {\n if (!column.sortable) {\n return\n }\n\n var sorters = [...this._sorters]\n\n var idx = sorters.findIndex(sorter => sorter.name == column.name)\n if (idx !== -1) {\n let sorter = sorters[idx]\n if (sorter.desc) {\n sorters.splice(idx, 1)\n } else {\n sorter.desc = true\n }\n } else {\n var sorter = {\n name: column.name\n }\n\n sorters.push(sorter)\n }\n\n this._sorters = sorters\n\n this.dispatchEvent(\n new CustomEvent('sorters-change', {\n bubbles: true,\n composed: true,\n detail: this._sorters\n })\n )\n }\n\n _accumalate(x: number) {\n this._lastAccVal = (this._lastAccVal ?? 0) + x\n return this._lastAccVal\n }\n\n _notifyWidthChange(idx: number, width: number) {\n if (!this._throttledNotifier) {\n this._throttledNotifier = throttle((idx: number, width: number) => {\n this.dispatchEvent(\n new CustomEvent('column-width-change', {\n bubbles: true,\n composed: true,\n detail: {\n idx,\n width\n }\n })\n )\n\n this._lastAccVal = 0\n }, 100)\n }\n\n this._throttledNotifier(idx, width)\n }\n\n _mousedown(e: MouseEvent, idx: number) {\n e.stopPropagation()\n e.preventDefault()\n\n var mousemoveHandler = ((e: MouseEvent) => {\n e.stopPropagation()\n e.preventDefault()\n let column = this.columns[idx]\n\n let width = Math.max(0, Number(column.width) + this._accumalate(e.movementX))\n if (width == 0) {\n /* CLARIFY-ME 왜 마지막 이벤트의 offsetX로 음수 값이 오는가 */\n return\n }\n\n this._notifyWidthChange(idx, width)\n }).bind(this)\n\n var mouseupHandler = ((e: MouseEvent) => {\n document.removeEventListener('mousemove', mousemoveHandler)\n document.removeEventListener('mouseup', mouseupHandler)\n\n mousemoveHandler(e)\n }).bind(this)\n\n document.addEventListener('mousemove', mousemoveHandler)\n document.addEventListener('mouseup', mouseupHandler)\n }\n}\n"]}