|
5 | 5 | <div |
6 | 6 | :class="[ |
7 | 7 | $style.factoripediaLeftPanel, |
8 | | - isMobileViewport && mobilePane === 'entry' && selectedItem ? $style.mobileGridBlocked : null |
| 8 | + isMobileViewport && mobilePane === 'entry' && selectedItem |
| 9 | + ? $style.mobileGridBlocked |
| 10 | + : null |
9 | 11 | ]" |
10 | 12 | @touchstart.passive="onMobileGridTouchStart" |
11 | 13 | @touchmove="onMobileGridTouchMove" |
|
43 | 45 | {{ selectedSciencePacks.length }}/{{ sciencePackOptions.length }} |
44 | 46 | </span> |
45 | 47 | </button> |
46 | | - <label |
47 | | - v-if="!isMobileViewport" |
48 | | - :class="$style.localeLabel" |
49 | | - > |
| 48 | + <label v-if="!isMobileViewport" :class="$style.localeLabel"> |
50 | 49 | <span :class="$style.visuallyHidden">Language</span> |
51 | 50 | <select |
52 | 51 | :class="$style.localeSelect" |
|
67 | 66 | <div :class="$style.headerHelpLinkGroup"> |
68 | 67 | <button |
69 | 68 | type="button" |
70 | | - :class="[$style.headerActionButton, $style.headerIconAction, 'fpio-button-chrome']" |
| 69 | + :class="[ |
| 70 | + $style.headerActionButton, |
| 71 | + $style.headerIconAction, |
| 72 | + 'fpio-button-chrome' |
| 73 | + ]" |
71 | 74 | title="Keyboard shortcuts" |
72 | 75 | aria-label="Keyboard shortcuts" |
73 | 76 | @click="showKeyboardHelp = true; closeSciencePackPanel()" |
|
127 | 130 | <path d="M15 9l-6 6M9 9l6 6" /> |
128 | 131 | </svg> |
129 | 132 | </span> |
130 | | - <span |
131 | | - v-else |
132 | | - :class="$style.headerLinkGlyph" |
133 | | - aria-hidden="true" |
134 | | - > |
| 133 | + <span v-else :class="$style.headerLinkGlyph" aria-hidden="true"> |
135 | 134 | <svg |
136 | 135 | xmlns="http://www.w3.org/2000/svg" |
137 | 136 | viewBox="0 0 24 24" |
|
205 | 204 | :class="$style.searchInput" |
206 | 205 | aria-label="Search recipes" |
207 | 206 | autocomplete="off" |
208 | | - > |
| 207 | + /> |
209 | 208 | </div> |
210 | 209 | </div> |
211 | 210 |
|
212 | 211 | <!-- Recipe Grid --> |
213 | | - <div |
214 | | - ref="gridContainer" |
215 | | - :class="$style.itemGrid" |
216 | | - :style="itemGrid.containerStyles" |
217 | | - > |
218 | | - <template |
219 | | - v-for="subgroup in groupedRecipes" |
220 | | - :key="subgroup.subgroup" |
221 | | - > |
| 212 | + <div ref="gridContainer" :class="$style.itemGrid" :style="itemGrid.containerStyles"> |
| 213 | + <template v-for="subgroup in groupedRecipes" :key="subgroup.subgroup"> |
222 | 214 | <!-- Subgroup wrapper --> |
223 | 215 | <div |
224 | 216 | v-if="subgroup.recipes.length > 0" |
225 | 217 | :class="$style.subgroupGrid" |
226 | 218 | :style="itemGrid.subgroupStyles" |
227 | 219 | > |
228 | | - <template |
229 | | - v-for="item in subgroup.recipes" |
230 | | - :key="item.name" |
231 | | - > |
| 220 | + <template v-for="item in subgroup.recipes" :key="item.name"> |
232 | 221 | <IconButton |
233 | 222 | :type="getPrimaryType(item)" |
234 | 223 | :name="item.name" |
235 | 224 | :size="itemGrid.buttonSize" |
236 | 225 | :is-selected=" |
237 | 226 | selectedItem?.name === item.name && |
238 | | - getPrimaryType(selectedItem) === getPrimaryType(item) |
| 227 | + getPrimaryType(selectedItem) === getPrimaryType(item) |
239 | 228 | " |
240 | 229 | :style="itemGrid.itemStyles" |
241 | 230 | @click="selectItem(getPrimaryType(item), item.name, item)" |
|
267 | 256 | ]" |
268 | 257 | :style="mobileOverlayPanelStyle" |
269 | 258 | :aria-hidden=" |
270 | | - isMobileViewport && !mobileEntryOverlayOpen && !mobileGridOpenSheetVisible ? true : undefined |
| 259 | + isMobileViewport && !mobileEntryOverlayOpen && !mobileGridOpenSheetVisible |
| 260 | + ? true |
| 261 | + : undefined |
271 | 262 | " |
272 | 263 | @touchstart.passive="onMobileOverlayTouchStart" |
273 | 264 | @touchmove="onMobileOverlayTouchMove" |
|
314 | 305 | <li><kbd>Esc</kbd> Clear selection</li> |
315 | 306 | <li><kbd>?</kbd> Toggle this help</li> |
316 | 307 | <li v-if="isMobileViewport"> |
317 | | - Tap an icon to open the entry; drag the panel right to move it with your finger, then release to snap |
318 | | - back or dismiss. A strip of the grid stays visible on the left while the entry is open. When you return |
319 | | - to the grid with an item still selected, drag left on the grid to open the entry again (same peek |
320 | | - as when dismissing). A hint also appears on the right edge of the browse view. |
| 308 | + Tap an icon to open the entry; drag the panel right to move it with your finger, then |
| 309 | + release to snap back or dismiss. A strip of the grid stays visible on the left while the |
| 310 | + entry is open. When you return to the grid with an item still selected, drag left on the |
| 311 | + grid to open the entry again (same peek as when dismissing). A hint also appears on the |
| 312 | + right edge of the browse view. |
321 | 313 | </li> |
322 | 314 | </ul> |
323 | 315 | <p :class="$style.modalHint"> |
|
331 | 323 | </div> |
332 | 324 |
|
333 | 325 | <Teleport to="body"> |
334 | | - <div |
335 | | - v-if="sciencePackPanelOpen" |
336 | | - :class="$style.sciencePackPortal" |
337 | | - > |
| 326 | + <div v-if="sciencePackPanelOpen" :class="$style.sciencePackPortal"> |
338 | 327 | <div |
339 | 328 | :class="$style.sciencePackBackdrop" |
340 | 329 | aria-hidden="true" |
|
385 | 374 | </div> |
386 | 375 | </div> |
387 | 376 | </Teleport> |
388 | | - |
389 | 377 | </div> |
390 | 378 | </template> |
391 | 379 |
|
@@ -568,8 +556,7 @@ const mobileOverlayPanelStyle = computed(() => { |
568 | 556 | const motion = mobileEntryMotionTransition.value |
569 | 557 | const gridSlideOpen = !open && mobileGridOpenSheetVisible.value |
570 | 558 | const transitionNone = |
571 | | - mobileOverlayDragging.value || |
572 | | - (mobileGridOpenDragging.value && !mobileGridOpenSnapCancel.value) |
| 559 | + mobileOverlayDragging.value || (mobileGridOpenDragging.value && !mobileGridOpenSnapCancel.value) |
573 | 560 | const transition = transitionNone ? 'none' : motion |
574 | 561 |
|
575 | 562 | if (!open && !gridSlideOpen) { |
@@ -620,7 +607,9 @@ watch( |
620 | 607 | ) |
621 | 608 |
|
622 | 609 | const selectedSciencePackSet = computed(() => new Set(selectedSciencePacks.value)) |
623 | | -const sciencePackVisibility = computed(() => createSciencePackVisibility(selectedSciencePacks.value)) |
| 610 | +const sciencePackVisibility = computed(() => |
| 611 | + createSciencePackVisibility(selectedSciencePacks.value) |
| 612 | +) |
624 | 613 | const hasActiveScienceFilter = computed(() => selectedSciencePacks.value.length > 0) |
625 | 614 | const itemGrid = computed(() => |
626 | 615 | useFactorioGrid({ |
@@ -785,7 +774,9 @@ function pruneInaccessibleSciencePacks(selectedSet, dependencyMap) { |
785 | 774 | changed = false |
786 | 775 | for (const packName of Array.from(selectedSet)) { |
787 | 776 | const dependencies = dependencyMap?.[packName] || [] |
788 | | - const hasMissingDependency = dependencies.some(dependencyName => !selectedSet.has(dependencyName)) |
| 777 | + const hasMissingDependency = dependencies.some( |
| 778 | + dependencyName => !selectedSet.has(dependencyName) |
| 779 | + ) |
789 | 780 | if (hasMissingDependency) { |
790 | 781 | selectedSet.delete(packName) |
791 | 782 | changed = true |
@@ -826,7 +817,10 @@ function setSciencePacksFromUrlParam(param) { |
826 | 817 | selectedSciencePacks.value = [] |
827 | 818 | return |
828 | 819 | } |
829 | | - const names = param.split(',').map(s => s.trim()).filter(Boolean) |
| 820 | + const names = param |
| 821 | + .split(',') |
| 822 | + .map(s => s.trim()) |
| 823 | + .filter(Boolean) |
830 | 824 | const dependencyMap = sciencePackDependencyMap.value |
831 | 825 | const selected = new Set() |
832 | 826 | const validNames = new Set(sciencePackOptions.value.map(p => p.name)) |
@@ -930,10 +924,7 @@ const firstEnabledCategoryKey = computed(() => { |
930 | 924 |
|
931 | 925 | // Computed property to determine which filters have no items when searching |
932 | 926 | const disabledFilters = computed(() => { |
933 | | - if ( |
934 | | - !categoryStructure.value || |
935 | | - (!searchQuery.value.trim() && !hasActiveScienceFilter.value) |
936 | | - ) { |
| 927 | + if (!categoryStructure.value || (!searchQuery.value.trim() && !hasActiveScienceFilter.value)) { |
937 | 928 | return new Set() |
938 | 929 | } |
939 | 930 |
|
@@ -1341,26 +1332,27 @@ watch(searchQuery, () => { |
1341 | 1332 | }, 350) |
1342 | 1333 | }) |
1343 | 1334 |
|
1344 | | -watch([selectedCategory, selectedSciencePacks, selectedItem], () => { |
1345 | | - if (isApplyingUrl.value) return |
1346 | | - updateURL() |
1347 | | -}, { deep: true }) |
1348 | | -
|
1349 | 1335 | watch( |
1350 | | - sciencePackPanelOpen, |
1351 | | - async open => { |
1352 | | - await nextTick() |
1353 | | - if (open) { |
1354 | | - updateSciencePackPopoverPosition() |
1355 | | - if (sciencePackPositionListenersCleanup) sciencePackPositionListenersCleanup() |
1356 | | - sciencePackPositionListenersCleanup = bindSciencePackPositionListeners() |
1357 | | - } else if (sciencePackPositionListenersCleanup) { |
1358 | | - sciencePackPositionListenersCleanup() |
1359 | | - sciencePackPositionListenersCleanup = null |
1360 | | - } |
1361 | | - } |
| 1336 | + [selectedCategory, selectedSciencePacks, selectedItem], |
| 1337 | + () => { |
| 1338 | + if (isApplyingUrl.value) return |
| 1339 | + updateURL() |
| 1340 | + }, |
| 1341 | + { deep: true } |
1362 | 1342 | ) |
1363 | 1343 |
|
| 1344 | +watch(sciencePackPanelOpen, async open => { |
| 1345 | + await nextTick() |
| 1346 | + if (open) { |
| 1347 | + updateSciencePackPopoverPosition() |
| 1348 | + if (sciencePackPositionListenersCleanup) sciencePackPositionListenersCleanup() |
| 1349 | + sciencePackPositionListenersCleanup = bindSciencePackPositionListeners() |
| 1350 | + } else if (sciencePackPositionListenersCleanup) { |
| 1351 | + sciencePackPositionListenersCleanup() |
| 1352 | + sciencePackPositionListenersCleanup = null |
| 1353 | + } |
| 1354 | +}) |
| 1355 | +
|
1364 | 1356 | // Unified selection functions |
1365 | 1357 | function selectItem(type, name, data = null, options = {}) { |
1366 | 1358 | if (!options.preserveVerticalColumn) { |
@@ -1398,28 +1390,25 @@ watch( |
1398 | 1390 | } |
1399 | 1391 | updateURL() |
1400 | 1392 | } |
1401 | | - }, |
| 1393 | + } |
1402 | 1394 | ) |
1403 | 1395 |
|
1404 | | -watch( |
1405 | | - [disabledFilters, categoryStructure, firstEnabledCategoryKey], |
1406 | | - () => { |
1407 | | - if (!selectedCategory.value || !categoryStructure.value?.[selectedCategory.value]) { |
1408 | | - const firstCategory = firstEnabledCategoryKey.value |
1409 | | - if (firstCategory) { |
1410 | | - selectedCategory.value = firstCategory |
1411 | | - } |
1412 | | - return |
| 1396 | +watch([disabledFilters, categoryStructure, firstEnabledCategoryKey], () => { |
| 1397 | + if (!selectedCategory.value || !categoryStructure.value?.[selectedCategory.value]) { |
| 1398 | + const firstCategory = firstEnabledCategoryKey.value |
| 1399 | + if (firstCategory) { |
| 1400 | + selectedCategory.value = firstCategory |
1413 | 1401 | } |
| 1402 | + return |
| 1403 | + } |
1414 | 1404 |
|
1415 | | - if (disabledFilters.value.has(selectedCategory.value)) { |
1416 | | - const firstEnabled = firstEnabledCategoryKey.value |
1417 | | - if (firstEnabled) { |
1418 | | - selectedCategory.value = firstEnabled |
1419 | | - } |
| 1405 | + if (disabledFilters.value.has(selectedCategory.value)) { |
| 1406 | + const firstEnabled = firstEnabledCategoryKey.value |
| 1407 | + if (firstEnabled) { |
| 1408 | + selectedCategory.value = firstEnabled |
1420 | 1409 | } |
1421 | 1410 | } |
1422 | | -) |
| 1411 | +}) |
1423 | 1412 |
|
1424 | 1413 | function updateMobileViewport() { |
1425 | 1414 | if (typeof window === 'undefined') return |
|
0 commit comments