Toggle favorite working
This commit is contained in:
parent
5e3f4ec621
commit
4ea2871c6d
13 changed files with 300 additions and 169 deletions
|
|
@ -1,3 +1,11 @@
|
||||||
|
Alt:
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
Favoriteforusers:
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
Description:
|
Description:
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,11 @@
|
||||||
|
Alt:
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
Favoriteforusers: - user://WWjXgPWk
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
Favoriteforclients:
|
Favoriteforclients:
|
||||||
|
|
||||||
- page://G418qZ4ABsoWFx4i
|
- page://G418qZ4ABsoWFx4i
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,11 @@ accept:
|
||||||
type: image
|
type: image
|
||||||
|
|
||||||
fields:
|
fields:
|
||||||
|
alt:
|
||||||
|
label: Texte alternatif
|
||||||
|
type: text
|
||||||
favoriteForUsers:
|
favoriteForUsers:
|
||||||
label: |
|
label: |
|
||||||
Dans les favoris des utilisateurs :
|
Dans les favoris des utilisateurs :
|
||||||
type: users
|
type: users
|
||||||
|
disabled: true
|
||||||
|
|
|
||||||
|
|
@ -16,89 +16,10 @@ return [
|
||||||
'language' => 'fr',
|
'language' => 'fr',
|
||||||
'css' => 'assets/css/panel.css',
|
'css' => 'assets/css/panel.css',
|
||||||
'favicon' => 'assets/favicons/favicon.svg',
|
'favicon' => 'assets/favicons/favicon.svg',
|
||||||
'menu' => [
|
'menu' => require(__DIR__ . '/menu.php'),
|
||||||
'site' => [
|
|
||||||
'label' => 'Dashboard',
|
|
||||||
'icon' => 'dashboard',
|
|
||||||
'current' => function (string $current): bool {
|
|
||||||
// the links of all your custom menu entries
|
|
||||||
$links = [
|
|
||||||
'pages/clients',
|
|
||||||
'pages/projects',
|
|
||||||
'pages/inspirations',
|
|
||||||
'pages/notifications',
|
|
||||||
'pages/events'
|
|
||||||
];
|
|
||||||
$path = Kirby\Cms\App::instance()->path();
|
|
||||||
return
|
|
||||||
$current === 'site' &&
|
|
||||||
A::every($links, fn ($link) => Str::contains($path, $link) === false);
|
|
||||||
}
|
|
||||||
],
|
|
||||||
'clients' => [
|
|
||||||
'label' => 'Clients',
|
|
||||||
'icon' => 'account',
|
|
||||||
'link' => 'pages/clients',
|
|
||||||
'current' => function (string $current): bool {
|
|
||||||
$path = Kirby\Cms\App::instance()->path();
|
|
||||||
return Str::contains($path, 'pages/clients');
|
|
||||||
}
|
|
||||||
],
|
|
||||||
'projects' => [
|
|
||||||
'label' => 'Projets',
|
|
||||||
'icon' => 'folder',
|
|
||||||
'link' => 'pages/projects',
|
|
||||||
'current' => function (string $current): bool {
|
|
||||||
$path = Kirby\Cms\App::instance()->path();
|
|
||||||
return Str::contains($path, 'pages/projects');
|
|
||||||
}
|
|
||||||
],
|
|
||||||
'inspirations' => [
|
|
||||||
'label' => 'Inspirations',
|
|
||||||
'icon' => 'images',
|
|
||||||
'link' => 'pages/inspirations',
|
|
||||||
'current' => function (string $current): bool {
|
|
||||||
$path = Kirby\Cms\App::instance()->path();
|
|
||||||
return Str::contains($path, 'pages/inspirations');
|
|
||||||
}
|
|
||||||
],
|
|
||||||
'-',
|
|
||||||
'notifications' => [
|
|
||||||
'label' => 'Notifications',
|
|
||||||
'icon' => 'bell',
|
|
||||||
'link' => 'pages/notifications',
|
|
||||||
'current' => function (string $current): bool {
|
|
||||||
$path = Kirby\Cms\App::instance()->path();
|
|
||||||
return Str::contains($path, 'pages/notifications');
|
|
||||||
}
|
|
||||||
],
|
|
||||||
'events' => [
|
|
||||||
'label' => 'Événements',
|
|
||||||
'icon' => 'calendar',
|
|
||||||
'link' => 'pages/events',
|
|
||||||
'current' => function (string $current): bool {
|
|
||||||
$path = Kirby\Cms\App::instance()->path();
|
|
||||||
return Str::contains($path, 'pages/events');
|
|
||||||
}
|
|
||||||
],
|
|
||||||
'-',
|
|
||||||
'users',
|
|
||||||
'system'
|
|
||||||
]
|
|
||||||
],
|
],
|
||||||
'routes' => [
|
'routes' => [
|
||||||
[
|
require(__DIR__ . '/routes/logout.php'),
|
||||||
'pattern' => '(:all)logout.php',
|
require(__DIR__ . '/routes/toggle-favorite.php'),
|
||||||
'action' => function () {
|
|
||||||
$kirby = kirby();
|
|
||||||
$user = $kirby->user();
|
|
||||||
$user->logout();
|
|
||||||
session_start();
|
|
||||||
|
|
||||||
go($_SESSION['redirect_url']);
|
|
||||||
|
|
||||||
return '<html><body>logout</body></html>';
|
|
||||||
}
|
|
||||||
]
|
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
|
||||||
71
public/site/config/menu.php
Normal file
71
public/site/config/menu.php
Normal file
|
|
@ -0,0 +1,71 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
'site' => [
|
||||||
|
'label' => 'Dashboard',
|
||||||
|
'icon' => 'dashboard',
|
||||||
|
'current' => function (string $current): bool {
|
||||||
|
// the links of all your custom menu entries
|
||||||
|
$links = [
|
||||||
|
'pages/clients',
|
||||||
|
'pages/projects',
|
||||||
|
'pages/inspirations',
|
||||||
|
'pages/notifications',
|
||||||
|
'pages/events'
|
||||||
|
];
|
||||||
|
$path = Kirby\Cms\App::instance()->path();
|
||||||
|
return
|
||||||
|
$current === 'site' &&
|
||||||
|
A::every($links, fn ($link) => Str::contains($path, $link) === false);
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'clients' => [
|
||||||
|
'label' => 'Clients',
|
||||||
|
'icon' => 'account',
|
||||||
|
'link' => 'pages/clients',
|
||||||
|
'current' => function (string $current): bool {
|
||||||
|
$path = Kirby\Cms\App::instance()->path();
|
||||||
|
return Str::contains($path, 'pages/clients');
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'projects' => [
|
||||||
|
'label' => 'Projets',
|
||||||
|
'icon' => 'folder',
|
||||||
|
'link' => 'pages/projects',
|
||||||
|
'current' => function (string $current): bool {
|
||||||
|
$path = Kirby\Cms\App::instance()->path();
|
||||||
|
return Str::contains($path, 'pages/projects');
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'inspirations' => [
|
||||||
|
'label' => 'Inspirations',
|
||||||
|
'icon' => 'images',
|
||||||
|
'link' => 'pages/inspirations',
|
||||||
|
'current' => function (string $current): bool {
|
||||||
|
$path = Kirby\Cms\App::instance()->path();
|
||||||
|
return Str::contains($path, 'pages/inspirations');
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'-',
|
||||||
|
'notifications' => [
|
||||||
|
'label' => 'Notifications',
|
||||||
|
'icon' => 'bell',
|
||||||
|
'link' => 'pages/notifications',
|
||||||
|
'current' => function (string $current): bool {
|
||||||
|
$path = Kirby\Cms\App::instance()->path();
|
||||||
|
return Str::contains($path, 'pages/notifications');
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'events' => [
|
||||||
|
'label' => 'Événements',
|
||||||
|
'icon' => 'calendar',
|
||||||
|
'link' => 'pages/events',
|
||||||
|
'current' => function (string $current): bool {
|
||||||
|
$path = Kirby\Cms\App::instance()->path();
|
||||||
|
return Str::contains($path, 'pages/events');
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'-',
|
||||||
|
'users',
|
||||||
|
'system'
|
||||||
|
];
|
||||||
13
public/site/config/routes/logout.php
Normal file
13
public/site/config/routes/logout.php
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
'pattern' => '(:all)logout.php',
|
||||||
|
'action' => function () {
|
||||||
|
$kirby = kirby();
|
||||||
|
$user = $kirby->user();
|
||||||
|
$user->logout();
|
||||||
|
session_start();
|
||||||
|
|
||||||
|
go(site()->url());
|
||||||
|
}
|
||||||
|
];
|
||||||
33
public/site/config/routes/toggle-favorite.php
Normal file
33
public/site/config/routes/toggle-favorite.php
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
'pattern' => '(:all)toggle-favorite.json',
|
||||||
|
'method' => 'post',
|
||||||
|
'action' => function () {
|
||||||
|
$json = file_get_contents('php://input');
|
||||||
|
$data = json_decode($json);
|
||||||
|
|
||||||
|
$fileName = $data->fileName;
|
||||||
|
|
||||||
|
$page = page($data->inspirationUri);
|
||||||
|
$file = $page->files()->find($fileName);
|
||||||
|
|
||||||
|
$user = Find::user($data->userUuid);
|
||||||
|
$favoriteForUsers = $file->favoriteForUsers()->toUsers();
|
||||||
|
|
||||||
|
if ($favoriteForUsers->has($user)) {
|
||||||
|
$favoriteForUsers->remove($user);
|
||||||
|
} else {
|
||||||
|
$favoriteForUsers->add($user);
|
||||||
|
}
|
||||||
|
|
||||||
|
$array = $favoriteForUsers->toArray();
|
||||||
|
$yaml = Data::encode($array, 'yaml');
|
||||||
|
|
||||||
|
$file->update([
|
||||||
|
'favoriteForUsers' => $yaml
|
||||||
|
]);
|
||||||
|
|
||||||
|
return $favoriteForUsers->toJson();
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
<script>
|
<script>
|
||||||
|
<?php if ($kirby->user()): ?>
|
||||||
const kirbyData = {
|
const kirbyData = {
|
||||||
user: {
|
user: {
|
||||||
role: '<?= $kirby->user()->role() ?>',
|
role: '<?= $kirby->user()->role() ?>',
|
||||||
|
uuid: '<?= $kirby->user()->uuid() ?>',
|
||||||
<?php if ($kirby->user()->role() == 'client'): ?>
|
<?php if ($kirby->user()->role() == 'client'): ?>
|
||||||
client: {
|
client: {
|
||||||
name: '<?= $kirby->user()->client()->toPage()->title() ?>',
|
name: '<?= $kirby->user()->client()->toPage()->title() ?>',
|
||||||
|
|
@ -10,6 +12,7 @@
|
||||||
<?php endif ?>
|
<?php endif ?>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
<?php endif ?>
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
@ -1,3 +1,9 @@
|
||||||
<?php snippet('header') ?>
|
<?php snippet('header') ?>
|
||||||
<div id="app"></div>
|
<?php
|
||||||
|
if ($kirby->user()) {
|
||||||
|
echo '<div id="app"></div>';
|
||||||
|
} else {
|
||||||
|
go($site->panel()->url());
|
||||||
|
}
|
||||||
|
?>
|
||||||
<?php snippet('footer') ?>
|
<?php snippet('footer') ?>
|
||||||
|
|
@ -7,12 +7,16 @@ $inspirations = $page->children()->map(function ($child) {
|
||||||
'new' => $child->new()->value() === "true" ? true : false,
|
'new' => $child->new()->value() === "true" ? true : false,
|
||||||
'date' => $child->date()->toDate('Y-MM-d'),
|
'date' => $child->date()->toDate('Y-MM-d'),
|
||||||
'url' => $child->url(),
|
'url' => $child->url(),
|
||||||
|
'uri' => $child->uri(),
|
||||||
'modified' => $child->modified('Y-MM-d'),
|
'modified' => $child->modified('Y-MM-d'),
|
||||||
'status' => $child->status(),
|
'status' => $child->status(),
|
||||||
'cover' => $child->cover()->toFile()->url(),
|
'cover' => $child->cover()->toFile()->url(),
|
||||||
'media' => $child->media()->toFiles()->map(function ($file) {
|
'media' => $child->media()->toFiles()->map(function ($file) {
|
||||||
return [
|
return [
|
||||||
'url' => $file->url()
|
'url' => $file->url(),
|
||||||
|
'ald' => $file->alt()->value(),
|
||||||
|
'favoriteForUsers' => $file->favoriteForUsers()->value(),
|
||||||
|
'name' => $file->filename()
|
||||||
];
|
];
|
||||||
})->values()
|
})->values()
|
||||||
];
|
];
|
||||||
|
|
|
||||||
114
src/components/inspirations/Image.vue
Normal file
114
src/components/inspirations/Image.vue
Normal file
|
|
@ -0,0 +1,114 @@
|
||||||
|
<template>
|
||||||
|
<figure class="flex" :style="'--rows: ' + (index % 2 ? 2 : 3)">
|
||||||
|
<button
|
||||||
|
class="favorite"
|
||||||
|
aria-label="Ajouter aux favoris"
|
||||||
|
:aria-pressed="isFavorite"
|
||||||
|
@click="isFavorite = !isFavorite"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
width="40"
|
||||||
|
height="40"
|
||||||
|
viewBox="0 0 40 40"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M5.49289 22.5821C5.50453 22.5937 5.51646 22.6051 5.52866 22.6161L19.3287 35.1161C19.7097 35.4613 20.2903 35.4613 20.6713 35.1161L34.4713 22.6161C34.4835 22.6051 34.4955 22.5937 34.5071 22.5821C38.7044 18.3848 37.6545 12.2706 34.2529 8.87931C32.5281 7.15976 30.1519 6.07621 27.4679 6.26656C25.0319 6.43932 22.4673 7.65151 20 10.1579C17.5321 7.65095 14.9651 6.43633 12.5266 6.25964C9.83985 6.06497 7.45863 7.14246 5.72977 8.85914C2.3178 12.247 1.27257 18.3618 5.49289 22.5821Z"
|
||||||
|
fill="currentColor"
|
||||||
|
stroke="white"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
<img :src="item.url" :alt="item.alt" :data-id="item.id" />
|
||||||
|
</figure>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import { ref, watch } from "vue";
|
||||||
|
import { useUserStore } from "../../stores/user";
|
||||||
|
import { useApiStore } from "../../stores/api";
|
||||||
|
|
||||||
|
const { item, inspirationUri } = defineProps({
|
||||||
|
item: Object,
|
||||||
|
inspirationUri: String,
|
||||||
|
});
|
||||||
|
|
||||||
|
const toggleFavoriteRoute = "/toggle-favorite.json";
|
||||||
|
const api = useApiStore();
|
||||||
|
const { user } = useUserStore();
|
||||||
|
const isFavorite = ref(item.favoriteForUsers?.includes(user.uuid) ?? false);
|
||||||
|
|
||||||
|
watch(isFavorite, (value) => {
|
||||||
|
const data = {
|
||||||
|
fileName: item.name,
|
||||||
|
userUuid: user.uuid,
|
||||||
|
inspirationUri,
|
||||||
|
};
|
||||||
|
api
|
||||||
|
.fetchRoute(toggleFavoriteRoute, "POST", data)
|
||||||
|
.then((res) =>
|
||||||
|
console.log("Image dans les favoris des utilisateurs : ", res)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<style scoped>
|
||||||
|
figure {
|
||||||
|
position: relative;
|
||||||
|
grid-row: span var(--rows);
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
margin: 0;
|
||||||
|
border-radius: var(--rounded-2xl);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
figure:hover::after {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
background: var(--color-black-20);
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
figure:hover .favorite {
|
||||||
|
display: initial;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Favorite button */
|
||||||
|
.favorite {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
width: 3.5rem;
|
||||||
|
height: 3.5rem;
|
||||||
|
margin: var(--space-8);
|
||||||
|
padding: var(--space-8);
|
||||||
|
color: var(--color-grey-400);
|
||||||
|
display: none;
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
.favorite[aria-pressed="false"]:hover::before {
|
||||||
|
content: "Ajouter dans mes favoris";
|
||||||
|
background: var(--color-background);
|
||||||
|
padding: 1.3rem 3.5rem 1.25rem 1rem;
|
||||||
|
position: absolute;
|
||||||
|
z-index: -1;
|
||||||
|
inset: -2px;
|
||||||
|
left: unset;
|
||||||
|
width: max-content;
|
||||||
|
border-radius: var(--rounded-xl);
|
||||||
|
color: var(--color-grey-700);
|
||||||
|
letter-spacing: var(--tracking-wide);
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: var(--text-sm);
|
||||||
|
}
|
||||||
|
.favorite[aria-pressed="true"] {
|
||||||
|
color: var(--color-brand);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -97,5 +97,28 @@ export const useApiStore = defineStore("api", () => {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return { fetchDataThroughKQL, fetchPageData };
|
async function fetchRoute(path, method, data) {
|
||||||
|
const config = {
|
||||||
|
method: method,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (data) {
|
||||||
|
config.body = JSON.stringify(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch(path, config);
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`HTTP error! status: ${response.status}`);
|
||||||
|
}
|
||||||
|
const data = await response.json();
|
||||||
|
console.log("La route " + path + " a fonctionné.");
|
||||||
|
return data;
|
||||||
|
} catch (error) {
|
||||||
|
console.error("La route " + path + " n'a pas fonctionné.", error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return { fetchDataThroughKQL, fetchPageData, fetchRoute };
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -9,34 +9,12 @@
|
||||||
<section :id="currentTab" class="inspiration">
|
<section :id="currentTab" class="inspiration">
|
||||||
<Header :inspiration="currentInspiration" />
|
<Header :inspiration="currentInspiration" />
|
||||||
<div class="grid masonry">
|
<div class="grid masonry">
|
||||||
<template v-for="(item, index) in currentInspiration.media">
|
<Image
|
||||||
<figure class="flex" :style="'--rows: ' + (index % 2 ? 2 : 3)">
|
v-for="(item, index) in currentInspiration.media"
|
||||||
<button
|
:key="item.id"
|
||||||
class="favorite"
|
:item="item"
|
||||||
aria-label="Ajouter aux favoris"
|
:inspirationUri="currentInspiration.uri"
|
||||||
aria-pressed="false"
|
/>
|
||||||
onclick="this.setAttribute('aria-pressed', this.getAttribute('aria-pressed') === 'true' ? 'false' : 'true');"
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
width="40"
|
|
||||||
height="40"
|
|
||||||
viewBox="0 0 40 40"
|
|
||||||
fill="none"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M5.49289 22.5821C5.50453 22.5937 5.51646 22.6051 5.52866 22.6161L19.3287 35.1161C19.7097 35.4613 20.2903 35.4613 20.6713 35.1161L34.4713 22.6161C34.4835 22.6051 34.4955 22.5937 34.5071 22.5821C38.7044 18.3848 37.6545 12.2706 34.2529 8.87931C32.5281 7.15976 30.1519 6.07621 27.4679 6.26656C25.0319 6.43932 22.4673 7.65151 20 10.1579C17.5321 7.65095 14.9651 6.43633 12.5266 6.25964C9.83985 6.06497 7.45863 7.14246 5.72977 8.85914C2.3178 12.247 1.27257 18.3618 5.49289 22.5821Z"
|
|
||||||
fill="currentColor"
|
|
||||||
stroke="white"
|
|
||||||
stroke-width="2"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
<img :src="item.url" alt="" />
|
|
||||||
</figure>
|
|
||||||
</template>
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</main>
|
</main>
|
||||||
|
|
@ -48,6 +26,7 @@ import Menu from "../components/Menu.vue";
|
||||||
import Selector from "../components/inspirations/Selector.vue";
|
import Selector from "../components/inspirations/Selector.vue";
|
||||||
import Header from "../components/inspirations/Header.vue";
|
import Header from "../components/inspirations/Header.vue";
|
||||||
import Tabs from "../components/Tabs.vue";
|
import Tabs from "../components/Tabs.vue";
|
||||||
|
import Image from "../components/inspirations/Image.vue";
|
||||||
import { ref, computed } from "vue";
|
import { ref, computed } from "vue";
|
||||||
|
|
||||||
const { data } = defineProps({
|
const { data } = defineProps({
|
||||||
|
|
@ -94,60 +73,4 @@ function changeTab(newValue) {
|
||||||
grid-auto-rows: 12rem;
|
grid-auto-rows: 12rem;
|
||||||
grid-auto-flow: dense;
|
grid-auto-flow: dense;
|
||||||
}
|
}
|
||||||
.masonry > * {
|
|
||||||
position: relative;
|
|
||||||
grid-row: span var(--rows);
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
margin: 0;
|
|
||||||
border-radius: var(--rounded-2xl);
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
.masonry img {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
object-fit: cover;
|
|
||||||
}
|
|
||||||
.masonry > *:hover::after {
|
|
||||||
content: "";
|
|
||||||
position: absolute;
|
|
||||||
inset: 0;
|
|
||||||
background: var(--color-black-20);
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
.masonry > *:hover .favorite {
|
|
||||||
display: initial;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Favorite button */
|
|
||||||
.favorite {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
right: 0;
|
|
||||||
width: 3.5rem;
|
|
||||||
height: 3.5rem;
|
|
||||||
margin: var(--space-8);
|
|
||||||
padding: var(--space-8);
|
|
||||||
color: var(--color-grey-400);
|
|
||||||
display: none;
|
|
||||||
z-index: 10;
|
|
||||||
}
|
|
||||||
.favorite[aria-pressed="false"]:hover::before {
|
|
||||||
content: "Ajouter dans mes favoris";
|
|
||||||
background: var(--color-background);
|
|
||||||
padding: 1.3rem 3.5rem 1.25rem 1rem;
|
|
||||||
position: absolute;
|
|
||||||
z-index: -1;
|
|
||||||
inset: -2px;
|
|
||||||
left: unset;
|
|
||||||
width: max-content;
|
|
||||||
border-radius: var(--rounded-xl);
|
|
||||||
color: var(--color-grey-700);
|
|
||||||
letter-spacing: var(--tracking-wide);
|
|
||||||
font-weight: 500;
|
|
||||||
font-size: var(--text-sm);
|
|
||||||
}
|
|
||||||
.favorite[aria-pressed="true"] {
|
|
||||||
color: var(--color-brand);
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue