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:
parent
3255806891
commit
8903b1ef95
|
@ -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>
|
||||
)
|
||||
}
|
|
@ -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}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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} />
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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' }}
|
||||
|
|
|
@ -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
|
||||
/>
|
||||
</>
|
||||
|
|
|
@ -56,6 +56,10 @@ module.exports = {
|
|||
display: 'none',
|
||||
},
|
||||
},
|
||||
'.break-anywhere': {
|
||||
'overflow-wrap': 'anywhere',
|
||||
'word-break': 'break-word', // for Safari
|
||||
},
|
||||
})
|
||||
}),
|
||||
],
|
||||
|
|
Loading…
Reference in New Issue
Block a user