From ab04bb756475361a0d81dc6248124f918d518e99 Mon Sep 17 00:00:00 2001 From: dqzx <4139931+dqzx@users.noreply.github.com> Date: Sat, 3 Jul 2021 11:42:35 +0100 Subject: [PATCH 1/6] Fix: trap tab focus within modal (#716) * Fix: trap tab focus within modal * Fix: trap tab focus within ComposedModal * change selector criteria for tabbable elements based on react component logic --- src/ComposedModal/ComposedModal.svelte | 27 ++++++++++++++++++++++++++ src/Modal/Modal.svelte | 27 +++++++++++++++++++++++--- 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/src/ComposedModal/ComposedModal.svelte b/src/ComposedModal/ComposedModal.svelte index 43c4621e..094eba37 100644 --- a/src/ComposedModal/ComposedModal.svelte +++ b/src/ComposedModal/ComposedModal.svelte @@ -103,6 +103,33 @@ class:is-visible="{open}" class:bx--modal--danger="{danger}" {...$$restProps} + on:keydown + on:keydown="{(e) => { + if (open) { + if (e.key === 'Escape') { + open = false; + } else if (e.key === 'Tab') { + // taken from github.com/carbon-design-system/carbon/packages/react/src/internal/keyboard/navigation.js + const selectorTabbable = ` + a[href], area[href], input:not([disabled]):not([tabindex='-1']), + button:not([disabled]):not([tabindex='-1']),select:not([disabled]):not([tabindex='-1']), + textarea:not([disabled]):not([tabindex='-1']), + iframe, object, embed, *[tabindex]:not([tabindex='-1']):not([disabled]), *[contenteditable=true] +`; + + const tabbable = Array.from(ref.querySelectorAll(selectorTabbable)); + + let index = tabbable.indexOf(document.activeElement); + if (index === -1 && e.shiftKey) index = 0; + + index += tabbable.length + (e.shiftKey ? -1 : 1); + index %= tabbable.length; + + tabbable[index].focus(); + e.preventDefault(); + } + } + }}" on:click on:click="{() => { if (!didClickInnerModal && !preventCloseOnClickOutside) open = false; diff --git a/src/Modal/Modal.svelte b/src/Modal/Modal.svelte index c167dec4..d4d65d24 100644 --- a/src/Modal/Modal.svelte +++ b/src/Modal/Modal.svelte @@ -138,11 +138,32 @@ class:bx--modal--danger="{danger}" {...$$restProps} on:keydown - on:keydown="{({ key }) => { + on:keydown="{(e) => { if (open) { - if (key === 'Escape') { + if (e.key === 'Escape') { open = false; - } else if (shouldSubmitOnEnter && key === 'Enter') { + } else if (e.key === 'Tab') { + // trap focus + + // taken from github.com/carbon-design-system/carbon/packages/react/src/internal/keyboard/navigation.js + const selectorTabbable = ` + a[href], area[href], input:not([disabled]):not([tabindex='-1']), + button:not([disabled]):not([tabindex='-1']),select:not([disabled]):not([tabindex='-1']), + textarea:not([disabled]):not([tabindex='-1']), + iframe, object, embed, *[tabindex]:not([tabindex='-1']):not([disabled]), *[contenteditable=true] +`; + + const tabbable = Array.from(ref.querySelectorAll(selectorTabbable)); + + let index = tabbable.indexOf(document.activeElement); + if (index === -1 && e.shiftKey) index = 0; + + index += tabbable.length + (e.shiftKey ? -1 : 1); + index %= tabbable.length; + + tabbable[index].focus(); + e.preventDefault(); + } else if (shouldSubmitOnEnter && e.key === 'Enter') { dispatch('submit'); } } From 9763bf5cab5d96759583f09bde8508ce2eeb6f01 Mon Sep 17 00:00:00 2001 From: Eric Liu Date: Sat, 3 Jul 2021 05:11:52 -0700 Subject: [PATCH 2/6] docs: add g80 to valid themes (#718) --- docs/src/layouts/ComponentLayout.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/layouts/ComponentLayout.svelte b/docs/src/layouts/ComponentLayout.svelte index 41982bcd..deb57cd7 100644 --- a/docs/src/layouts/ComponentLayout.svelte +++ b/docs/src/layouts/ComponentLayout.svelte @@ -37,7 +37,7 @@ onMount(() => { const currentTheme = window.location.search.split("?theme=")[1]; - if (["white", "g10", "g90", "g100"].includes(currentTheme)) { + if (["white", "g10", "g80", "g90", "g100"].includes(currentTheme)) { theme.set(currentTheme); } }); From 776639495f3d0cfa6d31dde38350c57cb07bbeb9 Mon Sep 17 00:00:00 2001 From: Eric Y Liu Date: Sat, 3 Jul 2021 13:34:38 -0700 Subject: [PATCH 3/6] fix(overflow-menu): add guard to prevent focus on falsy ref #714 Fixes #714 --- src/OverflowMenu/OverflowMenuItem.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OverflowMenu/OverflowMenuItem.svelte b/src/OverflowMenu/OverflowMenuItem.svelte index df56f4e6..4fb2718f 100644 --- a/src/OverflowMenu/OverflowMenuItem.svelte +++ b/src/OverflowMenu/OverflowMenuItem.svelte @@ -36,7 +36,7 @@ add({ id, text, primaryFocus }); afterUpdate(() => { - if (primaryFocus) { + if (ref && primaryFocus) { ref.focus(); } }); From f9183d343b8c4aa2abb7d9839c3adc56b3255ffb Mon Sep 17 00:00:00 2001 From: Eric Liu Date: Sat, 3 Jul 2021 13:42:24 -0700 Subject: [PATCH 4/6] fix(text-area): omit prop if readonly={false} #710 (#719) Fixes #710 --- src/TextArea/TextArea.svelte | 1 + 1 file changed, 1 insertion(+) diff --git a/src/TextArea/TextArea.svelte b/src/TextArea/TextArea.svelte index 8fac4cdd..8920cb0f 100644 --- a/src/TextArea/TextArea.svelte +++ b/src/TextArea/TextArea.svelte @@ -90,6 +90,7 @@ class:bx--text-area--light="{light}" class:bx--text-area--invalid="{invalid}" {...$$restProps} + readonly="{$$restProps.readonly === true ? true : undefined}" on:change on:input on:input="{({ target }) => { From c647cb27a7640a9e10286bf89b79e75f0e45810d Mon Sep 17 00:00:00 2001 From: Eric Y Liu Date: Sat, 3 Jul 2021 13:46:21 -0700 Subject: [PATCH 5/6] v0.38.2 --- CHANGELOG.md | 8 ++++++++ COMPONENT_INDEX.md | 3 ++- docs/src/COMPONENT_API.json | 1 + package.json | 2 +- preprocess/api.json | 2 +- types/ComposedModal/ComposedModal.d.ts | 1 + 6 files changed, 14 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b2339ef..6b9a1c5c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 +## [0.38.2](https://github.com/IBM/carbon-components-svelte/releases/tag/v0.38.2) - 2021-07-03 + +**Fixes** + +- prevent `