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
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
/>

<div class="h-full space-y-3 {className}">
{#each trackedHeaders as header, i}
{#each trackedHeaders as header, i (header.id)}
{@const headerLevel = getHeaderLevel(header.element)}
{@const margin = headerLevel - 1}
{@const parentHeader = trackedHeaders
Expand Down
5 changes: 3 additions & 2 deletions docs/src/lib/components/navbar/Search.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
} from '$lib/search';
import { goto } from '$app/navigation';
import { base } from '$app/paths';
import { SvelteMap } from 'svelte/reactivity';

interface Props {
class?: string;
Expand Down Expand Up @@ -53,7 +54,7 @@

const index = await getIndex();

const pages = new Map<string, IndexablePageFragment>();
const pages = new SvelteMap<string, IndexablePageFragment>();
const searchResult = index
.search(query, 5, { enrich: true })
.map((res) => res.result)
Expand Down Expand Up @@ -101,7 +102,7 @@
{#if value}
<Command.Empty>No results found.</Command.Empty>
<Command.Group>
{#each results as result}
{#each results as result (result.id)}
<Command.Item
onSelect={() => {
if (result.match?.heading) goto(`${base}${result.path}#${result.match.heading.id}`);
Expand Down
2 changes: 1 addition & 1 deletion docs/src/routes/community-plugins/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

Here are is a list of several plugins developed by the community:

{#each data.plugins as plugin}
{#each data.plugins as plugin (plugin.name)}
<PluginLink npmLink={plugin.npm} githubLink={plugin.github} name={plugin.name} />

{plugin.description}
Expand Down
50 changes: 15 additions & 35 deletions eslint.config.mjs → eslint.config.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,9 @@
import typescriptEslint from '@typescript-eslint/eslint-plugin';
import globals from 'globals';
import tsEslint from 'typescript-eslint';
import tsParser from '@typescript-eslint/parser';
import parser from 'svelte-eslint-parser';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import sveltePlugin from 'eslint-plugin-svelte';
import svelteParser from 'svelte-eslint-parser';
import globals from 'globals';
import js from '@eslint/js';
import { FlatCompat } from '@eslint/eslintrc';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const compat = new FlatCompat({
baseDirectory: __dirname,
recommendedConfig: js.configs.recommended,
allConfig: js.configs.all
});

export default [
{
Expand All @@ -39,50 +29,40 @@ export default [
'**/.rollup.cache'
]
},
...compat.extends(
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:svelte/recommended'
),
{
plugins: {
'@typescript-eslint': typescriptEslint
},

js.configs.recommended,
...tsEslint.configs.recommended,
...sveltePlugin.configs['flat/recommended'],

{
// No plugins block here anymore
languageOptions: {
globals: {
...globals.node,
...globals.browser
},

parser: tsParser,
ecmaVersion: 'latest',
sourceType: 'module',

parserOptions: {
extraFileExtensions: ['.svelte']
}
},

settings: {
'svelte3/typescript': true
},

rules: {
'no-mixed-spaces-and-tabs': 0,
'@typescript-eslint/no-unused-expressions': 0
'@typescript-eslint/no-unused-expressions': 0,
'svelte/no-navigation-without-resolve': 0
}
},

{
files: ['**/*.svelte'],

languageOptions: {
parser: parser,
ecmaVersion: 5,
sourceType: 'script',

parser: svelteParser,
parserOptions: {
parser: '@typescript-eslint/parser'
parser: tsParser
}
}
}
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"cz-conventional-changelog": "^3.3.0",
"eslint": "^9.20.1",
"eslint-config-prettier": "^8.10.0",
"eslint-plugin-svelte": "^2.46.1",
"eslint-plugin-svelte": "^3.17.1",
"globals": "^15.15.0",
"husky": "^8.0.3",
"lint-staged": "^13.3.0",
Expand All @@ -39,7 +39,8 @@
"prettier-plugin-tailwindcss": "^0.5.14",
"semantic-release": "^25.0.3",
"semantic-release-monorepo": "^8.0.2",
"svelte-eslint-parser": "^0.43.0"
"svelte-eslint-parser": "^0.43.0",
"typescript-eslint": "^8.59.2"
},
"lint-staged": {
"*.{js,ts,svelte}": "eslint --cache --fix --no-error-on-unmatched-pattern",
Expand Down
2 changes: 1 addition & 1 deletion packages/carta-md/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
},
"type": "module",
"dependencies": {
"diff": "^5.2.0",
"diff": "^5.2.2",
"esm-env": "^1.0.0",
"rehype-stringify": "^10.0.0",
"remark-gfm": "^4.0.0",
Expand Down
4 changes: 2 additions & 2 deletions packages/carta-md/src/lib/Markdown.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
-->

<script lang="ts">
import { onMount } from 'svelte';
import { onMount, untrack } from 'svelte';
import type { Carta } from './internal/carta';

interface Props {
Expand All @@ -31,7 +31,7 @@

let elem: HTMLDivElement | undefined = $state();

let rendered = $state(carta.renderSSR(value));
let rendered = $state(untrack(() => carta.renderSSR(value)));
onMount(async () => {
if (!elem) {
throw new Error('No element found.');
Expand Down
6 changes: 3 additions & 3 deletions packages/carta-md/src/lib/MarkdownEditor.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@
{#if mounted}
{#each carta.components.filter(({ parent }) => [parent]
.flat()
.includes('input')) as { component: DynamicComponent, props }}
.includes('input')) as { component: DynamicComponent, props }, index (index)}
<DynamicComponent {carta} {...props}></DynamicComponent>
{/each}
{/if}
Expand All @@ -227,7 +227,7 @@
{#if mounted}
{#each carta.components.filter(({ parent }) => [parent]
.flat()
.includes('renderer')) as { component: DynamicComponent, props }}
.includes('renderer')) as { component: DynamicComponent, props }, index (index)}
<DynamicComponent {carta} {...props}></DynamicComponent>
{/each}
{/if}
Expand All @@ -240,7 +240,7 @@
{#if mounted}
{#each carta.components.filter(({ parent }) => [parent]
.flat()
.includes('editor')) as { component: DynamicComponent, props }}
.includes('editor')) as { component: DynamicComponent, props }, index (index)}
<DynamicComponent {carta} {...props}></DynamicComponent>
{/each}
{/if}
Expand Down
6 changes: 3 additions & 3 deletions packages/carta-md/src/lib/internal/components/Input.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import type { Carta } from '../carta';
import type { UIEventHandler } from 'svelte/elements';
import type { TextAreaProps } from '../textarea-props';
import { onMount, type Snippet } from 'svelte';
import { onMount, untrack, type Snippet } from 'svelte';
import { debounce } from '../utils';
import { BROWSER } from 'esm-env';
import { speculativeHighlightUpdate } from '../speculative';
Expand Down Expand Up @@ -62,7 +62,7 @@
let highlightElem: HTMLDivElement;
let wrapperElem: HTMLDivElement;
let currentlyHighlightedValue = value;
let wasHidden = $state(hidden);
let wasHidden = $state(untrack(() => hidden));

const simpleUUID = Math.random().toString(36).substring(2);

Expand Down Expand Up @@ -126,7 +126,7 @@
/**
* Debounced version of the highlight function.
*/
const debouncedHighlight = debounce(highlight, highlightDelay);
const debouncedHighlight = $derived(debounce(highlight, highlightDelay));

/**
* Returns the highlighted text using a speculative update.
Expand Down
18 changes: 10 additions & 8 deletions packages/carta-md/src/lib/internal/components/Renderer.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,16 @@
let htmlContainer = $state<HTMLDivElement>();

// Debounce the rendering
const debouncedRenderer = debounce((value: string) => {
carta
.render(value)
.then((rendered) => {
htmlContainer!.innerHTML = rendered;
})
.then(() => onrender());
}, carta.rendererDebounce ?? 300);
const debouncedRenderer = $derived(
debounce((value: string) => {
carta
.render(value)
.then((rendered) => {
htmlContainer!.innerHTML = rendered;
})
.then(() => onrender());
}, carta.rendererDebounce ?? 300)
);

const onValueChange = (value: string) => {
debouncedRenderer(value);
Expand Down
14 changes: 5 additions & 9 deletions packages/carta-md/src/lib/internal/components/Toolbar.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import type { Labels } from '../labels';
import type { Carta } from '../carta';
import { handleArrowKeysNavigation } from '../accessibility';
import { onMount } from 'svelte';
import { onMount, untrack } from 'svelte';
import { debounce } from '../utils';
import MenuIcon from './icons/MenuIcon.svelte';

Expand Down Expand Up @@ -36,11 +36,11 @@
let menu: HTMLDivElement | undefined = $state();
let iconsContainer: HTMLDivElement | undefined = $state();

let visibleIcons = $state([...carta.icons]);
let visibleIcons = $state(untrack(() => [...carta.icons]));
let availableWidth = $state(0);
let iconWidth = $state(0);
let toolbarHeight = $state(0);
let iconsHidden = $state(false);
let iconsHidden = $derived(visibleIcons.length !== carta.icons.length);
let showMenu = $state(false);

const IconPadding = 8;
Expand Down Expand Up @@ -72,10 +72,6 @@
}

onMount(onResize);

$effect(() => {
iconsHidden = visibleIcons.length !== carta.icons.length;
});
</script>

<svelte:window onresize={onResize} onclick={onClick} />
Expand Down Expand Up @@ -108,7 +104,7 @@

<div class="carta-toolbar-right" bind:this={iconsContainer}>
{#if !(mode === 'tabs' && tab === 'preview')}
{#each visibleIcons as icon, index}
{#each visibleIcons as icon, index (icon.id)}
{@const label = labels.iconsLabels[icon.id] ?? icon.label}
<button
class="carta-icon"
Expand Down Expand Up @@ -151,7 +147,7 @@

{#if showMenu && iconsHidden}
<div class="carta-icons-menu" style="top: {toolbarHeight}px;" bind:this={menu}>
{#each carta.icons.filter((icon) => !visibleIcons.includes(icon)) as icon}
{#each carta.icons.filter((icon) => !visibleIcons.includes(icon)) as icon (icon.id)}
{@const label = labels.iconsLabels[icon.id] ?? icon.label}

<button
Expand Down
2 changes: 0 additions & 2 deletions packages/plugin-component/src/routes/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@
});

let value = $state('');

$inspect(value);
</script>

<svelte:head>
Expand Down
6 changes: 3 additions & 3 deletions packages/plugin-emoji/src/lib/Emoji.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import { run } from 'svelte/legacy';

import type { Carta } from 'carta-md';
import { onDestroy, onMount } from 'svelte';
import { onDestroy, onMount, untrack } from 'svelte';
import * as nodeEmoji from 'node-emoji';
import type { TransitionConfig } from 'svelte/transition';

Expand All @@ -20,7 +20,7 @@
let colonPosition = 0;
let hoveringIndex = $state(0);
let emojis: { emoji: string; name: string }[] = $state([]);
let emojisElements: HTMLButtonElement[] = $state(Array(maxResults));
let emojisElements: HTMLButtonElement[] = $state(untrack(() => Array(maxResults).fill(null)));

onMount(() => {
carta.input?.textarea.addEventListener('keydown', handleKeyDown);
Expand Down Expand Up @@ -216,7 +216,7 @@

{#if visible && filter.length > 0 && emojis.length > 0}
<div class="carta-emoji" in:inTransition out:outTransition use:carta.bindToCaret>
{#each emojis as emoji, i}
{#each emojis as emoji, i (emoji.name)}
<button
class={i === hoveringIndex ? 'carta-active' : ''}
title={emoji.name}
Expand Down
10 changes: 5 additions & 5 deletions packages/plugin-slash/src/lib/Slash.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import type { Carta } from 'carta-md';
import type { SlashSnippet } from './snippets';
import type { TransitionConfig } from 'svelte/transition';
import { onDestroy, onMount } from 'svelte';
import { onDestroy, onMount, untrack } from 'svelte';

interface Props {
carta: Carta;
Expand All @@ -19,11 +19,11 @@
let hoveringIndex = $state(0);
let filter = '';
let slashPosition = 0;
let filteredSnippets = $state(snippets);
let filteredSnippets = $state(untrack(() => snippets));
let groupedSnippets: [string, SlashSnippet[]][] = $derived(
Object.entries(groupBy(filteredSnippets, 'group'))
);
let snippetsElements: HTMLButtonElement[] = $state(Array(snippets.length));
let snippetsElements: HTMLButtonElement[] = $state(Array(untrack(() => filteredSnippets.length)));

onMount(() => {
carta.input?.textarea.addEventListener('keydown', handleKeyDown);
Expand Down Expand Up @@ -146,11 +146,11 @@

{#if visible && filteredSnippets.length > 0}
<div class="carta-slash" in:inTransition out:outTransition use:carta.bindToCaret>
{#each groupedSnippets as [group, snippets], groupIndex}
{#each groupedSnippets as [group, snippets], groupIndex (groupIndex)}
<span class="carta-slash-group">
{group}
</span>
{#each snippets as snippet, elemIndex}
{#each snippets as snippet, elemIndex (elemIndex)}
<button
bind:this={snippetsElements[getSnippetIndex(groupIndex, elemIndex)]}
onclick={() => useSnippet(snippet)}
Expand Down
Loading
Loading