@freightos/freightwind 2.1.3 → 2.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/components/upload.js +321 -0
- package/dist/cjs/index.js +5 -1
- package/dist/cjs/lib/file-extensions.js +678 -0
- package/dist/esm/components/upload.js +318 -0
- package/dist/esm/index.js +2 -0
- package/dist/esm/lib/file-extensions.js +671 -0
- package/dist/types/components/chip.d.ts +1 -1
- package/dist/types/components/upload.d.ts +66 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/lib/file-extensions.d.ts +52 -0
- package/package.json +3 -1
|
@@ -10,7 +10,7 @@ export interface ChipProps {
|
|
|
10
10
|
children?: string;
|
|
11
11
|
}
|
|
12
12
|
declare const chipVariants: (props?: ({
|
|
13
|
-
variant?: "default" | "
|
|
13
|
+
variant?: "default" | "success" | "error" | "info" | "warning" | "neutral" | "highlight" | "notice" | null | undefined;
|
|
14
14
|
} & import("class-variance-authority/dist/types").ClassProp) | undefined) => string;
|
|
15
15
|
declare function Chip({ variant, icon, closable, onClose, badge, children, }: ChipProps): import("react/jsx-runtime").JSX.Element | null;
|
|
16
16
|
export { Chip, chipVariants };
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { type HTMLAttributes } from 'react';
|
|
2
|
+
import { type VariantProps } from 'class-variance-authority';
|
|
3
|
+
export type UploadVariant = 'rectangle' | 'square';
|
|
4
|
+
export type ForbiddenReason = 'multiple' | 'type' | 'size' | 'extension' | 'custom';
|
|
5
|
+
export type UploadFile = File | {
|
|
6
|
+
name: string;
|
|
7
|
+
};
|
|
8
|
+
export type UploadTranslator = (key: string) => string;
|
|
9
|
+
declare const uploadVariants: (props?: ({
|
|
10
|
+
variant?: "square" | "rectangle" | null | undefined;
|
|
11
|
+
state?: "default" | "disabled" | "forbidden" | "uploading" | "uploading-spinner" | "success" | "error" | null | undefined;
|
|
12
|
+
} & import("class-variance-authority/dist/types").ClassProp) | undefined) => string;
|
|
13
|
+
export interface UploadProps extends Omit<HTMLAttributes<HTMLLabelElement>, 'onChange'>, VariantProps<typeof uploadVariants> {
|
|
14
|
+
/** Test automation identifier. Rendered as `data-test-id` on the root and propagated to inner DOM nodes. */
|
|
15
|
+
dataTestId: string;
|
|
16
|
+
/** Layout variant. */
|
|
17
|
+
variant?: UploadVariant;
|
|
18
|
+
/** Single associated file (controlled). Pass `{ name: string }` for SSR display-only previews. */
|
|
19
|
+
value?: UploadFile | null;
|
|
20
|
+
/** Multiple associated files (controlled). Overrides `value` when provided. */
|
|
21
|
+
files?: UploadFile[];
|
|
22
|
+
/** Max number of files allowed. Omit or set to 1 for single-file mode. Exceeding this → forbidden. */
|
|
23
|
+
maxFiles?: number;
|
|
24
|
+
/** MIME types / extensions accepted. Pass an array, e.g. `['application/pdf', '.png']`. */
|
|
25
|
+
accept?: string[];
|
|
26
|
+
/** Max bytes per file. Exceeding this → forbidden. */
|
|
27
|
+
maxSize?: number;
|
|
28
|
+
/** Drives the error visual state (red frame + red icon). */
|
|
29
|
+
isError?: boolean;
|
|
30
|
+
/** Disables the surface (gray border, no interaction, no remove allowed). */
|
|
31
|
+
isDisabled?: boolean;
|
|
32
|
+
/** Stretch the surface to fill its parent's width and height. */
|
|
33
|
+
isFillContainer?: boolean;
|
|
34
|
+
/** Override copy per state. Pass any subset; falls back to defaults. */
|
|
35
|
+
labels?: Partial<{
|
|
36
|
+
idleTitle: string;
|
|
37
|
+
idleSubtitle: string;
|
|
38
|
+
idleCompact: string;
|
|
39
|
+
uploading: string;
|
|
40
|
+
forbidden: Partial<Record<ForbiddenReason, {
|
|
41
|
+
title: string;
|
|
42
|
+
subtitle: string;
|
|
43
|
+
compact?: string;
|
|
44
|
+
}>>;
|
|
45
|
+
}>;
|
|
46
|
+
/** Optional translation function for all built-in copy. Defaults to identity. */
|
|
47
|
+
t?: UploadTranslator;
|
|
48
|
+
/** Fires when one or more files are selected or dropped. The component flips to `uploading` after this fires; call `setIsUploading(false)` when your async upload completes. Pass an optional `progress` value (0–1) to drive the determinate progress bar; omit it for the indeterminate animation. */
|
|
49
|
+
onUpload?: (files: File[], setIsUploading: (v: boolean, progress?: number) => void) => void;
|
|
50
|
+
/** Fires when the trash button is clicked. Removes ALL files. */
|
|
51
|
+
onRemove?: () => void;
|
|
52
|
+
/** Fires when an invalid drag/drop is detected. */
|
|
53
|
+
onForbidden?: (reason: ForbiddenReason) => void;
|
|
54
|
+
/** A11y label override for the surface. */
|
|
55
|
+
ariaLabel?: string;
|
|
56
|
+
/** Seed the internal uploading state on mount. Useful for static demos and Storybook. */
|
|
57
|
+
defaultUploading?: boolean;
|
|
58
|
+
/** Seed the initial progress value (0–1) when defaultUploading is true. Disables the indeterminate animation and shows a static determinate bar. */
|
|
59
|
+
defaultUploadProgress?: number;
|
|
60
|
+
/** Seed the forbidden state on mount with a specific reason. Useful for static demos and Storybook. */
|
|
61
|
+
defaultForbidden?: ForbiddenReason;
|
|
62
|
+
/** Controls the uploading display: 'progress' = text + progress bar (default); 'spinner' = 32×32 spinner only (no text — enforced for square too). */
|
|
63
|
+
uploadingStyle?: 'progress' | 'spinner';
|
|
64
|
+
}
|
|
65
|
+
export declare const Upload: import("react").ForwardRefExoticComponent<UploadProps & import("react").RefAttributes<HTMLLabelElement>>;
|
|
66
|
+
export { uploadVariants };
|
package/dist/types/index.d.ts
CHANGED
|
@@ -2,3 +2,5 @@ export { cn } from './lib/utils';
|
|
|
2
2
|
export { useStableId } from './lib/use-stable-id';
|
|
3
3
|
export { iconMap, renderInputIcon } from './lib/icon-utils';
|
|
4
4
|
export type { IconName, InputShellSize } from './lib/icon-utils';
|
|
5
|
+
export { Upload, uploadVariants } from './components/upload';
|
|
6
|
+
export type { UploadProps, UploadVariant, UploadFile, ForbiddenReason, UploadTranslator } from './components/upload';
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MIME-type → extensions map sourced from the IANA / Apache / Nginx MIME database
|
|
3
|
+
* (https://github.com/jshttp/mime-db). Keys are canonical MIME types
|
|
4
|
+
* (e.g. `image/aces`); values are the extensions that legitimately produce that
|
|
5
|
+
* type, without a leading dot and in lowercase.
|
|
6
|
+
*
|
|
7
|
+
* Used to validate uploaded files: reject when the browser-reported `File.type`
|
|
8
|
+
* is unknown, **and** cross-check that the filename's extension matches the set
|
|
9
|
+
* registered for that type. This catches "extension spoofing" — e.g. a `.exe`
|
|
10
|
+
* renamed to `.jpg` will report `application/x-msdownload` (or empty), which
|
|
11
|
+
* does not list `jpg`, so it fails validation.
|
|
12
|
+
*/
|
|
13
|
+
export declare const VALID_MIME_TYPES: Readonly<Record<string, readonly string[]>>;
|
|
14
|
+
/**
|
|
15
|
+
* Flat set of every extension known to {@link VALID_MIME_TYPES}, used by the
|
|
16
|
+
* extension-only fast path ({@link hasValidExtension}). Derived once at module
|
|
17
|
+
* load — kept in sync with the map automatically.
|
|
18
|
+
*/
|
|
19
|
+
export declare const VALID_FILE_EXTENSIONS: ReadonlySet<string>;
|
|
20
|
+
/**
|
|
21
|
+
* Normalize a filename or raw extension to a lowercase no-dot extension token.
|
|
22
|
+
* Returns null if no extension is present.
|
|
23
|
+
*/
|
|
24
|
+
export declare function normalizeExtension(input: string): string | null;
|
|
25
|
+
/**
|
|
26
|
+
* Returns true when the given filename ends in a recognized extension.
|
|
27
|
+
* Files with no extension, or extensions that aren't in {@link VALID_FILE_EXTENSIONS},
|
|
28
|
+
* are rejected as "fake" / nonsense.
|
|
29
|
+
*
|
|
30
|
+
* Prefer {@link validateFileType} when a `File` object is available — it catches
|
|
31
|
+
* extension spoofing that this function cannot.
|
|
32
|
+
*/
|
|
33
|
+
export declare function hasValidExtension(filename: string): boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Strict file validation: the browser-reported MIME type must be known, AND the
|
|
36
|
+
* filename's extension must be one of the extensions registered for that type.
|
|
37
|
+
*
|
|
38
|
+
* Rejects:
|
|
39
|
+
* - files with no extension
|
|
40
|
+
* - files whose `type` is empty or unknown to {@link VALID_MIME_TYPES}
|
|
41
|
+
* - files whose extension does not match the registered list for `file.type`
|
|
42
|
+
* (extension-spoofing guard, e.g. `.exe` renamed to `.jpg`)
|
|
43
|
+
*
|
|
44
|
+
* `file.type` comparison is case-insensitive; some browsers lowercase but a few
|
|
45
|
+
* legacy ones don't.
|
|
46
|
+
*/
|
|
47
|
+
export declare function validateFileType(file: File): boolean;
|
|
48
|
+
/**
|
|
49
|
+
* Look up every MIME type that legitimately produces the given extension.
|
|
50
|
+
* Useful for `accept`-attribute construction or reverse diagnostics.
|
|
51
|
+
*/
|
|
52
|
+
export declare function getMimeTypesForExtension(extension: string): readonly string[];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@freightos/freightwind",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.4",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "FreightWind Design System — icons, constants, and utilities for Freightos applications",
|
|
6
6
|
"main": "./dist/cjs/index.js",
|
|
@@ -96,6 +96,8 @@
|
|
|
96
96
|
}
|
|
97
97
|
},
|
|
98
98
|
"dependencies": {
|
|
99
|
+
"@radix-ui/react-direction": "^1.1.0",
|
|
100
|
+
"class-variance-authority": "^0.7.1",
|
|
99
101
|
"clsx": "^2.1.1",
|
|
100
102
|
"tailwind-merge": "^3.4.0"
|
|
101
103
|
}
|