Skip to content
This repository has been archived by the owner on Jun 29, 2023. It is now read-only.

Commit

Permalink
fix(block): prevent unintentional toggling when interacting with a sl…
Browse files Browse the repository at this point in the history
…otted control (#762)

#751
  • Loading branch information
jcfranco authored Jan 16, 2020
1 parent e462324 commit 217203a
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 23 deletions.
4 changes: 3 additions & 1 deletion src/components/calcite-block/calcite-block.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ describe("calcite-block", () => {
it("allows users to add a control in a collapsible block", async () => {
const page = await newE2EPage();
await page.setContent(
`<calcite-block heading="test-heading" collapsible><input class="nested-control" slot=${SLOTS.control} /></calcite-block>`
`<calcite-block heading="test-heading" collapsible><div class="nested-control" tabindex="0" slot=${SLOTS.control}>fake space/enter-bubbling control</div></calcite-block>`
);
const control = await page.find(".nested-control");
expect(await control.isVisible()).toBe(true);
Expand All @@ -189,6 +189,8 @@ describe("calcite-block", () => {
const block = await page.find("calcite-block");
const blockToggleSpy = await block.spyOnEvent("calciteBlockToggle");

await control.press("Space");
await control.press("Enter");
await control.click();
expect(blockToggleSpy).toHaveReceivedEventTimes(0);

Expand Down
19 changes: 18 additions & 1 deletion src/components/calcite-block/calcite-block.scss
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,14 @@

.header {
flex-grow: 1;
justify-content: flex-start;
}

.header-container {
position: relative;
display: flex;
align-items: center;

& > .header {
padding: var(--calcite-app-cap-spacing-half) var(--calcite-app-side-spacing-three-quarters);
}
Expand All @@ -35,7 +40,6 @@ calcite-loader[inline] {
}

.title {
flex-grow: 1;
margin: 0;
}

Expand Down Expand Up @@ -79,3 +83,16 @@ calcite-loader[inline] {
padding: 0 var(--calcite-app-side-spacing-three-quarters) var(--calcite-app-cap-spacing-half);
position: relative;
}

::slotted([slot="control"]) {
position: absolute;
margin: auto;
right: var(--calcite-app-side-spacing-three-quarters);
}

.calcite--rtl {
::slotted([slot="control"]) {
left: var(--calcite-app-side-spacing-three-quarters);
right: unset;
}
}
32 changes: 11 additions & 21 deletions src/components/calcite-block/calcite-block.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -99,18 +99,7 @@ export class CalciteBlock {
//
// --------------------------------------------------------------------------

onHeaderClick = (event: MouseEvent) => {
const controlSlot = this.el.shadowRoot.querySelector<HTMLSlotElement>(
`slot[name=${SLOTS.control}]`
);
const control = controlSlot && controlSlot.assignedNodes()[0];

if (control && control.contains(event.target as Node)) {
event.stopPropagation();
event.preventDefault();
return;
}

onHeaderClick = (): void => {
this.open = !this.open;
this.calciteBlockToggle.emit();
};
Expand All @@ -134,11 +123,6 @@ export class CalciteBlock {
textExpand
} = this;
const toggleLabel = open ? textCollapse : textExpand;
const content = loading ? (
<calcite-loader inline is-active></calcite-loader>
) : (
<slot name={SLOTS.control} />
);

const hasIcon = el.querySelector(`[slot=${SLOTS.icon}]`);
const headerContent = (
Expand All @@ -152,12 +136,11 @@ export class CalciteBlock {
<h3 class={CSS.heading}>{heading}</h3>
{summary ? <div class={CSS.summary}>{summary}</div> : null}
</div>
{content}
</header>
);

const controlSlot = el.querySelector(`[slot=${SLOTS.control}]`);
const hasContent = el.children.length > (controlSlot ? 1 : 0);
const slottedControl = el.querySelector(`[slot=${SLOTS.control}]`);
const hasContent = el.children.length > (slottedControl ? 1 : 0);

const headerNode = (
<div class={CSS.headerContainer}>
Expand All @@ -169,11 +152,18 @@ export class CalciteBlock {
title={toggleLabel}
>
{headerContent}
{controlSlot ? null : <calcite-icon scale="s" icon={open ? ICONS.close : ICONS.open} />}
{slottedControl ? null : (
<calcite-icon scale="s" icon={open ? ICONS.close : ICONS.open} />
)}
</button>
) : (
headerContent
)}
{loading ? (
<calcite-loader inline is-active></calcite-loader>
) : (
<slot name={SLOTS.control} />
)}
</div>
);

Expand Down

0 comments on commit 217203a

Please sign in to comment.