@strato-admin/cloudscape 0.1.0 → 0.3.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 (231) hide show
  1. package/dist/Admin.d.ts +6 -2
  2. package/dist/Admin.js +14 -8
  3. package/dist/RecordLink.js +5 -4
  4. package/dist/Settings.d.ts +17 -0
  5. package/dist/Settings.js +14 -0
  6. package/dist/button/BulkDeleteButton.d.ts +4 -1
  7. package/dist/button/BulkDeleteButton.js +37 -5
  8. package/dist/button/Button.d.ts +2 -1
  9. package/dist/button/CancelButton.d.ts +6 -0
  10. package/dist/button/CancelButton.js +10 -0
  11. package/dist/button/CreateButton.js +9 -8
  12. package/dist/button/DeleteButton.d.ts +13 -0
  13. package/dist/button/DeleteButton.js +36 -0
  14. package/dist/button/EditButton.d.ts +1 -1
  15. package/dist/button/EditButton.js +10 -10
  16. package/dist/button/SaveButton.js +2 -2
  17. package/dist/button/index.d.ts +2 -0
  18. package/dist/button/index.js +2 -0
  19. package/dist/collection-hooks/interfaces.d.ts +7 -3
  20. package/dist/collection-hooks/useCollection.d.ts +1 -1
  21. package/dist/collection-hooks/useCollection.js +15 -10
  22. package/dist/create/Create.d.ts +9 -17
  23. package/dist/create/Create.js +40 -12
  24. package/dist/create/CreateHeader.d.ts +2 -2
  25. package/dist/create/CreateHeader.js +4 -5
  26. package/dist/defaults.d.ts +6 -0
  27. package/dist/defaults.js +21 -0
  28. package/dist/detail/Detail.d.ts +33 -0
  29. package/dist/detail/Detail.js +22 -0
  30. package/dist/detail/DetailHeader.d.ts +11 -0
  31. package/dist/detail/{ShowHeader.js → DetailHeader.js} +7 -5
  32. package/dist/detail/DetailHub.d.ts +27 -0
  33. package/dist/detail/DetailHub.js +63 -0
  34. package/dist/detail/KeyValuePairs.d.ts +7 -1
  35. package/dist/detail/KeyValuePairs.js +14 -8
  36. package/dist/detail/index.d.ts +3 -2
  37. package/dist/detail/index.js +3 -2
  38. package/dist/edit/Edit.d.ts +8 -19
  39. package/dist/edit/Edit.js +48 -12
  40. package/dist/edit/EditHeader.d.ts +2 -2
  41. package/dist/edit/EditHeader.js +5 -4
  42. package/dist/field/ArrayField.d.ts +26 -10
  43. package/dist/field/ArrayField.js +38 -10
  44. package/dist/field/BadgeField.d.ts +1 -1
  45. package/dist/field/BadgeField.js +1 -1
  46. package/dist/field/BooleanField.d.ts +1 -1
  47. package/dist/field/BooleanField.js +2 -2
  48. package/dist/field/CurrencyField.d.ts +1 -1
  49. package/dist/field/CurrencyField.js +1 -1
  50. package/dist/field/DateField.d.ts +1 -1
  51. package/dist/field/DateField.js +1 -1
  52. package/dist/field/IdField.d.ts +1 -1
  53. package/dist/field/IdField.js +3 -3
  54. package/dist/field/NumberField.d.ts +1 -1
  55. package/dist/field/NumberField.js +1 -1
  56. package/dist/field/ReferenceField.d.ts +1 -1
  57. package/dist/field/ReferenceField.js +4 -2
  58. package/dist/field/ReferenceManyField.d.ts +35 -4
  59. package/dist/field/ReferenceManyField.js +17 -4
  60. package/dist/field/StatusIndicatorField.d.ts +1 -1
  61. package/dist/field/StatusIndicatorField.js +6 -5
  62. package/dist/field/TextField.d.ts +1 -1
  63. package/dist/field/TextField.js +1 -1
  64. package/dist/field/types.d.ts +9 -9
  65. package/dist/form/Form.d.ts +12 -2
  66. package/dist/form/Form.js +10 -16
  67. package/dist/form/index.d.ts +1 -1
  68. package/dist/form/index.js +1 -1
  69. package/dist/hooks/useSchemaFields.d.ts +22 -0
  70. package/dist/hooks/useSchemaFields.js +45 -0
  71. package/dist/i18n/Message.d.ts +15 -0
  72. package/dist/i18n/Message.js +19 -0
  73. package/dist/i18n/RecordMessage.d.ts +14 -0
  74. package/dist/i18n/RecordMessage.js +16 -0
  75. package/dist/i18n/index.d.ts +3 -0
  76. package/dist/i18n/index.js +2 -0
  77. package/dist/i18n/types.d.ts +19 -0
  78. package/dist/i18n/types.js +1 -0
  79. package/dist/index.d.ts +5 -1
  80. package/dist/index.js +5 -1
  81. package/dist/input/ArrayInput.d.ts +33 -0
  82. package/dist/input/{AttributeEditor.js → ArrayInput.js} +18 -11
  83. package/dist/input/AutocompleteInput.d.ts +1 -1
  84. package/dist/input/AutocompleteInput.js +3 -3
  85. package/dist/input/BooleanInput.d.ts +6 -0
  86. package/dist/input/BooleanInput.js +23 -0
  87. package/dist/input/CommonInputProps.d.ts +6 -0
  88. package/dist/input/CommonInputProps.js +6 -0
  89. package/dist/input/FieldTitle.js +4 -4
  90. package/dist/input/FormField.js +12 -3
  91. package/dist/input/FormFieldContext.d.ts +1 -1
  92. package/dist/input/NumberInput.d.ts +1 -1
  93. package/dist/input/NumberInput.js +3 -3
  94. package/dist/input/ReferenceInput.d.ts +1 -1
  95. package/dist/input/ReferenceInput.js +22 -12
  96. package/dist/input/SelectInput.d.ts +1 -1
  97. package/dist/input/SelectInput.js +3 -3
  98. package/dist/input/SliderInput.d.ts +1 -1
  99. package/dist/input/SliderInput.js +4 -4
  100. package/dist/input/TextAreaInput.d.ts +1 -1
  101. package/dist/input/TextAreaInput.js +3 -3
  102. package/dist/input/TextInput.d.ts +1 -1
  103. package/dist/input/TextInput.js +6 -12
  104. package/dist/input/index.d.ts +2 -1
  105. package/dist/input/index.js +2 -1
  106. package/dist/input/types.d.ts +33 -2
  107. package/dist/layout/AppLayout.js +6 -3
  108. package/dist/layout/Notifications.d.ts +1 -0
  109. package/dist/layout/Notifications.js +51 -0
  110. package/dist/layout/Ready.d.ts +6 -0
  111. package/dist/layout/Ready.js +24 -0
  112. package/dist/layout/TopNavigation.d.ts +4 -2
  113. package/dist/layout/TopNavigation.js +7 -7
  114. package/dist/layout/index.d.ts +2 -0
  115. package/dist/layout/index.js +2 -0
  116. package/dist/list/Cards.d.ts +31 -4
  117. package/dist/list/Cards.js +81 -10
  118. package/dist/list/List.d.ts +9 -12
  119. package/dist/list/List.js +41 -11
  120. package/dist/list/Table.d.ts +8 -4
  121. package/dist/list/Table.js +55 -55
  122. package/dist/list/TableHeader.d.ts +2 -2
  123. package/dist/list/TableHeader.js +4 -5
  124. package/dist/theme/ThemeManager.js +1 -1
  125. package/package.json +9 -6
  126. package/src/Admin.tsx +35 -18
  127. package/src/RecordLink.stories.tsx +1 -1
  128. package/src/RecordLink.tsx +5 -4
  129. package/src/Settings.tsx +16 -0
  130. package/src/__mocks__/ra-core.tsx +83 -0
  131. package/src/__mocks__/strato-core.tsx +36 -42
  132. package/src/button/BulkDeleteButton.test.tsx +45 -8
  133. package/src/button/BulkDeleteButton.tsx +75 -12
  134. package/src/button/Button.tsx +31 -2
  135. package/src/button/CancelButton.tsx +20 -0
  136. package/src/button/CreateButton.tsx +12 -10
  137. package/src/button/DeleteButton.tsx +96 -0
  138. package/src/button/EditButton.tsx +13 -12
  139. package/src/button/SaveButton.tsx +2 -3
  140. package/src/button/index.ts +2 -0
  141. package/src/collection-hooks/interfaces.ts +7 -3
  142. package/src/collection-hooks/useCollection.test.ts +115 -2
  143. package/src/collection-hooks/useCollection.ts +15 -10
  144. package/src/create/Create.test.tsx +3 -3
  145. package/src/create/Create.tsx +68 -37
  146. package/src/create/CreateHeader.tsx +6 -10
  147. package/src/defaults.tsx +28 -0
  148. package/src/detail/Detail-CollectionFields.test.tsx +84 -0
  149. package/src/detail/Detail.test.tsx +91 -0
  150. package/src/detail/Detail.tsx +48 -0
  151. package/src/detail/{ShowHeader.test.tsx → DetailHeader.test.tsx} +11 -9
  152. package/src/detail/DetailHeader.tsx +42 -0
  153. package/src/detail/DetailHub.tsx +88 -0
  154. package/src/detail/KeyValuePairs.test.tsx +2 -2
  155. package/src/detail/KeyValuePairs.tsx +25 -18
  156. package/src/detail/index.ts +3 -2
  157. package/src/edit/Edit.test.tsx +7 -5
  158. package/src/edit/Edit.tsx +92 -40
  159. package/src/edit/EditHeader.tsx +7 -5
  160. package/src/field/ArrayField.tsx +57 -11
  161. package/src/field/BadgeField.tsx +2 -3
  162. package/src/field/BooleanField.test.tsx +2 -3
  163. package/src/field/BooleanField.tsx +3 -3
  164. package/src/field/CurrencyField.tsx +1 -1
  165. package/src/field/DateField.tsx +1 -1
  166. package/src/field/IdField.test.tsx +8 -20
  167. package/src/field/IdField.tsx +5 -20
  168. package/src/field/NumberField.tsx +1 -1
  169. package/src/field/ReferenceField.test.tsx +15 -6
  170. package/src/field/ReferenceField.tsx +10 -7
  171. package/src/field/ReferenceManyField.test.tsx +55 -10
  172. package/src/field/ReferenceManyField.tsx +84 -13
  173. package/src/field/StatusIndicatorField.test.tsx +7 -21
  174. package/src/field/StatusIndicatorField.tsx +8 -20
  175. package/src/field/TextField.tsx +1 -1
  176. package/src/field/types.ts +12 -13
  177. package/src/form/Form.test.tsx +8 -4
  178. package/src/form/Form.tsx +24 -19
  179. package/src/form/index.ts +1 -1
  180. package/src/hooks/useSchemaFields.ts +89 -0
  181. package/src/i18n/Message.tsx +22 -0
  182. package/src/i18n/RecordMessage.tsx +22 -0
  183. package/src/i18n/index.ts +3 -0
  184. package/src/i18n/types.ts +19 -0
  185. package/src/index.ts +5 -1
  186. package/src/input/ArrayInput.test.tsx +81 -0
  187. package/src/input/{AttributeEditor.tsx → ArrayInput.tsx} +36 -18
  188. package/src/input/AutocompleteInput.test.tsx +2 -4
  189. package/src/input/AutocompleteInput.tsx +9 -11
  190. package/src/input/BooleanInput.tsx +42 -0
  191. package/src/input/CommonInputProps.tsx +8 -0
  192. package/src/input/FieldTitle.tsx +3 -15
  193. package/src/input/FormField.tsx +78 -67
  194. package/src/input/FormFieldContext.ts +1 -1
  195. package/src/input/NumberInput.tsx +10 -7
  196. package/src/input/ReferenceInput.test.tsx +12 -2
  197. package/src/input/ReferenceInput.tsx +32 -14
  198. package/src/input/SelectInput.tsx +14 -17
  199. package/src/input/SliderInput.test.tsx +2 -3
  200. package/src/input/SliderInput.tsx +48 -38
  201. package/src/input/TextAreaInput.tsx +10 -6
  202. package/src/input/TextInput.test.tsx +2 -4
  203. package/src/input/TextInput.tsx +35 -20
  204. package/src/input/index.ts +2 -1
  205. package/src/input/types.ts +40 -8
  206. package/src/layout/AppLayout.test.tsx +23 -3
  207. package/src/layout/AppLayout.tsx +11 -8
  208. package/src/layout/Notifications.test.tsx +102 -0
  209. package/src/layout/Notifications.tsx +61 -0
  210. package/src/layout/Ready.tsx +123 -0
  211. package/src/layout/TopNavigation.test.tsx +2 -3
  212. package/src/layout/TopNavigation.tsx +9 -8
  213. package/src/layout/index.ts +2 -0
  214. package/src/list/Cards.test.tsx +320 -0
  215. package/src/list/Cards.tsx +146 -16
  216. package/src/list/List.tsx +87 -26
  217. package/src/list/Table.test.tsx +40 -5
  218. package/src/list/Table.tsx +89 -98
  219. package/src/list/TableHeader.test.tsx +15 -11
  220. package/src/list/TableHeader.tsx +6 -8
  221. package/src/theme/ThemeManager.tsx +1 -1
  222. package/dist/__mocks__/strato-core.js +0 -50
  223. package/dist/__mocks__to__delete/strato-core.js +0 -50
  224. package/dist/detail/Show.d.ts +0 -39
  225. package/dist/detail/Show.js +0 -40
  226. package/dist/detail/ShowHeader.d.ts +0 -7
  227. package/dist/input/AttributeEditor.d.ts +0 -25
  228. package/src/detail/Show.test.tsx +0 -96
  229. package/src/detail/Show.tsx +0 -104
  230. package/src/detail/ShowHeader.tsx +0 -35
  231. package/src/input/AttributeEditor.test.tsx +0 -147
