diff --git a/apps/nextjs/src/components/board/sections/content.tsx b/apps/nextjs/src/components/board/sections/content.tsx index 9c6e475d4..98eb2f9c2 100644 --- a/apps/nextjs/src/components/board/sections/content.tsx +++ b/apps/nextjs/src/components/board/sections/content.tsx @@ -1,6 +1,7 @@ import { useMemo } from "react"; import type { GridItemHTMLElement } from "@homarr/gridstack"; +import { WidgetSizeProvider } from "@homarr/widgets"; import type { DynamicSectionItem, SectionItem } from "~/app/[locale]/boards/_types"; import { BoardItemContent } from "../items/item-content"; @@ -59,7 +60,13 @@ const Item = ({ item, innerRef }: ItemProps) => { minWidth={minWidth} minHeight={minHeight} > - {item.type === "item" ? : } + {item.type === "item" ? ( + + + + ) : ( + + )} ); }; diff --git a/packages/widgets/src/index.tsx b/packages/widgets/src/index.tsx index 5e66efc4f..9aa0d2c73 100644 --- a/packages/widgets/src/index.tsx +++ b/packages/widgets/src/index.tsx @@ -53,6 +53,7 @@ import * as weather from "./weather"; export type { WidgetDefinition, WidgetOptionsSettings } from "./definition"; export type { WidgetComponentProps }; +export { useWidgetSize, WidgetSizeProvider } from "./widget-size"; export const widgetImports = { clock, diff --git a/packages/widgets/src/weather/component.tsx b/packages/widgets/src/weather/component.tsx index f81736c27..2c0238fac 100644 --- a/packages/widgets/src/weather/component.tsx +++ b/packages/widgets/src/weather/component.tsx @@ -11,6 +11,7 @@ import { metricToImperial } from "@homarr/common"; import { useScopedI18n } from "@homarr/translation/client"; import type { WidgetComponentProps } from "../definition"; +import { useWidgetSize } from "../widget-size"; import { WeatherDescription, WeatherIcon } from "./icon"; export default function WeatherWidget({ isEditMode, options }: WidgetComponentProps<"weather">) { @@ -29,19 +30,23 @@ export default function WeatherWidget({ isEditMode, options }: WidgetComponentPr onData: (data) => utils.widget.weather.atLocation.setData(input, data), }); + const { gridWidth, gridHeight } = useWidgetSize(); + const isCompact = gridWidth <= 1 || gridHeight <= 1; + const showForecast = options.hasForecast && !isCompact; + return ( - {options.hasForecast ? ( + {showForecast ? ( ) : ( - + )} ); @@ -51,24 +56,28 @@ interface WeatherProps extends Pick, "options"> weather: RouterOutputs["widget"]["weather"]["atLocation"]; } -const DailyWeather = ({ options, weather }: WeatherProps) => { +const DailyWeather = ({ options, weather, compact }: WeatherProps & { compact?: boolean }) => { const t = useScopedI18n("widget.weather"); const tCommon = useScopedI18n("common"); + const iconSize = compact ? 20 : 30; + const tempSize = compact ? 20 : 30; + const detailSize = compact ? 13 : 16; + return ( <> - + - + {getPreferredUnit( weather.current.temperature, options.isFormatFahrenheit, @@ -77,10 +86,10 @@ const DailyWeather = ({ options, weather }: WeatherProps) => { - {options.showCurrentWindSpeed && ( + {options.showCurrentWindSpeed && !compact && ( - - + + {t("currentWindSpeed", { currentWindSpeed: (options.useImperialSpeed ? metricToImperial(weather.current.windspeed) @@ -95,8 +104,8 @@ const DailyWeather = ({ options, weather }: WeatherProps) => { )} - - + + {getPreferredUnit( weather.daily[0]?.maxTemp, options.isFormatFahrenheit, @@ -105,8 +114,8 @@ const DailyWeather = ({ options, weather }: WeatherProps) => { - - + + {getPreferredUnit( weather.daily[0]?.minTemp, options.isFormatFahrenheit, @@ -116,11 +125,11 @@ const DailyWeather = ({ options, weather }: WeatherProps) => { - {options.showCity && ( + {options.showCity && !compact && ( <> - - + + {options.location.name} diff --git a/packages/widgets/src/widget-size.tsx b/packages/widgets/src/widget-size.tsx new file mode 100644 index 000000000..b2031548c --- /dev/null +++ b/packages/widgets/src/widget-size.tsx @@ -0,0 +1,25 @@ +"use client"; + +import type { ReactNode } from "react"; +import { createContext, useContext } from "react"; + +export interface WidgetSize { + gridWidth: number; + gridHeight: number; +} + +const WidgetSizeContext = createContext(null); + +export const useWidgetSize = () => { + const ctx = useContext(WidgetSizeContext); + if (!ctx) throw new Error("useWidgetSize must be used within WidgetSizeProvider"); + return ctx; +}; + +interface WidgetSizeProviderProps extends WidgetSize { + children: ReactNode; +} + +export const WidgetSizeProvider = ({ gridWidth, gridHeight, children }: WidgetSizeProviderProps) => ( + {children} +);