@dxos/react-ui-form 0.8.4-main.74a063c4e0 → 0.8.4-main.765dc60934

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 (134) hide show
  1. package/LICENSE +102 -5
  2. package/dist/lib/browser/index.mjs +873 -446
  3. package/dist/lib/browser/index.mjs.map +4 -4
  4. package/dist/lib/browser/meta.json +1 -1
  5. package/dist/lib/browser/translations.mjs +82 -0
  6. package/dist/lib/browser/translations.mjs.map +7 -0
  7. package/dist/lib/node-esm/index.mjs +873 -446
  8. package/dist/lib/node-esm/index.mjs.map +4 -4
  9. package/dist/lib/node-esm/meta.json +1 -1
  10. package/dist/lib/node-esm/translations.mjs +84 -0
  11. package/dist/lib/node-esm/translations.mjs.map +7 -0
  12. package/dist/types/src/components/FieldEditor/FieldEditor.d.ts.map +1 -1
  13. package/dist/types/src/components/FieldEditor/FieldEditor.stories.d.ts +63 -61
  14. package/dist/types/src/components/FieldEditor/FieldEditor.stories.d.ts.map +1 -1
  15. package/dist/types/src/components/Form/Form.d.ts +34 -12
  16. package/dist/types/src/components/Form/Form.d.ts.map +1 -1
  17. package/dist/types/src/components/Form/Form.stories.d.ts +73 -71
  18. package/dist/types/src/components/Form/Form.stories.d.ts.map +1 -1
  19. package/dist/types/src/components/Form/FormField.d.ts +5 -5
  20. package/dist/types/src/components/Form/FormField.d.ts.map +1 -1
  21. package/dist/types/src/components/Form/FormFieldComponent.d.ts +8 -6
  22. package/dist/types/src/components/Form/FormFieldComponent.d.ts.map +1 -1
  23. package/dist/types/src/components/Form/FormFieldComponent.stories.d.ts.map +1 -1
  24. package/dist/types/src/components/Form/FormFieldSet.d.ts +5 -8
  25. package/dist/types/src/components/Form/FormFieldSet.d.ts.map +1 -1
  26. package/dist/types/src/components/Form/fields/ArrayField.d.ts +4 -4
  27. package/dist/types/src/components/Form/fields/ArrayField.d.ts.map +1 -1
  28. package/dist/types/src/components/Form/fields/BooleanField.d.ts.map +1 -1
  29. package/dist/types/src/components/Form/fields/GeoPointField.d.ts.map +1 -1
  30. package/dist/types/src/components/Form/fields/MarkdownField.d.ts +8 -1
  31. package/dist/types/src/components/Form/fields/MarkdownField.d.ts.map +1 -1
  32. package/dist/types/src/components/Form/fields/MarkdownField.stories.d.ts +84 -0
  33. package/dist/types/src/components/Form/fields/MarkdownField.stories.d.ts.map +1 -0
  34. package/dist/types/src/components/Form/fields/NumberField.d.ts.map +1 -1
  35. package/dist/types/src/components/Form/fields/RefField.d.ts +10 -4
  36. package/dist/types/src/components/Form/fields/RefField.d.ts.map +1 -1
  37. package/dist/types/src/components/Form/fields/SelectField.d.ts.map +1 -1
  38. package/dist/types/src/components/Form/fields/SelectOptionField.d.ts.map +1 -1
  39. package/dist/types/src/components/Form/fields/SelectOptionField.stories.d.ts +63 -61
  40. package/dist/types/src/components/Form/fields/SelectOptionField.stories.d.ts.map +1 -1
  41. package/dist/types/src/components/Form/fields/TextAreaField.d.ts.map +1 -1
  42. package/dist/types/src/components/Form/fields/TextField.d.ts +1 -1
  43. package/dist/types/src/components/Form/fields/TextField.d.ts.map +1 -1
  44. package/dist/types/src/components/Form/fields/TupleField.d.ts.map +1 -1
  45. package/dist/types/src/components/ObjectForm/ObjectForm.d.ts +9 -0
  46. package/dist/types/src/components/ObjectForm/ObjectForm.d.ts.map +1 -0
  47. package/dist/types/src/components/ObjectForm/index.d.ts +2 -0
  48. package/dist/types/src/components/ObjectForm/index.d.ts.map +1 -0
  49. package/dist/types/src/components/ObjectPicker/ObjectPicker.d.ts +17 -3
  50. package/dist/types/src/components/ObjectPicker/ObjectPicker.d.ts.map +1 -1
  51. package/dist/types/src/components/ObjectPicker/ObjectPicker.stories.d.ts +63 -61
  52. package/dist/types/src/components/ObjectPicker/ObjectPicker.stories.d.ts.map +1 -1
  53. package/dist/types/src/components/ObjectProperties/ObjectProperties.d.ts +9 -0
  54. package/dist/types/src/components/ObjectProperties/ObjectProperties.d.ts.map +1 -0
  55. package/dist/types/src/components/ObjectProperties/ObjectProperties.stories.d.ts +127 -0
  56. package/dist/types/src/components/ObjectProperties/ObjectProperties.stories.d.ts.map +1 -0
  57. package/dist/types/src/components/ObjectProperties/ObjectProperties.test.d.ts +2 -0
  58. package/dist/types/src/components/ObjectProperties/ObjectProperties.test.d.ts.map +1 -0
  59. package/dist/types/src/components/ObjectProperties/index.d.ts +2 -0
  60. package/dist/types/src/components/ObjectProperties/index.d.ts.map +1 -0
  61. package/dist/types/src/components/Settings/Settings.d.ts +24 -12
  62. package/dist/types/src/components/Settings/Settings.d.ts.map +1 -1
  63. package/dist/types/src/components/Settings/Settings.stories.d.ts +64 -61
  64. package/dist/types/src/components/Settings/Settings.stories.d.ts.map +1 -1
  65. package/dist/types/src/components/Settings/SettingsFieldSet.d.ts +43 -0
  66. package/dist/types/src/components/Settings/SettingsFieldSet.d.ts.map +1 -0
  67. package/dist/types/src/components/Settings/SettingsItem.d.ts +16 -0
  68. package/dist/types/src/components/Settings/SettingsItem.d.ts.map +1 -0
  69. package/dist/types/src/components/Settings/SettingsSelectField.d.ts +18 -0
  70. package/dist/types/src/components/Settings/SettingsSelectField.d.ts.map +1 -0
  71. package/dist/types/src/components/Settings/index.d.ts +2 -0
  72. package/dist/types/src/components/Settings/index.d.ts.map +1 -1
  73. package/dist/types/src/components/ViewEditor/ViewEditor.d.ts +3 -4
  74. package/dist/types/src/components/ViewEditor/ViewEditor.d.ts.map +1 -1
  75. package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts +63 -61
  76. package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts.map +1 -1
  77. package/dist/types/src/components/index.d.ts +2 -0
  78. package/dist/types/src/components/index.d.ts.map +1 -1
  79. package/dist/types/src/components/testing.d.ts +4 -4
  80. package/dist/types/src/components/testing.d.ts.map +1 -1
  81. package/dist/types/src/hooks/useFormHandler.d.ts.map +1 -1
  82. package/dist/types/src/hooks/useKeyHandler.d.ts.map +1 -1
  83. package/dist/types/src/index.d.ts +0 -2
  84. package/dist/types/src/index.d.ts.map +1 -1
  85. package/dist/types/src/translations.d.ts +63 -61
  86. package/dist/types/src/translations.d.ts.map +1 -1
  87. package/dist/types/src/util/field-type.d.ts +19 -0
  88. package/dist/types/src/util/field-type.d.ts.map +1 -0
  89. package/dist/types/src/util/field.d.ts.map +1 -1
  90. package/dist/types/src/util/formatting.d.ts.map +1 -1
  91. package/dist/types/src/util/index.d.ts +1 -0
  92. package/dist/types/src/util/index.d.ts.map +1 -1
  93. package/dist/types/src/util/properties.d.ts.map +1 -1
  94. package/dist/types/src/util/refs.d.ts.map +1 -1
  95. package/dist/types/tsconfig.tsbuildinfo +1 -1
  96. package/package.json +40 -38
  97. package/src/components/FieldEditor/FieldEditor.stories.tsx +2 -1
  98. package/src/components/FieldEditor/FieldEditor.tsx +3 -2
  99. package/src/components/Form/Form.stories.tsx +9 -19
  100. package/src/components/Form/Form.tsx +59 -7
  101. package/src/components/Form/FormField.tsx +12 -10
  102. package/src/components/Form/FormFieldComponent.tsx +6 -3
  103. package/src/components/Form/FormFieldSet.tsx +47 -31
  104. package/src/components/Form/fields/ArrayField.tsx +7 -6
  105. package/src/components/Form/fields/GeoPointField.tsx +3 -2
  106. package/src/components/Form/fields/MarkdownField.stories.tsx +206 -0
  107. package/src/components/Form/fields/MarkdownField.tsx +135 -45
  108. package/src/components/Form/fields/RefField.tsx +61 -30
  109. package/src/components/Form/fields/SelectOptionField.stories.tsx +8 -5
  110. package/src/components/Form/fields/SelectOptionField.tsx +6 -5
  111. package/src/components/Form/fields/TextField.tsx +2 -2
  112. package/src/components/ObjectForm/ObjectForm.tsx +114 -0
  113. package/src/components/ObjectForm/index.ts +5 -0
  114. package/src/components/ObjectPicker/ObjectPicker.stories.tsx +9 -6
  115. package/src/components/ObjectPicker/ObjectPicker.tsx +28 -12
  116. package/src/components/ObjectProperties/ObjectProperties.stories.tsx +362 -0
  117. package/src/components/ObjectProperties/ObjectProperties.test.tsx +101 -0
  118. package/src/components/ObjectProperties/ObjectProperties.tsx +141 -0
  119. package/src/components/ObjectProperties/index.ts +5 -0
  120. package/src/components/Settings/AUDIT.md +52 -0
  121. package/src/components/Settings/Settings.stories.tsx +50 -1
  122. package/src/components/Settings/Settings.tsx +7 -56
  123. package/src/components/Settings/SettingsFieldSet.tsx +257 -0
  124. package/src/components/Settings/SettingsItem.tsx +58 -0
  125. package/src/components/Settings/SettingsSelectField.tsx +59 -0
  126. package/src/components/Settings/index.ts +2 -0
  127. package/src/components/ViewEditor/ViewEditor.stories.tsx +10 -10
  128. package/src/components/ViewEditor/ViewEditor.tsx +19 -26
  129. package/src/components/index.ts +2 -0
  130. package/src/components/testing.tsx +20 -21
  131. package/src/index.ts +0 -4
  132. package/src/translations.ts +7 -3
  133. package/src/util/field-type.ts +60 -0
  134. package/src/util/index.ts +1 -0