@@ -1,96 +0,0 @@
1
- import React from 'react';
2
- import { render } from '@testing-library/react';
3
- import { vi, describe, it, expect, beforeEach } from 'vitest';
4
- import { useShowContext, useResourceContext } from '@strato-admin/core';
5
- import Show from './Show';
6
-
7
- // Mock strato-core
8
- vi.mock('@strato-admin/core', () => import('../__mocks__/strato-core'));
9
-
10
- // Mock react-router-dom
11
- vi.mock('react-router-dom', () => ({
12
- useNavigate: vi.fn(),
13
- }));
14
-
15
- // Mock Cloudscape components
16
- vi.mock('@cloudscape-design/components/container', () => ({
17
- default: ({ children, header }: any) => (
18
- <div data-testid="container">
19
- <div data-testid="container-header">{header}</div>
20
- <div data-testid="container-content">{children}</div>
21
- </div>
22
- ),
23
- }));
24
-
25
- vi.mock('@cloudscape-design/components/header', () => ({
26
- default: ({ children, actions }: any) => (
27
- <header>
28
- <div>{children}</div>
29
- <div>{actions}</div>
30
- </header>
31
- ),
32
- }));
33
-
34
- vi.mock('@cloudscape-design/components/space-between', () => ({
35
- default: ({ children }: any) => <div>{children}</div>,
36
- }));
37
-
38
- vi.mock('@cloudscape-design/components/button', () => ({
39
- default: ({ children }: any) => <button>{children}</button>,
40
- }));
41
-
42
- describe('Show', () => {
43
- beforeEach(() => {
44
- vi.clearAllMocks();
45
- });
46
-
47
- it('should render nothing when loading', () => {
48
- (useShowContext as any).mockReturnValue({
49
- isLoading: true,
50
- record: undefined,
51
- });
52
-
53
- const { queryByTestId } = render(
54
- <Show>
55
- <div data-testid="content" />
56
- </Show>,
57
- );
58
-
59
- expect(queryByTestId('container')).toBeNull();
60
- });
61
-
62
- it('should render content and title when record is loaded', () => {
63
- (useShowContext as any).mockReturnValue({
64
- isLoading: false,
65
- record: { id: 1 }, defaultTitle: 'Products',
66
- resource: 'products',
67
- });
68
- (useResourceContext as any).mockReturnValue('products');
69
-
70
- const { getByTestId, getByText } = render(
71
- <Show>
72
- <div data-testid="content">Hello World</div>
73
- </Show>,
74
- );
75
-
76
- expect(getByTestId('container')).toBeDefined();
77
- expect(getByTestId('content').textContent).toBe('Hello World');
78
- expect(getByText('Products')).toBeDefined();
79
- });
80
-
81
- it('should use provided title', () => {
82
- (useShowContext as any).mockReturnValue({
83
- isLoading: false,
84
- record: { id: 1 }, defaultTitle: 'Products',
85
- resource: 'products',
86
- });
87
-
88
- const { getByText } = render(
89
- <Show title="My Product">
90
- <div />
91
- </Show>,
92
- );
93
-
94
- expect(getByText('My Product')).toBeDefined();
95
- });
96
- });
@@ -1,104 +0,0 @@
1
- import React from 'react';
2
- import { ShowBase, useShowContext, type RaRecord, ResourceSchemaProvider } from '@strato-admin/core';
3
- import Container from '@cloudscape-design/components/container';
4
- import SpaceBetween from '@cloudscape-design/components/space-between';
5
- import { ShowHeader } from './ShowHeader';
6
- import KeyValuePairs from './KeyValuePairs';
7
-
8
- export interface ShowProps<_RecordType extends RaRecord = RaRecord> {
9
- children?: React.ReactNode;
10
- fieldSchema?: React.ReactNode;
11
- title?: React.ReactNode;
12
- actions?: React.ReactNode;
13
- resource?: string;
14
- id?: any;
15
- queryOptions?: any;
16
- include?: string[];
17
- exclude?: string[];
18
- }
19
-
20
- const ShowUI = ({
21
- children,
22
- resource,
23
- fieldSchema,
24
- title,
25
- actions,
26
- include,
27
- exclude,
28
- }: {
29
- children?: React.ReactNode;
30
- resource?: string;
31
- fieldSchema?: React.ReactNode;
32
- title?: React.ReactNode;
33
- actions?: React.ReactNode;
34
- include?: string[];
35
- exclude?: string[];
36
- }) => {
37
- const { record, isLoading } = useShowContext();
38
-
39
- if (isLoading || !record) {
40
- return null;
41
- }
42
-
43
- const finalChildren = children || <KeyValuePairs include={include} exclude={exclude} />;
44
-
45
- return (
46
- <ResourceSchemaProvider resource={resource} fieldSchema={fieldSchema}>
47
- <Container header={<ShowHeader title={title} actions={actions} />}>
48
- <SpaceBetween direction="vertical" size="l">
49
- {finalChildren}
50
- </SpaceBetween>
51
- </Container>
52
- </ResourceSchemaProvider>
53
- );
54
- };
55
-
56
- /**
57
- * A Show component that provides record context and a Cloudscape Container.
58
- *
59
- * @example
60
- * <Show>
61
- * <KeyValuePairs>
62
- * <TextField source="name" />
63
- * <NumberField source="price" />
64
- * </KeyValuePairs>
65
- * </Show>
66
- *
67
- * @example
68
- * // Using FieldSchema from context
69
- * <Show include={['name', 'price']} />
70
- *
71
- * @example
72
- * // Passing a custom field schema
73
- * <Show fieldSchema={<FieldSchema>...</FieldSchema>}>
74
- * <KeyValuePairs />
75
- * </Show>
76
- */
77
- export const Show = <RecordType extends RaRecord = RaRecord>({
78
- children,
79
- fieldSchema,
80
- title,
81
- actions,
82
- include,
83
- exclude,
84
- ...props
85
- }: ShowProps<RecordType>) => {
86
- return (
87
- <ShowBase {...props}>
88
- <ShowUI
89
- resource={props.resource}
90
- title={title}
91
- actions={actions}
92
- include={include}
93
- exclude={exclude}
94
- fieldSchema={fieldSchema}
95
- >
96
- {children}
97
- </ShowUI>
98
- </ShowBase>
99
- );
100
- };
101
-
102
- Show.Header = ShowHeader;
103
-
104
- export default Show;
@@ -1,35 +0,0 @@
1
- import React from 'react';
2
- import Header, { HeaderProps } from '@cloudscape-design/components/header';
3
- import SpaceBetween from '@cloudscape-design/components/space-between';
4
- import { useResourceContext, useShowContext, useTranslate, useResourceDefinitions } from '@strato-admin/core';
5
- import { EditButton } from '../button/EditButton';
6
-
7
- export interface ShowHeaderProps extends Omit<HeaderProps, 'children'> {
8
- title?: React.ReactNode;
9
- }
10
-
11
- export const ShowHeader = ({ title, actions, ...props }: ShowHeaderProps) => {
12
- const translate = useTranslate();
13
- const { record, defaultTitle } = useShowContext();
14
-
15
- const headerTitle = React.useMemo(() => {
16
- if (title !== undefined) {
17
- return typeof title === 'string' ? translate(title, { _: title }) : title;
18
- }
19
- return defaultTitle;
20
- }, [title, defaultTitle, translate]);
21
-
22
- const headerActions = actions || (
23
- <SpaceBetween direction="horizontal" size="xs">
24
- <EditButton record={record} />
25
- </SpaceBetween>
26
- );
27
-
28
- return (
29
- <Header variant="h2" {...props} actions={headerActions}>
30
- {headerTitle}
31
- </Header>
32
- );
33
- };
34
-
35
- export default ShowHeader;
@@ -1,147 +0,0 @@
1
-
2
- import { render } from '@testing-library/react';
3
- import { vi, describe, it, expect, beforeEach } from 'vitest';
4
- import { AttributeEditor } from './AttributeEditor';
5
- import { useFormContext, useFieldArray } from 'react-hook-form';
6
- import { useInput, useResourceContext } from '@strato-admin/core';
7
- import { useFormFieldContext } from './FormFieldContext';
8
-
9
- // Mock Cloudscape components
10
- vi.mock('@cloudscape-design/components/attribute-editor', () => ({
11
- default: ({ items, definition, onAddButtonClick, disableAddButton, hideAddButton }: any) => (
12
- <div data-testid="attribute-editor">
13
- {!hideAddButton && (
14
- <button onClick={onAddButtonClick} disabled={disableAddButton} data-testid="add-button">
15
- Add item
16
- </button>
17
- )}
18
- {items.map((item: any, index: number) => (
19
- <div key={index} data-testid={`item-${index}`}>
20
- {definition.map((def: any, defIndex: number) => (
21
- <div key={defIndex} data-testid={`field-${defIndex}`}>
22
- {def.control(item, index)}
23
- </div>
24
- ))}
25
- </div>
26
- ))}
27
- </div>
28
- ),
29
- }));
30
-
31
- vi.mock('@cloudscape-design/components/box', () => ({
32
- default: ({ children }: any) => <div>{children}</div>,
33
- }));
34
-
35
- // Mock ra-core hooks
36
- vi.mock('@strato-admin/core', () => ({
37
- useInput: vi.fn(),
38
- useResourceContext: vi.fn(),
39
- RecordContextProvider: ({ children }: any) => <>{children}</>,
40
- ArrayInputContext: {
41
- Provider: ({ children }: any) => <>{children}</>,
42
- },
43
- }));
44
-
45
- // Mock react-hook-form hooks
46
- vi.mock('react-hook-form', () => ({
47
- useFormContext: vi.fn(),
48
- useFieldArray: vi.fn(),
49
- }));
50
-
51
- // Mock local components and contexts
52
- vi.mock('./FormFieldContext', () => ({
53
- useFormFieldContext: vi.fn(),
54
- FormFieldContext: {
55
- Provider: ({ children }: any) => <>{children}</>,
56
- },
57
- }));
58
-
59
- vi.mock('./FieldTitle', () => ({
60
- FieldTitle: () => <div data-testid="field-title" />,
61
- }));
62
-
63
- vi.mock('./TextInput', () => ({
64
- default: ({ source }: any) => <div data-testid="text-input" data-source={source} />,
65
- }));
66
-
67
- vi.mock('./FormField', () => ({
68
- default: ({ children }: any) => <div data-testid="form-field">{children}</div>,
69
- }));
70
-
71
- describe('AttributeEditor', () => {
72
- const defaultFormContext = { control: {} };
73
- const defaultFieldArray = {
74
- fields: [{}],
75
- append: vi.fn(),
76
- remove: vi.fn(),
77
- };
78
- const defaultInput = {
79
- id: 'test',
80
- field: { name: 'test', value: [], onChange: vi.fn(), onBlur: vi.fn() },
81
- fieldState: { error: undefined, isTouched: false, isDirty: false },
82
- formState: { isSubmitted: false },
83
- isRequired: false,
84
- };
85
-
86
- beforeEach(() => {
87
- vi.mocked(useFormContext).mockReturnValue(defaultFormContext as any);
88
- vi.mocked(useFieldArray).mockReturnValue(defaultFieldArray as any);
89
- vi.mocked(useInput).mockReturnValue(defaultInput as any);
90
- vi.mocked(useFormFieldContext).mockReturnValue(undefined);
91
- vi.mocked(useResourceContext).mockReturnValue('test-resource');
92
- });
93
-
94
- it('should prefix source prop of immediate children', () => {
95
- const Child = ({ source }: any) => <div data-testid="child">{source}</div>;
96
-
97
- const { getByTestId } = render(
98
- <AttributeEditor source="products">
99
- <Child source="id" />
100
- </AttributeEditor>,
101
- );
102
-
103
- expect(getByTestId('child').textContent).toBe('products.0.id');
104
- });
105
-
106
- it('should NOT add source prop to children that do not have one', () => {
107
- const NonInput = ({ children }: any) => <div data-testid="non-input">{children}</div>;
108
-
109
- const { getByTestId } = render(
110
- <AttributeEditor source="products">
111
- <NonInput />
112
- </AttributeEditor>,
113
- );
114
-
115
- expect(getByTestId('non-input').getAttribute('source')).toBeNull();
116
- });
117
-
118
- it('should disable the add button when disableAddButton is true', () => {
119
- vi.mocked(useFieldArray).mockReturnValue({
120
- ...defaultFieldArray,
121
- fields: [],
122
- } as any);
123
-
124
- const { getByTestId } = render(
125
- <AttributeEditor source="products" disableAddButton>
126
- <div resource="id" />
127
- </AttributeEditor>,
128
- );
129
-
130
- expect(getByTestId('add-button').hasAttribute('disabled')).toBe(true);
131
- });
132
-
133
- it('should hide the add button when hideAddButton is true', () => {
134
- vi.mocked(useFieldArray).mockReturnValue({
135
- ...defaultFieldArray,
136
- fields: [],
137
- } as any);
138
-
139
- const { queryByTestId } = render(
140
- <AttributeEditor source="products" hideAddButton>
141
- <div resource="id" />
142
- </AttributeEditor>,
143
- );
144
-
145
- expect(queryByTestId('add-button')).toBeNull();
146
- });
147
- });