From b28e5792e2bb418d1eb319bea348e9d697e0ed6c Mon Sep 17 00:00:00 2001 From: kiosion Date: Wed, 4 Oct 2023 16:15:17 -0300 Subject: [PATCH] chore: Clean up dynamic code imports, types --- svelte-app/.eslintrc | 16 +- svelte-app/.prettierrc.json | 2 + svelte-app/src/components/code-block.svelte | 177 ++++++++---------- .../src/components/code-block/imports.ts | 81 ++++++++ svelte-app/src/components/icon.svelte | 21 ++- .../portable-text/portable-text.svelte | 18 +- .../serializers/custom-heading.svelte | 48 ++--- svelte-app/src/lib/icons.ts | 17 +- svelte-app/tsconfig.json | 1 - svelte-app/types/app/index.d.ts | 11 +- 10 files changed, 237 insertions(+), 155 deletions(-) create mode 100644 svelte-app/src/components/code-block/imports.ts diff --git a/svelte-app/.eslintrc b/svelte-app/.eslintrc index 7a2961009..fd86f5bfa 100644 --- a/svelte-app/.eslintrc +++ b/svelte-app/.eslintrc @@ -11,6 +11,7 @@ "es2017": true }, "extends": [ + "prettier", "eslint:recommended", "plugin:svelte/recommended", "plugin:@typescript-eslint/recommended" @@ -26,6 +27,10 @@ "@typescript-eslint/no-namespace": ["off"], "@typescript-eslint/restrict-template-expressions": ["off"], "@typescript-eslint/no-unused-vars": ["off"], + "@typescript-eslint/no-duplicate-imports": ["error"], + "@typescript-eslint/ban-ts-comment": ["error", { + "ts-expect-error": "allow-with-description" + }], "array-bracket-spacing": ["error", "never"], "arrow-spacing": ["error"], "block-scoped-var": ["error"], @@ -42,7 +47,7 @@ "keyword-spacing": ["error"], "linebreak-style": ["error"], "no-confusing-arrow": ["error"], - "no-duplicate-imports": ["error"], + "no-duplicate-imports": ["off"], "no-trailing-spaces": ["error"], "no-var": ["error"], "no-eval": ["error"], @@ -58,7 +63,14 @@ "no-unused-vars": ["off"], "object-shorthand": ["error"], "one-var-declaration-per-line": ["error"], - "prettier/prettier": ["error"], + "prettier/prettier": ["error", { + "bracketSpacing": true, + "svelteBracketNewLine": true + }, { + "usePrettierrc": true + }], + "arrow-body-style": ["off"], + "prefer-arrow-callback": ["off"], "quotes": ["error", "single", { "avoidEscape": true }], "quote-props": ["error", "as-needed"], "semi": ["error", "always"], diff --git a/svelte-app/.prettierrc.json b/svelte-app/.prettierrc.json index 5f91cbfb8..b7faff4e4 100644 --- a/svelte-app/.prettierrc.json +++ b/svelte-app/.prettierrc.json @@ -6,6 +6,8 @@ "singleQuote": true, "trailingComma": "none", "printWidth": 90, + "svelteBracketNewLine": true, + "bracketSpacing": true, "plugins": [ "./node_modules/prettier-plugin-svelte", "./node_modules/prettier-plugin-tailwindcss" diff --git a/svelte-app/src/components/code-block.svelte b/svelte-app/src/components/code-block.svelte index ae9914a0b..1f6f58fc4 100644 --- a/svelte-app/src/components/code-block.svelte +++ b/svelte-app/src/components/code-block.svelte @@ -1,24 +1,20 @@ - {#if hlStyles} + {#if HighlightStyles} - {@html hlStyles} + {@html HighlightStyles} {/if} @@ -122,7 +114,6 @@ role="group" aria-label={$t('Code block')} aria-labelledby={filename ? `${id}-filename` : undefined} - bind:this={container} > {#if filename}
{/if} - - - {#key copied} - - {/key} - - + + {#key copied} + + {/key} +
{/if} - {#if !lang} - - {:else} - {#await hlLang then resolvedLang} + + {#await Promise.all([HighlightSvelte, Highlight, LanguageType, LineNumbers]) then [resolvedHighlightSvelte, resolvedHighlight, resolvedLang, resolvedLineNumbers]} + {#if showLineNumbers === true} - - - {:else} - + this={resolvedLineNumbers} + {highlighted} + hideBorder + wrapLines + /> {/if} - {:catch error} -
Error loading: {error.message}
- {/await} - {/if} +
+ {:catch error} +
Error loading: {error.message}
+ {/await}
diff --git a/svelte-app/src/components/code-block/imports.ts b/svelte-app/src/components/code-block/imports.ts new file mode 100644 index 000000000..574da28c1 --- /dev/null +++ b/svelte-app/src/components/code-block/imports.ts @@ -0,0 +1,81 @@ +import { SvelteComponent } from 'svelte'; +import { derived, readable, writable } from 'svelte/store'; + +import type { ComponentType } from 'svelte'; +import type { + HighlightEvents, + HighlightProps, + HighlightSlots +} from 'svelte-highlight/Highlight.svelte'; +import type { + HighlightSvelteEvents, + HighlightSvelteProps, + HighlightSvelteSlots +} from 'svelte-highlight/HighlightSvelte.svelte'; +import type { + LineNumbersEvents, + LineNumbersProps, + LineNumbersSlots +} from 'svelte-highlight/LineNumbers.svelte'; + +class _LineNumbers extends SvelteComponent< + LineNumbersProps, + LineNumbersEvents, + LineNumbersSlots +> {} +class _HighlightSvelte extends SvelteComponent< + HighlightSvelteProps, + HighlightSvelteEvents, + HighlightSvelteSlots +> {} +class _Highlight extends SvelteComponent< + HighlightProps, + HighlightEvents, + HighlightSlots +> {} + +export type LineNumbers = ComponentType<_LineNumbers>; +export type HighlightSvelte = ComponentType<_HighlightSvelte>; +export type Highlight = ComponentType<_Highlight>; + +const stores = { + LineNumbers: writable | undefined>(undefined), + HighlightSvelte: writable | undefined>(undefined), + Highlight: writable | undefined>(undefined) +} as const; + +const genericDerivedAsyncImport = ( + name: K, + target: (typeof stores)[K] + ) => + derived(target, (value: Parameters<(typeof target)['set']>[0]) => { + if (value === undefined) { + const promise = import( + `../../../node_modules/svelte-highlight/${name}.svelte` + ).then((module) => module.default) as unknown as NonNullable; + // @ts-expect-error - TS infers target['set'] here as an Intersection of Writable ReturnTypes rather than Unions + target.set(promise); + return promise; + } + return value; + }), + empty = () => + readable>(new Promise((resolve) => resolve(undefined))); + +const lineNumbers = (useLineNumbers: boolean) => { + return useLineNumbers + ? genericDerivedAsyncImport('LineNumbers', stores.LineNumbers) + : empty(); + }, + highlightSvelte = (useHlSvelte: boolean) => { + return useHlSvelte + ? genericDerivedAsyncImport('HighlightSvelte', stores.HighlightSvelte) + : empty(); + }, + highlight = () => genericDerivedAsyncImport('Highlight', stores.Highlight); + +export { + highlight as Highlight, + highlightSvelte as HighlightSvelte, + lineNumbers as LineNumbers +}; diff --git a/svelte-app/src/components/icon.svelte b/svelte-app/src/components/icon.svelte index 8b3ee6e9e..10ea93093 100644 --- a/svelte-app/src/components/icon.svelte +++ b/svelte-app/src/components/icon.svelte @@ -8,17 +8,18 @@ width = 20, height = width, style = ''; + + const svg = icons.get(icon);
- {#await icons.get(icon) then svg} - - {/await} +
diff --git a/svelte-app/src/components/portable-text/portable-text.svelte b/svelte-app/src/components/portable-text/portable-text.svelte index d1acab650..2abf9eb49 100644 --- a/svelte-app/src/components/portable-text/portable-text.svelte +++ b/svelte-app/src/components/portable-text/portable-text.svelte @@ -6,6 +6,7 @@ import Logger from '$lib/logger'; import Icon from '$components/icon.svelte'; + import Link from '$components/link.svelte'; import { PortableText } from '@portabletext/svelte'; @@ -138,20 +139,15 @@
    {#each footnotes as note}
  1. - - + - customScrollTo(e, `src-${note._key}`)} - on:keydown={(e) => { - if (e.code === 'Space' || e.code === 'Enter') { - customScrollTo(e, `src-${note._key}`); - } - }}> customScrollTo(e, `note-${note._key}`)} + >
  2. diff --git a/svelte-app/src/components/portable-text/serializers/custom-heading.svelte b/svelte-app/src/components/portable-text/serializers/custom-heading.svelte index 385d355d1..9f8585251 100644 --- a/svelte-app/src/components/portable-text/serializers/custom-heading.svelte +++ b/svelte-app/src/components/portable-text/serializers/custom-heading.svelte @@ -1,38 +1,44 @@ - - + - + + +