diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3fc6d86..d8a7c6c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -38,8 +38,7 @@ repos: hooks: - id: eslint types: [file] - files: \.(svelte|js)$ - args: [--plugin, eslint-plugin-svelte3] + files: \.(svelte|js|ts)$ additional_dependencies: - eslint - svelte diff --git a/readme.md b/readme.md index 3950a84..9c8a245 100644 --- a/readme.md +++ b/readme.md @@ -1,6 +1,6 @@

- Svelte MultiSelect -
 Svelte MultiSelect + Svelte MultiSelect +
 Svelte MultiSelect

diff --git a/static/global.css b/src/app.css similarity index 90% rename from static/global.css rename to src/app.css index 67fb7c2..f333466 100644 --- a/static/global.css +++ b/src/app.css @@ -34,10 +34,12 @@ main { margin: auto; margin-bottom: 3em; width: 100%; + max-width: 50em; } a { color: var(--blue); text-decoration: none; + transition: 0.2s; } a:hover { color: orange; @@ -60,6 +62,9 @@ pre { a code { color: white; } +ul li { + margin: 1ex 0; +} div.table { overflow: scroll; @@ -76,6 +81,14 @@ tbody tr:nth-child(odd) { background: black; } +h1 { + display: flex; + font-size: clamp(2rem, 2rem + 2vw, 3rem); + place-items: center; + place-content: center; + margin: 1.2em 0; +} + :where(h2, h3, h4, h5, h6) { scroll-margin-top: 50px; transition: 0.3s; diff --git a/src/app.html b/src/app.html index 266ce82..6289a3c 100644 --- a/src/app.html +++ b/src/app.html @@ -17,7 +17,6 @@ - diff --git a/src/routes/__error.svelte b/src/routes/__error.svelte index 8f5a6ea..5357dbc 100644 --- a/src/routes/__error.svelte +++ b/src/routes/__error.svelte @@ -1,6 +1,61 @@ - - onMount(() => goto(`/`)) // go back to index page on missing routes + + + + {status} error + + +
+ {#if status === 404} +

{error.name} {status}: Page not found 😅

+ {:else if status >= 500} +

{error.name} {status}

+

+ This may be our fault. If page reloading doesn't help, please raise an issue on + GitHub. Thanks! 🙏 +

+ {:else} +

⚠️ {error.name} {status}

+ {/if} +

+ Return to index page. +

+ + {#if dev && error?.stack} +

Stack Trace

+
{error.stack}
+ {/if} +
+ + diff --git a/src/routes/__layout.svelte b/src/routes/__layout.svelte new file mode 100644 index 0000000..955d601 --- /dev/null +++ b/src/routes/__layout.svelte @@ -0,0 +1,8 @@ + + + + + diff --git a/src/routes/demos/__layout.svelte b/src/routes/demos/__layout.svelte new file mode 100644 index 0000000..642bb83 --- /dev/null +++ b/src/routes/demos/__layout.svelte @@ -0,0 +1,66 @@ + + +« back +

+ Svelte MultiSelect Svelte + MultiSelect +

+ +

Other examples

+ + +
+ +
+ + diff --git a/src/routes/css-classes.svx b/src/routes/demos/css-classes.svx similarity index 75% rename from src/routes/css-classes.svx rename to src/routes/demos/css-classes.svx index 58a6fee..b528889 100644 --- a/src/routes/css-classes.svx +++ b/src/routes/demos/css-classes.svx @@ -1,13 +1,9 @@ -
- -# External CSS Classes - -When using CSS frameworks like Tailwind, you can customize the appearance of `` through the following classes: +## External CSS Classes ```svelte ``` +
+ + -
+
+ +When using CSS frameworks like Tailwind, you can customize the appearance of `` through the following classes: diff --git a/src/routes/disabled.svx b/src/routes/demos/disabled.svx similarity index 76% rename from src/routes/disabled.svx rename to src/routes/demos/disabled.svx index 980dc36..1e69eae 100644 --- a/src/routes/disabled.svx +++ b/src/routes/demos/disabled.svx @@ -1,10 +1,9 @@ -
- -# Disabled +## Disabled ```svelte ``` +
+ + This component is disabled. Get outta here! - -
diff --git a/src/routes/max-select.svx b/src/routes/demos/max-select.svx similarity index 61% rename from src/routes/max-select.svx rename to src/routes/demos/max-select.svx index feff1c1..b8d4e15 100644 --- a/src/routes/max-select.svx +++ b/src/routes/demos/max-select.svx @@ -1,19 +1,10 @@ -
- -# Disabled MultiSelect - -Test that component in disabled state: - -- has attribute aria-disabled -- has disabled title -- has `` -- renders no buttons -- renders disabled slot +## Disabled MultiSelect ```svelte ``` +
+ +> + + + +
-
+Test that component in disabled state: + +- has attribute aria-disabled +- has disabled title +- has `` +- renders no buttons +- renders disabled slot diff --git a/src/routes/ui.svx b/src/routes/demos/ui.svx similarity index 71% rename from src/routes/ui.svx rename to src/routes/demos/ui.svx index 7a0a571..eca5c7e 100644 --- a/src/routes/ui.svx +++ b/src/routes/demos/ui.svx @@ -1,11 +1,31 @@ -
+## User interface -# User interface +```svelte + +``` + +
+ + + + +
This page is mostly used for testing. It checks that: @@ -15,7 +35,8 @@ This page is mostly used for testing. It checks that: - has custom title (if supplied with `removeAllTitle`) - component can be focused - which opens dropdown - - and closes dropdown when input looses focus + - and closes dropdown when user tabs out of input or clicks outside component + - importantly, we don't close dropdown when input looses focus - filters options to only list matches when entering text - accessibility - input is `aria-invalid` when component has `invalid=true` @@ -23,21 +44,3 @@ This page is mostly used for testing. It checks that: - has `aria-expanded='true'` when open - options have `aria-selected='false'` and selected items have `aria-selected='true` - invisible `input.form-control` is `aria-hidden` - -```svelte - -``` - - - -
diff --git a/src/routes/index.svelte b/src/routes/index.svelte index 6ca6b01..f9a5723 100644 --- a/src/routes/index.svelte +++ b/src/routes/index.svelte @@ -1,14 +1,13 @@ - -
@@ -17,42 +16,21 @@
+ diff --git a/src/routes/index.ts b/src/routes/index.ts deleted file mode 100644 index 771b477..0000000 --- a/src/routes/index.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { RequestHandler } from '@sveltejs/kit' - -export const get: RequestHandler = async () => { - const routes = Object.keys(import.meta.glob(`./*.svx`)).map( - (filename) => filename.split(`.`)[1] - ) - - return { body: { routes } } -} diff --git a/svelte.config.js b/svelte.config.js index 06710df..77b66a5 100644 --- a/svelte.config.js +++ b/svelte.config.js @@ -1,6 +1,7 @@ import adapter from '@sveltejs/adapter-static' import { s } from 'hastscript' import { mdsvex } from 'mdsvex' +import path from 'path' import linkHeadings from 'rehype-autolink-headings' import headingSlugs from 'rehype-slug' import preprocess from 'svelte-preprocess' @@ -42,6 +43,11 @@ export default { }, vite: { + resolve: { + alias: { + $src: path.resolve(`./src`), + }, + }, server: { fs: { allow: [`..`] }, // needed to import readme.md }, diff --git a/tests/multiselect.test.ts b/tests/multiselect.test.ts index 4052b35..d4df23e 100644 --- a/tests/multiselect.test.ts +++ b/tests/multiselect.test.ts @@ -21,13 +21,13 @@ const context = await browser.newContext({ describe(`input`, async () => { const page = await context.newPage() - await page.goto(`/ui`) + await page.goto(`/demos/ui`) test(`opens dropdown on focus`, async () => { expect(await page.$(`.multiselect > ul.options.hidden`)).toBeTruthy() expect(await page.$(`.multiselect.open`)).toBeNull() - await page.click(`input[placeholder='Pick your favorite fruits']`) + await page.click(`input[placeholder='Pick your favorite fruits!']`) expect(await page.$(`.multiselect.open`)).toBeTruthy() await page.waitForTimeout(500) // give DOM time to update @@ -42,9 +42,9 @@ describe(`input`, async () => { test(`closes dropdown on tab out`, async () => { // note we only test for close on tab out, not on blur since blur should not close in case user // clicked anywhere else inside component - await page.click(`input[placeholder='Pick your favorite fruits']`) + await page.click(`input[placeholder='Pick your favorite fruits!']`) - await page.focus(`input[placeholder='Pick your favorite fruits']`) + await page.focus(`input[placeholder='Pick your favorite fruits!']`) await page.keyboard.press(`Tab`) await page.waitForTimeout(500) // give DOM time to update @@ -57,7 +57,7 @@ describe(`input`, async () => { test(`filters dropdown to show only matching options when entering text`, async () => { await page.fill( - `input[placeholder='Pick your favorite fruits']`, + `input[placeholder='Pick your favorite fruits!']`, `Pineapple` ) @@ -71,7 +71,7 @@ describe(`input`, async () => { describe(`remove all button`, async () => { const page = await context.newPage() - await page.goto(`/ui`) + await page.goto(`/demos/ui`) await page.click(`.multiselect`) // open the dropdown await page.click(`.multiselect > ul.options > li`) // select 1st option @@ -101,7 +101,7 @@ describe(`remove all button`, async () => { describe(`external CSS classes`, async () => { const page = await context.newPage() - await page.goto(`/css-classes`) + await page.goto(`/demos/css-classes`) await page.click(`.multiselect`) // open the dropdown await page.click(`.multiselect > ul.options > li`) // select 1st option @@ -126,7 +126,7 @@ describe(`external CSS classes`, async () => { describe(`disabled multiselect`, async () => { const page = await context.newPage() - await page.goto(`/disabled`) + await page.goto(`/demos/disabled`) const div = await page.$(`.multiselect.disabled`) test(`has attribute aria-disabled`, async () => { @@ -156,12 +156,12 @@ describe(`disabled multiselect`, async () => { describe(`accessibility`, async () => { const page = await context.newPage() - await page.goto(`/ui`) + await page.goto(`/demos/ui`) test(`input is aria-invalid when component has invalid=true`, async () => { // don't interact with component before this test as it will set invalid=false const invalid = await page.getAttribute( - `input[placeholder='Pick your favorite fruits']`, + `input[placeholder='Pick your favorite fruits!']`, `aria-invalid`, { strict: true } ) @@ -213,9 +213,9 @@ describe(`accessibility`, async () => { describe(`multiselect`, async () => { test(`can select and remove many options`, async () => { const page = await context.newPage() - await page.goto(`/ui`) + await page.goto(`/demos/ui`) - await page.locator(`[placeholder="Pick your favorite fruits"]`).click() + await page.locator(`[placeholder="Pick your favorite fruits!"]`).click() for (const option of [`Avocado`, `Cherries`, `Peach`, `Lychee`, `Kiwi`]) { await page.locator(`text=${option} >> nth=0`).click() diff --git a/tsconfig.json b/tsconfig.json index 9ca761d..e03e36e 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -10,6 +10,10 @@ // enable source maps by default. "sourceMap": true, - "forceConsistentCasingInFileNames": true + "forceConsistentCasingInFileNames": true, + + "paths": { + "$src/*": ["./src/*"] + } } }