Replace style props with tailwind classes (#800)

* add utility class for `word-break: break-word`

* refactor visuallyHidden style out of Page

* refactor out ref sizing hack in sidebar

* replace style props with tailwind classes
This commit is contained in:
Sinclair Chen 2022-08-26 14:23:06 -07:00 committed by GitHub
parent 3255806891
commit 8903b1ef95
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 35 additions and 102 deletions

View File

@ -1,38 +0,0 @@
import clsx from 'clsx'
import { useState, ReactNode } from 'react'
export function AdvancedPanel(props: { children: ReactNode }) {
const { children } = props
const [collapsed, setCollapsed] = useState(true)
return (
<div
tabIndex={0}
className={clsx(
'collapse collapse-arrow relative',
collapsed ? 'collapse-close' : 'collapse-open'
)}
>
<div
onClick={() => setCollapsed((collapsed) => !collapsed)}
className="cursor-pointer"
>
<div className="mt-4 mr-6 text-right text-sm text-gray-500">
Advanced
</div>
<div
className="collapse-title absolute h-0 min-h-0 w-0 p-0"
style={{
top: -2,
right: -15,
color: '#6a7280' /* gray-500 */,
}}
/>
</div>
<div className="collapse-content m-0 !bg-transparent !p-0">
{children}
</div>
</div>
)
}

View File

@ -1,4 +1,5 @@
import { Point, ResponsiveLine } from '@nivo/line'
import clsx from 'clsx'
import dayjs from 'dayjs'
import { zip } from 'lodash'
import { useWindowSize } from 'web/hooks/use-window-size'
@ -26,8 +27,10 @@ export function DailyCountChart(props: {
return (
<div
className="w-full overflow-hidden"
style={{ height: !small && (!width || width >= 800) ? 400 : 250 }}
className={clsx(
'h-[250px] w-full overflow-hidden',
!small && 'md:h-[400px]'
)}
>
<ResponsiveLine
data={data}
@ -78,8 +81,10 @@ export function DailyPercentChart(props: {
return (
<div
className="w-full overflow-hidden"
style={{ height: !small && (!width || width >= 800) ? 400 : 250 }}
className={clsx(
'h-[250px] w-full overflow-hidden',
!small && 'md:h-[400px]'
)}
>
<ResponsiveLine
data={data}

View File

@ -108,10 +108,9 @@ export function ContractCard(props: {
/>
<p
className={clsx(
'break-words font-semibold text-indigo-700 group-hover:underline group-hover:decoration-indigo-400 group-hover:decoration-2',
'break-anywhere font-semibold text-indigo-700 group-hover:underline group-hover:decoration-indigo-400 group-hover:decoration-2',
questionClass
)}
style={{ /* For iOS safari */ wordBreak: 'break-word' }}
>
{question}
</p>

View File

@ -40,7 +40,7 @@ export function Leaderboard(props: {
{users.map((user, index) => (
<tr key={user.id}>
<td>{index + 1}</td>
<td style={{ maxWidth: 190 }}>
<td className="max-w-[190px]">
<SiteLink className="relative" href={`/${user.username}`}>
<Row className="items-center gap-4">
<Avatar avatarUrl={user.avatarUrl} size={8} />

View File

@ -38,10 +38,7 @@ export function Linkify(props: { text: string; gray?: boolean }) {
)
})
return (
<span
className="break-words"
style={{ /* For iOS safari */ wordBreak: 'break-word' }}
>
<span className="break-anywhere">
{text.split(regex).map((part, i) => (
<Fragment key={i}>
{part}

View File

@ -17,7 +17,7 @@ import { ManifoldLogo } from './manifold-logo'
import { MenuButton } from './menu'
import { ProfileSummary } from './profile-menu'
import NotificationsIcon from 'web/components/notifications-icon'
import React, { useState } from 'react'
import React from 'react'
import { IS_PRIVATE_MANIFOLD } from 'common/envs/constants'
import { CreateQuestionButton } from 'web/components/create-question-button'
import { useMemberGroups } from 'web/hooks/use-group'
@ -25,7 +25,6 @@ import { groupPath } from 'web/lib/firebase/groups'
import { trackCallback, withTracking } from 'web/lib/service/analytics'
import { Group } from 'common/group'
import { Spacer } from '../layout/spacer'
import { useWindowSize } from 'web/hooks/use-window-size'
import { CHALLENGES_ENABLED } from 'common/challenge'
import { buildArray } from 'common/util/array'
import TrophyIcon from 'web/lib/icons/trophy-icon'
@ -235,19 +234,22 @@ export default function Sidebar(props: { className?: string }) {
}))
return (
<nav aria-label="Sidebar" className={className}>
<nav
aria-label="Sidebar"
className={clsx('flex max-h-[100vh] flex-col', className)}
>
<ManifoldLogo className="py-6" twoLine />
<CreateQuestionButton user={user} />
<Spacer h={4} />
{user && (
<div className="w-full" style={{ minHeight: 80 }}>
<div className="min-h-[80px] w-full">
<ProfileSummary user={user} />
</div>
)}
{/* Mobile navigation */}
<div className="space-y-1 lg:hidden">
<div className="flex min-h-0 shrink flex-col gap-1 lg:hidden">
{mobileNavigationOptions.map((item) => (
<SidebarItem key={item.href} item={item} currentPage={currentPage} />
))}
@ -266,7 +268,7 @@ export default function Sidebar(props: { className?: string }) {
</div>
{/* Desktop navigation */}
<div className="hidden space-y-1 lg:block">
<div className="hidden min-h-0 shrink flex-col gap-1 lg:flex">
{navigationOptions.map((item) => (
<SidebarItem key={item.href} item={item} currentPage={currentPage} />
))}
@ -286,10 +288,6 @@ export default function Sidebar(props: { className?: string }) {
function GroupsList(props: { currentPage: string; memberItems: Item[] }) {
const { currentPage, memberItems } = props
const { height } = useWindowSize()
const [containerRef, setContainerRef] = useState<HTMLDivElement | null>(null)
const remainingHeight = (height ?? 0) - (containerRef?.offsetTop ?? 0)
// const preferredNotifications = useUnseenPreferredNotifications(
// privateUser,
// {
@ -315,11 +313,7 @@ function GroupsList(props: { currentPage: string; memberItems: Item[] }) {
currentPage={currentPage}
/>
<div
className="flex-1 space-y-0.5 overflow-auto"
style={{ height: remainingHeight }}
ref={setContainerRef}
>
<div className="min-h-0 shrink space-y-0.5 overflow-auto">
{memberItems.map((item) => (
<a
href={item.href}

View File

@ -164,10 +164,7 @@ export function AnswerLabel(props: {
return (
<Tooltip text={truncated === text ? false : text}>
<span
style={{ wordBreak: 'break-word' }}
className={clsx('whitespace-pre-line break-words', className)}
>
<span className={clsx('break-anywhere whitespace-pre-line', className)}>
{truncated}
</span>
</Tooltip>

View File

@ -6,13 +6,11 @@ import { Toaster } from 'react-hot-toast'
export function Page(props: {
rightSidebar?: ReactNode
suspend?: boolean
className?: string
rightSidebarClassName?: string
children?: ReactNode
}) {
const { children, rightSidebar, suspend, className, rightSidebarClassName } =
props
const { children, rightSidebar, className, rightSidebarClassName } = props
const bottomBarPadding = 'pb-[58px] lg:pb-0 '
return (
@ -23,10 +21,9 @@ export function Page(props: {
bottomBarPadding,
'mx-auto w-full lg:grid lg:grid-cols-12 lg:gap-x-2 xl:max-w-7xl xl:gap-x-8'
)}
style={suspend ? visuallyHiddenStyle : undefined}
>
<Toaster />
<Sidebar className="sticky top-0 hidden divide-gray-300 self-start pl-2 lg:col-span-2 lg:block" />
<Sidebar className="sticky top-0 hidden divide-gray-300 self-start pl-2 lg:col-span-2 lg:flex" />
<main
className={clsx(
'lg:col-span-8 lg:pt-6',
@ -46,22 +43,7 @@ export function Page(props: {
</div>
</aside>
</div>
<BottomNavBar />
</>
)
}
const visuallyHiddenStyle = {
clip: 'rect(0 0 0 0)',
clipPath: 'inset(50%)',
height: 1,
margin: -1,
overflow: 'hidden',
padding: 0,
position: 'absolute',
width: 1,
whiteSpace: 'nowrap',
userSelect: 'none',
visibility: 'hidden',
} as const

View File

@ -3,7 +3,7 @@ import { ReactNode } from 'react'
import Link from 'next/link'
export const linkClass =
'z-10 break-words hover:underline hover:decoration-indigo-400 hover:decoration-2'
'z-10 break-anywhere hover:underline hover:decoration-indigo-400 hover:decoration-2'
export const SiteLink = (props: {
href: string
@ -19,7 +19,6 @@ export const SiteLink = (props: {
className={clsx(linkClass, className)}
href={href}
target={href.startsWith('http') ? '_blank' : undefined}
style={{ /* For iOS safari */ wordBreak: 'break-word' }}
onClick={(e) => {
e.stopPropagation()
if (onClick) onClick()

View File

@ -148,10 +148,7 @@ export function UserPage(props: { user: User }) {
<Col className="mx-4 -mt-6">
<Row className={'flex-wrap justify-between gap-y-2'}>
<Col>
<span
className="text-2xl font-bold"
style={{ wordBreak: 'break-word' }}
>
<span className="break-anywhere text-2xl font-bold">
{user.name}
</span>
<span className="text-gray-500">@{user.username}</span>

View File

@ -33,7 +33,7 @@ const Home = (props: { auth: { user: User } | null }) => {
return (
<>
<Page suspend={!!contract}>
<Page className={contract ? 'sr-only' : ''}>
<Col className="mx-auto w-full p-2">
<ContractSearch
user={user}

View File

@ -203,8 +203,7 @@ function NewBidTable(props: {
<input
type="number"
placeholder="0"
className="input input-bordered"
style={{ maxWidth: 100 }}
className="input input-bordered max-w-[100px]"
value={newBid.toString()}
onChange={(e) => setNewBid(parseInt(e.target.value) || 0)}
onKeyUp={(e) => {
@ -292,7 +291,7 @@ export default function Simulator() {
YES
</div>
</h1>
<div className="mb-10 w-full" style={{ height: 500 }}>
<div className="mb-10 h-[500px] w-full">
<ResponsiveLine
data={data}
yScale={{ min: 0, max: 100, type: 'linear' }}

View File

@ -375,11 +375,10 @@ export function FirebaseAnalytics() {
</p>
<Spacer h={4} />
<iframe
className="w-full"
className="w-full border-0"
height={2200}
src="https://datastudio.google.com/embed/reporting/faeaf3a4-c8da-4275-b157-98dad017d305/page/Gg3"
frameBorder="0"
style={{ border: 0 }}
allowFullScreen
/>
</>
@ -400,11 +399,10 @@ export function WasabiCharts() {
</p>
<Spacer h={4} />
<iframe
className="w-full"
className="w-full border-0"
height={21000}
src="https://wasabipesto.com/jupyter/manifold/"
frameBorder="0"
style={{ border: 0 }}
allowFullScreen
/>
</>

View File

@ -56,6 +56,10 @@ module.exports = {
display: 'none',
},
},
'.break-anywhere': {
'overflow-wrap': 'anywhere',
'word-break': 'break-word', // for Safari
},
})
}),
],