@neovici/cosmoz-omnitable 8.8.1 → 8.11.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,367 +0,0 @@
1
- import { html, component, useCallback } from 'haunted';
2
- import { useMeta } from '@neovici/cosmoz-utils/lib/hooks/use-meta';
3
- import { checkbox, sort as sortStyle } from '../cosmoz-omnitable-styles';
4
- import { nothing } from 'lit-html';
5
- import { isEmpty } from '@neovici/cosmoz-utils/lib/template';
6
- import { defaultPlacement } from '@neovici/cosmoz-dropdown';
7
- import sort from './cosmoz-omnitable-sort';
8
- import group from './cosmoz-omnitable-group';
9
-
10
- const placement = ['bottom-right', ...defaultPlacement],
11
- settingsStyles = `
12
- :host {
13
- box-sizing: border-box;
14
- display: flex;
15
- flex-direction: column;
16
- max-height: 42vh;
17
- outline: none;
18
- padding-top: 14px;
19
- }
20
- .list {
21
- overflow-y: auto;
22
- flex: 1;
23
- padding: 2px 14px;
24
- min-width: 232px;
25
- }
26
- .item {
27
- display: flex;
28
- align-items: center;
29
- background: white;
30
- }
31
- .item.drag {
32
- opacity: 0.6;
33
- pointer-events: none;
34
- }
35
- .item.dragover {
36
- box-shadow: 0 -2px 0 0 currentColor;
37
- }
38
- .pull {
39
- border: none;
40
- padding: 0;
41
- font-size: 0;
42
- vertical-align: bottom;
43
- outline: none;
44
- background: transparent;
45
- cursor: move;
46
- margin-right: 12px;
47
- color: #c4c4c4;
48
- }
49
- .title {
50
- flex: 1;
51
- }
52
- .title[has-filter] {
53
- font-weight: bold;
54
- }
55
- ${checkbox}
56
- .checkbox {
57
- margin: 4px 0;
58
- }
59
-
60
- ${sortStyle}
61
- .sort {
62
- order: initial;
63
- margin: 0;
64
- width: auto;
65
- padding: 8px;
66
- }
67
-
68
- .buttons {
69
- display: flex;
70
- gap: 8px;
71
- padding: 12px 14px;
72
- box-shadow: inset 0px 1px 0px rgba(0, 0, 0, 0.15);
73
- }
74
- .button {
75
- border: none;
76
- cursor: pointer;
77
- background: var(--cosmoz-button-bg-color, #101010);
78
- color: var(--cosmoz-button-color, #fff);
79
- font-family: inherit;
80
- font-size: 13px;
81
- font-weight: 600;
82
- line-height: 26px;
83
- border-radius: 4px;
84
- padding: 8px;
85
- flex: 1;
86
- }
87
- .button:not(.reset):hover {
88
- background: var(--cosmoz-button-hover-bg-color, #3A3F44);
89
- }
90
- .button[disabled] {
91
- opacity: 0.2;
92
- pointer-events: none;
93
- }
94
- .reset {
95
- background: transparent;
96
- color: inherit;
97
- text-decoration: underline;
98
- }
99
- .group {
100
- padding: 0px 14px;
101
- box-shadow: inset 0px 1px 0px rgb(0 0 0 / 15%)
102
- }
103
- `,
104
- parseIndex = (str) => {
105
- const idx = parseInt(str, 10);
106
- return isFinite(idx) ? idx : undefined;
107
- },
108
- // eslint-disable-next-line max-lines-per-function
109
- useSettings = (host) => {
110
- const { settings, onSettings } = host,
111
- meta = useMeta({ settings, onSettings });
112
-
113
- return {
114
- settings: host.settings,
115
- collapsed: host.collapsed,
116
-
117
- settingsId: host.settingsId,
118
- hasChanges: host.hasChanges,
119
- onSave: host.onSave,
120
- onReset: host.onReset,
121
-
122
- filters: host.filters,
123
-
124
- onDown: useCallback(
125
- (e) => {
126
- if (!e.target.closest('.pull')) {
127
- return;
128
- }
129
-
130
- meta.handle = e.currentTarget;
131
- },
132
- [meta]
133
- ),
134
-
135
- onDragStart: useCallback(
136
- (e) => {
137
- const { target } = e,
138
- index = parseIndex(target.dataset.index);
139
-
140
- if (!meta.handle?.contains(target) || index == null) {
141
- return e.preventDefault();
142
- }
143
-
144
- meta.handle = null;
145
- e.dataTransfer.effectAllowed = 'move';
146
- e.dataTransfer.setData('omnitable/sort-index', index);
147
- setTimeout(() => target.classList.add('drag'), 0);
148
- target.addEventListener(
149
- 'dragend',
150
- (e) => e.target.classList.remove('drag'),
151
- { once: true }
152
- );
153
- },
154
- [meta]
155
- ),
156
-
157
- onDragEnter: useCallback((e) => {
158
- const ctg = e.currentTarget;
159
- if (ctg !== e.target) {
160
- return;
161
- }
162
-
163
- e.preventDefault();
164
- e.dataTransfer.dropEffect = 'move';
165
- ctg.classList.add('dragover');
166
- }, []),
167
-
168
- onDragOver: useCallback((e) => {
169
- e.preventDefault();
170
- e.currentTarget.classList.add('dragover');
171
- }, []),
172
-
173
- onDragLeave: useCallback((e) => {
174
- const ctg = e.currentTarget;
175
- if (ctg.contains(e.relatedTarget)) {
176
- return;
177
- }
178
-
179
- ctg.classList.remove('dragover');
180
- }, []),
181
-
182
- onDrop: useCallback(
183
- (e) => {
184
- const from = parseIndex(
185
- e.dataTransfer.getData('omnitable/sort-index')
186
- ),
187
- to = parseIndex(e.currentTarget.dataset.index),
188
- { settings, onSettings } = meta;
189
-
190
- e.currentTarget.classList.remove('dragover');
191
- e.preventDefault();
192
-
193
- const newSettings = settings.slice();
194
- newSettings.splice(
195
- to + (from >= to ? 0 : -1),
196
- 0,
197
- newSettings.splice(from, 1)[0]
198
- );
199
- onSettings(newSettings);
200
- },
201
- [meta]
202
- ),
203
-
204
- onToggle: useCallback(
205
- (e) => {
206
- const checked = e.target.checked,
207
- idx = parseIndex(e.target.closest('[data-index]')?.dataset.index),
208
- { settings, onSettings } = meta,
209
- newSettings = settings.slice(),
210
- setting = settings[idx],
211
- priority = e.target.windeterminate
212
- ? settings.reduce((acc, s) => Math.max(acc, s.priority), 0) + 1
213
- : setting.priority;
214
-
215
- newSettings.splice(idx, 1, {
216
- ...settings[idx],
217
- disabled: !checked,
218
- priority,
219
- });
220
- onSettings(newSettings);
221
- },
222
- [meta]
223
- ),
224
- };
225
- },
226
- renderItem =
227
- // eslint-disable-next-line max-lines-per-function
228
- ({
229
- onDragStart,
230
- onDragEnter,
231
- onDragOver,
232
- onDragLeave,
233
- onDrop,
234
- onDown,
235
- onToggle,
236
- collapsed,
237
- filters,
238
- }) =>
239
- (column, i) => {
240
- const indeterminate = collapsed?.includes(column.name),
241
- checked = !column.disabled && !indeterminate;
242
- return html` <div
243
- class="item"
244
- data-index=${i}
245
- @mousedown=${onDown}
246
- draggable="true"
247
- @dragstart=${onDragStart}
248
- @dragenter=${onDragEnter}
249
- @dragover=${onDragOver}
250
- @dragleave=${onDragLeave}
251
- @drop=${onDrop}
252
- >
253
- <button class="pull">
254
- <svg
255
- width="16"
256
- height="6"
257
- viewBox="0 0 16 6"
258
- fill="currentColor"
259
- xmlns="http://www.w3.org/2000/svg"
260
- >
261
- <rect width="16" height="2" />
262
- <rect y="4" width="16" height="2" />
263
- </svg>
264
- </button>
265
- <label
266
- class="title"
267
- ?has-filter=${!isEmpty(filters[column.name]?.filter)}
268
- >${column.title}</label
269
- >
270
- ${sort(column.name)}
271
- <input
272
- class="checkbox"
273
- type="checkbox"
274
- .checked=${checked}
275
- @click=${onToggle}
276
- .indeterminate=${indeterminate}
277
- .windeterminate=${indeterminate}
278
- />
279
- </div>`;
280
- },
281
- SettingsUI = (host) => {
282
- const { settings, settingsId, onSave, onReset, hasChanges, ...thru } =
283
- useSettings(host);
284
- return [
285
- html`
286
- <style>${settingsStyles}</style>
287
- <div class="list">${settings?.map(renderItem(thru))}</div>
288
- `,
289
- group(),
290
- settingsId && html`<div class="buttons">
291
- <button
292
- class="button reset"
293
- @click=${onReset}
294
- ?disabled=${!hasChanges}
295
- >
296
- Reset
297
- </button>
298
- <button class="button" @click=${onSave} ?disabled=${!hasChanges}>
299
- Save
300
- </button>
301
- </div>`
302
- ].filter(Boolean);
303
- },
304
- // eslint-disable-next-line max-lines-per-function
305
- Settings = ({
306
- anchor,
307
- settings,
308
- onSettings,
309
- collapsed,
310
- settingsId,
311
- hasChanges,
312
- onSave,
313
- onReset,
314
- filters,
315
- badge,
316
- }) => html`
317
- <style>
318
- :host {
319
- display: contents;
320
- color: var(--cosmoz-omnitable-settings-color, #101010);
321
- --cosmoz-dropdown-box-shadow: 0 3px 4px 0 rgb(0 0 0 / 14%),
322
- 0 1px 8px 0 rgb(0 0 0 / 12%), 0 3px 3px -2px rgb(0 0 0 / 40%);
323
- }
324
- cosmoz-dropdown::part(button) {
325
- --cosmoz-dropdown-button-size: 24px;
326
- padding: 0;
327
- background: transparent;
328
- color: inherit;
329
- }
330
- cosmoz-dropdown::part(anchor) {
331
- display: inline-block;
332
- }
333
- .badge {
334
- position: absolute;
335
- top: 1px;
336
- right: -4px;
337
- background-color: var(
338
- --cosmoz-omnitable-checkbox-checked-color,
339
- var(--primary-color)
340
- );
341
- width: 8px;
342
- height: 8px;
343
- border-radius: 100%;
344
- }
345
- </style>
346
- <cosmoz-dropdown
347
- .render=${() => html`<cosmoz-omnitable-settings-ui
348
- .anchor=${anchor}
349
- .settings=${settings}
350
- .onSettings=${onSettings}
351
- .collapsed=${collapsed}
352
- .settingsId=${settingsId}
353
- .hasChanges=${hasChanges}
354
- .onSave=${onSave}
355
- .onReset=${onReset}
356
- .filters=${filters}
357
- ></cosmoz-omnitable-settings-ui>`}
358
- .placement=${placement}
359
- >
360
- <svg viewBox="0 0 24 24" width="24" slot="button" fill="currentColor">
361
- <path d="M10 18h5V5h-5v13zm-6 0h5V5H4v13zM16 5v13h5V5h-5z"></path>
362
- </svg>
363
- ${badge ? html`<div class="badge" slot="button"></div>` : nothing}
364
- </cosmoz-dropdown>
365
- `;
366
- customElements.define('cosmoz-omnitable-settings', component(Settings));
367
- customElements.define('cosmoz-omnitable-settings-ui', component(SettingsUI));
@@ -1,37 +0,0 @@
1
- const byName = name => item => item.name === name;
2
-
3
- export const
4
- normalizeSettings = (columns = [], settings = [], savedSettings = []) => {
5
- const
6
- cols = columns.filter(column => !settings.some(byName(column.name)) && !savedSettings.some(byName(column.name))),
7
- _savedSettings = savedSettings.filter(column => !settings.some(byName(column.name)));
8
-
9
- return [
10
- ...settings,
11
- ..._savedSettings
12
- .flatMap(setting => {
13
- const column = columns.find(c => c.name === setting.name);
14
-
15
- if (!column) {
16
- return [];
17
- }
18
-
19
- return {
20
- ...setting,
21
- title: column.title,
22
- minWidth: parseInt(column.minWidth, 10)
23
- };
24
- }),
25
- ...cols.map(column => {
26
- const { name, title, priority, minWidth, width, flex } = column;
27
- return {
28
- name,
29
- title,
30
- priority,
31
- minWidth: parseInt(minWidth, 10),
32
- width: parseInt(width, 10),
33
- flex: parseInt(flex, 10)
34
- };
35
- })
36
- ];
37
- };