-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
49d8ef4
commit a677653
Showing
12 changed files
with
412 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
--- | ||
import type { MasonryProps } from './masonry' | ||
import styles from './masonry.module.scss' | ||
interface Props extends MasonryProps {} | ||
const { | ||
items, | ||
element = 'section', | ||
gap, | ||
columns = 3, | ||
sequential, | ||
className | ||
} = Astro.props | ||
const classes = [ | ||
styles.masonry, | ||
className | ||
] | ||
const Component = element | ||
const componentProps = { | ||
'class:list': classes, | ||
'style': gap ? `--w-masonry-gap: ${gap};` : null | ||
} | ||
const chunkSize = Math.ceil(items.length / columns) | ||
const columnGroups = Array.from({ length: columns }, (_, i) => { | ||
return sequential | ||
? items.slice(i * chunkSize, (i + 1) * chunkSize) | ||
: items.filter((_, index) => index % columns === i) | ||
}) | ||
--- | ||
|
||
<Component {...componentProps}> | ||
{columnGroups.map(column => ( | ||
<div class={styles.column}> | ||
{column.map(item => ( | ||
item.component | ||
? <item.component {...item.props}> | ||
{typeof item.children === 'object' | ||
? <item.children.component {...item.children.props}> | ||
<Fragment set:html={item.children.children} /> | ||
</item.children.component> | ||
: <Fragment set:html={item.children} /> | ||
} | ||
</item.component> | ||
: <Fragment set:html={item.html} /> | ||
))} | ||
</div> | ||
))} | ||
</Component> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
<script lang="ts"> | ||
import type { SvelteMasonryProps } from './masonry' | ||
import { classNames } from '../../utils/classNames' | ||
import styles from './masonry.module.scss' | ||
export let items: SvelteMasonryProps['items'] = [] | ||
export let element: SvelteMasonryProps['element'] = 'section' | ||
export let gap: SvelteMasonryProps['gap'] = '' | ||
export let columns: SvelteMasonryProps['columns'] = 3 | ||
export let sequential: SvelteMasonryProps['sequential'] = false | ||
export let className: SvelteMasonryProps['className'] = '' | ||
const classes = classNames([ | ||
styles.masonry, | ||
className | ||
]) | ||
const componentProps = { | ||
class: classes, | ||
style: gap ? `--w-masonry-gap: ${gap};` : null | ||
} | ||
const chunkSize = Math.ceil(items.length / columns!) | ||
const columnGroups = Array.from({ length: columns! }, (_, i) => { | ||
return sequential | ||
? items.slice(i * chunkSize, (i + 1) * chunkSize) | ||
: items.filter((_, index) => index % columns! === i) | ||
}) | ||
</script> | ||
|
||
|
||
<svelte:element this={element} {...componentProps}> | ||
{#each columnGroups as group} | ||
<div class={styles.column}> | ||
{#each group as item} | ||
{#if item.component} | ||
<svelte:component this={item.component} {...item.props}> | ||
{#if typeof item.children === 'object' && item.children.component} | ||
<svelte:component this={item.children.component} {...item.children.props}> | ||
{@html item.children.children} | ||
</svelte:component> | ||
{:else} | ||
{@html item.children} | ||
{/if} | ||
</svelte:component> | ||
{:else} | ||
{@html item.html} | ||
{/if} | ||
{/each} | ||
</div> | ||
{/each} | ||
</svelte:element> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
import React from 'react' | ||
import type { ReactMasonryProps } from './masonry' | ||
|
||
import { classNames } from '../../utils/classNames' | ||
|
||
import styles from './masonry.module.scss' | ||
|
||
const Masonry = ({ | ||
items, | ||
element = 'section', | ||
gap, | ||
columns = 3, | ||
sequential, | ||
className | ||
}: ReactMasonryProps) => { | ||
const classes = classNames([ | ||
styles.masonry, | ||
className | ||
]) | ||
|
||
const componentProps = { | ||
className: classes, | ||
style: gap | ||
? { '--w-masonry-gap': gap } as React.CSSProperties | ||
: undefined | ||
} | ||
|
||
const chunkSize = Math.ceil(items.length / columns!) | ||
const columnGroups = Array.from({ length: columns! }, (_, i) => { | ||
return sequential | ||
? items.slice(i * chunkSize, (i + 1) * chunkSize) | ||
: items.filter((_, index) => index % columns! === i) | ||
}) | ||
|
||
const Element = element as keyof JSX.IntrinsicElements | ||
|
||
return ( | ||
<Element {...componentProps}> | ||
{columnGroups.map((column, columnKey) => ( | ||
<div className={styles.column} key={columnKey}> | ||
{column.map((item, itemKey) => ( | ||
item.component | ||
? <item.component {...item.props} key={itemKey}> | ||
{typeof item.children === 'object' | ||
? <item.children.component {...item.children.props}> | ||
<span dangerouslySetInnerHTML={{ __html: String(item.children.children) }} /> | ||
</item.children.component> | ||
: <span dangerouslySetInnerHTML={{ __html: String(item.children) }} /> | ||
} | ||
</item.component> | ||
: <span | ||
key={itemKey} | ||
dangerouslySetInnerHTML={{ __html: String(item.html) }} | ||
/> | ||
))} | ||
</div> | ||
))} | ||
</Element> | ||
) | ||
} | ||
|
||
export default Masonry |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
@import '../../scss/config.scss'; | ||
|
||
body { | ||
--w-masonry-gap: 5px; | ||
} | ||
|
||
.masonry { | ||
@include layout(flex); | ||
|
||
gap: var(--w-masonry-gap); | ||
overflow-x: auto; | ||
|
||
.column { | ||
@include layout(flex, column); | ||
|
||
gap: var(--w-masonry-gap); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import type { FC } from 'react' | ||
import type { SvelteComponent } from 'svelte' | ||
|
||
type ChildrenProps<ComponentType> = { | ||
component: ComponentType; | ||
children?: string | number | ||
props?: { | ||
[key: string]: any | ||
} | ||
} | string | number | ||
|
||
type Items<ComponentType> = { | ||
component?: ComponentType; | ||
children?: ChildrenProps<ComponentType> | ||
html?: string | ||
props?: { | ||
[key: string]: any | ||
} | ||
} | ||
|
||
export type MasonryProps = { | ||
items: Items<(_props: any) => any>[] | ||
element?: string | ||
gap?: string | ||
columns?: number | ||
sequential?: boolean | ||
className?: string | ||
} | ||
|
||
export type SvelteMasonryProps = { | ||
items: Items<typeof SvelteComponent<any>>[] | ||
} & Omit<MasonryProps, 'items'> | ||
|
||
export type ReactMasonryProps = { | ||
items: Items<FC<any>>[] | ||
} & Omit<MasonryProps, 'items'> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.