Merge pull request #227 from sambecker/custom-matte-colors

Matte color configuration
This commit is contained in:
Sam Becker 2025-03-29 13:41:05 -05:00 committed by GitHub
commit 348e4db25c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 59 additions and 6 deletions

View File

@ -125,7 +125,7 @@ Application behavior can be changed by configuring the following environment var
#### Visual
- `NEXT_PUBLIC_DEFAULT_THEME = light | dark` sets preferred initial theme (defaults to `system` when not configured)
- `NEXT_PUBLIC_MATTE_PHOTOS = 1` constrains the size of each photo, and displays a surrounding border (potentially useful for photos with tall aspect ratios)
- `NEXT_PUBLIC_MATTE_PHOTOS = 1` constrains the size of each photo, and displays a surrounding border, potentially useful for photos with tall aspect ratios (colors can be customized via `NEXT_PUBLIC_MATTE_COLOR` + `NEXT_PUBLIC_MATTE_COLOR_DARK`)
#### Display
- `NEXT_PUBLIC_CATEGORY_VISIBILITY`

View File

@ -23,6 +23,7 @@ import ShareModals from '@/share/ShareModals';
import AdminUploadPanel from '@/admin/upload/AdminUploadPanel';
import { revalidatePath } from 'next/cache';
import RecipeModal from '@/recipe/RecipeModal';
import ThemeColors from '@/app/ThemeColors';
import '../tailwind.css';
@ -79,6 +80,7 @@ export default function RootLayout({
'3xl:flex flex-col items-center',
)}>
<AppStateProvider>
<ThemeColors />
<ThemeProvider attribute="class" defaultTheme={DEFAULT_THEME}>
<SwrConfigClient>
<div className={clsx(

View File

@ -71,6 +71,8 @@ export default function AdminAppConfigurationClient({
hasDefaultTheme,
defaultTheme,
arePhotosMatted,
matteColor,
matteColorDark,
// Display
categoryVisibility,
hasCategoryVisibility,
@ -114,8 +116,8 @@ export default function AdminAppConfigurationClient({
}) {
const renderEnvVars = (variables: string[]) =>
<div className="pt-1 flex flex-col gap-1">
{variables.map(envVar =>
<EnvVar key={envVar} variable={envVar} />)}
{variables.map(variable =>
<EnvVar key={variable} variable={variable} />)}
</div>;
const renderSubStatus = (
@ -478,7 +480,23 @@ export default function AdminAppConfigurationClient({
Set environment variable to {'"1"'} to constrain the size
{' '}
of each photo, and display a surrounding border:
{renderEnvVars(['NEXT_PUBLIC_MATTE_PHOTOS'])}
<div className="pt-1 flex flex-col gap-1">
<EnvVar variable="NEXT_PUBLIC_MATTE_PHOTOS" />
<EnvVar
variable="NEXT_PUBLIC_MATTE_COLOR"
accessory={matteColor && <span
className="size-[15px] border-medium rounded-sm ml-1"
style={{ backgroundColor: matteColor }}
/>}
/>
<EnvVar
variable="NEXT_PUBLIC_MATTE_COLOR_DARK"
accessory={matteColorDark && <span
className="size-[15px] border-medium rounded-sm ml-1"
style={{ backgroundColor: matteColorDark }}
/>}
/>
</div>
</ChecklistRow>
</ChecklistGroup>
<ChecklistGroup

14
src/app/ThemeColors.tsx Normal file
View File

@ -0,0 +1,14 @@
'use client';
import { MATTE_COLOR, MATTE_COLOR_DARK } from './config';
export default function ThemeColors() {
return (<>
{MATTE_COLOR && <style jsx global>{`
:root { --matte-bg: ${MATTE_COLOR}; }
`}</style>}
{MATTE_COLOR_DARK && <style jsx global>{`
:root { --matte-bg-dark: ${MATTE_COLOR_DARK}; }
`}</style>}
</>);
}

View File

@ -232,6 +232,10 @@ export const DEFAULT_THEME =
: 'system';
export const MATTE_PHOTOS =
process.env.NEXT_PUBLIC_MATTE_PHOTOS === '1';
export const MATTE_COLOR =
process.env.NEXT_PUBLIC_MATTE_COLOR;
export const MATTE_COLOR_DARK =
process.env.NEXT_PUBLIC_MATTE_COLOR_DARK;
// DISPLAY
@ -350,6 +354,8 @@ export const APP_CONFIGURATION = {
hasDefaultTheme: Boolean(process.env.NEXT_PUBLIC_DEFAULT_THEME),
defaultTheme: DEFAULT_THEME,
arePhotosMatted: MATTE_PHOTOS,
matteColor: MATTE_COLOR,
matteColorDark: MATTE_COLOR_DARK,
// Display
hasCategoryVisibility:
Boolean(process.env.NEXT_PUBLIC_CATEGORY_VISIBILITY),

View File

@ -5,12 +5,14 @@ import CopyButton from './CopyButton';
export default function EnvVar({
variable,
value,
accessory,
includeCopyButton = true,
trailingContent,
className,
}: {
variable: string,
value?: string,
accessory?: ReactNode,
includeCopyButton?: boolean,
trailingContent?: ReactNode,
className?: string,
@ -33,6 +35,7 @@ export default function EnvVar({
)}>
{variable}{value && ` = ${value}`}
</span>
{accessory}
{includeCopyButton &&
<span className="translate-y-[1px]">
<CopyButton

View File

@ -29,6 +29,8 @@ import {
SHOULD_PREFETCH_ALL_LINKS,
ALLOW_PUBLIC_DOWNLOADS,
SHOW_TAKEN_AT_TIME,
MATTE_COLOR,
MATTE_COLOR_DARK,
} from '@/app/config';
import AdminPhotoMenu from '@/admin/AdminPhotoMenu';
import { RevalidatePhoto } from './InfinitePhotoScroll';
@ -237,8 +239,16 @@ export default function PhotoLarge({
ariaLabel: `Admin menu for '${titleForPhoto(photo)}' photo`,
}} />;
const largePhotoContainerClassName = clsx(arePhotosMatted &&
'flex items-center justify-center aspect-3/2 bg-gray-100',
const largePhotoContainerClassName = clsx(
arePhotosMatted && 'flex items-center justify-center aspect-3/2',
// Matte theme colors defined in root layout
arePhotosMatted && (MATTE_COLOR
? 'bg-(--matte-bg)'
: 'bg-gray-100'),
arePhotosMatted && (MATTE_COLOR_DARK
? 'dark:bg-(--matte-bg-dark)'
// Only specify dark background when MATTE_COLOR is not configured
: !MATTE_COLOR && 'dark:bg-gray-700/30'),
);
return (