@configura/web-ui 1.6.1-alpha.7 → 1.6.2

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.
@@ -0,0 +1,3 @@
1
+ import React from "react";
2
+ export declare const ErrorContext: React.Context<(err: unknown) => void>;
3
+ //# sourceMappingURL=ErrorContext.d.ts.map
@@ -0,0 +1,2 @@
1
+ import React from "react";
2
+ export const ErrorContext = React.createContext(() => undefined);
@@ -1,5 +1,6 @@
1
1
  import { isRenderFormat } from "@configura/web-api";
2
- import React from "react";
2
+ import React, { useContext } from "react";
3
+ import { ErrorContext } from "./ErrorContext.js";
3
4
  import { CircleXmarkIcon } from "./icons/CircleXmarkIcon.js";
4
5
  import { DownloadIcon } from "./icons/DownloadIcon.js";
5
6
  import { ErrorIcon } from "./icons/ErrorIcon.js";
@@ -18,6 +19,7 @@ const spinner = (React.createElement("span", { className: "cfgLoadingSizer" },
18
19
  const TaskView = (props) => {
19
20
  const { task } = props;
20
21
  const { status, format, url, previewUrl } = task;
22
+ const setError = useContext(ErrorContext);
21
23
  let icon;
22
24
  let statusMessage;
23
25
  switch (status) {
@@ -48,7 +50,20 @@ const TaskView = (props) => {
48
50
  url === undefined ? (statusMessage) : (React.createElement("a", { href: url, title: statusMessage }, statusMessage)),
49
51
  status === "failed" && (React.createElement(React.Fragment, null,
50
52
  " ",
51
- React.createElement("button", { className: "cfgTaskList__restart", onClick: () => task.restart() }, "Restart")))),
52
- React.createElement("button", { className: "cfgTaskList__abort", onClick: () => task.abort() },
53
+ React.createElement("button", { className: "cfgTaskList__restart", onClick: () => {
54
+ task.restart().catch((e) => {
55
+ setError(e);
56
+ throw e;
57
+ });
58
+ } }, "Restart")))),
59
+ React.createElement("button", { className: "cfgTaskList__abort", onClick: () => {
60
+ try {
61
+ task.abort();
62
+ }
63
+ catch (e) {
64
+ setError(e);
65
+ throw e;
66
+ }
67
+ } },
53
68
  React.createElement(CircleXmarkIcon, null))));
54
69
  };
@@ -1,7 +1,9 @@
1
- import React from "react";
1
+ import React, { useContext } from "react";
2
+ import { ErrorContext } from "./ErrorContext.js";
2
3
  export const TaskStartView = (props) => {
3
4
  var _a, _b;
4
5
  const { taskHandler, product, renderTaskParams, getPreviewUrl } = props;
6
+ const setError = useContext(ErrorContext);
5
7
  const formats = (_a = props.formats) !== null && _a !== void 0 ? _a : taskHandler.availableFormats;
6
8
  if (formats.length === 0) {
7
9
  return null;
@@ -13,9 +15,14 @@ export const TaskStartView = (props) => {
13
15
  if (index === 0) {
14
16
  return;
15
17
  }
16
- taskHandler.start(formats[index - 1], product, typeof renderTaskParams === "function"
18
+ taskHandler
19
+ .start(formats[index - 1], product, typeof renderTaskParams === "function"
17
20
  ? renderTaskParams()
18
- : renderTaskParams, getPreviewUrl);
21
+ : renderTaskParams, getPreviewUrl)
22
+ .catch((e) => {
23
+ setError(e);
24
+ throw e;
25
+ });
19
26
  } },
20
27
  React.createElement("option", { value: "" }, "Export"),
21
28
  formats.map((format) => (React.createElement("option", { value: format, key: format }, format)))))));
@@ -1,22 +1,27 @@
1
- import React, { useState } from "react";
1
+ import React, { useContext, useState } from "react";
2
+ import { ErrorContext } from "../ErrorContext.js";
2
3
  import { ExpandableHeadingRow, ExpandableHeadingRowSymbol } from "../ExpandableHeadingRow.js";
3
- import { forwardProps } from "./CfgFeatureView.js";
4
+ import { forwardProps, } from "./CfgFeatureView.js";
4
5
  import { CfgProductConfigurationView } from "./CfgProductConfigurationView.js";
