Skip to content

Commit

Permalink
feat(button): add download property (#8882)
Browse files Browse the repository at this point in the history
**Related Issue:** #4077 

## Summary

Added the download property to the calcite-button when a href property
is specified. Used calcite-link as a reference for implementation.
  • Loading branch information
Ninkuk authored Mar 6, 2024
1 parent c2cabb3 commit fc55dde
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 0 deletions.
8 changes: 8 additions & 0 deletions packages/calcite-components/src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,10 @@ export namespace Components {
* When `true`, interaction is prevented and the component is displayed with lower opacity.
*/
"disabled": boolean;
/**
* Specifies the optional new name of the file after it is downloaded.
*/
"download": string | boolean;
/**
* The `id` of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any.
*/
Expand Down Expand Up @@ -8054,6 +8058,10 @@ declare namespace LocalJSX {
* When `true`, interaction is prevented and the component is displayed with lower opacity.
*/
"disabled"?: boolean;
/**
* Specifies the optional new name of the file after it is downloaded.
*/
"download"?: string | boolean;
/**
* The `id` of the form that will be associated with the component. When not set, the component will be associated with its ancestor form element, if any.
*/
Expand Down
37 changes: 37 additions & 0 deletions packages/calcite-components/src/components/button/button.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ describe("calcite-button", () => {
propertyName: "disabled",
defaultValue: false,
},
{
propertyName: "download",
defaultValue: false,
},
{
propertyName: "href",
defaultValue: undefined,
Expand Down Expand Up @@ -217,6 +221,39 @@ describe("calcite-button", () => {
expect(loader).toBeNull();
});

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

const elementAsLink = await page.find("calcite-button >>> a");

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

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

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

expect(await elementAsLink.getProperty("download")).toBe("");
expect(elementAsLink).toHaveAttribute("download");
expect(elementAsLink.getAttribute("download")).toBe("");

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

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

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

expect(await elementAsLink.getProperty("download")).toBe("");
expect(elementAsLink).not.toHaveAttribute("download");
});

it("renders as a button with requested props", async () => {
const page = await newE2EPage();
await page.setContent(
Expand Down
10 changes: 10 additions & 0 deletions packages/calcite-components/src/components/button/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,13 @@ export class Button
@Prop({ reflect: true })
form: string;

/**
* 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 https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#attr-download.
*/
@Prop({ reflect: true }) download: string | boolean = false;

/**
* Specifies the URL of the linked resource, which can be set as an absolute or relative path.
*/
Expand Down Expand Up @@ -287,6 +294,9 @@ export class Button
[CSS.iconEndEmpty]: !this.iconEnd,
}}
disabled={childElType === "button" ? this.disabled || this.loading : null}
download={
childElType === "a" && (this.download === "" || this.download) ? this.download : null
}
href={childElType === "a" && this.href}
name={childElType === "button" && this.name}
onClick={this.handleClick}
Expand Down
19 changes: 19 additions & 0 deletions packages/calcite-components/src/demos/button.html
Original file line number Diff line number Diff line change
Expand Up @@ -2199,6 +2199,25 @@
</section>
</div>

<!-- Download Button -->
<div class="loader">
<p>Download</p>

<section>
<calcite-label layout="inline">
<span>Boolean</span>
<calcite-button icon-start="download" download href="button.html">Download this page</calcite-button>
</calcite-label>

<calcite-label layout="inline">
<span>Value</span>
<calcite-button icon-start="download" download="sample-page.html" href="button.html"
>Download this page</calcite-button
>
</calcite-label>
</section>
</div>

<!--
***************************************************************
* WIDTHS
Expand Down

0 comments on commit fc55dde

Please sign in to comment.