mirror of
https://github.com/carbon-design-system/carbon-components-svelte.git
synced 2025-09-18 11:36:36 +00:00
fix(context-menu): obtain radio id from node directly
This commit is contained in:
parent
2c9c2f1690
commit
09e65d78c3
2 changed files with 29 additions and 45 deletions
|
@ -114,6 +114,7 @@
|
||||||
on:keydown
|
on:keydown
|
||||||
on:keydown="{(e) => {
|
on:keydown="{(e) => {
|
||||||
if ($hasPopup) return;
|
if ($hasPopup) return;
|
||||||
|
|
||||||
if (e.key === 'ArrowDown') {
|
if (e.key === 'ArrowDown') {
|
||||||
if (focusIndex < options.length - 1) focusIndex++;
|
if (focusIndex < options.length - 1) focusIndex++;
|
||||||
} else if (e.key === 'ArrowUp') {
|
} else if (e.key === 'ArrowUp') {
|
||||||
|
|
|
@ -52,20 +52,18 @@
|
||||||
const ctxGroup = getContext("ContextMenuGroup");
|
const ctxGroup = getContext("ContextMenuGroup");
|
||||||
const ctxRadioGroup = getContext("ContextMenuRadioGroup");
|
const ctxRadioGroup = getContext("ContextMenuRadioGroup");
|
||||||
|
|
||||||
|
// "moderate-01" duration (ms) from Carbon motion recommended for small expansion, short distance movements
|
||||||
|
const moderate01 = 150;
|
||||||
|
|
||||||
let unsubCurrentIds = undefined;
|
let unsubCurrentIds = undefined;
|
||||||
let unsubCurrentId = undefined;
|
let unsubCurrentId = undefined;
|
||||||
let unsubRadioIds = undefined;
|
|
||||||
let radioIds = [];
|
|
||||||
let timeoutHover = undefined;
|
let timeoutHover = undefined;
|
||||||
let rootMenuPosition = [0, 0];
|
let rootMenuPosition = [0, 0];
|
||||||
let currentIndex = -1;
|
|
||||||
let submenuOpen = false;
|
|
||||||
let focusIndex = 0;
|
let focusIndex = 0;
|
||||||
let options = [];
|
let options = [];
|
||||||
|
let role = "menuitem";
|
||||||
const unsubCurrentIndex = ctx.currentIndex.subscribe((index) => {
|
let submenuOpen = false;
|
||||||
currentIndex = index;
|
let submenuPosition = [0, 0];
|
||||||
});
|
|
||||||
|
|
||||||
const unsubPosition = ctx.position.subscribe((position) => {
|
const unsubPosition = ctx.position.subscribe((position) => {
|
||||||
rootMenuPosition = position;
|
rootMenuPosition = position;
|
||||||
|
@ -79,7 +77,7 @@
|
||||||
ctxGroup.toggleOption({ id });
|
ctxGroup.toggleOption({ id });
|
||||||
} else if (!!ctxRadioGroup) {
|
} else if (!!ctxRadioGroup) {
|
||||||
if (opts.fromKeyboard) {
|
if (opts.fromKeyboard) {
|
||||||
ctxRadioGroup.setOption({ id: radioIds[currentIndex] });
|
ctxRadioGroup.setOption({ id: opts.id });
|
||||||
} else {
|
} else {
|
||||||
ctxRadioGroup.setOption({ id });
|
ctxRadioGroup.setOption({ id });
|
||||||
}
|
}
|
||||||
|
@ -92,11 +90,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
selectable = selected === true;
|
if (selected === true) selectable = true;
|
||||||
|
|
||||||
if (ctxGroup) {
|
if (ctxGroup) {
|
||||||
unsubCurrentIds = ctxGroup.currentIds.subscribe((ids) => {
|
unsubCurrentIds = ctxGroup.currentIds.subscribe((_currentIds) => {
|
||||||
selected = ids.includes(id);
|
selected = _currentIds.includes(id);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,26 +102,28 @@
|
||||||
unsubCurrentId = ctxRadioGroup.currentId.subscribe((_id) => {
|
unsubCurrentId = ctxRadioGroup.currentId.subscribe((_id) => {
|
||||||
selected = id === _id;
|
selected = id === _id;
|
||||||
});
|
});
|
||||||
unsubRadioIds = ctxRadioGroup.radioIds.subscribe((ids) => {
|
|
||||||
radioIds = ids;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
unsubCurrentIndex();
|
|
||||||
unsubPosition();
|
unsubPosition();
|
||||||
if (unsubCurrentIds) unsubCurrentIds();
|
if (unsubCurrentIds) unsubCurrentIds();
|
||||||
if (unsubCurrentId) unsubCurrentId();
|
if (unsubCurrentId) unsubCurrentId();
|
||||||
if (unsubRadioIds) unsubRadioIds();
|
|
||||||
if (typeof timeoutHover === "number") clearTimeout(timeoutHover);
|
if (typeof timeoutHover === "number") clearTimeout(timeoutHover);
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
$: isSelectable = !!ctxGroup || selectable;
|
$: isSelectable = !!ctxGroup || selectable;
|
||||||
$: isRadio = !!ctxRadioGroup;
|
$: isRadio = !!ctxRadioGroup;
|
||||||
|
$: subOptions = $$slots.default;
|
||||||
$: if (isSelectable) {
|
$: ctx.setPopup(submenuOpen);
|
||||||
|
$: if (submenuOpen) {
|
||||||
|
const { width, y } = ref.getBoundingClientRect();
|
||||||
|
submenuPosition = [rootMenuPosition[0] + width, y];
|
||||||
|
}
|
||||||
|
$: {
|
||||||
|
if (isSelectable) {
|
||||||
indented = true;
|
indented = true;
|
||||||
|
role = "menuitemcheckbox";
|
||||||
|
|
||||||
if (selected) {
|
if (selected) {
|
||||||
if (ctxGroup) ctxGroup.addOption({ id });
|
if (ctxGroup) ctxGroup.addOption({ id });
|
||||||
|
@ -133,22 +133,8 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let submenuPosition = [0, 0];
|
|
||||||
|
|
||||||
$: subOptions = $$slots.default;
|
|
||||||
$: if (submenuOpen) {
|
|
||||||
const { width, y } = ref.getBoundingClientRect();
|
|
||||||
submenuPosition = [rootMenuPosition[0] + width, y];
|
|
||||||
}
|
|
||||||
|
|
||||||
$: ctx.setPopup(submenuOpen);
|
|
||||||
|
|
||||||
let role = "menuitem";
|
|
||||||
|
|
||||||
$: indented = isSelectable || isRadio;
|
|
||||||
$: {
|
|
||||||
if (isSelectable) role = "menuitemcheckbox";
|
|
||||||
if (isRadio) {
|
if (isRadio) {
|
||||||
|
indented = true;
|
||||||
role = "menuitemradio";
|
role = "menuitemradio";
|
||||||
ctxRadioGroup.addOption({ id });
|
ctxRadioGroup.addOption({ id });
|
||||||
|
|
||||||
|
@ -177,21 +163,18 @@
|
||||||
data-nested="{ref &&
|
data-nested="{ref &&
|
||||||
ref.closest('.bx--context-menu').getAttribute('data-level') === '2'}"
|
ref.closest('.bx--context-menu').getAttribute('data-level') === '2'}"
|
||||||
data-sub="{subOptions}"
|
data-sub="{subOptions}"
|
||||||
|
data-id="{id}"
|
||||||
{...$$restProps}
|
{...$$restProps}
|
||||||
on:keydown
|
on:keydown
|
||||||
on:keydown="{async ({ key }) => {
|
on:keydown="{async ({ key, target }) => {
|
||||||
if (
|
if (
|
||||||
subOptions &&
|
subOptions &&
|
||||||
(key === 'ArrowRight' || key === ' ' || key === 'Enter')
|
(key === 'ArrowRight' || key === ' ' || key === 'Enter')
|
||||||
) {
|
) {
|
||||||
submenuOpen = true;
|
submenuOpen = true;
|
||||||
|
|
||||||
await tick();
|
await tick();
|
||||||
|
|
||||||
options = [...ref.querySelectorAll('li[tabindex]')];
|
options = [...ref.querySelectorAll('li[tabindex]')];
|
||||||
|
|
||||||
if (options[focusIndex]) options[focusIndex].focus();
|
if (options[focusIndex]) options[focusIndex].focus();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,7 +199,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key === ' ' || key === 'Enter') {
|
if (key === ' ' || key === 'Enter') {
|
||||||
handleClick({ fromKeyboard: true });
|
handleClick({ fromKeyboard: true, id: target.getAttribute('data-id') });
|
||||||
}
|
}
|
||||||
}}"
|
}}"
|
||||||
on:mouseenter
|
on:mouseenter
|
||||||
|
@ -224,7 +207,7 @@
|
||||||
if (subOptions) {
|
if (subOptions) {
|
||||||
timeoutHover = setTimeout(() => {
|
timeoutHover = setTimeout(() => {
|
||||||
submenuOpen = true;
|
submenuOpen = true;
|
||||||
}, 150);
|
}, moderate01);
|
||||||
}
|
}
|
||||||
}}"
|
}}"
|
||||||
on:mouseleave
|
on:mouseleave
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue