@asteby/metacore-runtime-react 13.5.0 → 13.5.1

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
@@ -1,5 +1,16 @@
1
1
  # @asteby/metacore-runtime-react
2
2
 
3
+ ## 13.5.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 2778004: fix(action-modal): sticky header + footer, scrollable body
8
+
9
+ A tall declarative form (a journal entry with many line-items rows) used to push
10
+ the Cancel/Submit footer below the viewport. The action modal now caps at 90vh
11
+ and scrolls ONLY the field area — the title and the action buttons stay pinned
12
+ and always reachable.
13
+
3
14
  ## 13.5.0
4
15
 
5
16
  ### Minor Changes
@@ -135,12 +135,12 @@ function GenericActionModal({ open, onOpenChange, action, model, record, endpoin
135
135
  : hasLineItems
136
136
  ? '820px'
137
137
  : undefined;
138
- return (_jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(DialogContent, { className: widthPx ? '' : 'sm:max-w-lg', style: widthPx ? { maxWidth: widthPx, width: '95vw' } : undefined, children: [_jsxs(DialogHeader, { children: [_jsxs(DialogTitle, { className: "flex items-center gap-2", children: [_jsx(DynamicIcon, { name: action.icon, className: "h-5 w-5" }), action.label] }), action.confirmMessage && _jsx(DialogDescription, { children: action.confirmMessage })] }), _jsx("div", { className: "grid gap-4 py-4 sm:grid-cols-2", children: action.fields?.map((field) => {
138
+ return (_jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(DialogContent, { className: 'flex max-h-[90vh] flex-col overflow-hidden ' + (widthPx ? '' : 'sm:max-w-lg'), style: { maxHeight: '90vh', ...(widthPx ? { maxWidth: widthPx, width: '95vw' } : {}) }, children: [_jsxs(DialogHeader, { className: "shrink-0", children: [_jsxs(DialogTitle, { className: "flex items-center gap-2", children: [_jsx(DynamicIcon, { name: action.icon, className: "h-5 w-5" }), action.label] }), action.confirmMessage && _jsx(DialogDescription, { children: action.confirmMessage })] }), _jsx("div", { className: "-mx-1 grid min-h-0 flex-1 gap-4 overflow-y-auto px-1 py-4 sm:grid-cols-2", children: action.fields?.map((field) => {
139
139
  const fullWidth = isLineItemsField(field) ||
140
140
  resolveWidget(field) === 'textarea' ||
141
141
  resolveWidget(field) === 'richtext';
142
142
  return (_jsxs("div", { className: 'grid gap-2 ' + (fullWidth ? 'sm:col-span-2' : ''), children: [_jsxs(Label, { htmlFor: field.key, children: [field.label, field.required && _jsx("span", { className: "text-red-500 ml-1", children: "*" })] }), renderField(field, formData[field.key], (v) => updateField(field.key, v))] }, field.key));
143
- }) }), _jsxs(DialogFooter, { children: [_jsx(Button, { variant: "outline", onClick: () => onOpenChange(false), disabled: executing, children: t('common.cancel') }), _jsxs(Button, { onClick: execute, disabled: executing, style: action.color ? { backgroundColor: action.color, color: 'white' } : undefined, children: [executing ? _jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }) : _jsx(DynamicIcon, { name: action.icon, className: "mr-2 h-4 w-4" }), action.label] })] })] }) }));
143
+ }) }), _jsxs(DialogFooter, { className: "shrink-0", children: [_jsx(Button, { variant: "outline", onClick: () => onOpenChange(false), disabled: executing, children: t('common.cancel') }), _jsxs(Button, { onClick: execute, disabled: executing, style: action.color ? { backgroundColor: action.color, color: 'white' } : undefined, children: [executing ? _jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }) : _jsx(DynamicIcon, { name: action.icon, className: "mr-2 h-4 w-4" }), action.label] })] })] }) }));
144
144
  }
145
145
  function renderField(field, value, onChange) {
146
146
  // Repeatable line-items group → row grid (value is an array of row objects).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@asteby/metacore-runtime-react",
3
- "version": "13.5.0",
3
+ "version": "13.5.1",
4
4
  "description": "React runtime for metacore hosts — renders addon contributions dynamically",
5
5
  "repository": {
6
6
  "type": "git",
@@ -246,23 +246,28 @@ function GenericActionModal({ open, onOpenChange, action, model, record, endpoin
246
246
 
247
247
  return (
248
248
  <Dialog open={open} onOpenChange={onOpenChange}>
249
+ {/* Sticky header + footer, scrollable body: the form can grow tall
250
+ (many line-items rows) past the viewport, so cap the dialog at
251
+ 90vh and let ONLY the field area scroll — the title and the
252
+ Cancel/Submit actions stay pinned and always reachable. maxHeight
253
+ is inline (guaranteed) since an arbitrary max-h-[90vh] class may be
254
+ dropped by a consuming app's Tailwind scan. */}
249
255
  <DialogContent
250
- className={widthPx ? '' : 'sm:max-w-lg'}
251
- style={widthPx ? { maxWidth: widthPx, width: '95vw' } : undefined}
256
+ className={'flex max-h-[90vh] flex-col overflow-hidden ' + (widthPx ? '' : 'sm:max-w-lg')}
257
+ style={{ maxHeight: '90vh', ...(widthPx ? { maxWidth: widthPx, width: '95vw' } : {}) }}
252
258
  >
253
- <DialogHeader>
259
+ <DialogHeader className="shrink-0">
254
260
  <DialogTitle className="flex items-center gap-2">
255
261
  <DynamicIcon name={action.icon} className="h-5 w-5" />
256
262
  {action.label}
257
263
  </DialogTitle>
258
264
  {action.confirmMessage && <DialogDescription>{action.confirmMessage}</DialogDescription>}
259
265
  </DialogHeader>
260
- {/* Responsive 2-column grid: scalar fields (journal, date,
261
- reference) flow side-by-side instead of one tall vertical
262
- stack; line-items grids and textareas span the full width so
263
- they get room. Mirrors DynamicForm's pro layout — driven only
264
- by field shape, fully declarative. */}
265
- <div className="grid gap-4 py-4 sm:grid-cols-2">
266
+ {/* Scrollable body. Responsive 2-column grid: scalar fields
267
+ (journal, date, reference) flow side-by-side instead of one
268
+ tall vertical stack; line-items grids and textareas span the
269
+ full width. Mirrors DynamicForm — driven only by field shape. */}
270
+ <div className="-mx-1 grid min-h-0 flex-1 gap-4 overflow-y-auto px-1 py-4 sm:grid-cols-2">
266
271
  {action.fields?.map((field) => {
267
272
  const fullWidth =
268
273
  isLineItemsField(field) ||
@@ -282,7 +287,7 @@ function GenericActionModal({ open, onOpenChange, action, model, record, endpoin
282
287
  )
283
288
  })}
284
289
  </div>
285
- <DialogFooter>
290
+ <DialogFooter className="shrink-0">
286
291
  <Button variant="outline" onClick={() => onOpenChange(false)} disabled={executing}>
287
292
  {t('common.cancel')}
288
293
  </Button>