@melt-ui/svelte
Advanced tools
Comparing version 0.25.1 to 0.26.0
@@ -52,3 +52,3 @@ import { builder, effect, isBrowser, styleToString } from '../../internal/helpers'; | ||
: undefined, | ||
hidden: $loadingStatus === 'loaded' ? undefined : true, | ||
hidden: $loadingStatus === 'loaded' ? true : undefined, | ||
}; | ||
@@ -55,0 +55,0 @@ }, |
@@ -57,2 +57,7 @@ /// <reference types="svelte" /> | ||
}, string>; | ||
label: import("../../internal/helpers").ExplicitBuilderReturn<(import("svelte/store").Readable<any> | import("svelte/store").Readable<any>[] | [import("svelte/store").Readable<any>, ...import("svelte/store").Readable<any>[]]) | undefined, (node: HTMLElement) => { | ||
destroy: VoidFunction; | ||
}, () => { | ||
id: string; | ||
}, string>; | ||
}; |
@@ -6,2 +6,3 @@ import { usePopper } from '../../internal/actions'; | ||
import { derived, get, readonly, writable } from 'svelte/store'; | ||
import { createLabel } from '../label'; | ||
// prettier-ignore | ||
@@ -296,3 +297,12 @@ export const INTERACTION_KEYS = [kbd.ARROW_LEFT, kbd.ARROW_RIGHT, kbd.SHIFT, kbd.CAPS_LOCK, kbd.CONTROL, kbd.ALT, kbd.META, kbd.ENTER, kbd.F1, kbd.F2, kbd.F3, kbd.F4, kbd.F5, kbd.F6, kbd.F7, kbd.F8, kbd.F9, kbd.F10, kbd.F11, kbd.F12]; | ||
clickOutside: { | ||
handler: () => { | ||
handler: (e) => { | ||
const target = e.target; | ||
if (isHTMLElement(target)) { | ||
const closestLabel = target.closest(selector('label')); | ||
const isTrigger = target === $activeTrigger; | ||
const isLabel = target.id === ids.label; | ||
if (closestLabel || isTrigger || isLabel) { | ||
return; | ||
} | ||
} | ||
reset(); | ||
@@ -323,2 +333,13 @@ closeMenu(); | ||
}); | ||
// Use our existing label builder to create a label for the combobox input. | ||
const labelBuilder = createLabel(); | ||
const { action: labelAction } = get(labelBuilder); | ||
const label = builder(name('label'), { | ||
returned: () => { | ||
return { | ||
id: ids.label, | ||
}; | ||
}, | ||
action: labelAction, | ||
}); | ||
const item = builder(name('item'), { | ||
@@ -396,3 +417,4 @@ stores: [selectedItem], | ||
item, | ||
label, | ||
}; | ||
} |
@@ -5,2 +5,3 @@ import { createFocusTrap, usePortal } from '../../internal/actions'; | ||
import { get, writable } from 'svelte/store'; | ||
import { tick } from 'svelte'; | ||
const { name } = createElHelpers('dialog'); | ||
@@ -118,8 +119,10 @@ const defaults = { | ||
effect([open], ([$open]) => { | ||
if (node.hidden || !$open) { | ||
deactivate(); | ||
} | ||
else { | ||
activate(); | ||
} | ||
tick().then(() => { | ||
if (!$open) { | ||
deactivate(); | ||
} | ||
else { | ||
activate(); | ||
} | ||
}); | ||
}); | ||
@@ -126,0 +129,0 @@ return { |
/// <reference types="svelte" /> | ||
import type { CreateTooltipProps } from './types'; | ||
export declare function createTooltip(props?: CreateTooltipProps): { | ||
trigger: import("../../internal/helpers").ExplicitBuilderReturn<import("svelte/store").Writable<boolean>, (node: HTMLElement) => { | ||
trigger: import("../../internal/helpers").ExplicitBuilderReturn<(import("svelte/store").Readable<any> | import("svelte/store").Readable<any>[] | [import("svelte/store").Readable<any>, ...import("svelte/store").Readable<any>[]]) | undefined, (node: HTMLElement) => { | ||
destroy: () => void; | ||
}, ($open: boolean) => { | ||
role: "button"; | ||
'aria-haspopup': "dialog"; | ||
'aria-expanded': boolean; | ||
'data-state': string; | ||
'aria-controls': string; | ||
}, () => { | ||
'aria-describedby': string; | ||
id: string; | ||
@@ -18,2 +14,3 @@ }, string>; | ||
}, ($open: boolean) => { | ||
role: string; | ||
hidden: boolean | undefined; | ||
@@ -20,0 +17,0 @@ tabindex: number; |
@@ -1,5 +0,5 @@ | ||
import { addEventListener, builder, createElHelpers, executeCallbacks, generateId, isTouch, noop, omit, styleToString, } from '../../internal/helpers'; | ||
import { addEventListener, builder, createElHelpers, effect, executeCallbacks, generateId, makeHullFromElements, noop, omit, pointInPolygon, styleToString, } from '../../internal/helpers'; | ||
import { useFloating, usePortal } from '../../internal/actions'; | ||
import { tick } from 'svelte'; | ||
import { derived, get, writable } from 'svelte/store'; | ||
import { get, writable } from 'svelte/store'; | ||
const defaults = { | ||
@@ -11,5 +11,5 @@ positioning: { | ||
open: false, | ||
closeOnPointerDown: true, | ||
closeOnPointerDown: false, | ||
openDelay: 1000, | ||
closeDelay: 500, | ||
closeDelay: 0, | ||
}; | ||
@@ -26,34 +26,32 @@ const { name } = createElHelpers('tooltip'); | ||
}; | ||
let timeout = null; | ||
const openTooltip = derived(options, ($options) => { | ||
return () => { | ||
if (timeout) { | ||
window.clearTimeout(timeout); | ||
timeout = null; | ||
} | ||
timeout = window.setTimeout(() => { | ||
open.set(true); | ||
}, $options.openDelay); | ||
}; | ||
}); | ||
const closeTooltip = derived(options, ($options) => { | ||
return () => { | ||
if (timeout) { | ||
window.clearTimeout(timeout); | ||
timeout = null; | ||
} | ||
timeout = window.setTimeout(() => { | ||
open.set(false); | ||
}, $options.closeDelay); | ||
}; | ||
}); | ||
let openTimeout = null; | ||
let closeTimeout = null; | ||
let clickedTrigger = false; | ||
const openTooltip = () => { | ||
const $options = get(options); | ||
if (openTimeout) { | ||
window.clearTimeout(openTimeout); | ||
openTimeout = null; | ||
} | ||
if (clickedTrigger) | ||
return; | ||
openTimeout = window.setTimeout(() => { | ||
open.set(true); | ||
}, $options.openDelay); | ||
}; | ||
const closeTooltip = () => { | ||
const $options = get(options); | ||
if (closeTimeout) { | ||
window.clearTimeout(closeTimeout); | ||
closeTimeout = null; | ||
} | ||
closeTimeout = window.setTimeout(() => { | ||
open.set(false); | ||
clickedTrigger = false; | ||
}, $options.closeDelay); | ||
}; | ||
const trigger = builder(name('trigger'), { | ||
stores: open, | ||
returned: ($open) => { | ||
returned: () => { | ||
return { | ||
role: 'button', | ||
'aria-haspopup': 'dialog', | ||
'aria-expanded': $open, | ||
'data-state': $open ? 'open' : 'closed', | ||
'aria-controls': ids.content, | ||
'aria-describedby': ids.content, | ||
id: ids.trigger, | ||
@@ -63,11 +61,27 @@ }; | ||
action: (node) => { | ||
const unsub = executeCallbacks(addEventListener(node, 'mouseover', () => get(openTooltip)()), addEventListener(node, 'mouseout', () => get(closeTooltip)()), addEventListener(node, 'focus', () => open.set(true)), addEventListener(node, 'blur', () => open.set(false)), addEventListener(node, 'pointerdown', (e) => { | ||
if (isTouch(e)) { | ||
return; | ||
} | ||
e.preventDefault(); | ||
const unsub = executeCallbacks(addEventListener(node, 'pointerdown', () => { | ||
const $options = get(options); | ||
if ($options.closeOnPointerDown) { | ||
open.set(false); | ||
clickedTrigger = true; | ||
} | ||
}), addEventListener(node, 'mouseover', openTooltip), addEventListener(node, 'mouseleave', () => { | ||
if (openTimeout) { | ||
window.clearTimeout(openTimeout); | ||
openTimeout = null; | ||
} | ||
clickedTrigger = false; | ||
}), addEventListener(node, 'focus', openTooltip), addEventListener(node, 'blur', closeTooltip), addEventListener(node, 'keydown', (e) => { | ||
if (e.key === 'Escape') { | ||
if (openTimeout) { | ||
window.clearTimeout(openTimeout); | ||
openTimeout = null; | ||
} | ||
if (closeTimeout) { | ||
window.clearTimeout(closeTimeout); | ||
closeTimeout = null; | ||
} | ||
clickedTrigger = false; | ||
open.set(false); | ||
} | ||
})); | ||
@@ -83,2 +97,3 @@ return { | ||
return { | ||
role: 'tooltip', | ||
hidden: $open ? undefined : true, | ||
@@ -99,3 +114,3 @@ tabindex: -1, | ||
tick().then(() => { | ||
const triggerEl = document.getElementById(ids.trigger); | ||
const triggerEl = document.querySelector(`[aria-describedby="${ids.content}"]`); | ||
if (!triggerEl || node.hidden) | ||
@@ -112,3 +127,3 @@ return; | ||
}); | ||
unsub = executeCallbacks(addEventListener(node, 'mouseover', () => get(openTooltip)()), addEventListener(node, 'mouseout', () => get(closeTooltip)()), portalReturn && portalReturn.destroy ? portalReturn.destroy : noop, unsubOpen); | ||
unsub = executeCallbacks(addEventListener(node, 'mouseover', openTooltip), portalReturn && portalReturn.destroy ? portalReturn.destroy : noop, unsubOpen); | ||
return { | ||
@@ -133,3 +148,27 @@ destroy() { | ||
}); | ||
effect(open, ($open) => { | ||
if ($open) { | ||
return executeCallbacks(addEventListener(document, 'mousemove', (e) => { | ||
const triggerEl = document.getElementById(ids.trigger); | ||
if (!triggerEl || document.activeElement === triggerEl) | ||
return; | ||
const contentEl = document.getElementById(ids.content); | ||
if (!contentEl) | ||
return; | ||
const polygon = makeHullFromElements([triggerEl, contentEl]); | ||
const isMouseInTooltipArea = pointInPolygon({ | ||
x: e.clientX, | ||
y: e.clientY, | ||
}, polygon); | ||
if (isMouseInTooltipArea) { | ||
closeTimeout = null; | ||
return; | ||
} | ||
closeTooltip(); | ||
}), addEventListener(document, 'mouseleave', () => { | ||
closeTooltip(); | ||
})); | ||
} | ||
}); | ||
return { trigger, open, content, arrow, options }; | ||
} |
@@ -16,4 +16,5 @@ export * from './array'; | ||
export * from './platform'; | ||
export * from './polygon'; | ||
export * from './scroll'; | ||
export * from './rovingFocus'; | ||
export * from './typeahead'; |
@@ -16,4 +16,5 @@ export * from './array'; | ||
export * from './platform'; | ||
export * from './polygon'; | ||
export * from './scroll'; | ||
export * from './rovingFocus'; | ||
export * from './typeahead'; |
{ | ||
"name": "@melt-ui/svelte", | ||
"version": "0.25.1", | ||
"version": "0.26.0", | ||
"license": "MIT", | ||
@@ -140,4 +140,5 @@ "exports": { | ||
"pw": "pnpm exec playwright test", | ||
"pw:ui": "pnpm exec playwright test --ui" | ||
"pw:ui": "pnpm exec playwright test --ui", | ||
"changeset": "changeset" | ||
} | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Copyleft License
License(Experimental) Copyleft license information was found.
Found 1 instance in 1 package
Mixed license
License(Experimental) Package contains multiple licenses.
Found 1 instance in 1 package
Non-permissive License
License(Experimental) A license not known to be considered permissive was found.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
419001
255
10289
3
70