@fanvue/ui 3.21.1 → 3.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/charts.d.ts CHANGED
@@ -12,11 +12,12 @@ export declare type CardHierarchy = "primary" | "secondary";
12
12
 
13
13
  /**
14
14
  * Wraps any chart with a structured header containing title, subtitle,
15
- * optional trend chip, date range label, info tooltip, and a loading
15
+ * optional trend indicator, date range label, info tooltip, and a loading
16
16
  * skeleton state.
17
17
  *
18
- * The surface treatment comes from the underlying {@link Card} and is driven by
19
- * the `hierarchy` prop.
18
+ * At `hierarchy="primary"` this implements the V2 Insight Card surface, which
19
+ * differs from {@link Card}'s own primary hierarchy: a white fill, the strong
20
+ * border, and a 12px radius.
20
21
  *
21
22
  * @example
22
23
  * ```tsx
@@ -35,7 +36,11 @@ export declare const ChartCard: React_2.ForwardRefExoticComponent<ChartCardProps
35
36
 
36
37
  /** Props for {@link ChartCard}. */
37
38
  export declare interface ChartCardProps extends Omit<React_2.HTMLAttributes<HTMLDivElement>, "title"> {
38
- /** Surface treatment of the underlying {@link Card}. @default "primary" */
39
+ /**
40
+ * Surface treatment. `primary` follows the V2 Insight Card spec (white fill,
41
+ * strong border, 12px radius); `secondary` uses the {@link Card} secondary
42
+ * surface. @default "primary"
43
+ */
39
44
  hierarchy?: CardHierarchy;
40
45
  /** Card title text. Pass translated string for i18n. */
41
46
  title: React_2.ReactNode;
@@ -47,11 +52,14 @@ export declare interface ChartCardProps extends Omit<React_2.HTMLAttributes<HTML
47
52
  tooltipAriaLabel?: string;
48
53
  /** Date range or period label shown below the subtitle. */
49
54
  dateInfo?: React_2.ReactNode;
50
- /** Trend indicator chip config. Only rendered when {@link subtitle} is also provided. */
55
+ /**
56
+ * Trend indicator config. Rendered as a coloured directional arrow and label
57
+ * beside the subtitle, so it is only shown when {@link subtitle} is provided.
58
+ */
51
59
  trendChip?: {
52
- /** Display label (e.g. "12.5%"). */
60
+ /** Display label (e.g. "12.5% vs prev"). */
53
61
  label: React_2.ReactNode;
54
- /** Whether the trend is positive (green) or negative (red). */
62
+ /** Whether the trend is positive (green, arrow up) or negative (red, arrow down). */
55
63
  trend: "positive" | "negative";
56
64
  };
57
65
  /** Show loading skeleton instead of content. @default false */
@@ -6,7 +6,8 @@ const React = require("react");
6
6
  const cn = require("../../utils/cn.cjs");
7
7
  const Card = require("../Card/Card.cjs");
8
8
  const IconButton = require("../IconButton/IconButton.cjs");
9
- const InfoCircleIcon = require("../Icons/InfoCircleIcon.cjs");
9
+ const ArrowUpRightIcon = require("../Icons/ArrowUpRightIcon.cjs");
10
+ const InfoIcon = require("../Icons/InfoIcon.cjs");
10
11
  const Skeleton = require("../Skeleton/Skeleton.cjs");
11
12
  const Tooltip = require("../Tooltip/Tooltip.cjs");
12
13
  function _interopNamespaceDefault(e) {
@@ -27,8 +28,11 @@ function _interopNamespaceDefault(e) {
27
28
  }
28
29
  const React__namespace = /* @__PURE__ */ _interopNamespaceDefault(React);
29
30
  const TREND_CLASSES = {
30
- positive: "bg-success-surface text-success-content",
31
- negative: "bg-error-surface text-error-content"
31
+ positive: "text-success-content",
32
+ negative: "text-error-content"
33
+ };
34
+ const SURFACE_CLASSES = {
35
+ primary: "rounded-sm border-border-strong bg-background-primary"
32
36
  };
33
37
  const ChartCard = React__namespace.forwardRef(
34
38
  ({
@@ -44,45 +48,66 @@ const ChartCard = React__namespace.forwardRef(
44
48
  children,
45
49
  ...props
46
50
  }, ref) => {
47
- return /* @__PURE__ */ jsxRuntime.jsx(Card.Card, { ref, hierarchy, noPadding: true, className, ...props, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2 p-4", children: [
48
- loading ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
49
- /* @__PURE__ */ jsxRuntime.jsx(Skeleton.Skeleton, { animation: "wave", variant: "rounded", className: "h-4 w-32" }),
50
- /* @__PURE__ */ jsxRuntime.jsx(Skeleton.Skeleton, { animation: "wave", variant: "rounded", className: "h-7 w-44" }),
51
- /* @__PURE__ */ jsxRuntime.jsx(Skeleton.Skeleton, { animation: "wave", variant: "rounded", className: "h-3 w-24" })
52
- ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
53
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
54
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "typography-body-small-14px-semibold text-content-primary", children: title }),
55
- tooltip && /* @__PURE__ */ jsxRuntime.jsx(Tooltip.TooltipProvider, { children: /* @__PURE__ */ jsxRuntime.jsxs(Tooltip.Tooltip, { children: [
56
- /* @__PURE__ */ jsxRuntime.jsx(Tooltip.TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
57
- IconButton.IconButton,
58
- {
59
- variant: "tertiary",
60
- size: "32",
61
- "aria-label": tooltipAriaLabel,
62
- className: "text-content-tertiary hover:text-content-primary focus-visible:text-content-primary active:text-content-primary",
63
- icon: /* @__PURE__ */ jsxRuntime.jsx(InfoCircleIcon.InfoCircleIcon, {})
64
- }
65
- ) }),
66
- /* @__PURE__ */ jsxRuntime.jsx(Tooltip.TooltipContent, { children: tooltip })
67
- ] }) })
68
- ] }),
69
- subtitle && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
70
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "typography-header-heading-sm text-content-primary", children: subtitle }),
71
- trendChip && /* @__PURE__ */ jsxRuntime.jsx(
72
- "span",
73
- {
74
- className: cn.cn(
75
- "typography-description-12px-semibold whitespace-nowrap rounded-full px-2 py-0.5",
76
- TREND_CLASSES[trendChip.trend]
77
- ),
78
- children: trendChip.label
79
- }
80
- )
81
- ] }),
82
- dateInfo && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "typography-description-12px-regular text-content-tertiary", children: dateInfo })
83
- ] }),
84
- children && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-auto", children })
85
- ] }) });
51
+ return /* @__PURE__ */ jsxRuntime.jsx(
52
+ Card.Card,
53
+ {
54
+ ref,
55
+ hierarchy,
56
+ noPadding: true,
57
+ className: cn.cn(SURFACE_CLASSES[hierarchy], className),
58
+ ...props,
59
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2 p-4", children: [
60
+ loading ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
61
+ /* @__PURE__ */ jsxRuntime.jsx(Skeleton.Skeleton, { animation: "wave", variant: "rounded", className: "h-4 w-32" }),
62
+ /* @__PURE__ */ jsxRuntime.jsx(Skeleton.Skeleton, { animation: "wave", variant: "rounded", className: "h-7 w-44" }),
63
+ /* @__PURE__ */ jsxRuntime.jsx(Skeleton.Skeleton, { animation: "wave", variant: "rounded", className: "h-3 w-24" })
64
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
65
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
66
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "typography-body-small-14px-regular text-content-secondary", children: title }),
67
+ tooltip && /* @__PURE__ */ jsxRuntime.jsx(Tooltip.TooltipProvider, { children: /* @__PURE__ */ jsxRuntime.jsxs(Tooltip.Tooltip, { children: [
68
+ /* @__PURE__ */ jsxRuntime.jsx(Tooltip.TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
69
+ IconButton.IconButton,
70
+ {
71
+ variant: "tertiary",
72
+ size: "32",
73
+ "aria-label": tooltipAriaLabel,
74
+ className: "text-icons-primary hover:text-content-primary focus-visible:text-content-primary active:text-content-primary",
75
+ icon: /* @__PURE__ */ jsxRuntime.jsx(InfoIcon.InfoIcon, { size: 16 })
76
+ }
77
+ ) }),
78
+ /* @__PURE__ */ jsxRuntime.jsx(Tooltip.TooltipContent, { children: tooltip })
79
+ ] }) })
80
+ ] }),
81
+ subtitle && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-end gap-2", children: [
82
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "typography-header-heading-sm text-content-primary", children: subtitle }),
83
+ trendChip && /* @__PURE__ */ jsxRuntime.jsxs(
84
+ "span",
85
+ {
86
+ className: cn.cn(
87
+ "flex items-center gap-1 pb-px",
88
+ TREND_CLASSES[trendChip.trend]
89
+ ),
90
+ children: [
91
+ /* @__PURE__ */ jsxRuntime.jsx(
92
+ ArrowUpRightIcon.ArrowUpRightIcon,
93
+ {
94
+ className: cn.cn(
95
+ "size-4 shrink-0",
96
+ trendChip.trend === "negative" && "rotate-90"
97
+ )
98
+ }
99
+ ),
100
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "typography-body-small-14px-regular whitespace-nowrap", children: trendChip.label })
101
+ ]
102
+ }
103
+ )
104
+ ] }),
105
+ dateInfo && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "typography-description-12px-regular text-content-tertiary", children: dateInfo })
106
+ ] }),
107
+ children && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-auto", children })
108
+ ] })
109
+ }
110
+ );
86
111
  }
