Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@melt-ui/svelte

Package Overview
Dependencies
Maintainers
1
Versions
195
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@melt-ui/svelte - npm Package Compare versions

Comparing version 0.78.0 to 0.79.0

5

dist/builders/tags-input/create.d.ts

@@ -31,3 +31,3 @@ /// <reference types="svelte" />

}, string>;
edit: import("../../internal/helpers/index.js").MeltElement<[import("../../internal/helpers/withGet.js").WithGet<import("svelte/store").Writable<Tag | null>>, import("../../internal/helpers/withGet.js").WithGet<import("svelte/store").Writable<boolean>>], (node: HTMLElement) => MeltActionReturn<TagsInputEvents['edit']>, ([$editing, $editable]: [Tag | null, boolean]) => (tag: Tag) => {
edit: import("../../internal/helpers/index.js").MeltElement<import("svelte/store").Readable<(tag: Tag) => boolean>, (node: HTMLElement) => MeltActionReturn<TagsInputEvents['edit']>, ($isEditing: (tag: Tag) => boolean) => (tag: Tag) => {
readonly 'aria-hidden': boolean;

@@ -37,3 +37,3 @@ readonly 'data-tag-id': string;

readonly hidden: true | undefined;
readonly contenteditable: boolean | undefined;
readonly contenteditable: boolean;
readonly tabindex: -1;

@@ -71,2 +71,3 @@ readonly style: string | undefined;

isSelected: import("svelte/store").Readable<(tag: Tag) => boolean>;
isEditing: import("svelte/store").Readable<(tag: Tag) => boolean>;
isInputValid: (v: string) => boolean;

@@ -73,0 +74,0 @@ addTag: (v: string) => Promise<boolean>;

105

dist/builders/tags-input/create.js

@@ -1,2 +0,2 @@

import { addMeltEventListener, makeElement, createElHelpers, disabledAttr, effect, executeCallbacks, generateId, getElementByMeltId, isBrowser, isHTMLElement, kbd, omit, overridable, styleToString, toWritableStores, } from '../../internal/helpers/index.js';
import { addMeltEventListener, makeElement, createElHelpers, disabledAttr, effect, executeCallbacks, generateId, getElementByMeltId, isBrowser, isHTMLElement, kbd, omit, overridable, styleToString, toWritableStores, noop, } from '../../internal/helpers/index.js';
import { withGet } from '../../internal/helpers/withGet.js';

@@ -7,2 +7,3 @@ import { tick } from 'svelte';

import { focusInput, highlightText, setSelectedFromEl } from './helpers.js';
import { useInteractOutside } from '../../internal/actions/index.js';
const defaults = {

@@ -170,2 +171,6 @@ placeholder: '',

}
// Used to determine if tag is being edited
const isEditing = derived([editable, editing], ([$editable, $editing]) => {
return (tag) => $editable && $editing?.id === tag.id;
});
const root = makeElement(name(''), {

@@ -530,7 +535,6 @@ stores: [disabled],

const edit = makeElement(name('edit'), {
stores: [editing, editable],
returned: ([$editing, $editable]) => {
stores: isEditing,
returned: ($isEditing) => {
return (tag) => {
const editable = $editable;
const editing = editable ? $editing?.id === tag.id : undefined;
const editing = $isEditing(tag);
return {

@@ -563,48 +567,56 @@ 'aria-hidden': !editing,

};
const unsub = executeCallbacks(addMeltEventListener(node, 'blur', () => {
if (node.hasAttribute('hidden'))
let unsubInteractOutside = noop;
let unsubEvents = noop;
const unsubDerived = effect(isEditing, ($isEditing) => {
unsubInteractOutside();
unsubEvents();
if (!$isEditing(getElProps()))
return;
// Stop editing, reset the value to the original and clear an invalid state
editing.set(null);
node.textContent = getElProps().value;
getElementByMeltId(meltIds.root)?.removeAttribute('data-invalid-edit');
node.removeAttribute('data-invalid-edit');
}), addMeltEventListener(node, 'keydown', async (e) => {
if (node.hasAttribute('hidden'))
return;
if (e.key === kbd.ENTER) {
// Capture the edit value, validate and then update
e.preventDefault();
// Do nothing when the value is empty
const value = node.textContent;
if (!value)
return;
const t = { id: getElProps().id, value };
if (isInputValid(value) && (await updateTag(t, true))) {
node.textContent = t.value;
unsubInteractOutside = useInteractOutside(node).destroy;
unsubEvents = executeCallbacks(addMeltEventListener(node, 'blur', () => {
// Stop editing, reset the value to the original and clear an invalid state
editing.set(null);
node.textContent = getElProps().value;
getElementByMeltId(meltIds.root)?.removeAttribute('data-invalid-edit');
node.removeAttribute('data-invalid-edit');
}), addMeltEventListener(node, 'keydown', async (e) => {
if (e.key === kbd.ENTER) {
// Capture the edit value, validate and then update
e.preventDefault();
// Do nothing when the value is empty
const value = node.textContent;
if (!value)
return;
const t = { id: getElProps().id, value };
if (isInputValid(value) && (await updateTag(t, true))) {
node.textContent = t.value;
editValue.set('');
focusInput(meltIds.input);
}
else {
getElementByMeltId(meltIds.root)?.setAttribute('data-invalid-edit', '');
node.setAttribute('data-invalid-edit', '');
}
}
else if (e.key === kbd.ESCAPE) {
// Reset the value, clear the edit value store, set this tag as
// selected and focus on input
e.preventDefault();
e.stopImmediatePropagation();
node.textContent = getElProps().value;
editValue.set('');
setSelectedFromEl(node, selected);
focusInput(meltIds.input);
}
else {
getElementByMeltId(meltIds.root)?.setAttribute('data-invalid-edit', '');
node.setAttribute('data-invalid-edit', '');
}
}
else if (e.key === kbd.ESCAPE) {
// Reset the value, clear the edit value store, set this tag as
// selected and focus on input
e.preventDefault();
node.textContent = getElProps().value;
editValue.set('');
setSelectedFromEl(node, selected);
focusInput(meltIds.input);
}
}), addMeltEventListener(node, 'input', () => {
if (node.hasAttribute('hidden'))
return;
// Update the edit value store
editValue.set(node.textContent || '');
}));
}), addMeltEventListener(node, 'input', () => {
// Update the edit value store
editValue.set(node.textContent || '');
}));
});
return {
destroy: unsub,
destroy() {
unsubInteractOutside();
unsubEvents();
unsubDerived();
},
};

@@ -659,2 +671,3 @@ },

isSelected,
isEditing,
isInputValid,

@@ -661,0 +674,0 @@ addTag,

import { addEventListener, addMeltEventListener, makeElement, createElHelpers, effect, executeCallbacks, getPortalDestination, isBrowser, isDocument, isElement, isTouch, makeHullFromElements, noop, omit, overridable, styleToString, toWritableStores, portalAttr, isPointerInGraceArea, } from '../../internal/helpers/index.js';
import { useEscapeKeydown, useFloating, usePortal } from '../../internal/actions/index.js';
import { useEscapeKeydown, useFloating, useInteractOutside, usePortal, } from '../../internal/actions/index.js';
import { derived, writable } from 'svelte/store';

@@ -145,2 +145,3 @@ import { generateIds } from '../../internal/helpers/id.js';

let unsubPortal = noop;
let unsubInteractOutside = noop;
let unsubEscapeKeydown = noop;

@@ -150,2 +151,3 @@ const unsubDerived = effect([isVisible, positioning, portal], ([$isVisible, $positioning, $portal]) => {

unsubFloating();
unsubInteractOutside();
unsubEscapeKeydown();

@@ -158,7 +160,10 @@ const triggerEl = getEl('trigger');

unsubFloating();
unsubInteractOutside();
unsubEscapeKeydown();
const portalDest = getPortalDestination(node, $portal);
if (portalDest)
if (portalDest !== null) {
unsubPortal = usePortal(node, portalDest).destroy;
}
unsubFloating = useFloating(triggerEl, node, $positioning).destroy;
unsubInteractOutside = useInteractOutside(node).destroy;
const onEscapeKeyDown = () => {

@@ -205,2 +210,3 @@ if (openTimeout) {

unsubDerived();
unsubInteractOutside();
},

@@ -207,0 +213,0 @@ };

@@ -1,2 +0,1 @@

export * from './click-outside/index.js';
export * from './escape-keydown/index.js';

@@ -3,0 +2,0 @@ export * from './floating/index.js';

@@ -1,2 +0,1 @@

export * from './click-outside/index.js';
export * from './escape-keydown/index.js';

@@ -3,0 +2,0 @@ export * from './floating/index.js';

import type { InteractOutsideConfig } from './types.js';
export declare const useInteractOutside: <Node_1 extends HTMLElement>(node: Node_1, config: InteractOutsideConfig) => {
export declare const useInteractOutside: <Node_1 extends HTMLElement>(node: Node_1, config?: InteractOutsideConfig) => {
update: (config: InteractOutsideConfig) => void;
destroy(): void;
};
import { getOwnerDocument, isOrContainsTarget } from '../../helpers/elements.js';
import { addEventListener, isElement, executeCallbacks, noop, debounce, } from '../../helpers/index.js';
export const useInteractOutside = ((node, config) => {
const layers = new Set();
export const useInteractOutside = ((node, config = {}) => {
let unsubEvents = noop;

@@ -8,2 +9,3 @@ let unsubPointerDown = noop;

let unsubResetInterceptedEvents = noop;
layers.add(node);
const documentObj = getOwnerDocument(node);

@@ -61,2 +63,3 @@ let isPointerDown = false;

return;
let wasTopLayerInPointerDownCapture = false;
/**

@@ -67,3 +70,3 @@ * Debouncing `onPointerDown` ensures that other events can be flagged as not intercepted,

const onPointerDownDebounced = debounce((e) => {
if (isAnyEventIntercepted())
if (!wasTopLayerInPointerDownCapture || isAnyEventIntercepted())
return;

@@ -84,6 +87,7 @@ if (onInteractOutside && isValidEvent(e, node))

const onPointerUpDebounced = debounce((e) => {
if (isAnyEventIntercepted())
return;
if (shouldTriggerInteractOutside(e))
if (wasTopLayerInPointerDownCapture &&
!isAnyEventIntercepted() &&
shouldTriggerInteractOutside(e)) {
onInteractOutside?.(e);
}
resetPointerState();

@@ -99,5 +103,8 @@ }, 10);

unsubResetInterceptedEvents = resetInterceptedEventsDebounced.destroy;
const markTopLayerInPointerDown = () => {
wasTopLayerInPointerDownCapture = isHighestLayer(node);
};
unsubEvents = executeCallbacks(
/** Capture Events For Interaction Start */
setupCapturePhaseHandlerAndMarkAsIntercepted('pointerdown'), setupCapturePhaseHandlerAndMarkAsIntercepted('mousedown'), setupCapturePhaseHandlerAndMarkAsIntercepted('touchstart'),
setupCapturePhaseHandlerAndMarkAsIntercepted('pointerdown', markTopLayerInPointerDown), setupCapturePhaseHandlerAndMarkAsIntercepted('mousedown', markTopLayerInPointerDown), setupCapturePhaseHandlerAndMarkAsIntercepted('touchstart', markTopLayerInPointerDown),
/**

@@ -138,2 +145,3 @@ * Intercepted events are reset only at the end of an interaction, allowing

unsubResetInterceptedEvents();
layers.delete(node);
},

@@ -155,1 +163,4 @@ };

}
function isHighestLayer(node) {
return Array.from(layers).at(-1) === node;
}

@@ -1,19 +0,5 @@

import { isElement, last, noop, sleep } from '../../helpers/index.js';
import { isElement, noop } from '../../helpers/index.js';
import { useInteractOutside } from '../index.js';
const visibleModals = [];
export const useModal = ((node, config) => {
let unsubInteractOutside = noop;
// Filthy hack to allow closing elements before the new one appears
sleep(100).then(() => {
visibleModals.push(node);
});
function removeNodeFromVisibleModals() {
const index = visibleModals.indexOf(node);
if (index >= 0) {
visibleModals.splice(index, 1);
}
}
function isLastModal() {
return last(visibleModals) === node;
}
function update(config) {

@@ -23,7 +9,3 @@ unsubInteractOutside();

function closeModal() {
// we only want to call onClose if this is the topmost modal
if (isLastModal() && onClose) {
onClose();
removeNodeFromVisibleModals();
}
onClose?.();
}

@@ -34,11 +16,9 @@ function onInteractOutsideStart(e) {

return;
if (target && isLastModal()) {
e.stopImmediatePropagation();
}
e.stopImmediatePropagation();
}
function onInteractOutside(e) {
if (shouldCloseOnInteractOutside?.(e) && isLastModal()) {
e.stopImmediatePropagation();
closeModal();
}
if (!shouldCloseOnInteractOutside?.(e))
return;
e.stopImmediatePropagation();
closeModal();
}

@@ -48,2 +28,3 @@ unsubInteractOutside = useInteractOutside(node, {

onInteractOutside: closeOnInteractOutside ? onInteractOutside : undefined,
enabled: closeOnInteractOutside,
}).destroy;

@@ -55,3 +36,2 @@ }

destroy() {
removeNodeFromVisibleModals();
unsubInteractOutside();

@@ -58,0 +38,0 @@ },

{
"name": "@melt-ui/svelte",
"version": "0.78.0",
"version": "0.79.0",
"license": "MIT",

@@ -5,0 +5,0 @@ "repository": "github:melt-ui/melt-ui",

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc