diff --git a/.changeset/tired-words-buy.md b/.changeset/tired-words-buy.md new file mode 100644 index 00000000..15e0ed80 --- /dev/null +++ b/.changeset/tired-words-buy.md @@ -0,0 +1,7 @@ +--- +"@tapsioss/react-components": minor +"@tapsioss/web-components": minor +--- + +Expose File Input's Clear Event + \ No newline at end of file diff --git a/packages/react-components/src/FileInput/FileInput.ts b/packages/react-components/src/FileInput/FileInput.ts index ad43921d..a89e9cc5 100644 --- a/packages/react-components/src/FileInput/FileInput.ts +++ b/packages/react-components/src/FileInput/FileInput.ts @@ -6,6 +6,7 @@ import { import * as React from "react"; import { + FileInputClearEvent, FileInput as FileInputElement, FileInputRetryEvent, FileInputSlots, @@ -16,16 +17,27 @@ registerFileInput(); export const FileInput: ReactWebComponent< FileInputElement, - { onRetry: EventName; onChange: string; onInput: string } + { + onRetry: EventName; + onClear: EventName; + onChange: string; + onInput: string; + } > = createComponent({ tagName: "tapsi-file-input", elementClass: FileInputElement, react: React, events: { onRetry: "retry" as EventName, + onClear: "clear" as EventName, onChange: "input", onInput: "input", }, }); -export { FileInputElement, FileInputRetryEvent, FileInputSlots }; +export { + FileInputClearEvent, + FileInputElement, + FileInputRetryEvent, + FileInputSlots, +}; diff --git a/packages/web-components/src/file-input/events.ts b/packages/web-components/src/file-input/events.ts index eee93996..e22af38d 100644 --- a/packages/web-components/src/file-input/events.ts +++ b/packages/web-components/src/file-input/events.ts @@ -11,3 +11,15 @@ export class RetryEvent extends BaseEvent { }); } } + +export class ClearEvent extends BaseEvent { + public static readonly type = "clear"; + + constructor() { + super(ClearEvent.type, { + bubbles: true, + composed: true, + details: null, + }); + } +} diff --git a/packages/web-components/src/file-input/file-input.ts b/packages/web-components/src/file-input/file-input.ts index 341d817b..9e341ca3 100644 --- a/packages/web-components/src/file-input/file-input.ts +++ b/packages/web-components/src/file-input/file-input.ts @@ -32,7 +32,7 @@ import { withOnReportValidity, } from "../utils/index.ts"; import { ErrorMessages, scope, Slots } from "./constants.ts"; -import { RetryEvent } from "./events.ts"; +import { ClearEvent, RetryEvent } from "./events.ts"; import styles from "./file-input.style.ts"; import { clear, error, image } from "./icons.ts"; import { @@ -61,6 +61,7 @@ const BaseClass = withOnReportValidity( * @slot [placeholder-icon] - The slot for icon placeholder. * * @fires {RetryEvent} retry - Fires when the retry button is clicked. (bubbles) + * @fires {ClearEvent} clear - Fires when user clicks on the clear button for reseting the input value (bubbles) * @fires {Event} change - * Fires when the user modifies the element's value. * Unlike the `input` event, the change event is not necessarily fired for each @@ -593,6 +594,21 @@ export class FileInput extends BaseClass { return this.loading.toString() !== "false"; } + private _handleClear() { + this.reset(); + const event = new ClearEvent(); + + this.dispatchEvent(event); + event.stopPropagation(); + } + + private _handleRetry() { + const event = new RetryEvent(); + + this.dispatchEvent(event); + event.stopPropagation(); + } + private _renderHelperText() { const text = this._getSupportingOrErrorText(); @@ -647,13 +663,20 @@ export class FileInput extends BaseClass { src=${this._previewSrc} alt="preview" class="preview" + part="preview" />`; } - return html`${file.name}`; + return html`${file.name}`; } - return html`${toFaNumber(this.files.length.toString())} فایل انتخاب شده`; } @@ -664,20 +687,28 @@ export class FileInput extends BaseClass { let icon; if (!isNumber) { - icon = html`
+ icon = html`
`; } else { const { offset, progressSize, progressStroke, circumference, radius } = getProgressUiParams(parseInt(this.loading.toString())); - icon = html`
+ icon = html`
- ${toFaNumber(this.loading.toString())}٪ + ${toFaNumber(this.loading.toString())}٪
`; } - return html`
+ return html`
${icon} - ${this.loadingText} + ${this.loadingText}
`; } @@ -713,24 +756,37 @@ export class FileInput extends BaseClass { size="sm" variant="ghost" class="error-action" - @click=${() => this.dispatchEvent(new RetryEvent())} + part="error-action" + @click=${this._handleRetry} > تلاش مجدد `; } private _renderErrorState() { - return html`
-
${error}
+ return html`
+
+ ${error} +
${this._renderRetry()}
`; } private _renderEmptyState() { return html` -
+
${image}
- ${this.placeholder} + ${this.placeholder}
`; } @@ -762,16 +823,16 @@ export class FileInput extends BaseClass { private _renderClearIcon() { if (this._value) - return html`
- - ${clear} - -
`; + return html` + ${clear} + `; return null; } @@ -803,10 +864,10 @@ export class FileInput extends BaseClass { part="control" >
${this._renderFileInputContent()}${this._renderClearIcon()}
diff --git a/packages/web-components/src/index.ts b/packages/web-components/src/index.ts index 89cd8db0..2321c66c 100644 --- a/packages/web-components/src/index.ts +++ b/packages/web-components/src/index.ts @@ -90,6 +90,7 @@ import { } from "./empty-state/index.ts"; import { FileInput, + ClearEvent as FileInputClearEvent, RetryEvent as FileInputRetryEvent, Slots as FileInputSlots, register as registerFileInput, @@ -219,6 +220,7 @@ export { EmptyState, EmptyStateSlots, FileInput, + FileInputClearEvent, FileInputRetryEvent, FileInputSlots, IconButton,