Skip to content

Commit

Permalink
feat(handle): add selected property and calciteHandleChange event. (#…
Browse files Browse the repository at this point in the history
…8484)

**Related Issue:** #8522

## Summary

- depends on #8483
- Renames `activated` property to `selected` to align with other
components
- Makes `selected` public
- Adds public event `calciteHandleChange` for when `selected` is changed
via user
- Renames internal event `calciteInternalHandleChange` to
`calciteInternalAssistiveTextChange` to better illustrate its purpose
- adds tests
  • Loading branch information
driskull authored and benelan committed Jan 2, 2024
1 parent 4de7076 commit e99bbf7
Show file tree
Hide file tree
Showing 8 changed files with 92 additions and 55 deletions.
31 changes: 25 additions & 6 deletions packages/calcite-components/src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1768,7 +1768,10 @@ export namespace Components {
"min": number;
}
interface CalciteHandle {
"activated": boolean;
/**
* When `true`, disables unselecting the component when blurred.
*/
"blurUnselectDisabled": boolean;
/**
* When `true`, disables unselecting the component when blurred.
*/
Expand All @@ -1790,6 +1793,10 @@ export namespace Components {
* Made into a prop for testing purposes only
*/
"messages": HandleMessages;
/**
* When `true`, the component is selected.
*/
"selected": boolean;
/**
* Sets focus on the component.
*/
Expand Down Expand Up @@ -6144,8 +6151,9 @@ declare global {
new (): HTMLCalciteGraphElement;
};
interface HTMLCalciteHandleElementEventMap {
"calciteHandleChange": void;
"calciteHandleNudge": HandleNudge;
"calciteInternalHandleChange": HandleChange;
"calciteInternalAssistiveTextChange": HandleChange;
}
interface HTMLCalciteHandleElement extends Components.CalciteHandle, HTMLStencilElement {
addEventListener<K extends keyof HTMLCalciteHandleElementEventMap>(type: K, listener: (this: HTMLCalciteHandleElement, ev: CalciteHandleCustomEvent<HTMLCalciteHandleElementEventMap[K]>) => any, options?: boolean | AddEventListenerOptions): void;
Expand Down Expand Up @@ -9066,7 +9074,10 @@ declare namespace LocalJSX {
"min": number;
}
interface CalciteHandle {
"activated"?: boolean;
/**
* When `true`, disables unselecting the component when blurred.
*/
"blurUnselectDisabled"?: boolean;
/**
* When `true`, disables unselecting the component when blurred.
*/
Expand All @@ -9089,13 +9100,21 @@ declare namespace LocalJSX {
*/
"messages"?: HandleMessages;
/**
* Emitted when the handle is activated and the up or down arrow key is pressed.
* Emits whenever the component is selected or unselected.
*/
"onCalciteHandleChange"?: (event: CalciteHandleCustomEvent<void>) => void;
/**
* Emitted when the handle is selected and the up or down arrow key is pressed.
*/
"onCalciteHandleNudge"?: (event: CalciteHandleCustomEvent<HandleNudge>) => void;
/**
* Emitted when the handle is activated or deactivated.
* Emitted when the assistive text has changed.
*/
"onCalciteInternalHandleChange"?: (event: CalciteHandleCustomEvent<HandleChange>) => void;
"onCalciteInternalAssistiveTextChange"?: (event: CalciteHandleCustomEvent<HandleChange>) => void;
/**
* When `true`, the component is selected.
*/
"selected"?: boolean;
"setPosition"?: number;
"setSize"?: number;
}
Expand Down
32 changes: 19 additions & 13 deletions packages/calcite-components/src/components/handle/handle.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,67 +19,73 @@ describe("calcite-handle", () => {
accessible(`<calcite-handle></calcite-handle>`);
});

it("activates when focused and space is pressed", async () => {
it("sets selected to true when focused and space is pressed", async () => {
const page = await newE2EPage();
await page.setContent("<calcite-handle></calcite-handle>");

const handle = await page.find("calcite-handle");
const button = await page.find(`calcite-handle >>> .${CSS.handle}`);

expect(await handle.getProperty("activated")).toBe(false);
expect(await handle.getProperty("selected")).toBe(false);

await button.focus();

const calciteHandleChange = await page.spyOnEvent("calciteHandleChange", "window");
await page.keyboard.press(" ");

await page.waitForChanges();

expect(await handle.getProperty("activated")).toBe(true);
expect(await handle.getProperty("selected")).toBe(true);
expect(calciteHandleChange).toHaveReceivedEventTimes(1);
});

it("sets activated to false when blurred", async () => {
it("sets selected to false when blurred", async () => {
const page = await newE2EPage();
await page.setContent("<calcite-handle></calcite-handle>");

const handle = await page.find("calcite-handle");
const button = await page.find(`calcite-handle >>> .${CSS.handle}`);

expect(await handle.getProperty("activated")).toBe(false);
expect(await handle.getProperty("selected")).toBe(false);

await button.focus();

const calciteHandleChange = await page.spyOnEvent("calciteHandleChange", "window");
await page.keyboard.press(" ");

await page.waitForChanges();

expect(await handle.getProperty("activated")).toBe(true);
expect(await handle.getProperty("selected")).toBe(true);
expect(calciteHandleChange).toHaveReceivedEventTimes(1);

await page.$eval("calcite-handle", (handle: HTMLCalciteHandleElement) => handle.blur());

expect(await handle.getProperty("activated")).toBe(false);
expect(await handle.getProperty("selected")).toBe(false);
expect(calciteHandleChange).toHaveReceivedEventTimes(2);
});

it("does not set activated to false when blurUnselectDisabled and blurred", async () => {
it("does not set selected to false when blurUnselectDisabled and blurred", async () => {
const page = await newE2EPage();
await page.setContent("<calcite-handle blur-unselect-disabled></calcite-handle>");

const handle = await page.find("calcite-handle");
const button = await page.find(`calcite-handle >>> .${CSS.handle}`);

expect(await handle.getProperty("blurUnselectDisabled")).toBe(true);
expect(await handle.getProperty("activated")).toBe(false);
expect(await handle.getProperty("selected")).toBe(false);

await button.focus();

const calciteHandleChange = await page.spyOnEvent("calciteHandleChange", "window");
await page.keyboard.press(" ");

await page.waitForChanges();

expect(await handle.getProperty("activated")).toBe(true);
expect(await handle.getProperty("selected")).toBe(true);
expect(calciteHandleChange).toHaveReceivedEventTimes(1);

await page.$eval("calcite-handle", (handle: HTMLCalciteHandleElement) => handle.blur());

expect(await handle.getProperty("activated")).toBe(true);
expect(await handle.getProperty("selected")).toBe(true);
expect(calciteHandleChange).toHaveReceivedEventTimes(1);
});

it("fires calciteHandleNudge event when focused and up or down key is pressed", async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
&:focus {
@apply text-color-1 focus-inset;
}
&--activated {
&--selected {
@apply bg-foreground-3 text-color-1;
}
}
Expand Down
43 changes: 27 additions & 16 deletions packages/calcite-components/src/components/handle/handle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,20 +49,20 @@ export class Handle implements LoadableComponent, T9nComponent, InteractiveCompo
// --------------------------------------------------------------------------

/**
* @internal
* When `true`, the component is selected.
*/
@Prop({ mutable: true, reflect: true }) activated = false;
@Prop({ mutable: true, reflect: true }) selected = false;

@Watch("messages")
@Watch("label")
@Watch("activated")
@Watch("selected")
@Watch("setPosition")
@Watch("setSize")
handleAriaTextChange(): void {
const message = this.getAriaText("live");

if (message) {
this.calciteInternalHandleChange.emit({
this.calciteInternalAssistiveTextChange.emit({
message,
});
}
Expand Down Expand Up @@ -180,14 +180,21 @@ export class Handle implements LoadableComponent, T9nComponent, InteractiveCompo
// --------------------------------------------------------------------------

/**
* Emitted when the handle is activated and the up or down arrow key is pressed.
* Emits whenever the component is selected or unselected.
*
*/
@Event({ cancelable: false }) calciteHandleChange: EventEmitter<void>;

/**
* Emitted when the handle is selected and the up or down arrow key is pressed.
*/
@Event({ cancelable: false }) calciteHandleNudge: EventEmitter<HandleNudge>;

/**
* Emitted when the handle is activated or deactivated.
* Emitted when the assistive text has changed.
* @internal
*/
@Event({ cancelable: false }) calciteInternalHandleChange: EventEmitter<HandleChange>;
@Event({ cancelable: false }) calciteInternalAssistiveTextChange: EventEmitter<HandleChange>;

// --------------------------------------------------------------------------
//
Expand All @@ -210,18 +217,18 @@ export class Handle implements LoadableComponent, T9nComponent, InteractiveCompo
// --------------------------------------------------------------------------

getAriaText(type: "label" | "live"): string {
const { setPosition, setSize, label, messages, activated } = this;
const { setPosition, setSize, label, messages, selected } = this;

if (!messages || !label || typeof setSize !== "number" || typeof setPosition !== "number") {
return null;
}

const text =
type === "label"
? activated
? selected
? messages.dragHandleChange
: messages.dragHandleIdle
: activated
: selected
? messages.dragHandleActive
: messages.dragHandleCommit;

Expand All @@ -237,18 +244,19 @@ export class Handle implements LoadableComponent, T9nComponent, InteractiveCompo

switch (event.key) {
case " ":
this.activated = !this.activated;
this.selected = !this.selected;
this.calciteHandleChange.emit();
event.preventDefault();
break;
case "ArrowUp":
if (!this.activated) {
if (!this.selected) {
return;
}
event.preventDefault();
this.calciteHandleNudge.emit({ direction: "up" });
break;
case "ArrowDown":
if (!this.activated) {
if (!this.selected) {
return;
}
event.preventDefault();
Expand All @@ -262,7 +270,10 @@ export class Handle implements LoadableComponent, T9nComponent, InteractiveCompo
return;
}

this.activated = false;
if (this.selected) {
this.selected = false;
this.calciteHandleChange.emit();
}
};

// --------------------------------------------------------------------------
Expand All @@ -277,8 +288,8 @@ export class Handle implements LoadableComponent, T9nComponent, InteractiveCompo
<span
aria-disabled={this.disabled ? toAriaBoolean(this.disabled) : null}
aria-label={this.disabled ? null : this.getAriaText("label")}
aria-pressed={this.disabled ? null : toAriaBoolean(this.activated)}
class={{ [CSS.handle]: true, [CSS.handleActivated]: !this.disabled && this.activated }}
aria-pressed={this.disabled ? null : toAriaBoolean(this.selected)}
class={{ [CSS.handle]: true, [CSS.handleSelected]: !this.disabled && this.selected }}
onBlur={this.handleBlur}
onKeyDown={this.handleKeyDown}
role="button"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export const CSS = {
handle: "handle",
handleActivated: "handle--activated",
handleSelected: "handle--selected",
};

export const ICONS = {
Expand Down
8 changes: 4 additions & 4 deletions packages/calcite-components/src/components/list/list.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1015,7 +1015,7 @@ describe("calcite-list", () => {
await page.keyboard.press("Tab");
await page.keyboard.press("Tab");
await page.keyboard.press("Space");
expect(await handle.getProperty("activated")).toBe(true);
expect(await handle.getProperty("selected")).toBe(true);
await page.waitForChanges();

let totalMoves = 0;
Expand Down Expand Up @@ -1125,7 +1125,7 @@ describe("calcite-list", () => {
);

await page.keyboard.press("Space");
expect(await handle.getProperty("activated")).toBe(true);
expect(await handle.getProperty("selected")).toBe(true);
await page.waitForChanges();

expect(assistiveTextElement.textContent).toBe(
Expand All @@ -1139,7 +1139,7 @@ describe("calcite-list", () => {

await page.keyboard.press("ArrowDown");
await page.waitForChanges();
expect(await handle.getProperty("activated")).toBe(true);
expect(await handle.getProperty("selected")).toBe(true);
await page.waitForTimeout(debounceTimeout);

startIndex += 1;
Expand Down Expand Up @@ -1170,7 +1170,7 @@ describe("calcite-list", () => {
await page.keyboard.press("ArrowUp");
await page.keyboard.press("Space");
await page.waitForChanges();
expect(await handle.getProperty("activated")).toBe(false);
expect(await handle.getProperty("selected")).toBe(false);
});
});
});
Loading

0 comments on commit e99bbf7

Please sign in to comment.