@scalewing/react 1.38.0 → 1.39.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/CHANGELOG.md +9 -0
- package/README.md +53 -1
- package/dist/chart-axis.d.ts +61 -0
- package/dist/chart-axis.js +83 -0
- package/dist/chart-dates.d.ts +6 -0
- package/dist/chart-dates.js +15 -0
- package/dist/chart-metrics.d.ts +40 -0
- package/dist/chart-metrics.js +48 -0
- package/dist/chart-scale.d.ts +48 -0
- package/dist/chart-scale.js +116 -0
- package/dist/chart-table-rows.d.ts +8 -0
- package/dist/chart-table-rows.js +1 -0
- package/dist/column-chart-bars.d.ts +38 -0
- package/dist/column-chart-bars.js +82 -0
- package/dist/column-chart-callouts.d.ts +48 -0
- package/dist/column-chart-callouts.js +54 -0
- package/dist/column-chart-input.d.ts +40 -0
- package/dist/column-chart-input.js +60 -0
- package/dist/column-chart-layout.d.ts +63 -0
- package/dist/column-chart-layout.js +97 -0
- package/dist/components/BarChart.d.ts +1 -1
- package/dist/components/BarChart.js +1 -1
- package/dist/components/ChartLegend.d.ts +38 -0
- package/dist/components/ChartLegend.js +32 -0
- package/dist/components/ColumnChart.d.ts +72 -0
- package/dist/components/ColumnChart.js +71 -0
- package/dist/components/DataBar.d.ts +6 -6
- package/dist/components/LineChart.d.ts +83 -0
- package/dist/components/LineChart.js +77 -0
- package/dist/components/chart/ChartTable.d.ts +16 -0
- package/dist/components/chart/ChartTable.js +12 -0
- package/dist/components/chart/ChartValueAxis.d.ts +14 -0
- package/dist/components/chart/ChartValueAxis.js +11 -0
- package/dist/components/chart/use-chart-width.d.ts +8 -0
- package/dist/components/chart/use-chart-width.js +34 -0
- package/dist/components/column-chart/ChartCalloutList.d.ts +16 -0
- package/dist/components/column-chart/ChartCalloutList.js +13 -0
- package/dist/components/column-chart/ColumnChartDrawing.d.ts +17 -0
- package/dist/components/column-chart/ColumnChartDrawing.js +18 -0
- package/dist/components/line-chart/LineChartDrawing.d.ts +17 -0
- package/dist/components/line-chart/LineChartDrawing.js +16 -0
- package/dist/css/chart-marks.d.ts +10 -0
- package/dist/css/chart-marks.js +15 -0
- package/dist/css/chart-tones.d.ts +68 -0
- package/dist/css/chart-tones.js +130 -0
- package/dist/css/{css-chart.d.ts → css-bar-chart.d.ts} +2 -2
- package/dist/css/{css-chart.js → css-bar-chart.js} +2 -2
- package/dist/css/css-chart-legend.d.ts +5 -0
- package/dist/css/css-chart-legend.js +102 -0
- package/dist/css/css-chart-plot.d.ts +2 -0
- package/dist/css/css-chart-plot.js +170 -0
- package/dist/css/css-components.js +14 -2
- package/dist/css/css-data-bar.d.ts +4 -9
- package/dist/css/css-data-bar.js +15 -31
- package/dist/css/css-line-chart.d.ts +2 -0
- package/dist/css/css-line-chart.js +31 -0
- package/dist/css/stylesheet.js +10 -2
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/is-one-of.d.ts +5 -0
- package/dist/is-one-of.js +7 -0
- package/dist/line-chart-input.d.ts +39 -0
- package/dist/line-chart-input.js +70 -0
- package/dist/line-chart-layout.d.ts +68 -0
- package/dist/line-chart-layout.js +99 -0
- package/dist/line-chart-markers.d.ts +29 -0
- package/dist/line-chart-markers.js +57 -0
- package/dist/line-chart-path.d.ts +18 -0
- package/dist/line-chart-path.js +33 -0
- package/dist/line-chart-points.d.ts +6 -0
- package/dist/line-chart-points.js +8 -0
- package/dist/line-chart-table.d.ts +15 -0
- package/dist/line-chart-table.js +29 -0
- package/dist/styles.css +219 -0
- package/package.json +1 -1
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { categoricalColorKeys, categoricalHues, } from '@scalewing/tokens';
|
|
2
|
+
import { isOneOf } from '../is-one-of.js';
|
|
3
|
+
/** A source as its custom property. */
|
|
4
|
+
function sourceProperty(source) {
|
|
5
|
+
return 'semantic' in source
|
|
6
|
+
? `var(--sw-color-${source.semantic})`
|
|
7
|
+
: `var(--sw-categorical-${source.categorical})`;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* The statement tones a range bar's fill takes (see DataBar). `danger` is
|
|
11
|
+
* for a shortage, never for cash leaving: an outflow is `muted`.
|
|
12
|
+
*/
|
|
13
|
+
export const statementFillTones = [
|
|
14
|
+
'neutral',
|
|
15
|
+
'success',
|
|
16
|
+
'muted',
|
|
17
|
+
'strong',
|
|
18
|
+
'accent',
|
|
19
|
+
'danger',
|
|
20
|
+
];
|
|
21
|
+
/**
|
|
22
|
+
* Every fill tone: the categorical colours (a chart's series), then the
|
|
23
|
+
* statement tones a range bar adds. `neutral` is in both and is one grey.
|
|
24
|
+
*/
|
|
25
|
+
export const chartFillTones = [
|
|
26
|
+
...categoricalColorKeys,
|
|
27
|
+
...statementFillTones.filter((tone) => tone !== 'neutral'),
|
|
28
|
+
];
|
|
29
|
+
/** The tones a line, a marker or the boxed period is drawn in. */
|
|
30
|
+
export const chartStrokeTones = [
|
|
31
|
+
'accent',
|
|
32
|
+
'success',
|
|
33
|
+
'warning',
|
|
34
|
+
'danger',
|
|
35
|
+
'neutral',
|
|
36
|
+
];
|
|
37
|
+
export const chartTones = [
|
|
38
|
+
...new Set([...chartFillTones, ...chartStrokeTones]),
|
|
39
|
+
];
|
|
40
|
+
/**
|
|
41
|
+
* How much of a categorical colour a column's fill mixes into the surface:
|
|
42
|
+
* a lighter fill, so a line drawn over the columns stands apart, that
|
|
43
|
+
* keeps 1.5:1 on the surface in every palette and scheme.
|
|
44
|
+
*/
|
|
45
|
+
export const categoricalFillShare = 0.72;
|
|
46
|
+
/**
|
|
47
|
+
* How much of the danger colour its fill mixes into the surface (a
|
|
48
|
+
* shortage's range bar, never cash leaving): a light red, at 1.5:1 or more
|
|
49
|
+
* on the surface in every palette and scheme, as every other fill.
|
|
50
|
+
*/
|
|
51
|
+
export const dangerFillShare = 0.4;
|
|
52
|
+
/** Each fill tone's colour, mixed into the surface. */
|
|
53
|
+
export const chartFillMixes = {
|
|
54
|
+
...Object.fromEntries(categoricalHues.map((hue) => [
|
|
55
|
+
hue,
|
|
56
|
+
{ categorical: hue, share: categoricalFillShare, into: 'surface' },
|
|
57
|
+
])),
|
|
58
|
+
neutral: { semantic: 'muted', share: 0.65, into: 'surface' },
|
|
59
|
+
success: { semantic: 'success', share: 0.55, into: 'surface' },
|
|
60
|
+
muted: { semantic: 'muted', share: 0.35, into: 'surface' },
|
|
61
|
+
strong: { semantic: 'text', share: 0.85, into: 'surface' },
|
|
62
|
+
accent: { semantic: 'accent', share: 1, into: 'surface' },
|
|
63
|
+
danger: { semantic: 'danger', share: dangerFillShare, into: 'surface' },
|
|
64
|
+
};
|
|
65
|
+
/** Each stroke tone's colour: a semantic colour, or muted for neutral. */
|
|
66
|
+
export const chartStrokeColors = {
|
|
67
|
+
accent: { semantic: 'accent' },
|
|
68
|
+
success: { semantic: 'success' },
|
|
69
|
+
warning: { semantic: 'warning' },
|
|
70
|
+
danger: { semantic: 'danger' },
|
|
71
|
+
neutral: { semantic: 'muted' },
|
|
72
|
+
};
|
|
73
|
+
/**
|
|
74
|
+
* How much of a line's stroke the area under it takes, over transparency:
|
|
75
|
+
* a quiet tint behind the line, decorative (the line carries the values).
|
|
76
|
+
*/
|
|
77
|
+
export const chartAreaShare = 0.12;
|
|
78
|
+
/** How much of a hue's colour its words keep, moved toward the text colour. */
|
|
79
|
+
export const categoricalInkShare = 0.3;
|
|
80
|
+
/** How much of a semantic colour its words keep, moved toward the text colour. */
|
|
81
|
+
export const semanticInkShare = 0.5;
|
|
82
|
+
/** The tones whose words are drawn beside a mark: a series' and a stroke's. */
|
|
83
|
+
export const chartInkTones = [...categoricalHues, ...chartStrokeTones];
|
|
84
|
+
/** The words beside a mark: its tone moved toward the text colour. */
|
|
85
|
+
export const chartInkMixes = {
|
|
86
|
+
...Object.fromEntries(categoricalHues.map((hue) => [
|
|
87
|
+
hue,
|
|
88
|
+
{ categorical: hue, share: categoricalInkShare, into: 'text' },
|
|
89
|
+
])),
|
|
90
|
+
accent: { semantic: 'accent', share: semanticInkShare, into: 'text' },
|
|
91
|
+
success: { semantic: 'success', share: semanticInkShare, into: 'text' },
|
|
92
|
+
warning: { semantic: 'warning', share: semanticInkShare, into: 'text' },
|
|
93
|
+
danger: { semantic: 'danger', share: semanticInkShare, into: 'text' },
|
|
94
|
+
neutral: { semantic: 'muted', share: 1, into: 'text' },
|
|
95
|
+
};
|
|
96
|
+
/** A mix as CSS: the colour alone when unmixed. */
|
|
97
|
+
export function chartColorMix(mix) {
|
|
98
|
+
const color = sourceProperty(mix);
|
|
99
|
+
if (mix.share === 1)
|
|
100
|
+
return color;
|
|
101
|
+
return `color-mix(in srgb, ${color} ${Math.round(mix.share * 100)}%, var(--sw-color-${mix.into}))`;
|
|
102
|
+
}
|
|
103
|
+
/** A fill tone's colour. */
|
|
104
|
+
export function chartFill(tone) {
|
|
105
|
+
return chartColorMix(chartFillMixes[tone]);
|
|
106
|
+
}
|
|
107
|
+
/*
|
|
108
|
+
* A tone class hands its roles to the marks inside it as custom
|
|
109
|
+
* properties, `--sw-chart-fill`, `--sw-chart-stroke` and `--sw-chart-ink`,
|
|
110
|
+
* so a legend swatch, a column, a line and a label each read the role it
|
|
111
|
+
* draws. A tone sets only the roles it has.
|
|
112
|
+
*/
|
|
113
|
+
function toneDeclarations(tone) {
|
|
114
|
+
const declarations = [];
|
|
115
|
+
if (isOneOf(chartFillTones, tone))
|
|
116
|
+
declarations.push(`--sw-chart-fill: ${chartFill(tone)};`);
|
|
117
|
+
if (isOneOf(chartStrokeTones, tone))
|
|
118
|
+
declarations.push(`--sw-chart-stroke: ${sourceProperty(chartStrokeColors[tone])};`);
|
|
119
|
+
if (isOneOf(chartInkTones, tone))
|
|
120
|
+
declarations.push(`--sw-chart-ink: ${chartColorMix(chartInkMixes[tone])};`);
|
|
121
|
+
return declarations.join(' ');
|
|
122
|
+
}
|
|
123
|
+
export function cssChartToneClasses() {
|
|
124
|
+
return chartTones
|
|
125
|
+
.map((tone) => `.sw-chart-tone-${tone} { ${toneDeclarations(tone)} }`)
|
|
126
|
+
.join('\n');
|
|
127
|
+
}
|
|
128
|
+
export function chartToneClassCatalog() {
|
|
129
|
+
return chartTones.map((tone) => `sw-chart-tone-${tone}`);
|
|
130
|
+
}
|
|
@@ -5,5 +5,5 @@
|
|
|
5
5
|
*/
|
|
6
6
|
export declare const barChartTones: readonly ["accent", "success", "warning", "danger"];
|
|
7
7
|
export type BarChartTone = (typeof barChartTones)[number];
|
|
8
|
-
export declare function
|
|
9
|
-
export declare function
|
|
8
|
+
export declare function cssBarChartClasses(): string;
|
|
9
|
+
export declare function barChartClassCatalog(): string[];
|
|
@@ -66,7 +66,7 @@ function divergingRules() {
|
|
|
66
66
|
.sw-bar-chart-diverging .sw-bar-chart-track::before { background: CanvasText; }
|
|
67
67
|
}`;
|
|
68
68
|
}
|
|
69
|
-
export function
|
|
69
|
+
export function cssBarChartClasses() {
|
|
70
70
|
return `.sw-bar-chart {
|
|
71
71
|
display: grid;
|
|
72
72
|
gap: var(--sw-space-2);
|
|
@@ -155,7 +155,7 @@ ${divergingRules()}
|
|
|
155
155
|
.sw-bar-chart-fill { background: CanvasText; }
|
|
156
156
|
}`;
|
|
157
157
|
}
|
|
158
|
-
export function
|
|
158
|
+
export function barChartClassCatalog() {
|
|
159
159
|
return [
|
|
160
160
|
'sw-bar-chart',
|
|
161
161
|
'sw-bar-chart-plot',
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/** The marks a legend item can show: what its words name in the chart. */
|
|
2
|
+
export declare const chartLegendSwatches: readonly ["bar", "line", "marker", "box"];
|
|
3
|
+
export type ChartLegendSwatch = (typeof chartLegendSwatches)[number];
|
|
4
|
+
export declare function cssChartLegendClasses(): string;
|
|
5
|
+
export declare function chartLegendClassCatalog(): string[];
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { typographyVariants } from '@scalewing/tokens';
|
|
2
|
+
import { chartHairline, chartLineWidth } from './chart-marks.js';
|
|
3
|
+
const caption = typographyVariants.caption;
|
|
4
|
+
/** The marks a legend item can show: what its words name in the chart. */
|
|
5
|
+
export const chartLegendSwatches = ['bar', 'line', 'marker', 'box'];
|
|
6
|
+
/*
|
|
7
|
+
* Each swatch reads its colour from the item's tone class
|
|
8
|
+
* (`sw-chart-tone-<tone>`, `chart-tones.ts`): a bar is the tone's fill, a
|
|
9
|
+
* square a spacing step 3 wide; a line is its stroke, a spacing step 4
|
|
10
|
+
* long at the charts' line width; a marker is a downward triangle in the
|
|
11
|
+
* stroke, the shape a chart's marker takes; a box is the dashed outline of
|
|
12
|
+
* the boxed current period. Forced colours draw every swatch in the system
|
|
13
|
+
* text colour, as they draw the marks.
|
|
14
|
+
*/
|
|
15
|
+
function swatchRules() {
|
|
16
|
+
return `.sw-chart-legend-bar {
|
|
17
|
+
background: var(--sw-chart-fill);
|
|
18
|
+
border-radius: calc(var(--sw-radius-sm) / 4);
|
|
19
|
+
height: var(--sw-space-3);
|
|
20
|
+
width: var(--sw-space-3);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.sw-chart-legend-line {
|
|
24
|
+
background: var(--sw-chart-stroke);
|
|
25
|
+
border-radius: var(--sw-radius-pill);
|
|
26
|
+
height: ${chartLineWidth}px;
|
|
27
|
+
width: var(--sw-space-4);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.sw-chart-legend-marker {
|
|
31
|
+
background: var(--sw-chart-stroke);
|
|
32
|
+
clip-path: polygon(0 0, 100% 0, 50% 100%);
|
|
33
|
+
height: var(--sw-space-3);
|
|
34
|
+
width: var(--sw-space-3);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.sw-chart-legend-box {
|
|
38
|
+
border: ${chartHairline}px dashed var(--sw-chart-stroke);
|
|
39
|
+
border-radius: calc(var(--sw-radius-sm) / 2);
|
|
40
|
+
box-sizing: border-box;
|
|
41
|
+
height: var(--sw-space-3);
|
|
42
|
+
width: var(--sw-space-4);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
@media (forced-colors: active) {
|
|
46
|
+
.sw-chart-legend-bar,
|
|
47
|
+
.sw-chart-legend-line,
|
|
48
|
+
.sw-chart-legend-marker { background: CanvasText; }
|
|
49
|
+
.sw-chart-legend-box { border-color: CanvasText; }
|
|
50
|
+
}`;
|
|
51
|
+
}
|
|
52
|
+
/*
|
|
53
|
+
* A legend is a list of its items in a wrapping row, in the caption type:
|
|
54
|
+
* each item its swatch, then its words. The words wrap within the item
|
|
55
|
+
* rather than push the row past its container, and the swatch stays
|
|
56
|
+
* centred on their first line.
|
|
57
|
+
*/
|
|
58
|
+
export function cssChartLegendClasses() {
|
|
59
|
+
return `.sw-chart-legend {
|
|
60
|
+
color: var(--sw-color-text);
|
|
61
|
+
column-gap: var(--sw-space-5);
|
|
62
|
+
display: flex;
|
|
63
|
+
flex-wrap: wrap;
|
|
64
|
+
font-family: var(--sw-font-sans);
|
|
65
|
+
font-size: ${caption.fontSize}px;
|
|
66
|
+
font-weight: ${caption.fontWeight};
|
|
67
|
+
letter-spacing: ${caption.letterSpacing}px;
|
|
68
|
+
line-height: ${caption.lineHeight}px;
|
|
69
|
+
list-style: none;
|
|
70
|
+
margin: 0;
|
|
71
|
+
padding: 0;
|
|
72
|
+
row-gap: var(--sw-space-2);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.sw-chart-legend-item {
|
|
76
|
+
align-items: flex-start;
|
|
77
|
+
display: inline-flex;
|
|
78
|
+
gap: var(--sw-space-2);
|
|
79
|
+
min-width: 0;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.sw-chart-legend-swatch {
|
|
83
|
+
display: block;
|
|
84
|
+
flex: none;
|
|
85
|
+
/* Centred on the first line of the words, however many lines they wrap to. */
|
|
86
|
+
margin-block-start: calc((${caption.lineHeight}px - var(--sw-space-3)) / 2);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.sw-chart-legend-line {
|
|
90
|
+
margin-block-start: calc((${caption.lineHeight}px - ${chartLineWidth}px) / 2);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
${swatchRules()}`;
|
|
94
|
+
}
|
|
95
|
+
export function chartLegendClassCatalog() {
|
|
96
|
+
return [
|
|
97
|
+
'sw-chart-legend',
|
|
98
|
+
'sw-chart-legend-item',
|
|
99
|
+
'sw-chart-legend-swatch',
|
|
100
|
+
...chartLegendSwatches.map((swatch) => `sw-chart-legend-${swatch}`),
|
|
101
|
+
];
|
|
102
|
+
}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { typographyVariants } from '@scalewing/tokens';
|
|
2
|
+
import { chartBoxDash, chartHairline, chartLeaderDash, chartLineWidth, } from './chart-marks.js';
|
|
3
|
+
const caption = typographyVariants.caption;
|
|
4
|
+
/*
|
|
5
|
+
* The parts every plotted chart (ColumnChart, LineChart) draws in its SVG:
|
|
6
|
+
* the words in the caption type, the grid and zero lines, the boxed
|
|
7
|
+
* period, a line and its last value, and the callouts with their leaders.
|
|
8
|
+
* Every colour is a theme colour or a tone's role (`chart-tones.ts`), read
|
|
9
|
+
* from the tone class on the mark or its group; words with no tone are
|
|
10
|
+
* the text colour.
|
|
11
|
+
*/
|
|
12
|
+
function plotRules() {
|
|
13
|
+
return `.sw-chart {
|
|
14
|
+
display: grid;
|
|
15
|
+
gap: var(--sw-space-2);
|
|
16
|
+
min-width: 0;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.sw-chart-svg {
|
|
20
|
+
display: block;
|
|
21
|
+
font-family: var(--sw-font-sans);
|
|
22
|
+
font-size: ${caption.fontSize}px;
|
|
23
|
+
height: auto;
|
|
24
|
+
letter-spacing: ${caption.letterSpacing}px;
|
|
25
|
+
max-width: 100%;
|
|
26
|
+
overflow: visible;
|
|
27
|
+
width: 100%;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.sw-chart-tick,
|
|
31
|
+
.sw-chart-category {
|
|
32
|
+
fill: var(--sw-color-muted);
|
|
33
|
+
font-variant-numeric: tabular-nums;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.sw-chart-tick-line { fill: var(--sw-chart-ink); }
|
|
37
|
+
|
|
38
|
+
.sw-chart-grid {
|
|
39
|
+
stroke: var(--sw-color-border);
|
|
40
|
+
stroke-width: ${chartHairline};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.sw-chart-zero {
|
|
44
|
+
stroke: var(--sw-color-muted);
|
|
45
|
+
stroke-width: ${chartHairline};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.sw-chart-highlight {
|
|
49
|
+
fill: none;
|
|
50
|
+
stroke: var(--sw-chart-stroke);
|
|
51
|
+
stroke-dasharray: ${chartBoxDash};
|
|
52
|
+
stroke-width: ${chartHairline};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.sw-chart-line {
|
|
56
|
+
fill: none;
|
|
57
|
+
stroke: var(--sw-chart-stroke);
|
|
58
|
+
stroke-linecap: round;
|
|
59
|
+
stroke-linejoin: round;
|
|
60
|
+
stroke-width: ${chartLineWidth};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.sw-chart-dot { fill: var(--sw-chart-stroke); }
|
|
64
|
+
|
|
65
|
+
.sw-chart-end-label {
|
|
66
|
+
fill: var(--sw-chart-ink);
|
|
67
|
+
font-variant-numeric: tabular-nums;
|
|
68
|
+
font-weight: 600;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.sw-chart-leader {
|
|
72
|
+
stroke: var(--sw-chart-ink, var(--sw-color-text));
|
|
73
|
+
stroke-dasharray: ${chartLeaderDash};
|
|
74
|
+
stroke-width: ${chartHairline};
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.sw-chart-callout-text {
|
|
78
|
+
fill: var(--sw-chart-ink, var(--sw-color-text));
|
|
79
|
+
font-weight: 600;
|
|
80
|
+
}`;
|
|
81
|
+
}
|
|
82
|
+
/*
|
|
83
|
+
* On a compact chart the callouts are a list under the plot: each its
|
|
84
|
+
* words in its hue's ink, after a dot in its hue's fill (the colour of its
|
|
85
|
+
* column) centred on their first line.
|
|
86
|
+
*/
|
|
87
|
+
function calloutListRules() {
|
|
88
|
+
return `.sw-chart-callouts {
|
|
89
|
+
display: grid;
|
|
90
|
+
font-family: var(--sw-font-sans);
|
|
91
|
+
font-size: ${caption.fontSize}px;
|
|
92
|
+
gap: var(--sw-space-1);
|
|
93
|
+
letter-spacing: ${caption.letterSpacing}px;
|
|
94
|
+
line-height: ${caption.lineHeight}px;
|
|
95
|
+
list-style: none;
|
|
96
|
+
margin: 0;
|
|
97
|
+
padding: 0;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.sw-chart-callout {
|
|
101
|
+
align-items: flex-start;
|
|
102
|
+
color: var(--sw-chart-ink, var(--sw-color-text));
|
|
103
|
+
display: flex;
|
|
104
|
+
font-weight: 600;
|
|
105
|
+
gap: var(--sw-space-2);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.sw-chart-callout-dot {
|
|
109
|
+
background: var(--sw-chart-fill, currentColor);
|
|
110
|
+
border-radius: var(--sw-radius-pill);
|
|
111
|
+
flex: none;
|
|
112
|
+
height: var(--sw-space-2);
|
|
113
|
+
margin-block-start: calc((${caption.lineHeight}px - var(--sw-space-2)) / 2);
|
|
114
|
+
width: var(--sw-space-2);
|
|
115
|
+
}`;
|
|
116
|
+
}
|
|
117
|
+
/*
|
|
118
|
+
* Forced colours keep the drawing legible in the system colours: marks in
|
|
119
|
+
* the text colour (columns outlined in the canvas colour so a stack's
|
|
120
|
+
* parts stay apart), the line and its last value in the highlight colour,
|
|
121
|
+
* grid lines in the grey text colour, and every word in the text colour.
|
|
122
|
+
* The hidden table carries the figures there as everywhere.
|
|
123
|
+
*/
|
|
124
|
+
function forcedColorRules() {
|
|
125
|
+
return `@media (forced-colors: active) {
|
|
126
|
+
.sw-chart-column { fill: CanvasText; stroke: Canvas; }
|
|
127
|
+
.sw-chart-grid { stroke: GrayText; }
|
|
128
|
+
.sw-chart-zero,
|
|
129
|
+
.sw-chart-highlight,
|
|
130
|
+
.sw-chart-leader { stroke: CanvasText; }
|
|
131
|
+
.sw-chart-line { stroke: Highlight; }
|
|
132
|
+
.sw-chart-dot,
|
|
133
|
+
.sw-chart-end-label { fill: Highlight; }
|
|
134
|
+
.sw-chart-tick,
|
|
135
|
+
.sw-chart-category,
|
|
136
|
+
.sw-chart-callout-text { fill: CanvasText; }
|
|
137
|
+
.sw-chart-callout { color: CanvasText; }
|
|
138
|
+
.sw-chart-callout-dot { background: CanvasText; }
|
|
139
|
+
}`;
|
|
140
|
+
}
|
|
141
|
+
export function cssChartPlotClasses() {
|
|
142
|
+
return `${plotRules()}
|
|
143
|
+
|
|
144
|
+
.sw-chart-column { fill: var(--sw-chart-fill); }
|
|
145
|
+
|
|
146
|
+
${calloutListRules()}
|
|
147
|
+
|
|
148
|
+
${forcedColorRules()}`;
|
|
149
|
+
}
|
|
150
|
+
export function chartPlotClassCatalog() {
|
|
151
|
+
return [
|
|
152
|
+
'sw-chart',
|
|
153
|
+
'sw-chart-svg',
|
|
154
|
+
'sw-chart-tick',
|
|
155
|
+
'sw-chart-tick-line',
|
|
156
|
+
'sw-chart-category',
|
|
157
|
+
'sw-chart-grid',
|
|
158
|
+
'sw-chart-zero',
|
|
159
|
+
'sw-chart-highlight',
|
|
160
|
+
'sw-chart-line',
|
|
161
|
+
'sw-chart-dot',
|
|
162
|
+
'sw-chart-end-label',
|
|
163
|
+
'sw-chart-leader',
|
|
164
|
+
'sw-chart-callout-text',
|
|
165
|
+
'sw-chart-column',
|
|
166
|
+
'sw-chart-callouts',
|
|
167
|
+
'sw-chart-callout',
|
|
168
|
+
'sw-chart-callout-dot',
|
|
169
|
+
];
|
|
170
|
+
}
|
|
@@ -1,9 +1,13 @@
|
|
|
1
|
+
import { cssChartToneClasses } from './chart-tones.js';
|
|
1
2
|
import { cssActionBarClasses } from './css-action-bar.js';
|
|
2
3
|
import { cssActionMenuClasses } from './css-action-menu.js';
|
|
3
4
|
import { cssAccordionClasses } from './css-accordion.js';
|
|
4
5
|
import { cssButtonClasses } from './css-button.js';
|
|
5
6
|
import { cssCalendarButtonClasses } from './css-calendar-button.js';
|
|
6
|
-
import {
|
|
7
|
+
import { cssBarChartClasses } from './css-bar-chart.js';
|
|
8
|
+
import { cssChartLegendClasses } from './css-chart-legend.js';
|
|
9
|
+
import { cssChartPlotClasses } from './css-chart-plot.js';
|
|
10
|
+
import { cssLineChartClasses } from './css-line-chart.js';
|
|
7
11
|
import { cssDataBarClasses } from './css-data-bar.js';
|
|
8
12
|
import { cssPaginationClasses } from './css-pagination.js';
|
|
9
13
|
import { cssCheckboxClasses } from './css-checkbox.js';
|
|
@@ -137,10 +141,18 @@ ${cssDateFieldClasses()}
|
|
|
137
141
|
|
|
138
142
|
${cssCalendarButtonClasses()}
|
|
139
143
|
|
|
140
|
-
${
|
|
144
|
+
${cssBarChartClasses()}
|
|
141
145
|
|
|
142
146
|
${cssDataBarClasses()}
|
|
143
147
|
|
|
148
|
+
${cssChartToneClasses()}
|
|
149
|
+
|
|
150
|
+
${cssChartLegendClasses()}
|
|
151
|
+
|
|
152
|
+
${cssChartPlotClasses()}
|
|
153
|
+
|
|
154
|
+
${cssLineChartClasses()}
|
|
155
|
+
|
|
144
156
|
${cssPaginationClasses()}
|
|
145
157
|
|
|
146
158
|
${cssChromeClasses()}
|
|
@@ -1,16 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* What a range bar's fill means: the start or a carried figure (`neutral`),
|
|
3
3
|
* money in (`success`), money out (`muted`, never danger: an outflow is not
|
|
4
|
-
* an error), a subtotal (`strong`)
|
|
5
|
-
* (`accent`)
|
|
4
|
+
* an error), a subtotal (`strong`), what was counted or recorded
|
|
5
|
+
* (`accent`), and a shortage (`danger`, light red: for a shortage, never
|
|
6
|
+
* for cash leaving).
|
|
6
7
|
*/
|
|
7
|
-
export declare const dataBarTones: readonly ["neutral", "success", "muted", "strong", "accent"];
|
|
8
|
+
export declare const dataBarTones: readonly ["neutral", "success", "muted", "strong", "accent", "danger"];
|
|
8
9
|
export type DataBarTone = (typeof dataBarTones)[number];
|
|
9
|
-
export declare const dataBarToneMixes: Record<DataBarTone, {
|
|
10
|
-
color: 'muted' | 'success' | 'text' | 'accent';
|
|
11
|
-
share: number;
|
|
12
|
-
}>;
|
|
13
|
-
/** A tone's fill: its colour, mixed into the surface by its share. */
|
|
14
|
-
export declare function dataBarToneFill(tone: DataBarTone): string;
|
|
15
10
|
export declare function cssDataBarClasses(): string;
|
|
16
11
|
export declare function dataBarClassCatalog(): string[];
|
package/dist/css/css-data-bar.js
CHANGED
|
@@ -1,42 +1,26 @@
|
|
|
1
|
+
import { chartFill, statementFillTones } from './chart-tones.js';
|
|
1
2
|
/**
|
|
2
3
|
* What a range bar's fill means: the start or a carried figure (`neutral`),
|
|
3
4
|
* money in (`success`), money out (`muted`, never danger: an outflow is not
|
|
4
|
-
* an error), a subtotal (`strong`)
|
|
5
|
-
* (`accent`)
|
|
5
|
+
* an error), a subtotal (`strong`), what was counted or recorded
|
|
6
|
+
* (`accent`), and a shortage (`danger`, light red: for a shortage, never
|
|
7
|
+
* for cash leaving).
|
|
6
8
|
*/
|
|
7
|
-
export const dataBarTones =
|
|
8
|
-
'neutral',
|
|
9
|
-
'success',
|
|
10
|
-
'muted',
|
|
11
|
-
'strong',
|
|
12
|
-
'accent',
|
|
13
|
-
];
|
|
9
|
+
export const dataBarTones = statementFillTones;
|
|
14
10
|
/*
|
|
15
|
-
* Each tone is a
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
11
|
+
* Each tone is a chart fill (`chart-tones.ts`, shared with ChartLegend's
|
|
12
|
+
* `bar` swatch so a statement's legend matches its bars): a semantic
|
|
13
|
+
* colour mixed into the surface where the board draws a lighter fill. The
|
|
14
|
+
* bar is decorative (the figure is the cell's text), so the mixes keep the
|
|
15
|
+
* tones apart from one another rather than meeting a text contrast: every
|
|
16
|
+
* tone at 1.5:1 or more on the surface, and the three greys (out, start,
|
|
17
|
+
* subtotal) 1.5:1 or more from the next one, in every palette and scheme
|
|
18
|
+
* (`data-bar.test.tsx`). `accent` is the accent itself; `danger` is the
|
|
19
|
+
* danger colour at 40 %.
|
|
22
20
|
*/
|
|
23
|
-
export const dataBarToneMixes = {
|
|
24
|
-
neutral: { color: 'muted', share: 0.65 },
|
|
25
|
-
success: { color: 'success', share: 0.55 },
|
|
26
|
-
muted: { color: 'muted', share: 0.35 },
|
|
27
|
-
strong: { color: 'text', share: 0.85 },
|
|
28
|
-
accent: { color: 'accent', share: 1 },
|
|
29
|
-
};
|
|
30
|
-
/** A tone's fill: its colour, mixed into the surface by its share. */
|
|
31
|
-
export function dataBarToneFill(tone) {
|
|
32
|
-
const { color, share } = dataBarToneMixes[tone];
|
|
33
|
-
if (share === 1)
|
|
34
|
-
return `var(--sw-color-${color})`;
|
|
35
|
-
return `color-mix(in srgb, var(--sw-color-${color}) ${Math.round(share * 100)}%, var(--sw-color-surface))`;
|
|
36
|
-
}
|
|
37
21
|
function toneRules() {
|
|
38
22
|
return dataBarTones
|
|
39
|
-
.map((tone) => `.sw-data-bar-${tone} > .sw-data-bar-fill { background: ${
|
|
23
|
+
.map((tone) => `.sw-data-bar-${tone} > .sw-data-bar-fill { background: ${chartFill(tone)}; }`)
|
|
40
24
|
.join('\n');
|
|
41
25
|
}
|
|
42
26
|
/*
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { chartAreaShare } from './chart-tones.js';
|
|
2
|
+
/*
|
|
3
|
+
* The marks only a line chart draws, beside the shared plot classes
|
|
4
|
+
* (`css-chart-plot.ts`): the area under the line, a quiet tint of its
|
|
5
|
+
* stroke; a marker's triangle in its tone's stroke; and the marker's
|
|
6
|
+
* words in its tone's ink. Forced colours drop the area and draw markers
|
|
7
|
+
* and their words in the text colour, apart from the line's highlight
|
|
8
|
+
* colour.
|
|
9
|
+
*/
|
|
10
|
+
export function cssLineChartClasses() {
|
|
11
|
+
return `.sw-chart-area {
|
|
12
|
+
fill: color-mix(in srgb, var(--sw-chart-stroke) ${chartAreaShare * 100}%, transparent);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.sw-chart-marker { fill: var(--sw-chart-stroke); }
|
|
16
|
+
|
|
17
|
+
.sw-chart-marker-label {
|
|
18
|
+
fill: var(--sw-chart-ink);
|
|
19
|
+
font-variant-numeric: tabular-nums;
|
|
20
|
+
font-weight: 600;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
@media (forced-colors: active) {
|
|
24
|
+
.sw-chart-area { fill: none; }
|
|
25
|
+
.sw-chart-marker,
|
|
26
|
+
.sw-chart-marker-label { fill: CanvasText; }
|
|
27
|
+
}`;
|
|
28
|
+
}
|
|
29
|
+
export function lineChartClassCatalog() {
|
|
30
|
+
return ['sw-chart-area', 'sw-chart-marker', 'sw-chart-marker-label'];
|
|
31
|
+
}
|
package/dist/css/stylesheet.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { cardVariants, darkTheme, lightTheme, typographyVariants, } from '@scalewing/tokens';
|
|
2
|
+
import { chartToneClassCatalog } from './chart-tones.js';
|
|
2
3
|
import { actionBarClassCatalog } from './css-action-bar.js';
|
|
3
4
|
import { actionMenuClassCatalog } from './css-action-menu.js';
|
|
4
5
|
import { accordionClassCatalog } from './css-accordion.js';
|
|
@@ -30,7 +31,10 @@ import { boxBorderClassCatalog } from './css-box-border.js';
|
|
|
30
31
|
import { boxLinkClassCatalog } from './css-box-link.js';
|
|
31
32
|
import { cssComponentClasses } from './css-components.js';
|
|
32
33
|
import { buttonClassCatalog } from './css-button.js';
|
|
33
|
-
import {
|
|
34
|
+
import { barChartClassCatalog } from './css-bar-chart.js';
|
|
35
|
+
import { chartLegendClassCatalog } from './css-chart-legend.js';
|
|
36
|
+
import { chartPlotClassCatalog } from './css-chart-plot.js';
|
|
37
|
+
import { lineChartClassCatalog } from './css-line-chart.js';
|
|
34
38
|
import { dataBarClassCatalog } from './css-data-bar.js';
|
|
35
39
|
import { paginationClassCatalog } from './css-pagination.js';
|
|
36
40
|
import { dataClassCatalog } from './css-data.js';
|
|
@@ -70,8 +74,12 @@ export function utilityClassCatalog() {
|
|
|
70
74
|
...segmentedClassCatalog(),
|
|
71
75
|
...tableClassCatalog(),
|
|
72
76
|
...scrollRegionClassCatalog(),
|
|
73
|
-
...
|
|
77
|
+
...barChartClassCatalog(),
|
|
74
78
|
...dataBarClassCatalog(),
|
|
79
|
+
...chartToneClassCatalog(),
|
|
80
|
+
...chartLegendClassCatalog(),
|
|
81
|
+
...chartPlotClassCatalog(),
|
|
82
|
+
...lineChartClassCatalog(),
|
|
75
83
|
...paginationClassCatalog(),
|
|
76
84
|
...chromeClassCatalog(),
|
|
77
85
|
...sectionNavClassCatalog(),
|
package/dist/index.d.ts
CHANGED
|
@@ -16,6 +16,9 @@ export { RadioGroup, type RadioGroupOption, type RadioGroupProps, } from './comp
|
|
|
16
16
|
export { AppHeader, appHeaderAppearances, type AppHeaderAppearance, type AppHeaderProps, } from './components/AppHeader.js';
|
|
17
17
|
export { Badge, type BadgeProps, type BadgeSize, type BadgeTone, badgeSizes, badgeTones, } from './components/Badge.js';
|
|
18
18
|
export { BarChart, type BarChartItem, type BarChartProps, type BarChartTone, barChartTones, } from './components/BarChart.js';
|
|
19
|
+
export { ChartLegend, type ChartFillTone, type ChartLegendItem, type ChartLegendProps, type ChartLegendSwatch, type ChartStrokeTone, type ChartTone, chartFillTones, chartLegendSwatches, chartStrokeTones, } from './components/ChartLegend.js';
|
|
20
|
+
export { ColumnChart, type ColumnChartCallout, type ColumnChartLine, type ColumnChartMode, type ColumnChartProps, type ColumnChartSeries, columnChartModes, } from './components/ColumnChart.js';
|
|
21
|
+
export { LineChart, type LineChartCurve, type LineChartMarker, type LineChartPeriod, type LineChartPoint, type LineChartProps, lineChartCurves, } from './components/LineChart.js';
|
|
19
22
|
export { DataBar, type DataBarProps, type DataBarTone, dataBarTones, } from './components/DataBar.js';
|
|
20
23
|
export { Pagination, type PaginationLabels, type PaginationProps, } from './components/Pagination.js';
|
|
21
24
|
export { Button, type ButtonDisabledAppearance, type ButtonProps, type ButtonSize, type ButtonVariant, } from './components/Button.js';
|
package/dist/index.js
CHANGED
|
@@ -15,6 +15,9 @@ export { RadioGroup, } from './components/RadioGroup.js';
|
|
|
15
15
|
export { AppHeader, appHeaderAppearances, } from './components/AppHeader.js';
|
|
16
16
|
export { Badge, badgeSizes, badgeTones, } from './components/Badge.js';
|
|
17
17
|
export { BarChart, barChartTones, } from './components/BarChart.js';
|
|
18
|
+
export { ChartLegend, chartFillTones, chartLegendSwatches, chartStrokeTones, } from './components/ChartLegend.js';
|
|
19
|
+
export { ColumnChart, columnChartModes, } from './components/ColumnChart.js';
|
|
20
|
+
export { LineChart, lineChartCurves, } from './components/LineChart.js';
|
|
18
21
|
export { DataBar, dataBarTones, } from './components/DataBar.js';
|
|
19
22
|
export { Pagination, } from './components/Pagination.js';
|
|
20
23
|
export { Button, } from './components/Button.js';
|