Skip to content

Commit

Permalink
refactor(file-upload): add invalid prop
Browse files Browse the repository at this point in the history
  • Loading branch information
segunadebayo committed Sep 5, 2024
1 parent 44628a1 commit 4c1923e
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 63 deletions.
6 changes: 6 additions & 0 deletions .changeset/plenty-toys-behave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@zag-js/file-upload": minor
---

Add support for `invalid` prop in file upload to explicitly mark upload operation as invalid. This could be paired with
the `rejectedFiles` to show an error message.
30 changes: 8 additions & 22 deletions .xstate/file-upload.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,7 @@ const {
const fetchMachine = createMachine({
id: "fileupload",
initial: "idle",
context: {
"!isWithinRange": false,
"!isWithinRange": false
},
context: {},
on: {
"FILES.SET": {
actions: ["setFilesFromEvent"]
Expand Down Expand Up @@ -45,13 +42,9 @@ const fetchMachine = createMachine({
actions: ["openFilePicker"]
},
"DROPZONE.FOCUS": "focused",
"DROPZONE.DRAG_OVER": [{
cond: "!isWithinRange",
target: "dragging",
actions: ["setInvalid"]
}, {
"DROPZONE.DRAG_OVER": {
target: "dragging"
}]
}
}
},
focused: {
Expand All @@ -63,24 +56,19 @@ const fetchMachine = createMachine({
"DROPZONE.CLICK": {
actions: ["openFilePicker"]
},
"DROPZONE.DRAG_OVER": [{
cond: "!isWithinRange",
target: "dragging",
actions: ["setInvalid"]
}, {
"DROPZONE.DRAG_OVER": {
target: "dragging"
}]
}
}
},
dragging: {
on: {
"DROPZONE.DROP": {
target: "idle",
actions: ["clearInvalid", "setFilesFromEvent", "syncInputElement"]
actions: ["setFilesFromEvent", "syncInputElement"]
},
"DROPZONE.DRAG_LEAVE": {
target: "idle",
actions: ["clearInvalid"]
target: "idle"
}
}
}
Expand All @@ -93,7 +81,5 @@ const fetchMachine = createMachine({
};
})
},
guards: {
"!isWithinRange": ctx => ctx["!isWithinRange"]
}
guards: {}
});
4 changes: 3 additions & 1 deletion packages/machines/file-upload/src/file-upload.connect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,9 @@ export function connect<T extends PropTypes>(state: State, send: Send, normalize
dir: state.context.dir,
id: dom.getDropzoneId(state.context),
tabIndex: disabled ? undefined : 0,
role: "button",
"aria-label": translations.dropzone,
"aria-disabled": disabled,
"aria-invalid": state.context.invalid,
"data-invalid": dataAttr(state.context.invalid),
"data-disabled": dataAttr(disabled),
"data-dragging": dataAttr(dragging),
Expand Down Expand Up @@ -124,6 +125,7 @@ export function connect<T extends PropTypes>(state: State, send: Send, normalize
id: dom.getTriggerId(state.context),
disabled,
"data-disabled": dataAttr(disabled),
"data-invalid": dataAttr(state.context.invalid),
type: "button",
onClick(event) {
if (disabled) return
Expand Down
44 changes: 11 additions & 33 deletions packages/machines/file-upload/src/file-upload.machine.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import { createMachine, guards, ref } from "@zag-js/core"
import { createMachine, ref } from "@zag-js/core"
import { raf } from "@zag-js/dom-query"
import { getAcceptAttrString, isFileEqual } from "@zag-js/file-utils"
import { compact } from "@zag-js/utils"
import { dom } from "./file-upload.dom"
import type { MachineContext, MachineState, FileRejection, UserDefinedContext } from "./file-upload.types"
import { getFilesFromEvent, isFilesWithinRange } from "./file-upload.utils"

const { not } = guards
import type { FileRejection, MachineContext, MachineState, UserDefinedContext } from "./file-upload.types"
import { getFilesFromEvent } from "./file-upload.utils"

export function machine(userContext: UserDefinedContext) {
const ctx = compact(userContext)
Expand All @@ -22,8 +20,8 @@ export function machine(userContext: UserDefinedContext) {
...ctx,
acceptedFiles: ref([]),
rejectedFiles: ref([]),
invalid: false,
translations: {
dropzone: "dropzone",
itemPreview: (file) => `preview of ${file.name}`,
deleteFile: (file) => `delete file ${file.name}`,
...ctx.translations,
Expand Down Expand Up @@ -57,14 +55,9 @@ export function machine(userContext: UserDefinedContext) {
actions: ["openFilePicker"],
},
"DROPZONE.FOCUS": "focused",
"DROPZONE.DRAG_OVER": [
{
guard: not("isWithinRange"),
target: "dragging",
actions: ["setInvalid"],
},
{ target: "dragging" },
],
"DROPZONE.DRAG_OVER": {
target: "dragging",
},
},
},
focused: {
Expand All @@ -76,34 +69,25 @@ export function machine(userContext: UserDefinedContext) {
"DROPZONE.CLICK": {
actions: ["openFilePicker"],
},
"DROPZONE.DRAG_OVER": [
{
guard: not("isWithinRange"),
target: "dragging",
actions: ["setInvalid"],
},
{ target: "dragging" },
],
"DROPZONE.DRAG_OVER": {
target: "dragging",
},
},
},
dragging: {
on: {
"DROPZONE.DROP": {
target: "idle",
actions: ["clearInvalid", "setFilesFromEvent", "syncInputElement"],
actions: ["setFilesFromEvent", "syncInputElement"],
},
"DROPZONE.DRAG_LEAVE": {
target: "idle",
actions: ["clearInvalid"],
},
},
},
},
},
{
guards: {
isWithinRange: (ctx, evt) => isFilesWithinRange(ctx, evt.count),
},
actions: {
syncInputElement(ctx) {
const inputEl = dom.getHiddenInputEl(ctx)
Expand All @@ -123,12 +107,6 @@ export function machine(userContext: UserDefinedContext) {
dom.getHiddenInputEl(ctx)?.click()
})
},
setInvalid(ctx) {
ctx.invalid = true
},
clearInvalid(ctx) {
ctx.invalid = false
},
setFilesFromEvent(ctx, evt) {
const result = getFilesFromEvent(ctx, evt.files)
const { acceptedFiles, rejectedFiles } = result
Expand Down
1 change: 1 addition & 0 deletions packages/machines/file-upload/src/file-upload.props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export const props = createProps<UserDefinedContext>()([
"maxFileSize",
"minFileSize",
"name",
"invalid",
"onFileAccept",
"onFileReject",
"onFileChange",
Expand Down
14 changes: 7 additions & 7 deletions packages/machines/file-upload/src/file-upload.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,9 @@ export type ElementIds = Partial<{
}>

export interface IntlTranslations {
itemPreview(file: File): string
deleteFile(file: File): string
dropzone?: string
itemPreview?(file: File): string
deleteFile?(file: File): string
}

interface PublicContext extends LocaleProperties, CommonProperties {
Expand Down Expand Up @@ -118,14 +119,13 @@ interface PublicContext extends LocaleProperties, CommonProperties {
* Whether to accept directories, only works in webkit browsers
*/
directory?: boolean
/**
* Whether the file input is invalid
*/
invalid?: boolean
}

interface PrivateContext {
/**
* @internal
* Whether the files includes any rejection
*/
invalid: boolean
/**
* @internal
* The rejected files
Expand Down

0 comments on commit 4c1923e

Please sign in to comment.