@luomus/laji-form 15.1.44 → 15.1.46

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/dist/styles.css CHANGED
@@ -3871,7 +3871,7 @@ body .laji-form {
3871
3871
  background-color: white;
3872
3872
  right: 1px;
3873
3873
  bottom: 1px;
3874
- height: 23px;
3874
+ height: 21px;
3875
3875
  width: 23px;
3876
3876
  line-height: initial;
3877
3877
  font-size: 20px;
@@ -3880,6 +3880,7 @@ body .laji-form {
3880
3880
  position: absolute;
3881
3881
  right: 3px;
3882
3882
  bottom: 0px;
3883
+ line-height: 21px;
3883
3884
  }
3884
3885
  .laji-form-dropdown-caret img {
3885
3886
  width: 20px;
@@ -403,7 +403,7 @@ function Label({ label, children, id, required, registry = {}, uiSchema = {} })
403
403
  const labelElem = (React.createElement(LabelComponent, { htmlFor: id, "aria-describedby": `${id}--help` },
404
404
  React.createElement("div", null,
405
405
  React.createElement("strong", { dangerouslySetInnerHTML: { __html: label + requiredHtml } }),
406
- showHelp ? React.createElement(Help, { focusable: true, onFocus: onHelpFocus, onBlur: onHelpBlur, onClick: onHelpClick }) : null),
406
+ showHelp ? React.createElement(Help, { focusable: true, onFocus: onHelpFocus, onBlur: onHelpBlur, onClick: onHelpClick, id: id }) : null),
407
407
  children));
408
408
  return help ? React.createElement(React.Fragment, null,
409
409
  React.createElement(OverlayTrigger, { placement: helpPlacement || "right", overlay: tooltipElem, hoverable: helpHoverable, formContext: registry.formContext, show: focused || undefined, style: { display: "inline-block" } }, labelElem),
@@ -22,10 +22,10 @@ exports.rulePropType = PropTypes.oneOfType([
22
22
  complement: PropTypes.bool
23
23
  }),
24
24
  PropTypes.shape({
25
- rule: PropTypes.oneOf(["isAdmin", "isEdit"]),
25
+ rule: PropTypes.oneOf(["isAdmin", "isEdit", "isReadonly"]),
26
26
  complement: PropTypes.bool
27
27
  }),
28
- PropTypes.oneOf(["isAdmin", "isEdit"])
28
+ PropTypes.oneOf(["isAdmin", "isEdit", "isReadonly"]),
29
29
  ]);
