DuyTa's picture
Upload folder using huggingface_hub
bc20498 verified
import { addMeltEventListener, makeElement, createElHelpers, disabledAttr, executeCallbacks, getElemDirection, handleRovingFocus, isHTMLElement, kbd, noop, omit, overridable, toWritableStores, } from '../../internal/helpers/index.js';
import { derived, writable } from 'svelte/store';
const defaults = {
type: 'single',
orientation: 'horizontal',
loop: true,
rovingFocus: true,
disabled: false,
defaultValue: '',
};
const { name, selector } = createElHelpers('toggle-group');
export const createToggleGroup = (props) => {
const withDefaults = { ...defaults, ...props };
const options = toWritableStores(omit(withDefaults, 'value'));
const { type, orientation, loop, rovingFocus, disabled } = options;
const defaultValue = withDefaults.defaultValue
? withDefaults.defaultValue
: withDefaults.type === 'single'
? undefined
: [];
const valueWritable = withDefaults.value ?? writable(defaultValue);
const value = overridable(valueWritable, withDefaults?.onValueChange);
const root = makeElement(name(), {
stores: orientation,
returned: ($orientation) => {
return {
role: 'group',
'data-orientation': $orientation,
};
},
});
const item = makeElement(name('item'), {
stores: [value, disabled, orientation, type],
returned: ([$value, $disabled, $orientation, $type]) => {
return (props) => {
const itemValue = typeof props === 'string' ? props : props.value;
const argDisabled = typeof props === 'string' ? false : !!props.disabled;
const disabled = $disabled || argDisabled;
const pressed = Array.isArray($value) ? $value.includes(itemValue) : $value === itemValue;
const isSingle = $type === 'single';
const isMultiple = $type === 'multiple' || $type === undefined;
return {
disabled: disabledAttr(disabled),
pressed,
'data-orientation': $orientation,
'data-disabled': disabledAttr(disabled),
'data-state': pressed ? 'on' : 'off',
'data-value': itemValue,
'aria-pressed': isMultiple ? pressed : undefined,
'aria-checked': isSingle ? pressed : undefined,
type: 'button',
role: isSingle ? 'radio' : undefined,
tabindex: pressed ? 0 : -1,
};
};
},
action: (node) => {
let unsub = noop;
const parentGroup = node.closest(selector());
if (!isHTMLElement(parentGroup))
return {};
const items = Array.from(parentGroup.querySelectorAll(selector('item')));
const $value = value.get();
const anyPressed = Array.isArray($value) ? $value.length > 0 : $value ? true : false;
if (!anyPressed && items[0] === node) {
node.tabIndex = 0;
}
function getNodeProps() {
const itemValue = node.dataset.value;
const disabled = node.dataset.disabled === 'true';
return { value: itemValue, disabled };
}
function handleValueUpdate() {
const { value: itemValue, disabled } = getNodeProps();
if (itemValue === undefined || disabled)
return;
value.update(($value) => {
if (Array.isArray($value)) {
if ($value.includes(itemValue)) {
return $value.filter((i) => i !== itemValue);
}
return [...$value, itemValue];
}
return $value === itemValue ? undefined : itemValue;
});
}
unsub = executeCallbacks(addMeltEventListener(node, 'click', () => {
handleValueUpdate();
}), addMeltEventListener(node, 'keydown', (e) => {
if (e.key === kbd.SPACE || e.key === kbd.ENTER) {
e.preventDefault();
handleValueUpdate();
return;
}
if (!rovingFocus.get())
return;
const el = e.currentTarget;
if (!isHTMLElement(el))
return;
const root = el.closest(selector());
if (!isHTMLElement(root))
return;
const items = Array.from(root.querySelectorAll(selector('item') + ':not([data-disabled])')).filter((item) => isHTMLElement(item));
const currentIndex = items.indexOf(el);
const dir = getElemDirection(el);
const $orientation = orientation.get();
const nextKey = {
horizontal: dir === 'rtl' ? kbd.ARROW_LEFT : kbd.ARROW_RIGHT,
vertical: kbd.ARROW_DOWN,
}[$orientation ?? 'horizontal'];
const prevKey = {
horizontal: dir === 'rtl' ? kbd.ARROW_RIGHT : kbd.ARROW_LEFT,
vertical: kbd.ARROW_UP,
}[$orientation ?? 'horizontal'];
const $loop = loop.get();
if (e.key === nextKey) {
e.preventDefault();
const nextIndex = currentIndex + 1;
if (nextIndex >= items.length && $loop) {
handleRovingFocus(items[0]);
}
else {
handleRovingFocus(items[nextIndex]);
}
}
else if (e.key === prevKey) {
e.preventDefault();
const prevIndex = currentIndex - 1;
if (prevIndex < 0 && $loop) {
handleRovingFocus(items[items.length - 1]);
}
else {
handleRovingFocus(items[prevIndex]);
}
}
else if (e.key === kbd.HOME) {
e.preventDefault();
handleRovingFocus(items[0]);
}
else if (e.key === kbd.END) {
e.preventDefault();
handleRovingFocus(items[items.length - 1]);
}
}));
return {
destroy: unsub,
};
},
});
const isPressed = derived(value, ($value) => {
return (itemValue) => {
return Array.isArray($value) ? $value.includes(itemValue) : $value === itemValue;
};
});
return {
elements: {
root,
item,
},
states: {
value,
},
helpers: {
isPressed,
},
options,
};
};