use fluent UI

This commit is contained in:
cupcakearmy 2022-01-16 01:27:04 +01:00
parent fbd535a63c
commit ebd0199375
No known key found for this signature in database
GPG Key ID: 3235314B4D31232F
6 changed files with 69 additions and 55 deletions

View File

@ -1,6 +1,6 @@
# svelte-hint # svelte-hint
Svelte library for tooltips internally powered by the awesome [Popper.js](https://popper.js.org/) with sensible default values. Svelte library for tooltips internally powered by the awesome [Fluent UI](https://floating-ui.com/) with sensible default values.
Check out the **[demo](https://svelte-hint.pages.dev/)** to see it in action. Check out the **[demo](https://svelte-hint.pages.dev/)** to see it in action.
@ -51,11 +51,12 @@ npm install svelte-hint
### Props ### Props
| Prop | Type | Default | Description | | Prop | Type | Default | Description |
| ----------- | ----------------------- | ------------------- | ----------------------------------------------------------------------------------------------------- | | ----------- | ----------------------------- | ------------------- | --------------------------------------------------------------------------------------------------------------------- |
| `placement` | `Placement` | `auto` | For possible values see [popper](https://popper.js.org/docs/v2/constructors/#options). |
| `text` | `string` | `''` | Text to be used as the tooltip. If empty the slot will be used. | | `text` | `string` | `''` | Text to be used as the tooltip. If empty the slot will be used. |
| `boundary` | `HTMLElement \| string` | `'clippingParents'` | See [popper docs](https://popper.js.org/docs/v2/utils/detect-overflow/#boundary) for possible values. | | `placement` | `Placement` | `auto` | See the [Fluent UI docs](https://floating-ui.com/docs/computePosition#placement). |
| `offset` | `number` | `4` | The offset is the distance that the tooltip gets positioned from the trigger. | | `boundary` | `HTMLElement \| string` | `'clippingParents'` | See the [Fluent UI docs](https://floating-ui.com/docs/detectOverflow#boundary). |
| `offset` | `Options` | `4` | See the [Fluent UI docs](https://floating-ui.com/docs/offset#options). |
| `auto` | `boolean \| 'start' \| 'end'` | `false` | Use the [`autoPlacement`](https://floating-ui.com/docs/autoPlacement) middleware. If set `placement` will be ignored. |
### Slots ### Slots

View File

@ -1,6 +1,6 @@
{ {
"name": "svelte-hint", "name": "svelte-hint",
"version": "1.0.0-rc.1", "version": "1.0.0-rc.2",
"description": "Tooltip library for svelte", "description": "Tooltip library for svelte",
"author": { "author": {
"name": "Niccolo Borgioli", "name": "Niccolo Borgioli",
@ -19,6 +19,7 @@
"publish": "rm -rf ./package && pnpm run check && pnpm run package && pnpm publish ./package" "publish": "rm -rf ./package && pnpm run check && pnpm run package && pnpm publish ./package"
}, },
"devDependencies": { "devDependencies": {
"@floating-ui/core": "^0.3.1",
"@sveltejs/adapter-auto": "next", "@sveltejs/adapter-auto": "next",
"@sveltejs/kit": "next", "@sveltejs/kit": "next",
"bulma": "^0.9.3", "bulma": "^0.9.3",
@ -31,6 +32,6 @@
"typescript": "^4.5.4" "typescript": "^4.5.4"
}, },
"dependencies": { "dependencies": {
"@popperjs/core": "^2" "@floating-ui/dom": "^0.1.10"
} }
} }

25
pnpm-lock.yaml generated
View File

@ -1,7 +1,8 @@
lockfileVersion: 5.3 lockfileVersion: 5.3
specifiers: specifiers:
'@popperjs/core': ^2 '@floating-ui/core': ^0.3.1
'@floating-ui/dom': ^0.1.10
'@sveltejs/adapter-auto': next '@sveltejs/adapter-auto': next
'@sveltejs/kit': next '@sveltejs/kit': next
bulma: ^0.9.3 bulma: ^0.9.3
@ -14,11 +15,12 @@ specifiers:
typescript: ^4.5.4 typescript: ^4.5.4
dependencies: dependencies:
'@popperjs/core': 2.11.2 '@floating-ui/dom': 0.1.10
devDependencies: devDependencies:
'@floating-ui/core': 0.3.1
'@sveltejs/adapter-auto': 1.0.0-next.10 '@sveltejs/adapter-auto': 1.0.0-next.10
'@sveltejs/kit': 1.0.0-next.228_svelte@3.46.0 '@sveltejs/kit': 1.0.0-next.229_svelte@3.46.0
bulma: 0.9.3 bulma: 0.9.3
interactjs: 1.10.11 interactjs: 1.10.11
svelte: 3.46.0 svelte: 3.46.0
@ -30,6 +32,15 @@ devDependencies:
packages: packages:
/@floating-ui/core/0.3.1:
resolution: {integrity: sha512-ensKY7Ub59u16qsVIFEo2hwTCqZ/r9oZZFh51ivcLGHfUwTn8l1Xzng8RJUe91H/UP8PeqeBronAGx0qmzwk2g==}
/@floating-ui/dom/0.1.10:
resolution: {integrity: sha512-4kAVoogvQm2N0XE0G6APQJuCNuErjOfPW8Ux7DFxh8+AfugWflwVJ5LDlHOwrwut7z/30NUvdtHzQ3zSip4EzQ==}
dependencies:
'@floating-ui/core': 0.3.1
dev: false
/@iarna/toml/2.2.5: /@iarna/toml/2.2.5:
resolution: {integrity: sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==} resolution: {integrity: sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==}
dev: true dev: true
@ -59,10 +70,6 @@ packages:
fastq: 1.13.0 fastq: 1.13.0
dev: true dev: true
/@popperjs/core/2.11.2:
resolution: {integrity: sha512-92FRmppjjqz29VMJ2dn+xdyXZBrMlE42AV6Kq6BwjWV7CNUW1hs2FtxSNLQE+gJhaZ6AAmYuO9y8dshhcBl7vA==}
dev: false
/@rollup/pluginutils/4.1.2: /@rollup/pluginutils/4.1.2:
resolution: {integrity: sha512-ROn4qvkxP9SyPeHaf7uQC/GPFY6L/OWy9+bd9AwcjOAWQwxRscoEyAUD8qCY5o5iL4jqQwoLk2kaTKJPb/HwzQ==} resolution: {integrity: sha512-ROn4qvkxP9SyPeHaf7uQC/GPFY6L/OWy9+bd9AwcjOAWQwxRscoEyAUD8qCY5o5iL4jqQwoLk2kaTKJPb/HwzQ==}
engines: {node: '>= 8.0.0'} engines: {node: '>= 8.0.0'}
@ -99,8 +106,8 @@ packages:
esbuild: 0.13.15 esbuild: 0.13.15
dev: true dev: true
/@sveltejs/kit/1.0.0-next.228_svelte@3.46.0: /@sveltejs/kit/1.0.0-next.229_svelte@3.46.0:
resolution: {integrity: sha512-77e8G7CcmqHhMyAbtjrAWjRDDgFiZArFhujKGql5YM68TWx0cCoipqGdhK0m3EJ/t/NL+T2YuK/9nvtrSNEK6A==} resolution: {integrity: sha512-i609g5T58Qdgh/qgO1atak70R7woNuJwWp7GtF/YUOZ9csMR9JPUr1tfX9lSh2I4Ez7j+Dc10RLlQ3szVywfXA==}
engines: {node: '>=14.13'} engines: {node: '>=14.13'}
hasBin: true hasBin: true
peerDependencies: peerDependencies:

View File

@ -1,5 +1,5 @@
<script lang="ts"> <script lang="ts">
import Hint, { Placement } from '../lib/Hint.svelte' import Hint from '../lib/Hint.svelte'
import interact from 'interactjs' import interact from 'interactjs'
import { onMount } from 'svelte' import { onMount } from 'svelte'
@ -11,7 +11,8 @@
let direction = 'bottom' let direction = 'bottom'
let align = 'center' let align = 'center'
$: placement = `${direction}-${align}`.replace('-center', '') as Placement $: placement = `${direction}-${align}`.replace('-center', '') as any
$: auto = (placement.startsWith('auto') && (placement.includes('-') ? placement.split('-')[1] : true)) as any
let knob: HTMLDivElement let knob: HTMLDivElement
@ -74,13 +75,17 @@
<div class="container bg-light"> <div class="container bg-light">
<div bind:this={knob}> <div bind:this={knob}>
<Hint {placement} {offset} {text}> <Hint {placement} {offset} {text} {auto}>
<button class="btn btn-success drag">Hover me!</button> <button class="btn btn-success drag">Hover me!</button>
<div slot="hint">Test</div> <div slot="hint">Test</div>
</Hint> </Hint>
</div> </div>
</div> </div>
<p>
Positioning gets recalculated <b>when hovering</b>, not while moving the button around.
</p>
<style> <style>
.container { .container {
width: 100%; width: 100%;

View File

@ -1,47 +1,41 @@
<script lang="ts" context="module"> <script lang="ts" context="module">
export type { Placement } from '@popperjs/core' import type { DOMDetectOverflowOptions, Placement } from '@floating-ui/dom'
</script> </script>
<script lang="ts"> <script lang="ts">
import { createPopper, Instance, Placement } from '@popperjs/core' import { computePosition, flip, shift, offset as offsetMiddleware, autoPlacement } from '@floating-ui/dom'
import { onMount } from 'svelte' import { onMount } from 'svelte'
export let placement: Placement = 'auto' export let placement: Placement | undefined = undefined
export let text: string | null = null export let text: string | null = null
export let boundary: HTMLElement | string = 'clippingParents' export let boundary: DOMDetectOverflowOptions['boundary'] = 'clippingParents'
export let offset: number = 4 export let offset: Parameters<typeof offsetMiddleware>[0] = 4
export let auto: boolean | 'start' | 'end' = false
let trigger: HTMLSpanElement | null = null let trigger: HTMLSpanElement | null = null
let hint: HTMLSpanElement | null = null let hint: HTMLSpanElement | null = null
let instance: Instance | null = null
let dataShow = false let dataShow = false
let id = '' let id = ''
$: if (hint && trigger) { async function update() {
if (instance) instance.destroy() if (!hint || !trigger) return
instance = createPopper(trigger, hint, {
placement, const options = {
modifiers: [ placement: placement as Placement,
{ middleware: auto
name: 'offset', ? [offsetMiddleware(offset), autoPlacement({ boundary, alignment: typeof auto === 'string' ? auto : null })]
options: { : [offsetMiddleware(offset), flip({ boundary }), shift({ boundary, padding: 4 })],
offset: [0, offset], }
}, const { x, y } = await computePosition(trigger, hint, options)
}, Object.assign(hint!.style, {
{ left: `${x}px`,
name: 'flip', top: `${y}px`,
options: {
boundary,
},
},
],
}) })
} }
function show() { async function show() {
console.debug('show', hint) await update()
dataShow = true dataShow = true
instance?.update()
} }
function hide() { function hide() {
@ -49,14 +43,19 @@
} }
onMount(() => { onMount(() => {
update()
id = Math.random().toString(16).slice(2) // Random id for the tooltip id = Math.random().toString(16).slice(2) // Random id for the tooltip
const showEvents = ['mouseenter', 'focus']
const hideEvents = ['mouseleave', 'blur'] // Bind events
showEvents.forEach((event) => trigger?.addEventListener(event, show, false)) const events: [keyof HTMLElementEventMap, EventListener][] = [
hideEvents.forEach((event) => trigger?.addEventListener(event, hide, false)) ['mouseenter', show],
['focus', show],
['mouseleave', hide],
['blur', hide],
]
events.forEach(([event, handler]) => trigger?.addEventListener(event, handler))
return () => { return () => {
showEvents.forEach((event) => trigger?.removeEventListener(event, show, false)) events.forEach(([event, handler]) => trigger?.removeEventListener(event, handler))
hideEvents.forEach((event) => trigger?.removeEventListener(event, hide, false))
} }
}) })
</script> </script>
@ -74,6 +73,7 @@
<style> <style>
.svelte-hint-tooltip { .svelte-hint-tooltip {
position: absolute;
visibility: hidden; visibility: hidden;
} }

View File

@ -8,7 +8,7 @@
<p> <p>
Svelte utility library for Tooltips. Heavy lifting of positioning is done by Svelte utility library for Tooltips. Heavy lifting of positioning is done by
<a href="https://popper.js.org/">Popper.js</a>. <a href="https://floating-ui.com/">Floating UI</a>.
</p> </p>
<p> <p>
If you are looking for installation and docs please see the If you are looking for installation and docs please see the