yummy-guide-generic-administrate 0.2.1 → 0.3.1
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.
- checksums.yaml +4 -4
- data/README.md +52 -0
- data/app/assets/javascripts/yummy_guide_administrate/fixed_submit_actions.js +324 -0
- data/app/assets/javascripts/yummy_guide_administrate/sticky_table_headers.js +125 -97
- data/app/assets/stylesheets/yummy_guide_administrate/_fixed_submit_actions.scss +45 -0
- data/app/assets/stylesheets/yummy_guide_administrate/components.scss +53 -12
- data/lib/yummy_guide/administrate/engine.rb +1 -0
- data/lib/yummy_guide/administrate/version.rb +1 -1
- metadata +3 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b442ee0d24ba8d34271193cdbc8c2da175d5b91b3a2b847706ce5f5c316eff66
|
|
4
|
+
data.tar.gz: cc6d60ef4a0b80f2561638de33ce7abef3908ba1064c77c2c94e628d47dec970
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ad2200cef92ab686ffb9fabee36c87672ff48dc1a507406995057effa3afff4bad625eb7fbaad8011ddf4ffa8eb93b5b95af2455436f131fabbdc18a8ff55873
|
|
7
|
+
data.tar.gz: 2502a4c2723a4d8fc25ca7d1ba5fd10aff5a2002dbfff58f5c698d042b21e21ebd0597c863463ec1b086934b3450e56088e718d5fddae8a8b1a861bd02bf08c5
|
data/README.md
CHANGED
|
@@ -46,6 +46,7 @@ bundle install
|
|
|
46
46
|
- fixed table header partial
|
|
47
47
|
- filter form partial
|
|
48
48
|
- `clipboards.js`
|
|
49
|
+
- `fixed_submit_actions.js`
|
|
49
50
|
- `filter_form.js`
|
|
50
51
|
- `sticky_left_columns.js`
|
|
51
52
|
- `sticky_table_headers.js`
|
|
@@ -259,6 +260,7 @@ end
|
|
|
259
260
|
|
|
260
261
|
```js
|
|
261
262
|
//= require yummy_guide_administrate/clipboards
|
|
263
|
+
//= require yummy_guide_administrate/fixed_submit_actions
|
|
262
264
|
//= require yummy_guide_administrate/filter_form
|
|
263
265
|
//= require yummy_guide_administrate/sticky_left_columns
|
|
264
266
|
//= require yummy_guide_administrate/sticky_table_headers
|
|
@@ -268,6 +270,56 @@ end
|
|
|
268
270
|
*= require yummy_guide_administrate/components
|
|
269
271
|
```
|
|
270
272
|
|
|
273
|
+
### 固定更新ボタン
|
|
274
|
+
|
|
275
|
+
管理画面の `new` / `edit` 系フォームでは、submit セクションを画面下に固定表示できます。
|
|
276
|
+
この機能は `fixed_submit_actions.js` と `components.css` に含まれる style によって動作します。
|
|
277
|
+
|
|
278
|
+
#### 固定対象を明示指定する場合
|
|
279
|
+
|
|
280
|
+
固定したい submit セクションに `data-fixed-submit-actions="true"` を付けます。
|
|
281
|
+
|
|
282
|
+
```erb
|
|
283
|
+
<div class="form-actions" data-fixed-submit-actions="true">
|
|
284
|
+
<%= f.submit %>
|
|
285
|
+
</div>
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
この指定がある場合、gem はその submit セクションを最優先で固定対象にします。
|
|
289
|
+
1 ページに複数フォームがあっても、明示指定した submit セクションだけが固定表示されます。
|
|
290
|
+
|
|
291
|
+
#### 設定しなかった場合の挙動
|
|
292
|
+
|
|
293
|
+
`data-fixed-submit-actions="true"` が 1 件もない場合、gem は admin の `new` / `edit`
|
|
294
|
+
ページで submit セクションを自動選択します。
|
|
295
|
+
|
|
296
|
+
- 各フォーム内の `.form-actions` / `.form_submit` を候補にする
|
|
297
|
+
- `form-actions--top` が付いた上部 submit は除外する
|
|
298
|
+
- `data-fixed-submit-exclude="true"` が付いた submit セクションも除外する
|
|
299
|
+
- 各フォームでは最後の submit セクションだけを候補にする
|
|
300
|
+
- 複数フォームがあるページでは、現在表示中のフォームに対応する submit を固定する
|
|
301
|
+
|
|
302
|
+
上部 submit と下部 submit の両方があるフォームでは、下部 submit が自動で選ばれます。
|
|
303
|
+
|
|
304
|
+
#### fixed 帯に表示されるボタン
|
|
305
|
+
|
|
306
|
+
fixed 帯には submit セクションのクローンを表示します。
|
|
307
|
+
|
|
308
|
+
- 元のフォーム内ボタンの見た目は変更しない
|
|
309
|
+
- fixed 帯にだけ大きいボタンサイズを適用する
|
|
310
|
+
- 1 つの submit セクションに複数 submit ボタンがある場合は全部表示する
|
|
311
|
+
|
|
312
|
+
#### 自動選択から除外したい場合
|
|
313
|
+
|
|
314
|
+
自動選択の候補から外したい submit セクションには、`data-fixed-submit-exclude="true"`
|
|
315
|
+
を付けます。
|
|
316
|
+
|
|
317
|
+
```erb
|
|
318
|
+
<div class="form-actions" data-fixed-submit-exclude="true">
|
|
319
|
+
<%= f.submit "Preview" %>
|
|
320
|
+
</div>
|
|
321
|
+
```
|
|
322
|
+
|
|
271
323
|
### Custom field
|
|
272
324
|
|
|
273
325
|
dashboard から共通 field を利用できます。
|
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
(function() {
|
|
2
|
+
var ACTION_SELECTOR = ".form-actions, .form_submit";
|
|
3
|
+
var EXPLICIT_ACTION_SELECTOR = '[data-fixed-submit-actions="true"]';
|
|
4
|
+
var SUBMIT_SELECTOR = 'input[type="submit"], button[type="submit"], button.async-form__submit';
|
|
5
|
+
var scheduled = false;
|
|
6
|
+
var bar = null;
|
|
7
|
+
var barActions = null;
|
|
8
|
+
var observedAction = null;
|
|
9
|
+
var observer = null;
|
|
10
|
+
|
|
11
|
+
function toArray(nodeList) {
|
|
12
|
+
return Array.prototype.slice.call(nodeList || []);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function matchesSelector(element, selector) {
|
|
16
|
+
if (!element || element.nodeType !== 1) return false;
|
|
17
|
+
|
|
18
|
+
var proto = Element.prototype;
|
|
19
|
+
var matcher = proto.matches || proto.msMatchesSelector || proto.webkitMatchesSelector;
|
|
20
|
+
return matcher ? matcher.call(element, selector) : false;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function closest(element, selector) {
|
|
24
|
+
var current = element;
|
|
25
|
+
|
|
26
|
+
while (current && current.nodeType === 1) {
|
|
27
|
+
if (matchesSelector(current, selector)) return current;
|
|
28
|
+
current = current.parentElement;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function isVisible(element) {
|
|
35
|
+
if (!element) return false;
|
|
36
|
+
|
|
37
|
+
var styles = window.getComputedStyle(element);
|
|
38
|
+
return styles.display !== "none" &&
|
|
39
|
+
styles.visibility !== "hidden" &&
|
|
40
|
+
element.getClientRects().length > 0;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function containsSubmitControl(element) {
|
|
44
|
+
return !!element && !!element.querySelector(SUBMIT_SELECTOR);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function isAutoTargetPage() {
|
|
48
|
+
var path = window.location.pathname || "";
|
|
49
|
+
|
|
50
|
+
return path.indexOf("/admin/") === 0 &&
|
|
51
|
+
(path.indexOf("/new") !== -1 || path.indexOf("/edit") !== -1);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function isIgnoredAction(action) {
|
|
55
|
+
return action.classList.contains("form-actions--top") ||
|
|
56
|
+
action.getAttribute("data-fixed-submit-exclude") === "true";
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function explicitInstance() {
|
|
60
|
+
var action = toArray(document.querySelectorAll(".main-content " + EXPLICIT_ACTION_SELECTOR)).find(function(candidate) {
|
|
61
|
+
return containsSubmitControl(candidate) && !isIgnoredAction(candidate);
|
|
62
|
+
});
|
|
63
|
+
var form = closest(action, "form");
|
|
64
|
+
|
|
65
|
+
if (!action || !form || !containsSubmitControl(action) || isIgnoredAction(action)) {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return {
|
|
70
|
+
form: form,
|
|
71
|
+
action: action
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function actionCandidates(form) {
|
|
76
|
+
return toArray(form.querySelectorAll(ACTION_SELECTOR)).filter(function(action) {
|
|
77
|
+
return closest(action, "form") === form &&
|
|
78
|
+
containsSubmitControl(action) &&
|
|
79
|
+
!isIgnoredAction(action);
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function autoInstances() {
|
|
84
|
+
return toArray(document.querySelectorAll(".main-content form")).map(function(form) {
|
|
85
|
+
var candidates = actionCandidates(form);
|
|
86
|
+
var action = candidates[candidates.length - 1];
|
|
87
|
+
|
|
88
|
+
if (!action) return null;
|
|
89
|
+
|
|
90
|
+
return {
|
|
91
|
+
form: form,
|
|
92
|
+
action: action
|
|
93
|
+
};
|
|
94
|
+
}).filter(Boolean);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function anchorPosition() {
|
|
98
|
+
var header = document.querySelector(".main-content__header");
|
|
99
|
+
var headerBottom = header && isVisible(header) ? header.getBoundingClientRect().bottom : 0;
|
|
100
|
+
var viewportAnchor = Math.min(window.innerHeight * 0.35, 320);
|
|
101
|
+
|
|
102
|
+
return Math.min(
|
|
103
|
+
Math.max(headerBottom + 24, viewportAnchor),
|
|
104
|
+
Math.max(window.innerHeight - 48, 0)
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function visibleInstances(instances) {
|
|
109
|
+
return instances.map(function(instance) {
|
|
110
|
+
instance.formRect = instance.form.getBoundingClientRect();
|
|
111
|
+
instance.actionRect = instance.action.getBoundingClientRect();
|
|
112
|
+
return instance;
|
|
113
|
+
}).filter(function(instance) {
|
|
114
|
+
return isVisible(instance.form) &&
|
|
115
|
+
isVisible(instance.action) &&
|
|
116
|
+
instance.formRect.bottom > 0 &&
|
|
117
|
+
instance.formRect.top < window.innerHeight;
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function selectAutoInstance(instances) {
|
|
122
|
+
if (!instances.length) return null;
|
|
123
|
+
|
|
124
|
+
var anchorY = anchorPosition();
|
|
125
|
+
var containing = instances.filter(function(instance) {
|
|
126
|
+
return instance.formRect.top <= anchorY && instance.formRect.bottom > anchorY;
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
if (containing.length) {
|
|
130
|
+
return containing.sort(function(left, right) {
|
|
131
|
+
return right.formRect.top - left.formRect.top;
|
|
132
|
+
})[0];
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
var below = instances.filter(function(instance) {
|
|
136
|
+
return instance.formRect.top > anchorY;
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
if (below.length) {
|
|
140
|
+
return below.sort(function(left, right) {
|
|
141
|
+
return left.formRect.top - right.formRect.top;
|
|
142
|
+
})[0];
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return instances.sort(function(left, right) {
|
|
146
|
+
return right.formRect.bottom - left.formRect.bottom;
|
|
147
|
+
})[0];
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function currentInstance() {
|
|
151
|
+
var explicit = explicitInstance();
|
|
152
|
+
if (explicit) return explicit;
|
|
153
|
+
|
|
154
|
+
if (!isAutoTargetPage()) return null;
|
|
155
|
+
|
|
156
|
+
return selectAutoInstance(visibleInstances(autoInstances()));
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function ensureBar() {
|
|
160
|
+
if (bar) return;
|
|
161
|
+
|
|
162
|
+
bar = document.createElement("div");
|
|
163
|
+
bar.className = "admin-fixed-submit-bar";
|
|
164
|
+
bar.hidden = true;
|
|
165
|
+
|
|
166
|
+
barActions = document.createElement("div");
|
|
167
|
+
barActions.className = "admin-fixed-submit-bar__actions";
|
|
168
|
+
bar.appendChild(barActions);
|
|
169
|
+
|
|
170
|
+
document.body.appendChild(bar);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
function hideBar() {
|
|
174
|
+
ensureBar();
|
|
175
|
+
bar.hidden = true;
|
|
176
|
+
bar.style.removeProperty("--fixed-submit-left");
|
|
177
|
+
bar.style.removeProperty("--fixed-submit-width");
|
|
178
|
+
barActions.innerHTML = "";
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
function stripIds(node) {
|
|
182
|
+
if (!node || node.nodeType !== 1) return;
|
|
183
|
+
|
|
184
|
+
node.removeAttribute("id");
|
|
185
|
+
toArray(node.querySelectorAll("[id]")).forEach(function(child) {
|
|
186
|
+
child.removeAttribute("id");
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
function syncCloneControls(clone, sourceAction) {
|
|
191
|
+
var sourceControls = toArray(sourceAction.querySelectorAll(SUBMIT_SELECTOR));
|
|
192
|
+
var cloneControls = toArray(clone.querySelectorAll(SUBMIT_SELECTOR));
|
|
193
|
+
|
|
194
|
+
cloneControls.forEach(function(cloneControl, index) {
|
|
195
|
+
var sourceControl = sourceControls[index];
|
|
196
|
+
|
|
197
|
+
if (!sourceControl) {
|
|
198
|
+
cloneControl.remove();
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
if (cloneControl.tagName === "INPUT") {
|
|
203
|
+
cloneControl.type = "button";
|
|
204
|
+
} else if (cloneControl.tagName === "BUTTON") {
|
|
205
|
+
cloneControl.type = "button";
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
cloneControl.disabled = !!sourceControl.disabled;
|
|
209
|
+
|
|
210
|
+
cloneControl.addEventListener("click", function(event) {
|
|
211
|
+
event.preventDefault();
|
|
212
|
+
if (sourceControl.disabled) return;
|
|
213
|
+
sourceControl.click();
|
|
214
|
+
});
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
function renderClone(instance) {
|
|
219
|
+
ensureBar();
|
|
220
|
+
barActions.innerHTML = "";
|
|
221
|
+
|
|
222
|
+
var clone = instance.action.cloneNode(true);
|
|
223
|
+
stripIds(clone);
|
|
224
|
+
clone.removeAttribute("data-fixed-submit-actions");
|
|
225
|
+
clone.classList.add("admin-fixed-submit-bar__action-clone");
|
|
226
|
+
syncCloneControls(clone, instance.action);
|
|
227
|
+
|
|
228
|
+
barActions.appendChild(clone);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
function fixedFrame(instance) {
|
|
232
|
+
var mainContent = closest(instance.form, ".main-content") || document.querySelector(".main-content");
|
|
233
|
+
var section = closest(instance.action, ".main-content__body") || closest(instance.form, ".main-content__body") || instance.form;
|
|
234
|
+
var viewportMargin = window.innerWidth <= 767 ? 8 : 16;
|
|
235
|
+
var mainRect = mainContent ? mainContent.getBoundingClientRect() : { left: 0, right: window.innerWidth };
|
|
236
|
+
var sectionRect = section.getBoundingClientRect();
|
|
237
|
+
var left = Math.max(mainRect.left, sectionRect.left, viewportMargin);
|
|
238
|
+
var right = Math.min(mainRect.right, sectionRect.right, window.innerWidth - viewportMargin);
|
|
239
|
+
|
|
240
|
+
return {
|
|
241
|
+
left: Math.max(left, viewportMargin),
|
|
242
|
+
width: Math.max(right - left, 0)
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
function shouldPin(instance) {
|
|
247
|
+
var actionRect = instance.action.getBoundingClientRect();
|
|
248
|
+
var revealThreshold = Math.min(96, Math.max(48, actionRect.height));
|
|
249
|
+
|
|
250
|
+
return isVisible(instance.form) &&
|
|
251
|
+
isVisible(instance.action) &&
|
|
252
|
+
instance.form.getBoundingClientRect().bottom > 0 &&
|
|
253
|
+
instance.form.getBoundingClientRect().top < window.innerHeight &&
|
|
254
|
+
actionRect.top > window.innerHeight - revealThreshold;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
function observeAction(action) {
|
|
258
|
+
if (observedAction === action) return;
|
|
259
|
+
|
|
260
|
+
if (observer) observer.disconnect();
|
|
261
|
+
|
|
262
|
+
observedAction = action;
|
|
263
|
+
if (!action) return;
|
|
264
|
+
|
|
265
|
+
observer = new MutationObserver(function() {
|
|
266
|
+
scheduleSync();
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
observer.observe(action, {
|
|
270
|
+
subtree: true,
|
|
271
|
+
childList: true,
|
|
272
|
+
attributes: true,
|
|
273
|
+
characterData: true
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
function sync() {
|
|
278
|
+
var instance = currentInstance();
|
|
279
|
+
|
|
280
|
+
if (!instance) {
|
|
281
|
+
observeAction(null);
|
|
282
|
+
hideBar();
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
observeAction(instance.action);
|
|
287
|
+
|
|
288
|
+
if (!shouldPin(instance)) {
|
|
289
|
+
hideBar();
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
var frame = fixedFrame(instance);
|
|
294
|
+
if (frame.width <= 0) {
|
|
295
|
+
hideBar();
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
renderClone(instance);
|
|
300
|
+
bar.style.setProperty("--fixed-submit-left", frame.left + "px");
|
|
301
|
+
bar.style.setProperty("--fixed-submit-width", frame.width + "px");
|
|
302
|
+
bar.hidden = false;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
function scheduleSync() {
|
|
306
|
+
if (scheduled) return;
|
|
307
|
+
|
|
308
|
+
scheduled = true;
|
|
309
|
+
(window.requestAnimationFrame || window.setTimeout)(function() {
|
|
310
|
+
scheduled = false;
|
|
311
|
+
sync();
|
|
312
|
+
}, 16);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
function initialize() {
|
|
316
|
+
ensureBar();
|
|
317
|
+
scheduleSync();
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
document.addEventListener("DOMContentLoaded", initialize);
|
|
321
|
+
window.addEventListener("load", scheduleSync);
|
|
322
|
+
window.addEventListener("scroll", scheduleSync, { passive: true });
|
|
323
|
+
window.addEventListener("resize", scheduleSync);
|
|
324
|
+
})();
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
(function() {
|
|
2
|
-
var TABLE_SELECTOR =
|
|
3
|
-
var WRAPPER_SELECTOR =
|
|
2
|
+
var TABLE_SELECTOR = 'table[data-fixed-columns-count]';
|
|
3
|
+
var WRAPPER_SELECTOR = '[data-fixed-header-scroll], .scroll-table, .home-table__wrapper, .table-wrap, .af__table__content';
|
|
4
4
|
var resizeObservers = new WeakMap();
|
|
5
5
|
var observedScrolls = new WeakMap();
|
|
6
6
|
var scrollSyncStates = new WeakMap();
|
|
7
7
|
|
|
8
8
|
function directCells(row) {
|
|
9
9
|
return Array.from(row.children).filter(function(cell) {
|
|
10
|
-
return cell.tagName ===
|
|
10
|
+
return cell.tagName === 'TH' || cell.tagName === 'TD';
|
|
11
11
|
});
|
|
12
12
|
}
|
|
13
13
|
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
function cssPixelValue(value) {
|
|
19
|
-
return preciseNumber(value) +
|
|
19
|
+
return preciseNumber(value) + 'px';
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
function measuredWidth(element) {
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
function fixedColumnsCount(table) {
|
|
38
|
-
var parsedCount = parseInt(table.dataset.fixedColumnsCount ||
|
|
38
|
+
var parsedCount = parseInt(table.dataset.fixedColumnsCount || '0', 10);
|
|
39
39
|
return Number.isNaN(parsedCount) ? 0 : Math.max(parsedCount, 0);
|
|
40
40
|
}
|
|
41
41
|
|
|
@@ -55,23 +55,24 @@
|
|
|
55
55
|
if (!element) return false;
|
|
56
56
|
|
|
57
57
|
var styles = window.getComputedStyle(element);
|
|
58
|
-
return styles.display !==
|
|
58
|
+
return styles.display !== 'none' && styles.visibility !== 'hidden' && element.getClientRects().length > 0;
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
function trackedTablesInWrapper(scroll) {
|
|
62
62
|
return Array.from(scroll.querySelectorAll(TABLE_SELECTOR)).filter(function(table) {
|
|
63
|
-
return table.getAttribute(
|
|
63
|
+
return table.getAttribute('aria-hidden') !== 'true' && !table.classList.contains('table-fixed-header__table');
|
|
64
64
|
});
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
function isSourceTableCandidate(table) {
|
|
68
|
-
return table.getAttribute(
|
|
69
|
-
!table.classList.contains(
|
|
70
|
-
!table.closest(
|
|
68
|
+
return table.getAttribute('aria-hidden') !== 'true' &&
|
|
69
|
+
!table.classList.contains('table-fixed-header__table') &&
|
|
70
|
+
!table.closest('[data-fixed-table-header]');
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
function activeSourceTable(scroll) {
|
|
74
74
|
var tables = trackedTablesInWrapper(scroll);
|
|
75
|
+
|
|
75
76
|
return tables.find(isVisible) || tables[0] || null;
|
|
76
77
|
}
|
|
77
78
|
|
|
@@ -79,14 +80,16 @@
|
|
|
79
80
|
var existingWrapper = table.closest(WRAPPER_SELECTOR);
|
|
80
81
|
|
|
81
82
|
if (existingWrapper) {
|
|
82
|
-
existingWrapper.setAttribute(
|
|
83
|
-
existingWrapper.classList.
|
|
83
|
+
existingWrapper.setAttribute('data-fixed-header-scroll', '');
|
|
84
|
+
if (!existingWrapper.classList.contains('home-table__wrapper')) {
|
|
85
|
+
existingWrapper.classList.add('sticky-table-scroll');
|
|
86
|
+
}
|
|
84
87
|
return existingWrapper;
|
|
85
88
|
}
|
|
86
89
|
|
|
87
|
-
var wrapper = document.createElement(
|
|
88
|
-
wrapper.className =
|
|
89
|
-
wrapper.setAttribute(
|
|
90
|
+
var wrapper = document.createElement('div');
|
|
91
|
+
wrapper.className = 'scroll-table sticky-table-scroll';
|
|
92
|
+
wrapper.setAttribute('data-fixed-header-scroll', '');
|
|
90
93
|
table.parentNode.insertBefore(wrapper, table);
|
|
91
94
|
wrapper.appendChild(table);
|
|
92
95
|
|
|
@@ -95,40 +98,40 @@
|
|
|
95
98
|
|
|
96
99
|
function autoFixedHeaderSlot(scroll) {
|
|
97
100
|
var sibling = scroll.previousElementSibling;
|
|
98
|
-
if (!sibling || !sibling.hasAttribute(
|
|
101
|
+
if (!sibling || !sibling.hasAttribute('data-auto-fixed-table-header')) return null;
|
|
99
102
|
|
|
100
103
|
return sibling;
|
|
101
104
|
}
|
|
102
105
|
|
|
103
106
|
function explicitFixedHeaderSlot(scroll) {
|
|
104
|
-
var mainContent = scroll.closest(
|
|
107
|
+
var mainContent = scroll.closest('.main-content');
|
|
105
108
|
if (!mainContent) return null;
|
|
106
109
|
|
|
107
|
-
return Array.from(mainContent.querySelectorAll(
|
|
108
|
-
return !slot.hasAttribute(
|
|
110
|
+
return Array.from(mainContent.querySelectorAll('[data-fixed-table-header]')).find(function(slot) {
|
|
111
|
+
return !slot.hasAttribute('data-auto-fixed-table-header');
|
|
109
112
|
}) || null;
|
|
110
113
|
}
|
|
111
114
|
|
|
112
115
|
function prepareFixedHeaderSlot(slot, inline) {
|
|
113
|
-
slot.classList.add(
|
|
116
|
+
slot.classList.add('table-fixed-header-slot');
|
|
114
117
|
|
|
115
118
|
if (inline) {
|
|
116
|
-
slot.setAttribute(
|
|
119
|
+
slot.setAttribute('data-fixed-header-inline', 'true');
|
|
117
120
|
} else {
|
|
118
|
-
slot.removeAttribute(
|
|
121
|
+
slot.removeAttribute('data-fixed-header-inline');
|
|
119
122
|
}
|
|
120
123
|
}
|
|
121
124
|
|
|
122
125
|
function numericPixelValue(value) {
|
|
123
|
-
var parsedValue = parseFloat(value ||
|
|
126
|
+
var parsedValue = parseFloat(value || '0');
|
|
124
127
|
return Number.isNaN(parsedValue) ? 0 : parsedValue;
|
|
125
128
|
}
|
|
126
129
|
|
|
127
130
|
function syncAutoSlotGap(slot) {
|
|
128
131
|
if (!slot) return;
|
|
129
132
|
|
|
130
|
-
if (!slot.hasAttribute(
|
|
131
|
-
slot.style.removeProperty(
|
|
133
|
+
if (!slot.hasAttribute('data-auto-fixed-table-header')) {
|
|
134
|
+
slot.style.removeProperty('margin-bottom');
|
|
132
135
|
return;
|
|
133
136
|
}
|
|
134
137
|
|
|
@@ -136,8 +139,8 @@
|
|
|
136
139
|
if (!parent) return;
|
|
137
140
|
|
|
138
141
|
var parentStyles = window.getComputedStyle(parent);
|
|
139
|
-
var isColumnFlex = parentStyles.display ===
|
|
140
|
-
var isGrid = parentStyles.display ===
|
|
142
|
+
var isColumnFlex = parentStyles.display === 'flex' && parentStyles.flexDirection.indexOf('column') === 0;
|
|
143
|
+
var isGrid = parentStyles.display === 'grid';
|
|
141
144
|
var gap = numericPixelValue(parentStyles.rowGap || parentStyles.gap);
|
|
142
145
|
|
|
143
146
|
if ((isColumnFlex || isGrid) && gap > 0) {
|
|
@@ -145,28 +148,30 @@
|
|
|
145
148
|
return;
|
|
146
149
|
}
|
|
147
150
|
|
|
148
|
-
slot.style.removeProperty(
|
|
151
|
+
slot.style.removeProperty('margin-bottom');
|
|
149
152
|
}
|
|
150
153
|
|
|
151
154
|
function ensureFixedHeaderScrollViewport(slot) {
|
|
152
|
-
var fixedScroll = slot.querySelector(
|
|
155
|
+
var fixedScroll = slot.querySelector('.table-fixed-header__scroll');
|
|
156
|
+
|
|
153
157
|
if (fixedScroll) return fixedScroll;
|
|
154
158
|
|
|
155
|
-
fixedScroll = document.createElement(
|
|
156
|
-
fixedScroll.className =
|
|
157
|
-
slot.innerHTML =
|
|
159
|
+
fixedScroll = document.createElement('div');
|
|
160
|
+
fixedScroll.className = 'table-fixed-header__scroll';
|
|
161
|
+
slot.innerHTML = '';
|
|
158
162
|
slot.appendChild(fixedScroll);
|
|
159
163
|
|
|
160
164
|
return fixedScroll;
|
|
161
165
|
}
|
|
162
166
|
|
|
163
167
|
function ensureFixedHeaderSpacer(fixedScroll) {
|
|
164
|
-
var spacer = fixedScroll.querySelector(
|
|
168
|
+
var spacer = fixedScroll.querySelector('.table-fixed-header__spacer');
|
|
169
|
+
|
|
165
170
|
if (spacer) return spacer;
|
|
166
171
|
|
|
167
|
-
spacer = document.createElement(
|
|
168
|
-
spacer.className =
|
|
169
|
-
spacer.setAttribute(
|
|
172
|
+
spacer = document.createElement('div');
|
|
173
|
+
spacer.className = 'table-fixed-header__spacer';
|
|
174
|
+
spacer.setAttribute('aria-hidden', 'true');
|
|
170
175
|
fixedScroll.appendChild(spacer);
|
|
171
176
|
|
|
172
177
|
return spacer;
|
|
@@ -185,10 +190,10 @@
|
|
|
185
190
|
return autoSlot;
|
|
186
191
|
}
|
|
187
192
|
|
|
188
|
-
autoSlot = document.createElement(
|
|
189
|
-
autoSlot.className =
|
|
190
|
-
autoSlot.setAttribute(
|
|
191
|
-
autoSlot.setAttribute(
|
|
193
|
+
autoSlot = document.createElement('div');
|
|
194
|
+
autoSlot.className = 'table-fixed-header-slot';
|
|
195
|
+
autoSlot.setAttribute('data-fixed-table-header', '');
|
|
196
|
+
autoSlot.setAttribute('data-auto-fixed-table-header', 'true');
|
|
192
197
|
autoSlot.hidden = true;
|
|
193
198
|
scroll.parentNode.insertBefore(autoSlot, scroll);
|
|
194
199
|
|
|
@@ -196,24 +201,28 @@
|
|
|
196
201
|
}
|
|
197
202
|
|
|
198
203
|
function closestMainContentHeader(scroll) {
|
|
199
|
-
var mainContent = scroll.closest(
|
|
204
|
+
var mainContent = scroll.closest('.main-content');
|
|
200
205
|
if (!mainContent) return null;
|
|
201
206
|
|
|
202
|
-
return mainContent.querySelector(
|
|
207
|
+
return mainContent.querySelector('.main-content__header');
|
|
203
208
|
}
|
|
204
209
|
|
|
205
210
|
function syncStickyPageHeader(scroll, slot) {
|
|
206
211
|
var header = closestMainContentHeader(scroll);
|
|
207
212
|
if (!header) {
|
|
208
|
-
slot.style.top =
|
|
213
|
+
slot.style.top = '0px';
|
|
209
214
|
syncAutoSlotGap(slot);
|
|
210
215
|
return;
|
|
211
216
|
}
|
|
212
217
|
|
|
213
|
-
if (
|
|
214
|
-
|
|
218
|
+
if (!header.classList.contains('reservations-list-header')) {
|
|
219
|
+
header.classList.add('main-content__header--sticky-table-layout');
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
if (slot.hasAttribute('data-auto-fixed-table-header')) {
|
|
223
|
+
slot.style.top = Math.ceil(header.getBoundingClientRect().height) + 'px';
|
|
215
224
|
} else {
|
|
216
|
-
slot.style.top =
|
|
225
|
+
slot.style.top = '0px';
|
|
217
226
|
}
|
|
218
227
|
|
|
219
228
|
syncAutoSlotGap(slot);
|
|
@@ -222,53 +231,60 @@
|
|
|
222
231
|
function syncFixedHeaderScroll(scroll, fixedScroll, scrollLeft) {
|
|
223
232
|
if (!scroll || !fixedScroll) return;
|
|
224
233
|
|
|
225
|
-
var left = typeof scrollLeft ===
|
|
234
|
+
var left = typeof scrollLeft === 'number' ? scrollLeft : scroll.scrollLeft;
|
|
235
|
+
|
|
226
236
|
fixedScroll.scrollLeft = left;
|
|
227
237
|
}
|
|
228
238
|
|
|
229
239
|
function fixedHeaderTableClassName(sourceTable) {
|
|
230
240
|
var excludedClasses = {
|
|
231
|
-
|
|
232
|
-
|
|
241
|
+
'table-with-fixed-header': true,
|
|
242
|
+
'home-table--with-fixed-header': true,
|
|
243
|
+
'table-fixed-header__table': true,
|
|
244
|
+
'home-table--fixed-header': true
|
|
233
245
|
};
|
|
234
246
|
|
|
235
247
|
var classes = sourceTable.className ? sourceTable.className.split(/\s+/).filter(function(className) {
|
|
236
248
|
return className && !excludedClasses[className];
|
|
237
249
|
}) : [];
|
|
238
250
|
|
|
239
|
-
classes.push(
|
|
251
|
+
classes.push('table-fixed-header__table');
|
|
252
|
+
if (sourceTable.classList.contains('home-table')) {
|
|
253
|
+
classes.push('home-table--fixed-header');
|
|
254
|
+
}
|
|
240
255
|
|
|
241
|
-
return Array.from(new Set(classes)).join(
|
|
256
|
+
return Array.from(new Set(classes)).join(' ');
|
|
242
257
|
}
|
|
243
258
|
|
|
244
259
|
function applyColGroup(table, widths) {
|
|
245
260
|
if (!table || !widths.length) return;
|
|
246
261
|
|
|
247
|
-
var colgroup = table.querySelector(
|
|
262
|
+
var colgroup = table.querySelector('colgroup[data-fixed-header-colgroup]');
|
|
263
|
+
|
|
248
264
|
if (!colgroup) {
|
|
249
|
-
colgroup = document.createElement(
|
|
250
|
-
colgroup.setAttribute(
|
|
265
|
+
colgroup = document.createElement('colgroup');
|
|
266
|
+
colgroup.setAttribute('data-fixed-header-colgroup', 'true');
|
|
251
267
|
table.insertBefore(colgroup, table.firstChild);
|
|
252
268
|
}
|
|
253
269
|
|
|
254
|
-
colgroup.innerHTML =
|
|
270
|
+
colgroup.innerHTML = '';
|
|
255
271
|
|
|
256
272
|
widths.forEach(function(width) {
|
|
257
|
-
var col = document.createElement(
|
|
273
|
+
var col = document.createElement('col');
|
|
258
274
|
col.style.width = cssPixelValue(width);
|
|
259
275
|
colgroup.appendChild(col);
|
|
260
276
|
});
|
|
261
277
|
}
|
|
262
278
|
|
|
263
279
|
function applyFixedHeaderCellWidths(fixedTable, widths) {
|
|
264
|
-
var headerRow = fixedTable && fixedTable.querySelector(
|
|
280
|
+
var headerRow = fixedTable && fixedTable.querySelector('thead tr');
|
|
265
281
|
if (!headerRow) return;
|
|
266
282
|
|
|
267
283
|
directCells(headerRow).forEach(function(cell, index) {
|
|
268
284
|
var width = widths[index];
|
|
269
285
|
if (!width) {
|
|
270
|
-
cell.style.removeProperty(
|
|
271
|
-
cell.style.removeProperty(
|
|
286
|
+
cell.style.removeProperty('width');
|
|
287
|
+
cell.style.removeProperty('min-width');
|
|
272
288
|
return;
|
|
273
289
|
}
|
|
274
290
|
|
|
@@ -279,13 +295,13 @@
|
|
|
279
295
|
|
|
280
296
|
function widthCandidateRows(sourceTable, headerCellCount) {
|
|
281
297
|
var candidates = [];
|
|
282
|
-
var headerRow = sourceTable.querySelector(
|
|
298
|
+
var headerRow = sourceTable.querySelector('thead tr');
|
|
283
299
|
|
|
284
300
|
if (headerRow) {
|
|
285
301
|
candidates.push(headerRow);
|
|
286
302
|
}
|
|
287
303
|
|
|
288
|
-
Array.from(sourceTable.querySelectorAll(
|
|
304
|
+
Array.from(sourceTable.querySelectorAll('tbody tr, tfoot tr')).forEach(function(row) {
|
|
289
305
|
var cells = directCells(row);
|
|
290
306
|
if (cells.length !== headerCellCount || cells.some(function(cell) { return cell.colSpan > 1; })) return;
|
|
291
307
|
|
|
@@ -296,7 +312,7 @@
|
|
|
296
312
|
}
|
|
297
313
|
|
|
298
314
|
function hasMeasurableDataRow(sourceTable, headerCellCount) {
|
|
299
|
-
return Array.from(sourceTable.querySelectorAll(
|
|
315
|
+
return Array.from(sourceTable.querySelectorAll('tbody tr, tfoot tr')).some(function(row) {
|
|
300
316
|
var cells = directCells(row);
|
|
301
317
|
return cells.length === headerCellCount && !cells.some(function(cell) { return cell.colSpan > 1; });
|
|
302
318
|
});
|
|
@@ -305,7 +321,7 @@
|
|
|
305
321
|
function removeGeneratedColGroup(table) {
|
|
306
322
|
if (!table) return;
|
|
307
323
|
|
|
308
|
-
var colgroup = table.querySelector(
|
|
324
|
+
var colgroup = table.querySelector('colgroup[data-fixed-header-colgroup]');
|
|
309
325
|
if (colgroup) {
|
|
310
326
|
colgroup.remove();
|
|
311
327
|
}
|
|
@@ -314,11 +330,11 @@
|
|
|
314
330
|
function generatedColGroupWidths(table, expectedCount) {
|
|
315
331
|
if (!table) return [];
|
|
316
332
|
|
|
317
|
-
var colgroup = table.querySelector(
|
|
333
|
+
var colgroup = table.querySelector('colgroup[data-fixed-header-colgroup]');
|
|
318
334
|
if (!colgroup) return [];
|
|
319
335
|
|
|
320
336
|
var widths = Array.from(colgroup.children).map(function(col) {
|
|
321
|
-
var inlineWidth = parseFloat(col.style.width ||
|
|
337
|
+
var inlineWidth = parseFloat(col.style.width || '0');
|
|
322
338
|
return Number.isNaN(inlineWidth) ? 0 : preciseNumber(inlineWidth);
|
|
323
339
|
});
|
|
324
340
|
|
|
@@ -327,7 +343,7 @@
|
|
|
327
343
|
return widths;
|
|
328
344
|
}
|
|
329
345
|
|
|
330
|
-
function clearFixedHeaderState(slot, sourceTable) {
|
|
346
|
+
function clearFixedHeaderState(slot, scroll, sourceTable) {
|
|
331
347
|
if (slot) {
|
|
332
348
|
slot.hidden = true;
|
|
333
349
|
}
|
|
@@ -335,13 +351,21 @@
|
|
|
335
351
|
if (!sourceTable) return;
|
|
336
352
|
|
|
337
353
|
removeGeneratedColGroup(sourceTable);
|
|
338
|
-
sourceTable.classList.remove(
|
|
354
|
+
sourceTable.classList.remove('table-with-fixed-header');
|
|
355
|
+
|
|
356
|
+
if (sourceTable.classList.contains('home-table')) {
|
|
357
|
+
sourceTable.classList.remove('home-table--with-fixed-header');
|
|
358
|
+
|
|
359
|
+
if (scroll) {
|
|
360
|
+
scroll.classList.remove('home-table__wrapper--fixed-header-ready');
|
|
361
|
+
}
|
|
362
|
+
}
|
|
339
363
|
}
|
|
340
364
|
|
|
341
365
|
function measuredColumnWidths(sourceTable, fixedTable, options) {
|
|
342
366
|
var settings = options || {};
|
|
343
|
-
var sourceHead = sourceTable.querySelector(
|
|
344
|
-
var sourceRow = sourceHead && sourceHead.querySelector(
|
|
367
|
+
var sourceHead = sourceTable.querySelector('thead');
|
|
368
|
+
var sourceRow = sourceHead && sourceHead.querySelector('tr');
|
|
345
369
|
|
|
346
370
|
if (!sourceRow) return [];
|
|
347
371
|
|
|
@@ -362,7 +386,7 @@
|
|
|
362
386
|
}
|
|
363
387
|
|
|
364
388
|
if (!widths.some(Boolean) && fixedTable && settings.allowFixedTableFallback !== false) {
|
|
365
|
-
var fixedRow = fixedTable.querySelector(
|
|
389
|
+
var fixedRow = fixedTable.querySelector('thead tr');
|
|
366
390
|
var fixedCells = fixedRow ? directCells(fixedRow) : [];
|
|
367
391
|
|
|
368
392
|
fixedCells.forEach(function(cell, index) {
|
|
@@ -374,12 +398,12 @@
|
|
|
374
398
|
}
|
|
375
399
|
|
|
376
400
|
function applyFixedHeaderStickyColumns(sourceTable, fixedTable, widths) {
|
|
377
|
-
var headerRow = fixedTable.querySelector(
|
|
401
|
+
var headerRow = fixedTable.querySelector('thead tr');
|
|
378
402
|
if (!headerRow) return;
|
|
379
403
|
|
|
380
404
|
directCells(headerRow).forEach(function(cell) {
|
|
381
|
-
cell.classList.remove(
|
|
382
|
-
cell.style.removeProperty(
|
|
405
|
+
cell.classList.remove('sticky-left', 'sticky-left--last');
|
|
406
|
+
cell.style.removeProperty('left');
|
|
383
407
|
});
|
|
384
408
|
|
|
385
409
|
var count = fixedColumnsCount(sourceTable);
|
|
@@ -388,9 +412,9 @@
|
|
|
388
412
|
var offsets = stickyOffsets(widths.slice(0, count));
|
|
389
413
|
|
|
390
414
|
directCells(headerRow).slice(0, offsets.length).forEach(function(cell, index) {
|
|
391
|
-
cell.classList.add(
|
|
415
|
+
cell.classList.add('sticky-left');
|
|
392
416
|
if (index === offsets.length - 1) {
|
|
393
|
-
cell.classList.add(
|
|
417
|
+
cell.classList.add('sticky-left--last');
|
|
394
418
|
}
|
|
395
419
|
cell.style.left = cssPixelValue(offsets[index]);
|
|
396
420
|
});
|
|
@@ -399,36 +423,36 @@
|
|
|
399
423
|
function buildFixedTableHeader(slot, scroll, sourceTable) {
|
|
400
424
|
if (!slot || !scroll || !sourceTable) return;
|
|
401
425
|
|
|
402
|
-
var sourceHead = sourceTable.querySelector(
|
|
426
|
+
var sourceHead = sourceTable.querySelector('thead');
|
|
403
427
|
if (!sourceHead) {
|
|
404
|
-
clearFixedHeaderState(slot, sourceTable);
|
|
428
|
+
clearFixedHeaderState(slot, scroll, sourceTable);
|
|
405
429
|
return;
|
|
406
430
|
}
|
|
407
431
|
|
|
408
|
-
var sourceRow = sourceHead.querySelector(
|
|
432
|
+
var sourceRow = sourceHead.querySelector('tr');
|
|
409
433
|
var headerCells = sourceRow ? directCells(sourceRow) : [];
|
|
410
434
|
var hasDataRow = hasMeasurableDataRow(sourceTable, headerCells.length);
|
|
411
435
|
|
|
412
436
|
if (!headerCells.length) {
|
|
413
|
-
clearFixedHeaderState(slot, sourceTable);
|
|
437
|
+
clearFixedHeaderState(slot, scroll, sourceTable);
|
|
414
438
|
return;
|
|
415
439
|
}
|
|
416
440
|
|
|
417
441
|
var fixedScroll = ensureFixedHeaderScrollViewport(slot);
|
|
418
|
-
var fixedTable = fixedScroll.querySelector(
|
|
442
|
+
var fixedTable = fixedScroll.querySelector('.table-fixed-header__table');
|
|
419
443
|
var fixedSpacer = ensureFixedHeaderSpacer(fixedScroll);
|
|
420
444
|
|
|
421
445
|
if (!fixedTable) {
|
|
422
|
-
fixedTable = document.createElement(
|
|
423
|
-
fixedTable.setAttribute(
|
|
446
|
+
fixedTable = document.createElement('table');
|
|
447
|
+
fixedTable.setAttribute('aria-hidden', 'true');
|
|
424
448
|
}
|
|
425
449
|
|
|
426
450
|
fixedTable.className = fixedHeaderTableClassName(sourceTable);
|
|
427
|
-
fixedTable.dataset.fixedColumnsCount = sourceTable.dataset.fixedColumnsCount ||
|
|
451
|
+
fixedTable.dataset.fixedColumnsCount = sourceTable.dataset.fixedColumnsCount || '0';
|
|
428
452
|
fixedTable.innerHTML = sourceHead.outerHTML;
|
|
429
453
|
|
|
430
454
|
if (fixedTable.parentNode !== fixedScroll) {
|
|
431
|
-
fixedScroll.innerHTML =
|
|
455
|
+
fixedScroll.innerHTML = '';
|
|
432
456
|
fixedScroll.appendChild(fixedTable);
|
|
433
457
|
fixedScroll.appendChild(fixedSpacer);
|
|
434
458
|
}
|
|
@@ -436,9 +460,8 @@
|
|
|
436
460
|
var widths = measuredColumnWidths(sourceTable, fixedTable, {
|
|
437
461
|
allowFixedTableFallback: hasDataRow
|
|
438
462
|
});
|
|
439
|
-
|
|
440
463
|
if (!widths.some(Boolean)) {
|
|
441
|
-
clearFixedHeaderState(slot, sourceTable);
|
|
464
|
+
clearFixedHeaderState(slot, scroll, sourceTable);
|
|
442
465
|
return;
|
|
443
466
|
}
|
|
444
467
|
|
|
@@ -449,15 +472,20 @@
|
|
|
449
472
|
|
|
450
473
|
var fixedScrollWidth = measuredTableWidth(sourceTable, widths);
|
|
451
474
|
|
|
452
|
-
fixedTable.style.transform =
|
|
453
|
-
fixedTable.style.marginLeft =
|
|
475
|
+
fixedTable.style.transform = '';
|
|
476
|
+
fixedTable.style.marginLeft = '';
|
|
454
477
|
fixedTable.style.width = cssPixelValue(fixedScrollWidth);
|
|
455
|
-
fixedSpacer.style.width =
|
|
456
|
-
fixedSpacer.style.minWidth =
|
|
478
|
+
fixedSpacer.style.width = '0px';
|
|
479
|
+
fixedSpacer.style.minWidth = '0px';
|
|
457
480
|
syncStickyPageHeader(scroll, slot);
|
|
458
481
|
syncFixedHeaderScroll(scroll, fixedScroll);
|
|
459
482
|
|
|
460
|
-
sourceTable.classList.add(
|
|
483
|
+
sourceTable.classList.add('table-with-fixed-header');
|
|
484
|
+
if (sourceTable.classList.contains('home-table')) {
|
|
485
|
+
sourceTable.classList.add('home-table--with-fixed-header');
|
|
486
|
+
scroll.classList.add('home-table__wrapper--fixed-header-ready');
|
|
487
|
+
}
|
|
488
|
+
|
|
461
489
|
slot.hidden = false;
|
|
462
490
|
}
|
|
463
491
|
|
|
@@ -483,7 +511,7 @@
|
|
|
483
511
|
function observeFixedHeaderScroll(scroll) {
|
|
484
512
|
if (observedScrolls.has(scroll)) return;
|
|
485
513
|
|
|
486
|
-
scroll.addEventListener(
|
|
514
|
+
scroll.addEventListener('scroll', function() {
|
|
487
515
|
var state = scrollSyncStates.get(scroll) || {};
|
|
488
516
|
state.scrollLeft = scroll.scrollLeft;
|
|
489
517
|
|
|
@@ -492,7 +520,7 @@
|
|
|
492
520
|
state.frame = window.requestAnimationFrame(function() {
|
|
493
521
|
var slot = ensureFixedHeaderSlot(scroll);
|
|
494
522
|
state.frame = null;
|
|
495
|
-
syncFixedHeaderScroll(scroll, slot.querySelector(
|
|
523
|
+
syncFixedHeaderScroll(scroll, slot.querySelector('.table-fixed-header__scroll'), state.scrollLeft);
|
|
496
524
|
});
|
|
497
525
|
|
|
498
526
|
scrollSyncStates.set(scroll, state);
|
|
@@ -545,14 +573,14 @@
|
|
|
545
573
|
initializeFixedHeaders(document);
|
|
546
574
|
}
|
|
547
575
|
|
|
548
|
-
if (document.readyState ===
|
|
549
|
-
document.addEventListener(
|
|
576
|
+
if (document.readyState === 'loading') {
|
|
577
|
+
document.addEventListener('DOMContentLoaded', initializeFromDocument);
|
|
550
578
|
} else {
|
|
551
579
|
initializeFromDocument();
|
|
552
580
|
}
|
|
553
581
|
|
|
554
|
-
document.addEventListener(
|
|
555
|
-
window.addEventListener(
|
|
582
|
+
document.addEventListener('turbo:load', initializeFromDocument);
|
|
583
|
+
window.addEventListener('resize', initializeFromDocument);
|
|
556
584
|
|
|
557
585
|
if (window.MutationObserver) {
|
|
558
586
|
var mutationObserver = new MutationObserver(function(mutations) {
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
.admin-fixed-submit-bar {
|
|
2
|
+
position: fixed;
|
|
3
|
+
left: var(--fixed-submit-left, 0);
|
|
4
|
+
width: var(--fixed-submit-width, 100%);
|
|
5
|
+
bottom: 0;
|
|
6
|
+
z-index: 20;
|
|
7
|
+
padding: 0.9rem 1rem calc(0.9rem + env(safe-area-inset-bottom));
|
|
8
|
+
background: #fff;
|
|
9
|
+
border-top: 1px solid #d9dde8;
|
|
10
|
+
box-sizing: border-box;
|
|
11
|
+
|
|
12
|
+
@media screen and (max-width: 767px) {
|
|
13
|
+
padding-left: 0.8rem;
|
|
14
|
+
padding-right: 0.8rem;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.admin-fixed-submit-bar[hidden] {
|
|
19
|
+
display: none !important;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.admin-fixed-submit-bar__actions,
|
|
23
|
+
.admin-fixed-submit-bar__action-clone {
|
|
24
|
+
display: flex;
|
|
25
|
+
justify-content: flex-end;
|
|
26
|
+
align-items: center;
|
|
27
|
+
gap: 0.75rem;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.admin-fixed-submit-bar__action-clone,
|
|
31
|
+
.admin-fixed-submit-bar__action-clone.form-actions,
|
|
32
|
+
.admin-fixed-submit-bar__action-clone.form_submit {
|
|
33
|
+
margin: 0;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.admin-fixed-submit-bar__actions input[type="submit"],
|
|
37
|
+
.admin-fixed-submit-bar__actions input[type="button"],
|
|
38
|
+
.admin-fixed-submit-bar__actions button[type="submit"],
|
|
39
|
+
.admin-fixed-submit-bar__actions button[type="button"],
|
|
40
|
+
.admin-fixed-submit-bar__actions .async-form__submit {
|
|
41
|
+
min-width: 20rem;
|
|
42
|
+
min-height: 3.5rem;
|
|
43
|
+
font-size: 1.5em;
|
|
44
|
+
font-weight: 600;
|
|
45
|
+
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
@import "fixed_submit_actions";
|
|
2
|
+
|
|
1
3
|
.scroll-table {
|
|
2
4
|
overflow-x: auto;
|
|
3
5
|
}
|
|
@@ -5,7 +7,9 @@
|
|
|
5
7
|
.scroll-table table th,
|
|
6
8
|
.scroll-table table td,
|
|
7
9
|
.sticky-table-scroll table th,
|
|
8
|
-
.sticky-table-scroll table td
|
|
10
|
+
.sticky-table-scroll table td,
|
|
11
|
+
.home-table th,
|
|
12
|
+
.home-table td {
|
|
9
13
|
vertical-align: middle;
|
|
10
14
|
}
|
|
11
15
|
|
|
@@ -169,19 +173,23 @@ td.cell-data:hover .admin-copy-cell__button:not([disabled]),
|
|
|
169
173
|
.scroll-table table th.sticky-left,
|
|
170
174
|
.scroll-table table td.sticky-left,
|
|
171
175
|
.sticky-table-scroll table th.sticky-left,
|
|
172
|
-
.sticky-table-scroll table td.sticky-left
|
|
176
|
+
.sticky-table-scroll table td.sticky-left,
|
|
177
|
+
.home-table th.sticky-left,
|
|
178
|
+
.home-table td.sticky-left {
|
|
173
179
|
position: sticky;
|
|
174
180
|
background-clip: padding-box;
|
|
175
181
|
}
|
|
176
182
|
|
|
177
183
|
.scroll-table table th.sticky-left,
|
|
178
|
-
.sticky-table-scroll table th.sticky-left
|
|
184
|
+
.sticky-table-scroll table th.sticky-left,
|
|
185
|
+
.home-table th.sticky-left {
|
|
179
186
|
z-index: 4;
|
|
180
187
|
background-color: #121012;
|
|
181
188
|
}
|
|
182
189
|
|
|
183
190
|
.scroll-table table td.sticky-left,
|
|
184
|
-
.sticky-table-scroll table td.sticky-left
|
|
191
|
+
.sticky-table-scroll table td.sticky-left,
|
|
192
|
+
.home-table td.sticky-left {
|
|
185
193
|
z-index: 3;
|
|
186
194
|
background-color: var(--sticky-cell-background, #fff);
|
|
187
195
|
}
|
|
@@ -189,7 +197,9 @@ td.cell-data:hover .admin-copy-cell__button:not([disabled]),
|
|
|
189
197
|
.scroll-table table th.sticky-left::after,
|
|
190
198
|
.scroll-table table td.sticky-left::after,
|
|
191
199
|
.sticky-table-scroll table th.sticky-left::after,
|
|
192
|
-
.sticky-table-scroll table td.sticky-left::after
|
|
200
|
+
.sticky-table-scroll table td.sticky-left::after,
|
|
201
|
+
.home-table th.sticky-left::after,
|
|
202
|
+
.home-table td.sticky-left::after {
|
|
193
203
|
content: "";
|
|
194
204
|
position: absolute;
|
|
195
205
|
top: -1px;
|
|
@@ -203,14 +213,18 @@ td.cell-data:hover .admin-copy-cell__button:not([disabled]),
|
|
|
203
213
|
.scroll-table table th.sticky-left--last,
|
|
204
214
|
.scroll-table table td.sticky-left--last,
|
|
205
215
|
.sticky-table-scroll table th.sticky-left--last,
|
|
206
|
-
.sticky-table-scroll table td.sticky-left--last
|
|
216
|
+
.sticky-table-scroll table td.sticky-left--last,
|
|
217
|
+
.home-table th.sticky-left--last,
|
|
218
|
+
.home-table td.sticky-left--last {
|
|
207
219
|
box-shadow: 6px 0 8px -8px rgba(0, 0, 0, 0.35);
|
|
208
220
|
}
|
|
209
221
|
|
|
210
222
|
.scroll-table table th.sticky,
|
|
211
223
|
.scroll-table table td.sticky,
|
|
212
224
|
.sticky-table-scroll table th.sticky,
|
|
213
|
-
.sticky-table-scroll table td.sticky
|
|
225
|
+
.sticky-table-scroll table td.sticky,
|
|
226
|
+
.home-table th.sticky,
|
|
227
|
+
.home-table td.sticky {
|
|
214
228
|
position: sticky;
|
|
215
229
|
right: 0;
|
|
216
230
|
background-color: inherit;
|
|
@@ -221,7 +235,9 @@ td.cell-data:hover .admin-copy-cell__button:not([disabled]),
|
|
|
221
235
|
.scroll-table table th.sticky::before,
|
|
222
236
|
.scroll-table table td.sticky::before,
|
|
223
237
|
.sticky-table-scroll table th.sticky::before,
|
|
224
|
-
.sticky-table-scroll table td.sticky::before
|
|
238
|
+
.sticky-table-scroll table td.sticky::before,
|
|
239
|
+
.home-table th.sticky::before,
|
|
240
|
+
.home-table td.sticky::before {
|
|
225
241
|
content: "";
|
|
226
242
|
position: absolute;
|
|
227
243
|
top: -1px;
|
|
@@ -233,12 +249,14 @@ td.cell-data:hover .admin-copy-cell__button:not([disabled]),
|
|
|
233
249
|
}
|
|
234
250
|
|
|
235
251
|
.scroll-table table th.sticky,
|
|
236
|
-
.sticky-table-scroll table th.sticky
|
|
252
|
+
.sticky-table-scroll table th.sticky,
|
|
253
|
+
.home-table th.sticky {
|
|
237
254
|
z-index: 5;
|
|
238
255
|
}
|
|
239
256
|
|
|
240
257
|
.scroll-table table td.sticky,
|
|
241
|
-
.sticky-table-scroll table td.sticky
|
|
258
|
+
.sticky-table-scroll table td.sticky,
|
|
259
|
+
.home-table td.sticky {
|
|
242
260
|
z-index: 4;
|
|
243
261
|
background-color: var(--sticky-cell-background, #fff);
|
|
244
262
|
}
|
|
@@ -251,7 +269,8 @@ td.cell-data:hover .admin-copy-cell__button:not([disabled]),
|
|
|
251
269
|
}
|
|
252
270
|
|
|
253
271
|
td.actions-column .sticky__item,
|
|
254
|
-
.sticky-table-scroll td.actions-column .sticky__item
|
|
272
|
+
.sticky-table-scroll td.actions-column .sticky__item,
|
|
273
|
+
.home-table td.actions-column .sticky__item {
|
|
255
274
|
width: max-content;
|
|
256
275
|
}
|
|
257
276
|
|
|
@@ -292,7 +311,8 @@ td.actions-column .sticky__item,
|
|
|
292
311
|
top: 0;
|
|
293
312
|
}
|
|
294
313
|
|
|
295
|
-
.table-with-fixed-header thead
|
|
314
|
+
.table-with-fixed-header thead,
|
|
315
|
+
.home-table--with-fixed-header thead {
|
|
296
316
|
display: none;
|
|
297
317
|
}
|
|
298
318
|
|
|
@@ -384,6 +404,27 @@ td.actions-column .sticky__item,
|
|
|
384
404
|
box-shadow: 6px 0 8px -8px rgba(0, 0, 0, 0.35);
|
|
385
405
|
}
|
|
386
406
|
|
|
407
|
+
|
|
408
|
+
.home-table--fixed-header {
|
|
409
|
+
table-layout: fixed;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
.home-table--fixed-header th {
|
|
413
|
+
position: static;
|
|
414
|
+
top: auto;
|
|
415
|
+
z-index: auto;
|
|
416
|
+
border: 1px solid #121012;
|
|
417
|
+
white-space: normal;
|
|
418
|
+
overflow-wrap: break-word;
|
|
419
|
+
word-break: break-word;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
.home-table--fixed-header th.sticky {
|
|
423
|
+
position: sticky;
|
|
424
|
+
right: 0;
|
|
425
|
+
z-index: 5;
|
|
426
|
+
}
|
|
427
|
+
|
|
387
428
|
.yummy-guide-administrate-filter-form {
|
|
388
429
|
display: flex;
|
|
389
430
|
flex-direction: column;
|
|
@@ -9,6 +9,7 @@ module YummyGuide
|
|
|
9
9
|
app.config.assets.precompile += %w[
|
|
10
10
|
yummy_guide_administrate/components.css
|
|
11
11
|
yummy_guide_administrate/clipboards.js
|
|
12
|
+
yummy_guide_administrate/fixed_submit_actions.js
|
|
12
13
|
yummy_guide_administrate/filter_form.js
|
|
13
14
|
yummy_guide_administrate/sticky_left_columns.js
|
|
14
15
|
yummy_guide_administrate/sticky_table_headers.js
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: yummy-guide-generic-administrate
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- akatsuki-kk
|
|
@@ -92,8 +92,10 @@ files:
|
|
|
92
92
|
- app/assets/images/yummy_guide_administrate/icon-copy.svg
|
|
93
93
|
- app/assets/javascripts/yummy_guide_administrate/clipboards.js
|
|
94
94
|
- app/assets/javascripts/yummy_guide_administrate/filter_form.js
|
|
95
|
+
- app/assets/javascripts/yummy_guide_administrate/fixed_submit_actions.js
|
|
95
96
|
- app/assets/javascripts/yummy_guide_administrate/sticky_left_columns.js
|
|
96
97
|
- app/assets/javascripts/yummy_guide_administrate/sticky_table_headers.js
|
|
98
|
+
- app/assets/stylesheets/yummy_guide_administrate/_fixed_submit_actions.scss
|
|
97
99
|
- app/assets/stylesheets/yummy_guide_administrate/components.scss
|
|
98
100
|
- app/controllers/concerns/yummy_guide/administrate/datetime_filter_parameters.rb
|
|
99
101
|
- app/controllers/concerns/yummy_guide/administrate/default_sorting.rb
|