feat: Banner background inherits cluster icon
This commit is contained in:
parent
32d27bc9fb
commit
a0d64eaffa
3 changed files with 65 additions and 17 deletions
|
|
@ -0,0 +1,15 @@
|
|||
.linearBlur::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
-webkit-backdrop-filter: blur(var(--blur));
|
||||
backdrop-filter: blur(var(--blur));
|
||||
|
||||
-webkit-mask: linear-gradient(var(--degrees), transparent, black 50%);
|
||||
mask: linear-gradient(var(--degrees), transparent, black 50%);
|
||||
|
||||
background: linear-gradient(var(--degrees), transparent, rgba(0, 0, 0, 0.4) 50%);
|
||||
}
|
||||
|
|
@ -1,21 +1,28 @@
|
|||
import { convertFileSrc } from '@tauri-apps/api/core';
|
||||
import { type JSX, splitProps } from 'solid-js';
|
||||
import { type JSX, type ParentProps, Show, splitProps } from 'solid-js';
|
||||
import styles from './ClusterCover.module.scss';
|
||||
import defaultCover from '~assets/images/default_instance_cover.jpg';
|
||||
import type { Cluster } from '~bindings';
|
||||
|
||||
type ClusterCoverProps = JSX.HTMLAttributes<HTMLImageElement> & {
|
||||
cluster: Cluster | undefined;
|
||||
override?: string;
|
||||
fallback?: string;
|
||||
linearBlur?: {
|
||||
degrees?: number;
|
||||
blur?: number;
|
||||
class?: string;
|
||||
};
|
||||
};
|
||||
|
||||
function ClusterCover(props: ClusterCoverProps) {
|
||||
const [split, rest] = splitProps(props, ['cluster', 'override', 'onError']);
|
||||
const [split, rest] = splitProps(props, ['cluster', 'override', 'onError', 'fallback', 'linearBlur', 'class']);
|
||||
|
||||
const image = () => {
|
||||
const url = split.override || split.cluster?.meta.icon_url || split.cluster?.meta.icon;
|
||||
|
||||
if (url === undefined || url === null)
|
||||
return defaultCover;
|
||||
return split.fallback || defaultCover;
|
||||
|
||||
if (url.startsWith('/'))
|
||||
return convertFileSrc(url);
|
||||
|
|
@ -23,17 +30,33 @@ function ClusterCover(props: ClusterCoverProps) {
|
|||
return url;
|
||||
};
|
||||
|
||||
const Wrapper = (props: ParentProps) => (
|
||||
<Show when={split.linearBlur !== undefined} fallback={<>{props.children}</>}>
|
||||
<div
|
||||
class={`${styles.linearBlur} ${split.linearBlur?.class || ''}`}
|
||||
style={{
|
||||
'--degrees': `${split.linearBlur?.degrees ?? 0}deg`,
|
||||
'--blur': `${split.linearBlur?.blur ?? 0}px`,
|
||||
}}
|
||||
children={props.children}
|
||||
/>
|
||||
</Show>
|
||||
);
|
||||
|
||||
return (
|
||||
<img
|
||||
{...rest}
|
||||
src={image()}
|
||||
onError={(e) => {
|
||||
e.currentTarget.src = split.override ? convertFileSrc(split.override) : defaultCover;
|
||||
if (split.onError)
|
||||
<Wrapper>
|
||||
<img
|
||||
{...rest}
|
||||
class={`${styles.cover} ${split.class || ''}`}
|
||||
src={image()}
|
||||
onError={(e) => {
|
||||
e.currentTarget.src = split.override ? convertFileSrc(split.override) : defaultCover;
|
||||
if (split.onError)
|
||||
// @ts-expect-error -- jsx stuff
|
||||
split.onError!(e);
|
||||
}}
|
||||
/>
|
||||
split.onError!(e);
|
||||
}}
|
||||
/>
|
||||
</Wrapper>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import {
|
||||
ChevronRightIcon,
|
||||
DotsVerticalIcon,
|
||||
PlayIcon,
|
||||
PlusIcon,
|
||||
SearchMdIcon,
|
||||
|
|
@ -8,7 +8,7 @@ import { For, Show, createEffect, createSignal } from 'solid-js';
|
|||
import { useNavigate } from '@solidjs/router';
|
||||
|
||||
import { mergeRefs } from '@solid-primitives/refs';
|
||||
import image from '../../assets/images/header.png';
|
||||
import BannerBackground from '../../assets/images/header.png';
|
||||
import Button from '../components/base/Button';
|
||||
import TextField from '../components/base/TextField';
|
||||
import ClusterRoot from './cluster/ClusterRoot';
|
||||
|
|
@ -217,8 +217,18 @@ function Banner(props: BannerProps) {
|
|||
});
|
||||
|
||||
return (
|
||||
<div class="relative w-full h-52">
|
||||
<img src={image} class="absolute rounded-xl w-full h-52 object-cover" />
|
||||
<div class="relative w-full h-52 min-h-52 overflow-hidden rounded-xl">
|
||||
<ClusterCover
|
||||
class="absolute rounded-xl w-full h-52 object-cover"
|
||||
linearBlur={{
|
||||
degrees: 270,
|
||||
blur: 30,
|
||||
class: 'after:right-1/3!',
|
||||
}}
|
||||
cluster={cluster()}
|
||||
fallback={BannerBackground}
|
||||
/>
|
||||
|
||||
<div class="relative z-10 h-full px-8 py-6 text-fg-primary flex flex-col justify-between items-start">
|
||||
<div class="flex flex-col gap-y-2">
|
||||
<h1>{cluster()?.meta.name || 'Create a cluster'}</h1>
|
||||
|
|
@ -254,7 +264,7 @@ function Banner(props: BannerProps) {
|
|||
<Button
|
||||
buttonStyle="iconSecondary"
|
||||
class="bg-op-10!"
|
||||
children={<ChevronRightIcon />}
|
||||
children={<DotsVerticalIcon />}
|
||||
onClick={() => ClusterRoot.open(navigate, cluster()!.uuid)}
|
||||
/>
|
||||
</>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue