Style changes made in live pairing session. Updates #10261 Co-authored-by: Will Norris <will@tailscale.com> Co-authored-by: Alessandro Mingione <alessandro@tailscale.com> Signed-off-by: Sonia Appasamy <sonia@tailscale.com>main
parent
1a4d423328
commit
014ae98297
@ -0,0 +1,40 @@ |
||||
// Copyright (c) Tailscale Inc & AUTHORS
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
import cx from "classnames" |
||||
import React from "react" |
||||
|
||||
type Props = { |
||||
children: React.ReactNode |
||||
className?: string |
||||
elevated?: boolean |
||||
empty?: boolean |
||||
noPadding?: boolean |
||||
} |
||||
|
||||
/** |
||||
* Card is a box with a border, rounded corners, and some padding. Use it to |
||||
* group content into a single container and give it more importance. The |
||||
* elevation prop gives it a box shadow, while the empty prop a light gray |
||||
* background color. |
||||
* |
||||
* <Card>{content}</Card> |
||||
* <Card elevated>{content}</Card> |
||||
* <Card empty><EmptyState description="You don't have any keys" /></Card> |
||||
* |
||||
*/ |
||||
export default function Card(props: Props) { |
||||
const { children, className, elevated, empty, noPadding } = props |
||||
return ( |
||||
<div |
||||
className={cx("rounded-md border", className, { |
||||
"shadow-soft": elevated, |
||||
"bg-gray-0": empty, |
||||
"bg-white": !empty, |
||||
"p-6": !noPadding, |
||||
})} |
||||
> |
||||
{children} |
||||
</div> |
||||
) |
||||
} |
||||
@ -0,0 +1,44 @@ |
||||
// Copyright (c) Tailscale Inc & AUTHORS
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
import cx from "classnames" |
||||
import React, { cloneElement } from "react" |
||||
|
||||
type Props = { |
||||
action?: React.ReactNode |
||||
className?: string |
||||
description: string |
||||
icon?: React.ReactElement |
||||
title?: string |
||||
} |
||||
|
||||
/** |
||||
* EmptyState shows some text and an optional action when some area that can |
||||
* house content is empty (eg. no search results, empty tables). |
||||
*/ |
||||
export default function EmptyState(props: Props) { |
||||
const { action, className, description, icon, title } = props |
||||
const iconColor = "text-gray-500" |
||||
const iconComponent = getIcon(icon, iconColor) |
||||
|
||||
return ( |
||||
<div |
||||
className={cx("flex justify-center", className, { |
||||
"flex-col items-center": action || icon || title, |
||||
})} |
||||
> |
||||
{icon && <div className="mb-2">{iconComponent}</div>} |
||||
{title && ( |
||||
<h3 className="text-xl font-medium text-center mb-2">{title}</h3> |
||||
)} |
||||
<div className="w-full text-center max-w-xl text-gray-500"> |
||||
{description} |
||||
</div> |
||||
{action && <div className="mt-3.5">{action}</div>} |
||||
</div> |
||||
) |
||||
} |
||||
|
||||
function getIcon(icon: React.ReactElement | undefined, iconColor: string) { |
||||
return icon ? cloneElement(icon, { className: iconColor }) : null |
||||
} |
||||
Loading…
Reference in new issue