@nolwenture/formik-jsonschema-form 0.3.0 → 0.4.1
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 +93 -1
- package/dist/Form.js +2 -0
- package/dist/Form.stories.js +7 -4
- package/dist/_sampleData.js +23 -12
- package/dist/styledComponents.d.ts +20 -1
- package/dist/styledComponents.js +80 -5
- package/dist/templates/ArrayFieldTemplate.js +3 -3
- package/dist/templates/FieldTemplate.js +3 -3
- package/dist/templates/ObjectFieldTemplate.js +3 -3
- package/dist/types.d.ts +9 -0
- package/dist/utils.d.ts +1 -0
- package/package.json +6 -2
package/README.md
CHANGED
|
@@ -50,9 +50,70 @@ export function MyFormComponent() {
|
|
|
50
50
|
}
|
|
51
51
|
```
|
|
52
52
|
|
|
53
|
+
Pass your uiSchema to the `Form`component. which should be passed as a child to the `Formik`component,
|
|
54
|
+
just like schema. uiSchema will tell the form more about its own layout and styles.
|
|
55
|
+
|
|
56
|
+
Basic available elements to add to the form or a field of the form via uiSchema are:
|
|
57
|
+
|
|
58
|
+
- "ui:title"
|
|
59
|
+
- "ui:description"
|
|
60
|
+
- "ui:help"
|
|
61
|
+
- "ui:options"
|
|
62
|
+
- "ui:info"
|
|
63
|
+
|
|
64
|
+
Most of those elements take a string for value, but `ui:info` takes an object with the possible keys of
|
|
65
|
+
|
|
66
|
+
- `label` for the clickable anchor (if not provided, default value is "i")
|
|
67
|
+
- `content` for the content of the popup container, and
|
|
68
|
+
- `position` taking a string of either "top", "bottom", "left" or "right" (if not provided, default value is "top")
|
|
69
|
+
|
|
70
|
+
All elements of `ui:info` are customisable. The styledComponent is called `InfoFieldButton` and it consists of the following elements:
|
|
71
|
+
|
|
72
|
+
- InfoFieldContainerElement
|
|
73
|
+
- InfoFieldBoxElement
|
|
74
|
+
- InfoFieldBoxInnerElement
|
|
75
|
+
- InfoFieldBoxArrowElement
|
|
76
|
+
- InfoFieldLabel
|
|
77
|
+
|
|
78
|
+
```tsx
|
|
79
|
+
import { Form } from "@nolwenture/formik-jsonschema-form";
|
|
80
|
+
import { Formik } from "formik";
|
|
81
|
+
|
|
82
|
+
const schema = {
|
|
83
|
+
title: "My form",
|
|
84
|
+
type: "object",
|
|
85
|
+
properties: {
|
|
86
|
+
firstName: { type: "string", title: "First name" },
|
|
87
|
+
lastName: { type: "string", title: "Last name" },
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
const uiSchema = {
|
|
92
|
+
"ui:description": "Form description",
|
|
93
|
+
firstName: { "ui:description": "Field description" },
|
|
94
|
+
lastName: {
|
|
95
|
+
"ui:info": {
|
|
96
|
+
label: "?",
|
|
97
|
+
content: "Add your family name",
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
export function MyFormComponent() {
|
|
103
|
+
return (
|
|
104
|
+
<Formik
|
|
105
|
+
initialValues={{ firstName: "", lastName: "" }}
|
|
106
|
+
onSubmit={handleSubmit}
|
|
107
|
+
>
|
|
108
|
+
<Form schema={schema} uiSchema={uiSchema}></Form>
|
|
109
|
+
</Formik>
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
53
114
|
### Using custom components
|
|
54
115
|
|
|
55
|
-
Form components (such as wrappers) can be
|
|
116
|
+
Form components (such as wrappers) can be overridden with custom ones
|
|
56
117
|
|
|
57
118
|
Here is an example of overriding `FieldWrapper` (wrapper used on all fields):
|
|
58
119
|
|
|
@@ -87,6 +148,37 @@ return (
|
|
|
87
148
|
);
|
|
88
149
|
```
|
|
89
150
|
|
|
151
|
+
And another example how to override `InfoFieldButton`:
|
|
152
|
+
|
|
153
|
+
```tsx
|
|
154
|
+
const CustomInfoFieldButton = styled(InfoFieldButton)`
|
|
155
|
+
outline: 2px red solid;
|
|
156
|
+
margin: 0.5em;
|
|
157
|
+
${InfoFieldButton.styles.InfoFieldBoxInnerElementStyle} {
|
|
158
|
+
min-width: 200px;
|
|
159
|
+
background: orange;
|
|
160
|
+
color: blue;
|
|
161
|
+
}
|
|
162
|
+
${InfoFieldButton.styles.InfoFieldLabelStyle} {
|
|
163
|
+
color: green;
|
|
164
|
+
}
|
|
165
|
+
`;
|
|
166
|
+
|
|
167
|
+
...
|
|
168
|
+
|
|
169
|
+
return (
|
|
170
|
+
<Formik initialValues={initialValues} onSubmit={handleOnSubmit}>
|
|
171
|
+
<Form
|
|
172
|
+
schema={schema}
|
|
173
|
+
uiSchema={uiSchema}
|
|
174
|
+
components={{
|
|
175
|
+
InfoFieldButton: CustomInfoFieldButton,
|
|
176
|
+
}}
|
|
177
|
+
></Form>
|
|
178
|
+
</Formik>
|
|
179
|
+
);
|
|
180
|
+
```
|
|
181
|
+
|
|
90
182
|
Custom fields can be used in addition to all the default fields:
|
|
91
183
|
|
|
92
184
|
```tsx
|
package/dist/Form.js
CHANGED
|
@@ -36,6 +36,8 @@ export function Form(props) {
|
|
|
36
36
|
"children",
|
|
37
37
|
"fields",
|
|
38
38
|
"formContext",
|
|
39
|
+
"components",
|
|
40
|
+
"hideUnmarkedAdditionalProperties",
|
|
39
41
|
]);
|
|
40
42
|
var isSubmitting = useFormikContext().isSubmitting;
|
|
41
43
|
var schema = props.schema, _a = props.uiSchema, uiSchema = _a === void 0 ? {} : _a, className = props.className, children = props.children, _b = props.fields, fields = _b === void 0 ? {} : _b, _c = props.templates, templates = _c === void 0 ? {} : _c, _d = props.components, components = _d === void 0 ? {} : _d, _e = props.formContext, formContext = _e === void 0 ? {} : _e, _f = props.useItemsAsAdditionalItems, useItemsAsAdditionalItems = _f === void 0 ? false : _f, _g = props.hideUnmarkedAdditionalProperties, hideUnmarkedAdditionalProperties = _g === void 0 ? false : _g;
|
package/dist/Form.stories.js
CHANGED
|
@@ -53,6 +53,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
53
53
|
import { action } from "@storybook/addon-actions";
|
|
54
54
|
import styled from "styled-components";
|
|
55
55
|
import { Formik, useFormikContext } from "formik";
|
|
56
|
+
import { InfoFieldButton } from "./styledComponents";
|
|
56
57
|
import { completeSchema, completeUiSchema, simpleSchema, simpleUiSchema, generatedSchema, requiredInputSchema, } from "./_sampleData";
|
|
57
58
|
import { Form, styledComponents } from "./";
|
|
58
59
|
export default {
|
|
@@ -76,10 +77,12 @@ export var Simple = Template.bind({});
|
|
|
76
77
|
Simple.args = {
|
|
77
78
|
schema: simpleSchema,
|
|
78
79
|
};
|
|
80
|
+
var InfoFieldButtonNew = styled(InfoFieldButton)(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n outline: 2px red solid;\n margin: 0.5em;\n ", " {\n min-width: 200px;\n background: orange;\n color: blue;\n }\n ", " {\n color: green;\n }\n"], ["\n outline: 2px red solid;\n margin: 0.5em;\n ", " {\n min-width: 200px;\n background: orange;\n color: blue;\n }\n ", " {\n color: green;\n }\n"])), InfoFieldButton.styles.InfoFieldBoxInnerElementStyle, InfoFieldButton.styles.InfoFieldLabelStyle);
|
|
79
81
|
export var WithUiSchema = Template.bind({});
|
|
80
82
|
WithUiSchema.args = {
|
|
81
83
|
schema: simpleSchema,
|
|
82
84
|
uiSchema: simpleUiSchema,
|
|
85
|
+
components: { InfoFieldButton: InfoFieldButtonNew },
|
|
83
86
|
};
|
|
84
87
|
export var CompleteSchema = Template.bind({});
|
|
85
88
|
CompleteSchema.args = {
|
|
@@ -97,15 +100,15 @@ export var StrictlyTyped = function () {
|
|
|
97
100
|
}); } }, { children: _jsx(Form, { schema: simpleSchema }) })));
|
|
98
101
|
};
|
|
99
102
|
/*** CUSTOMIZATION ***/
|
|
100
|
-
var CustomizedForm = styled(Form)(
|
|
101
|
-
var CustomizedFieldWrapper = styled.div(
|
|
103
|
+
var CustomizedForm = styled(Form)(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n ", " {\n color: red;\n }\n"], ["\n ", " {\n color: red;\n }\n"])), styledComponents.FieldTitle);
|
|
104
|
+
var CustomizedFieldWrapper = styled.div(templateObject_3 || (templateObject_3 = __makeTemplateObject(["\n outline: 2px solid\n ", ";\n"], ["\n outline: 2px solid\n ", ";\n"])), function (props) { return (props.title === "ABC" ? "blue" : "transparent"); });
|
|
102
105
|
var CustomizedErrorMessage = function (props) {
|
|
103
106
|
var name = props.name;
|
|
104
107
|
var errors = useFormikContext().errors;
|
|
105
108
|
var error = errors[name];
|
|
106
109
|
return error ? _jsx("p", { children: error }) : _jsx("p", { children: "Hurray! No errors" });
|
|
107
110
|
};
|
|
108
|
-
var CustomizedRequiredIndicator = styled(styledComponents.RequiredIndicator)(
|
|
111
|
+
var CustomizedRequiredIndicator = styled(styledComponents.RequiredIndicator)(templateObject_4 || (templateObject_4 = __makeTemplateObject(["\n color: aqua;\n"], ["\n color: aqua;\n"])));
|
|
109
112
|
export var StylesCustomized = function () {
|
|
110
113
|
return (_jsx(Formik, __assign({ initialValues: {}, onSubmit: function (values, formikHelpers) { return __awaiter(void 0, void 0, void 0, function () {
|
|
111
114
|
return __generator(this, function (_a) {
|
|
@@ -139,4 +142,4 @@ WithRequiredInput.args = {
|
|
|
139
142
|
schema: requiredInputSchema,
|
|
140
143
|
uiSchema: {},
|
|
141
144
|
};
|
|
142
|
-
var templateObject_1, templateObject_2, templateObject_3;
|
|
145
|
+
var templateObject_1, templateObject_2, templateObject_3, templateObject_4;
|
package/dist/_sampleData.js
CHANGED
|
@@ -8,6 +8,11 @@ export var simpleSchema = {
|
|
|
8
8
|
};
|
|
9
9
|
export var simpleUiSchema = {
|
|
10
10
|
"ui:description": "Description text",
|
|
11
|
+
firstName: {
|
|
12
|
+
"ui:info": {
|
|
13
|
+
content: "A small info",
|
|
14
|
+
},
|
|
15
|
+
},
|
|
11
16
|
};
|
|
12
17
|
export var completeSchema = {
|
|
13
18
|
title: "Inventory",
|
|
@@ -293,7 +298,7 @@ export var generatedSchema = {
|
|
|
293
298
|
};
|
|
294
299
|
export var requiredInputSchema = {
|
|
295
300
|
title: "TITLE",
|
|
296
|
-
required: [
|
|
301
|
+
required: ["lastName"],
|
|
297
302
|
properties: {
|
|
298
303
|
firstName: { type: "string", title: "First name" },
|
|
299
304
|
lastName: { type: "string", title: "Last name" },
|
|
@@ -303,21 +308,27 @@ export var requiredInputSchema = {
|
|
|
303
308
|
items: {
|
|
304
309
|
type: "object",
|
|
305
310
|
title: "Favourites",
|
|
306
|
-
required: [
|
|
311
|
+
required: ["favouriteFood"],
|
|
307
312
|
properties: {
|
|
308
313
|
favouriteFood: { type: "string", title: "Favourite food" },
|
|
309
|
-
favouriteSong: { type: "string", title: "Favourite song" }
|
|
310
|
-
}
|
|
314
|
+
favouriteSong: { type: "string", title: "Favourite song" },
|
|
315
|
+
},
|
|
311
316
|
},
|
|
312
317
|
additionalItems: {
|
|
313
318
|
type: "object",
|
|
314
319
|
title: "Second favourites",
|
|
315
|
-
required: [
|
|
320
|
+
required: ["secondFavouriteSong"],
|
|
316
321
|
properties: {
|
|
317
|
-
secondFavouriteFood: {
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
322
|
+
secondFavouriteFood: {
|
|
323
|
+
type: "string",
|
|
324
|
+
title: "Second favourite food",
|
|
325
|
+
},
|
|
326
|
+
secondFavouriteSong: {
|
|
327
|
+
type: "string",
|
|
328
|
+
title: "Second favourite song",
|
|
329
|
+
},
|
|
330
|
+
},
|
|
331
|
+
},
|
|
321
332
|
},
|
|
322
333
|
nestedObject: {
|
|
323
334
|
type: "object",
|
|
@@ -325,8 +336,8 @@ export var requiredInputSchema = {
|
|
|
325
336
|
required: ["tasks"],
|
|
326
337
|
properties: {
|
|
327
338
|
hobbies: { type: "string", title: "Hobbies" },
|
|
328
|
-
tasks: { type: "string", title: "Tasks" }
|
|
329
|
-
}
|
|
330
|
-
}
|
|
339
|
+
tasks: { type: "string", title: "Tasks" },
|
|
340
|
+
},
|
|
341
|
+
},
|
|
331
342
|
},
|
|
332
343
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
2
|
import * as formik from "formik";
|
|
3
|
-
import { ArrayFieldButtonProps, ObjectFieldButtonProps } from "./types";
|
|
3
|
+
import { ArrayFieldButtonProps, InfoFieldButtonProps, ObjectFieldButtonProps } from "./types";
|
|
4
4
|
export declare const Form: import("styled-components").StyledComponent<import("react").ForwardRefExoticComponent<Pick<import("react").DetailedHTMLProps<import("react").FormHTMLAttributes<HTMLFormElement>, HTMLFormElement>, "defaultChecked" | "defaultValue" | "suppressContentEditableWarning" | "suppressHydrationWarning" | "accessKey" | "className" | "contentEditable" | "contextMenu" | "dir" | "draggable" | "hidden" | "id" | "lang" | "placeholder" | "slot" | "spellCheck" | "style" | "tabIndex" | "title" | "translate" | "radioGroup" | "role" | "about" | "datatype" | "inlist" | "prefix" | "property" | "resource" | "typeof" | "vocab" | "autoCapitalize" | "autoCorrect" | "autoSave" | "color" | "itemProp" | "itemScope" | "itemType" | "itemID" | "itemRef" | "results" | "security" | "unselectable" | "inputMode" | "is" | "aria-activedescendant" | "aria-atomic" | "aria-autocomplete" | "aria-busy" | "aria-checked" | "aria-colcount" | "aria-colindex" | "aria-colspan" | "aria-controls" | "aria-current" | "aria-describedby" | "aria-details" | "aria-disabled" | "aria-dropeffect" | "aria-errormessage" | "aria-expanded" | "aria-flowto" | "aria-grabbed" | "aria-haspopup" | "aria-hidden" | "aria-invalid" | "aria-keyshortcuts" | "aria-label" | "aria-labelledby" | "aria-level" | "aria-live" | "aria-modal" | "aria-multiline" | "aria-multiselectable" | "aria-orientation" | "aria-owns" | "aria-placeholder" | "aria-posinset" | "aria-pressed" | "aria-readonly" | "aria-relevant" | "aria-required" | "aria-roledescription" | "aria-rowcount" | "aria-rowindex" | "aria-rowspan" | "aria-selected" | "aria-setsize" | "aria-sort" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "children" | "dangerouslySetInnerHTML" | "onCopy" | "onCopyCapture" | "onCut" | "onCutCapture" | "onPaste" | "onPasteCapture" | "onCompositionEnd" | "onCompositionEndCapture" | "onCompositionStart" | "onCompositionStartCapture" | "onCompositionUpdate" | "onCompositionUpdateCapture" | "onFocus" | "onFocusCapture" | "onBlur" | "onBlurCapture" | "onChange" | "onChangeCapture" | "onBeforeInput" | "onBeforeInputCapture" | "onInput" | "onInputCapture" | "onReset" | "onResetCapture" | "onSubmit" | "onSubmitCapture" | "onInvalid" | "onInvalidCapture" | "onLoad" | "onLoadCapture" | "onError" | "onErrorCapture" | "onKeyDown" | "onKeyDownCapture" | "onKeyPress" | "onKeyPressCapture" | "onKeyUp" | "onKeyUpCapture" | "onAbort" | "onAbortCapture" | "onCanPlay" | "onCanPlayCapture" | "onCanPlayThrough" | "onCanPlayThroughCapture" | "onDurationChange" | "onDurationChangeCapture" | "onEmptied" | "onEmptiedCapture" | "onEncrypted" | "onEncryptedCapture" | "onEnded" | "onEndedCapture" | "onLoadedData" | "onLoadedDataCapture" | "onLoadedMetadata" | "onLoadedMetadataCapture" | "onLoadStart" | "onLoadStartCapture" | "onPause" | "onPauseCapture" | "onPlay" | "onPlayCapture" | "onPlaying" | "onPlayingCapture" | "onProgress" | "onProgressCapture" | "onRateChange" | "onRateChangeCapture" | "onSeeked" | "onSeekedCapture" | "onSeeking" | "onSeekingCapture" | "onStalled" | "onStalledCapture" | "onSuspend" | "onSuspendCapture" | "onTimeUpdate" | "onTimeUpdateCapture" | "onVolumeChange" | "onVolumeChangeCapture" | "onWaiting" | "onWaitingCapture" | "onAuxClick" | "onAuxClickCapture" | "onClick" | "onClickCapture" | "onContextMenu" | "onContextMenuCapture" | "onDoubleClick" | "onDoubleClickCapture" | "onDrag" | "onDragCapture" | "onDragEnd" | "onDragEndCapture" | "onDragEnter" | "onDragEnterCapture" | "onDragExit" | "onDragExitCapture" | "onDragLeave" | "onDragLeaveCapture" | "onDragOver" | "onDragOverCapture" | "onDragStart" | "onDragStartCapture" | "onDrop" | "onDropCapture" | "onMouseDown" | "onMouseDownCapture" | "onMouseEnter" | "onMouseLeave" | "onMouseMove" | "onMouseMoveCapture" | "onMouseOut" | "onMouseOutCapture" | "onMouseOver" | "onMouseOverCapture" | "onMouseUp" | "onMouseUpCapture" | "onSelect" | "onSelectCapture" | "onTouchCancel" | "onTouchCancelCapture" | "onTouchEnd" | "onTouchEndCapture" | "onTouchMove" | "onTouchMoveCapture" | "onTouchStart" | "onTouchStartCapture" | "onPointerDown" | "onPointerDownCapture" | "onPointerMove" | "onPointerMoveCapture" | "onPointerUp" | "onPointerUpCapture" | "onPointerCancel" | "onPointerCancelCapture" | "onPointerEnter" | "onPointerEnterCapture" | "onPointerLeave" | "onPointerLeaveCapture" | "onPointerOver" | "onPointerOverCapture" | "onPointerOut" | "onPointerOutCapture" | "onGotPointerCapture" | "onGotPointerCaptureCapture" | "onLostPointerCapture" | "onLostPointerCaptureCapture" | "onScroll" | "onScrollCapture" | "onWheel" | "onWheelCapture" | "onAnimationStart" | "onAnimationStartCapture" | "onAnimationEnd" | "onAnimationEndCapture" | "onAnimationIteration" | "onAnimationIterationCapture" | "onTransitionEnd" | "onTransitionEndCapture" | "name" | "acceptCharset" | "action" | "autoComplete" | "encType" | "method" | "noValidate" | "target" | "key"> & import("react").RefAttributes<HTMLFormElement>>, any, {}, never>;
|
|
5
5
|
export declare const FormButtonWrapper: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
6
6
|
export declare const FormButton: import("styled-components").StyledComponent<"button", any, {}, never>;
|
|
@@ -32,6 +32,25 @@ export declare const FieldWrapper: import("styled-components").StyledComponent<"
|
|
|
32
32
|
export declare const FieldTitle: import("styled-components").StyledComponent<"label", any, {}, never>;
|
|
33
33
|
export declare const FieldDescription: import("styled-components").StyledComponent<"p", any, {}, never>;
|
|
34
34
|
export declare const FieldHelp: import("styled-components").StyledComponent<"p", any, {}, never>;
|
|
35
|
+
interface InfoFieldBoxElementProps {
|
|
36
|
+
position: "top" | "right" | "bottom" | "left";
|
|
37
|
+
}
|
|
38
|
+
export declare const InfoFieldBoxElement: import("styled-components").StyledComponent<"div", any, InfoFieldBoxElementProps, never>;
|
|
39
|
+
export declare const InfoFieldBoxArrowElement: import("styled-components").StyledComponent<"div", any, InfoFieldBoxElementProps, never>;
|
|
40
|
+
export declare const InfoFieldBoxInnerElement: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
41
|
+
export declare const InfoFieldContainerElement: import("styled-components").StyledComponent<"a", any, {}, never>;
|
|
42
|
+
export declare const InfoFieldLabel: import("styled-components").StyledComponent<"span", any, {}, never>;
|
|
43
|
+
export declare const InfoFieldButton: {
|
|
44
|
+
({ label, content, position, props, className, }: InfoFieldButtonProps): JSX.Element;
|
|
45
|
+
styles: {
|
|
46
|
+
InfoFieldContainerElementStyle: import("styled-components").StyledComponent<"a", any, {}, never>;
|
|
47
|
+
InfoFieldBoxElementStyle: import("styled-components").StyledComponent<"div", any, InfoFieldBoxElementProps, never>;
|
|
48
|
+
InfoFieldBoxInnerElementStyle: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
49
|
+
InfoFieldBoxArrowElementStyle: import("styled-components").StyledComponent<"div", any, InfoFieldBoxElementProps, never>;
|
|
50
|
+
InfoFieldLabelStyle: import("styled-components").StyledComponent<"span", any, {}, never>;
|
|
51
|
+
};
|
|
52
|
+
};
|
|
35
53
|
export declare const ErrorMessage: import("styled-components").StyledComponent<import("react").ComponentType<formik.ErrorMessageProps>, any, {}, never>;
|
|
36
54
|
export declare const FieldInput: import("styled-components").StyledComponent<({ formikAs, ...props }: any) => JSX.Element, any, {}, never>;
|
|
37
55
|
export declare const RequiredIndicator: import("styled-components").StyledComponent<"span", any, {}, never>;
|
|
56
|
+
export {};
|
package/dist/styledComponents.js
CHANGED
|
@@ -24,7 +24,7 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
24
24
|
}
|
|
25
25
|
return t;
|
|
26
26
|
};
|
|
27
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
27
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
28
28
|
import styled from "styled-components";
|
|
29
29
|
import * as formik from "formik";
|
|
30
30
|
import { ArrayFieldButtonPurpose, ObjectFieldButtonPurpose, } from "./types";
|
|
@@ -92,7 +92,82 @@ export var FieldWrapper = styled.div(templateObject_21 || (templateObject_21 = _
|
|
|
92
92
|
export var FieldTitle = styled.label(templateObject_22 || (templateObject_22 = __makeTemplateObject(["\n font-weight: 700;\n"], ["\n font-weight: 700;\n"])));
|
|
93
93
|
export var FieldDescription = styled.p(templateObject_23 || (templateObject_23 = __makeTemplateObject(["\n margin: 0;\n font-size: 0.9em;\n"], ["\n margin: 0;\n font-size: 0.9em;\n"])));
|
|
94
94
|
export var FieldHelp = styled.p(templateObject_24 || (templateObject_24 = __makeTemplateObject(["\n margin: 0;\n font-size: 0.9em;\n"], ["\n margin: 0;\n font-size: 0.9em;\n"])));
|
|
95
|
-
export var
|
|
95
|
+
export var InfoFieldBoxElement = styled.div(templateObject_25 || (templateObject_25 = __makeTemplateObject(["\n transition: opacity 0.5s;\n position: absolute;\n z-index: 1080;\n opacity: 0;\n visibility: hidden;\n margin: 0;\n font-size: 0.875rem;\n word-wrap: break-word;\n min-width: max-content;\n\n top: ", ";\n bottom: ", ";\n left: ", ";\n right: ", ";\n transform: translate(\n ", ",\n ", "\n );\n"], ["\n transition: opacity 0.5s;\n position: absolute;\n z-index: 1080;\n opacity: 0;\n visibility: hidden;\n margin: 0;\n font-size: 0.875rem;\n word-wrap: break-word;\n min-width: max-content;\n\n top: ", ";\n bottom: ", ";\n left: ", ";\n right: ", ";\n transform: translate(\n ", ",\n ", "\n );\n"])), function (_a) {
|
|
96
|
+
var position = _a.position;
|
|
97
|
+
return position === "bottom" ? "140%" : position === "top" ? "auto" : "50%";
|
|
98
|
+
}, function (_a) {
|
|
99
|
+
var position = _a.position;
|
|
100
|
+
return position === "top"
|
|
101
|
+
? "140%"
|
|
102
|
+
: position === "right" || position === "left"
|
|
103
|
+
? "50%"
|
|
104
|
+
: "auto";
|
|
105
|
+
}, function (_a) {
|
|
106
|
+
var position = _a.position;
|
|
107
|
+
return position === "right"
|
|
108
|
+
? "100%"
|
|
109
|
+
: position === "bottom" || position === "top"
|
|
110
|
+
? "50%"
|
|
111
|
+
: "auto";
|
|
112
|
+
}, function (_a) {
|
|
113
|
+
var position = _a.position;
|
|
114
|
+
return position === "left"
|
|
115
|
+
? "100%"
|
|
116
|
+
: position === "bottom" || position === "top"
|
|
117
|
+
? "50%"
|
|
118
|
+
: "auto";
|
|
119
|
+
}, function (_a) {
|
|
120
|
+
var position = _a.position;
|
|
121
|
+
return position === "bottom" || position === "top" ? "-50%" : "0";
|
|
122
|
+
}, function (_a) {
|
|
123
|
+
var position = _a.position;
|
|
124
|
+
return position === "right" || position === "left" ? "-50%" : "0";
|
|
125
|
+
});
|
|
126
|
+
export var InfoFieldBoxArrowElement = styled.div(templateObject_26 || (templateObject_26 = __makeTemplateObject(["\n top: ", ";\n left: ", ";\n bottom: ", ";\n border: solid transparent;\n content: \"\";\n height: 0;\n width: 0;\n position: absolute;\n pointer-events: none;\n border-top-color: ", ";\n border-bottom-color: ", ";\n border-right-color: ", ";\n border-left-color: ", ";\n border-width: 5px;\n margin-left: -5px;\n"], ["\n top: ", ";\n left: ", ";\n bottom: ", ";\n border: solid transparent;\n content: \"\";\n height: 0;\n width: 0;\n position: absolute;\n pointer-events: none;\n border-top-color: ", ";\n border-bottom-color: ", ";\n border-right-color: ", ";\n border-left-color: ", ";\n border-width: 5px;\n margin-left: -5px;\n"])), function (_a) {
|
|
127
|
+
var position = _a.position;
|
|
128
|
+
return position === "top"
|
|
129
|
+
? "100%"
|
|
130
|
+
: position === "right" || position === "left"
|
|
131
|
+
? "40%"
|
|
132
|
+
: "unset";
|
|
133
|
+
}, function (_a) {
|
|
134
|
+
var position = _a.position;
|
|
135
|
+
return position === "top" || position === "bottom"
|
|
136
|
+
? "50%"
|
|
137
|
+
: position === "right"
|
|
138
|
+
? "-2%"
|
|
139
|
+
: "102.5%";
|
|
140
|
+
}, function (_a) {
|
|
141
|
+
var position = _a.position;
|
|
142
|
+
return (position === "bottom" ? "100%" : "unset");
|
|
143
|
+
}, function (_a) {
|
|
144
|
+
var position = _a.position;
|
|
145
|
+
return position === "top" ? "grey" : "transparent";
|
|
146
|
+
}, function (_a) {
|
|
147
|
+
var position = _a.position;
|
|
148
|
+
return position === "bottom" ? "grey" : "transparent";
|
|
149
|
+
}, function (_a) {
|
|
150
|
+
var position = _a.position;
|
|
151
|
+
return position === "right" ? "grey" : "transparent";
|
|
152
|
+
}, function (_a) {
|
|
153
|
+
var position = _a.position;
|
|
154
|
+
return position === "left" ? "grey" : "transparent";
|
|
155
|
+
});
|
|
156
|
+
export var InfoFieldBoxInnerElement = styled.div(templateObject_27 || (templateObject_27 = __makeTemplateObject(["\n padding: 0.25rem 0.5rem;\n color: white;\n text-align: center;\n background: grey;\n border: solid 1px grey;\n border-radius: 0.25rem;\n cursor: default;\n"], ["\n padding: 0.25rem 0.5rem;\n color: white;\n text-align: center;\n background: grey;\n border: solid 1px grey;\n border-radius: 0.25rem;\n cursor: default;\n"])));
|
|
157
|
+
export var InfoFieldContainerElement = styled.a(templateObject_28 || (templateObject_28 = __makeTemplateObject(["\n position: relative;\n color: black;\n background: none;\n outline: none;\n cursor: pointer;\n border: 1px solid black;\n border-radius: 50%;\n line-height: 1em;\n font-size: 0.7em;\n padding: 0 0.44em;\n text-decoration: unset;\n\n &:active,\n &:focus {\n color: white;\n background: black;\n ", " {\n opacity: 1;\n visibility: visible;\n }\n }\n"], ["\n position: relative;\n color: black;\n background: none;\n outline: none;\n cursor: pointer;\n border: 1px solid black;\n border-radius: 50%;\n line-height: 1em;\n font-size: 0.7em;\n padding: 0 0.44em;\n text-decoration: unset;\n\n &:active,\n &:focus {\n color: white;\n background: black;\n ", " {\n opacity: 1;\n visibility: visible;\n }\n }\n"])), InfoFieldBoxElement);
|
|
158
|
+
export var InfoFieldLabel = styled.span(templateObject_29 || (templateObject_29 = __makeTemplateObject([""], [""])));
|
|
159
|
+
export var InfoFieldButton = function (_a) {
|
|
160
|
+
var label = _a.label, content = _a.content, position = _a.position, props = _a.props, className = _a.className;
|
|
161
|
+
return (_jsxs(InfoFieldContainerElement, __assign({ href: "#", onClick: function (e) { return e.preventDefault(); }, className: className }, { children: [_jsx(InfoFieldLabel, { children: label !== null && label !== void 0 ? label : "i" }), _jsxs(InfoFieldBoxElement, __assign({ position: position !== null && position !== void 0 ? position : "top", role: "tooltip" }, { children: [_jsx(InfoFieldBoxArrowElement, { position: position !== null && position !== void 0 ? position : "top" }), _jsx(InfoFieldBoxInnerElement, { children: content })] }))] })));
|
|
162
|
+
};
|
|
163
|
+
InfoFieldButton.styles = {
|
|
164
|
+
InfoFieldContainerElementStyle: InfoFieldContainerElement,
|
|
165
|
+
InfoFieldBoxElementStyle: InfoFieldBoxElement,
|
|
166
|
+
InfoFieldBoxInnerElementStyle: InfoFieldBoxInnerElement,
|
|
167
|
+
InfoFieldBoxArrowElementStyle: InfoFieldBoxArrowElement,
|
|
168
|
+
InfoFieldLabelStyle: InfoFieldLabel,
|
|
169
|
+
};
|
|
170
|
+
export var ErrorMessage = styled(formik.ErrorMessage)(templateObject_30 || (templateObject_30 = __makeTemplateObject([""], [""])));
|
|
96
171
|
/*
|
|
97
172
|
* Works like Formik field, but "as" props needs to be given with "formikAs", since styled components uses as.
|
|
98
173
|
*
|
|
@@ -100,6 +175,6 @@ export var ErrorMessage = styled(formik.ErrorMessage)(templateObject_25 || (temp
|
|
|
100
175
|
export var FieldInput = styled(function (_a) {
|
|
101
176
|
var formikAs = _a.formikAs, props = __rest(_a, ["formikAs"]);
|
|
102
177
|
return _jsx(formik.Field, __assign({}, props, { as: formikAs }));
|
|
103
|
-
})(
|
|
104
|
-
export var RequiredIndicator = styled.span(
|
|
105
|
-
var templateObject_1, templateObject_2, templateObject_3, templateObject_4, templateObject_5, templateObject_6, templateObject_7, templateObject_8, templateObject_9, templateObject_10, templateObject_11, templateObject_12, templateObject_13, templateObject_14, templateObject_15, templateObject_16, templateObject_17, templateObject_18, templateObject_19, templateObject_20, templateObject_21, templateObject_22, templateObject_23, templateObject_24, templateObject_25, templateObject_26, templateObject_27;
|
|
178
|
+
})(templateObject_31 || (templateObject_31 = __makeTemplateObject([""], [""])));
|
|
179
|
+
export var RequiredIndicator = styled.span(templateObject_32 || (templateObject_32 = __makeTemplateObject([""], [""])));
|
|
180
|
+
var templateObject_1, templateObject_2, templateObject_3, templateObject_4, templateObject_5, templateObject_6, templateObject_7, templateObject_8, templateObject_9, templateObject_10, templateObject_11, templateObject_12, templateObject_13, templateObject_14, templateObject_15, templateObject_16, templateObject_17, templateObject_18, templateObject_19, templateObject_20, templateObject_21, templateObject_22, templateObject_23, templateObject_24, templateObject_25, templateObject_26, templateObject_27, templateObject_28, templateObject_29, templateObject_30, templateObject_31, templateObject_32;
|
|
@@ -14,14 +14,14 @@ import { useContext } from "react";
|
|
|
14
14
|
import { FormRegistry } from "../Form";
|
|
15
15
|
import { useExtractUiSchema, getDescription, getTitle } from "../utils";
|
|
16
16
|
export function ArrayFieldTemplate(props) {
|
|
17
|
-
var _a = useContext(FormRegistry).components, ArrayFieldWrapper = _a.ArrayFieldWrapper, ArrayFieldTitle = _a.ArrayFieldTitle, FieldDescription = _a.FieldDescription, ErrorMessage = _a.ErrorMessage, FieldHelp = _a.FieldHelp;
|
|
17
|
+
var _a = useContext(FormRegistry).components, ArrayFieldWrapper = _a.ArrayFieldWrapper, ArrayFieldTitle = _a.ArrayFieldTitle, FieldDescription = _a.FieldDescription, ErrorMessage = _a.ErrorMessage, FieldHelp = _a.FieldHelp, InfoFieldButton = _a.InfoFieldButton;
|
|
18
18
|
var name = props.name, uiSchema = props.uiSchema, children = props.children;
|
|
19
19
|
var title = getTitle(props);
|
|
20
20
|
var description = getDescription(props);
|
|
21
|
-
var _b = useExtractUiSchema(uiSchema), help = _b.help,
|
|
21
|
+
var _b = useExtractUiSchema(uiSchema), help = _b.help, info = _b.info,
|
|
22
22
|
//TODO: This is not right
|
|
23
23
|
_c = _b.props,
|
|
24
24
|
//TODO: This is not right
|
|
25
25
|
_d = _c === void 0 ? {} : _c, wrappertProps = _d.wrapper, titleProps = _d.title, descriptionProps = _d.description, helpProps = _d.help, errorProps = _d.error;
|
|
26
|
-
return (_jsxs(ArrayFieldWrapper, __assign({}, wrappertProps, { children: [title && (_jsx(ArrayFieldTitle, __assign({}, titleProps, { htmlFor: name }, { children: title }))), description && (_jsx(FieldDescription, __assign({}, descriptionProps, { children: description }))), children, help && _jsx(FieldHelp, __assign({}, helpProps, { children: help })), _jsx(ErrorMessage, __assign({}, errorProps, { name: name }))] })));
|
|
26
|
+
return (_jsxs(ArrayFieldWrapper, __assign({}, wrappertProps, { children: [title && (_jsx(ArrayFieldTitle, __assign({}, titleProps, { htmlFor: name }, { children: title }))), info && _jsx(InfoFieldButton, __assign({}, info)), description && (_jsx(FieldDescription, __assign({}, descriptionProps, { children: description }))), children, help && _jsx(FieldHelp, __assign({}, helpProps, { children: help })), _jsx(ErrorMessage, __assign({}, errorProps, { name: name }))] })));
|
|
27
27
|
}
|
|
@@ -14,14 +14,14 @@ import { useContext } from "react";
|
|
|
14
14
|
import { FormRegistry } from "../Form";
|
|
15
15
|
import { useExtractUiSchema, getDescription, getTitle } from "../utils";
|
|
16
16
|
export function FieldTemplate(props) {
|
|
17
|
-
var _a = useContext(FormRegistry).components, FieldWrapper = _a.FieldWrapper, FieldTitle = _a.FieldTitle, FieldDescription = _a.FieldDescription, ErrorMessage = _a.ErrorMessage, FieldHelp = _a.FieldHelp, RequiredIndicator = _a.RequiredIndicator;
|
|
17
|
+
var _a = useContext(FormRegistry).components, FieldWrapper = _a.FieldWrapper, FieldTitle = _a.FieldTitle, FieldDescription = _a.FieldDescription, ErrorMessage = _a.ErrorMessage, FieldHelp = _a.FieldHelp, RequiredIndicator = _a.RequiredIndicator, InfoFieldButton = _a.InfoFieldButton;
|
|
18
18
|
var name = props.name, uiSchema = props.uiSchema, children = props.children;
|
|
19
19
|
var title = getTitle(props);
|
|
20
20
|
var description = getDescription(props);
|
|
21
|
-
var _b = useExtractUiSchema(uiSchema), help = _b.help,
|
|
21
|
+
var _b = useExtractUiSchema(uiSchema), help = _b.help, info = _b.info,
|
|
22
22
|
//TODO: This is not right
|
|
23
23
|
_c = _b.props,
|
|
24
24
|
//TODO: This is not right
|
|
25
25
|
_d = _c === void 0 ? {} : _c, wrappertProps = _d.wrapper, titleProps = _d.title, descriptionProps = _d.description, helpProps = _d.help, errorProps = _d.error;
|
|
26
|
-
return (_jsxs(FieldWrapper, __assign({}, wrappertProps, { children: [title && (_jsxs(FieldTitle, __assign({}, titleProps, { htmlFor: name }, { children: [title, props.required && _jsx(RequiredIndicator, { children: "*" })] }))), description && (_jsx(FieldDescription, __assign({}, descriptionProps, { children: description }))), children, help && _jsx(FieldHelp, __assign({}, helpProps, { children: help })), _jsx(ErrorMessage, __assign({}, errorProps, { name: name }))] })));
|
|
26
|
+
return (_jsxs(FieldWrapper, __assign({}, wrappertProps, { children: [title && (_jsxs(FieldTitle, __assign({}, titleProps, { htmlFor: name }, { children: [title, props.required && _jsx(RequiredIndicator, { children: "*" })] }))), info && _jsx(InfoFieldButton, __assign({}, info)), description && (_jsx(FieldDescription, __assign({}, descriptionProps, { children: description }))), children, help && _jsx(FieldHelp, __assign({}, helpProps, { children: help })), _jsx(ErrorMessage, __assign({}, errorProps, { name: name }))] })));
|
|
27
27
|
}
|
|
@@ -14,14 +14,14 @@ import { useContext } from "react";
|
|
|
14
14
|
import { FormRegistry } from "../Form";
|
|
15
15
|
import { getDescription, getTitle, useExtractUiSchema } from "../utils";
|
|
16
16
|
export function ObjectFieldTemplate(props) {
|
|
17
|
-
var _a = useContext(FormRegistry).components, FieldDescription = _a.FieldDescription, ObjectFieldTitle = _a.ObjectFieldTitle, ObjectFieldWrapper = _a.ObjectFieldWrapper, FieldHelp = _a.FieldHelp;
|
|
17
|
+
var _a = useContext(FormRegistry).components, FieldDescription = _a.FieldDescription, ObjectFieldTitle = _a.ObjectFieldTitle, ObjectFieldWrapper = _a.ObjectFieldWrapper, FieldHelp = _a.FieldHelp, InfoFieldButton = _a.InfoFieldButton;
|
|
18
18
|
var children = props.children, uiSchema = props.uiSchema;
|
|
19
19
|
var title = getTitle(props);
|
|
20
20
|
var description = getDescription(props);
|
|
21
|
-
var _b = useExtractUiSchema(uiSchema), help = _b.help,
|
|
21
|
+
var _b = useExtractUiSchema(uiSchema), help = _b.help, info = _b.info,
|
|
22
22
|
//TODO: This is not right
|
|
23
23
|
_c = _b.props,
|
|
24
24
|
//TODO: This is not right
|
|
25
25
|
_d = _c === void 0 ? {} : _c, wrapperProps = _d.wrapper, titleProps = _d.title, descriptionProps = _d.description, helpProps = _d.help;
|
|
26
|
-
return (_jsxs(ObjectFieldWrapper, __assign({}, wrapperProps, { children: [title && _jsx(ObjectFieldTitle, __assign({}, titleProps, { children: title })), description && _jsx(FieldDescription, __assign({}, descriptionProps, { children: description })), children, help && _jsx(FieldHelp, __assign({}, helpProps, { children: help }))] })));
|
|
26
|
+
return (_jsxs(ObjectFieldWrapper, __assign({}, wrapperProps, { children: [title && _jsx(ObjectFieldTitle, __assign({}, titleProps, { children: title })), info && _jsx(InfoFieldButton, __assign({}, info)), description && (_jsx(FieldDescription, __assign({}, descriptionProps, { children: description }))), children, help && _jsx(FieldHelp, __assign({}, helpProps, { children: help }))] })));
|
|
27
27
|
}
|
package/dist/types.d.ts
CHANGED
|
@@ -36,6 +36,7 @@ export type UiSchema = {
|
|
|
36
36
|
[key: string]: any;
|
|
37
37
|
};
|
|
38
38
|
"ui:help"?: React.ReactNode | React.ReactNode[];
|
|
39
|
+
"ui:info"?: InfoFieldButtonProps;
|
|
39
40
|
[name: string]: any;
|
|
40
41
|
};
|
|
41
42
|
export type FormRegistryContextValue = {
|
|
@@ -116,6 +117,7 @@ export type ComponentsType = {
|
|
|
116
117
|
FieldTitle: React.FunctionComponent<any>;
|
|
117
118
|
FieldDescription: React.FunctionComponent<any>;
|
|
118
119
|
FieldHelp: React.FunctionComponent<any>;
|
|
120
|
+
InfoFieldButton: React.FunctionComponent<any>;
|
|
119
121
|
ErrorMessage: React.FunctionComponent<any>;
|
|
120
122
|
FieldInput: React.FunctionComponent<any>;
|
|
121
123
|
RequiredIndicator: React.FunctionComponent<any>;
|
|
@@ -142,6 +144,13 @@ export type ArrayFieldButtonProps = {
|
|
|
142
144
|
onClick: () => void;
|
|
143
145
|
uiSchema: UiSchema;
|
|
144
146
|
};
|
|
147
|
+
export type InfoFieldButtonProps = {
|
|
148
|
+
label?: React.ReactNode;
|
|
149
|
+
content: React.ReactNode;
|
|
150
|
+
position?: 'top' | 'right' | 'bottom' | 'left';
|
|
151
|
+
className?: string;
|
|
152
|
+
props: any;
|
|
153
|
+
};
|
|
145
154
|
/*** ***/
|
|
146
155
|
export type AjvError = {
|
|
147
156
|
message: string;
|
package/dist/utils.d.ts
CHANGED
|
@@ -18,6 +18,7 @@ export declare function useExtractUiSchema(props?: UiSchema | undefined): {
|
|
|
18
18
|
field?: UiSchema["ui:field"];
|
|
19
19
|
props?: UiSchema["ui:props"];
|
|
20
20
|
help?: UiSchema["ui:help"];
|
|
21
|
+
info?: UiSchema["ui:info"];
|
|
21
22
|
};
|
|
22
23
|
export declare const guessType: (value: any) => "string" | "number" | "boolean" | "object" | "array" | "null";
|
|
23
24
|
export declare function getSchemaType(schema: Schema): import("json-schema").JSONSchema7TypeName | import("json-schema").JSONSchema7TypeName[] | undefined;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nolwenture/formik-jsonschema-form",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "Formik form generation from json schema",
|
|
5
5
|
"author": "Antti Vikman <antti.vikman@nolwenture.com>",
|
|
6
6
|
"contributors": [
|
|
@@ -22,7 +22,11 @@
|
|
|
22
22
|
],
|
|
23
23
|
"main": "./dist/index.js",
|
|
24
24
|
"types": "./dist/index.d.ts",
|
|
25
|
-
"files": [
|
|
25
|
+
"files": [
|
|
26
|
+
"dist",
|
|
27
|
+
"package.json",
|
|
28
|
+
"LICENSE"
|
|
29
|
+
],
|
|
26
30
|
"dependencies": {
|
|
27
31
|
"@testing-library/jest-dom": "^5.16.4",
|
|
28
32
|
"@testing-library/react": "^13.3.0",
|