@dxos/react-ui-form 0.8.4-main.5acf9ea → 0.8.4-main.5ea62a8

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 (94) hide show
  1. package/dist/lib/browser/index.mjs +556 -508
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/node-esm/index.mjs +556 -508
  5. package/dist/lib/node-esm/index.mjs.map +4 -4
  6. package/dist/lib/node-esm/meta.json +1 -1
  7. package/dist/types/src/components/ControlSection/ControlSection.d.ts +2 -2
  8. package/dist/types/src/components/ControlSection/ControlSection.d.ts.map +1 -1
  9. package/dist/types/src/components/ControlSection/ControlSection.stories.d.ts +79 -4
  10. package/dist/types/src/components/ControlSection/ControlSection.stories.d.ts.map +1 -1
  11. package/dist/types/src/components/FieldEditor/FieldEditor.d.ts +2 -2
  12. package/dist/types/src/components/FieldEditor/FieldEditor.d.ts.map +1 -1
  13. package/dist/types/src/components/FieldEditor/FieldEditor.stories.d.ts +74 -4
  14. package/dist/types/src/components/FieldEditor/FieldEditor.stories.d.ts.map +1 -1
  15. package/dist/types/src/components/Form/ArrayField.d.ts +2 -2
  16. package/dist/types/src/components/Form/ArrayField.d.ts.map +1 -1
  17. package/dist/types/src/components/Form/Defaults.d.ts +5 -5
  18. package/dist/types/src/components/Form/Defaults.d.ts.map +1 -1
  19. package/dist/types/src/components/Form/Form.d.ts +5 -4
  20. package/dist/types/src/components/Form/Form.d.ts.map +1 -1
  21. package/dist/types/src/components/Form/Form.stories.d.ts +126 -30
  22. package/dist/types/src/components/Form/Form.stories.d.ts.map +1 -1
  23. package/dist/types/src/components/Form/FormActions.d.ts.map +1 -1
  24. package/dist/types/src/components/Form/FormContent.d.ts +16 -10
  25. package/dist/types/src/components/Form/FormContent.d.ts.map +1 -1
  26. package/dist/types/src/components/Form/FormContext.d.ts +1 -1
  27. package/dist/types/src/components/Form/FormContext.d.ts.map +1 -1
  28. package/dist/types/src/components/Form/Input.d.ts +4 -1
  29. package/dist/types/src/components/Form/Input.d.ts.map +1 -1
  30. package/dist/types/src/components/Form/RefField.d.ts +10 -4
  31. package/dist/types/src/components/Form/RefField.d.ts.map +1 -1
  32. package/dist/types/src/components/Form/custom/GeoPointInput.d.ts +1 -1
  33. package/dist/types/src/components/Form/custom/GeoPointInput.d.ts.map +1 -1
  34. package/dist/types/src/components/Form/custom/SelectOptionsInput.d.ts +1 -1
  35. package/dist/types/src/components/Form/custom/SelectOptionsInput.d.ts.map +1 -1
  36. package/dist/types/src/components/Form/custom/SelectOptionsInput.stories.d.ts +74 -3
  37. package/dist/types/src/components/Form/custom/SelectOptionsInput.stories.d.ts.map +1 -1
  38. package/dist/types/src/components/Form/custom/TupleInput.d.ts +1 -1
  39. package/dist/types/src/components/Form/factory.d.ts.map +1 -1
  40. package/dist/types/src/components/ViewEditor/ViewEditor.d.ts +1 -1
  41. package/dist/types/src/components/ViewEditor/ViewEditor.d.ts.map +1 -1
  42. package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts +73 -3
  43. package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts.map +1 -1
  44. package/dist/types/src/components/index.d.ts +0 -1
  45. package/dist/types/src/components/index.d.ts.map +1 -1
  46. package/dist/types/src/components/testing.d.ts +6 -3
  47. package/dist/types/src/components/testing.d.ts.map +1 -1
  48. package/dist/types/src/hooks/useForm.d.ts +1 -1
  49. package/dist/types/src/hooks/useForm.d.ts.map +1 -1
  50. package/dist/types/src/translations.d.ts +9 -4
  51. package/dist/types/src/translations.d.ts.map +1 -1
  52. package/dist/types/src/util/field.d.ts.map +1 -1
  53. package/dist/types/tsconfig.tsbuildinfo +1 -1
  54. package/package.json +34 -32
  55. package/src/components/ControlSection/ControlSection.stories.tsx +8 -10
  56. package/src/components/ControlSection/ControlSection.tsx +26 -12
  57. package/src/components/FieldEditor/FieldEditor.stories.tsx +8 -9
  58. package/src/components/FieldEditor/FieldEditor.test.tsx +3 -2
  59. package/src/components/FieldEditor/FieldEditor.tsx +22 -17
  60. package/src/components/Form/ArrayField.tsx +8 -8
  61. package/src/components/Form/Defaults.tsx +22 -20
  62. package/src/components/Form/Form.stories.tsx +129 -93
  63. package/src/components/Form/Form.tsx +16 -12
  64. package/src/components/Form/FormActions.tsx +2 -1
  65. package/src/components/Form/FormContent.tsx +96 -34
  66. package/src/components/Form/FormContext.tsx +5 -5
  67. package/src/components/Form/Input.tsx +4 -1
  68. package/src/components/Form/RefField.tsx +124 -38
  69. package/src/components/Form/custom/GeoPointInput.tsx +29 -21
  70. package/src/components/Form/custom/SelectOptionsInput.stories.tsx +7 -6
  71. package/src/components/Form/custom/SelectOptionsInput.tsx +29 -30
  72. package/src/components/Form/custom/TupleInput.tsx +2 -2
  73. package/src/components/Form/factory.tsx +1 -1
  74. package/src/components/ViewEditor/ViewEditor.stories.tsx +17 -8
  75. package/src/components/ViewEditor/ViewEditor.test.tsx +7 -10
  76. package/src/components/ViewEditor/ViewEditor.tsx +90 -107
  77. package/src/components/index.ts +0 -2
  78. package/src/components/testing.tsx +15 -9
  79. package/src/hooks/useForm.ts +5 -3
  80. package/src/hooks/useRefQueryLookupHandler.ts +1 -1
  81. package/src/translations.ts +11 -5
  82. package/src/util/field.ts +8 -18
  83. package/dist/types/src/components/deprecated/Form.d.ts +0 -15
  84. package/dist/types/src/components/deprecated/Form.d.ts.map +0 -1
  85. package/dist/types/src/components/deprecated/Form.stories.d.ts +0 -13
  86. package/dist/types/src/components/deprecated/Form.stories.d.ts.map +0 -1
  87. package/dist/types/src/components/deprecated/FormInput.d.ts +0 -16
  88. package/dist/types/src/components/deprecated/FormInput.d.ts.map +0 -1
  89. package/dist/types/src/components/deprecated/index.d.ts +0 -2
  90. package/dist/types/src/components/deprecated/index.d.ts.map +0 -1
  91. package/src/components/deprecated/Form.stories.tsx +0 -62
  92. package/src/components/deprecated/Form.tsx +0 -119
  93. package/src/components/deprecated/FormInput.tsx +0 -71
  94. package/src/components/deprecated/index.ts +0 -5
