@evoke-platform/ui-components 1.13.0-dev.6 → 1.13.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.
Files changed (53) hide show
  1. package/dist/published/components/custom/CriteriaBuilder/CriteriaBuilder.d.ts +4 -4
  2. package/dist/published/components/custom/CriteriaBuilder/CriteriaBuilder.js +72 -145
  3. package/dist/published/components/custom/CriteriaBuilder/CriteriaBuilder.test.js +67 -189
  4. package/dist/published/components/custom/CriteriaBuilder/PropertyTree.d.ts +6 -6
  5. package/dist/published/components/custom/CriteriaBuilder/PropertyTree.js +25 -12
  6. package/dist/published/components/custom/CriteriaBuilder/PropertyTreeItem.d.ts +5 -4
  7. package/dist/published/components/custom/CriteriaBuilder/PropertyTreeItem.js +22 -34
  8. package/dist/published/components/custom/CriteriaBuilder/types.d.ts +11 -2
  9. package/dist/published/components/custom/CriteriaBuilder/utils.d.ts +34 -6
  10. package/dist/published/components/custom/CriteriaBuilder/utils.js +89 -18
  11. package/dist/published/components/custom/Form/FormComponents/DocumentComponent/Document.js +1 -1
  12. package/dist/published/components/custom/Form/FormComponents/DocumentComponent/DocumentList.js +3 -6
  13. package/dist/published/components/custom/Form/FormComponents/RepeatableFieldComponent/RepeatableField.js +1 -1
  14. package/dist/published/components/custom/Form/utils.d.ts +0 -1
  15. package/dist/published/components/custom/FormField/DateTimePickerSelect/DateTimePickerSelect.js +1 -2
  16. package/dist/published/components/custom/FormV2/FormRenderer.d.ts +1 -1
  17. package/dist/published/components/custom/FormV2/FormRenderer.js +2 -1
  18. package/dist/published/components/custom/FormV2/FormRendererContainer.d.ts +3 -1
  19. package/dist/published/components/custom/FormV2/FormRendererContainer.js +23 -26
  20. package/dist/published/components/custom/FormV2/components/Body.js +1 -1
  21. package/dist/published/components/custom/FormV2/components/Footer.js +1 -1
  22. package/dist/published/components/custom/FormV2/components/FormContext.d.ts +0 -1
  23. package/dist/published/components/custom/FormV2/components/FormFieldTypes/CollectionFiles/ActionDialog.d.ts +0 -1
  24. package/dist/published/components/custom/FormV2/components/FormFieldTypes/CollectionFiles/RepeatableField.js +3 -3
  25. package/dist/published/components/custom/FormV2/components/FormFieldTypes/DocumentFiles/Document.d.ts +2 -3
  26. package/dist/published/components/custom/FormV2/components/FormFieldTypes/DocumentFiles/Document.js +10 -46
  27. package/dist/published/components/custom/FormV2/components/FormFieldTypes/DocumentFiles/DocumentList.d.ts +3 -4
  28. package/dist/published/components/custom/FormV2/components/FormFieldTypes/DocumentFiles/DocumentList.js +23 -29
  29. package/dist/published/components/custom/FormV2/components/FormFieldTypes/relatedObjectFiles/InstanceLookup.js +1 -1
  30. package/dist/published/components/custom/FormV2/components/FormSections.js +0 -1
  31. package/dist/published/components/custom/FormV2/components/Header.d.ts +1 -0
  32. package/dist/published/components/custom/FormV2/components/Header.js +19 -8
  33. package/dist/published/components/custom/FormV2/components/HtmlView.d.ts +9 -0
  34. package/dist/published/components/custom/FormV2/components/HtmlView.js +42 -0
  35. package/dist/published/components/custom/FormV2/components/RecursiveEntryRenderer.js +4 -8
  36. package/dist/published/components/custom/FormV2/components/types.d.ts +1 -6
  37. package/dist/published/components/custom/FormV2/components/utils.d.ts +7 -5
  38. package/dist/published/components/custom/FormV2/components/utils.js +79 -156
  39. package/dist/published/components/custom/FormV2/tests/FormRenderer.test.js +2 -2
  40. package/dist/published/components/custom/FormV2/tests/FormRendererContainer.test.js +84 -0
  41. package/dist/published/components/custom/HistoryLog/HistoryData.js +1 -2
  42. package/dist/published/components/custom/HistoryLog/index.js +1 -2
  43. package/dist/published/components/custom/ViewDetailsV2/InstanceEntryRenderer.js +10 -24
  44. package/dist/published/components/custom/ViewDetailsV2/ViewDetailsV2Container.d.ts +3 -0
  45. package/dist/published/components/custom/ViewDetailsV2/ViewDetailsV2Container.js +3 -1
  46. package/dist/published/stories/Backdrop.stories.d.ts +2 -2
  47. package/dist/published/stories/CriteriaBuilder.stories.js +22 -70
  48. package/dist/published/stories/FormLabel.stories.d.ts +2 -2
  49. package/dist/published/stories/FormRenderer.stories.d.ts +3 -3
  50. package/dist/published/stories/FormRendererContainer.stories.d.ts +15 -5
  51. package/dist/published/stories/ViewDetailsV2Container.stories.d.ts +9 -0
  52. package/dist/published/theme/hooks.d.ts +1 -2
  53. package/package.json +10 -15
@@ -115,27 +115,9 @@ export const getEntryId = (entry) => {
115
115
  ? entry.input.id
116
116
  : undefined;
117
117
  };
118
- const getEntryType = (entry, parameters) => {
119
- if (entry?.type === 'inputField') {
120
- return entry?.input?.type;
121
- }
122
- else if (entry?.type === 'input') {
123
- // For 'input' type entries, look up the parameter by parameterId
124
- const parameter = parameters?.find((param) => param.id === entry.parameterId);
125
- return parameter?.type;
126
- }
127
- };
128
118
  export function getPrefixedUrl(url) {
129
119
  const wcsMatchers = ['/apps', '/pages', '/widgets'];
130
- const dataMatchers = [
131
- '/objects',
132
- '/correspondenceTemplates',
133
- '/documents',
134
- '/payments',
135
- '/forms',
136
- '/locations',
137
- '/files',
138
- ];
120
+ const dataMatchers = ['/objects', '/correspondenceTemplates', '/documents', '/payments', '/forms', '/locations'];
139
121
  const signalrMatchers = ['/hubs'];
140
122
  const accessManagementMatchers = ['/users'];
141
123
  const workflowMatchers = ['/workflows'];
@@ -487,90 +469,53 @@ export const docProperties = [
487
469
  type: 'string',
488
470
  },
489
471
  ];