5
6
  export const CfgAdditionalProductView = React.memo((props) => {
6
- const { product, permanentlyExpandedLevels, additionalProductComponent } = props;
7
+ const { product, permanentlyExpandedLevels, startOpen } = props;
7
8
  const { partNumber, optional, selected, configuration, additionalProducts, preview, description, visible: configurationVisible, } = product;
8
- const [open, setOpen] = useState(false);
9
+ const setError = useContext(ErrorContext);
10
+ const [open, setOpen] = useState(startOpen === true);
9
11
  if (!configurationVisible) {
10
12
  // Visibility of a Product should not affect its Additional Products.
11
13
  // (Those have their own visibility.)
12
- return (React.createElement(AdditionalProductsView, { additionalProducts: additionalProducts, permanentlyExpandedLevels: permanentlyExpandedLevels, additionalProductComponent: additionalProductComponent }));
14
+ return (React.createElement(AdditionalProductsView, Object.assign({}, forwardProps(props), { additionalProducts: additionalProducts, permanentlyExpandedLevels: permanentlyExpandedLevels })));
13
15
  }
14
16
  const openOrSelected = optional ? selected : open;
15
17
  const hasChildren = configuration.features.length !== 0 || additionalProducts.length !== 0;
16
18
  return (React.createElement("li", { className: "cfgFeatureItem cfgAdditionalProduct" },
17
19
  React.createElement(ExpandableHeadingRow, { heading: description || partNumber, expandable: optional || (hasChildren && permanentlyExpandedLevels <= 0), open: openOrSelected, onClick: () => {
18
20
  if (optional) {
19
- product.setSelected(!selected);
21
+ product.setSelected(!selected).catch((e) => {
22
+ setError(e);
23
+ throw e;
24
+ });
20
25
  }
21
26
  else {
22
27
  setOpen((prev) => !prev);
@@ -28,11 +33,10 @@ export const CfgAdditionalProductView = React.memo((props) => {
28
33
  (openOrSelected || 0 < permanentlyExpandedLevels) && (React.createElement("div", { className: "cfgFeatureItem__subTree" },
29
34
  React.createElement(CfgProductConfigurationView, Object.assign({}, forwardProps(props), { productOrConfiguration: configuration })),
30
35
  additionalProducts.length !== 0 && (React.createElement("ul", { className: `cfgOptionTree cfgOptionTree--topLevel` },
31
- React.createElement(AdditionalProductsView, { additionalProducts: additionalProducts, permanentlyExpandedLevels: permanentlyExpandedLevels, additionalProductComponent: additionalProductComponent }))))),
36
+ React.createElement(AdditionalProductsView, Object.assign({}, forwardProps(props), { additionalProducts: additionalProducts, permanentlyExpandedLevels: permanentlyExpandedLevels })))))),
32
37
  React.createElement("hr", { className: "cfgFeatureItem__hr cfgHr" })));
33
38
  });
34
39
  const AdditionalProductsView = (props) => {
35
- const { additionalProducts, permanentlyExpandedLevels, additionalProductComponent } = props;
36
- const AdditionalProductComponent = additionalProductComponent !== null && additionalProductComponent !== void 0 ? additionalProductComponent : CfgAdditionalProductView;
40
+ const { additionalProducts, permanentlyExpandedLevels, additionalProductComponent: AdditionalProductComponent, } = props;
37
41
  return (React.createElement(React.Fragment, null, additionalProducts.map((additionalProduct) => (React.createElement(AdditionalProductComponent, Object.assign({ key: additionalProduct.key }, forwardProps(props), { product: additionalProduct, permanentlyExpandedLevels: permanentlyExpandedLevels - 1 }))))));
38
42
  };
@@ -2,16 +2,7 @@ import React from "react";
2
2
  import { CssProps } from "../../utilities.js";
3
3
  import { CfgOptionViewProps } from "./CfgFeatureView.js";
4
4
  export declare const CfgCheckboxView: React.FC<CfgOptionViewProps & CssProps>;
5
- export declare const CfgCheckboxViewMemo: React.NamedExoticComponent<import("./CfgProductConfigurationView.js").PassthroughProps & {
6
- additionalProductComponent?: React.ComponentType<import("./CfgFeatureView.js").CfgAdditionalProductViewProps> | undefined;
7
- featureFlattenComponent?: React.ComponentType<import("./CfgFeatureView.js").CfgFeatureViewProps> | undefined;
8
- optionFlattenComponent?: React.ComponentType<CfgOptionViewProps> | undefined;
9
- featureGroupComponent?: React.ComponentType<import("./CfgFeatureView.js").CfgFeatureViewProps> | undefined;
10
- featureSelectManyComponent?: React.ComponentType<import("./CfgFeatureView.js").CfgFeatureViewProps> | undefined;
11
- optionSelectManyComponent?: React.ComponentType<CfgOptionViewProps> | undefined;
12
- featureSelectOneComponent?: React.ComponentType<import("./CfgFeatureView.js").CfgFeatureViewProps> | undefined;
13
- optionSelectOneComponent?: React.ComponentType<CfgOptionViewProps> | undefined;
14
- } & {
5
+ export declare const CfgCheckboxViewMemo: React.NamedExoticComponent<import("./CfgProductConfigurationView.js").PassthroughProps & import("./CfgFeatureView.js").CfgProductConfigurationComponent & {
15
6
  option: import("@configura/web-api").CfgOption;
16
7
  } & CssProps>;
17
8
  //# sourceMappingURL=CfgCheckboxView.d.ts.map
@@ -1,17 +1,24 @@
1
- import React from "react";
1
+ import React, { useContext } from "react";
2
2
  import { useUuid } from "../../useUniqueId.js";
3
+ import { ErrorContext } from "../ErrorContext.js";
3
4
  import { Checkmark } from "../icons/Checkmark.js";
4
5
  import { forwardProps } from "./CfgFeatureView.js";
5
6
  import { CfgOptionFeaturesView } from "./CfgOptionFeaturesView.js";
6
7
  import { CfgOptionPriceView } from "./CfgOptionPriceView.js";
7
8
  export const CfgCheckboxView = (props) => {
8
9
  const { option, upchargeDisplayMode } = props;
9
- const { thumbnail, description, selected, code } = option;
10
+ const setError = useContext(ErrorContext);
11
+ const { thumbnail, description, selected, code, selectedChangeInProgress } = option;
10
12
  const uniqueId = useUuid();
11
13
  return (React.createElement("li", { className: props.className, style: props.style },
12
14
  React.createElement("label", { className: "cfgFeatureItemOptional", htmlFor: uniqueId },
13
- React.createElement("input", { checked: selected, className: "cfgFeatureItem__hiddenInput", id: uniqueId, name: uniqueId, onChange: () => option.setSelected(!selected), type: "checkbox" }),
14
- React.createElement("div", { className: "cfgFeatureItem__checkbox" }, selected && React.createElement(Checkmark, null)),
15
+ React.createElement("input", { checked: selected, className: "cfgFeatureItem__hiddenInput", id: uniqueId, name: uniqueId, onChange: () => {
16
+ option.setSelected(!selected).catch((e) => {
17
+ setError(e);
18
+ throw e;
19
+ });
20
+ }, type: "checkbox" }),
21
+ React.createElement("div", { className: "cfgFeatureItem__checkbox" }, selected === !selectedChangeInProgress && React.createElement(Checkmark, null)),
15
22
  thumbnail && (React.createElement("img", { alt: `Thumbnail for ${description}`, className: "cfgThumbnailImage cfgMl1", src: thumbnail })),
16
23
  React.createElement("div", { className: "cfgFeatureItemOptional__titleWrapper" },
17
24
  React.createElement("div", { className: "cfgFeatureItemOptional__title" },
@@ -2,16 +2,7 @@ import React from "react";
2
2
  import { CssProps } from "../../utilities.js";
3
3
  import { CfgFeatureViewProps } from "./CfgFeatureView.js";
4
4
  export declare const CfgCheckboxesView: React.FC<CfgFeatureViewProps & CssProps>;
5
- export declare const CfgCheckboxesViewMemo: React.NamedExoticComponent<import("./CfgProductConfigurationView.js").PassthroughProps & {
6
- additionalProductComponent?: React.ComponentType<import("./CfgFeatureView.js").CfgAdditionalProductViewProps> | undefined;
7
- featureFlattenComponent?: React.ComponentType<CfgFeatureViewProps> | undefined;
8
- optionFlattenComponent?: React.ComponentType<import("./CfgFeatureView.js").CfgOptionViewProps> | undefined;
9
- featureGroupComponent?: React.ComponentType<CfgFeatureViewProps> | undefined;
10
- featureSelectManyComponent?: React.ComponentType<CfgFeatureViewProps> | undefined;
11
- optionSelectManyComponent?: React.ComponentType<import("./CfgFeatureView.js").CfgOptionViewProps> | undefined;
12
- featureSelectOneComponent?: React.ComponentType<CfgFeatureViewProps> | undefined;
13
- optionSelectOneComponent?: React.ComponentType<import("./CfgFeatureView.js").CfgOptionViewProps> | undefined;
14
- } & {
5
+ export declare const CfgCheckboxesViewMemo: React.NamedExoticComponent<import("./CfgProductConfigurationView.js").PassthroughProps & import("./CfgFeatureView.js").CfgProductConfigurationComponent & {
15
6
  feature: import("@configura/web-api").CfgFeature;
16
7
  } & CssProps>;
17
8
  //# sourceMappingURL=CfgCheckboxesView.d.ts.map
@@ -1,10 +1,9 @@
1
1
  import { SelectionType } from "@configura/web-api";
2
2
  import React from "react";
3
- import { CfgCheckboxViewMemo } from "./CfgCheckboxView.js";
4
3
  import { forwardProps } from "./CfgFeatureView.js";
5
4
  export const CfgCheckboxesView = (props) => {
6
- var _a, _b;
7
- const { feature } = props;
5
+ var _a;
6
+ const { feature, optionSelectManyComponent: OptionComponent } = props;
8
7
  if (feature.selectionType !== SelectionType.SelectMany) {
9
8
  throw Error(`Unsupported selection type expected: ${SelectionType.SelectMany}, got: ${feature.selectionType}`);
10
9
  }
@@ -12,8 +11,7 @@ export const CfgCheckboxesView = (props) => {
12
11
  if (options.length === 0) {
13
12
  return null;
14
13
  }
15
- const OptionComponent = (_a = props.optionSelectManyComponent) !== null && _a !== void 0 ? _a : CfgCheckboxViewMemo;
16
- return (React.createElement("li", { className: `cfgFeatureItem cfgFeatureItem--optional ${(_b = props.className) !== null && _b !== void 0 ? _b : ""}`, style: props.style },
14
+ return (React.createElement("li", { className: `cfgFeatureItem cfgFeatureItem--optional ${(_a = props.className) !== null && _a !== void 0 ? _a : ""}`, style: props.style },
17
15
  React.createElement("h3", { className: "cfgFeatureItemOptional__header" }, description),
18
16
  React.createElement("ul", { className: "cfgOptionTree" }, options.map((option) => (React.createElement(OptionComponent, Object.assign({ option: option, key: option.key }, forwardProps(props))))))));
19
17
  };
@@ -2,16 +2,7 @@ import React from "react";
2
2
  import { CssProps } from "../../utilities.js";
3
3
  import { CfgOptionViewProps } from "./CfgFeatureView.js";
4
4
  export declare const CfgDropdownOptionView: React.FC<CfgOptionViewProps & CssProps>;
5
- export declare const CfgDropdownOptionViewMemo: React.NamedExoticComponent<import("./CfgProductConfigurationView.js").PassthroughProps & {
6
- additionalProductComponent?: React.ComponentType<import("./CfgFeatureView.js").CfgAdditionalProductViewProps> | undefined;
7
- featureFlattenComponent?: React.ComponentType<import("./CfgFeatureView.js").CfgFeatureViewProps> | undefined;
8
- optionFlattenComponent?: React.ComponentType<CfgOptionViewProps> | undefined;
9
- featureGroupComponent?: React.ComponentType<import("./CfgFeatureView.js").CfgFeatureViewProps> | undefined;
10
- featureSelectManyComponent?: React.ComponentType<import("./CfgFeatureView.js").CfgFeatureViewProps> | undefined;
11
- optionSelectManyComponent?: React.ComponentType<CfgOptionViewProps> | undefined;
12
- featureSelectOneComponent?: React.ComponentType<import("./CfgFeatureView.js").CfgFeatureViewProps> | undefined;
13
- optionSelectOneComponent?: React.ComponentType<CfgOptionViewProps> | undefined;
14
- } & {
5
+ export declare const CfgDropdownOptionViewMemo: React.NamedExoticComponent<import("./CfgProductConfigurationView.js").PassthroughProps & import("./CfgFeatureView.js").CfgProductConfigurationComponent & {
15
6
  option: import("@configura/web-api").CfgOption;
16
7
  } & CssProps>;
17
8
  //# sourceMappingURL=CfgDropdownOptionView.d.ts.map
@@ -1,5 +1,6 @@
1
- import React from "react";
1
+ import React, { useContext } from "react";
2
2
  import { useUuid } from "../../useUniqueId.js";
3
+ import { ErrorContext } from "../ErrorContext.js";
3
4
  import { Checkmark } from "../icons/Checkmark.js";
4
5
  import { forwardProps } from "./CfgFeatureView.js";
5
6
  import { CfgOptionFeaturesView } from "./CfgOptionFeaturesView.js";
@@ -8,23 +9,30 @@ import { CfgOptionPriceView } from "./CfgOptionPriceView.js";
8
9
  export const CfgDropdownOptionView = (props) => {
9
10
  var _a;
10
11
  const { option, upchargeDisplayMode } = props;
11
- const { code, thumbnail, description, selected } = option;
12
+ const { code, thumbnail, description, selected, selectedChangeInProgress } = option;
13
+ const setError = useContext(ErrorContext);
12
14
  const optionClasses = selected ? "cfgFeatureItemOption--checked" : "";
13
15
  const uniqueId = useUuid();
14
16
  return (React.createElement("li", { className: `cfgFeatureItem cfgMb1 ${(_a = props.className) !== null && _a !== void 0 ? _a : ""}`, style: props.style },
15
17
  React.createElement("label", { className: `cfgFeatureItemOption ${optionClasses}`, htmlFor: uniqueId },
16
18
  React.createElement("input", { checked: selected, className: "cfgFeatureItem__hiddenInput", id: uniqueId, name: uniqueId, onChange: () => {
17
- option.setSelected(true);
19
+ option.setSelected(true).catch((e) => {
20
+ setError(e);
21
+ throw e;
22
+ });
18
23
  }, onClick: () => {
19
24
  // As a convenience for when wanting to re-select something already
20
25
  // selected to use the propagation side effects we have added this
21
26
  // which will trigger a setSelected even though this is strictly not
22
27
  // a change.
23
28
  if (selected) {
24
- option.setSelected(true);
29
+ option.setSelected(true).catch((e) => {
30
+ setError(e);
31
+ throw e;
32
+ });
25
33
  }
26
34
  }, type: "radio", value: code }),
27
- React.createElement("div", { className: "cfgFeatureItem__radio" }, selected && React.createElement(Checkmark, null)),
35
+ React.createElement("div", { className: "cfgFeatureItem__radio" }, selected === !selectedChangeInProgress && React.createElement(Checkmark, null)),
28
36
  thumbnail && (React.createElement("img", { alt: `Thumbnail for ${description}`, className: "cfgThumbnailImage cfgMl1", src: thumbnail })),
29
37
  React.createElement("div", { className: "cfgFeatureItemOption__titleWrapper" },
30
38
  React.createElement("div", { className: "cfgFeatureItemOption__title" },
@@ -2,16 +2,7 @@ import React from "react";
2
2
  import { CssProps } from "../../utilities.js";
3
3
  import { CfgFeatureViewProps } from "./CfgFeatureView.js";
4
4
  export declare const CfgDropdownView: React.FC<CfgFeatureViewProps & CssProps>;
5
- export declare const CfgDropdownViewMemo: React.NamedExoticComponent<import("./CfgProductConfigurationView.js").PassthroughProps & {
6
- additionalProductComponent?: React.ComponentType<import("./CfgFeatureView.js").CfgAdditionalProductViewProps> | undefined;
7
- featureFlattenComponent?: React.ComponentType<CfgFeatureViewProps> | undefined;
8
- optionFlattenComponent?: React.ComponentType<import("./CfgFeatureView.js").CfgOptionViewProps> | undefined;
9
- featureGroupComponent?: React.ComponentType<CfgFeatureViewProps> | undefined;
10
- featureSelectManyComponent?: React.ComponentType<CfgFeatureViewProps> | undefined;
11
- optionSelectManyComponent?: React.ComponentType<import("./CfgFeatureView.js").CfgOptionViewProps> | undefined;
12
- featureSelectOneComponent?: React.ComponentType<CfgFeatureViewProps> | undefined;
13
- optionSelectOneComponent?: React.ComponentType<import("./CfgFeatureView.js").CfgOptionViewProps> | undefined;
14
- } & {
5
+ export declare const CfgDropdownViewMemo: React.NamedExoticComponent<import("./CfgProductConfigurationView.js").PassthroughProps & import("./CfgFeatureView.js").CfgProductConfigurationComponent & {
15
6
  feature: import("@configura/web-api").CfgFeature;
16
7
  } & CssProps>;
17
8
  //# sourceMappingURL=CfgDropdownView.d.ts.map
@@ -1,18 +1,16 @@
1
1
  import { SelectionType } from "@configura/web-api";
2
2
  import React, { useState } from "react";
3
3
  import { ExpandableHeadingRow } from "../ExpandableHeadingRow.js";
4
- import { CfgDropdownOptionViewMemo } from "./CfgDropdownOptionView.js";
5
4
  import { forwardProps } from "./CfgFeatureView.js";
6
5
  export const CfgDropdownView = (props) => {
7
- var _a, _b;
8
- const { feature } = props;
6
+ var _a;
7
+ const { feature, optionSelectOneComponent: OptionComponent, startOpen } = props;
9
8
  if (feature.selectionType !== SelectionType.SelectOne) {
10
9
  throw Error(`Unsupported selection type expected: ${SelectionType.SelectOne}, got: ${feature.selectionType}`);
11
10
  }
12
- const OptionComponent = (_a = props.optionSelectOneComponent) !== null && _a !== void 0 ? _a : CfgDropdownOptionViewMemo;
13
11
  const { description, preview, options } = feature;
14
- const [open, setOpen] = useState(false);
15
- return (React.createElement("li", { className: `cfgFeatureItem ${(_b = props.className) !== null && _b !== void 0 ? _b : ""}`, style: props.style },
12
+ const [open, setOpen] = useState(startOpen === true);
13
+ return (React.createElement("li", { className: `cfgFeatureItem ${(_a = props.className) !== null && _a !== void 0 ? _a : ""}`, style: props.style },
16
14
  React.createElement(ExpandableHeadingRow, { heading: description, open: open, onClick: () => setOpen((prev) => !prev) }, preview && (React.createElement("div", { className: "cfgThumbnailPlaceholder" },
17
15
  React.createElement("img", { alt: `Preview for ${description}`, className: "cfgThumbnailImage", src: preview })))),
18
16
  React.createElement("div", { className: "cfgFeatureItem__subTree" },
@@ -12,28 +12,21 @@ export declare type CfgAdditionalProductViewProps = CfgProductConfigurationCompo
12
12
  product: CfgProduct;
13
13
  permanentlyExpandedLevels: number;
14
14
  };
15
- export declare type CfgProductConfigurationComponentAndPassthroughProps = PassthroughProps & {
16
- additionalProductComponent?: React.ComponentType<CfgAdditionalProductViewProps>;
17
- featureFlattenComponent?: React.ComponentType<CfgFeatureViewProps>;
18
- optionFlattenComponent?: React.ComponentType<CfgOptionViewProps>;
19
- featureGroupComponent?: React.ComponentType<CfgFeatureViewProps>;
20
- featureSelectManyComponent?: React.ComponentType<CfgFeatureViewProps>;
21
- optionSelectManyComponent?: React.ComponentType<CfgOptionViewProps>;
22
- featureSelectOneComponent?: React.ComponentType<CfgFeatureViewProps>;
23
- optionSelectOneComponent?: React.ComponentType<CfgOptionViewProps>;
15
+ export declare type CfgProductConfigurationComponent = {
16
+ additionalProductComponent: React.ComponentType<CfgAdditionalProductViewProps>;
17
+ featureFlattenComponent: React.ComponentType<CfgFeatureViewProps>;
18
+ featureGroupComponent: React.ComponentType<CfgFeatureViewProps>;
19
+ featureSelectManyComponent: React.ComponentType<CfgFeatureViewProps>;
20
+ optionSelectManyComponent: React.ComponentType<CfgOptionViewProps>;
21
+ featureSelectOneComponent: React.ComponentType<CfgFeatureViewProps>;
22
+ optionSelectOneComponent: React.ComponentType<CfgOptionViewProps>;
24
23
  };
24
+ export declare const completeWithDefaultProductConfigurationComponents: <T>(incomplete: T & Partial<CfgProductConfigurationComponent>) => T & CfgProductConfigurationComponent;
25
+ export declare const useCompleteWithDefaultProductConfigurationComponents: (incomplete: Partial<CfgProductConfigurationComponent>) => CfgProductConfigurationComponent;
26
+ export declare type CfgProductConfigurationComponentAndPassthroughProps = PassthroughProps & CfgProductConfigurationComponent;
25
27
  export declare const forwardProps: (props: CfgProductConfigurationComponentAndPassthroughProps) => CfgProductConfigurationComponentAndPassthroughProps;
26
28
  export declare const CfgFeatureView: React.FC<CfgFeatureViewProps & CssProps>;
27
- export declare const CfgFeatureViewMemo: React.NamedExoticComponent<PassthroughProps & {
28
- additionalProductComponent?: React.ComponentType<CfgAdditionalProductViewProps> | undefined;
29
- featureFlattenComponent?: React.ComponentType<CfgFeatureViewProps> | undefined;
30
- optionFlattenComponent?: React.ComponentType<CfgOptionViewProps> | undefined;
31
- featureGroupComponent?: React.ComponentType<CfgFeatureViewProps> | undefined;
32
- featureSelectManyComponent?: React.ComponentType<CfgFeatureViewProps> | undefined;
33
- optionSelectManyComponent?: React.ComponentType<CfgOptionViewProps> | undefined;
34
- featureSelectOneComponent?: React.ComponentType<CfgFeatureViewProps> | undefined;
35
- optionSelectOneComponent?: React.ComponentType<CfgOptionViewProps> | undefined;
36
- } & {
29
+ export declare const CfgFeatureViewMemo: React.NamedExoticComponent<PassthroughProps & CfgProductConfigurationComponent & {
37
30
  feature: CfgFeature;
38
31
  } & CssProps>;
39
32
  //# sourceMappingURL=CfgFeatureView.d.ts.map
@@ -1,31 +1,51 @@
1
1
  import { SelectionType } from "@configura/web-api";
2
- import React from "react";
2
+ import React, { useMemo } from "react";
3
+ import { CfgAdditionalProductView } from "./CfgAdditionalProductView.js";
3
4
  import { CfgCheckboxesViewMemo } from "./CfgCheckboxesView.js";
5
+ import { CfgCheckboxViewMemo } from "./CfgCheckboxView.js";
6
+ import { CfgDropdownOptionViewMemo } from "./CfgDropdownOptionView.js";
4
7
  import { CfgDropdownViewMemo } from "./CfgDropdownView.js";
5
8
  import { CfgGroupViewMemo } from "./CfgGroupView.js";
6
- export const forwardProps = (props) => {
7
- return {
8
- upchargeDisplayMode: props.upchargeDisplayMode,
9
- additionalProductComponent: props.additionalProductComponent,
10
- featureFlattenComponent: props.featureFlattenComponent,
11
- optionFlattenComponent: props.optionFlattenComponent,
12
- featureGroupComponent: props.featureGroupComponent,
13
- featureSelectManyComponent: props.featureSelectManyComponent,
14
- optionSelectManyComponent: props.optionSelectManyComponent,
15
- featureSelectOneComponent: props.featureSelectOneComponent,
16
- optionSelectOneComponent: props.optionSelectOneComponent,
17
- };
9
+ export const completeWithDefaultProductConfigurationComponents = (incomplete) => {
10
+ var _a, _b, _c, _d, _e, _f, _g;
11
+ return (Object.assign(Object.assign({}, incomplete), { additionalProductComponent: (_a = incomplete.additionalProductComponent) !== null && _a !== void 0 ? _a : CfgAdditionalProductView, featureFlattenComponent: (_b = incomplete.featureFlattenComponent) !== null && _b !== void 0 ? _b : CfgGroupViewMemo, featureGroupComponent: (_c = incomplete.featureGroupComponent) !== null && _c !== void 0 ? _c : CfgGroupViewMemo, featureSelectManyComponent: (_d = incomplete.featureSelectManyComponent) !== null && _d !== void 0 ? _d : CfgCheckboxesViewMemo, optionSelectManyComponent: (_e = incomplete.optionSelectManyComponent) !== null && _e !== void 0 ? _e : CfgCheckboxViewMemo, featureSelectOneComponent: (_f = incomplete.featureSelectOneComponent) !== null && _f !== void 0 ? _f : CfgDropdownViewMemo, optionSelectOneComponent: (_g = incomplete.optionSelectOneComponent) !== null && _g !== void 0 ? _g : CfgDropdownOptionViewMemo }));
18
12
  };
13
+ export const useCompleteWithDefaultProductConfigurationComponents = (incomplete) => {
14
+ const { additionalProductComponent, featureFlattenComponent, featureGroupComponent, featureSelectManyComponent, featureSelectOneComponent, optionSelectManyComponent, optionSelectOneComponent, } = incomplete;
15
+ return useMemo(() => completeWithDefaultProductConfigurationComponents({
16
+ additionalProductComponent,
17
+ featureFlattenComponent,
18
+ featureGroupComponent,
19
+ featureSelectManyComponent,
20
+ featureSelectOneComponent,
21
+ optionSelectManyComponent,
22
+ optionSelectOneComponent,
23
+ }), [
24
+ additionalProductComponent,
25
+ featureFlattenComponent,
26
+ featureGroupComponent,
27
+ featureSelectManyComponent,
28
+ featureSelectOneComponent,
29
+ optionSelectManyComponent,
30
+ optionSelectOneComponent,
31
+ ]);
32
+ };
33
+ export const forwardProps = (props) => ({
34
+ upchargeDisplayMode: props.upchargeDisplayMode,
35
+ startOpen: props.startOpen,
36
+ additionalProductComponent: props.additionalProductComponent,
37
+ featureFlattenComponent: props.featureFlattenComponent,
38
+ featureGroupComponent: props.featureGroupComponent,
39
+ featureSelectManyComponent: props.featureSelectManyComponent,
40
+ optionSelectManyComponent: props.optionSelectManyComponent,
41
+ featureSelectOneComponent: props.featureSelectOneComponent,
42
+ optionSelectOneComponent: props.optionSelectOneComponent,
43
+ });
19
44
  export const CfgFeatureView = (props) => {
20
- var _a, _b, _c;
21
- const { feature } = props;
22
- const FlattenComponent = props.featureFlattenComponent || CfgGroupViewMemo;
45
+ const { feature, featureFlattenComponent: FlattenComponent, featureGroupComponent: GroupComponent, featureSelectManyComponent: SelectManyComponent, featureSelectOneComponent: SelectOneComponent, } = props;
23
46
  if (!feature.visible) {
24
47
  return React.createElement(FlattenComponent, Object.assign({}, props));
25
48
  }
26
- const GroupComponent = (_a = props.featureGroupComponent) !== null && _a !== void 0 ? _a : CfgGroupViewMemo;
27
- const SelectManyComponent = (_b = props.featureSelectManyComponent) !== null && _b !== void 0 ? _b : CfgCheckboxesViewMemo;
28
- const SelectOneComponent = (_c = props.featureSelectOneComponent) !== null && _c !== void 0 ? _c : CfgDropdownViewMemo;
29
49
  switch (feature.selectionType) {
30
50
  case SelectionType.Group:
31
51
  return React.createElement(GroupComponent, Object.assign({}, props));
@@ -8,14 +8,16 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  });
9
9
  };
10
10
  import { NumericValueDiscrete, NumericValueRangeDefinition } from "@configura/web-api";
11
- import React, { useEffect, useState } from "react";
11
+ import React, { useContext, useEffect, useState } from "react";
12
12
  import { useRerender } from "../../useRerender.js";
13
13
  import { useUuid } from "../../useUniqueId.js";
14
+ import { ErrorContext } from "../ErrorContext.js";
14
15
  import { Checkmark } from "../icons/Checkmark.js";
15
16
  import { ErrorIcon } from "../icons/ErrorIcon.js";
16
17
  export const CfgOptionNumericView = (props) => {
17
18
  const { option } = props;
18
19
  const { isUseNumericValue } = option;
20
+ const setError = useContext(ErrorContext);
19
21
  // Contrary to most other components this one has its own connection to the
20
22
  // option that is backing it. This is for it to be able to "live" update
21
23
  // as we drag sliders. The value is not "commited" at immediate drag, and so
@@ -42,7 +44,12 @@ export const CfgOptionNumericView = (props) => {
42
44
  if (isSingleRange && ranges[0] instanceof NumericValueDiscrete) {
43
45
  return null;
44
46
  }
45
- return (React.createElement("ul", { className: `cfgOptionTree cfgOptionTree--subLevel cfgOptionTree--indent ${props.className || ""}`, style: props.style }, ranges.map((range) => (React.createElement(NumericValueView, { currentValue: numericValue, unit: unit, range: range, key: range.first, hasNoSiblings: isSingleRange, updateValue: (value, commit) => __awaiter(void 0, void 0, void 0, function* () { return yield option.setNumericValue(value, commit); }) })))));
47
+ return (React.createElement("ul", { className: `cfgOptionTree cfgOptionTree--subLevel cfgOptionTree--indent ${props.className || ""}`, style: props.style }, ranges.map((range) => (React.createElement(NumericValueView, { currentValue: numericValue, unit: unit, range: range, key: range.first, hasNoSiblings: isSingleRange, updateValue: (value, commit) => __awaiter(void 0, void 0, void 0, function* () {
48
+ return yield option.setNumericValue(value, commit).catch((e) => {
49
+ setError(e);
50
+ throw e;
51
+ });
52
+ }) })))));
46
53
  };
47
54
  /**
48
55
  * Displays GUI for selecting in one "range". Please note that the range
@@ -1,19 +1,23 @@
1
1
  import { CfgProduct, CfgProductConfiguration } from "@configura/web-api";
2
2
  import React from "react";
3
3
  import { CssProps } from "../../utilities.js";
4
- import { CfgProductConfigurationComponentAndPassthroughProps } from "./CfgFeatureView.js";
4
+ import { CfgProductConfigurationComponent } from "./CfgFeatureView.js";
5
5
  export declare enum UpchargeDisplayMode {
6
6
  SelectionImpact = 0,
7
7
  None = 1,
8
8
  Price = 2
9
9
  }
10
+ /**
11
+ * @param upchargeDisplayMode How upcharge on Options is displayed
12
+ * @param startOpen Setting this to true will make all selected options be expanded from start. This is bad for performance when viewing large products.
13
+ */
10
14
  export declare type PassthroughProps = {
11
15
  upchargeDisplayMode?: UpchargeDisplayMode;
16
+ startOpen?: boolean;
12
17
  };
13
- declare type Props = PassthroughProps & {
18
+ export declare type CfgProductConfigurationViewProps = PassthroughProps & Partial<CfgProductConfigurationComponent> & CssProps & {
14
19
  productOrConfiguration: CfgProductConfiguration | CfgProduct;
15
20
  permanentlyExpandedAdditionalProductLevels?: number;
16
21
  };
17
- export declare const CfgProductConfigurationView: React.FC<Props & CfgProductConfigurationComponentAndPassthroughProps & CssProps>;
18
- export {};
22
+ export declare const CfgProductConfigurationView: React.FC<CfgProductConfigurationViewProps>;
19
23
  //# sourceMappingURL=CfgProductConfigurationView.d.ts.map
@@ -1,8 +1,7 @@
1
1
  import { CfgProduct, CfgProductConfiguration } from "@configura/web-api";
2
2
  import React, { useEffect } from "react";
3
3
  import { useRerender } from "../../useRerender.js";
4
- import { CfgAdditionalProductView } from "./CfgAdditionalProductView.js";
5
- import { CfgFeatureViewMemo, forwardProps, } from "./CfgFeatureView.js";
4
+ import { CfgFeatureViewMemo, forwardProps, useCompleteWithDefaultProductConfigurationComponents, } from "./CfgFeatureView.js";
6
5
  export var UpchargeDisplayMode;
7
6
  (function (UpchargeDisplayMode) {
8
7
  UpchargeDisplayMode[UpchargeDisplayMode["SelectionImpact"] = 0] = "SelectionImpact";
@@ -10,11 +9,13 @@ export var UpchargeDisplayMode;
10
9
  UpchargeDisplayMode[UpchargeDisplayMode["Price"] = 2] = "Price";
11
10
  })(UpchargeDisplayMode || (UpchargeDisplayMode = {}));
12
11
  export const CfgProductConfigurationView = React.memo((props) => {
13
- const { productOrConfiguration, permanentlyExpandedAdditionalProductLevels, additionalProductComponent, } = props;
12
+ const completedProps = Object.assign(Object.assign({}, props), useCompleteWithDefaultProductConfigurationComponents(props));
13
+ const { productOrConfiguration, permanentlyExpandedAdditionalProductLevels, additionalProductComponent: AdditionalProductComponent, } = completedProps;
14
14
  const configuration = productOrConfiguration instanceof CfgProduct
15
15
  ? productOrConfiguration.configuration
16
16
  : productOrConfiguration;
17
- const configurationVisible = productOrConfiguration instanceof CfgProductConfiguration || productOrConfiguration.visible;
17
+ const configurationVisible = productOrConfiguration instanceof CfgProductConfiguration ||
18
+ productOrConfiguration.visible;
18
19
  const features = configuration.features.reduce((agg, feature) => {
19
20
  // It is possible in Cat Creator to double add a Feature. This fills no known
20
21
  // purpose and React can not handle this, so we filter out the duplicates.
@@ -27,7 +28,7 @@ export const CfgProductConfigurationView = React.memo((props) => {
27
28
  const additionalProducts = productOrConfiguration instanceof CfgProduct
28
29
  ? productOrConfiguration.additionalProducts
29
30
  : undefined;
30
- const AdditionalProductComponent = additionalProductComponent || CfgAdditionalProductView;
31
+ // const AdditionalProductComponent = additionalProductComponent || CfgAdditionalProductView;
31
32
  // Re-rendering is driven from the very top of the tree. However, when selecting an option
32
33
  // the change is not bubbled all the way to the top (and then down again) until after
33
34
  // validation has been done. This keeps the 3D-view from re-rendering until after validation
@@ -41,6 +42,6 @@ export const CfgProductConfigurationView = React.memo((props) => {
41
42
  };
42
43
  }, [configuration, rerender]);
43
44
  return (React.createElement(React.Fragment, null,
44
- configurationVisible && (React.createElement("ul", { className: `cfgOptionTree cfgOptionTree--topLevel ${props.className || ""}`, style: props.style }, features.map((f) => (React.createElement(CfgFeatureViewMemo, Object.assign({ feature: f, key: f.key }, forwardProps(props))))))),
45
- additionalProducts !== undefined && (React.createElement("ul", { className: `cfgOptionTree cfgOptionTree--topLevel` }, additionalProducts.map((additionalProduct) => (React.createElement(AdditionalProductComponent, Object.assign({ key: additionalProduct.key }, forwardProps(props), { additionalProductComponent: AdditionalProductComponent, product: additionalProduct, permanentlyExpandedLevels: permanentlyExpandedAdditionalProductLevels !== null && permanentlyExpandedAdditionalProductLevels !== void 0 ? permanentlyExpandedAdditionalProductLevels : 0 }))))))));
45
+ configurationVisible && (React.createElement("ul", { className: `cfgOptionTree cfgOptionTree--topLevel ${props.className || ""}`, style: props.style }, features.map((f) => (React.createElement(CfgFeatureViewMemo, Object.assign({ feature: f, key: f.key }, forwardProps(completedProps))))))),
46
+ additionalProducts !== undefined && (React.createElement("ul", { className: `cfgOptionTree cfgOptionTree--topLevel` }, additionalProducts.map((additionalProduct) => (React.createElement(AdditionalProductComponent, Object.assign({ key: additionalProduct.key }, forwardProps(completedProps), { product: additionalProduct, permanentlyExpandedLevels: permanentlyExpandedAdditionalProductLevels !== null && permanentlyExpandedAdditionalProductLevels !== void 0 ? permanentlyExpandedAdditionalProductLevels : 0 }))))))));
46
47
  });
package/dist/index.d.ts CHANGED
@@ -2,6 +2,7 @@ export * from "./components/CanvasWrapper.js";
2
2
  export * from "./components/Configurator.js";
3
3
  export * from "./components/ConfiguratorWrapper.js";
4
4
  export * from "./components/CurrencyPrice.js";
5
+ export * from "./components/ErrorContext.js";
5
6
  export * from "./components/ExpandableHeadingRow.js";
6
7
  export * from "./components/icons/Checkmark.js";
7
8
  export * from "./components/icons/Chevron.js";
package/dist/index.js CHANGED
@@ -2,6 +2,7 @@ export * from "./components/CanvasWrapper.js";
2
2
  export * from "./components/Configurator.js";
3
3
  export * from "./components/ConfiguratorWrapper.js";
4
4
  export * from "./components/CurrencyPrice.js";
5
+ export * from "./components/ErrorContext.js";
5
6
  export * from "./components/ExpandableHeadingRow.js";
6
7
  export * from "./components/icons/Checkmark.js";
7
8
  export * from "./components/icons/Chevron.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@configura/web-ui",
3
- "version": "1.6.1-alpha.7",
3
+ "version": "1.6.2",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -32,7 +32,7 @@
32
32
  ]
33
33
  },
34
34
  "dependencies": {
35
- "@configura/web-api": "1.6.1-alpha.7"
35
+ "@configura/web-api": "1.6.2"
36
36
  },
37
37
  "devDependencies": {
38
38
  "@babel/preset-env": "^7.14.4",
@@ -64,5 +64,5 @@
64
64
  "publishConfig": {
65
65
  "access": "public"
66
66
  },
67
- "gitHead": "b5ff49b200d294f18c4c0aff4f69b0296cff3cdf"
67
+ "gitHead": "7d15c3d75c39de15271da189ed1d0d5bfa719d79"
68
68
  }