@saasquatch/mint-components 1.3.2-12 → 1.3.2-16

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 (37) hide show
  1. package/dist/cjs/loader.cjs.js +1 -1
  2. package/dist/cjs/mint-components.cjs.js +1 -1
  3. package/dist/cjs/sqm-divided-layout_30.cjs.entry.js +365 -435
  4. package/dist/collection/components/sqm-portal-register/sqm-portal-register.js +1 -1
  5. package/dist/collection/components/sqm-reward-exchange-list/RewardExchangeListData.js +7 -2
  6. package/dist/collection/components/sqm-reward-exchange-list/sqm-reward-exchange-list-view.js +39 -35
  7. package/dist/collection/components/sqm-reward-exchange-list/sqm-reward-exchange-list.js +29 -7
  8. package/dist/collection/components/sqm-reward-exchange-list/useRewardExchangeList.js +7 -31
  9. package/dist/collection/components/sqm-stencilbook/sqm-stencilbook.js +0 -2
  10. package/dist/collection/components/sqm-task-card/TaskCard.stories.js +167 -222
  11. package/dist/collection/components/sqm-task-card/progress-bar/progress-bar-view.js +12 -5
  12. package/dist/collection/components/sqm-task-card/sqm-task-card-view.js +82 -50
  13. package/dist/collection/components/sqm-task-card/sqm-task-card.js +10 -2
  14. package/dist/esm/loader.js +1 -1
  15. package/dist/esm/mint-components.js +1 -1
  16. package/dist/esm/sqm-divided-layout_30.entry.js +365 -435
  17. package/dist/esm-es5/loader.js +1 -1
  18. package/dist/esm-es5/mint-components.js +1 -1
  19. package/dist/esm-es5/sqm-divided-layout_30.entry.js +1 -1
  20. package/dist/mint-components/mint-components.esm.js +1 -1
  21. package/dist/mint-components/p-0e35cbd8.system.entry.js +1 -0
  22. package/dist/mint-components/p-16f5a7cb.system.js +1 -1
  23. package/dist/mint-components/{p-d2e71fe0.entry.js → p-e6dbc0cc.entry.js} +10 -10
  24. package/dist/types/components/sqm-reward-exchange-list/RewardExchangeListData.d.ts +3 -2
  25. package/dist/types/components/sqm-reward-exchange-list/sqm-reward-exchange-list-view.d.ts +2 -2
  26. package/dist/types/components/sqm-reward-exchange-list/sqm-reward-exchange-list.d.ts +4 -0
  27. package/dist/types/components/sqm-reward-exchange-list/useRewardExchangeList.d.ts +1 -0
  28. package/dist/types/components/sqm-task-card/TaskCard.stories.d.ts +9 -4
  29. package/dist/types/components/sqm-task-card/progress-bar/progress-bar-view.d.ts +1 -0
  30. package/dist/types/components/sqm-task-card/sqm-task-card-view.d.ts +1 -1
  31. package/dist/types/components/sqm-task-card/sqm-task-card.d.ts +2 -1
  32. package/dist/types/components.d.ts +9 -1
  33. package/grapesjs/grapesjs.js +1 -1
  34. package/package.json +1 -1
  35. package/dist/collection/components/sqm-task-card/progress-bar/progress-bar.stories.js +0 -53
  36. package/dist/mint-components/p-b47179b8.system.entry.js +0 -1
  37. package/dist/types/components/sqm-task-card/progress-bar/progress-bar.stories.d.ts +0 -12
@@ -14799,7 +14799,6 @@ const EXCHANGE = dist.gql `
14799
14799
  `;
14800
14800
  function useRewardExchangeList(props) {
14801
14801
  var _a, _b, _c, _d;
14802
- const drawerRef = useRef();
14803
14802
  const [exchangeState, setExchangeState] = useReducer((state, next) => ({
14804
14803
  ...state,
14805
14804
  ...next,
@@ -14813,22 +14812,16 @@ function useRewardExchangeList(props) {
14813
14812
  const { selectedItem, selectedStep, redeemStage, amount, exchangeError } = exchangeState;
14814
14813
  const user = T$1();
14815
14814
  const [exchange, { data: exchangeResponse, errors }] = be(EXCHANGE);
14816
- const { data, loading } = en(GET_EXCHANGE_LIST, !(user === null || user === void 0 ? void 0 : user.jwt));
14815
+ const { data, loading, refetch } = en(GET_EXCHANGE_LIST, !(user === null || user === void 0 ? void 0 : user.jwt));
14817
14816
  useEffect(() => {
14818
14817
  var _a, _b;
14819
14818
  if ((_b = (_a = exchangeResponse === null || exchangeResponse === void 0 ? void 0 : exchangeResponse.exchangeReward) === null || _a === void 0 ? void 0 : _a.reward) === null || _b === void 0 ? void 0 : _b.id) {
14820
14819
  setExchangeState({ redeemStage: "success" });
14821
14820
  }
14822
14821
  if (!!errors) {
14823
- console.log("YEA");
14824
14822
  setExchangeState({ exchangeError: true });
14825
14823
  }
14826
14824
  }, [exchangeResponse, errors]);
14827
- function openDrawer() {
14828
- var _a;
14829
- setExchangeState({ redeemStage: "chooseReward" });
14830
- (_a = drawerRef.current) === null || _a === void 0 ? void 0 : _a.show();
14831
- }
14832
14825
  function exchangeReward() {
14833
14826
  if (!selectedItem)
14834
14827
  return;
@@ -14886,29 +14879,16 @@ function useRewardExchangeList(props) {
14886
14879
  }
14887
14880
  exchange({ exchangeRewardInput: exchangeVariables });
14888
14881
  }
14889
- const resetState = useCallback((e) => {
14890
- var _a, _b;
14891
- // selects also trigger an sl-hide event :(
14892
- //@ts-ignore - componentId is not private here
14893
- if (((_a = e === null || e === void 0 ? void 0 : e.target) === null || _a === void 0 ? void 0 : _a.componentId) !== ((_b = drawerRef.current) === null || _b === void 0 ? void 0 : _b.componentId))
14894
- return;
14882
+ const resetState = (refresh) => {
14883
+ refresh && refetch();
14895
14884
  setExchangeState({
14896
14885
  amount: 0,
14897
14886
  selectedStep: undefined,
14898
14887
  selectedItem: undefined,
14899
14888
  exchangeError: false,
14889
+ redeemStage: "chooseReward",
14900
14890
  });
14901
- }, []);
14902
- useEffect(() => {
14903
- if (!(drawerRef === null || drawerRef === void 0 ? void 0 : drawerRef.current))
14904
- return;
14905
- const drawer = drawerRef.current;
14906
- // Clear input value when drawer is closed
14907
- drawer.addEventListener("sl-hide", resetState);
14908
- return () => {
14909
- drawer.removeEventListener("sl-hide", resetState);
14910
- };
14911
- }, [drawerRef.current]);
14891
+ };
14912
14892
  function setStage(stage) {
14913
14893
  setExchangeState({ redeemStage: stage });
14914
14894
  }
@@ -14926,17 +14906,13 @@ function useRewardExchangeList(props) {
14926
14906
  },
14927
14907
  data: {
14928
14908
  exchangeList: (_b = (_a = data === null || data === void 0 ? void 0 : data.viewer) === null || _a === void 0 ? void 0 : _a.visibleRewardExchangeItems) === null || _b === void 0 ? void 0 : _b.data,
14929
- //@ts-ignore
14930
14909
  fuelTankCode: (_d = (_c = exchangeResponse === null || exchangeResponse === void 0 ? void 0 : exchangeResponse.exchangeReward) === null || _c === void 0 ? void 0 : _c.reward) === null || _d === void 0 ? void 0 : _d.fuelTankCode,
14931
14910
  },
14932
14911
  callbacks: {
14933
14912
  exchangeReward,
14934
- openDrawer,
14935
14913
  setExchangeState,
14936
14914
  setStage,
14937
- },
14938
- refs: {
14939
- drawerRef,
14915
+ resetState,
14940
14916
  },
14941
14917
  };
14942
14918
  }
@@ -15117,7 +15093,7 @@ function RewardExchangeView(props) {
15117
15093
  flexWrap: "wrap",
15118
15094
  margin: "var(--sl-spacing-medium) 0",
15119
15095
  "& .cancel": {
15120
- width: "150px",
15096
+ width: "20%",
15121
15097
  marginLeft: "auto",
15122
15098
  marginRight: "var(--sl-spacing-medium)",
15123
15099
  "&::part(base)": {
@@ -15126,7 +15102,7 @@ function RewardExchangeView(props) {
15126
15102
  },
15127
15103
  },
15128
15104
  "& .continue": {
15129
- width: "150px",
15105
+ width: "20%",
15130
15106
  "&::part(base)": {
15131
15107
  background: "var(--sl-color-neutral-500)",
15132
15108
  fontWeight: "var(--sl-font-weight-normal)",
@@ -15139,7 +15115,7 @@ function RewardExchangeView(props) {
15139
15115
  jss.setup(create());
15140
15116
  const sheet = jss.createStyleSheet(style);
15141
15117
  const styleString = sheet.toString();
15142
- const { states, data, callbacks, refs } = props;
15118
+ const { states, data, callbacks } = props;
15143
15119
  const { selectedItem, selectedStep } = states;
15144
15120
  function getInput() {
15145
15121
  var _a, _b;
@@ -15162,12 +15138,13 @@ function RewardExchangeView(props) {
15162
15138
  step.prettyDestinationValue,
15163
15139
  h("div", { slot: "suffix", style: { fontSize: "75%", float: "right" } },
15164
15140
  step.prettySourceValue,
15165
- step.unavailableReasonCode && (h("p", { style: { fontSize: "70%", color: "#F2994A" } }, step.unavailableReasonCode))))))));
15141
+ step.unavailableReasonCode && (h("p", { style: { fontSize: "70%", color: "#F2994A" } }, intl.formatMessage({
15142
+ id: "unavailableCode",
15143
+ defaultMessage: states.content.text.notAvailableError,
15144
+ }, { unavailableReason: step.unavailableReason || step.unavailableReasonCode })))))))));
15166
15145
  }
15167
15146
  function chooseReward() {
15168
15147
  var _a;
15169
- const nextStage = "chooseAmount";
15170
- // console.log({ nextStage, ruleType: selectedItem?.ruleType });
15171
15148
  return [
15172
15149
  h("div", { style: {
15173
15150
  display: "grid",
@@ -15217,13 +15194,14 @@ function RewardExchangeView(props) {
15217
15194
  fontSize: "70%",
15218
15195
  color: "#F2994A",
15219
15196
  marginTop: "0",
15220
- } }, item.unavailableReasonCode ===
15221
- "INSUFFICIENT_REDEEMABLE_CREDIT"
15222
- ? "Not enough points"
15223
- : item.unavailableReasonCode))))));
15197
+ } }, intl.formatMessage({
15198
+ id: "unavailableCode",
15199
+ defaultMessage: states.content.text.notAvailableError,
15200
+ }, { unavailableReason: item.unavailableReason || item.unavailableReasonCode })))))));
15224
15201
  })),
15225
15202
  h("div", { class: sheet.classes.KutayButton },
15226
- h("sl-button", { class: "continue", size: "large", onClick: () => callbacks.setStage(nextStage), disabled: !states.selectedItem }, "Continue")),
15203
+ h("sl-button", { class: "cancel", size: "large", type: "text" }, "Cancel"),
15204
+ h("sl-button", { class: "continue", size: "large", onClick: () => callbacks.setStage("chooseAmount"), disabled: !states.selectedItem }, "Continue")),
15227
15205
  ];
15228
15206
  }
15229
15207
  function chooseAmount() {
@@ -15233,13 +15211,10 @@ function RewardExchangeView(props) {
15233
15211
  h("p", null, selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.description),
15234
15212
  h("div", { class: sheet.classes.InputBox }, input),
15235
15213
  h("div", { class: sheet.classes.KutayButton },
15236
- h("sl-button", { class: "cancel", size: "large", type: "text", onClick: () => callbacks.setStage("chooseReward") }, "Cancel"),
15237
- h("sl-button", { class: "continue", size: "large", onClick: () => callbacks.setStage("confirmation"), disabled: states.selectedItem.ruleType !== "FIXED_GLOBAL_REWARD" ||
15238
- (input && !states.amount) }, "Continue to confirmation"))));
15214
+ h("sl-button", { class: "cancel", size: "large", type: "text", onClick: () => callbacks.resetState() }, "Cancel"),
15215
+ h("sl-button", { class: "continue", size: "large", onClick: () => callbacks.setStage("confirmation"), disabled: input && !states.amount }, "Continue to confirmation"))));
15239
15216
  }
15240
- // console.log({ selectedItem, selectedStep });
15241
15217
  function confirmation() {
15242
- const previousStage = "chooseAmount";
15243
15218
  return (h("div", null,
15244
15219
  h("h2", null, "Confirm and redeem"),
15245
15220
  h("div", { style: { textAlign: "center" } },
@@ -15259,13 +15234,14 @@ function RewardExchangeView(props) {
15259
15234
  h("p", { style: { marginBottom: "0", flex: "1" } }, selectedStep === null || selectedStep === void 0 ? void 0 : selectedStep.prettyDestinationValue)))),
15260
15235
  h("div", { class: sheet.classes.Buttons },
15261
15236
  h("sl-button", { onClick: callbacks.exchangeReward, style: { display: "block" }, class: sheet.classes.Button }, "Redeem"),
15262
- h("a", { onClick: () => callbacks.setStage(previousStage), style: { display: "block" }, class: sheet.classes.Button }, "Back"))));
15237
+ h("a", { onClick: () => callbacks.setStage("chooseAmount"), style: { display: "block" }, class: sheet.classes.Button }, "Back"))));
15263
15238
  }
15264
15239
  function success() {
15265
15240
  return (h("div", { style: { textAlign: "center" } },
15266
15241
  h("img", { class: sheet.classes.FullImage, src: getAssetPath("./assets/Reward-icon.png") }),
15267
15242
  h("p", { style: { color: "forestgreen" } }, "Reward Redeemed"),
15268
- (data === null || data === void 0 ? void 0 : data.fuelTankCode) && h("pre", null, data === null || data === void 0 ? void 0 : data.fuelTankCode)));
15243
+ (data === null || data === void 0 ? void 0 : data.fuelTankCode) && h("pre", null, data === null || data === void 0 ? void 0 : data.fuelTankCode),
15244
+ h("sl-button", { onClick: () => callbacks.resetState(true) }, "Done")));
15269
15245
  }
15270
15246
  const stages = {
15271
15247
  chooseReward: () => chooseReward(),
@@ -15287,7 +15263,25 @@ function RewardExchangeView(props) {
15287
15263
  })),
15288
15264
  h(ProgressBar, { stageCount: 3, currentStage: stageNumber })));
