Skip to content

Commit

Permalink
Improve theming (#36)
Browse files Browse the repository at this point in the history
* Added sizes to the theme

* Change specificity in CSS variables

* Added TweetContainer

* Added changeset
  • Loading branch information
lfades authored Mar 7, 2023
1 parent 545a83d commit f5a987e
Show file tree
Hide file tree
Showing 17 changed files with 158 additions and 137 deletions.
5 changes: 5 additions & 0 deletions .changeset/brave-mayflies-draw.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'next-tweet': minor
---

Improved accessibility, added support for symbols, improved decoding and improved theming.
13 changes: 8 additions & 5 deletions apps/test-app/app/light/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import type { FC, ReactNode } from 'react'
import cslx from 'clsx'
import s from './layout.module.css'

const Layout: FC<{ children: ReactNode }> = ({ children }) => (
<div className={s.root} data-theme="light">
<main className={s.main}>{children}</main>
<footer className={s.footer}>
<p>🤯 This tweet was statically generated.</p>
</footer>
<div data-theme="dark">
<div className={cslx(s.root, 'next-tweet-theme')}>
<main className={s.main}>{children}</main>
<footer className={s.footer}>
<p>🤯 This tweet was statically generated.</p>
</footer>
</div>
</div>
)

Expand Down
25 changes: 14 additions & 11 deletions apps/test-app/components/tweet-page.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { FC } from 'react'
import clsx from 'clsx'
import { useRouter } from 'next/router'
import { EmbeddedTweet, TweetSkeleton } from 'next-tweet'
import type { Tweet } from 'next-tweet/api'
Expand All @@ -8,18 +9,20 @@ const TweetPage: FC<{ tweet: Tweet }> = ({ tweet }) => {
const { isFallback } = useRouter()

return (
<div className={s.root} data-theme="dark">
<main className={s.main}>
{isFallback ? (
<TweetSkeleton />
) : (
<EmbeddedTweet tweet={tweet} priority />
)}
</main>
<div data-theme="dark">
<div className={clsx(s.root, 'next-tweet-theme')}>
<main className={s.main}>
{isFallback ? (
<TweetSkeleton />
) : (
<EmbeddedTweet tweet={tweet} priority />
)}
</main>

<footer className={s.footer}>
<p>🤯 This tweet was statically generated.</p>
</footer>
<footer className={s.footer}>
<p>🤯 This tweet was statically generated.</p>
</footer>
</div>
</div>
)
}
Expand Down
27 changes: 0 additions & 27 deletions packages/next-tweet/src/embedded-tweet.module.css
Original file line number Diff line number Diff line change
@@ -1,30 +1,3 @@
.root {
min-width: 250px;
max-width: 550px;
overflow: hidden;
border: var(--tweet-border);
border-radius: 12px;
margin: var(--tweet-container-margin);
box-sizing: border-box;
/* Base font styles */
color: var(--tweet-font-color);
font: var(--tweet-font-family);
font-weight: 400;
}
.article {
position: relative;
outline-style: none;
box-sizing: border-box;
display: flex;
flex-direction: column;
padding: 0.75rem 1rem 0.25rem 1rem;
transition-property: background-color, box-shadow;
transition-duration: 0.2s;
background-color: var(--tweet-bg-color);
}
.article:hover {
background-color: var(--tweet-bg-color-hover);
}
.notFound {
display: flex;
flex-direction: column;
Expand Down
48 changes: 21 additions & 27 deletions packages/next-tweet/src/embedded-tweet.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import clsx from 'clsx'
import type { Tweet } from './api'
import { TweetContainer } from './tweet-container'
import { TweetHeader } from './tweet-header'
import { TweetInReplyTo } from './tweet-in-reply-to'
import { TweetBody } from './tweet-body'
Expand All @@ -8,37 +8,31 @@ import { TweetInfo } from './tweet-info'
import { TweetActions } from './tweet-actions'
import { TweetReplies } from './tweet-replies'
import s from './embedded-tweet.module.css'
import './theme.css'

type Props = {
tweet?: Tweet
priority?: boolean
}

export const EmbeddedTweet = ({ tweet, priority }: Props) => (
<div className={clsx('next-tweet-theme', s.root)}>
<article className={s.article}>
{tweet ? (
<>
<TweetHeader tweet={tweet} priority={priority} />
{tweet.in_reply_to_status_id_str && <TweetInReplyTo tweet={tweet} />}
<TweetBody tweet={tweet} />
{tweet.mediaDetails?.length ? (
<TweetMedia tweet={tweet} priority={priority} />
) : null}
<TweetInfo tweet={tweet} />
<TweetActions tweet={tweet} />
<TweetReplies tweet={tweet} />
</>
) : (
<div className={s.notFound}>
<h3>Not Found</h3>
<p>
Sorry, we can&apos;t create an embed for that. It may have been
deleted or made private. Please try again.
</p>
</div>
)}
</article>
</div>
<TweetContainer>
{tweet ? (
<>
<TweetHeader tweet={tweet} priority={priority} />
{tweet.in_reply_to_status_id_str && <TweetInReplyTo tweet={tweet} />}
<TweetBody tweet={tweet} />
{tweet.mediaDetails?.length ? (
<TweetMedia tweet={tweet} priority={priority} />
) : null}
<TweetInfo tweet={tweet} />
<TweetActions tweet={tweet} />
<TweetReplies tweet={tweet} />
</>
) : (
<div className={s.notFound}>
<h3>Tweet not found</h3>
<p>The embedded tweet could not be found…</p>
</div>
)}
</TweetContainer>
)
40 changes: 32 additions & 8 deletions packages/next-tweet/src/theme.css
Original file line number Diff line number Diff line change
@@ -1,14 +1,41 @@
[data-theme='light'] .next-tweet-theme,
.light .next-tweet-theme,
.next-tweet-theme {
--tweet-container-margin: 1.5rem 0;

/* Header */
--tweet-header-font-size: 0.9375rem;
--tweet-header-line-height: 1.25rem;

/* Text */
--tweet-body-font-size: 1.25rem;
--tweet-body-line-height: 1.5rem;

/* Info */
--tweet-info-font-size: 0.9375rem;
--tweet-info-line-height: 1.25rem;

/* Actions like the like, reply and copy buttons */
--tweet-actions-font-size: 0.875rem;
--tweet-actions-line-height: 1rem;
--tweet-actions-font-weight: 700;
--tweet-actions-icon-size: 1.25em;
--tweet-actions-icon-wrapper-size: calc(
var(--tweet-actions-icon-size) + 0.75em
);

/* Reply button */
--tweet-replies-font-size: 0.875rem;
--tweet-replies-line-height: 1rem;
--tweet-replies-font-weight: 700;
}

:is([data-theme='light'], .light) :where(.next-tweet-theme) {
--tweet-skeleton-gradient: linear-gradient(
270deg,
#fafafa,
#eaeaea,
#eaeaea,
#fafafa
);
--tweet-container-margin: 1.5rem 0;
--tweet-border: 1px solid rgb(207, 217, 222);
--tweet-font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
Helvetica, Arial, sans-serif;
Expand All @@ -28,16 +55,14 @@
--tweet-verified-blue-color: var(--tweet-color-blue-primary);
}

[data-theme='dark'] .next-tweet-theme,
.dark .next-tweet-theme {
:is([data-theme='dark'], .dark) :where(.next-tweet-theme) {
--tweet-skeleton-gradient: linear-gradient(
270deg,
#15202b,
rgb(30, 39, 50),
rgb(30, 39, 50),
rgb(21, 32, 43)
);
--tweet-container-margin: 1.5rem 0;
--tweet-border: 1px solid rgb(66, 83, 100);
--tweet-font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
Helvetica, Arial, sans-serif;
Expand All @@ -58,15 +83,14 @@
}

@media (prefers-color-scheme: dark) {
.next-tweet-theme {
:where(.next-tweet-theme) {
--tweet-skeleton-gradient: linear-gradient(
270deg,
#15202b,
rgb(30, 39, 50),
rgb(30, 39, 50),
rgb(21, 32, 43)
);
--tweet-container-margin: 1.5rem 0;
--tweet-border: 1px solid rgb(66, 83, 100);
--tweet-font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
Helvetica, Arial, sans-serif;
Expand Down
12 changes: 6 additions & 6 deletions packages/next-tweet/src/tweet-actions.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@
.likeIconWrapper,
.replyIconWrapper,
.copyIconWrapper {
width: 32px;
height: 32px;
width: var(--tweet-actions-icon-wrapper-size);
height: var(--tweet-actions-icon-wrapper-size);
display: flex;
justify-content: center;
align-items: center;
Expand All @@ -45,7 +45,7 @@
.likeIcon,
.replyIcon,
.copyIcon {
height: 1.25em;
height: var(--tweet-actions-icon-size);
fill: currentColor;
user-select: none;
}
Expand All @@ -55,9 +55,9 @@
.likeCount,
.replyText,
.copyText {
font-size: 0.875rem;
font-weight: 700;
line-height: 1rem;
font-size: var(--tweet-actions-font-size);
font-weight: var(--tweet-actions-font-weight);
line-height: var(--tweet-actions-line-height);
margin-left: 0.25rem;
}

Expand Down
4 changes: 2 additions & 2 deletions packages/next-tweet/src/tweet-body.module.css
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.root {
line-height: 1.5rem;
font-size: 1.25rem;
line-height: var(--tweet-body-line-height);
font-size: var(--tweet-body-font-size);
overflow-wrap: break-word;
white-space: pre-wrap;
}
25 changes: 25 additions & 0 deletions packages/next-tweet/src/tweet-container.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
.root {
width: 100%;
min-width: 250px;
max-width: 550px;
overflow: hidden;
/* Base font styles */
color: var(--tweet-font-color);
font-family: var(--tweet-font-family);
font-weight: 400;
box-sizing: border-box;
border: var(--tweet-border);
border-radius: 12px;
margin: var(--tweet-container-margin);
background-color: var(--tweet-bg-color);
transition-property: background-color, box-shadow;
transition-duration: 0.2s;
}
.root:hover {
background-color: var(--tweet-bg-color-hover);
}
.article {
position: relative;
box-sizing: inherit;
padding: 0.75rem 1rem;
}
12 changes: 12 additions & 0 deletions packages/next-tweet/src/tweet-container.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import type { PropsWithChildren } from 'react'
import clsx from 'clsx'
import s from './tweet-container.module.css'
import './theme.css'

type Props = PropsWithChildren<{ className?: string }>

export const TweetContainer = ({ className, children }: Props) => (
<div className={clsx('next-tweet-theme', s.root, className)}>
<article className={s.article}>{children}</article>
</div>
)
4 changes: 2 additions & 2 deletions packages/next-tweet/src/tweet-header.module.css
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
.header {
display: flex;
padding-bottom: 0.75rem;
line-height: 1.25rem;
font-size: 0.9375rem;
line-height: var(--tweet-header-line-height);
font-size: var(--tweet-header-font-size);
white-space: nowrap;
overflow-wrap: break-word;
overflow: hidden;
Expand Down
4 changes: 2 additions & 2 deletions packages/next-tweet/src/tweet-info-created-at.module.css
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
.root {
color: inherit;
text-decoration: none;
font-size: 0.9375rem;
line-height: 1.25rem;
font-size: var(--tweet-info-font-size);
line-height: var(--tweet-info-line-height);
}
.root:hover {
text-decoration-thickness: 1px;
Expand Down
6 changes: 3 additions & 3 deletions packages/next-tweet/src/tweet-info.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
text-decoration: none;
}
.infoLink {
height: 32px;
width: 32px;
height: var(--tweet-actions-icon-wrapper-size);
width: var(--tweet-actions-icon-wrapper-size);
font: inherit;
margin-left: auto;
display: flex;
Expand All @@ -30,7 +30,7 @@
.infoIcon {
color: inherit;
fill: currentColor;
height: 1.25em;
height: var(--tweet-actions-icon-size);
user-select: none;
}
.infoLink:hover > .infoIcon {
Expand Down
2 changes: 1 addition & 1 deletion packages/next-tweet/src/tweet-media-video.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ export const TweetMediaVideo = ({ media }: Props) => {
const sortedMp4Videos = variants
.filter((vid) => vid.content_type === 'video/mp4')
.sort((a, b) => (b.bitrate ?? 0) - (a.bitrate ?? 0))
// Skip the highest quality video and use the next quality

// Skip the highest quality video and use the next quality
return sortedMp4Videos.length > 1 ? sortedMp4Videos[1] : sortedMp4Videos[0]
}, [variants])

Expand Down
9 changes: 4 additions & 5 deletions packages/next-tweet/src/tweet-replies.module.css
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
.replies {
padding-top: 0.25rem;
padding-bottom: 0.75rem;
padding: 0.25rem 0;
}
.link {
text-decoration: none;
Expand All @@ -22,9 +21,9 @@
background-color: var(--tweet-color-blue-secondary-hover);
}
.text {
font-weight: 700;
font-size: 0.875rem;
line-height: 1rem;
font-weight: var(--tweet-replies-font-weight);
font-size: var(--tweet-replies-font-size);
line-height: var(--tweet-replies-line-height);
overflow-wrap: break-word;
white-space: nowrap;
text-overflow: ellipsis;
Expand Down
Loading

0 comments on commit f5a987e

Please sign in to comment.