@@ -9,8 +9,7 @@ import * as Option from 'effect/Option';
9
9
  import * as Schema from 'effect/Schema';
10
10
  import React, { forwardRef, useCallback, useContext, useImperativeHandle, useMemo, useState } from 'react';
11
11
 
12
- import { Entity, Feed, Filter, Format, Obj, Query, QueryAST, Ref, type SchemaRegistry } from '@dxos/echo';
13
- import { View } from '@dxos/echo';
12
+ import { Entity, Feed, Filter, Format, Obj, Query, QueryAST, Ref, type SchemaRegistry, View } from '@dxos/echo';
14
13
  import { EchoSchema, type JsonProp, isMutable, toJsonSchema } from '@dxos/echo/internal';
15
14
  import { invariant } from '@dxos/invariant';
16
15
  import { useObject, useQuery } from '@dxos/react-client/echo';
@@ -24,9 +23,10 @@ import {
24
23
  createEchoChangeCallback,
25
24
  getTypenameFromQuery,
26
25
  } from '@dxos/schema';
27
- import { mx, osTranslations, subtleHover } from '@dxos/ui-theme';
26
+ import { mx, osTranslations } from '@dxos/ui-theme';
27
+
28
+ import { translationKey } from '#translations';
28
29
 
29
- import { translationKey } from '../../translations';
30
30
  import { FieldEditor } from '../FieldEditor';