15289
15265
  }
15290
- console.log(props);
15266
+ // const BackButton = () => {
15267
+ // if (states.redeemStage === "success") return "";
15268
+ // let previousStage: Stages = "";
15269
+ // if (states.redeemStage === "confirmation") {
15270
+ // previousStage = "chooseAmount";
15271
+ // } else if (states.redeemStage === "chooseAmount") {
15272
+ // previousStage = "chooseReward";
15273
+ // }
15274
+ // return (
15275
+ // <div slot="label">
15276
+ // <a
15277
+ // style={{ cursor: "pointer", fontSize: "80%", color: "#858585" }}
15278
+ // onClick={() => callbacks.setStage(previousStage)}
15279
+ // >
15280
+ // <LeftArrow /> Back
15281
+ // </a>
15282
+ // </div>
15283
+ // );
15284
+ // };
15291
15285
  return (h("div", { class: sheet.classes.Container },
15292
15286
  h("style", { type: "text/css" }, styleString),
15293
15287
  h("div", null,
@@ -15305,6 +15299,10 @@ const SqmRewardExchangeList = class {
15305
15299
  * @uiName Exchange button text
15306
15300
  */
15307
15301
  this.buttonText = "Exchange Rewards";
15302
+ /**
15303
+ * @uiName Exchange button text
15304
+ */
15305
+ this.notAvailableError = "{unavailableReason, select, US_TAX {US Tax limit} INSUFFICIENT_REDEEMABLE_CREDIT {Not enough points} other {Not available} }";
15308
15306
  h$1(this);
15309
15307
  }
15310
15308
  disconnectedCallback() { }
@@ -15318,10 +15316,10 @@ const SqmRewardExchangeList = class {
15318
15316
  // if (missingProps) {
15319
15317
  // return <RequiredPropsError missingProps={missingProps} />;
15320
15318
  // }
15321
- const { states, data, callbacks, refs } = j$1()
15319
+ const { states, data, callbacks } = j$1()
15322
15320
  ? useRewardExchangeListDemo(getProps(this))
15323
15321
  : useRewardExchangeList(getProps(this));
15324
- return (h(Host, { style: { display: "contents" } }, h(RewardExchangeView, { states: states, data: data, callbacks: callbacks, refs: refs })));
15322
+ return (h(Host, { style: { display: "contents" } }, h(RewardExchangeView, { states: states, data: data, callbacks: callbacks })));
15325
15323
  }
15326
15324
  static get assetsDirs() { return ["assets"]; }
15327
15325
  };
@@ -15342,12 +15340,9 @@ function useRewardExchangeListDemo(props) {
15342
15340
  },
15343
15341
  callbacks: {
15344
15342
  exchangeReward: () => { },
15345
- openDrawer: () => { },
15346
15343
  setExchangeState: (_) => { },
15347
15344
  setStage: (_) => { },
15348
- },
15349
- refs: {
15350
- drawerRef: {},
15345
+ resetState: () => { },
15351
15346
  },
15352
15347
  }, props.demoData || {}, { arrayMerge: (_, a) => a });
15353
15348
  }
@@ -21030,6 +21025,69 @@ const PasswordField = /*#__PURE__*/Object.freeze({
21030
21025
  ValidationError: ValidationError
21031
21026
  });
21032
21027
 