@@ -11,18 +11,19 @@ import { invariant } from '@dxos/invariant';
11
11
  import { Callout, IconButton, type ThemedClassName, useTranslation } from '@dxos/react-ui';
12
12
  import { List } from '@dxos/react-ui-list';
13
13
  import { cardSpacing } from '@dxos/react-ui-stack';
14
- import { ghostHover, inputTextLabel, mx } from '@dxos/react-ui-theme';
15
- import { FieldSchema, type FieldType, VIEW_FIELD_LIMIT, type DataType, ProjectionModel } from '@dxos/schema';
14
+ import { inputTextLabel, mx, subtleHover } from '@dxos/react-ui-theme';
15
+ import { type DataType, FieldSchema, type FieldType, ProjectionModel, VIEW_FIELD_LIMIT } from '@dxos/schema';
16
16
 
17
17
  import { translationKey } from '../../translations';
18
18
  import { FieldEditor } from '../FieldEditor';
19
19
  import { Form, type FormProps } from '../Form';
20
20
 
21
- const grid = 'grid grid-cols-[32px_1fr_32px_32px] min-bs-[2.5rem]';
21
+ const listGrid = 'grid grid-cols-[min-content_1fr_min-content_min-content_min-content]';
22
+ const listItemGrid = 'grid grid-cols-subgrid col-span-5';
22
23
 
