yummy-guide-generic-administrate 0.8.8 → 0.8.10
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/app/assets/javascripts/yummy_guide_administrate/column_resizer.js +187 -25
- data/app/assets/stylesheets/yummy_guide_administrate/components.scss +0 -5
- data/lib/yummy_guide/administrate/version.rb +1 -1
- data/spec/yummy_guide/administrate/collection_helper_spec.rb +1 -0
- data/spec/yummy_guide/administrate/column_resizer_asset_spec.rb +24 -2
- data/spec/yummy_guide/administrate/copy_cell_asset_spec.rb +27 -0
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8c30d8690fff8a7358f89a9e8e56a651b9b7630e3d1e69237325a215e0e7a3f0
|
|
4
|
+
data.tar.gz: 488e2ad28e15eec00b0e8387734c1cdf5bd56426ba9f916fe611c03a700203aa
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d95722f019bf3930435bd7602d9d937cf744bfa3b261fa771412f17f6b0ca047959bd3212af6cdd9b0c81992872f019ced8d79671e6fdbe38cb093084f227b78
|
|
7
|
+
data.tar.gz: a0afec4d0c4f2c8615664eea22ca12ef10e5332a70062cde6f535e4a4b251df567c0950e5056a5ea209cd3d3393e73f8b7f2f834056a78b1177ce38744f220a5
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
(function() {
|
|
2
2
|
var TABLE_SELECTOR = 'table[data-fixed-columns-count]';
|
|
3
|
+
var CSS_STICKY_TABLE_SELECTOR = '[data-css-sticky-table]';
|
|
4
|
+
var MAIN_CONTENT_SELECTOR = '.main-content';
|
|
5
|
+
var STICKY_PAGE_HEADER_SELECTOR = '.main-content__header--sticky-table-layout, [data-reservations-sticky-header], .main-content__header';
|
|
6
|
+
var STICKY_PAGE_HEADER_HEIGHT_VARIABLE = '--admin-sticky-page-header-height';
|
|
3
7
|
var HANDLE_CLASS = 'admin-column-resizer__handle';
|
|
4
8
|
var HEADER_CLASS = 'admin-column-resizer__header';
|
|
5
9
|
var TABLE_CLASS = 'admin-column-resizer__table';
|
|
@@ -19,6 +23,8 @@
|
|
|
19
23
|
var generatedRuleCount = 0;
|
|
20
24
|
var initializedHandles = new WeakSet();
|
|
21
25
|
var tableStates = new WeakMap();
|
|
26
|
+
var stickyPageHeaderResizeObservers = new WeakMap();
|
|
27
|
+
var stickyPageHeaderLayoutFrames = new WeakMap();
|
|
22
28
|
var applyingWidth = false;
|
|
23
29
|
|
|
24
30
|
function storageScopeForTable(table) {
|
|
@@ -78,6 +84,176 @@
|
|
|
78
84
|
return preciseNumber(rectWidth || element.offsetWidth || 0);
|
|
79
85
|
}
|
|
80
86
|
|
|
87
|
+
function pushUnique(array, item) {
|
|
88
|
+
if (item && array.indexOf(item) === -1) {
|
|
89
|
+
array.push(item);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function hasCssStickyTable(element) {
|
|
94
|
+
if (!element) return false;
|
|
95
|
+
|
|
96
|
+
return (element.matches && element.matches(CSS_STICKY_TABLE_SELECTOR)) ||
|
|
97
|
+
!!(element.querySelector && element.querySelector(CSS_STICKY_TABLE_SELECTOR));
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function closestMainContent(element) {
|
|
101
|
+
if (!element || element.nodeType !== Node.ELEMENT_NODE) return null;
|
|
102
|
+
|
|
103
|
+
if (element.matches && element.matches(MAIN_CONTENT_SELECTOR)) {
|
|
104
|
+
return element;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return element.closest ? element.closest(MAIN_CONTENT_SELECTOR) : null;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function collectStickyTableMainContents(root) {
|
|
111
|
+
var mainContents = [];
|
|
112
|
+
var element = root && root.nodeType === Node.ELEMENT_NODE ? root : null;
|
|
113
|
+
|
|
114
|
+
if (element) {
|
|
115
|
+
pushUnique(mainContents, closestMainContent(element));
|
|
116
|
+
|
|
117
|
+
if (element.matches && element.matches(CSS_STICKY_TABLE_SELECTOR)) {
|
|
118
|
+
pushUnique(mainContents, closestMainContent(element));
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (root && root.querySelectorAll) {
|
|
123
|
+
root.querySelectorAll(MAIN_CONTENT_SELECTOR).forEach(function(mainContent) {
|
|
124
|
+
if (hasCssStickyTable(mainContent)) {
|
|
125
|
+
pushUnique(mainContents, mainContent);
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
root.querySelectorAll(CSS_STICKY_TABLE_SELECTOR).forEach(function(tableWrapper) {
|
|
130
|
+
pushUnique(mainContents, closestMainContent(tableWrapper));
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return mainContents;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function stickyPageHeader(mainContent) {
|
|
138
|
+
if (!mainContent) return null;
|
|
139
|
+
|
|
140
|
+
return Array.from(mainContent.children).find(function(child) {
|
|
141
|
+
return child.matches && child.matches(STICKY_PAGE_HEADER_SELECTOR);
|
|
142
|
+
}) || null;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function measuredStickyPageHeaderHeight(mainContent, header) {
|
|
146
|
+
var previousHeight = mainContent.style.getPropertyValue(STICKY_PAGE_HEADER_HEIGHT_VARIABLE);
|
|
147
|
+
|
|
148
|
+
if (previousHeight) {
|
|
149
|
+
mainContent.style.removeProperty(STICKY_PAGE_HEADER_HEIGHT_VARIABLE);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
var rectHeight = header.getBoundingClientRect().height;
|
|
153
|
+
var scrollHeight = header.scrollHeight || 0;
|
|
154
|
+
var height = Math.max(rectHeight || 0, scrollHeight);
|
|
155
|
+
|
|
156
|
+
if (previousHeight) {
|
|
157
|
+
mainContent.style.setProperty(STICKY_PAGE_HEADER_HEIGHT_VARIABLE, previousHeight);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
return preciseNumber(height);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
function refreshStickyPageHeaderLayout(mainContent) {
|
|
164
|
+
if (!mainContent) return false;
|
|
165
|
+
|
|
166
|
+
if (!hasCssStickyTable(mainContent)) {
|
|
167
|
+
mainContent.style.removeProperty(STICKY_PAGE_HEADER_HEIGHT_VARIABLE);
|
|
168
|
+
return false;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
var header = stickyPageHeader(mainContent);
|
|
172
|
+
|
|
173
|
+
if (!header) {
|
|
174
|
+
mainContent.style.removeProperty(STICKY_PAGE_HEADER_HEIGHT_VARIABLE);
|
|
175
|
+
return false;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
var height = measuredStickyPageHeaderHeight(mainContent, header);
|
|
179
|
+
|
|
180
|
+
if (height > 0) {
|
|
181
|
+
var value = cssPixelValue(height);
|
|
182
|
+
|
|
183
|
+
if (mainContent.style.getPropertyValue(STICKY_PAGE_HEADER_HEIGHT_VARIABLE) !== value) {
|
|
184
|
+
mainContent.style.setProperty(STICKY_PAGE_HEADER_HEIGHT_VARIABLE, value);
|
|
185
|
+
}
|
|
186
|
+
} else {
|
|
187
|
+
mainContent.style.removeProperty(STICKY_PAGE_HEADER_HEIGHT_VARIABLE);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
return true;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function observeStickyPageHeaderLayout(mainContent) {
|
|
194
|
+
if (!window.ResizeObserver || !mainContent) return;
|
|
195
|
+
|
|
196
|
+
var header = stickyPageHeader(mainContent);
|
|
197
|
+
var currentObserver = stickyPageHeaderResizeObservers.get(mainContent);
|
|
198
|
+
|
|
199
|
+
if (!header) {
|
|
200
|
+
if (currentObserver) {
|
|
201
|
+
currentObserver.observer.disconnect();
|
|
202
|
+
stickyPageHeaderResizeObservers.delete(mainContent);
|
|
203
|
+
}
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
if (currentObserver && currentObserver.header === header) return;
|
|
208
|
+
|
|
209
|
+
if (currentObserver) {
|
|
210
|
+
currentObserver.observer.disconnect();
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
var observer = new ResizeObserver(function() {
|
|
214
|
+
scheduleStickyPageHeaderLayout(mainContent);
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
observer.observe(header);
|
|
218
|
+
|
|
219
|
+
stickyPageHeaderResizeObservers.set(mainContent, {
|
|
220
|
+
header: header,
|
|
221
|
+
observer: observer
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
function scheduleStickyPageHeaderLayout(mainContent) {
|
|
226
|
+
if (!mainContent || stickyPageHeaderLayoutFrames.has(mainContent)) return;
|
|
227
|
+
|
|
228
|
+
var frame = window.requestAnimationFrame(function() {
|
|
229
|
+
stickyPageHeaderLayoutFrames.delete(mainContent);
|
|
230
|
+
refreshStickyPageHeaderLayout(mainContent);
|
|
231
|
+
observeStickyPageHeaderLayout(mainContent);
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
stickyPageHeaderLayoutFrames.set(mainContent, frame);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
function refreshStickyHeaderLayout(root) {
|
|
238
|
+
var refreshed = false;
|
|
239
|
+
|
|
240
|
+
collectStickyTableMainContents(root || document).forEach(function(mainContent) {
|
|
241
|
+
refreshed = refreshStickyPageHeaderLayout(mainContent) || refreshed;
|
|
242
|
+
observeStickyPageHeaderLayout(mainContent);
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
return refreshed;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
function refreshStickyHeaderLayoutForTable(table) {
|
|
249
|
+
var mainContent = closestMainContent(table);
|
|
250
|
+
|
|
251
|
+
if (!mainContent) return false;
|
|
252
|
+
|
|
253
|
+
scheduleStickyPageHeaderLayout(mainContent);
|
|
254
|
+
return true;
|
|
255
|
+
}
|
|
256
|
+
|
|
81
257
|
function viewportHeight() {
|
|
82
258
|
return window.innerHeight || document.documentElement.clientHeight || 0;
|
|
83
259
|
}
|
|
@@ -218,14 +394,6 @@
|
|
|
218
394
|
return tables;
|
|
219
395
|
}
|
|
220
396
|
|
|
221
|
-
function shouldInitializeForAddedNode(node) {
|
|
222
|
-
if (!node.matches) return false;
|
|
223
|
-
if (node.matches(TABLE_SELECTOR) || (node.querySelector && node.querySelector(TABLE_SELECTOR))) return true;
|
|
224
|
-
if (!node.closest || !node.closest(TABLE_SELECTOR)) return false;
|
|
225
|
-
|
|
226
|
-
return !!node.closest('thead') || node.matches('colgroup, col');
|
|
227
|
-
}
|
|
228
|
-
|
|
229
397
|
function allTrackedTables() {
|
|
230
398
|
return Array.from(document.querySelectorAll(TABLE_SELECTOR));
|
|
231
399
|
}
|
|
@@ -422,6 +590,7 @@
|
|
|
422
590
|
if (key && storageKeyForTable(table) !== key) return;
|
|
423
591
|
|
|
424
592
|
applyTableColumnWidth(table, columnId, width);
|
|
593
|
+
refreshStickyHeaderLayoutForTable(table);
|
|
425
594
|
});
|
|
426
595
|
}
|
|
427
596
|
|
|
@@ -430,6 +599,7 @@
|
|
|
430
599
|
if (key && storageKeyForTable(table) !== key) return;
|
|
431
600
|
|
|
432
601
|
clearTableColumnWidth(table, columnId);
|
|
602
|
+
refreshStickyHeaderLayoutForTable(table);
|
|
433
603
|
});
|
|
434
604
|
}
|
|
435
605
|
|
|
@@ -440,6 +610,8 @@
|
|
|
440
610
|
|
|
441
611
|
applyTableColumnWidth(table, columnId, width);
|
|
442
612
|
});
|
|
613
|
+
|
|
614
|
+
refreshStickyHeaderLayoutForTable(table);
|
|
443
615
|
}
|
|
444
616
|
|
|
445
617
|
function applyStoredWidthsToTables(tables) {
|
|
@@ -609,6 +781,8 @@
|
|
|
609
781
|
}
|
|
610
782
|
|
|
611
783
|
function refreshStickyLeftColumns(sourceTable) {
|
|
784
|
+
refreshStickyHeaderLayoutForTable(sourceTable);
|
|
785
|
+
|
|
612
786
|
var api = window.YummyGuideAdministrateStickyLeftColumns;
|
|
613
787
|
|
|
614
788
|
if (api && typeof api.refreshTable === 'function') {
|
|
@@ -671,6 +845,7 @@
|
|
|
671
845
|
widths[pendingWidth.columnId] = preciseNumber(pendingWidth.width);
|
|
672
846
|
safeWriteWidths(pendingWidth.storageKey, widths);
|
|
673
847
|
refreshStickyLeftColumnsForWidth(pendingWidth);
|
|
848
|
+
refreshStickyHeaderLayoutForTable(pendingWidth.sourceTable);
|
|
674
849
|
window.requestAnimationFrame(function() {
|
|
675
850
|
stopApplyingWidth(pendingWidth.preview);
|
|
676
851
|
});
|
|
@@ -841,6 +1016,7 @@
|
|
|
841
1016
|
});
|
|
842
1017
|
|
|
843
1018
|
applyStoredWidthsToTables(configuredTables);
|
|
1019
|
+
refreshStickyHeaderLayout(root);
|
|
844
1020
|
}
|
|
845
1021
|
|
|
846
1022
|
function initializeFromDocument() {
|
|
@@ -856,23 +1032,9 @@
|
|
|
856
1032
|
document.addEventListener('turbo:load', initializeFromDocument);
|
|
857
1033
|
window.addEventListener('resize', initializeFromDocument);
|
|
858
1034
|
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
mutation.addedNodes.forEach(function(node) {
|
|
863
|
-
if (node.nodeType !== Node.ELEMENT_NODE) return;
|
|
864
|
-
if (!shouldInitializeForAddedNode(node)) return;
|
|
865
|
-
|
|
866
|
-
initializeColumnResizer(node);
|
|
867
|
-
});
|
|
868
|
-
});
|
|
869
|
-
});
|
|
870
|
-
|
|
871
|
-
mutationObserver.observe(document.documentElement, {
|
|
872
|
-
childList: true,
|
|
873
|
-
subtree: true
|
|
874
|
-
});
|
|
875
|
-
}
|
|
1035
|
+
window.YummyGuideAdministrateColumnResizer = {
|
|
1036
|
+
refreshStickyHeaderLayout: refreshStickyHeaderLayout
|
|
1037
|
+
};
|
|
876
1038
|
|
|
877
1039
|
setTimeout(initializeFromDocument, 100);
|
|
878
1040
|
setTimeout(initializeFromDocument, 300);
|
|
@@ -419,11 +419,6 @@
|
|
|
419
419
|
cursor: default;
|
|
420
420
|
}
|
|
421
421
|
|
|
422
|
-
.admin-copy-cell__button[data-behavior="copy-cell"],
|
|
423
|
-
.admin-copy-cell__icon {
|
|
424
|
-
display: none !important;
|
|
425
|
-
}
|
|
426
|
-
|
|
427
422
|
.admin-copy-cell__link:hover,
|
|
428
423
|
.admin-copy-cell__link:focus-visible,
|
|
429
424
|
.admin-copy-cell__link:active,
|
|
@@ -270,6 +270,7 @@ RSpec.describe YummyGuide::Administrate::CollectionHelper do
|
|
|
270
270
|
expect(cell[:linkable]).to be(false)
|
|
271
271
|
expect(cell[:content]).to include('href="/areas/japan/nagano/matsumoto/articles/test-article"')
|
|
272
272
|
expect(cell[:content]).to include('data-behavior="copy-cell"')
|
|
273
|
+
expect(cell[:content]).to include('class="admin-copy-cell__icon"')
|
|
273
274
|
expect(cell[:content]).to include('data-copy-text="Page"')
|
|
274
275
|
end
|
|
275
276
|
|
|
@@ -42,7 +42,6 @@ RSpec.describe "column resizer assets" do
|
|
|
42
42
|
# 固定ヘッダー複製用の同期処理を持たず、元テーブルの固定左列だけ再計算することを静的に確認する
|
|
43
43
|
it "does not depend on duplicated fixed header synchronization" do
|
|
44
44
|
expect(javascript_source).not_to include("YummyGuideAdministrateStickyTableHeaders")
|
|
45
|
-
expect(javascript_source).not_to include("refreshStickyHeader")
|
|
46
45
|
expect(javascript_source).not_to include("scheduleStickyRefresh")
|
|
47
46
|
expect(javascript_source).not_to include("table-fixed-header__table")
|
|
48
47
|
expect(javascript_source).to include("refreshStickyLeftColumnsForWidth(pendingWidth)")
|
|
@@ -147,7 +146,7 @@ RSpec.describe "column resizer assets" do
|
|
|
147
146
|
expect(components_source).to include("position: static !important")
|
|
148
147
|
expect(components_source).to include('table[data-mobile-fixed-columns-count="1"] th.sticky-left-mobile')
|
|
149
148
|
expect(components_source).to include("position: sticky !important")
|
|
150
|
-
expect(components_source).to include("min-inline-size:
|
|
149
|
+
expect(components_source).to include("min-inline-size: 0 !important")
|
|
151
150
|
expect(components_source).to include("width: max-content !important")
|
|
152
151
|
expect(components_source).to include("@media (max-width: 767px)")
|
|
153
152
|
expect(components_source).to include(".scroll-table table th.sticky.actions-column")
|
|
@@ -166,6 +165,21 @@ RSpec.describe "column resizer assets" do
|
|
|
166
165
|
expect(components_source).to include("width: var(--admin-sticky-actions-right, 0px)")
|
|
167
166
|
end
|
|
168
167
|
|
|
168
|
+
# 固定ページヘッダーの実高さをCSS変数へ反映し、テーブルヘッダー位置を追従させることを静的に確認する
|
|
169
|
+
it "updates sticky table header offset from measured page header height" do
|
|
170
|
+
expect(javascript_source).to include("CSS_STICKY_TABLE_SELECTOR = '[data-css-sticky-table]'")
|
|
171
|
+
expect(javascript_source).to include("STICKY_PAGE_HEADER_HEIGHT_VARIABLE = '--admin-sticky-page-header-height'")
|
|
172
|
+
expect(javascript_source).to include("function measuredStickyPageHeaderHeight(mainContent, header)")
|
|
173
|
+
expect(javascript_source).to include("header.getBoundingClientRect().height")
|
|
174
|
+
expect(javascript_source).to include("header.scrollHeight || 0")
|
|
175
|
+
expect(javascript_source).to include("mainContent.style.setProperty(STICKY_PAGE_HEADER_HEIGHT_VARIABLE, value)")
|
|
176
|
+
expect(javascript_source).to include("mainContent.style.removeProperty(STICKY_PAGE_HEADER_HEIGHT_VARIABLE)")
|
|
177
|
+
expect(javascript_source).to include("new ResizeObserver(function()")
|
|
178
|
+
expect(javascript_source).to include("refreshStickyHeaderLayoutForTable(table)")
|
|
179
|
+
expect(javascript_source).to include("refreshStickyHeaderLayoutForTable(pendingWidth.sourceTable)")
|
|
180
|
+
expect(javascript_source).to include("refreshStickyHeaderLayout: refreshStickyHeaderLayout")
|
|
181
|
+
end
|
|
182
|
+
|
|
169
183
|
# 固定ナビがテーブルより前面の不透明なスクロール領域として表示されることを静的に確認する
|
|
170
184
|
it "keeps fixed navigation above sticky tables with an opaque background" do
|
|
171
185
|
expect(components_source).to include("--admin-page-background: #f6f7f7")
|
|
@@ -216,6 +230,14 @@ RSpec.describe "column resizer assets" do
|
|
|
216
230
|
expect(components_source).not_to include("table-with-fixed-header")
|
|
217
231
|
end
|
|
218
232
|
|
|
233
|
+
# document全体のDOM変更監視と一時切り分け用パラメータが残っていないことを静的に確認する
|
|
234
|
+
it "does not observe document mutations during table initialization" do
|
|
235
|
+
expect(javascript_source).not_to include("new MutationObserver")
|
|
236
|
+
expect(javascript_source).not_to include("mutationObserver.observe(document.documentElement")
|
|
237
|
+
expect(javascript_source).not_to include("admin_column_resizer_disable")
|
|
238
|
+
expect(javascript_source).not_to include("probeFeatureDisabled")
|
|
239
|
+
end
|
|
240
|
+
|
|
219
241
|
# 幅リセット時も固定列のCSS変数を再計算することを静的に確認する
|
|
220
242
|
it "recalculates CSS sticky-left offsets after clearing a column width" do
|
|
221
243
|
expect(javascript_source).to include("clearColumnWidth(columnId, key)")
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
RSpec.describe "copy cell assets" do
|
|
4
|
+
let(:components_source) do
|
|
5
|
+
File.read(File.expand_path("../../../app/assets/stylesheets/yummy_guide_administrate/components.scss", __dir__))
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
# コピー用ボタンとアイコンをCSSで強制的に隠さないことを静的に確認する
|
|
9
|
+
it "does not force-hide the copy cell button or icon" do
|
|
10
|
+
expect(components_source.scan(/\.admin-copy-cell__(?:button|icon)[^{]*\{[^}]*display:\s*none\s*!important/m)).to be_empty
|
|
11
|
+
expect(components_source).to include(".admin-copy-cell__icon {\n display: inline-flex;")
|
|
12
|
+
expect(components_source).to include('mask: image-url("yummy_guide_administrate/icon-copy.svg") center / contain no-repeat;')
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# テーブルセルではホバーやフォーカス時にコピー操作が表示されることを静的に確認する
|
|
16
|
+
it "reveals copy cell controls on hover or focus" do
|
|
17
|
+
expect(components_source).to include("td.cell-data:hover .admin-copy-cell__button:not([disabled])")
|
|
18
|
+
expect(components_source).to include(".admin-copy-cell:focus-within .admin-copy-cell__link")
|
|
19
|
+
expect(components_source).to include(".admin-copy-cell__button:focus-visible")
|
|
20
|
+
expect(components_source).to include("opacity: 1;")
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# 詳細画面ではコピー操作が常時表示される指定を維持することを静的に確認する
|
|
24
|
+
it "keeps attribute copy controls visible" do
|
|
25
|
+
expect(components_source).to match(/\.attribute-data \.admin-copy-cell__link,\s*\.attribute-data \.admin-copy-cell__button:not\(\[disabled\]\) \{\s*opacity: 1;/m)
|
|
26
|
+
end
|
|
27
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: yummy-guide-generic-administrate
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.8.
|
|
4
|
+
version: 0.8.10
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- akatsuki-kk
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-06-
|
|
11
|
+
date: 2026-06-16 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: administrate
|
|
@@ -144,6 +144,7 @@ files:
|
|
|
144
144
|
- spec/yummy_guide/administrate/application_dashboard_spec.rb
|
|
145
145
|
- spec/yummy_guide/administrate/collection_helper_spec.rb
|
|
146
146
|
- spec/yummy_guide/administrate/column_resizer_asset_spec.rb
|
|
147
|
+
- spec/yummy_guide/administrate/copy_cell_asset_spec.rb
|
|
147
148
|
- spec/yummy_guide/administrate/datetime_filter_parameters_spec.rb
|
|
148
149
|
- spec/yummy_guide/administrate/datetime_input_helper_spec.rb
|
|
149
150
|
- spec/yummy_guide/administrate/fields/json_pretty_field_spec.rb
|