490
- export const uploadFiles = async (files, apiServices, actionId = '_create', linkTo, shortCircuit = true) => {
472
+ /**
473
+ * Upload files using the POST /files endpoint for sys__file objects
474
+ */
475
+ export const uploadFiles = async (files, apiServices, actionId = '_create', metadata, linkTo) => {
491
476
  // Separate already uploaded files from files that need uploading
492
477
  const alreadyUploaded = files.filter((file) => !('size' in file));
493
478
  const filesToUpload = files.filter((file) => 'size' in file);
494
- let failedUpload = false;
495
- // Upload all files in parallel, handling each result individually
496
- const uploadPromises = [];
497
- for (const file of filesToUpload) {
479
+ // Upload all files in parallel
480
+ const uploadPromises = filesToUpload.map(async (file) => {
498
481
  const formData = new FormData();
499
482
  formData.append('file', file);
500
483
  formData.append('actionId', actionId);
501
484
  formData.append('objectId', 'sys__file');
502
- formData.append('input', JSON.stringify({ name: file.name, contentType: file.type }));
485
+ if (metadata) {
486
+ for (const [key, value] of Object.entries(metadata)) {
487
+ formData.append(key, value);
488
+ }
489
+ }
503
490
  if (linkTo) {
504
491
  formData.append('linkTo', JSON.stringify(linkTo));
505
492
  }
506
- const uploadPromise = (async () => {
507
- try {
508
- const fileInstance = await apiServices.post(getPrefixedUrl(`/files`), formData);
509
- return {
510
- id: fileInstance.id,
511
- name: fileInstance.name,
512
- unsaved: true,
513
- };
514
- }
515
- catch (error) {
516
- console.error(`Failed to upload file ${file.name}:`, error);
517
- failedUpload = true;
518
- }
519
- })();
520
- uploadPromises.push(uploadPromise);
521
- }
522
- if (!shortCircuit) {
523
- // Wait for all upload attempts to complete (successes and failures)
524
- const uploadResults = await Promise.allSettled(uploadPromises);
525
- const uploadedFiles = uploadResults
526
- .filter((result) => result.status === 'fulfilled' && !!result.value)
527
- .map((result) => result.value);
528
- const failedCount = filesToUpload.length - uploadedFiles.length;
493
+ const fileInstance = await apiServices.post(getPrefixedUrl(`/files`), formData);
529
494
  return {
530
- successfulUploads: [...alreadyUploaded, ...uploadedFiles],
531
- errorMessage: failedCount > 0 ? `Failed to upload ${failedCount} file(s)` : undefined,
495
+ id: fileInstance.id,
496
+ name: fileInstance.name,
532
497
  };
533
- }
498
+ });
534
499
  const uploadedFiles = await Promise.all(uploadPromises);
535
- if (failedUpload) {
536
- return {
537
- successfulUploads: [],
538
- errorMessage: 'An error occurred when uploading files',
539
- };
540
- }
541
- return {
542
- successfulUploads: [...alreadyUploaded, ...uploadedFiles],
543
- };
500
+ return [...alreadyUploaded, ...uploadedFiles];
544
501
  };
545
502
  /**
546
503
  * Creates file links for uploaded files by calling the objects endpoint with sys__fileLink
547
504
  * This is used after instance creation when the instance ID becomes available
548
505
  */
549
- export const createFileLinks = async (fileReferences, linkedInstance, apiServices) => {
550
- // Link files in parallel, handling each result individually
551
- const linkPromises = [];
552
- for (const file of fileReferences) {
553
- const linkPromise = (async () => {
554
- try {
555
- await apiServices.post(getPrefixedUrl(`/objects/sys__fileLink/instances`), {
556
- name: 'File Link',
557
- file: { id: file.id, name: file.name },
558
- linkedInstance,
559
- }, {
560
- params: {
561
- actionId: '_create',
562
- },
563
- });
564
- }
565
- catch (error) {
566
- console.error(`Failed to create file link for ${file.name}:`, error);
567
- // The file remains unlinked and can be retried later
568
- }
569
- })();
570
- linkPromises.push(linkPromise);
571
- }
572
- // Wait for all linking attempts to complete (successes and failures)
573
- await Promise.allSettled(linkPromises);
506
+ export const createFileLinks = async (files, linkedInstance, apiServices) => {
507
+ const linkPromises = files.map(async (file) => {
508
+ await apiServices.post(getPrefixedUrl(`/objects/sys__fileLink/instances`), {
509
+ name: 'File Link',
510
+ file: { id: file.id, name: file.name },
511
+ linkedInstance,
512
+ }, {
513
+ params: {
514
+ actionId: '_create',
515
+ },
516
+ });
517
+ });
518
+ await Promise.all(linkPromises);
574
519
  };
575
520
  export const uploadDocuments = async (files, metadata, apiServices, instanceId, objectId) => {
576
521
  const allDocuments = [];
@@ -598,29 +543,20 @@ export const uploadDocuments = async (files, metadata, apiServices, instanceId,
598
543
  export const deleteDocuments = async (submittedFields, requestSuccess, apiServices, object, instance, action, setSnackbarError) => {
599
544
  const documentProperties = action?.parameters
600
545
  ? action.parameters.filter((param) => ['document', 'file'].includes(param.type))
601
- : object.properties?.filter((prop) => ['document', 'file'].includes(prop.type));
546
+ : object?.properties?.filter((prop) => ['document', 'file'].includes(prop.type));
602
547
  for (const docProperty of documentProperties ?? []) {
603
548
  const savedValue = submittedFields[docProperty.id];
604
- const originalValue = instance[docProperty.id];
549
+ const originalValue = instance?.[docProperty.id];
605
550
  const documentsToRemove = requestSuccess
606
551
  ? (originalValue?.filter((file) => !savedValue?.some((f) => f.id === file.id)) ?? [])
607
552
  : (savedValue?.filter((file) => !originalValue?.some((f) => f.id === file.id)) ?? []);
608
553
  for (const doc of documentsToRemove) {
609
554
  try {
610
- // Build context for state model
611
- const fieldType = docProperty.type === 'file' ? 'file' : 'document';
612
- if (fieldType === 'file') {
613
- // For file properties, unlink the file. Don't delete the actual file
614
- // since other instances may be using it.
615
- await apiServices.post(getPrefixedUrl(`/files/${doc.id}/unlinkInstance`), {
616
- linkedInstanceId: instance.id,
617
- linkedObjectId: object.id,
618
- });
619
- }
620
- else {
621
- // For document properties, delete the document
622
- await apiServices.delete(getPrefixedUrl(`/objects/${object.id}/instances/${instance.id}/documents/${doc.id}`));
623
- }
555
+ // Use different endpoints based on property type
556
+ const deleteEndpoint = docProperty.type === 'file'
557
+ ? getPrefixedUrl(`/files/${doc.id}`)
558
+ : getPrefixedUrl(`/objects/${object.id}/instances/${instance.id}/documents/${doc.id}`);
559
+ await apiServices?.delete(deleteEndpoint);
624
560
  }
625
561
  catch (error) {
626
562
  if (error) {
@@ -635,28 +571,16 @@ export const deleteDocuments = async (submittedFields, requestSuccess, apiServic
635
571
  }
636
572
  }
637
573
  };
638
- async function handleUploads(files, propertyType, entry, apiServices, objectId, instanceId) {
639
- if (propertyType === 'file') {
640
- // Get the createActionId from display options, default to '_create'
641
- const createActionId = entry?.display?.createActionId ?? '_create';
642
- return await uploadFiles(files, apiServices, createActionId, instanceId ? { id: instanceId, objectId } : undefined);
643
- }
644
- else if (propertyType === 'document' && instanceId) {
645
- try {
646
- const docs = await uploadDocuments(files, {
647
- type: '',
648
- view_permission: '',
649
- ...entry?.documentMetadata,
650
- }, apiServices, instanceId, objectId);
651
- return { successfulUploads: docs };
652
- }
653
- catch (error) {
654
- console.error('Error uploading documents:', error);
655
- return { successfulUploads: [], errorMessage: 'Error uploading documents' };
656
- }
657
- }
658
- return { successfulUploads: [] };
659
- }
574
+ const getEntryType = (entry, parameters) => {
575
+ if (entry?.type === 'inputField') {
576
+ return entry.input.type;
577
+ }
578
+ else if (entry?.type === 'input') {
579
+ // For 'input' type entries, look up the parameter by parameterId
580
+ const parameter = parameters?.find((param) => param.id === entry.parameterId);
581
+ return parameter?.type;
582
+ }
583
+ };
660
584
  /**
661
585
  * Transforms a form submission into a format safe for API submission.
662
586
  *
@@ -674,45 +598,45 @@ export async function formatSubmission(submission, apiServices, objectId, instan
674
598
  if (associatedObject) {
675
599
  delete submission[associatedObject.propertyId];
676
600
  }
677
- const allEntries = getUnnestedEntries(form?.entries ?? []);
601
+ const allEntries = getUnnestedEntries(form?.entries ?? []) ?? [];
678
602
  for (const [key, value] of Object.entries(submission)) {
679
603
  const entry = allEntries?.find((entry) => getEntryId(entry) === key);
680
604
  if (isArray(value)) {
681
- const propertyType = getEntryType(entry, parameters);
682
- // The only array types we need to handle specially are 'file' and 'document'.
683
- if (propertyType !== 'file' && propertyType !== 'document') {
684
- continue;
685
- }
686
- // Only upload if array contains File instances (not SavedDocumentReference).
605
+ // Only upload if array contains File instances (not SavedDocumentReference)
687
606
  const fileInArray = value.some((item) => item instanceof File);
688
607
  if (fileInArray && apiServices && objectId) {
689
- const result = await handleUploads(value, propertyType ?? '', entry, apiServices, objectId, instanceId);
690
- if (result.errorMessage) {
691
- setSnackbarError?.({
692
- showAlert: true,
693
- // Provide generic message since we're ignoring a partial upload.
694
- message: `An error occurred while uploading associated ${propertyType === 'file' ? 'files' : 'documents'}`,
695
- isError: true,
696
- });
697
- return submission;
608
+ // Determine property type from the entry
609
+ const parameterType = getEntryType(entry, parameters);
610
+ try {
611
+ let uploadedDocuments = [];
612
+ if (parameterType === 'file') {
613
+ uploadedDocuments = await uploadFiles(value, apiServices, '_create', {
614
+ ...entry?.documentMetadata,
615
+ },
616
+ // Only pass linkTo if instanceId exists (update action)
617
+ instanceId ? { id: instanceId, objectId } : undefined);
618
+ }
619
+ else if (parameterType === 'document' && instanceId) {
620
+ uploadedDocuments = await uploadDocuments(value, {
621
+ type: '',
622
+ view_permission: '',
623
+ ...entry?.documentMetadata,
624
+ }, apiServices, instanceId, objectId);
625
+ }
626
+ submission[key] = uploadedDocuments;
698
627
  }
699
- else {
700
- // Filter out 'unsaved' flag before submission since the api doesn't know about it.
701
- submission[key] = result.successfulUploads.map((file) => ({ id: file.id, name: file.name }));
628
+ catch (err) {
629
+ if (err) {
630
+ setSnackbarError &&
631
+ setSnackbarError({
632
+ showAlert: true,
633
+ message: `An error occurred while uploading associated ${parameterType === 'file' ? 'files' : 'documents'}`,
634
+ isError: true,
635
+ });
636
+ }
637
+ return submission;
702
638
  }
703
639
  }
704
- else {
705
- // Filter out 'unsaved' flag before submission since the api doesn't know about it.
706
- submission[key] = value
707
- // This should never happen but it's possible that the else branch
708
- // is reached because either 'apiServices' or 'objectId' is undefined.
709
- // If that's the case the submission will fail if we submit File blobs.
710
- .filter((file) => !(file instanceof File))
711
- .map((file) => ({
712
- id: file.id,
713
- name: file.name,
714
- }));
715
- }
716
640
  // if there are address fields with no value address needs to be set to undefined to be able to submit
717
641
  }
718
642
  else if (typeof value === 'object' && value !== null) {
@@ -725,8 +649,7 @@ export async function formatSubmission(submission, apiServices, objectId, instan
725
649
  submission[key] =
726
650
  entry &&
727
651
  ['input', 'inputField'].includes(entry.type) &&
728
- (entry.display?.relatedObjectId ||
729
- associatedObject?.objectId)
652
+ entry.display?.relatedObjectId
730
653
  ? pick(value, 'id', 'name', 'objectId')
731
654
  : pick(value, 'id', 'name');
732
655
  }
@@ -1483,7 +1483,7 @@ describe('FormRenderer', () => {
1483
1483
  await user.click(addButton);
1484
1484
  await screen.findByRole('dialog');
1485
1485
  // Make sure other form entry is present
1486
- await screen.findByRole('textbox', { name: 'Name *' });
1486
+ await screen.findByRole('textbox', { name: /Name */i });
1487
1487
  const relatedObjectField = screen.queryByRole('textbox', { name: 'Related Object' });
1488
1488
  expect(relatedObjectField).not.toBeInTheDocument();
1489
1489
  });
@@ -1502,7 +1502,7 @@ describe('FormRenderer', () => {
1502
1502
  const addButton = await screen.findByRole('button', { name: /add/i });
1503
1503
  await user.click(addButton);
1504
1504
  await screen.findByRole('dialog');
1505
- const nameField = await screen.findByRole('textbox', { name: 'Name *' });
1505
+ const nameField = await screen.findByRole('textbox', { name: /Name */ });
1506
1506
  await user.type(nameField, 'New Collection Item');
1507
1507
  const submitButton = screen.getByRole('button', { name: 'Create Collection Item' });
1508
1508
  await user.click(submitButton);
@@ -997,6 +997,90 @@ describe('FormRendererContainer', () => {
997
997
  });
998
998
  });
999
999
  });
1000
+ it('should display title by default', async () => {
1001
+ const form = {
1002
+ id: 'simpleForm',
1003
+ name: 'Simple Form',
1004
+ entries: [],
1005
+ actionId: '_create',
1006
+ objectId: 'simpleObject',
1007
+ };
1008
+ const simpleObject = {
1009
+ id: 'simpleObject',
1010
+ name: 'Simple Object',
1011
+ actions: [
1012
+ {
1013
+ id: '_create',
1014
+ name: 'Create',
1015
+ type: 'create',
1016
+ parameters: [],
1017
+ outputEvent: 'created',
1018
+ },
1019
+ ],
1020
+ properties: [],
1021
+ };
1022
+ server.use(http.get(`/api/data/objects/${simpleObject.id}/effective`, () => HttpResponse.json(simpleObject)), http.get(`/api/data/forms/${form.id}`, () => HttpResponse.json(form)));
1023
+ render(React.createElement(FormRendererContainer, { objectId: simpleObject.id, formId: form.id, dataType: "objectInstances" }));
1024
+ await screen.findByText('Simple Form');
1025
+ });
1026
+ it('should display title', async () => {
1027
+ const form = {
1028
+ id: 'simpleForm',
1029
+ name: 'Simple Form',
1030
+ entries: [],
1031
+ actionId: '_create',
1032
+ objectId: 'simpleObject',
1033
+ };
1034
+ const simpleObject = {
1035
+ id: 'simpleObject',
1036
+ name: 'Simple Object',
1037
+ actions: [
1038
+ {
1039
+ id: '_create',
1040
+ name: 'Create',
1041
+ type: 'create',
1042
+ parameters: [],
1043
+ outputEvent: 'created',
1044
+ },
1045
+ ],
1046
+ properties: [],
1047
+ };
1048
+ server.use(http.get(`/api/data/objects/${simpleObject.id}/effective`, () => HttpResponse.json(simpleObject)), http.get(`/api/data/forms/${form.id}`, () => HttpResponse.json(form)));
1049
+ render(React.createElement(FormRendererContainer, { objectId: simpleObject.id, formId: form.id, title: {
1050
+ hidden: false,
1051
+ }, dataType: "objectInstances" }));
1052
+ await screen.findByText('Simple Form');
1053
+ });
1054
+ it('should not display title', async () => {
1055
+ const form = {
1056
+ id: 'simpleForm',
1057
+ name: 'Simple Form',
1058
+ entries: [],
1059
+ actionId: '_create',
1060
+ objectId: 'simpleObject',
1061
+ };
1062
+ const simpleObject = {
1063
+ id: 'simpleObject',
1064
+ name: 'Simple Object',
1065
+ actions: [
1066
+ {
1067
+ id: '_create',
1068
+ name: 'Create',
1069
+ type: 'create',
1070
+ parameters: [],
1071
+ outputEvent: 'created',
1072
+ },
1073
+ ],
1074
+ properties: [],
1075
+ };
1076
+ server.use(http.get(`/api/data/objects/${simpleObject.id}/effective`, () => HttpResponse.json(simpleObject)), http.get(`/api/data/forms/${form.id}`, () => HttpResponse.json(form)));
1077
+ render(React.createElement(FormRendererContainer, { objectId: simpleObject.id, formId: form.id, title: {
1078
+ hidden: true,
1079
+ }, dataType: "objectInstances" }));
1080
+ await waitFor(() => {
1081
+ expect(screen.queryByText('Simple Form')).not.toBeInTheDocument();
1082
+ });
1083
+ });
1000
1084
  it('should display a submit button', async () => {
1001
1085
  const form = {
1002
1086
  id: 'simpleForm',
@@ -6,8 +6,7 @@ import React from 'react';
6
6
  import { Typography } from '../../core';
7
7
  import { Box, Grid } from '../../layout';
8
8
  import DisplayedProperty from './DisplayedProperty';
9
- // eslint-disable-next-line @typescript-eslint/no-var-requires
10
- const { format } = require('small-date');
9
+ import { format } from 'small-date';
11
10
  export const nanoid = customAlphabet(uppercase + lowercase);
12
11
  const styles = {
13
12
  timelineHeader: {
@@ -9,8 +9,7 @@ import Box from '../../layout/Box';
9
9
  import HistoryFilter from './Filter';
10
10
  import HistoricalData from './HistoryData';
11
11
  import HistoryLoading from './HistoryLoading';
12
- // eslint-disable-next-line @typescript-eslint/no-var-requires
13
- const { format } = require('small-date');
12
+ import { format } from 'small-date';
14
13
  /**
15
14
  * Renders a timeline of the instance's history log.
16
15
  * Users can filter the history by type and sort by date.
@@ -1,6 +1,5 @@
1
1
  import { useApiServices, useApp, } from '@evoke-platform/context';
2
2
  import { CancelRounded, CheckCircleRounded } from '@mui/icons-material';
3
- import DOMPurify from 'dompurify';
4
3
  import { isEmpty, isNil } from 'lodash';
5
4
  import { DateTime } from 'luxon';
6
5
  import React, { useEffect, useMemo, useState } from 'react';
@@ -17,6 +16,7 @@ import { Document } from '../FormV2/components/FormFieldTypes/DocumentFiles/Docu
17
16
  import { Image } from '../FormV2/components/FormFieldTypes/Image';
18
17
  import PropertyProtection from '../FormV2/components/PropertyProtection';
19
18
  import { entryIsVisible, fetchCollectionData, filterEmptySections, getDefaultPages, isAddressProperty, } from '../FormV2/components/utils';
19
+ import HtmlView from '../FormV2/components/HtmlView';
20
20
  function ViewOnlyEntryRenderer(props) {
21
21
  const { entry } = props;
22
22
  const { fetchedOptions, setFetchedOptions, object, instance, richTextEditor: RichTextEditor } = useFormContext();
@@ -53,36 +53,22 @@ function ViewOnlyEntryRenderer(props) {
53
53
  useEffect(() => {
54
54
  (async () => {
55
55
  if (object?.properties && !fetchedOptions[`${entryId}NavigationSlug`]) {
56
- const property = object.properties.find((prop) => prop.id === entryId);
57
- if (!property || property.type !== 'object') {
58
- return;
59
- }
60
- if (!property.objectId) {
61
- property.objectId = instance?.[entryId] && (instance?.[entryId]).objectId;
62
- }
63
- try {
64
- const pages = await getDefaultPages([property], defaultPages, findDefaultPageSlugFor);
65
- if (property?.objectId && pages[property.objectId]) {
66
- setNavigationSlug(pages[property.objectId]);
67
- setFetchedOptions({
68
- [`${entryId}NavigationSlug`]: pages[property.objectId],
69
- });
70
- }
71
- }
72
- catch (error) {
73
- console.error('Error fetching default pages:', error);
56
+ const pages = await getDefaultPages(object.properties, defaultPages, findDefaultPageSlugFor);
57
+ if (fieldDefinition?.objectId && pages[fieldDefinition.objectId]) {
58
+ setNavigationSlug(pages[fieldDefinition.objectId]);
59
+ setFetchedOptions({
60
+ [`${entryId}NavigationSlug`]: pages[fieldDefinition.objectId],
61
+ });
74
62
  }
75
63
  }
76
64
  })();
77
- }, [object, defaultPages, findDefaultPageSlugFor, instance, entryId, fetchedOptions]);
65
+ }, [object, defaultPages, findDefaultPageSlugFor, fieldDefinition]);
78
66
  // If the entry is hidden, clear its value and any nested values, and skip rendering
79
67
  if (!entryIsVisible(entry, instance)) {
80
68
  return null;
81
69
  }
82
70
  if (entry.type === 'content') {
83
- return (React.createElement(Box, { dangerouslySetInnerHTML: { __html: DOMPurify.sanitize(entry.html) }, sx: {
84
- fontFamily: 'Roboto, Helvetica, Arial, sans-serif',
85
- } }));
71
+ return React.createElement(HtmlView, { value: entry.html });
86
72
  }
87
73
  else if (entry.type === 'readonlyField') {
88
74
  if (isAddressProperty(entryId)) {
@@ -143,7 +129,7 @@ function ViewOnlyEntryRenderer(props) {
143
129
  }
144
130
  else if (fieldDefinition.type === 'document' || fieldDefinition.type === 'file') {
145
131
  return (React.createElement(FieldWrapper, { inputId: entryId, inputType: fieldDefinition.type, label: display?.label || fieldDefinition?.name || 'default', value: fieldValue, required: display?.required || false, prefix: display?.prefix, suffix: display?.suffix, viewOnly: true },
146
- React.createElement(Document, { id: entryId, fieldType: fieldDefinition.type, error: false, value: fieldValue, canUpdateProperty: false })));
132
+ React.createElement(Document, { id: entryId, error: false, value: fieldValue, canUpdateProperty: false })));
147
133
  }
148
134
  else if (fieldDefinition.type === 'collection') {
149
135
  return fieldDefinition?.manyToManyPropertyId ? (middleObject && initialMiddleObjectInstances && (React.createElement(FieldWrapper, { inputId: entryId, inputType: 'collection', label: display?.label || fieldDefinition?.name || 'default', value: fieldValue, required: display?.required || false, viewOnly: true },
@@ -2,6 +2,9 @@ import React, { ComponentType } from 'react';
2
2
  import { BaseProps, SimpleEditorProps } from '../FormV2/components/types';
3
3
  import { FormRendererProps } from '../FormV2/FormRenderer';
4
4
  export type ViewDetailsV2ContainerProps = BaseProps & {
5
+ title?: {
6
+ hidden?: boolean;
7
+ };
5
8
  panelLayoutId?: string;
6
9
  instanceId?: string;
7
10
  objectId: string;
@@ -10,7 +10,7 @@ import Header from '../FormV2/components/Header';
10
10
  import { assignIdsToSectionsAndRichText, getPrefixedUrl } from '../FormV2/components/utils';
11
11
  import ViewOnlyEntryRenderer from './InstanceEntryRenderer';
12
12
  function ViewDetailsV2Container(props) {
13
- const { instanceId, panelLayoutId, objectId, richTextEditor, renderHeader, renderBody } = props;
13
+ const { instanceId, panelLayoutId, objectId, title, richTextEditor, renderHeader, renderBody } = props;
14
14
  const apiServices = useApiServices();
15
15
  const [sanitizedObject, setSanitizedObject] = useState();
16
16
  const [instance, setInstance] = useState();
@@ -85,6 +85,7 @@ function ViewDetailsV2Container(props) {
85
85
  const isLoading = (instanceId && !instance) || !panelLayout || !sanitizedObject;
86
86
  const hasSections = updatedEntries.some((entry) => entry.type === 'sections');
87
87
  const headerProps = {
88
+ hideTitle: title?.hidden === true,
88
89
  title: panelLayout?.name,
89
90
  onExpandAll: handleExpandAll,
90
91
  onCollapseAll: handleCollapseAll,
@@ -103,6 +104,7 @@ function ViewDetailsV2Container(props) {
103
104
  (renderHeader ? renderHeader({ ...headerProps }) : React.createElement(Header, { ...headerProps })),
104
105
  React.createElement(Box, { sx: {
105
106
  paddingX: isSm || isXs ? 2 : 3,
107
+ paddingY: isSm || isXs ? '6px' : '14px',
106
108
  borderTop: '1px solid #e9ecef',
107
109
  } },
108
110
  React.createElement(FormContext.Provider, { value: {
@@ -1,12 +1,12 @@
1
1
  import React from 'react';
2
2
  declare const _default: import("@storybook/types").ComponentAnnotations<import("@storybook/react/dist/types-0fc72a6d").R, import("@mui/material").BackdropOwnProps & import("@mui/material/OverridableComponent").CommonProps & Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & {
3
3
  ref?: ((instance: HTMLDivElement | null) => void) | React.RefObject<HTMLDivElement> | null | undefined;
4
- }, "components" | "color" | "className" | "style" | "classes" | "children" | "defaultChecked" | "defaultValue" | "suppressContentEditableWarning" | "suppressHydrationWarning" | "accessKey" | "autoCapitalize" | "autoFocus" | "contentEditable" | "contextMenu" | "dir" | "draggable" | "enterKeyHint" | "hidden" | "id" | "lang" | "nonce" | "slot" | "spellCheck" | "tabIndex" | "title" | "translate" | "radioGroup" | "role" | "about" | "content" | "datatype" | "inlist" | "prefix" | "property" | "rel" | "resource" | "rev" | "typeof" | "vocab" | "autoCorrect" | "autoSave" | "itemProp" | "itemScope" | "itemType" | "itemID" | "itemRef" | "results" | "security" | "unselectable" | "inputMode" | "is" | "exportparts" | "part" | "aria-activedescendant" | "aria-atomic" | "aria-autocomplete" | "aria-braillelabel" | "aria-brailleroledescription" | "aria-busy" | "aria-checked" | "aria-colcount" | "aria-colindex" | "aria-colindextext" | "aria-colspan" | "aria-controls" | "aria-current" | "aria-describedby" | "aria-description" | "aria-details" | "aria-disabled" | "aria-dropeffect" | "aria-errormessage" | "aria-expanded" | "aria-flowto" | "aria-grabbed" | "aria-haspopup" | "aria-hidden" | "aria-invalid" | "aria-keyshortcuts" | "aria-label" | "aria-labelledby" | "aria-level" | "aria-live" | "aria-modal" | "aria-multiline" | "aria-multiselectable" | "aria-orientation" | "aria-owns" | "aria-placeholder" | "aria-posinset" | "aria-pressed" | "aria-readonly" | "aria-relevant" | "aria-required" | "aria-roledescription" | "aria-rowcount" | "aria-rowindex" | "aria-rowindextext" | "aria-rowspan" | "aria-selected" | "aria-setsize" | "aria-sort" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "dangerouslySetInnerHTML" | "onCopy" | "onCopyCapture" | "onCut" | "onCutCapture" | "onPaste" | "onPasteCapture" | "onCompositionEnd" | "onCompositionEndCapture" | "onCompositionStart" | "onCompositionStartCapture" | "onCompositionUpdate" | "onCompositionUpdateCapture" | "onFocus" | "onFocusCapture" | "onBlur" | "onBlurCapture" | "onChange" | "onChangeCapture" | "onBeforeInput" | "onBeforeInputCapture" | "onInput" | "onInputCapture" | "onReset" | "onResetCapture" | "onSubmit" | "onSubmitCapture" | "onInvalid" | "onInvalidCapture" | "onLoad" | "onLoadCapture" | "onError" | "onErrorCapture" | "onKeyDown" | "onKeyDownCapture" | "onKeyPress" | "onKeyPressCapture" | "onKeyUp" | "onKeyUpCapture" | "onAbort" | "onAbortCapture" | "onCanPlay" | "onCanPlayCapture" | "onCanPlayThrough" | "onCanPlayThroughCapture" | "onDurationChange" | "onDurationChangeCapture" | "onEmptied" | "onEmptiedCapture" | "onEncrypted" | "onEncryptedCapture" | "onEnded" | "onEndedCapture" | "onLoadedData" | "onLoadedDataCapture" | "onLoadedMetadata" | "onLoadedMetadataCapture" | "onLoadStart" | "onLoadStartCapture" | "onPause" | "onPauseCapture" | "onPlay" | "onPlayCapture" | "onPlaying" | "onPlayingCapture" | "onProgress" | "onProgressCapture" | "onRateChange" | "onRateChangeCapture" | "onResize" | "onResizeCapture" | "onSeeked" | "onSeekedCapture" | "onSeeking" | "onSeekingCapture" | "onStalled" | "onStalledCapture" | "onSuspend" | "onSuspendCapture" | "onTimeUpdate" | "onTimeUpdateCapture" | "onVolumeChange" | "onVolumeChangeCapture" | "onWaiting" | "onWaitingCapture" | "onAuxClick" | "onAuxClickCapture" | "onClick" | "onClickCapture" | "onContextMenu" | "onContextMenuCapture" | "onDoubleClick" | "onDoubleClickCapture" | "onDrag" | "onDragCapture" | "onDragEnd" | "onDragEndCapture" | "onDragEnter" | "onDragEnterCapture" | "onDragExit" | "onDragExitCapture" | "onDragLeave" | "onDragLeaveCapture" | "onDragOver" | "onDragOverCapture" | "onDragStart" | "onDragStartCapture" | "onDrop" | "onDropCapture" | "onMouseDown" | "onMouseDownCapture" | "onMouseEnter" | "onMouseLeave" | "onMouseMove" | "onMouseMoveCapture" | "onMouseOut" | "onMouseOutCapture" | "onMouseOver" | "onMouseOverCapture" | "onMouseUp" | "onMouseUpCapture" | "onSelect" | "onSelectCapture" | "onTouchCancel" | "onTouchCancelCapture" | "onTouchEnd" | "onTouchEndCapture" | "onTouchMove" | "onTouchMoveCapture" | "onTouchStart" | "onTouchStartCapture" | "onPointerDown" | "onPointerDownCapture" | "onPointerMove" | "onPointerMoveCapture" | "onPointerUp" | "onPointerUpCapture" | "onPointerCancel" | "onPointerCancelCapture" | "onPointerEnter" | "onPointerLeave" | "onPointerOver" | "onPointerOverCapture" | "onPointerOut" | "onPointerOutCapture" | "onGotPointerCapture" | "onGotPointerCaptureCapture" | "onLostPointerCapture" | "onLostPointerCaptureCapture" | "onScroll" | "onScrollCapture" | "onWheel" | "onWheelCapture" | "onAnimationStart" | "onAnimationStartCapture" | "onAnimationEnd" | "onAnimationEndCapture" | "onAnimationIteration" | "onAnimationIterationCapture" | "onTransitionEnd" | "onTransitionEndCapture" | "sx" | "ref" | "transitionDuration" | "componentsProps" | "slotProps" | "slots" | "in" | "mountOnEnter" | "unmountOnExit" | "timeout" | "easing" | "addEndListener" | "onEnter" | "onEntering" | "onEntered" | "onExit" | "onExiting" | "onExited" | "appear" | "enter" | "exit" | "invisible" | "open" | "TransitionComponent"> & {
4
+ }, "components" | "color" | "className" | "style" | "classes" | "children" | "defaultChecked" | "defaultValue" | "suppressContentEditableWarning" | "suppressHydrationWarning" | "accessKey" | "autoCapitalize" | "autoFocus" | "contentEditable" | "contextMenu" | "dir" | "draggable" | "enterKeyHint" | "hidden" | "id" | "lang" | "nonce" | "slot" | "spellCheck" | "tabIndex" | "title" | "translate" | "radioGroup" | "role" | "about" | "content" | "datatype" | "inlist" | "prefix" | "property" | "rel" | "resource" | "rev" | "typeof" | "vocab" | "autoCorrect" | "autoSave" | "itemProp" | "itemScope" | "itemType" | "itemID" | "itemRef" | "results" | "security" | "unselectable" | "inputMode" | "is" | "exportparts" | "part" | "aria-activedescendant" | "aria-atomic" | "aria-autocomplete" | "aria-braillelabel" | "aria-brailleroledescription" | "aria-busy" | "aria-checked" | "aria-colcount" | "aria-colindex" | "aria-colindextext" | "aria-colspan" | "aria-controls" | "aria-current" | "aria-describedby" | "aria-description" | "aria-details" | "aria-disabled" | "aria-dropeffect" | "aria-errormessage" | "aria-expanded" | "aria-flowto" | "aria-grabbed" | "aria-haspopup" | "aria-hidden" | "aria-invalid" | "aria-keyshortcuts" | "aria-label" | "aria-labelledby" | "aria-level" | "aria-live" | "aria-modal" | "aria-multiline" | "aria-multiselectable" | "aria-orientation" | "aria-owns" | "aria-placeholder" | "aria-posinset" | "aria-pressed" | "aria-readonly" | "aria-relevant" | "aria-required" | "aria-roledescription" | "aria-rowcount" | "aria-rowindex" | "aria-rowindextext" | "aria-rowspan" | "aria-selected" | "aria-setsize" | "aria-sort" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "dangerouslySetInnerHTML" | "onCopy" | "onCopyCapture" | "onCut" | "onCutCapture" | "onPaste" | "onPasteCapture" | "onCompositionEnd" | "onCompositionEndCapture" | "onCompositionStart" | "onCompositionStartCapture" | "onCompositionUpdate" | "onCompositionUpdateCapture" | "onFocus" | "onFocusCapture" | "onBlur" | "onBlurCapture" | "onChange" | "onChangeCapture" | "onBeforeInput" | "onBeforeInputCapture" | "onInput" | "onInputCapture" | "onReset" | "onResetCapture" | "onSubmit" | "onSubmitCapture" | "onInvalid" | "onInvalidCapture" | "onLoad" | "onLoadCapture" | "onError" | "onErrorCapture" | "onKeyDown" | "onKeyDownCapture" | "onKeyPress" | "onKeyPressCapture" | "onKeyUp" | "onKeyUpCapture" | "onAbort" | "onAbortCapture" | "onCanPlay" | "onCanPlayCapture" | "onCanPlayThrough" | "onCanPlayThroughCapture" | "onDurationChange" | "onDurationChangeCapture" | "onEmptied" | "onEmptiedCapture" | "onEncrypted" | "onEncryptedCapture" | "onEnded" | "onEndedCapture" | "onLoadedData" | "onLoadedDataCapture" | "onLoadedMetadata" | "onLoadedMetadataCapture" | "onLoadStart" | "onLoadStartCapture" | "onPause" | "onPauseCapture" | "onPlay" | "onPlayCapture" | "onPlaying" | "onPlayingCapture" | "onProgress" | "onProgressCapture" | "onRateChange" | "onRateChangeCapture" | "onSeeked" | "onSeekedCapture" | "onSeeking" | "onSeekingCapture" | "onStalled" | "onStalledCapture" | "onSuspend" | "onSuspendCapture" | "onTimeUpdate" | "onTimeUpdateCapture" | "onVolumeChange" | "onVolumeChangeCapture" | "onWaiting" | "onWaitingCapture" | "onAuxClick" | "onAuxClickCapture" | "onClick" | "onClickCapture" | "onContextMenu" | "onContextMenuCapture" | "onDoubleClick" | "onDoubleClickCapture" | "onDrag" | "onDragCapture" | "onDragEnd" | "onDragEndCapture" | "onDragEnter" | "onDragEnterCapture" | "onDragExit" | "onDragExitCapture" | "onDragLeave" | "onDragLeaveCapture" | "onDragOver" | "onDragOverCapture" | "onDragStart" | "onDragStartCapture" | "onDrop" | "onDropCapture" | "onMouseDown" | "onMouseDownCapture" | "onMouseEnter" | "onMouseLeave" | "onMouseMove" | "onMouseMoveCapture" | "onMouseOut" | "onMouseOutCapture" | "onMouseOver" | "onMouseOverCapture" | "onMouseUp" | "onMouseUpCapture" | "onSelect" | "onSelectCapture" | "onTouchCancel" | "onTouchCancelCapture" | "onTouchEnd" | "onTouchEndCapture" | "onTouchMove" | "onTouchMoveCapture" | "onTouchStart" | "onTouchStartCapture" | "onPointerDown" | "onPointerDownCapture" | "onPointerMove" | "onPointerMoveCapture" | "onPointerUp" | "onPointerUpCapture" | "onPointerCancel" | "onPointerCancelCapture" | "onPointerEnter" | "onPointerLeave" | "onPointerOver" | "onPointerOverCapture" | "onPointerOut" | "onPointerOutCapture" | "onGotPointerCapture" | "onGotPointerCaptureCapture" | "onLostPointerCapture" | "onLostPointerCaptureCapture" | "onScroll" | "onScrollCapture" | "onWheel" | "onWheelCapture" | "onAnimationStart" | "onAnimationStartCapture" | "onAnimationEnd" | "onAnimationEndCapture" | "onAnimationIteration" | "onAnimationIterationCapture" | "onTransitionEnd" | "onTransitionEndCapture" | "sx" | "ref" | "transitionDuration" | "componentsProps" | "slotProps" | "slots" | "in" | "mountOnEnter" | "unmountOnExit" | "timeout" | "easing" | "addEndListener" | "onEnter" | "onEntering" | "onEntered" | "onExit" | "onExiting" | "onExited" | "appear" | "enter" | "exit" | "invisible" | "open" | "TransitionComponent"> & {
5
5
  component?: React.ElementType<any, keyof React.JSX.IntrinsicElements> | undefined;
6
6
  }>;
7
7
  export default _default;
8
8
  export declare const Backdrop: import("@storybook/types").AnnotatedStoryFn<import("@storybook/react/dist/types-0fc72a6d").R, import("@mui/material").BackdropOwnProps & import("@mui/material/OverridableComponent").CommonProps & Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & {
9
9
  ref?: ((instance: HTMLDivElement | null) => void) | React.RefObject<HTMLDivElement> | null | undefined;
10
- }, "components" | "color" | "className" | "style" | "classes" | "children" | "defaultChecked" | "defaultValue" | "suppressContentEditableWarning" | "suppressHydrationWarning" | "accessKey" | "autoCapitalize" | "autoFocus" | "contentEditable" | "contextMenu" | "dir" | "draggable" | "enterKeyHint" | "hidden" | "id" | "lang" | "nonce" | "slot" | "spellCheck" | "tabIndex" | "title" | "translate" | "radioGroup" | "role" | "about" | "content" | "datatype" | "inlist" | "prefix" | "property" | "rel" | "resource" | "rev" | "typeof" | "vocab" | "autoCorrect" | "autoSave" | "itemProp" | "itemScope" | "itemType" | "itemID" | "itemRef" | "results" | "security" | "unselectable" | "inputMode" | "is" | "exportparts" | "part" | "aria-activedescendant" | "aria-atomic" | "aria-autocomplete" | "aria-braillelabel" | "aria-brailleroledescription" | "aria-busy" | "aria-checked" | "aria-colcount" | "aria-colindex" | "aria-colindextext" | "aria-colspan" | "aria-controls" | "aria-current" | "aria-describedby" | "aria-description" | "aria-details" | "aria-disabled" | "aria-dropeffect" | "aria-errormessage" | "aria-expanded" | "aria-flowto" | "aria-grabbed" | "aria-haspopup" | "aria-hidden" | "aria-invalid" | "aria-keyshortcuts" | "aria-label" | "aria-labelledby" | "aria-level" | "aria-live" | "aria-modal" | "aria-multiline" | "aria-multiselectable" | "aria-orientation" | "aria-owns" | "aria-placeholder" | "aria-posinset" | "aria-pressed" | "aria-readonly" | "aria-relevant" | "aria-required" | "aria-roledescription" | "aria-rowcount" | "aria-rowindex" | "aria-rowindextext" | "aria-rowspan" | "aria-selected" | "aria-setsize" | "aria-sort" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "dangerouslySetInnerHTML" | "onCopy" | "onCopyCapture" | "onCut" | "onCutCapture" | "onPaste" | "onPasteCapture" | "onCompositionEnd" | "onCompositionEndCapture" | "onCompositionStart" | "onCompositionStartCapture" | "onCompositionUpdate" | "onCompositionUpdateCapture" | "onFocus" | "onFocusCapture" | "onBlur" | "onBlurCapture" | "onChange" | "onChangeCapture" | "onBeforeInput" | "onBeforeInputCapture" | "onInput" | "onInputCapture" | "onReset" | "onResetCapture" | "onSubmit" | "onSubmitCapture" | "onInvalid" | "onInvalidCapture" | "onLoad" | "onLoadCapture" | "onError" | "onErrorCapture" | "onKeyDown" | "onKeyDownCapture" | "onKeyPress" | "onKeyPressCapture" | "onKeyUp" | "onKeyUpCapture" | "onAbort" | "onAbortCapture" | "onCanPlay" | "onCanPlayCapture" | "onCanPlayThrough" | "onCanPlayThroughCapture" | "onDurationChange" | "onDurationChangeCapture" | "onEmptied" | "onEmptiedCapture" | "onEncrypted" | "onEncryptedCapture" | "onEnded" | "onEndedCapture" | "onLoadedData" | "onLoadedDataCapture" | "onLoadedMetadata" | "onLoadedMetadataCapture" | "onLoadStart" | "onLoadStartCapture" | "onPause" | "onPauseCapture" | "onPlay" | "onPlayCapture" | "onPlaying" | "onPlayingCapture" | "onProgress" | "onProgressCapture" | "onRateChange" | "onRateChangeCapture" | "onResize" | "onResizeCapture" | "onSeeked" | "onSeekedCapture" | "onSeeking" | "onSeekingCapture" | "onStalled" | "onStalledCapture" | "onSuspend" | "onSuspendCapture" | "onTimeUpdate" | "onTimeUpdateCapture" | "onVolumeChange" | "onVolumeChangeCapture" | "onWaiting" | "onWaitingCapture" | "onAuxClick" | "onAuxClickCapture" | "onClick" | "onClickCapture" | "onContextMenu" | "onContextMenuCapture" | "onDoubleClick" | "onDoubleClickCapture" | "onDrag" | "onDragCapture" | "onDragEnd" | "onDragEndCapture" | "onDragEnter" | "onDragEnterCapture" | "onDragExit" | "onDragExitCapture" | "onDragLeave" | "onDragLeaveCapture" | "onDragOver" | "onDragOverCapture" | "onDragStart" | "onDragStartCapture" | "onDrop" | "onDropCapture" | "onMouseDown" | "onMouseDownCapture" | "onMouseEnter" | "onMouseLeave" | "onMouseMove" | "onMouseMoveCapture" | "onMouseOut" | "onMouseOutCapture" | "onMouseOver" | "onMouseOverCapture" | "onMouseUp" | "onMouseUpCapture" | "onSelect" | "onSelectCapture" | "onTouchCancel" | "onTouchCancelCapture" | "onTouchEnd" | "onTouchEndCapture" | "onTouchMove" | "onTouchMoveCapture" | "onTouchStart" | "onTouchStartCapture" | "onPointerDown" | "onPointerDownCapture" | "onPointerMove" | "onPointerMoveCapture" | "onPointerUp" | "onPointerUpCapture" | "onPointerCancel" | "onPointerCancelCapture" | "onPointerEnter" | "onPointerLeave" | "onPointerOver" | "onPointerOverCapture" | "onPointerOut" | "onPointerOutCapture" | "onGotPointerCapture" | "onGotPointerCaptureCapture" | "onLostPointerCapture" | "onLostPointerCaptureCapture" | "onScroll" | "onScrollCapture" | "onWheel" | "onWheelCapture" | "onAnimationStart" | "onAnimationStartCapture" | "onAnimationEnd" | "onAnimationEndCapture" | "onAnimationIteration" | "onAnimationIterationCapture" | "onTransitionEnd" | "onTransitionEndCapture" | "sx" | "ref" | "transitionDuration" | "componentsProps" | "slotProps" | "slots" | "in" | "mountOnEnter" | "unmountOnExit" | "timeout" | "easing" | "addEndListener" | "onEnter" | "onEntering" | "onEntered" | "onExit" | "onExiting" | "onExited" | "appear" | "enter" | "exit" | "invisible" | "open" | "TransitionComponent"> & {
10
+ }, "components" | "color" | "className" | "style" | "classes" | "children" | "defaultChecked" | "defaultValue" | "suppressContentEditableWarning" | "suppressHydrationWarning" | "accessKey" | "autoCapitalize" | "autoFocus" | "contentEditable" | "contextMenu" | "dir" | "draggable" | "enterKeyHint" | "hidden" | "id" | "lang" | "nonce" | "slot" | "spellCheck" | "tabIndex" | "title" | "translate" | "radioGroup" | "role" | "about" | "content" | "datatype" | "inlist" | "prefix" | "property" | "rel" | "resource" | "rev" | "typeof" | "vocab" | "autoCorrect" | "autoSave" | "itemProp" | "itemScope" | "itemType" | "itemID" | "itemRef" | "results" | "security" | "unselectable" | "inputMode" | "is" | "exportparts" | "part" | "aria-activedescendant" | "aria-atomic" | "aria-autocomplete" | "aria-braillelabel" | "aria-brailleroledescription" | "aria-busy" | "aria-checked" | "aria-colcount" | "aria-colindex" | "aria-colindextext" | "aria-colspan" | "aria-controls" | "aria-current" | "aria-describedby" | "aria-description" | "aria-details" | "aria-disabled" | "aria-dropeffect" | "aria-errormessage" | "aria-expanded" | "aria-flowto" | "aria-grabbed" | "aria-haspopup" | "aria-hidden" | "aria-invalid" | "aria-keyshortcuts" | "aria-label" | "aria-labelledby" | "aria-level" | "aria-live" | "aria-modal" | "aria-multiline" | "aria-multiselectable" | "aria-orientation" | "aria-owns" | "aria-placeholder" | "aria-posinset" | "aria-pressed" | "aria-readonly" | "aria-relevant" | "aria-required" | "aria-roledescription" | "aria-rowcount" | "aria-rowindex" | "aria-rowindextext" | "aria-rowspan" | "aria-selected" | "aria-setsize" | "aria-sort" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "dangerouslySetInnerHTML" | "onCopy" | "onCopyCapture" | "onCut" | "onCutCapture" | "onPaste" | "onPasteCapture" | "onCompositionEnd" | "onCompositionEndCapture" | "onCompositionStart" | "onCompositionStartCapture" | "onCompositionUpdate" | "onCompositionUpdateCapture" | "onFocus" | "onFocusCapture" | "onBlur" | "onBlurCapture" | "onChange" | "onChangeCapture" | "onBeforeInput" | "onBeforeInputCapture" | "onInput" | "onInputCapture" | "onReset" | "onResetCapture" | "onSubmit" | "onSubmitCapture" | "onInvalid" | "onInvalidCapture" | "onLoad" | "onLoadCapture" | "onError" | "onErrorCapture" | "onKeyDown" | "onKeyDownCapture" | "onKeyPress" | "onKeyPressCapture" | "onKeyUp" | "onKeyUpCapture" | "onAbort" | "onAbortCapture" | "onCanPlay" | "onCanPlayCapture" | "onCanPlayThrough" | "onCanPlayThroughCapture" | "onDurationChange" | "onDurationChangeCapture" | "onEmptied" | "onEmptiedCapture" | "onEncrypted" | "onEncryptedCapture" | "onEnded" | "onEndedCapture" | "onLoadedData" | "onLoadedDataCapture" | "onLoadedMetadata" | "onLoadedMetadataCapture" | "onLoadStart" | "onLoadStartCapture" | "onPause" | "onPauseCapture" | "onPlay" | "onPlayCapture" | "onPlaying" | "onPlayingCapture" | "onProgress" | "onProgressCapture" | "onRateChange" | "onRateChangeCapture" | "onSeeked" | "onSeekedCapture" | "onSeeking" | "onSeekingCapture" | "onStalled" | "onStalledCapture" | "onSuspend" | "onSuspendCapture" | "onTimeUpdate" | "onTimeUpdateCapture" | "onVolumeChange" | "onVolumeChangeCapture" | "onWaiting" | "onWaitingCapture" | "onAuxClick" | "onAuxClickCapture" | "onClick" | "onClickCapture" | "onContextMenu" | "onContextMenuCapture" | "onDoubleClick" | "onDoubleClickCapture" | "onDrag" | "onDragCapture" | "onDragEnd" | "onDragEndCapture" | "onDragEnter" | "onDragEnterCapture" | "onDragExit" | "onDragExitCapture" | "onDragLeave" | "onDragLeaveCapture" | "onDragOver" | "onDragOverCapture" | "onDragStart" | "onDragStartCapture" | "onDrop" | "onDropCapture" | "onMouseDown" | "onMouseDownCapture" | "onMouseEnter" | "onMouseLeave" | "onMouseMove" | "onMouseMoveCapture" | "onMouseOut" | "onMouseOutCapture" | "onMouseOver" | "onMouseOverCapture" | "onMouseUp" | "onMouseUpCapture" | "onSelect" | "onSelectCapture" | "onTouchCancel" | "onTouchCancelCapture" | "onTouchEnd" | "onTouchEndCapture" | "onTouchMove" | "onTouchMoveCapture" | "onTouchStart" | "onTouchStartCapture" | "onPointerDown" | "onPointerDownCapture" | "onPointerMove" | "onPointerMoveCapture" | "onPointerUp" | "onPointerUpCapture" | "onPointerCancel" | "onPointerCancelCapture" | "onPointerEnter" | "onPointerLeave" | "onPointerOver" | "onPointerOverCapture" | "onPointerOut" | "onPointerOutCapture" | "onGotPointerCapture" | "onGotPointerCaptureCapture" | "onLostPointerCapture" | "onLostPointerCaptureCapture" | "onScroll" | "onScrollCapture" | "onWheel" | "onWheelCapture" | "onAnimationStart" | "onAnimationStartCapture" | "onAnimationEnd" | "onAnimationEndCapture" | "onAnimationIteration" | "onAnimationIterationCapture" | "onTransitionEnd" | "onTransitionEndCapture" | "sx" | "ref" | "transitionDuration" | "componentsProps" | "slotProps" | "slots" | "in" | "mountOnEnter" | "unmountOnExit" | "timeout" | "easing" | "addEndListener" | "onEnter" | "onEntering" | "onEntered" | "onExit" | "onExiting" | "onExited" | "appear" | "enter" | "exit" | "invisible" | "open" | "TransitionComponent"> & {
11
11
  component?: React.ElementType<any, keyof React.JSX.IntrinsicElements> | undefined;
12
12
  }>;