Release 2025-05-23-xzNR

This commit is contained in:
pluja
2025-05-23 21:50:03 +00:00
parent 4806a7fd4e
commit 970622d061
14 changed files with 1202 additions and 1090 deletions

View File

@@ -58,27 +58,17 @@ const button = tv({
},
},
color: {
black: {
base: 'border-night-500 bg-night-800 hover:bg-night-900 hover:text-day-200 focus-visible:bg-night-500 text-white/50 focus-visible:text-white focus-visible:ring-white',
},
white: {
base: 'border-day-300 bg-day-100 hover:bg-day-200 text-black focus-visible:ring-green-500',
},
gray: {
base: 'border-day-500 bg-day-400 hover:bg-day-500 text-black focus-visible:ring-white',
},
success: {
base: 'border-green-600 bg-green-500 text-black hover:bg-green-600',
},
error: {
base: 'border-red-600 bg-red-500 text-white hover:bg-red-600',
},
warning: {
base: 'border-yellow-600 bg-yellow-500 text-white hover:bg-yellow-600',
},
info: {
base: 'border-blue-600 bg-blue-500 text-white hover:bg-blue-600',
},
black: '',
white: '',
gray: '',
success: '',
danger: '',
warning: '',
info: '',
},
variant: {
solid: '',
faded: '',
},
shadow: {
true: {
@@ -92,6 +82,107 @@ const button = tv({
},
},
compoundVariants: [
// Color variants - solid
{
color: 'black',
variant: 'solid',
class: {
base: 'border-night-500 bg-night-800 hover:bg-night-900 hover:text-day-200 focus-visible:bg-night-500 text-white/50 focus-visible:text-white focus-visible:ring-white',
},
},
{
color: 'white',
variant: 'solid',
class: {
base: 'border-day-300 bg-day-100 hover:bg-day-200 text-black focus-visible:ring-green-500',
},
},
{
color: 'gray',
variant: 'solid',
class: {
base: 'border-day-500 bg-day-400 hover:bg-day-500 text-black focus-visible:ring-white',
},
},
{
color: 'success',
variant: 'solid',
class: {
base: 'border-green-600 bg-green-500 text-black hover:bg-green-600',
},
},
{
color: 'danger',
variant: 'solid',
class: {
base: 'border-red-600 bg-red-500 text-white hover:bg-red-600',
},
},
{
color: 'warning',
variant: 'solid',
class: {
base: 'border-yellow-600 bg-yellow-500 text-white hover:bg-yellow-600',
},
},
{
color: 'info',
variant: 'solid',
class: {
base: 'border-blue-600 bg-blue-500 text-white hover:bg-blue-600',
},
},
// Color variants - faded
{
color: 'black',
variant: 'faded',
class: {
base: 'border-night-300/30 bg-night-800/30 hover:bg-night-700/50 text-white/70 hover:text-white/90 focus-visible:ring-white/50',
},
},
{
color: 'white',
variant: 'faded',
class: {
base: 'border-day-300/30 bg-day-100/30 hover:bg-day-200/50 text-white/70 hover:text-white/90 focus-visible:ring-white/50',
},
},
{
color: 'gray',
variant: 'faded',
class: {
base: 'border-day-500/30 bg-day-400/30 hover:bg-day-500/50 text-day-300 hover:text-day-100 focus-visible:ring-white/50',
},
},
{
color: 'success',
variant: 'faded',
class: {
base: 'border-green-600/30 bg-green-500/30 text-green-300 hover:bg-green-500/50 hover:text-green-100',
},
},
{
color: 'danger',
variant: 'faded',
class: {
base: 'border-red-600/30 bg-red-500/30 text-red-300 hover:bg-red-500/50 hover:text-red-100',
},
},
{
color: 'warning',
variant: 'faded',
class: {
base: 'border-yellow-600/30 bg-yellow-500/30 text-yellow-300 hover:bg-yellow-500/50 hover:text-yellow-100',
},
},
{
color: 'info',
variant: 'faded',
class: {
base: 'border-blue-600/30 bg-blue-500/30 text-blue-300 hover:bg-blue-500/50 hover:text-blue-100',
},
},
// Shadow variants
{
color: 'black',
shadow: true,
@@ -113,7 +204,7 @@ const button = tv({
class: 'shadow-green-500/30',
},
{
color: 'error',
color: 'danger',
shadow: true,
class: 'shadow-red-500/30',
},
@@ -127,6 +218,7 @@ const button = tv({
shadow: true,
class: 'shadow-blue-500/30',
},
// Icon only variants
{
iconOnly: true,
size: 'sm',
@@ -146,6 +238,7 @@ const button = tv({
defaultVariants: {
size: 'md',
color: 'black',
variant: 'solid',
shadow: false,
disabled: false,
iconOnly: false,
@@ -159,6 +252,7 @@ const {
endIcon,
size,
color,
variant,
shadow,
class: className,
classNames,
@@ -174,7 +268,7 @@ const {
icon: iconSlot,
label: labelSlot,
endIcon: endIconSlot,
} = button({ size, color, shadow, disabled, iconOnly: !label && !(!!icon && !!endIcon) })
} = button({ size, color, variant, shadow, disabled, iconOnly: !label && !(!!icon && !!endIcon) })
const ActualTag = disabled && Tag === 'a' ? 'span' : Tag
---

View File

@@ -0,0 +1,24 @@
---
import { cn } from '../lib/cn'
import type { AstroChildren } from '../lib/astro'
import type { HTMLAttributes } from 'astro/types'
type Props = HTMLAttributes<'section'> & {
title: string
subtitle?: string
heading?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'
children: AstroChildren
}
const { title, subtitle, class: className, heading = 'h2', ...props } = Astro.props
const HeadingTag = heading
---
<section class={cn('mt-24 space-y-2 first:mt-0', className)} {...props}>
<HeadingTag class="font-title text-center text-3xl leading-none font-bold">{title}</HeadingTag>
{subtitle && <p class="text-day-400 text-center">{subtitle}</p>}
<slot />
</section>

View File

@@ -0,0 +1,24 @@
---
import { cn } from '../lib/cn'
import type { AstroChildren } from '../lib/astro'
import type { HTMLAttributes } from 'astro/types'
type Props = HTMLAttributes<'section'> & {
title: string
subtitle?: string
heading?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'
children: AstroChildren
}
const { title, subtitle, class: className, heading = 'h3', ...props } = Astro.props
const HeadingTag = heading
---
<section class={cn('mt-6 space-y-2 first:mt-0', className)} {...props}>
<HeadingTag class="font-title text-day-400 text-center text-lg font-medium">{title}</HeadingTag>
{subtitle && <p class="text-day-400 text-center">{subtitle}</p>}
<slot />
</section>

View File

@@ -12,13 +12,15 @@ type Props = Omit<ComponentProps<typeof InputWrapper>, 'children' | 'inputId'> &
options: {
label: string
value: string
icon?: string
icon?: string[] | string
iconClassName?: string[] | string
}[]
disabled?: boolean
selectedValues?: string[]
size?: 'lg' | 'md'
}
const { options, disabled, selectedValues = [], ...wrapperProps } = Astro.props
const { options, disabled, selectedValues = [], size = 'md', ...wrapperProps } = Astro.props
const inputId = Astro.locals.makeId(`input-${wrapperProps.name}`)
const hasError = !!wrapperProps.error && wrapperProps.error.length > 0
@@ -26,23 +28,38 @@ const hasError = !!wrapperProps.error && wrapperProps.error.length > 0
<InputWrapper inputId={inputId} {...wrapperProps}>
<div class={cn(baseInputClassNames.div, hasError && baseInputClassNames.error)}>
<div class="h-48 overflow-y-auto mask-y-from-[calc(100%-var(--spacing)*8)] py-5">
<div
class={cn('h-48 overflow-y-auto mask-y-from-[calc(100%-var(--spacing)*8)] py-5', {
'h-96': size === 'lg',
'h-48': size === 'md',
})}
>
{
options.map((option) => (
<label class="hover:bg-night-500 flex cursor-pointer items-center gap-2 px-5 py-1">
<input
transition:persist
type="checkbox"
name={wrapperProps.name}
value={option.value}
checked={selectedValues.includes(option.value)}
class={cn(hasError && baseInputClassNames.error, disabled && baseInputClassNames.disabled)}
disabled={disabled}
/>
{option.icon && <Icon name={option.icon} class="size-4" />}
<span class="text-sm leading-none">{option.label}</span>
</label>
))
options.map((option) => {
const icons = option.icon ? (Array.isArray(option.icon) ? option.icon : [option.icon]) : []
const iconClassName = option.iconClassName
? Array.isArray(option.iconClassName)
? option.iconClassName
: Array.from({ length: icons.length }, () => option.iconClassName)
: []
return (
<label class="hover:bg-night-500 flex cursor-pointer items-center gap-2 px-5 py-1">
<input
transition:persist
type="checkbox"
name={wrapperProps.name}
value={option.value}
checked={selectedValues.includes(option.value)}
class={cn(hasError && baseInputClassNames.error, disabled && baseInputClassNames.disabled)}
disabled={disabled}
/>
{icons.map((icon, index) => (
<Icon name={icon} class={cn('size-4', iconClassName[index])} />
))}
<span class="text-sm leading-none">{option.label}</span>
</label>
)
})
}
</div>
</div>

View File

@@ -10,7 +10,7 @@ import type { ComponentProps, HTMLAttributes } from 'astro/types'
type Props = Omit<ComponentProps<typeof InputWrapper>, 'children' | 'inputId' | 'required'> & {
inputProps?: Omit<HTMLAttributes<'textarea'>, 'name'>
value?: string
value?: string | null | undefined
}
const { inputProps, value, ...wrapperProps } = Astro.props