Skip to content

Commit 7242108

Browse files
committed
Add trend label field
1 parent 8a2046d commit 7242108

File tree

12 files changed

+166
-9
lines changed

12 files changed

+166
-9
lines changed

packages/core/components/ui/trend-arrow.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
width: 1.25rem;
1111
}
1212

13-
.cove-trend-arrow__wrap--below .cove-trend-arrow {
13+
.cove-trend-arrow__wrap--below.cove-trend-arrow__wrap--with-label .cove-trend-arrow {
1414
margin-left: 0.2em;
1515
}
1616

packages/core/helpers/trendIndicator.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export type TrendIndicatorConfig = {
2525
mappings?: TrendIndicatorMapping[]
2626
upLabel?: string
2727
downLabel?: string
28+
trendLabel?: string
2829
}
2930

3031
export type TrendResolutionState = 'resolved' | 'ambiguous' | 'unmapped' | 'invalid' | 'disabled'

packages/data-bite/src/CdcDataBite.tsx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -284,19 +284,24 @@ const CdcDataBite = (props: CdcDataBiteProps) => {
284284

285285
return typeof label === 'string' ? label.trim() : ''
286286
}, [trendIndicator?.downLabel, trendIndicator?.upLabel, trendResolution.arrowType, trendResolution.state])
287+
const resolvedTrendFooterLabel =
288+
typeof trendIndicator?.trendLabel === 'string' ? trendIndicator.trendLabel.trim() : ''
287289

288290
const renderTrendArrow = ({ wrapperClassName = '' } = {}) => {
289291
if (trendResolution.state !== 'resolved' || !trendResolution.arrowType) {
290292
return null
291293
}
292294
const ariaLabel = `Trend ${trendResolution.arrowType}${resolvedTrendLabel ? `: ${resolvedTrendLabel}` : ''}`
295+
const resolvedWrapperClassName = [wrapperClassName, resolvedTrendLabel ? 'cove-trend-arrow__wrap--with-label' : '']
296+
.filter(Boolean)
297+
.join(' ')
293298

294299
return (
295300
<TrendArrow
296301
arrowType={trendResolution.arrowType}
297302
label={resolvedTrendLabel}
298303
ariaLabel={ariaLabel}
299-
wrapperClassName={wrapperClassName}
304+
wrapperClassName={resolvedWrapperClassName}
300305
/>
301306
)
302307
}
@@ -634,7 +639,7 @@ const CdcDataBite = (props: CdcDataBiteProps) => {
634639
const showBite = undefined !== dataColumn && undefined !== dataFunction
635640
const isTp5 = showBite && biteStyle === 'tp5'
636641
const hasTrendArrow = trendResolution.state === 'resolved' && !!trendResolution.arrowType
637-
const shouldUseTrendBelow = Boolean(hasTrendArrow && resolvedTrendLabel)
642+
const shouldUseTrendBelow = Boolean(hasTrendArrow && (resolvedTrendLabel || resolvedTrendFooterLabel))
638643
const shouldUseContentBelow = Boolean(config.visual?.useWrap || shouldUseTrendBelow)
639644
const tp5Value = isTp5 ? calculateDataBite(true) : ''
640645
const tp5BodyLayoutClasses = [
@@ -711,6 +716,9 @@ const CdcDataBite = (props: CdcDataBiteProps) => {
711716
wrapperClassName: 'cove-trend-arrow__wrap--below'
712717
})}
713718
</span>
719+
{resolvedTrendFooterLabel && (
720+
<span className='cdc-callout__trend-footer-label'>{resolvedTrendFooterLabel}</span>
721+
)}
714722
</div>
715723
)}
716724
</div>

packages/data-bite/src/components/EditorPanel/EditorPanel.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,14 @@ const EditorPanel: React.FC<DataBiteEditorPanelProps> = () => {
414414
placeholder='Decreasing'
415415
updateField={updateField}
416416
/>
417+
<TextField
418+
value={config.trendIndicator?.trendLabel || ''}
419+
section='trendIndicator'
420+
fieldName='trendLabel'
421+
label='Trend Label'
422+
placeholder='(compared to one year prior)'
423+
updateField={updateField}
424+
/>
417425
</>
418426
))}
419427
</div>

packages/data-bite/src/data/initial-state.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ export default {
4444
numericThreshold: 0,
4545
mappings: [],
4646
upLabel: '',
47-
downLabel: ''
47+
downLabel: '',
48+
trendLabel: ''
4849
},
4950
markupVariables: [],
5051
enableMarkupVariables: false

packages/data-bite/src/scss/bite.scss

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,7 @@
246246

247247
.cdc-callout__trend-row {
248248
display: flex;
249+
flex-direction: column;
249250
align-items: flex-start;
250251
min-width: 0;
251252
}
@@ -254,6 +255,14 @@
254255
min-width: 0;
255256
}
256257

