adjust padding and text styles for album group

This commit is contained in:
jeffvli
2026-07-10 19:48:37 -07:00
parent d40530b7f6
commit b834d8eade
3 changed files with 87 additions and 46 deletions
@@ -13,7 +13,6 @@
flex-shrink: 0; flex-shrink: 0;
height: 100%; height: 100%;
aspect-ratio: 1; aspect-ratio: 1;
padding-top: calc(var(--theme-spacing-xs) * 0.5);
overflow: hidden; overflow: hidden;
border-radius: var(--theme-radius-md); border-radius: var(--theme-radius-md);
@@ -49,33 +48,23 @@
align-content: start; align-content: start;
min-width: 0; min-width: 0;
padding: 0; padding: 0;
padding-top: calc(var(--theme-spacing-xs) * 0.5);
} }
.info.enlarged-image { .info.enlarged-image {
padding-top: var(--theme-spacing-xs); padding-top: var(--theme-spacing-xs);
} }
.album-name { .album-title {
font-size: var(--theme-font-size-sm); font-weight: 500;
line-height: 1.25;
overflow-wrap: anywhere; overflow-wrap: anywhere;
} white-space: normal;
.album-name a {
color: inherit;
text-decoration: none;
&:hover {
text-decoration: underline;
}
} }
.metadata-row { .metadata-row {
font-size: var(--theme-font-size-xs); font-size: var(--theme-font-size-xs);
line-height: 1.25; color: var(--theme-colors-foreground-muted);
overflow-wrap: anywhere; overflow-wrap: anywhere;
opacity: 0.7; white-space: normal;
} }
.controls-row { .controls-row {
@@ -6,7 +6,11 @@ import { generatePath, Link } from 'react-router';
import imageColumnStyles from '../item-detail-list/columns/image-column.module.css'; import imageColumnStyles from '../item-detail-list/columns/image-column.module.css';
import { AlbumGroupControls } from './album-group-controls'; import { AlbumGroupControls } from './album-group-controls';
import styles from './album-group-header.module.css'; import styles from './album-group-header.module.css';
import { AlbumGroupMetadata, renderAlbumGroupMetadataItem } from './album-group-metadata'; import {
AlbumGroupMetadata,
AlbumGroupTextSize,
renderAlbumGroupMetadataItem,
} from './album-group-metadata';
import { TableItemSize } from './item-table-list'; import { TableItemSize } from './item-table-list';
import { ItemImage } from '/@/renderer/components/item-image/item-image'; import { ItemImage } from '/@/renderer/components/item-image/item-image';
@@ -22,6 +26,7 @@ import {
useAlbumGroupShowFavoriteRating, useAlbumGroupShowFavoriteRating,
usePlayButtonBehavior, usePlayButtonBehavior,
} from '/@/renderer/store'; } from '/@/renderer/store';
import { Text } from '/@/shared/components/text/text';
import { LibraryItem, Song } from '/@/shared/types/domain-types'; import { LibraryItem, Song } from '/@/shared/types/domain-types';
import { Play } from '/@/shared/types/types'; import { Play } from '/@/shared/types/types';
@@ -31,7 +36,7 @@ interface AlbumGroupHeaderProps {
onPlay?: (playType: Play) => void; onPlay?: (playType: Play) => void;
rowIndex?: number; rowIndex?: number;
setAlbumGroupContentHeight?: (rowIndex: number, height: number) => void; setAlbumGroupContentHeight?: (rowIndex: number, height: number) => void;
size?: 'compact' | 'large' | 'normal'; size?: AlbumGroupTextSize;
song: Song | undefined; song: Song | undefined;
} }
@@ -157,19 +162,25 @@ export const AlbumGroupHeader = ({
ref={infoRef} ref={infoRef}
style={{ minHeight: resolvedInfoHeight ?? infoHeight }} style={{ minHeight: resolvedInfoHeight ?? infoHeight }}
> >
<div className={styles.albumName}> {song?.album &&
{song?.albumId && albumPath ? ( (song.albumId && albumPath ? (
<Link state={{ item: song }} to={albumPath}> <Text
{song.album ?? ''} className={styles.albumTitle}
</Link> component={Link}
isLink
isNoSelect
state={{ item: song }}
to={albumPath}
>
{song.album}
</Text>
) : ( ) : (
(song?.album ?? '') <Text className={styles.albumTitle} isNoSelect>
)} {song.album}
</div> </Text>
))}
{metadataRows.map((row) => ( {metadataRows.map((row) => (
<div className={styles.metadataRow} key={row.id}> <div key={row.id}>{row.content}</div>
{row.content}
</div>
))} ))}
{showFavoriteRating && ( {showFavoriteRating && (
<div className={styles.controlsRow}> <div className={styles.controlsRow}>
@@ -2,7 +2,12 @@ import { TFunction } from 'i18next';
import { Fragment, ReactNode } from 'react'; import { Fragment, ReactNode } from 'react';
import { generatePath, Link } from 'react-router'; import { generatePath, Link } from 'react-router';
import { JoinedArtists } from '/@/renderer/features/albums/components/joined-artists'; import styles from './album-group-header.module.css';
import {
JOINED_ARTISTS_MUTED_PROPS,
JoinedArtists,
} from '/@/renderer/features/albums/components/joined-artists';
import { AppRoute } from '/@/renderer/router/routes'; import { AppRoute } from '/@/renderer/router/routes';
import { AlbumGroupItem } from '/@/renderer/store'; import { AlbumGroupItem } from '/@/renderer/store';
import { formatDurationString, formatPartialIsoDateUTC, formatSizeString } from '/@/renderer/utils'; import { formatDurationString, formatPartialIsoDateUTC, formatSizeString } from '/@/renderer/utils';
@@ -20,6 +25,23 @@ export type AlbumGroupMetadata = {
songCount: number; songCount: number;
}; };
export type AlbumGroupTextSize = 'compact' | 'large' | 'normal';
const metadataTextProps = {
isMuted: true,
isNoSelect: true,
size: 'xs' as const,
};
const albumGroupArtistProps = {
linkProps: { ...JOINED_ARTISTS_MUTED_PROPS.linkProps, size: 'xs' as const },
rootTextProps: { ...JOINED_ARTISTS_MUTED_PROPS.rootTextProps, size: 'xs' as const },
};
const MetadataTextContainer = ({ children }: { children: ReactNode }) => (
<div className={styles.metadataRow}>{children}</div>
);
export const computeAlbumGroupMetadata = ( export const computeAlbumGroupMetadata = (
songs: Song[], songs: Song[],
songCount: number, songCount: number,
@@ -78,17 +100,21 @@ export const renderAlbumGroupMetadataItem = (
} }
return ( return (
<JoinedArtists <div className={styles.metadataRow}>
artistName={song?.albumArtistName ?? ''} <JoinedArtists
artists={song?.albumArtists ?? []} artistName={song?.albumArtistName ?? ''}
linkProps={{ fw: 400 }} artists={song?.albumArtists ?? []}
rootTextProps={{ fw: 400, size: 'xs' }} linkProps={albumGroupArtistProps.linkProps}
/> rootTextProps={albumGroupArtistProps.rootTextProps}
/>
</div>
); );
case AlbumGroupItem.DURATION: case AlbumGroupItem.DURATION:
return metadata.duration > 0 ? ( return metadata.duration > 0 ? (
<Text size="xs">{formatDurationString(metadata.duration)}</Text> <MetadataTextContainer>
<Text {...metadataTextProps}>{formatDurationString(metadata.duration)}</Text>
</MetadataTextContainer>
) : null; ) : null;
case AlbumGroupItem.GENRES: case AlbumGroupItem.GENRES:
@@ -97,14 +123,13 @@ export const renderAlbumGroupMetadataItem = (
} }
return ( return (
<> <div className={styles.metadataRow}>
{metadata.genres.map((genre, index) => ( {metadata.genres.map((genre, index) => (
<Fragment key={genre.id}> <Fragment key={genre.id}>
<Text <Text
{...metadataTextProps}
component={Link} component={Link}
fw={400}
isLink isLink
size="xs"
state={{ item: genre }} state={{ item: genre }}
to={generatePath(AppRoute.LIBRARY_GENRES_DETAIL, { to={generatePath(AppRoute.LIBRARY_GENRES_DETAIL, {
genreId: genre.id, genreId: genre.id,
@@ -115,30 +140,46 @@ export const renderAlbumGroupMetadataItem = (
{index < metadata.genres.length - 1 && ', '} {index < metadata.genres.length - 1 && ', '}
</Fragment> </Fragment>
))} ))}
</> </div>
); );
case AlbumGroupItem.RELEASE_DATE: { case AlbumGroupItem.RELEASE_DATE: {
const releaseDate = formatReleaseDate(metadata); const releaseDate = formatReleaseDate(metadata);
return releaseDate ? <Text size="xs">{releaseDate}</Text> : null; return releaseDate ? (
<MetadataTextContainer>
<Text {...metadataTextProps}>{releaseDate}</Text>
</MetadataTextContainer>
) : null;
} }
case AlbumGroupItem.RELEASE_TYPE: case AlbumGroupItem.RELEASE_TYPE:
return metadata.releaseType ? <Text size="xs">{metadata.releaseType}</Text> : null; return metadata.releaseType ? (
<MetadataTextContainer>
<Text {...metadataTextProps}>{metadata.releaseType}</Text>
</MetadataTextContainer>
) : null;
case AlbumGroupItem.RELEASE_YEAR: case AlbumGroupItem.RELEASE_YEAR:
return metadata.releaseYear != null && metadata.releaseYear > 0 ? ( return metadata.releaseYear != null && metadata.releaseYear > 0 ? (
<Text size="xs">{metadata.releaseYear}</Text> <MetadataTextContainer>
<Text {...metadataTextProps}>{metadata.releaseYear}</Text>
</MetadataTextContainer>
) : null; ) : null;
case AlbumGroupItem.SIZE: case AlbumGroupItem.SIZE:
return metadata.size > 0 ? ( return metadata.size > 0 ? (
<Text size="xs">{formatSizeString(metadata.size)}</Text> <MetadataTextContainer>
<Text {...metadataTextProps}>{formatSizeString(metadata.size)}</Text>
</MetadataTextContainer>
) : null; ) : null;
case AlbumGroupItem.SONG_COUNT: case AlbumGroupItem.SONG_COUNT:
return metadata.songCount > 0 ? ( return metadata.songCount > 0 ? (
<Text size="xs">{t('entity.trackWithCount', { count: metadata.songCount })}</Text> <MetadataTextContainer>
<Text {...metadataTextProps}>
{t('entity.trackWithCount', { count: metadata.songCount })}
</Text>
</MetadataTextContainer>
) : null; ) : null;
default: default: