Add Plugins submit button (#76)

* plugins.toml: improve text

* plugins: add cta for plugin submission, use more TS

* plugins: relabel submit pluign button

* improve plugins.toml instructions
This commit is contained in:
VDawg 2024-10-17 17:03:09 +03:00 committed by GitHub
parent 5934c40d93
commit 24b9b73de5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
23 changed files with 138 additions and 89 deletions

View file

@ -63,6 +63,8 @@
"shiki": "^1.7.0", "shiki": "^1.7.0",
"smol-toml": "^1.3.0", "smol-toml": "^1.3.0",
"svelte-inview": "^4.0.2", "svelte-inview": "^4.0.2",
"tailwind-merge": "^2.5.4",
"ts-pattern": "^5.2.0" "ts-pattern": "^5.2.0"
} },
"packageManager": "pnpm@9.12.1+sha512.e5a7e52a4183a02d5931057f7a0dbff9d5e9ce3161e33fa68ae392125b79282a8a8a470a51dfc8a0ed86221442eb2fb57019b0990ed24fab519bf0e1bc5ccfc4"
} }

View file

@ -53,6 +53,9 @@ importers:
svelte-inview: svelte-inview:
specifier: ^4.0.2 specifier: ^4.0.2
version: 4.0.2(svelte@4.2.18) version: 4.0.2(svelte@4.2.18)
tailwind-merge:
specifier: ^2.5.4
version: 2.5.4
ts-pattern: ts-pattern:
specifier: ^5.2.0 specifier: ^5.2.0
version: 5.2.0 version: 5.2.0
@ -1541,6 +1544,9 @@ packages:
resolution: {integrity: sha512-d0FdzYIiAePqRJEb90WlJDkjUEx42xhivxN8muUBmfZnP+tzUgz12DJ2hRJi8sIHCME7jeK1PTMgKPSfTd8JrA==} resolution: {integrity: sha512-d0FdzYIiAePqRJEb90WlJDkjUEx42xhivxN8muUBmfZnP+tzUgz12DJ2hRJi8sIHCME7jeK1PTMgKPSfTd8JrA==}
engines: {node: '>=16'} engines: {node: '>=16'}
tailwind-merge@2.5.4:
resolution: {integrity: sha512-0q8cfZHMu9nuYP/b5Shb7Y7Sh1B7Nnl5GqNr1U+n2p6+mybvRtayrQ+0042Z5byvTA8ihjlP8Odo8/VnHbZu4Q==}
tailwindcss-animate@1.0.7: tailwindcss-animate@1.0.7:
resolution: {integrity: sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==} resolution: {integrity: sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==}
peerDependencies: peerDependencies:
@ -3036,6 +3042,8 @@ snapshots:
magic-string: 0.30.5 magic-string: 0.30.5
periscopic: 3.1.0 periscopic: 3.1.0
tailwind-merge@2.5.4: {}
tailwindcss-animate@1.0.7(tailwindcss@3.4.4): tailwindcss-animate@1.0.7(tailwindcss@3.4.4):
dependencies: dependencies:
tailwindcss: 3.4.4 tailwindcss: 3.4.4

View file

@ -2,7 +2,6 @@
import { globby } from 'globby' import { globby } from 'globby'
import { spawnSync } from 'node:child_process' import { spawnSync } from 'node:child_process'
import { getFileNameWithoutExtension } from '../src/lib/Helper.mjs'
// This script should be run from the root of the application // This script should be run from the root of the application
const root = new URL('..', import.meta.url) const root = new URL('..', import.meta.url)
@ -89,3 +88,8 @@ function exec(command) {
throw new Error(error) throw new Error(error)
} }
} }
/** Get the filename of a filepath without its extension */
export function getFileNameWithoutExtension(filePath) {
return filePath.split('/').at(-1)?.replace(/\..*$/, '')
}

View file

