this repo has no description atmosphereconf-vods.wisp.place/
4
fork

Configure Feed

Select the types of activity you want to include in your feed.

improve hover

+97 -47
+36 -6
src/routes/tracks.$trackSlug.tsx
··· 1 - import { createFileRoute, createLink, Link } from "@tanstack/react-router"; 1 + import type { LinkProps } from "@tanstack/react-router"; 2 + import { createFileRoute, createLink } from "@tanstack/react-router"; 2 3 import * as stylex from "@stylexjs/stylex"; 3 4 import { Info } from "lucide-react"; 4 5 5 6 import { AspectRatio, AspectRatioImage } from "#/components/aspect-ratio"; 7 + import type { CardProps } from "#/components/card"; 6 8 import { 7 9 Card, 8 10 CardBody, ··· 29 31 getTrackBySlug, 30 32 } from "#/lib/conference"; 31 33 import { Body } from "#/components/typography"; 34 + import { mergeProps, useHover } from "react-aria"; 35 + import { animationDuration } from "../components/theme/animations.stylex"; 32 36 33 37 const CardLink = createLink(Card); 34 38 39 + function SessionCardLink( 40 + props: CardProps & LinkProps & { children: React.ReactNode }, 41 + ) { 42 + const { isHovered, hoverProps } = useHover({}); 43 + 44 + return ( 45 + <CardLink 46 + {...mergeProps( 47 + props as React.ComponentProps<typeof CardLink>, 48 + hoverProps, 49 + )} 50 + data-hovered={isHovered || undefined} 51 + style={styles.sessionCard} 52 + /> 53 + ); 54 + } 55 + 35 56 export const Route = createFileRoute("/tracks/$trackSlug")({ 36 57 component: TrackRouteComponent, 37 58 }); ··· 110 131 borderBottomWidth: 1, 111 132 }, 112 133 sessionCard: { 134 + cursor: "pointer", 113 135 textDecoration: "none", 114 136 color: "inherit", 115 - backgroundColor: uiColor.bgSubtle, 116 - borderColor: uiColor.border2, 137 + backgroundColor: { 138 + default: uiColor.bgSubtle, 139 + ":is([data-hovered])": uiColor.component1, 140 + }, 141 + borderColor: { 142 + default: uiColor.border2, 143 + ":is([data-hovered])": uiColor.border3, 144 + }, 145 + transitionDuration: animationDuration.fast, 146 + transitionProperty: "background-color, border-color", 147 + transitionTimingFunction: "ease-in-out", 117 148 }, 118 149 timeBadge: { 119 150 borderColor: uiColor.border2, ··· 232 263 </Flex> 233 264 234 265 {sessions.map((session) => ( 235 - <CardLink 266 + <SessionCardLink 236 267 key={session.id} 237 268 to="/videos/$videoSlug" 238 269 params={{ videoSlug: session.slug }} 239 270 search={{ autoplay: false }} 240 - style={styles.sessionCard} 241 271 > 242 272 <CardHeader style={styles.sessionHeader}> 243 273 <CardTitle>{session.title}</CardTitle> ··· 274 304 </div> 275 305 </Flex> 276 306 </CardBody> 277 - </CardLink> 307 + </SessionCardLink> 278 308 ))} 279 309 </section> 280 310 ))}
+61 -41
src/routes/videos.$videoSlug.tsx
··· 1 - import { 2 - createFileRoute, 3 - createLink, 4 - Link, 5 - useRouter, 6 - } from "@tanstack/react-router"; 1 + import type { LinkProps } from "@tanstack/react-router"; 2 + import { createFileRoute, createLink, useRouter } from "@tanstack/react-router"; 7 3 import * as stylex from "@stylexjs/stylex"; 8 4 import { Link as AriaLink } from "react-aria-components"; 9 5 6 + import type { CardProps } from "#/components/card"; 10 7 import { 11 8 Card, 12 9 CardBody, ··· 40 37 import { radius } from "../components/theme/radius.stylex"; 41 38 import { animationDuration } from "../components/theme/animations.stylex"; 42 39 import { Tooltip } from "#/components/tooltip"; 40 + import { mergeProps, useHover } from "react-aria"; 43 41 44 42 const RouterLink = createLink(DSLink); 45 43 ··· 50 48 component: VideoRouteComponent, 51 49 }); 52 50 51 + const CardLink = createLink(Card); 52 + function SessionCardLink( 53 + props: CardProps & LinkProps & { children: React.ReactNode }, 54 + ) { 55 + const { isHovered, hoverProps } = useHover({}); 56 + console.log({ isHovered }); 57 + return ( 58 + <CardLink 59 + {...mergeProps( 60 + props as React.ComponentProps<typeof CardLink>, 61 + hoverProps, 62 + )} 63 + data-hovered={isHovered || undefined} 64 + style={styles.relatedLink} 65 + /> 66 + ); 67 + } 68 + 53 69 const styles = stylex.create({ 54 70 root: { 55 71 paddingBottom: verticalSpace["10xl"], ··· 93 109 relatedLink: { 94 110 textDecoration: "none", 95 111 color: "inherit", 96 - }, 97 - relatedCard: { 98 - backgroundColor: uiColor.bgSubtle, 99 - borderColor: uiColor.border2, 100 - height: "100%", 112 + cursor: "pointer", 113 + backgroundColor: { 114 + default: uiColor.bgSubtle, 115 + ":is([data-hovered])": uiColor.component1, 116 + }, 117 + borderColor: { 118 + default: uiColor.border2, 119 + ":is([data-hovered])": uiColor.border3, 120 + }, 121 + transitionDuration: animationDuration.fast, 122 + transitionProperty: "background-color, border-color", 123 + transitionTimingFunction: "ease-in-out", 101 124 }, 102 125 relatedHeader: { 103 126 gridTemplate: { ··· 379 402 </Text> 380 403 <div {...stylex.props(styles.relatedGrid)}> 381 404 {siblings.map((candidate) => ( 382 - <Link 405 + <SessionCardLink 383 406 key={candidate.id} 384 407 to="/videos/$videoSlug" 385 408 params={{ videoSlug: candidate.slug }} 386 409 search={{ autoplay: false }} 387 - {...stylex.props(styles.relatedLink)} 388 410 > 389 - <Card style={styles.relatedCard}> 390 - <CardHeader style={styles.relatedHeader}> 391 - <CardTitle>{candidate.title}</CardTitle> 392 - <CardHeaderAction style={styles.relatedHeaderAction}> 393 - <Text size="sm" style={styles.tag}> 394 - {formatLocalTime(candidate.startsAt)} -{" "} 395 - {formatLocalTime(candidate.endsAt)} 396 - </Text> 397 - </CardHeaderAction> 398 - </CardHeader> 399 - <CardBody style={styles.grow}> 400 - {candidate.description ? ( 401 - <div {...stylex.props(styles.descriptionWrapper)}> 402 - <div {...stylex.props(styles.relatedDescription)}> 403 - {candidate.description} 404 - </div> 411 + <CardHeader style={styles.relatedHeader}> 412 + <CardTitle>{candidate.title}</CardTitle> 413 + <CardHeaderAction style={styles.relatedHeaderAction}> 414 + <Text size="sm" style={styles.tag}> 415 + {formatLocalTime(candidate.startsAt)} -{" "} 416 + {formatLocalTime(candidate.endsAt)} 417 + </Text> 418 + </CardHeaderAction> 419 + </CardHeader> 420 + <CardBody style={styles.grow}> 421 + {candidate.description ? ( 422 + <div {...stylex.props(styles.descriptionWrapper)}> 423 + <div {...stylex.props(styles.relatedDescription)}> 424 + {candidate.description} 405 425 </div> 406 - ) : null} 407 - {candidate.speakerProfiles.length > 0 ? ( 408 - <SpeakerList 409 - speakers={candidate.speakerProfiles} 410 - size="sm" 411 - showHandles={false} 412 - wrap 413 - /> 414 - ) : null} 415 - </CardBody> 416 - </Card> 417 - </Link> 426 + </div> 427 + ) : null} 428 + {candidate.speakerProfiles.length > 0 ? ( 429 + <SpeakerList 430 + speakers={candidate.speakerProfiles} 431 + size="sm" 432 + showHandles={false} 433 + wrap 434 + /> 435 + ) : null} 436 + </CardBody> 437 + </SessionCardLink> 418 438 ))} 419 439 </div> 420 440 </Flex>