Skip to content

Commit

Permalink
Add scroll-into-view-if-needed ponyfill (#97)
Browse files Browse the repository at this point in the history
* yarn add -D scroll-into-view-if-needed

* readme add npm + pnpm install commands

* use scrollIntoView with scrollMode='if-needed' since scrollIntoViewIfNeeded not supported by Firefox (see #87)

* ensure input uses text color and not --sms-selected-text-color

* bump vite to v3.0.4

fixes import.meta.glob complains about template strings even if they're static (see vite#9349)

* add RepoSlot.svelte used in frontend_libs example
  • Loading branch information
janosh authored Aug 2, 2022
1 parent 13c26ca commit e01b88a
Show file tree
Hide file tree
Showing 13 changed files with 372 additions and 429 deletions.
28 changes: 14 additions & 14 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,16 @@
"package": "svelte-kit package",
"serve": "yarn build && yarn preview",
"check": "svelte-check --ignore package",
"test": "yarn vitest && playwright test tests/multiselect.test.ts",
"vitest": "vitest --run tests/index.test.ts tests/readme.test.ts"
"test": "vitest --run tests/index.test.ts tests/readme.test.ts && playwright test tests/multiselect.test.ts"
},
"devDependencies": {
"@playwright/test": "^1.23.1",
"@sveltejs/adapter-static": "^1.0.0-next.34",
"@sveltejs/kit": "^1.0.0-next.360",
"@sveltejs/vite-plugin-svelte": "^1.0.0-next.49",
"@typescript-eslint/eslint-plugin": "^5.30.5",
"@typescript-eslint/parser": "^5.30.5",
"eslint": "^8.19.0",
"@playwright/test": "^1.24.1",
"@sveltejs/adapter-static": "^1.0.0-next.38",
"@sveltejs/kit": "^1.0.0-next.396",
"@sveltejs/vite-plugin-svelte": "^1.0.1",
"@typescript-eslint/eslint-plugin": "^5.31.0",
"@typescript-eslint/parser": "^5.31.0",
"eslint": "^8.20.0",
"eslint-plugin-svelte3": "^4.0.0",
"hastscript": "^7.0.2",
"jsdom": "^20.0.0",
Expand All @@ -36,16 +35,17 @@
"prettier-plugin-svelte": "^2.7.0",
"rehype-autolink-headings": "^6.1.1",
"rehype-slug": "^5.0.1",
"svelte": "^3.48.0",
"scroll-into-view-if-needed": "^2.2.29",
"svelte": "^3.49.0",
"svelte-check": "^2.8.0",
"svelte-github-corner": "^0.1.0",
"svelte-preprocess": "^4.10.6",
"svelte-toc": "^0.2.9",
"svelte2tsx": "^0.5.11",
"svelte-toc": "^0.2.10",
"svelte2tsx": "^0.5.13",
"tslib": "^2.4.0",
"typescript": "^4.7.4",
"vite": "^2.9.13",
"vitest": "^0.18.0"
"vite": "^3.0.4",
"vitest": "^0.19.1"
},
"keywords": [
"svelte",
Expand Down
2 changes: 1 addition & 1 deletion playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
const config = {
browser: `chromium`,
webServer: {
command: `yarn serve`,
command: `yarn serve --port 3000`,
port: 3000,
},
}
Expand Down
10 changes: 7 additions & 3 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,17 @@

## Recent breaking changes

- v4.0.1 renamed the `readonly` prop to `disabled` which now prevents all form or user interaction with this component including opening the dropdown list which was still possible before. See [#45](https://github.com/janosh/svelte-multiselect/issues/45) for details. The associated CSS class applied to the outer `div` was likewise renamed to `div.multiselect.{readonly=>disabled}`.
- v4.0.1 renamed the `readonly` prop to `disabled` which now prevents all form of user interaction with this component including opening the dropdown list which was still possible before. See [#45](https://github.com/janosh/svelte-multiselect/issues/45) for details. The associated CSS class applied to the outer `div` was likewise renamed `div.multiselect.{readonly=>disabled}`.

- v4.0.3 CSS variables starting with `--sms-input-<attr>` were renamed to just `--sms-<attr>`. E.g. `--sms-input-min-height` is now `--sms-min-height`.

- v5.0.0 Support both simple and object options. Previously string or number options were converted to objects internally and returned by `bind:selected`. Now, if you pass in `string[]`, that's what you'll get from `bind:selected`.
- v5.0.0 Support both simple and object options. Previously strings and numbers were converted to `{ value, label }` objects internally and returned by `bind:selected`. Now, if you pass in `string[]`, that's exactly what you'll get from `bind:selected`.

## Installation

```sh
npm install -D svelte-multiselect
pnpm install -D svelte-multiselect
yarn add -D svelte-multiselect
```

Expand Down Expand Up @@ -108,9 +110,11 @@ Full list of props/bindable variables for this component:

## Exposed methods

1. `filterFunc = (op: Option, searchText: string) => boolean`: Determine what options are shown when user enters search string to filter dropdown list. Defaults to:
1. `filterFunc = (op: Option, searchText: string) => boolean`: Customize how dropdown options are filtered when user enters search string into `<MultiSelect />`. Defaults to:

```ts
import type { Option } from 'svelte-multiselect'

filterFunc = (op: Option, searchText: string) => {
if (!searchText) return true
return `${op.label}`.toLowerCase().includes(searchText.toLowerCase())
Expand Down
2 changes: 1 addition & 1 deletion src/components/Confetti.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
const emojis = [`🥳`, `🎉`, ``]
let confetti = [...new Array(nItems).keys()]
let confetti = [...Array(nItems).keys()]
.map((idx) => ({
emoji: emojis[idx % emojis.length],
x: Math.random() * 100,
Expand Down
5 changes: 4 additions & 1 deletion src/components/Examples.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import ColorSlot from './ColorSlot.svelte'
import Confetti from './Confetti.svelte'
import LanguageSlot from './LanguageSlot.svelte'
import RepoSlot from './RepoSlot.svelte'
let selected_ml: string[]
let selected_colors: ObjectOption[]
Expand Down Expand Up @@ -82,7 +83,9 @@
setTimeout(() => (showConfetti = false), 3000)
}
}}
/>
>
<RepoSlot let:idx {idx} let:option {option} slot="option" />
</MultiSelect>
{#if showConfetti}
<Confetti />
{/if}
Expand Down
36 changes: 36 additions & 0 deletions src/components/RepoSlot.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<script lang="ts">
import type { ObjectOption } from '../lib'
import { Octocat } from '../lib/icons'
export let option: ObjectOption
export let idx: number
</script>

<span>
<small>{idx + 1}</small>
<strong>{option.label}</strong>
<small on:click|stopPropagation>
<a href="https://github.com/{option.repo_handle}" target="_blank">
<Octocat width="14pt" />{option.repo_handle}
</a>
</small>
</span>

<style>
span {
display: flex;
place-items: center;
gap: 10pt;
}
span small:first-child {
width: 6pt;
text-align: right;
}
a {
display: flex;
gap: 3pt;
font-style: normal;
font-weight: lighter;
place-items: center;
}
</style>
7 changes: 5 additions & 2 deletions src/lib/MultiSelect.svelte
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<script lang="ts">
import scrollIntoView from 'scroll-into-view-if-needed'
import { createEventDispatcher } from 'svelte'
import type { DispatchEvents, MultiSelectEvents, Option } from './'
import { get_label, get_value } from './'
Expand Down Expand Up @@ -244,7 +245,7 @@
// around start/end of option list. Find a better solution than waiting 10 ms to.
setTimeout(() => {
const li = document.querySelector(`ul.options > li.active`)
li?.scrollIntoView()
if (li) scrollIntoView(li, { scrollMode: `if-needed` })
}, 10)
}
}
Expand Down Expand Up @@ -514,9 +515,11 @@
background: none;
flex: 1; /* this + next line fix issue #12 https://git.io/JiDe3 */
min-width: 2em;
color: inherit;
/* ensure input uses text color and not --sms-selected-text-color */
color: var(--sms-text-color);
font-size: inherit;
cursor: inherit; /* needed for disabled state */
border-radius: 0; /* reset ul.selected > li */
}
:where(div.multiselect > ul.selected > li > input)::placeholder {
padding-left: 5pt;
Expand Down
5 changes: 5 additions & 0 deletions src/lib/icons/Octocat.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<svg {...$$props} viewBox="0 0 24 24" fill="currentColor">
<path
d="M8.422 20.081c0 .896.01 1.753.016 2.285a.617.617 0 0 0 .422.58c2.078.686 4.317.718 6.414.091l.292-.087a.67.67 0 0 0 .478-.638c.005-.733.017-2.017.017-3.53c0-1.372-.477-2.25-1.031-2.707c3.399-.366 6.97-1.61 6.97-7.227c0-1.61-.592-2.91-1.566-3.934c.153-.366.688-1.866-.153-3.878c0 0-1.28-.403-4.201 1.5a14.76 14.76 0 0 0-3.82-.494c-1.298 0-2.597.165-3.819.494C5.52.65 4.24 1.036 4.24 1.036c-.84 2.012-.306 3.512-.153 3.878a5.565 5.565 0 0 0-1.566 3.934c0 5.598 3.552 6.86 6.951 7.227c-.439.366-.84 1.006-.973 1.957c-.879.384-3.075 1.006-4.45-1.207c-.286-.44-1.146-1.519-2.349-1.5c-1.28.018-.516.695.02.97c.648.347 1.393 1.646 1.565 2.067c.306.823 1.299 2.396 5.137 1.72Z"
/>
</svg>
1 change: 1 addition & 0 deletions src/lib/icons/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export { default as ExpandIcon } from './ChevronExpand.svelte'
export { default as CrossIcon } from './Cross.svelte'
export { default as DisabledIcon } from './Disabled.svelte'
export { default as Octocat } from './Octocat.svelte'
43 changes: 26 additions & 17 deletions src/options.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,30 @@
export const frontend_libs = [
[`Svelte`, `JavaScript`],
[`React`, `JavaScript`],
[`Vue`, `JavaScript`],
[`Angular`, `JavaScript`],
[`Polymer`, `JavaScript`],
[`Ruby on Rails`, `Ruby`],
[`ASP.net`, `C#`],
[`Laravel`, `PHP`],
[`Django`, `Python`],
[`Express`, `JavaScript`],
[`Spring`, `JavaScript`],
[`jQuery`, `JavaScript`],
[`Flask`, `Python`],
[`Flutter`, `Dart`],
[`Bootstrap`, `JavaScript`],
[`Sinatra`, `Ruby`],
].map(([label, lang]) => ({ label, value: label, lang }))
[`Svelte`, `JavaScript`, `sveltejs/svelte`],
[`React`, `JavaScript`, `facebook/react`],
[`Vue`, `JavaScript`, `vuejs/vue`],
[`Angular`, `JavaScript`, `angular/angular`],
[`Polymer`, `JavaScript`, `polymer/polymer`],
[`Ruby on Rails`, `Ruby`, `rubyonrails/rails`],
[`ASP.net`, `C#`, `aspnet/aspnet`],
[`Laravel`, `PHP`, `laravel/laravel`],
[`Django`, `Python`, `djangoproject/django`],
[`Express`, `JavaScript`, `expressjs/express`],
[`Spring`, `JavaScript`, `spring-projects/spring-framework`],
[`jQuery`, `JavaScript`, `jquery/jquery`],
[`Flask`, `Python`, `pallets/flask`],
[`Flutter`, `Dart`, `flutter/flutter`],
[`Bootstrap`, `JavaScript`, `twbs/bootstrap`],
[`Sinatra`, `Ruby`, `sinatra/sinatra`],
[`Solid`, `JavaScript`, `solidjs/solid`],
[`Ember JS`, `JavaScript`, `emberjs/ember.js`],
[`Backbone`, `JavaScript`, `jashkenas/backbone`],
[`Preact`, `JavaScript`, `preactjs/preact`],
].map(([label, lang, repo_handle]) => ({
label,
value: label,
lang,
repo_handle,
}))

export const ml_libs =
`TensorFlow PyTorch scikit-learn Spark ML Torch Huggingface Keras Caffe Theano CNTK`
Expand Down
4 changes: 2 additions & 2 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@

"paths": {
"$src/*": ["./src/*"],
"$lib": ["src/lib"],
"$lib/*": ["src/lib/*"]
"$lib": ["./src/lib"],
"$lib/*": ["./src/lib/*"]
}
}
}
7 changes: 5 additions & 2 deletions vite.config.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import { sveltekit } from '@sveltejs/kit/vite'
import path from 'path'
import { resolve } from 'path'

export default {
plugins: [sveltekit()],
test: {
environment: `jsdom`,
deps: {
inline: [`compute-scroll-into-view`],
},
},
resolve: {
alias: {
$src: path.resolve(`./src`),
$src: resolve(`./src`),
},
},
server: {
Expand Down
Loading

0 comments on commit e01b88a

Please sign in to comment.