30
30
  exports.operationPropType = PropTypes.shape({
31
31
  type: PropTypes.oneOf(["merge", "wrap"]),
@@ -29,7 +29,7 @@ let MultiLanguageField = class MultiLanguageField extends React.Component {
29
29
  return sortA - sortB;
30
30
  });
31
31
  return (React.createElement(React.Fragment, null,
32
- React.createElement(Label, { label: schema.title || "", required: required || uiSchema["ui:required"], uiSchema: uiSchema }),
32
+ React.createElement(Label, { label: schema.title || "", required: required || uiSchema["ui:required"], uiSchema: uiSchema, id: this.props.idSchema.$id }),
33
33
  languages.map(_lang => {
34
34
  var _a;
35
35
  return (React.createElement(SchemaField, Object.assign({}, this.props, { key: _lang, schema: Object.assign({ title: "" }, schema.properties[_lang]), uiSchema: {
@@ -325,7 +325,7 @@ class NamedPlaceChooser extends React.Component {
325
325
  return data;
326
326
  }, []);
327
327
  return (React.createElement("div", { style: { height: "inherit" } },
328
- React.createElement(SelectWidget_1.default, { disabled: !places, options: { enumOptions: enums, placeholder: `${translations.SelectPlaceFromList}...` }, onChange: this.onSelectChange, selectOnChange: false, includeEmpty: false, schema: {}, id: "named-place-chooser-select", formContext: this.props.formContext }),
328
+ React.createElement(SelectWidget_1.default, { disabled: !places, options: { enumOptions: enums, placeholder: `${translations.SelectPlaceFromList}...` }, onChange: this.onSelectChange, selectOnChange: false, includeEmpty: true, schema: {}, id: "named-place-chooser-select", formContext: this.props.formContext }),
329
329
  React.createElement(MapArrayField_1.Map, { ref: getMapRef, data: data, markerPopupOffset: 45, featurePopupOffset: 5, controls: { draw: false }, lang: this.props.formContext.lang, bodyAsDialogRoot: false, formContext: this.props.formContext }),
330
330
  (!places) ? React.createElement(Spinner, null) : null,
331
331
  React.createElement("div", { style: { display: "none" }, ref: this.setPopupContainerRef },
@@ -504,7 +504,7 @@ let UncontrolledArrayFieldTemplate = class UncontrolledArrayFieldTemplate extend
504
504
  const titleUiSchema = Object.assign(Object.assign({}, arrayTemplateFieldProps.uiSchema), { "ui:options": Object.assign(Object.assign({}, utils_1.getUiOptions(arrayTemplateFieldProps.uiSchema)), { titleFormatters: that.props.uiSchema.titleFormatters }) });
505
505
  return activeIdx !== undefined && arrayTemplateFieldProps.items && arrayTemplateFieldProps.items[activeIdx] ?
506
506
  React.createElement("div", { key: utils_1.getUUID(this.props.formData[activeIdx]) || activeIdx },
507
- React.createElement(Title, { title: title, label: title, schema: this.props.schema, uiSchema: titleUiSchema, formData: that.props.formData, registry: this.props.registry }),
507
+ React.createElement(Title, { title: title, label: title, schema: this.props.schema, uiSchema: titleUiSchema, formData: that.props.formData, registry: this.props.registry, id: this.props.idSchema.$id }),
508
508
  React.createElement(DescriptionFieldTemplate, { description: this.props.uiSchema["ui:description"], schema: this.props.schema }),
509
509
  arrayTemplateFieldProps.items[activeIdx].children)
510
510
  : null;
@@ -738,7 +738,7 @@ let TableArrayFieldTemplate = class TableArrayFieldTemplate extends React.Compon
738
738
  const onMouseLeave = this.customEventSender("endHighlight");
739
739
  const { Table } = this.context.theme;
740
740
  return (React.createElement("div", { style: { position: "relative" }, className: "single-active-array-table-container" },
741
- React.createElement(Title, { title: title, label: title, uiSchema: uiSchema, schema: schema, formData: formData, registry: this.props.registry }),
741
+ React.createElement(Title, { title: title, label: title, uiSchema: uiSchema, schema: schema, formData: formData, registry: this.props.registry, id: this.props.idSchema.$id }),
742
742
  React.createElement(DescriptionFieldTemplate, { description: uiSchema["ui:description"], schema: this.props.schema }),
743
743
  React.createElement("div", { className: "laji-form-field-template-item" },
744
744
  React.createElement("div", { className: "table-responsive laji-form-field-template-schema" },
@@ -749,7 +749,7 @@ let TableArrayFieldTemplate = class TableArrayFieldTemplate extends React.Compon
749
749
  const sortableHeaderProps = this.getSortableHeaderProps(col, this.props);
750
750
  const { ui, tooltip } = sortableHeaderProps, _sortableHeaderProps = __rest(sortableHeaderProps, ["ui", "tooltip"]);
751
751
  const className = utils_1.classNames("darker", sortableHeaderProps.className);
752
- return (React.createElement(components_1.TooltipComponent, { key: col, tooltip: tooltip, placement: "top" },
752
+ return (React.createElement(components_1.TooltipComponent, { key: col, tooltip: tooltip, placement: "top", id: `${this.props.idSchema[col].$id}-header` },
753
753
  React.createElement("th", Object.assign({ key: col }, _sortableHeaderProps, { className: className }),
754
754
  ((uiSchema.items || {})[col] || {})["ui:title"] || schema.items.properties[col].title,
755
755
  ui || null)));
@@ -963,10 +963,10 @@ class AccordionHeader extends React.Component {
963
963
  }),
964
964
  hasHelp &&
965
965
  React.createElement(React.Fragment, null,
966
- React.createElement(components_1.Help, { focusable: true, onFocus: this.onHelpFocus, onBlur: this.onHelpBlur, onClick: this.onHelpClick }),
966
+ React.createElement(components_1.Help, { focusable: true, onFocus: this.onHelpFocus, onBlur: this.onHelpBlur, onClick: this.onHelpClick, id: `${that.props.idSchema.$id}_{idx}` }),
967
967
  React.createElement("div", { id: `${that.props.idSchema.$id}_${idx}--help`, style: { display: "none" } }, uiSchema["ui:help"]))));
968
968
  const { Tooltip } = this.context.theme;
969
- const tooltip = React.createElement(Tooltip, null, uiSchema["ui:help"]);
969
+ const tooltip = React.createElement(Tooltip, { id: `${that.props.idSchema.$id}_${idx}-help` }, uiSchema["ui:help"]);
970
970
  const headerTextComponent = hasHelp ? React.createElement(components_1.OverlayTrigger, { placement: "right", overlay: tooltip, show: this.state && this.state.focused || undefined }, headerText) : headerText;
971
971
  const header = (React.createElement("div", { className: this.props.className, role: "tab", id: `${that.props.idSchema.$id}_${utils_1.getFormDataIndex(idx, that.props.uiSchema)}-header`, onClick: this.onHeaderClick, onMouseEnter: this.onMouseEnter, onMouseLeave: this.onMouseLeave, onKeyDown: this.onKeyDown, tabIndex: "0" },
972
972
  React.createElement("div", { className: this.props.wrapperClassName },
@@ -17,7 +17,7 @@ let TagArrayField = class TagArrayField extends React.Component {
17
17
  render() {
18
18
  const { FieldTemplate } = this.props.registry.templates;
19
19
  const { uiSchema } = this.props;
20
- return (React.createElement(FieldTemplate, Object.assign({}, this.props, { forceDisplayLabel: true, rawHelp: uiSchema["ui:help"], description: uiSchema["ui:description"], rawErrors: [] }),
20
+ return (React.createElement(FieldTemplate, Object.assign({}, this.props, { forceDisplayLabel: true, rawHelp: uiSchema["ui:help"], description: uiSchema["ui:description"], rawErrors: [], id: this.props.idSchema.$id }),
21
21
  React.createElement(TagInputComponent, Object.assign({}, this.props, { id: this.props.idSchema.$id, tags: this.props.formData }))));
22
22
  }
23
23
  };
@@ -288,7 +288,7 @@ class ArrayFieldTemplateWithoutKeyHandling extends React.Component {
288
288
  });
289
289
  const title = "ui:title" in props.uiSchema ? props.uiSchema["ui:title"] : props.title;
290
290
  return (React.createElement("div", { className: props.className },
291
- React.createElement(Title, { title: title, label: title, uiSchema: this.props.uiSchema, registry: this.props.registry }),
291
+ React.createElement(Title, { title: title, label: title, uiSchema: this.props.uiSchema, registry: this.props.registry, id: this.props.idSchema.$id }),
292
292
  topButtons,
293
293
  props.description && React.createElement(Description, { description: props.description }),
294
294
  orderable ?
@@ -1,9 +1,2 @@
1
1
  export default TitleField;
2
- declare function TitleField({ title, id, formData, style, uiSchema, registry }: {
3
- title: any;
4
- id: any;
5
- formData: any;
6
- style: any;
7
- uiSchema?: {} | undefined;
8
- registry?: {} | undefined;
9
- }): JSX.Element | null;
2
+ declare function TitleField(props: any): JSX.Element | null;
@@ -5,7 +5,8 @@ const components_1 = require("../components");
5
5
  const utils_1 = require("../../utils");
6
6
  const Context_1 = require("../../Context");
7
7
  const ReactContext_1 = require("../../ReactContext");
8
- const TitleField = ({ title, id, formData, style, uiSchema = {}, registry = {} }) => {
8
+ const TitleField = (props) => {
9
+ const { title, id, formData, style, uiSchema = {}, registry = {} } = props;
9
10
  const { "ui:help": help, "ui:helpHoverable": helpHoverable, "_ui:renderedButtons": buttons } = uiSchema;
10
11
  const { titleClassName: className, titleFormatters = [] } = utils_1.getUiOptions(uiSchema);
11
12
  const renderedFormatters = titleFormatters.map((titleFormatter) => {
@@ -26,7 +27,7 @@ const TitleField = ({ title, id, formData, style, uiSchema = {}, registry = {} }
26
27
  if (renderedFormatters.length === 0 && utils_1.isEmptyString(title)) {
27
28
  return null;
28
29
  }
29
- const helpComponent = help ? React.createElement(components_1.Help, { focusable: true, onFocus: onHelpFocus, onBlur: onHelpBlur, onClick: onHelpClick }) : null;
30
+ const helpComponent = help ? React.createElement(components_1.Help, { focusable: true, onFocus: onHelpFocus, onBlur: onHelpBlur, onClick: onHelpClick, id: id }) : null;
30
31
  let titleTextContent = React.createElement("span", null,
31
32
  React.createElement("span", { dangerouslySetInnerHTML: { __html: title } }),
32
33
  " ",
@@ -61,6 +61,7 @@ export class Autosuggest extends React.Component<any, any, any> {
61
61
  onInformalTaxonGroupSelected: (id: any) => void;
62
62
  onInformalTaxonGroupHide: () => void;
63
63
  onToggle: () => void;
64
+ onKeyDown: any;
64
65
  isSuggested: () => any;
65
66
  renderInput: (inputProps: any) => JSX.Element;
66
67
  }
@@ -636,6 +636,7 @@ class Autosuggest extends React.Component {
636
636
  this.props.onToggle(!this.props.toggled);
637
637
  setTimeout(() => this.props.formContext.utils.focusById(this.props.id), 1); // Refocus input
638
638
  };
639
+ this.onKeyDown = this.props.formContext.utils.keyboardClick(this.onToggle);
639
640
  this.isSuggested = () => {
640
641
  const { suggestion } = this.state;
641
642
  return !!suggestion && this.isValueSuggested(this.props);
@@ -699,7 +700,7 @@ class Autosuggest extends React.Component {
699
700
  const props = {
700
701
  className: utils_1.classNames("autosuggest-input-addon", "power-user-addon", this.props.toggled && "active"),
701
702
  onMouseDown: this.onToggle,
702
- onKeyDown: this.onToggleByKeyboard
703
+ onKeyDown: this.onKeyDown
703
704
  };
704
705
  if (toggleable && toggleable.glyphClass) {
705
706
  return (React.createElement(components_1.Button, Object.assign({}, props),
package/lib/utils.js CHANGED
@@ -776,11 +776,8 @@ function checkRules(rules, props, cache, prop = "formData") {
776
776
  const passes = (Array.isArray(rules) ? rules : [rules]).every((rule, idx) => {
777
777
  let passes;
778
778
  // BW compatibility for old string rule
779
- if (rule === "isAdmin") {
780
- rule = { rule: "isAdmin" };
781
- }
782
- else if (rule === "isEdit") {
783
- rule = { rule: "isEdit" };
779
+ if (["isAdmin", "isEdit", "isReadonly"].includes(rule)) {
780
+ rule = { rule };
784
781
  }
785
782
  const { field, regexp, valueIn, valueIncludes, valueLengthLessThan, rule: _rule } = rule;
786
783
  if (_rule) {
@@ -790,6 +787,9 @@ function checkRules(rules, props, cache, prop = "formData") {
790
787
  else if (_rule === "isEdit") {
791
788
  passes = props.formContext.uiSchemaContext.isEdit;
792
789
  }
790
+ else if (_rule === "isReadonly") {
791
+ passes = props.readonly;
792
+ }
793
793
  }
794
794
  else {
795
795
  let value = parseJSONPointer(props[prop] || {}, field);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@luomus/laji-form",
3
- "version": "15.1.44",
3
+ "version": "15.1.46",
4
4
  "description": "React module capable of building dynamic forms from Laji form json schemas",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -24,6 +24,7 @@
24
24
  "prepublishOnly": "npm run build && git push && git push --tags",
25
25
  "lint": "eslint -c .eslintrc.prod.json src playground",
26
26
  "test": "npx playwright test",
27
+ "test:ui": "npx playwright test --ui",
27
28
  "test:docker": "npm run test:docker:build && npm run test:docker:run --",
28
29
  "test:lightweight": "npx playwright test --project chromium",
29
30
  "test:docker:build": "docker build -t laji-form-test -f test.Dockerfile .",
@@ -38,7 +39,7 @@
38
39
  "repository": "git+https://github.com/luomus/laji-form.git",
39
40
  "license": "MIT",
40
41
  "dependencies": {
41
- "@luomus/laji-map": "^5.1.11",
42
+ "@luomus/laji-map": "^5.1.13",
42
43
  "@luomus/laji-validate": "^0.0.122",
43
44
  "@rjsf/core": "~5.1.0",
44
45
  "@rjsf/utils": "~5.1.0",
@@ -232,6 +232,10 @@ export declare class DemoPageForm extends Form {
232
232
  getState(): Promise<{
233
233
  formData: any;
234
234
  }>;
235
+ getProps(): Promise<{
236
+ schema: any;
237
+ uiSchema: any;
238
+ }>;
235
239
  submit(): Promise<void>;
236
240
  startSubmit(): void;
237
241
  submitOnlySchemaValidations(): Promise<any>;
@@ -302,6 +302,12 @@ class DemoPageForm extends Form {
302
302
  return { formData };
303
303
  });
304
304
  }
305
+ getProps() {
306
+ return this.page.evaluate(() => {
307
+ const { schema, uiSchema } = window.lajiForm.lajiForm.props;
308
+ return { schema, uiSchema };
309
+ });
310
+ }
305
311
  submit() {
306
312
  return __awaiter(this, void 0, void 0, function* () {
307
313
  yield this.e("submit()");