258+
.cdc-callout__trend-footer-label {
259+
color: var(--cool-gray-90, #1c1d1f);
260+
font-family: var(--app-font-main);
261+
font-size: 1rem;
262+
font-weight: 400;
263+
line-height: 1.5rem;
264+
}
265+
257266
.cdc-callout__body--content-below .cdc-callout__content-slot,
258267
.cdc-callout__body--trend-below .cdc-callout__content-slot {
259268
grid-column: 1;

packages/data-bite/src/test/CdcDataBite.test.jsx

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,52 @@ describe('Data Bite', () => {
8888
expect(container.querySelector('.cdc-callout__trend-slot--below')).toBeInTheDocument()
8989
expect(container.querySelector('.cdc-callout__trend-slot--inline')).not.toBeInTheDocument()
9090
expect(container.querySelector('.cdc-callout__body--content-below')).toBeInTheDocument()
91-
expect(container.querySelector('.mock-trend-arrow-wrap.cove-trend-arrow__wrap--below')).toBeInTheDocument()
91+
expect(
92+
container.querySelector('.mock-trend-arrow-wrap.cove-trend-arrow__wrap--below.cove-trend-arrow__wrap--with-label')
93+
).toBeInTheDocument()
94+
})
95+
96+
it('moves the trend indicator below the value when a footer trend label is configured', () => {
97+
const { container } = render(
98+
<CdcDataBite
99+
config={{
100+
type: 'data-bite',
101+
theme: 'theme-blue',
102+
title: 'Test title',
103+
biteStyle: 'tp5',
104+
biteBody: 'Test body',
105+
dataColumn: 'value',
106+
dataFunction: 'Pass Through',
107+
dataFormat: {
108+
prefix: '',
109+
suffix: '',
110+
commas: false,
111+
roundToPlace: 0
112+
},
113+
visual: {
114+
showTitle: true,
115+
useWrap: false,
116+
whiteBackground: false,
117+
border: true
118+
},
119+
trendIndicator: {
120+
mode: 'categorical',
121+
column: 'trend',
122+
mappings: [{ sourceValue: 'increase', arrowType: 'up' }],
123+
trendLabel: '(compared to one year prior)'
124+
},
125+
data: [{ value: '42', trend: 'increase' }]
126+
}}
127+
/>
128+
)
129+
130+
expect(container.querySelector('.cdc-callout__body--trend-below')).toBeInTheDocument()
131+
expect(container.querySelector('.cdc-callout__trend-footer-label')).toHaveTextContent(
132+
'(compared to one year prior)'
133+
)
134+
expect(
135+
container.querySelector('.mock-trend-arrow-wrap.cove-trend-arrow__wrap--below.cove-trend-arrow__wrap--with-label')
136+
).not.toBeInTheDocument()
92137
})
93138

94139
it('keeps the trend indicator inline when no trend label is configured', () => {

packages/waffle-chart/src/CdcWaffleChart.tsx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -424,21 +424,26 @@ const WaffleChart = ({ config, isEditor, link = '', showConfigConfirm, updateCon
424424
? trendIndicator?.downLabel
425425
: ''
426426
const resolvedTrendLabel = typeof trendLabel === 'string' ? trendLabel.trim() : ''
427+
const resolvedTrendFooterLabel =
428+
typeof trendIndicator?.trendLabel === 'string' ? trendIndicator.trendLabel.trim() : ''
427429
const hasTrendArrow = trendResolution?.state === 'resolved' && !!trendResolution?.arrowType
428-
const shouldUseTrendBelow = Boolean(hasTrendArrow && resolvedTrendLabel)
430+
const shouldUseTrendBelow = Boolean(hasTrendArrow && (resolvedTrendLabel || resolvedTrendFooterLabel))
429431

430432
const renderTrendArrow = ({ wrapperClassName = '' } = {}) => {
431433
if (trendResolution?.state !== 'resolved' || !trendResolution?.arrowType) {
432434
return null
433435
}
434436
const ariaLabel = `Trend ${trendResolution.arrowType}${resolvedTrendLabel ? `: ${resolvedTrendLabel}` : ''}`
437+
const resolvedWrapperClassName = [wrapperClassName, resolvedTrendLabel ? 'cove-trend-arrow__wrap--with-label' : '']
438+
.filter(Boolean)
439+
.join(' ')
435440

436441
return (
437442
<TrendArrow
438443
arrowType={trendResolution.arrowType}
439444
label={resolvedTrendLabel}
440445
ariaLabel={ariaLabel}
441-
wrapperClassName={wrapperClassName}
446+
wrapperClassName={resolvedWrapperClassName}
442447
/>
443448
)
444449
}
@@ -467,6 +472,9 @@ const WaffleChart = ({ config, isEditor, link = '', showConfigConfirm, updateCon
467472
wrapperClassName: 'cove-trend-arrow__wrap--below'
468473
})}
469474
</span>
475+
{resolvedTrendFooterLabel && (
476+
<span className='cove-waffle-chart__trend-footer-label'>{resolvedTrendFooterLabel}</span>
477+
)}
470478
</div>
471479
)}
472480
</div>

packages/waffle-chart/src/components/EditorPanel.jsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,14 @@ const EditorPanel = memo(props => {
458458
placeholder='Decreasing'
459459
updateField={updateField}
460460
/>
461+
<TextField
462+
value={config.trendIndicator?.trendLabel || ''}
463+
section='trendIndicator'
464+
fieldName='trendLabel'
465+
label='Trend Label'
466+
placeholder='(compared to one year prior)'
467+
updateField={updateField}
468+
/>
461469
</>
462470
)}
463471
</div>

packages/waffle-chart/src/data/initial-state.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ export default {
6060
numericThreshold: 0,
6161
mappings: [],
6262
upLabel: '',
63-
downLabel: ''
63+
downLabel: '',
64+
trendLabel: ''
6465
},
6566
markupVariables: [],
6667
enableMarkupVariables: false

0 commit comments

Comments
 (0)