Landing Zone
Cards for high-level information as a first touch point in a dashboard.
Card + Callout + ProgressBar + List
Issues solved
338
/ 450
Resolving 6x more issues than receiving
45 days until all issues are solved with the current cadence and income rate. Keep going, you got this!
Solved
338 (75%)
Open
112 (25%)
Open issues
Topic
- Issue #249 Input bar
- Issue #142 Custom colors
- Issue #136 Button loading state
- Issue #129 minValue for Charts
- Issue #128 Dark mode support
- Issue #124 className props
import { Bold, Button, Callout, Card, Flex, List, ListItem, Metric, ProgressBar, Text, } from "@tremor/react"; import { ArrowNarrowRightIcon, TrendingUpIcon } from "@heroicons/react/solid"; interface Issues { issue: string; topic: string; } const issues: Issues[] = [ { issue: "Issue #249", topic: "Input bar", }, { issue: "Issue #142", topic: "Custom colors", }, { issue: "Issue #136", topic: "Button loading state", }, { issue: "Issue #129", topic: "minValue for Charts", }, { issue: "Issue #128", topic: "Dark mode support", }, { issue: "Issue #124", topic: "className props", }, ]; export default function Example() { return ( <Card className="max-w-md mx-auto"> <Text> Issues solved </Text> <Flex justifyContent="start" className="space-x-1" alignItems="baseline"> <Metric> 338 </Metric> <Text>/ 450</Text> </Flex> <Callout title="Resolving 6x more issues than receiving" icon={TrendingUpIcon} color="emerald" className="mt-6" > 45 days until all issues are solved with the current cadence and income rate. Keep going, you got this! </Callout> <ProgressBar percentageValue={75} color="emerald" className="mt-6" /> <Flex className="mt-4"> <div> <Text>Solved</Text> <Text color="emerald"> <Bold>338</Bold> (75%){" "} </Text> </div> <div> <Text className="text-right">Open</Text> <Text className="text-right"> <Bold>112</Bold> (25%){" "} </Text> </div> </Flex> <Flex className="mt-6"> <Text> <Bold>Open issues</Bold> </Text> <Text> <Bold>Topic</Bold> </Text> </Flex> <List className="mt-1"> {issues.map((item) => ( <ListItem key={item.issue}> <span> {item.issue} </span> <span> {item.topic} </span> </ListItem> ))} </List> <Flex className="mt-6 pt-4 border-t"> <Button size="xs" variant="light" icon={ArrowNarrowRightIcon} iconPosition="right" > View more </Button> </Flex> </Card> ); }
Card + DataBars + Flex
Zurich
Vienna
On time
10:40
Platform 2
7H 50M
18:30
No Reservation
Vienna
St. Anton am Arlberg
Delayed
13:30
Sched. 13:30
19:40
Sched. 18:55
+45 minutes behind plan
Due to maintenance work, we have a minor delay. If you need assistance with your travels today please contact the info hotline.
Nightjet Direction Bregenz
22:55
10:22
1st
2nd
11H 22M
22:55 Vienna
07:49 Feldkirch
Pl. 1
Pl. 9
08:05 Feldkirch
08:28 Buchs SG
Pl. 7
Pl. 3
08:30 Buchs SG
10:22 Zurich HB
Pl. 5
Pl. 6
import { Callout, Card, Text, Flex, CategoryBar, Grid, Icon, Title, Bold, ProgressBar, List, ListItem, } from "@tremor/react"; import { ChevronDoubleRightIcon, ExclamationIcon, MoonIcon, UserIcon, UserGroupIcon, } from "@heroicons/react/solid"; export default function Example() { return ( <Grid numColsSm={1} numColsLg={1} className="gap-4 "> <Card className="max-w-md mx-auto"> <Flex className="truncate" justifyContent="between"> <Flex className="truncate" justifyContent="start"> <Text> <Bold>Zurich</Bold> </Text> <Icon variant="simple" icon={ChevronDoubleRightIcon} size="xs" color="slate" /> <Text className="truncate"> <Bold>Vienna</Bold> </Text> </Flex> <Text color="indigo"> <Bold>On time</Bold> </Text> </Flex> <ProgressBar color="indigo" percentageValue={61} className="mt-3" /> <Flex justifyContent="between" className="mt-3"> <div> <Title>10:40</Title> <Text>Platform 2</Text> </div> <div> <Text className="text-center">7H 50M</Text> </div> <div className="text-right"> <Title>18:30</Title> <Text className="text-right">No Reservation</Text> </div> </Flex> </Card> <Card className="max-w-md mx-auto"> <Flex className="truncate" justifyContent="between"> <Flex className="truncate" justifyContent="start"> <Text> <Bold>Vienna</Bold> </Text> <Icon variant="simple" icon={ChevronDoubleRightIcon} size="xs" color="slate" /> <Text className="truncate"> <Bold>St. Anton am Arlberg </Bold> </Text> </Flex> <Text color="rose"> <Bold>Delayed</Bold> </Text> </Flex> <ProgressBar percentageValue={65} showAnimation={true} color="rose" className="mt-3" /> <Flex justifyContent="between" className="mt-3"> <div> <Title> 13:30 </Title> <Text> Sched. 13:30 </Text> </div> <div className="text-right"> <Title> 19:40 </Title> <Text className="text-right"> Sched. 18:55 </Text> </div> </Flex> <Callout title="+45 minutes behind plan" icon={ExclamationIcon} color="rose" className="mt-6" > Due to maintenance work, we have a minor delay. If you need assistance with your travels today please contact the info hotline. </Callout> </Card> <Card className="max-w-md mx-auto"> <Flex justifyContent="start"> <Text> <Bold> Nightjet Direction Bregenz </Bold> </Text> <Icon variant="simple" icon={MoonIcon} size="xs" color="slate" /> </Flex> <Flex justifyContent="between" className="mt-3 space-x-3"> <Title> 22:55 </Title> <div className="w-full"> <CategoryBar categoryPercentageValues={[75, 15, 10]} percentageValue={75} colors={["yellow", "gray", "gray"]} showLabels={false} /> </div> <Title> 10:22 </Title> </Flex> <Flex className="mt-3"> <div> <Flex alignItems="baseline" justifyContent="start" className="space-x-2" > <Flex justifyContent="start" alignItems="baseline"> <Text>1st</Text> <Icon variant="simple" icon={UserIcon} size="xs" color="slate" /> </Flex> <Flex justifyContent="start" alignItems="baseline"> <Text>2nd</Text> <Icon variant="simple" icon={UserGroupIcon} size="xs" color="slate" /> </Flex> </Flex> </div> <Text>11H 22M</Text> </Flex> <List className="mt-4"> <ListItem> <div> <Text> <Bold>22:55</Bold> Vienna{" "} </Text> <Text> <Bold>07:49</Bold> Feldkirch{" "} </Text> </div> <div> <Text className="text-right"> <Bold>Pl. 1</Bold>{" "} </Text> <Text className="text-right"> <Bold>Pl. 9</Bold>{" "} </Text> </div> </ListItem> <ListItem> <div> <Text> <Bold>08:05</Bold> Feldkirch{" "} </Text> <Text> <Bold>08:28</Bold> Buchs SG{" "} </Text> </div> <div> <Text className="text-right"> <Bold>Pl. 7</Bold>{" "} </Text> <Text className="text-right"> <Bold>Pl. 3</Bold>{" "} </Text> </div> </ListItem> <ListItem> <div> <Text> <Bold>08:30</Bold> Buchs SG{" "} </Text> <Text> <Bold>10:22</Bold> Zurich HB{" "} </Text> </div> <div> <Text className="text-right"> <Bold>Pl. 5</Bold>{" "} </Text> <Text className="text-right"> <Bold>Pl. 6</Bold>{" "} </Text> </div> </ListItem> </List> </Card> </Grid> ); }
Card + Metric + CallOut
Sales
$ 23,456
Performing as usual
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod.
Profit
$ 12,789
Immediate action required
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod.
Customers
456
Critical performance
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod.
Orders
1,789
Performing as usual
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod.
import { Card, Metric, Text, Flex, Button, Callout, Grid } from "@tremor/react"; import { CogIcon, ShieldExclamationIcon, CheckCircleIcon, ArrowNarrowRightIcon, } from "@heroicons/react/solid"; const categories = [ { title: "Sales", metric: "$ 23,456", text: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod.", status: "Performing as usual", color: "emerald", }, { title: "Profit", metric: "$ 12,789", text: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod.", status: "Immediate action required", }, { title: "Customers", metric: "456", text: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod.", status: "Critical performance", }, { title: "Orders", metric: "1,789", text: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod.", status: "Performing as usual", }, ]; const statusMapping: { [key: string]: any } = { "Performing as usual": { icon: CheckCircleIcon, color: "emerald" }, "Immediate action required": { icon: ShieldExclamationIcon, color: "rose" }, "Critical performance": { icon: CogIcon, color: "amber" }, }; export default function Example() { return ( <Grid numColsSm={2} className="gap-6"> {categories.map((item) => ( <Card key={item.title}> <Text>{item.title}</Text> <Metric>{item.metric}</Metric> <Callout className="mt-6" title={item.status} icon={statusMapping[item.status].icon} color={statusMapping[item.status].color} > {item.text} </Callout> <Flex className="mt-6 pt-4 border-t"> <Button size="xs" variant="light" icon={ArrowNarrowRightIcon} iconPosition="right" > View more </Button> </Flex> </Card> ))} </Grid> ); }
Card + Icon
Sales
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
Profit
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
Customers
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
Orders
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
import { Card, Text, Button, Icon, Flex, Title, Grid } from "@tremor/react"; import { ShoppingBagIcon, CashIcon, UsersIcon, ShoppingCartIcon, ArrowNarrowRightIcon, } from "@heroicons/react/solid"; const categories = [ { title: "Sales", text: `Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.`, icon: ShoppingBagIcon, }, { title: "Profit", text: `Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.`, icon: CashIcon, }, { title: "Customers", text: `Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.`, icon: UsersIcon, }, { title: "Orders", text: `Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.`, icon: ShoppingCartIcon, }, ]; export default function Example() { return ( <Grid numColsSm={2} className="gap-6"> {categories.map((item) => ( <Card key={item.title}> <Icon variant="light" icon={item.icon} size="lg" color="blue" /> <Title className="mt-6">{item.title}</Title> <Text className="mt-2">{item.text}</Text> <Flex className="mt-6 pt-4 border-t"> <Button size="xs" variant="light" icon={ArrowNarrowRightIcon} iconPosition="right" > View more </Button> </Flex> </Card> ))} </Grid> ); }
Card + Dropdown + ListBar
Sources
Source
Visits
456
271
191
185
91
/* eslint-disable max-len */ import { Title, Text, Card, Flex, Dropdown, DropdownItem, Bold, BarList, } from "@tremor/react"; import { JSXElementConstructor, useEffect, useState } from "react"; const categories = [ { key: "all", name: "All" }, { key: "socials", name: "Socials" }, { key: "devTools", name: "Dev Tools" }, { key: "organic", name: "Organic" }, ]; interface VisitsData { name: string; value: number; category: string; icon: JSXElementConstructor<any>; } const visits: VisitsData[] = [ { name: "Google", value: 456, category: "organic", icon: function GoogleIcon() { return ( <svg xmlns="http://www.w3.org/2000/svg" className="mr-2.5 fill-slate-500" viewBox="0 0 24 24" width="20" height="20" > <path fill="none" d="M0 0h24v24H0z" /> <path d="M3.064 7.51A9.996 9.996 0 0 1 12 2c2.695 0 4.959.99 6.69 2.605l-2.867 2.868C14.786 6.482 13.468 5.977 12 5.977c-2.605 0-4.81 1.76-5.595 4.123-.2.6-.314 1.24-.314 1.9 0 .66.114 1.3.314 1.9.786 2.364 2.99 4.123 5.595 4.123 1.345 0 2.49-.355 3.386-.955a4.6 4.6 0 0 0 1.996-3.018H12v-3.868h9.418c.118.654.182 1.336.182 2.045 0 3.046-1.09 5.61-2.982 7.35C16.964 21.105 14.7 22 12 22A9.996 9.996 0 0 1 2 12c0-1.614.386-3.14 1.064-4.49z" /> </svg> ); }, }, { name: "GitHub", value: 271, category: "devTools", icon: function GitHubIcon() { return ( <svg xmlns="http://www.w3.org/2000/svg" className="mr-2.5 fill-slate-900" viewBox="0 0 24 24" width="20" height="20" > <path fill="none" d="M0 0h24v24H0z" /> <path d="M12 2C6.475 2 2 6.475 2 12a9.994 9.994 0 0 0 6.838 9.488c.5.087.687-.213.687-.476 0-.237-.013-1.024-.013-1.862-2.512.463-3.162-.612-3.362-1.175-.113-.288-.6-1.175-1.025-1.413-.35-.187-.85-.65-.013-.662.788-.013 1.35.725 1.538 1.025.9 1.512 2.338 1.087 2.912.825.088-.65.35-1.087.638-1.337-2.225-.25-4.55-1.113-4.55-4.938 0-1.088.387-1.987 1.025-2.688-.1-.25-.45-1.275.1-2.65 0 0 .837-.262 2.75 1.026a9.28 9.28 0 0 1 2.5-.338c.85 0 1.7.112 2.5.337 1.912-1.3 2.75-1.024 2.75-1.024.55 1.375.2 2.4.1 2.65.637.7 1.025 1.587 1.025 2.687 0 3.838-2.337 4.688-4.562 4.938.362.312.675.912.675 1.85 0 1.337-.013 2.412-.013 2.75 0 .262.188.574.688.474A10.016 10.016 0 0 0 22 12c0-5.525-4.475-10-10-10z" /> </svg> ); }, }, { name: "Twitter", value: 191, category: "socials", icon: function GoogleIcon() { return ( <svg xmlns="http://www.w3.org/2000/svg" className="mr-2.5 fill-blue-500" viewBox="0 0 24 24" width="20" height="20" > <path fill="none" d="M0 0h24v24H0z" /> <path d="M22.162 5.656a8.384 8.384 0 0 1-2.402.658A4.196 4.196 0 0 0 21.6 4c-.82.488-1.719.83-2.656 1.015a4.182 4.182 0 0 0-7.126 3.814 11.874 11.874 0 0 1-8.62-4.37 4.168 4.168 0 0 0-.566 2.103c0 1.45.738 2.731 1.86 3.481a4.168 4.168 0 0 1-1.894-.523v.052a4.185 4.185 0 0 0 3.355 4.101 4.21 4.21 0 0 1-1.89.072A4.185 4.185 0 0 0 7.97 16.65a8.394 8.394 0 0 1-6.191 1.732 11.83 11.83 0 0 0 6.41 1.88c7.693 0 11.9-6.373 11.9-11.9 0-.18-.005-.362-.013-.54a8.496 8.496 0 0 0 2.087-2.165z" /> </svg> ); }, }, { name: "Reddit", value: 185, category: "socials", icon: function RedditIcon() { return ( <svg xmlns="http://www.w3.org/2000/svg" className="mr-2.5 fill-orange-500" viewBox="0 0 24 24" width="20" height="20" > <path fill="none" d="M0 0h24v24H0z" /> <path d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm6.67-10a1.46 1.46 0 0 0-2.47-1 7.12 7.12 0 0 0-3.85-1.23L13 6.65l2.14.45a1 1 0 1 0 .13-.61L12.82 6a.31.31 0 0 0-.37.24l-.74 3.47a7.14 7.14 0 0 0-3.9 1.23 1.46 1.46 0 1 0-1.61 2.39 2.87 2.87 0 0 0 0 .44c0 2.24 2.61 4.06 5.83 4.06s5.83-1.82 5.83-4.06a2.87 2.87 0 0 0 0-.44 1.46 1.46 0 0 0 .81-1.33zm-10 1a1 1 0 1 1 2 0 1 1 0 0 1-2 0zm5.81 2.75a3.84 3.84 0 0 1-2.47.77 3.84 3.84 0 0 1-2.47-.77.27.27 0 0 1 .38-.38A3.27 3.27 0 0 0 12 16a3.28 3.28 0 0 0 2.09-.61.28.28 0 1 1 .39.4v-.04zm-.18-1.71a1 1 0 1 1 1-1 1 1 0 0 1-1.01 1.04l.01-.04z" /> </svg> ); }, }, { name: "Youtube", value: 91, category: "socials", icon: function YouTubeIcon() { return ( <svg xmlns="http://www.w3.org/2000/svg" className="mr-2.5 fill-red-500" viewBox="0 0 24 24" width="20" height="20" > <path fill="none" d="M0 0h24v24H0z" /> <path d="M21.543 6.498C22 8.28 22 12 22 12s0 3.72-.457 5.502c-.254.985-.997 1.76-1.938 2.022C17.896 20 12 20 12 20s-5.893 0-7.605-.476c-.945-.266-1.687-1.04-1.938-2.022C2 15.72 2 12 2 12s0-3.72.457-5.502c.254-.985.997-1.76 1.938-2.022C6.107 4 12 4 12 4s5.896 0 7.605.476c.945.266 1.687 1.04 1.938 2.022zM10 15.5l6-3.5-6-3.5v7z" /> </svg> ); }, }, ]; const filterByCategory = (category: string, data: VisitsData[]) => category === "all" ? data : data.filter((item) => item.category === category); export default function Example() { const [selectedCategory, setSelectedCategory] = useState("all"); const [filteredData, setFilteredData] = useState(visits); useEffect(() => { setFilteredData(filterByCategory(selectedCategory, visits)); }, [selectedCategory]); return ( <Card className="max-w-md mx-auto"> <Flex className="space-x-8"> <Title>Sources</Title> <Dropdown onValueChange={(value) => setSelectedCategory(value)} placeholder="Source Selection" className="max-w-xs" > {categories.map((category) => ( <DropdownItem key={category.key} value={category.key} text={category.name} /> ))} </Dropdown> </Flex> <Flex className="mt-8"> <Text> <Bold>Source</Bold> </Text> <Text> <Bold>Visits</Bold> </Text> </Flex> <BarList data={filteredData} showAnimation={false} className="mt-4" /> </Card> ); }
Card + Tabs + ListBar
Page Visits by Audience
Site
Visits
652
542
234
134
12
7
import { useState } from "react"; import { Title, Text, Card, Flex, Tab, TabList, Bold, BarList, } from "@tremor/react"; import { CodeIcon, TableIcon } from "@heroicons/react/solid"; const categories = [ { key: "developers", name: "Developers", icon: CodeIcon }, { key: "analysts", name: "Analysts", icon: TableIcon }, ]; const developerVisits = [ { name: "/home", value: 652 }, { name: "/about", value: 134 }, { name: "/docs", value: 542 }, { name: "/tempates", value: 234 }, { name: "/terms", value: 12 }, { name: "/refund", value: 7 }, ]; const analystVisits = [ { name: "/home", value: 456 }, { name: "/about", value: 271 }, { name: "/docs", value: 46 }, { name: "/templates", value: 191 }, { name: "/terms", value: 82 }, { name: "/refund", value: 15 }, ]; const visits: { [key: string]: any } = { developers: developerVisits, analysts: analystVisits, }; const sortData = (data: any[]) => data.sort((a, b) => { if (a.value < b.value) return 1; if (a.value > b.value) return -1; return 0; }); export default function Example() { const [selectedCategory, setSelectedCategory] = useState("developers"); return ( <Card className="max-w-md mx-auto"> <Title>Page Visits by Audience</Title> <TabList onValueChange={(value) => setSelectedCategory(value)} defaultValue={selectedCategory} className="mt-6" > {categories.map((category) => ( <Tab key={category.key} value={category.key} icon={category.icon} text={category.name} /> ))} </TabList> <Flex className="mt-6"> <Text> <Bold>Site</Bold> </Text> <Text> <Bold>Visits</Bold> </Text> </Flex> <BarList data={sortData(visits[selectedCategory])} showAnimation={false} className="mt-4" /> </Card> ); }
Card + DonutChart + Legend + Dropdown + List
Sales
New York
London
San Francisco
Hong Kong
Singapore
Zurich
Vienna
- New York
6.1%
- London
1.2%
- San Francisco
2.3%
- Hong Kong
0.5%
- Singapore
1.8%
- Zurich
3.4%
- Vienna
3.1%
import { BadgeDelta, Card, DeltaType, DonutChart, Dropdown, DropdownItem, Flex, Legend, List, ListItem, Title, } from "@tremor/react"; import { useEffect, useState } from "react"; const regions = [ { key: "all", name: "All Regions" }, { key: "us", name: "United States" }, { key: "europe", name: "Europe" }, { key: "asia", name: "Asia" }, ]; interface CityData { name: string; region: string; sales: number; delta: string; deltaType: DeltaType; } const cities: CityData[] = [ { name: "New York", region: "us", sales: 984888, delta: "6.1%", deltaType: "increase", }, { name: "London", region: "europe", sales: 456700, delta: "1.2%", deltaType: "moderateDecrease", }, { name: "San Francisco", region: "us", sales: 240000, delta: "2.3%", deltaType: "moderateIncrease", }, { name: "Hong Kong", region: "asia", sales: 390800, delta: "0.5%", deltaType: "moderateDecrease", }, { name: "Singapore", region: "asia", sales: 190800, delta: "1.8%", deltaType: "moderateIncrease", }, { name: "Zurich", region: "europe", sales: 164400, delta: "3.4%", deltaType: "decrease", }, { name: "Vienna", region: "europe", sales: 139800, delta: "3.1%", deltaType: "moderateIncrease", }, ]; const valueFormatter = (number: number) => `${Intl.NumberFormat("us").format(number).toString()} $`; const filterByRegion = (region: string, data: CityData[]) => region === "all" ? data : data.filter((city) => city.region === region); export default function Example() { const [selectedRegion, setSelectedRegion] = useState("all"); const [filteredData, setFilteredData] = useState(cities); useEffect(() => { const data = cities; setFilteredData(filterByRegion(selectedRegion, data)); }, [selectedRegion]); return ( <Card className="max-w-md mx-auto"> <Flex className="space-x-8" justifyContent="start" alignItems="center"> <Title>Sales</Title> <Dropdown onValueChange={(value) => setSelectedRegion(value)} placeholder="Region Selection" > {regions.map((region) => ( <DropdownItem key={region.key} value={region.key} text={region.name} /> ))} </Dropdown> </Flex> <Legend categories={filteredData.map((city) => city.name)} className="mt-6" /> <DonutChart data={filteredData} category="sales" index="name" valueFormatter={valueFormatter} className="mt-6" /> <List className="mt-6"> {filteredData.map((city) => ( <ListItem key={city.name}> {city.name} <BadgeDelta deltaType={city.deltaType} size="xs"> {city.delta} </BadgeDelta> </ListItem> ))} </List> </Card> ); }
Card + DonutChart + Metric + Toggle + List + BadgeDelta
Overview
Portfolio value
$ 25,465
Asset Allocation
1 Asset class • 5 Holdings
import { BadgeDelta, Button, Card, DeltaType, DonutChart, Flex, Toggle, ToggleItem, Bold, Divider, List, ListItem, Metric, Text, Title, } from "@tremor/react"; import { ViewListIcon, ChartPieIcon } from "@heroicons/react/outline"; import { ArrowNarrowRightIcon } from "@heroicons/react/solid"; import { useState } from "react"; interface StockData { name: string; value: number; performance: string; deltaType: DeltaType; } const stocks: StockData[] = [ { name: "Off Running AG", value: 10456, performance: "6.1%", deltaType: "increase", }, { name: "Not Normal Inc.", value: 5789, performance: "1.2%", deltaType: "moderateDecrease", }, { name: "Logibling Inc.", value: 4367, performance: "2.3%", deltaType: "moderateIncrease", }, { name: "Raindrop Inc.", value: 3421, performance: "0.5%", deltaType: "moderateDecrease", }, { name: "Mwatch Group", value: 1432, performance: "3.4%", deltaType: "decrease", }, ]; const valueFormatter = (number: number) => `$ ${Intl.NumberFormat("us").format(number).toString()}`; export default function Example() { const [selectedView, setSelectedView] = useState("chart"); return ( <Card className="max-w-md mx-auto"> <Flex className="space-x-8" justifyContent="between" alignItems="center"> <Title>Overview</Title> <Toggle defaultValue="chart" color="gray" onValueChange={(value) => setSelectedView(value)} > <ToggleItem value="chart" icon={ChartPieIcon} /> <ToggleItem value="list" icon={ViewListIcon} /> </Toggle> </Flex> <Text className="mt-8">Portfolio value</Text> <Metric>$ 25,465</Metric> <Divider /> <Text className="mt-8"> <Bold>Asset Allocation</Bold> </Text> <Text>1 Asset class • 5 Holdings</Text> {selectedView === "chart" ? ( <DonutChart data={stocks} showAnimation={false} category="value" index="name" valueFormatter={valueFormatter} className="mt-6" /> ) : ( <> <Flex className="mt-8" justifyContent="between"> <Text className="truncate"> <Bold>Stocks</Bold> </Text> <Text>Since transaction</Text> </Flex> <List className="mt-4"> {stocks.map((stock) => ( <ListItem key={stock.name}> <Text>{stock.name}</Text> <Flex justifyContent="end" className="space-x-2"> <Text> $ {Intl.NumberFormat("us").format(stock.value).toString()} </Text> <BadgeDelta deltaType={stock.deltaType} size="xs"> {stock.performance} </BadgeDelta> </Flex> </ListItem> ))} </List> </> )} <Flex className="mt-6 pt-4 border-t"> <Button size="xs" variant="light" icon={ArrowNarrowRightIcon} iconPosition="right" > View more </Button> </Flex> </Card> ); }
Card + Tabs + ProgressBar + BadgeDelta + InlineButton
Total Sales
23.1%
$ 442,276
from $ 382,482
Product A
38% ($ 100,838)
Product B
34% ($ 90,224)
Product C
28% ($ 74,301)
import { Card, TabList, Tab, ProgressBar, Text, Flex, Button, Metric, BadgeDelta, } from "@tremor/react"; import { ArrowNarrowRightIcon } from "@heroicons/react/solid"; import { useState } from "react"; const products: { [key: string]: any } = [ { title: "Product A", percentageValue: 38, metric: "$ 100,838", location: "A", }, { title: "Product B", percentageValue: 34, metric: "$ 90,224", location: "A", }, { title: "Product C", percentageValue: 28, metric: "$ 74,301", location: "A", }, { title: "Product Z", percentageValue: 82, metric: "$ 108,799", location: "B", }, { title: "Product E", percentageValue: 10, metric: "$ 13,268", location: "B", }, { title: "Product N", percentageValue: 8, metric: "$ 10,614", location: "B", }, ]; export default function Example() { const [selectedLocation, setSelectedLocation] = useState("A"); return ( <Card className="max-w-md mx-auto"> <Flex alignItems="start"> <Text>Total Sales</Text> <BadgeDelta deltaType="moderateIncrease">23.1%</BadgeDelta> </Flex> <Flex justifyContent="start" alignItems="baseline" className="space-x-3 truncate" > <Metric>$ 442,276</Metric> <Text>from $ 382,482</Text> </Flex> <TabList defaultValue="A" onValueChange={(value) => setSelectedLocation(value)} className="mt-6" > <Tab value="A" text="Location A" /> <Tab value="B" text="Location B" /> </TabList> {products .filter((item: any) => item.location === selectedLocation) .map((item: any) => ( <div key={item.title} className="space-y-2 mt-4"> <Flex> <Text>{item.title}</Text> <Text>{`${item.percentageValue}% (${item.metric})`}</Text> </Flex> <ProgressBar percentageValue={item.percentageValue} /> </div> ))} <Flex className="mt-6 pt-4 border-t"> <Button size="xs" variant="light" icon={ArrowNarrowRightIcon} iconPosition="right" > View more </Button> </Flex> </Card> ); }
Card + AreaChart + Tabs + ProgressBar + BadgeDelta + InlineButton
Total Sales
23.1%
$ 442,276
from $ 382,482
Product A
38% ($ 100,838)
Product B
34% ($ 90,224)
Product C
28% ($ 74,301)
import { Card, TabList, Tab, ProgressBar, Text, Flex, Button, Metric, BadgeDelta, AreaChart, } from "@tremor/react"; import { ArrowNarrowRightIcon } from "@heroicons/react/solid"; import { useState } from "react"; const sales = [ { Month: "Jan 21", Sales: 2890, }, { Month: "Feb 21", Sales: 1890, }, { Month: "Mar 21", Sales: 2190, }, { Month: "Apr 21", Sales: 3470, }, { Month: "May 21", Sales: 2170, }, { Month: "Jun 21", Sales: 3170, }, { Month: "Jul 21", Sales: 3490, }, { Month: "Aug 21", Sales: 2680, }, { Month: "Sep 21", Sales: 1290, }, { Month: "Oct 21", Sales: 1010, }, { Month: "Nov 21", Sales: 2350, }, { Month: "Dec 21", Sales: 3350, }, ]; const products: { [key: string]: any } = [ { title: "Product A", percentageValue: 38, metric: "$ 100,838", location: "A", }, { title: "Product B", percentageValue: 34, metric: "$ 90,224", location: "A", }, { title: "Product C", percentageValue: 28, metric: "$ 74,301", location: "A", }, { title: "Product Z", percentageValue: 82, metric: "$ 108,799", location: "B", }, { title: "Product E", percentageValue: 10, metric: "$ 13,268", location: "B", }, { title: "Product N", percentageValue: 8, metric: "$ 10,614", location: "B", }, ]; const valueFormatter = (number: number) => `$ ${Intl.NumberFormat("us").format(number).toString()}`; export default function Example() { const [selectedLocation, setSelectedLocation] = useState("A"); return ( <Card className="max-w-md mx-auto"> <Flex alignItems="start"> <Text>Total Sales</Text> <BadgeDelta deltaType="moderateIncrease">23.1%</BadgeDelta> </Flex> <Flex justifyContent="start" alignItems="baseline" className="space-x-3 truncate" > <Metric>$ 442,276</Metric> <Text>from $ 382,482</Text> </Flex> <AreaChart className="mt-10 h-48" data={sales} index="Month" categories={["Sales"]} colors={["blue"]} showYAxis={false} showLegend={false} startEndOnly={true} valueFormatter={valueFormatter} /> <TabList className="mt-4" defaultValue="A" onValueChange={(value) => setSelectedLocation(value)} > <Tab value="A" text="Location A" /> <Tab value="B" text="Location B" /> </TabList> {products .filter((item: any) => item.location === selectedLocation) .map((item: any) => ( <div key={item.title} className="mt-4 space-y-2"> <Flex> <Text>{item.title}</Text> <Text>{`${item.percentageValue}% (${item.metric})`}</Text> </Flex> <ProgressBar percentageValue={item.percentageValue} /> </div> ))} <Flex className="mt-6 pt-4 border-t"> <Button size="xs" variant="light" icon={ArrowNarrowRightIcon} iconPosition="right" > View more </Button> </Flex> </Card> ); }
Card + Accordion + ProgressBar
Total Sales
$ 453,890
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod. Sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod.
Performing as average
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod. Sit amet, consetetur sadipscing elitr. Per aspera ad astra.
Performing above average
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod. Sit amet, consetetur sadipscing elitr. Per aspera ad astra.
Performing below average
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod. Sit amet, consetetur sadipscing elitr. Per aspera ad astra.
import { Card, Metric, Text, Flex, Button, Callout, Accordion, AccordionBody, AccordionHeader, AccordionList, ProgressBar, } from "@tremor/react"; import { ArrowCircleRightIcon, ArrowCircleUpIcon, ArrowCircleDownIcon, ArrowNarrowRightIcon, } from "@heroicons/react/solid"; const products = [ { name: "Product A", metric: "$ 23,456", percentageValue: 80, status: "Performing as average", info: `Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod. Sit amet, consetetur sadipscing elitr. Per aspera ad astra.`, icon: ArrowCircleRightIcon, }, { name: "Product B", metric: "$ 20,123", percentageValue: 78, status: "Performing above average", info: `Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod. Sit amet, consetetur sadipscing elitr. Per aspera ad astra.`, icon: ArrowCircleUpIcon, }, { name: "Product C", metric: "$ 8,100", percentageValue: 62, status: "Performing below average", info: `Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod. Sit amet, consetetur sadipscing elitr. Per aspera ad astra.`, icon: ArrowCircleDownIcon, }, ]; export default function Example() { return ( <Card className="max-w-md mx-auto"> <Text>Total Sales</Text> <Metric>$ 453,890</Metric> <Text className="mt-4"> Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod. Sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod. </Text> <AccordionList className="mt-6"> {products.map((item, idx) => ( <Accordion key={item.name} expanded={idx === 0 && true}> <AccordionHeader> <div className="space-y-2"> <Flex> <Text>{item.name}</Text> <Text className="truncate">{`${item.metric} (${item.percentageValue}%)`}</Text> </Flex> <ProgressBar percentageValue={item.percentageValue} /> </div> </AccordionHeader> <AccordionBody> <Callout title={item.status} icon={item.icon} color="gray" className="mt-2" > {item.info} </Callout> </AccordionBody> </Accordion> ))} </AccordionList> </Card> ); }
Card + Icon + RangeBar + InlineButton
Overview
Peer Comparison • May 2022
Sales
$ 34,567
Engagement
8.2
Support
567
Customers
1,234
import { Card, Text, Flex, Button, Icon, Title, Bold, RangeBar, } from "@tremor/react"; import { CashIcon, ChatAlt2Icon, SupportIcon, UsersIcon, InformationCircleIcon, ArrowNarrowRightIcon, } from "@heroicons/react/solid"; const categories = [ { title: "Sales", metric: "$ 34,567", percentageValue: 80, minMetric: "$ 27,996", minPercentageValue: 65, maxMetric: "€ 36,178", maxPercentageValue: 84, icon: CashIcon, }, { title: "Engagement", metric: "8.2", percentageValue: 70, minMetric: "5.3", minPercentageValue: 45, maxMetric: "7.5", maxPercentageValue: 64, icon: ChatAlt2Icon, }, { title: "Support", metric: "567", percentageValue: 30, minMetric: "1,096", minPercentageValue: 58, maxMetric: "1,361", maxPercentageValue: 72, icon: SupportIcon, }, { title: "Customers", metric: "1,234", percentageValue: 40, minMetric: "926", minPercentageValue: 30, maxMetric: "2,098", maxPercentageValue: 68, icon: UsersIcon, }, ]; export default function Example() { return ( <Card className="max-w-md mx-auto"> <Flex justifyContent="start" className="-space-x-0.5" alignItems="center"> <Title> Overview </Title> <Icon icon={InformationCircleIcon} size="sm" color="gray" tooltip="Shows individual performance against peer group performance (gray bar)" /> </Flex> <Text>Peer Comparison • May 2022</Text> {categories.map((item) => ( <Flex key={item.title} justifyContent="start" className="space-x-6 mt-6" > <Icon icon={item.icon} color="blue" variant="shadow" size="lg" /> <div className="space-y-2 w-full"> <Flex> <Text> <Bold>{item.title}</Bold> </Text> <Text>{item.metric}</Text> </Flex> <RangeBar percentageValue={item.percentageValue} minPercentageValue={item.minPercentageValue} maxPercentageValue={item.maxPercentageValue} markerTooltip={`${item.percentageValue}%`} rangeTooltip={`${item.minMetric} (${item.minPercentageValue}%) - ${item.maxMetric} (${item.maxPercentageValue}%)`} /> </div> </Flex> ))} <Flex className="mt-6 pt-4 border-t"> <Button size="xs" variant="light" icon={ArrowNarrowRightIcon} iconPosition="right" > View more </Button> </Flex> </Card> ); }
Card + CategoryBar + Metric
Overall Performance Score
13.1%
65
/100
$ 456,000
Sales
89,123
Transactions
22
Merchants
678
Orders
import { Card, Text, Flex, Metric, CategoryBar, BadgeDelta, Grid, } from "@tremor/react"; const categories = [ { title: "Sales", metric: "$ 456,000", }, { title: "Transactions", metric: "89,123", }, { title: "Merchants", metric: "22", }, { title: "Orders", metric: "678", }, ]; export default function Example() { return ( <Card className="max-w-lg mx-auto"> <Card> <Flex> <Text className="truncate">Overall Performance Score</Text> <BadgeDelta deltaType="moderateIncrease">13.1%</BadgeDelta> </Flex> <Flex justifyContent="start" alignItems="baseline" className="space-x-1" > <Metric>65</Metric> <Text>/100</Text> </Flex> <CategoryBar categoryPercentageValues={[10, 25, 45, 20]} colors={["emerald", "yellow", "orange", "red"]} percentageValue={65} tooltip="65%" className="mt-2" /> </Card> <Grid numColsSm={2} className="mt-4 gap-4"> {categories.map((item) => ( <Card key={item.title}> <Metric className="mt-2 truncate">{item.metric}</Metric> <Text>{item.title}</Text> </Card> ))} </Grid> </Card> ); }
Card + List + BarList
Activity Overview
Activity by session (#)
56
45
34
12
10
Activity by time (h)
120.9
63.6
41.3
6.2
6.1
Activity by heart rate (bpm)
162
172
142
165
128
Activity by distance (km)
1,243.45
342.32
278.12
190.04
0
import { Card, Title, Bold, Text, Tab, TabList, Button, Flex, BarList, Grid, } from "@tremor/react"; import { ArrowNarrowRightIcon } from "@heroicons/react/solid"; import React, { useState } from "react"; const Runners = { Chris: "Chris", Severin: "Severin", Achilleas: "Achilleas", }; const data = [ { name: "Chris", session: [ { name: "Long runs", value: 56 }, { name: "Fartlek runs", value: 45 }, { name: "Recover runs", value: 34 }, { name: "Runs with Lena", value: 12 }, { name: "Functional strength", value: 10 }, ], time: [ { name: "Long runs", value: 120.9 }, { name: "Fartlek runs", value: 63.6 }, { name: "Recover runs", value: 41.3 }, { name: "Runs with Lena", value: 6.2 }, { name: "Functional strength", value: 6.1 }, ], bpm: [ { name: "Long runs", value: 162 }, { name: "Fartlek runs", value: 172 }, { name: "Recover runs", value: 142 }, { name: "Runs with Lena", value: 165 }, { name: "Functional strength", value: 128 }, ], km: [ { name: "Long runs", value: 1243.45 }, { name: "Fartlek runs", value: 342.32 }, { name: "Recover runs", value: 278.12 }, { name: "Runs with Lena", value: 190.04 }, { name: "Functional strength", value: 0 }, ], }, { name: "Severin", session: [ { name: "Long runs", value: 32 }, { name: "Fartlek runs", value: 53 }, { name: "Recover runs", value: 27 }, { name: "Runs with Sophia", value: 21 }, { name: "Functional strength", value: 8 }, ], time: [ { name: "Long runs", value: 90.5 }, { name: "Fartlek runs", value: 70.6 }, { name: "Recover runs", value: 120.7 }, { name: "Runs with Sophia", value: 20.6 }, { name: "Functional strength", value: 30.2 }, ], bpm: [ { name: "Long runs", value: 172 }, { name: "Fartlek runs", value: 146 }, { name: "Recover runs", value: 138 }, { name: "Runs with Sophia", value: 156 }, { name: "Functional strength", value: 121 }, ], km: [ { name: "Long runs", value: 1432.75 }, { name: "Fartlek runs", value: 267.32 }, { name: "Recover runs", value: 321.92 }, { name: "Runs with Sophia", value: 210.73 }, { name: "Functional strength", value: 120.05 }, ], }, { name: "Achilleas", session: [ { name: "Long runs", value: 46 }, { name: "Fartlek runs", value: 28 }, { name: "Recover runs", value: 21 }, { name: "Runs with Lexi", value: 56 }, { name: "Functional strength", value: 27 }, ], time: [ { name: "Long runs", value: 110.9 }, { name: "Fartlek runs", value: 45.6 }, { name: "Recover runs", value: 32.3 }, { name: "Runs with Lexi", value: 32.2 }, { name: "Functional strength", value: 10.5 }, ], bpm: [ { name: "Long runs", value: 177 }, { name: "Fartlek runs", value: 158 }, { name: "Recover runs", value: 132 }, { name: "Runs with Lexi", value: 155 }, { name: "Functional strength", value: 134 }, ], km: [ { name: "Long runs", value: 1103.63 }, { name: "Fartlek runs", value: 342.32 }, { name: "Recover runs", value: 278.12 }, { name: "Runs with Lexi", value: 190.04 }, { name: "Functional strength", value: 0 }, ], }, ]; const valueFormatter = (number: number) => Intl.NumberFormat("us").format(number).toString(); export default function Exmaple() { const [selectedRunner, setSelectedRunner] = useState(Runners.Chris); return ( <Card> <Title> Activity Overview</Title> <TabList defaultValue={selectedRunner} onValueChange={(value) => setSelectedRunner(value)} className="mt-8" > <Tab value={Runners.Chris} text="Chris" /> <Tab value={Runners.Severin} text="Severin" /> <Tab value={Runners.Achilleas} text="Achilleas" /> </TabList> {data .filter((item) => item.name === selectedRunner) .map((item) => ( <Grid key={item.name} numColsMd={2} className="gap-x-8 gap-y-2 mt-6"> <div> <Text className="mt-8"> <Bold>Activity by session (#)</Bold> </Text> <BarList className="mt-4" data={item.session} valueFormatter={valueFormatter} /> </div> <div> <Text className="mt-8"> <Bold>Activity by time (h)</Bold> </Text> <BarList className="mt-4" data={item.time} valueFormatter={valueFormatter} /> </div> <div> <Text className="mt-8"> <Bold>Activity by heart rate (bpm)</Bold> </Text> <BarList className="mt-4" data={item.bpm} valueFormatter={valueFormatter} /> </div> <div> <Text className="mt-8"> <Bold>Activity by distance (km)</Bold> </Text> <BarList className="mt-4" data={item.km} valueFormatter={valueFormatter} /> </div> </Grid> ))} <Flex className="mt-6 pt-4 border-t"> <Button size="xs" variant="light" icon={ArrowNarrowRightIcon} iconPosition="right" > View more </Button> </Flex> </Card> ); }