@schematichq/schematic-components 0.3.10 → 0.3.12

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.
@@ -8936,7 +8936,7 @@ var EmbedProvider = ({
8936
8936
  (0, import_react2.useEffect)(() => {
8937
8937
  if (accessToken) {
8938
8938
  const { headers = {} } = apiConfig ?? {};
8939
- headers["X-Schematic-Components-Version"] = "0.3.10";
8939
+ headers["X-Schematic-Components-Version"] = "0.3.12";
8940
8940
  headers["X-Schematic-Session-ID"] = sessionIdRef.current;
8941
8941
  const config = new Configuration({
8942
8942
  ...apiConfig,
@@ -11059,7 +11059,9 @@ function resolveDesignProps(props) {
11059
11059
  usage: {
11060
11060
  isVisible: props.usage?.isVisible ?? true,
11061
11061
  fontStyle: props.usage?.fontStyle ?? "heading6"
11062
- }
11062
+ },
11063
+ // there is a typescript bug with `RecursivePartial` so we must cast to `string[] | undefined`
11064
+ visibleFeatures: props.visibleFeatures
11063
11065
  };
11064
11066
  }
11065
11067
  var IncludedFeatures = (0, import_react14.forwardRef)(({ className, ...rest }, ref) => {
@@ -11069,7 +11071,16 @@ var IncludedFeatures = (0, import_react14.forwardRef)(({ className, ...rest }, r
11069
11071
  const elements = (0, import_react14.useRef)([]);
11070
11072
  const shouldWrapChildren = useWrapChildren(elements.current);
11071
11073
  const isLightBackground = useIsLightBackground();
11072
- const shouldShowFeatures = (data.featureUsage?.features ?? []).length > 0 || data.company?.plan || (data.company?.addOns ?? []).length > 0 || false;
11074
+ const featureUsage = props.visibleFeatures ? props.visibleFeatures.reduce((acc, id) => {
11075
+ const mappedFeatureUsage = data.featureUsage?.features.find(
11076
+ (usage) => usage.feature?.id === id
11077
+ );
11078
+ if (mappedFeatureUsage) {
11079
+ acc.push(mappedFeatureUsage);
11080
+ }
11081
+ return acc;
11082
+ }, []) : data.featureUsage?.features || [];
11083
+ const shouldShowFeatures = featureUsage.length > 0 || data.company?.plan || (data.company?.addOns ?? []).length > 0 || false;
11073
11084
  if (!shouldShowFeatures) {
11074
11085
  return null;
11075
11086
  }
@@ -11092,82 +11103,76 @@ var IncludedFeatures = (0, import_react14.forwardRef)(({ className, ...rest }, r
11092
11103
  children: props.header.text
11093
11104
  }
11094
11105
  ) }),
11095
- (data.featureUsage?.features || []).reduce(
11096
- (acc, { allocation, feature, usage }, index) => {
11097
- return [
11098
- ...acc,
11099
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
11100
- Flex,
11101
- {
11102
- ref: (el) => el && elements.current.push(el),
11103
- $flexWrap: "wrap",
11104
- $justifyContent: "space-between",
11105
- $alignItems: "center",
11106
- $gap: "1rem",
11107
- children: [
11108
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(Flex, { $flexGrow: "1", $flexBasis: "min-content", $gap: "1rem", children: [
11109
- props.icons.isVisible && feature?.icon && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
11110
- IconRound,
11106
+ featureUsage.map(({ allocation, feature, usage }, index) => {
11107
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
11108
+ Flex,
11109
+ {
11110
+ ref: (el) => el && elements.current.push(el),
11111
+ $flexWrap: "wrap",
11112
+ $justifyContent: "space-between",
11113
+ $alignItems: "center",
11114
+ $gap: "1rem",
11115
+ children: [
11116
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(Flex, { $flexGrow: "1", $flexBasis: "min-content", $gap: "1rem", children: [
11117
+ props.icons.isVisible && feature?.icon && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
11118
+ IconRound,
11119
+ {
11120
+ name: feature.icon,
11121
+ size: "sm",
11122
+ colors: [
11123
+ theme.primary,
11124
+ isLightBackground ? "hsla(0, 0%, 0%, 0.0625)" : "hsla(0, 0%, 100%, 0.25)"
11125
+ ]
11126
+ }
11127
+ ),
11128
+ feature?.name && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Flex, { $alignItems: "center", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
11129
+ Text,
11130
+ {
11131
+ $font: theme.typography[props.icons.fontStyle].fontFamily,
11132
+ $size: theme.typography[props.icons.fontStyle].fontSize,
11133
+ $weight: theme.typography[props.icons.fontStyle].fontWeight,
11134
+ $color: theme.typography[props.icons.fontStyle].color,
11135
+ children: feature.name
11136
+ }
11137
+ ) })
11138
+ ] }),
11139
+ (feature?.featureType === "event" || feature?.featureType === "trait") && feature?.name && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
11140
+ Box,
11141
+ {
11142
+ $flexBasis: "min-content",
11143
+ $flexGrow: "1",
11144
+ $textAlign: shouldWrapChildren ? "left" : "right",
11145
+ children: [
11146
+ props.entitlement.isVisible && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Box, { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
11147
+ Text,
11111
11148
  {
11112
- name: feature.icon,
11113
- size: "sm",
11114
- colors: [
11115
- theme.primary,
11116
- isLightBackground ? "hsla(0, 0%, 0%, 0.0625)" : "hsla(0, 0%, 100%, 0.25)"
11117
- ]
11149
+ $font: theme.typography[props.entitlement.fontStyle].fontFamily,
11150
+ $size: theme.typography[props.entitlement.fontStyle].fontSize,
11151
+ $weight: theme.typography[props.entitlement.fontStyle].fontWeight,
11152
+ $lineHeight: 1.25,
11153
+ $color: theme.typography[props.entitlement.fontStyle].color,
11154
+ children: typeof allocation === "number" ? `${formatNumber(allocation)} ${(0, import_pluralize2.default)(feature.name, allocation)}` : `Unlimited ${(0, import_pluralize2.default)(feature.name)}`
11118
11155
  }
11119
- ),
11120
- feature?.name && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Flex, { $alignItems: "center", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
11156
+ ) }),
11157
+ props.usage.isVisible && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Box, { $whiteSpace: "nowrap", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
11121
11158
  Text,
11122
11159
  {
11123
- $font: theme.typography[props.icons.fontStyle].fontFamily,
11124
- $size: theme.typography[props.icons.fontStyle].fontSize,
11125
- $weight: theme.typography[props.icons.fontStyle].fontWeight,
11126
- $color: theme.typography[props.icons.fontStyle].color,
11127
- children: feature.name
11160
+ $font: theme.typography[props.usage.fontStyle].fontFamily,
11161
+ $size: theme.typography[props.usage.fontStyle].fontSize,
11162
+ $weight: theme.typography[props.usage.fontStyle].fontWeight,
11163
+ $lineHeight: 1.5,
11164
+ $color: theme.typography[props.usage.fontStyle].color,
11165
+ children: typeof usage === "number" && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_jsx_runtime15.Fragment, { children: typeof allocation === "number" ? `${formatNumber(usage)} of ${formatNumber(allocation)} used` : `${formatNumber(usage)} used` })
11128
11166
  }
11129
11167
  ) })
11130
- ] }),
11131
- (feature?.featureType === "event" || feature?.featureType === "trait") && feature?.name && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
11132
- Box,
11133
- {
11134
- $flexBasis: "min-content",
11135
- $flexGrow: "1",
11136
- $textAlign: shouldWrapChildren ? "left" : "right",
11137
- children: [
11138
- props.entitlement.isVisible && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Box, { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
11139
- Text,
11140
- {
11141
- $font: theme.typography[props.entitlement.fontStyle].fontFamily,
11142
- $size: theme.typography[props.entitlement.fontStyle].fontSize,
11143
- $weight: theme.typography[props.entitlement.fontStyle].fontWeight,
11144
- $lineHeight: 1.25,
11145
- $color: theme.typography[props.entitlement.fontStyle].color,
11146
- children: typeof allocation === "number" ? `${formatNumber(allocation)} ${(0, import_pluralize2.default)(feature.name, allocation)}` : `Unlimited ${(0, import_pluralize2.default)(feature.name)}`
11147
- }
11148
- ) }),
11149
- props.usage.isVisible && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Box, { $whiteSpace: "nowrap", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
11150
- Text,
11151
- {
11152
- $font: theme.typography[props.usage.fontStyle].fontFamily,
11153
- $size: theme.typography[props.usage.fontStyle].fontSize,
11154
- $weight: theme.typography[props.usage.fontStyle].fontWeight,
11155
- $lineHeight: 1.5,
11156
- $color: theme.typography[props.usage.fontStyle].color,
11157
- children: typeof usage === "number" && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_jsx_runtime15.Fragment, { children: typeof allocation === "number" ? `${formatNumber(usage)} of ${formatNumber(allocation)} used` : `${formatNumber(usage)} used` })
11158
- }
11159
- ) })
11160
- ]
11161
- }
11162
- )
11163
- ]
11164
- },
11165
- index
11166
- )
11167
- ];
11168
- },
11169
- []
11170
- )
11168
+ ]
11169
+ }
11170
+ )
11171
+ ]
11172
+ },
11173
+ index
11174
+ );
11175
+ })
11171
11176
  ]
