Skip to content
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

Prototype: Mobile Channel Nav - single line #5021

Open
wants to merge 6 commits into
base: prototype/channel-page-switcher
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
173 changes: 24 additions & 149 deletions src/views/Home/Channel/Page/Carousel/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,150 +16,15 @@ import styles from './styles.module.css'

type ColumnCount = '4' | '5' | '6' | '7'

const ChannelCarousel = () => {
const host = typeof window !== 'undefined' ? window.location.origin : ''
const items = [
{
id: '1',
title: 'Item 1',
link: `${host}/#channel=1`,
},
{
id: '2',
title: 'Item 2',
link: `${host}/#channel=2`,
},
{
id: '3',
title: 'Item 3',
link: `${host}/#channel=3`,
},
{
id: '4',
title: 'Item 4',
link: `${host}/#channel=4`,
},
{
id: '5',
title: 'Item 5',
link: `${host}/#channel=5`,
},
{
id: '6',
title: 'Item 6',
link: `${host}/#channel=6`,
},
{
id: '7',
title: 'Item 7',
link: `${host}/#channel=7`,
},
{
id: '8',
title: 'Item 8',
link: `${host}/#channel=8`,
},
{
id: '9',
title: 'Item 9',
link: `${host}/#channel=9`,
},
{
id: '10',
title: 'Item 10',
link: `${host}/#channel=10`,
},
{
id: '11',
title: 'Item 11',
link: `${host}/#channel=11`,
},
{
id: '12',
title: 'Item 12',
link: `${host}/#channel=12`,
},
{
id: '13',
title: 'Item 13',
link: `${host}/#channel=13`,
},
{
id: '14',
title: 'Item 14',
link: `${host}/#channel=14`,
},
{
id: '15',
title: 'Item 15',
link: `${host}/#channel=15`,
},
{
id: '16',
title: 'Item 16',
link: `${host}/#channel=16`,
},
{
id: '17',
title: 'Item 17',
link: `${host}/#channel=17`,
},
{
id: '18',
title: 'Item 18',
link: `${host}/#channel=18`,
},
{
id: '19',
title: 'Item 19',
link: `${host}/#channel=19`,
},
{
id: '20',
title: 'Item 20',
link: `${host}/#channel=20`,
},
{
id: '21',
title: 'Item 21',
link: `${host}/#channel=21`,
},
{
id: '22',
title: 'Item 22',
link: `${host}/#channel=22`,
},
{
id: '23',
title: 'Item 23',
link: `${host}/#channel=23`,
},
{
id: '24',
title: 'Item 24',
link: `${host}/#channel=24`,
},
{
id: '25',
title: 'Item 25',
link: `${host}/#channel=25`,
},
{
id: '26',
title: 'Item 26',
link: `${host}/#channel=26`,
},
{
id: '27',
title: 'Item 27',
link: `${host}/#channel=27`,
},
{
id: '28',
title: 'Item 28',
link: `${host}/#channel=28`,
},
]
type ChannelCarouselProps = {
items: {
id: string
title: string
link: string
}[]
}

const ChannelCarousel = ({ items }: ChannelCarouselProps) => {
const [dot, setDot] = useState(0)
const [, setSnaps] = useState<any[]>([])
const [carousel, carouselApi] = useEmblaCarousel({
Expand Down Expand Up @@ -231,11 +96,14 @@ const ChannelCarousel = () => {
if (!carouselApi) {
return
}

const channel = parseInt(hash.split('=')[1], 10)
const pageIndex = slicedItems.findIndex((item) =>
item.find((i: any) => i.id === channel.toString())
)
carouselApi.reInit()
carouselApi.scrollTo(0)
carouselApi.scrollTo(pageIndex)
setDot(pageIndex)

setDot(0)
setSnaps(carouselApi.scrollSnapList())

carouselApi.on('select', onSelect)
Expand Down Expand Up @@ -267,8 +135,13 @@ const ChannelCarousel = () => {
if (hash) {
const channel = parseInt(hash.split('=')[1], 10)
setSelectedChannel(channel)
// const pageIndex = Math.floor(channel / (Number(columnCount) * 2))
const pageIndex = slicedItems.findIndex((item) =>
item.find((i: any) => i.id === channel.toString())
)
carouselApi?.scrollTo(pageIndex)
}
}, [hash])
}, [slicedItems, hash])

return (
<section className={styles.carousel}>
Expand Down Expand Up @@ -309,7 +182,9 @@ const ChannelCarousel = () => {
</div>
</section>
<footer className={styles.footer}>
<section className={styles.dots}>
<section
className={classnames(['page-channel-carousel-dots', styles.dots])}
>
{slicedItems?.map((_, index) => (
<Dot
key={index}
Expand Down
80 changes: 80 additions & 0 deletions src/views/Home/Channel/SingleLine/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import classnames from 'classnames'
import { useState } from 'react'
import { useEffect } from 'react'

import styles from './styles.module.css'

type SingleLineProps = {
items: {
id: string
title: string
link: string
}[]
}

const SingleLine = ({ items }: SingleLineProps) => {
const [hash, setHash] = useState('')

useEffect(() => {
// Function to update the hash state
const updateHash = () => {
setHash(window.location.hash)
}

// Set the initial hash
updateHash()

// Add an event listener to update the hash when it changes
window.addEventListener('hashchange', updateHash)

// Clean up the event listener on component unmount
return () => {
window.removeEventListener('hashchange', updateHash)
}
}, [])

const [selectedChannel, setSelectedChannel] = useState(1)

useEffect(() => {
if (hash) {
const channel = parseInt(hash.split('=')[1], 10)
setSelectedChannel(channel)

// scroll to the selected channel
const selectedChannel = document.querySelector(
`.singleLine-item[data-channel-id="${channel}"]`
)
if (selectedChannel) {
selectedChannel.scrollIntoView({
behavior: 'smooth',
inline: 'center',
block: 'nearest',
})
}
}
}, [hash])

return (
// <div className={styles.container}>
<section className={styles.singleLine}>
{items.map((item) => (
<a
key={item.id}
href={item.link}
className={classnames({
['singleLine-item']: true,
[styles.item]: true,
[styles.selectedChannel]:
selectedChannel === parseInt(item?.id || '1', 10),
})}
data-channel-id={item.id}
>
{item.title}
</a>
))}
</section>
// </div>
)
}

export default SingleLine
43 changes: 43 additions & 0 deletions src/views/Home/Channel/SingleLine/styles.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/* 频道行样式 */

.container {
position: fixed;
top: 65px;
z-index: var(--z-index-sticky-tabs);
}

.singleLine {
position: fixed;
top: 65px;
right: 0;
left: 0;
z-index: var(--z-index-sticky-tabs);
display: flex;
gap: var(--sp12);
align-items: center;

/* margin: 0 calc(var(--sp16) * -1); */
overflow-x: auto; /* horizontal scroll */
white-space: nowrap;
background-color: var(--color-white);
border-bottom: 1px solid var(--color-grey-hover);
scrollbar-width: none; /* Firefox hide scrollbar */

&::-webkit-scrollbar {
display: none;
}

& .item {
flex-shrink: 0; /* prevent shrink */
padding: 8px 10px;
color: var(--color-grey-darker);
white-space: nowrap;
cursor: pointer;

&.selectedChannel {
font-weight: 600;
color: var(--color-black);
border-bottom: 1px solid var(--color-black);
}
}
}
Loading
Loading