@cdx-ui/components 0.3.4 → 0.3.6
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/README.md +1 -1
- package/coverage.svg +1 -1
- package/docs/components/bar-chart/content.md +703 -0
- package/docs/components/content.md +9 -1
- package/docs/components/line-chart/content.md +567 -0
- package/docs/components/pie-chart/content.md +493 -0
- package/docs/components/progress-segmented/content.md +1 -1
- package/docs/components/select/content.md +144 -2
- package/docs/components/stepper/content.md +599 -0
- package/docs/components/system-alert/content.md +533 -0
- package/docs/foundations/expressions/icons/content.md +1 -1
- package/docs/foundations/styles/tokens/all-tokens/content.md +2 -1
- package/docs/llms.txt +10 -0
- package/docs/patterns/content.md +1 -0
- package/docs/patterns/dashboard/content.md +423 -19
- package/docs/patterns/insights/content.md +590 -0
- package/docs/resources/release-notes/0.3.4/content.md +27 -0
- package/docs/resources/release-notes/0.3.5/content.md +7 -0
- package/docs/resources/release-notes/content.md +2 -0
- package/lib/commonjs/components/BarChart/geometry.js +1130 -0
- package/lib/commonjs/components/BarChart/geometry.js.map +1 -0
- package/lib/commonjs/components/BarChart/index.js +942 -0
- package/lib/commonjs/components/BarChart/index.js.map +1 -0
- package/lib/commonjs/components/BarChart/styles.js +26 -0
- package/lib/commonjs/components/BarChart/styles.js.map +1 -0
- package/lib/commonjs/components/Button/index.js +2 -2
- package/lib/commonjs/components/Button/index.js.map +1 -1
- package/lib/commonjs/components/Chip/styles.js +3 -1
- package/lib/commonjs/components/Chip/styles.js.map +1 -1
- package/lib/commonjs/components/LineChart/geometry.js +698 -0
- package/lib/commonjs/components/LineChart/geometry.js.map +1 -0
- package/lib/commonjs/components/LineChart/index.js +747 -0
- package/lib/commonjs/components/LineChart/index.js.map +1 -0
- package/lib/commonjs/components/LineChart/styles.js +25 -0
- package/lib/commonjs/components/LineChart/styles.js.map +1 -0
- package/lib/commonjs/components/PieChart/geometry.js +216 -0
- package/lib/commonjs/components/PieChart/geometry.js.map +1 -0
- package/lib/commonjs/components/PieChart/index.js +476 -0
- package/lib/commonjs/components/PieChart/index.js.map +1 -0
- package/lib/commonjs/components/PieChart/styles.js +88 -0
- package/lib/commonjs/components/PieChart/styles.js.map +1 -0
- package/lib/commonjs/components/ProgressCircle/ProgressCircleRing.js +9 -31
- package/lib/commonjs/components/ProgressCircle/ProgressCircleRing.js.map +1 -1
- package/lib/commonjs/components/ProgressCircle/ProgressRing.js +52 -0
- package/lib/commonjs/components/ProgressCircle/ProgressRing.js.map +1 -0
- package/lib/commonjs/components/ScrollShadow/useScrollShadow.js +8 -7
- package/lib/commonjs/components/ScrollShadow/useScrollShadow.js.map +1 -1
- package/lib/commonjs/components/Stepper/index.js +369 -0
- package/lib/commonjs/components/Stepper/index.js.map +1 -0
- package/lib/commonjs/components/Stepper/styles.js +211 -0
- package/lib/commonjs/components/Stepper/styles.js.map +1 -0
- package/lib/commonjs/components/Stepper/useStepperLabelFit.js +22 -0
- package/lib/commonjs/components/Stepper/useStepperLabelFit.js.map +1 -0
- package/lib/commonjs/components/Stepper/useStepperLabelFit.web.js +52 -0
- package/lib/commonjs/components/Stepper/useStepperLabelFit.web.js.map +1 -0
- package/lib/commonjs/components/Stepper/useStepperRingColors.js +31 -0
- package/lib/commonjs/components/Stepper/useStepperRingColors.js.map +1 -0
- package/lib/commonjs/components/SystemAlert/animation.js +218 -0
- package/lib/commonjs/components/SystemAlert/animation.js.map +1 -0
- package/lib/commonjs/components/SystemAlert/index.js +525 -0
- package/lib/commonjs/components/SystemAlert/index.js.map +1 -0
- package/lib/commonjs/components/SystemAlert/styles.js +178 -0
- package/lib/commonjs/components/SystemAlert/styles.js.map +1 -0
- package/lib/commonjs/components/SystemAlert/useSystemAlertStatusBarStyle.js +53 -0
- package/lib/commonjs/components/SystemAlert/useSystemAlertStatusBarStyle.js.map +1 -0
- package/lib/commonjs/components/Tabs/index.js +4 -0
- package/lib/commonjs/components/Tabs/index.js.map +1 -1
- package/lib/commonjs/components/Tabs/styles.js +1 -1
- package/lib/commonjs/components/Tabs/styles.js.map +1 -1
- package/lib/commonjs/components/chart/ChartInspector.js +610 -0
- package/lib/commonjs/components/chart/ChartInspector.js.map +1 -0
- package/lib/commonjs/components/chart/format.js +93 -0
- package/lib/commonjs/components/chart/format.js.map +1 -0
- package/lib/commonjs/components/chart/index.js +2 -0
- package/lib/commonjs/components/chart/index.js.map +1 -0
- package/lib/commonjs/components/chart/motion.js +97 -0
- package/lib/commonjs/components/chart/motion.js.map +1 -0
- package/lib/commonjs/components/chart/palette.js +178 -0
- package/lib/commonjs/components/chart/palette.js.map +1 -0
- package/lib/commonjs/components/chart/size.js +34 -0
- package/lib/commonjs/components/chart/size.js.map +1 -0
- package/lib/commonjs/components/chart/ticks.js +59 -0
- package/lib/commonjs/components/chart/ticks.js.map +1 -0
- package/lib/commonjs/components/chart/types.js +6 -0
- package/lib/commonjs/components/chart/types.js.map +1 -0
- package/lib/commonjs/components/chart/useChartHostWidth.js +27 -0
- package/lib/commonjs/components/chart/useChartHostWidth.js.map +1 -0
- package/lib/commonjs/components/index.js +60 -0
- package/lib/commonjs/components/index.js.map +1 -1
- package/lib/commonjs/figma/SystemAlert.Button.figma.js +28 -0
- package/lib/commonjs/figma/SystemAlert.Button.figma.js.map +1 -0
- package/lib/commonjs/figma/SystemAlert.Close.figma.js +22 -0
- package/lib/commonjs/figma/SystemAlert.Close.figma.js.map +1 -0
- package/lib/commonjs/figma/SystemAlert.Description.figma.js +20 -0
- package/lib/commonjs/figma/SystemAlert.Description.figma.js.map +1 -0
- package/lib/commonjs/figma/SystemAlert.IconButton.figma.js +31 -0
- package/lib/commonjs/figma/SystemAlert.IconButton.figma.js.map +1 -0
- package/lib/commonjs/figma/SystemAlert.figma.js +48 -0
- package/lib/commonjs/figma/SystemAlert.figma.js.map +1 -0
- package/lib/module/components/BarChart/geometry.js +1110 -0
- package/lib/module/components/BarChart/geometry.js.map +1 -0
- package/lib/module/components/BarChart/index.js +936 -0
- package/lib/module/components/BarChart/index.js.map +1 -0
- package/lib/module/components/BarChart/styles.js +22 -0
- package/lib/module/components/BarChart/styles.js.map +1 -0
- package/lib/module/components/Button/index.js +2 -2
- package/lib/module/components/Button/index.js.map +1 -1
- package/lib/module/components/Chip/styles.js +3 -1
- package/lib/module/components/Chip/styles.js.map +1 -1
- package/lib/module/components/LineChart/geometry.js +685 -0
- package/lib/module/components/LineChart/geometry.js.map +1 -0
- package/lib/module/components/LineChart/index.js +741 -0
- package/lib/module/components/LineChart/index.js.map +1 -0
- package/lib/module/components/LineChart/styles.js +21 -0
- package/lib/module/components/LineChart/styles.js.map +1 -0
- package/lib/module/components/PieChart/geometry.js +209 -0
- package/lib/module/components/PieChart/geometry.js.map +1 -0
- package/lib/module/components/PieChart/index.js +471 -0
- package/lib/module/components/PieChart/index.js.map +1 -0
- package/lib/module/components/PieChart/styles.js +84 -0
- package/lib/module/components/PieChart/styles.js.map +1 -0
- package/lib/module/components/ProgressCircle/ProgressCircleRing.js +10 -32
- package/lib/module/components/ProgressCircle/ProgressCircleRing.js.map +1 -1
- package/lib/module/components/ProgressCircle/ProgressRing.js +48 -0
- package/lib/module/components/ProgressCircle/ProgressRing.js.map +1 -0
- package/lib/module/components/ScrollShadow/useScrollShadow.js +8 -7
- package/lib/module/components/ScrollShadow/useScrollShadow.js.map +1 -1
- package/lib/module/components/Stepper/index.js +360 -0
- package/lib/module/components/Stepper/index.js.map +1 -0
- package/lib/module/components/Stepper/styles.js +206 -0
- package/lib/module/components/Stepper/styles.js.map +1 -0
- package/lib/module/components/Stepper/useStepperLabelFit.js +18 -0
- package/lib/module/components/Stepper/useStepperLabelFit.js.map +1 -0
- package/lib/module/components/Stepper/useStepperLabelFit.web.js +48 -0
- package/lib/module/components/Stepper/useStepperLabelFit.web.js.map +1 -0
- package/lib/module/components/Stepper/useStepperRingColors.js +28 -0
- package/lib/module/components/Stepper/useStepperRingColors.js.map +1 -0
- package/lib/module/components/SystemAlert/animation.js +213 -0
- package/lib/module/components/SystemAlert/animation.js.map +1 -0
- package/lib/module/components/SystemAlert/index.js +515 -0
- package/lib/module/components/SystemAlert/index.js.map +1 -0
- package/lib/module/components/SystemAlert/styles.js +174 -0
- package/lib/module/components/SystemAlert/styles.js.map +1 -0
- package/lib/module/components/SystemAlert/useSystemAlertStatusBarStyle.js +49 -0
- package/lib/module/components/SystemAlert/useSystemAlertStatusBarStyle.js.map +1 -0
- package/lib/module/components/Tabs/index.js +4 -0
- package/lib/module/components/Tabs/index.js.map +1 -1
- package/lib/module/components/Tabs/styles.js +1 -1
- package/lib/module/components/Tabs/styles.js.map +1 -1
- package/lib/module/components/chart/ChartInspector.js +600 -0
- package/lib/module/components/chart/ChartInspector.js.map +1 -0
- package/lib/module/components/chart/format.js +84 -0
- package/lib/module/components/chart/format.js.map +1 -0
- package/lib/module/components/chart/index.js +2 -0
- package/lib/module/components/chart/index.js.map +1 -0
- package/lib/module/components/chart/motion.js +89 -0
- package/lib/module/components/chart/motion.js.map +1 -0
- package/lib/module/components/chart/palette.js +168 -0
- package/lib/module/components/chart/palette.js.map +1 -0
- package/lib/module/components/chart/size.js +29 -0
- package/lib/module/components/chart/size.js.map +1 -0
- package/lib/module/components/chart/ticks.js +55 -0
- package/lib/module/components/chart/ticks.js.map +1 -0
- package/lib/module/components/chart/types.js +4 -0
- package/lib/module/components/chart/types.js.map +1 -0
- package/lib/module/components/chart/useChartHostWidth.js +23 -0
- package/lib/module/components/chart/useChartHostWidth.js.map +1 -0
- package/lib/module/components/index.js +5 -0
- package/lib/module/components/index.js.map +1 -1
- package/lib/module/figma/SystemAlert.Button.figma.js +22 -0
- package/lib/module/figma/SystemAlert.Button.figma.js.map +1 -0
- package/lib/module/figma/SystemAlert.Close.figma.js +18 -0
- package/lib/module/figma/SystemAlert.Close.figma.js.map +1 -0
- package/lib/module/figma/SystemAlert.Description.figma.js +14 -0
- package/lib/module/figma/SystemAlert.Description.figma.js.map +1 -0
- package/lib/module/figma/SystemAlert.IconButton.figma.js +25 -0
- package/lib/module/figma/SystemAlert.IconButton.figma.js.map +1 -0
- package/lib/module/figma/SystemAlert.figma.js +42 -0
- package/lib/module/figma/SystemAlert.figma.js.map +1 -0
- package/lib/typescript/components/BarChart/geometry.d.ts +236 -0
- package/lib/typescript/components/BarChart/geometry.d.ts.map +1 -0
- package/lib/typescript/components/BarChart/index.d.ts +193 -0
- package/lib/typescript/components/BarChart/index.d.ts.map +1 -0
- package/lib/typescript/components/BarChart/styles.d.ts +32 -0
- package/lib/typescript/components/BarChart/styles.d.ts.map +1 -0
- package/lib/typescript/components/Chip/styles.d.ts.map +1 -1
- package/lib/typescript/components/LineChart/geometry.d.ts +248 -0
- package/lib/typescript/components/LineChart/geometry.d.ts.map +1 -0
- package/lib/typescript/components/LineChart/index.d.ts +105 -0
- package/lib/typescript/components/LineChart/index.d.ts.map +1 -0
- package/lib/typescript/components/LineChart/styles.d.ts +12 -0
- package/lib/typescript/components/LineChart/styles.d.ts.map +1 -0
- package/lib/typescript/components/PieChart/geometry.d.ts +43 -0
- package/lib/typescript/components/PieChart/geometry.d.ts.map +1 -0
- package/lib/typescript/components/PieChart/index.d.ts +147 -0
- package/lib/typescript/components/PieChart/index.d.ts.map +1 -0
- package/lib/typescript/components/PieChart/styles.d.ts +27 -0
- package/lib/typescript/components/PieChart/styles.d.ts.map +1 -0
- package/lib/typescript/components/ProgressCircle/ProgressCircleRing.d.ts.map +1 -1
- package/lib/typescript/components/ProgressCircle/ProgressRing.d.ts +17 -0
- package/lib/typescript/components/ProgressCircle/ProgressRing.d.ts.map +1 -0
- package/lib/typescript/components/ScrollShadow/useScrollShadow.d.ts.map +1 -1
- package/lib/typescript/components/Stepper/index.d.ts +68 -0
- package/lib/typescript/components/Stepper/index.d.ts.map +1 -0
- package/lib/typescript/components/Stepper/styles.d.ts +46 -0
- package/lib/typescript/components/Stepper/styles.d.ts.map +1 -0
- package/lib/typescript/components/Stepper/useStepperLabelFit.d.ts +15 -0
- package/lib/typescript/components/Stepper/useStepperLabelFit.d.ts.map +1 -0
- package/lib/typescript/components/Stepper/useStepperLabelFit.web.d.ts +10 -0
- package/lib/typescript/components/Stepper/useStepperLabelFit.web.d.ts.map +1 -0
- package/lib/typescript/components/Stepper/useStepperRingColors.d.ts +6 -0
- package/lib/typescript/components/Stepper/useStepperRingColors.d.ts.map +1 -0
- package/lib/typescript/components/SystemAlert/animation.d.ts +56 -0
- package/lib/typescript/components/SystemAlert/animation.d.ts.map +1 -0
- package/lib/typescript/components/SystemAlert/index.d.ts +110 -0
- package/lib/typescript/components/SystemAlert/index.d.ts.map +1 -0
- package/lib/typescript/components/SystemAlert/styles.d.ts +38 -0
- package/lib/typescript/components/SystemAlert/styles.d.ts.map +1 -0
- package/lib/typescript/components/SystemAlert/useSystemAlertStatusBarStyle.d.ts +14 -0
- package/lib/typescript/components/SystemAlert/useSystemAlertStatusBarStyle.d.ts.map +1 -0
- package/lib/typescript/components/Tabs/index.d.ts.map +1 -1
- package/lib/typescript/components/chart/ChartInspector.d.ts +101 -0
- package/lib/typescript/components/chart/ChartInspector.d.ts.map +1 -0
- package/lib/typescript/components/chart/format.d.ts +16 -0
- package/lib/typescript/components/chart/format.d.ts.map +1 -0
- package/lib/typescript/components/chart/index.d.ts +3 -0
- package/lib/typescript/components/chart/index.d.ts.map +1 -0
- package/lib/typescript/components/chart/motion.d.ts +27 -0
- package/lib/typescript/components/chart/motion.d.ts.map +1 -0
- package/lib/typescript/components/chart/palette.d.ts +44 -0
- package/lib/typescript/components/chart/palette.d.ts.map +1 -0
- package/lib/typescript/components/chart/size.d.ts +25 -0
- package/lib/typescript/components/chart/size.d.ts.map +1 -0
- package/lib/typescript/components/chart/ticks.d.ts +3 -0
- package/lib/typescript/components/chart/ticks.d.ts.map +1 -0
- package/lib/typescript/components/chart/types.d.ts +163 -0
- package/lib/typescript/components/chart/types.d.ts.map +1 -0
- package/lib/typescript/components/chart/useChartHostWidth.d.ts +9 -0
- package/lib/typescript/components/chart/useChartHostWidth.d.ts.map +1 -0
- package/lib/typescript/components/index.d.ts +5 -0
- package/lib/typescript/components/index.d.ts.map +1 -1
- package/lib/typescript/figma/SystemAlert.Button.figma.d.ts +11 -0
- package/lib/typescript/figma/SystemAlert.Button.figma.d.ts.map +1 -0
- package/lib/typescript/figma/SystemAlert.Close.figma.d.ts +11 -0
- package/lib/typescript/figma/SystemAlert.Close.figma.d.ts.map +1 -0
- package/lib/typescript/figma/SystemAlert.Description.figma.d.ts +8 -0
- package/lib/typescript/figma/SystemAlert.Description.figma.d.ts.map +1 -0
- package/lib/typescript/figma/SystemAlert.IconButton.figma.d.ts +11 -0
- package/lib/typescript/figma/SystemAlert.IconButton.figma.d.ts.map +1 -0
- package/lib/typescript/figma/SystemAlert.figma.d.ts +8 -0
- package/lib/typescript/figma/SystemAlert.figma.d.ts.map +1 -0
- package/package.json +5 -5
- package/src/components/BarChart/geometry.ts +1469 -0
- package/src/components/BarChart/index.tsx +1424 -0
- package/src/components/BarChart/styles.ts +31 -0
- package/src/components/Button/index.tsx +1 -1
- package/src/components/Chip/styles.ts +3 -1
- package/src/components/LineChart/geometry.ts +957 -0
- package/src/components/LineChart/index.tsx +1109 -0
- package/src/components/LineChart/styles.ts +26 -0
- package/src/components/PieChart/geometry.ts +295 -0
- package/src/components/PieChart/index.tsx +715 -0
- package/src/components/PieChart/styles.ts +101 -0
- package/src/components/ProgressCircle/ProgressCircleRing.tsx +10 -39
- package/src/components/ProgressCircle/ProgressRing.tsx +60 -0
- package/src/components/ScrollShadow/useScrollShadow.ts +12 -11
- package/src/components/Stepper/index.tsx +452 -0
- package/src/components/Stepper/styles.ts +234 -0
- package/src/components/Stepper/useStepperLabelFit.ts +21 -0
- package/src/components/Stepper/useStepperLabelFit.web.ts +53 -0
- package/src/components/Stepper/useStepperRingColors.ts +29 -0
- package/src/components/SystemAlert/animation.ts +252 -0
- package/src/components/SystemAlert/index.tsx +684 -0
- package/src/components/SystemAlert/styles.ts +212 -0
- package/src/components/SystemAlert/useSystemAlertStatusBarStyle.ts +57 -0
- package/src/components/Tabs/index.tsx +4 -0
- package/src/components/Tabs/styles.ts +1 -1
- package/src/components/chart/ChartInspector.tsx +726 -0
- package/src/components/chart/format.ts +95 -0
- package/src/components/chart/index.ts +24 -0
- package/src/components/chart/motion.ts +98 -0
- package/src/components/chart/palette.tsx +247 -0
- package/src/components/chart/size.ts +21 -0
- package/src/components/chart/ticks.ts +53 -0
- package/src/components/chart/types.ts +183 -0
- package/src/components/chart/useChartHostWidth.ts +26 -0
- package/src/components/index.ts +5 -0
|
@@ -0,0 +1,590 @@
|
|
|
1
|
+
# Insights (https://design.candescent.com/docs/patterns/insights)
|
|
2
|
+
|
|
3
|
+
## Insights Overview
|
|
4
|
+
|
|
5
|
+
A summary card over topic tabs of chart preview cards for budget, spending, daily spend, cash flow, and credit score.
|
|
6
|
+
|
|
7
|
+
**Platforms:** iOS, Android
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import {
|
|
11
|
+
BarChart,
|
|
12
|
+
Box,
|
|
13
|
+
Card,
|
|
14
|
+
Chip,
|
|
15
|
+
Divider,
|
|
16
|
+
Heading,
|
|
17
|
+
HStack,
|
|
18
|
+
Insight,
|
|
19
|
+
LineChart,
|
|
20
|
+
PieChart,
|
|
21
|
+
Tabs,
|
|
22
|
+
Text,
|
|
23
|
+
VStack,
|
|
24
|
+
} from '@cdx-ui/components';
|
|
25
|
+
import { FILL_WIDTH, formatUsd, formatUsdThousands } from '../_utils';
|
|
26
|
+
|
|
27
|
+
const SAFE_TO_SPEND = [
|
|
28
|
+
{ id: 'left', label: 'Left to spend', value: 462, color: 'simple-primary' },
|
|
29
|
+
// TODO(forge-ui): charts have no light neutral color for a progress track. `categorical-6` is
|
|
30
|
+
// the closest existing token but is much darker than the design's grey.
|
|
31
|
+
{ id: 'spent', label: 'Spent on bills', value: 738, color: 'categorical-6' },
|
|
32
|
+
] as const;
|
|
33
|
+
|
|
34
|
+
const SPENDING = [
|
|
35
|
+
{ id: 'housing', label: 'Housing', value: 2130 },
|
|
36
|
+
{ id: 'food', label: 'Food and dining', value: 1065 },
|
|
37
|
+
{ id: 'shopping', label: 'Shopping', value: 800 },
|
|
38
|
+
{ id: 'transport', label: 'Transport', value: 745 },
|
|
39
|
+
{ id: 'other', label: 'Other', value: 585, color: 'categorical-6' },
|
|
40
|
+
] as const;
|
|
41
|
+
|
|
42
|
+
// Today is its own series so it can take a darker color than the earlier days; both share one
|
|
43
|
+
// stack, so each day still draws a single bar.
|
|
44
|
+
// TODO(forge-ui): BarChart can't format band-axis labels, so the single-letter days are the data
|
|
45
|
+
// itself and tooltips and screen readers read "S" for both Saturday and Sunday.
|
|
46
|
+
const DAILY_SPENDING = [
|
|
47
|
+
{ day: 'S', earlier: 46, today: null },
|
|
48
|
+
{ day: 'S', earlier: 62, today: null },
|
|
49
|
+
{ day: 'M', earlier: 38, today: null },
|
|
50
|
+
{ day: 'T', earlier: 62, today: null },
|
|
51
|
+
{ day: 'W', earlier: 50, today: null },
|
|
52
|
+
{ day: 'T', earlier: 36, today: null },
|
|
53
|
+
{ day: 'F', earlier: null, today: 37 },
|
|
54
|
+
];
|
|
55
|
+
|
|
56
|
+
const CASH_FLOW = [
|
|
57
|
+
{ day: 'Mon', moneyIn: 6200, moneyOut: 2400 },
|
|
58
|
+
{ day: 'Tue', moneyIn: 1800, moneyOut: 3100 },
|
|
59
|
+
{ day: 'Wed', moneyIn: 2500, moneyOut: 1900 },
|
|
60
|
+
{ day: 'Thu', moneyIn: 7400, moneyOut: 4200 },
|
|
61
|
+
{ day: 'Fri', moneyIn: 3100, moneyOut: 2800 },
|
|
62
|
+
{ day: 'Sat', moneyIn: 900, moneyOut: 1600 },
|
|
63
|
+
{ day: 'Sun', moneyIn: 600, moneyOut: 1200 },
|
|
64
|
+
];
|
|
65
|
+
|
|
66
|
+
const CASH_FLOW_SUMMARY = [
|
|
67
|
+
{ label: 'Money in', value: '$22,500' },
|
|
68
|
+
{ label: 'Money out', value: '$17,200' },
|
|
69
|
+
{ label: 'Net', value: '+$5,300', color: 'success' as const },
|
|
70
|
+
];
|
|
71
|
+
|
|
72
|
+
const CREDIT_SCORE = [
|
|
73
|
+
{ month: 'May', score: 575 },
|
|
74
|
+
{ month: 'Jun', score: 572 },
|
|
75
|
+
{ month: 'Jul', score: 568 },
|
|
76
|
+
{ month: 'Aug', score: 571 },
|
|
77
|
+
{ month: 'Sep', score: 560 },
|
|
78
|
+
{ month: 'Oct', score: 547 },
|
|
79
|
+
];
|
|
80
|
+
|
|
81
|
+
function OnTrackChip() {
|
|
82
|
+
return (
|
|
83
|
+
<Chip color="action" size="small">
|
|
84
|
+
<Chip.Label>On track</Chip.Label>
|
|
85
|
+
</Chip>
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function SafeToSpendCard() {
|
|
90
|
+
return (
|
|
91
|
+
<Card>
|
|
92
|
+
<Card.Stripe />
|
|
93
|
+
<Card.Header>
|
|
94
|
+
<Heading size="sm">Safe to spend</Heading>
|
|
95
|
+
<OnTrackChip />
|
|
96
|
+
</Card.Header>
|
|
97
|
+
<Card.Content>
|
|
98
|
+
<VStack space="md">
|
|
99
|
+
<HStack space="lg" className="items-center">
|
|
100
|
+
<Box className="size-24">
|
|
101
|
+
<PieChart
|
|
102
|
+
series={[
|
|
103
|
+
{
|
|
104
|
+
id: 'safe-to-spend',
|
|
105
|
+
data: SAFE_TO_SPEND,
|
|
106
|
+
innerRadius: '80%',
|
|
107
|
+
valueFormatter: formatUsd,
|
|
108
|
+
},
|
|
109
|
+
]}
|
|
110
|
+
width={96}
|
|
111
|
+
height={96}
|
|
112
|
+
hideLegend
|
|
113
|
+
accessibilityLabel="$462 of your $1,200 monthly budget is left after bills."
|
|
114
|
+
/>
|
|
115
|
+
</Box>
|
|
116
|
+
<VStack space="xs" className="flex-1">
|
|
117
|
+
<Heading size="xl">$462</Heading>
|
|
118
|
+
<Text size="sm" color="secondary">
|
|
119
|
+
left after bills
|
|
120
|
+
</Text>
|
|
121
|
+
</VStack>
|
|
122
|
+
</HStack>
|
|
123
|
+
<Text color="secondary">
|
|
124
|
+
You have <Text weight="semibold">$57/day</Text> for the next 8 days until your Jan 30
|
|
125
|
+
paycheck.
|
|
126
|
+
</Text>
|
|
127
|
+
</VStack>
|
|
128
|
+
</Card.Content>
|
|
129
|
+
</Card>
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function SpendingCard() {
|
|
134
|
+
return (
|
|
135
|
+
<Card>
|
|
136
|
+
<Card.Header>
|
|
137
|
+
<Heading size="sm">Spending this month</Heading>
|
|
138
|
+
</Card.Header>
|
|
139
|
+
<Card.Content>
|
|
140
|
+
<VStack space="lg">
|
|
141
|
+
<PieChart
|
|
142
|
+
series={[
|
|
143
|
+
{
|
|
144
|
+
id: 'spending',
|
|
145
|
+
data: SPENDING,
|
|
146
|
+
innerRadius: '72%',
|
|
147
|
+
paddingAngle: 2,
|
|
148
|
+
cornerRadius: 4,
|
|
149
|
+
valueFormatter: formatUsd,
|
|
150
|
+
},
|
|
151
|
+
]}
|
|
152
|
+
width={192}
|
|
153
|
+
height={192}
|
|
154
|
+
legendLayout="list"
|
|
155
|
+
centerLabel={
|
|
156
|
+
<Box className="items-center">
|
|
157
|
+
<Heading size="md">$5,325</Heading>
|
|
158
|
+
<Text size="xs" color="secondary" className="uppercase">
|
|
159
|
+
Total
|
|
160
|
+
</Text>
|
|
161
|
+
</Box>
|
|
162
|
+
}
|
|
163
|
+
/>
|
|
164
|
+
<Insight aiGenerated>
|
|
165
|
+
<Insight.Description>
|
|
166
|
+
Food and dining is 18% higher than last month, mostly from weekend restaurant visits.
|
|
167
|
+
</Insight.Description>
|
|
168
|
+
</Insight>
|
|
169
|
+
</VStack>
|
|
170
|
+
</Card.Content>
|
|
171
|
+
</Card>
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
function DailySpendingCard() {
|
|
176
|
+
return (
|
|
177
|
+
<Card>
|
|
178
|
+
<Card.Header>
|
|
179
|
+
<Heading size="sm">Daily spending</Heading>
|
|
180
|
+
<OnTrackChip />
|
|
181
|
+
</Card.Header>
|
|
182
|
+
<Card.Content>
|
|
183
|
+
<HStack space="lg" className="flex-wrap items-end">
|
|
184
|
+
<VStack space="sm">
|
|
185
|
+
<VStack space="xs">
|
|
186
|
+
<Heading size="xl">$37</Heading>
|
|
187
|
+
<Text weight="medium">spent so far today</Text>
|
|
188
|
+
</VStack>
|
|
189
|
+
<Text size="sm" color="secondary">
|
|
190
|
+
Daily average: $49
|
|
191
|
+
</Text>
|
|
192
|
+
</VStack>
|
|
193
|
+
<BarChart
|
|
194
|
+
className="min-w-32 flex-1"
|
|
195
|
+
dataset={DAILY_SPENDING}
|
|
196
|
+
xAxis={[{ id: 'day', dataKey: 'day', scaleType: 'band' }]}
|
|
197
|
+
yAxis={[{ id: 'spend', position: 'none', min: 0, max: 62 }]}
|
|
198
|
+
series={[
|
|
199
|
+
{
|
|
200
|
+
id: 'earlier',
|
|
201
|
+
dataKey: 'earlier',
|
|
202
|
+
label: 'Spent',
|
|
203
|
+
stack: 'day',
|
|
204
|
+
color: 'simple-primary',
|
|
205
|
+
valueFormatter: formatUsd,
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
id: 'today',
|
|
209
|
+
dataKey: 'today',
|
|
210
|
+
label: 'Spent so far today',
|
|
211
|
+
stack: 'day',
|
|
212
|
+
color: 'simple-secondary',
|
|
213
|
+
valueFormatter: formatUsd,
|
|
214
|
+
},
|
|
215
|
+
]}
|
|
216
|
+
grid={{ horizontal: false }}
|
|
217
|
+
tooltip={{ trigger: 'item' }}
|
|
218
|
+
categoryGapRatio={0.7}
|
|
219
|
+
borderRadius={999}
|
|
220
|
+
width={FILL_WIDTH}
|
|
221
|
+
height={112}
|
|
222
|
+
hideLegend
|
|
223
|
+
scrollable={false}
|
|
224
|
+
accessibilityLabel="Spending for the last seven days. $37 so far today, Friday, against a $49 daily average."
|
|
225
|
+
/>
|
|
226
|
+
</HStack>
|
|
227
|
+
</Card.Content>
|
|
228
|
+
</Card>
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
function CashFlowCard() {
|
|
233
|
+
return (
|
|
234
|
+
<Card>
|
|
235
|
+
<Card.Header>
|
|
236
|
+
<Heading size="sm">Cash flow this week</Heading>
|
|
237
|
+
</Card.Header>
|
|
238
|
+
<Card.Content>
|
|
239
|
+
<VStack space="lg">
|
|
240
|
+
<BarChart
|
|
241
|
+
dataset={CASH_FLOW}
|
|
242
|
+
xAxis={[{ id: 'day', dataKey: 'day', scaleType: 'band' }]}
|
|
243
|
+
yAxis={[
|
|
244
|
+
{
|
|
245
|
+
id: 'amount',
|
|
246
|
+
min: 0,
|
|
247
|
+
max: 15000,
|
|
248
|
+
tickNumber: 4,
|
|
249
|
+
valueFormatter: formatUsdThousands,
|
|
250
|
+
},
|
|
251
|
+
]}
|
|
252
|
+
series={[
|
|
253
|
+
{
|
|
254
|
+
id: 'moneyIn',
|
|
255
|
+
dataKey: 'moneyIn',
|
|
256
|
+
label: 'In',
|
|
257
|
+
stack: 'flow',
|
|
258
|
+
valueFormatter: formatUsd,
|
|
259
|
+
},
|
|
260
|
+
{
|
|
261
|
+
id: 'moneyOut',
|
|
262
|
+
dataKey: 'moneyOut',
|
|
263
|
+
label: 'Out',
|
|
264
|
+
stack: 'flow',
|
|
265
|
+
valueFormatter: formatUsd,
|
|
266
|
+
},
|
|
267
|
+
]}
|
|
268
|
+
borderRadius={2}
|
|
269
|
+
width={FILL_WIDTH}
|
|
270
|
+
height={176}
|
|
271
|
+
scrollable={false}
|
|
272
|
+
accessibilityLabel="Money in and out each day this week."
|
|
273
|
+
/>
|
|
274
|
+
<VStack>
|
|
275
|
+
{CASH_FLOW_SUMMARY.map((row, index) => (
|
|
276
|
+
<VStack key={row.label}>
|
|
277
|
+
{index > 0 ? <Divider /> : null}
|
|
278
|
+
<HStack className="items-center justify-between py-2">
|
|
279
|
+
<Text size="sm" color="secondary">
|
|
280
|
+
{row.label}
|
|
281
|
+
</Text>
|
|
282
|
+
<Text size="sm" weight="medium" color={row.color}>
|
|
283
|
+
{row.value}
|
|
284
|
+
</Text>
|
|
285
|
+
</HStack>
|
|
286
|
+
</VStack>
|
|
287
|
+
))}
|
|
288
|
+
</VStack>
|
|
289
|
+
<Insight aiGenerated>
|
|
290
|
+
<Insight.Description>
|
|
291
|
+
More came in than went out this week. Moving $1,000 to savings would still leave a
|
|
292
|
+
cushion.
|
|
293
|
+
</Insight.Description>
|
|
294
|
+
</Insight>
|
|
295
|
+
</VStack>
|
|
296
|
+
</Card.Content>
|
|
297
|
+
</Card>
|
|
298
|
+
);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
function CreditScoreCard() {
|
|
302
|
+
return (
|
|
303
|
+
<Card>
|
|
304
|
+
<Card.Header>
|
|
305
|
+
<Heading size="sm">Credit score</Heading>
|
|
306
|
+
</Card.Header>
|
|
307
|
+
<Card.Content>
|
|
308
|
+
<VStack space="lg">
|
|
309
|
+
<HStack space="lg" className="items-center">
|
|
310
|
+
<LineChart
|
|
311
|
+
className="min-w-0 flex-1"
|
|
312
|
+
dataset={CREDIT_SCORE}
|
|
313
|
+
xAxis={[
|
|
314
|
+
{
|
|
315
|
+
id: 'month',
|
|
316
|
+
dataKey: 'month',
|
|
317
|
+
tickLabelInterval: (_, index) => (CREDIT_SCORE.length - 1 - index) % 2 === 0,
|
|
318
|
+
},
|
|
319
|
+
]}
|
|
320
|
+
yAxis={[{ id: 'score', min: 540, max: 580, tickNumber: 3 }]}
|
|
321
|
+
series={[{ id: 'score', dataKey: 'score', label: 'Credit score', color: 'danger' }]}
|
|
322
|
+
width={FILL_WIDTH}
|
|
323
|
+
height={128}
|
|
324
|
+
hideLegend
|
|
325
|
+
scrollable={false}
|
|
326
|
+
accessibilityLabel="Credit score from May to October, falling from 575 to 547."
|
|
327
|
+
/>
|
|
328
|
+
<VStack space="xs" className="items-end">
|
|
329
|
+
<Heading size="xl">547</Heading>
|
|
330
|
+
<Text size="sm" color="secondary">
|
|
331
|
+
Poor
|
|
332
|
+
</Text>
|
|
333
|
+
<Text size="sm" color="danger">
|
|
334
|
+
−13 since Sep
|
|
335
|
+
</Text>
|
|
336
|
+
</VStack>
|
|
337
|
+
</HStack>
|
|
338
|
+
<Insight aiGenerated color="danger">
|
|
339
|
+
{/* TODO(forge-ui): a summary Insight has no body-size title, and Insight.Title renders
|
|
340
|
+
as a heading. The emphasized first line is a semibold nested Text instead. */}
|
|
341
|
+
<Insight.Description>
|
|
342
|
+
<Text weight="semibold">
|
|
343
|
+
2 missed payments in the last 90 days are impacting your score
|
|
344
|
+
</Text>
|
|
345
|
+
{'\n'}
|
|
346
|
+
<Text color="secondary">
|
|
347
|
+
Set up autopay on all your cards and bills to prevent this.
|
|
348
|
+
</Text>
|
|
349
|
+
</Insight.Description>
|
|
350
|
+
</Insight>
|
|
351
|
+
</VStack>
|
|
352
|
+
</Card.Content>
|
|
353
|
+
</Card>
|
|
354
|
+
);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
export default function InsightsOverviewBlock() {
|
|
358
|
+
return (
|
|
359
|
+
<VStack space="lg" className="w-full">
|
|
360
|
+
<Heading size="md">Your money this month</Heading>
|
|
361
|
+
<SafeToSpendCard />
|
|
362
|
+
<Tabs defaultValue="spending">
|
|
363
|
+
<Tabs.List accessibilityLabel="Insight topics" scrollable={false} className="self-center">
|
|
364
|
+
<Tabs.Tab value="spending">
|
|
365
|
+
<Tabs.TabLabel>Spending</Tabs.TabLabel>
|
|
366
|
+
</Tabs.Tab>
|
|
367
|
+
<Tabs.Tab value="cash-flow">
|
|
368
|
+
<Tabs.TabLabel>Cash flow</Tabs.TabLabel>
|
|
369
|
+
</Tabs.Tab>
|
|
370
|
+
<Tabs.Tab value="credit">
|
|
371
|
+
<Tabs.TabLabel>Credit</Tabs.TabLabel>
|
|
372
|
+
</Tabs.Tab>
|
|
373
|
+
</Tabs.List>
|
|
374
|
+
<Tabs.Panel value="spending" className="mt-3">
|
|
375
|
+
<VStack space="lg">
|
|
376
|
+
<SpendingCard />
|
|
377
|
+
<DailySpendingCard />
|
|
378
|
+
</VStack>
|
|
379
|
+
</Tabs.Panel>
|
|
380
|
+
<Tabs.Panel value="cash-flow" className="mt-3">
|
|
381
|
+
<CashFlowCard />
|
|
382
|
+
</Tabs.Panel>
|
|
383
|
+
<Tabs.Panel value="credit" className="mt-3">
|
|
384
|
+
<CreditScoreCard />
|
|
385
|
+
</Tabs.Panel>
|
|
386
|
+
</Tabs>
|
|
387
|
+
</VStack>
|
|
388
|
+
);
|
|
389
|
+
}
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
## Insight with Chart
|
|
393
|
+
|
|
394
|
+
Dismissible insight cards that back their headline with a chart: a horizontal bar comparison with month-over-month change, and a cash-flow waterfall.
|
|
395
|
+
|
|
396
|
+
**Platforms:** iOS, Android
|
|
397
|
+
|
|
398
|
+
```tsx
|
|
399
|
+
import {
|
|
400
|
+
BarChart,
|
|
401
|
+
Button,
|
|
402
|
+
Insight,
|
|
403
|
+
Text,
|
|
404
|
+
VStack,
|
|
405
|
+
type ChartValueFormatter,
|
|
406
|
+
} from '@cdx-ui/components';
|
|
407
|
+
import { FILL_WIDTH, formatUsd } from '../_utils';
|
|
408
|
+
|
|
409
|
+
const SPENDING = [
|
|
410
|
+
{ category: 'Housing', amount: 1800, change: 0 },
|
|
411
|
+
{ category: 'Dining', amount: 720, change: 195 },
|
|
412
|
+
{ category: 'Transport', amount: 510, change: -110 },
|
|
413
|
+
];
|
|
414
|
+
|
|
415
|
+
// TODO(forge-ui): bar labels are plain SVG text, so the change can't take the design's trend
|
|
416
|
+
// icon or tertiary color. It is written into the label as an arrow instead.
|
|
417
|
+
const formatSpending: ChartValueFormatter = (value, { dataIndex }) => {
|
|
418
|
+
const change = dataIndex === undefined ? 0 : SPENDING[dataIndex].change;
|
|
419
|
+
if (change === 0) return formatUsd(value);
|
|
420
|
+
return `${formatUsd(value)} ${change > 0 ? '↗' : '↘'} ${formatUsd(Math.abs(change))}`;
|
|
421
|
+
};
|
|
422
|
+
|
|
423
|
+
const CASH_FLOW = [
|
|
424
|
+
{ step: 'Starting', amount: 2300, isTotal: true },
|
|
425
|
+
{ step: 'Income', amount: 1850 },
|
|
426
|
+
{ step: 'Expenses', amount: -1430 },
|
|
427
|
+
{ step: 'Ending', isTotal: true },
|
|
428
|
+
];
|
|
429
|
+
|
|
430
|
+
function SpendingInsight() {
|
|
431
|
+
return (
|
|
432
|
+
<Insight layout="detail" onClose={() => {}}>
|
|
433
|
+
<Insight.Tag>Spending</Insight.Tag>
|
|
434
|
+
<Insight.Header>
|
|
435
|
+
<Insight.Title>
|
|
436
|
+
Housing made up 36% of your spending this month vs. last month
|
|
437
|
+
</Insight.Title>
|
|
438
|
+
</Insight.Header>
|
|
439
|
+
<Insight.Content>
|
|
440
|
+
<BarChart
|
|
441
|
+
dataset={SPENDING}
|
|
442
|
+
layout="horizontal"
|
|
443
|
+
yAxis={[{ id: 'category', dataKey: 'category', scaleType: 'band' }]}
|
|
444
|
+
xAxis={[{ id: 'amount', position: 'none', min: 0, max: 1800 }]}
|
|
445
|
+
series={[
|
|
446
|
+
{
|
|
447
|
+
id: 'amount',
|
|
448
|
+
dataKey: 'amount',
|
|
449
|
+
label: 'This month',
|
|
450
|
+
valueFormatter: formatSpending,
|
|
451
|
+
},
|
|
452
|
+
]}
|
|
453
|
+
barLabel
|
|
454
|
+
grid={{ vertical: false }}
|
|
455
|
+
borderRadius={4}
|
|
456
|
+
width={FILL_WIDTH}
|
|
457
|
+
height={112}
|
|
458
|
+
hideLegend
|
|
459
|
+
scrollable={false}
|
|
460
|
+
accessibilityLabel="Spending this month by category. Housing $1,800, unchanged. Dining $720, up $195. Transport $510, down $110."
|
|
461
|
+
/>
|
|
462
|
+
</Insight.Content>
|
|
463
|
+
<Insight.Footer>
|
|
464
|
+
<Button variant="outline" color="action" size="small" className="flex-1">
|
|
465
|
+
<Button.Label>Compare spending</Button.Label>
|
|
466
|
+
</Button>
|
|
467
|
+
</Insight.Footer>
|
|
468
|
+
</Insight>
|
|
469
|
+
);
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
function CashFlowInsight() {
|
|
473
|
+
return (
|
|
474
|
+
<Insight layout="detail" onClose={() => {}}>
|
|
475
|
+
<Insight.Tag>Cashflow</Insight.Tag>
|
|
476
|
+
<Insight.Header>
|
|
477
|
+
<Insight.Title>You brought in $420 more than you spent this week</Insight.Title>
|
|
478
|
+
<Insight.Description>
|
|
479
|
+
You received <Text weight="bold">$1,850</Text> and spent{' '}
|
|
480
|
+
<Text weight="bold">$1,430 this week</Text>, so your checking balance grew from{' '}
|
|
481
|
+
<Text weight="bold">$2,300 to $2,720</Text>.
|
|
482
|
+
</Insight.Description>
|
|
483
|
+
</Insight.Header>
|
|
484
|
+
<Insight.Content>
|
|
485
|
+
<BarChart
|
|
486
|
+
dataset={CASH_FLOW}
|
|
487
|
+
xAxis={[{ id: 'step', dataKey: 'step', scaleType: 'band' }]}
|
|
488
|
+
yAxis={[{ id: 'amount', position: 'none', min: 0, max: 4150 }]}
|
|
489
|
+
series={[
|
|
490
|
+
{
|
|
491
|
+
id: 'balance',
|
|
492
|
+
dataKey: 'amount',
|
|
493
|
+
waterfall: { totalKey: 'isTotal' },
|
|
494
|
+
valueFormatter: formatUsd,
|
|
495
|
+
},
|
|
496
|
+
]}
|
|
497
|
+
barLabel
|
|
498
|
+
grid={{ horizontal: false }}
|
|
499
|
+
borderRadius={4}
|
|
500
|
+
width={FILL_WIDTH}
|
|
501
|
+
height={240}
|
|
502
|
+
hideLegend
|
|
503
|
+
scrollable={false}
|
|
504
|
+
accessibilityLabel="Checking balance this week: starting $2,300, income $1,850, expenses $1,430, ending $2,720."
|
|
505
|
+
/>
|
|
506
|
+
</Insight.Content>
|
|
507
|
+
<Insight.Footer>
|
|
508
|
+
<Button variant="outline" color="action" size="small" className="flex-1">
|
|
509
|
+
<Button.Label>Compare spending</Button.Label>
|
|
510
|
+
</Button>
|
|
511
|
+
<Button variant="outline" color="action" size="small" className="flex-1">
|
|
512
|
+
<Button.Label>View categories</Button.Label>
|
|
513
|
+
</Button>
|
|
514
|
+
</Insight.Footer>
|
|
515
|
+
</Insight>
|
|
516
|
+
);
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
export default function InsightChartBlock() {
|
|
520
|
+
return (
|
|
521
|
+
<VStack space="lg" className="w-full">
|
|
522
|
+
<SpendingInsight />
|
|
523
|
+
<CashFlowInsight />
|
|
524
|
+
</VStack>
|
|
525
|
+
);
|
|
526
|
+
}
|
|
527
|
+
```
|
|
528
|
+
|
|
529
|
+
## Insight with Table
|
|
530
|
+
|
|
531
|
+
A dismissible insight card that lists upcoming bills in a compact table.
|
|
532
|
+
|
|
533
|
+
**Platforms:** iOS, Android
|
|
534
|
+
|
|
535
|
+
```tsx
|
|
536
|
+
import { Avatar, Button, HStack, Insight, Table, Text } from '@cdx-ui/components';
|
|
537
|
+
import { Call, DirectionsCar, HumidityLow, Wifi } from '@cdx-ui/icons';
|
|
538
|
+
|
|
539
|
+
const BILLS = [
|
|
540
|
+
{ name: 'Car insurance', icon: DirectionsCar, due: 'Oct 13', amount: '$460' },
|
|
541
|
+
{ name: 'Phone', icon: Call, due: 'Oct 14', amount: '$68' },
|
|
542
|
+
{ name: 'Internet', icon: Wifi, due: 'Oct 15', amount: '$96' },
|
|
543
|
+
{ name: 'Water', icon: HumidityLow, due: 'Oct 16', amount: '$111' },
|
|
544
|
+
];
|
|
545
|
+
|
|
546
|
+
export default function InsightTableBlock() {
|
|
547
|
+
return (
|
|
548
|
+
<Insight layout="detail" onClose={() => {}} className="w-full">
|
|
549
|
+
<Insight.Tag>Bills</Insight.Tag>
|
|
550
|
+
<Insight.Header>
|
|
551
|
+
<Insight.Title>We found 7 recurring bills</Insight.Title>
|
|
552
|
+
<Insight.Description>
|
|
553
|
+
4 due next week · about <Text weight="bold">$735</Text>
|
|
554
|
+
</Insight.Description>
|
|
555
|
+
</Insight.Header>
|
|
556
|
+
<Insight.Content>
|
|
557
|
+
<Table fullBleed accessibilityLabel="Bills due next week">
|
|
558
|
+
<Table.Body>
|
|
559
|
+
{BILLS.map((bill) => (
|
|
560
|
+
<Table.Row key={bill.name}>
|
|
561
|
+
<Table.Cell colSpan={2}>
|
|
562
|
+
<HStack space="sm" className="items-center">
|
|
563
|
+
<Avatar color="brand" variant="subtle" shape="circle" size="sm">
|
|
564
|
+
<Avatar.Icon as={bill.icon} />
|
|
565
|
+
</Avatar>
|
|
566
|
+
<Text numberOfLines={1}>{bill.name}</Text>
|
|
567
|
+
</HStack>
|
|
568
|
+
</Table.Cell>
|
|
569
|
+
<Table.Cell align="end">
|
|
570
|
+
<Text size="sm" color="secondary">
|
|
571
|
+
{bill.due}
|
|
572
|
+
</Text>
|
|
573
|
+
</Table.Cell>
|
|
574
|
+
<Table.Cell align="end">
|
|
575
|
+
<Text weight="medium">{bill.amount}</Text>
|
|
576
|
+
</Table.Cell>
|
|
577
|
+
</Table.Row>
|
|
578
|
+
))}
|
|
579
|
+
</Table.Body>
|
|
580
|
+
</Table>
|
|
581
|
+
</Insight.Content>
|
|
582
|
+
<Insight.Footer>
|
|
583
|
+
<Button variant="outline" color="action" size="small" className="flex-1">
|
|
584
|
+
<Button.Label>View bills</Button.Label>
|
|
585
|
+
</Button>
|
|
586
|
+
</Insight.Footer>
|
|
587
|
+
</Insight>
|
|
588
|
+
);
|
|
589
|
+
}
|
|
590
|
+
```
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# 0.3.4 (https://design.candescent.com/docs/resources/release-notes/0.3.4)
|
|
2
|
+
|
|
3
|
+
Select adds multiple selection, in-list search, and a native bottom sheet; Input gains a subtle variant for fields inside popups and sheets.
|
|
4
|
+
|
|
5
|
+
This release expands **[Select](https://design.candescent.com/docs/components/select/content.md)** for long option lists and native pickers, adds a filled **[Input](https://design.candescent.com/docs/components/input/content.md)** variant for search fields inside overlays, and fixes **[Drawer](https://design.candescent.com/docs/components/drawer/content.md)** permanent panels on web.
|
|
6
|
+
|
|
7
|
+
## What's new
|
|
8
|
+
|
|
9
|
+
**[Select](https://design.candescent.com/docs/components/select/content.md)** — Set **`type="multiple"`** so `value` is a `string[]` and each option press toggles selection while the popup stays open. Use **`Select.ItemControl`** for checkbox affordances and **`Select.Value`** with a function child to read `selectedItems` and `selectedText`; multiple mode joins labels with a comma on one line. Add **`Select.Search`** and **`Select.Empty`** to filter options in single and multiple mode via controllable `inputValue`, `defaultInputValue`, `onInputChange`, and an optional custom `filter`; the query clears when the popup closes and selected values still resolve against the full item list. On iOS and Android, swap **`Select.Content`** for **`Select.BottomSheet`** to present the same search and list regions in the shared picker sheet (web still renders the dropdown). Disabled items no longer receive keyboard highlight. Wrappers that assume `value` is always a `string` should narrow with `Extract<SelectProps, { type?: 'single' }>` ([#857](https://github.com/dfh-candescent/forge-design-system/pull/857)).
|
|
10
|
+
|
|
11
|
+
**[Input](https://design.candescent.com/docs/components/input/content.md)** — Pass **`variant="subtle"`** for a filled, borderless field suited to search inputs inside popovers and bottom sheets. **`Select.Search`** defaults to subtle in both dropdown and sheet paths; override with the search field’s own **`variant`** prop ([#857](https://github.com/dfh-candescent/forge-design-system/pull/857)).
|
|
12
|
+
|
|
13
|
+
## Bug fixes
|
|
14
|
+
|
|
15
|
+
**[Drawer](https://design.candescent.com/docs/components/drawer/content.md)** — A permanent panel on web collapses to zero width when closed instead of leaving an empty surface behind ([#861](https://github.com/dfh-candescent/forge-design-system/pull/861)).
|
|
16
|
+
|
|
17
|
+
**[Select](https://design.candescent.com/docs/components/select/content.md)** — The first option receives highlight when items load or change after the popup opens, so screen readers get a valid `aria-activedescendant` without an arrow key ([#857](https://github.com/dfh-candescent/forge-design-system/pull/857)).
|
|
18
|
+
|
|
19
|
+
## Documentation
|
|
20
|
+
|
|
21
|
+
**Invite User drawer** — Web-only Forms pattern: a permanent right-side drawer with name, email, role select, and a searchable multi-select for teams shown as removable chips ([#861](https://github.com/dfh-candescent/forge-design-system/pull/861)).
|
|
22
|
+
|
|
23
|
+
**Input**, **OTP Input**, and **Insurance Disclosure** — Component page titles use Title Case in the sidebar ([#860](https://github.com/dfh-candescent/forge-design-system/pull/860)).
|
|
24
|
+
|
|
25
|
+
**Text** — New demos for nested inline text, slot composition, and mixed nesting ([#858](https://github.com/dfh-candescent/forge-design-system/pull/858)).
|
|
26
|
+
|
|
27
|
+
**Pattern blocks** — Block section headings on pattern pages are clickable anchor links for deep linking ([#862](https://github.com/dfh-candescent/forge-design-system/pull/862)).
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# 0.3.5 (https://design.candescent.com/docs/resources/release-notes/0.3.5)
|
|
2
|
+
|
|
3
|
+
Selected subtle Chip labels stay visible on Android when the variant changes from outline to subtle.
|
|
4
|
+
|
|
5
|
+
## Bug fixes
|
|
6
|
+
|
|
7
|
+
**[Chip](https://design.candescent.com/docs/components/chip/content.md)** — A selected chip that switches from `outline` to `subtle` keeps its label painted on Android ([#872](https://github.com/dfh-candescent/forge-design-system/pull/872)).
|
|
@@ -8,6 +8,8 @@ Notes are generated from the release commit itself, so the versions and commit r
|
|
|
8
8
|
each entry are exact. Releases that contained nothing but backlog or dependency bookkeeping
|
|
9
9
|
are omitted.
|
|
10
10
|
|
|
11
|
+
- [0.3.5](https://design.candescent.com/docs/resources/release-notes/0.3.5/content.md) — 2026-10-21 — Selected subtle Chip labels stay visible on Android when the variant changes from outline to subtle.
|
|
12
|
+
- [0.3.4](https://design.candescent.com/docs/resources/release-notes/0.3.4/content.md) — 2026-10-20 — Select adds multiple selection, in-list search, and a native bottom sheet; Input gains a subtle variant for fields inside popups and sheets.
|
|
11
13
|
- [0.3.3](https://design.candescent.com/docs/resources/release-notes/0.3.3/content.md) — 2026-10-15 — Insight and InsightStack add dismissible summary cards with status colors, optional AI styling, and stacked depth for insight feeds.
|
|
12
14
|
- [0.3.2](https://design.candescent.com/docs/resources/release-notes/0.3.2/content.md) — 2026-10-13 — CurrencyInput adds an outline variant for bordered amount fields; BottomSheet opens reliably in optimized web production builds.
|
|
13
15
|
- [0.3.1](https://design.candescent.com/docs/resources/release-notes/0.3.1/content.md) — 2026-10-13 — DataGrid adds filterMode for server-side search and filters; IconButton adds warning, success, and info color options.
|