@oslokommune/punkt-react 15.0.3 → 15.1.0
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/CHANGELOG.md +31 -0
- package/dist/index.d.ts +173 -0
- package/dist/punkt-react.es.js +8216 -7134
- package/dist/punkt-react.umd.js +435 -435
- package/package.json +4 -4
- package/src/components/fileupload/DropZone.tsx +236 -0
- package/src/components/fileupload/FileUpload.test.tsx +584 -0
- package/src/components/fileupload/FileUpload.tsx +425 -0
- package/src/components/fileupload/QueueDisplay.test.tsx +222 -0
- package/src/components/fileupload/QueueDisplay.tsx +155 -0
- package/src/components/fileupload/QueueItemContent.tsx +200 -0
- package/src/components/fileupload/Subcomponents.tsx +363 -0
- package/src/components/fileupload/Truncate.test.tsx +256 -0
- package/src/components/fileupload/Truncate.tsx +137 -0
- package/src/components/fileupload/extensions/Comments.tsx +188 -0
- package/src/components/fileupload/extensions/Remove.tsx +10 -0
- package/src/components/fileupload/extensions/Rename.tsx +79 -0
- package/src/components/fileupload/hooks/index.ts +3 -0
- package/src/components/fileupload/hooks/useFileAttributes.ts +46 -0
- package/src/components/fileupload/hooks/useImagePreview.ts +42 -0
- package/src/components/fileupload/hooks/useOperationState.ts +30 -0
- package/src/components/fileupload/hooks.ts +4 -0
- package/src/components/fileupload/texts.ts +20 -0
- package/src/components/fileupload/types.ts +94 -0
- package/src/components/fileupload/utils.ts +56 -0
- package/src/components/index.ts +1 -0
- package/src/components/interfaces.ts +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,37 @@ og skriver commits ca etter [Conventional Commits](https://conventionalcommits.o
|
|
|
5
5
|
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
+
## [15.1.0](https://github.com/oslokommune/punkt/compare/15.0.4...15.1.0) (2026-02-16)
|
|
9
|
+
|
|
10
|
+
### ⚠ BREAKING CHANGES
|
|
11
|
+
Ingen
|
|
12
|
+
|
|
13
|
+
### Features
|
|
14
|
+
* Fileupload (#3115). * add stateless controlled FileUpload with form/custom upload modes
|
|
15
|
+
* Controlled API (value + onFilesChanged) with generated file IDs (FileItemList)
|
|
16
|
+
* Drag & drop + file dialog, single/multiple selection
|
|
17
|
+
* form submit or custom immediate upload via onFileUploadRequested + hidden ID inputs
|
|
18
|
+
* Queue display with remove/rename/comment extensions + custom item renderer (incl. thumbnail + preview modal)
|
|
19
|
+
* responsive fileupload
|
|
20
|
+
* Built-in validation (format + max size + custom hook) and accessible status/error announcements
|
|
21
|
+
* add docs
|
|
22
|
+
* style FU according to Figma design
|
|
23
|
+
* re-usable `PreviewCodeTabs example`
|
|
24
|
+
------
|
|
25
|
+
Co-authored-by: Vidar Ramdal <vramdal@gmail.com>
|
|
26
|
+
Co-authored-by: Jan Schjetne <jan.schjetne@origo.oslo.kommune.no>
|
|
27
|
+
Co-authored-by: miichu <mythng94@gmail.com@gmail.com>
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
### Bug Fixes
|
|
31
|
+
Ingen
|
|
32
|
+
|
|
33
|
+
### Chores
|
|
34
|
+
Ingen
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
|
|
8
39
|
## [15.0.3](https://github.com/oslokommune/punkt/compare/15.0.2...15.0.3) (2026-02-13)
|
|
9
40
|
|
|
10
41
|
### ⚠ BREAKING CHANGES
|
package/dist/index.d.ts
CHANGED
|
@@ -73,11 +73,111 @@ declare type ExtendedLoader = IPktLoader_2 & PktElType;
|
|
|
73
73
|
|
|
74
74
|
declare type ExtendedProgressbar = IPktProgressbar_2 & PktElType;
|
|
75
75
|
|
|
76
|
+
/**
|
|
77
|
+
* A selected file plus metadata used by the FileUpload UI.
|
|
78
|
+
*
|
|
79
|
+
* Notes:
|
|
80
|
+
* - A `fileId` is generated automatically if omitted.
|
|
81
|
+
* - `attributes.targetFilename` is the filename shown in the queue and may be updated by extensions (e.g. rename).
|
|
82
|
+
*/
|
|
83
|
+
declare class FileItem implements FileItem {
|
|
84
|
+
fileId: TFileId;
|
|
85
|
+
file: File;
|
|
86
|
+
attributes: Record<string, any>;
|
|
87
|
+
constructor(file: File, fileId?: TFileId);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Shared props for `PktFileUpload` (both `form` and `custom` strategies).
|
|
92
|
+
*
|
|
93
|
+
* The component can be used as:
|
|
94
|
+
* - **controlled**: pass `value` + `onFilesChanged`
|
|
95
|
+
* - **uncontrolled**: pass `defaultValue` (internal state is not stored; you still receive new lists via callbacks)
|
|
96
|
+
*/
|
|
97
|
+
declare interface IBaseFileUploadProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'checked' | 'size' | 'type' | 'value' | 'onChange' | 'width' | 'defaultValue'> {
|
|
98
|
+
/** Called with the next file list when files are added/removed/updated. */
|
|
99
|
+
onFilesChanged?: (files: TFileItemList) => void;
|
|
100
|
+
/** Allow selecting/dropping multiple files. */
|
|
101
|
+
multiple?: boolean;
|
|
102
|
+
/** Controlled value (recommended). */
|
|
103
|
+
value?: TFileItemList;
|
|
104
|
+
/** Upload mode. Defaults to `"form"`. */
|
|
105
|
+
uploadStrategy?: TUploadStrategy;
|
|
106
|
+
/** Field name. Used for native input (`form`) or hidden ID inputs (`custom`). */
|
|
107
|
+
name: string;
|
|
108
|
+
/** Enable comment operation (disabled automatically in thumbnail view). */
|
|
109
|
+
addCommentsEnabled?: boolean;
|
|
110
|
+
/** Enable rename operation (disabled automatically in thumbnail view). */
|
|
111
|
+
renameFilesEnabled?: boolean;
|
|
112
|
+
/** Renderer for queue items (`filename`, `thumbnail`, or custom function). */
|
|
113
|
+
itemRenderer?: keyof typeof ItemRenderers | TItemRenderer;
|
|
114
|
+
/** Number of trailing characters to keep when truncating long filenames. */
|
|
115
|
+
truncateTail?: number;
|
|
116
|
+
/**
|
|
117
|
+
* Called immediately when a file is added in `uploadStrategy="custom"`.
|
|
118
|
+
* Use it to start uploading the file and update `transfers`.
|
|
119
|
+
*/
|
|
120
|
+
onFileUploadRequested?: (fileItem: FileItem) => void;
|
|
121
|
+
/** Uncontrolled initial value (use either `value` or `defaultValue`, not both). */
|
|
122
|
+
defaultValue?: TFileItemList;
|
|
123
|
+
/** Extra operations appended after built-ins (rename/comment). */
|
|
124
|
+
extraOperations?: Array<TQueueItemExtension>;
|
|
125
|
+
/** Stretch to full container width (drop zone + queue). */
|
|
126
|
+
fullWidth?: boolean;
|
|
127
|
+
/** Allowed formats for built-in validation (extensions like `pdf`, or MIME patterns like `image/*`). */
|
|
128
|
+
allowedFormats?: string[];
|
|
129
|
+
/** Custom message for invalid format. Use `{formats}` placeholder. */
|
|
130
|
+
formatErrorMessage?: string;
|
|
131
|
+
/** Max file size (e.g. `"5MB"` or bytes). */
|
|
132
|
+
maxFileSize?: string | number;
|
|
133
|
+
/** Custom message for size validation. Use `{maxSize}` placeholder. */
|
|
134
|
+
sizeErrorMessage?: string;
|
|
135
|
+
/** Optional additional validation hook (runs after built-in format/size checks). Return string to block. */
|
|
136
|
+
onFileValidation?: (file: File) => string | null;
|
|
137
|
+
/** External/programmatic error message shown under the component. */
|
|
138
|
+
errorMessage?: string;
|
|
139
|
+
/** External error flag (combined with internal validation errors). */
|
|
140
|
+
hasError?: boolean;
|
|
141
|
+
/** Disable the whole component (no interaction). */
|
|
142
|
+
disabled?: boolean;
|
|
143
|
+
/** Optional label/title (wraps the component in `PktInputWrapper`). */
|
|
144
|
+
label?: string;
|
|
145
|
+
/** Help text under the label. */
|
|
146
|
+
helptext?: string | ReactNode;
|
|
147
|
+
/** Show "Valgfritt" tag in wrapper. */
|
|
148
|
+
optionalTag?: boolean;
|
|
149
|
+
/** Show "Må fylles ut" tag in wrapper. */
|
|
150
|
+
requiredTag?: boolean;
|
|
151
|
+
/** Enable image preview modal (only applies to thumbnail renderer). */
|
|
152
|
+
enableImagePreview?: boolean;
|
|
153
|
+
}
|
|
154
|
+
|
|
76
155
|
declare interface IBreadcrumbs {
|
|
77
156
|
text: string;
|
|
78
157
|
href: string;
|
|
79
158
|
}
|
|
80
159
|
|
|
160
|
+
/** Props for `uploadStrategy="form"` (native file input submission). */
|
|
161
|
+
declare interface IFileInputFileUploadProps extends IBaseFileUploadProps, Omit<HTMLAttributes<HTMLInputElement>, 'value' | 'onChange' | 'defaultValue'> {
|
|
162
|
+
uploadStrategy?: 'form';
|
|
163
|
+
onFileUploadRequested?: never;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Props for `uploadStrategy="custom"` (upload handled externally).
|
|
168
|
+
*
|
|
169
|
+
* Requirements:
|
|
170
|
+
* - `transfers` must be provided (to render status/progress)
|
|
171
|
+
* - `onFileUploadRequested` is called for each added file
|
|
172
|
+
*/
|
|
173
|
+
declare interface ImmediateFileUploadProps extends IBaseFileUploadProps {
|
|
174
|
+
id: string;
|
|
175
|
+
uploadStrategy: 'custom';
|
|
176
|
+
transfers: Array<TFileTransfer>;
|
|
177
|
+
onFileUploadRequested: (fileItem: FileItem) => void;
|
|
178
|
+
onTransferCancelled?: (fileItemId: string) => void;
|
|
179
|
+
}
|
|
180
|
+
|
|
81
181
|
declare interface InputProps extends InputHTMLAttributes<HTMLInputElement> {
|
|
82
182
|
/** The input's label */
|
|
83
183
|
label?: string;
|
|
@@ -293,6 +393,8 @@ export declare interface IPktDatepicker extends Omit<InputHTMLAttributes<HTMLInp
|
|
|
293
393
|
className?: string;
|
|
294
394
|
}
|
|
295
395
|
|
|
396
|
+
export declare type IPktFileUpload = IFileInputFileUploadProps | ImmediateFileUploadProps;
|
|
397
|
+
|
|
296
398
|
export declare interface IPktFooter extends HTMLAttributes<HTMLDivElement> {
|
|
297
399
|
columnOne: Column;
|
|
298
400
|
columnTwo: Column;
|
|
@@ -755,6 +857,8 @@ declare interface ITableRowProps extends HTMLAttributes<HTMLTableRowElement> {
|
|
|
755
857
|
children: ReactNode;
|
|
756
858
|
}
|
|
757
859
|
|
|
860
|
+
declare const ItemRenderers: Record<string, TItemRenderer>;
|
|
861
|
+
|
|
758
862
|
declare interface Link {
|
|
759
863
|
href: string;
|
|
760
864
|
text: string;
|
|
@@ -803,6 +907,8 @@ declare interface PktElType extends HTMLAttributes<HTMLElement> {
|
|
|
803
907
|
id?: string;
|
|
804
908
|
}
|
|
805
909
|
|
|
910
|
+
export declare const PktFileUpload: FC<IPktFileUpload>;
|
|
911
|
+
|
|
806
912
|
export declare const PktFooter: FC<IPktFooter>;
|
|
807
913
|
|
|
808
914
|
export declare const PktFooterSimple: FC<IPktFooterSimple>;
|
|
@@ -926,16 +1032,83 @@ declare type TCardPadding = 'none' | 'default';
|
|
|
926
1032
|
|
|
927
1033
|
declare type TCardTagPosition = 'top' | 'bottom';
|
|
928
1034
|
|
|
1035
|
+
declare type TFileAndTransfer = FileItem & Pick<TFileTransfer, 'progress' | 'errorMessage' | 'showProgress' | 'lastProgress'>;
|
|
1036
|
+
|
|
1037
|
+
declare type TFileAttribute<T> = {
|
|
1038
|
+
get: (fileId: TFileId) => T | undefined;
|
|
1039
|
+
set: (fileId: TFileId, attributeValue: T | undefined) => void;
|
|
1040
|
+
};
|
|
1041
|
+
|
|
1042
|
+
declare type TFileAttributes = <T>(attributeName: string) => TFileAttribute<T>;
|
|
1043
|
+
|
|
1044
|
+
/** Unique identifier assigned to each selected file. */
|
|
1045
|
+
declare type TFileId = string;
|
|
1046
|
+
|
|
1047
|
+
/** The value type for `PktFileUpload` (`value` / `defaultValue`). */
|
|
1048
|
+
declare type TFileItemList = Array<FileItem>;
|
|
1049
|
+
|
|
1050
|
+
/**
|
|
1051
|
+
* Transfer status for a file when using `uploadStrategy="custom"`.
|
|
1052
|
+
*
|
|
1053
|
+
* - `progress`: `0..1` during upload, or a state (`queued`, `done`, `error`, `canceled`)
|
|
1054
|
+
* - `showProgress`: if false, UI uses indeterminate "Laster opp..." style instead of progress bar
|
|
1055
|
+
* - `lastProgress`: used to render a "failed at X%" bar when an upload errors
|
|
1056
|
+
*/
|
|
1057
|
+
declare type TFileTransfer = {
|
|
1058
|
+
fileId: TFileId;
|
|
1059
|
+
progress: number | 'done' | 'error' | 'canceled' | 'queued';
|
|
1060
|
+
errorMessage?: string;
|
|
1061
|
+
showProgress?: boolean;
|
|
1062
|
+
lastProgress?: number;
|
|
1063
|
+
};
|
|
1064
|
+
|
|
1065
|
+
/**
|
|
1066
|
+
* Custom renderer for how a queue item is displayed (e.g. filename vs thumbnail grid).
|
|
1067
|
+
*
|
|
1068
|
+
* Must return a renderable React element (or `null`).
|
|
1069
|
+
*/
|
|
1070
|
+
declare type TItemRenderer = (props: {
|
|
1071
|
+
transferItem: TFileAndTransfer;
|
|
1072
|
+
queueItemOperations: Array<TQueueItemOperation>;
|
|
1073
|
+
onPreviewClick?: () => void;
|
|
1074
|
+
}) => ReactElement | null;
|
|
1075
|
+
|
|
929
1076
|
declare type TPktAccordionSkin = TAccordionSkin;
|
|
930
1077
|
|
|
931
1078
|
declare type TPktAccordionSkin_2 = TAccordionSkin;
|
|
932
1079
|
|
|
1080
|
+
/** Factory that produces a queue item operation given access to file attributes. */
|
|
1081
|
+
declare type TQueueItemExtension = (attributes: TFileAttributes) => TQueueItemOperation;
|
|
1082
|
+
|
|
1083
|
+
/**
|
|
1084
|
+
* An operation that can be attached to a queue item (rename, comment, remove, etc).
|
|
1085
|
+
*
|
|
1086
|
+
* An operation may:
|
|
1087
|
+
* - be a simple action (`onClick`)
|
|
1088
|
+
* - render inline UI (e.g. rename)
|
|
1089
|
+
* - render extended UI (e.g. comments)
|
|
1090
|
+
* - render hidden inputs for form submission (`renderHidden`)
|
|
1091
|
+
*/
|
|
1092
|
+
declare type TQueueItemOperation = {
|
|
1093
|
+
title: string | ((fileItem: FileItem) => string);
|
|
1094
|
+
ariaLabel?: string | ((fileItem: FileItem) => string);
|
|
1095
|
+
onClick?: (transferItem: FileItem) => void;
|
|
1096
|
+
renderInlineUI?: (fileItem: FileItem, closeOperationUi: () => void) => ReactNode;
|
|
1097
|
+
renderExtendedUI?: (fileItem: FileItem, closeOperationUi: () => void) => ReactNode;
|
|
1098
|
+
renderContent?: (fileItem: FileItem, activateOperation?: () => void, isOperationActive?: boolean) => ReactNode;
|
|
1099
|
+
renderHidden?: (fileItem: FileItem) => ReactNode;
|
|
1100
|
+
symbol: symbol;
|
|
1101
|
+
};
|
|
1102
|
+
|
|
933
1103
|
declare type TSkin = 'blue' | 'green' | 'red' | 'beige' | 'yellow' | 'grey' | 'gray' | 'blue-light';
|
|
934
1104
|
|
|
935
1105
|
declare type TSkin_2 = IPktTag['skin'];
|
|
936
1106
|
|
|
937
1107
|
declare type TStepStatus = 'completed' | 'incomplete' | 'current';
|
|
938
1108
|
|
|
1109
|
+
/** Upload mode: `form` posts the files on submit, `custom` posts file IDs and uploads separately. */
|
|
1110
|
+
declare type TUploadStrategy = 'custom' | 'form';
|
|
1111
|
+
|
|
939
1112
|
/** User object for header components */
|
|
940
1113
|
declare interface User {
|
|
941
1114
|
name: string;
|