@visns-studio/visns-components 6.23.2 → 6.24.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/package.json CHANGED
@@ -93,7 +93,7 @@
93
93
  "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0"
94
94
  },
95
95
  "name": "@visns-studio/visns-components",
96
- "version": "6.23.2",
96
+ "version": "6.24.0",
97
97
  "description": "Various packages to assist in the development of our Custom Applications.",
98
98
  "main": "src/index.js",
99
99
  "files": [
@@ -43,6 +43,7 @@ import NativeDateFilterEditor from './columns/NativeDateFilterEditor';
43
43
  import SelectFilterEditor from './columns/SelectFilterEditor';
44
44
  import { toast } from 'react-toastify';
45
45
  import fetchUtil from '../utils/fetchUtil';
46
+ import { resolveFormVariant } from '../utils/formLayout';
46
47
  import { confirmDialog } from './utils/ConfirmDialog';
47
48
  import {
48
49
  useDensity,
@@ -6781,10 +6782,14 @@ const DataGrid = forwardRef(
6781
6782
  /* A record form is the case a side sheet is for: the list
6782
6783
  stays visible behind it, a long form scrolls naturally
6783
6784
  instead of stretching the dialog, and the width is fixed
6784
- so the fields keep one measure on every monitor. A view
6785
- that genuinely wants the centred dialog sets
6786
- `form.layout: "modal"`. */
6787
- variant={formData.layout === 'modal' ? 'modal' : 'sheet'}
6785
+ so the fields keep one measure on every monitor. That is
6786
+ the library default, so forms land in the sheet unless
6787
+ something says otherwise. A whole project can flip to the
6788
+ centred dialog with `setDefaultFormLayout('modal')` at
6789
+ bootstrap, and a single view that wants the other
6790
+ presentation overrides it with `form.layout: "modal"` or
6791
+ `form.layout: "sheet"`. */
6792
+ variant={resolveFormVariant(formData.layout)}
6788
6793
  size={formData.modalSize || 'medium'}
6789
6794
  >
6790
6795
  <Form
@@ -47,6 +47,7 @@ import { saveAs } from 'file-saver';
47
47
  import { toast } from 'react-toastify';
48
48
  import imageCompression from 'browser-image-compression';
49
49
  import fetchUtil from '../../utils/fetchUtil';
50
+ import { resolveFormVariant } from '../../utils/formLayout';
50
51
  import {
51
52
  CheckCircle as CircleCheck,
52
53
  Copy,
@@ -4267,7 +4268,7 @@ function GenericDetail({
4267
4268
  title={formData.title || 'Edit Details'}
4268
4269
  closeOnDocumentClick={false}
4269
4270
  verticalAlign={formData.verticalAlign || 'center'}
4270
- variant={formData.layout === 'modal' ? 'modal' : 'sheet'}
4271
+ variant={resolveFormVariant(formData.layout)}
4271
4272
  size={formData.modalSize || 'medium'}
4272
4273
  >
4273
4274
  <Form
package/src/index.js CHANGED
@@ -14,6 +14,14 @@ import {
14
14
  SECONDARY_GRID_HEIGHT,
15
15
  } from './components/utils/useDensity';
16
16
  import { readBuildEnv, buildEnv } from './components/utils/buildEnv';
17
+ // Project-wide default for how record CRUD forms are presented — the side
18
+ // sheet unless an app calls setDefaultFormLayout('modal') at bootstrap. A
19
+ // form config's own `layout` still wins.
20
+ import {
21
+ setDefaultFormLayout,
22
+ getDefaultFormLayout,
23
+ resolveFormVariant,
24
+ } from './utils/formLayout';
17
25
 
18
26
  /** CRM Components */
19
27
  import AsyncSelect from './components/AsyncSelect';
@@ -478,6 +486,7 @@ export {
478
486
  GenericQuote,
479
487
  GenericReport,
480
488
  GenericSort,
489
+ getDefaultFormLayout,
481
490
  GroupedReportRenderer,
482
491
  hasChallengeState,
483
492
  ImpersonateGate,
@@ -523,6 +532,7 @@ export {
523
532
  resolveAuthEndpoints,
524
533
  resolveClientPaths,
525
534
  resolveClientProtocol,
535
+ resolveFormVariant,
526
536
  // Passkeys (WebAuthn). Exported so a consuming app can build its own
527
537
  // enrolment screen against the same marshalling the login screen uses.
528
538
  base64UrlToBytes,
@@ -536,6 +546,7 @@ export {
536
546
  SectionTypeSelector,
537
547
  SelectList,
538
548
  Select,
549
+ setDefaultFormLayout,
539
550
  showConfirmDialog,
540
551
  SortableList,
541
552
  StagePopupModal,
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Project-wide default for how record CRUD forms are presented.
3
+ *
4
+ * StandardModal can draw a form either as a centred dialog (`variant="modal"`)
5
+ * or as a right-side slide-in sheet (`variant="sheet"`). The library ships with
6
+ * the sheet as its default so existing projects keep the presentation they
7
+ * already have. A consuming app that prefers the classic centred dialog calls
8
+ * `setDefaultFormLayout('modal')` once at bootstrap (before the first render)
9
+ * and every DataGrid / GenericDetail form follows.
10
+ *
11
+ * An individual form config still wins in both directions: set
12
+ * `layout: 'modal'` or `layout: 'sheet'` on the form and that form ignores the
13
+ * project default.
14
+ */
15
+
16
+ /** The two presentations StandardModal understands. */
17
+ const VALID_LAYOUTS = ['modal', 'sheet'];
18
+
19
+ /** Library default — the side sheet, unless a project opts out. */
20
+ let defaultFormLayout = 'sheet';
21
+
22
+ /** Warn at most once so a bad bootstrap call is not a console flood. */
23
+ let warnedInvalidLayout = false;
24
+
25
+ /**
26
+ * Set the project-wide default presentation for record forms.
27
+ * @param {'modal'|'sheet'} layout - Presentation to use when a form config does
28
+ * not specify its own `layout`.
29
+ * @returns {void} Anything other than 'modal' or 'sheet' is ignored.
30
+ */
31
+ export const setDefaultFormLayout = (layout) => {
32
+ if (!VALID_LAYOUTS.includes(layout)) {
33
+ if (!warnedInvalidLayout) {
34
+ warnedInvalidLayout = true;
35
+ // eslint-disable-next-line no-console
36
+ console.warn(
37
+ `setDefaultFormLayout: expected 'modal' or 'sheet', received ${JSON.stringify(layout)}. Keeping '${defaultFormLayout}'.`
38
+ );
39
+ }
40
+ return;
41
+ }
42
+
43
+ defaultFormLayout = layout;
44
+ };
45
+
46
+ /**
47
+ * Read the current project-wide default.
48
+ * @returns {'modal'|'sheet'} The default presentation for record forms.
49
+ */
50
+ export const getDefaultFormLayout = () => defaultFormLayout;
51
+
52
+ /**
53
+ * Resolve the StandardModal variant for one form.
54
+ * @param {string} [layout] - The form config's own `layout`, if it has one.
55
+ * @returns {'modal'|'sheet'} The form's own layout when it is valid, otherwise
56
+ * the project-wide default.
57
+ */
58
+ export const resolveFormVariant = (layout) =>
59
+ (VALID_LAYOUTS.includes(layout) ? layout : defaultFormLayout);