@dxos/react-ui-form 0.8.4-main.c1de068 → 0.8.4-main.c85a9c8dae
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/README.md +0 -1
- package/dist/lib/browser/index.mjs +2314 -2078
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +2314 -2078
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/types/src/components/FieldEditor/FieldEditor.d.ts +8 -7
- package/dist/types/src/components/FieldEditor/FieldEditor.d.ts.map +1 -1
- package/dist/types/src/components/FieldEditor/FieldEditor.stories.d.ts +82 -5
- package/dist/types/src/components/FieldEditor/FieldEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/Form/Form.d.ts +81 -25
- package/dist/types/src/components/Form/Form.d.ts.map +1 -1
- package/dist/types/src/components/Form/Form.stories.d.ts +127 -55
- package/dist/types/src/components/Form/Form.stories.d.ts.map +1 -1
- package/dist/types/src/components/Form/FormField.d.ts +37 -0
- package/dist/types/src/components/Form/FormField.d.ts.map +1 -0
- package/dist/types/src/components/Form/FormFieldComponent.d.ts +78 -0
- package/dist/types/src/components/Form/FormFieldComponent.d.ts.map +1 -0
- package/dist/types/src/components/Form/FormFieldComponent.stories.d.ts +9 -0
- package/dist/types/src/components/Form/FormFieldComponent.stories.d.ts.map +1 -0
- package/dist/types/src/components/Form/FormFieldSet.d.ts +19 -0
- package/dist/types/src/components/Form/FormFieldSet.d.ts.map +1 -0
- package/dist/types/src/components/Form/fields/ArrayField.d.ts +18 -0
- package/dist/types/src/components/Form/fields/ArrayField.d.ts.map +1 -0
- package/dist/types/src/components/Form/fields/BooleanField.d.ts +4 -0
- package/dist/types/src/components/Form/fields/BooleanField.d.ts.map +1 -0
- package/dist/types/src/components/Form/fields/GeoPointField.d.ts +5 -0
- package/dist/types/src/components/Form/fields/GeoPointField.d.ts.map +1 -0
- package/dist/types/src/components/Form/fields/MarkdownField.d.ts +4 -0
- package/dist/types/src/components/Form/fields/MarkdownField.d.ts.map +1 -0
- package/dist/types/src/components/Form/fields/NumberField.d.ts +4 -0
- package/dist/types/src/components/Form/fields/NumberField.d.ts.map +1 -0
- package/dist/types/src/components/Form/fields/RefField.d.ts +14 -0
- package/dist/types/src/components/Form/fields/RefField.d.ts.map +1 -0
- package/dist/types/src/components/Form/fields/SelectField.d.ts +10 -0
- package/dist/types/src/components/Form/fields/SelectField.d.ts.map +1 -0
- package/dist/types/src/components/Form/fields/SelectOptionField.d.ts +5 -0
- package/dist/types/src/components/Form/fields/SelectOptionField.d.ts.map +1 -0
- package/dist/types/src/components/Form/fields/SelectOptionField.stories.d.ts +82 -0
- package/dist/types/src/components/Form/fields/SelectOptionField.stories.d.ts.map +1 -0
- package/dist/types/src/components/Form/fields/TextAreaField.d.ts +4 -0
- package/dist/types/src/components/Form/fields/TextAreaField.d.ts.map +1 -0
- package/dist/types/src/components/Form/fields/TextField.d.ts +4 -0
- package/dist/types/src/components/Form/fields/TextField.d.ts.map +1 -0
- package/dist/types/src/components/Form/fields/TupleField.d.ts +6 -0
- package/dist/types/src/components/Form/fields/TupleField.d.ts.map +1 -0
- package/dist/types/src/components/Form/fields/index.d.ts +12 -0
- package/dist/types/src/components/Form/fields/index.d.ts.map +1 -0
- package/dist/types/src/components/Form/index.d.ts +2 -4
- package/dist/types/src/components/Form/index.d.ts.map +1 -1
- package/dist/types/src/components/ObjectPicker/ObjectPicker.d.ts +46 -0
- package/dist/types/src/components/ObjectPicker/ObjectPicker.d.ts.map +1 -0
- package/dist/types/src/components/ObjectPicker/ObjectPicker.stories.d.ts +85 -0
- package/dist/types/src/components/ObjectPicker/ObjectPicker.stories.d.ts.map +1 -0
- package/dist/types/src/components/ObjectPicker/index.d.ts +2 -0
- package/dist/types/src/components/ObjectPicker/index.d.ts.map +1 -0
- package/dist/types/src/components/Settings/Settings.d.ts +56 -0
- package/dist/types/src/components/Settings/Settings.d.ts.map +1 -0
- package/dist/types/src/components/Settings/Settings.stories.d.ts +81 -0
- package/dist/types/src/components/Settings/Settings.stories.d.ts.map +1 -0
- package/dist/types/src/components/Settings/index.d.ts +2 -0
- package/dist/types/src/components/Settings/index.d.ts.map +1 -0
- package/dist/types/src/components/ViewEditor/ViewEditor.d.ts +22 -10
- package/dist/types/src/components/ViewEditor/ViewEditor.d.ts.map +1 -1
- package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts +84 -8
- package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/index.d.ts +2 -2
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/components/testing.d.ts +4 -3
- package/dist/types/src/components/testing.d.ts.map +1 -1
- package/dist/types/src/hooks/index.d.ts +2 -3
- package/dist/types/src/hooks/index.d.ts.map +1 -1
- package/dist/types/src/hooks/useFormHandler.d.ts +82 -0
- package/dist/types/src/hooks/useFormHandler.d.ts.map +1 -0
- package/dist/types/src/hooks/useKeyHandler.d.ts +6 -0
- package/dist/types/src/hooks/useKeyHandler.d.ts.map +1 -0
- package/dist/types/src/translations.d.ts +19 -10
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/util/field.d.ts +3 -3
- package/dist/types/src/util/field.d.ts.map +1 -1
- package/dist/types/src/util/formatting.d.ts +2 -2
- package/dist/types/src/util/formatting.d.ts.map +1 -1
- package/dist/types/src/util/index.d.ts +1 -1
- package/dist/types/src/util/index.d.ts.map +1 -1
- package/dist/types/src/util/properties.d.ts +7 -0
- package/dist/types/src/util/properties.d.ts.map +1 -0
- package/dist/types/src/util/refs.d.ts +2 -3
- package/dist/types/src/util/refs.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +51 -42
- package/src/components/FieldEditor/FieldEditor.stories.tsx +51 -32
- package/src/components/FieldEditor/FieldEditor.test.tsx +3 -2
- package/src/components/FieldEditor/FieldEditor.tsx +87 -83
- package/src/components/Form/Form.stories.tsx +156 -219
- package/src/components/Form/Form.tsx +347 -96
- package/src/components/Form/FormField.tsx +294 -0
- package/src/components/Form/FormFieldComponent.stories.tsx +65 -0
- package/src/components/Form/FormFieldComponent.tsx +172 -0
- package/src/components/Form/FormFieldSet.tsx +123 -0
- package/src/components/Form/README.md +3 -0
- package/src/components/Form/fields/ArrayField.tsx +149 -0
- package/src/components/Form/fields/BooleanField.tsx +22 -0
- package/src/components/Form/fields/GeoPointField.tsx +120 -0
- package/src/components/Form/fields/MarkdownField.tsx +78 -0
- package/src/components/Form/fields/NumberField.tsx +39 -0
- package/src/components/Form/fields/RefField.tsx +189 -0
- package/src/components/Form/fields/SelectField.tsx +65 -0
- package/src/components/Form/fields/SelectOptionField.stories.tsx +64 -0
- package/src/components/Form/{custom/SelectOptionsInput.tsx → fields/SelectOptionField.tsx} +46 -41
- package/src/components/Form/fields/TextAreaField.tsx +38 -0
- package/src/components/Form/fields/TextField.tsx +38 -0
- package/src/components/Form/{custom/TupleInput.tsx → fields/TupleField.tsx} +16 -9
- package/src/components/Form/fields/index.ts +15 -0
- package/src/components/Form/index.ts +3 -4
- package/src/components/ObjectPicker/ObjectPicker.stories.tsx +210 -0
- package/src/components/ObjectPicker/ObjectPicker.tsx +175 -0
- package/src/components/{ControlSection → ObjectPicker}/index.ts +1 -1
- package/src/components/Settings/Settings.stories.tsx +56 -0
- package/src/components/Settings/Settings.tsx +230 -0
- package/src/components/Settings/index.ts +5 -0
- package/src/components/ViewEditor/ViewEditor.stories.tsx +140 -62
- package/src/components/ViewEditor/ViewEditor.test.tsx +17 -18
- package/src/components/ViewEditor/ViewEditor.tsx +341 -202
- package/src/components/index.ts +2 -3
- package/src/components/testing.tsx +22 -11
- package/src/hooks/index.ts +2 -3
- package/src/hooks/useFormHandler.ts +380 -0
- package/src/hooks/useKeyHandler.tsx +37 -0
- package/src/translations.ts +21 -12
- package/src/util/field.ts +33 -43
- package/src/util/formatting.ts +22 -22
- package/src/util/index.ts +1 -1
- package/src/util/properties.ts +18 -0
- package/src/util/refs.ts +12 -18
- package/dist/types/src/components/ControlSection/ControlSection.d.ts +0 -23
- package/dist/types/src/components/ControlSection/ControlSection.d.ts.map +0 -1
- package/dist/types/src/components/ControlSection/ControlSection.stories.d.ts +0 -8
- package/dist/types/src/components/ControlSection/ControlSection.stories.d.ts.map +0 -1
- package/dist/types/src/components/ControlSection/index.d.ts +0 -2
- package/dist/types/src/components/ControlSection/index.d.ts.map +0 -1
- package/dist/types/src/components/Form/ArrayField.d.ts +0 -16
- package/dist/types/src/components/Form/ArrayField.d.ts.map +0 -1
- package/dist/types/src/components/Form/Defaults.d.ts +0 -14
- package/dist/types/src/components/Form/Defaults.d.ts.map +0 -1
- package/dist/types/src/components/Form/FormActions.d.ts +0 -9
- package/dist/types/src/components/Form/FormActions.d.ts.map +0 -1
- package/dist/types/src/components/Form/FormContent.d.ts +0 -57
- package/dist/types/src/components/Form/FormContent.d.ts.map +0 -1
- package/dist/types/src/components/Form/FormContext.d.ts +0 -23
- package/dist/types/src/components/Form/FormContext.d.ts.map +0 -1
- package/dist/types/src/components/Form/Input.d.ts +0 -26
- package/dist/types/src/components/Form/Input.d.ts.map +0 -1
- package/dist/types/src/components/Form/RefField.d.ts +0 -12
- package/dist/types/src/components/Form/RefField.d.ts.map +0 -1
- package/dist/types/src/components/Form/custom/GeoPointInput.d.ts +0 -4
- package/dist/types/src/components/Form/custom/GeoPointInput.d.ts.map +0 -1
- package/dist/types/src/components/Form/custom/SelectOptionsInput.d.ts +0 -4
- package/dist/types/src/components/Form/custom/SelectOptionsInput.d.ts.map +0 -1
- package/dist/types/src/components/Form/custom/SelectOptionsInput.stories.d.ts +0 -7
- package/dist/types/src/components/Form/custom/SelectOptionsInput.stories.d.ts.map +0 -1
- package/dist/types/src/components/Form/custom/TupleInput.d.ts +0 -6
- package/dist/types/src/components/Form/custom/TupleInput.d.ts.map +0 -1
- package/dist/types/src/components/Form/custom/index.d.ts +0 -4
- package/dist/types/src/components/Form/custom/index.d.ts.map +0 -1
- package/dist/types/src/components/Form/factory.d.ts +0 -8
- package/dist/types/src/components/Form/factory.d.ts.map +0 -1
- package/dist/types/src/components/deprecated/Form.d.ts +0 -15
- package/dist/types/src/components/deprecated/Form.d.ts.map +0 -1
- package/dist/types/src/components/deprecated/Form.stories.d.ts +0 -13
- package/dist/types/src/components/deprecated/Form.stories.d.ts.map +0 -1
- package/dist/types/src/components/deprecated/FormInput.d.ts +0 -16
- package/dist/types/src/components/deprecated/FormInput.d.ts.map +0 -1
- package/dist/types/src/components/deprecated/index.d.ts +0 -2
- package/dist/types/src/components/deprecated/index.d.ts.map +0 -1
- package/dist/types/src/hooks/useForm.d.ts +0 -67
- package/dist/types/src/hooks/useForm.d.ts.map +0 -1
- package/dist/types/src/hooks/useQueryRefOptions.d.ts +0 -23
- package/dist/types/src/hooks/useQueryRefOptions.d.ts.map +0 -1
- package/dist/types/src/hooks/useRefQueryLookupHandler.d.ts +0 -8
- package/dist/types/src/hooks/useRefQueryLookupHandler.d.ts.map +0 -1
- package/dist/types/src/util/schema.d.ts +0 -3
- package/dist/types/src/util/schema.d.ts.map +0 -1
- package/src/components/ControlSection/ControlSection.stories.tsx +0 -41
- package/src/components/ControlSection/ControlSection.tsx +0 -139
- package/src/components/Form/ArrayField.tsx +0 -124
- package/src/components/Form/Defaults.tsx +0 -203
- package/src/components/Form/FormActions.tsx +0 -53
- package/src/components/Form/FormContent.tsx +0 -240
- package/src/components/Form/FormContext.tsx +0 -110
- package/src/components/Form/Input.tsx +0 -51
- package/src/components/Form/RefField.tsx +0 -213
- package/src/components/Form/custom/GeoPointInput.tsx +0 -72
- package/src/components/Form/custom/SelectOptionsInput.stories.tsx +0 -61
- package/src/components/Form/custom/index.ts +0 -7
- package/src/components/Form/factory.tsx +0 -31
- package/src/components/deprecated/Form.stories.tsx +0 -62
- package/src/components/deprecated/Form.tsx +0 -119
- package/src/components/deprecated/FormInput.tsx +0 -71
- package/src/components/deprecated/index.ts +0 -5
- package/src/hooks/useForm.ts +0 -291
- package/src/hooks/useQueryRefOptions.ts +0 -53
- package/src/hooks/useRefQueryLookupHandler.ts +0 -39
- package/src/util/schema.ts +0 -14
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import { type Schema } from 'effect';
|
|
2
|
-
import { type BaseObject } from '@dxos/echo-schema';
|
|
3
|
-
import { type SimpleType, type JsonPath } from '@dxos/effect';
|
|
4
|
-
import { type ValidationError } from '@dxos/schema';
|
|
5
|
-
import { type MaybePromise } from '@dxos/util';
|
|
6
|
-
/**
|
|
7
|
-
* Return type from `useForm` hook.
|
|
8
|
-
*/
|
|
9
|
-
export type FormHandler<T extends BaseObject> = {
|
|
10
|
-
values: Partial<T>;
|
|
11
|
-
errors: Record<JsonPath, string>;
|
|
12
|
-
touched: Record<JsonPath, boolean>;
|
|
13
|
-
changed: Record<JsonPath, boolean>;
|
|
14
|
-
canSave: boolean;
|
|
15
|
-
formIsValid: boolean;
|
|
16
|
-
handleSave: () => void;
|
|
17
|
-
getStatus: (path: string | (string | number)[]) => {
|
|
18
|
-
status?: 'error';
|
|
19
|
-
error?: string;
|
|
20
|
-
};
|
|
21
|
-
getValue: <V>(path: (string | number)[]) => V | undefined;
|
|
22
|
-
onValueChange: <V>(path: (string | number)[], type: SimpleType, value: V) => void;
|
|
23
|
-
onTouched: (path: (string | number)[]) => void;
|
|
24
|
-
};
|
|
25
|
-
/**
|
|
26
|
-
* Hook options.
|
|
27
|
-
*/
|
|
28
|
-
export interface FormOptions<T extends BaseObject> {
|
|
29
|
-
/**
|
|
30
|
-
* Effect schema (Type literal).
|
|
31
|
-
*/
|
|
32
|
-
schema: Schema.Schema<T, any>;
|
|
33
|
-
/**
|
|
34
|
-
* Initial values (which may not pass validation).
|
|
35
|
-
*/
|
|
36
|
-
initialValues: Partial<T>;
|
|
37
|
-
/**
|
|
38
|
-
* Callback for value changes. Note: This is called even when values are invalid.
|
|
39
|
-
* Sometimes the parent component may want to know about changes even if the form is
|
|
40
|
-
* in an invalid state.
|
|
41
|
-
*/
|
|
42
|
-
onValuesChanged?: (values: Partial<T>) => void;
|
|
43
|
-
/**
|
|
44
|
-
* Custom validation function that runs only after schema validation passes.
|
|
45
|
-
* Use this for complex validation logic that can't be expressed in the schema.
|
|
46
|
-
* @returns Array of validation errors, or undefined if validation passes
|
|
47
|
-
*/
|
|
48
|
-
onValidate?: (values: T) => ValidationError[] | undefined;
|
|
49
|
-
/**
|
|
50
|
-
* Called when the form is valid.
|
|
51
|
-
*/
|
|
52
|
-
onValid?: (values: T, meta: {
|
|
53
|
-
changed: FormHandler<T>['changed'];
|
|
54
|
-
}) => void;
|
|
55
|
-
/**
|
|
56
|
-
* Called when the form is submitted and passes validation.
|
|
57
|
-
*/
|
|
58
|
-
onSave?: (values: T, meta: {
|
|
59
|
-
changed: FormHandler<T>['changed'];
|
|
60
|
-
}) => MaybePromise<void>;
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* Creates a hook for managing form state, including values, validation, and submission.
|
|
64
|
-
* Deeply integrated with `@dxos/schema` for schema-based validation.
|
|
65
|
-
*/
|
|
66
|
-
export declare const useForm: <T extends BaseObject>({ schema, initialValues, onValuesChanged, onValidate, onValid, onSave, }: FormOptions<T>) => FormHandler<T>;
|
|
67
|
-
//# sourceMappingURL=useForm.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useForm.d.ts","sourceRoot":"","sources":["../../../../src/hooks/useForm.ts"],"names":[],"mappings":"AAIA,OAAO,EAAa,KAAK,MAAM,EAAE,MAAM,QAAQ,CAAC;AAGhD,OAAO,EAAE,KAAK,UAAU,EAAsB,MAAM,mBAAmB,CAAC;AACxE,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,QAAQ,EAA4C,MAAM,cAAc,CAAC;AAGxG,OAAO,EAAkB,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AACpE,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C;;GAEG;AACH,MAAM,MAAM,WAAW,CAAC,CAAC,SAAS,UAAU,IAAI;IAK9C,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACjC,OAAO,EAAE,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACnC,OAAO,EAAE,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,MAAM,IAAI,CAAC;IAMvB,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,KAAK;QAAE,MAAM,CAAC,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACxF,QAAQ,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,KAAK,CAAC,GAAG,SAAS,CAAC;IAC1D,aAAa,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;IAClF,SAAS,EAAE,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,KAAK,IAAI,CAAC;CAChD,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,WAAW,CAAC,CAAC,SAAS,UAAU;IAC/C;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAE9B;;OAEG;IACH,aAAa,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IAE1B;;;;OAIG;IACH,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;IAE/C;;;;OAIG;IAEH,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,eAAe,EAAE,GAAG,SAAS,CAAC;IAE1D;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE;QAAE,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;KAAE,KAAK,IAAI,CAAC;IAE5E;;OAEG;IACH,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE;QAAE,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;KAAE,KAAK,YAAY,CAAC,IAAI,CAAC,CAAC;CAC1F;AAED;;;GAGG;AACH,eAAO,MAAM,OAAO,GAAI,CAAC,SAAS,UAAU,EAAE,0EAO3C,WAAW,CAAC,CAAC,CAAC,KAAG,WAAW,CAAC,CAAC,CAoLhC,CAAC"}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { type TypeAnnotation } from '@dxos/echo-schema';
|
|
2
|
-
import { type DXN } from '@dxos/keys';
|
|
3
|
-
import { type TagPickerItemData } from '@dxos/react-ui-tag-picker';
|
|
4
|
-
import { type MaybePromise } from '@dxos/util';
|
|
5
|
-
export type RefOption = {
|
|
6
|
-
dxn: DXN;
|
|
7
|
-
label?: string;
|
|
8
|
-
};
|
|
9
|
-
export type QueryRefOptions = (type: TypeAnnotation) => MaybePromise<RefOption[]>;
|
|
10
|
-
type UseQueryRefOptionsProps = {
|
|
11
|
-
refTypeInfo: TypeAnnotation | undefined;
|
|
12
|
-
onQueryRefOptions?: QueryRefOptions;
|
|
13
|
-
};
|
|
14
|
-
/**
|
|
15
|
-
* Hook to query reference options based on type information.
|
|
16
|
-
* Used internally within forms to fetch and format reference options for reference fields.
|
|
17
|
-
*/
|
|
18
|
-
export declare const useQueryRefOptions: ({ refTypeInfo, onQueryRefOptions }: UseQueryRefOptionsProps) => {
|
|
19
|
-
options: TagPickerItemData[];
|
|
20
|
-
loading: boolean;
|
|
21
|
-
};
|
|
22
|
-
export {};
|
|
23
|
-
//# sourceMappingURL=useQueryRefOptions.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useQueryRefOptions.d.ts","sourceRoot":"","sources":["../../../../src/hooks/useQueryRefOptions.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,KAAK,GAAG,EAAE,MAAM,YAAY,CAAC;AAEtC,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AACnE,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,MAAM,MAAM,SAAS,GAAG;IAAE,GAAG,EAAE,GAAG,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AACrD,MAAM,MAAM,eAAe,GAAG,CAAC,IAAI,EAAE,cAAc,KAAK,YAAY,CAAC,SAAS,EAAE,CAAC,CAAC;AAElF,KAAK,uBAAuB,GAAG;IAAE,WAAW,EAAE,cAAc,GAAG,SAAS,CAAC;IAAC,iBAAiB,CAAC,EAAE,eAAe,CAAA;CAAE,CAAC;AAEhH;;;GAGG;AACH,eAAO,MAAM,kBAAkB,GAAI,oCAAoC,uBAAuB;;;CA+B7F,CAAC"}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { type Space } from '@dxos/react-client/echo';
|
|
2
|
-
import { type QueryRefOptions } from './useQueryRefOptions';
|
|
3
|
-
type UseRefQueryLookupProps = {
|
|
4
|
-
space?: Space;
|
|
5
|
-
};
|
|
6
|
-
export declare const useRefQueryLookupHandler: ({ space }: UseRefQueryLookupProps) => QueryRefOptions;
|
|
7
|
-
export {};
|
|
8
|
-
//# sourceMappingURL=useRefQueryLookupHandler.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useRefQueryLookupHandler.d.ts","sourceRoot":"","sources":["../../../../src/hooks/useRefQueryLookupHandler.ts"],"names":[],"mappings":"AAOA,OAAO,EAAU,KAAK,KAAK,EAAE,MAAM,yBAAyB,CAAC;AAG7D,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAE5D,KAAK,sBAAsB,GAAG;IAAE,KAAK,CAAC,EAAE,KAAK,CAAA;CAAE,CAAC;AAEhD,eAAO,MAAM,wBAAwB,GAAI,WAAW,sBAAsB,KAAG,eAwB5E,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../../src/util/schema.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAInC,eAAO,MAAM,oBAAoB,GAAI,KAAK,SAAS,CAAC,GAAG,8BAKtD,CAAC"}
|
|
@@ -1,41 +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 { StackItem } from '@dxos/react-ui-stack';
|
|
11
|
-
import { withLayout, withTheme } from '@dxos/storybook-utils';
|
|
12
|
-
|
|
13
|
-
import { ControlPage, ControlSection, type ControlSectionProps } from './ControlSection';
|
|
14
|
-
import { translations } from '../../translations';
|
|
15
|
-
|
|
16
|
-
const meta: Meta<ControlSectionProps> = {
|
|
17
|
-
title: 'ui/react-ui-form/ControlSection',
|
|
18
|
-
component: ControlSection,
|
|
19
|
-
render: (args) => (
|
|
20
|
-
<StackItem.Content classNames='w-[40rem]'>
|
|
21
|
-
<ControlPage>
|
|
22
|
-
<ControlSection {...args} />
|
|
23
|
-
</ControlPage>
|
|
24
|
-
</StackItem.Content>
|
|
25
|
-
),
|
|
26
|
-
decorators: [withLayout({ fullscreen: true, classNames: 'justify-center' }), withTheme],
|
|
27
|
-
parameters: {
|
|
28
|
-
translations,
|
|
29
|
-
},
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
export default meta;
|
|
33
|
-
|
|
34
|
-
type Story = StoryObj<ControlSectionProps>;
|
|
35
|
-
|
|
36
|
-
export const Default: Story = {
|
|
37
|
-
args: {
|
|
38
|
-
title: 'Control Section',
|
|
39
|
-
description: 'This is a control section',
|
|
40
|
-
},
|
|
41
|
-
};
|
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Copyright 2025 DXOS.org
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
import React, { type ComponentPropsWithoutRef, type PropsWithChildren } from 'react';
|
|
6
|
-
|
|
7
|
-
import {
|
|
8
|
-
Button,
|
|
9
|
-
type ButtonProps,
|
|
10
|
-
Input,
|
|
11
|
-
type Label,
|
|
12
|
-
type ThemedClassName,
|
|
13
|
-
toLocalizedString,
|
|
14
|
-
useTranslation,
|
|
15
|
-
} from '@dxos/react-ui';
|
|
16
|
-
import { mx } from '@dxos/react-ui-theme';
|
|
17
|
-
|
|
18
|
-
import { translationKey } from '../../translations';
|
|
19
|
-
|
|
20
|
-
export type ControlPageProps = ThemedClassName<ComponentPropsWithoutRef<'div'>>;
|
|
21
|
-
|
|
22
|
-
export const ControlPage = ({ children, classNames, ...props }: ControlPageProps) => {
|
|
23
|
-
return (
|
|
24
|
-
<div role='none' className={mx('pli-cardSpacingInline', classNames)} {...props}>
|
|
25
|
-
{children}
|
|
26
|
-
</div>
|
|
27
|
-
);
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
export type ControlSectionProps = PropsWithChildren<{
|
|
31
|
-
title: Label;
|
|
32
|
-
description?: Label;
|
|
33
|
-
}>;
|
|
34
|
-
|
|
35
|
-
export const ControlSection = ({ title, description, children }: ControlSectionProps) => {
|
|
36
|
-
return (
|
|
37
|
-
<>
|
|
38
|
-
<ControlSectionHeading title={title} description={description} />
|
|
39
|
-
{children}
|
|
40
|
-
</>
|
|
41
|
-
);
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
export const ControlSectionHeading = ({ title, description }: Omit<ControlSectionProps, 'children'>) => {
|
|
45
|
-
const { t } = useTranslation(translationKey);
|
|
46
|
-
return (
|
|
47
|
-
<>
|
|
48
|
-
<h2 className='pli-trimMd container-max-width text-xl mbs-trimLg mbe-trimMd'>{toLocalizedString(title, t)}</h2>
|
|
49
|
-
{description && (
|
|
50
|
-
<p className='pli-trimMd mlb-trimMd container-max-width text-description'>
|
|
51
|
-
{toLocalizedString(description, t)}
|
|
52
|
-
</p>
|
|
53
|
-
)}
|
|
54
|
-
</>
|
|
55
|
-
);
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
export const ControlGroupButton = ({ classNames, ...props }: ButtonProps) => {
|
|
59
|
-
return <Button {...props} classNames={['md:col-span-2', classNames]} />;
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
export type ControlGroupProps = ThemedClassName<PropsWithChildren<{}>>;
|
|
63
|
-
|
|
64
|
-
export const ControlGroup = ({ children, classNames }: ControlGroupProps) => (
|
|
65
|
-
<div
|
|
66
|
-
role='none'
|
|
67
|
-
className={mx('group container-max-width grid grid-cols-1 md:grid-cols-[1fr_min-content] gap-trimMd', classNames)}
|
|
68
|
-
>
|
|
69
|
-
{children}
|
|
70
|
-
</div>
|
|
71
|
-
);
|
|
72
|
-
|
|
73
|
-
export const ControlFrame = ({ children }: ControlGroupProps) => (
|
|
74
|
-
<div
|
|
75
|
-
role='none'
|
|
76
|
-
className='p-trimMd container-max-width grid grid-cols-1 md:grid-cols-[1fr_1fr] gap-trimSm md:gap-trimMd border border-separator rounded-md'
|
|
77
|
-
>
|
|
78
|
-
{children}
|
|
79
|
-
</div>
|
|
80
|
-
);
|
|
81
|
-
|
|
82
|
-
export type ControlItemProps = PropsWithChildren<{
|
|
83
|
-
title: Label;
|
|
84
|
-
description?: Label;
|
|
85
|
-
}>;
|
|
86
|
-
|
|
87
|
-
export const controlItemClasses =
|
|
88
|
-
'pli-trimMd plb-trimMd container-max-width grid md:col-span-2 grid-cols-subgrid items-center gap-trimSm border border-separator rounded-md *:first:!mbs-0 *:last:!mbe-0';
|
|
89
|
-
|
|
90
|
-
const controlItemTitleClasses = 'text-lg font-normal';
|
|
91
|
-
const controlItemDescriptionClasses = 'text-base mlb-trimSm md:mbe-0 text-description';
|
|
92
|
-
|
|
93
|
-
export const ControlItem = ({ title, description, children }: ControlItemProps) => {
|
|
94
|
-
const { t } = useTranslation(translationKey);
|
|
95
|
-
|
|
96
|
-
return (
|
|
97
|
-
<div className={controlItemClasses}>
|
|
98
|
-
<div role='none'>
|
|
99
|
-
<h3 className={controlItemTitleClasses}>{toLocalizedString(title, t)}</h3>
|
|
100
|
-
{description && <p className={controlItemDescriptionClasses}>{toLocalizedString(description, t)}</p>}
|
|
101
|
-
</div>
|
|
102
|
-
{children}
|
|
103
|
-
</div>
|
|
104
|
-
);
|
|
105
|
-
};
|
|
106
|
-
|
|
107
|
-
export const ControlItemInput = ({ title, description, children }: ControlItemProps) => {
|
|
108
|
-
const { t } = useTranslation(translationKey);
|
|
109
|
-
|
|
110
|
-
return (
|
|
111
|
-
<Input.Root>
|
|
112
|
-
<div className={controlItemClasses}>
|
|
113
|
-
<div role='none'>
|
|
114
|
-
<Input.Label classNames={controlItemTitleClasses}>{toLocalizedString(title, t)}</Input.Label>
|
|
115
|
-
{description && (
|
|
116
|
-
<Input.DescriptionAndValidation>
|
|
117
|
-
<Input.Description classNames={controlItemDescriptionClasses}>
|
|
118
|
-
{toLocalizedString(description, t)}
|
|
119
|
-
</Input.Description>
|
|
120
|
-
</Input.DescriptionAndValidation>
|
|
121
|
-
)}
|
|
122
|
-
</div>
|
|
123
|
-
{children}
|
|
124
|
-
</div>
|
|
125
|
-
</Input.Root>
|
|
126
|
-
);
|
|
127
|
-
};
|
|
128
|
-
|
|
129
|
-
export const ControlFrameItem = ({ title, description, children }: ControlItemProps) => {
|
|
130
|
-
const { t } = useTranslation(translationKey);
|
|
131
|
-
|
|
132
|
-
return (
|
|
133
|
-
<div role='group' className='min-is-0'>
|
|
134
|
-
<h3 className='text-lg mbe-2'>{toLocalizedString(title, t)}</h3>
|
|
135
|
-
{description && <p className='mlb-trimSm md:mbe-0 text-description'>{toLocalizedString(description, t)}</p>}
|
|
136
|
-
{children}
|
|
137
|
-
</div>
|
|
138
|
-
);
|
|
139
|
-
};
|
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Copyright 2025 DXOS.org
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
import { SchemaAST, pipe } from 'effect';
|
|
6
|
-
import { capitalize } from 'effect/String';
|
|
7
|
-
import React, { Fragment, useCallback } from 'react';
|
|
8
|
-
|
|
9
|
-
import { findNode, getDiscriminatedType, isDiscriminatedUnion, SimpleType } from '@dxos/effect';
|
|
10
|
-
import { invariant } from '@dxos/invariant';
|
|
11
|
-
import { IconButton, useTranslation } from '@dxos/react-ui';
|
|
12
|
-
import { getSchemaProperties, type SchemaProperty } from '@dxos/schema';
|
|
13
|
-
|
|
14
|
-
import { type ComponentLookup } from './Form';
|
|
15
|
-
import { FormField } from './FormContent';
|
|
16
|
-
import { useFormValues, type FormInputStateProps } from './FormContext';
|
|
17
|
-
import { InputHeader, type InputComponent } from './Input';
|
|
18
|
-
import { translationKey } from '../../translations';
|
|
19
|
-
import { findArrayElementType } from '../../util';
|
|
20
|
-
|
|
21
|
-
type ArrayFieldProps = {
|
|
22
|
-
property: SchemaProperty<any>;
|
|
23
|
-
readonly?: boolean;
|
|
24
|
-
inputProps: FormInputStateProps;
|
|
25
|
-
path?: (string | number)[];
|
|
26
|
-
Custom?: Partial<Record<string, InputComponent>>;
|
|
27
|
-
lookupComponent?: ComponentLookup;
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
export const ArrayField = ({ property, readonly, path, inputProps, Custom, lookupComponent }: ArrayFieldProps) => {
|
|
31
|
-
const { t } = useTranslation(translationKey);
|
|
32
|
-
const { ast, name, type, title } = property;
|
|
33
|
-
// TODO(wittjosiah): The fallback to an empty array stops the form from crashing but isn't immediately live.
|
|
34
|
-
// It doesn't become live until another field is touched, but that's better than the whole form crashing.
|
|
35
|
-
const values = (useFormValues(path ?? []) ?? []) as any[];
|
|
36
|
-
invariant(Array.isArray(values), `Values at path ${path?.join('.')} must be an array.`);
|
|
37
|
-
const label = title ?? pipe(name, capitalize);
|
|
38
|
-
|
|
39
|
-
const elementType = findArrayElementType(ast);
|
|
40
|
-
|
|
41
|
-
const getDefaultObjectValue = (typeNode: SchemaAST.AST): any => {
|
|
42
|
-
const baseNode = findNode(typeNode, isDiscriminatedUnion);
|
|
43
|
-
const typeLiteral = baseNode ? getDiscriminatedType(baseNode, {}) : findNode(typeNode, SchemaAST.isTypeLiteral);
|
|
44
|
-
if (!typeLiteral) {
|
|
45
|
-
return {};
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
return Object.fromEntries(getSchemaProperties(typeLiteral, {}).map((prop) => [prop.name, prop.defaultValue]));
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
const getDefaultValue = () =>
|
|
52
|
-
type === 'object' && elementType ? getDefaultObjectValue(elementType) : SimpleType.getDefaultValue(type);
|
|
53
|
-
|
|
54
|
-
const handleAdd = useCallback(() => {
|
|
55
|
-
inputProps.onValueChange(type, [...values, getDefaultValue()]);
|
|
56
|
-
}, [type, elementType, inputProps, values]);
|
|
57
|
-
|
|
58
|
-
const handleRemove = useCallback(
|
|
59
|
-
(index: number) => {
|
|
60
|
-
const newValues = values.filter((_, i) => i !== index);
|
|
61
|
-
inputProps.onValueChange(type, newValues);
|
|
62
|
-
},
|
|
63
|
-
[type, inputProps, values],
|
|
64
|
-
);
|
|
65
|
-
|
|
66
|
-
if (!elementType) {
|
|
67
|
-
return null;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
return readonly && values.length < 1 ? null : (
|
|
71
|
-
<>
|
|
72
|
-
<InputHeader readonly label={label} />
|
|
73
|
-
<div
|
|
74
|
-
role='none'
|
|
75
|
-
className={
|
|
76
|
-
readonly
|
|
77
|
-
? 'flex flex-wrap gap-1 mlb-1'
|
|
78
|
-
: values.length > 0
|
|
79
|
-
? 'grid gap-1 grid-cols-[1fr_min-content] mlb-1'
|
|
80
|
-
: 'hidden'
|
|
81
|
-
}
|
|
82
|
-
>
|
|
83
|
-
{values.map((_value, index) => {
|
|
84
|
-
const field = (
|
|
85
|
-
<FormField
|
|
86
|
-
property={{
|
|
87
|
-
...property,
|
|
88
|
-
array: false, // NOTE(ZaymonFC): This breaks arrays of arrays but ¯\_(ツ)_/¯. Ping me if you need that.
|
|
89
|
-
ast: elementType,
|
|
90
|
-
}}
|
|
91
|
-
path={[...(path ?? []), index]}
|
|
92
|
-
readonly={readonly}
|
|
93
|
-
inline
|
|
94
|
-
Custom={Custom}
|
|
95
|
-
lookupComponent={lookupComponent}
|
|
96
|
-
/>
|
|
97
|
-
);
|
|
98
|
-
return readonly ? (
|
|
99
|
-
field
|
|
100
|
-
) : (
|
|
101
|
-
<Fragment key={index}>
|
|
102
|
-
<div role='none'>{field}</div>
|
|
103
|
-
<IconButton
|
|
104
|
-
icon='ph--trash--regular'
|
|
105
|
-
iconOnly
|
|
106
|
-
label={t('button remove')}
|
|
107
|
-
onClick={() => handleRemove(index)}
|
|
108
|
-
classNames='self-center'
|
|
109
|
-
/>
|
|
110
|
-
</Fragment>
|
|
111
|
-
);
|
|
112
|
-
})}
|
|
113
|
-
</div>
|
|
114
|
-
{!readonly && (
|
|
115
|
-
<IconButton
|
|
116
|
-
classNames='is-full mlb-cardSpacingBlock flex'
|
|
117
|
-
icon='ph--plus--regular'
|
|
118
|
-
label={t('add field')}
|
|
119
|
-
onClick={handleAdd}
|
|
120
|
-
/>
|
|
121
|
-
)}
|
|
122
|
-
</>
|
|
123
|
-
);
|
|
124
|
-
};
|
|
@@ -1,203 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Copyright 2024 DXOS.org
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
import React, { useCallback, useEffect, useRef } from 'react';
|
|
6
|
-
|
|
7
|
-
import { Input, Select, useTranslation } from '@dxos/react-ui';
|
|
8
|
-
|
|
9
|
-
import { type InputProps, InputHeader } from './Input';
|
|
10
|
-
import { translationKey } from '../../translations';
|
|
11
|
-
|
|
12
|
-
export const TextInput = ({
|
|
13
|
-
type,
|
|
14
|
-
label,
|
|
15
|
-
inputOnly,
|
|
16
|
-
disabled,
|
|
17
|
-
placeholder,
|
|
18
|
-
getStatus,
|
|
19
|
-
getValue,
|
|
20
|
-
onValueChange,
|
|
21
|
-
onBlur,
|
|
22
|
-
}: InputProps) => {
|
|
23
|
-
const { status, error } = getStatus();
|
|
24
|
-
|
|
25
|
-
return disabled && !getValue() ? null : disabled && inputOnly ? (
|
|
26
|
-
<p>{getValue() ?? ''}</p>
|
|
27
|
-
) : (
|
|
28
|
-
<Input.Root validationValence={status}>
|
|
29
|
-
{!inputOnly && <InputHeader error={error} label={label} />}
|
|
30
|
-
{disabled ? (
|
|
31
|
-
<p>{getValue() ?? ''}</p>
|
|
32
|
-
) : (
|
|
33
|
-
<Input.TextInput
|
|
34
|
-
disabled={disabled}
|
|
35
|
-
placeholder={placeholder}
|
|
36
|
-
value={getValue() ?? ''}
|
|
37
|
-
onChange={(event) => onValueChange(type, event.target.value)}
|
|
38
|
-
onBlur={onBlur}
|
|
39
|
-
/>
|
|
40
|
-
)}
|
|
41
|
-
{inputOnly && <Input.Validation>{error}</Input.Validation>}
|
|
42
|
-
</Input.Root>
|
|
43
|
-
);
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
export const NumberInput = ({
|
|
47
|
-
type,
|
|
48
|
-
label,
|
|
49
|
-
inputOnly,
|
|
50
|
-
disabled,
|
|
51
|
-
placeholder,
|
|
52
|
-
getStatus,
|
|
53
|
-
getValue,
|
|
54
|
-
onValueChange,
|
|
55
|
-
onBlur,
|
|
56
|
-
}: InputProps) => {
|
|
57
|
-
const { status, error } = getStatus();
|
|
58
|
-
|
|
59
|
-
return disabled && !getValue() ? null : disabled && inputOnly ? (
|
|
60
|
-
<p>{getValue() ?? ''}</p>
|
|
61
|
-
) : (
|
|
62
|
-
<Input.Root validationValence={status}>
|
|
63
|
-
{!inputOnly && <InputHeader error={error} label={label} />}
|
|
64
|
-
{disabled ? (
|
|
65
|
-
<p>{getValue() ?? ''}</p>
|
|
66
|
-
) : (
|
|
67
|
-
<Input.TextInput
|
|
68
|
-
type='number'
|
|
69
|
-
disabled={disabled}
|
|
70
|
-
placeholder={placeholder}
|
|
71
|
-
value={getValue() ?? 0}
|
|
72
|
-
onChange={(event) => onValueChange(type, event.target.value)}
|
|
73
|
-
onBlur={onBlur}
|
|
74
|
-
/>
|
|
75
|
-
)}
|
|
76
|
-
{inputOnly && <Input.DescriptionAndValidation>{error}</Input.DescriptionAndValidation>}
|
|
77
|
-
</Input.Root>
|
|
78
|
-
);
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
export const BooleanInput = ({ type, label, inputOnly, getStatus, getValue, onValueChange, disabled }: InputProps) => {
|
|
82
|
-
const { status, error } = getStatus();
|
|
83
|
-
const checked = Boolean(getValue());
|
|
84
|
-
const { t } = useTranslation(translationKey);
|
|
85
|
-
|
|
86
|
-
return (
|
|
87
|
-
<Input.Root validationValence={status}>
|
|
88
|
-
{!inputOnly && <InputHeader error={error} label={label} />}
|
|
89
|
-
{disabled ? (
|
|
90
|
-
<p>{t(checked ? 'boolean input true value' : 'boolean input false value')}</p>
|
|
91
|
-
) : (
|
|
92
|
-
<Input.Switch checked={checked} onCheckedChange={(value) => onValueChange(type, value)} />
|
|
93
|
-
)}
|
|
94
|
-
{inputOnly && <Input.DescriptionAndValidation>{error}</Input.DescriptionAndValidation>}
|
|
95
|
-
</Input.Root>
|
|
96
|
-
);
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
export type SelectInputOptions = InputProps & {
|
|
100
|
-
options?: Array<{ value: string | number; label?: string }>;
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
export const SelectInput = ({
|
|
104
|
-
type,
|
|
105
|
-
label,
|
|
106
|
-
inputOnly,
|
|
107
|
-
disabled,
|
|
108
|
-
placeholder,
|
|
109
|
-
options,
|
|
110
|
-
getStatus,
|
|
111
|
-
getValue,
|
|
112
|
-
onValueChange,
|
|
113
|
-
}: SelectInputOptions) => {
|
|
114
|
-
const { status, error } = getStatus();
|
|
115
|
-
|
|
116
|
-
const value = getValue() as string | undefined;
|
|
117
|
-
const handleValueChange = useCallback((value: string | number) => onValueChange(type, value), [type, onValueChange]);
|
|
118
|
-
|
|
119
|
-
return disabled && !value ? null : (
|
|
120
|
-
<Input.Root validationValence={status}>
|
|
121
|
-
{!inputOnly && <InputHeader error={error} label={label} />}
|
|
122
|
-
{disabled ? (
|
|
123
|
-
<p>{options?.find(({ value: optionValue }) => optionValue === value)?.label ?? String(value)}</p>
|
|
124
|
-
) : (
|
|
125
|
-
<Select.Root value={value} onValueChange={handleValueChange}>
|
|
126
|
-
{/* TODO(burdon): Placeholder not working? */}
|
|
127
|
-
<Select.TriggerButton classNames='is-full' disabled={disabled} placeholder={placeholder} />
|
|
128
|
-
<Select.Portal>
|
|
129
|
-
<Select.Content>
|
|
130
|
-
<Select.Viewport>
|
|
131
|
-
{options?.map(({ value, label }) => (
|
|
132
|
-
// NOTE: Numeric values are converted to and from strings.
|
|
133
|
-
<Select.Option key={String(value)} value={String(value)}>
|
|
134
|
-
{label ?? String(value)}
|
|
135
|
-
</Select.Option>
|
|
136
|
-
))}
|
|
137
|
-
</Select.Viewport>
|
|
138
|
-
</Select.Content>
|
|
139
|
-
</Select.Portal>
|
|
140
|
-
</Select.Root>
|
|
141
|
-
)}
|
|
142
|
-
{inputOnly && <Input.DescriptionAndValidation>{error}</Input.DescriptionAndValidation>}
|
|
143
|
-
</Input.Root>
|
|
144
|
-
);
|
|
145
|
-
};
|
|
146
|
-
|
|
147
|
-
export const MarkdownInput = ({
|
|
148
|
-
type,
|
|
149
|
-
label,
|
|
150
|
-
inputOnly,
|
|
151
|
-
disabled,
|
|
152
|
-
placeholder,
|
|
153
|
-
getStatus,
|
|
154
|
-
getValue,
|
|
155
|
-
onValueChange,
|
|
156
|
-
onBlur,
|
|
157
|
-
}: InputProps) => {
|
|
158
|
-
const { status, error } = getStatus();
|
|
159
|
-
const textareaRef = useRef<HTMLTextAreaElement>(null);
|
|
160
|
-
|
|
161
|
-
// TODO(ZaymonFC): If we start using `Enter` for form submission, we should prevent default behavior here
|
|
162
|
-
// since we're using a textarea element and the user needs to be able to enter new lines.
|
|
163
|
-
|
|
164
|
-
const adjustHeight = useCallback(() => {
|
|
165
|
-
const textarea = textareaRef.current;
|
|
166
|
-
if (textarea) {
|
|
167
|
-
textarea.style.blockSize = 'auto'; // For measurement.
|
|
168
|
-
textarea.style.blockSize = `${textarea.scrollHeight + 2}px`;
|
|
169
|
-
}
|
|
170
|
-
}, []);
|
|
171
|
-
|
|
172
|
-
// Adjust height on initial render.
|
|
173
|
-
useEffect(() => {
|
|
174
|
-
adjustHeight();
|
|
175
|
-
}, [adjustHeight]);
|
|
176
|
-
|
|
177
|
-
// Adjust height when the content changes.
|
|
178
|
-
useEffect(() => {
|
|
179
|
-
adjustHeight();
|
|
180
|
-
}, [getValue(), adjustHeight]);
|
|
181
|
-
|
|
182
|
-
return (
|
|
183
|
-
<Input.Root validationValence={status}>
|
|
184
|
-
{!inputOnly && <InputHeader error={error} label={label} />}
|
|
185
|
-
{disabled ? (
|
|
186
|
-
<p>{getValue() ?? ''}</p>
|
|
187
|
-
) : (
|
|
188
|
-
<Input.TextArea
|
|
189
|
-
ref={textareaRef}
|
|
190
|
-
disabled={disabled}
|
|
191
|
-
placeholder={placeholder}
|
|
192
|
-
value={getValue() ?? ''}
|
|
193
|
-
classNames={'min-bs-auto max-h-40 overflow-auto'}
|
|
194
|
-
onChange={(event) => onValueChange(type, event.target.value)}
|
|
195
|
-
onBlur={onBlur}
|
|
196
|
-
style={{ resize: 'none' }}
|
|
197
|
-
spellCheck={false}
|
|
198
|
-
/>
|
|
199
|
-
)}
|
|
200
|
-
{inputOnly && <Input.Validation>{error}</Input.Validation>}
|
|
201
|
-
</Input.Root>
|
|
202
|
-
);
|
|
203
|
-
};
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Copyright 2025 DXOS.org
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
import React from 'react';
|
|
6
|
-
|
|
7
|
-
import { IconButton, useTranslation } from '@dxos/react-ui';
|
|
8
|
-
import { cardSpacing } from '@dxos/react-ui-stack';
|
|
9
|
-
import { mx } from '@dxos/react-ui-theme';
|
|
10
|
-
|
|
11
|
-
import { useFormContext } from './FormContext';
|
|
12
|
-
import { translationKey } from '../../translations';
|
|
13
|
-
|
|
14
|
-
export type FormOuterSpacing = boolean | 'blockStart-0' | 'scroll-fields';
|
|
15
|
-
|
|
16
|
-
export type FormActionsProps = {
|
|
17
|
-
readonly?: boolean;
|
|
18
|
-
onCancel?: () => void;
|
|
19
|
-
outerSpacing?: FormOuterSpacing;
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
export const FormActions = ({ readonly, onCancel, outerSpacing = true }: FormActionsProps) => {
|
|
23
|
-
const { t } = useTranslation(translationKey);
|
|
24
|
-
const { canSave, handleSave } = useFormContext();
|
|
25
|
-
|
|
26
|
-
return (
|
|
27
|
-
<div
|
|
28
|
-
role='none'
|
|
29
|
-
className={mx(
|
|
30
|
-
outerSpacing === 'scroll-fields'
|
|
31
|
-
? 'pli-cardSpacingInline mbe-cardSpacingBlock'
|
|
32
|
-
: outerSpacing
|
|
33
|
-
? cardSpacing
|
|
34
|
-
: 'mbs-cardSpacingBlock',
|
|
35
|
-
'flex [&_button]:grow gap-1 first:mbs-0',
|
|
36
|
-
)}
|
|
37
|
-
>
|
|
38
|
-
{onCancel && !readonly && (
|
|
39
|
-
<IconButton data-testid='cancel-button' icon='ph--x--regular' label={t('button cancel')} onClick={onCancel} />
|
|
40
|
-
)}
|
|
41
|
-
{handleSave && (
|
|
42
|
-
<IconButton
|
|
43
|
-
type='submit'
|
|
44
|
-
data-testid='save-button'
|
|
45
|
-
disabled={!canSave}
|
|
46
|
-
icon='ph--check--regular'
|
|
47
|
-
label={t('button save')}
|
|
48
|
-
onClick={handleSave}
|
|
49
|
-
/>
|
|
50
|
-
)}
|
|
51
|
-
</div>
|
|
52
|
-
);
|
|
53
|
-
};
|