-
Notifications
You must be signed in to change notification settings - Fork 887
chore: use emotion for styling (pt. 2) #9951
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
949c010
3934f0e
056d867
8808da4
23404c6
d464bb8
4201a56
e3e626a
4d68033
f254256
af80a93
ea5bb1b
48f3bfc
2eb0c99
8fa8a37
f71a979
12fc96c
a446e59
e4a6477
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,8 @@ | ||
import IconButton from "@mui/material/Button"; | ||
import { makeStyles } from "@mui/styles"; | ||
import Tooltip from "@mui/material/Tooltip"; | ||
import Check from "@mui/icons-material/Check"; | ||
import { useClipboard } from "hooks/useClipboard"; | ||
import { combineClasses } from "utils/combineClasses"; | ||
import { css } from "@emotion/react"; | ||
import { FileCopyIcon } from "../Icons/FileCopyIcon"; | ||
|
||
interface CopyButtonProps { | ||
|
@@ -29,51 +28,53 @@ export const CopyButton: React.FC<React.PropsWithChildren<CopyButtonProps>> = ({ | |
buttonClassName = "", | ||
tooltipTitle = Language.tooltipTitle, | ||
}) => { | ||
const styles = useStyles(); | ||
const { isCopied, copy: copyToClipboard } = useClipboard(text); | ||
|
||
const fileCopyIconStyles = css` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thoughts on these style rules being at the top of the component vs at the bottom? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think I prefer to define things top to bottom, but I'm fine with anything. Another question, though: is there any difference between having the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've always put stateful logic (hooks, contexts, queries) at the top of the file while moving CSS to the bottom, but I don't have a strong opinion, just a habit. I'm happy with either. Would be nice to stay consistent either way we go. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeah, I like top-to-bottom. my instinct is always to scroll up for stuff like this, and I'm always a little sad when I realize I was supposed to scroll down. :p There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. although that's probably less of an issue here than it was with |
||
width: 20px; | ||
height: 20px; | ||
`; | ||
|
||
return ( | ||
<Tooltip title={tooltipTitle} placement="top"> | ||
<div | ||
className={combineClasses([styles.copyButtonWrapper, wrapperClassName])} | ||
className={wrapperClassName} | ||
css={{ | ||
display: "flex", | ||
}} | ||
> | ||
<IconButton | ||
className={combineClasses([styles.copyButton, buttonClassName])} | ||
className={buttonClassName} | ||
css={(theme) => css` | ||
border-radius: ${theme.shape.borderRadius}px; | ||
padding: ${theme.spacing(0.85)}; | ||
min-width: 32px; | ||
|
||
&:hover { | ||
background: ${theme.palette.background.paper}; | ||
} | ||
`} | ||
onClick={copyToClipboard} | ||
size="small" | ||
aria-label={Language.ariaLabel} | ||
variant="text" | ||
> | ||
{isCopied ? ( | ||
<Check className={styles.fileCopyIcon} /> | ||
<Check css={fileCopyIconStyles} /> | ||
) : ( | ||
<FileCopyIcon className={styles.fileCopyIcon} /> | ||
<FileCopyIcon css={fileCopyIconStyles} /> | ||
)} | ||
{ctaCopy && ( | ||
<div | ||
css={(theme) => ({ | ||
marginLeft: theme.spacing(1), | ||
})} | ||
> | ||
{ctaCopy} | ||
</div> | ||
)} | ||
{ctaCopy && <div className={styles.buttonCopy}>{ctaCopy}</div>} | ||
</IconButton> | ||
</div> | ||
</Tooltip> | ||
); | ||
}; | ||
|
||
const useStyles = makeStyles((theme) => ({ | ||
copyButtonWrapper: { | ||
display: "flex", | ||
}, | ||
copyButton: { | ||
borderRadius: theme.shape.borderRadius, | ||
padding: theme.spacing(0.85), | ||
minWidth: 32, | ||
|
||
"&:hover": { | ||
background: theme.palette.background.paper, | ||
}, | ||
}, | ||
fileCopyIcon: { | ||
width: 20, | ||
height: 20, | ||
}, | ||
buttonCopy: { | ||
marginLeft: theme.spacing(1), | ||
}, | ||
})); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could the Record be updated to be indexed by type
Exclude<AvatarProps["size"], undefined>
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Though maybe it'd be better to life the size prop into a separate type, and just reference it in
AvatarProps
andsizeStyles
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that's what is cool about
satisfies
, it doesn't widen the type, it makes sure thatT extends Record<...>
. if you added an incorrect key here, it would still cause a type error at the lookup, because the keys are still literal types.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that's what is cool about
satisfies
, it doesn't widen the type, it makes sure thatT extends Record<...>
. if you added an incorrect key here, it would still cause a type error at the lookup, because TS still knows the actual keys the object has.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, you're right that it doesn't widen the type, but I guess the way I look at it is that right now, we have a narrow type, but wide type-checking, when ideally both would be as narrow as possible.
So for this example specifically, there's nothing requiring that all sizes be present in the record – the key for type-checking is any arbitrary string, so TypeScript has no ability to detect typos in key names or forgotten keys. All it knows is that there should be some number of strings in there (including zero)
Like, if we decide to add a "lg" size down the line, there aren't any protections to make sure we don't forget to add a matching style. But with the record being keyed by all members of the union, TypeScript will complain if something doesn't line up
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there are! the lookup will fail, we don't need a more stringent
satisfies
to catch that. it'd just make this type harder to write.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh wait, yeah, you're right. I was worried because we don't have the
noUncheckedIndexedAccess
compiler setting turned on, which can cause issues with trying to read properties from a record, but because it technically isn't a record, and just has the type-checking of one, it's safe.So we will get errors when trying to consume a property that doesn't exist, instead of weird false positives
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yup, exactly!