87
112
  );
88
113
  ChartCard.displayName = "ChartCard";
@@ -1 +1 @@
1
- {"version":3,"file":"ChartCard.cjs","sources":["../../../../src/components/Chart/ChartCard.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { Card, type CardHierarchy } from \"../Card/Card\";\nimport { IconButton } from \"../IconButton/IconButton\";\nimport { InfoCircleIcon } from \"../Icons/InfoCircleIcon\";\nimport { Skeleton } from \"../Skeleton/Skeleton\";\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from \"../Tooltip/Tooltip\";\n\n/** Props for {@link ChartCard}. */\nexport interface ChartCardProps extends Omit<React.HTMLAttributes<HTMLDivElement>, \"title\"> {\n /** Surface treatment of the underlying {@link Card}. @default \"primary\" */\n hierarchy?: CardHierarchy;\n /** Card title text. Pass translated string for i18n. */\n title: React.ReactNode;\n /** Large subtitle value (e.g. formatted price or count). */\n subtitle?: React.ReactNode;\n /** Tooltip text shown next to the title. Pass translated string for i18n. */\n tooltip?: React.ReactNode;\n /** Accessible label for the info tooltip trigger. Override for i18n. @default \"More info\" */\n tooltipAriaLabel?: string;\n /** Date range or period label shown below the subtitle. */\n dateInfo?: React.ReactNode;\n /** Trend indicator chip config. Only rendered when {@link subtitle} is also provided. */\n trendChip?: {\n /** Display label (e.g. \"12.5%\"). */\n label: React.ReactNode;\n /** Whether the trend is positive (green) or negative (red). */\n trend: \"positive\" | \"negative\";\n };\n /** Show loading skeleton instead of content. @default false */\n loading?: boolean;\n /** Chart content rendered below the header. */\n children?: React.ReactNode;\n}\n\nconst TREND_CLASSES: Record<\"positive\" | \"negative\", string> = {\n positive: \"bg-success-surface text-success-content\",\n negative: \"bg-error-surface text-error-content\",\n};\n\n/**\n * Wraps any chart with a structured header containing title, subtitle,\n * optional trend chip, date range label, info tooltip, and a loading\n * skeleton state.\n *\n * The surface treatment comes from the underlying {@link Card} and is driven by\n * the `hierarchy` prop.\n *\n * @example\n * ```tsx\n * <ChartCard\n * title=\"Revenue\"\n * subtitle=\"$4,523\"\n * trendChip={{ label: \"+12.5%\", trend: \"positive\" }}\n * dateInfo=\"Jan 1 – Mar 17\"\n * tooltip=\"Total revenue for the selected period.\"\n * >\n * <MyLineChart />\n * </ChartCard>\n * ```\n */\nexport const ChartCard = React.forwardRef<HTMLDivElement, ChartCardProps>(\n (\n {\n className,\n hierarchy = \"primary\",\n title,\n subtitle,\n tooltip,\n tooltipAriaLabel = \"More info\",\n dateInfo,\n trendChip,\n loading = false,\n children,\n ...props\n },\n ref,\n ) => {\n return (\n <Card ref={ref} hierarchy={hierarchy} noPadding className={className} {...props}>\n <div className=\"flex flex-col gap-2 p-4\">\n {loading ? (\n <>\n <Skeleton animation=\"wave\" variant=\"rounded\" className=\"h-4 w-32\" />\n <Skeleton animation=\"wave\" variant=\"rounded\" className=\"h-7 w-44\" />\n <Skeleton animation=\"wave\" variant=\"rounded\" className=\"h-3 w-24\" />\n </>\n ) : (\n <>\n <div className=\"flex items-center gap-1.5\">\n <span className=\"typography-body-small-14px-semibold text-content-primary\">\n {title}\n </span>\n {tooltip && (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <IconButton\n variant=\"tertiary\"\n size=\"32\"\n aria-label={tooltipAriaLabel}\n className=\"text-content-tertiary hover:text-content-primary focus-visible:text-content-primary active:text-content-primary\"\n icon={<InfoCircleIcon />}\n />\n </TooltipTrigger>\n <TooltipContent>{tooltip}</TooltipContent>\n </Tooltip>\n </TooltipProvider>\n )}\n </div>\n {subtitle && (\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"typography-header-heading-sm text-content-primary\">\n {subtitle}\n </span>\n {trendChip && (\n <span\n className={cn(\n \"typography-description-12px-semibold whitespace-nowrap rounded-full px-2 py-0.5\",\n TREND_CLASSES[trendChip.trend],\n )}\n >\n {trendChip.label}\n </span>\n )}\n </div>\n )}\n {dateInfo && (\n <span className=\"typography-description-12px-regular text-content-tertiary\">\n {dateInfo}\n </span>\n )}\n </>\n )}\n {children && <div className=\"mt-auto\">{children}</div>}\n </div>\n </Card>\n );\n },\n);\nChartCard.displayName = \"ChartCard\";\n"],"names":["React","jsx","Card","jsxs","Fragment","Skeleton","TooltipProvider","Tooltip","TooltipTrigger","IconButton","InfoCircleIcon","TooltipContent","cn"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmCA,MAAM,gBAAyD;AAAA,EAC7D,UAAU;AAAA,EACV,UAAU;AACZ;AAuBO,MAAM,YAAYA,iBAAM;AAAA,EAC7B,CACE;AAAA,IACE;AAAA,IACA,YAAY;AAAA,IACZ;AAAA,IACA;AAAA,IACA;AAAA,IACA,mBAAmB;AAAA,IACnB;AAAA,IACA;AAAA,IACA,UAAU;AAAA,IACV;AAAA,IACA,GAAG;AAAA,EAAA,GAEL,QACG;AACH,WACEC,2BAAAA,IAACC,KAAAA,MAAA,EAAK,KAAU,WAAsB,WAAS,MAAC,WAAuB,GAAG,OACxE,UAAAC,gCAAC,OAAA,EAAI,WAAU,2BACZ,UAAA;AAAA,MAAA,UACCA,2BAAAA,KAAAC,qBAAA,EACE,UAAA;AAAA,QAAAH,+BAACI,SAAAA,YAAS,WAAU,QAAO,SAAQ,WAAU,WAAU,YAAW;AAAA,uCACjEA,SAAAA,UAAA,EAAS,WAAU,QAAO,SAAQ,WAAU,WAAU,YAAW;AAAA,uCACjEA,SAAAA,UAAA,EAAS,WAAU,QAAO,SAAQ,WAAU,WAAU,WAAA,CAAW;AAAA,MAAA,EAAA,CACpE,IAEAF,2BAAAA,KAAAC,WAAAA,UAAA,EACE,UAAA;AAAA,QAAAD,2BAAAA,KAAC,OAAA,EAAI,WAAU,6BACb,UAAA;AAAA,UAAAF,2BAAAA,IAAC,QAAA,EAAK,WAAU,4DACb,UAAA,OACH;AAAA,UACC,WACCA,2BAAAA,IAACK,yBAAA,EACC,UAAAH,gCAACI,QAAAA,SAAA,EACC,UAAA;AAAA,YAAAN,2BAAAA,IAACO,QAAAA,gBAAA,EAAe,SAAO,MACrB,UAAAP,2BAAAA;AAAAA,cAACQ,WAAAA;AAAAA,cAAA;AAAA,gBACC,SAAQ;AAAA,gBACR,MAAK;AAAA,gBACL,cAAY;AAAA,gBACZ,WAAU;AAAA,gBACV,qCAAOC,eAAAA,gBAAA,CAAA,CAAe;AAAA,cAAA;AAAA,YAAA,GAE1B;AAAA,YACAT,2BAAAA,IAACU,QAAAA,kBAAgB,UAAA,QAAA,CAAQ;AAAA,UAAA,EAAA,CAC3B,EAAA,CACF;AAAA,QAAA,GAEJ;AAAA,QACC,YACCR,2BAAAA,KAAC,OAAA,EAAI,WAAU,qCACb,UAAA;AAAA,UAAAF,2BAAAA,IAAC,QAAA,EAAK,WAAU,qDACb,UAAA,UACH;AAAA,UACC,aACCA,2BAAAA;AAAAA,YAAC;AAAA,YAAA;AAAA,cACC,WAAWW,GAAAA;AAAAA,gBACT;AAAA,gBACA,cAAc,UAAU,KAAK;AAAA,cAAA;AAAA,cAG9B,UAAA,UAAU;AAAA,YAAA;AAAA,UAAA;AAAA,QACb,GAEJ;AAAA,QAED,YACCX,2BAAAA,IAAC,QAAA,EAAK,WAAU,6DACb,UAAA,SAAA,CACH;AAAA,MAAA,GAEJ;AAAA,MAED,YAAYA,2BAAAA,IAAC,OAAA,EAAI,WAAU,WAAW,SAAA,CAAS;AAAA,IAAA,EAAA,CAClD,EAAA,CACF;AAAA,EAEJ;AACF;AACA,UAAU,cAAc;;"}
1
+ {"version":3,"file":"ChartCard.cjs","sources":["../../../../src/components/Chart/ChartCard.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { Card, type CardHierarchy } from \"../Card/Card\";\nimport { IconButton } from \"../IconButton/IconButton\";\nimport { ArrowUpRightIcon } from \"../Icons/ArrowUpRightIcon\";\nimport { InfoIcon } from \"../Icons/InfoIcon\";\nimport { Skeleton } from \"../Skeleton/Skeleton\";\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from \"../Tooltip/Tooltip\";\n\n/** Props for {@link ChartCard}. */\nexport interface ChartCardProps extends Omit<React.HTMLAttributes<HTMLDivElement>, \"title\"> {\n /**\n * Surface treatment. `primary` follows the V2 Insight Card spec (white fill,\n * strong border, 12px radius); `secondary` uses the {@link Card} secondary\n * surface. @default \"primary\"\n */\n hierarchy?: CardHierarchy;\n /** Card title text. Pass translated string for i18n. */\n title: React.ReactNode;\n /** Large subtitle value (e.g. formatted price or count). */\n subtitle?: React.ReactNode;\n /** Tooltip text shown next to the title. Pass translated string for i18n. */\n tooltip?: React.ReactNode;\n /** Accessible label for the info tooltip trigger. Override for i18n. @default \"More info\" */\n tooltipAriaLabel?: string;\n /** Date range or period label shown below the subtitle. */\n dateInfo?: React.ReactNode;\n /**\n * Trend indicator config. Rendered as a coloured directional arrow and label\n * beside the subtitle, so it is only shown when {@link subtitle} is provided.\n */\n trendChip?: {\n /** Display label (e.g. \"12.5% vs prev\"). */\n label: React.ReactNode;\n /** Whether the trend is positive (green, arrow up) or negative (red, arrow down). */\n trend: \"positive\" | \"negative\";\n };\n /** Show loading skeleton instead of content. @default false */\n loading?: boolean;\n /** Chart content rendered below the header. */\n children?: React.ReactNode;\n}\n\nconst TREND_CLASSES: Record<\"positive\" | \"negative\", string> = {\n positive: \"text-success-content\",\n negative: \"text-error-content\",\n};\n\nconst SURFACE_CLASSES: Partial<Record<CardHierarchy, string>> = {\n primary: \"rounded-sm border-border-strong bg-background-primary\",\n};\n\n/**\n * Wraps any chart with a structured header containing title, subtitle,\n * optional trend indicator, date range label, info tooltip, and a loading\n * skeleton state.\n *\n * At `hierarchy=\"primary\"` this implements the V2 Insight Card surface, which\n * differs from {@link Card}'s own primary hierarchy: a white fill, the strong\n * border, and a 12px radius.\n *\n * @example\n * ```tsx\n * <ChartCard\n * title=\"Revenue\"\n * subtitle=\"$4,523\"\n * trendChip={{ label: \"+12.5%\", trend: \"positive\" }}\n * dateInfo=\"Jan 1 – Mar 17\"\n * tooltip=\"Total revenue for the selected period.\"\n * >\n * <MyLineChart />\n * </ChartCard>\n * ```\n */\nexport const ChartCard = React.forwardRef<HTMLDivElement, ChartCardProps>(\n (\n {\n className,\n hierarchy = \"primary\",\n title,\n subtitle,\n tooltip,\n tooltipAriaLabel = \"More info\",\n dateInfo,\n trendChip,\n loading = false,\n children,\n ...props\n },\n ref,\n ) => {\n return (\n <Card\n ref={ref}\n hierarchy={hierarchy}\n noPadding\n className={cn(SURFACE_CLASSES[hierarchy], className)}\n {...props}\n >\n <div className=\"flex flex-col gap-2 p-4\">\n {loading ? (\n <>\n <Skeleton animation=\"wave\" variant=\"rounded\" className=\"h-4 w-32\" />\n <Skeleton animation=\"wave\" variant=\"rounded\" className=\"h-7 w-44\" />\n <Skeleton animation=\"wave\" variant=\"rounded\" className=\"h-3 w-24\" />\n </>\n ) : (\n <>\n <div className=\"flex items-center gap-1\">\n <span className=\"typography-body-small-14px-regular text-content-secondary\">\n {title}\n </span>\n {tooltip && (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <IconButton\n variant=\"tertiary\"\n size=\"32\"\n aria-label={tooltipAriaLabel}\n className=\"text-icons-primary hover:text-content-primary focus-visible:text-content-primary active:text-content-primary\"\n icon={<InfoIcon size={16} />}\n />\n </TooltipTrigger>\n <TooltipContent>{tooltip}</TooltipContent>\n </Tooltip>\n </TooltipProvider>\n )}\n </div>\n {subtitle && (\n <div className=\"flex flex-wrap items-end gap-2\">\n <span className=\"typography-header-heading-sm text-content-primary\">\n {subtitle}\n </span>\n {trendChip && (\n <span\n className={cn(\n \"flex items-center gap-1 pb-px\",\n TREND_CLASSES[trendChip.trend],\n )}\n >\n <ArrowUpRightIcon\n className={cn(\n \"size-4 shrink-0\",\n trendChip.trend === \"negative\" && \"rotate-90\",\n )}\n />\n <span className=\"typography-body-small-14px-regular whitespace-nowrap\">\n {trendChip.label}\n </span>\n </span>\n )}\n </div>\n )}\n {dateInfo && (\n <span className=\"typography-description-12px-regular text-content-tertiary\">\n {dateInfo}\n </span>\n )}\n </>\n )}\n {children && <div className=\"mt-auto\">{children}</div>}\n </div>\n </Card>\n );\n },\n);\nChartCard.displayName = \"ChartCard\";\n"],"names":["React","jsx","Card","cn","jsxs","Fragment","Skeleton","TooltipProvider","Tooltip","TooltipTrigger","IconButton","InfoIcon","TooltipContent","ArrowUpRightIcon"],"mappings":"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"}
@@ -4,12 +4,16 @@ import * as React from "react";
4
4
  import { cn } from "../../utils/cn.mjs";
5
5
  import { Card } from "../Card/Card.mjs";
6
6
  import { IconButton } from "../IconButton/IconButton.mjs";
7
- import { InfoCircleIcon } from "../Icons/InfoCircleIcon.mjs";
7
+ import { ArrowUpRightIcon } from "../Icons/ArrowUpRightIcon.mjs";
8
+ import { InfoIcon } from "../Icons/InfoIcon.mjs";
8
9
  import { Skeleton } from "../Skeleton/Skeleton.mjs";
9
10
  import { TooltipProvider, Tooltip, TooltipTrigger, TooltipContent } from "../Tooltip/Tooltip.mjs";
10
11
  const TREND_CLASSES = {
11
- positive: "bg-success-surface text-success-content",
12
- negative: "bg-error-surface text-error-content"
12
+ positive: "text-success-content",
13
+ negative: "text-error-content"
14
+ };
15
+ const SURFACE_CLASSES = {
16
+ primary: "rounded-sm border-border-strong bg-background-primary"
13
17
  };
14
18
  const ChartCard = React.forwardRef(
15
19
  ({
@@ -25,45 +29,66 @@ const ChartCard = React.forwardRef(
25
29
  children,
26
30
  ...props
27
31
  }, ref) => {
28
- return /* @__PURE__ */ jsx(Card, { ref, hierarchy, noPadding: true, className, ...props, children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2 p-4", children: [
29
- loading ? /* @__PURE__ */ jsxs(Fragment, { children: [
30
- /* @__PURE__ */ jsx(Skeleton, { animation: "wave", variant: "rounded", className: "h-4 w-32" }),
31
- /* @__PURE__ */ jsx(Skeleton, { animation: "wave", variant: "rounded", className: "h-7 w-44" }),
32
- /* @__PURE__ */ jsx(Skeleton, { animation: "wave", variant: "rounded", className: "h-3 w-24" })
33
- ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
34
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
35
- /* @__PURE__ */ jsx("span", { className: "typography-body-small-14px-semibold text-content-primary", children: title }),
36
- tooltip && /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsxs(Tooltip, { children: [
37
- /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
38
- IconButton,
39
- {
40
- variant: "tertiary",
41
- size: "32",
42
- "aria-label": tooltipAriaLabel,
43
- className: "text-content-tertiary hover:text-content-primary focus-visible:text-content-primary active:text-content-primary",
44
- icon: /* @__PURE__ */ jsx(InfoCircleIcon, {})
45
- }
46
- ) }),
47
- /* @__PURE__ */ jsx(TooltipContent, { children: tooltip })
48
- ] }) })
49
- ] }),
50
- subtitle && /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
51
- /* @__PURE__ */ jsx("span", { className: "typography-header-heading-sm text-content-primary", children: subtitle }),
52
- trendChip && /* @__PURE__ */ jsx(
53
- "span",
54
- {
55
- className: cn(
56
- "typography-description-12px-semibold whitespace-nowrap rounded-full px-2 py-0.5",
57
- TREND_CLASSES[trendChip.trend]
58
- ),
59
- children: trendChip.label
60
- }
61
- )
62
- ] }),
63
- dateInfo && /* @__PURE__ */ jsx("span", { className: "typography-description-12px-regular text-content-tertiary", children: dateInfo })
64
- ] }),
65
- children && /* @__PURE__ */ jsx("div", { className: "mt-auto", children })
66
- ] }) });
32
+ return /* @__PURE__ */ jsx(
33
+ Card,
34
+ {
35
+ ref,
36
+ hierarchy,
37
+ noPadding: true,
38
+ className: cn(SURFACE_CLASSES[hierarchy], className),
39
+ ...props,
40
+ children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2 p-4", children: [
41
+ loading ? /* @__PURE__ */ jsxs(Fragment, { children: [
42
+ /* @__PURE__ */ jsx(Skeleton, { animation: "wave", variant: "rounded", className: "h-4 w-32" }),
43
+ /* @__PURE__ */ jsx(Skeleton, { animation: "wave", variant: "rounded", className: "h-7 w-44" }),
44
+ /* @__PURE__ */ jsx(Skeleton, { animation: "wave", variant: "rounded", className: "h-3 w-24" })
45
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
46
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
47
+ /* @__PURE__ */ jsx("span", { className: "typography-body-small-14px-regular text-content-secondary", children: title }),
48
+ tooltip && /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsxs(Tooltip, { children: [
49
+ /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
50
+ IconButton,
51
+ {
52
+ variant: "tertiary",
53
+ size: "32",
54
+ "aria-label": tooltipAriaLabel,
55
+ className: "text-icons-primary hover:text-content-primary focus-visible:text-content-primary active:text-content-primary",
56
+ icon: /* @__PURE__ */ jsx(InfoIcon, { size: 16 })
57
+ }
58
+ ) }),
59
+ /* @__PURE__ */ jsx(TooltipContent, { children: tooltip })
60
+ ] }) })
61
+ ] }),
62
+ subtitle && /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-end gap-2", children: [
63
+ /* @__PURE__ */ jsx("span", { className: "typography-header-heading-sm text-content-primary", children: subtitle }),
64
+ trendChip && /* @__PURE__ */ jsxs(
65
+ "span",
66
+ {
67
+ className: cn(
68
+ "flex items-center gap-1 pb-px",
69
+ TREND_CLASSES[trendChip.trend]
70
+ ),
71
+ children: [
72
+ /* @__PURE__ */ jsx(
73
+ ArrowUpRightIcon,
74
+ {
75
+ className: cn(
76
+ "size-4 shrink-0",
77
+ trendChip.trend === "negative" && "rotate-90"
78
+ )
79
+ }
80
+ ),
81
+ /* @__PURE__ */ jsx("span", { className: "typography-body-small-14px-regular whitespace-nowrap", children: trendChip.label })
82
+ ]
83
+ }
84
+ )
85
+ ] }),
86
+ dateInfo && /* @__PURE__ */ jsx("span", { className: "typography-description-12px-regular text-content-tertiary", children: dateInfo })
87
+ ] }),
88
+ children && /* @__PURE__ */ jsx("div", { className: "mt-auto", children })
89
+ ] })
90
+ }
91
+ );
67
92
  }
