Skip to content

Commit

Permalink
feat: dropdown responsive
Browse files Browse the repository at this point in the history
Signed-off-by: Maud Royer <hello@maudroyer.fr>
  • Loading branch information
jillro committed Apr 8, 2024
1 parent 921217b commit e462118
Show file tree
Hide file tree
Showing 6 changed files with 187 additions and 84 deletions.
149 changes: 129 additions & 20 deletions src/components/ActionDropdown.vue
Original file line number Diff line number Diff line change
@@ -1,51 +1,160 @@
<script setup>
import { ref } from "vue"
import { onClickOutside } from "@vueuse/core"
import { onUpdated, ref, watch } from "vue"
import { onClickOutside, useSwipe } from "@vueuse/core"
import { useHead } from "@unhead/vue"
const show = ref(false)
const fadeIn = ref(false)
const actionsMenuRef = ref(null)
const props = defineProps({
withIcons: {
type: Boolean,
default: false
}
})
onUpdated(() => {
setTimeout(() => {
fadeIn.value = show.value
}, 1)
})
const down = ref('16px')
const { direction, lengthY } = useSwipe(
actionsMenuRef,
{
onSwipe: () => {
if (direction.value === 'DOWN' && lengthY.value < 0) {
down.value = (16 + lengthY.value) + 'px'
} else {
down.value = '16px'
}
console.log(down.value)
},
onSwipeEnd: () => {
if (lengthY.value < -30) {
show.value = false
down.value = '16px'
}
}
}
)
onClickOutside(actionsMenuRef, () => {
show.value = false
})
watch(show, (value) => {
if (value && !window.matchMedia('(min-width: 580px)').matches) {
useHead({ htmlAttrs: {
'data-fr-scrolling': true,
tagDuplicateStrategy: 'replace'
}
})
} else {
useHead({
htmlAttrs: {
'data-fr-scrolling': null,
tagDuplicateStrategy: 'replace'
}
})
}
})
</script>

<template>
<button type="button" @click.stop.prevent="show = !show" class="fr-btn fr-btn--tertiary-no-outline fr-icon-more-fill show-actions">
Autres actions
</button>
<div class="menu-container">
<div v-if="show" class="fr-menu" ref="actionsMenuRef">
<ul class="fr-menu__list fr-btns-group fr-btns-group--icon-left">
<li>
<slot/>
</li>
</ul>
</div>
<div class="menu-anchor">
<slot name="trigger" :toggle="() => show =! show">
<button type="button" @click.stop.prevent="show = !show" class="fr-btn fr-btn--tertiary-no-outline fr-icon-more-fill show-actions">
Autres actions
</button>
</slot>
<dialog class="menu-container" :open="show">
<div class="fr-menu" :class="{ '--fade-in': fadeIn }" ref="actionsMenuRef" :style="{ '--down': down }">
<ul class="fr-menu__list fr-btns-group fr-btns-group--equisized" :class="{ 'fr-btns-group--icon-left': props.withIcons }">
<slot/>
</ul>
</div>
</dialog>
</div>
</template>

