Launch Week Day 4: Introducing Data Exports.Learn More
Socket
Book a DemoSign in
Socket

@melt-ui/svelte

Package Overview
Dependencies
Maintainers
1
Versions
199
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.8.3
to
0.9.0
+48
dist/builders/slider/index.d.ts
import { type Readable } from 'svelte/store';
type CreateSliderArgs = {
value: number[];
min?: number;
max?: number;
step?: number;
orientation?: 'horizontal' | 'vertical';
disabled?: boolean;
};
export declare const createSlider: (args?: CreateSliderArgs) => {
root: Readable<{
disabled: boolean;
'data-orientation': "horizontal" | "vertical";
} & {
'data-melt-id': string;
}>;
slider: Readable<{
disabled: boolean;
'data-orientation': "horizontal" | "vertical";
} & {
'data-melt-id': string;
}>;
range: Readable<{
style: string;
}>;
thumb: Readable<() => {
role: string;
'aria-label': string;
'aria-valuemin': number;
'aria-valuemax': number;
'aria-valuenow': number;
'data-melt-part': string;
style: string;
tabindex: number;
} & {
'data-melt-id': string;
}>;
value: import("svelte/store").Writable<number[]>;
options: import("svelte/store").Writable<Omit<{
value: number[];
min: number;
max: number;
step: number;
orientation: 'horizontal' | 'vertical';
disabled: boolean;
}, "value">>;
};
export {};
import { effect, elementDerived, elementMultiDerived, getElementByMeltId, isBrowser, kbd, omit, styleToString, } from '../../internal/helpers';
import { derived, get, writable } from 'svelte/store';
const defaults = {
value: [],
min: 0,
max: 100,
step: 1,
orientation: 'horizontal',
disabled: false,
};
export const createSlider = (args = defaults) => {
const withDefaults = { ...defaults, ...args };
const options = writable(omit(withDefaults, 'value'));
const value = writable(withDefaults.value);
const isActive = writable(false);
const currentThumbIndex = writable(0);
const activeThumb = writable(null);
const root = elementDerived(options, ($options) => {
return { disabled: $options.disabled, 'data-orientation': $options.orientation };
});
const range = derived([value, options], ([$value, $options]) => {
const orientationStyles = $options.orientation === 'horizontal'
? {
left: `${$value.length > 1 ? Math.min(...$value) ?? 0 : 0}%`,
right: `calc(${100 - (Math.max(...$value) ?? 0)}%)`,
}
: {
top: `${$value.length > 1 ? Math.min(...$value) ?? 0 : 0}%`,
bottom: `calc(${100 - (Math.max(...$value) ?? 0)}%)`,
};
return {
style: styleToString({
position: 'absolute',
...orientationStyles,
}),
};
});
const getAllThumbs = derived(root, ($root) => {
return () => {
const rootEl = getElementByMeltId($root['data-melt-id']);
if (!rootEl)
return;
return Array.from(rootEl.querySelectorAll('[data-melt-part="thumb"]'));
};
});
const updatePosition = (val, index) => {
value.update((prev) => {
if (!prev)
return [val];
const isFirst = index === 0;
const isLast = index === prev.length - 1;
if (!isLast && val > prev[index + 1]) {
prev[index] = prev[index + 1];
}
else if (!isFirst && val < prev[index - 1]) {
prev[index] = prev[index - 1];
}
else {
prev[index] = val;
}
return prev.map(Math.abs);
});
};
const thumb = elementMultiDerived([value, getAllThumbs, options], ([$value, $getAllThumbs, $options], { attach, index }) => {
return () => {
const { min: $min, max: $max, disabled: $disabled } = $options;
const currentThumb = get(currentThumbIndex);
if (currentThumb < $value.length) {
currentThumbIndex.update((prev) => prev + 1);
}
attach('keydown', (event) => {
if ($disabled)
return;
const target = event.currentTarget;
const thumbs = $getAllThumbs();
if (!thumbs)
return;
const index = thumbs.indexOf(target);
currentThumbIndex.set(index);
if (![
kbd.ARROW_LEFT,
kbd.ARROW_RIGHT,
kbd.ARROW_UP,
kbd.ARROW_DOWN,
kbd.HOME,
kbd.END,
].includes(event.key)) {
return;
}
event.preventDefault();
const step = $options.step;
const $value = get(value);
switch (event.key) {
case kbd.HOME: {
updatePosition($min, index);
break;
}
case kbd.END: {
updatePosition($max, index);
break;
}
case kbd.ARROW_LEFT: {
if ($value[index] > $min && $options.orientation === 'horizontal') {
const newValue = $value[index] - step;
updatePosition(newValue, index);
}
break;
}
case kbd.ARROW_RIGHT: {
if ($value[index] < $max && $options.orientation === 'horizontal') {
const newValue = $value[index] + step;
updatePosition(newValue, index);
}
break;
}
case kbd.ARROW_UP: {
if ($value[index] > $min && $options.orientation === 'vertical') {
const newValue = $value[index] - step;
updatePosition(newValue, index);
}
else if ($value[index] < $max) {
const newValue = $value[index] + step;
updatePosition(newValue, index);
}
break;
}
case kbd.ARROW_DOWN: {
if ($value[index] < $max && $options.orientation === 'vertical') {
const newValue = $value[index] + step;
updatePosition(newValue, index);
}
else if ($value[index] > $min) {
const newValue = $value[index] - step;
updatePosition(newValue, index);
}
break;
}
}
});
return {
role: 'slider',
'aria-label': 'Volume',
'aria-valuemin': $min,
'aria-valuemax': $max,
'aria-valuenow': $value[index],
'data-melt-part': 'thumb',
style: styleToString({
position: 'absolute',
...($options.orientation === 'horizontal'
? { left: `${$value[index]}%;`, translate: '-50% 0' }
: { top: `${$value[index]}%;`, translate: '0 -50%`' }),
}),
tabindex: $disabled ? -1 : 0,
};
};
});
effect([root, getAllThumbs, options], ([$root, $getAllThumbs, $options]) => {
const { min: $min, max: $max, disabled: $disabled } = $options;
if (!isBrowser || $disabled)
return;
const applyPosition = (clientXY, activeThumbIdx, leftOrTop, rightOrBottom) => {
const percent = (clientXY - leftOrTop) / (rightOrBottom - leftOrTop);
const val = Math.round(percent * ($max - $min) + $min);
if (val < $min || val > $max)
return;
const step = $options.step;
const newValue = Math.round(val / step) * step;
updatePosition(newValue, activeThumbIdx);
};
const getClosestThumb = (e) => {
const thumbs = $getAllThumbs();
if (!thumbs)
return;
thumbs.forEach((thumb) => thumb.blur());
const distances = thumbs.map((thumb) => {
if ($options.orientation === 'horizontal') {
const { left, right } = thumb.getBoundingClientRect();
return Math.abs(e.clientX - (left + right) / 2);
}
else {
const { top, bottom } = thumb.getBoundingClientRect();
return Math.abs(e.clientY - (top + bottom) / 2);
}
});
const thumb = thumbs[distances.indexOf(Math.min(...distances))];
const index = thumbs.indexOf(thumb);
return { thumb, index };
};
const pointerDown = (e) => {
e.preventDefault();
const sliderEl = getElementByMeltId($root['data-melt-id']);
const closestThumb = getClosestThumb(e);
if (!closestThumb || !sliderEl)
return;
if (!sliderEl.contains(e.target))
return;
activeThumb.set(closestThumb);
closestThumb.thumb.focus();
isActive.set(true);
if ($options.orientation === 'horizontal') {
const { left, right } = sliderEl.getBoundingClientRect();
applyPosition(e.clientX, closestThumb.index, left, right);
}
else {
const { top, bottom } = sliderEl.getBoundingClientRect();
applyPosition(e.clientY, closestThumb.index, top, bottom);
}
};
const pointerUp = () => {
isActive.set(false);
};
const pointerMove = (e) => {
if (!get(isActive))
return;
const sliderEl = getElementByMeltId($root['data-melt-id']);
const closestThumb = get(activeThumb);
if (!sliderEl || !closestThumb)
return;
closestThumb.thumb.focus();
if ($options.orientation === 'horizontal') {
const { left, right } = sliderEl.getBoundingClientRect();
applyPosition(e.clientX, closestThumb.index, left, right);
}
else {
const { top, bottom } = sliderEl.getBoundingClientRect();
applyPosition(e.clientY, closestThumb.index, top, bottom);
}
};
document.addEventListener('pointerdown', pointerDown);
document.addEventListener('pointerup', pointerUp);
document.addEventListener('pointerleave', pointerUp);
document.addEventListener('pointermove', pointerMove);
return () => {
document.removeEventListener('pointerdown', pointerDown);
document.removeEventListener('pointerup', pointerUp);
document.removeEventListener('pointerleave', pointerUp);
document.removeEventListener('pointermove', pointerMove);
};
});
return {
root,
slider: root,
range,
thumb,
value,
options,
};
};
+1
-0

