GlassKit UI
Primitives

WeatherTile

A glanceable weather complication: a condition glyph + big temperature, the condition, and an optional location / hi-lo line. A popping surface.

72°
SunnySan Francisco · H:78° L:61°

Installation

npx @glasskit-ui/cli add weather-tile

Install the SDK (it provides GlassViewport, useDpad and the stylesheet), then copy these files into your project:

npm install @glasskit-ui/react
// components/lib/utils.tsimport { clsx, type ClassValue } from "clsx";import { twMerge } from "tailwind-merge";export type { ClassValue };/** * Merge class names the shadcn way: clsx joins conditionals, tailwind-merge * de-dupes conflicting Tailwind utilities so a consumer's `className` override * wins (e.g. passing `px-2` beats the component's `px-6`). Lens components are * Tailwind utilities + `--gk-*` tokens, so this de-dupe matters. */export function cn(...inputs: ClassValue[]): string {  return twMerge(clsx(inputs));}/** * Accessible name from a free-form `label` prop: the label itself when it's a * plain string, otherwise undefined (a ReactNode can't become an aria-label). */export function stringLabel(label: unknown): string | undefined {  return typeof label === "string" ? label : undefined;}
// components/glasskit/weather-tile.tsximport type { ReactNode } from "react";import { cn } from "../lib/utils";/** * <WeatherTile> — a glanceable weather complication: a condition glyph + big * temperature, the condition text, and an optional location / hi-lo line. A * popping surface; pure display. */export function WeatherTile({  temp,  condition,  icon,  location,  range,  className,}: {  temp: ReactNode;  condition?: ReactNode;  /** Condition glyph — typically a <Icon>. */  icon?: ReactNode;  location?: ReactNode;  /** Hi / lo, e.g. "H:78° L:61°". */  range?: ReactNode;  className?: string;}) {  return (    <div      className={cn(        "surface flex w-full flex-col items-start gap-1.5 rounded-[22px] px-[22px] py-5",        className,      )}    >      <div className="flex items-center gap-3.5">        {icon != null ? (          <span className="[&_.gk-icon]:size-11 [&_.gk-icon]:text-[#ffd66b] [&_.gk-icon]:[filter:drop-shadow(0_0_8px_rgba(255,214,107,0.4))]">            {icon}          </span>        ) : null}        <span className="text-[56px] font-bold leading-none [font-variant-numeric:tabular-nums]">          {temp}        </span>      </div>      {condition != null ? (        <span className="t-body text-muted-foreground">{condition}</span>      ) : null}      {location != null || range != null ? (        <span className="t-caption text-foreground-faint">          {location}          {location != null && range != null ? " · " : null}          {range}        </span>      ) : null}    </div>  );}

Usage

<WeatherTile  icon={<Icon size="lg"><SunIcon /></Icon>}  temp="72°" condition="Sunny" location="San Francisco" range="H:78° L:61°"/>

Props

PropTypeDefaultDescription
tempReactNodeTemperature.
conditionReactNodeCondition text.
iconReactNodeCondition glyph.
location / rangeReactNodePlace · hi-lo line.

On this page