11172
11177
  }
11173
11178
  );
@@ -11202,7 +11207,9 @@ function resolveDesignProps2(props) {
11202
11207
  };
11203
11208
  }
11204
11209
  function formatInvoices(invoices) {
11205
- return (invoices || []).map(({ amountDue, dueDate, url }) => ({
11210
+ return (invoices || []).filter(
11211
+ ({ url, amountDue, amountPaid }) => url && (amountDue === 0 || amountPaid > 0)
11212
+ ).sort((a2, b2) => a2.dueDate && b2.dueDate ? +b2.dueDate - +a2.dueDate : 1).map(({ amountDue, dueDate, url }) => ({
11206
11213
  ...dueDate && { date: toPrettyDate(dueDate) },
11207
11214
  amount: formatCurrency(amountDue),
11208
11215
  url
@@ -11213,26 +11220,34 @@ var InvoiceDate = ({ date, fontStyle, url }) => {
11213
11220
  const dateText = /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
11214
11221
  Text,
11215
11222
  {
11223
+ ...url && { onClick: () => {
11224
+ } },
11216
11225
  $font: theme.typography[fontStyle].fontFamily,
11217
11226
  $size: theme.typography[fontStyle].fontSize,
11218
11227
  $weight: theme.typography[fontStyle].fontWeight,
11219
- $color: theme.typography[fontStyle].color,
11228
+ $color: url ? theme.typography.link.color : theme.typography.text.color,
11220
11229
  children: date
11221
11230
  }
11222
11231
  );
11223
11232
  if (url) {
11224
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("a", { href: url, target: "_blank", children: dateText });
11233
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("a", { href: url, target: "_blank", children: dateText });
11225
11234
  }
11226
11235
  return dateText;
11227
11236
  };
11228
- var Invoices = (0, import_react15.forwardRef)(({ className, ...rest }, ref) => {
11237
+ var Invoices = (0, import_react15.forwardRef)(({ className, data, ...rest }, ref) => {
11229
11238
  const props = resolveDesignProps2(rest);
11230
11239
  const theme = nt();
11231
11240
  const { api } = useEmbed();
11232
- const [invoices, setInvoices] = (0, import_react15.useState)(() => formatInvoices(rest.data));
11241
+ const [invoices, setInvoices] = (0, import_react15.useState)(() => formatInvoices(data));
11242
+ const [listSize, setListSize] = (0, import_react15.useState)(props.limit.number);
11243
+ const toggleListSize = () => {
11244
+ setListSize(
11245
+ (prev2) => prev2 !== props.limit.number ? props.limit.number : 12
11246
+ );
11247
+ };
11233
11248
  (0, import_react15.useEffect)(() => {
11234
- api?.listInvoices().then(({ data }) => {
11235
- setInvoices(formatInvoices(data));
11249
+ api?.listInvoices().then(({ data: data2 }) => {
11250
+ setInvoices(formatInvoices(data2));
11236
11251
  });
11237
11252
  }, [api]);
11238
11253
  return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Element, { ref, className, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(Flex, { $flexDirection: "column", $gap: "1rem", children: [
@@ -11246,10 +11261,7 @@ var Invoices = (0, import_react15.forwardRef)(({ className, ...rest }, ref) => {
11246
11261
  children: "Invoices"
11247
11262
  }
11248
11263
  ) }),
11249
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Flex, { $flexDirection: "column", $gap: "0.5rem", children: invoices.slice(
11250
- 0,
11251
- props.limit.isVisible && props.limit.number || invoices.length
11252
- ).map(({ date, amount, url }, index) => {
11264
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Flex, { $flexDirection: "column", $gap: "0.5rem", children: invoices.slice(0, listSize).map(({ date, amount, url }, index) => {
11253
11265
  return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(Flex, { $justifyContent: "space-between", children: [
11254
11266
  props.date.isVisible && date && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
11255
11267
  InvoiceDate,
@@ -11272,15 +11284,25 @@ var Invoices = (0, import_react15.forwardRef)(({ className, ...rest }, ref) => {
11272
11284
  ] }, index);
11273
11285
  }) }),
11274
11286
  props.collapse.isVisible && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(Flex, { $alignItems: "center", $gap: "0.5rem", children: [
11275
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Icon2, { name: "chevron-down", style: { color: "#D0D0D0" } }),
11276
11287
  /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
11288
+ Icon2,
11289
+ {
11290
+ name: `chevron-${listSize === props.limit.number ? "down" : "up"}`,
11291
+ style: { color: "#D0D0D0" }
11292
+ }
11293
+ ),
11294
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
11277
11295
  Text,
11278
11296
  {
11297
+ onClick: toggleListSize,
11279
11298
  $font: theme.typography[props.collapse.fontStyle].fontFamily,
11280
11299
  $size: theme.typography[props.collapse.fontStyle].fontSize,
11281
11300
  $weight: theme.typography[props.collapse.fontStyle].fontWeight,
11282
11301
  $color: theme.typography[props.collapse.fontStyle].color,
11283
- children: "See all"
11302
+ children: [
11303
+ "See ",
11304
+ listSize === props.limit.number ? "more" : "less"
11305
+ ]
11284
11306
  }
11285
11307
  )
11286
11308
  ] })
@@ -11312,7 +11334,9 @@ function resolveDesignProps3(props) {
11312
11334
  usage: {
11313
11335
  isVisible: props.usage?.isVisible ?? true,
11314
11336
  fontStyle: props.usage?.fontStyle ?? "heading5"
11315
- }
11337
+ },
11338
+ // there is a typescript bug with `RecursivePartial` so we must cast to `string[] | undefined`
11339
+ visibleFeatures: props.visibleFeatures
11316
11340
  };
11317
11341
  }
11318
11342
  var MeteredFeatures = (0, import_react16.forwardRef)(({ className, ...rest }, ref) => {
@@ -11322,13 +11346,22 @@ var MeteredFeatures = (0, import_react16.forwardRef)(({ className, ...rest }, re
11322
11346
  const theme = nt();
11323
11347
  const { data } = useEmbed();
11324
11348
  const isLightBackground = useIsLightBackground();
11325
- const features = (data.featureUsage?.features || []).filter(({ feature }) => {
11326
- return feature?.featureType === "event" || feature?.featureType === "trait";
11327
- });
11328
- if (features.length === 0) {
11349
+ const featureUsage = props.visibleFeatures ? props.visibleFeatures.reduce((acc, id) => {
11350
+ const mappedFeatureUsage = data.featureUsage?.features.find(
11351
+ (usage) => usage.feature?.id === id
11352
+ );
11353
+ if (mappedFeatureUsage?.feature?.featureType === "event" || mappedFeatureUsage?.feature?.featureType === "trait") {
11354
+ acc.push(mappedFeatureUsage);
11355
+ }
11356
+ return acc;
11357
+ }, []) : (data.featureUsage?.features || []).filter(
11358
+ (usage) => usage.feature?.featureType === "event" || usage.feature?.featureType === "trait"
11359
+ );
11360
+ const shouldShowFeatures = featureUsage.length > 0 || data.company?.plan || (data.company?.addOns ?? []).length > 0 || false;
11361
+ if (!shouldShowFeatures) {
11329
11362
  return null;
11330
11363
  }
11331
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Flex, { ref, className, $flexDirection: "column", children: features.map(({ allocation, feature, usage }, index) => {
11364
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Flex, { ref, className, $flexDirection: "column", children: featureUsage.map(({ allocation, feature, usage }, index) => {
11332
11365
  return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(Element, { as: Flex, $gap: "1.5rem", children: [
11333
11366
  props.icon.isVisible && feature?.icon && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
11334
11367
  IconRound,
@@ -11968,7 +12001,7 @@ var UpcomingBill = (0, import_react20.forwardRef)(({ className, ...rest }, ref)
11968
12001
  const { upcomingInvoice } = (0, import_react20.useMemo)(() => {
11969
12002
  return {
11970
12003
  upcomingInvoice: {
11971
- ...data.upcomingInvoice?.amountDue && {
12004
+ ...typeof data.upcomingInvoice?.amountDue === "number" && {
11972
12005
  amountDue: data.upcomingInvoice.amountDue
11973
12006
  },
11974
12007
  ...data.subscription?.interval && {
@@ -11980,11 +12013,11 @@ var UpcomingBill = (0, import_react20.forwardRef)(({ className, ...rest }, ref)
11980
12013
  }
11981
12014
  };
11982
12015
  }, [data.subscription, data.upcomingInvoice]);
11983
- if (!upcomingInvoice.amountDue || !upcomingInvoice.dueDate) {
12016
+ if (typeof upcomingInvoice.amountDue !== "number" || !upcomingInvoice.dueDate) {
11984
12017
  return null;
11985
12018
  }
11986
12019
  return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(Element, { ref, className, children: [
11987
- props.header.isVisible && upcomingInvoice.dueDate && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
12020
+ props.header.isVisible && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
11988
12021
  Flex,
11989
12022
  {
11990
12023
  $justifyContent: "space-between",
@@ -12006,7 +12039,7 @@ var UpcomingBill = (0, import_react20.forwardRef)(({ className, ...rest }, ref)
12006
12039
  )
12007
12040
  }
12008
12041
  ),
12009
- upcomingInvoice.amountDue && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(Flex, { $justifyContent: "space-between", $alignItems: "start", $gap: "1rem", children: [
12042
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(Flex, { $justifyContent: "space-between", $alignItems: "start", $gap: "1rem", children: [
12010
12043
  props.price.isVisible && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Flex, { $alignItems: "end", $flexGrow: "1", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
12011
12044
  Text,
12012
12045
  {
@@ -12047,7 +12080,8 @@ var components = {
12047
12080
  IncludedFeatures,
12048
12081
  MeteredFeatures,
12049
12082
  UpcomingBill,
12050
- PaymentMethod
12083
+ PaymentMethod,
12084
+ Invoices
12051
12085
  };
12052
12086
  function createRenderer(options) {
12053
12087
  const { useFallback = false } = options || {};
@@ -1290,6 +1290,7 @@ declare interface DesignProps {
1290
1290
  isVisible: boolean;
1291
1291
  fontStyle: FontStyle;
1292
1292
  };
1293
+ visibleFeatures?: string[];
1293
1294
  }
1294
1295
 
1295
1296
  declare interface DesignProps_2 {
@@ -1335,6 +1336,7 @@ declare interface DesignProps_3 {
1335
1336
  isVisible: boolean;
1336
1337
  fontStyle: FontStyle;
1337
1338
  };
1339
+ visibleFeatures?: string[];
1338
1340
  }
1339
1341
 
1340
1342
  declare interface DesignProps_4 {
@@ -2398,7 +2400,7 @@ declare interface InvoiceResponseData {
2398
2400
  url?: string | null;
2399
2401
  }
2400
2402
 
2401
- export declare const Invoices: ForwardRefExoticComponent<ElementProps & DesignProps_2 & {
2403
+ export declare const Invoices: ForwardRefExoticComponent<ElementProps & RecursivePartial<DesignProps_2> & {
2402
2404
  data?: ListInvoicesResponse["data"];
2403
2405
  } & HTMLAttributes<HTMLDivElement> & RefAttributes<HTMLDivElement | null>>;
2404
2406
 
@@ -8896,7 +8896,7 @@ var EmbedProvider = ({
8896
8896
  useEffect(() => {
8897
8897
  if (accessToken) {
8898
8898
  const { headers = {} } = apiConfig ?? {};
8899
- headers["X-Schematic-Components-Version"] = "0.3.10";
8899
+ headers["X-Schematic-Components-Version"] = "0.3.12";
8900
8900
  headers["X-Schematic-Session-ID"] = sessionIdRef.current;
8901
8901
  const config = new Configuration({
8902
8902
  ...apiConfig,
@@ -11019,7 +11019,9 @@ function resolveDesignProps(props) {
11019
11019
  usage: {
11020
11020
  isVisible: props.usage?.isVisible ?? true,
11021
11021
  fontStyle: props.usage?.fontStyle ?? "heading6"
11022
- }
11022
+ },
11023
+ // there is a typescript bug with `RecursivePartial` so we must cast to `string[] | undefined`
11024
+ visibleFeatures: props.visibleFeatures
11023
11025
  };
11024
11026
  }
11025
11027
  var IncludedFeatures = forwardRef5(({ className, ...rest }, ref) => {
@@ -11029,7 +11031,16 @@ var IncludedFeatures = forwardRef5(({ className, ...rest }, ref) => {
11029
11031
  const elements = useRef3([]);
11030
11032
  const shouldWrapChildren = useWrapChildren(elements.current);
11031
11033
  const isLightBackground = useIsLightBackground();
11032
- const shouldShowFeatures = (data.featureUsage?.features ?? []).length > 0 || data.company?.plan || (data.company?.addOns ?? []).length > 0 || false;
11034
+ const featureUsage = props.visibleFeatures ? props.visibleFeatures.reduce((acc, id) => {
11035
+ const mappedFeatureUsage = data.featureUsage?.features.find(
11036
+ (usage) => usage.feature?.id === id
11037
+ );
11038
+ if (mappedFeatureUsage) {
11039
+ acc.push(mappedFeatureUsage);
11040
+ }
11041
+ return acc;
11042
+ }, []) : data.featureUsage?.features || [];
11043
+ const shouldShowFeatures = featureUsage.length > 0 || data.company?.plan || (data.company?.addOns ?? []).length > 0 || false;
11033
11044
  if (!shouldShowFeatures) {
11034
11045
  return null;
11035
11046
  }
@@ -11052,82 +11063,76 @@ var IncludedFeatures = forwardRef5(({ className, ...rest }, ref) => {
11052
11063
  children: props.header.text
11053
11064
  }
11054
11065
  ) }),
11055
- (data.featureUsage?.features || []).reduce(
11056
- (acc, { allocation, feature, usage }, index) => {
11057
- return [
11058
- ...acc,
11059
- /* @__PURE__ */ jsxs8(
11060
- Flex,
11061
- {
11062
- ref: (el) => el && elements.current.push(el),
11063
- $flexWrap: "wrap",
11064
- $justifyContent: "space-between",
11065
- $alignItems: "center",
11066
- $gap: "1rem",
11067
- children: [
11068
- /* @__PURE__ */ jsxs8(Flex, { $flexGrow: "1", $flexBasis: "min-content", $gap: "1rem", children: [
11069
- props.icons.isVisible && feature?.icon && /* @__PURE__ */ jsx15(
11070
- IconRound,
11066
+ featureUsage.map(({ allocation, feature, usage }, index) => {
11067
+ return /* @__PURE__ */ jsxs8(
11068
+ Flex,
11069
+ {
11070
+ ref: (el) => el && elements.current.push(el),
11071
+ $flexWrap: "wrap",
11072
+ $justifyContent: "space-between",
11073
+ $alignItems: "center",
11074
+ $gap: "1rem",
11075
+ children: [
11076
+ /* @__PURE__ */ jsxs8(Flex, { $flexGrow: "1", $flexBasis: "min-content", $gap: "1rem", children: [
11077
+ props.icons.isVisible && feature?.icon && /* @__PURE__ */ jsx15(
11078
+ IconRound,
11079
+ {
11080
+ name: feature.icon,
11081
+ size: "sm",
11082
+ colors: [
11083
+ theme.primary,
11084
+ isLightBackground ? "hsla(0, 0%, 0%, 0.0625)" : "hsla(0, 0%, 100%, 0.25)"
11085
+ ]
11086
+ }
11087
+ ),
11088
+ feature?.name && /* @__PURE__ */ jsx15(Flex, { $alignItems: "center", children: /* @__PURE__ */ jsx15(
11089
+ Text,
11090
+ {
11091
+ $font: theme.typography[props.icons.fontStyle].fontFamily,
11092
+ $size: theme.typography[props.icons.fontStyle].fontSize,
11093
+ $weight: theme.typography[props.icons.fontStyle].fontWeight,
11094
+ $color: theme.typography[props.icons.fontStyle].color,
11095
+ children: feature.name
11096
+ }
11097
+ ) })
11098
+ ] }),
11099
+ (feature?.featureType === "event" || feature?.featureType === "trait") && feature?.name && /* @__PURE__ */ jsxs8(
11100
+ Box,
11101
+ {
11102
+ $flexBasis: "min-content",
11103
+ $flexGrow: "1",
11104
+ $textAlign: shouldWrapChildren ? "left" : "right",
11105
+ children: [
11106
+ props.entitlement.isVisible && /* @__PURE__ */ jsx15(Box, { children: /* @__PURE__ */ jsx15(
11107
+ Text,
11071
11108
  {
11072
- name: feature.icon,
11073
- size: "sm",
11074
- colors: [
11075
- theme.primary,
11076
- isLightBackground ? "hsla(0, 0%, 0%, 0.0625)" : "hsla(0, 0%, 100%, 0.25)"
11077
- ]
11109
+ $font: theme.typography[props.entitlement.fontStyle].fontFamily,
11110
+ $size: theme.typography[props.entitlement.fontStyle].fontSize,
11111
+ $weight: theme.typography[props.entitlement.fontStyle].fontWeight,
11112
+ $lineHeight: 1.25,
11113
+ $color: theme.typography[props.entitlement.fontStyle].color,
11114
+ children: typeof allocation === "number" ? `${formatNumber(allocation)} ${(0, import_pluralize2.default)(feature.name, allocation)}` : `Unlimited ${(0, import_pluralize2.default)(feature.name)}`
11078
11115
  }
11079
- ),
11080
- feature?.name && /* @__PURE__ */ jsx15(Flex, { $alignItems: "center", children: /* @__PURE__ */ jsx15(
11116
+ ) }),
11117
+ props.usage.isVisible && /* @__PURE__ */ jsx15(Box, { $whiteSpace: "nowrap", children: /* @__PURE__ */ jsx15(
11081
11118
  Text,
11082
11119
  {
11083
- $font: theme.typography[props.icons.fontStyle].fontFamily,
11084
- $size: theme.typography[props.icons.fontStyle].fontSize,
11085
- $weight: theme.typography[props.icons.fontStyle].fontWeight,
11086
- $color: theme.typography[props.icons.fontStyle].color,
11087
- children: feature.name
11120
+ $font: theme.typography[props.usage.fontStyle].fontFamily,
11121
+ $size: theme.typography[props.usage.fontStyle].fontSize,
11122
+ $weight: theme.typography[props.usage.fontStyle].fontWeight,
11123
+ $lineHeight: 1.5,
11124
+ $color: theme.typography[props.usage.fontStyle].color,
11125
+ children: typeof usage === "number" && /* @__PURE__ */ jsx15(Fragment2, { children: typeof allocation === "number" ? `${formatNumber(usage)} of ${formatNumber(allocation)} used` : `${formatNumber(usage)} used` })
11088
11126
  }
11089
11127
  ) })
11090
- ] }),
11091
- (feature?.featureType === "event" || feature?.featureType === "trait") && feature?.name && /* @__PURE__ */ jsxs8(
11092
- Box,
11093
- {
11094
- $flexBasis: "min-content",
11095
- $flexGrow: "1",
11096
- $textAlign: shouldWrapChildren ? "left" : "right",
11097
- children: [
11098
- props.entitlement.isVisible && /* @__PURE__ */ jsx15(Box, { children: /* @__PURE__ */ jsx15(
11099
- Text,
11100
- {
11101
- $font: theme.typography[props.entitlement.fontStyle].fontFamily,
11102
- $size: theme.typography[props.entitlement.fontStyle].fontSize,
11103
- $weight: theme.typography[props.entitlement.fontStyle].fontWeight,
11104
- $lineHeight: 1.25,
11105
- $color: theme.typography[props.entitlement.fontStyle].color,
11106
- children: typeof allocation === "number" ? `${formatNumber(allocation)} ${(0, import_pluralize2.default)(feature.name, allocation)}` : `Unlimited ${(0, import_pluralize2.default)(feature.name)}`
11107
- }
11108
- ) }),
11109
- props.usage.isVisible && /* @__PURE__ */ jsx15(Box, { $whiteSpace: "nowrap", children: /* @__PURE__ */ jsx15(
11110
- Text,
11111
- {
11112
- $font: theme.typography[props.usage.fontStyle].fontFamily,
11113
- $size: theme.typography[props.usage.fontStyle].fontSize,
11114
- $weight: theme.typography[props.usage.fontStyle].fontWeight,
11115
- $lineHeight: 1.5,
11116
- $color: theme.typography[props.usage.fontStyle].color,
11117
- children: typeof usage === "number" && /* @__PURE__ */ jsx15(Fragment2, { children: typeof allocation === "number" ? `${formatNumber(usage)} of ${formatNumber(allocation)} used` : `${formatNumber(usage)} used` })
11118
- }
11119
- ) })
11120
- ]
11121
- }
11122
- )
11123
- ]
11124
- },
11125
- index
11126
- )
11127
- ];
11128
- },
11129
- []
11130
- )
11128
+ ]
11129
+ }
11130
+ )
11131
+ ]
11132
+ },
11133
+ index
11134
+ );
11135
+ })
11131
11136
  ]
11132
11137
  }
11133
11138
  );
@@ -11162,7 +11167,9 @@ function resolveDesignProps2(props) {
11162
11167
  };
11163
11168
  }
11164
11169
  function formatInvoices(invoices) {
11165
- return (invoices || []).map(({ amountDue, dueDate, url }) => ({
11170
+ return (invoices || []).filter(
11171
+ ({ url, amountDue, amountPaid }) => url && (amountDue === 0 || amountPaid > 0)
11172
+ ).sort((a2, b2) => a2.dueDate && b2.dueDate ? +b2.dueDate - +a2.dueDate : 1).map(({ amountDue, dueDate, url }) => ({
11166
11173
  ...dueDate && { date: toPrettyDate(dueDate) },
11167
11174
  amount: formatCurrency(amountDue),
11168
11175
  url
@@ -11173,26 +11180,34 @@ var InvoiceDate = ({ date, fontStyle, url }) => {
11173
11180
  const dateText = /* @__PURE__ */ jsx16(
11174
11181
  Text,
11175
11182
  {
11183
+ ...url && { onClick: () => {
11184
+ } },
11176
11185
  $font: theme.typography[fontStyle].fontFamily,
11177
11186
  $size: theme.typography[fontStyle].fontSize,
11178
11187
  $weight: theme.typography[fontStyle].fontWeight,
11179
- $color: theme.typography[fontStyle].color,
11188
+ $color: url ? theme.typography.link.color : theme.typography.text.color,
11180
11189
  children: date
11181
11190
  }
11182
11191
  );
11183
11192
  if (url) {
11184
- /* @__PURE__ */ jsx16("a", { href: url, target: "_blank", children: dateText });
11193
+ return /* @__PURE__ */ jsx16("a", { href: url, target: "_blank", children: dateText });
11185
11194
  }
11186
11195
  return dateText;
11187
11196
  };
11188
- var Invoices = forwardRef6(({ className, ...rest }, ref) => {
11197
+ var Invoices = forwardRef6(({ className, data, ...rest }, ref) => {
11189
11198
  const props = resolveDesignProps2(rest);
11190
11199
  const theme = nt();
11191
11200
  const { api } = useEmbed();
11192
- const [invoices, setInvoices] = useState5(() => formatInvoices(rest.data));
11201
+ const [invoices, setInvoices] = useState5(() => formatInvoices(data));
11202
+ const [listSize, setListSize] = useState5(props.limit.number);
11203
+ const toggleListSize = () => {
11204
+ setListSize(
11205
+ (prev2) => prev2 !== props.limit.number ? props.limit.number : 12
11206
+ );
11207
+ };
11193
11208
  useEffect5(() => {
11194
- api?.listInvoices().then(({ data }) => {
11195
- setInvoices(formatInvoices(data));
11209
+ api?.listInvoices().then(({ data: data2 }) => {
11210
+ setInvoices(formatInvoices(data2));
11196
11211
  });
11197
11212
  }, [api]);
11198
11213
  return /* @__PURE__ */ jsx16(Element, { ref, className, children: /* @__PURE__ */ jsxs9(Flex, { $flexDirection: "column", $gap: "1rem", children: [
@@ -11206,10 +11221,7 @@ var Invoices = forwardRef6(({ className, ...rest }, ref) => {
11206
11221
  children: "Invoices"
11207
11222
  }
11208
11223
  ) }),
11209
- /* @__PURE__ */ jsx16(Flex, { $flexDirection: "column", $gap: "0.5rem", children: invoices.slice(
11210
- 0,
11211
- props.limit.isVisible && props.limit.number || invoices.length
11212
- ).map(({ date, amount, url }, index) => {
11224
+ /* @__PURE__ */ jsx16(Flex, { $flexDirection: "column", $gap: "0.5rem", children: invoices.slice(0, listSize).map(({ date, amount, url }, index) => {
11213
11225
  return /* @__PURE__ */ jsxs9(Flex, { $justifyContent: "space-between", children: [
11214
11226
  props.date.isVisible && date && /* @__PURE__ */ jsx16(
11215
11227
  InvoiceDate,
@@ -11232,15 +11244,25 @@ var Invoices = forwardRef6(({ className, ...rest }, ref) => {
11232
11244
  ] }, index);
11233
11245
  }) }),
11234
11246
  props.collapse.isVisible && /* @__PURE__ */ jsxs9(Flex, { $alignItems: "center", $gap: "0.5rem", children: [
11235
- /* @__PURE__ */ jsx16(Icon2, { name: "chevron-down", style: { color: "#D0D0D0" } }),
11236
11247
  /* @__PURE__ */ jsx16(
11248
+ Icon2,
11249
+ {
11250
+ name: `chevron-${listSize === props.limit.number ? "down" : "up"}`,
11251
+ style: { color: "#D0D0D0" }
11252
+ }
11253
+ ),
11254
+ /* @__PURE__ */ jsxs9(
11237
11255
  Text,
11238
11256
  {
11257
+ onClick: toggleListSize,
11239
11258
  $font: theme.typography[props.collapse.fontStyle].fontFamily,
11240
11259
  $size: theme.typography[props.collapse.fontStyle].fontSize,
11241
11260
  $weight: theme.typography[props.collapse.fontStyle].fontWeight,
11242
11261
  $color: theme.typography[props.collapse.fontStyle].color,
11243
- children: "See all"
11262
+ children: [
11263
+ "See ",
11264
+ listSize === props.limit.number ? "more" : "less"
11265
+ ]
11244
11266
  }
11245
11267
  )
11246
11268
  ] })
@@ -11272,7 +11294,9 @@ function resolveDesignProps3(props) {
11272
11294
  usage: {
11273
11295
  isVisible: props.usage?.isVisible ?? true,
11274
11296
  fontStyle: props.usage?.fontStyle ?? "heading5"
11275
- }
11297
+ },
11298
+ // there is a typescript bug with `RecursivePartial` so we must cast to `string[] | undefined`
11299
+ visibleFeatures: props.visibleFeatures
11276
11300
  };
11277
11301
  }
11278
11302
  var MeteredFeatures = forwardRef7(({ className, ...rest }, ref) => {
@@ -11282,13 +11306,22 @@ var MeteredFeatures = forwardRef7(({ className, ...rest }, ref) => {
11282
11306
  const theme = nt();
11283
11307
  const { data } = useEmbed();
11284
11308
  const isLightBackground = useIsLightBackground();
11285
- const features = (data.featureUsage?.features || []).filter(({ feature }) => {
11286
- return feature?.featureType === "event" || feature?.featureType === "trait";
11287
- });
11288
- if (features.length === 0) {
11309
+ const featureUsage = props.visibleFeatures ? props.visibleFeatures.reduce((acc, id) => {
11310
+ const mappedFeatureUsage = data.featureUsage?.features.find(
11311
+ (usage) => usage.feature?.id === id
11312
+ );
11313
+ if (mappedFeatureUsage?.feature?.featureType === "event" || mappedFeatureUsage?.feature?.featureType === "trait") {
11314
+ acc.push(mappedFeatureUsage);
11315
+ }
11316
+ return acc;
11317
+ }, []) : (data.featureUsage?.features || []).filter(
11318
+ (usage) => usage.feature?.featureType === "event" || usage.feature?.featureType === "trait"
11319
+ );
11320
+ const shouldShowFeatures = featureUsage.length > 0 || data.company?.plan || (data.company?.addOns ?? []).length > 0 || false;
11321
+ if (!shouldShowFeatures) {
11289
11322
  return null;
11290
11323
  }
11291
- return /* @__PURE__ */ jsx17(Flex, { ref, className, $flexDirection: "column", children: features.map(({ allocation, feature, usage }, index) => {
11324
+ return /* @__PURE__ */ jsx17(Flex, { ref, className, $flexDirection: "column", children: featureUsage.map(({ allocation, feature, usage }, index) => {
11292
11325
  return /* @__PURE__ */ jsxs10(Element, { as: Flex, $gap: "1.5rem", children: [
11293
11326
  props.icon.isVisible && feature?.icon && /* @__PURE__ */ jsx17(
11294
11327
  IconRound,
@@ -11932,7 +11965,7 @@ var UpcomingBill = forwardRef10(({ className, ...rest }, ref) => {
11932
11965
  const { upcomingInvoice } = useMemo4(() => {
11933
11966
  return {
11934
11967
  upcomingInvoice: {
11935
- ...data.upcomingInvoice?.amountDue && {
11968
+ ...typeof data.upcomingInvoice?.amountDue === "number" && {
11936
11969
  amountDue: data.upcomingInvoice.amountDue
11937
11970
  },
11938
11971
  ...data.subscription?.interval && {
@@ -11944,11 +11977,11 @@ var UpcomingBill = forwardRef10(({ className, ...rest }, ref) => {
11944
11977
  }
11945
11978
  };
11946
11979
  }, [data.subscription, data.upcomingInvoice]);
11947
- if (!upcomingInvoice.amountDue || !upcomingInvoice.dueDate) {
11980
+ if (typeof upcomingInvoice.amountDue !== "number" || !upcomingInvoice.dueDate) {
11948
11981
  return null;
11949
11982
  }
11950
11983
  return /* @__PURE__ */ jsxs14(Element, { ref, className, children: [
11951
- props.header.isVisible && upcomingInvoice.dueDate && /* @__PURE__ */ jsx21(
11984
+ props.header.isVisible && /* @__PURE__ */ jsx21(
11952
11985
  Flex,
11953
11986
  {
11954
11987
  $justifyContent: "space-between",
@@ -11970,7 +12003,7 @@ var UpcomingBill = forwardRef10(({ className, ...rest }, ref) => {
11970
12003
  )
11971
12004
  }
11972
12005
  ),
11973
- upcomingInvoice.amountDue && /* @__PURE__ */ jsxs14(Flex, { $justifyContent: "space-between", $alignItems: "start", $gap: "1rem", children: [
12006
+ /* @__PURE__ */ jsxs14(Flex, { $justifyContent: "space-between", $alignItems: "start", $gap: "1rem", children: [
11974
12007
  props.price.isVisible && /* @__PURE__ */ jsx21(Flex, { $alignItems: "end", $flexGrow: "1", children: /* @__PURE__ */ jsx21(
11975
12008
  Text,
11976
12009
  {
@@ -12011,7 +12044,8 @@ var components = {
12011
12044
  IncludedFeatures,
12012
12045
  MeteredFeatures,
12013
12046
  UpcomingBill,
12014
- PaymentMethod
12047
+ PaymentMethod,
12048
+ Invoices
12015
12049
  };
12016
12050
  function createRenderer(options) {
12017
12051
  const { useFallback = false } = options || {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@schematichq/schematic-components",
3
- "version": "0.3.10",
3
+ "version": "0.3.12",
4
4
  "main": "dist/schematic-components.cjs.js",
5
5
  "module": "dist/schematic-components.esm.js",
6
6
  "types": "dist/schematic-components.d.ts",