23
24
  const ViewMetaSchema = Schema.Struct({
24
25
  typename: Format.URL.annotations({
25
- title: 'Typename',
26
+ title: 'Record type',
26
27
  }),
27
28
  }).pipe(Schema.mutable);
28
29
 
@@ -48,20 +49,20 @@ export const ViewEditor = ({
48
49
  schema,
49
50
  view,
50
51
  registry,
51
- readonly: _readonly,
52
+ readonly,
52
53
  showHeading = false,
53
54
  onTypenameChanged,
54
55
  onDelete,
55
56
  outerSpacing = true,
56
57
  }: ViewEditorProps) => {
58
+ const schemaReadonly = !isMutable(schema);
57
59
  const { t } = useTranslation(translationKey);
58
- const projection = useMemo(() => {
60
+ const projectionModel = useMemo(() => {
59
61
  // Use reactive and mutable version of json schema when schema is mutable.
60
62
  const jsonSchema = schema instanceof EchoSchema ? schema.jsonSchema : toJsonSchema(schema);
61
63
  return new ProjectionModel(jsonSchema, view.projection);
62
64
  }, [schema, view.projection]);
63
- const [field, setField] = useState<FieldType>();
64
- const readonly = _readonly || !isMutable(schema);
65
+ const [expandedField, setExpandedField] = useState<FieldType['id']>();
65
66
 
66
67
  // TODO(burdon): Should be reactive.
67
68
  const viewValues = useMemo(() => {
@@ -72,12 +73,9 @@ export const ViewEditor = ({
72
73
  };
73
74
  }, [view.query.typename]);
74
75
 
75
- const handleSelect = useCallback(
76
+ const handleToggleField = useCallback(
76
77
  (field: FieldType) => {
77
- if (readonly) {
78
- return;
79
- }
80
- setField((f) => (f === field ? undefined : field));
78
+ setExpandedField((prevExpandedFieldId) => (prevExpandedFieldId === field.id ? undefined : field.id));
81
79
  },
82
80
  [readonly],
83
81
  );
@@ -86,9 +84,9 @@ export const ViewEditor = ({
86
84
 
87
85
  const handleAdd = useCallback(() => {
88
86
  invariant(!readonly);
89
- const field = projection.createFieldProjection();
90
- setField(field);
91
- }, [schema, projection, readonly]);
87
+ const field = projectionModel.createFieldProjection();
88
+ setExpandedField(field.id);
89
+ }, [schema, projectionModel, readonly]);
92
90
 
93
91
  const handleUpdate = useCallback(
94
92
  ({ typename }: ViewMetaType) => {
@@ -105,13 +103,13 @@ export const ViewEditor = ({
105
103
  const handleDelete = useCallback(
106
104
  (fieldId: string) => {
107
105
  invariant(!readonly);
108
- if (fieldId === field?.id) {
109
- setField(undefined);
106
+ if (fieldId === expandedField) {
107
+ setExpandedField(undefined);
110
108
  }
111
109
 
112
110
  onDelete?.(fieldId);
113
111
  },
114
- [field, onDelete, readonly],
112
+ [expandedField, onDelete, readonly],
115
113
  );
116
114
 
117
115
  const handleMove = useCallback(
@@ -126,34 +124,33 @@ export const ViewEditor = ({
126
124
  [view.projection.fields, readonly],
127
125
  );
128
126
 
129
- const handleClose = useCallback(() => setField(undefined), []);
130
-
131
- const hiddenProperties = projection.getHiddenProperties();
127
+ const handleClose = useCallback(() => setExpandedField(undefined), []);
132
128
 
133
129
  const handleHide = useCallback(
134
130
  (fieldId: string) => {
135
- setField(undefined);
136
- projection.hideFieldProjection(fieldId);
131
+ setExpandedField(undefined);
132
+ projectionModel.hideFieldProjection(fieldId);
137
133
  },
138
- [projection],
134
+ [projectionModel],
139
135
  );
140
136
 
141
137
  const handleShow = useCallback(
142
138
  (property: string) => {
143
- setField(undefined);
144
- projection.showFieldProjection(property as JsonProp);
139
+ setExpandedField(undefined);
140
+ projectionModel.showFieldProjection(property as JsonProp);
145
141
  },
146
- [projection],
142
+ [projectionModel],
147
143
  );
148
144
 
149
145
  return (
150
146
  <div role='none' className={mx(classNames)}>
151
- {readonly && (
152
- <div role='none' className={mx('is-full', outerSpacing && 'plb-cardSpacingBlock pli-cardSpacingInline')}>
153
- <Callout.Root valence='info'>
154
- <Callout.Title>{t('system schema description')}</Callout.Title>
155
- </Callout.Root>
156
- </div>
147
+ {schemaReadonly && (
148
+ <Callout.Root
149
+ valence='info'
150
+ classNames={['is-full mlb-cardSpacingBlock', outerSpacing && 'mli-cardSpacingInline']}
151
+ >
152
+ <Callout.Title>{t('system schema description')}</Callout.Title>
153
+ </Callout.Root>
157
154
  )}
158
155
 
159
156
  {/* TODO(burdon): Is the form read-only or just the schema? */}
@@ -162,98 +159,84 @@ export const ViewEditor = ({
162
159
  autoSave
163
160
  schema={ViewMetaSchema}
164
161
  values={viewValues}
165
- readonly={readonly}
162
+ readonly={readonly ? 'disabled-input' : false}
166
163
  onSave={handleUpdate}
167
164
  outerSpacing={outerSpacing}
168
165
  />
169
166
 
170
167
  <div role='none' className={outerSpacing ? cardSpacing : 'mlb-cardSpacingBlock'}>
171
- <label className={mx(inputTextLabel)}>{t('fields label')}</label>
168
+ <h2 className={mx(inputTextLabel)}>{t('fields label')}</h2>
172
169
 
173
170
  <List.Root<FieldType>
174
171
  items={view.projection.fields}
175
172
  isItem={Schema.is(FieldSchema)}
176
173
  getId={(field) => field.id}
177
- readonly={readonly}
178
174
  onMove={readonly ? undefined : handleMove}
175
+ readonly={readonly}
179
176
  >
180
177
  {({ items: fields }) => (
181
178
  <>
182
- {showHeading && (
183
- <div role='heading' className={grid}>
184
- <div />
185
- <div className='flex items-center text-sm'>{t('field path label')}</div>
186
- </div>
187
- )}
188
-
189
- <div role='list' className='flex flex-col is-full'>
190
- {fields?.map((field) => (
191
- <List.Item<FieldType>
192
- key={field.id}
193
- item={field}
194
- classNames={mx(grid, ghostHover, 'overflow-hidden', !readonly && 'cursor-pointer')}
195
- >
196
- <List.ItemDragHandle />
197
- <List.ItemTitle onClick={() => handleSelect(field)}>{field.path}</List.ItemTitle>
198
- <List.ItemButton
199
- data-testid='hide-field-button'
200
- icon='ph--eye-slash--regular'
201
- // TDOO(burdon): Is this the correct test?
202
- disabled={view.projection.fields.length <= 1}
203
- onClick={() => handleHide(field.id)}
204
- />
205
- {/* TODO(burdon): Remove unless implement undo. */}
206
- {!readonly && (
207
- <List.ItemDeleteButton
208
- disabled={view.projection.fields.length <= 1}
209
- onClick={() => handleDelete(field.id)}
210
- />
211
- )}
212
- </List.Item>
213
- ))}
179
+ {showHeading && <h3 className='text-sm'>{t('field path label')}</h3>}
180
+ <div role='list' className={listGrid}>
181
+ {fields?.map((field) => {
182
+ const hidden = field.visible === false;
183
+ return (
184
+ <List.Item<FieldType>
185
+ key={field.id}
186
+ item={field}
187
+ classNames={listItemGrid}
188
+ aria-expanded={expandedField === field.id}
189
+ >
190
+ <div role='none' className={mx(subtleHover, listItemGrid, 'rounded-sm cursor-pointer min-bs-10')}>
191
+ <List.ItemDragHandle disabled={readonly} />
192
+ <List.ItemTitle classNames={hidden && 'text-subdued'} onClick={() => handleToggleField(field)}>
193
+ {field.path}
194
+ </List.ItemTitle>
195
+ <List.ItemButton
196
+ label={t(hidden ? 'show field label' : 'hide field label')}
197
+ data-testid={hidden ? 'show-field-button' : 'hide-field-button'}
198
+ icon={hidden ? 'ph--eye-closed--regular' : 'ph--eye--regular'}
199
+ autoHide={false}
200
+ disabled={readonly || (!hidden && projectionModel.fields.length <= 1)}
201
+ onClick={() => (hidden ? handleShow(field.path) : handleHide(field.id))}
202
+ />
203
+ {/* TODO(burdon): Remove unless implement undo. */}
204
+ <List.ItemDeleteButton
205
+ label={t('delete field label')}
206
+ autoHide={false}
207
+ disabled={readonly || schemaReadonly || view.projection.fields.length <= 1}
208
+ onClick={() => handleDelete(field.id)}
209
+ data-testid='field.delete'
210
+ />
211
+ <IconButton
212
+ iconOnly
213
+ variant='ghost'
214
+ label={t('toggle expand label', { ns: 'os' })}
215
+ icon={expandedField === field.id ? 'ph--caret-down--regular' : 'ph--caret-right--regular'}
216
+ onClick={() => handleToggleField(field)}
217
+ />
218
+ </div>
219
+ {expandedField === field.id && (
220
+ <div role='none' className='col-span-5 mbs-1 mbe-1 border border-separator rounded-md'>
221
+ <FieldEditor
222
+ readonly={readonly || schemaReadonly ? 'disabled-input' : false}
223
+ projection={projectionModel}
224
+ field={field}
225
+ registry={registry}
226
+ onSave={handleClose}
227
+ />
228
+ </div>
229
+ )}
230
+ </List.Item>
231
+ );
232
+ })}
214
233
  </div>
215
234
  </>
216
235
  )}
217
236
  </List.Root>
218
-
219
- {hiddenProperties.length > 0 && (
220
- <>
221
- <label className={mx(inputTextLabel)}>{t('hidden fields label')}</label>
222
-
223
- <List.Root<string>
224
- items={hiddenProperties}
225
- isItem={(item): item is string => typeof item === 'string'}
226
- getId={(property) => property}
227
- >
228
- {({ items: properties }) => (
229
- <div role='list' className='flex flex-col is-full'>
230
- {properties?.map((property) => (
231
- <List.Item<string>
232
- key={property}
233
- item={property}
234
- classNames={mx(grid, ghostHover, !readonly && 'cursor-pointer')}
235
- >
236
- <List.ItemDragHandle disabled />
237
- <List.ItemTitle>{property}</List.ItemTitle>
238
- <List.ItemButton
239
- icon='ph--eye--regular'
240
- onClick={() => handleShow(property)}
241
- data-testid='show-field-button'
242
- />
243
- </List.Item>
244
- ))}
245
- </div>
246
- )}
247
- </List.Root>
248
- </>
249
- )}
250
237
  </div>
251
238
 
252
- {field && (
253
- <FieldEditor key={field.id} projection={projection} field={field} registry={registry} onSave={handleClose} />
254
- )}
255
-
256
- {!readonly && !field && (
239
+ {!readonly && !expandedField && (
257
240
  <div role='none' className={outerSpacing ? cardSpacing : 'mlb-cardSpacingBlock'}>
258
241
  <IconButton
259
242
  icon='ph--plus--regular'
@@ -261,7 +244,7 @@ export const ViewEditor = ({
261
244
  onClick={readonly ? undefined : handleAdd}
262
245
  // TODO(burdon): Show field limit in ux (not tooltip).
263
246
  disabled={view.projection.fields.length >= VIEW_FIELD_LIMIT}
264
- classNames='flex is-full'
247
+ classNames='is-full'
265
248
  />
266
249
  </div>
267
250
  )}
@@ -2,8 +2,6 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- export * from './deprecated';
6
-
7
5
  export * from './ControlSection';
8
6
  export * from './FieldEditor';
9
7
  export * from './Form';
@@ -9,16 +9,22 @@ import { Card } from '@dxos/react-ui-stack';
9
9
  import { JsonFilter } from '@dxos/react-ui-syntax-highlighter';
10
10
  import { mx, textBlockWidth } from '@dxos/react-ui-theme';
11
11
 
12
- export const TestLayout = ({ classNames, json, children }: ThemedClassName<PropsWithChildren<{ json?: any }>>) => (
13
- <div className='w-full h-full grid grid-cols-[1fr_1fr] gap-2 overflow-hidden'>
14
- <div className={mx('p-4 justify-center overflow-y-auto', classNames)}>{children}</div>
15
- <JsonFilter data={json} classNames='w-full text-xs' testId='debug' />
16
- </div>
17
- );
12
+ type TestLayoutProps = ThemedClassName<PropsWithChildren<{ json?: any }>>;
18
13
 
19
- export const TestPanel = ({ classNames, children }: ThemedClassName<PropsWithChildren>) => (
20
- <Card.StaticRoot classNames={[textBlockWidth, classNames]}>{children}</Card.StaticRoot>
21
- );
14
+ export const TestLayout = ({ classNames, children, json }: TestLayoutProps) => {
15
+ return (
16
+ <div className='w-full h-full grid grid-cols-[1fr_1fr] gap-2 overflow-hidden'>
17
+ <div className={mx('p-4 justify-center overflow-y-auto', classNames)}>{children}</div>
18
+ <JsonFilter data={json} classNames='w-full text-xs' testId='debug' />
19
+ </div>
20
+ );
21
+ };
22
+
23
+ type TestPanelProps = ThemedClassName<PropsWithChildren>;
24
+
25
+ export const TestPanel = ({ classNames, children }: TestPanelProps) => {
26
+ return <Card.StaticRoot classNames={[textBlockWidth, classNames]}>{children}</Card.StaticRoot>;
27
+ };
22
28
 
23
29
  // Symbol for accessing debug objects in tests.
24
30
  export const VIEW_EDITOR_DEBUG_SYMBOL = Symbol('viewEditorDebug');
@@ -2,14 +2,14 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { SchemaAST, type Schema } from 'effect';
5
+ import { type Schema, SchemaAST } from 'effect';
6
6
  import { useCallback, useEffect, useMemo, useState } from 'react';
7
7
 
8
8
  import { type BaseObject, getValue, setValue } from '@dxos/echo-schema';
9
- import { type SimpleType, type JsonPath, createJsonPath, fromEffectValidationPath } from '@dxos/effect';
9
+ import { type JsonPath, type SimpleType, createJsonPath, fromEffectValidationPath } from '@dxos/effect';
10
10
  import { invariant } from '@dxos/invariant';
11
11
  import { log } from '@dxos/log';
12
- import { validateSchema, type ValidationError } from '@dxos/schema';
12
+ import { type ValidationError, validateSchema } from '@dxos/schema';
13
13
  import { type MaybePromise } from '@dxos/util';
14
14
 
15
15
  /**
@@ -26,6 +26,8 @@ export type FormHandler<T extends BaseObject> = {
26
26
  changed: Record<JsonPath, boolean>;
27
27
  canSave: boolean;
28
28
  formIsValid: boolean;
29
+
30
+ // TODO(burdon): Return onSave.
29
31
  handleSave: () => void;
30
32
 
31
33
  //
@@ -4,7 +4,7 @@
4
4
 
5
5
  import { useCallback } from 'react';
6
6
 
7
- import { getObjectDXN, type TypeAnnotation } from '@dxos/echo-schema';
7
+ import { type TypeAnnotation, getObjectDXN } from '@dxos/echo-schema';
8
8
  import { Filter, type Space } from '@dxos/react-client/echo';
9
9
  import { isNonNullable } from '@dxos/util';
10
10
 
@@ -25,6 +25,11 @@ export const translations = [
25
25
  'field limit reached': 'Maximum number of fields reached',
26
26
  'boolean input true value': 'Yes',
27
27
  'boolean input false value': 'No',
28
+ 'show field label': 'Show field',
29
+ 'hide field label': 'Hide field',
30
+ 'delete field label': 'Delete field',
31
+ 'ref field placeholder_one': 'Select…',
32
+ 'ref field placeholder_other': 'Select items…',
28
33
 
29
34
  // TODO(burdon): Factor out?
30
35
  'button cancel': 'Cancel',
@@ -60,9 +65,9 @@ export const translations = [
60
65
  'format url': 'URL',
61
66
  'format uuid': 'UUID',
62
67
 
63
- // Placeholders.
64
- 'placeholder latitude': 'Latitude',
65
- 'placeholder longitude': 'Longitude',
68
+ // GeoPointInput.
69
+ 'latitude label': 'Latitude',
70
+ 'longitude label': 'Longitude',
66
71
 
67
72
  // SelectOptionsInput.
68
73
  'select option label': 'Label',
@@ -72,8 +77,9 @@ export const translations = [
72
77
  'select option add': 'Add option',
73
78
 
74
79
  // System schema message.
75
- 'system schema title': 'System Schema',
76
- 'system schema description': 'This is a system schema and cannot be modified.',
80
+ 'system schema title': 'System record type',
81
+ 'system schema description':
82
+ 'This is a system record type and cannot be modified, though the view can still be configured.',
77
83
  },
78
84
  },
79
85
  },
package/src/util/field.ts CHANGED
@@ -112,24 +112,7 @@ export type CellClassesForFieldTypeProps = {
112
112
  };
113
113
 
114
114
  export const cellClassesForFieldType = ({ type, format }: CellClassesForFieldTypeProps): string[] | undefined => {
115
- if (!format) {
116
- switch (type) {
117
- case TypeEnum.Number:
118
- return ['text-right', 'font-mono'];
119
- case TypeEnum.Boolean:
120
- return ['text-right', 'font-mono'];
121
- case TypeEnum.String:
122
- return undefined;
123
- case TypeEnum.Ref:
124
- return undefined;
125
-
126
- default: {
127
- return undefined;
128
- }
129
- }
130
- }
131
-
132
- switch (format) {
115
+ switch (format || type) {
133
116
  case FormatEnum.Markdown:
134
117
  return undefined;
135
118
  case FormatEnum.Time:
@@ -143,6 +126,13 @@ export const cellClassesForFieldType = ({ type, format }: CellClassesForFieldTyp
143
126
  case FormatEnum.JSON:
144
127
  case FormatEnum.DID:
145
128
  return ['font-mono'];
129
+ case TypeEnum.Number:
130
+ case TypeEnum.Boolean:
131
+ return ['text-right', 'font-mono'];
132
+ case TypeEnum.String:
133
+ return undefined;
134
+ case TypeEnum.Ref:
135
+ return undefined;
146
136
  default:
147
137
  return undefined;
148
138
  }
@@ -1,15 +0,0 @@
1
- import { type Schema } from 'effect';
2
- import React from 'react';
3
- import { type ThemedClassName } from '@dxos/react-ui';
4
- import { type Projection } from '@dxos/schema';
5
- export type DeprecatedFormProps<T extends {} = {}> = ThemedClassName<{
6
- projection: Projection;
7
- object: T;
8
- schema?: Schema.Schema<T>;
9
- readonly?: boolean;
10
- }>;
11
- /**
12
- * Schema-based object form.
13
- */
14
- export declare const DeprecatedForm: <T extends {} = {}>({ classNames, projection, object, schema, readonly, }: DeprecatedFormProps<T>) => React.JSX.Element;
15
- //# sourceMappingURL=Form.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Form.d.ts","sourceRoot":"","sources":["../../../../../src/components/deprecated/Form.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAa,KAAK,MAAM,EAAgB,MAAM,QAAQ,CAAC;AAC9D,OAAO,KAAmB,MAAM,OAAO,CAAC;AAGxC,OAAO,EAAS,KAAK,eAAe,EAA+C,MAAM,gBAAgB,CAAC;AAE1G,OAAO,EAAgC,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAE7E,MAAM,MAAM,mBAAmB,CAAC,CAAC,SAAS,EAAE,GAAG,EAAE,IAAI,eAAe,CAAC;IACnE,UAAU,EAAE,UAAU,CAAC;IACvB,MAAM,EAAE,CAAC,CAAC;IACV,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAC1B,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,cAAc,GAAI,CAAC,SAAS,EAAE,GAAG,EAAE,EAAE,uDAM/C,mBAAmB,CAAC,CAAC,CAAC,sBA0DxB,CAAC"}
@@ -1,13 +0,0 @@
1
- import '@dxos-theme';
2
- import { type Meta, type StoryObj } from '@storybook/react-vite';
3
- import React from 'react';
4
- import { type TestType } from '@dxos/schema/testing';
5
- import { type DeprecatedFormProps } from './Form';
6
- declare const DefaultStory: (props: DeprecatedFormProps) => React.JSX.Element;
7
- declare const meta: Meta<typeof DefaultStory>;
8
- export default meta;
9
- type Story = StoryObj<DeprecatedFormProps<TestType>>;
10
- export declare const Default: Story;
11
- export declare const Empty: Story;
12
- export declare const Readonly: Story;
13
- //# sourceMappingURL=Form.stories.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Form.stories.d.ts","sourceRoot":"","sources":["../../../../../src/components/deprecated/Form.stories.tsx"],"names":[],"mappings":"AAIA,OAAO,aAAa,CAAC;AAErB,OAAO,EAAE,KAAK,IAAI,EAAE,KAAK,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjE,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,EAAkC,KAAK,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAGrF,OAAO,EAAkB,KAAK,mBAAmB,EAAE,MAAM,QAAQ,CAAC;AAIlE,QAAA,MAAM,YAAY,GAAI,OAAO,mBAAmB,sBAM/C,CAAC;AAEF,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,YAAY,CAQnC,CAAC;AAEF,eAAe,IAAI,CAAC;AAEpB,KAAK,KAAK,GAAG,QAAQ,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC,CAAC;AAErD,eAAO,MAAM,OAAO,EAAE,KAMrB,CAAC;AAEF,eAAO,MAAM,KAAK,EAAE,KAKnB,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,KAOtB,CAAC"}
@@ -1,16 +0,0 @@
1
- import { type JSX, type PropsWithChildren } from 'react';
2
- import { type ThemedClassName } from '@dxos/react-ui';
3
- /**
4
- * @deprecated
5
- */
6
- export declare const DeprecatedFormContainer: ({ children, classNames }: ThemedClassName<PropsWithChildren>) => JSX.Element;
7
- export type DeprecatedFormInputProps = {
8
- label: string;
9
- description?: JSX.Element;
10
- secondary?: JSX.Element;
11
- };
12
- /**
13
- * @deprecated
14
- */
15
- export declare const DeprecatedFormInput: ({ label, description, secondary, children, }: PropsWithChildren<DeprecatedFormInputProps>) => JSX.Element;
16
- //# sourceMappingURL=FormInput.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"FormInput.d.ts","sourceRoot":"","sources":["../../../../../src/components/deprecated/FormInput.tsx"],"names":[],"mappings":"AAIA,OAAc,EAAE,KAAK,GAAG,EAAE,KAAK,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAEhE,OAAO,EAAS,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAG7D;;GAEG;AACH,eAAO,MAAM,uBAAuB,GAAI,0BAA0B,eAAe,CAAC,iBAAiB,CAAC,gBAQnG,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC;IAC1B,SAAS,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC;CACzB,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,mBAAmB,GAAI,8CAKjC,iBAAiB,CAAC,wBAAwB,CAAC,gBAkC7C,CAAC"}
@@ -1,2 +0,0 @@
1
- export * from './FormInput';
2
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/components/deprecated/index.ts"],"names":[],"mappings":"AAIA,cAAc,aAAa,CAAC"}
@@ -1,62 +0,0 @@
1
- //
2
- // Copyright 2024 DXOS.org
3
- //
4
-
5
- import '@dxos-theme';
6
-
7
- import { type Meta, type StoryObj } from '@storybook/react-vite';
8
- import React from 'react';
9
-
10
- import { live } from '@dxos/live-object';
11
- import { testData, TestSchema, testView, type TestType } from '@dxos/schema/testing';
12
- import { withLayout, withTheme } from '@dxos/storybook-utils';
13
-
14
- import { DeprecatedForm, type DeprecatedFormProps } from './Form';
15
- import { translations } from '../../translations';
16
- import { TestLayout, TestPanel } from '../testing';
17
-
18
- const DefaultStory = (props: DeprecatedFormProps) => (
19
- <TestLayout json={{ props }}>
20
- <TestPanel>
21
- <DeprecatedForm {...props} />
22
- </TestPanel>
23
- </TestLayout>
24
- );
25
-
26
- const meta: Meta<typeof DefaultStory> = {
27
- title: 'ui/react-ui-form/DeprecatedForm',
28
- component: DeprecatedForm,
29
- render: DefaultStory,
30
- decorators: [withLayout({ fullscreen: true }), withTheme],
31
- parameters: {
32
- translations,
33
- },
34
- };
35
-
36
- export default meta;
37
-
38
- type Story = StoryObj<DeprecatedFormProps<TestType>>;
39
-
40
- export const Default: Story = {
41
- args: {
42
- object: live(testData),
43
- projection: live(testView).projection,
44
- schema: TestSchema,
45
- },
46
- };
47
-
48
- export const Empty: Story = {
49
- args: {
50
- projection: live(testView).projection,
51
- schema: TestSchema,
52
- },
53
- };
54
-
55
- export const Readonly: Story = {
56
- args: {
57
- object: live(testData),
58
- projection: live(testView).projection,
59
- schema: TestSchema,
60
- readonly: true,
61
- },
62
- };