From ded1369f9ceb64c38268000d72de42326971beb9 Mon Sep 17 00:00:00 2001 From: David Dias Date: Sun, 11 Jun 2023 12:11:19 -0400 Subject: [PATCH] fix: mobile css issues --- package.json | 3 + pnpm-lock.yaml | 82 +++++++++++++++++-- public/rss/feed.xml | 2 +- public/rss/fr/feed.xml | 2 +- src/components/BlogPost/BlogPost.tsx | 4 +- src/components/Header/Header.tsx | 2 +- .../LatestPostsSection/LatestPostsSection.tsx | 2 +- src/components/MdxComponents/custom-link.tsx | 7 +- .../MdxComponents/responsive-image.tsx | 5 +- src/components/Paragraph/Paragraph.tsx | 2 +- src/pages/articles/[slug].tsx | 2 +- src/pages/index.tsx | 2 +- src/styles/globals.css | 4 + src/utils/extract-links.ts | 25 ++++++ 14 files changed, 119 insertions(+), 25 deletions(-) create mode 100644 src/utils/extract-links.ts diff --git a/package.json b/package.json index 25a35ec4..a7c6c12f 100644 --- a/package.json +++ b/package.json @@ -90,12 +90,15 @@ "rehype-autolink-headings": "^6.1.1", "rehype-figure": "^1.0.1", "rehype-image-placeholder": "^1.0.1", + "rehype-parse": "^8.0.4", "rehype-prism-plus": "1.5.1", "rehype-slug": "5.1.0", + "rehype-stringify": "^9.0.3", "remark-gfm": "^3.0.1", "swr": "2.1.5", "ts-node": "^10.9.1", "typescript": "4.7.4", + "unified": "^10.1.2", "unist-util-visit": "^4.1.0" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 86fce888..09afdb14 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -69,14 +69,17 @@ specifiers: rehype-autolink-headings: ^6.1.1 rehype-figure: ^1.0.1 rehype-image-placeholder: ^1.0.1 + rehype-parse: ^8.0.4 rehype-prism-plus: 1.5.1 rehype-slug: 5.1.0 + rehype-stringify: ^9.0.3 remark-gfm: ^3.0.1 slugify: ^1.6.6 swr: 2.1.5 tailwindcss: 3.3.2 ts-node: ^10.9.1 typescript: 4.7.4 + unified: ^10.1.2 unist-util-visit: ^4.1.0 dependencies: @@ -152,12 +155,15 @@ devDependencies: rehype-autolink-headings: 6.1.1 rehype-figure: 1.0.1 rehype-image-placeholder: 1.0.1 + rehype-parse: 8.0.4 rehype-prism-plus: 1.5.1 rehype-slug: 5.1.0 + rehype-stringify: 9.0.3 remark-gfm: 3.0.1 swr: 2.1.5_react@18.2.0 ts-node: 10.9.1_cvilj4l3ytrlnvtlqw3tscihve typescript: 4.7.4 + unified: 10.1.2 unist-util-visit: 4.1.0 packages: @@ -1670,13 +1676,13 @@ packages: markdown-extensions: 1.1.1 periscopic: 3.0.4 remark-mdx: 2.2.1 - remark-parse: 10.0.1 + remark-parse: 10.0.2 remark-rehype: 10.1.0 unified: 10.1.2 unist-util-position-from-estree: 1.1.1 unist-util-stringify-position: 3.0.2 unist-util-visit: 4.1.2 - vfile: 5.3.4 + vfile: 5.3.7 transitivePeerDependencies: - supports-color dev: false @@ -3777,7 +3783,7 @@ packages: espree: 9.5.2 estree-util-visit: 1.2.1 remark-mdx: 2.3.0 - remark-parse: 10.0.1 + remark-parse: 10.0.2 remark-stringify: 10.0.2 synckit: 0.8.5 tslib: 2.5.0 @@ -3894,7 +3900,7 @@ packages: eslint-mdx: 2.1.0_eslint@8.42.0 eslint-plugin-markdown: 3.0.0_eslint@8.42.0 remark-mdx: 2.3.0 - remark-parse: 10.0.1 + remark-parse: 10.0.2 remark-stringify: 10.0.2 tslib: 2.5.0 unified: 10.1.2 @@ -4720,6 +4726,22 @@ packages: '@types/hast': 2.3.4 dev: true + /hast-util-raw/7.2.3: + resolution: {integrity: sha512-RujVQfVsOrxzPOPSzZFiwofMArbQke6DJjnFfceiEbFh7S05CbPt0cYN+A5YeD3pso0JQk6O1aHBnx9+Pm2uqg==} + dependencies: + '@types/hast': 2.3.4 + '@types/parse5': 6.0.3 + hast-util-from-parse5: 7.1.0 + hast-util-to-parse5: 7.1.0 + html-void-elements: 2.0.1 + parse5: 6.0.1 + unist-util-position: 4.0.3 + unist-util-visit: 4.1.2 + vfile: 5.3.7 + web-namespaces: 2.0.1 + zwitch: 2.0.4 + dev: true + /hast-util-to-estree/2.1.0: resolution: {integrity: sha512-Vwch1etMRmm89xGgz+voWXvVHba2iiMdGMKmaMfYt35rbVtFDq8JNwwAIvi8zHMkO6Gvqo9oTMwJTmzVRfXh4g==} dependencies: @@ -4742,6 +4764,33 @@ packages: - supports-color dev: false + /hast-util-to-html/8.0.4: + resolution: {integrity: sha512-4tpQTUOr9BMjtYyNlt0P50mH7xj0Ks2xpo8M943Vykljf99HW6EzulIoJP1N3eKOSScEHzyzi9dm7/cn0RfGwA==} + dependencies: + '@types/hast': 2.3.4 + '@types/unist': 2.0.6 + ccount: 2.0.1 + comma-separated-tokens: 2.0.2 + hast-util-raw: 7.2.3 + hast-util-whitespace: 2.0.0 + html-void-elements: 2.0.1 + property-information: 6.1.1 + space-separated-tokens: 2.0.1 + stringify-entities: 4.0.3 + zwitch: 2.0.4 + dev: true + + /hast-util-to-parse5/7.1.0: + resolution: {integrity: sha512-YNRgAJkH2Jky5ySkIqFXTQiaqcAtJyVE+D5lkN6CdtOqrnkLfGYYrEcKuHOJZlp+MwjSwuD3fZuawI+sic/RBw==} + dependencies: + '@types/hast': 2.3.4 + comma-separated-tokens: 2.0.2 + property-information: 6.1.1 + space-separated-tokens: 2.0.1 + web-namespaces: 2.0.1 + zwitch: 2.0.4 + dev: true + /hast-util-to-string/2.0.0: resolution: {integrity: sha512-02AQ3vLhuH3FisaMM+i/9sm4OXGSq1UhOOCpTLLQtHdL3tZt7qil69r8M8iDkZYyC0HCFylcYoP+8IO7ddta1A==} dependencies: @@ -4750,7 +4799,6 @@ packages: /hast-util-whitespace/2.0.0: resolution: {integrity: sha512-Pkw+xBHuV6xFeJprJe2BBEoDV+AvQySaz3pPDRUs5PNZEMQjpXJJueqrpcHIXxnWTcAGi/UOCgVShlkY6kLoqg==} - dev: false /hastscript/6.0.0: resolution: {integrity: sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==} @@ -4783,6 +4831,10 @@ packages: react-is: 16.13.1 dev: true + /html-void-elements/2.0.1: + resolution: {integrity: sha512-0quDb7s97CfemeJAnW9wC0hw78MtW7NU3hqtCD75g2vFlDLt36llsYD7uB7SUzojLMP24N5IatXf7ylGXiGG9A==} + dev: true + /https-proxy-agent/5.0.1: resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} engines: {node: '>= 6'} @@ -7179,6 +7231,14 @@ packages: unist-util-visit: 4.1.2 dev: true + /rehype-stringify/9.0.3: + resolution: {integrity: sha512-kWiZ1bgyWlgOxpqD5HnxShKAdXtb2IUljn3hQAhySeak6IOQPPt6DeGnsIh4ixm7yKJWzm8TXFuC/lPfcWHJqw==} + dependencies: + '@types/hast': 2.3.4 + hast-util-to-html: 8.0.4 + unified: 10.1.2 + dev: true + /remark-gfm/3.0.1: resolution: {integrity: sha512-lEFDoi2PICJyNrACFOfDD3JlLkuSbOa5Wd8EPt06HUdptv8Gn0bxYTdbU/XXQ3swAPkEaGxxPN9cbnMHvVu1Ig==} dependencies: @@ -7208,8 +7268,8 @@ packages: - supports-color dev: true - /remark-parse/10.0.1: - resolution: {integrity: sha512-1fUyHr2jLsVOkhbvPRBJ5zTKZZyD6yZzYaWCS6BPBdQ8vEMBCH+9zNCDA6tET/zHCi/jLqjCWtlJZUPk+DbnFw==} + /remark-parse/10.0.2: + resolution: {integrity: sha512-3ydxgHa/ZQzG8LvC7jTXccARYDcRld3VfcgIIFs7bI6vbRSxJJmzgLEIIoYKyrfhaY+ujuWaf/PJiMZXoiCXgw==} dependencies: '@types/mdast': 3.0.10 mdast-util-from-markdown: 1.2.0 @@ -8118,7 +8178,7 @@ packages: is-buffer: 2.0.5 is-plain-obj: 4.1.0 trough: 2.1.0 - vfile: 5.3.4 + vfile: 5.3.7 /unist-builder/3.0.0: resolution: {integrity: sha512-GFxmfEAa0vi9i5sd0R2kcrI9ks0r82NasRq5QHh2ysGngrc6GiqD5CDf1FjPenY4vApmFASBIIlk/jj5J5YbmQ==} @@ -8160,7 +8220,6 @@ packages: resolution: {integrity: sha512-p/5EMGIa1qwbXjA+QgcBXaPWjSnZfQ2Sc3yBEEfgPwsEmJd8Qh+DSk3LGnmOM4S1bY2C0AjmMnB8RuEYxpPwXQ==} dependencies: '@types/unist': 2.0.6 - dev: false /unist-util-remove-position/4.0.1: resolution: {integrity: sha512-0yDkppiIhDlPrfHELgB+NLQD5mfjup3a8UYclHruTJWmY74je8g+CIFr79x5f6AkmzSwlvKLbs63hC0meOMowQ==} @@ -8328,6 +8387,7 @@ packages: is-buffer: 2.0.5 unist-util-stringify-position: 3.0.2 vfile-message: 3.1.2 + dev: false /vfile/5.3.7: resolution: {integrity: sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g==} @@ -8535,3 +8595,7 @@ packages: /zwitch/2.0.2: resolution: {integrity: sha512-JZxotl7SxAJH0j7dN4pxsTV6ZLXoLdGME+PsjkL/DaBrVryK9kTGq06GfKrwcSOqypP+fdXGoCHE36b99fWVoA==} + + /zwitch/2.0.4: + resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} + dev: true diff --git a/public/rss/feed.xml b/public/rss/feed.xml index 3a791e56..c1113f3b 100644 --- a/public/rss/feed.xml +++ b/public/rss/feed.xml @@ -4,7 +4,7 @@ The David Dias | Front-End Developer, podcaster & content creator https://thedaviddias.dev Hey, I'm David Dias! Front-End Developer based in Toronto/Canada. I love talking about code, technology, expatriation and life. - Sun, 11 Jun 2023 15:24:24 GMT + Sun, 11 Jun 2023 15:34:22 GMT https://validator.w3.org/feed/docs/rss2.html https://github.com/jpmonette/feed en diff --git a/public/rss/fr/feed.xml b/public/rss/fr/feed.xml index 4d41670d..28009cb3 100644 --- a/public/rss/fr/feed.xml +++ b/public/rss/fr/feed.xml @@ -4,7 +4,7 @@ The David Dias | Développeur Front-End, podcasteur & créateur de contenu https://thedaviddias.dev Salut toi! Je m'appele David Dias. Je suis développeur Front-End, podcasteur, créateur de contenu numérique passioné pour résoudre les problèmes digitaux et humains! J'aime rencontrer de nouvelles personnes, bâtir des communautées et parler de tech, d'expatriation et de web. - Sun, 11 Jun 2023 15:24:24 GMT + Sun, 11 Jun 2023 15:34:22 GMT https://validator.w3.org/feed/docs/rss2.html https://github.com/jpmonette/feed fr diff --git a/src/components/BlogPost/BlogPost.tsx b/src/components/BlogPost/BlogPost.tsx index 07b1d71f..fb4e8abf 100644 --- a/src/components/BlogPost/BlogPost.tsx +++ b/src/components/BlogPost/BlogPost.tsx @@ -16,7 +16,7 @@ export const BlogPost: React.FC = ({ post, isCategoryPage }) => { const { t } = useTranslation('common') return ( -
+
{!isCategoryPage && ( @@ -26,7 +26,7 @@ export const BlogPost: React.FC = ({ post, isCategoryPage }) => { href={`${t('category.path')}/${slugify(post.frontMatter.categories[0], { lower: true, })}`} - className="block !font-semibold text-gray-600 hover:text-gray-900 dark:text-gray-400 dark:hover:text-gray-100 uppercase text-x" + className="block pb-2 !font-semibold text-gray-600 hover:text-gray-900 dark:text-gray-400 dark:hover:text-gray-100 uppercase text-x" > Category: {post.frontMatter.categories[0]} diff --git a/src/components/Header/Header.tsx b/src/components/Header/Header.tsx index 48e4ed06..d6718b9f 100644 --- a/src/components/Header/Header.tsx +++ b/src/components/Header/Header.tsx @@ -35,7 +35,7 @@ export const Header: React.FC = ({ pathname }) => { return (
{userLocale === ('fr' || 'fr-FR' || 'fr-CA') ? : null} -
+
{isHomepage ? ( diff --git a/src/components/LatestPostsSection/LatestPostsSection.tsx b/src/components/LatestPostsSection/LatestPostsSection.tsx index 5899b988..1c1a283c 100644 --- a/src/components/LatestPostsSection/LatestPostsSection.tsx +++ b/src/components/LatestPostsSection/LatestPostsSection.tsx @@ -14,7 +14,7 @@ export const LatestPostsSection: React.FC = ({ articles }) = const { t } = useTranslation('common') return ( -
+
{t('articles.sections.latest-posts')}
diff --git a/src/components/MdxComponents/custom-link.tsx b/src/components/MdxComponents/custom-link.tsx index 73f246a8..d6b6293f 100644 --- a/src/components/MdxComponents/custom-link.tsx +++ b/src/components/MdxComponents/custom-link.tsx @@ -10,12 +10,7 @@ export const CustomLink: React.FC = ({ href, children }) => { if (external) { return ( - + {children} diff --git a/src/components/MdxComponents/responsive-image.tsx b/src/components/MdxComponents/responsive-image.tsx index 3ad8cf5a..f25ea7f0 100644 --- a/src/components/MdxComponents/responsive-image.tsx +++ b/src/components/MdxComponents/responsive-image.tsx @@ -1,6 +1,7 @@ import Image, { ImageProps } from 'next/image' import { CustomLink } from '../CustomLink' +import { extractLinks } from '@/utils/extract-links' export const ResponsiveImage: React.FC = ({ src, @@ -10,6 +11,8 @@ export const ResponsiveImage: React.FC = ({ width, ...rest }) => { + const updatedFigcaption = title && extractLinks(title) + return (
@@ -32,7 +35,7 @@ export const ResponsiveImage: React.FC = ({ {title && (
- +
)}
diff --git a/src/components/Paragraph/Paragraph.tsx b/src/components/Paragraph/Paragraph.tsx index 6b4bc7a1..5390798e 100644 --- a/src/components/Paragraph/Paragraph.tsx +++ b/src/components/Paragraph/Paragraph.tsx @@ -9,7 +9,7 @@ type ParagraphProps = { export const Paragraph = ({ className, prose = true, as = 'p', ...rest }: ParagraphProps) => { return React.createElement(as, { className: `${prose && 'prose'} max-w-full text-lg my-3 leading-relaxed dark:text-gray-300 ${ - className && className + className ? className : '' }`, ...rest, }) diff --git a/src/pages/articles/[slug].tsx b/src/pages/articles/[slug].tsx index 8fa2403a..eedbb464 100644 --- a/src/pages/articles/[slug].tsx +++ b/src/pages/articles/[slug].tsx @@ -236,7 +236,7 @@ const BlogPostPage: NextPage = ({ {title} -
+
{description}
diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 0c6efb74..0d132ff8 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -82,7 +82,7 @@ const Home: NextPage = ({ articles, notes, ghProjects, fallback }) => sameAs={listSocialUrl(social)} />
-
+

{t('home.hero.greetings1')}

diff --git a/src/styles/globals.css b/src/styles/globals.css index a5219ec0..b4d3e878 100755 --- a/src/styles/globals.css +++ b/src/styles/globals.css @@ -75,3 +75,7 @@ input:-webkit-autofill:focus { .goodreads-shelf img { @apply rounded-lg object-cover h-36; } + +.external-link { + @apply text-indigo-600 dark:text-indigo-400 underline hover:text-indigo-800 dark:hover:text-indigo-500 hover:no-underline transition-colors duration-200; +} diff --git a/src/utils/extract-links.ts b/src/utils/extract-links.ts new file mode 100644 index 00000000..70db24d5 --- /dev/null +++ b/src/utils/extract-links.ts @@ -0,0 +1,25 @@ +import { unified } from 'unified' +import rehypeParse from 'rehype-parse' +import rehypeStringify from 'rehype-stringify' +import { Parent, visit } from 'unist-util-visit' + +export const extractLinks = (html: string) => { + const processor = unified() + .use(rehypeParse, { fragment: true }) // Parse as fragment, not full HTML document + .use( + () => (tree: Parent) => + visit(tree, 'element', (node: any) => { + if (node.tagName === 'a') { + node.properties = node.properties || {} + node.properties.className = 'external-link' + node.properties.rel = 'noopener noreferrer' + node.properties.target = '_blank' + } + }) + ) + .use(rehypeStringify) + + const result = processor.processSync(html).toString() + + return result +}