mirror of
https://codeberg.org/Freedium-cfd/web.git
synced 2026-03-11 09:04:37 +00:00
feat(article): add mixtape embed functionality and styles
This commit is contained in:
parent
53cc7a1555
commit
3dd9ec8916
6 changed files with 91 additions and 2 deletions
Binary file not shown.
|
|
@ -54,6 +54,7 @@
|
|||
"shiki-transformer-copy-button": "^0.0.3",
|
||||
"svelte-bricks": "^0.2.1",
|
||||
"svelte-lazy": "1.2.9",
|
||||
"svelte-legos": "^0.2.5"
|
||||
"svelte-legos": "^0.2.5",
|
||||
"unist-util-visit": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -241,7 +241,7 @@
|
|||
}
|
||||
|
||||
:global(.prose a::after) {
|
||||
content: "";
|
||||
content: '';
|
||||
@apply icon-[heroicons-outline--external-link] inline-block ml-1 w-3.5 h-3.5 align-text-bottom;
|
||||
}
|
||||
|
||||
|
|
@ -323,4 +323,45 @@
|
|||
:global(.prose kbd) {
|
||||
@apply px-2 py-1.5 text-xs font-semibold text-gray-800 bg-gray-100 border border-gray-200 rounded-lg dark:bg-gray-600 dark:text-gray-100 dark:border-gray-500;
|
||||
}
|
||||
|
||||
/* Mixtape embeds */
|
||||
:global(.prose .mixtape-embed) {
|
||||
@apply items-center p-2 overflow-hidden border border-gray-300 mt-7;
|
||||
}
|
||||
|
||||
:global(.prose .mixtape-content) {
|
||||
@apply flex flex-row justify-between p-2 overflow-hidden;
|
||||
}
|
||||
|
||||
:global(.prose .mixtape-text) {
|
||||
@apply flex flex-col justify-center p-2;
|
||||
}
|
||||
|
||||
:global(.prose .mixtape-text h2) {
|
||||
@apply text-base font-bold text-black dark:text-gray-100;
|
||||
}
|
||||
|
||||
:global(.prose .mixtape-description) {
|
||||
@apply block mt-2;
|
||||
}
|
||||
|
||||
:global(.prose .mixtape-description h3) {
|
||||
@apply text-sm text-gray-700;
|
||||
}
|
||||
|
||||
:global(.prose .mixtape-site) {
|
||||
@apply mt-5;
|
||||
}
|
||||
|
||||
:global(.prose .mixtape-site p) {
|
||||
@apply text-xs text-gray-700;
|
||||
}
|
||||
|
||||
:global(.prose .mixtape-image) {
|
||||
@apply relative flex h-40 flex-row w-60;
|
||||
}
|
||||
|
||||
:global(.prose .mixtape-image-inner) {
|
||||
@apply absolute inset-0 bg-center bg-cover;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -129,3 +129,7 @@ _For more information, visit our [documentation](https://docs.uploadthing.com)._
|
|||
```js
|
||||
console.log('Hello, world!');
|
||||
```
|
||||
|
||||
[](https://miro.medium.com/v2/resize:fit:320/1*abc123.jpg)
|
||||
> **Why React Hooks are the Future of React Development**
|
||||
> Learn how React Hooks are revolutionizing the way we write components and manage state in React applications. Discover the benefits and best practices.
|
||||
|
|
|
|||
41
new-web/src/lib/utils/remark/mixtape-embed.js
Normal file
41
new-web/src/lib/utils/remark/mixtape-embed.js
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
import { visit } from 'unist-util-visit';
|
||||
|
||||
function remarkMixtapeEmbed() {
|
||||
return (tree) => {
|
||||
visit(tree, 'paragraph', (node) => {
|
||||
const text = node.children[0].value;
|
||||
const mixtapeRegex = /\[!\[(.*?)\]\((.*?)\)\]\((.*?)\)\n>(.*?)\n>(.*?)\n/;
|
||||
|
||||
const match = mixtapeRegex.exec(text);
|
||||
if (match) {
|
||||
const [, altText, linkUrl, imageUrl, title, description] = match;
|
||||
const siteName = new URL(linkUrl).hostname;
|
||||
|
||||
node.type = 'html';
|
||||
node.value = `
|
||||
<div class="mixtape-embed">
|
||||
<a href="${linkUrl}" target="_blank" rel="noopener follow">
|
||||
<div class="mixtape-content">
|
||||
<div class="mixtape-text">
|
||||
<h2>${title}</h2>
|
||||
<div class="mixtape-description">
|
||||
<h3>${description}</h3>
|
||||
</div>
|
||||
<div class="mixtape-site">
|
||||
<p>${siteName}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mixtape-image">
|
||||
<div class="mixtape-image-inner" style="background-image: url(${imageUrl})"></div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
`;
|
||||
node.children = undefined;
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
export default remarkMixtapeEmbed;
|
||||
|
|
@ -5,6 +5,7 @@ import adapter from '@sveltejs/adapter-auto';
|
|||
import { toHtml } from 'hast-util-to-html';
|
||||
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
|
||||
import { h } from 'hastscript';
|
||||
import remarkMixtapeEmbed from './src/lib/utils/remark/mixtape-embed.js';
|
||||
|
||||
const readySvg =
|
||||
"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='1em' height='1em' viewBox='0 0 24 24'><path fill='none' stroke='white' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M8.25 7.5V6.108c0-1.135.845-2.098 1.976-2.192q.56-.045 1.124-.08M15.75 18H18a2.25 2.25 0 0 0 2.25-2.25V6.108c0-1.135-.845-2.098-1.976-2.192a48 48 0 0 0-1.123-.08M15.75 18.75v-1.875a3.375 3.375 0 0 0-3.375-3.375h-1.5a1.125 1.125 0 0 1-1.125-1.125v-1.5A3.375 3.375 0 0 0 6.375 7.5H5.25m11.9-3.664A2.25 2.25 0 0 0 15 2.25h-1.5a2.25 2.25 0 0 0-2.15 1.586m5.8 0q.099.316.1.664v.75h-6V4.5q.001-.348.1-.664M6.75 7.5H4.875c-.621 0-1.125.504-1.125 1.125v12c0 .621.504 1.125 1.125 1.125h9.75c.621 0 1.125-.504 1.125-1.125V16.5a9 9 0 0 0-9-9'/></svg>";
|
||||
|
|
@ -91,6 +92,7 @@ export function renderCodeCopyButton(code, options = {}) {
|
|||
/** @type {import('mdsvex').MdsvexOptions} */
|
||||
const mdsvexOptions = {
|
||||
extensions: ['.md'],
|
||||
remarkPlugins: [remarkMixtapeEmbed],
|
||||
rehypePlugins: [[rehypeExternalLinks, { target: '_blank', rel: ['nofollow'] }]],
|
||||
highlight: {
|
||||
highlighter: async (code, lang = 'text') => {
|
||||
|
|
|
|||
Loading…
Reference in a new issue