@@ -12,4 +12,5 @@ export * from './accordion';

export * from './radio-group';
export * from './slider';
export * from './dialog';
export * from './tooltip';
export * from './pagination';

@@ -12,4 +12,5 @@ export * from './accordion';

export * from './radio-group';
export * from './slider';
export * from './dialog';
export * from './tooltip';
export * from './pagination';
+1
-1
import { elementDerived, elementMultiDerived, kbd, omit } from '../../internal/helpers';
import { derived, writable } from 'svelte/store';
const defaults = {
perPage: 10,
perPage: 1,
siblingCount: 1,

@@ -6,0 +6,0 @@ page: 1,

@@ -18,2 +18,3 @@ import type { FloatingConfig } from '../../internal/actions';

selected?: string | number;
name?: string;
};

@@ -47,2 +48,4 @@ export declare function createSelect(args?: CreateSelectArgs): {

'data-selected': string | undefined;
'data-value': string | number;
'data-type': "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function";
tabindex: number;

@@ -53,3 +56,3 @@ } & {

selected: import("svelte/store").Writable<string | number | null>;
selectedText: import("svelte/store").Writable<string | null>;
selectedText: import("svelte/store").Writable<string | number | null>;
arrow: import("svelte/store").Readable<{

@@ -60,9 +63,14 @@ 'data-arrow': boolean;

isSelected: import("svelte/store").Readable<(value: string | number) => boolean>;
options: import("svelte/store").Writable<{
positioning?: FloatingConfig | undefined;
arrowSize?: number | undefined;
required?: boolean | undefined;
disabled?: boolean | undefined;
selected?: string | number | undefined;
options: import("svelte/store").Writable<Omit<CreateSelectArgs, "selected">>;
input: import("svelte/store").Readable<{
type: string;
name: string | undefined;
value: string | number | null;
'aria-hidden': boolean;
hidden: boolean;
tabIndex: number;
required: boolean | undefined;
disabled: boolean | undefined;
style: string;
}>;
};
import { usePopper } from '../../internal/actions/popper';
import { debounce, effect, elementDerived, elementMultiDerived, getElementByMeltId, isBrowser, kbd, styleToString, uuid, } from '../../internal/helpers';
import { debounce, effect, elementDerived, elementMultiDerived, getElementByMeltId, isBrowser, kbd, omit, styleToString, uuid, } from '../../internal/helpers';
import { sleep } from '../../internal/helpers/sleep';

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

const withDefaults = { ...defaults, ...args };
const options = writable({ ...withDefaults });
const options = writable(omit(withDefaults, 'selected'));
const open = writable(false);

@@ -105,2 +105,4 @@ const selected = writable(withDefaults.selected ?? null);

'data-selected': $selected === value ? '' : undefined,
'data-value': value,
'data-type': typeof value,
tabindex: 0,

@@ -192,3 +194,11 @@ };

if (selectedOption) {
selectedText.set(selectedOption.innerText);
const data = selectedOption.getAttribute('data-value');
if (data) {
if (selectedOption.getAttribute('data-type') === 'number') {
selectedText.set(+data);
}
else {
selectedText.set(data);
}
}
}

@@ -202,3 +212,22 @@ });

});
return { trigger, menu, open, option, selected, selectedText, arrow, isSelected, options };
const input = derived([selected, options], ([$selected, $options]) => {
return {
type: 'hidden',
name: $options.name,
value: $selected,
'aria-hidden': true,
hidden: true,
tabIndex: -1,
required: $options.required,
disabled: $options.disabled,
style: styleToString({
position: 'absolute',
opacity: 0,
'pointer-events': 'none',
margin: 0,
transform: 'translateX(-100%)',
}),
};
});
return { trigger, menu, open, option, selected, selectedText, arrow, isSelected, options, input };
}

