fix(ui): links align themselves left by default; improve responsive spacing in card

This commit is contained in:
upsiflu 2024-12-21 01:20:03 +01:00
parent 2c608ae467
commit e37aa17f85
2 changed files with 30 additions and 15 deletions

View File

@ -16,17 +16,15 @@ const props = defineProps<{
tags?: string[] tags?: string[]
image?: string | { src: string, style?: "withPadding" } image?: string | { src: string, style?: "withPadding" }
icon?: string icon?: string
} & { } & ({
[Size in 'small' | 'auto']?: true [Width in 'small' | 'auto']?: true
} & Partial<RouterLinkProps> & (PastelProps | ColorProps | DefaultProps) & RaisedProps & VariantProps>() } | { width: string }) & Partial<RouterLinkProps> & (PastelProps | ColorProps | DefaultProps) & RaisedProps & VariantProps>()
const image = typeof props.image === 'string' ? { src: props.image } : props.image const image = typeof props.image === 'string' ? { src: props.image } : props.image
const isExternalLink = computed(() => { const isExternalLink = computed(() => {
return typeof props.to === 'string' && props.to.startsWith('http') return typeof props.to === 'string' && props.to.startsWith('http')
}) })
// const fallbackWidth =
</script> </script>
<template> <template>
@ -48,7 +46,7 @@ const isExternalLink = computed(() => {
</div> </div>
<img v-else-if="image" :src="image?.src" <img v-else-if="image" :src="image?.src"
:class="{ [$style.image]: true, [$style['with-padding']]: image?.style === 'withPadding' }" /> :class="{ [$style.image]: true, [$style['with-padding']]: image?.style === 'withPadding' }" />
<Spacer v-else :size="props.small? 4 : 12" /> <Spacer v-else :size="'small' in props ? 4 : 12" />
<!-- Icon --> <!-- Icon -->
@ -74,6 +72,8 @@ const isExternalLink = computed(() => {
<slot /> <slot />
</Layout> </Layout>
<Spacer grow :size="0" />
<!-- Footer and Action --> <!-- Footer and Action -->
<div v-if="$slots.footer" :class="$style.footer"> <div v-if="$slots.footer" :class="$style.footer">
<slot name="footer" /> <slot name="footer" />
@ -83,7 +83,7 @@ const isExternalLink = computed(() => {
<slot name="action" /> <slot name="action" />
</div> </div>
<Spacer v-if="!$slots.footer && !$slots.action" :size="props.small? 8 : 16" /> <Spacer v-if="!$slots.footer && !$slots.action" :size="'small' in props? 8 : 16" />
</Layout> </Layout>
</template> </template>
@ -91,7 +91,7 @@ const isExternalLink = computed(() => {
<style module> <style module>
.card { .card {
/* Override --width with your preferred value */ /* Override --width with your preferred value */
--fw-card-width: var(--width, v-bind("props.small ? 'min-content' : props.auto ? 'auto' : '320px'")); --fw-card-width: var(--width, v-bind("'small' in props ? 'min-content' : 'auto' in props ? 'auto' : props.width || '320px'"));
--fw-card-padding: v-bind("props.small ? '16px' : '24px'"); --fw-card-padding: v-bind("props.small ? '16px' : '24px'");
position: relative; position: relative;
@ -138,6 +138,12 @@ const isExternalLink = computed(() => {
>.icon { >.icon {
position: absolute; position: absolute;
top: 22px;
right: 22px;
font-size: 1rem;
}
&:has(>.image)>.icon {
top: var(--fw-card-padding); top: var(--fw-card-padding);
right: var(--fw-card-padding); right: var(--fw-card-padding);
@ -145,6 +151,7 @@ const isExternalLink = computed(() => {
} }
>.title { >.title {
margin: 0;
padding: 0 var(--fw-card-padding); padding: 0 var(--fw-card-padding);
line-height: 1.3em; line-height: 1.3em;
font-size: 1.125em; font-size: 1.125em;
@ -155,10 +162,12 @@ const isExternalLink = computed(() => {
overflow: hidden; overflow: hidden;
flex-shrink: 0; flex-shrink: 0;
} }
&:has(>.icon)>.title {
padding-right:calc(var(--fw-card-padding) + 22px);
}
&.is-category>.title { &.is-category>.title {
font-size: 1.75em; font-size: 1.75em;
padding-bottom: .25em; padding-bottom: .125em;
} }
>.alert { >.alert {

View File

@ -5,7 +5,7 @@ import { type ColorProps, type DefaultProps, type VariantProps, propsToColor } f
const { to, icon, thickWhenActive, round, ...colorProps } = defineProps<{ const { to, icon, thickWhenActive, round, ...colorProps } = defineProps<{
width?: 'standard' | 'auto' | 'full' width?: 'standard' | 'auto' | 'full'
alignText?: 'left' | 'center' | 'right' alignText?: 'left' | 'center' | 'right' | 'stretch'
alignSelf?: 'start' | 'center' | 'end' alignSelf?: 'start' | 'center' | 'end'
thickWhenActive?: true thickWhenActive?: true
@ -30,7 +30,7 @@ const isSimple = propsToColor(colorProps).class === ''
$style.link, $style.link,
'is-' + width, 'is-' + width,
'is-text-aligned-' + (alignText ?? 'center'), 'is-text-aligned-' + (alignText ?? 'center'),
'is-self-aligned-' + (alignSelf ?? 'center'), 'is-self-aligned-' + (alignSelf ?? 'left'),
round && $style['is-round'], round && $style['is-round'],
isIconOnly && $style['is-icon-only'], isIconOnly && $style['is-icon-only'],
isSimple && $style['force-underline'], isSimple && $style['force-underline'],
@ -49,9 +49,9 @@ const isSimple = propsToColor(colorProps).class === ''
v-bind="propsToColor({ ...colorProps, interactive: true })" v-bind="propsToColor({ ...colorProps, interactive: true })"
:class="[ :class="[
$style.link, $style.link,
'is-' + width, $style['is-' + width],
'is-text-aligned-' + (alignText ?? 'center'), $style['is-text-aligned-' + (alignText ?? 'center')],
'is-self-aligned-' + (alignSelf ?? 'center'), $style['is-self-aligned-' + (alignSelf ?? 'start')],
round && $style['is-round'], round && $style['is-round'],
isIconOnly && $style['is-icon-only'], isIconOnly && $style['is-icon-only'],
isSimple && $style['no-spacing'], isSimple && $style['no-spacing'],
@ -139,6 +139,12 @@ const isSimple = propsToColor(colorProps).class === ''
justify-content: flex-end; justify-content: flex-end;
} }
&.is-text-aligned-stretch {
justify-content: stretch;
align-content: stretch;
> span { width:100%; }
}
&.is-self-aligned-start { &.is-self-aligned-start {
align-self: flex-start; align-self: flex-start;
} }