@limetech/lime-elements 40.17.0 → 40.18.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.
Files changed (45) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/cjs/heading-level-BxCuIKkm.js +14 -0
  3. package/dist/cjs/limel-collapsible-section.cjs.entry.js +4 -9
  4. package/dist/cjs/limel-file-viewer.cjs.entry.js +422 -248
  5. package/dist/cjs/limel-form-header.cjs.entry.js +1 -1
  6. package/dist/cjs/limel-form.cjs.entry.js +30 -21
  7. package/dist/collection/components/collapsible-section/collapsible-section.js +11 -9
  8. package/dist/collection/components/form/fields/schema-field.js +8 -1
  9. package/dist/collection/components/form/form.js +9 -6
  10. package/dist/collection/components/form/form.test-schemas.js +154 -0
  11. package/dist/collection/components/form/templates/array-field-collapsible-item.js +13 -3
  12. package/dist/collection/components/form/templates/heading-level.js +0 -10
  13. package/dist/collection/components/form/templates/object-field.js +6 -3
  14. package/dist/collection/components/form-header/form-header.js +3 -3
  15. package/dist/collection/global/shared-types/heading-level.types.js +1 -0
  16. package/dist/collection/interface.js +1 -0
  17. package/dist/collection/util/heading-level.js +10 -0
  18. package/dist/esm/heading-level-B3C0kDpZ.js +12 -0
  19. package/dist/esm/limel-collapsible-section.entry.js +2 -7
  20. package/dist/esm/limel-file-viewer.entry.js +422 -248
  21. package/dist/esm/limel-form-header.entry.js +1 -1
  22. package/dist/esm/limel-form.entry.js +28 -19
  23. package/dist/lime-elements/lime-elements.esm.js +1 -1
  24. package/dist/lime-elements/p-49a53f0b.entry.js +1 -0
  25. package/dist/lime-elements/{p-72907ffd.entry.js → p-68129487.entry.js} +1 -1
  26. package/dist/lime-elements/p-B3C0kDpZ.js +1 -0
  27. package/dist/lime-elements/{p-9436aba6.entry.js → p-be84c9f2.entry.js} +4 -4
  28. package/dist/lime-elements/p-e8255f0b.entry.js +1 -0
  29. package/dist/types/components/collapsible-section/collapsible-section.d.ts +2 -1
  30. package/dist/types/components/form/fields/schema-field.d.ts +1 -0
  31. package/dist/types/components/form/form.d.ts +5 -2
  32. package/dist/types/components/form/form.test-schemas.d.ts +7 -0
  33. package/dist/types/components/form/form.types.d.ts +17 -7
  34. package/dist/types/components/form/row/row.d.ts +1 -1
  35. package/dist/types/components/form/templates/array-field-collapsible-item.d.ts +5 -1
  36. package/dist/types/components/form/templates/heading-level.d.ts +1 -6
  37. package/dist/types/components/form/templates/object-field.d.ts +2 -0
  38. package/dist/types/components/form-header/form-header.d.ts +1 -1
  39. package/dist/types/components.d.ts +13 -7
  40. package/dist/types/global/shared-types/heading-level.types.d.ts +7 -0
  41. package/dist/types/interface.d.ts +2 -1
  42. package/dist/types/util/heading-level.d.ts +7 -0
  43. package/package.json +2 -2
  44. package/dist/lime-elements/p-1d13245d.entry.js +0 -1
  45. package/dist/lime-elements/p-e6be5819.entry.js +0 -1
@@ -32,7 +32,7 @@ const FormHeader = class {
32
32
  this.headingLevel = 1;
33
33
  }
34
34
  render() {
35
- return (index.h(index.Host, { key: 'bfb0a90340ac54c7f083df2989fd8c2acb97308f' }, this.renderHeading(), this.renderHelp(), this.renderDescription()));
35
+ return (index.h(index.Host, { key: '0d8282124405665c18b93aa753dd40cf616a6e6b' }, this.renderHeading(), this.renderHelp(), this.renderDescription()));
36
36
  }
