Compare commits
5 commits
18fa2810c4
...
62aaaeee9a
Author | SHA1 | Date | |
---|---|---|---|
|
62aaaeee9a | ||
|
66d0bc8d84 | ||
|
bb3ba32dc5 | ||
|
fbbac36b4a | ||
|
487de9237b |
6 changed files with 377 additions and 332 deletions
|
@ -5,12 +5,7 @@
|
|||
@supports (grid-template-rows: masonry) {
|
||||
.NativeMasonry {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(44px, min-content));
|
||||
grid-template-columns: repeat(auto-fit, minmax(33%, min-content));
|
||||
grid-template-rows: masonry;
|
||||
|
||||
&:has(> :last-child:nth-child(2n)) {
|
||||
grid-template-columns: repeat(2, minmax(auto, min-content));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,10 +5,8 @@ import {
|
|||
type Ref,
|
||||
createRenderEffect,
|
||||
onCleanup,
|
||||
children,
|
||||
createEffect,
|
||||
createSignal,
|
||||
onMount,
|
||||
} from "solid-js";
|
||||
import { Dynamic, type DynamicProps } from "solid-js/web";
|
||||
import MasonryLayout from "masonry-layout";
|
||||
|
@ -20,7 +18,6 @@ type MasonryContainer =
|
|||
| Component<{
|
||||
ref?: Ref<Element>;
|
||||
class?: string;
|
||||
children?: JSX.Element;
|
||||
}>;
|
||||
|
||||
type ElementOf<T extends MasonryContainer> =
|
||||
|
@ -37,7 +34,10 @@ function forwardRef<T>(value: T, ref?: Ref<T>) {
|
|||
(ref as (value: T) => void)(value);
|
||||
}
|
||||
|
||||
function createMasonry(element: Element, options: () => MasonryLayout.Options) {
|
||||
function createCompatMasonry(
|
||||
element: Element,
|
||||
options: () => MasonryLayout.Options,
|
||||
) {
|
||||
const layout = new MasonryLayout(element, {
|
||||
initLayout: false,
|
||||
});
|
||||
|
@ -46,11 +46,21 @@ function createMasonry(element: Element, options: () => MasonryLayout.Options) {
|
|||
|
||||
const size = createElementSize(element);
|
||||
|
||||
const treeMutObx = new MutationObserver(() => {
|
||||
layout.reloadItems?.();
|
||||
});
|
||||
|
||||
onCleanup(() => treeMutObx.disconnect());
|
||||
|
||||
createRenderEffect(() => {
|
||||
const opts = options();
|
||||
layout.option?.(opts);
|
||||
});
|
||||
|
||||
createRenderEffect(() => {
|
||||
treeMutObx.observe(element, { childList: true });
|
||||
});
|
||||
|
||||
createRenderEffect(() => {
|
||||
const width = size.width; // only tracking width
|
||||
layout.layout?.();
|
||||
|
@ -61,8 +71,6 @@ function createMasonry(element: Element, options: () => MasonryLayout.Options) {
|
|||
layout.layout?.();
|
||||
});
|
||||
}
|
||||
|
||||
return layout;
|
||||
}
|
||||
|
||||
const supportsCSSMasonryLayout = /* @__PURE__ */ CSS.supports(
|
||||
|
@ -85,9 +93,7 @@ if (import.meta.env.VITE_PLATFROM_MASONRY_ALWAYS_COMPAT) {
|
|||
function MasonryCompat<T extends MasonryContainer>(
|
||||
oprops: DynamicProps<T> & { class?: string },
|
||||
) {
|
||||
const [props, rest] = splitProps(oprops, ["ref", "children", "class"]);
|
||||
|
||||
const childrenComponents = children(() => props.children);
|
||||
const [props, rest] = splitProps(oprops, ["ref", "class"]);
|
||||
|
||||
return (
|
||||
<Dynamic
|
||||
|
@ -96,7 +102,7 @@ function MasonryCompat<T extends MasonryContainer>(
|
|||
|
||||
const [columnGap, setColumnGap] = createSignal<number>();
|
||||
|
||||
const layout = createMasonry(element, () => {
|
||||
createCompatMasonry(element, () => {
|
||||
return {
|
||||
gutter: columnGap(),
|
||||
};
|
||||
|
@ -115,18 +121,9 @@ function MasonryCompat<T extends MasonryContainer>(
|
|||
setColumnGap(Number(colGap.slice(0, colGap.length - 2)));
|
||||
}
|
||||
});
|
||||
|
||||
createRenderEffect(() => {
|
||||
childrenComponents(); // just tracks
|
||||
setTimeout(() => {
|
||||
layout.reloadItems?.();
|
||||
layout.layout?.();
|
||||
}, 0);
|
||||
});
|
||||
}}
|
||||
class={`Masonry CompatMasonry ${props.class || ""}`}
|
||||
{...rest}
|
||||
children={childrenComponents}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -147,6 +144,13 @@ function MasonryNative<T extends MasonryContainer>(
|
|||
* and fallback to masonry-layout if not supported. The children
|
||||
* must have specified width and height.
|
||||
*
|
||||
* Testing native behaviour:
|
||||
* - Firefox: in `about:config`, search for `layout.css.grid-template-masonry-value.enabled`
|
||||
*
|
||||
* Class `NativeMasonry` will be added to the element if it's under the
|
||||
* css masonry layout, otherwise it's `CompatMasonry`. `Masonry` is always
|
||||
* added.
|
||||
*
|
||||
* **Children Changes** As the children changed, reflow will be triggered,
|
||||
* and there is might be a blink (or transition) for user. If it's not your
|
||||
* intention, don't remove/add the direct children. Instead wraps them under
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
.StackedPage {
|
||||
container: StackedPage / size;
|
||||
display: contents;
|
||||
max-width: 100vw;
|
||||
max-width: 100dvw;
|
||||
|
||||
contain: layout;
|
||||
contain: strict;
|
||||
container: StackedPage / inline-size;
|
||||
width: 100vw;
|
||||
width: 100dvw;
|
||||
height: 100vh;
|
||||
height: 100dvh;
|
||||
}
|
||||
|
||||
dialog.StackedPage {
|
||||
|
|
|
@ -115,6 +115,46 @@
|
|||
}
|
||||
}
|
||||
|
||||
@supports (container-type: inline-size) {
|
||||
@container StackedPage (inline-size >=960px) {
|
||||
.Profile {
|
||||
display: grid;
|
||||
grid-template-columns: auto 560px;
|
||||
grid-template-rows: min-content 1fr;
|
||||
height: 100cqh;
|
||||
|
||||
>.topbar {
|
||||
grid-column: 1 / 3;
|
||||
grid-row: 1 /2;
|
||||
|
||||
.MuiToolbar-root {
|
||||
padding-right: calc(560px + 24px);
|
||||
}
|
||||
}
|
||||
|
||||
>.details {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
|
||||
>.intro {
|
||||
flex-grow: 1;
|
||||
}
|
||||
}
|
||||
|
||||
>.recent-toots {
|
||||
overflow-y: auto;
|
||||
margin-top: calc(-1 * var(--scaffold-topbar-height));
|
||||
z-index: calc(var(--tutu-zidx-nav, 1) + 1);
|
||||
|
||||
>.toot-list-toolbar {
|
||||
top: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.Profile__page-title {
|
||||
flex-grow: 1;
|
||||
white-space: nowrap;
|
||||
|
|
|
@ -237,6 +237,7 @@ const Profile: Component = () => {
|
|||
}
|
||||
class="Profile"
|
||||
>
|
||||
<div class="details">
|
||||
<Menu
|
||||
id={optMenuId}
|
||||
open={menuOpen()}
|
||||
|
@ -424,7 +425,9 @@ const Profile: Component = () => {
|
|||
aria-label="Display name"
|
||||
></Body2>
|
||||
</div>
|
||||
<span aria-label="Complete username" class="username">{fullUsername()}</span>
|
||||
<span aria-label="Complete username" class="username">
|
||||
{fullUsername()}
|
||||
</span>
|
||||
</div>
|
||||
<div role="presentation">
|
||||
<Switch>
|
||||
|
@ -493,7 +496,9 @@ const Profile: Component = () => {
|
|||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="recent-toots">
|
||||
<div class="toot-list-toolbar">
|
||||
<TootFilterButton
|
||||
options={{
|
||||
|
@ -546,6 +551,7 @@ const Profile: Component = () => {
|
|||
</IconButton>
|
||||
</div>
|
||||
</Show>
|
||||
</div>
|
||||
</Scaffold>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
contain: layout style;
|
||||
gap: 4px;
|
||||
|
||||
> * {
|
||||
>* {
|
||||
max-height: 35vh;
|
||||
min-height: 40px;
|
||||
min-width: 40px;
|
||||
|
@ -26,16 +26,16 @@
|
|||
}
|
||||
}
|
||||
|
||||
> * > * {
|
||||
>*>* {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
> * > :where(img, video) {
|
||||
>*> :where(img, video) {
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
> * >.sensitive-placeholder {
|
||||
>*>.sensitive-placeholder {
|
||||
display: inline-flex;
|
||||
display: inline flex;
|
||||
align-items: center;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue