@datagouv/components-next 1.0.2-dev.194 → 1.0.2-dev.196
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.
- package/dist/{Datafair.client-Drn-ygd-.js → Datafair.client-B5S6jUM0.js} +1 -1
- package/dist/{ImagePreview.client-DCzPQ-xK.js → ImagePreview.client-Bud_7ZAe.js} +1 -1
- package/dist/{JsonPreview.client-Dqioe7mC.js → JsonPreview.client-CcbiaqLn.js} +2 -2
- package/dist/{MapContainer.client-CV5ZRvvr.js → MapContainer.client-BuEqCYhG.js} +2 -2
- package/dist/{PdfPreview.client-XFmjFK8r.js → PdfPreview.client-BkmqtPwL.js} +2 -2
- package/dist/{Pmtiles.client-DAp930rV.js → Pmtiles.client-2ekE6L4s.js} +1 -1
- package/dist/{PreviewWrapper.vue_vue_type_script_setup_true_lang-BkPS3zke.js → PreviewWrapper.vue_vue_type_script_setup_true_lang-6SP7VFio.js} +1 -1
- package/dist/{XmlPreview.client-zetBGS4F.js → XmlPreview.client-CoMSGllV.js} +3 -3
- package/dist/components-next.js +1 -1
- package/dist/{index-DWuJwKzS.js → index-DxELxzUW.js} +1 -1
- package/dist/{leaflet-src-DiG78UoJ.js → leaflet-src-K9O-7m9Z.js} +1 -1
- package/dist/{main-dOC1WJIR.js → main-B03fYwPN.js} +7797 -7794
- package/dist/{vue3-xml-viewer.common-D1KbuT3v.js → vue3-xml-viewer.common-BEL6n95l.js} +1 -1
- package/package.json +1 -1
- package/src/components/LoadingBlock.vue +4 -1
- package/src/components/Pagination.vue +2 -4
- package/src/components/Search/GlobalSearch.vue +9 -6
- package/src/functions/scroll.ts +20 -0
package/package.json
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="relative">
|
|
3
3
|
<div :class="{ 'opacity-50 min-h-64': loading }">
|
|
4
|
+
<!-- Keep the previous content while reloading, dimmed under the loader:
|
|
5
|
+
dropping it collapses the page height, which makes the browser clamp
|
|
6
|
+
the scroll and throws the reader back to the top. -->
|
|
4
7
|
<slot
|
|
5
|
-
v-if="!
|
|
8
|
+
v-if="!hasError && data"
|
|
6
9
|
:data="data"
|
|
7
10
|
/>
|
|
8
11
|
<slot
|
|
@@ -104,6 +104,7 @@ import { computed, useTemplateRef } from 'vue'
|
|
|
104
104
|
import { useRoute } from 'vue-router'
|
|
105
105
|
import { useTranslation } from '../composables/useTranslation'
|
|
106
106
|
import { clampPage, getVisiblePages } from '../functions/paginate'
|
|
107
|
+
import { scrollToBlockTop } from '../functions/scroll'
|
|
107
108
|
|
|
108
109
|
type Props = {
|
|
109
110
|
/**
|
|
@@ -141,10 +142,7 @@ const nav = useTemplateRef('navRef')
|
|
|
141
142
|
function change(index: number) {
|
|
142
143
|
emit('change', index)
|
|
143
144
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
nav.value.parentElement.style.scrollMarginTop = '100px'
|
|
147
|
-
nav.value.parentElement.scrollIntoView({ behavior: 'smooth', block: 'start' })
|
|
145
|
+
scrollToBlockTop(nav.value?.parentElement)
|
|
148
146
|
}
|
|
149
147
|
|
|
150
148
|
function onClick(index: number) {
|
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
>
|
|
7
7
|
<div
|
|
8
8
|
v-if="!hideSearchInput"
|
|
9
|
-
ref="search"
|
|
10
9
|
class="flex flex-wrap items-center justify-between"
|
|
11
10
|
data-cy="search"
|
|
12
11
|
>
|
|
@@ -357,6 +356,7 @@
|
|
|
357
356
|
<script setup lang="ts">
|
|
358
357
|
import { computed, provide, shallowReactive, useSlots, watch, useTemplateRef, type Component, type Ref } from 'vue'
|
|
359
358
|
import { useRouteQuery } from '@vueuse/router'
|
|
359
|
+
import { useRoute } from 'vue-router'
|
|
360
360
|
import { RiBookShelfLine, RiBuilding2Line, RiCloseCircleLine, RiDatabase2Line, RiLightbulbLine, RiLineChartLine, RiRssLine, RiTerminalLine } from '@remixicon/vue'
|
|
361
361
|
import magnifyingGlassSrc from '../../../assets/illustrations/magnifying_glass.svg?url'
|
|
362
362
|
import { useTranslation } from '../../composables/useTranslation'
|
|
@@ -365,6 +365,7 @@ import { configKey, forEachActiveCustomFilter, isCustomFilterActive, searchFilte
|
|
|
365
365
|
import { useStableQueryParams } from '../../composables/useStableQueryParams'
|
|
366
366
|
import { useComponentsConfig } from '../../config'
|
|
367
367
|
import { useFetch } from '../../functions/api'
|
|
368
|
+
import { scrollToBlockTop } from '../../functions/scroll'
|
|
368
369
|
import type { AsyncDataRequestStatus } from '../../functions/api.types'
|
|
369
370
|
import type { Dataset } from '../../types/datasets'
|
|
370
371
|
import type { Dataservice } from '../../types/dataservices'
|
|
@@ -423,6 +424,7 @@ if (!currentType.value) currentType.value = configKey(props.config[0] ?? { class
|
|
|
423
424
|
|
|
424
425
|
const { t } = useTranslation()
|
|
425
426
|
const componentsConfig = useComponentsConfig()
|
|
427
|
+
const route = useRoute()
|
|
426
428
|
|
|
427
429
|
// Custom filter registry for useSearchFilter composable
|
|
428
430
|
const customFilterRegistry = shallowReactive(new Map<string, CustomFilterEntry>())
|
|
@@ -797,14 +799,15 @@ function getFacets(key: string): FacetItem[] | undefined {
|
|
|
797
799
|
}
|
|
798
800
|
|
|
799
801
|
// Scroll handling
|
|
800
|
-
const
|
|
802
|
+
const resultsRef = useTemplateRef('results')
|
|
801
803
|
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
804
|
+
// Every criteria lives in the URL, custom filters included, so watching the
|
|
805
|
+
// query covers them all: whenever the result list is replaced, bring its top
|
|
806
|
+
// back into view rather than leaving the reader in the middle of a list they
|
|
807
|
+
// have not seen yet.
|
|
808
|
+
watch(() => route.query, () => scrollToBlockTop(resultsRef.value))
|
|
805
809
|
|
|
806
810
|
function changePage(newPage: number) {
|
|
807
811
|
page.value = newPage
|
|
808
|
-
scrollToTop()
|
|
809
812
|
}
|
|
810
813
|
</script>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// Leaves room for the sticky elements sitting at the top of the viewport.
|
|
2
|
+
const SCROLL_MARGIN = 100
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Bring the top of a block back into view after its content changed (paging,
|
|
6
|
+
* searching, filtering), so the reader restarts at the first result.
|
|
7
|
+
*
|
|
8
|
+
* Does nothing when the top of the block is already on screen: aligning the
|
|
9
|
+
* viewport on a block the reader is already looking at moves the page under
|
|
10
|
+
* them for no reason.
|
|
11
|
+
*/
|
|
12
|
+
export function scrollToBlockTop(block: HTMLElement | null | undefined) {
|
|
13
|
+
if (!block) return
|
|
14
|
+
|
|
15
|
+
const { top } = block.getBoundingClientRect()
|
|
16
|
+
if (top >= 0 && top <= window.innerHeight) return
|
|
17
|
+
|
|
18
|
+
block.style.scrollMarginTop = `${SCROLL_MARGIN}px`
|
|
19
|
+
block.scrollIntoView({ behavior: 'smooth', block: 'start' })
|
|
20
|
+
}
|