37
37
  renderHeading() {
38
38
  if (!this.heading) {
@@ -2,6 +2,7 @@
2
2
 
3
3
  var index = require('./index-BlsqxTB1.js');
4
4
  var _commonjsHelpers = require('./_commonjsHelpers-CFO10eej.js');
5
+ var headingLevel = require('./heading-level-BxCuIKkm.js');
5
6
  var _baseIteratee = require('./_baseIteratee-Cistiy8H.js');
6
7
  var isEmpty = require('./isEmpty-BsdhcVKT.js');
7
8
  var helpProps = require('./help-props-Ds30nnt1.js');
@@ -44023,16 +44024,6 @@ function isType(input, type) {
44023
44024
  return input === type;
44024
44025
  }
44025
44026
 
44026
- /**
44027
- * @param level - any value
44028
- * @returns whether the value is a heading level, from `1` to `6`
44029
- */
44030
- function isHeadingLevel(level) {
44031
- return (typeof level === 'number' &&
44032
- Number.isSafeInteger(level) &&
44033
- level >= 1 &&
44034
- level <= 6);
44035
- }
44036
44027
  /**
44037
44028
  * The heading level that a title at the current depth in the form gets.
44038
44029
  */
@@ -44398,6 +44389,7 @@ const ArrayItemErrorsContext = reactExports.createContext(null);
44398
44389
 
44399
44390
  const ObjectFieldTemplate = (props) => {
44400
44391
  const arrayContext = reactExports.useContext(ArrayFieldContext);
44392
+ const headingLevel = reactExports.useContext(HeadingLevelContext);
44401
44393
  const id = props.fieldPathId.$id;
44402
44394
  if (arrayContext && id !== 'root') {
44403
44395
  return React.createElement(ArrayFieldContext.Provider, { value: null }, renderProperties(props.properties, props.schema, props.fieldPathId.path.map(String)));
@@ -44405,13 +44397,13 @@ const ObjectFieldTemplate = (props) => {
44405
44397
  if (id === 'root' || !isCollapsible(props.schema)) {
44406
44398
  return renderFieldWithTitle(props);
44407
44399
  }
44408
- return renderCollapsibleField(props);
44400
+ return renderCollapsibleField(props, headingLevel);
44409
44401
  };
44410
44402
  function renderFieldWithTitle(props) {
44411
44403
  var _a;
44412
44404
  return renderSection(props.title, props.description, (_a = props.schema.lime) === null || _a === void 0 ? void 0 : _a.help, renderProperties(props.properties, props.schema, props.fieldPathId.path.map(String)));
44413
44405
  }
44414
- function renderCollapsibleField(props) {
44406
+ function renderCollapsibleField(props, headingLevel) {
44415
44407
  var _a;
44416
44408
  const defaultOpen = !isCollapsed(props.schema);
44417
44409
  const helpElement = getHelpComponent(props.schema, {
@@ -44421,10 +44413,11 @@ function renderCollapsibleField(props) {
44421
44413
  const invalid = revealErrors && hasNestedErrors(props.errorSchema);
44422
44414
  return React.createElement('limel-collapsible-section', {
44423
44415
  header: props.title,
44416
+ headingLevel: headingLevel,
44424
44417
  id: getSchemaObjectPropertyPath(props.registry.formContext.schema, props.fieldPathId),
44425
44418
  'is-open': defaultOpen,
44426
44419
  invalid: invalid,
44427
- }, helpElement, renderDescription(props.description), renderProperties(props.properties, props.schema, props.fieldPathId.path.map(String)));
44420
+ }, helpElement, renderDescription(props.description), React.createElement(BelowHeading, { hasHeading: !!props.title }, renderProperties(props.properties, props.schema, props.fieldPathId.path.map(String))));
44428
44421
  }
44429
44422
  function getSchemaObjectPropertyPath(schema, fieldPathId) {
44430
44423
  var _a, _b;
@@ -44821,10 +44814,11 @@ class CollapsibleItemTemplate extends React.Component {
44821
44814
  section.removeEventListener('open', this.handleOpen);
44822
44815
  }
44823
44816
  render() {
44824
- const { data, schema, formSchema, errorSchema, revealErrors } = this.props;
44817
+ const { errorSchema, revealErrors } = this.props;
44818
+ const header = getItemHeader(this.props);
44825
44819
  let children;
44826
44820
  if (this.state.isOpen) {
44827
- children = this.props.children;
44821
+ children = React.createElement(BelowHeading, { hasHeading: !!header }, this.props.children);
44828
44822
  }
44829
44823
  const dragHandle = this.props.allowItemReorder
44830
44824
  ? React.createElement('limel-drag-handle', {
@@ -44834,7 +44828,8 @@ class CollapsibleItemTemplate extends React.Component {
44834
44828
  : null;
44835
44829
  const invalid = revealErrors === true && hasNestedErrors(errorSchema);
44836
44830
  return React.createElement('limel-collapsible-section', {
44837
- header: findTitle(data, schema, formSchema) || 'New item',
44831
+ header: header,
44832
+ headingLevel: this.context,
44838
44833
  class: 'array-item limel-form-array-item--object',
44839
44834
  ref: (section) => {
44840
44835
  this.section = section;
@@ -44866,6 +44861,13 @@ class CollapsibleItemTemplate extends React.Component {
44866
44861
  event.detail.run(event);
44867
44862
  }
44868
44863
  }
44864
+ CollapsibleItemTemplate.contextType = HeadingLevelContext;
44865
+ function getItemHeader(props) {
44866
+ const { data, schema, formSchema } = props;
44867
+ const title = findTitle(data, schema, formSchema);
44868
+ const text = Array.isArray(title) ? title.join(', ') : title;
44869
+ return text ? String(text) : 'New item';
44870
+ }
44869
44871
  /**
44870
44872
  * An item counts as new while it holds nothing the user entered. Since
44871
44873
  * `@rjsf/core` 6.10 fills a required property with its default as soon as the
@@ -45347,6 +45349,10 @@ class SchemaField extends React.Component {
45347
45349
  const fallbackText = (_c = (_b = (_a = schema.lime) === null || _a === void 0 ? void 0 : _a.component) === null || _b === void 0 ? void 0 : _b.props) === null || _c === void 0 ? void 0 : _c.helperText;
45348
45350
  return getErrorText(errors, schema.description, fallbackText);
45349
45351
  }
45352
+ hasHeaderFromForm(schema) {
45353
+ var _a, _b;
45354
+ return ((_b = (_a = schema.lime) === null || _a === void 0 ? void 0 : _a.component) === null || _b === void 0 ? void 0 : _b.showHeader) === true && !this.context;
45355
+ }
45350
45356
  handleCustomComponentChange(event) {
45351
45357
  const { schema } = this.props;
45352
45358
  event.stopPropagation();
@@ -45405,7 +45411,9 @@ class SchemaField extends React.Component {
45405
45411
  const { name, props: userDefinedComponentProps } = getCustomComponent(schema);
45406
45412
  verifyCustomComponentIsDefined(name);
45407
45413
  const component = React.createElement(name, Object.assign(Object.assign(Object.assign({}, userDefinedComponentProps), this.buildCustomComponentProps()), { onChange: this.handleCustomComponentChange }));
45408
- return React.createElement(FieldTemplate, Object.assign(Object.assign({}, this.props), { classNames: 'rjsf-field rjsf-field-custom' }), component, getHelpComponent(schema));
45414
+ const hasHeader = this.hasHeaderFromForm(schema);
45415
+ return React.createElement(FieldTemplate, Object.assign(Object.assign({}, this.props), { classNames: 'rjsf-field rjsf-field-custom' }), hasHeader &&
45416
+ renderHeader(schema.title, schema.description, schema.lime.help), component, !hasHeader && getHelpComponent(schema));
45409
45417
  }
45410
45418
  render() {
45411
45419
  var _a;
@@ -46158,7 +46166,8 @@ const Form = class {
46158
46166
  /**
46159
46167
  * The level, from `1` to `6`, of the topmost headings in the form.
46160
46168
  * The headings of the sections inside them get one level more for each
46161
- * level of nesting, down to `6`.
46169
+ * level of nesting, down to `6`. A collapsible section, and each item
46170
+ * of a list that is shown as one, counts as a level too.
46162
46171
  *
46163
46172
  * Set it so that the headings of the form fit below the headings of
46164
46173
  * the page around it. For example, when the form is in a section with
@@ -46191,7 +46200,7 @@ const Form = class {
46191
46200
  this.warnIfHeadingLevelIsInvalid();
46192
46201
  }
46193
46202
  warnIfHeadingLevelIsInvalid() {
46194
- if (!isHeadingLevel(this.headingLevel)) {
46203
+ if (!headingLevel.isHeadingLevel(this.headingLevel)) {
46195
46204
  console.warn(`limel-form: headingLevel must be a number from 1 to 6, but it is ${this.headingLevel}. The headings start at level 1 instead.`);
46196
46205
  }
46197
46206
  }
@@ -46221,7 +46230,7 @@ const Form = class {
46221
46230
  this.initialized = false;
46222
46231
  }
46223
46232
  render() {
46224
- return index.h("div", { key: '3f2e4aedf778c43f02ab87c32074cb3face9a55b', class: "root" });
46233
+ return index.h("div", { key: 'e034b4254d91f376a19f0efabc434c4df24edfc7', class: "root" });
46225
46234
  }
46226
46235
  reactRender() {
46227
46236
  if (!this.root) {
@@ -46229,7 +46238,7 @@ const Form = class {
46229
46238
  this.root = clientExports.createRoot(rootElement);
46230
46239
  }
46231
46240
  this.root.render(React.createElement(HeadingLevelContext.Provider, {
46232
- value: isHeadingLevel(this.headingLevel)
46241
+ value: headingLevel.isHeadingLevel(this.headingLevel)
46233
46242
  ? this.headingLevel
46234
46243
  : 1,
46235
46244
  }, React.createElement(Form$1, {
@@ -4,13 +4,8 @@ import { makeEnterClickable, removeEnterClickable, } from "../../util/make-enter
4
4
  import { createRandomString } from "../../util/random-string";
5
5
  import { getIconColor, getIconName, getIconTitle, } from "../icon/get-icon-props";
6
6
  import translate from "../../global/translations";
7
+ import { isHeadingLevel } from "../../util/heading-level";
7
8
  const DEFAULT_HEADING_LEVEL = 2;
8
- function isHeadingLevel(level) {
9
- return (typeof level === 'number' &&
10
- Number.isSafeInteger(level) &&
11
- level >= 1 &&
12
- level <= 6);
13
- }
14
9
  /**
15
10
  * A collapsible section can be used to group related content together
16
11
  * and hide the group when not needed.
@@ -135,7 +130,7 @@ export class CollapsibleSection {
135
130
  removeEnterClickable(button);
136
131
  }
137
132
  render() {
138
- return (h("section", { key: '1cb8db604bbbc8f8dbb7ca97895b3cfcf4dcd80b', class: `${this.isOpen ? 'open' : ''}`, "aria-invalid": this.invalid, "aria-labelledby": this.header ? this.headingId : null }, h("header", { key: '4e55c5b636b1d049df4d77a77a35285648096ea0' }, h("button", { key: '29eefb5499fb0f00cbdf513698acf8f357a935a6', class: "open-close-toggle", onClick: this.onClick, "aria-controls": this.bodyId, "aria-expanded": this.isOpen ? 'true' : 'false', "aria-label": this.getCollapsibleSectionAriaLabel(), type: "button" }), this.renderExpandCollapseSign(), this.renderIcon(), this.renderHeading(), h("div", { key: '16ec84abfe81a812c9d30188a714b58d363ca8a3', class: "divider-line", role: "presentation" }), this.renderHeaderSlot(), this.renderActions()), h("div", { key: 'f28ff7d73f05dc1a6ca0dcd9948cb67107647598', class: "body", inert: !this.isOpen, "aria-hidden": String(!this.isOpen), id: this.bodyId, role: "region" }, h("slot", { key: '33d0fda5501c178f92dff4a1b0361a43829fe095' }))));
133
+ return (h("section", { key: 'ff18dacc5e74d3bd8d16da55be3e5340922acf86', class: `${this.isOpen ? 'open' : ''}`, "aria-invalid": this.invalid, "aria-labelledby": this.header ? this.headingId : null }, h("header", { key: 'f4dba35493c7ce7344ff34d2fbaeeb769f8c87eb' }, h("button", { key: 'd3a632b4002d01774c9bb88f250be4e196340ef3', class: "open-close-toggle", onClick: this.onClick, "aria-controls": this.bodyId, "aria-expanded": this.isOpen ? 'true' : 'false', "aria-label": this.getCollapsibleSectionAriaLabel(), type: "button" }), this.renderExpandCollapseSign(), this.renderIcon(), this.renderHeading(), h("div", { key: '8d8489917d5e1bfa8de3cca8294651f448c8129c', class: "divider-line", role: "presentation" }), this.renderHeaderSlot(), this.renderActions()), h("div", { key: 'fd7e13cf3bd26815d62c3fbac0ef04ed4db364b5', class: "body", inert: !this.isOpen, "aria-hidden": String(!this.isOpen), id: this.bodyId, role: "region" }, h("slot", { key: '90ed08286c1091f5c5c5feec827729cfa65588fc' }))));
139
134
  }
140
135
  getHeadingLevel() {
141
136
  return isHeadingLevel(this.headingLevel)
@@ -207,9 +202,16 @@ export class CollapsibleSection {
207
202
  "type": "number",
208
203
  "mutable": false,
209
204
  "complexType": {
210
- "original": "1 | 2 | 3 | 4 | 5 | 6",
205
+ "original": "HeadingLevel",
211
206
  "resolved": "1 | 2 | 3 | 4 | 5 | 6",
212
- "references": {}
207
+ "references": {
208
+ "HeadingLevel": {
209
+ "location": "import",
210
+ "path": "../../global/shared-types/heading-level.types",
211
+ "id": "src/global/shared-types/heading-level.types.ts::HeadingLevel",
212
+ "referenceLocation": "HeadingLevel"
213
+ }
214
+ }
213
215
  },
214
216
  "required": false,
215
217
  "optional": false,
@@ -4,6 +4,7 @@ import { isEmpty } from "lodash-es";
4
4
  import { hasValue, isFieldInvalid, isFieldRequired, getErrorText, } from "../validation-display";
5
5
  import { resetDependentFields, schemaAllowsNull } from "./field-helpers";
6
6
  import { FieldTemplate } from "../templates";
7
+ import { renderHeader } from "../templates/common";
7
8
  import { getHelpComponent } from "../help";
8
9
  import { TimePicker } from "../widgets/time-picker";
9
10
  import { isIntegerType, isNumberType } from "../schema";
@@ -111,6 +112,10 @@ export class SchemaField extends React.Component {
111
112
  const fallbackText = (_c = (_b = (_a = schema.lime) === null || _a === void 0 ? void 0 : _a.component) === null || _b === void 0 ? void 0 : _b.props) === null || _c === void 0 ? void 0 : _c.helperText;
112
113
  return getErrorText(errors, schema.description, fallbackText);
113
114
  }
115
+ hasHeaderFromForm(schema) {
116
+ var _a, _b;
117
+ return ((_b = (_a = schema.lime) === null || _a === void 0 ? void 0 : _a.component) === null || _b === void 0 ? void 0 : _b.showHeader) === true && !this.context;
118
+ }
114
119
  handleCustomComponentChange(event) {
115
120
  const { schema } = this.props;
116
121
  event.stopPropagation();
@@ -169,7 +174,9 @@ export class SchemaField extends React.Component {
169
174
  const { name, props: userDefinedComponentProps } = getCustomComponent(schema);
170
175
  verifyCustomComponentIsDefined(name);
171
176
  const component = React.createElement(name, Object.assign(Object.assign(Object.assign({}, userDefinedComponentProps), this.buildCustomComponentProps()), { onChange: this.handleCustomComponentChange }));
172
- return React.createElement(FieldTemplate, Object.assign(Object.assign({}, this.props), { classNames: 'rjsf-field rjsf-field-custom' }), component, getHelpComponent(schema));
177
+ const hasHeader = this.hasHeaderFromForm(schema);
178
+ return React.createElement(FieldTemplate, Object.assign(Object.assign({}, this.props), { classNames: 'rjsf-field rjsf-field-custom' }), hasHeader &&
179
+ renderHeader(schema.title, schema.description, schema.lime.help), component, !hasHeader && getHelpComponent(schema));
173
180
  }
174
181
  render() {
175
182
  var _a;
@@ -14,6 +14,7 @@ import { h, } from "@stencil/core";
14
14
  import React from "react";
15
15
  import { createRoot } from "react-dom/client";
16
16
  import JSONSchemaForm from "@rjsf/core";
17
+ import { isHeadingLevel } from "../../util/heading-level";
17
18
  import { ArrayFieldTemplate, ArrayFieldItemTemplate, FieldTemplate, ObjectFieldTemplate, } from "./templates";
18
19
  import { SchemaField as CustomSchemaField } from "./fields/schema-field";
19
20
  import { ArrayField as CustomArrayField } from "./fields/array-field";
@@ -22,13 +23,14 @@ import { widgets } from "./widgets";
22
23
  import { rjsfValidator } from "./validator";
23
24
  import { isEqual, mapValues } from "lodash-es";
24
25
  import { showField } from "./show-field";
25
- import { HeadingLevelContext, isHeadingLevel } from "./templates/heading-level";
26
+ import { HeadingLevelContext } from "./templates/heading-level";
26
27
  /**
27
28
  * @exampleComponent limel-example-form
28
29
  * @exampleComponent limel-example-nested-form
29
30
  * @exampleComponent limel-example-list-form
30
31
  * @exampleComponent limel-example-dynamic-form
31
32
  * @exampleComponent limel-example-custom-component-form
33
+ * @exampleComponent limel-example-custom-component-header-form
32
34
  * @exampleComponent limel-example-props-factory-form
33
35
  * @exampleComponent limel-example-form-layout
34
36
  * @exampleComponent limel-example-form-span-fields
@@ -56,7 +58,8 @@ export class Form {
56
58
  /**
57
59
  * The level, from `1` to `6`, of the topmost headings in the form.
58
60
  * The headings of the sections inside them get one level more for each
59
- * level of nesting, down to `6`.
61
+ * level of nesting, down to `6`. A collapsible section, and each item
62
+ * of a list that is shown as one, counts as a level too.
60
63
  *
61
64
  * Set it so that the headings of the form fit below the headings of
62
65
  * the page around it. For example, when the form is in a section with
@@ -119,7 +122,7 @@ export class Form {
119
122
  this.initialized = false;
120
123
  }
121
124
  render() {
122
- return h("div", { key: '3f2e4aedf778c43f02ab87c32074cb3face9a55b', class: "root" });
125
+ return h("div", { key: 'e034b4254d91f376a19f0efabc434c4df24edfc7', class: "root" });
123
126
  }
124
127
  reactRender() {
125
128
  if (!this.root) {
@@ -419,8 +422,8 @@ export class Form {
419
422
  "references": {
420
423
  "HeadingLevel": {
421
424
  "location": "import",
422
- "path": "./form.types",
423
- "id": "src/components/form/form.types.ts::HeadingLevel",
425
+ "path": "../../global/shared-types/heading-level.types",
426
+ "id": "src/global/shared-types/heading-level.types.ts::HeadingLevel",
424
427
  "referenceLocation": "HeadingLevel"
425
428
  }
426
429
  }
@@ -429,7 +432,7 @@ export class Form {
429
432
  "optional": false,
430
433
  "docs": {
431
434
  "tags": [],
432
- "text": "The level, from `1` to `6`, of the topmost headings in the form.\nThe headings of the sections inside them get one level more for each\nlevel of nesting, down to `6`.\n\nSet it so that the headings of the form fit below the headings of\nthe page around it. For example, when the form is in a section with\nan `h2` heading, set it to `3`."
435
+ "text": "The level, from `1` to `6`, of the topmost headings in the form.\nThe headings of the sections inside them get one level more for each\nlevel of nesting, down to `6`. A collapsible section, and each item\nof a list that is shown as one, counts as a level too.\n\nSet it so that the headings of the form fit below the headings of\nthe page around it. For example, when the form is in a section with\nan `h2` heading, set it to `3`."
433
436
  },
434
437
  "getter": false,
435
438
  "setter": false,
@@ -322,6 +322,92 @@ export const customComponentSchema = {
322
322
  },
323
323
  },
324
324
  };
325
+ export const customComponentWithHeaderSchema = {
326
+ type: 'object',
327
+ title: 'Form',
328
+ properties: {
329
+ enabled: {
330
+ type: 'boolean',
331
+ title: 'Enabled',
332
+ description: 'Turns the feature on',
333
+ lime: {
334
+ help: 'Read more about the feature',
335
+ component: {
336
+ name: 'limel-switch',
337
+ showHeader: true,
338
+ },
339
+ },
340
+ },
341
+ section: {
342
+ type: 'object',
343
+ title: 'Section',
344
+ properties: {
345
+ nested: {
346
+ type: 'boolean',
347
+ title: 'Nested',
348
+ lime: {
349
+ component: {
350
+ name: 'limel-switch',
351
+ showHeader: true,
352
+ },
353
+ },
354
+ },
355
+ },
356
+ },
357
+ },
358
+ };
359
+ export const requiredCustomComponentWithHeaderSchema = {
360
+ type: 'object',
361
+ properties: {
362
+ name: { type: 'string', title: 'Name' },
363
+ enabled: {
364
+ type: 'boolean',
365
+ title: 'Enabled',
366
+ description: 'Turns the feature on',
367
+ lime: {
368
+ component: {
369
+ name: 'limel-switch',
370
+ showHeader: true,
371
+ },
372
+ },
373
+ },
374
+ },
375
+ required: ['name', 'enabled'],
376
+ };
377
+ export const customComponentWithHelpSchema = {
378
+ type: 'object',
379
+ properties: {
380
+ enabled: {
381
+ type: 'boolean',
382
+ title: 'Enabled',
383
+ lime: {
384
+ help: 'Read more about the feature',
385
+ component: { name: 'limel-switch' },
386
+ },
387
+ },
388
+ },
389
+ };
390
+ export const rowLayoutWithCustomComponentHeaderSchema = {
391
+ type: 'object',
392
+ properties: {
393
+ active: {
394
+ type: 'boolean',
395
+ title: 'Active',
396
+ description: 'Active description',
397
+ lime: {
398
+ component: {
399
+ name: 'limel-switch',
400
+ showHeader: true,
401
+ },
402
+ },
403
+ },
404
+ },
405
+ lime: {
406
+ layout: {
407
+ type: 'row',
408
+ },
409
+ },
410
+ };
325
411
  export const undefinedComponentSchema = {
326
412
  type: 'object',
327
413
  properties: {
@@ -455,6 +541,26 @@ export const nestedArrayObjectSchema = {
455
541
  },
456
542
  },
457
543
  };
544
+ export const arrayItemWithEmptyListSchema = {
545
+ type: 'object',
546
+ properties: {
547
+ people: {
548
+ type: 'array',
549
+ title: 'People',
550
+ items: {
551
+ type: 'object',
552
+ properties: {
553
+ tags: {
554
+ type: 'array',
555
+ title: 'Tags',
556
+ items: { type: 'string' },
557
+ },
558
+ role: { type: 'string', title: 'Role' },
559
+ },
560
+ },
561
+ },
562
+ },
563
+ };
458
564
  export const topLevelStringCustomComponentSchema = {
459
565
  type: 'object',
460
566
  properties: {
@@ -729,6 +835,54 @@ export const untitledRootSchema = {
729
835
  },
730
836
  },
731
837
  };
838
+ export const nestedCollapsibleSchema = {
839
+ type: 'object',
840
+ title: 'Form',
841
+ properties: {
842
+ details: {
843
+ type: 'object',
844
+ title: 'Details',
845
+ lime: { collapsible: true },
846
+ properties: {
847
+ address: {
848
+ type: 'object',
849
+ title: 'Address',
850
+ lime: { collapsible: true },
851
+ properties: {
852
+ street: { type: 'string', title: 'Street' },
853
+ position: {
854
+ type: 'object',
855
+ title: 'Position',
856
+ properties: {
857
+ latitude: { type: 'number', title: 'Latitude' },
858
+ },
859
+ },
860
+ },
861
+ },
862
+ },
863
+ },
864
+ },
865
+ };
866
+ export const untitledCollapsibleSchema = {
867
+ type: 'object',
868
+ title: 'Form',
869
+ properties: {
870
+ details: {
871
+ type: 'object',
872
+ title: '',
873
+ lime: { collapsible: true },
874
+ properties: {
875
+ section: {
876
+ type: 'object',
877
+ title: 'Section',
878
+ properties: {
879
+ name: { type: 'string', title: 'Name' },
880
+ },
881
+ },
882
+ },
883
+ },
884
+ },
885
+ };
732
886
  export const untitledRowSchema = {
733
887
  type: 'object',
734
888
  title: 'Form',
@@ -3,6 +3,7 @@ import { findTitle, hasNestedErrors } from "./common";
3
3
  import { getDefaultFormState, } from "@rjsf/utils";
4
4
  import { isEmpty, isEqual } from "lodash-es";
5
5
  import { rjsfValidator } from "../validator";
6
+ import { BelowHeading, HeadingLevelContext } from "./heading-level";
6
7
  export class CollapsibleItemTemplate extends React.Component {
7
8
  constructor(props) {
8
9
  super(props);
@@ -35,10 +36,11 @@ export class CollapsibleItemTemplate extends React.Component {
35
36
  section.removeEventListener('open', this.handleOpen);
36
37
  }
37
38
  render() {
38
- const { data, schema, formSchema, errorSchema, revealErrors } = this.props;
39
+ const { errorSchema, revealErrors } = this.props;
40
+ const header = getItemHeader(this.props);
39
41
  let children;
40
42
  if (this.state.isOpen) {
41
- children = this.props.children;
43
+ children = React.createElement(BelowHeading, { hasHeading: !!header }, this.props.children);
42
44
  }
43
45
  const dragHandle = this.props.allowItemReorder
44
46
  ? React.createElement('limel-drag-handle', {
@@ -48,7 +50,8 @@ export class CollapsibleItemTemplate extends React.Component {
48
50
  : null;
49
51
  const invalid = revealErrors === true && hasNestedErrors(errorSchema);
50
52
  return React.createElement('limel-collapsible-section', {
51
- header: findTitle(data, schema, formSchema) || 'New item',
53
+ header: header,
54
+ headingLevel: this.context,
52
55
  class: 'array-item limel-form-array-item--object',
53
56
  ref: (section) => {
54
57
  this.section = section;
@@ -80,6 +83,13 @@ export class CollapsibleItemTemplate extends React.Component {
80
83
  event.detail.run(event);
81
84
  }
82
85
  }
86
+ CollapsibleItemTemplate.contextType = HeadingLevelContext;
87
+ function getItemHeader(props) {
88
+ const { data, schema, formSchema } = props;
89
+ const title = findTitle(data, schema, formSchema);
90
+ const text = Array.isArray(title) ? title.join(', ') : title;
91
+ return text ? String(text) : 'New item';
92
+ }
83
93
  /**
84
94
  * An item counts as new while it holds nothing the user entered. Since
85
95
  * `@rjsf/core` 6.10 fills a required property with its default as soon as the
@@ -1,14 +1,4 @@
1
1
  import React, { useContext } from "react";
2
- /**
3
- * @param level - any value
4
- * @returns whether the value is a heading level, from `1` to `6`
5
- */
6
- export function isHeadingLevel(level) {
7
- return (typeof level === 'number' &&
8
- Number.isSafeInteger(level) &&
9
- level >= 1 &&
10
- level <= 6);
11
- }
12
2
  /**
13
3
  * The heading level that a title at the current depth in the form gets.
14
4
  */
@@ -4,8 +4,10 @@ import { GridLayout } from "./grid-layout";
4
4
  import { RowLayout } from "./row-layout";
5
5
  import { getHelpComponent } from "../help";
6
6
  import { ArrayFieldContext } from "./array-context";
7
+ import { BelowHeading, HeadingLevelContext } from "./heading-level";
7
8
  export const ObjectFieldTemplate = (props) => {
8
9
  const arrayContext = useContext(ArrayFieldContext);
10
+ const headingLevel = useContext(HeadingLevelContext);
9
11
  const id = props.fieldPathId.$id;
10
12
  if (arrayContext && id !== 'root') {
11
13
  return React.createElement(ArrayFieldContext.Provider, { value: null }, renderProperties(props.properties, props.schema, props.fieldPathId.path.map(String)));
@@ -13,13 +15,13 @@ export const ObjectFieldTemplate = (props) => {
13
15
  if (id === 'root' || !isCollapsible(props.schema)) {
14
16
  return renderFieldWithTitle(props);
15
17
  }
16
- return renderCollapsibleField(props);
18
+ return renderCollapsibleField(props, headingLevel);
17
19
  };
18
20
  function renderFieldWithTitle(props) {
19
21
  var _a;
20
22
  return renderSection(props.title, props.description, (_a = props.schema.lime) === null || _a === void 0 ? void 0 : _a.help, renderProperties(props.properties, props.schema, props.fieldPathId.path.map(String)));
21
23
  }
22
- function renderCollapsibleField(props) {
24
+ function renderCollapsibleField(props, headingLevel) {
23
25
  var _a;
24
26
  const defaultOpen = !isCollapsed(props.schema);
25
27
  const helpElement = getHelpComponent(props.schema, {
@@ -29,10 +31,11 @@ function renderCollapsibleField(props) {
29
31
  const invalid = revealErrors && hasNestedErrors(props.errorSchema);
30
32
  return React.createElement('limel-collapsible-section', {
31
33
  header: props.title,
34
+ headingLevel: headingLevel,
32
35
  id: getSchemaObjectPropertyPath(props.registry.formContext.schema, props.fieldPathId),
33
36
  'is-open': defaultOpen,
34
37
  invalid: invalid,
35
- }, helpElement, renderDescription(props.description), renderProperties(props.properties, props.schema, props.fieldPathId.path.map(String)));
38
+ }, helpElement, renderDescription(props.description), React.createElement(BelowHeading, { hasHeading: !!props.title }, renderProperties(props.properties, props.schema, props.fieldPathId.path.map(String))));
36
39
  }
37
40
  function getSchemaObjectPropertyPath(schema, fieldPathId) {
38
41
  var _a, _b;
@@ -29,7 +29,7 @@ export class FormHeader {
29
29
  this.headingLevel = 1;
30
30
  }
31
31
  render() {
32
- return (h(Host, { key: 'bfb0a90340ac54c7f083df2989fd8c2acb97308f' }, this.renderHeading(), this.renderHelp(), this.renderDescription()));
32
+ return (h(Host, { key: '0d8282124405665c18b93aa753dd40cf616a6e6b' }, this.renderHeading(), this.renderHelp(), this.renderDescription()));
33
33
  }
34
34
  renderHeading() {
35
35
  if (!this.heading) {
@@ -91,8 +91,8 @@ export class FormHeader {
91
91
  "references": {
92
92
  "HeadingLevel": {
93
93
  "location": "import",
94
- "path": "../form/form.types",
95
- "id": "src/components/form/form.types.ts::HeadingLevel",
94
+ "path": "../../global/shared-types/heading-level.types",
95
+ "id": "src/global/shared-types/heading-level.types.ts::HeadingLevel",
96
96
  "referenceLocation": "HeadingLevel"
97
97
  }
98
98
  }
@@ -44,6 +44,7 @@ export * from './global/shared-types/separator.types';
44
44
  export * from './global/shared-types/icon.types';
45
45
  export * from './global/shared-types/image.types';
46
46
  export * from './global/shared-types/color.types';
47
+ export * from './global/shared-types/heading-level.types';
47
48
  export * from './components/text-editor/text-editor.types';
48
49
  export * from './components/text-editor/types';
49
50
  export * from './components/text-editor/prosemirror-adapter/menu/types';
@@ -0,0 +1,10 @@
1
+ /**
2
+ * @param level - any value
3
+ * @returns whether the value is a heading level, from `1` to `6`
4
+ */
5
+ export function isHeadingLevel(level) {
6
+ return (typeof level === 'number' &&
7
+ Number.isSafeInteger(level) &&
8
+ level >= 1 &&
9
+ level <= 6);
10
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @param level - any value
3
+ * @returns whether the value is a heading level, from `1` to `6`
4
+ */
5
+ function isHeadingLevel(level) {
6
+ return (typeof level === 'number' &&
7
+ Number.isSafeInteger(level) &&
8
+ level >= 1 &&
9
+ level <= 6);
10
+ }
11
+
12
+ export { isHeadingLevel as i };