Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,22 @@ describe("calcite-split-button", () => {
propertyName: "placement",
defaultValue: "bottom-end",
},
{
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome! Can you also add reflects tests for these new props?

propertyName: "download",
defaultValue: false,
},
{
propertyName: "href",
defaultValue: undefined,
},
{
propertyName: "rel",
defaultValue: undefined,
},
{
propertyName: "target",
defaultValue: undefined,
},
]);
});

Expand All @@ -30,6 +46,22 @@ describe("calcite-split-button", () => {
propertyName: "placement",
value: "bottom-end",
},
{
propertyName: "download",
value: true,
},
{
propertyName: "href",
value: "/",
},
{
propertyName: "rel",
value: "external",
},
{
propertyName: "target",
value: "_blank",
},
]);
});

Expand Down Expand Up @@ -261,4 +293,37 @@ describe("calcite-split-button", () => {
await dropdownCloseEvent;
expect(await positionContainer.isVisible()).toBe(false);
});

it("sets download attribute", async () => {
const page = await newE2EPage();
await page.setContent(`<calcite-split-button href="/">Continue</calcite-split-button>`);

const elementAsButton = await page.find("calcite-split-button >>> calcite-button");

expect(elementAsButton).not.toBeNull();
expect(await elementAsButton.getProperty("download")).toBe(false);
expect(elementAsButton).not.toHaveAttribute("download");

const element = await page.find("calcite-split-button");

element.setProperty("download", true);
await page.waitForChanges();

expect(await elementAsButton.getProperty("download")).toEqual(true);
expect(elementAsButton).toHaveAttribute("download");
expect(elementAsButton.getAttribute("download")).toBe("");

const newFilename = "my-cool-file.jpg";
element.setProperty("download", newFilename);
await page.waitForChanges();

expect(await elementAsButton.getProperty("download")).toBe(newFilename);
expect(elementAsButton.getAttribute("download")).toBe(newFilename);

element.setProperty("download", false);
await page.waitForChanges();

expect(await elementAsButton.getProperty("download")).toBe(false);
expect(elementAsButton).not.toHaveAttribute("download");
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -287,3 +287,35 @@ export const appearanceAndKindCombinations_TestOnly = (): string => html`
`;

export const loadingAndDisabled_TestOnly = (): string => html`<calcite-button loading disabled>Test</calcite-button>`;

export const primaryAsALink = (): string =>
html` <calcite-split-button
scale="m"
primary-text="Primary Option"
dropdown-icon-type="overflow"
href="split-button.html"
rel="external"
target="_blank"
>
<calcite-dropdown-group selection-mode="none">
<calcite-dropdown-item>Option 2</calcite-dropdown-item>
<calcite-dropdown-item>Option 3</calcite-dropdown-item>
<calcite-dropdown-item>Option 4</calcite-dropdown-item>
</calcite-dropdown-group>
</calcite-split-button>`;

export const primaryAsADownload = (): string =>
html` <calcite-split-button
download
scale="m"
primary-text="Primary Option"
primary-icon-start="download"
dropdown-icon-type="overflow"
href="/"
>
<calcite-dropdown-group selection-mode="none">
<calcite-dropdown-item>Option 2</calcite-dropdown-item>
<calcite-dropdown-item>Option 3</calcite-dropdown-item>
<calcite-dropdown-item>Option 4</calcite-dropdown-item>
</calcite-dropdown-group>
</calcite-split-button>`;
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
// @ts-strict-ignore
import { LitElement, property, createEvent, h, method, JsxNode } from "@arcgis/lumina";
import {
LitElement,
property,
createEvent,
h,
method,
JsxNode,
stringOrBoolean,
} from "@arcgis/lumina";
import { FlipPlacement, MenuPlacement, OverlayPositioning } from "../../utils/floating-ui";
import {
InteractiveComponent,
Expand Down Expand Up @@ -67,6 +75,14 @@ export class SplitButton extends LitElement implements InteractiveComponent, Loa
/** When `true`, interaction is prevented and the component is displayed with lower opacity. */
@property({ reflect: true }) disabled = false;

/**
* Prompts the user to save the linked URL instead of navigating to it. Can be used with or without a value:
* Without a value, the browser will suggest a filename/extension.
*
* @see [Global download attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#download).
*/
@property({ reflect: true, converter: stringOrBoolean }) download: string | boolean = false;

/** Specifies the icon used for the dropdown menu. */
@property({ reflect: true }) dropdownIconType: DropdownIconType = "chevron";

Expand All @@ -76,6 +92,9 @@ export class SplitButton extends LitElement implements InteractiveComponent, Loa
/** Specifies the component's fallback slotted content `placement` when it's initial or specified `placement` has insufficient space available. */
@property() flipPlacements: FlipPlacement[];

/** Specifies the URL of the linked resource, which can be set as an absolute or relative path. */
@property({ reflect: true }) href: string;

/** Specifies the kind of the component, which will apply to border and background, if applicable. */
@property({ reflect: true }) kind: Extract<"brand" | "danger" | "inverse" | "neutral", Kind> =
"brand";
Expand All @@ -92,6 +111,13 @@ export class SplitButton extends LitElement implements InteractiveComponent, Loa
*/
@property({ reflect: true }) overlayPositioning: OverlayPositioning = "absolute";

/**
* Defines the relationship between the `href` value and the current document.
*
* @mdn [rel](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/rel)
*/
@property({ reflect: true }) rel: string;

/**
* Determines where the component will be positioned relative to the container element.
*
Expand All @@ -117,6 +143,13 @@ export class SplitButton extends LitElement implements InteractiveComponent, Loa
/** Specifies the size of the component. */
@property({ reflect: true }) scale: Scale = "m";

/**
* Specifies where to open the linked document defined in the `href` property.
*
* @mdn [target](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#attr-target)
*/
@property({ reflect: true }) target: string;

/** Specifies the width of the component. [Deprecated] The `"half"` value is deprecated, use `"full"` instead. */
@property({ reflect: true }) width: Extract<Width, "auto" | "half" | "full"> = "auto";

Expand Down Expand Up @@ -181,15 +214,19 @@ export class SplitButton extends LitElement implements InteractiveComponent, Loa
<calcite-button
appearance={this.appearance}
disabled={this.disabled}
download={this.download}
href={this.href}
iconEnd={this.primaryIconEnd ? this.primaryIconEnd : null}
iconFlipRtl={this.primaryIconFlipRtl ? this.primaryIconFlipRtl : null}
iconStart={this.primaryIconStart ? this.primaryIconStart : null}
kind={this.kind}
label={this.primaryLabel}
loading={this.loading}
onClick={this.calciteSplitButtonPrimaryClickHandler}
rel={this.rel}
scale={this.scale}
splitChild={"primary"}
target={this.target}
type="button"
width={buttonWidth}
>
Expand Down
118 changes: 118 additions & 0 deletions packages/calcite-components/src/demos/split-button.html
Original file line number Diff line number Diff line change
Expand Up @@ -5568,6 +5568,124 @@
</div>
</div>

<!--
**************************************************
* DOWNLOAD
**************************************************
-->
<div class="parent-flex">
<div class="child-flex right-aligned-text">When primary is download</div>
<div class="child-flex">
<calcite-split-button
download
dropdown-icon-type="chevron"
scale="s"
primary-text="Primary Option"
primary-icon-start="download"
href="/"
>
<calcite-dropdown-group selection-mode="none">
<calcite-dropdown-item>Option 2</calcite-dropdown-item>
<calcite-dropdown-item>Option 3</calcite-dropdown-item>
<calcite-dropdown-item>Option 4</calcite-dropdown-item>
</calcite-dropdown-group>
</calcite-split-button>
</div>

<div class="child-flex">
<calcite-split-button
download
dropdown-icon-type="chevron"
scale="m"
primary-text="Primary Option"
primary-icon-start="download"
href="/"
>
<calcite-dropdown-group selection-mode="none">
<calcite-dropdown-item>Option 2</calcite-dropdown-item>
<calcite-dropdown-item>Option 3</calcite-dropdown-item>
<calcite-dropdown-item>Option 4</calcite-dropdown-item>
</calcite-dropdown-group>
</calcite-split-button>
</div>

<div class="child-flex">
<calcite-split-button
download
dropdown-icon-type="chevron"
scale="l"
primary-text="Primary Option"
primary-icon-start="download"
href="/"
>
<calcite-dropdown-group selection-mode="none">
<calcite-dropdown-item>Option 2</calcite-dropdown-item>
<calcite-dropdown-item>Option 3</calcite-dropdown-item>
<calcite-dropdown-item>Option 4</calcite-dropdown-item>
</calcite-dropdown-group>
</calcite-split-button>
</div>
</div>

<!--
**************************************************
* LINK
**************************************************
-->
<div class="parent-flex">
<div class="child-flex right-aligned-text">When primary is link</div>
<div class="child-flex">
<calcite-split-button
dropdown-icon-type="chevron"
scale="s"
primary-text="Primary Option"
href="/"
rel="external"
target="_blank"
>
<calcite-dropdown-group selection-mode="none">
<calcite-dropdown-item>Option 2</calcite-dropdown-item>
<calcite-dropdown-item>Option 3</calcite-dropdown-item>
<calcite-dropdown-item>Option 4</calcite-dropdown-item>
</calcite-dropdown-group>
</calcite-split-button>
</div>

<div class="child-flex">
<calcite-split-button
dropdown-icon-type="chevron"
scale="m"
primary-text="Primary Option"
href="/"
rel="external"
target="_blank"
>
<calcite-dropdown-group selection-mode="none">
<calcite-dropdown-item>Option 2</calcite-dropdown-item>
<calcite-dropdown-item>Option 3</calcite-dropdown-item>
<calcite-dropdown-item>Option 4</calcite-dropdown-item>
</calcite-dropdown-group>
</calcite-split-button>
</div>

<div class="child-flex">
<calcite-split-button
dropdown-icon-type="chevron"
scale="l"
primary-text="Primary Option"
href="/"
rel="external"
target="_blank"
>
<calcite-dropdown-group selection-mode="none">
<calcite-dropdown-item>Option 2</calcite-dropdown-item>
<calcite-dropdown-item>Option 3</calcite-dropdown-item>
<calcite-dropdown-item>Option 4</calcite-dropdown-item>
</calcite-dropdown-group>
</calcite-split-button>
</div>
</div>

<hr />

<!--
Expand Down