@@ -51,2 +51,5 @@ import { type Readable } from 'svelte/store';

};
type MultiHelpers = Helpers & {
index: number;
};
type ReturnWithObj<T extends () => void, Obj> = ReturnType<T> extends void ? Obj : ReturnType<T> & Obj;

@@ -89,3 +92,3 @@ /**

*/
export declare function elementMultiDerived<S extends Stores, T extends (...args: any[]) => Record<string, unknown> | void>(stores: S, fn: (values: StoresValues<S>, helpers: Helpers) => T): Readable<(...args: Parameters<T>) => ReturnWithObj<T, {
export declare function elementMultiDerived<S extends Stores, T extends (...args: any[]) => Record<string, unknown> | void>(stores: S, fn: (values: StoresValues<S>, helpers: MultiHelpers) => T): Readable<(...args: Parameters<T>) => ReturnWithObj<T, {
'data-melt-id': string;

@@ -92,0 +95,0 @@ }>>;

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

const { addUnsubscriber, createElInterface, unsubscribe } = initElementHelpers((newId) => (id = newId));
let index = 0;
return derived(stores, ($storeValues) => {

@@ -175,3 +176,10 @@ // Unsubscribe from all events

const { attach, getElement, addAction } = createElInterface();
const returned = fn($storeValues, { attach, getElement, addUnsubscriber, addAction });
const returned = fn($storeValues, {
attach,
getElement,
addUnsubscriber,
addAction,
index: index++,
});
addUnsubscriber(() => index--);
return { ...returned(...args), 'data-melt-id': id };

@@ -178,0 +186,0 @@ };

{
"name": "@melt-ui/svelte",
"version": "0.8.3",
"version": "0.9.0",
"license": "MIT",

@@ -5,0 +5,0 @@ "exports": {