68
93
  );
69
94
  ChartCard.displayName = "ChartCard";
@@ -1 +1 @@
1
- {"version":3,"file":"ChartCard.mjs","sources":["../../../src/components/Chart/ChartCard.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { Card, type CardHierarchy } from \"../Card/Card\";\nimport { IconButton } from \"../IconButton/IconButton\";\nimport { InfoCircleIcon } from \"../Icons/InfoCircleIcon\";\nimport { Skeleton } from \"../Skeleton/Skeleton\";\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from \"../Tooltip/Tooltip\";\n\n/** Props for {@link ChartCard}. */\nexport interface ChartCardProps extends Omit<React.HTMLAttributes<HTMLDivElement>, \"title\"> {\n /** Surface treatment of the underlying {@link Card}. @default \"primary\" */\n hierarchy?: CardHierarchy;\n /** Card title text. Pass translated string for i18n. */\n title: React.ReactNode;\n /** Large subtitle value (e.g. formatted price or count). */\n subtitle?: React.ReactNode;\n /** Tooltip text shown next to the title. Pass translated string for i18n. */\n tooltip?: React.ReactNode;\n /** Accessible label for the info tooltip trigger. Override for i18n. @default \"More info\" */\n tooltipAriaLabel?: string;\n /** Date range or period label shown below the subtitle. */\n dateInfo?: React.ReactNode;\n /** Trend indicator chip config. Only rendered when {@link subtitle} is also provided. */\n trendChip?: {\n /** Display label (e.g. \"12.5%\"). */\n label: React.ReactNode;\n /** Whether the trend is positive (green) or negative (red). */\n trend: \"positive\" | \"negative\";\n };\n /** Show loading skeleton instead of content. @default false */\n loading?: boolean;\n /** Chart content rendered below the header. */\n children?: React.ReactNode;\n}\n\nconst TREND_CLASSES: Record<\"positive\" | \"negative\", string> = {\n positive: \"bg-success-surface text-success-content\",\n negative: \"bg-error-surface text-error-content\",\n};\n\n/**\n * Wraps any chart with a structured header containing title, subtitle,\n * optional trend chip, date range label, info tooltip, and a loading\n * skeleton state.\n *\n * The surface treatment comes from the underlying {@link Card} and is driven by\n * the `hierarchy` prop.\n *\n * @example\n * ```tsx\n * <ChartCard\n * title=\"Revenue\"\n * subtitle=\"$4,523\"\n * trendChip={{ label: \"+12.5%\", trend: \"positive\" }}\n * dateInfo=\"Jan 1 – Mar 17\"\n * tooltip=\"Total revenue for the selected period.\"\n * >\n * <MyLineChart />\n * </ChartCard>\n * ```\n */\nexport const ChartCard = React.forwardRef<HTMLDivElement, ChartCardProps>(\n (\n {\n className,\n hierarchy = \"primary\",\n title,\n subtitle,\n tooltip,\n tooltipAriaLabel = \"More info\",\n dateInfo,\n trendChip,\n loading = false,\n children,\n ...props\n },\n ref,\n ) => {\n return (\n <Card ref={ref} hierarchy={hierarchy} noPadding className={className} {...props}>\n <div className=\"flex flex-col gap-2 p-4\">\n {loading ? (\n <>\n <Skeleton animation=\"wave\" variant=\"rounded\" className=\"h-4 w-32\" />\n <Skeleton animation=\"wave\" variant=\"rounded\" className=\"h-7 w-44\" />\n <Skeleton animation=\"wave\" variant=\"rounded\" className=\"h-3 w-24\" />\n </>\n ) : (\n <>\n <div className=\"flex items-center gap-1.5\">\n <span className=\"typography-body-small-14px-semibold text-content-primary\">\n {title}\n </span>\n {tooltip && (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <IconButton\n variant=\"tertiary\"\n size=\"32\"\n aria-label={tooltipAriaLabel}\n className=\"text-content-tertiary hover:text-content-primary focus-visible:text-content-primary active:text-content-primary\"\n icon={<InfoCircleIcon />}\n />\n </TooltipTrigger>\n <TooltipContent>{tooltip}</TooltipContent>\n </Tooltip>\n </TooltipProvider>\n )}\n </div>\n {subtitle && (\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"typography-header-heading-sm text-content-primary\">\n {subtitle}\n </span>\n {trendChip && (\n <span\n className={cn(\n \"typography-description-12px-semibold whitespace-nowrap rounded-full px-2 py-0.5\",\n TREND_CLASSES[trendChip.trend],\n )}\n >\n {trendChip.label}\n </span>\n )}\n </div>\n )}\n {dateInfo && (\n <span className=\"typography-description-12px-regular text-content-tertiary\">\n {dateInfo}\n </span>\n )}\n </>\n )}\n {children && <div className=\"mt-auto\">{children}</div>}\n </div>\n </Card>\n );\n },\n);\nChartCard.displayName = \"ChartCard\";\n"],"names":[],"mappings":";;;;;;;;;AAmCA,MAAM,gBAAyD;AAAA,EAC7D,UAAU;AAAA,EACV,UAAU;AACZ;AAuBO,MAAM,YAAY,MAAM;AAAA,EAC7B,CACE;AAAA,IACE;AAAA,IACA,YAAY;AAAA,IACZ;AAAA,IACA;AAAA,IACA;AAAA,IACA,mBAAmB;AAAA,IACnB;AAAA,IACA;AAAA,IACA,UAAU;AAAA,IACV;AAAA,IACA,GAAG;AAAA,EAAA,GAEL,QACG;AACH,WACE,oBAAC,MAAA,EAAK,KAAU,WAAsB,WAAS,MAAC,WAAuB,GAAG,OACxE,UAAA,qBAAC,OAAA,EAAI,WAAU,2BACZ,UAAA;AAAA,MAAA,UACC,qBAAA,UAAA,EACE,UAAA;AAAA,QAAA,oBAAC,YAAS,WAAU,QAAO,SAAQ,WAAU,WAAU,YAAW;AAAA,4BACjE,UAAA,EAAS,WAAU,QAAO,SAAQ,WAAU,WAAU,YAAW;AAAA,4BACjE,UAAA,EAAS,WAAU,QAAO,SAAQ,WAAU,WAAU,WAAA,CAAW;AAAA,MAAA,EAAA,CACpE,IAEA,qBAAA,UAAA,EACE,UAAA;AAAA,QAAA,qBAAC,OAAA,EAAI,WAAU,6BACb,UAAA;AAAA,UAAA,oBAAC,QAAA,EAAK,WAAU,4DACb,UAAA,OACH;AAAA,UACC,WACC,oBAAC,iBAAA,EACC,UAAA,qBAAC,SAAA,EACC,UAAA;AAAA,YAAA,oBAAC,gBAAA,EAAe,SAAO,MACrB,UAAA;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,SAAQ;AAAA,gBACR,MAAK;AAAA,gBACL,cAAY;AAAA,gBACZ,WAAU;AAAA,gBACV,0BAAO,gBAAA,CAAA,CAAe;AAAA,cAAA;AAAA,YAAA,GAE1B;AAAA,YACA,oBAAC,kBAAgB,UAAA,QAAA,CAAQ;AAAA,UAAA,EAAA,CAC3B,EAAA,CACF;AAAA,QAAA,GAEJ;AAAA,QACC,YACC,qBAAC,OAAA,EAAI,WAAU,qCACb,UAAA;AAAA,UAAA,oBAAC,QAAA,EAAK,WAAU,qDACb,UAAA,UACH;AAAA,UACC,aACC;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,WAAW;AAAA,gBACT;AAAA,gBACA,cAAc,UAAU,KAAK;AAAA,cAAA;AAAA,cAG9B,UAAA,UAAU;AAAA,YAAA;AAAA,UAAA;AAAA,QACb,GAEJ;AAAA,QAED,YACC,oBAAC,QAAA,EAAK,WAAU,6DACb,UAAA,SAAA,CACH;AAAA,MAAA,GAEJ;AAAA,MAED,YAAY,oBAAC,OAAA,EAAI,WAAU,WAAW,SAAA,CAAS;AAAA,IAAA,EAAA,CAClD,EAAA,CACF;AAAA,EAEJ;AACF;AACA,UAAU,cAAc;"}
1
+ {"version":3,"file":"ChartCard.mjs","sources":["../../../src/components/Chart/ChartCard.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { Card, type CardHierarchy } from \"../Card/Card\";\nimport { IconButton } from \"../IconButton/IconButton\";\nimport { ArrowUpRightIcon } from \"../Icons/ArrowUpRightIcon\";\nimport { InfoIcon } from \"../Icons/InfoIcon\";\nimport { Skeleton } from \"../Skeleton/Skeleton\";\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from \"../Tooltip/Tooltip\";\n\n/** Props for {@link ChartCard}. */\nexport interface ChartCardProps extends Omit<React.HTMLAttributes<HTMLDivElement>, \"title\"> {\n /**\n * Surface treatment. `primary` follows the V2 Insight Card spec (white fill,\n * strong border, 12px radius); `secondary` uses the {@link Card} secondary\n * surface. @default \"primary\"\n */\n hierarchy?: CardHierarchy;\n /** Card title text. Pass translated string for i18n. */\n title: React.ReactNode;\n /** Large subtitle value (e.g. formatted price or count). */\n subtitle?: React.ReactNode;\n /** Tooltip text shown next to the title. Pass translated string for i18n. */\n tooltip?: React.ReactNode;\n /** Accessible label for the info tooltip trigger. Override for i18n. @default \"More info\" */\n tooltipAriaLabel?: string;\n /** Date range or period label shown below the subtitle. */\n dateInfo?: React.ReactNode;\n /**\n * Trend indicator config. Rendered as a coloured directional arrow and label\n * beside the subtitle, so it is only shown when {@link subtitle} is provided.\n */\n trendChip?: {\n /** Display label (e.g. \"12.5% vs prev\"). */\n label: React.ReactNode;\n /** Whether the trend is positive (green, arrow up) or negative (red, arrow down). */\n trend: \"positive\" | \"negative\";\n };\n /** Show loading skeleton instead of content. @default false */\n loading?: boolean;\n /** Chart content rendered below the header. */\n children?: React.ReactNode;\n}\n\nconst TREND_CLASSES: Record<\"positive\" | \"negative\", string> = {\n positive: \"text-success-content\",\n negative: \"text-error-content\",\n};\n\nconst SURFACE_CLASSES: Partial<Record<CardHierarchy, string>> = {\n primary: \"rounded-sm border-border-strong bg-background-primary\",\n};\n\n/**\n * Wraps any chart with a structured header containing title, subtitle,\n * optional trend indicator, date range label, info tooltip, and a loading\n * skeleton state.\n *\n * At `hierarchy=\"primary\"` this implements the V2 Insight Card surface, which\n * differs from {@link Card}'s own primary hierarchy: a white fill, the strong\n * border, and a 12px radius.\n *\n * @example\n * ```tsx\n * <ChartCard\n * title=\"Revenue\"\n * subtitle=\"$4,523\"\n * trendChip={{ label: \"+12.5%\", trend: \"positive\" }}\n * dateInfo=\"Jan 1 – Mar 17\"\n * tooltip=\"Total revenue for the selected period.\"\n * >\n * <MyLineChart />\n * </ChartCard>\n * ```\n */\nexport const ChartCard = React.forwardRef<HTMLDivElement, ChartCardProps>(\n (\n {\n className,\n hierarchy = \"primary\",\n title,\n subtitle,\n tooltip,\n tooltipAriaLabel = \"More info\",\n dateInfo,\n trendChip,\n loading = false,\n children,\n ...props\n },\n ref,\n ) => {\n return (\n <Card\n ref={ref}\n hierarchy={hierarchy}\n noPadding\n className={cn(SURFACE_CLASSES[hierarchy], className)}\n {...props}\n >\n <div className=\"flex flex-col gap-2 p-4\">\n {loading ? (\n <>\n <Skeleton animation=\"wave\" variant=\"rounded\" className=\"h-4 w-32\" />\n <Skeleton animation=\"wave\" variant=\"rounded\" className=\"h-7 w-44\" />\n <Skeleton animation=\"wave\" variant=\"rounded\" className=\"h-3 w-24\" />\n </>\n ) : (\n <>\n <div className=\"flex items-center gap-1\">\n <span className=\"typography-body-small-14px-regular text-content-secondary\">\n {title}\n </span>\n {tooltip && (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <IconButton\n variant=\"tertiary\"\n size=\"32\"\n aria-label={tooltipAriaLabel}\n className=\"text-icons-primary hover:text-content-primary focus-visible:text-content-primary active:text-content-primary\"\n icon={<InfoIcon size={16} />}\n />\n </TooltipTrigger>\n <TooltipContent>{tooltip}</TooltipContent>\n </Tooltip>\n </TooltipProvider>\n )}\n </div>\n {subtitle && (\n <div className=\"flex flex-wrap items-end gap-2\">\n <span className=\"typography-header-heading-sm text-content-primary\">\n {subtitle}\n </span>\n {trendChip && (\n <span\n className={cn(\n \"flex items-center gap-1 pb-px\",\n TREND_CLASSES[trendChip.trend],\n )}\n >\n <ArrowUpRightIcon\n className={cn(\n \"size-4 shrink-0\",\n trendChip.trend === \"negative\" && \"rotate-90\",\n )}\n />\n <span className=\"typography-body-small-14px-regular whitespace-nowrap\">\n {trendChip.label}\n </span>\n </span>\n )}\n </div>\n )}\n {dateInfo && (\n <span className=\"typography-description-12px-regular text-content-tertiary\">\n {dateInfo}\n </span>\n )}\n </>\n )}\n {children && <div className=\"mt-auto\">{children}</div>}\n </div>\n </Card>\n );\n },\n);\nChartCard.displayName = \"ChartCard\";\n"],"names":[],"mappings":";;;;;;;;;;AA2CA,MAAM,gBAAyD;AAAA,EAC7D,UAAU;AAAA,EACV,UAAU;AACZ;AAEA,MAAM,kBAA0D;AAAA,EAC9D,SAAS;AACX;AAwBO,MAAM,YAAY,MAAM;AAAA,EAC7B,CACE;AAAA,IACE;AAAA,IACA,YAAY;AAAA,IACZ;AAAA,IACA;AAAA,IACA;AAAA,IACA,mBAAmB;AAAA,IACnB;AAAA,IACA;AAAA,IACA,UAAU;AAAA,IACV;AAAA,IACA,GAAG;AAAA,EAAA,GAEL,QACG;AACH,WACE;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA,WAAS;AAAA,QACT,WAAW,GAAG,gBAAgB,SAAS,GAAG,SAAS;AAAA,QAClD,GAAG;AAAA,QAEJ,UAAA,qBAAC,OAAA,EAAI,WAAU,2BACZ,UAAA;AAAA,UAAA,UACC,qBAAA,UAAA,EACE,UAAA;AAAA,YAAA,oBAAC,YAAS,WAAU,QAAO,SAAQ,WAAU,WAAU,YAAW;AAAA,gCACjE,UAAA,EAAS,WAAU,QAAO,SAAQ,WAAU,WAAU,YAAW;AAAA,gCACjE,UAAA,EAAS,WAAU,QAAO,SAAQ,WAAU,WAAU,WAAA,CAAW;AAAA,UAAA,EAAA,CACpE,IAEA,qBAAA,UAAA,EACE,UAAA;AAAA,YAAA,qBAAC,OAAA,EAAI,WAAU,2BACb,UAAA;AAAA,cAAA,oBAAC,QAAA,EAAK,WAAU,6DACb,UAAA,OACH;AAAA,cACC,WACC,oBAAC,iBAAA,EACC,UAAA,qBAAC,SAAA,EACC,UAAA;AAAA,gBAAA,oBAAC,gBAAA,EAAe,SAAO,MACrB,UAAA;AAAA,kBAAC;AAAA,kBAAA;AAAA,oBACC,SAAQ;AAAA,oBACR,MAAK;AAAA,oBACL,cAAY;AAAA,oBACZ,WAAU;AAAA,oBACV,MAAM,oBAAC,UAAA,EAAS,MAAM,GAAA,CAAI;AAAA,kBAAA;AAAA,gBAAA,GAE9B;AAAA,gBACA,oBAAC,kBAAgB,UAAA,QAAA,CAAQ;AAAA,cAAA,EAAA,CAC3B,EAAA,CACF;AAAA,YAAA,GAEJ;AAAA,YACC,YACC,qBAAC,OAAA,EAAI,WAAU,kCACb,UAAA;AAAA,cAAA,oBAAC,QAAA,EAAK,WAAU,qDACb,UAAA,UACH;AAAA,cACC,aACC;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,WAAW;AAAA,oBACT;AAAA,oBACA,cAAc,UAAU,KAAK;AAAA,kBAAA;AAAA,kBAG/B,UAAA;AAAA,oBAAA;AAAA,sBAAC;AAAA,sBAAA;AAAA,wBACC,WAAW;AAAA,0BACT;AAAA,0BACA,UAAU,UAAU,cAAc;AAAA,wBAAA;AAAA,sBACpC;AAAA,oBAAA;AAAA,oBAEF,oBAAC,QAAA,EAAK,WAAU,wDACb,oBAAU,MAAA,CACb;AAAA,kBAAA;AAAA,gBAAA;AAAA,cAAA;AAAA,YACF,GAEJ;AAAA,YAED,YACC,oBAAC,QAAA,EAAK,WAAU,6DACb,UAAA,SAAA,CACH;AAAA,UAAA,GAEJ;AAAA,UAED,YAAY,oBAAC,OAAA,EAAI,WAAU,WAAW,SAAA,CAAS;AAAA,QAAA,EAAA,CAClD;AAAA,MAAA;AAAA,IAAA;AAAA,EAGN;AACF;AACA,UAAU,cAAc;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fanvue/ui",
3
- "version": "3.21.1",
3
+ "version": "3.22.0",
4
4
  "description": "React component library built with Tailwind CSS for Fanvue ecosystem",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org",
@@ -142,7 +142,7 @@
142
142
  "jsdom": "27.4.0",
143
143
  "lint-staged": "16.2.7",
144
144
  "playwright": "^1.58.1",
145
- "postcss": "8.5.12",
145
+ "postcss": "8.5.20",
146
146
  "react": "19.2.3",
147
147
  "react-day-picker": "9.13.1",
148
148
  "react-dom": "19.2.3",
@@ -166,9 +166,9 @@
166
166
  "minimatch": ">=10.2.3",
167
167
  "ajv": ">=8.18.0",
168
168
  "fast-uri": ">=3.1.4",
169
- "brace-expansion": ">=5.0.7",
169
+ "brace-expansion": ">=5.0.8",
170
170
  "yaml": ">=2.8.3",
171
- "postcss": ">=8.5.10",
171
+ "postcss": ">=8.5.18",
172
172
  "tmp": ">=0.2.7",
173
173
  "ws": ">=8.20.1",
174
174
  "qs": ">=6.15.2",