@nolwenture/formik-jsonschema-form 0.3.0 → 0.4.0

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 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 overriden with custom ones
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
@@ -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)(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n ", " {\n color: red;\n }\n"], ["\n ", " {\n color: red;\n }\n"])), styledComponents.FieldTitle);
101
- var CustomizedFieldWrapper = styled.div(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n outline: 2px solid\n ", ";\n"], ["\n outline: 2px solid\n ", ";\n"])), function (props) { return (props.title === "ABC" ? "blue" : "transparent"); });
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)(templateObject_3 || (templateObject_3 = __makeTemplateObject(["\n color: aqua;\n"], ["\n color: aqua;\n"])));
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;
@@ -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: ['lastName'],
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: ['favouriteFood'],
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: ['secondFavouriteSong'],
320
+ required: ["secondFavouriteSong"],
316
321
  properties: {
317
- secondFavouriteFood: { type: "string", title: "Second favourite food" },
318
- secondFavouriteSong: { type: "string", title: "Second favourite song" }
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 {};
@@ -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 ErrorMessage = styled(formik.ErrorMessage)(templateObject_25 || (templateObject_25 = __makeTemplateObject([""], [""])));
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
- })(templateObject_26 || (templateObject_26 = __makeTemplateObject([""], [""])));
104
- export var RequiredIndicator = styled.span(templateObject_27 || (templateObject_27 = __makeTemplateObject([""], [""])));
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.0",
3
+ "version": "0.4.0",
4
4
  "description": "Formik form generation from json schema",
5
5
  "author": "Antti Vikman <antti.vikman@nolwenture.com>",
6
6
  "contributors": [