21028
+ /**
21029
+ * Displays a cartesian product of the input props
21030
+ *
21031
+ * @returns
21032
+ */
21033
+ function MatrixStory({ matrix, props, Component, }) {
21034
+ const propMatrix = Object.keys(matrix).map((propKey) => {
21035
+ const propValues = matrix[propKey];
21036
+ return propValues.map((val) => {
21037
+ return {
21038
+ [propKey]: val,
21039
+ };
21040
+ });
21041
+ });
21042
+ const combinations = cartesian(...propMatrix);
21043
+ const propsCombinations = combinations.map((combo) => {
21044
+ return combo.reduce((props, prop) => {
21045
+ return {
21046
+ ...props,
21047
+ ...prop,
21048
+ };
21049
+ }, {});
21050
+ });
21051
+ return propsCombinations.map((combo) => {
21052
+ const example = { ...props, ...combo };
21053
+ return (h("div", null,
21054
+ h(PropsTable, { values: example }),
21055
+ h("hr", null),
21056
+ h(Component, Object.assign({}, example))));
21057
+ });
21058
+ }
21059
+ function PropsTable({ values }) {
21060
+ return (h("table", null,
21061
+ h("tbody", null, Object.keys(values).map((key) => {
21062
+ return (h("tr", null,
21063
+ h("th", null, key),
21064
+ h("td", null, JSON.stringify(values[key]))));
21065
+ }))));
21066
+ }
21067
+ /**
21068
+ * Source: https://stackoverflow.com/questions/15298912/javascript-generating-combinations-from-n-arrays-with-m-elements
21069
+ *
21070
+ * TODO: Could replace with a fork of https://www.npmjs.com/package/cartesian
21071
+ *
21072
+ * @param args - an array of arrays
21073
+ * @returns combinations of the elements in those array
21074
+ */
21075
+ function cartesian(...args) {
21076
+ var r = [], max = args.length - 1;
21077
+ function helper(arr, i) {
21078
+ for (var j = 0, l = args[i].length; j < l; j++) {
21079
+ var a = arr.slice(0); // clone arr
21080
+ a.push(args[i][j]);
21081
+ if (i == max)
21082
+ r.push(a);
21083
+ else
21084
+ helper(a, i + 1);
21085
+ }
21086
+ }
21087
+ helper([], 0);
21088
+ return r;
21089
+ }
21090
+
21033
21091
  const checkmark_circle = () => {
21034
21092
  return (h("svg", { xmlns: "http://www.w3.org/2000/svg", width: "18", height: "18", viewBox: "0 0 18 18" },
21035
21093
  h("path", { fill: "currentColor", "fill-rule": "evenodd", d: "M1.636 9a7.364 7.364 0 1114.728 0A7.364 7.364 0 011.636 9zM9 0a9 9 0 100 18A9 9 0 009 0zm5.192 6.266a.982.982 0 00-1.548-1.208l-4.787 6.137-2.58-2.58a.982.982 0 00-1.39 1.388l3.367 3.366a.982.982 0 001.468-.09l5.47-7.013z", "clip-rule": "evenodd" })));
@@ -21047,7 +21105,7 @@ const gift = () => {
21047
21105
  };
21048
21106
 
21049
21107
  function ProgressBarView(props) {
21050
- const { progress = 0, goal = 1, steps = false, progressBarUnit = "", repeatable = false, complete = false, } = props;
21108
+ const { progress = 0, goal = 1, steps = false, progressBarUnit = "", repeatable = false, complete = false, expired = false, } = props;
21051
21109
  console.log("progress bar props", props);
21052
21110
  const gift1 = gift();
21053
21111
  const gift2 = gift();
@@ -21076,7 +21134,10 @@ function ProgressBarView(props) {
21076
21134
  ProgressBar: {
21077
21135
  "& .progress-bar": {
21078
21136
  height: "15px",
21079
- marginTop: steps ? "var(--sl-spacing-x-medium)" : "var(--sl-spacing-large)",
21137
+ marginTop: steps
21138
+ ? "var(--sl-spacing-medium)"
21139
+ : "var(--sl-spacing-large)",
21140
+ filter: expired ? "grayscale(1)" : "",
21080
21141
  marginBottom: "var(--sl-spacing-xx-large)",
21081
21142
  marginRight: "var(--sl-spacing-x-small)",
21082
21143
  fontSize: "var(--sl-font-size-x-small)",
@@ -21094,7 +21155,9 @@ function ProgressBarView(props) {
21094
21155
  width: "100%",
21095
21156
  height: "4px",
21096
21157
  borderRadius: "4px",
21097
- backgroundColor: complete ? "var(--sl-color-success-500)" : "var(--sl-color-primary-500)",
21158
+ backgroundColor: complete
21159
+ ? "var(--sl-color-success-500)"
21160
+ : "var(--sl-color-primary-500)",
21098
21161
  },
21099
21162
  "& .progress": {
21100
21163
  display: "block",
@@ -21107,7 +21170,9 @@ function ProgressBarView(props) {
21107
21170
  width: "12px",
21108
21171
  height: "12px",
21109
21172
  display: "flex",
21110
- backgroundColor: complete ? "var(--sl-color-success-500)" : "var(--sl-color-primary-500)",
21173
+ backgroundColor: complete
21174
+ ? "var(--sl-color-success-500)"
21175
+ : "var(--sl-color-primary-500)",
21111
21176
  borderRadius: "50%",
21112
21177
  position: "relative",
21113
21178
  left: "47%",
@@ -21297,7 +21362,7 @@ function ProgressBarView(props) {
21297
21362
  }
21298
21363
  else {
21299
21364
  items.push(h("div", { class: "remain" }));
21300
- items.push(h("div", { class: "empty" }, progressBarUnit + i));
21365
+ items.push(h("div", { class: "empty" }, i));
21301
21366
  }
21302
21367
  }
21303
21368
  else if (i == goal) {
@@ -21355,7 +21420,6 @@ function ProgressBarView(props) {
21355
21420
  }
21356
21421
 
21357
21422
  function TaskCardView(props) {
21358
- const { rewardAmount, cardTitle, description, showProgressBar, progress = 0, goal, rewardUnit, repeatable, showExpiry, dateExpires, buttonText, buttonLink, loading, } = props;
21359
21423
  console.log({ props });
21360
21424
  const checkmark_circle$1 = checkmark_circle();
21361
21425
  const arrow_left_right$1 = arrow_left_right();
@@ -21369,16 +21433,28 @@ function TaskCardView(props) {
21369
21433
  position: "relative",
21370
21434
  boxSizing: "border-box",
21371
21435
  minWidth: "347px",
21372
- background: "var(--sl-color-white)",
21373
- border: "1px solid var(--sl-color-gray-300)",
21436
+ background: "var(--sl-color-neutral-0)",
21437
+ border: "1px solid var(--sl-color-neutral-300)",
21374
21438
  borderRadius: "var(--sl-border-radius-medium)",
21375
21439
  fontSize: "var(--sl-font-size-small)",
21376
21440
  lineHeight: "var(--sl-line-height-dense)",
21441
+ color: "var(--sl-color-neutral-600)",
21377
21442
  },
21378
21443
  "& .main.complete": {
21379
21444
  background: "var(--sl-color-success-50)",
21380
21445
  borderColor: "var(--sl-color-success-700)",
21381
21446
  },
21447
+ "& .main.expired": {
21448
+ color: "var(--sl-color-neutral-400)",
21449
+ background: "var(--sl-color-neutral-100)",
21450
+ },
21451
+ "& .title": {
21452
+ fontSize: "var(--sl-font-size-small)",
21453
+ fontWeight: "var(--sl-font-weight-semibold)",
21454
+ },
21455
+ "& .black": {
21456
+ color: "var(--sl-color-neutral-1000)",
21457
+ },
21382
21458
  },
21383
21459
  Header: {
21384
21460
  display: "flex",
@@ -21391,7 +21467,6 @@ function TaskCardView(props) {
21391
21467
  },
21392
21468
  "& .value": {
21393
21469
  alignSelf: "center",
21394
- color: "var(--sl-color-black)",
21395
21470
  fontSize: "var(--sl-font-size-x-large)",
21396
21471
  fontWeight: "var(--sl-font-weight-semibold)",
21397
21472
  lineHeight: "100%",
@@ -21400,16 +21475,21 @@ function TaskCardView(props) {
21400
21475
  "& .text": {
21401
21476
  alignSelf: "end",
21402
21477
  textTransform: "uppercase",
21403
- color: "var(--sl-color-gray-600)",
21404
21478
  fontSize: "var(--sl-font-size-x-small)",
21405
21479
  lineHeight: "var(--sl-font-size-medium)",
21406
21480
  marginRight: "var(--sl-spacing-xx-small)",
21407
21481
  },
21408
- },
21409
- Title: {
21410
- color: "var(--sl-color-black)",
21411
- fontSize: "var(--sl-font-size-small)",
21412
- fontWeight: "var(--sl-font-weight-semibold)",
21482
+ "& .end": {
21483
+ color: "var(--sl-color-warning-600)",
21484
+ fontWeight: "var(--sl-font-weight-semibold)",
21485
+ marginBottom: "var(--sl-spacing-xx-small)",
21486
+ },
21487
+ "& .black": {
21488
+ color: "var(--sl-color-neutral-1000)",
21489
+ },
21490
+ "& .neutral": {
21491
+ color: "var(--sl-color-neutral-400)",
21492
+ },
21413
21493
  },
21414
21494
  Footer: {
21415
21495
  display: "flex",
@@ -21421,58 +21501,69 @@ function TaskCardView(props) {
21421
21501
  marginTop: "auto",
21422
21502
  verticalAlign: "text-bottom",
21423
21503
  fontSize: "var(--sl-font-size-x-small)",
21424
- color: "var(--sl-color-gray-600)",
21425
21504
  },
21426
21505
  "& .success": {
21427
- color: "var(--sl-color-success-600)!important",
21506
+ color: "var(--sl-color-success-600)",
21428
21507
  fontWeight: "var(--sl-font-weight-semibold)",
21429
21508
  },
21430
21509
  "& .action": {
21431
21510
  marginTop: "auto",
21432
21511
  marginLeft: "auto",
21512
+ "&::part(base)": {
21513
+ color: "var(--sl-color-neutral-0)",
21514
+ borderRadius: "var(--sl-border-radius-medium)",
21515
+ },
21516
+ "&.disabled::part(base)": {
21517
+ border: "1px solid var(--sl-color-neutral-400)",
21518
+ background: "var(--sl-color-neutral-400)",
21519
+ },
21433
21520
  },
21434
- "& sl-button.action::part(base) ": {
21435
- color: "var(--sl-color-white)",
21436
- background: "var(--sl-color-primary-500)",
21437
- border: "1px solid var(--sl-color-primary-500)",
21438
- borderRadius: "var(--sl-border-radius-medium)",
21439
- },
21440
- "& sl-button.action.completed::part(base) ": {
21441
- border: "1px solid var(--sl-color-gray-300)!important",
21442
- background: "var(--sl-color-gray-300)!important",
21521
+ "& .neutral": {
21522
+ color: "var(--sl-color-neutral-400)",
21443
21523
  },
21444
21524
  },
21445
21525
  };
21446
21526
  jss.setup(create());
21447
21527
  const sheet = jss.createStyleSheet(style);
21448
21528
  const styleString = sheet.toString();
21449
- const showComplete = progress >= goal;
21450
- const repetitions = showProgressBar ? Math.floor(progress / goal) : progress;
21451
- const taskComplete = showComplete && repeatable === false;
21452
- console.log({ showProgressBar, loading });
21529
+ const showComplete = props.progress >= props.goal;
21530
+ const repetitions = props.showProgressBar
21531
+ ? Math.floor(props.progress / props.goal)
21532
+ : props.progress;
21533
+ const taskComplete = showComplete && props.repeatable === false;
21534
+ const dateExpire = props.showExpiry && luxon.DateTime.fromISO(props.dateExpires.split("/").pop());
21535
+ const taskExpired = props.showExpiry && luxon.DateTime.now() > dateExpire;
21536
+ const dateExpireText = dateExpire.toLocaleString(luxon.DateTime.DATE_FULL);
21537
+ console.log(taskExpired);
21453
21538
  return (h("div", { class: sheet.classes.TaskCard },
21454
- h("div", { class: showComplete ? "main complete" : "main" },
21539
+ h("div", { class: taskExpired ? "main expired" : taskComplete ? "main complete" : "main" },
21455
21540
  h("style", { type: "text/css" }, styleString),
21456
- h("div", { class: sheet.classes.Header },
21457
- showComplete && h("span", { class: "icon" }, checkmark_circle$1),
21458
- h("span", { class: "value" }, rewardAmount),
21459
- h("span", { class: "text" }, rewardUnit)),
21460
- h("div", { class: sheet.classes.Title }, cardTitle),
21461
- h(Details, { description: description }),
21462
- showProgressBar && loading ? (h("sl-skeleton", { style: { width: "98%", margin: "0 auto" } })) : (showProgressBar && h(ProgressBarView, Object.assign({}, props, { complete: taskComplete }))),
21463
- h("div", { class: sheet.classes.Footer },
21541
+ h("div", { class: sheet.classes.Header }, props.loading ? (h("sl-skeleton", { style: { width: "22%", margin: "0" } })) : (h("div", null,
21542
+ taskExpired && (h("div", { class: "end" },
21543
+ " ",
21544
+ "Ended " + dateExpireText,
21545
+ " ")),
21546
+ showComplete && (h("span", { class: taskExpired ? "icon neutral" : "icon" }, checkmark_circle$1)),
21547
+ h("span", { class: taskExpired ? "value" : "value black" }, props.rewardAmount),
21548
+ h("span", { class: "text" }, props.rewardUnit)))),
21549
+ props.loading ? (h("sl-skeleton", { style: { width: "42%", margin: "0 16px" } })) : (h("div", { class: taskExpired ? "title" : "title black" }, props.cardTitle)),
21550
+ props.loading ? (h("sl-skeleton", { style: { margin: "12px 16px" } })) : (h(Details, Object.assign({}, props))),
21551
+ props.showProgressBar && props.loading ? (h("sl-skeleton", { style: { margin: "0 16px" } })) : (props.showProgressBar && (h(ProgressBarView, Object.assign({}, props, { complete: taskComplete, expired: taskExpired })))),
21552
+ h("div", { class: sheet.classes.Footer }, props.loading ? (h("sl-skeleton", { style: { width: "25%", marginLeft: "auto" } })) : (h("div", { style: { display: "contents" } },
21464
21553
  h("span", { class: "text" },
21465
- repeatable && (h("div", null,
21466
- h("span", { class: repetitions > 0 ? "icon success" : "icon" }, arrow_left_right$1),
21467
- h("span", { class: repetitions > 0 ? "success" : "" },
21468
- "Completed ",
21469
- repetitions,
21470
- " times"))),
21471
- showExpiry && (h("span", null,
21472
- "Ends ",
21473
- " ",
21474
- dateExpires))),
21475
- h("sl-button", { class: taskComplete ? "action completed" : "action", size: "small", onClick: () => window.open(buttonLink), disabled: taskComplete }, buttonText)))));
21554
+ props.repeatable && (h("div", null,
21555
+ h("span", { class: repetitions > 0
21556
+ ? taskExpired
21557
+ ? "icon neutral"
21558
+ : "icon success"
21559
+ : "icon" }, arrow_left_right$1),
21560
+ h("span", { class: repetitions > 0
21561
+ ? taskExpired
21562
+ ? "neutral"
21563
+ : "success"
21564
+ : "" }, "Completed " + repetitions + " times"))),
21565
+ props.showExpiry && !taskExpired && (h("span", null, "Ends " + dateExpireText))),
21566
+ h("sl-button", { class: taskComplete || taskExpired ? "action disabled" : "action", type: "primary", size: "small", onClick: () => window.open(props.buttonLink), disabled: taskComplete || taskExpired }, props.buttonText)))))));
21476
21567
  }
21477
21568
  function Details(props) {
21478
21569
  const style = {
@@ -21487,7 +21578,7 @@ function Details(props) {
21487
21578
  position: "absolute",
21488
21579
  top: "var(--sl-spacing-medium)",
21489
21580
  right: "var(--sl-spacing-medium)",
21490
- color: "var(--sl-color-gray-700)",
21581
+ color: "var(--sl-color-neutral-700)",
21491
21582
  fontSize: "var(--sl-font-size-large)",
21492
21583
  "& :hover": {
21493
21584
  color: "var(--sl-color-primary-700)",
@@ -21496,16 +21587,21 @@ function Details(props) {
21496
21587
  transition: "transform var(--sl-transition-medium) ease",
21497
21588
  },
21498
21589
  "& input:checked ~ .summary": {
21499
- transition: "max-height var(--sl-transition-medium) ease",
21590
+ transition: "all var(--sl-transition-medium) ease",
21500
21591
  maxHeight: "300px",
21592
+ marginBottom: props.steps
21593
+ ? "var(--sl-spacing-large)"
21594
+ : props.showProgressBar
21595
+ ? "var(--sl-spacing-xx-large)"
21596
+ : "var(--sl-spacing-large)",
21501
21597
  },
21502
21598
  "& .summary": {
21503
21599
  display: "block",
21504
21600
  overflow: "hidden",
21505
- color: "var(--sl-color-gray-700)",
21506
- fontSize: "var(--sl-font-size-x-small)",
21601
+ fontSize: "var(--sl-font-size-small)",
21507
21602
  maxHeight: "0px",
21508
- transition: "max-height var(--sl-transition-fast) ease-out",
21603
+ transition: "all var(--sl-transition-fast) ease-out",
21604
+ marginBottom: "var(--sl-spacing-medium)",
21509
21605
  },
21510
21606
  },
21511
21607
  };
@@ -21522,14 +21618,21 @@ function Details(props) {
21522
21618
  h("span", { class: "summary" }, props.description))));
21523
21619
  }
21524
21620
 
21525
- const scenario$5 = "@author:derek\r\n@owner:\r\nFeature: Task Card\r\n\r\n\tScenario: A header, body title, description and a CTA button are always displayed\r\n\t\tGiven the Task Card is configured with the following props\r\n\t\t\t| prop | value |\r\n\t\t\t| rewardAmount | \"40\" |\r\n\t\t\t| rewardUnit | \"Points\" |\r\n\t\t\t| cardTitle | Complete a survey |\r\n\t\t\t| description | Fill out our survey form and receive points! |\r\n\t\t\t| buttonText | Take Survey |\r\n\t\t\t| buttonLink | https://example.com/ |\r\n\t\tWhen a user views the Task Card\r\n\t\tThen they see \"40 Points\" as the heading\r\n\t\tAnd the \"40\" is bolded\r\n\t\tAnd they see \"Complete a survey\" bolded in the body\r\n\t\tAnd a details icon in the top right hand corner\r\n\t\tAnd a button with text \"Take Survey\" in the bottom right hand corner\r\n\t\tWhen they click the button\r\n\t\tThen they are redirected to \"example.com\" in a new window\r\n\t\tWhen they click the details icon\r\n\t\tThen \"Fill out our survey form and receive points!\" is shown as the card description\r\n\r\n\tScenario: A loading state is displayed while the Task Card is loading\r\n\t\tGiven a Task Card component\r\n\t\tWhen a user views the Task Card\r\n\t\tThen a loading state is displayed\r\n\t\tWhen the Task Card has loaded\r\n\t\tThen the loading state disapears\r\n\r\n\tScenario Outline: The Progress Bar can be shown or hidden but is hidden by default\r\n\t\tGiven a Task Card component\r\n\t\tAnd it <mayHave> \"showProgressBar\" <value>\r\n\t\tWhen a user views the Task Card\r\n\t\tThen the progress bar <mayBe> displayed\r\n\t\tExamples:\r\n\t\t\t| mayHave | value | mayBe |\r\n\t\t\t| has | true | is |\r\n\t\t\t| has | false | isn't |\r\n\t\t\t| doesn't have | | isn't |\r\n\r\n\tScenario Outline: Tasks can be repeatable or one-time only but are one-time only be default\r\n\t\tGiven a Task Card component\r\n\t\tAnd it <mayHave> \"repeatable\" <value>\r\n\t\tAnd a user who has already completed the task\r\n\t\tWhen they views the Task Card\r\n\t\tThen they see a green checkmark icon beside the card heading\r\n\t\tAnd the card <mayBe> green\r\n\t\tAnd the card's border <mayBe> green\r\n\t\tAnd the CTA button <mayBe> disabled\r\n\t\tAnd the CTA button <mayBe> grey\r\n\t\tExamples:\r\n\t\t\t| mayHave | value | mayBe |\r\n\t\t\t| has | true | isn't |\r\n\t\t\t| has | false | is |\r\n\t\t\t| doesn't have | | is |\r\n\r\n\tScenario: Task Expiries can be configured and disable the CTA after the expiry\r\n\t\tGiven a Task Card component\r\n\t\tAnd it is configured for <expiry>\r\n\t\tWhen a user views the Card on <day>\r\n\t\tThen they the expiry on <cardLocation>\r\n\t\tAnd the text <mayBe> orange\r\n\t\tAnd the card <mayBe> disabled\r\n\t\tAnd the card <mayBe> grey\r\n\t\tAnd the user <mayBe> unable to complete the loyalty task\r\n\t\tExamples:\r\n\t\t\t| expiry | day | cardLocation | mayBe |\r\n\t\t\t| Dec 31 2021 11:59:59 | Dec 1st 2021 12:00:00 | bottom left | isn't |\r\n\t\t\t| Dec 31 2021 11:59:59 | Dec 31 2021 11:00:00 | top right | isn't |\r\n\t\t\t| Dec 31 2021 11:59:59 | Jan 15th 2022 10:00:00 | top right | is |\r\n\r\n\tScenario Outline: Task expiry can be hidden or shown but is hidden by default\r\n\t\tGiven a Task Card\r\n\t\tAnd it is configured with an expiry\r\n\t\tAnd it <mayHave> \"showExpiry\" <value>\r\n\t\tWhen a user views the Task card\r\n\t\tThen the expiry <mayBe> shown in the bottom left hand corner\r\n\t\tExamples:\r\n\t\t\t| mayHave | value | mayBe |\r\n\t\t\t| has | true | is |\r\n\t\t\t| has | false | isn't |\r\n\t\t\t| doesn't have | | isn't |\r\n\r\n\t#DS: Currently this text is non configurable and isnt set up for proper pluralization\r\n\tScenario Outline: A task completion count is displayed for repeatable tasks\r\n\t\tGiven a Task Card is configured for a repeatable task\r\n\t\tAnd has \"goalCompletionNumber\" <goalCompletionNumberValue>\r\n\t\tAnd a user with <userGoalProgress>\r\n\t\tWhen the user views the task card\r\n\t\tThen they see a repeat icon\r\n\t\tAnd the <text> in the bottom left hand corner\r\n\t\tAnd the <text> is green\r\n\t\tExamples:\r\n\t\t\t| goalCompletionNumber | userGoalProgress | text |\r\n\t\t\t| 1 | 0 | Completed 0 times |\r\n\t\t\t| 1 | 1 | Completed 1 times |\r\n\t\t\t| 1 | 2 | Completed 2 times |\r\n\t\t\t| 10 | 5 | Completed 0 times |\r\n\t\t\t| 10 | 12 | Completed 1 times |\r\n\t\t\t| 10 | 29 | Completed 2 times |\r\n\r\n\tScenario Outline: The source of a user's progress can be a custom field or a program goal\r\n\t\tGiven a Task Card is configured to have <progressSourcePath> progress source\r\n\t\tAnd a user\r\n\t\tWhen they view the Task card\r\n\t\tThen the value at <progressSourcePath> is used to benchmark their progress against the Goal Completion Count\r\n\t\tExamples:\r\n\t\t\t| value |\r\n\t\t\t| /customFields/activityCount |\r\n\t\t\t| /customFields/purchaseTotal |\r\n\t\t\t| /programGoals/count%2FComment-on-Article |\r\n\t\t\t| /programGoals/count/Referral-Started%2Freferrals |\r\n\r\n\tScenario Outline: The users completion of a goal is calculated by the Goal Completion Number\r\n\t\tGiven a Task Card is configured to have <goalValue>\r\n\t\tAnd a user who has <progressValue>\r\n\t\tWhen they view the Task Card\r\n\t\tThen they are shown to have <progressValue> towards <goalValue>\r\n\t\tWhen their progress grows larger than <goalValue>\r\n\t\tThen the task is marked as completed\r\n\t\tExamples:\r\n\t\t\t| goalValue | progressValue |\r\n\t\t\t| 1 | 0 |\r\n\t\t\t| 10 | 9 |\r\n\t\t\t| 5 | 2 |\r\n\r\n\tScenario: The Goal Completion Number defaults to 1\r\n\t\tGiven a Task Card without a configured \"goalCompletionNumber\"\r\n\t\tAnd a user who has <progressValue>\r\n\t\tWhen they view the Task Card\r\n\t\tThen it <mayBe> marked as completed\r\n\t\tExamples:\r\n\t\t\t| progressValue | mayBe |\r\n\t\t\t| 0 | isn't |\r\n\t\t\t| 1 | is |\r\n\t\t\t| 2 | is |";
21621
+ const scenarioTaskCard = "@author:derek\r\n@owner:\r\nFeature: Task Card\r\n\r\n\tScenario: A header, body title, description and a CTA button are always displayed\r\n\t\tGiven the Task Card is configured with the following props\r\n\t\t\t| prop | value |\r\n\t\t\t| rewardAmount | \"40\" |\r\n\t\t\t| rewardUnit | \"Points\" |\r\n\t\t\t| cardTitle | Complete a survey |\r\n\t\t\t| description | Fill out our survey form and receive points! |\r\n\t\t\t| buttonText | Take Survey |\r\n\t\t\t| buttonLink | https://example.com/ |\r\n\t\tWhen a user views the Task Card\r\n\t\tThen they see \"40 Points\" as the heading\r\n\t\tAnd the \"40\" is bolded\r\n\t\tAnd they see \"Complete a survey\" bolded in the body\r\n\t\tAnd a details icon in the top right hand corner\r\n\t\tAnd a button with text \"Take Survey\" in the bottom right hand corner\r\n\t\tWhen they click the button\r\n\t\tThen they are redirected to \"example.com\" in a new window\r\n\t\tWhen they click the details icon\r\n\t\tThen \"Fill out our survey form and receive points!\" is shown as the card description\r\n\r\n\tScenario: A loading state is displayed while the Task Card is loading\r\n\t\tGiven a Task Card component\r\n\t\tWhen a user views the Task Card\r\n\t\tThen a loading state is displayed\r\n\t\tWhen the Task Card has loaded\r\n\t\tThen the loading state disapears\r\n\r\n\tScenario Outline: The Progress Bar can be shown or hidden but is hidden by default\r\n\t\tGiven a Task Card component\r\n\t\tAnd it <mayHave> \"showProgressBar\" <value>\r\n\t\tWhen a user views the Task Card\r\n\t\tThen the progress bar <mayBe> displayed\r\n\t\tExamples:\r\n\t\t\t| mayHave | value | mayBe |\r\n\t\t\t| has | true | is |\r\n\t\t\t| has | false | isn't |\r\n\t\t\t| doesn't have | | isn't |\r\n\r\n\tScenario Outline: Tasks can be repeatable or one-time only but are one-time only be default\r\n\t\tGiven a Task Card component\r\n\t\tAnd it <mayHave> \"repeatable\" <value>\r\n\t\tAnd a user who has already completed the task\r\n\t\tWhen they views the Task Card\r\n\t\tThen they see a green checkmark icon beside the card heading\r\n\t\tAnd the card <mayBe> green\r\n\t\tAnd the card's border <mayBe> green\r\n\t\tAnd the CTA button <mayBe> disabled\r\n\t\tAnd the CTA button <mayBe> grey\r\n\t\tExamples:\r\n\t\t\t| mayHave | value | mayBe |\r\n\t\t\t| has | true | isn't |\r\n\t\t\t| has | false | is |\r\n\t\t\t| doesn't have | | is |\r\n\r\n\tScenario: Task Expiries can be configured and disable the CTA after the expiry\r\n\t\tGiven a Task Card component\r\n\t\tAnd it is configured for <expiry>\r\n\t\tWhen a user views the Card on <day>\r\n\t\tThen they the expiry on <cardLocation>\r\n\t\tAnd the text <mayBe> orange\r\n\t\tAnd the card <mayBe> disabled\r\n\t\tAnd the card <mayBe> grey\r\n\t\tAnd the user <mayBe> unable to complete the loyalty task\r\n\t\tExamples:\r\n\t\t\t| expiry | day | cardLocation | mayBe |\r\n\t\t\t| Dec 31 2021 11:59:59 | Dec 1st 2021 12:00:00 | bottom left | isn't |\r\n\t\t\t| Dec 31 2021 11:59:59 | Dec 31 2021 11:00:00 | top right | isn't |\r\n\t\t\t| Dec 31 2021 11:59:59 | Jan 15th 2022 10:00:00 | top right | is |\r\n\r\n\tScenario Outline: Task expiry can be hidden or shown but is hidden by default\r\n\t\tGiven a Task Card\r\n\t\tAnd it is configured with an expiry\r\n\t\tAnd it <mayHave> \"showExpiry\" <value>\r\n\t\tWhen a user views the Task card\r\n\t\tThen the expiry <mayBe> shown in the bottom left hand corner\r\n\t\tExamples:\r\n\t\t\t| mayHave | value | mayBe |\r\n\t\t\t| has | true | is |\r\n\t\t\t| has | false | isn't |\r\n\t\t\t| doesn't have | | isn't |\r\n\r\n\t#DS: Currently this text is non configurable and isnt set up for proper pluralization\r\n\tScenario Outline: A task completion count is displayed for repeatable tasks\r\n\t\tGiven a Task Card is configured for a repeatable task\r\n\t\tAnd has \"goalCompletionNumber\" <goalCompletionNumberValue>\r\n\t\tAnd a user with <userGoalProgress>\r\n\t\tWhen the user views the task card\r\n\t\tThen they see a repeat icon\r\n\t\tAnd the <text> in the bottom left hand corner\r\n\t\tAnd the <text> is green\r\n\t\tExamples:\r\n\t\t\t| goalCompletionNumber | userGoalProgress | text |\r\n\t\t\t| 1 | 0 | Completed 0 times |\r\n\t\t\t| 1 | 1 | Completed 1 times |\r\n\t\t\t| 1 | 2 | Completed 2 times |\r\n\t\t\t| 10 | 5 | Completed 0 times |\r\n\t\t\t| 10 | 12 | Completed 1 times |\r\n\t\t\t| 10 | 29 | Completed 2 times |\r\n\r\n\tScenario Outline: The source of a user's progress can be a custom field or a program goal\r\n\t\tGiven a Task Card is configured to have <progressSourcePath> progress source\r\n\t\tAnd a user\r\n\t\tWhen they view the Task card\r\n\t\tThen the value at <progressSourcePath> is used to benchmark their progress against the Goal Completion Count\r\n\t\tExamples:\r\n\t\t\t| value |\r\n\t\t\t| /customFields/activityCount |\r\n\t\t\t| /customFields/purchaseTotal |\r\n\t\t\t| /programGoals/count%2FComment-on-Article |\r\n\t\t\t| /programGoals/count/Referral-Started%2Freferrals |\r\n\r\n\tScenario Outline: The users completion of a goal is calculated by the Goal Completion Number\r\n\t\tGiven a Task Card is configured to have <goalValue>\r\n\t\tAnd a user who has <progressValue>\r\n\t\tWhen they view the Task Card\r\n\t\tThen they are shown to have <progressValue> towards <goalValue>\r\n\t\tWhen their progress grows larger than <goalValue>\r\n\t\tThen the task is marked as completed\r\n\t\tExamples:\r\n\t\t\t| goalValue | progressValue |\r\n\t\t\t| 1 | 0 |\r\n\t\t\t| 10 | 9 |\r\n\t\t\t| 5 | 2 |\r\n\r\n\tScenario: The Goal Completion Number defaults to 1\r\n\t\tGiven a Task Card without a configured \"goalCompletionNumber\"\r\n\t\tAnd a user who has <progressValue>\r\n\t\tWhen they view the Task Card\r\n\t\tThen it <mayBe> marked as completed\r\n\t\tExamples:\r\n\t\t\t| progressValue | mayBe |\r\n\t\t\t| 0 | isn't |\r\n\t\t\t| 1 | is |\r\n\t\t\t| 2 | is |";
21622
+
21623
+ const scenarioProgressBar = "@author:\r\n@owner:\r\nFeature: Task Card Progress Bar\r\n\r\n\tScenario Outline: Progress Bar\r\n\r\n\t\tGiven <progress> and <goal>\r\n\t\tThen I have <progressBar>\r\n\t\tAnd <progressBar> shows <progress> with <unit> above\r\n\t\tAnd gift icon has <color>\r\n\t\tAnd gift icon shows <goal> with <unit> below\r\n\r\n\t\tExamples:\r\n\t\t\t| progress | goal | progressBar | unit | color |\r\n\t\t\t| -100 | 500 | ●――――――――――――――――――🎁 | $ | no |\r\n\t\t\t| 0 | 500 | ●――――――――――――――――――🎁 | $ | no |\r\n\t\t\t| 250 | 500 | ―――――――――●―――――――――🎁 | $ | no |\r\n\t\t\t| 500 | 500 | ―――――――――――――――――――🎁 | $ | yes |\r\n\t\t\t| 1000 | 500 | ―――――――――――――――――――🎁 | $ | yes |\r\n\r\n\tScenario Outline: Progress Bar Steps\r\n\r\n\t\tGiven <progress> and <goal>\r\n\t\tAnd steps is enabled\r\n\t\tThen I have <progressBar>\r\n\t\tAnd <progressBar> has incrementing steps from 1 to <goal>\r\n\t\tAnd gift icon has <color>\r\n\t\tAnd gift icon shows <goal> below\r\n\r\n\t\tExamples:\r\n\t\t\t| progress | goal | progressBar | color |\r\n\t\t\t| -1 | 5 | ―――○―――○―――○―――○―――🎁 | no |\r\n\t\t\t| 0 | 5 | ―――○―――○―――○―――○―――🎁 | no |\r\n\t\t\t| 1 | 5 | ―――●―――○―――○―――○―――🎁 | no |\r\n\t\t\t| 5 | 5 | ―――○―――○―――○―――●―――🎁 | yes |\r\n\t\t\t| 7 | 5 | ―――○―――○―――○―――●―――🎁 | yes |\r\n\r\n\r\n\tScenario Outline: Progress Bar Repeatable\r\n\r\n\t\tGiven <progress> and <goal>\r\n\t\tThen I have <progressBar>\r\n\t\tAnd <progressBar> shows <progress> with <unit> above\r\n\t\tAnd <icon1> has <color1>\r\n\t\tAnd <icon2> has <color2>\r\n\t\tAnd <icon3> has <color3>\r\n\t\tAnd <icon1> shows <text1> below\r\n\t\tAnd <icon2> shows <text2> below\r\n\t\tAnd <icon3> shows <text3> below\r\n\r\n\t\tExamples:\r\n\t\t\t| progress | goal | progressBar | unit | icon1 | icon2 | icon3 | color1 | color2 | color3 | text 1 | text 2 | text 3 |\r\n\t\t\t| 250 | 500 | ――――●――――🎁―――――――🎁 | $ | NA | gift | gift | NA | no | no | NA | 500 | 1000 |\r\n\t\t\t| 500 | 500 | ―――――――――🎁―――――――🎁 | $ | NA | gift | gift | NA | yes | no | NA | 500 | 1000 |\r\n\t\t\t| 750 | 500 | ―――――――――🎁―――●―――🎁 | $ | NA | gift | gift | NA | yes | no | NA | 500 | 1000 |\r\n\t\t\t| 1000 | 500 | 🎁―――――――🎁―――――――🎁 | $ | gift | gift | gift | yes | yes | no | 500 | 1000 | 1500 |\r\n\t\t\t| 1250 | 500 | 🎁―――――――🎁―――●―――🎁 | $ | gift | gift | gift | yes | yes | no | 500 | 1000 | 1500 |\r\n\r\n\t# \t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t math logic inside text ?\r\n\t# | 1250 | 500 | 🎁―――――――🎁―――●―――🎁 | gift | gift | gift | yes | yes | no | goal * (⌊ progress / goal ⌋ - 1) | goal * ⌊ progress / goal ⌋ | goal * (⌊ progress / goal ⌋ +1) |\r\n\r\n\r\n\tScenario Outline: Progress Bar Steps Repeatable\r\n\r\n\t\tGiven <progress> and <goal>\r\n\t\tAnd steps is enabled\r\n\t\tThen I have <progressBar>\r\n\t\tAnd <progressBar> has incrementing steps\r\n\r\n\t\tExamples:\r\n\t\t\t| progress | goal | progressBar |";
21526
21624
 
21625
+ const scenario$5 = scenarioTaskCard + scenarioProgressBar;
21527
21626
  const TaskCard_stories = {
21528
21627
  title: "Components/Task Card/",
21529
21628
  parameters: {
21530
21629
  scenario: scenario$5,
21531
21630
  },
21532
21631
  };
21632
+ const storyFrame = {
21633
+ display: "inline-flex",
21634
+ gap: "32px",
21635
+ };
21533
21636
  const resizable = {
21534
21637
  width: "347px",
21535
21638
  minWidth: "347px",
@@ -21537,49 +21640,55 @@ const resizable = {
21537
21640
  height: "fit-content",
21538
21641
  overflow: "hidden",
21539
21642
  };
21540
- const NotRepeatable = () => {
21541
- const oneAction = {
21542
- rewardAmount: 20,
21543
- showExpiry: false,
21544
- rewardUnit: "Points",
21545
- cardTitle: "Complete a survey",
21546
- repeatable: false,
21547
- description: "Description of action and reward. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut eget quisque commodo leo.",
21548
- buttonText: "Take survey",
21549
- goal: 1,
21550
- buttonLink: "https://example.com/",
21551
- showProgressBar: false,
21552
- loading: false,
21553
- };
21554
- const coupleActions = {
21555
- rewardAmount: 40,
21556
- rewardUnit: "Points",
21557
- cardTitle: "Comment on 5 articles",
21558
- showProgressBar: true,
21559
- showExpiry: false,
21560
- goal: 5,
21561
- repeatable: false,
21562
- steps: true,
21563
- description: "Description of action and reward. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut eget quisque commodo leo.",
21564
- buttonText: "Start reading",
21565
- buttonLink: "https://example.com/",
21566
- loading: false,
21567
- };
21568
- const manyActions = {
21569
- rewardAmount: 150,
21570
- rewardUnit: "Points",
21571
- cardTitle: "Spend $500 at our Store",
21572
- showProgressBar: true,
21573
- showExpiry: false,
21574
- goal: 500,
21575
- repeatable: false,
21576
- progressBarUnit: "$",
21577
- description: "Description of action and reward. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut eget quisque commodo leo.",
21578
- buttonText: "Visit our Store",
21579
- buttonLink: "https://example.com/",
21580
- loading: false,
21581
- };
21582
- return (h("div", { style: { display: "inline-flex", gap: "32px" } },
21643
+ const oneAction = {
21644
+ rewardAmount: 20,
21645
+ rewardUnit: "Points",
21646
+ cardTitle: "Complete a survey",
21647
+ description: "Description of action and reward. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut eget quisque commodo leo.",
21648
+ repeatable: false,
21649
+ showProgressBar: false,
21650
+ progress: 0,
21651
+ goal: 1,
21652
+ buttonText: "Take survey",
21653
+ buttonLink: "https://example.com/",
21654
+ showExpiry: false,
21655
+ dateExpires: null,
21656
+ loading: false,
21657
+ };
21658
+ const coupleActions = {
21659
+ rewardAmount: 40,
21660
+ rewardUnit: "Points",
21661
+ cardTitle: "Comment on 5 articles",
21662
+ description: "Description of action and reward. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut eget quisque commodo leo.",
21663
+ repeatable: false,
21664
+ showProgressBar: true,
21665
+ steps: true,
21666
+ progress: 1,
21667
+ goal: 5,
21668
+ buttonText: "Take survey",
21669
+ buttonLink: "https://example.com/",
21670
+ showExpiry: false,
21671
+ dateExpires: null,
21672
+ loading: false,
21673
+ };
21674
+ const manyActions = {
21675
+ rewardAmount: 150,
21676
+ rewardUnit: "Points",
21677
+ cardTitle: "Spend $500 at our Store",
21678
+ description: "Description of action and reward. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut eget quisque commodo leo.",
21679
+ repeatable: false,
21680
+ showProgressBar: true,
21681
+ progress: 100,
21682
+ goal: 500,
21683
+ progressBarUnit: "$",
21684
+ buttonText: "Take survey",
21685
+ buttonLink: "https://example.com/",
21686
+ showExpiry: false,
21687
+ dateExpires: null,
21688
+ loading: false,
21689
+ };
21690
+ const TaskCardNotRepeatable = () => {
21691
+ return (h("div", { style: storyFrame },
21583
21692
  h("div", { style: resizable },
21584
21693
  h("h4", null, "One Action"),
21585
21694
  h(TaskCardView, Object.assign({}, oneAction, { progress: 0 })),
@@ -21590,9 +21699,6 @@ const NotRepeatable = () => {
21590
21699
  h("h5", null)),
21591
21700
  h("div", { style: resizable },
21592
21701
  h("h4", null, "A Couple Actions"),
21593
- h(TaskCardView, Object.assign({}, coupleActions, { progress: 0 })),
21594
- " ",
21595
- h("h5", null),
21596
21702
  h(TaskCardView, Object.assign({}, coupleActions, { progress: 1 })),
21597
21703
  " ",
21598
21704
  h("h5", null),
@@ -21601,9 +21707,6 @@ const NotRepeatable = () => {
21601
21707
  h("h5", null)),
21602
21708
  h("div", { style: resizable },
21603
21709
  h("h4", null, "Many Actions"),
21604
- h(TaskCardView, Object.assign({}, manyActions, { progress: 0 })),
21605
- " ",
21606
- h("h5", null),
21607
21710
  h(TaskCardView, Object.assign({}, manyActions, { progress: 230 })),
21608
21711
  " ",
21609
21712
  h("h5", null),
@@ -21611,329 +21714,142 @@ const NotRepeatable = () => {
21611
21714
  " ",
21612
21715
  h("h5", null))));
21613
21716
  };
21614
- const NotRepeatableWithExpiry = () => {
21615
- const oneAction = {
21616
- rewardAmount: 20,
21617
- rewardUnit: "Points",
21618
- cardTitle: "Complete a survey",
21619
- description: "Description of action and reward. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut eget quisque commodo leo.",
21620
- buttonText: "Take survey",
21621
- goal: 1,
21622
- showExpiry: true,
21623
- repeatable: false,
21624
- dateExpires: "Nov 1, 2021",
21625
- buttonLink: "https://example.com/",
21626
- showProgressBar: false,
21627
- loading: false,
21628
- };
21629
- const coupleActions = {
21630
- rewardAmount: 40,
21631
- rewardUnit: "Points",
21632
- cardTitle: "Comment on 5 articles",
21633
- showProgressBar: true,
21634
- goal: 5,
21635
- steps: true,
21636
- description: "Description of action and reward. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut eget quisque commodo leo.",
21637
- buttonText: "Start reading",
21638
- showExpiry: true,
21639
- repeatable: false,
21640
- dateExpires: "Nov 1, 2021",
21641
- buttonLink: "https://example.com/",
21642
- loading: false,
21643
- };
21644
- const manyActions = {
21645
- rewardAmount: 150,
21646
- rewardUnit: "Points",
21647
- repeatable: false,
21648
- cardTitle: "Spend $500 at our Store",
21649
- showProgressBar: true,
21650
- goal: 500,
21651
- progressBarUnit: "$",
21652
- description: "Description of action and reward. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut eget quisque commodo leo.",
21653
- buttonText: "Visit our Store",
21654
- showExpiry: true,
21655
- dateExpires: "Nov 1, 2021",
21656
- buttonLink: "https://example.com/",
21657
- loading: false,
21658
- };
21659
- return (h("div", { style: { display: "inline-flex", gap: "32px" } },
21717
+ const TaskCardRepeatable = () => {
21718
+ return (h("div", { style: storyFrame },
21660
21719
  h("div", { style: resizable },
21661
21720
  h("h4", null, "One Action"),
21662
- h(TaskCardView, Object.assign({}, oneAction, { progress: 0 })),
21721
+ h(TaskCardView, Object.assign({}, oneAction, { progress: 0, repeatable: true })),
21663
21722
  " ",
21664
21723
  h("h5", null),
21665
- h(TaskCardView, Object.assign({}, oneAction, { progress: 1 })),
21724
+ h(TaskCardView, Object.assign({}, oneAction, { progress: 1, repeatable: true })),
21666
21725
  " ",
21667
21726
  h("h5", null)),
21668
21727
  h("div", { style: resizable },
21669
21728
  h("h4", null, "A Couple Actions"),
21670
- h(TaskCardView, Object.assign({}, coupleActions, { progress: 0 })),
21671
- " ",
21729
+ h(TaskCardView, Object.assign({}, coupleActions, { progress: 1, repeatable: true })),
21672
21730
  h("h5", null),
21673
- h(TaskCardView, Object.assign({}, coupleActions, { progress: 1 })),
21674
- " ",
21731
+ h(TaskCardView, Object.assign({}, coupleActions, { progress: 5, repeatable: true })),
21675
21732
  h("h5", null),
21676
- h(TaskCardView, Object.assign({}, coupleActions, { progress: 5 })),
21677
- " ",
21733
+ h(TaskCardView, Object.assign({}, coupleActions, { progress: 7, repeatable: true })),
21734
+ h("h5", null),
21735
+ h(TaskCardView, Object.assign({}, coupleActions, { progress: 10, repeatable: true })),
21678
21736
  h("h5", null)),
21679
21737
  h("div", { style: resizable },
21680
21738
  h("h4", null, "Many Actions"),
21681
- h(TaskCardView, Object.assign({}, manyActions, { progress: 0 })),
21682
- " ",
21739
+ h(TaskCardView, Object.assign({}, manyActions, { progress: 100, repeatable: true })),
21683
21740
  h("h5", null),
21684
- h(TaskCardView, Object.assign({}, manyActions, { progress: 230 })),
21685
- " ",
21741
+ h(TaskCardView, Object.assign({}, manyActions, { progress: 500, repeatable: true })),
21686
21742
  h("h5", null),
21687
- h(TaskCardView, Object.assign({}, manyActions, { progress: 500 })),
21688
- " ",
21743
+ h(TaskCardView, Object.assign({}, manyActions, { progress: 650, repeatable: true })),
21744
+ h("h5", null),
21745
+ h(TaskCardView, Object.assign({}, manyActions, { progress: 1000, repeatable: true })),
21689
21746
  h("h5", null))));
21690
21747
  };
21691
- const Repeatable = () => {
21692
- const oneAction = {
21693
- rewardAmount: 20,
21694
- rewardUnit: "Points",
21695
- showExpiry: false,
21696
- cardTitle: "Complete a survey",
21697
- description: "Description of action and reward. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut eget quisque commodo leo.",
21698
- buttonText: "Take survey",
21699
- goal: 1,
21700
- repeatable: true,
21701
- buttonLink: "https://example.com/",
21702
- showProgressBar: false,
21703
- loading: false,
21704
- };
21705
- const coupleActions = {
21706
- rewardAmount: 40,
21707
- rewardUnit: "Points",
21708
- showExpiry: false,
21709
- cardTitle: "Comment on 5 articles",
21710
- showProgressBar: true,
21711
- repeatable: true,
21712
- goal: 5,
21713
- steps: true,
21714
- description: "Description of action and reward. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut eget quisque commodo leo.",
21715
- buttonText: "Start reading",
21716
- buttonLink: "https://example.com/",
21717
- loading: false,
21718
- };
21719
- const manyActions = {
21720
- rewardAmount: 150,
21721
- rewardUnit: "Points",
21722
- showExpiry: false,
21723
- cardTitle: "Spend $500 at our Store",
21724
- showProgressBar: true,
21725
- repeatable: true,
21726
- goal: 500,
21727
- progressBarUnit: "$",
21728
- description: "Description of action and reward. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut eget quisque commodo leo.",
21729
- buttonText: "Visit our Store",
21730
- buttonLink: "https://example.com/",
21731
- loading: false,
21748
+ const TaskCardDateExpires = () => {
21749
+ const expire = {
21750
+ showExpiry: true,
21751
+ dateExpires: "2021-12-01T08:00:00.000Z/2077-12-01T08:00:00.000Z",
21732
21752
  };
21733
- return (h("div", { style: { display: "inline-flex", gap: "32px" } },
21753
+ const expireRepeat = { ...expire, repeatable: true };
21754
+ return (h("div", { style: storyFrame },
21734
21755
  h("div", { style: resizable },
21735
21756
  h("h4", null, "One Action"),
21736
- h(TaskCardView, Object.assign({}, oneAction, { progress: 0 })),
21757
+ h(TaskCardView, Object.assign({}, oneAction, expire)),
21737
21758
  " ",
21738
21759
  h("h5", null),
21739
- h(TaskCardView, Object.assign({}, oneAction, { progress: 1 })),
21760
+ h(TaskCardView, Object.assign({}, oneAction, expireRepeat)),
21740
21761
  " ",
21741
21762
  h("h5", null)),
21742
21763
  h("div", { style: resizable },
21743
21764
  h("h4", null, "A Couple Actions"),
21744
- h(TaskCardView, Object.assign({}, coupleActions, { progress: 1 })),
21765
+ h(TaskCardView, Object.assign({}, coupleActions, expire)),
21745
21766
  " ",
21746
21767
  h("h5", null),
21747
- h(TaskCardView, Object.assign({}, coupleActions, { progress: 5 })),
21768
+ h(TaskCardView, Object.assign({}, coupleActions, expireRepeat)),
21769
+ " ",
21770
+ h("h5", null)),
21771
+ h("div", { style: resizable },
21772
+ h("h4", null, "Many Actions"),
21773
+ h(TaskCardView, Object.assign({}, manyActions, expire)),
21748
21774
  " ",
21749
21775
  h("h5", null),
21750
- h(TaskCardView, Object.assign({}, coupleActions, { progress: 7 })),
21776
+ h(TaskCardView, Object.assign({}, manyActions, expireRepeat)),
21777
+ " ",
21778
+ h("h5", null))));
21779
+ };
21780
+ const TaskCardLoading = () => {
21781
+ const loading = { loading: true };
21782
+ return (h("div", { style: storyFrame },
21783
+ h("div", { style: resizable },
21784
+ h("h4", null, "One Action"),
21785
+ h(TaskCardView, Object.assign({}, oneAction, loading)),
21751
21786
  " ",
21752
21787
  h("h5", null),
21753
- h(TaskCardView, Object.assign({}, coupleActions, { progress: 10 })),
21788
+ h(TaskCardView, Object.assign({}, oneAction, loading)),
21754
21789
  " ",
21755
21790
  h("h5", null)),
21756
21791
  h("div", { style: resizable },
21757
- h("h4", null, "Many Actions"),
21758
- h(TaskCardView, Object.assign({}, manyActions, { progress: 100 })),
21792
+ h("h4", null, "A Couple Actions"),
21793
+ h(TaskCardView, Object.assign({}, coupleActions, loading)),
21759
21794
  " ",
21760
21795
  h("h5", null),
21761
- h(TaskCardView, Object.assign({}, manyActions, { progress: 500 })),
21796
+ h(TaskCardView, Object.assign({}, coupleActions, loading)),
21762
21797
  " ",
21763
- h("h5", null),
21764
- h(TaskCardView, Object.assign({}, manyActions, { progress: 650 })),
21798
+ h("h5", null)),
21799
+ h("div", { style: resizable },
21800
+ h("h4", null, "Many Actions"),
21801
+ h(TaskCardView, Object.assign({}, manyActions, loading)),
21765
21802
  " ",
21766
21803
  h("h5", null),
21767
- h(TaskCardView, Object.assign({}, manyActions, { progress: 1000 })),
21804
+ h(TaskCardView, Object.assign({}, manyActions, loading)),
21768
21805
  " ",
21769
21806
  h("h5", null))));
21770
21807
  };
21771
- const RepeatableWithExpiry = () => {
21772
- const oneAction = {
21773
- rewardAmount: 20,
21774
- rewardUnit: "Points",
21775
- cardTitle: "Complete a survey",
21776
- description: "Description of action and reward. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut eget quisque commodo leo.",
21777
- buttonText: "Take survey",
21778
- goal: 1,
21779
- repeatable: true,
21808
+ const TaskCardExpired = () => {
21809
+ const expire = {
21780
21810
  showExpiry: true,
21781
- dateExpires: "Nov 1, 2021",
21782
- buttonLink: "https://example.com/",
21783
- showProgressBar: false,
21784
- loading: false,
21811
+ dateExpires: "2021-12-01T08:00:00.000Z/2021-12-01T08:00:00.000Z",
21785
21812
  };
21786
- const coupleActions = {
21787
- rewardAmount: 40,
21788
- rewardUnit: "Points",
21789
- cardTitle: "Comment on 5 articles",
21790
- showProgressBar: true,
21791
- repeatable: true,
21792
- goal: 5,
21793
- steps: true,
21794
- description: "Description of action and reward. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut eget quisque commodo leo.",
21795
- buttonText: "Start reading",
21796
- showExpiry: true,
21797
- dateExpires: "Nov 1, 2021",
21798
- buttonLink: "https://example.com/",
21799
- loading: false,
21800
- };
21801
- const manyActions = {
21802
- rewardAmount: 150,
21803
- rewardUnit: "Points",
21804
- cardTitle: "Spend $500 at our Store",
21805
- showProgressBar: true,
21806
- repeatable: true,
21807
- goal: 500,
21808
- progressBarUnit: "$",
21809
- description: "Description of action and reward. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut eget quisque commodo leo.",
21810
- buttonText: "Visit our Store",
21811
- showExpiry: true,
21812
- dateExpires: "Nov 1, 2021",
21813
- buttonLink: "https://example.com/",
21814
- loading: false,
21815
- };
21816
- return (h("div", { style: { display: "inline-flex", gap: "32px" } },
21813
+ const expireRepeat = { ...expire, repeatable: true };
21814
+ return (h("div", { style: storyFrame },
21817
21815
  h("div", { style: resizable },
21818
21816
  h("h4", null, "One Action"),
21819
- h(TaskCardView, Object.assign({}, oneAction, { progress: 0 })),
21817
+ h(TaskCardView, Object.assign({}, oneAction, { progress: 0 }, expire)),
21820
21818
  " ",
21821
21819
  h("h5", null),
21822
- h(TaskCardView, Object.assign({}, oneAction, { progress: 1 })),
21820
+ h(TaskCardView, Object.assign({}, oneAction, { progress: 1 }, expire)),
21821
+ " ",
21822
+ h("h5", null),
21823
+ h(TaskCardView, Object.assign({}, oneAction, { progress: 0 }, expireRepeat)),
21824
+ " ",
21825
+ h("h5", null),
21826
+ h(TaskCardView, Object.assign({}, oneAction, { progress: 1 }, expireRepeat)),
21823
21827
  " ",
21824
21828
  h("h5", null)),
21825
21829
  h("div", { style: resizable },
21826
21830
  h("h4", null, "A Couple Actions"),
21827
- h(TaskCardView, Object.assign({}, coupleActions, { progress: 1 })),
21831
+ h(TaskCardView, Object.assign({}, coupleActions, { progress: 1 }, expire)),
21828
21832
  " ",
21829
21833
  h("h5", null),
21830
- h(TaskCardView, Object.assign({}, coupleActions, { progress: 5 })),
21834
+ h(TaskCardView, Object.assign({}, coupleActions, { progress: 5 }, expire)),
21831
21835
  " ",
21832
21836
  h("h5", null),
21833
- h(TaskCardView, Object.assign({}, coupleActions, { progress: 7 })),
21834
- " ",
21837
+ h(TaskCardView, Object.assign({}, coupleActions, { progress: 1 }, expireRepeat)),
21835
21838
  h("h5", null),
21836
- h(TaskCardView, Object.assign({}, coupleActions, { progress: 10 })),
21837
- " ",
21839
+ h(TaskCardView, Object.assign({}, coupleActions, { progress: 5 }, expireRepeat)),
21838
21840
  h("h5", null)),
21839
21841
  h("div", { style: resizable },
21840
21842
  h("h4", null, "Many Actions"),
21841
- h(TaskCardView, Object.assign({}, manyActions, { progress: 100 })),
21843
+ h(TaskCardView, Object.assign({}, manyActions, { progress: 100 }, expire)),
21842
21844
  " ",
21843
21845
  h("h5", null),
21844
- h(TaskCardView, Object.assign({}, manyActions, { progress: 500 })),
21846
+ h(TaskCardView, Object.assign({}, manyActions, { progress: 500 }, expire)),
21845
21847
  " ",
21846
21848
  h("h5", null),
21847
- h(TaskCardView, Object.assign({}, manyActions, { progress: 650 })),
21848
- " ",
21849
+ h(TaskCardView, Object.assign({}, manyActions, { progress: 100 }, expireRepeat)),
21849
21850
  h("h5", null),
21850
- h(TaskCardView, Object.assign({}, manyActions, { progress: 1000 })),
21851
- " ",
21851
+ h(TaskCardView, Object.assign({}, manyActions, { progress: 500 }, expireRepeat)),
21852
21852
  h("h5", null))));
21853
- };
21854
-
21855
- const TaskCard$1 = /*#__PURE__*/Object.freeze({
21856
- __proto__: null,
21857
- 'default': TaskCard_stories,
21858
- NotRepeatable: NotRepeatable,
21859
- NotRepeatableWithExpiry: NotRepeatableWithExpiry,
21860
- Repeatable: Repeatable,
21861
- RepeatableWithExpiry: RepeatableWithExpiry
21862
- });
21863
-
21864
- /**
21865
- * Displays a cartesian product of the input props
21866
- *
21867
- * @returns
21868
- */
21869
- function MatrixStory({ matrix, props, Component, }) {
21870
- const propMatrix = Object.keys(matrix).map((propKey) => {
21871
- const propValues = matrix[propKey];
21872
- return propValues.map((val) => {
21873
- return {
21874
- [propKey]: val,
21875
- };
21876
- });
21877
- });
21878
- const combinations = cartesian(...propMatrix);
21879
- const propsCombinations = combinations.map((combo) => {
21880
- return combo.reduce((props, prop) => {
21881
- return {
21882
- ...props,
21883
- ...prop,
21884
- };
21885
- }, {});
21886
- });
21887
- return propsCombinations.map((combo) => {
21888
- const example = { ...props, ...combo };
21889
- return (h("div", null,
21890
- h(PropsTable, { values: example }),
21891
- h("hr", null),
21892
- h(Component, Object.assign({}, example))));
21893
- });
21894
- }
21895
- function PropsTable({ values }) {
21896
- return (h("table", null,
21897
- h("tbody", null, Object.keys(values).map((key) => {
21898
- return (h("tr", null,
21899
- h("th", null, key),
21900
- h("td", null, JSON.stringify(values[key]))));
21901
- }))));
21902
- }
21903
- /**
21904
- * Source: https://stackoverflow.com/questions/15298912/javascript-generating-combinations-from-n-arrays-with-m-elements
21905
- *
21906
- * TODO: Could replace with a fork of https://www.npmjs.com/package/cartesian
21907
- *
21908
- * @param args - an array of arrays
21909
- * @returns combinations of the elements in those array
21910
- */
21911
- function cartesian(...args) {
21912
- var r = [], max = args.length - 1;
21913
- function helper(arr, i) {
21914
- for (var j = 0, l = args[i].length; j < l; j++) {
21915
- var a = arr.slice(0); // clone arr
21916
- a.push(args[i][j]);
21917
- if (i == max)
21918
- r.push(a);
21919
- else
21920
- helper(a, i + 1);
21921
- }
21922
- }
21923
- helper([], 0);
21924
- return r;
21925
- }
21926
-
21927
- const scenario$6 = "@author:\r\n@owner:\r\nFeature: Task Card Progress Bar\r\n\r\n\tScenario Outline: Progress Bar\r\n\r\n\t\tGiven <progress> and <goal>\r\n\t\tThen I have <progressBar>\r\n\t\tAnd <progressBar> shows <progress> with <unit> above\r\n\t\tAnd gift icon has <color>\r\n\t\tAnd gift icon shows <goal> with <unit> below\r\n\r\n\t\tExamples:\r\n\t\t\t| progress | goal | progressBar | unit | color |\r\n\t\t\t| -100 | 500 | ●――――――――――――――――――🎁 | $ | no |\r\n\t\t\t| 0 | 500 | ●――――――――――――――――――🎁 | $ | no |\r\n\t\t\t| 250 | 500 | ―――――――――●―――――――――🎁 | $ | no |\r\n\t\t\t| 500 | 500 | ―――――――――――――――――――🎁 | $ | yes |\r\n\t\t\t| 1000 | 500 | ―――――――――――――――――――🎁 | $ | yes |\r\n\r\n\tScenario Outline: Progress Bar Steps\r\n\r\n\t\tGiven <progress> and <goal>\r\n\t\tAnd steps is enabled\r\n\t\tThen I have <progressBar>\r\n\t\tAnd <progressBar> has incrementing steps from 1 to <goal>\r\n\t\tAnd gift icon has <color>\r\n\t\tAnd gift icon shows <goal> below\r\n\r\n\t\tExamples:\r\n\t\t\t| progress | goal | progressBar | color |\r\n\t\t\t| -1 | 5 | ―――○―――○―――○―――○―――🎁 | no |\r\n\t\t\t| 0 | 5 | ―――○―――○―――○―――○―――🎁 | no |\r\n\t\t\t| 1 | 5 | ―――●―――○―――○―――○―――🎁 | no |\r\n\t\t\t| 5 | 5 | ―――○―――○―――○―――●―――🎁 | yes |\r\n\t\t\t| 7 | 5 | ―――○―――○―――○―――●―――🎁 | yes |\r\n\r\n\r\n\tScenario Outline: Progress Bar Repeatable\r\n\r\n\t\tGiven <progress> and <goal>\r\n\t\tThen I have <progressBar>\r\n\t\tAnd <progressBar> shows <progress> with <unit> above\r\n\t\tAnd <icon1> has <color1>\r\n\t\tAnd <icon2> has <color2>\r\n\t\tAnd <icon3> has <color3>\r\n\t\tAnd <icon1> shows <text1> below\r\n\t\tAnd <icon2> shows <text2> below\r\n\t\tAnd <icon3> shows <text3> below\r\n\r\n\t\tExamples:\r\n\t\t\t| progress | goal | progressBar | unit | icon1 | icon2 | icon3 | color1 | color2 | color3 | text 1 | text 2 | text 3 |\r\n\t\t\t| 250 | 500 | ――――●――――🎁―――――――🎁 | $ | NA | gift | gift | NA | no | no | NA | 500 | 1000 |\r\n\t\t\t| 500 | 500 | ―――――――――🎁―――――――🎁 | $ | NA | gift | gift | NA | yes | no | NA | 500 | 1000 |\r\n\t\t\t| 750 | 500 | ―――――――――🎁―――●―――🎁 | $ | NA | gift | gift | NA | yes | no | NA | 500 | 1000 |\r\n\t\t\t| 1000 | 500 | 🎁―――――――🎁―――――――🎁 | $ | gift | gift | gift | yes | yes | no | 500 | 1000 | 1500 |\r\n\t\t\t| 1250 | 500 | 🎁―――――――🎁―――●―――🎁 | $ | gift | gift | gift | yes | yes | no | 500 | 1000 | 1500 |\r\n\r\n\t# \t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t math logic inside text ?\r\n\t# | 1250 | 500 | 🎁―――――――🎁―――●―――🎁 | gift | gift | gift | yes | yes | no | goal * (⌊ progress / goal ⌋ - 1) | goal * ⌊ progress / goal ⌋ | goal * (⌊ progress / goal ⌋ +1) |\r\n\r\n\r\n\tScenario Outline: Progress Bar Steps Repeatable\r\n\r\n\t\tGiven <progress> and <goal>\r\n\t\tAnd steps is enabled\r\n\t\tThen I have <progressBar>\r\n\t\tAnd <progressBar> has incrementing steps\r\n\r\n\t\tExamples:\r\n\t\t\t| progress | goal | progressBar |";
21928
-
21929
- const progressBar_stories = {
21930
- title: "Components/Task Card Progress Bar",
21931
- parameters: {
21932
- scenario: scenario$6,
21933
- },
21934
- };
21935
- const Default$a = () => {
21936
- return h(ProgressBarView, null);
21937
21853
  };
21938
21854
  const ProgressBar$1 = () => {
21939
21855
  const props = {
@@ -21976,10 +21892,14 @@ const ProgressBarStepsRepeatable = () => {
21976
21892
  h(MatrixStory, { matrix: { progress: [1, 5, 7, 12] }, props: props, Component: ProgressBarView })));
21977
21893
  };
21978
21894
 
21979
- const TaskCardProgressBar = /*#__PURE__*/Object.freeze({
21895
+ const TaskCard$1 = /*#__PURE__*/Object.freeze({
21980
21896
  __proto__: null,
21981
- 'default': progressBar_stories,
21982
- Default: Default$a,
21897
+ 'default': TaskCard_stories,
21898
+ TaskCardNotRepeatable: TaskCardNotRepeatable,
21899
+ TaskCardRepeatable: TaskCardRepeatable,
21900
+ TaskCardDateExpires: TaskCardDateExpires,
21901
+ TaskCardLoading: TaskCardLoading,
21902
+ TaskCardExpired: TaskCardExpired,
21983
21903
  ProgressBar: ProgressBar$1,
21984
21904
  ProgressBarSteps: ProgressBarSteps,
21985
21905
  ProgressBarRepeatable: ProgressBarRepeatable,
@@ -24998,7 +24918,7 @@ const ReferralIframeReadme = "# sqm-referral-iframe\r\n\r\n\r\n\r\n<!-- Auto Gen
24998
24918
 
24999
24919
  const ForgotPasswordReadme = "# sqm-portal-forgot-password\r\n\r\n\r\n\r\n<!-- Auto Generated Below -->\r\n\r\n\r\n## Properties\r\n\r\n| Property | Attribute | Description | Type | Default |\r\n| ------------- | -------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------- |\r\n| `demoData` | -- | | `{ states?: { error: string; loading: boolean; success: boolean; }; content?: { secondaryButton: any; messageSlot: any; emailLabel?: string; submitLabel?: string; }; }` | `undefined` |\r\n| `emailLabel` | `email-label` | | `string` | `\"Email\"` |\r\n| `submitLabel` | `submit-label` | | `string` | `\"Request Password Reset\"` |\r\n\r\n\r\n## Dependencies\r\n\r\n### Depends on\r\n\r\n- [sqm-form-message](../sqm-form-message)\r\n\r\n### Graph\r\n```mermaid\r\ngraph TD;\r\n sqm-portal-forgot-password --> sqm-form-message\r\n style sqm-portal-forgot-password fill:#f9f,stroke:#333,stroke-width:4px\r\n```\r\n\r\n----------------------------------------------\r\n\r\n*Built with [StencilJS](https://stenciljs.com/)*\r\n";
25000
24920
 
25001
- const RegisterReadme = "# sqm-portal-register\r\n\r\n\r\n\r\n<!-- Auto Generated Below -->\r\n\r\n\r\n## Properties\r\n\r\n| Property | Attribute | Description | Type | Default |\r\n| -------------------------- | ---------------------------- | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- |\r\n| `confirmPassword` | `confirm-password` | | `boolean` | `false` |\r\n| `confirmPasswordLabel` | `confirm-password-label` | | `string` | `\"Confirm Password\"` |\r\n| `demoData` | -- | | `{ states?: { error: string; loading: boolean; confirmPassword: boolean; hideInputs: boolean; validationState?: FormState; enablePasswordValidation?: boolean; }; refs?: { formRef: any; }; content?: { formData?: any; passwordField?: any; secondaryButton?: any; emailLabel?: string; passwordLabel?: string; submitLabel?: string; pageLabel?: string; confirmPasswordLabel: string; }; }` | `undefined` |\r\n| `emailLabel` | `email-label` | | `string` | `\"Email\"` |\r\n| `enablePasswordValidation` | `enable-password-validation` | | `boolean` | `true` |\r\n| `hideInputs` | `hide-inputs` | | `boolean` | `false` |\r\n| `loginLabel` | `login-label` | | `string` | `\"Sign in\"` |\r\n| `nextPage` | `next-page` | | `string` | `\"/\"` |\r\n| `pageLabel` | `page-label` | | `string` | `\"Register\"` |\r\n| `passwordLabel` | `password-label` | | `string` | `\"Password\"` |\r\n| `submitLabel` | `submit-label` | | `string` | `\"Register\"` |\r\n\r\n\r\n## Dependencies\r\n\r\n### Used by\r\n\r\n - [sqm-stencilbook](../sqm-stencilbook)\r\n\r\n### Depends on\r\n\r\n- [sqm-form-message](../sqm-form-message)\r\n- [sqm-password-field](../sqm-password-field)\r\n\r\n### Graph\r\n```mermaid\r\ngraph TD;\r\n sqm-portal-register --> sqm-form-message\r\n sqm-portal-register --> sqm-password-field\r\n sqm-stencilbook --> sqm-portal-register\r\n style sqm-portal-register fill:#f9f,stroke:#333,stroke-width:4px\r\n```\r\n\r\n----------------------------------------------\r\n\r\n*Built with [StencilJS](https://stenciljs.com/)*\r\n";
24921
+ const RegisterReadme = "# sqm-portal-register\r\n\r\n\r\n\r\n<!-- Auto Generated Below -->\n\n\n## Properties\n\n| Property | Attribute | Description | Type | Default |\n| -------------------------- | ---------------------------- | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- |\n| `confirmPassword` | `confirm-password` | | `boolean` | `false` |\n| `confirmPasswordLabel` | `confirm-password-label` | | `string` | `\"Confirm Password\"` |\n| `demoData` | -- | | `{ states?: { error: string; loading: boolean; confirmPassword: boolean; hideInputs: boolean; validationState?: FormState; enablePasswordValidation?: boolean; }; content?: { formData?: any; passwordField?: any; secondaryButton?: any; emailLabel?: string; passwordLabel?: string; submitLabel?: string; pageLabel?: string; confirmPasswordLabel: string; }; refs?: { formRef: any; }; }` | `undefined` |\n| `emailLabel` | `email-label` | | `string` | `\"Email\"` |\n| `enablePasswordValidation` | `enable-password-validation` | | `boolean` | `true` |\n| `hideInputs` | `hide-inputs` | | `boolean` | `false` |\n| `loginLabel` | `login-label` | | `string` | `\"Sign in\"` |\n| `nextPage` | `next-page` | | `string` | `\"/\"` |\n| `pageLabel` | `page-label` | | `string` | `\"Register\"` |\n| `passwordLabel` | `password-label` | | `string` | `\"Password\"` |\n| `submitLabel` | `submit-label` | | `string` | `\"Register\"` |\n\n\n## Dependencies\n\n### Used by\n\n - [sqm-stencilbook](../sqm-stencilbook)\n\n### Depends on\n\n- [sqm-form-message](../sqm-form-message)\n- [sqm-password-field](../sqm-password-field)\n\n### Graph\n```mermaid\ngraph TD;\n sqm-portal-register --> sqm-form-message\n sqm-portal-register --> sqm-password-field\n sqm-stencilbook --> sqm-portal-register\n style sqm-portal-register fill:#f9f,stroke:#333,stroke-width:4px\n```\n\n----------------------------------------------\n\n*Built with [StencilJS](https://stenciljs.com/)*\n";
25002
24922
 
25003
24923
  const EditProfileReadme = "# sqm-portal-profile\r\n\r\n\r\n\r\n<!-- Auto Generated Below -->\r\n\r\n\r\n## Properties\r\n\r\n| Property | Attribute | Description | Type | Default |\r\n| ------------------------ | --------------------------- | ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ |\r\n| `countrytext` | `countrytext` | | `string` | `\"Country\"` |\r\n| `demoData` | -- | | `{ states?: { success: boolean; loading: boolean; submitDisabled: boolean; showCountry: boolean; formState: { country: string; firstName: string; lastName: string; errors: any; error: string; }; user: { id: string; accountId: string; firstName: string; lastName: string; email: string; countryCode: string; }; text: { firstnametext: string; lastnametext: string; emailtext: string; countrytext: string; editProfileHeader: string; editProfileSubHeader: string; submitChangeButtonText: string; }; }; }` | `undefined` |\r\n| `editProfileHeader` | `edit-profile-header` | | `string` | `\"Edit your profile\"` |\r\n| `editProfileSubHeader` | `edit-profile-sub-header` | | `string` | `\"Personal Information\"` |\r\n| `emailtext` | `emailtext` | | `string` | `\"Email\"` |\r\n| `firstnametext` | `firstnametext` | | `string` | `\"First Name\"` |\r\n| `lastnametext` | `lastnametext` | | `string` | `\"Last Name\"` |\r\n| `showCountry` | `show-country` | | `boolean` | `true` |\r\n| `submitChangeButtonText` | `submit-change-button-text` | | `string` | `\"Submit Changes\"` |\r\n\r\n\r\n## Dependencies\r\n\r\n### Depends on\r\n\r\n- [sqm-form-message](../sqm-form-message)\r\n\r\n### Graph\r\n```mermaid\r\ngraph TD;\r\n sqm-portal-profile --> sqm-form-message\r\n style sqm-portal-profile fill:#f9f,stroke:#333,stroke-width:4px\r\n```\r\n\r\n----------------------------------------------\r\n\r\n*Built with [StencilJS](https://stenciljs.com/)*\r\n";
25004
24924
 
@@ -25204,7 +25124,7 @@ const ProgramMenu$1 = /*#__PURE__*/Object.freeze({
25204
25124
  const PoweredByImg_stories = {
25205
25125
  title: "Powered By",
25206
25126
  };
25207
- const Default$b = () => {
25127
+ const Default$a = () => {
25208
25128
  return h(PoweredByImg$1, null);
25209
25129
  };
25210
25130
  const CustomColor = () => {
@@ -25217,17 +25137,17 @@ const CustomWidthAndHeight = () => {
25217
25137
  const PoweredByImg = /*#__PURE__*/Object.freeze({
25218
25138
  __proto__: null,
25219
25139
  'default': PoweredByImg_stories,
25220
- Default: Default$b,
25140
+ Default: Default$a,
25221
25141
  CustomColor: CustomColor,
25222
25142
  CustomWidthAndHeight: CustomWidthAndHeight
25223
25143
  });
25224
25144
 
25225
- const scenario$7 = "Feature: Portal Footer\r\n\r\n Background: A user is viewing the portal\r\n Given a hosted portal\r\n And a user is viewing the portal\r\n And the portal has a footer\r\n\r\n Scenario Outline: FAQ and T&C links/text are configurable and open in a new page when clicked\r\n Given the footer has prop \"terms-link\" with value \"https://example.com/terms\"\r\n And prop \"terms-text\" with value \"Terms and Conditions\"\r\n And prop \"faq-link\" with value \"https://example.com/FAQ\"\r\n And prop \"faq-text\" with value \"Visit FAQ\"\r\n When a user clicks on the \"Visit FAQ\" link\r\n Then they will be redirected to \"https://example.com/FAQ\" in a new page\r\n When they go back to the portal\r\n And click on the \"Terms and Conditions\" link\r\n Then they will be redirected to \"https://example.com/terms\" in a new page\r\n\r\n Scenario Outline: FAQ/T&C Links are not shown if a link is not provided\r\n Given the footer does not have <linkProp>\r\n But it <mayHave> <textProp> with <value>\r\n Then the <link> will not be shown in the footer\r\n Examples:\r\n | linkProp | mayHave | textProp | value | link |\r\n | terms-link | has | termsText | Terms and Conditions | T&C Link |\r\n | faq-link | has | faqText | Visit FAQ | FAQ Link |\r\n | terms-link | doesn't have | | | T&C Link |\r\n | faq-link | doesn't have | | | FAQ Link |\r\n\r\n Scenario Outline: The support email and text is configurable but has a default\r\n Given the footer <mayHave> <emailPropWithValue>\r\n And the footer <mayAlsoHave> <textPropWithValue>\r\n Then the footer's support email text is <renderedEmailText>\r\n And the email address will be a mailto link with <mailtoEmail>\r\n When the user clicks on the email address mailto Link\r\n Then the users preferred email client will open with a draft email to <mailtoEmail>\r\n Examples:\r\n | mayHave | emailPropWithValue | mayAlsoHave | textPropWithValue | mailtoEmail | renderedEmailText |\r\n | has | support@saasquatch.com | has | For support please contact {email} | support@saasquatch.com | For support please contact support@saasquatch.com |\r\n | doesn't have | N/A | doesn't have | N/A | support@example.com | For program support, contact support@example.com |\r\n\r\n Scenario Outline: Powered by SaaSquatch is shown by default\r\n Given the footer <mayHaveProp> \"show-powered-by\" with <value>\r\n Then the powered by SaaSquatch image <mayBeShown>\r\n Examples:\r\n | mayHaveProp | value | mayBeShown |\r\n | has prop | true | is shown |\r\n | has prop | false | isn't shown |\r\n | has prop | test | is shown |\r\n | has prop | | is shown |\r\n | doesn't have prop | | is shown |\r\n\r\n Scenario: Powered By Saasquatch links out to \"https://saasquatch.com\"\r\n Given the footer has the powered by SaaSquatch image\r\n When a user clicks on it\r\n Then they will be redirected to \"https://saasquatch.com\" in a new page";
25145
+ const scenario$6 = "Feature: Portal Footer\r\n\r\n Background: A user is viewing the portal\r\n Given a hosted portal\r\n And a user is viewing the portal\r\n And the portal has a footer\r\n\r\n Scenario Outline: FAQ and T&C links/text are configurable and open in a new page when clicked\r\n Given the footer has prop \"terms-link\" with value \"https://example.com/terms\"\r\n And prop \"terms-text\" with value \"Terms and Conditions\"\r\n And prop \"faq-link\" with value \"https://example.com/FAQ\"\r\n And prop \"faq-text\" with value \"Visit FAQ\"\r\n When a user clicks on the \"Visit FAQ\" link\r\n Then they will be redirected to \"https://example.com/FAQ\" in a new page\r\n When they go back to the portal\r\n And click on the \"Terms and Conditions\" link\r\n Then they will be redirected to \"https://example.com/terms\" in a new page\r\n\r\n Scenario Outline: FAQ/T&C Links are not shown if a link is not provided\r\n Given the footer does not have <linkProp>\r\n But it <mayHave> <textProp> with <value>\r\n Then the <link> will not be shown in the footer\r\n Examples:\r\n | linkProp | mayHave | textProp | value | link |\r\n | terms-link | has | termsText | Terms and Conditions | T&C Link |\r\n | faq-link | has | faqText | Visit FAQ | FAQ Link |\r\n | terms-link | doesn't have | | | T&C Link |\r\n | faq-link | doesn't have | | | FAQ Link |\r\n\r\n Scenario Outline: The support email and text is configurable but has a default\r\n Given the footer <mayHave> <emailPropWithValue>\r\n And the footer <mayAlsoHave> <textPropWithValue>\r\n Then the footer's support email text is <renderedEmailText>\r\n And the email address will be a mailto link with <mailtoEmail>\r\n When the user clicks on the email address mailto Link\r\n Then the users preferred email client will open with a draft email to <mailtoEmail>\r\n Examples:\r\n | mayHave | emailPropWithValue | mayAlsoHave | textPropWithValue | mailtoEmail | renderedEmailText |\r\n | has | support@saasquatch.com | has | For support please contact {email} | support@saasquatch.com | For support please contact support@saasquatch.com |\r\n | doesn't have | N/A | doesn't have | N/A | support@example.com | For program support, contact support@example.com |\r\n\r\n Scenario Outline: Powered by SaaSquatch is shown by default\r\n Given the footer <mayHaveProp> \"show-powered-by\" with <value>\r\n Then the powered by SaaSquatch image <mayBeShown>\r\n Examples:\r\n | mayHaveProp | value | mayBeShown |\r\n | has prop | true | is shown |\r\n | has prop | false | isn't shown |\r\n | has prop | test | is shown |\r\n | has prop | | is shown |\r\n | doesn't have prop | | is shown |\r\n\r\n Scenario: Powered By Saasquatch links out to \"https://saasquatch.com\"\r\n Given the footer has the powered by SaaSquatch image\r\n When a user clicks on it\r\n Then they will be redirected to \"https://saasquatch.com\" in a new page";
25226
25146
 
25227
25147
  const PortalFooter_stories = {
25228
25148
  title: "Portal Footer",
25229
25149
  parameters: {
25230
- scenario: scenario$7,
25150
+ scenario: scenario$6,
25231
25151
  },
25232
25152
  };
25233
25153
  const defaultProps$9 = {
@@ -25256,12 +25176,12 @@ const PortalFooter = /*#__PURE__*/Object.freeze({
25256
25176
  FooterNoPoweredBy: FooterNoPoweredBy
25257
25177
  });
25258
25178
 
25259
- const scenario$8 = "Feature: Hero Unit\r\n\r\n Background: A portal with a hero unit exists\r\n Given a hosted portal\r\n And the portal has hero unit on the login page\r\n And a user is viewing the login page\r\n\r\n Scenario: The hero unit defaults to a single column layout\r\n Given a hero unit does not have a \"columns\" prop\r\n But the following html is wrapped by the hero unit\r\n \"\"\"\r\n <sqm-portal-login></sqm-portal-login>\r\n <div slot=\"secondary-column\">\r\n <h1 style=\"text-align:center\">Get Referring!</h1>\r\n <p style=\"text-align:center\">\r\n Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do\r\n eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim\r\n ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut\r\n aliquip ex ea commodo consequat. Duis aute irure dolor in\r\n reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla\r\n pariatur.\r\n </p>\r\n </div>\r\n \"\"\"\r\n Then only a single column will be displayed\r\n And within it will be the login component\r\n\r\n Scenario Outline: The hero unit supports single or dual column layouts\r\n Given a hero unit with prop \"columns\" having <columnValue>\r\n And it wraps <html>\r\n Then the hero unit displays <columnValue> columns\r\n Examples:\r\n | columnValue | html |\r\n | 1 | <h1>Column 1!</h1> |\r\n | 2 | <h1>Column 1!</h1><div slot=\"secondary-column\"><h1 style=\"text-align:center\">Column 2!</h1></div> |\r\n\r\n Scenario: HTML to be displayed in the second column comes from the \"secondary-column\" slot\r\n Given a hero unit with \"columns\" \"2\"\r\n And the following html\r\n \"\"\"\r\n <h1>Column 1!</h1>\r\n <div>\r\n <h1 style=\"text-align:center\">Column 2!</h1>\r\n </div>\r\n \"\"\"\r\n When the hero unit is rendered\r\n Then only one column is displayed with content\r\n And column 1 will contain the \"Column 1!\" text\r\n And column 1 will contain the \"Column 2!\" text\r\n When the div for column two is updated to have 'slot=\"secondary-column\"'\r\n Then the two columns are displayed with content\r\n And column 1 will contain the \"Column 1!\" text\r\n And column 2 will contain the \"Column 2!\" text\r\n\r\n Scenario Outline: A background for the hero unit can be set as an image or colour\r\n Given a hero unit with <backgroundPropValue>\r\n Then the background will be <background>\r\n Examples:\r\n | background | background |\r\n | https://images.unsplash.com/photo-1599676821464-3555954838d | image of misty mountains |\r\n | LightSlateGrey | light slate grey |\r\n | #00FF00 | green |\r\n | rgb(128,0,128) | purple |\r\n\r\n Scenario Outline: Wrap Direction can be configured for mobile experiences\r\n Given a hero unit with the following HTML\r\n \"\"\"\r\n <h1>Column 1!</h1>\r\n <div slot=\"secondary-column\">\r\n <h1 style=\"text-align:center\">Column 2!</h1>\r\n </div>\r\n \"\"\"\r\n And prop \"wrap-direction\" has <value>\r\n When the window width is less than 600px\r\n Then the two columns will stack\r\n And <column> will be on top\r\n Examples:\r\n | value | column |\r\n | wrap | 1 |\r\n | wrap-reverse | 2 |\r\n | | 1 |";
25179
+ const scenario$7 = "Feature: Hero Unit\r\n\r\n Background: A portal with a hero unit exists\r\n Given a hosted portal\r\n And the portal has hero unit on the login page\r\n And a user is viewing the login page\r\n\r\n Scenario: The hero unit defaults to a single column layout\r\n Given a hero unit does not have a \"columns\" prop\r\n But the following html is wrapped by the hero unit\r\n \"\"\"\r\n <sqm-portal-login></sqm-portal-login>\r\n <div slot=\"secondary-column\">\r\n <h1 style=\"text-align:center\">Get Referring!</h1>\r\n <p style=\"text-align:center\">\r\n Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do\r\n eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim\r\n ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut\r\n aliquip ex ea commodo consequat. Duis aute irure dolor in\r\n reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla\r\n pariatur.\r\n </p>\r\n </div>\r\n \"\"\"\r\n Then only a single column will be displayed\r\n And within it will be the login component\r\n\r\n Scenario Outline: The hero unit supports single or dual column layouts\r\n Given a hero unit with prop \"columns\" having <columnValue>\r\n And it wraps <html>\r\n Then the hero unit displays <columnValue> columns\r\n Examples:\r\n | columnValue | html |\r\n | 1 | <h1>Column 1!</h1> |\r\n | 2 | <h1>Column 1!</h1><div slot=\"secondary-column\"><h1 style=\"text-align:center\">Column 2!</h1></div> |\r\n\r\n Scenario: HTML to be displayed in the second column comes from the \"secondary-column\" slot\r\n Given a hero unit with \"columns\" \"2\"\r\n And the following html\r\n \"\"\"\r\n <h1>Column 1!</h1>\r\n <div>\r\n <h1 style=\"text-align:center\">Column 2!</h1>\r\n </div>\r\n \"\"\"\r\n When the hero unit is rendered\r\n Then only one column is displayed with content\r\n And column 1 will contain the \"Column 1!\" text\r\n And column 1 will contain the \"Column 2!\" text\r\n When the div for column two is updated to have 'slot=\"secondary-column\"'\r\n Then the two columns are displayed with content\r\n And column 1 will contain the \"Column 1!\" text\r\n And column 2 will contain the \"Column 2!\" text\r\n\r\n Scenario Outline: A background for the hero unit can be set as an image or colour\r\n Given a hero unit with <backgroundPropValue>\r\n Then the background will be <background>\r\n Examples:\r\n | background | background |\r\n | https://images.unsplash.com/photo-1599676821464-3555954838d | image of misty mountains |\r\n | LightSlateGrey | light slate grey |\r\n | #00FF00 | green |\r\n | rgb(128,0,128) | purple |\r\n\r\n Scenario Outline: Wrap Direction can be configured for mobile experiences\r\n Given a hero unit with the following HTML\r\n \"\"\"\r\n <h1>Column 1!</h1>\r\n <div slot=\"secondary-column\">\r\n <h1 style=\"text-align:center\">Column 2!</h1>\r\n </div>\r\n \"\"\"\r\n And prop \"wrap-direction\" has <value>\r\n When the window width is less than 600px\r\n Then the two columns will stack\r\n And <column> will be on top\r\n Examples:\r\n | value | column |\r\n | wrap | 1 |\r\n | wrap-reverse | 2 |\r\n | | 1 |";
25260
25180
 
25261
25181
  const Hero_stories = {
25262
25182
  title: "Hero Layout",
25263
25183
  parameters: {
25264
- scenario: scenario$8,
25184
+ scenario: scenario$7,
25265
25185
  },
25266
25186
  };
25267
25187
  const LoginOneColumn = () => {
@@ -25438,12 +25358,12 @@ const Hero = /*#__PURE__*/Object.freeze({
25438
25358
  TwoColumnLoginWithImgElement: TwoColumnLoginWithImgElement
25439
25359
  });
25440
25360
 
25441
- const scenario$9 = "@owner:sam\r\n@author:sam\r\n\r\nFeature: Referral Iframe\r\n\r\n Used to provide an external form for submitting referral leads using the current user's referral code\r\n\r\n Background: A user is logged in\r\n Given there is a logged in user\r\n\r\n @motivating\r\n Scenario: Referral code is passed to the iframe as a query parameter\r\n Given the \"iframe-src\" is \"https://example.com\"\r\n And the user has navigated to \"/refer\"\r\n And the user's referral code is \"BOBBYREFER\"\r\n When the iframe content is loaded\r\n Then the iframe url will be \"https://example.com?rsCode=BOBBYREFER\"\r\n\r\n @ui\r\n Scenario Outline: The height and width of the iFrame can be controlled via props\r\n Given the \"iframe-src\" is \"https://example.com\"\r\n And the iframe content is 1000x1000\r\n And the \"iframe-height\" is set to <heightValue>\r\n And the \"iframe-width\" is set to <widthValue>\r\n Then the content of the iframe will be displayed with scrollbars\r\n And the dimension of the iFrame displayed will be 500x500\r\n When the \"iframe-height\" is set to <heightValue>\r\n And the \"iframe-width\" is set to <widthValue>\r\n Then the full content of the iframe will be displayed on the page\r\n And the dimension of the iFrame displayed will be 1000x1000\r\n Examples:\r\n | heightValue | widthValue |\r\n | 500px | 500px |\r\n | 50% | 50% |\r\n\r\n @minutae\r\n Scenario Outline: The iFrame will fail fast if a iFrame source isn't provided\r\n Given \"iframe-src\" <mayBeAnAttribute>\r\n And it <mayHaveValue>\r\n When a user views the referral iFrame component\r\n Then an alert with an error message is displayed in place of the iFrame\r\n And it has a details section\r\n When \"More details\" is clicked\r\n Then the following information will be displayed\r\n | component being used |\r\n | missing attribute(s) |\r\n\r\n Examples:\r\n | mayBeAnAttribute | mayHaveValue |\r\n | is not an attribute | N/A |\r\n | is an attribute | \"\" |\r\n | is an attribute | |";
25361
+ const scenario$8 = "@owner:sam\r\n@author:sam\r\n\r\nFeature: Referral Iframe\r\n\r\n Used to provide an external form for submitting referral leads using the current user's referral code\r\n\r\n Background: A user is logged in\r\n Given there is a logged in user\r\n\r\n @motivating\r\n Scenario: Referral code is passed to the iframe as a query parameter\r\n Given the \"iframe-src\" is \"https://example.com\"\r\n And the user has navigated to \"/refer\"\r\n And the user's referral code is \"BOBBYREFER\"\r\n When the iframe content is loaded\r\n Then the iframe url will be \"https://example.com?rsCode=BOBBYREFER\"\r\n\r\n @ui\r\n Scenario Outline: The height and width of the iFrame can be controlled via props\r\n Given the \"iframe-src\" is \"https://example.com\"\r\n And the iframe content is 1000x1000\r\n And the \"iframe-height\" is set to <heightValue>\r\n And the \"iframe-width\" is set to <widthValue>\r\n Then the content of the iframe will be displayed with scrollbars\r\n And the dimension of the iFrame displayed will be 500x500\r\n When the \"iframe-height\" is set to <heightValue>\r\n And the \"iframe-width\" is set to <widthValue>\r\n Then the full content of the iframe will be displayed on the page\r\n And the dimension of the iFrame displayed will be 1000x1000\r\n Examples:\r\n | heightValue | widthValue |\r\n | 500px | 500px |\r\n | 50% | 50% |\r\n\r\n @minutae\r\n Scenario Outline: The iFrame will fail fast if a iFrame source isn't provided\r\n Given \"iframe-src\" <mayBeAnAttribute>\r\n And it <mayHaveValue>\r\n When a user views the referral iFrame component\r\n Then an alert with an error message is displayed in place of the iFrame\r\n And it has a details section\r\n When \"More details\" is clicked\r\n Then the following information will be displayed\r\n | component being used |\r\n | missing attribute(s) |\r\n\r\n Examples:\r\n | mayBeAnAttribute | mayHaveValue |\r\n | is not an attribute | N/A |\r\n | is an attribute | \"\" |\r\n | is an attribute | |";
25442
25362
 
25443
25363
  const ReferralIframe_stories = {
25444
25364
  title: "Referral Iframe",
25445
25365
  parameters: {
25446
- scenario: scenario$9,
25366
+ scenario: scenario$8,
25447
25367
  },
25448
25368
  };
25449
25369
  const props = {
@@ -25474,12 +25394,12 @@ const ReferralIframe$1 = /*#__PURE__*/Object.freeze({
25474
25394
  ReferralIframeError: ReferralIframeError
25475
25395
  });
25476
25396
 
25477
- const scenario$a = "@owner:sam\r\n@author:sam\r\n\r\nFeature: Name Fields\r\n\r\n Fields to be used to fill the first and last name of a user during registration\r\n\r\n Background:\r\n Given the current page is \"/register\"\r\n\r\n @motivating\r\n Scenario: Both first name and last name are required\r\n Given the email field has valid input\r\n And the password field has valid input\r\n And first name field is empty\r\n And last name field is empty\r\n When register is clicked\r\n Then the name fields will be highlighted in red\r\n And the error messages will say \"Cannot be empty\"\r\n\r\n @motivating\r\n Scenario: First and last name are upserted with the SaaSquatch user\r\n Given all fields have been filled with data\r\n | firstName | lastName | email | password |\r\n | Bob | Testerson | bob@example.com | SecurePassword1 |\r\n When register is clicked\r\n Then the email verification page will be loaded\r\n And the user will be upserted\r\n And the SaaSquatch user will contain data\r\n | firstName | lastName | email |\r\n | Bob | Testerson | bob@example.com |\r\n\r\n";
25397
+ const scenario$9 = "@owner:sam\r\n@author:sam\r\n\r\nFeature: Name Fields\r\n\r\n Fields to be used to fill the first and last name of a user during registration\r\n\r\n Background:\r\n Given the current page is \"/register\"\r\n\r\n @motivating\r\n Scenario: Both first name and last name are required\r\n Given the email field has valid input\r\n And the password field has valid input\r\n And first name field is empty\r\n And last name field is empty\r\n When register is clicked\r\n Then the name fields will be highlighted in red\r\n And the error messages will say \"Cannot be empty\"\r\n\r\n @motivating\r\n Scenario: First and last name are upserted with the SaaSquatch user\r\n Given all fields have been filled with data\r\n | firstName | lastName | email | password |\r\n | Bob | Testerson | bob@example.com | SecurePassword1 |\r\n When register is clicked\r\n Then the email verification page will be loaded\r\n And the user will be upserted\r\n And the SaaSquatch user will contain data\r\n | firstName | lastName | email |\r\n | Bob | Testerson | bob@example.com |\r\n\r\n";
25478
25398
 
25479
25399
  const NameFields_stories = {
25480
25400
  title: "Name Fields",
25481
25401
  parameters: {
25482
- scenario: scenario$a,
25402
+ scenario: scenario$9,
25483
25403
  },
25484
25404
  };
25485
25405
  const props$1 = {
@@ -25532,7 +25452,7 @@ const baseResponse = (data) => ({
25532
25452
  },
25533
25453
  callbacks: {
25534
25454
  exchangeReward: null,
25535
- openDrawer: null,
25455
+ resetState: null,
25536
25456
  setStage: null,
25537
25457
  setExchangeState: null,
25538
25458
  refs: null,
@@ -25684,6 +25604,7 @@ const test2 = {
25684
25604
  prettyDestinationValue: "1 Salmon Coin",
25685
25605
  available: true,
25686
25606
  unavailableReasonCode: null,
25607
+ unavailableReason: ""
25687
25608
  },
25688
25609
  {
25689
25610
  sourceValue: 2,
@@ -25692,6 +25613,7 @@ const test2 = {
25692
25613
  prettyDestinationValue: "2 Salmons",
25693
25614
  available: true,
25694
25615
  unavailableReasonCode: null,
25616
+ unavailableReason: ""
25695
25617
  },
25696
25618
  {
25697
25619
  sourceValue: 3,
@@ -25700,6 +25622,7 @@ const test2 = {
25700
25622
  prettyDestinationValue: "3 Salmons",
25701
25623
  available: true,
25702
25624
  unavailableReasonCode: null,
25625
+ unavailableReason: ""
25703
25626
  },
25704
25627
  {
25705
25628
  sourceValue: 4,
@@ -25708,6 +25631,7 @@ const test2 = {
25708
25631
  prettyDestinationValue: "4 Salmons",
25709
25632
  available: true,
25710
25633
  unavailableReasonCode: null,
25634
+ unavailableReason: ""
25711
25635
  },
25712
25636
  {
25713
25637
  sourceValue: 5,
@@ -25716,6 +25640,7 @@ const test2 = {
25716
25640
  prettyDestinationValue: "5 Salmons",
25717
25641
  available: true,
25718
25642
  unavailableReasonCode: null,
25643
+ unavailableReason: ""
25719
25644
  },
25720
25645
  ],
25721
25646
  },
@@ -25726,7 +25651,7 @@ const test2 = {
25726
25651
  },
25727
25652
  callbacks: {
25728
25653
  exchangeReward: null,
25729
- openDrawer: null,
25654
+ resetState: null,
25730
25655
  setStage: null,
25731
25656
  setExchangeState: null,
25732
25657
  refs: {
@@ -25746,7 +25671,7 @@ const resizable$1 = {
25746
25671
  height: "fit-content",
25747
25672
  overflow: "hidden",
25748
25673
  };
25749
- const Default$c = () => {
25674
+ const Default$b = () => {
25750
25675
  return (h("div", { style: resizable$1 },
25751
25676
  h(RewardExchangeView, Object.assign({}, test))));
25752
25677
  };
@@ -25758,7 +25683,7 @@ const Default2 = () => {
25758
25683
  const RewardExchangeList = /*#__PURE__*/Object.freeze({
25759
25684
  __proto__: null,
25760
25685
  'default': RewardExchangeList_stories,
25761
- Default: Default$c,
25686
+ Default: Default$b,
25762
25687
  Default2: Default2
25763
25688
  });
25764
25689
 
@@ -28382,7 +28307,6 @@ const stories = [
28382
28307
  UserName,
28383
28308
  PasswordField,
28384
28309
  TaskCard$1,
28385
- TaskCardProgressBar,
28386
28310
  PortalTemplates,
28387
28311
  ProgramMenu$1,
28388
28312
  PoweredByImg,
@@ -28477,6 +28401,12 @@ const TaskCard$2 = class {
28477
28401
  * @uiName Show Goal Expiry
28478
28402
  */
28479
28403
  this.showExpiry = false;
28404
+ /**
28405
+ * @uiName Date Goal Expires
28406
+ * @uiWidget DateRange
28407
+ * @uiOptions {"allowPastDates":true, "months": 1}
28408
+ */
28409
+ this.dateExpires = "/";
28480
28410
  /**
28481
28411
  * @uiName CTA Button Text
28482
28412
  */