<style scoped>
.menu-container {
.menu-anchor {
position: relative;
display: inline-block;
white-space: initial;
display: inline-flex;
flex-direction: row;
align-items: flex-end;
}
.menu-container {
display: none;
background: transparent;
}
.menu-container[open] {
position: fixed;
top: 0;
left: 0;
height: 100vh;
width: 100vw;
border: none;
z-index: var(--z-index-dropdown);
background: var(--grey-50-1000-a375, rgba(22, 22, 22, 0.64));
transition: background 0.3s;
display: block;
@media (min-width: 580px) {
background: transparent;
margin: 0;
width: 0;
position: relative;
padding: 0;
height: auto;
}
}
.fr-menu {
position: absolute;
right: 100%;
top: -100%;
bottom: -10rem;
transition: bottom 0.3s;
right: 1rem;
left: 1rem;
margin: 0;
padding: 0;
border-radius: 0.3125rem;
filter: drop-shadow(var(--overlap-shadow));
&.--fade-in {
bottom: v-bind(down);
}
@media (min-width: 580px) {
z-index: 1000;
left: auto;
top: 0;
right: 0;
height: auto;
bottom: auto;
&.--fade-in {
bottom: auto;
}
}
:deep(.fr-menu__list) {
border-radius: 0.3125rem;
margin: 0;
width: auto;
padding: 0;
background-color: var(--background-overlap-grey);
--hover: var(--background-overlap-grey-hover);
--active: var(--background-overlap-grey-active);
box-shadow: inset 0 1px 0 0 var(--border-open-blue-france);
}
:deep(.fr-btn) {
font-weight: 700;
justify-content: flex-start;
margin: 0;
padding: 0.75rem !important;
width: 100%;
Expand Down
22 changes: 14 additions & 8 deletions src/components/Features/FeatureGroup.vue
Original file line number Diff line number Diff line change
Expand Up @@ -87,16 +87,22 @@
<td class="actions">
<button type="button" class="fr-hidden fr-unhidden-sm fr-unhidden-md fr-unhidden-lg fr-unhidden-xl" :class="{'fr-btn': true, 'fr-btn--tertiary-no-outline': true, 'fr-icon-edit-line': true }" @click="toggleEditForm(feature.id)" aria-label="Modifier" />
<ActionDropdown>
<router-link v-if="permissions.canChangeGeometry" :to="`/exploitations/${operatorStore.operator.numeroBio}/${recordStore.record.record_id}/modifier/${feature.id}`" type="button" class="fr-btn fr-btn--tertiary-no-outline fr-icon-geometry fr-text--sm">
<ActionDropdown with-icons>
<li v-if="permissions.canChangeGeometry">
<router-link :to="`/exploitations/${operatorStore.operator.numeroBio}/${recordStore.record.record_id}/modifier/${feature.id}`" type="button" class="fr-btn fr-btn--tertiary-no-outline fr-icon-geometry fr-text--sm">
Modifier le contour
</router-link>
<button v-else type="button" disabled class="fr-btn fr-btn--tertiary-no-outline fr-icon-geometry fr-text--sm">
Modifier le contour
</button>
<button type="button" @click.prevent="toggleDeleteForm(feature.id)" :disabled="!permissions.canDeleteFeature" class="fr-btn fr-btn--tertiary-no-outline fr-icon-delete-line btn--error fr-text--sm">
Supprimer la parcelle
</button>
</li>
<li v-else>
<button type="button" disabled class="fr-btn fr-btn--tertiary-no-outline fr-icon-geometry fr-text--sm">
Modifier le contour
</button>
</li>
<li>
<button type="button" @click.prevent="toggleDeleteForm(feature.id)" :disabled="!permissions.canDeleteFeature" class="fr-btn fr-btn--tertiary-no-outline fr-icon-delete-line btn--error fr-text--sm">
Supprimer la parcelle
</button>
</li>
</ActionDropdown>
</td>
</tr>
Expand Down
62 changes: 22 additions & 40 deletions src/components/Features/MassActionsSelector.vue
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
<template>
<nav ref="openerElement" role="navigation" class="fr-translate fr-nav" data-fr-js-navigation="true">
<div class="fr-nav__item" data-fr-js-navigation-item="true">
<button type="button" class="fr-btn fr-btn--sm fr-btn--secondary fr-btn--icon-right fr-icon-arrow-down-s-line menu-button" aria-controls="mass-actions__actions" :aria-expanded="isMenuOpen" @click="(isMenuOpen = !isMenuOpen)" data-fr-js-collapse-button="true">
<ActionDropdown>
<template #trigger="{ toggle }">
<button class="fr-btn fr-btn--sm fr-btn--secondary fr-btn--icon-right fr-icon-arrow-down-s-line menu-button" @click="toggle">
{{ label }}
</button>
<div :class="['fr-collapse', 'fr-translate__menu', 'fr-menu', isMenuOpen && 'fr-collapse--expanded']" id="mass-actions__actions" data-fr-js-collapse="true" style="--collapse-max-height: none; --collapse: -148px">
<ul class="fr-menu__list">
<li class="w-full" v-for="({ label, component }) in actions" :key="label">
<button class="fr-btn fr-btn--tertiary-no-outline w-full" type="button" @click="openModalWithComponent(component)">
{{ label }}
</button>
</li>
</ul>
</div>
</div>
</nav>
</template>
<li v-for="({ label, component }) in actions" :key="label">
<button
class="fr-btn fr-text--sm fr-btn--sm fr-btn--tertiary-no-outline"
@click="openModalWithComponent(component)"
>
{{ label }}
</button>
</li>
</ActionDropdown>

<Teleport to="body">
<Component :is="modalComponent" v-if="(modalComponent && isModalOpen)" @close="isModalOpen = false" @submit="handleSubmit" />
Expand All @@ -24,6 +23,7 @@
<script setup>
import { ref } from 'vue'
import { onClickOutside } from '@vueuse/core'
import ActionDropdown from "@/components/ActionDropdown.vue"
defineProps({
label: {
Expand Down Expand Up @@ -58,32 +58,14 @@ function handleSubmit ({ ids, patch }) {
</script>

<style scoped>
.fr-translate.fr-nav {
text-align: right;
}
.fr-nav__item {
display: inline-flex;
position: relative;
.menu-button {
border: 1px solid #fff;
background-color: #fff;
margin-bottom: 0;
box-shadow: none;
}
.fr-translate__menu {
position: absolute;
left: 0;
top: calc(100%);
min-width: 25em;
text-align: left;
}
.fr-translate .menu-button {
border: 1px solid #fff;
background-color: #fff;
margin-bottom: 0;
box-shadow: none;
}
.fr-translate .menu-button::before {
content: none;
}
.fr-menu__list .fr-btn {
width: 100%;
}
li .fr-btn {
min-width: 250px;
}
</style>
2 changes: 1 addition & 1 deletion src/components/record/Table.vue
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ async function performAsyncRecordAction (promise, text = 'Modification enregistr
background-color: var(--background-action-high-blue-france);
position: sticky;
top: 0;
z-index: var(--z-index-mass-actions);
z-index: var(--z-index-dropdown);
}
.fr-table .summary.summary__mass-actions .fr-checkbox-group input[type="checkbox"]:checked + label::before{
Expand Down
34 changes: 20 additions & 14 deletions src/pages/exploitations/[numeroBio]/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -115,20 +115,26 @@ meta:
Du {{ dateFormat(record.certification_date_debut) }} au {{ dateFormat(record.certification_date_fin) }}</span>
</td>
<td>
<ActionDropdown>
<button type="button" @click.stop.prevent="editVersionModal = record.record_id" class="fr-btn fr-btn--tertiary-no-outline fr-icon-edit-line fr-text--sm">
Modifier les informations
</button>
<button
type="button"
@click.stop.prevent="duplicateVersion(record.record_id)"
class="fr-btn fr-btn--tertiary-no-outline fr-icon-duplicate fr-text--sm"
>
Dupliquer la version
</button>
<button type="button" @click.stop.prevent="deleteRecordModal = record.record_id" class="fr-btn fr-btn--tertiary-no-outline fr-icon-delete-line btn--error fr-text--sm">
Supprimer la version
</button>
<ActionDropdown with-icons>
<li>
<button type="button" @click.stop.prevent="editVersionModal = record.record_id" class="fr-btn fr-btn--tertiary-no-outline fr-icon-edit-line fr-text--sm">
Modifier les informations
</button>
</li>
<li>
<button
type="button"
@click.stop.prevent="duplicateVersion(record.record_id)"
class="fr-btn fr-btn--tertiary-no-outline fr-icon-duplicate fr-text--sm"
>
Dupliquer la version
</button>
</li>
<li>
<button type="button" @click.stop.prevent="deleteRecordModal = record.record_id" class="fr-btn fr-btn--tertiary-no-outline fr-icon-delete-line btn--error fr-text--sm">
Supprimer la version
</button>
</li>
</ActionDropdown>
</td>
</tr>
Expand Down
2 changes: 1 addition & 1 deletion src/styles/variables.css
Original file line number Diff line number Diff line change
Expand Up @@ -809,7 +809,7 @@

:root {
--z-index-map: calc(var(--ground) + 10);
--z-index-mass-actions: calc(var(--ground) + 50);
--z-index-dropdown: calc(var(--ground) + 50);
--z-index-map-large: calc(var(--ground) + 100);
}

Expand Down

0 comments on commit e462118

Please sign in to comment.