@dxos/react-ui-form 0.8.2-main.f11618f → 0.8.2-staging.7ac8446

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 (47) hide show
  1. package/dist/lib/browser/index.mjs +102 -253
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/node/index.cjs +161 -312
  5. package/dist/lib/node/index.cjs.map +4 -4
  6. package/dist/lib/node/meta.json +1 -1
  7. package/dist/lib/node-esm/index.mjs +102 -253
  8. package/dist/lib/node-esm/index.mjs.map +4 -4
  9. package/dist/lib/node-esm/meta.json +1 -1
  10. package/dist/types/src/components/{ControlSection/ControlSection.d.ts → ControlSection.d.ts} +5 -8
  11. package/dist/types/src/components/ControlSection.d.ts.map +1 -0
  12. package/dist/types/src/components/Form/ArrayField.d.ts.map +1 -1
  13. package/dist/types/src/components/Form/Form.d.ts +1 -3
  14. package/dist/types/src/components/Form/Form.d.ts.map +1 -1
  15. package/dist/types/src/components/Form/Form.stories.d.ts +2 -4
  16. package/dist/types/src/components/Form/Form.stories.d.ts.map +1 -1
  17. package/dist/types/src/components/Form/FormContent.d.ts +10 -13
  18. package/dist/types/src/components/Form/FormContent.d.ts.map +1 -1
  19. package/dist/types/src/components/Form/FormContext.d.ts +2 -2
  20. package/dist/types/src/components/Form/FormContext.d.ts.map +1 -1
  21. package/dist/types/src/components/Form/custom/GeoPointInput.d.ts.map +1 -1
  22. package/dist/types/src/components/Form/custom/SelectOptionsInput.d.ts.map +1 -1
  23. package/dist/types/src/components/index.d.ts.map +1 -1
  24. package/dist/types/src/util/formatting.d.ts.map +1 -1
  25. package/package.json +24 -24
  26. package/src/components/{ControlSection/ControlSection.tsx → ControlSection.tsx} +14 -38
  27. package/src/components/Form/ArrayField.tsx +1 -3
  28. package/src/components/Form/Form.stories.tsx +5 -48
  29. package/src/components/Form/Form.tsx +0 -4
  30. package/src/components/Form/FormContent.tsx +15 -59
  31. package/src/components/Form/FormContext.tsx +2 -10
  32. package/src/components/Form/custom/GeoPointInput.tsx +2 -2
  33. package/src/components/Form/custom/SelectOptionsInput.tsx +2 -2
  34. package/src/components/deprecated/Form.stories.tsx +6 -6
  35. package/src/components/deprecated/FormInput.tsx +1 -1
  36. package/src/components/index.ts +0 -1
  37. package/src/util/formatting.ts +3 -15
  38. package/dist/types/src/components/ControlSection/ControlSection.d.ts.map +0 -1
  39. package/dist/types/src/components/ControlSection/ControlSection.stories.d.ts +0 -8
  40. package/dist/types/src/components/ControlSection/ControlSection.stories.d.ts.map +0 -1
  41. package/dist/types/src/components/ControlSection/index.d.ts +0 -2
  42. package/dist/types/src/components/ControlSection/index.d.ts.map +0 -1
  43. package/dist/types/src/components/Form/RefField.d.ts +0 -23
  44. package/dist/types/src/components/Form/RefField.d.ts.map +0 -1
  45. package/src/components/ControlSection/ControlSection.stories.tsx +0 -29
  46. package/src/components/ControlSection/index.ts +0 -5
  47. package/src/components/Form/RefField.tsx +0 -151
@@ -7,9 +7,7 @@ import '@dxos-theme';
7
7
  import { type Meta, type StoryObj } from '@storybook/react';
8
8
  import React, { useCallback, useState } from 'react';
9
9
 