@ -1,13 +1,15 @@
#############################################
# To submit a plugin add a new entry to this file.
#############################################
# Structure:
# - name: Name of the plugin # - name: Name of the plugin
# - tagline: Very concise description of the plugin # - tagline: Very concise description of the plugin
# - url: Link to the Github repository # - url: Link to the Git repository/website
# - logo: Relative link to the logo placed in the `/static/plugins-data/logos/` directory (without the `/static/` though) # - logo (optional): Relative link to the logo placed in the `/static/plugins-data/logos/` directory (without the `/static/` though)
# - tags: Tags for the plugin. Capitalized # - tags: Tags for the plugin. Capitalized
# - featured: Whether the plugin is featured at the top. A maximum of 4 is shown # - featured (optional): Whether the plugin is featured at the top. A maximum of 4 are shown
# - weight: Determines the sort order. A higher weight comes first. # - weight (optional): Determines the sort order. A higher weight comes first.
# Please only use darkmode images/videos.
# Do not use yellow and yellowish colors, unless nesssecary.
[[plugins]] [[plugins]]

View file

@ -17,6 +17,9 @@ import {
import { inview } from 'svelte-inview' import { inview } from 'svelte-inview'
import { pick } from 'remeda' import { pick } from 'remeda'
import { writable } from 'svelte/store' import { writable } from 'svelte/store'
import type { ClassValue } from 'clsx'
import clsx from 'clsx'
import { twMerge } from 'tailwind-merge'
/** /**
* Fade: The initial opacity from 0 to 1. * Fade: The initial opacity from 0 to 1.
@ -24,12 +27,18 @@ import { writable } from 'svelte/store'
* Zoom: The scale from 0 to 1. * Zoom: The scale from 0 to 1.
* *
* Slide: Slide in in pixels. * Slide: Slide in in pixels.
*
* @param {{fade?: number, zoom?: number, slide?: number, duration?: number, delay?: number, threshold?: number}} options
* @param { HTMLElement } node
* @returns
*/ */
export function animateIn(node, options = {}) { export function animateIn(
node: HTMLElement,
options: {
fade?: number
zoom?: number
slide?: number
duration?: number
delay?: number
threshold?: number
} = {}
) {
// Do nothing on mobile // Do nothing on mobile
if (getIsMobile()) return { destroy: () => undefined } if (getIsMobile()) return { destroy: () => undefined }
@ -53,9 +62,10 @@ export function animateIn(node, options = {}) {
}) })
.join(';') .join(';')
// @ts-ignore
node.style = style node.style = style
let timeoutId let timeoutId: NodeJS.Timeout
node.addEventListener('inview_enter', callback) node.addEventListener('inview_enter', callback)
@ -85,14 +95,14 @@ export function animateIn(node, options = {}) {
* @param {number} given * @param {number} given
* @returns * @returns
*/ */
export function lerp(start, end, given) { export function lerp(start: number, end: number, given: number) {
return (1 - given) * start + given * end return (1 - given) * start + given * end
} }
/** /**
* Taken from https://stackoverflow.com/questions/11381673/detecting-a-mobile-browser/11381730#11381730 * Taken from https://stackoverflow.com/questions/11381673/detecting-a-mobile-browser/11381730#11381730
*/ */
export function getIsMobile() { export function getIsMobile(): boolean {
let check = false let check = false
;(function (a) { ;(function (a) {
if ( if (
@ -104,23 +114,28 @@ export function getIsMobile() {
) )
) )
check = true check = true
// @ts-expect-error
})(navigator.userAgent || navigator.vendor || window.opera) })(navigator.userAgent || navigator.vendor || window.opera)
return check return check
} }
/** Get the `generated_<filename>` for the provided path **/ /** Get the `generated_<filename>` for the provided path **/
export function getGeneratedPath(path, extension = 'webp') { export function getGeneratedPath(path: string, extension: string = 'webp') {
const directory = path.substring(0, path.lastIndexOf('/')) const directory = path.substring(0, path.lastIndexOf('/'))
const filename = getFileNameWithoutExtension(path) const filename = getFileNameWithoutExtension(path)
return `${directory}/generated_${filename}.${extension}` return `${directory}/generated_${filename}.${extension}`
} }
/** Get a random item from an array */ /** Get a random item from an array */
export function getRandom(array) { export function getRandom<T>(array: T[]): T {
return array.at(Math.floor(Math.random() * array.length)) return array.at(Math.floor(Math.random() * array.length))!
} }
export function formatDate(date, dateStyle = 'long', locales = 'en') { export function formatDate(
date: string,
dateStyle: 'full' | 'long' | 'medium' | 'short' = 'long',
locales = 'en'
) {
const dateToFormat = new Date(date) const dateToFormat = new Date(date)
const dateFormatter = new Intl.DateTimeFormat(locales, { dateStyle }) const dateFormatter = new Intl.DateTimeFormat(locales, { dateStyle })
@ -128,13 +143,7 @@ export function formatDate(date, dateStyle = 'long', locales = 'en') {
return dateFormatter.format(dateToFormat) return dateFormatter.format(dateToFormat)
} }
/** export function trimText(text: string, maxLenght: number) {
*
* @param {string} text
* @param {number} maxLenght
* @returns
*/
export function trimText(text, maxLenght) {
if (text.length < maxLenght - 1) return text if (text.length < maxLenght - 1) return text
const lastSpace = text.slice(0, maxLenght).lastIndexOf(' ') const lastSpace = text.slice(0, maxLenght).lastIndexOf(' ')
@ -143,8 +152,8 @@ export function trimText(text, maxLenght) {
} }
/** Get the filename of a filepath without its extension */ /** Get the filename of a filepath without its extension */
export function getFileNameWithoutExtension(filePath) { export function getFileNameWithoutExtension(filePath: string) {
return filePath.split('/').at(-1).replace(/\..*$/, '') return filePath.split('/').at(-1)?.replace(/\..*$/, '')
} }
/** /**
@ -180,10 +189,8 @@ export function createThresholdStream({ clicksTarget = 69, clicksEachMs = 400, f
/** /**
* Tell the browser to preload an image * Tell the browser to preload an image
*
* @param {string} src
*/ */
export function preloadImage(src) { export function preloadImage(src: string) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const image = new Image() const image = new Image()
image.src = src image.src = src
@ -195,29 +202,27 @@ export function preloadImage(src) {
/** /**
* A writable store but as as an observable. * A writable store but as as an observable.
* Observables are much nicher than regular stores. * Observables are much nicher than regular stores.
* @template T
* @param {T} init
* @returns {Observable<T> & { update: (updater: (state: T) => T) => void}}
*/ */
export function writableObservable(init) { export function writableObservable<T>(
init: T
): Observable<T> & { update: (updater: (state: T) => T) => void } {
const { update, subscribe } = writable(init) const { update, subscribe } = writable(init)
const observable = new Observable((subscriber) => { const observable = new Observable((subscriber) => {
const unsubscribe = subscribe((value) => subscriber.next(value)) const unsubscribe = subscribe((value) => subscriber.next(value))
return unsubscribe return unsubscribe
}) })
// @ts-ignore
observable.update = update observable.update = update
// @ts-ignore
return observable return observable
} }
/** /** Convert a store to an observable */
* Convert a store to an observable export function convertStoreToObservable<T>(
* @template T store: import('svelte/store').Readable<T>
* @param {import('svelte/store').Readable<T>} store ): Observable<T> {
* @returns {Observable<T>}
*/
export function convertStoreToObservable(store) {
return new Observable((subscriber) => { return new Observable((subscriber) => {
return store.subscribe((value) => subscriber.next(value)) return store.subscribe((value) => subscriber.next(value))
}) })
@ -225,10 +230,11 @@ export function convertStoreToObservable(store) {
/** /**
* Checks if two rectangles are intersecting * Checks if two rectangles are intersecting
* @param {{size: number, coordinates: [x: number, y: number]}} rect1
* @param {{size: number, coordinates: [x: number, y: number]} rect2
*/ */
export function isIntersecting(rect1, rect2) { export function isIntersecting(
rect1: { size: number; coordinates: [x: number, y: number] },
rect2: { size: number; coordinates: [x: number, y: number] }
) {
return !( return !(
rect1.coordinates[0] + rect1.size < rect2.coordinates[0] || rect1.coordinates[0] + rect1.size < rect2.coordinates[0] ||
rect2.coordinates[0] + rect2.size < rect1.coordinates[0] || rect2.coordinates[0] + rect2.size < rect1.coordinates[0] ||
@ -236,3 +242,11 @@ export function isIntersecting(rect1, rect2) {
rect2.coordinates[1] + rect2.size < rect1.coordinates[1] rect2.coordinates[1] + rect2.size < rect1.coordinates[1]
) )
} }
/**
* Merges class names using clsx and tailwind-merge.
* @returns The merged class name string.
*/
export function cn(...inputs: ClassValue[]): string {
return twMerge(clsx(inputs))
}

View file

@ -1,12 +1,13 @@
<script> <script lang="ts">
import clsx from 'clsx' import { cn } from '$lib/Helper'
import Card from './Card.svelte'
/** @type { 'md'|'lg'|'xl'}*/ export let size: 'md' | 'lg' | 'xl' = 'md'
export let size = 'md' export let type: 'primary' | 'outline' | 'fancyOutline' = 'primary'
/** @type { 'primary'|'outline'|'fancyOutline' }*/
export let type = 'primary'
$: classes = clsx( export let href: string | undefined = undefined
$: classes = cn(
'animate rounded text-sm font-bold hover:scale-[1.01] active:scale-100', 'animate rounded text-sm font-bold hover:scale-[1.01] active:scale-100',
'primary' == type && 'bg-slate-200 text-black', 'primary' == type && 'bg-slate-200 text-black',
'outline' == type && 'bg-transparent text-white outline outline-2 outline-slate-200', 'outline' == type && 'bg-transparent text-white outline outline-2 outline-slate-200',
@ -20,7 +21,17 @@
{#if type === 'fancyOutline'} {#if type === 'fancyOutline'}
<div class="relative max-w-max"> <div class="relative max-w-max">
<button class={classes} on:click><slot>NO LABEL PROVIDED</slot></button> <svelte:element
this={href ? 'a' : 'button'}
{...$$restProps}
{href}
role="button"
tabindex="0"
class={classes}
on:click
>
<slot>NO LABEL PROVIDED</slot>
</svelte:element>
<span <span
class="fancy-bg absolute inset-0 -z-10 h-full w-[110%] min-w-[5rem] scale-y-75 bg-cyan-500/90 px-4 py-2 blur-xl" class="fancy-bg absolute inset-0 -z-10 h-full w-[110%] min-w-[5rem] scale-y-75 bg-cyan-500/90 px-4 py-2 blur-xl"
style="--easing: x; --duration: 8s;" style="--easing: x; --duration: 8s;"
@ -35,7 +46,15 @@
/> />
</div> </div>
{:else} {:else}
<button class={classes} on:click><slot>NO LABEL PROVIDED</slot></button> <svelte:element
this={href ? 'a' : 'button'}
{...$$restProps}
{href}
role="button"
tabindex="0"
class={classes}
on:click><slot>NO LABEL PROVIDED</slot></svelte:element
>
{/if} {/if}
<style lang="postcss"> <style lang="postcss">

View file

@ -3,7 +3,7 @@
import { getContext, onMount } from 'svelte' import { getContext, onMount } from 'svelte'
import { cardsContext } from '$lib/components/CardsContainer.svelte' import { cardsContext } from '$lib/components/CardsContainer.svelte'
import { spring } from 'svelte/motion' import { spring } from 'svelte/motion'
import { getIsMobile } from '$lib/Helper.mjs' import { getIsMobile } from '$lib/Helper.ts'
/** @type {'cyan' | 'purple'}*/ /** @type {'cyan' | 'purple'}*/
export let color = 'cyan' export let color = 'cyan'
/** @type {number | number}*/ /** @type {number | number}*/
@ -107,7 +107,7 @@
<style lang="postcss"> <style lang="postcss">
.card { .card {
@apply relative flex items-end justify-end rounded-3xl transition-colors duration-300; @apply relative flex items-end justify-end rounded-3xl transition-colors duration-300;
z-index: 2; z-index: 2;
contain: paint style layout; contain: paint style layout;
@ -161,7 +161,7 @@
} }
.gradient { .gradient {
@apply pointer-events-none absolute inset-0 h-full w-full; @apply pointer-events-none absolute inset-0 h-full w-full;
width: calc(100% - 2px); width: calc(100% - 2px);
border-radius: inherit; border-radius: inherit;
height: calc(100% - 2px); height: calc(100% - 2px);

View file

@ -3,7 +3,7 @@
</script> </script>
<script> <script>
import { getIsMobile } from '$lib/Helper.mjs' import { getIsMobile } from '$lib/Helper.ts'
import { BehaviorSubject, Subject, throttle, throttleTime } from 'rxjs' import { BehaviorSubject, Subject, throttle, throttleTime } from 'rxjs'
import { onMount, setContext } from 'svelte' import { onMount, setContext } from 'svelte'

View file

@ -3,7 +3,7 @@
import { createEventDispatcher, getContext, onDestroy, onMount } from 'svelte' import { createEventDispatcher, getContext, onDestroy, onMount } from 'svelte'
import { spring } from 'svelte/motion' import { spring } from 'svelte/motion'
import { contextId as ctxId } from '../../routes/home-slices/CommunitySlice.svelte' import { contextId as ctxId } from '../../routes/home-slices/CommunitySlice.svelte'
import { convertStoreToObservable, isIntersecting, lerp } from '$lib/Helper.mjs' import { convertStoreToObservable, isIntersecting, lerp } from '$lib/Helper.ts'
import { inview } from 'svelte-inview' import { inview } from 'svelte-inview'
import { Subject, distinctUntilChanged, throttle, throttleTime } from 'rxjs' import { Subject, distinctUntilChanged, throttle, throttleTime } from 'rxjs'

View file

@ -1,5 +1,5 @@
<script> <script>
import { lerp } from '$lib/Helper.mjs' import { lerp } from '$lib/Helper.ts'
import { createNoise2D } from 'simplex-noise' import { createNoise2D } from 'simplex-noise'
import { onMount } from 'svelte' import { onMount } from 'svelte'
import { expoIn } from 'svelte/easing' import { expoIn } from 'svelte/easing'

View file

@ -1,5 +1,5 @@
<script> <script>
import { animateIn } from '$lib/Helper.mjs' import { animateIn } from '$lib/Helper.ts'
import clsx from 'clsx' import clsx from 'clsx'
/** @type { 'left' | 'right' | 'center'} */ /** @type { 'left' | 'right' | 'center'} */

View file

@ -1,7 +1,7 @@
<script> <script>
import ArrowRight from '~icons/mingcute/arrow-right-circle-line' import ArrowRight from '~icons/mingcute/arrow-right-circle-line'
import { animateIn, formatDate } from '$lib/Helper.mjs' import { animateIn, formatDate } from '$lib/Helper.ts'
export let entry export let entry
$: link = `/news/${entry.slug}` $: link = `/news/${entry.slug}`

View file

@ -1,5 +1,5 @@
<script> <script>
import { getGeneratedPath } from '$lib/Helper.mjs' import { getGeneratedPath } from '$lib/Helper.ts'
import { inview } from 'svelte-inview' import { inview } from 'svelte-inview'
/** @type {string} */ /** @type {string} */
@ -133,7 +133,7 @@
.title_ { .title_ {
filter: saturate(1.5) brightness(1); filter: saturate(1.5) brightness(1);
@apply relative -mt-1 mb-5 py-1 text-4xl font-bold text-transparent sm:text-6xl; @apply relative -mt-1 mb-5 py-1 text-4xl font-bold text-transparent sm:text-6xl;
background-image: linear-gradient( background-image: linear-gradient(
-195deg, -195deg,
theme(colors.white / 80%) 50%, theme(colors.white / 80%) 50%,

View file

@ -15,7 +15,7 @@
import Poz from './community/Poz.svelte' import Poz from './community/Poz.svelte'
import { writable } from 'svelte/store' import { writable } from 'svelte/store'
import { Observable } from 'rxjs' import { Observable } from 'rxjs'
import { writableObservable } from '$lib/Helper.mjs' import { writableObservable } from '$lib/Helper.ts'
import TitleHeading from '$lib/components/Title/TitleHeading.svelte' import TitleHeading from '$lib/components/Title/TitleHeading.svelte'
import TitleSubtile from '$lib/components/Title/TitleSubtile.svelte' import TitleSubtile from '$lib/components/Title/TitleSubtile.svelte'

View file

@ -1,5 +1,5 @@
<script> <script>
import { animateIn, getGeneratedPath } from '$lib/Helper.mjs' import { animateIn, getGeneratedPath } from '$lib/Helper.ts'
/** @type {string} /** @type {string}
* The path to the image. Usually the file within `static`, but can also be an URL * The path to the image. Usually the file within `static`, but can also be an URL

View file

@ -1,5 +1,5 @@
<script lang="ts"> <script lang="ts">
import { animateIn } from '$lib/Helper.mjs' import { animateIn } from '$lib/Helper.ts'
import Button from '$lib/components/Button.svelte' import Button from '$lib/components/Button.svelte'
import TitleHeading from '$lib/components/Title/TitleHeading.svelte' import TitleHeading from '$lib/components/Title/TitleHeading.svelte'
import TitlePre from '$lib/components/Title/TitlePre.svelte' import TitlePre from '$lib/components/Title/TitlePre.svelte'

View file

@ -1,5 +1,5 @@
<script> <script>
import { getIsMobile } from '$lib/Helper.mjs' import { getIsMobile } from '$lib/Helper.ts'
import Button from '$lib/components/Button.svelte' import Button from '$lib/components/Button.svelte'
import { onMount } from 'svelte' import { onMount } from 'svelte'
import { inview } from 'svelte-inview' import { inview } from 'svelte-inview'

View file

@ -18,7 +18,7 @@
take take
} from 'rxjs' } from 'rxjs'
import GitTile from '$lib/components/GitTile.svelte' import GitTile from '$lib/components/GitTile.svelte'
import { lerp } from '$lib/Helper.mjs' import { lerp } from '$lib/Helper.ts'
import { cubicInOut, expoInOut } from 'svelte/easing' import { cubicInOut, expoInOut } from 'svelte/easing'
import DiscordProfilePicture from '$lib/components/DiscordProfilePicture.svelte' import DiscordProfilePicture from '$lib/components/DiscordProfilePicture.svelte'
import { setContext } from 'svelte' import { setContext } from 'svelte'

View file

@ -1,5 +1,5 @@
<script> <script>
import { animateIn } from '$lib/Helper.mjs' import { animateIn } from '$lib/Helper.ts'
import archLogo from '$lib/images/logos/arch.svg' import archLogo from '$lib/images/logos/arch.svg'
import nixLogo from '$lib/images/logos/nixos.svg' import nixLogo from '$lib/images/logos/nixos.svg'
import bsdLogo from '$lib/images/logos/freebsd.svg' import bsdLogo from '$lib/images/logos/freebsd.svg'

View file

@ -6,7 +6,7 @@
import IconSlideLeft from '~icons/mingcute/align-arrow-left-line' import IconSlideLeft from '~icons/mingcute/align-arrow-left-line'
import clsx from 'clsx' import clsx from 'clsx'
import Video from '$lib/components/Video.svelte' import Video from '$lib/components/Video.svelte'
import { animateIn } from '$lib/Helper.mjs' import { animateIn } from '$lib/Helper.ts'
import { Subject, debounceTime, map, tap, throttle, throttleTime } from 'rxjs' import { Subject, debounceTime, map, tap, throttle, throttleTime } from 'rxjs'
import { onMount } from 'svelte' import { onMount } from 'svelte'
import { fade } from 'svelte/transition' import { fade } from 'svelte/transition'

View file

@ -1,5 +1,5 @@
<script> <script>
import { createThresholdStream, lerp, preloadImage } from '$lib/Helper.mjs' import { createThresholdStream, lerp, preloadImage } from '$lib/Helper.ts'
import DiscordProfilePicture from '$lib/components/DiscordProfilePicture.svelte' import DiscordProfilePicture from '$lib/components/DiscordProfilePicture.svelte'
import { Subject, filter, first, map, merge, of, startWith, switchMap, timer } from 'rxjs' import { Subject, filter, first, map, merge, of, startWith, switchMap, timer } from 'rxjs'
import edgePoz from '$lib/images/poz/msedgepoz.webp' import edgePoz from '$lib/images/poz/msedgepoz.webp'

View file

@ -4,10 +4,11 @@
import PluginCard from './PluginCard.svelte' import PluginCard from './PluginCard.svelte'
import clsx from 'clsx' import clsx from 'clsx'
import * as R from 'remeda' import * as R from 'remeda'
import { getGeneratedPath } from '$lib/Helper.mjs' import { getGeneratedPath } from '$lib/Helper.ts'
import TitleSubtile from '$lib/components/Title/TitleSubtile.svelte' import TitleSubtile from '$lib/components/Title/TitleSubtile.svelte'
import TitlePre from '$lib/components/Title/TitlePre.svelte' import TitlePre from '$lib/components/Title/TitlePre.svelte'
import TitleHeading from '$lib/components/Title/TitleHeading.svelte' import TitleHeading from '$lib/components/Title/TitleHeading.svelte'
import Button from '$lib/components/Button.svelte'
export let data export let data
@ -41,24 +42,23 @@
> >
<div class="top-light"></div> <div class="top-light"></div>
<header class="header mt-24 md:mt-32"> <header class="mt-24 flex flex-col items-center justify-center md:mt-32">
<Title> <Title>
<TitlePre>Plugins</TitlePre> <TitlePre slot="pre">Plugins</TitlePre>
<TitleHeading slot="title" class="">Unlock full power</TitleHeading> <TitleHeading slot="title" class="">Unlock full power</TitleHeading>
<TitleSubtile>Easily load up plugins and customize everything</TitleSubtile> <TitleSubtile>Easily load up plugins and customize everything</TitleSubtile>
</Title> </Title>
<!-- <div class="absolute top-0"> <div
{#each plugins.filter(({ logo }) => logo) as { logo }, index} class="mt-8 animate-in fade-in-0 slide-in-from-bottom-2 fill-mode-backwards [animation-delay:300ms] [animation-duration:1500ms]"
<img >
src={getGeneratedPath(logo)} <Button
alt="" href="https://github.com/hyprwm/hyprland-website/blob/main/src/content/plugins.toml"
width={index * 50} target="_blank"
height={index * 50} class="outline-primary "
class="bg-logo" type="outline">Submit a plugin</Button
/> >
{/each} </div>
</div> -->
</header> </header>
<section <section

View file

@ -1,5 +1,5 @@
<script> <script>
import { getGeneratedPath, trimText } from '$lib/Helper.mjs' import { getGeneratedPath, trimText } from '$lib/Helper.ts'
import Card from '$lib/components/Card.svelte' import Card from '$lib/components/Card.svelte'
import clsx from 'clsx' import clsx from 'clsx'
import Tag from './Tag.svelte' import Tag from './Tag.svelte'