{"id":13723189,"url":"https://github.com/flekschas/svelte-simple-modal","last_synced_at":"2025-05-14T18:02:12.828Z","repository":{"id":34880878,"uuid":"186435238","full_name":"flekschas/svelte-simple-modal","owner":"flekschas","description":"A simple, small, and content-agnostic modal for Svelte v3, v4, and v5","archived":false,"fork":false,"pushed_at":"2025-03-10T13:59:49.000Z","size":645,"stargazers_count":426,"open_issues_count":7,"forks_count":33,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-05-14T18:01:43.155Z","etag":null,"topics":["dialog","modal","popup","svelte","svelte-components","svelte-v3","svelte-v4","svelte-v5"],"latest_commit_sha":null,"homepage":"https://svelte.dev/playground/b95ce66b0ef34064a34afc5c0249f313?version=5.17.3","language":"Svelte","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/flekschas.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-05-13T14:23:28.000Z","updated_at":"2025-04-29T04:43:47.000Z","dependencies_parsed_at":"2023-02-12T12:30:31.447Z","dependency_job_id":"89b38bb3-61d1-4798-8945-fbb73ba62f0e","html_url":"https://github.com/flekschas/svelte-simple-modal","commit_stats":{"total_commits":211,"total_committers":16,"mean_commits":13.1875,"dds":"0.17535545023696686","last_synced_commit":"7127035dabc0716bd516250acb177825c37b4e62"},"previous_names":[],"tags_count":51,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flekschas%2Fsvelte-simple-modal","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flekschas%2Fsvelte-simple-modal/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flekschas%2Fsvelte-simple-modal/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flekschas%2Fsvelte-simple-modal/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/flekschas","download_url":"https://codeload.github.com/flekschas/svelte-simple-modal/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254198453,"owners_count":22030964,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dialog","modal","popup","svelte","svelte-components","svelte-v3","svelte-v4","svelte-v5"],"created_at":"2024-08-03T01:01:37.002Z","updated_at":"2025-05-14T18:02:12.758Z","avatar_url":"https://github.com/flekschas.png","language":"Svelte","funding_links":[],"categories":["components and libraries"],"sub_categories":["layout and structure"],"readme":"\u003ch1 align=\"center\"\u003e\n  Svelte Simple Modal\n\u003c/h1\u003e\n\n\u003cdiv align=\"center\"\u003e\n  \n  **A simple, small, and content-agnostic modal for [Svelte](https://svelte.dev).**\n  \n\u003c/div\u003e\n\n\u003cbr/\u003e\n\n\u003cdiv align=\"center\"\u003e\n  \n  [![NPM Version](https://img.shields.io/npm/v/svelte-simple-modal.svg?style=flat-square\u0026color=7f99ff)](https://npmjs.org/package/svelte-simple-modal)\n  [![Build Status](https://img.shields.io/github/actions/workflow/status/flekschas/svelte-simple-modal/build.yml?branch=master\u0026color=a17fff\u0026style=flat-square)](https://github.com/flekschas/svelte-simple-modal/actions?query=workflow%3Abuild)\n  [![File Size](http://img.badgesize.io/https://unpkg.com/svelte-simple-modal/src/Modal.svelte?compression=gzip\u0026style=flat-square\u0026color=e17fff)](https://bundlephobia.com/result?p=svelte-simple-modal)\n  [![Code Style Prettier](https://img.shields.io/badge/code%20style-prettier-ff7fe1.svg?style=flat-square)](https://github.com/prettier/prettier#readme)\n  [![Demo](https://img.shields.io/badge/demo-👍-ff7fa5.svg?style=flat-square)](https://svelte.dev/repl/033e824fad0a4e34907666e7196caec4?version=3.18.2)\n  \n\u003c/div\u003e\n\n\u003cdiv id=\"teaser-matrices\" align=\"center\"\u003e\n  \n  ![simple-modal](https://user-images.githubusercontent.com/932103/57642565-9d335d00-7585-11e9-80c6-e4b835f02428.gif)\n  \n\u003c/div\u003e\n\n**Live demo:** https://svelte.dev/playground/b95ce66b0ef34064a34afc5c0249f313?version=5.17.3\n\n**Works with:** Svelte `\u003e=v5`!\n\n\u003e [!NOTE]  \n\u003e If you want to use Svelte Simple Modal with Svelte v3 or v4, check out [version 1](https://github.com/flekschas/svelte-simple-modal/tree/v1).\n\n## Table of Contents\n\n- [Install](#install)\n  - [Rollup Setup](#rollup-setup)\n- [Usage](#usage)\n  - [TypeScript Example](#usage-with-typescript)\n  - [Svelte Store Example](#usage-with-a-svelte-store)\n  - [Styling](#styling)\n  - [SSR](#server-side-rendering)\n  - [Accessibility](#accessibility)\n- [API](#api)\n  - [Component](#component-api)\n  - [Events](#component-events)\n  - [Context API](#context-api)\n  - [Store API](#store-api)\n- [FAQ](#faq)\n\n## Install\n\n```bash\nnpm install --save svelte-simple-modal\n```\n\n#### Rollup Setup\n\nMake sure that the main application's version of `svelte` is used for bundling by setting `@rollup/plugin-node-resolve`'s `dedupe` option as follows:\n\n```js\nimport resolve from '@rollup/plugin-node-resolve';\n\nexport default {\n  plugins: [\n    resolve({\n      dedupe: ['svelte', 'svelte/transition', 'svelte/internal'], // important!\n    }),\n  ],\n};\n```\n\n## Usage\n\nImport the `Modal` component into your main app component (e.g., `App.svelte`).\n\nThe modal is exposing [two context functions](#context-api):\n\n- [`open()`](#open) opens a component as a modal.\n- [`close()`](#close) simply closes the modal.\n\n```svelte\n\u003c!-- App.svelte --\u003e\n\u003cscript\u003e\n  import Content from './Content.svelte';\n  import Modal from 'svelte-simple-modal';\n\u003c/script\u003e\n\n\u003cModal\u003e\u003cContent /\u003e\u003c/Modal\u003e\n\n\n\u003c!-- Content.svelte --\u003e\n\u003cscript\u003e\n  import { getContext } from 'svelte';\n  import Popup from './Popup.svelte';\n  const { open } = getContext('simple-modal');\n  const showSurprise = () =\u003e open(Popup, { message: \"It's a modal!\" });\n\u003c/script\u003e\n\n\u003cp\u003e\u003cbutton on:click={showSurprise}\u003eShow me a surprise!\u003c/button\u003e\u003c/p\u003e\n\n\n\u003c!-- Popup.svelte --\u003e\n\u003cscript\u003e\n  export let message = 'Hi';\n\u003c/script\u003e\n\n\u003cp\u003e🎉 {message} 🍾\u003c/p\u003e\n```\n\n**Demo:** https://svelte.dev/repl/52e0ade6d42546d8892faf8528c70d30\n\n### Usage with TypeScript\n\nYou can use the `Context` type exported by the package to validate the `getContext` function:\n\n```ts\nimport type { Context } from 'svelte-simple-modal';\nconst { open } = getContext\u003cContext\u003e('simple-modal');\n// ...\n```\n\n### Usage With a Svelte Store\n\nAlternatively, you can use a [Svelte store](#store-api) to show/hide a component as a modal.\n\n```svelte\n\u003c!-- App.svelte --\u003e\n\u003cscript\u003e\n  import { writable } from 'svelte/store';\n  import Modal, { bind } from 'svelte-simple-modal';\n  import Popup from './Popup.svelte';\n  const modal = writable(null);\n  const showModal = () =\u003e modal.set(bind(Popup, { message: \"It's a modal!\" }));\n\u003c/script\u003e\n\n\u003cModal show={$modal}\u003e\n  \u003cbutton on:click={showModal}\u003eShow modal\u003c/button\u003e\n\u003c/Modal\u003e\n```\n\n**Demo:** https://svelte.dev/repl/aec0c7d9f5084e7daa64f6d0c8ef0209\n\nThe `\u003cPopup /\u003e` component is the same as in the example above.\n\nTo hide the modal programmatically, simply unset the store. E.g., `modal.set(null)`.\n\n### Styling\n\nThe modal comes pre-styled for convenience but you can easily extent or replace the styling using either custom CSS classes or explicit CSS styles.\n\nCustom CSS classes can be applied via the `classBg`, `classWindow`, `classWindowWrap`, `classContent`, and `classCloseButton` properties. For instance, you could customize the styling with [TailwindCSS](https://tailwindcss.com/) as follows:\n\n```svelte\n\u003cModal\n  show={$modal}\n  unstyled={true}\n  classBg=\"fixed top-0 left-0 w-screen h-screen flex flex-col justify-center bg-orange-100/[.9]\"\n  classWindowWrap=\"relative m-2 max-h-full\"\n  classWindow=\"relative w-40 max-w-full max-h-full my-2 mx-auto text-orange-200 rounded shadow-md bg-indigo-900\"\n  classContent=\"relative p-2 overflow-auto\"\n  closeButton={false}\n\u003e\n  \u003cbutton on:click={showModal}\u003eShow modal\u003c/button\u003e\n\u003c/Modal\u003e\n```\n\n**Demo:** https://svelte.dev/repl/f2a988ddbd5644f18d7cd4a4a8277993\n\n\u003e Note: to take full control over the modal styles with CSS classes you have to reset existing styles via `unstyled={true}` as internal CSS classes are always applied last due to Svelte's class scoping.\n\nAlternatively, you can also apply CSS styles directly via the `styleBg`, `styleWindow`, `styleWindowWrap`, `styleContent`, and `styleCloseButton` properties. For instance:\n\n```svelte\n\u003cModal\n  show={$modal}\n  styleBg={{ backgroundColor: 'rgba(255, 255, 255, 0.85)' }}\n  styleWindow={{ boxShadow: '0 2px 5px 0 rgba(0, 0, 0, 0.15)' }}\n\u003e\n  \u003cbutton on:click={showModal}\u003eShow modal\u003c/button\u003e\n\u003c/Modal\u003e\n```\n\n**Demo:** https://svelte.dev/repl/50df1c694b3243c1bd524b27f86eec51\n\n### Server-Side Rendering\n\nWith [SvelteKit](https://kit.svelte.dev/) you can enable [SSR](https://www.google.com/search?q=server+side+rendering) using the `browser` environmental variable as follows:\n\n```svelte\n\u003cscript\u003e\n  import Modal from 'svelte-simple-modal';\n  import { browser } from '$app/env';\n\u003c/script\u003e\n\n{#if browser}\n  \u003cModal\u003e\n    \u003cContent /\u003e\n  \u003c/Modal\u003e\n{/if}\n```\n\nAlternatively, you can enable SSR by dynamically importing svelte-simple-modal in `onMount()` as follows:\n\n```js\nimport { onMount } from 'svelte';\n\nonMount(async () =\u003e {\n  const svelteSimpleModal = await import('svelte-simple-modal');\n  Modal = svelteSimpleModal.default;\n});\n```\n\n### Accessibility\n\nThe library applies the following WAI-ARIA guidelines for modal dialogs\nautomtically:\n\n- `aria-modal=\"true\"` and `role=\"dialog\"` are applied automatically\n- The tab focus is trapped in the modal\n- The modal is closed on pressing the `esc` key\n\nTo further improve the accessibility you'll have to either provide a label via\n[`ariaLabel`](https://www.w3.org/TR/wai-aria-1.1/#aria-label) or reference a\ntitle element via [`ariaLabelledBy`](https://www.w3.org/TR/wai-aria-1.1/#aria-labelledby).\nThe `ariaLabel` is automatically omitted when `ariaLabelledBy` is specified.\n\n## API\n\n### Component API\n\nThe `\u003cModal /\u003e` component accepts the following optional properties:\n\n| Property                  | Type                                                 | Default             | Description                                                                                                                                                                                                                                                 |\n| ------------------------- | ---------------------------------------------------- | ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| **show**                  | Component \\| null                                    | `null`              | A Svelte component to show as the modal. See [Store API](#store-api) for details.                                                                                                                                                                           |\n| **id**                    | string \\| null                                       | `null`              | Element ID to be assigned to the modal's root DOM element.                                                                                                                                                                                                  |\n| **ariaLabel**             | string \\| null                                       | `null`              | Accessibility label of the modal. See [W3C WAI-ARIA](https://www.w3.org/TR/wai-aria-1.1/#aria-label) for details.                                                                                                                                           |\n| **ariaLabelledBy**        | string \\| null                                       | `null`              | Element ID holding the accessibility label of the modal. See [W3C WAI-ARIA](https://www.w3.org/TR/wai-aria-1.1/#aria-labelledby) for details.                                                                                                               |\n| **closeButton**           | Component \\| boolean                                 | `true`              | If `true` a button for closing the modal is rendered. You can also pass in a [custom Svelte component](#custom-close-button) to have full control over the styling.                                                                                         |\n| **closeOnEsc**            | boolean                                              | `true`              | If `true` the modal will close when pressing the escape key.                                                                                                                                                                                                |\n| **closeOnOuterClick**     | boolean                                              | `true`              | If `true` the modal will close when clicking outside the modal window.                                                                                                                                                                                      |\n| **transitionBg**          | function                                             | `svelte.fade`       | Transition function for the background.                                                                                                                                                                                                                     |\n| **transitionBgProps**     | BlurParams \\| FadeParams \\| FlyParams \\| SlideParams | `{}`                | Properties of the transition function for the background.                                                                                                                                                                                                   |\n| **transitionWindow**      | function                                             | `svelte.fade`       | Transition function for the window.                                                                                                                                                                                                                         |\n| **transitionWindowProps** | BlurParams \\| FadeParams \\| FlyParams \\| SlideParams | `{}`                | Properties of the transition function for the window.                                                                                                                                                                                                       |\n| **classBg**               | string \\| null                                       | `null`              | Class name for the background element.                                                                                                                                                                                                                      |\n| **classWindowWrap**       | string \\| null                                       | `null`              | Class name for the modal window wrapper element.                                                                                                                                                                                                            |\n| **classWindow**           | string \\| null                                       | `null`              | Class name for the modal window element.                                                                                                                                                                                                                    |\n| **classContent**          | string \\| null                                       | `null`              | Class name for the modal content element.                                                                                                                                                                                                                   |\n| **classCloseButton**      | string \\| null                                       | `null`              | Class name for the built-in close button.                                                                                                                                                                                                                   |\n| **styleBg**               | Record\u003cstring, string \\| number\u003e                     | `{}`                | Style properties of the background.                                                                                                                                                                                                                         |\n| **styleWindowWrap**       | Record\u003cstring, string \\| number\u003e                     | `{}`                | Style properties of the modal window wrapper element.                                                                                                                                                                                                       |\n| **styleWindow**           | Record\u003cstring, string \\| number\u003e                     | `{}`                | Style properties of the modal window.                                                                                                                                                                                                                       |\n| **styleContent**          | Record\u003cstring, string \\| number\u003e                     | `{}`                | Style properties of the modal content.                                                                                                                                                                                                                      |\n| **styleCloseButton**      | Record\u003cstring, string \\| number\u003e                     | `{}`                | Style properties of the built-in close button.                                                                                                                                                                                                              |\n| **unstyled**              | boolean                                              | `false`             | When `true`, the default styles are not applied to the modal elements.                                                                                                                                                                                      |\n| **disableFocusTrap**      | boolean                                              | `false`             | If `true` elements outside the modal can be in focus. This can be useful in certain edge cases.                                                                                                                                                             |\n| **isTabbable**            | (node: Element): boolean                             | internal function   | A function to determine if an HTML element is tabbable.                                                                                                                                                                                                     |\n| **key**                   | string                                               | `\"simple-modal\"`    | The context key that is used to expose `open()` and `close()`. Adjust to avoid clashes with other contexts.                                                                                                                                                 |\n| **setContext**            | function                                             | `svelte.setContent` | You can normally ingore this property when you have [configured Rollup properly](#rollup-setup). If you want to bundle simple-modal with its own version of Svelte you have to pass `setContext()` from your main app to simple-modal using this parameter. |\n\n### Component Events\n\nThe `\u003cModal /\u003e` component dispatches the following events:\n\n- `open`: dispatched when the modal window starts to open.\n- `opened`: dispatched when the modal window opened.\n- `close`: dispatched when the modal window starts to close.\n- `closed`: dispatched when the modal window closed.\n\nAlternatively, you can listen to those events via callbacks passed to [`open()`](#open) and [`close()`](#close).\n\n### Context API\n\nSvelte Simple Modal uses [Svelte's context API](https://svelte.dev/tutorial/context-api) to expose the `open()` and `close()` methods. You can get these methods as follows:\n\n```js\nconst { open, close } = getContext('simple-modal');\n```\n\n\u003ca name=\"open\" href=\"#open\"\u003e#\u003c/a\u003e \u003cb\u003eopen\u003c/b\u003e(\u003ci\u003eComponent\u003c/i\u003e, \u003ci\u003eprops = {}\u003c/i\u003e, \u003ci\u003eoptions = {}\u003c/i\u003e, \u003ci\u003ecallbacks = {}\u003c/i\u003e)\n\nOpens the modal with `\u003cComponent {props}\u003e` rendered as the content. `options` can be used to adjust the modal behavior once for the modal that is about to be opened. The `options` allows to customize all [parameters](#parameters) except `key` and `setContext`:\n\n```javascript\n{\n  closeButton: false,\n  closeOnEsc: false,\n  closeOnOuterClick: false,\n  transitionBg: fade,\n  transitionBgProps: {\n    duration: 5000\n  },\n  transitionWindow: fly,\n  transitionWindowProps: {\n    y: 100,\n    duration: 250\n  },\n  styleBg: { backgroundImage: 'http://example.com/my-background.jpg' },\n  styleWindow: { fontSize: '20em' },\n  styleContent: { color: 'yellow' },\n  styleCloseButton: { width: '3rem', height: '3rem' },\n  disableFocusTrap: true\n}\n```\n\n\u003ca name=\"close\" href=\"#close\"\u003e#\u003c/a\u003e \u003cb\u003eclose\u003c/b\u003e(\u003ci\u003ecallbacks = {}\u003c/i\u003e)\n\nCloses the modal. Similar to `open()`, this method supports adding callbacks for the closing transition:\n\n```javascript\n{\n  onClose: () =\u003e { /* modal window starts to close */ },\n  onClosed: () =\u003e { /* modal window closed */ },\n}\n```\n\nCallbacks are triggered at the beginning and end of the opening and closing transition. The following callbacks are supported:\n\n```javascript\n{\n  onOpen: () =\u003e { /* modal window starts to open */ },\n  onOpened: () =\u003e { /* modal window opened */ },\n  onClose: () =\u003e { /* modal window starts to close */ },\n  onClosed: () =\u003e { /* modal window closed */ },\n}\n```\n\n### Store API\n\nYou can also use [Svelte stores](https://svelte.dev/tutorial/writable-stores) to open a modal using the `\u003cModal /\u003e`'s [`show` property](#properties) as follows:\n\n```svelte\n\u003c!-- App.svelte --\u003e\n\u003cscript\u003e\n  import { writable } from 'svelte/store';\n  import Modal from 'svelte-simple-modal';\n  import Popup from './Popup.svelte';\n  const modal = writable(null);\n  const showModal = () =\u003e modal.set(Popup);\n\u003c/script\u003e\n\n\u003cModal show={$modal}\u003e\n  \u003cbutton on:click={showModal}\u003eShow modal\u003c/button\u003e\n\u003c/Modal\u003e\n\n\u003c!-- Popup.svelte --\u003e\n\u003cp\u003e🎉 Hi 🍾\u003c/p\u003e\n```\n\n**Demo:** https://svelte.dev/repl/6f55b643195646408e780ceeb779ac2a\n\nAn added benefit of using stores is that the component opening the modal does not have to be a parent of `\u003cModal /\u003e`. For instance, in the example above, `App.svelte` is toggling `Popup.svelte` as a modal even though `App.svelte` is not a child of `\u003cModal /\u003e`.\n\n#### Bind Props to a Component Shown as a Modal\n\nSometimes you want to pass properties to the component shown as a modal. To accomplish this, you can use our `bind()` helper function as follows:\n\n```svelte\n\u003cscript\u003e\n  import { bind } from 'svelte-simple-modal';\n  import Popup from './Popup.svelte';\n  import { modal } from './App.svelte';\n\n  modal.set(bind(Popup, { name: 'custom name' }));\n\u003c/script\u003e\n```\n\nIf you've worked with React/JSX then think of `const c = bind(Component, props)` as the equivalent of `const c = \u003cComponent ...props /\u003e`.\n\n## FAQ\n\n#### Custom Close Button\n\n**This feature requires Svelte \u003e=v3.19!**\n\nUnfortunately, it's not possible to adjust all styles of the built-in close button via the `styleCloseButton` option. If you need full control you can implement your own Svelte component and use that as the close button. To do so pass your component via the `closeButton` option to `\u003cModal /\u003e` or `open()`.\n\nFor example, your close button might look as follows:\n\n```svelte\n\u003c!-- CloseButton.svelte --\u003e\n\u003cscript\u003e\n  // This property is used by Modal.svelte to pass down the close function\n  export let onClose;\n\u003c/script\u003e\n\n\u003cbutton on:click={onClose}\u003eCustom Close Button\u003c/button\u003e\n\n\u003cstyle\u003e\n  /* Customize to your liking */\n  button {\n    position: absolute;\n    top: -3rem;\n    right: 0;\n  }\n\u003c/style\u003e\n```\n\nNow you can set it as the default close button by passing it to `\u003cModal /\u003e` as follows:\n\n```svelte\n\u003c!-- App.svelte --\u003e\n\u003cscript\u003e\n  import Content from './Content.svelte';\n  import CloseButton from './CloseButton.svelte';\n  import Modal from 'svelte-simple-modal';\n\u003c/script\u003e\n\n\u003cModal closeButton={CloseButton}\u003e\n  \u003cContent /\u003e\n\u003c/Modal\u003e\n```\n\nOr you can pass `CloseButton` to `open()` as shown below:\n\n```svelte\n\u003c!-- Content.svelte --\u003e\n\u003cscript\u003e\n  import { getContext } from 'svelte';\n  import Surprise from './Surprise.svelte';\n  import CloseButton from './CloseButton.svelte';\n\n  const { open } = getContext('simple-modal');\n\n  const showSurprise = () =\u003e {\n    open(Surprise, { message: \"It's a modal!\" }, { closeButton: CloseButton });\n  };\n\u003c/script\u003e\n\n\u003cp\u003e\u003cbutton on:click={showSurprise}\u003eShow me a surprise!\u003c/button\u003e\u003c/p\u003e\n```\n\n## License\n\n[MIT](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflekschas%2Fsvelte-simple-modal","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fflekschas%2Fsvelte-simple-modal","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflekschas%2Fsvelte-simple-modal/lists"}