Skip to content
Merged
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
3 changes: 1 addition & 2 deletions index.css
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@

@layer base {
svg {
vertical-align: middle;
fill: currentColor;
@apply align-middle fill-current;
}
}

Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
{
"name": "webdevhome.github.io",
"version": "2.1.0",
"version": "2.2.0",
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"build": "npm test && vite build",
"preview": "vite preview",
"typecheck": "tsc"
"test": "tsc && eslint src"
},
"dependencies": {
"@mdi/react": "^1.4.0",
Expand Down
29 changes: 23 additions & 6 deletions src/components/App/App.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {
mdiArrowCollapseUp,
mdiArrowLeft,
mdiCheck,
mdiFormatListChecks,
Expand All @@ -17,6 +18,7 @@ import { FooterDivider } from '../Footer/FooterDivider'
import { FooterGroup } from '../Footer/FooterGroup'
import { AppAction } from '../Header/AppAction'
import { AppHeader } from '../Header/AppHeader'
import { JumpLinks } from '../JumpLinks/JumpLinks'
import { LinkGroup } from '../Links/LinkGroup'
import { Search } from '../Search/Search'
import { AppContent } from './AppContent'
Expand All @@ -34,6 +36,13 @@ export const WebdevHome: FC = () => {
const allLinks = useAllLinks()
const hiddenLinksCount = useHiddenLinksCount()

function handleScrollTopClick() {
const htmlEl = document.children.item(0)
if (htmlEl === null) return

htmlEl.scrollTo({ top: 0, behavior: 'smooth' })
}

return (
<div className="min-h-full">
<div
Expand All @@ -50,6 +59,11 @@ export const WebdevHome: FC = () => {
<>
{isCurrentAppMode(AppMode.default) ? (
<>
<AppAction
icon={mdiArrowCollapseUp}
label="Top"
action={handleScrollTopClick}
/>
<AppAction
icon={mdiMagnify}
label="Search"
Expand All @@ -64,7 +78,7 @@ export const WebdevHome: FC = () => {
<AppAction
icon={mdiStickerTextOutline}
active={toggleDescriptions.showDescriptions}
label="Descriptions"
label="Link info"
action={toggleDescriptions.toggle}
/>
<AppAction
Expand Down Expand Up @@ -123,11 +137,14 @@ export const WebdevHome: FC = () => {

<div className="h-full">
{isCurrentAppMode(AppMode.default, AppMode.customize) ? (
<AppContent>
{links.items.map((group) => (
<LinkGroup group={group} key={group.name} />
))}
</AppContent>
<>
<JumpLinks />
<AppContent>
{links.items.map((group, index) => (
<LinkGroup group={group} key={group.name} />
))}
</AppContent>
</>
) : (
<Search />
)}
Expand Down
2 changes: 1 addition & 1 deletion src/components/App/AppContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export const AppContent: FC<PropsWithChildren> = ({ children }) => {
<div
className={classNames(
'grid grid-cols-[repeat(auto-fill,minmax(290px,1fr))]',
'gap-x-2 sm:gap-x-4 lg:gap-x-8 gap-y-20',
'gap-x-2 sm:gap-x-4 lg:gap-x-8 gap-y-8',
'px-page py-4 lg:py-8',
)}
>
Expand Down
4 changes: 2 additions & 2 deletions src/components/Header/AppAction.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export const AppAction: FC<Props> = ({
return (
<div
className={classNames(
'flex items-center',
'flex flex-col items-center md:flex-row',
'p-2',
'rounded-md',
'select-none',
Expand All @@ -44,7 +44,7 @@ export const AppAction: FC<Props> = ({
>
<MdiIcon path={icon} />

<div className="ml-2 text-sm font-semibold tracking-wide">{label}</div>
<div className="md:ml-2 text-xs md:text-sm font-semibold">{label}</div>
</div>
)
}
4 changes: 2 additions & 2 deletions src/components/Header/AppHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export const AppHeader: FC<Props> = ({ actions }) => {
<div
className={classNames(
'grid items-center',
'grid-rows-[auto,auto] md:grid-rows-[auto] md:grid-cols-[1fr,auto]',
'grid-rows-[auto,auto] lg:grid-rows-[auto] lg:grid-cols-[1fr,auto]',
'px-page',
)}
>
Expand All @@ -20,7 +20,7 @@ export const AppHeader: FC<Props> = ({ actions }) => {
{actions !== null ? (
<div
className={classNames(
'flex gap-x-2 justify-center flex-wrap',
'flex md:gap-x-2 justify-center flex-wrap',
'py-2',
)}
>
Expand Down
5 changes: 3 additions & 2 deletions src/components/Header/Logo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ export const Logo: FC = () => {
className={classNames(
'font-mono text-2xl',
'tracking-wide',
'text-center md:text-left text-gray-400 dark:text-gray-200',
'pt-2 md:pt-0',
'text-center lg:text-left text-gray-400 dark:text-gray-200',
'pt-2 lg:pt-0',
'text-nowrap',
)}
>
<span>&lt;</span>
Expand Down
34 changes: 34 additions & 0 deletions src/components/JumpLinks/JumpLink.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import classNames from 'classnames'
import { FC } from 'react'
import { slugify } from '../../utils/slugify'

interface Props {
label: string
color?: string
}

export const JumpLink: FC<Props> = ({ label, color = 'gray' }) => {
function handleClick() {
const target = document.getElementById(slugify(label))
if (target === null) return

target.scrollIntoView({ behavior: 'smooth' })
}

return (
<div
className={classNames(
'jump-link',
'px-3 py-1 md:px-2.5 md:py-0.5',
'rounded-md',
'cursor-pointer',
'text-sm font-semibold',
`bg-${color}-100 dark:bg-${color}-600`,
`text-${color}-800 dark:text-${color}-50`,
)}
onClick={handleClick}
>
{label}
</div>
)
}
45 changes: 45 additions & 0 deletions src/components/JumpLinks/JumpLinks.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { mdiChevronDown, mdiChevronUp } from '@mdi/js'
import classNames from 'classnames'
import { FC, useState } from 'react'
import { MdiIcon } from '../Icon/MdiIcon'
import { JumpLink } from './JumpLink'
import { links } from '../../links'
import { useAllLinksInGroupAreHidden } from '../../stores/hiddenLinks/hiddenLinksHooks'

export const JumpLinks: FC = () => {
const allLinksInGroupAreHidden = useAllLinksInGroupAreHidden()

const [isOpen, setIsOpen] = useState(false)

function handleToggleClick() {
setIsOpen(!isOpen)
}

return (
<div className="jump-links px-page pt-4 lg:pt-8">
<div
className="flex items-center gap-x-2 md:hidden dark:text-white cursor-default select-none"
onClick={handleToggleClick}
>
<MdiIcon path={isOpen ? mdiChevronUp : mdiChevronDown}></MdiIcon>
<div>Jump to</div>
</div>
<div
className={classNames('flex flex-wrap gap-1 md:flex pt-2', {
hidden: !isOpen,
block: isOpen,
})}
>
{links.items
.filter((group) => !allLinksInGroupAreHidden(group))
.map((linkGroup, index) => (
<JumpLink
key={index}
label={linkGroup.name}
color={linkGroup.color}
/>
))}
</div>
</div>
)
}
18 changes: 11 additions & 7 deletions src/components/Links/LinkGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
useAllLinksInGroupAreHidden,
useGetIsLinkHidden,
} from '../../stores/hiddenLinks/hiddenLinksHooks'
import { slugify } from '../../utils/slugify'
import { MdiIcon } from '../Icon/MdiIcon'
import { Link } from './Link'
import { LinkGroupButton } from './LinkGroupButton'
Expand All @@ -34,20 +35,20 @@ export const LinkGroup: FC<Props> = ({ group }) => {
}, [group.items, getIsLinkHidden])

const allGroupLinksAreHidden = useMemo(
() => allLinksInGroupAreHidden(group.items.map((link) => link.url)),
[allLinksInGroupAreHidden, group.items],
() => allLinksInGroupAreHidden(group),
[allLinksInGroupAreHidden, group],
)

const handleToggleGroupClick = useCallback(
(...items: LinkItem[]): void => {
dispatch(toggleHiddenLinksGroup(items.map((link) => link.url)))
dispatch(toggleHiddenLinksGroup(items))
},
[dispatch],
)

const noVisibleLinksInGroup = useMemo(() => {
return allLinksInGroupAreHidden(group.items.map((link) => link.url))
}, [allLinksInGroupAreHidden, group.items])
return allLinksInGroupAreHidden(group)
}, [allLinksInGroupAreHidden, group])

const showHiddenLinksButtonLabel = useMemo(() => {
const hiddenLinksCount = hiddenLinks.length
Expand All @@ -67,14 +68,17 @@ export const LinkGroup: FC<Props> = ({ group }) => {
}

return (
<div>
<div
id={slugify(group.name)}
className="scroll-mt-32 md:scroll-mt-28 lg:scroll-mt-20"
>
<div className="flex gap-x-1 mb-2">
<div
className={classNames(
'flex-auto',
'px-4 py-2',
`bg-${group.color ?? 'gray'}-100 dark:bg-${group.color ?? 'gray'}-600`,
'font-semibold uppercase tracking-wider',
'text-center font-semibold uppercase tracking-wider',
`text-${group.color ?? 'gray'}-800 dark:text-${group.color ?? 'gray'}-50`,
'rounded-md',
)}
Expand Down
Loading