10
- import { ContactType } from '@dxos/client/testing';
11
- import { AST, type BaseObject, Expando, Format, getDXN, Ref, S, type TypeAnnotation } from '@dxos/echo-schema';
12
- import { live } from '@dxos/live-object';
10
+ import { AST, type BaseObject, Format, S } from '@dxos/echo-schema';
13
11
  import { Testing } from '@dxos/schema/testing';
14
12
  import { withLayout, withTheme } from '@dxos/storybook-utils';
15
13
 
@@ -80,9 +78,9 @@ export const Default: Story<TestType> = {
80
78
  },
81
79
  };
82
80
 
83
- export const Organization: Story<Testing.Organization> = {
81
+ export const Org: Story<Testing.Org> = {
84
82
  args: {
85
- schema: Testing.OrganizationSchema,
83
+ schema: Testing.OrgSchema,
86
84
  values: {
87
85
  name: 'DXOS',
88
86
  // website: 'https://dxos.org',
@@ -90,9 +88,9 @@ export const Organization: Story<Testing.Organization> = {
90
88
  },
91
89
  };
92
90
 
93
- export const OrganizationAutoSave: Story<Testing.Organization> = {
91
+ export const OrgAutoSave: Story<Testing.Org> = {
94
92
  args: {
95
- schema: Testing.OrganizationSchema,
93
+ schema: Testing.OrgSchema,
96
94
  values: {
97
95
  name: 'DXOS',
98
96
  // website: 'https://dxos.org',
@@ -241,44 +239,3 @@ export const Enum: StoryObj<FormProps<ColorType>> = {
241
239
  },
242
240
  },
243
241
  };
244
-
245
- const RefSchema = S.Struct({
246
- contact: Ref(ContactType).annotations({ title: 'Contact Reference' }),
247
- optionalContact: S.optional(Ref(ContactType).annotations({ title: 'Optional Contact Reference' })),
248
- unknownExpando: S.optional(Ref(Expando).annotations({ title: 'Optional Ref to an Expando (DXN Input)' })),
249
- });
250
-
251
- const RefStory = ({ values: initialValues }: FormProps<any>) => {
252
- const [values, setValues] = useState(initialValues);
253
- const handleSave = useCallback<NonNullable<FormProps<any>['onSave']>>((values) => {
254
- setValues(values);
255
- }, []);
256
-
257
- const contact1 = live(ContactType, { identifiers: [] });
258
- const contact2 = live(ContactType, { identifiers: [] });
259
-
260
- const onQueryRefOptions = useCallback((typeInfo: TypeAnnotation) => {
261
- switch (typeInfo.typename) {
262
- case ContactType.typename:
263
- return [
264
- { dxn: getDXN(contact1)!, label: 'John Coltraine' },
265
- { dxn: getDXN(contact2)!, label: 'Erykah Badu' },
266
- ];
267
- default:
268
- return [];
269
- }
270
- }, []);
271
-
272
- return (
273
- <TestLayout json={{ values, schema: RefSchema.ast.toJSON() }}>
274
- <TestPanel>
275
- <Form schema={RefSchema} values={values} onSave={handleSave} onQueryRefOptions={onQueryRefOptions} />
276
- </TestPanel>
277
- </TestLayout>
278
- );
279
- };
280
-
281
- export const Refs: StoryObj<FormProps<ContactType>> = {
282
- render: RefStory,
283
- args: { values: {} },
284
- };
@@ -13,7 +13,6 @@ import { FormActions } from './FormActions';
13
13
  import { FormFields } from './FormContent';
14
14
  import { FormProvider } from './FormContext';
15
15
  import { type InputProps, type InputComponent } from './Input';
16
- import { type QueryRefOptions } from './RefField';
17
16
  import { type FormOptions } from '../../hooks';
18
17
 
19
18
  export type PropsFilter<T extends BaseObject> = (props: SchemaProperty<T>[]) => SchemaProperty<T>[];
@@ -42,7 +41,6 @@ export type FormProps<T extends BaseObject> = ThemedClassName<
42
41
  autoSave?: boolean;
43
42
  testId?: string;
44
43
  onCancel?: () => void;
45
- onQueryRefOptions?: QueryRefOptions;
46
44
  lookupComponent?: ComponentLookup;
47
45
  /**
48
46
  * Map of custom renderers for specific properties.
@@ -67,7 +65,6 @@ export const Form = <T extends BaseObject>({
67
65
  onValidate,
68
66
  onSave,
69
67
  onCancel,
70
- onQueryRefOptions,
71
68
  lookupComponent,
72
69
  Custom,
73
70
  }: FormProps<T>) => {
@@ -103,7 +100,6 @@ export const Form = <T extends BaseObject>({
103
100
  readonly={readonly}
104
101
  filter={filter}
105
102
  sort={sort}
106
- onQueryRefOptions={onQueryRefOptions}
107
103
  lookupComponent={lookupComponent}
108
104
  Custom={Custom}
109
105
  />
@@ -1,5 +1,5 @@
1
1
  //
2
- // Copyright 2025 DXOS.org
2
+ // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
5
  import { pipe } from 'effect';
@@ -17,29 +17,29 @@ import { SelectInput } from './Defaults';
17
17
  import { type ComponentLookup } from './Form';
18
18
  import { useInputProps, useFormValues } from './FormContext';
19
19
  import { type InputComponent } from './Input';
20
- import { RefField, type QueryRefOptions } from './RefField';
21
20
  import { getInputComponent } from './factory';
22
21
 
22
+ export type FormContentProps = {
23
+ schema: S.Schema.All;
24
+ path?: (string | number)[];
25
+ filter?: (props: SchemaProperty<any>[]) => SchemaProperty<any>[];
26
+ sort?: string[];
27
+ readonly?: boolean;
28
+ lookupComponent?: ComponentLookup;
29
+ Custom?: Partial<Record<string, InputComponent>>;
30
+ };
31
+
23
32
  export type FormFieldProps = {
24
33
  property: SchemaProperty<any>;
25
34
  path?: (string | number)[];
26
35
  readonly?: boolean;
27
36
  /** Used to indicate if input should be presented inline (e.g. for array items). */
28
37
  inline?: boolean;
29
- onQueryRefOptions?: QueryRefOptions;
30
38
  lookupComponent?: ComponentLookup;
31
39
  Custom?: Partial<Record<string, InputComponent>>;
32
40
  };
33
41
 
34
- export const FormField = ({
35
- property,
36
- path,
37
- readonly,
38
- inline,
39
- onQueryRefOptions,
40
- lookupComponent,
41
- Custom,
42
- }: FormFieldProps) => {
42
+ export const FormField = ({ property, path, readonly, inline, lookupComponent, Custom }: FormFieldProps) => {
43
43
  const inputProps = useInputProps(path);
44
44
  const { ast, name, type, format, title, description, options, examples, array } = property;
45
45
 
@@ -120,22 +120,6 @@ export const FormField = ({
120
120
  );
121
121
  }
122
122
 
123
- // TODO(ZaymonFC): Extract this to it's own component.
124
- if (format === 'ref') {
125
- return (
126
- <RefField
127
- ast={ast}
128
- type={type}
129
- label={label}
130
- readonly={readonly}
131
- placeholder={placeholder}
132
- inline={inline}
133
- onQueryRefOptions={onQueryRefOptions}
134
- inputProps={inputProps}
135
- />
136
- );
137
- }
138
-
139
123
  if (type === 'object') {
140
124
  const baseNode = findNode(ast, isDiscriminatedUnion);
141
125
  const typeLiteral = baseNode
@@ -145,15 +129,8 @@ export const FormField = ({
145
129
  if (typeLiteral) {
146
130
  return (
147
131
  <div role='none'>
148
- {!inline && <h3 className='text-lg mbs-2 mbe-1'>{label}</h3>}
149
- <FormFields
150
- schema={S.make(typeLiteral)}
151
- path={path}
152
- readonly={readonly}
153
- onQueryRefOptions={onQueryRefOptions}
154
- Custom={Custom}
155
- lookupComponent={lookupComponent}
156
- />
132
+ {!inline && <div>{label}</div>}
133
+ <FormFields schema={S.make(typeLiteral)} path={path} readonly={readonly} Custom={Custom} />
157
134
  </div>
158
135
  );
159
136
  }
@@ -162,27 +139,7 @@ export const FormField = ({
162
139
  return null;
163
140
  };
164
141
 
165
- export type FormContentProps = {
166
- schema: S.Schema.All;
167
- path?: (string | number)[];
168
- filter?: (props: SchemaProperty<any>[]) => SchemaProperty<any>[];
169
- sort?: string[];
170
- readonly?: boolean;
171
- onQueryRefOptions?: QueryRefOptions;
172
- lookupComponent?: ComponentLookup;
173
- Custom?: Partial<Record<string, InputComponent>>;
174
- };
175
-
176
- export const FormFields = ({
177
- schema,
178
- path,
179
- filter,
180
- sort,
181
- readonly,
182
- onQueryRefOptions,
183
- lookupComponent,
184
- Custom,
185
- }: FormContentProps) => {
142
+ export const FormFields = ({ schema, path, filter, sort, readonly, lookupComponent, Custom }: FormContentProps) => {
186
143
  const values = useFormValues(path);
187
144
 
188
145
  const properties = useMemo(() => {
@@ -202,7 +159,6 @@ export const FormFields = ({
202
159
  property={property}
203
160
  path={[...(path ?? []), property.name]}
204
161
  readonly={readonly}
205
- onQueryRefOptions={onQueryRefOptions}
206
162
  lookupComponent={lookupComponent}
207
163
  Custom={Custom}
208
164
  />
@@ -2,15 +2,7 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import React, {
6
- createContext,
7
- type RefObject,
8
- useContext,
9
- useEffect,
10
- useMemo,
11
- type FocusEvent,
12
- type PropsWithChildren,
13
- } from 'react';
5
+ import React, { createContext, useContext, useEffect, useMemo, type FocusEvent, type PropsWithChildren } from 'react';
14
6
 
15
7
  import { raise } from '@dxos/debug';
16
8
  import { type BaseObject, getValue } from '@dxos/echo-schema';
@@ -61,7 +53,7 @@ export const FormProvider = ({
61
53
  ...formOptions
62
54
  }: PropsWithChildren<
63
55
  FormOptions<any> & {
64
- formRef?: RefObject<HTMLDivElement>;
56
+ formRef?: React.RefObject<HTMLDivElement>;
65
57
  autoSave?: boolean;
66
58
  }
67
59
  >) => {
@@ -2,7 +2,7 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- import React, { useCallback, useState, useEffect, useMemo, type ChangeEvent } from 'react';
5
+ import React, { useCallback, useState, useEffect, useMemo } from 'react';
6
6
 
7
7
  import { type GeoPoint, GeoLocation } from '@dxos/echo-schema';
8
8
  import { Input, useTranslation } from '@dxos/react-ui';
@@ -28,7 +28,7 @@ export const GeoPointInput = ({ type, label, disabled, getStatus, getValue, onVa
28
28
 
29
29
  const handleCoordinateChange = useCallback(
30
30
  (coordinateType: keyof Pick<GeoLocation, 'longitude' | 'latitude'>, setText: (text: string) => void) =>
31
- (event: ChangeEvent<HTMLInputElement>) => {
31
+ (event: React.ChangeEvent<HTMLInputElement>) => {
32
32
  const inputText = event.target.value;
33
33
  setText(inputText);
34
34
  if (inputText !== '' && inputText !== '-') {
@@ -2,7 +2,7 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import React, { type ChangeEvent, type KeyboardEvent, useCallback, useEffect, useState, useRef } from 'react';
5
+ import React, { useCallback, useEffect, useState, type ChangeEvent, useRef } from 'react';
6
6
 
7
7
  import { type SelectOption } from '@dxos/echo-schema';
8
8
  import { PublicKey } from '@dxos/keys';
@@ -89,7 +89,7 @@ export const SelectOptionInput = ({ type, label, disabled, getStatus, getValue,
89
89
  [options, type, onValueChange],
90
90
  );
91
91
 
92
- const handleKeyDown = useCallback((e: KeyboardEvent<HTMLInputElement>) => {
92
+ const handleKeyDown = useCallback((e: React.KeyboardEvent<HTMLInputElement>) => {
93
93
  if (e.key === 'Enter') {
94
94
  setSelectedId(null);
95
95
  }
@@ -7,7 +7,7 @@ import '@dxos-theme';
7
7
  import { type Meta, type StoryObj } from '@storybook/react';
8
8
  import React from 'react';
9
9
 
10
- import { live } from '@dxos/live-object';
10
+ import { create } from '@dxos/live-object';
11
11
  import { testData, TestSchema, testView, type TestType } from '@dxos/schema/testing';
12
12
  import { withLayout, withTheme } from '@dxos/storybook-utils';
13
13
 
@@ -39,23 +39,23 @@ type Story = StoryObj<DeprecatedFormProps<TestType>>;
39
39
 
40
40
  export const Default: Story = {
41
41
  args: {
42
- object: live(testData),
43
- view: live(testView),
42
+ object: create(testData),
43
+ view: create(testView),
44
44
  schema: TestSchema,
45
45
  },
46
46
  };
47
47
 
48
48
  export const Empty: Story = {
49
49
  args: {
50
- view: live(testView),
50
+ view: create(testView),
51
51
  schema: TestSchema,
52
52
  },
53
53
  };
54
54
 
55
55
  export const Readonly: Story = {
56
56
  args: {
57
- object: live(testData),
58
- view: live(testView),
57
+ object: create(testData),
58
+ view: create(testView),
59
59
  schema: TestSchema,
60
60
  readonly: true,
61
61
  },
@@ -12,7 +12,7 @@ import { mx, textBlockWidth } from '@dxos/react-ui-theme';
12
12
  */
13
13
  export const DeprecatedFormContainer = ({ children, classNames }: ThemedClassName<PropsWithChildren>) => {
14
14
  return (
15
- <div role='none' className='container-max-width p-4 justify-center overflow-x-hidden overflow-y-auto'>
15
+ <div role='none' className='w-full p-4 justify-center overflow-x-hidden overflow-y-auto'>
16
16
  <div role='form' className={mx('flex flex-col', textBlockWidth, classNames)}>
17
17
  {children}
18
18
  </div>
@@ -3,7 +3,6 @@
3
3
  //
4
4
 
5
5
  export * from './deprecated';
6
-
7
6
  export * from './ControlSection';
8
7
  export * from './FieldEditor';
9
8
  export * from './Form';
@@ -64,25 +64,13 @@ export const formatForDisplay = ({ type, format, value, locale = undefined }: Va
64
64
  });
65
65
  }
66
66
  case FormatEnum.Date: {
67
- try {
68
- return formatDate(new Date(value as number), 'yyyy-MM-dd');
69
- } catch (error) {
70
- return 'Invalid Date';
71
- }
67
+ return formatDate(new Date(value as number), 'yyyy-MM-dd');
72
68
  }
73
69
  case FormatEnum.Time: {
74
- try {
75
- return formatDate(new Date(value as number), 'HH:mm:ss');
76
- } catch (error) {
77
- return 'Invalid Time';
78
- }
70
+ return formatDate(new Date(value as number), 'HH:mm:ss');
79
71
  }
80
72
  case FormatEnum.DateTime: {
81
- try {
82
- return formatDate(new Date(value as number), 'yyyy-MM-dd HH:mm:ss');
83
- } catch (error) {
84
- return 'Invalid DateTime';
85
- }
73
+ return formatDate(new Date(value as number), 'yyyy-MM-dd HH:mm:ss');
86
74
  }
87
75
  case FormatEnum.GeoPoint: {
88
76
  if (value === null || value === undefined) {
@@ -1 +0,0 @@
1
- {"version":3,"file":"ControlSection.d.ts","sourceRoot":"","sources":["../../../../../src/components/ControlSection/ControlSection.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,EAAE,KAAK,wBAAwB,EAAE,KAAK,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAErF,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,KAAK,EAEV,KAAK,eAAe,EAGrB,MAAM,gBAAgB,CAAC;AAKxB,MAAM,MAAM,gBAAgB,GAAG,eAAe,CAAC,wBAAwB,CAAC,KAAK,CAAC,CAAC,CAAC;AAEhF,eAAO,MAAM,WAAW,uCAAwC,gBAAgB,sBAM/E,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,iBAAiB,CAAC;IAClD,KAAK,EAAE,KAAK,CAAC;IACb,WAAW,CAAC,EAAE,KAAK,CAAC;CACrB,CAAC,CAAC;AAEH,eAAO,MAAM,cAAc,qCAAsC,mBAAmB,sBAOnF,CAAC;AAEF,eAAO,MAAM,qBAAqB,2BAA4B,IAAI,CAAC,mBAAmB,EAAE,UAAU,CAAC,sBAUlG,CAAC;AAEF,eAAO,MAAM,kBAAkB,6BAA8B,WAAW,sBAEvE,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,eAAe,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC,CAAC;AAEvE,eAAO,MAAM,YAAY,6BAA8B,iBAAiB,sBAOvE,CAAC;AAEF,eAAO,MAAM,YAAY,iBAAkB,iBAAiB,sBAO3D,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,iBAAiB,CAAC;IAC/C,KAAK,EAAE,KAAK,CAAC;IACb,WAAW,CAAC,EAAE,KAAK,CAAC;CACrB,CAAC,CAAC;AAEH,eAAO,MAAM,kBAAkB,iHACiF,CAAC;AAKjH,eAAO,MAAM,WAAW,qCAAsC,gBAAgB,sBAY7E,CAAC;AAEF,eAAO,MAAM,gBAAgB,qCAAsC,gBAAgB,sBAoBlF,CAAC;AAEF,eAAO,MAAM,gBAAgB,qCAAsC,gBAAgB,sBAUlF,CAAC"}
@@ -1,8 +0,0 @@
1
- import '@dxos-theme';
2
- import { type Meta, type StoryObj } from '@storybook/react';
3
- import { type ControlSectionProps } from './ControlSection';
4
- declare const meta: Meta<ControlSectionProps>;
5
- export default meta;
6
- type Story = StoryObj<ControlSectionProps>;
7
- export declare const Default: Story;
8
- //# sourceMappingURL=ControlSection.stories.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ControlSection.stories.d.ts","sourceRoot":"","sources":["../../../../../src/components/ControlSection/ControlSection.stories.tsx"],"names":[],"mappings":"AAIA,OAAO,aAAa,CAAC;AAErB,OAAO,EAAE,KAAK,IAAI,EAAE,KAAK,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAI5D,OAAO,EAAkB,KAAK,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAG5E,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,mBAAmB,CAOnC,CAAC;AAEF,eAAe,IAAI,CAAC;AAEpB,KAAK,KAAK,GAAG,QAAQ,CAAC,mBAAmB,CAAC,CAAC;AAE3C,eAAO,MAAM,OAAO,EAAE,KAErB,CAAC"}
@@ -1,2 +0,0 @@
1
- export * from './ControlSection';
2
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/components/ControlSection/index.ts"],"names":[],"mappings":"AAIA,cAAc,kBAAkB,CAAC"}
@@ -1,23 +0,0 @@
1
- import React from 'react';
2
- import { type AST, type TypeAnnotation } from '@dxos/echo-schema';
3
- import { type SimpleType } from '@dxos/effect';
4
- import { DXN } from '@dxos/keys';
5
- import { type MaybePromise } from '@dxos/util';
6
- import { type FormInputStateProps } from './FormContext';
7
- export type QueryRefOptions = (type: TypeAnnotation) => MaybePromise<{
8
- dxn: DXN;
9
- label?: string;
10
- }[]>;
11
- type RefFieldProps = {
12
- ast: AST.AST;
13
- type: SimpleType;
14
- label: string;
15
- readonly?: boolean;
16
- placeholder?: string;
17
- inline?: boolean;
18
- onQueryRefOptions?: QueryRefOptions;
19
- inputProps: FormInputStateProps;
20
- };
21
- export declare const RefField: ({ ast, type, label, readonly, placeholder, inline, onQueryRefOptions, inputProps, }: RefFieldProps) => React.JSX.Element | null;
22
- export {};
23
- //# sourceMappingURL=RefField.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"RefField.d.ts","sourceRoot":"","sources":["../../../../../src/components/Form/RefField.tsx"],"names":[],"mappings":"AAIA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAEnD,OAAO,EACL,KAAK,GAAG,EAKR,KAAK,cAAc,EACpB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAkB,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/D,OAAO,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAGjC,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAG/C,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAEzD,MAAM,MAAM,eAAe,GAAG,CAAC,IAAI,EAAE,cAAc,KAAK,YAAY,CAAC;IAAE,GAAG,EAAE,GAAG,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,EAAE,CAAC,CAAC;AAErG,KAAK,aAAa,GAAG;IACnB,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC;IACb,IAAI,EAAE,UAAU,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,iBAAiB,CAAC,EAAE,eAAe,CAAC;IACpC,UAAU,EAAE,mBAAmB,CAAC;CACjC,CAAC;AAEF,eAAO,MAAM,QAAQ,wFASlB,aAAa,6BAyGf,CAAC"}
@@ -1,29 +0,0 @@
1
- //
2
- // Copyright 2024 DXOS.org
3
- //
4
-
5
- import '@dxos-theme';
6
-
7
- import { type Meta, type StoryObj } from '@storybook/react';
8
-
9
- import { withLayout, withTheme } from '@dxos/storybook-utils';
10
-
11
- import { ControlSection, type ControlSectionProps } from './ControlSection';
12
- import translations from '../../translations';
13
-
14
- const meta: Meta<ControlSectionProps> = {
15
- title: 'ui/react-ui-form/ControlSection',
16
- component: ControlSection,
17
- decorators: [withLayout({ tooltips: true }), withTheme],
18
- parameters: {
19
- translations,
20
- },
21
- };
22
-
23
- export default meta;
24
-
25
- type Story = StoryObj<ControlSectionProps>;
26
-
27
- export const Default: Story = {
28
- args: {},
29
- };
@@ -1,5 +0,0 @@
1
- //
2
- // Copyright 2025 DXOS.org
3
- //
4
-
5
- export * from './ControlSection';
@@ -1,151 +0,0 @@
1
- //
2
- // Copyright 2025 DXOS.org
3
- //
4
-
5
- import React, { useEffect, useState } from 'react';
6
-
7
- import {
8
- type AST,
9
- Expando,
10
- getTypeAnnotation,
11
- ReferenceAnnotationId,
12
- type ReferenceAnnotationValue,
13
- type TypeAnnotation,
14
- } from '@dxos/echo-schema';
15
- import { findAnnotation, type SimpleType } from '@dxos/effect';
16
- import { DXN } from '@dxos/keys';
17
- import { refFromDXN, RefImpl } from '@dxos/live-object';
18
- import { log } from '@dxos/log';
19
- import { type MaybePromise } from '@dxos/util';
20
-
21
- import { SelectInput, TextInput } from './Defaults';
22
- import { type FormInputStateProps } from './FormContext';
23
-
24
- export type QueryRefOptions = (type: TypeAnnotation) => MaybePromise<{ dxn: DXN; label?: string }[]>;
25
-
26
- type RefFieldProps = {
27
- ast: AST.AST;
28
- type: SimpleType;
29
- label: string;
30
- readonly?: boolean;
31
- placeholder?: string;
32
- inline?: boolean;
33
- onQueryRefOptions?: QueryRefOptions;
34
- inputProps: FormInputStateProps;
35
- };
36
-
37
- export const RefField = ({
38
- ast,
39
- type,
40
- label,
41
- readonly,
42
- placeholder,
43
- inline,
44
- onQueryRefOptions,
45
- inputProps,
46
- }: RefFieldProps) => {
47
- const { getValue, onValueChange, ...restInputProps } = inputProps;
48
- const refTypeInfo = findAnnotation<ReferenceAnnotationValue>(ast, ReferenceAnnotationId);
49
- const [refOptions, setRefOptions] = useState<Array<{ value: string; label?: string }>>([]);
50
- const [loading, setLoading] = useState(false);
51
-
52
- useEffect(() => {
53
- if (!refTypeInfo || !onQueryRefOptions) {
54
- return;
55
- }
56
-
57
- const fetchOptions = async () => {
58
- setLoading(true);
59
- try {
60
- const options = await onQueryRefOptions(refTypeInfo);
61
- setRefOptions(
62
- options.map((option) => ({
63
- label: option.label,
64
- value: option.dxn.toString(),
65
- })),
66
- );
67
- } catch (error) {
68
- log.error('Failed to fetch ref options:', error);
69
- setRefOptions([]);
70
- } finally {
71
- setLoading(false);
72
- }
73
- };
74
-
75
- void fetchOptions();
76
- }, [refTypeInfo, onQueryRefOptions]);
77
-
78
- if (!refTypeInfo) {
79
- return null;
80
- }
81
-
82
- // If ref type is expando, fall back to taking a DXN in string format.
83
- if (refTypeInfo.typename === getTypeAnnotation(Expando)?.typename || !onQueryRefOptions) {
84
- const handleOnValueChange = (_type: any, dxnString: string) => {
85
- const dxn = DXN.tryParse(dxnString);
86
- if (dxn) {
87
- onValueChange?.('object', refFromDXN(dxn));
88
- } else if (dxnString === '') {
89
- onValueChange?.('object', undefined);
90
- } else {
91
- onValueChange?.('string', dxnString);
92
- }
93
- };
94
-
95
- const handleGetValue = () => {
96
- const formValue = getValue();
97
- if (typeof formValue === 'string') {
98
- return formValue;
99
- }
100
- if (formValue instanceof RefImpl) {
101
- return formValue.dxn.toString();
102
- }
103
-
104
- return undefined;
105
- };
106
-
107
- return (
108
- <TextInput
109
- type={type}
110
- label={label}
111
- disabled={readonly}
112
- placeholder={placeholder}
113
- inputOnly={inline}
114
- getValue={handleGetValue as <V>() => V | undefined}
115
- onValueChange={handleOnValueChange}
116
- {...restInputProps}
117
- />
118
- );
119
- }
120
-
121
- const handleGetValue = () => {
122
- const formValue = getValue();
123
-
124
- if (formValue instanceof RefImpl) {
125
- return formValue.dxn.toString();
126
- }
127
-
128
- return undefined;
129
- };
130
-
131
- const handleValueChanged = (_type: any, dxnString: string) => {
132
- const dxn = DXN.parse(dxnString);
133
- const ref = refFromDXN(dxn);
134
-
135
- onValueChange('object', ref);
136
- };
137
-
138
- return (
139
- <SelectInput
140
- type={type}
141
- label={label}
142
- disabled={readonly || loading}
143
- placeholder={loading ? 'Loading options...' : placeholder}
144
- inputOnly={inline}
145
- getValue={handleGetValue as <V>() => V | undefined}
146
- onValueChange={handleValueChanged}
147
- options={refOptions}
148
- {...restInputProps}
149
- />
150
- );
151
- };