mirror of
https://github.com/saicaca/fuwari.git
synced 2026-01-12 15:22:52 +01:00
feat: initial commit
(cherry picked from commit 44c4d7b9521fe449e61edc614446195861932f8c)
This commit is contained in:
77
src/components/control/Button.astro
Normal file
77
src/components/control/Button.astro
Normal file
@@ -0,0 +1,77 @@
|
||||
---
|
||||
interface Props {
|
||||
id?: string;
|
||||
isIcon?: boolean;
|
||||
iconName?: string;
|
||||
width?: string;
|
||||
height?: string;
|
||||
regular?: boolean;
|
||||
light?: boolean
|
||||
card?: boolean;
|
||||
iconSize?: number,
|
||||
class?: string
|
||||
disabled?: boolean
|
||||
}
|
||||
const props = Astro.props;
|
||||
const {
|
||||
id,
|
||||
isIcon = false,
|
||||
iconName,
|
||||
width,
|
||||
height = '44px',
|
||||
regular,
|
||||
light,
|
||||
iconSize = 24,
|
||||
card,
|
||||
disabled = false,
|
||||
} = Astro.props;
|
||||
const className = Astro.props.class;
|
||||
import { Icon } from 'astro-icon/components';
|
||||
---
|
||||
|
||||
<button id={id}
|
||||
disabled={disabled}
|
||||
class:list={[
|
||||
className,
|
||||
`
|
||||
rounded-lg
|
||||
transition
|
||||
h-[var(--height)]
|
||||
`,
|
||||
{
|
||||
'w-[var(--width)]': width,
|
||||
'w-[var(--height)]': isIcon,
|
||||
|
||||
'bg-none': light,
|
||||
'hover:bg-[var(--btn-plain-bg-hover)]': light,
|
||||
'active:bg-[var(--btn-plain-bg-active)]': light,
|
||||
'text-neutral-900': light,
|
||||
'hover:text-[var(--primary)]': light,
|
||||
|
||||
'dark:text-neutral-300': light || regular,
|
||||
'dark:hover:text-[var(--primary)]': light,
|
||||
|
||||
'bg-[var(--btn-regular-bg)]': regular,
|
||||
'hover:bg-[oklch(0.9_0.05_var(--hue))]': regular,
|
||||
'active:bg-[oklch(0.85_0.08_var(--hue))]': regular,
|
||||
'text-[var(--btn-content)]': regular,
|
||||
|
||||
'dark:bg-[oklch(0.38_0.04_var(--hue))]': regular,
|
||||
'dark:hover:bg-[oklch(0.45_0.045_var(--hue))]': regular,
|
||||
'dark:active:bg-[oklch(0.5_0.05_var(--hue))]': regular,
|
||||
|
||||
'card-base': card,
|
||||
'enabled:hover:bg-[var(--btn-card-bg-hover)]': card,
|
||||
'enabled:active:bg-[var(--btn-card-bg-active)]': card,
|
||||
'disabled:text-black/10': card,
|
||||
'disabled:dark:text-white/10': card,
|
||||
}
|
||||
]}
|
||||
>
|
||||
{props.isIcon && <Icon class="mx-auto" name={props.iconName} size={iconSize}></Icon> }
|
||||
<slot />
|
||||
</button>
|
||||
|
||||
<style define:vars={{ height, width, iconSize }}>
|
||||
|
||||
</style>
|
||||
42
src/components/control/ButtonLink.astro
Normal file
42
src/components/control/ButtonLink.astro
Normal file
@@ -0,0 +1,42 @@
|
||||
---
|
||||
interface Props {
|
||||
badge?: string
|
||||
url?: string
|
||||
}
|
||||
const { badge, url } = Astro.props
|
||||
---
|
||||
<a href={url}>
|
||||
<button
|
||||
class:list={`
|
||||
w-full
|
||||
h-10
|
||||
rounded-lg
|
||||
bg-none
|
||||
hover:bg-[var(--btn-plain-bg-hover)]
|
||||
active:bg-[var(--btn-plain-bg-active)]
|
||||
transition-all
|
||||
pl-2
|
||||
hover:pl-3
|
||||
|
||||
text-neutral-700
|
||||
hover:text-[var(--primary)]
|
||||
dark:text-neutral-300
|
||||
dark:hover:text-[var(--primary)]
|
||||
`
|
||||
}
|
||||
>
|
||||
<div class="flex items-center justify-between relative mr-2">
|
||||
<div class="overflow-hidden text-left whitespace-nowrap overflow-ellipsis ">
|
||||
<slot></slot>
|
||||
</div>
|
||||
{ badge !== undefined && badge !== null && badge !== '' &&
|
||||
<div class="transition h-[28px] ml-4 min-w-[32px] rounded-lg text-sm font-bold
|
||||
text-[var(--btn-content)] dark:text-[var(--deep-text)]
|
||||
bg-[oklch(0.95_0.025_var(--hue))] dark:bg-[var(--primary)]
|
||||
flex items-center justify-center">
|
||||
{ badge }
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</button>
|
||||
</a>
|
||||
15
src/components/control/ButtonTag.astro
Normal file
15
src/components/control/ButtonTag.astro
Normal file
@@ -0,0 +1,15 @@
|
||||
---
|
||||
import Button from "./Button.astro";
|
||||
interface Props {
|
||||
size?: string;
|
||||
dot?: boolean;
|
||||
href?: string;
|
||||
}
|
||||
const { size, dot, href }: Props = Astro.props;
|
||||
---
|
||||
<a href={href}>
|
||||
<Button regular height="32px" class="text-[15px] px-3 flex flex-row items-center">
|
||||
{dot && <div class="h-1 w-1 bg-[var(--btn-content)] dark:bg-[var(--card-bg)] transition rounded-md mr-2"></div>}
|
||||
<slot></slot>
|
||||
</Button>
|
||||
</a>
|
||||
84
src/components/control/Pagination.astro
Normal file
84
src/components/control/Pagination.astro
Normal file
@@ -0,0 +1,84 @@
|
||||
---
|
||||
import type { Page } from "astro";
|
||||
import { Icon } from 'astro-icon/components';
|
||||
interface Props {
|
||||
page: Page;
|
||||
class?: string;
|
||||
}
|
||||
|
||||
const {page} = Astro.props;
|
||||
|
||||
const HIDDEN = -1;
|
||||
|
||||
const className = Astro.props.class;
|
||||
import Button from "./Button.astro";
|
||||
|
||||
const ADJ_DIST = 2;
|
||||
const VISIBLE = ADJ_DIST * 2 + 1;
|
||||
|
||||
// for test
|
||||
let count = 1;
|
||||
let l = page.currentPage, r = page.currentPage;
|
||||
while (0 < l - 1 && r + 1 <= page.lastPage && count + 2 <= VISIBLE) {
|
||||
count += 2;
|
||||
l--;
|
||||
r++;
|
||||
}
|
||||
while (0 < l - 1 && count < VISIBLE) {
|
||||
count++;
|
||||
l--;
|
||||
}
|
||||
while (r + 1 <= page.lastPage && count < VISIBLE) {
|
||||
count++;
|
||||
r++;
|
||||
}
|
||||
|
||||
let pages: number[] = [];
|
||||
if (l > 1)
|
||||
pages.push(1);
|
||||
if (l == 3)
|
||||
pages.push(2);
|
||||
if (l > 3)
|
||||
pages.push(HIDDEN);
|
||||
for (let i = l; i <= r; i++)
|
||||
pages.push(i);
|
||||
if (r < page.lastPage - 2)
|
||||
pages.push(HIDDEN);
|
||||
if (r == page.lastPage - 2)
|
||||
pages.push(page.lastPage - 1);
|
||||
if (r < page.lastPage)
|
||||
pages.push(page.lastPage);
|
||||
|
||||
const parts: string[] = page.url.current.split('/');
|
||||
const commonUrl: string = parts.slice(0, -1).join('/') + '/';
|
||||
---
|
||||
|
||||
<div class:list={[className, "flex flex-row gap-3 justify-center"]}>
|
||||
<a href={page.url.prev}>
|
||||
<Button isIcon card iconName="material-symbols:chevron-left-rounded" class="text-[var(--primary)]" iconSize={28}
|
||||
disabled = {page.url.prev == undefined}
|
||||
></Button>
|
||||
</a>
|
||||
<div class="bg-[var(--card-bg)] flex flex-row rounded-lg items-center text-neutral-700 dark:text-neutral-300 font-bold">
|
||||
{pages.map((p) => {
|
||||
if (p == HIDDEN)
|
||||
return <Icon name="material-symbols:more-horiz" class="mx-1"/>;
|
||||
if (p == page.currentPage)
|
||||
return <div class="h-[44px] w-[44px] rounded-lg bg-[var(--primary)] flex items-center justify-center
|
||||
font-bold text-white dark:text-black/70"
|
||||
>
|
||||
{p}
|
||||
</div>
|
||||
return <a href={commonUrl + p}>
|
||||
<Button card iconName="material-symbols:chevron-left-rounded" height="44px" width="44px">
|
||||
{p}
|
||||
</Button>
|
||||
</a>
|
||||
})}
|
||||
</div>
|
||||
<a href={page.url.next}>
|
||||
<Button isIcon card iconName="material-symbols:chevron-right-rounded" class="text-[var(--primary)]" iconSize={28}
|
||||
disabled = {page.url.next == undefined}
|
||||
></Button>
|
||||
</a>
|
||||
</div>
|
||||
Reference in New Issue
Block a user