31
31
  import {
32
32
  Form,
@@ -100,8 +100,8 @@ export const ViewEditor = forwardRef<ProjectionModel, ViewEditorProps>(
100
100
  if (from._tag !== 'scope') {
101
101
  return undefined;
102
102
  }
103
- return Option.fromNullable(from.scope.queues).pipe(
104
- Option.flatMap((queues) => Array.head(queues)),
103
+ return Option.fromNullable(from.scope.feeds).pipe(
104
+ Option.flatMap((feeds) => Array.head(feeds)),
105
105
  Option.map(String),
106
106
  Option.getOrUndefined,
107
107
  );
@@ -160,13 +160,13 @@ export const ViewEditor = forwardRef<ProjectionModel, ViewEditorProps>(
160
160
  const handleUpdate = useCallback(
161
161
  (values: any) => {
162
162
  const targetValue = values.target;
163
- let queueDxn: string | undefined;
163
+ let feedDXN: string | undefined;
164
164
 
165
165
  if (Ref.isRef(targetValue)) {
166
- const feedDxn = targetValue.dxn.toString();
167
- const feed = feeds.find((feed) => Obj.getDXN(feed).toString() === feedDxn);
166
+ const targetDXN = targetValue.dxn.toString();
167
+ const feed = feeds.find((feed) => Obj.getDXN(feed).toString() === targetDXN);
168
168
  if (feed) {
169
- queueDxn = Feed.getQueueDxn(feed)?.toString();
169
+ feedDXN = Feed.getQueueDxn(feed)?.toString();
170
170
  }
171
171
  }
172
172
 
@@ -175,7 +175,7 @@ export const ViewEditor = forwardRef<ProjectionModel, ViewEditorProps>(
175
175
  mode === 'schema'
176
176
  ? Query.select(Filter.typename(values.query)).ast
177
177
  : JSON.parse(JSON.stringify(values.query));
178
- onQueryChanged?.(query, queueDxn);
178
+ onQueryChanged?.(query, feedDXN);
179
179
  },
180
180
  [onQueryChanged, mode, feeds],
181
181
  );
@@ -189,7 +189,7 @@ export const ViewEditor = forwardRef<ProjectionModel, ViewEditorProps>(
189
189
  );
190
190
 
191
191
  return (
192
- <div role='none' className={mx(classNames)}>
192
+ <div className={mx(classNames)}>
193
193
  {/* If readonly is set, then the callout is not needed. */}
194
194
  {schemaReadonly && !readonly && (
195
195
  <Message.Root valence='info' classNames='my-form-padding'>
@@ -274,12 +274,12 @@ const FieldList = ({ schema, view, registry, readonly, showHeading = false, onDe
274
274
  const handleMove = useCallback(
275
275
  (fromIndex: number, toIndex: number) => {
276
276
  invariant(!readonly);
277
- Obj.change(view, (obj) => {
277
+ Obj.update(view, (view) => {
278
278
  // NOTE(ZaymonFC): Using arrayMove here causes a race condition with the kanban model.
279
- const fields = [...obj.projection.fields];
279
+ const fields = [...view.projection.fields];
280
280
  const [moved] = fields.splice(fromIndex, 1);
281
281
  fields.splice(toIndex, 0, moved);
282
- obj.projection.fields = fields;
282
+ view.projection.fields = fields;
283
283
  });
284
284
  },
285
285
  [view, readonly],
@@ -328,20 +328,13 @@ const FieldList = ({ schema, view, registry, readonly, showHeading = false, onDe
328
328
  classNames={'grid grid-cols-subgrid col-span-5'}
329
329
  aria-expanded={expandedField === field.id}
330
330
  >
331
- <div
332
- role='none'
333
- className={mx(
334
- subtleHover,
335
- 'grid grid-cols-subgrid col-span-5',
336
- 'rounded-xs cursor-pointer min-h-10',
337
- )}
338
- >
331
+ <div className='grid grid-cols-subgrid col-span-5 rounded-xs cursor-pointer min-h-10 dx-hover'>
339
332
  <List.ItemDragHandle disabled={readonly || schemaReadonly} />
340
333
  <List.ItemTitle classNames={hidden && 'text-subdued'} onClick={() => handleToggleField(field)}>
341
334
  {field.path}
342
335
  </List.ItemTitle>
343
336
  <List.ItemIconButton
344
- label={t(hidden ? 'show field label' : 'hide field label')}
337
+ label={t(hidden ? 'show-field.label' : 'hide-field.label')}
345
338
  data-testid={hidden ? 'show-field-button' : 'hide-field-button'}
346
339
  icon={hidden ? 'ph--eye-closed--regular' : 'ph--eye--regular'}
347
340
  autoHide={false}
@@ -369,7 +362,7 @@ const FieldList = ({ schema, view, registry, readonly, showHeading = false, onDe
369
362
  )}
370
363
  </div>
371
364
  {expandedField === field.id && !readonly && (
372
- <div role='none' className='col-span-5 mt-1 mb-1 border border-separator rounded-md'>
365
+ <div className='col-span-full mt-1 mb-1 border border-separator rounded-md'>
373
366
  <FieldEditor
374
367
  readonly={readonly || schemaReadonly}
375
368
  registry={registry}
@@ -384,7 +377,7 @@ const FieldList = ({ schema, view, registry, readonly, showHeading = false, onDe
384
377
  })}
385
378
  </div>
386
379
  {!readonly && !expandedField && (
387
- <div role='none' className='my-form-padding'>
380
+ <div className='my-form-padding'>
388
381
  <IconButton
389
382
  icon='ph--plus--regular'
390
383
  label={t('add-property-button.label')}
@@ -4,6 +4,8 @@
4
4
 
5
5
  export * from './FieldEditor';
6
6
  export * from './Form';
7
+ export * from './ObjectForm';
7
8
  export * from './ObjectPicker';
9
+ export * from './ObjectProperties';
8
10
  export * from './Settings';
9
11
  export * from './ViewEditor';
@@ -4,27 +4,25 @@
4
4
 
5
5
  import React, { type PropsWithChildren } from 'react';
6
6
 
7
- import { Column, type ThemedClassName } from '@dxos/react-ui';
8
- import { Json } from '@dxos/react-ui-syntax-highlighter';
9
- import { mx } from '@dxos/ui-theme';
7
+ import { type ThemedClassName } from '@dxos/react-ui';
8
+ import { Syntax } from '@dxos/react-ui-syntax-highlighter';
9
+ import { composableProps, slottable } from '@dxos/ui-theme';
10
10
 
11
- type TestLayoutProps = ThemedClassName<PropsWithChildren<{ json?: any }>>;
11
+ type TestLayoutProps = PropsWithChildren<{ json?: any }>;
12
12
 
13
- export const TestLayout = ({ classNames, children, json }: TestLayoutProps) => {
13
+ export const TestLayout = ({ children, json }: TestLayoutProps) => {
14
14
  return (
15
- <div className='h-full w-full grid grid-cols-[1fr_1fr] p-4 gap-4 overflow-hidden'>
16
- <TestPanel classNames={['dx-container', classNames]}>
17
- <Column.Root classNames='dx-container' gutter='sm'>
18
- {children}
19
- </Column.Root>
20
- </TestPanel>
21
- <TestPanel classNames={'overflow-hidden'}>
22
- <Json.Root data={json}>
23
- <Json.Content classNames='h-full'>
24
- <Json.Filter />
25
- <Json.Data testId='debug' classNames='text-xs' />
26
- </Json.Content>
27
- </Json.Root>
15
+ <div className='dx-container grid grid-cols-[1fr_1fr] p-4 gap-4'>
16
+ <TestPanel>{children}</TestPanel>
17
+ <TestPanel>
18
+ <Syntax.Root data={json}>
19
+ <Syntax.Content>
20
+ <Syntax.Filter />
21
+ <Syntax.Viewport>
22
+ <Syntax.Code testId='debug' classNames='text-xs' />
23
+ </Syntax.Viewport>
24
+ </Syntax.Content>
25
+ </Syntax.Root>
28
26
  </TestPanel>
29
27
  </div>
30
28
  );
@@ -32,14 +30,15 @@ export const TestLayout = ({ classNames, children, json }: TestLayoutProps) => {
32
30
 
33
31
  type TestPanelProps = ThemedClassName<PropsWithChildren>;
34
32
 
35
- const TestPanel = ({ classNames, children }: TestPanelProps) => {
33
+ const TestPanel = slottable<HTMLDivElement, TestPanelProps>(({ children }, forwardedRef) => {
36
34
  return (
37
- <div role='none' className={mx(['dx-document h-full bg-modal-surface rounded-md', classNames])}>
35
+ <div {...composableProps({ classNames: 'dx-container bg-modal-surface rounded-md' })} ref={forwardedRef}>
38
36
  {children}
39
37
  </div>
40
38
  );
41
- };
39
+ });
42
40
 
43
41
  // Symbol for accessing debug objects in tests.
44
42
  export const VIEW_EDITOR_DEBUG_SYMBOL = Symbol('viewEditorDebug');
45
43
  export const FIELD_EDITOR_DEBUG_SYMBOL = Symbol('fieldEditorDebug');
44
+ export const OBJECT_PROPERTIES_DEBUG_SYMBOL = Symbol('objectPropertiesDebug');
package/src/index.ts CHANGED
@@ -2,10 +2,6 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- import { translations } from './translations';
6
-
7
5
  export * from './components';
8
6
  export * from './hooks';
9
7
  export * from './util';
10
-
11
- export { translations };
@@ -14,22 +14,25 @@ export const translations = [
14
14
  'hidden-fields.label': 'Hidden Fields',
15
15
  'empty-readonly-ref-field.label': '(none)',
16
16
 
17
- 'add-property-button.label': 'Add property',
18
17
  'field-property.label': 'Property',
19
18
  'field-property.placeholder': 'Property name',
20
19
  'field-format.label': 'Type',
21
20
  'field-path.label': 'Field path',
22
- 'add-field.button': 'Add field',
21
+
22
+ 'add-item.button': 'Add item',
23
+ 'add-property-button.label': 'Add property',
23
24
  'boolean-input-true.value': 'Yes',
24
25
  'boolean-input-false.value': 'No',
25
26
  'show-field.label': 'Show field',
26
27
  'hide-field.label': 'Hide field',
27
28
  'delete-field.label': 'Delete field',
29
+ 'create-option.label': 'Create',
30
+ 'add-tag.label': 'Add tag',
31
+
28
32
  'ref-field-combobox-input.placeholder': 'Search…',
29
33
  'ref-field.placeholder': 'Select…',
30
34
  'ref-field.placeholder_one': 'Select…',
31
35
  'ref-field.placeholder_other': 'Select items…',
32
- 'create-option.label': 'Create',
33
36
 
34
37
  'example.placeholder': 'Example',
35
38
  'latitude.placeholder': 'Latitude (e.g., 40.7128)',
@@ -37,6 +40,7 @@ export const translations = [
37
40
 
38
41
  'cancel-button.label': 'Cancel',
39
42
  'save-button.label': 'Save',
43
+ 'create-text.label': 'Create text',
40
44
 
41
45
  // TypeFormat
42
46
  'format.boolean.label': 'Boolean',
@@ -0,0 +1,60 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import * as SchemaAST from 'effect/SchemaAST';
6
+
7
+ import { getAnnotation, isLiteralUnion } from '@dxos/effect';
8
+
9
+ /**
10
+ * Detected field type for a schema property.
11
+ */
12
+ export type SettingsFieldType = 'boolean' | 'string' | 'number' | 'select' | 'struct';
13
+
14
+ export type SelectOption = {
15
+ value: string | number;
16
+ label?: string;
17
+ };
18
+
19
+ /**
20
+ * Detect the field type from an Effect Schema AST node.
21
+ */
22
+ export const detectFieldType = (ast: SchemaAST.AST): SettingsFieldType | undefined => {
23
+ if (isLiteralUnion(ast)) {
24
+ return 'select';
25
+ }
26
+ if (SchemaAST.isTypeLiteral(ast)) {
27
+ return 'struct';
28
+ }
29
+
30
+ switch (ast._tag) {
31
+ case 'BooleanKeyword':
32
+ return 'boolean';
33
+ case 'StringKeyword':
34
+ return 'string';
35
+ case 'NumberKeyword':
36
+ return 'number';
37
+ }
38
+
39
+ return undefined;
40
+ };
41
+
42
+ /**
43
+ * Extract select options from a literal union AST node.
44
+ * Reads title annotations from individual literals for labels.
45
+ */
46
+ export const getSelectOptionsFromAst = (ast: SchemaAST.AST): SelectOption[] | undefined => {
47
+ if (!isLiteralUnion(ast)) {
48
+ return undefined;
49
+ }
50
+
51
+ return (ast as SchemaAST.Union<SchemaAST.Literal>).types.flatMap((literalNode) => {
52
+ const value = literalNode.literal;
53
+ if (typeof value !== 'string' && typeof value !== 'number') {
54
+ return [];
55
+ }
56
+ const title = getAnnotation<string>(SchemaAST.TitleAnnotationId, false)(literalNode);
57
+ const label = title ?? (typeof value === 'string' ? value.charAt(0).toUpperCase() + value.slice(1) : String(value));
58
+ return [{ value, label }];
59
+ });
60
+ };
package/src/util/index.ts CHANGED
@@ -3,6 +3,7 @@
3
3
  //
4
4
 
5
5
  export * from './field';
6
+ export * from './field-type';
6
7
  export * from './formatting';
7
8
  export * from './properties';
8
9
  export * from './refs';