@neovici/cosmoz-omnitable 8.5.3 → 8.6.0

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.
@@ -1,11 +1,17 @@
1
1
  import { html, component } from 'haunted';
2
2
  import { repeat } from 'lit-html/directives/repeat';
3
3
  import './lib/cosmoz-omnitable-resize-nub';
4
+ import sort from './lib/cosmoz-omnitable-sort';
4
5
 
5
- const renderHeaderRow = ({
6
+ const /* eslint-disable-next-line max-lines-per-function */
7
+ renderHeaderRow = ({
6
8
  data,
7
9
  columns,
8
10
  groupOnColumn,
11
+ sortOnColumn,
12
+ setSortOn,
13
+ descending,
14
+ setDescending,
9
15
  filters,
10
16
  setFilterState,
11
17
  }) =>
@@ -19,6 +25,13 @@ const renderHeaderRow = ({
19
25
  title=${column.title}
20
26
  name=${column.name}
21
27
  >
28
+ ${sort({
29
+ column,
30
+ sortOnColumn,
31
+ setSortOn,
32
+ descending,
33
+ setDescending,
34
+ })}
22
35
  ${column.renderHeader(
23
36
  column,
24
37
  filters[column.name] ?? {},
@@ -1,73 +1,123 @@
1
1
  /* eslint-disable max-lines */
2
- const checkbox = `
3
- .checkbox {
4
- box-sizing: border-box;
5
- width: 18px;
6
- height: 18px;
7
- background: transparent;
8
- border-radius: 4px;
9
- appearance: none;
10
- -webkit-appearance: none;
11
- outline: none;
12
- position: relative;
13
- user-select: none;
14
- cursor: pointer;
15
- display: inline-block;
16
- box-shadow: 0 0 0 2px rgba(0,0,0, 0.16) inset;
17
- -webkit-tap-highlight-color: rgba(0,0,0,0);
18
- vertical-align: middle;
19
- transition: background-color 140ms;
20
- margin: 1px 12px;
21
- flex: none;
22
- }
23
-
24
- .checkbox:checked {
25
- background-color: var(--cosmoz-omnitable-checkbox-checked-color, var(--primary-color));
26
- box-shadow: none;
27
- }
28
-
29
- .checkbox:checked::before {
30
- content: "";
31
- position: absolute;
32
- box-sizing: content-box;
33
- width: 5px;
34
- height: 10px;
35
- border: 2.4px solid #fff;
36
- border-top: none;
37
- border-left: none;
38
- transform-origin: 5px 10px;
39
- transform: translate(3px) rotate(45deg);
40
- }
41
-
42
- .checkbox::after {
43
- content: '';
44
- display: block;
45
- bottom: -5px;
46
- left: -5px;
47
- right: -5px;
48
- top: -5px;
49
- }
50
-
51
- .checkbox:hover {
52
- box-shadow: 0 0 0 2px rgba(0, 0, 0, 1) inset, 0 0 2px 6px #2021240f;
53
- }
54
-
55
- .checkbox:checked:hover {
56
- box-shadow: 0 0 2px 6px #2021240f;
57
- }
58
-
59
- .checkbox:indeterminate::before {
60
- content: "";
61
- position: absolute;
62
- width: 10px;
63
- height: 2px;
64
- left: 4px;
65
- top: 8px;
66
- background-color: var(--cosmoz-omnitable-checkbox-checked-color, var(--primary-color));
67
- }
68
- `;
2
+ import { tagged as css } from '@neovici/cosmoz-utils';
3
+ const checkbox = css`
4
+ .checkbox {
5
+ box-sizing: border-box;
6
+ width: 18px;
7
+ height: 18px;
8
+ background: transparent;
9
+ border-radius: 4px;
10
+ appearance: none;
11
+ -webkit-appearance: none;
12
+ outline: none;
13
+ position: relative;
14
+ user-select: none;
15
+ cursor: pointer;
16
+ display: inline-block;
17
+ box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.16) inset;
18
+ -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
19
+ vertical-align: middle;
20
+ transition: background-color 140ms;
21
+ margin: 1px 12px;
22
+ flex: none;
23
+ }
24
+
25
+ .checkbox:checked {
26
+ background-color: var(
27
+ --cosmoz-omnitable-checkbox-checked-color,
28
+ var(--primary-color)
29
+ );
30
+ box-shadow: none;
31
+ }
32
+
33
+ .checkbox:checked::before {
34
+ content: '';
35
+ position: absolute;
36
+ box-sizing: content-box;
37
+ width: 5px;
38
+ height: 10px;
39
+ border: 2.4px solid #fff;
40
+ border-top: none;
41
+ border-left: none;
42
+ transform-origin: 5px 10px;
43
+ transform: translate(3px) rotate(45deg);
44
+ }
45
+
46
+ .checkbox::after {
47
+ content: '';
48
+ display: block;
49
+ bottom: -5px;
50
+ left: -5px;
51
+ right: -5px;
52
+ top: -5px;
53
+ }
54
+
55
+ .checkbox:hover {
56
+ box-shadow: 0 0 0 2px rgba(0, 0, 0, 1) inset, 0 0 2px 6px #2021240f;
57
+ }
58
+
59
+ .checkbox:checked:hover {
60
+ box-shadow: 0 0 2px 6px #2021240f;
61
+ }
62
+
63
+ .checkbox:indeterminate::before {
64
+ content: '';
65
+ position: absolute;
66
+ width: 10px;
67
+ height: 2px;
68
+ left: 4px;
69
+ top: 8px;
70
+ background-color: var(
71
+ --cosmoz-omnitable-checkbox-checked-color,
72
+ var(--primary-color)
73
+ );
74
+ }
75
+ `,
76
+ sort = css`
77
+ .sort {
78
+ display: inline-flex;
79
+ width: 10px;
80
+ cursor: pointer;
81
+ align-items: center;
82
+ margin-top: 18px;
83
+ overflow: hidden;
84
+ flex: none;
85
+ background: none;
86
+ border: none;
87
+ outline: none;
88
+ color: inherit;
89
+ padding: 0;
90
+ order: 112;
91
+ }
92
+ .sort svg {
93
+ display: block;
94
+ }
95
+ .sort[data-sort] {
96
+ color: var(
97
+ --cosmoz-omnitable-checkbox-checked-color,
98
+ var(--primary-color)
99
+ );
100
+ }
101
+ .sort[data-sort='desc'] {
102
+ transform: scaleY(-1);
103
+ }
104
+ :not(:hover) > .sort:not([data-sort]) {
105
+ display: none;
106
+ }
107
+
108
+ .header-cell {
109
+ display: inline-flex;
110
+ position: relative;
111
+ }
112
+ .header-cell:hover .sort + *,
113
+ .header-cell .sort[data-sort] + * {
114
+ max-width: calc(100% - 10px);
115
+ }
116
+
117
+ `;
69
118
 
70
119
  export { checkbox };
120
+
71
121
  export default `<style>
72
122
  :host {
73
123
  display: flex;
@@ -115,7 +165,9 @@ export default `<style>
115
165
  }
116
166
  .header-cell {
117
167
  --paper-input-container: {
118
- padding-top: 0;
168
+ padding-top: 0;
169
+ padding-bottom: 0;
170
+ --paper-font-caption_-_line-height: 18px;
119
171
  }
120
172
  }
121
173
 
@@ -455,10 +507,10 @@ export default `<style>
455
507
  color: rgba(0, 0, 0, 0.54);
456
508
  }
457
509
 
458
- ${ checkbox }
510
+ ${checkbox}
459
511
 
460
512
  .all {
461
- margin-bottom: 14px;
513
+ margin-bottom: 6px;
462
514
  }
463
515
 
464
516
  .expand {
@@ -475,4 +527,5 @@ export default `<style>
475
527
  .expand:hover, .fold:hover {
476
528
  color: #000;
477
529
  }
530
+ ${sort}
478
531
  </style>`;
@@ -53,6 +53,10 @@ class Omnitable extends hauntedPolymer(useOmnitable)(mixin({ isEmpty }, translat
53
53
  columns="[[ normalizedColumns ]]"
54
54
  filters="[[ filters ]]"
55
55
  group-on-column="[[ groupOnColumn ]]"
56
+ descending="[[ descending ]]"
57
+ set-descending="[[ setDescending ]]"
58
+ sort-on-column="[[ sortOnColumn ]]"
59
+ set-sort-on="[[ setSortOn ]]"
56
60
  content="[[ _renderSettings(normalizedSettings, collapsedColumns, settingsId, hasChangedSettings, hasHiddenFilter, filters) ]]"
57
61
  set-filter-state="[[ setFilterState ]]"
58
62
  ></cosmoz-omnitable-header-row>
@@ -8,17 +8,17 @@ const placement = ['bottom-right', ...defaultPlacement],
8
8
  settingsStyles = `
9
9
  :host {
10
10
  box-sizing: border-box;
11
- padding: 12px;
12
11
  display: flex;
13
12
  flex-direction: column;
14
13
  max-height: 42vh;
15
14
  outline: none;
15
+ padding-top: 14px;
16
16
  }
17
17
  .list {
18
18
  overflow-y: auto;
19
19
  flex: 1;
20
- padding-top: 2px;
21
- min-width: 225px;
20
+ padding: 2px 14px;
21
+ min-width: 232px;
22
22
  }
23
23
  .item {
24
24
  display: flex;
@@ -32,7 +32,7 @@ const placement = ['bottom-right', ...defaultPlacement],
32
32
  .item.dragover {
33
33
  box-shadow: 0 -2px 0 0 currentColor;
34
34
  }
35
- .sort {
35
+ .pull {
36
36
  border: none;
37
37
  padding: 0;
38
38
  font-size: 0;
@@ -41,6 +41,7 @@ const placement = ['bottom-right', ...defaultPlacement],
41
41
  background: transparent;
42
42
  cursor: move;
43
43
  margin-right: 12px;
44
+ color: #c4c4c4;
44
45
  }
45
46
  .title {
46
47
  flex: 1;
@@ -48,12 +49,17 @@ const placement = ['bottom-right', ...defaultPlacement],
48
49
  .title[has-filter] {
49
50
  font-weight: bold;
50
51
  }
51
- ${ checkbox }
52
+ ${checkbox}
53
+ .checkbox {
54
+ margin: 4px 0;
55
+ }
52
56
 
53
57
  .buttons {
54
58
  display: flex;
59
+ gap: 8px;
55
60
  margin-top: 10px;
56
- gap: 7px;
61
+ padding: 12px 14px;
62
+ box-shadow: inset 0px 1px 0px rgba(0, 0, 0, 0.15);
57
63
  }
58
64
  .button {
59
65
  border: none;
@@ -62,32 +68,32 @@ const placement = ['bottom-right', ...defaultPlacement],
62
68
  color: var(--cosmoz-button-color, #fff);
63
69
  font-family: inherit;
64
70
  font-size: 13px;
65
- font-weight: 500;
71
+ font-weight: 600;
66
72
  line-height: 26px;
67
- height: 26px;
68
73
  border-radius: 4px;
69
- padding: 0 8px;
74
+ padding: 8px;
70
75
  flex: 1;
71
76
  }
72
- .button:hover {
73
- background: var(--cosmoz-button-hover-bg-color, #3A3F44);
77
+ .button:not(.reset):hover {
78
+ background: var(--cosmoz-button-hover-bg-color, #3A3F44);
74
79
  }
75
80
  .button[disabled] {
76
- opacity: 0.7;
81
+ opacity: 0.2;
77
82
  pointer-events: none;
78
83
  }
84
+ .reset {
85
+ background: transparent;
86
+ color: inherit;
87
+ text-decoration: underline;
88
+ }
79
89
  `,
80
-
81
- parseIndex = str => {
90
+ parseIndex = (str) => {
82
91
  const idx = parseInt(str, 10);
83
92
  return isFinite(idx) ? idx : undefined;
84
93
  },
85
-
86
94
  // eslint-disable-next-line max-lines-per-function
87
- useSettings = host => {
88
-
89
- const
90
- { settings, onSettings } = host,
95
+ useSettings = (host) => {
96
+ const { settings, onSettings } = host,
91
97
  meta = useMeta({ settings, onSettings });
92
98
 
93
99
  return {
@@ -101,30 +107,40 @@ const placement = ['bottom-right', ...defaultPlacement],
101
107
 
102
108
  filters: host.filters,
103
109
 
104
- onDown: useCallback(e => {
105
- if (!e.target.closest('.sort')) {
106
- return;
107
- }
110
+ onDown: useCallback(
111
+ (e) => {
112
+ if (!e.target.closest('.pull')) {
113
+ return;
114
+ }
108
115
 
109
- meta.handle = e.currentTarget;
110
- }, [meta]),
116
+ meta.handle = e.currentTarget;
117
+ },
118
+ [meta]
119
+ ),
111
120
 
112
- onDragStart: useCallback(e => {
113
- const { target } = e,
114
- index = parseIndex(target.dataset.index);
121
+ onDragStart: useCallback(
122
+ (e) => {
123
+ const { target } = e,
124
+ index = parseIndex(target.dataset.index);
115
125
 
116
- if (!meta.handle?.contains(target) || index == null) {
117
- return e.preventDefault();
118
- }
126
+ if (!meta.handle?.contains(target) || index == null) {
127
+ return e.preventDefault();
128
+ }
119
129
 
120
- meta.handle = null;
121
- e.dataTransfer.effectAllowed = 'move';
122
- e.dataTransfer.setData('omnitable/sort-index', index);
123
- setTimeout(() => target.classList.add('drag'), 0);
124
- target.addEventListener('dragend', e => e.target.classList.remove('drag'), { once: true });
125
- }, [meta]),
130
+ meta.handle = null;
131
+ e.dataTransfer.effectAllowed = 'move';
132
+ e.dataTransfer.setData('omnitable/sort-index', index);
133
+ setTimeout(() => target.classList.add('drag'), 0);
134
+ target.addEventListener(
135
+ 'dragend',
136
+ (e) => e.target.classList.remove('drag'),
137
+ { once: true }
138
+ );
139
+ },
140
+ [meta]
141
+ ),
126
142
 
127
- onDragEnter: useCallback(e => {
143
+ onDragEnter: useCallback((e) => {
128
144
  const ctg = e.currentTarget;
129
145
  if (ctg !== e.target) {
130
146
  return;
@@ -135,12 +151,12 @@ const placement = ['bottom-right', ...defaultPlacement],
135
151
  ctg.classList.add('dragover');
136
152
  }, []),
137
153
 
138
- onDragOver: useCallback(e => {
154
+ onDragOver: useCallback((e) => {
139
155
  e.preventDefault();
140
156
  e.currentTarget.classList.add('dragover');
141
157
  }, []),
142
158
 
143
- onDragLeave: useCallback(e => {
159
+ onDragLeave: useCallback((e) => {
144
160
  const ctg = e.currentTarget;
145
161
  if (ctg.contains(e.relatedTarget)) {
146
162
  return;
@@ -149,77 +165,152 @@ const placement = ['bottom-right', ...defaultPlacement],
149
165
  ctg.classList.remove('dragover');
150
166
  }, []),
151
167
 
152
- onDrop: useCallback(e => {
153
- const from = parseIndex(e.dataTransfer.getData('omnitable/sort-index')),
154
- to = parseIndex(e.currentTarget.dataset.index),
155
- { settings, onSettings } = meta;
168
+ onDrop: useCallback(
169
+ (e) => {
170
+ const from = parseIndex(
171
+ e.dataTransfer.getData('omnitable/sort-index')
172
+ ),
173
+ to = parseIndex(e.currentTarget.dataset.index),
174
+ { settings, onSettings } = meta;
156
175
 
157
- e.currentTarget.classList.remove('dragover');
158
- e.preventDefault();
176
+ e.currentTarget.classList.remove('dragover');
177
+ e.preventDefault();
159
178
 
160
- const newSettings = settings.slice();
161
- newSettings.splice(to + (from >= to ? 0 : -1), 0, newSettings.splice(from, 1)[0]);
162
- onSettings(newSettings);
163
- }, [meta]),
164
-
165
- onToggle: useCallback(e => {
166
- const checked = e.target.checked,
167
- idx = parseIndex(e.target.closest('[data-index]')?.dataset.index),
168
- { settings, onSettings } = meta,
169
- newSettings = settings.slice(),
170
- setting = settings[idx],
171
- priority = e.target.windeterminate ? settings.reduce((acc, s) => Math.max(acc, s.priority), 0) + 1 : setting.priority;
172
-
173
- newSettings.splice(idx, 1, { ...settings[idx], disabled: !checked, priority });
174
- onSettings(newSettings);
175
- }, [meta])
179
+ const newSettings = settings.slice();
180
+ newSettings.splice(
181
+ to + (from >= to ? 0 : -1),
182
+ 0,
183
+ newSettings.splice(from, 1)[0]
184
+ );
185
+ onSettings(newSettings);
186
+ },
187
+ [meta]
188
+ ),
189
+
190
+ onToggle: useCallback(
191
+ (e) => {
192
+ const checked = e.target.checked,
193
+ idx = parseIndex(e.target.closest('[data-index]')?.dataset.index),
194
+ { settings, onSettings } = meta,
195
+ newSettings = settings.slice(),
196
+ setting = settings[idx],
197
+ priority = e.target.windeterminate
198
+ ? settings.reduce((acc, s) => Math.max(acc, s.priority), 0) + 1
199
+ : setting.priority;
200
+
201
+ newSettings.splice(idx, 1, {
202
+ ...settings[idx],
203
+ disabled: !checked,
204
+ priority,
205
+ });
206
+ onSettings(newSettings);
207
+ },
208
+ [meta]
209
+ ),
176
210
  };
177
211
  },
178
-
179
- renderItem = ({ onDragStart, onDragEnter, onDragOver, onDragLeave, onDrop, onDown, onToggle, collapsed, filters }) => (column, i) => {
180
- const indeterminate = collapsed?.includes(column.name),
181
- checked = !column.disabled && !indeterminate;
182
- return html`
183
- <div class="item" data-index=${ i } @mousedown=${ onDown } draggable="true"
184
- @dragstart=${ onDragStart } @dragenter=${ onDragEnter } @dragover=${ onDragOver } @dragleave=${ onDragLeave }
185
- @drop=${ onDrop }
186
- >
187
- <button class="sort" mousedown="">
188
- <svg viewBox="0 0 24 24" width="24"><path d="M20 9H4v2h16V9zM4 15h16v-2H4v2z"></path></svg>
189
- </button>
190
- <label class="title" ?has-filter=${ !isEmpty(filters[column.name]?.filter) }>${ column.title }</label>
191
- <input class="checkbox" type="checkbox" .checked=${ checked } @click=${ onToggle }
192
- .indeterminate=${ indeterminate } .windeterminate=${ indeterminate }
212
+ renderItem =
213
+ // eslint-disable-next-line max-lines-per-function
214
+ ({
215
+ onDragStart,
216
+ onDragEnter,
217
+ onDragOver,
218
+ onDragLeave,
219
+ onDrop,
220
+ onDown,
221
+ onToggle,
222
+ collapsed,
223
+ filters,
224
+ }) =>
225
+ (column, i) => {
226
+ const indeterminate = collapsed?.includes(column.name),
227
+ checked = !column.disabled && !indeterminate;
228
+ return html` <div
229
+ class="item"
230
+ data-index=${i}
231
+ @mousedown=${onDown}
232
+ draggable="true"
233
+ @dragstart=${onDragStart}
234
+ @dragenter=${onDragEnter}
235
+ @dragover=${onDragOver}
236
+ @dragleave=${onDragLeave}
237
+ @drop=${onDrop}
193
238
  >
194
- </div>`;
195
- },
196
-
197
- SettingsUI = host => {
198
- const { settings, settingsId, onSave, onReset, hasChanges, ...thru } = useSettings(host);
239
+ <button class="pull">
240
+ <svg
241
+ width="16"
242
+ height="6"
243
+ viewBox="0 0 16 6"
244
+ fill="currentColor"
245
+ xmlns="http://www.w3.org/2000/svg"
246
+ >
247
+ <rect width="16" height="2" />
248
+ <rect y="4" width="16" height="2" />
249
+ </svg>
250
+ </button>
251
+ <label
252
+ class="title"
253
+ ?has-filter=${!isEmpty(filters[column.name]?.filter)}
254
+ >${column.title}</label
255
+ >
256
+ <input
257
+ class="checkbox"
258
+ type="checkbox"
259
+ .checked=${checked}
260
+ @click=${onToggle}
261
+ .indeterminate=${indeterminate}
262
+ .windeterminate=${indeterminate}
263
+ />
264
+ </div>`;
265
+ },
266
+ SettingsUI = (host) => {
267
+ const { settings, settingsId, onSave, onReset, hasChanges, ...thru } =
268
+ useSettings(host);
199
269
  return [
200
270
  html`
201
- <style>${ settingsStyles }</style>
202
- <div class="list">${ settings?.map(renderItem(thru)) }</div>
271
+ <style>
272
+ ${settingsStyles}
273
+ </style>
274
+ <div class="list">${settings?.map(renderItem(thru))}</div>
203
275
  `,
204
276
  settingsId
205
277
  ? html`<div class="buttons">
206
- <button class="button" @click=${ onSave } ?disabled=${ !hasChanges }>Save</button>
207
- <button class="button" @click=${ onReset } ?disabled=${ !hasChanges }>Reset</button>
208
- </div>`
209
- : nothing
278
+ <button
279
+ class="button reset"
280
+ @click=${onReset}
281
+ ?disabled=${!hasChanges}
282
+ >
283
+ Reset
284
+ </button>
285
+ <button class="button" @click=${onSave} ?disabled=${!hasChanges}>
286
+ Save
287
+ </button>
288
+ </div>`
289
+ : nothing,
210
290
  ];
211
291
  },
212
-
213
- Settings = ({ anchor, settings, onSettings, collapsed, settingsId, hasChanges, onSave, onReset, filters, badge }) => html`
292
+ // eslint-disable-next-line max-lines-per-function
293
+ Settings = ({
294
+ anchor,
295
+ settings,
296
+ onSettings,
297
+ collapsed,
298
+ settingsId,
299
+ hasChanges,
300
+ onSave,
301
+ onReset,
302
+ filters,
303
+ badge,
304
+ }) => html`
214
305
  <style>
215
306
  :host {
216
307
  display: contents;
217
308
  color: var(--cosmoz-omnitable-settings-color, #101010);
218
- --cosmoz-dropdown-box-shadow: 0 3px 4px 0 rgb(0 0 0 / 14%), 0 1px 8px 0 rgb(0 0 0 / 12%), 0 3px 3px -2px rgb(0 0 0 / 40%);
309
+ --cosmoz-dropdown-box-shadow: 0 3px 4px 0 rgb(0 0 0 / 14%),
310
+ 0 1px 8px 0 rgb(0 0 0 / 12%), 0 3px 3px -2px rgb(0 0 0 / 40%);
219
311
  }
220
312
  cosmoz-dropdown::part(button) {
221
313
  --cosmoz-dropdown-button-size: 24px;
222
- margin-bottom: 10px;
223
314
  padding: 0;
224
315
  background: transparent;
225
316
  color: inherit;
@@ -231,19 +322,34 @@ const placement = ['bottom-right', ...defaultPlacement],
231
322
  position: absolute;
232
323
  top: 1px;
233
324
  right: -4px;
234
- background-color: var(--cosmoz-omnitable-checkbox-checked-color, var(--primary-color));
325
+ background-color: var(
326
+ --cosmoz-omnitable-checkbox-checked-color,
327
+ var(--primary-color)
328
+ );
235
329
  width: 8px;
236
330
  height: 8px;
237
331
  border-radius: 100%;
238
332
  }
239
333
  </style>
240
- <cosmoz-dropdown .render=${ () => html`<cosmoz-omnitable-settings-ui
241
- .anchor=${ anchor } .settings=${ settings } .onSettings=${ onSettings } .collapsed=${ collapsed }
242
- .settingsId=${ settingsId } .hasChanges=${ hasChanges } .onSave=${ onSave } .onReset=${ onReset }
243
- .filters=${ filters }></cosmoz-omnitable-settings-ui>` } .placement=${ placement }>
244
- <svg viewBox="0 0 24 24" width="24" slot="button" fill="currentColor"><path d="M10 18h5V5h-5v13zm-6 0h5V5H4v13zM16 5v13h5V5h-5z"></path></svg>
245
- ${ badge ? html`<div class="badge" slot="button"></div>` : nothing }
334
+ <cosmoz-dropdown
335
+ .render=${() => html`<cosmoz-omnitable-settings-ui
336
+ .anchor=${anchor}
337
+ .settings=${settings}
338
+ .onSettings=${onSettings}
339
+ .collapsed=${collapsed}
340
+ .settingsId=${settingsId}
341
+ .hasChanges=${hasChanges}
342
+ .onSave=${onSave}
343
+ .onReset=${onReset}
344
+ .filters=${filters}
345
+ ></cosmoz-omnitable-settings-ui>`}
346
+ .placement=${placement}
347
+ >
348
+ <svg viewBox="0 0 24 24" width="24" slot="button" fill="currentColor">
349
+ <path d="M10 18h5V5h-5v13zm-6 0h5V5H4v13zM16 5v13h5V5h-5z"></path>
350
+ </svg>
351
+ ${badge ? html`<div class="badge" slot="button"></div>` : nothing}
246
352
  </cosmoz-dropdown>
247
- `;
353
+ `;
248
354
  customElements.define('cosmoz-omnitable-settings', component(Settings));
249
355
  customElements.define('cosmoz-omnitable-settings-ui', component(SettingsUI));
@@ -0,0 +1,44 @@
1
+ import { html } from 'haunted';
2
+ import { ifDefined } from 'lit-html/directives/if-defined';
3
+
4
+ const sortIcon = html`<svg
5
+ width="8"
6
+ height="6"
7
+ viewBox="0 0 8 6"
8
+ fill="currentColor"
9
+ xmlns="http://www.w3.org/2000/svg"
10
+ >
11
+ <path
12
+ d="M3.56699 0.75C3.75944 0.416666 4.24056 0.416667 4.43301 0.75L7.03109 5.25C7.22354 5.58333 6.98298 6 6.59808 6L1.40192 6C1.01702 6 0.776461 5.58333 0.968911 5.25L3.56699 0.75Z"
13
+ />
14
+ </svg> `;
15
+
16
+ export default ({
17
+ column,
18
+ sortOnColumn,
19
+ setSortOn,
20
+ descending,
21
+ setDescending,
22
+ }) => html` <button
23
+ class="sort"
24
+ data-sort=${ifDefined(
25
+ (column === sortOnColumn && (descending ? 'desc' : 'asc')) || undefined
26
+ )}
27
+ @click=${(e) => {
28
+ const sort = e.currentTarget?.dataset.sort;
29
+ if (!sort) {
30
+ setSortOn(column.name);
31
+ setDescending(false);
32
+ }
33
+ if (sort === 'asc') {
34
+ setDescending(true);
35
+ }
36
+ if (sort === 'desc') {
37
+ setSortOn();
38
+ setDescending(false);
39
+ }
40
+ }}
41
+ >
42
+ ${sortIcon}
43
+ </button>`;
44
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neovici/cosmoz-omnitable",
3
- "version": "8.5.3",
3
+ "version": "8.6.0",
4
4
  "description": "[![Build Status](https://travis-ci.org/Neovici/cosmoz-omnitable.svg?branch=master)](https://travis-ci.org/Neovici/cosmoz-omnitable)",
5
5
  "keywords": [
6
6
  "web-components"