@carlonicora/nextjs-jsonapi 3.5.7 → 3.5.9
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/{BlockNoteEditor-PZ5HOXFK.mjs → BlockNoteEditor-5AQQQQY3.mjs} +2 -2
- package/dist/{BlockNoteEditor-JSZ2YZVY.js → BlockNoteEditor-EWMWY4SK.js} +9 -9
- package/dist/{BlockNoteEditor-JSZ2YZVY.js.map → BlockNoteEditor-EWMWY4SK.js.map} +1 -1
- package/dist/billing/index.js +333 -333
- package/dist/billing/index.mjs +1 -1
- package/dist/{chunk-N73QMKQU.js → chunk-EJIWXCXI.js} +319 -213
- package/dist/chunk-EJIWXCXI.js.map +1 -0
- package/dist/{chunk-C7I6YFTA.mjs → chunk-OE2WEAPU.mjs} +126 -20
- package/dist/chunk-OE2WEAPU.mjs.map +1 -0
- package/dist/client/index.js +2 -2
- package/dist/client/index.mjs +1 -1
- package/dist/components/index.d.mts +21 -1
- package/dist/components/index.d.ts +21 -1
- package/dist/components/index.js +4 -2
- package/dist/components/index.js.map +1 -1
- package/dist/components/index.mjs +3 -1
- package/dist/contexts/index.js +2 -2
- package/dist/contexts/index.mjs +1 -1
- package/dist/features/help/index.js +31 -31
- package/dist/features/help/index.mjs +1 -1
- package/dist/features/tokenusage/index.js +75 -75
- package/dist/features/tokenusage/index.mjs +1 -1
- package/package.json +1 -1
- package/src/components/forms/EditorSheet.tsx +44 -22
- package/src/components/forms/FileUploader.tsx +18 -2
- package/src/components/forms/MultiFileUploader.tsx +23 -5
- package/src/components/forms/index.ts +1 -1
- package/dist/chunk-C7I6YFTA.mjs.map +0 -1
- package/dist/chunk-N73QMKQU.js.map +0 -1
- /package/dist/{BlockNoteEditor-PZ5HOXFK.mjs.map → BlockNoteEditor-5AQQQQY3.mjs.map} +0 -0
|
@@ -65,12 +65,23 @@ function resolveTriggerIsNativeButton(trigger: ReactNode): boolean {
|
|
|
65
65
|
* base `data-[side=left]:sm:max-w-sm`.
|
|
66
66
|
*/
|
|
67
67
|
// rtl-ok: keyed to the resolved physical side, not to a writing direction
|
|
68
|
+
/**
|
|
69
|
+
* On a phone an editor IS the page. SheetContent's base is `w-3/4`, which
|
|
70
|
+
* leaves a dead 25% strip of the page showing behind the form and squeezes
|
|
71
|
+
* every field — so each size takes the full width and hands over to its
|
|
72
|
+
* `sm:max-w-*` cap from the `sm` breakpoint up. Same width utility and same
|
|
73
|
+
* variant as the base, so `cn`'s tailwind-merge replaces it rather than
|
|
74
|
+
* fighting it on specificity.
|
|
75
|
+
*/
|
|
76
|
+
// rtl-ok: keyed to the resolved physical side, not to a writing direction
|
|
77
|
+
const fullWidthOnMobile = "data-[side=right]:w-full data-[side=left]:w-full";
|
|
78
|
+
|
|
68
79
|
const sizeClasses: Record<EditorSheetSize, string> = {
|
|
69
|
-
sm:
|
|
70
|
-
md:
|
|
71
|
-
lg:
|
|
72
|
-
xl:
|
|
73
|
-
"2xl":
|
|
80
|
+
sm: `${fullWidthOnMobile} data-[side=right]:sm:max-w-2xl data-[side=left]:sm:max-w-2xl`,
|
|
81
|
+
md: `${fullWidthOnMobile} data-[side=right]:sm:max-w-3xl data-[side=left]:sm:max-w-3xl`,
|
|
82
|
+
lg: `${fullWidthOnMobile} data-[side=right]:sm:max-w-5xl data-[side=left]:sm:max-w-5xl`,
|
|
83
|
+
xl: `${fullWidthOnMobile} data-[side=right]:sm:max-w-7xl data-[side=left]:sm:max-w-7xl`,
|
|
84
|
+
"2xl": `${fullWidthOnMobile} data-[side=right]:sm:!max-w-[min(96rem,90vw)] data-[side=left]:sm:!max-w-[min(96rem,90vw)]`,
|
|
74
85
|
};
|
|
75
86
|
|
|
76
87
|
export type EditorSheetProps<T extends FieldValues> = {
|
|
@@ -261,23 +272,34 @@ export function EditorSheet<T extends FieldValues>({
|
|
|
261
272
|
// warned on every native-button trigger).
|
|
262
273
|
<SheetTrigger nativeButton={resolveTriggerIsNativeButton(trigger)} render={trigger as ReactElement} />
|
|
263
274
|
) : (
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
275
|
+
// The default trigger goes through `render` for the SAME reason the
|
|
276
|
+
// caller-supplied one above does. As CHILDREN, the Button rendered a
|
|
277
|
+
// second `role="button"` inside SheetTrigger's own button: two nodes
|
|
278
|
+
// with one accessible name, which a screen reader announces as a
|
|
279
|
+
// button inside a button and which makes
|
|
280
|
+
// `getByRole("button", { name })` ambiguous (e2e DRQ-01 failed strict
|
|
281
|
+
// mode on exactly this). `nativeButton={false}` because both variants
|
|
282
|
+
// render a <div>, matching the element the trigger actually emits.
|
|
283
|
+
<SheetTrigger
|
|
284
|
+
nativeButton={false}
|
|
285
|
+
render={
|
|
286
|
+
isEdit ? (
|
|
287
|
+
<Button
|
|
288
|
+
render={<div />}
|
|
289
|
+
nativeButton={false}
|
|
290
|
+
size="sm"
|
|
291
|
+
variant="ghost"
|
|
292
|
+
className="text-muted-foreground"
|
|
293
|
+
>
|
|
294
|
+
<PencilIcon />
|
|
295
|
+
</Button>
|
|
296
|
+
) : (
|
|
297
|
+
<Button render={<div />} nativeButton={false} size="sm" variant="outline">
|
|
298
|
+
{t("ui.buttons.create")}
|
|
299
|
+
</Button>
|
|
300
|
+
)
|
|
301
|
+
}
|
|
302
|
+
/>
|
|
281
303
|
))}
|
|
282
304
|
<SheetContent side="end" className={sizeClasses[size]}>
|
|
283
305
|
<SheetHeader className="border-b px-6 py-4">
|
|
@@ -112,11 +112,27 @@ export const FileUploader = forwardRef<HTMLDivElement, FileUploaderProps & React
|
|
|
112
112
|
|
|
113
113
|
const handleKeyDown = useCallback(
|
|
114
114
|
(e: React.KeyboardEvent<HTMLDivElement>) => {
|
|
115
|
+
if (!value) return;
|
|
116
|
+
|
|
117
|
+
// Only swallow the keys this component actually handles. Blanket
|
|
118
|
+
// preventDefault() killed Space / PageDown / arrow scrolling for as long
|
|
119
|
+
// as focus was anywhere inside the uploader — the page simply stopped
|
|
120
|
+
// responding to the keyboard while a file was selected.
|
|
121
|
+
const handledKeys = [
|
|
122
|
+
"ArrowLeft",
|
|
123
|
+
"ArrowRight",
|
|
124
|
+
"ArrowUp",
|
|
125
|
+
"ArrowDown",
|
|
126
|
+
"Enter",
|
|
127
|
+
"Space",
|
|
128
|
+
"Delete",
|
|
129
|
+
"Backspace",
|
|
130
|
+
"Escape",
|
|
131
|
+
];
|
|
132
|
+
if (!handledKeys.includes(e.key)) return;
|
|
115
133
|
e.preventDefault();
|
|
116
134
|
e.stopPropagation();
|
|
117
135
|
|
|
118
|
-
if (!value) return;
|
|
119
|
-
|
|
120
136
|
const moveNext = () => {
|
|
121
137
|
const nextIndex = activeIndex + 1;
|
|
122
138
|
setActiveIndex(nextIndex > value.length - 1 ? 0 : nextIndex);
|
|
@@ -10,18 +10,31 @@ import { FileInput, FileUploader } from "./FileUploader";
|
|
|
10
10
|
type MultiFileUploaderProps = {
|
|
11
11
|
files: File[];
|
|
12
12
|
setFiles: (files: File[]) => void;
|
|
13
|
+
/**
|
|
14
|
+
* Let one trip through the picker return several files. OPT-IN, and it stays
|
|
15
|
+
* that way: every existing caller was written against one-file-at-a-time, so
|
|
16
|
+
* flipping the default would change behaviour in every app consuming this
|
|
17
|
+
* package to suit whichever one asked last.
|
|
18
|
+
*/
|
|
19
|
+
multiple?: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Extra classes for the tile grid — density is the caller's business. The
|
|
22
|
+
* default is one column on the smallest screens, which suits a desktop form;
|
|
23
|
+
* a phone-first caller can ask for more columns without moving the default
|
|
24
|
+
* out from under anyone else.
|
|
25
|
+
*/
|
|
26
|
+
className?: string;
|
|
13
27
|
};
|
|
14
28
|
|
|
15
29
|
const dropzone = {
|
|
16
|
-
multiple: false,
|
|
17
30
|
maxSize: 100 * 1024 * 1024,
|
|
18
31
|
preventDropOnDocument: false,
|
|
19
32
|
accept: {
|
|
20
33
|
"application/images": [".jpg", ".jpeg", ".png", ".gif", ".webp", ".svg", ".docx", ".xslx", ".pdf", ".txt", ".md"],
|
|
21
34
|
},
|
|
22
|
-
} satisfies DropzoneOptions
|
|
35
|
+
} satisfies Omit<DropzoneOptions, "multiple">;
|
|
23
36
|
|
|
24
|
-
export default function MultiFileUploader({ files, setFiles }: MultiFileUploaderProps) {
|
|
37
|
+
export default function MultiFileUploader({ files, setFiles, multiple = false, className }: MultiFileUploaderProps) {
|
|
25
38
|
const uploadFiles = (newFiles: File[] | null) => {
|
|
26
39
|
if (!newFiles) return;
|
|
27
40
|
|
|
@@ -33,11 +46,16 @@ export default function MultiFileUploader({ files, setFiles }: MultiFileUploader
|
|
|
33
46
|
};
|
|
34
47
|
|
|
35
48
|
return (
|
|
36
|
-
<div
|
|
49
|
+
<div
|
|
50
|
+
className={cn(
|
|
51
|
+
"grid w-full grid-cols-1 gap-4 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 2xl:grid-cols-6",
|
|
52
|
+
className,
|
|
53
|
+
)}
|
|
54
|
+
>
|
|
37
55
|
<FileUploader
|
|
38
56
|
value={files}
|
|
39
57
|
onValueChange={uploadFiles}
|
|
40
|
-
dropzoneOptions={dropzone}
|
|
58
|
+
dropzoneOptions={{ ...dropzone, multiple }}
|
|
41
59
|
className="text-muted-foreground hover:text-primary relative aspect-square h-full cursor-pointer overflow-hidden rounded-lg border"
|
|
42
60
|
>
|
|
43
61
|
<FileInput className={cn("text-muted-foreground flex h-full w-full flex-col items-center justify-center")}>
|
|
@@ -26,6 +26,6 @@ export * from "./FormSlider";
|
|
|
26
26
|
export * from "./FormSwitch";
|
|
27
27
|
export * from "./FormTextarea";
|
|
28
28
|
export * from "./GdprConsentCheckbox";
|
|
29
|
-
export
|
|
29
|
+
export { default as MultiFileUploader } from "./MultiFileUploader";
|
|
30
30
|
export * from "./PasswordInput";
|
|
31
31
|
export * from "./useEditorDialog";
|