@object-ui/fields 17.3.0 → 17.6.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/CHANGELOG.md +1655 -0
- package/README.md +1 -12
- package/dist/FieldEditWidget.d.ts +23 -3
- package/dist/currency.d.ts +46 -0
- package/dist/field-type-alias.d.ts +35 -1
- package/dist/index.cjs +4 -4
- package/dist/index.css +651 -0
- package/dist/index.d.ts +474 -85
- package/dist/index.js +5418 -5023
- package/dist/widgets/AddressField.d.ts +4 -12
- package/dist/widgets/AutoNumberField.d.ts +1 -1
- package/dist/widgets/AvatarField.d.ts +1 -1
- package/dist/widgets/BooleanField.d.ts +1 -1
- package/dist/widgets/CapabilityMultiSelectField.d.ts +1 -1
- package/dist/widgets/CheckboxesField.d.ts +1 -1
- package/dist/widgets/CodeField.d.ts +1 -1
- package/dist/widgets/ColorField.d.ts +1 -1
- package/dist/widgets/CurrencyField.d.ts +1 -1
- package/dist/widgets/DateField.d.ts +1 -1
- package/dist/widgets/DateTimeField.d.ts +1 -1
- package/dist/widgets/EmailField.d.ts +1 -1
- package/dist/widgets/FileField.d.ts +18 -2
- package/dist/widgets/FilterConditionField.d.ts +28 -1
- package/dist/widgets/FormulaField.d.ts +1 -1
- package/dist/widgets/FullscreenFieldEditor.d.ts +49 -152
- package/dist/widgets/GeolocationField.d.ts +1 -1
- package/dist/widgets/GridField.d.ts +68 -6
- package/dist/widgets/ImageField.d.ts +1 -1
- package/dist/widgets/LocationField.d.ts +1 -1
- package/dist/widgets/LookupField.d.ts +1 -1
- package/dist/widgets/MasterDetailField.d.ts +1 -1
- package/dist/widgets/MultiSelectField.d.ts +1 -1
- package/dist/widgets/NumberField.d.ts +1 -1
- package/dist/widgets/ObjectField.d.ts +1 -1
- package/dist/widgets/ObjectRefField.d.ts +1 -1
- package/dist/widgets/OptionsEmptyState.d.ts +21 -1
- package/dist/widgets/PasswordField.d.ts +1 -1
- package/dist/widgets/PercentField.d.ts +1 -1
- package/dist/widgets/PhoneField.d.ts +1 -1
- package/dist/widgets/QRCodeField.d.ts +1 -1
- package/dist/widgets/RadioField.d.ts +1 -1
- package/dist/widgets/RatingField.d.ts +1 -1
- package/dist/widgets/RecipientPickerField.d.ts +1 -1
- package/dist/widgets/RecordPickerDialog.d.ts +34 -10
- package/dist/widgets/RichTextField.d.ts +37 -1
- package/dist/widgets/SelectField.d.ts +26 -6
- package/dist/widgets/SignatureField.d.ts +32 -2
- package/dist/widgets/SliderField.d.ts +37 -2
- package/dist/widgets/SummaryField.d.ts +1 -1
- package/dist/widgets/TagsField.d.ts +1 -1
- package/dist/widgets/TextAreaField.d.ts +6 -2
- package/dist/widgets/TextField.d.ts +1 -1
- package/dist/widgets/TimeField.d.ts +1 -1
- package/dist/widgets/UrlField.d.ts +1 -1
- package/dist/widgets/UserField.d.ts +1 -1
- package/dist/widgets/VectorField.d.ts +1 -1
- package/dist/widgets/_cell-renderer-bridge.d.ts +1 -1
- package/dist/widgets/address-format.d.ts +88 -0
- package/dist/widgets/file-size-guard.d.ts +41 -0
- package/dist/widgets/lookupColumnDisplay.d.ts +93 -0
- package/dist/widgets/nativeDateValue.d.ts +37 -0
- package/dist/widgets/richTextDisplay.d.ts +80 -0
- package/dist/widgets/toDomProps.d.ts +30 -10
- package/dist/widgets/toHostGroupProps.d.ts +189 -0
- package/dist/widgets/types.d.ts +8 -3
- package/dist/widgets/useRecordQuery.d.ts +7 -1
- package/package.json +17 -14
- package/dist/FieldEditWidget.test.d.ts +0 -8
- package/dist/__tests__/DateCellRenderer.test.d.ts +0 -0
- package/dist/__tests__/NumberCellRenderer.test.d.ts +0 -0
- package/dist/__tests__/cell-truncation.test.d.ts +0 -0
- package/dist/__tests__/field-carrier-sdui.test.d.ts +0 -0
- package/dist/__tests__/lookupCellDisplayField.test.d.ts +0 -0
- package/dist/__tests__/lookupCellDisplayName.test.d.ts +0 -0
- package/dist/__tests__/lookupCellReferenceKey.test.d.ts +0 -0
- package/dist/__tests__/registry-collision.test.d.ts +0 -0
- package/dist/__tests__/resolveFieldCurrency.test.d.ts +0 -1
- package/dist/__tests__/spec-symbol-batch7.test.d.ts +0 -8
- package/dist/__tests__/validation-feedback.test.d.ts +0 -0
- package/dist/__tests__/widget-aria-invalid-e2e.test.d.ts +0 -0
- package/dist/__tests__/widget-aria-invalid-registry-e2e.test.d.ts +0 -0
- package/dist/__tests__/widget-dom-leak-e2e.test.d.ts +0 -0
- package/dist/__tests__/widget-props-contract.test.d.ts +0 -8
- package/dist/coerce-safe-value.test.d.ts +0 -1
- package/dist/complex-widgets.test.d.ts +0 -1
- package/dist/datetime-widgets.test.d.ts +0 -1
- package/dist/field-type-coverage.test.d.ts +0 -1
- package/dist/standard-widgets.test.d.ts +0 -0
- package/dist/widgets/AddressField.uniqueIds.test.d.ts +0 -0
- package/dist/widgets/CapabilityMultiSelectField.test.d.ts +0 -0
- package/dist/widgets/CharacterCount.d.ts +0 -56
- package/dist/widgets/CheckboxesField.cascade.test.d.ts +0 -0
- package/dist/widgets/GeolocationField.uniqueIds.test.d.ts +0 -0
- package/dist/widgets/GridField.test.d.ts +0 -1
- package/dist/widgets/ImageLightbox.test.d.ts +0 -1
- package/dist/widgets/LookupField.dependsOn.test.d.ts +0 -8
- package/dist/widgets/LookupField.gateHintLabel.test.d.ts +0 -8
- package/dist/widgets/LookupField.hydration.test.d.ts +0 -1
- package/dist/widgets/LookupField.idField.test.d.ts +0 -1
- package/dist/widgets/MultiSelectField.cascade.test.d.ts +0 -0
- package/dist/widgets/OptionsEmptyState.no-provider.test.d.ts +0 -0
- package/dist/widgets/OptionsEmptyState.test.d.ts +0 -0
- package/dist/widgets/PeoplePicker.test.d.ts +0 -8
- package/dist/widgets/PeoplePickerComponents.test.d.ts +0 -8
- package/dist/widgets/RadioField.cascade.test.d.ts +0 -0
- package/dist/widgets/RecipientPickerField.test.d.ts +0 -0
- package/dist/widgets/RecordPickerDialog.filterOptions.test.d.ts +0 -8
- package/dist/widgets/RecordPickerDialog.selectLabel.test.d.ts +0 -8
- package/dist/widgets/SelectField.cascade.test.d.ts +0 -0
- package/dist/widgets/TagsField.placeholder.no-provider.test.d.ts +0 -0
- package/dist/widgets/TagsField.placeholder.test.d.ts +0 -0
- package/dist/widgets/UserFieldPicker.test.d.ts +0 -8
- package/dist/widgets/__tests__/FilterConditionField.matchAll.test.d.ts +0 -8
- package/dist/widgets/__tests__/FilterConditionField.operators.test.d.ts +0 -8
- package/dist/widgets/__tests__/FullscreenFieldEditor.i18n.test.d.ts +0 -0
- package/dist/widgets/__tests__/FullscreenFieldEditor.no-provider.test.d.ts +0 -0
- package/dist/widgets/__tests__/RichTextField.fullscreenDisabled.test.d.ts +0 -0
- package/dist/widgets/__tests__/RichTextField.mobileFullscreen.test.d.ts +0 -0
- package/dist/widgets/__tests__/TextAreaField.characterCount.announcements.test.d.ts +0 -0
- package/dist/widgets/__tests__/TextAreaField.characterCount.i18n.test.d.ts +0 -0
- package/dist/widgets/__tests__/TextAreaField.characterCount.no-provider.test.d.ts +0 -0
- package/dist/widgets/__tests__/TextAreaField.fullscreenCharacterCount.i18n.test.d.ts +0 -0
- package/dist/widgets/__tests__/TextAreaField.fullscreenCharacterCount.test.d.ts +0 -0
- package/dist/widgets/__tests__/TextAreaField.fullscreenDisabled.test.d.ts +0 -0
- package/dist/widgets/__tests__/TextAreaField.mobileFullscreen.test.d.ts +0 -0
- package/dist/widgets/deriveLookupColumns.test.d.ts +0 -1
- package/dist/widgets/file-value.test.d.ts +0 -1
- package/dist/widgets/personDisplay.test.d.ts +0 -8
- package/dist/widgets/recentLookups.test.d.ts +0 -1
- package/dist/widgets/useRecordQuery.test.d.ts +0 -8
- package/dist/widgets/useUploadingSignal.test.d.ts +0 -1
- package/src/FieldEditWidget.test.ts +0 -133
- package/src/FieldEditWidget.tsx +0 -191
- package/src/__tests__/DateCellRenderer.test.tsx +0 -73
- package/src/__tests__/NumberCellRenderer.test.tsx +0 -60
- package/src/__tests__/cell-truncation.test.tsx +0 -96
- package/src/__tests__/field-carrier-sdui.test.tsx +0 -169
- package/src/__tests__/lookupCellDisplayField.test.tsx +0 -107
- package/src/__tests__/lookupCellDisplayName.test.tsx +0 -119
- package/src/__tests__/lookupCellReferenceKey.test.tsx +0 -57
- package/src/__tests__/registry-collision.test.ts +0 -91
- package/src/__tests__/resolveFieldCurrency.test.ts +0 -20
- package/src/__tests__/spec-symbol-batch7.test.ts +0 -126
- package/src/__tests__/validation-feedback.test.tsx +0 -361
- package/src/__tests__/widget-aria-invalid-e2e.test.tsx +0 -265
- package/src/__tests__/widget-aria-invalid-registry-e2e.test.tsx +0 -338
- package/src/__tests__/widget-dom-leak-e2e.test.tsx +0 -598
- package/src/__tests__/widget-props-contract.test.tsx +0 -142
- package/src/coerce-safe-value.test.ts +0 -34
- package/src/complex-widgets.test.tsx +0 -908
- package/src/currency.ts +0 -14
- package/src/datetime-widgets.test.tsx +0 -93
- package/src/field-type-alias.ts +0 -100
- package/src/field-type-coverage.test.ts +0 -67
- package/src/index.tsx +0 -2503
- package/src/standard-widgets.test.tsx +0 -357
- package/src/widgets/AddressField.tsx +0 -132
- package/src/widgets/AddressField.uniqueIds.test.tsx +0 -92
- package/src/widgets/AutoNumberField.tsx +0 -18
- package/src/widgets/AvatarField.tsx +0 -117
- package/src/widgets/BooleanField.tsx +0 -52
- package/src/widgets/CapabilityMultiSelectField.test.tsx +0 -168
- package/src/widgets/CapabilityMultiSelectField.tsx +0 -229
- package/src/widgets/CharacterCount.tsx +0 -263
- package/src/widgets/CheckboxesField.cascade.test.tsx +0 -143
- package/src/widgets/CheckboxesField.tsx +0 -136
- package/src/widgets/CodeField.tsx +0 -41
- package/src/widgets/ColorField.tsx +0 -53
- package/src/widgets/CurrencyField.tsx +0 -95
- package/src/widgets/DateField.tsx +0 -31
- package/src/widgets/DateTimeField.tsx +0 -37
- package/src/widgets/EmailField.tsx +0 -37
- package/src/widgets/FileField.tsx +0 -494
- package/src/widgets/FilterConditionField.tsx +0 -454
- package/src/widgets/FormulaField.tsx +0 -33
- package/src/widgets/FullscreenFieldEditor.tsx +0 -271
- package/src/widgets/GeolocationField.tsx +0 -167
- package/src/widgets/GeolocationField.uniqueIds.test.tsx +0 -88
- package/src/widgets/GridField.test.tsx +0 -406
- package/src/widgets/GridField.tsx +0 -966
- package/src/widgets/ImageCropperDialog.tsx +0 -245
- package/src/widgets/ImageField.tsx +0 -255
- package/src/widgets/ImageLightbox.test.tsx +0 -52
- package/src/widgets/ImageLightbox.tsx +0 -108
- package/src/widgets/LocationField.tsx +0 -57
- package/src/widgets/LookupField.dependsOn.test.tsx +0 -233
- package/src/widgets/LookupField.gateHintLabel.test.tsx +0 -135
- package/src/widgets/LookupField.hydration.test.tsx +0 -136
- package/src/widgets/LookupField.idField.test.tsx +0 -61
- package/src/widgets/LookupField.tsx +0 -1291
- package/src/widgets/MarkdownContent.tsx +0 -19
- package/src/widgets/MasterDetailField.tsx +0 -131
- package/src/widgets/MultiSelectField.cascade.test.tsx +0 -143
- package/src/widgets/MultiSelectField.tsx +0 -142
- package/src/widgets/NumberField.tsx +0 -49
- package/src/widgets/ObjectField.tsx +0 -94
- package/src/widgets/ObjectRefField.tsx +0 -121
- package/src/widgets/OptionsEmptyState.no-provider.test.tsx +0 -88
- package/src/widgets/OptionsEmptyState.test.tsx +0 -169
- package/src/widgets/OptionsEmptyState.tsx +0 -83
- package/src/widgets/PasswordField.tsx +0 -49
- package/src/widgets/PeoplePicker.test.tsx +0 -360
- package/src/widgets/PeoplePicker.tsx +0 -579
- package/src/widgets/PeoplePickerComponents.test.tsx +0 -104
- package/src/widgets/PercentField.tsx +0 -95
- package/src/widgets/PersonRow.tsx +0 -117
- package/src/widgets/PhoneField.tsx +0 -37
- package/src/widgets/QRCodeField.tsx +0 -103
- package/src/widgets/RadioField.cascade.test.tsx +0 -141
- package/src/widgets/RadioField.tsx +0 -111
- package/src/widgets/RatingField.tsx +0 -81
- package/src/widgets/RecipientPickerField.test.tsx +0 -157
- package/src/widgets/RecipientPickerField.tsx +0 -188
- package/src/widgets/RecordPickerDialog.filterOptions.test.tsx +0 -611
- package/src/widgets/RecordPickerDialog.selectLabel.test.tsx +0 -112
- package/src/widgets/RecordPickerDialog.tsx +0 -1316
- package/src/widgets/RichTextField.tsx +0 -176
- package/src/widgets/SelectField.cascade.test.tsx +0 -138
- package/src/widgets/SelectField.tsx +0 -162
- package/src/widgets/SelectionTray.tsx +0 -110
- package/src/widgets/SignatureField.tsx +0 -140
- package/src/widgets/SliderField.tsx +0 -39
- package/src/widgets/SummaryField.tsx +0 -31
- package/src/widgets/TagsField.placeholder.no-provider.test.tsx +0 -68
- package/src/widgets/TagsField.placeholder.test.tsx +0 -95
- package/src/widgets/TagsField.tsx +0 -88
- package/src/widgets/TextAreaField.tsx +0 -213
- package/src/widgets/TextField.tsx +0 -45
- package/src/widgets/TimeField.tsx +0 -31
- package/src/widgets/UrlField.tsx +0 -46
- package/src/widgets/UserField.tsx +0 -58
- package/src/widgets/UserFieldPicker.test.tsx +0 -78
- package/src/widgets/VectorField.tsx +0 -29
- package/src/widgets/__tests__/FilterConditionField.matchAll.test.ts +0 -66
- package/src/widgets/__tests__/FilterConditionField.operators.test.ts +0 -142
- package/src/widgets/__tests__/FullscreenFieldEditor.i18n.test.tsx +0 -248
- package/src/widgets/__tests__/FullscreenFieldEditor.no-provider.test.tsx +0 -116
- package/src/widgets/__tests__/RichTextField.fullscreenDisabled.test.tsx +0 -244
- package/src/widgets/__tests__/RichTextField.mobileFullscreen.test.tsx +0 -195
- package/src/widgets/__tests__/TextAreaField.characterCount.announcements.test.tsx +0 -417
- package/src/widgets/__tests__/TextAreaField.characterCount.i18n.test.tsx +0 -287
- package/src/widgets/__tests__/TextAreaField.characterCount.no-provider.test.tsx +0 -160
- package/src/widgets/__tests__/TextAreaField.fullscreenCharacterCount.i18n.test.tsx +0 -161
- package/src/widgets/__tests__/TextAreaField.fullscreenCharacterCount.test.tsx +0 -346
- package/src/widgets/__tests__/TextAreaField.fullscreenDisabled.test.tsx +0 -246
- package/src/widgets/__tests__/TextAreaField.mobileFullscreen.test.tsx +0 -175
- package/src/widgets/_cell-renderer-bridge.ts +0 -19
- package/src/widgets/deriveLookupColumns.test.ts +0 -112
- package/src/widgets/deriveLookupColumns.ts +0 -108
- package/src/widgets/file-value.test.ts +0 -230
- package/src/widgets/file-value.ts +0 -246
- package/src/widgets/openNativePicker.ts +0 -18
- package/src/widgets/personDisplay.test.ts +0 -113
- package/src/widgets/personDisplay.ts +0 -92
- package/src/widgets/recentLookups.test.ts +0 -45
- package/src/widgets/recentLookups.ts +0 -47
- package/src/widgets/toDomProps.ts +0 -175
- package/src/widgets/types.ts +0 -242
- package/src/widgets/useCascadingOptions.ts +0 -46
- package/src/widgets/useFieldTranslation.ts +0 -150
- package/src/widgets/useRecordQuery.test.ts +0 -174
- package/src/widgets/useRecordQuery.ts +0 -264
- package/src/widgets/useUploadingSignal.test.tsx +0 -62
- package/src/widgets/useUploadingSignal.ts +0 -20
- package/src/withFieldCarrier.tsx +0 -75
package/src/currency.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ObjectUI
|
|
3
|
-
* Copyright (c) 2024-present ObjectStack Inc.
|
|
4
|
-
*
|
|
5
|
-
* Licensed under the MIT license found in the LICENSE file.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* `resolveFieldCurrency` now lives in `@object-ui/i18n` (co-located with
|
|
10
|
-
* `useLocalization`, which supplies the tenant default). This module re-exports
|
|
11
|
-
* it so the long-standing `@object-ui/fields` import path keeps working for
|
|
12
|
-
* every field/cell renderer that already depends on it.
|
|
13
|
-
*/
|
|
14
|
-
export { resolveFieldCurrency } from '@object-ui/i18n';
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
import { render, screen, fireEvent } from '@testing-library/react';
|
|
2
|
-
import { describe, it, expect, vi } from 'vitest';
|
|
3
|
-
import { DateField } from './widgets/DateField';
|
|
4
|
-
import { DateTimeField } from './widgets/DateTimeField';
|
|
5
|
-
import { TimeField } from './widgets/TimeField';
|
|
6
|
-
import type { FieldWidgetComponentProps } from './widgets/types';
|
|
7
|
-
|
|
8
|
-
const mockField = {
|
|
9
|
-
name: 'test_field',
|
|
10
|
-
label: 'Test Field',
|
|
11
|
-
type: 'date',
|
|
12
|
-
} as any;
|
|
13
|
-
|
|
14
|
-
const baseProps: FieldWidgetComponentProps<string> = {
|
|
15
|
-
field: mockField,
|
|
16
|
-
value: '',
|
|
17
|
-
onChange: vi.fn(),
|
|
18
|
-
readonly: false,
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
describe('Date/Time Widgets', () => {
|
|
22
|
-
describe('DateField', () => {
|
|
23
|
-
it('renders date input in edit mode', () => {
|
|
24
|
-
const { container } = render(<DateField {...baseProps} />);
|
|
25
|
-
const dateInput = container.querySelector('input[type="date"]');
|
|
26
|
-
expect(dateInput).toBeInTheDocument();
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
it('calls onChange when value changes', () => {
|
|
30
|
-
const { container } = render(<DateField {...baseProps} />);
|
|
31
|
-
const input = container.querySelector('input[type="date"]') as HTMLInputElement;
|
|
32
|
-
fireEvent.change(input, { target: { value: '2023-01-01' } });
|
|
33
|
-
expect(baseProps.onChange).toHaveBeenCalledWith('2023-01-01');
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
it('renders formatted date in readonly mode', () => {
|
|
37
|
-
render(<DateField {...baseProps} readonly value="2023-01-01" />);
|
|
38
|
-
const date = new Date('2023-01-01');
|
|
39
|
-
expect(screen.getByText(date.toLocaleDateString())).toBeInTheDocument();
|
|
40
|
-
expect(document.querySelector('input')).not.toBeInTheDocument();
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
it('renders dash for empty readonly value', () => {
|
|
44
|
-
render(<DateField {...baseProps} readonly value={''} />);
|
|
45
|
-
expect(screen.getByText('—')).toBeInTheDocument();
|
|
46
|
-
});
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
describe('DateTimeField', () => {
|
|
50
|
-
it('renders datetime-local input in edit mode', () => {
|
|
51
|
-
const { container } = render(<DateTimeField {...baseProps} />);
|
|
52
|
-
const input = container.querySelector('input[type="datetime-local"]');
|
|
53
|
-
expect(input).toBeInTheDocument();
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
it('calls onChange when value changes', () => {
|
|
57
|
-
const { container } = render(<DateTimeField {...baseProps} />);
|
|
58
|
-
const input = container.querySelector('input[type="datetime-local"]') as HTMLInputElement;
|
|
59
|
-
fireEvent.change(input, { target: { value: '2023-01-01T12:00' } });
|
|
60
|
-
expect(baseProps.onChange).toHaveBeenCalledWith('2023-01-01T12:00');
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
it('renders formatted datetime in readonly mode', () => {
|
|
64
|
-
const val = '2023-01-01T12:00:00.000Z';
|
|
65
|
-
render(<DateTimeField {...baseProps} readonly value={val} />);
|
|
66
|
-
const date = new Date(val);
|
|
67
|
-
const span = screen.getByText((content) => {
|
|
68
|
-
return content.includes(date.toLocaleDateString());
|
|
69
|
-
});
|
|
70
|
-
expect(span).toBeInTheDocument();
|
|
71
|
-
});
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
describe('TimeField', () => {
|
|
75
|
-
it('renders time input in edit mode', () => {
|
|
76
|
-
const { container } = render(<TimeField {...baseProps} />);
|
|
77
|
-
const input = container.querySelector('input[type="time"]');
|
|
78
|
-
expect(input).toBeInTheDocument();
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
it('calls onChange when value changes', () => {
|
|
82
|
-
const { container } = render(<TimeField {...baseProps} />);
|
|
83
|
-
const input = container.querySelector('input[type="time"]') as HTMLInputElement;
|
|
84
|
-
fireEvent.change(input, { target: { value: '14:30' } });
|
|
85
|
-
expect(baseProps.onChange).toHaveBeenCalledWith('14:30');
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
it('renders value directly in readonly mode', () => {
|
|
89
|
-
render(<TimeField {...baseProps} readonly value="14:30" />);
|
|
90
|
-
expect(screen.getByText('14:30')).toBeInTheDocument();
|
|
91
|
-
});
|
|
92
|
-
});
|
|
93
|
-
});
|
package/src/field-type-alias.ts
DELETED
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ObjectUI
|
|
3
|
-
* Copyright (c) 2024-present ObjectStack Inc.
|
|
4
|
-
*
|
|
5
|
-
* This source code is licensed under the MIT license found in the
|
|
6
|
-
* LICENSE file in the root directory of this source tree.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Map field type to form component type
|
|
11
|
-
*
|
|
12
|
-
* @param fieldType - The ObjectQL field type identifier to convert
|
|
13
|
-
* (for example: `"text"`, `"number"`, `"date"`, `"lookup"`).
|
|
14
|
-
* @returns The normalized form field type string used in the form schema
|
|
15
|
-
* (for example: `"input"`, `"textarea"`, `"date-picker"`, `"select"`).
|
|
16
|
-
*/
|
|
17
|
-
export function mapFieldTypeToFormType(fieldType: string): string {
|
|
18
|
-
const typeMap: Record<string, string> = {
|
|
19
|
-
// Text-based fields
|
|
20
|
-
text: 'field:text',
|
|
21
|
-
textarea: 'field:textarea',
|
|
22
|
-
markdown: 'field:markdown', // Markdown editor (fallback to textarea)
|
|
23
|
-
html: 'field:html', // Rich text editor (fallback to textarea)
|
|
24
|
-
richtext: 'field:richtext', // WYSIWYG rich-text editor
|
|
25
|
-
secret: 'field:password', // encrypted-at-rest value — mask input like a password
|
|
26
|
-
|
|
27
|
-
// Numeric fields
|
|
28
|
-
number: 'field:number',
|
|
29
|
-
currency: 'field:currency',
|
|
30
|
-
percent: 'field:percent',
|
|
31
|
-
slider: 'field:slider',
|
|
32
|
-
progress: 'field:slider', // bounded 0..100 progress — edit via slider
|
|
33
|
-
rating: 'field:rating',
|
|
34
|
-
|
|
35
|
-
// Date/Time fields
|
|
36
|
-
date: 'field:date',
|
|
37
|
-
datetime: 'field:datetime',
|
|
38
|
-
time: 'field:time',
|
|
39
|
-
|
|
40
|
-
// Boolean
|
|
41
|
-
boolean: 'field:boolean',
|
|
42
|
-
toggle: 'field:boolean', // toggle is a boolean rendered as a switch
|
|
43
|
-
|
|
44
|
-
// Selection fields
|
|
45
|
-
select: 'field:select',
|
|
46
|
-
multiselect: 'field:multiselect',
|
|
47
|
-
radio: 'field:radio',
|
|
48
|
-
checkboxes: 'field:checkboxes',
|
|
49
|
-
tags: 'field:tags',
|
|
50
|
-
lookup: 'field:lookup',
|
|
51
|
-
master_detail: 'field:master_detail',
|
|
52
|
-
tree: 'field:lookup', // hierarchical reference — pick the parent via a lookup
|
|
53
|
-
// `user` is a lookup specialized to sys_user; `owner` mirrors it (record
|
|
54
|
-
// ownership). Both render via the UserField person-picker (delegates to the
|
|
55
|
-
// lookup picker). Without these they would fall through to `field:text`.
|
|
56
|
-
user: 'field:user',
|
|
57
|
-
owner: 'field:owner',
|
|
58
|
-
|
|
59
|
-
// Contact fields
|
|
60
|
-
email: 'field:email',
|
|
61
|
-
phone: 'field:phone',
|
|
62
|
-
url: 'field:url',
|
|
63
|
-
|
|
64
|
-
// File / media fields
|
|
65
|
-
file: 'field:file',
|
|
66
|
-
image: 'field:image',
|
|
67
|
-
avatar: 'field:avatar',
|
|
68
|
-
video: 'field:file', // uploads as a file
|
|
69
|
-
audio: 'field:file', // uploads as a file
|
|
70
|
-
signature: 'field:signature',
|
|
71
|
-
|
|
72
|
-
// Special / enhanced fields
|
|
73
|
-
password: 'field:password',
|
|
74
|
-
location: 'field:location', // Location/map field (fallback to input)
|
|
75
|
-
geolocation: 'field:geolocation',
|
|
76
|
-
address: 'field:address',
|
|
77
|
-
color: 'field:color',
|
|
78
|
-
code: 'field:code',
|
|
79
|
-
json: 'field:code', // JSON edited in the code editor
|
|
80
|
-
qrcode: 'field:qrcode',
|
|
81
|
-
vector: 'field:vector',
|
|
82
|
-
|
|
83
|
-
// Embedded structured values (stored as JSON on the row)
|
|
84
|
-
object: 'field:object',
|
|
85
|
-
composite: 'field:object', // embedded object
|
|
86
|
-
record: 'field:object', // name-keyed map
|
|
87
|
-
repeater: 'field:grid', // embedded array of rows
|
|
88
|
-
|
|
89
|
-
// Auto-generated/computed fields (typically read-only)
|
|
90
|
-
formula: 'field:formula',
|
|
91
|
-
summary: 'field:summary',
|
|
92
|
-
// `@objectstack/spec` spells this `autonumber`; the widget map key is
|
|
93
|
-
// `auto_number`. Map both spellings so a spec-typed field/param doesn't
|
|
94
|
-
// fall through to the plain text input.
|
|
95
|
-
autonumber: 'field:auto_number',
|
|
96
|
-
auto_number: 'field:auto_number',
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
return typeMap[fieldType] || 'field:text';
|
|
100
|
-
}
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ObjectUI
|
|
3
|
-
* Copyright (c) 2024-present ObjectStack Inc.
|
|
4
|
-
*
|
|
5
|
-
* Regression guard for the field-type → renderer registries. These mappings
|
|
6
|
-
* regressed once already: ~25 specialized field types silently fell back to a
|
|
7
|
-
* plain text input (form) and the raw text cell renderer (read), because the
|
|
8
|
-
* mapping tables were incomplete. This test locks them in so a dropped entry
|
|
9
|
-
* fails CI instead of shipping a broken widget.
|
|
10
|
-
*/
|
|
11
|
-
import { describe, it, expect } from 'vitest';
|
|
12
|
-
import { mapFieldTypeToFormType, getCellRenderer, TextCellRenderer } from './index';
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Field types that MUST resolve to a dedicated form widget — never the
|
|
16
|
-
* `field:text` fallback. (Plain text-ish types like text/textarea are
|
|
17
|
-
* intentionally excluded.)
|
|
18
|
-
*/
|
|
19
|
-
const FORM_WIDGET_TYPES = [
|
|
20
|
-
'textarea', 'email', 'url', 'phone', 'password', 'secret',
|
|
21
|
-
'markdown', 'html', 'richtext',
|
|
22
|
-
'number', 'currency', 'percent', 'slider', 'progress', 'rating',
|
|
23
|
-
'date', 'datetime', 'time',
|
|
24
|
-
'boolean', 'toggle',
|
|
25
|
-
'select', 'multiselect', 'radio', 'checkboxes', 'tags',
|
|
26
|
-
'lookup', 'master_detail', 'tree',
|
|
27
|
-
'file', 'image', 'avatar', 'video', 'audio', 'signature',
|
|
28
|
-
'location', 'geolocation', 'address', 'color', 'code', 'json', 'qrcode', 'vector',
|
|
29
|
-
'object', 'composite', 'record', 'repeater',
|
|
30
|
-
// `autonumber` is the spec `FieldType` spelling; `auto_number` is the widget
|
|
31
|
-
// map key. Both must resolve to the AutoNumber widget, not text.
|
|
32
|
-
'formula', 'summary', 'auto_number', 'autonumber',
|
|
33
|
-
];
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Field types that MUST resolve to a dedicated read/cell renderer — never the
|
|
37
|
-
* generic text cell renderer. (markdown/html/richtext render formatted;
|
|
38
|
-
* code/qrcode/time legitimately stay textual and are excluded.)
|
|
39
|
-
*/
|
|
40
|
-
const CELL_RENDERER_TYPES = [
|
|
41
|
-
'email', 'url', 'phone', 'number', 'currency', 'percent', 'progress',
|
|
42
|
-
'boolean', 'toggle', 'date', 'datetime',
|
|
43
|
-
'select', 'multiselect', 'radio', 'checkboxes', 'tags',
|
|
44
|
-
'lookup', 'master_detail', 'tree',
|
|
45
|
-
'file', 'video', 'audio', 'image', 'avatar', 'signature',
|
|
46
|
-
'markdown', 'html', 'richtext',
|
|
47
|
-
'location', 'geolocation', 'address', 'color', 'json',
|
|
48
|
-
'formula', 'summary', 'user', 'owner',
|
|
49
|
-
];
|
|
50
|
-
|
|
51
|
-
describe('field-type renderer coverage (regression guard)', () => {
|
|
52
|
-
it.each(FORM_WIDGET_TYPES)('maps "%s" to a dedicated form widget (not field:text)', (type) => {
|
|
53
|
-
const widget = mapFieldTypeToFormType(type);
|
|
54
|
-
expect(widget).toMatch(/^field:/);
|
|
55
|
-
expect(widget).not.toBe('field:text');
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
it.each(CELL_RENDERER_TYPES)('resolves "%s" to a dedicated cell renderer (not TextCellRenderer)', (type) => {
|
|
59
|
-
const renderer = getCellRenderer(type);
|
|
60
|
-
expect(renderer).toBeTypeOf('function');
|
|
61
|
-
expect(renderer).not.toBe(TextCellRenderer);
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
it('falls back to field:text for unknown types', () => {
|
|
65
|
-
expect(mapFieldTypeToFormType('something-unknown')).toBe('field:text');
|
|
66
|
-
});
|
|
67
|
-
});
|