mirror of
https://github.com/cupcakearmy/svelte-hint.git
synced 2024-12-24 08:56:28 +00:00
use fluent UI
This commit is contained in:
parent
fbd535a63c
commit
ebd0199375
15
README.md
15
README.md
@ -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.
|
||||||
|
|
||||||
@ -50,12 +50,13 @@ 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. |
|
| `placement` | `Placement` | `auto` | See the [Fluent UI docs](https://floating-ui.com/docs/computePosition#placement). |
|
||||||
| `boundary` | `HTMLElement \| string` | `'clippingParents'` | See [popper docs](https://popper.js.org/docs/v2/utils/detect-overflow/#boundary) for possible values. |
|
| `boundary` | `HTMLElement \| string` | `'clippingParents'` | See the [Fluent UI docs](https://floating-ui.com/docs/detectOverflow#boundary). |
|
||||||
| `offset` | `number` | `4` | The offset is the distance that the tooltip gets positioned from the trigger. |
|
| `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
|
||||||
|
|
||||||
|
@ -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
25
pnpm-lock.yaml
generated
@ -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:
|
||||||
|
@ -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%;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user