@oslokommune/punkt-react 15.0.4 → 15.2.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 CHANGED
@@ -5,6 +5,55 @@ og skriver commits ca etter [Conventional Commits](https://conventionalcommits.o
5
5
 
6
6
  ---
7
7
 
8
+ ## [15.2.0](https://github.com/oslokommune/punkt/compare/15.1.0...15.2.0) (2026-02-18)
9
+
10
+ ### ⚠ BREAKING CHANGES
11
+ Ingen
12
+
13
+ ### Features
14
+ * Fix ios-readonly-bug for DatePicker border (#3259).
15
+
16
+
17
+ ### Bug Fixes
18
+ Ingen
19
+
20
+ ### Chores
21
+ Ingen
22
+
23
+ ---
24
+
25
+
26
+ ## [15.1.0](https://github.com/oslokommune/punkt/compare/15.0.4...15.1.0) (2026-02-16)
27
+
28
+ ### ⚠ BREAKING CHANGES
29
+ Ingen
30
+
31
+ ### Features
32
+ * Fileupload (#3115). * add stateless controlled FileUpload with form/custom upload modes
33
+ * Controlled API (value + onFilesChanged) with generated file IDs (FileItemList)
34
+ * Drag & drop + file dialog, single/multiple selection
35
+ * form submit or custom immediate upload via onFileUploadRequested + hidden ID inputs
36
+ * Queue display with remove/rename/comment extensions + custom item renderer (incl. thumbnail + preview modal)
37
+ * responsive fileupload
38
+ * Built-in validation (format + max size + custom hook) and accessible status/error announcements
39
+ * add docs
40
+ * style FU according to Figma design
41
+ * re-usable `PreviewCodeTabs example`
42
+ ------
43
+ Co-authored-by: Vidar Ramdal <vramdal@gmail.com>
44
+ Co-authored-by: Jan Schjetne <jan.schjetne@origo.oslo.kommune.no>
45
+ Co-authored-by: miichu <mythng94@gmail.com@gmail.com>
46
+
47
+
48
+ ### Bug Fixes
49
+ Ingen
50
+
51
+ ### Chores
52
+ Ingen
53
+
54
+ ---
55
+
56
+
8
57
  ## [15.0.3](https://github.com/oslokommune/punkt/compare/15.0.2...15.0.3) (2026-02-13)
9
58
 
10
59
  ### ⚠ 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;