@cdc/waffle-chart 4.26.1 → 4.26.2
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/cdcwafflechart.js +10145 -9597
- package/examples/default.json +10 -0
- package/examples/tp5-gauge-white.json +158 -0
- package/examples/tp5-gauge.json +158 -0
- package/index.html +1 -33
- package/package.json +30 -33
- package/src/CdcWaffleChart.tsx +100 -28
- package/src/_stories/WaffleChart.Editor.stories.tsx +237 -0
- package/src/_stories/WaffleChart.stories.tsx +49 -2
- package/src/components/EditorPanel.jsx +53 -61
- package/src/scss/waffle-chart.scss +134 -1
- package/src/store/chart.reducer.ts +1 -1
- package/src/types/Config.ts +1 -1
|
@@ -729,3 +729,240 @@ export const VisualSectionTests: Story = {
|
|
|
729
729
|
)
|
|
730
730
|
}
|
|
731
731
|
}
|
|
732
|
+
|
|
733
|
+
/**
|
|
734
|
+
* TP5 GAUGE - GENERAL SECTION TESTS
|
|
735
|
+
* Tests all functionality within the General accordion for TP5 Gauge configs.
|
|
736
|
+
*/
|
|
737
|
+
export const TP5GaugeGeneralSectionTests: Story = {
|
|
738
|
+
args: {
|
|
739
|
+
configUrl: '/packages/waffle-chart/examples/tp5-gauge.json',
|
|
740
|
+
isEditor: true
|
|
741
|
+
},
|
|
742
|
+
play: async ({ canvasElement }) => {
|
|
743
|
+
const canvas = within(canvasElement)
|
|
744
|
+
await waitForEditor(canvas)
|
|
745
|
+
await openAccordion(canvas, 'General')
|
|
746
|
+
await waitForPresence('.cdc-callout', canvasElement)
|
|
747
|
+
|
|
748
|
+
// ============================================================================
|
|
749
|
+
// TEST 1: Chart Type Change (TP5 Gauge <-> TP5 Waffle)
|
|
750
|
+
// Expectation: Gauge container swaps with waffle container.
|
|
751
|
+
// ============================================================================
|
|
752
|
+
const chartTypeSelect = canvas.getByLabelText(/chart type/i) as HTMLSelectElement
|
|
753
|
+
expect(chartTypeSelect).toBeTruthy()
|
|
754
|
+
|
|
755
|
+
const getChartTypeState = () => ({
|
|
756
|
+
hasGauge: !!canvasElement.querySelector('.cove-gauge-chart'),
|
|
757
|
+
hasWaffle: !!canvasElement.querySelector('.cove-waffle-chart')
|
|
758
|
+
})
|
|
759
|
+
|
|
760
|
+
await performAndAssert(
|
|
761
|
+
'TP5 Gauge to TP5 Waffle',
|
|
762
|
+
getChartTypeState,
|
|
763
|
+
async () => {
|
|
764
|
+
await userEvent.selectOptions(chartTypeSelect, 'TP5 Waffle')
|
|
765
|
+
},
|
|
766
|
+
(before, after) => before.hasGauge !== after.hasGauge && after.hasWaffle
|
|
767
|
+
)
|
|
768
|
+
|
|
769
|
+
await performAndAssert(
|
|
770
|
+
'TP5 Waffle to TP5 Gauge',
|
|
771
|
+
getChartTypeState,
|
|
772
|
+
async () => {
|
|
773
|
+
await userEvent.selectOptions(chartTypeSelect, 'TP5 Gauge')
|
|
774
|
+
},
|
|
775
|
+
(before, after) => before.hasGauge !== after.hasGauge && after.hasGauge
|
|
776
|
+
)
|
|
777
|
+
|
|
778
|
+
// ============================================================================
|
|
779
|
+
// TEST 2: Title Update
|
|
780
|
+
// Expectation: Callout heading text updates.
|
|
781
|
+
// ============================================================================
|
|
782
|
+
const titleInput = canvas.getByLabelText(/^title$/i, { selector: 'input' }) as HTMLInputElement
|
|
783
|
+
await userEvent.clear(titleInput)
|
|
784
|
+
await userEvent.type(titleInput, 'TP5 Gauge Title Update')
|
|
785
|
+
|
|
786
|
+
await performAndAssert(
|
|
787
|
+
'TP5 Gauge Title Update',
|
|
788
|
+
() => canvasElement.querySelector('.cdc-callout__heading')?.textContent?.trim() || '',
|
|
789
|
+
async () => {}, // action already performed above
|
|
790
|
+
(before, after) => after === 'TP5 Gauge Title Update'
|
|
791
|
+
)
|
|
792
|
+
|
|
793
|
+
// ============================================================================
|
|
794
|
+
// TEST 3: Show Title Toggle
|
|
795
|
+
// Expectation: Callout heading appears/disappears.
|
|
796
|
+
// ============================================================================
|
|
797
|
+
const showTitleCheckbox = canvasElement.querySelector('input[name="showTitle"]') as HTMLInputElement
|
|
798
|
+
expect(showTitleCheckbox).toBeTruthy()
|
|
799
|
+
|
|
800
|
+
const headingVisible = () => !!canvasElement.querySelector('.cdc-callout__heading')
|
|
801
|
+
const wasVisible = headingVisible()
|
|
802
|
+
|
|
803
|
+
await performAndAssert(
|
|
804
|
+
'TP5 Gauge Title Toggle',
|
|
805
|
+
headingVisible,
|
|
806
|
+
async () => {
|
|
807
|
+
await userEvent.click(showTitleCheckbox)
|
|
808
|
+
},
|
|
809
|
+
(before, after) => after !== before
|
|
810
|
+
)
|
|
811
|
+
|
|
812
|
+
await performAndAssert(
|
|
813
|
+
'TP5 Gauge Title Toggle Reset',
|
|
814
|
+
headingVisible,
|
|
815
|
+
async () => {
|
|
816
|
+
await userEvent.click(showTitleCheckbox)
|
|
817
|
+
},
|
|
818
|
+
(before, after) => after === wasVisible
|
|
819
|
+
)
|
|
820
|
+
|
|
821
|
+
// ============================================================================
|
|
822
|
+
// TEST 4: Message Update
|
|
823
|
+
// Expectation: Gauge content text updates.
|
|
824
|
+
// ============================================================================
|
|
825
|
+
const messageTextarea = canvas.getByLabelText(/message/i) as HTMLTextAreaElement
|
|
826
|
+
const newMessage = 'Updated TP5 gauge message text'
|
|
827
|
+
await userEvent.clear(messageTextarea)
|
|
828
|
+
await userEvent.type(messageTextarea, newMessage)
|
|
829
|
+
await waitForTextContent(
|
|
830
|
+
canvasElement.querySelector('.cove-gauge-chart__content .cove-waffle-chart__data--text') as HTMLElement,
|
|
831
|
+
newMessage
|
|
832
|
+
)
|
|
833
|
+
|
|
834
|
+
// ============================================================================
|
|
835
|
+
// TEST 5: Subtext Update
|
|
836
|
+
// Expectation: Subtext text updates.
|
|
837
|
+
// ============================================================================
|
|
838
|
+
const subtextInput = canvas.getByLabelText(/subtext/i) as HTMLInputElement
|
|
839
|
+
const newSubtext = 'Updated TP5 gauge subtext'
|
|
840
|
+
await userEvent.clear(subtextInput)
|
|
841
|
+
await userEvent.type(subtextInput, newSubtext)
|
|
842
|
+
await waitForTextContent(
|
|
843
|
+
canvasElement.querySelector('.cove-gauge-chart .cove-waffle-chart__subtext') as HTMLElement,
|
|
844
|
+
newSubtext
|
|
845
|
+
)
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
/**
|
|
850
|
+
* TP5 GAUGE - DATA SECTION TESTS
|
|
851
|
+
* Tests all functionality within the Data accordion for TP5 Gauge configs.
|
|
852
|
+
*/
|
|
853
|
+
export const TP5GaugeDataSectionTests: Story = {
|
|
854
|
+
args: {
|
|
855
|
+
configUrl: '/packages/waffle-chart/examples/tp5-gauge.json',
|
|
856
|
+
isEditor: true
|
|
857
|
+
},
|
|
858
|
+
play: async ({ canvasElement }) => {
|
|
859
|
+
const canvas = within(canvasElement)
|
|
860
|
+
await waitForEditor(canvas)
|
|
861
|
+
await openAccordion(canvas, 'Data')
|
|
862
|
+
|
|
863
|
+
const getPrimaryText = () =>
|
|
864
|
+
canvasElement.querySelector('.cove-waffle-chart__data--primary')?.textContent?.replace(/\s+/g, ' ').trim() || ''
|
|
865
|
+
|
|
866
|
+
// ============================================================================
|
|
867
|
+
// TEST 1: Data Function Change
|
|
868
|
+
// Expectation: Primary value text changes.
|
|
869
|
+
// ============================================================================
|
|
870
|
+
const dataFunctionSelect = canvasElement.querySelector('select[name="dataFunction"]') as HTMLSelectElement
|
|
871
|
+
await waitForOptionsToPopulate(dataFunctionSelect, 2)
|
|
872
|
+
const dataFunctionOptions = Array.from(dataFunctionSelect.options).map(opt => opt.value)
|
|
873
|
+
const nextFunction = dataFunctionOptions.find(opt => opt && opt !== dataFunctionSelect.value)
|
|
874
|
+
expect(nextFunction).toBeTruthy()
|
|
875
|
+
|
|
876
|
+
await performAndAssert(
|
|
877
|
+
'TP5 Gauge Data Function Change',
|
|
878
|
+
getPrimaryText,
|
|
879
|
+
async () => {
|
|
880
|
+
await userEvent.selectOptions(dataFunctionSelect, nextFunction as string)
|
|
881
|
+
},
|
|
882
|
+
(before, after) => after !== before
|
|
883
|
+
)
|
|
884
|
+
|
|
885
|
+
// ============================================================================
|
|
886
|
+
// TEST 2: Value Description Update
|
|
887
|
+
// Expectation: Primary value text includes new descriptor.
|
|
888
|
+
// ============================================================================
|
|
889
|
+
const valueDescriptionInput = canvasElement.querySelector(
|
|
890
|
+
'input[name="null-null-valueDescription"]'
|
|
891
|
+
) as HTMLInputElement
|
|
892
|
+
expect(valueDescriptionInput).toBeTruthy()
|
|
893
|
+
const newDescription = 'out of total'
|
|
894
|
+
await userEvent.clear(valueDescriptionInput)
|
|
895
|
+
await userEvent.type(valueDescriptionInput, newDescription)
|
|
896
|
+
await performAndAssert(
|
|
897
|
+
'TP5 Gauge Value Description Update',
|
|
898
|
+
getPrimaryText,
|
|
899
|
+
async () => {}, // action already performed above
|
|
900
|
+
(before, after) => after.includes(newDescription)
|
|
901
|
+
)
|
|
902
|
+
|
|
903
|
+
// ============================================================================
|
|
904
|
+
// TEST 3: Denominator Update
|
|
905
|
+
// Expectation: Primary value text changes to include new denominator.
|
|
906
|
+
// ============================================================================
|
|
907
|
+
const denominatorInput = canvasElement.querySelector('input[name="null-null-dataDenom"]') as HTMLInputElement
|
|
908
|
+
expect(denominatorInput).toBeTruthy()
|
|
909
|
+
await performAndAssert(
|
|
910
|
+
'TP5 Gauge Denominator Update',
|
|
911
|
+
getPrimaryText,
|
|
912
|
+
async () => {
|
|
913
|
+
await userEvent.clear(denominatorInput)
|
|
914
|
+
await userEvent.type(denominatorInput, '250')
|
|
915
|
+
},
|
|
916
|
+
(before, after) => after !== before && after.includes('250')
|
|
917
|
+
)
|
|
918
|
+
}
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
/**
|
|
922
|
+
* TP5 GAUGE - VISUAL SECTION TESTS
|
|
923
|
+
* Tests all functionality within the Visual accordion for TP5 Gauge configs.
|
|
924
|
+
*/
|
|
925
|
+
export const TP5GaugeVisualSectionTests: Story = {
|
|
926
|
+
args: {
|
|
927
|
+
configUrl: '/packages/waffle-chart/examples/tp5-gauge.json',
|
|
928
|
+
isEditor: true
|
|
929
|
+
},
|
|
930
|
+
play: async ({ canvasElement }) => {
|
|
931
|
+
const canvas = within(canvasElement)
|
|
932
|
+
await waitForEditor(canvas)
|
|
933
|
+
await openAccordion(canvas, 'Visual')
|
|
934
|
+
await waitForPresence('.cdc-callout', canvasElement)
|
|
935
|
+
|
|
936
|
+
// ============================================================================
|
|
937
|
+
// TEST 1: White Background Toggle
|
|
938
|
+
// Expectation: Callout classes and flag visibility toggle.
|
|
939
|
+
// ============================================================================
|
|
940
|
+
const whiteBackgroundCheckbox = canvas.getByLabelText(/use white background style/i) as HTMLInputElement
|
|
941
|
+
expect(whiteBackgroundCheckbox).toBeTruthy()
|
|
942
|
+
|
|
943
|
+
const getCalloutState = () => {
|
|
944
|
+
const callout = canvasElement.querySelector('.cdc-callout') as HTMLElement
|
|
945
|
+
return {
|
|
946
|
+
classes: callout ? Array.from(callout.classList).sort().join(' ') : '',
|
|
947
|
+
hasFlag: !!canvasElement.querySelector('.cdc-callout__flag')
|
|
948
|
+
}
|
|
949
|
+
}
|
|
950
|
+
|
|
951
|
+
await performAndAssert(
|
|
952
|
+
'TP5 Gauge White Background Toggle',
|
|
953
|
+
getCalloutState,
|
|
954
|
+
async () => {
|
|
955
|
+
await userEvent.click(whiteBackgroundCheckbox)
|
|
956
|
+
},
|
|
957
|
+
(before, after) => before.classes !== after.classes || before.hasFlag !== after.hasFlag,
|
|
958
|
+
after => {
|
|
959
|
+
if (after.hasFlag) {
|
|
960
|
+
expect(after.classes.includes('cdc-callout--data')).toBe(true)
|
|
961
|
+
} else {
|
|
962
|
+
expect(after.classes.includes('cdc-callout--data')).toBe(false)
|
|
963
|
+
expect(after.classes.includes('dfe-block')).toBe(false)
|
|
964
|
+
}
|
|
965
|
+
}
|
|
966
|
+
)
|
|
967
|
+
}
|
|
968
|
+
}
|
|
@@ -2,6 +2,7 @@ import React from 'react'
|
|
|
2
2
|
import type { Meta, StoryObj } from '@storybook/react-vite'
|
|
3
3
|
|
|
4
4
|
import WaffleChart from '../CdcWaffleChart'
|
|
5
|
+
import { assertVisualizationRendered } from '@cdc/core/helpers/testing'
|
|
5
6
|
|
|
6
7
|
const meta: Meta<typeof WaffleChart> = {
|
|
7
8
|
title: 'Components/Templates/WaffleChart',
|
|
@@ -105,7 +106,10 @@ export const Person: Story = {
|
|
|
105
106
|
<>
|
|
106
107
|
<WaffleChart {...args} />
|
|
107
108
|
</>
|
|
108
|
-
)
|
|
109
|
+
),
|
|
110
|
+
play: async ({ canvasElement }) => {
|
|
111
|
+
await assertVisualizationRendered(canvasElement)
|
|
112
|
+
}
|
|
109
113
|
}
|
|
110
114
|
|
|
111
115
|
export const Gauge: Story = {
|
|
@@ -186,7 +190,10 @@ export const Gauge: Story = {
|
|
|
186
190
|
<>
|
|
187
191
|
<WaffleChart {...args} />
|
|
188
192
|
</>
|
|
189
|
-
)
|
|
193
|
+
),
|
|
194
|
+
play: async ({ canvasElement }) => {
|
|
195
|
+
await assertVisualizationRendered(canvasElement)
|
|
196
|
+
}
|
|
190
197
|
}
|
|
191
198
|
|
|
192
199
|
export const Waffle_Chart_TP5_Style: Story = {
|
|
@@ -200,6 +207,9 @@ export const Waffle_Chart_TP5_Style: Story = {
|
|
|
200
207
|
'TP5 Style - A new layout style that displays the waffle chart in a callout component with a blue background and icon. The title appears inside the callout header. This style mimics the CDC Template Package 5.0 callout component design and includes an optional white background variant.'
|
|
201
208
|
}
|
|
202
209
|
}
|
|
210
|
+
},
|
|
211
|
+
play: async ({ canvasElement }) => {
|
|
212
|
+
await assertVisualizationRendered(canvasElement)
|
|
203
213
|
}
|
|
204
214
|
}
|
|
205
215
|
|
|
@@ -214,6 +224,43 @@ export const Waffle_Chart_TP5_Style_White_Background: Story = {
|
|
|
214
224
|
'TP5 Style with White Background - The white background variant of the TP5 style features a white background with a teal border instead of the default blue background. The icon remains visible in this variant.'
|
|
215
225
|
}
|
|
216
226
|
}
|
|
227
|
+
},
|
|
228
|
+
play: async ({ canvasElement }) => {
|
|
229
|
+
await assertVisualizationRendered(canvasElement)
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
export const TP5_Gauge: Story = {
|
|
234
|
+
args: {
|
|
235
|
+
configUrl: '/packages/waffle-chart/examples/tp5-gauge.json'
|
|
236
|
+
},
|
|
237
|
+
parameters: {
|
|
238
|
+
docs: {
|
|
239
|
+
description: {
|
|
240
|
+
story:
|
|
241
|
+
'TP5 Gauge - A TP5 callout-style gauge with a blue background, callout flag, and title inside the callout header.'
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
},
|
|
245
|
+
play: async ({ canvasElement }) => {
|
|
246
|
+
await assertVisualizationRendered(canvasElement)
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
export const TP5_Gauge_White_Background: Story = {
|
|
251
|
+
args: {
|
|
252
|
+
configUrl: '/packages/waffle-chart/examples/tp5-gauge-white.json'
|
|
253
|
+
},
|
|
254
|
+
parameters: {
|
|
255
|
+
docs: {
|
|
256
|
+
description: {
|
|
257
|
+
story:
|
|
258
|
+
'TP5 Gauge with White Background - The white background variant of the TP5 gauge features a white callout with a teal border and no callout flag.'
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
},
|
|
262
|
+
play: async ({ canvasElement }) => {
|
|
263
|
+
await assertVisualizationRendered(canvasElement)
|
|
217
264
|
}
|
|
218
265
|
}
|
|
219
266
|
|
|
@@ -57,7 +57,8 @@ const EditorPanel = memo(props => {
|
|
|
57
57
|
const approvedWaffleChartOptions = [
|
|
58
58
|
{ value: 'Waffle', label: 'Waffle' },
|
|
59
59
|
{ value: 'TP5 Waffle', label: 'TP5 Style Waffle' },
|
|
60
|
-
{ value: 'Gauge', label: 'Gauge' }
|
|
60
|
+
{ value: 'Gauge', label: 'Gauge' },
|
|
61
|
+
{ value: 'TP5 Gauge', label: 'TP5 Style Gauge' }
|
|
61
62
|
]
|
|
62
63
|
|
|
63
64
|
const editorContent = (
|
|
@@ -70,15 +71,6 @@ const EditorPanel = memo(props => {
|
|
|
70
71
|
updateField={updateField}
|
|
71
72
|
options={approvedWaffleChartOptions}
|
|
72
73
|
/>
|
|
73
|
-
{config.visualizationType === 'Gauge' && (
|
|
74
|
-
<Select
|
|
75
|
-
value={config.visualizationSubType}
|
|
76
|
-
fieldName='visualizationSubType'
|
|
77
|
-
label='Chart Subtype'
|
|
78
|
-
updateField={updateField}
|
|
79
|
-
options={['Linear']}
|
|
80
|
-
/>
|
|
81
|
-
)}
|
|
82
74
|
<TextField
|
|
83
75
|
value={config.title}
|
|
84
76
|
fieldName='title'
|
|
@@ -263,7 +255,7 @@ const EditorPanel = memo(props => {
|
|
|
263
255
|
</div>
|
|
264
256
|
</li>
|
|
265
257
|
</ul>
|
|
266
|
-
{config.visualizationType === 'Gauge' && (
|
|
258
|
+
{(config.visualizationType === 'Gauge' || config.visualizationType === 'TP5 Gauge') && (
|
|
267
259
|
<>
|
|
268
260
|
<hr className='cove-accordion__divider' />
|
|
269
261
|
<div className='cove-accordion__panel-section reverse-labels'>
|
|
@@ -344,8 +336,8 @@ const EditorPanel = memo(props => {
|
|
|
344
336
|
Add Filter
|
|
345
337
|
</Button>
|
|
346
338
|
</Accordion.Section>
|
|
347
|
-
|
|
348
|
-
|
|
339
|
+
{config.visualizationType !== 'Gauge' && config.visualizationType !== 'TP5 Gauge' && (
|
|
340
|
+
<Accordion.Section title='Chart Settings'>
|
|
349
341
|
<Select
|
|
350
342
|
value={config.shape}
|
|
351
343
|
fieldName='shape'
|
|
@@ -353,62 +345,62 @@ const EditorPanel = memo(props => {
|
|
|
353
345
|
updateField={updateField}
|
|
354
346
|
options={['circle', 'square', 'person']}
|
|
355
347
|
/>
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
348
|
+
{config.visualizationType !== 'TP5 Waffle' && (
|
|
349
|
+
<>
|
|
350
|
+
<div
|
|
351
|
+
className='cove-accordion__panel-row cove-accordion__small-inputs'
|
|
352
|
+
style={{ marginTop: '1rem', marginBottom: '1rem' }}
|
|
353
|
+
>
|
|
354
|
+
<div className='cove-accordion__panel-col'>
|
|
355
|
+
<TextField
|
|
356
|
+
type='number'
|
|
357
|
+
value={config.nodeWidth}
|
|
358
|
+
fieldName='nodeWidth'
|
|
359
|
+
label='Width'
|
|
360
|
+
updateField={updateField}
|
|
361
|
+
/>
|
|
362
|
+
</div>
|
|
363
|
+
<div className='cove-accordion__panel-col'>
|
|
364
|
+
<TextField
|
|
365
|
+
type='number'
|
|
366
|
+
value={config.nodeSpacer}
|
|
367
|
+
fieldName='nodeSpacer'
|
|
368
|
+
label='Spacer'
|
|
369
|
+
updateField={updateField}
|
|
370
|
+
/>
|
|
371
|
+
</div>
|
|
371
372
|
</div>
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
value={config.
|
|
376
|
-
fieldName='
|
|
377
|
-
label='
|
|
373
|
+
|
|
374
|
+
<div className='cove-input-group'>
|
|
375
|
+
<Select
|
|
376
|
+
value={config.orientation}
|
|
377
|
+
fieldName='orientation'
|
|
378
|
+
label='Layout'
|
|
378
379
|
updateField={updateField}
|
|
380
|
+
options={['horizontal', 'vertical']}
|
|
379
381
|
/>
|
|
380
382
|
</div>
|
|
381
|
-
</div>
|
|
382
383
|
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
<label>
|
|
395
|
-
<span className='edit-label column-heading cove-input__label'>Data Point Font Size</span>
|
|
396
|
-
</label>
|
|
397
|
-
<div className='cove-accordion__panel-row cove-accordion__small-inputs align-center'>
|
|
398
|
-
<div className='cove-accordion__panel-col'>
|
|
399
|
-
<TextField type='number' value={config.fontSize} fieldName='fontSize' updateField={updateField} />
|
|
400
|
-
</div>
|
|
401
|
-
<div className='cove-accordion__panel-col' style={{ display: 'flex', alignItems: 'center' }}>
|
|
402
|
-
<label className='accordion__panel-label--muted'> default (50px)</label>
|
|
384
|
+
<div className='cove-input-group'>
|
|
385
|
+
<label>
|
|
386
|
+
<span className='edit-label column-heading cove-input__label'>Data Point Font Size</span>
|
|
387
|
+
</label>
|
|
388
|
+
<div className='cove-accordion__panel-row cove-accordion__small-inputs align-center'>
|
|
389
|
+
<div className='cove-accordion__panel-col'>
|
|
390
|
+
<TextField type='number' value={config.fontSize} fieldName='fontSize' updateField={updateField} />
|
|
391
|
+
</div>
|
|
392
|
+
<div className='cove-accordion__panel-col' style={{ display: 'flex', alignItems: 'center' }}>
|
|
393
|
+
<label className='accordion__panel-label--muted'> default (50px)</label>
|
|
394
|
+
</div>
|
|
403
395
|
</div>
|
|
404
396
|
</div>
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
397
|
+
</>
|
|
398
|
+
)}
|
|
399
|
+
</Accordion.Section>
|
|
400
|
+
)}
|
|
409
401
|
|
|
410
402
|
{/* Visual section for TP5 style */}
|
|
411
|
-
{config.visualizationType === 'TP5 Waffle' && (
|
|
403
|
+
{(config.visualizationType === 'TP5 Waffle' || config.visualizationType === 'TP5 Gauge') && (
|
|
412
404
|
<Accordion.Section title='Visual'>
|
|
413
405
|
<CheckBox
|
|
414
406
|
value={config.visual?.whiteBackground}
|
|
@@ -421,7 +413,7 @@ const EditorPanel = memo(props => {
|
|
|
421
413
|
)}
|
|
422
414
|
|
|
423
415
|
{/* Visual section for other styles */}
|
|
424
|
-
{config.visualizationType !== 'TP5 Waffle' && (
|
|
416
|
+
{config.visualizationType !== 'TP5 Waffle' && config.visualizationType !== 'TP5 Gauge' && (
|
|
425
417
|
<Accordion.Section title='Visual'>
|
|
426
418
|
<VisualSection
|
|
427
419
|
config={config}
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
justify-items: center;
|
|
19
19
|
align-items: flex-start;
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
&>svg {
|
|
22
22
|
margin: 0.7em 0;
|
|
23
23
|
}
|
|
24
24
|
}
|
|
@@ -96,6 +96,7 @@
|
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
@at-root {
|
|
99
|
+
|
|
99
100
|
.cove-waffle-chart.font-small,
|
|
100
101
|
.cove-gauge-chart.font-small #{&} {
|
|
101
102
|
.cove-waffle-chart__data--primary {
|
|
@@ -135,6 +136,7 @@
|
|
|
135
136
|
&.waffle__style--tp5 {
|
|
136
137
|
.cove-component__content {
|
|
137
138
|
background: none !important;
|
|
139
|
+
container-type: inline-size;
|
|
138
140
|
}
|
|
139
141
|
|
|
140
142
|
.cdc-callout {
|
|
@@ -167,8 +169,21 @@
|
|
|
167
169
|
}
|
|
168
170
|
|
|
169
171
|
.cove-waffle-chart {
|
|
172
|
+
align-items: flex-start;
|
|
170
173
|
padding: 0;
|
|
171
174
|
row-gap: 1rem;
|
|
175
|
+
flex-wrap: nowrap;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// Container query: wrap when width is less than 576px
|
|
179
|
+
@container (max-width: 576px) {
|
|
180
|
+
.cove-waffle-chart {
|
|
181
|
+
flex-wrap: wrap;
|
|
182
|
+
|
|
183
|
+
.cove-waffle-chart__chart {
|
|
184
|
+
width: 100% !important;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
172
187
|
}
|
|
173
188
|
|
|
174
189
|
.cove-waffle-chart__chart {
|
|
@@ -190,9 +205,11 @@
|
|
|
190
205
|
margin-top: 0.5rem;
|
|
191
206
|
font-size: 1rem;
|
|
192
207
|
}
|
|
208
|
+
|
|
193
209
|
.cove-waffle-chart__subtext {
|
|
194
210
|
font-size: 1rem;
|
|
195
211
|
}
|
|
212
|
+
|
|
196
213
|
.cove-waffle-chart__data--primary {
|
|
197
214
|
font-size: 2rem;
|
|
198
215
|
color: var(--colors-cyan-60v);
|
|
@@ -212,4 +229,120 @@
|
|
|
212
229
|
}
|
|
213
230
|
}
|
|
214
231
|
}
|
|
232
|
+
|
|
233
|
+
// TP5 Style for Gauge Chart
|
|
234
|
+
&.gauge__style--tp5 {
|
|
235
|
+
.cove-component__content {
|
|
236
|
+
background: none !important;
|
|
237
|
+
container-type: inline-size;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
.cdc-callout {
|
|
241
|
+
box-shadow: 0 2px 4px rgb(159 159 159 / 10%);
|
|
242
|
+
margin: 0 !important;
|
|
243
|
+
padding: 1.5rem;
|
|
244
|
+
background-color: var(--colors-cyan-10, #eff9fa);
|
|
245
|
+
border: 1px solid var(--colors-cyan-15, #dff2f6);
|
|
246
|
+
position: relative;
|
|
247
|
+
border-radius: 0.25rem;
|
|
248
|
+
gap: 0.5rem;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
.cdc-callout__flag {
|
|
252
|
+
position: absolute;
|
|
253
|
+
top: -0.25rem;
|
|
254
|
+
right: 1.08rem;
|
|
255
|
+
width: 1.85rem;
|
|
256
|
+
height: auto;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
.cdc-callout__heading {
|
|
260
|
+
font-family: var(--fonts-nunito) !important;
|
|
261
|
+
width: 100%;
|
|
262
|
+
font-size: 1.1rem;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
.cove-gauge-chart {
|
|
266
|
+
padding: 0;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
.cove-gauge-chart__chart {
|
|
270
|
+
width: 100%;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
.cove-gauge-chart__chart>svg {
|
|
274
|
+
display: block;
|
|
275
|
+
width: 100%;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
.cove-gauge-chart__body {
|
|
279
|
+
flex-wrap: nowrap;
|
|
280
|
+
gap: 1rem;
|
|
281
|
+
row-gap: 0.5rem;
|
|
282
|
+
margin-bottom: 0.5rem;
|
|
283
|
+
align-items: flex-start; // Align to top instead of center when content varies
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// Container query: wrap when width is less than 576px
|
|
287
|
+
@container (max-width: 576px) {
|
|
288
|
+
.cove-gauge-chart__body {
|
|
289
|
+
flex-wrap: wrap;
|
|
290
|
+
|
|
291
|
+
.cove-gauge-chart__value-section {
|
|
292
|
+
width: 100%;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
.cove-gauge-chart__value-section {
|
|
298
|
+
width: auto;
|
|
299
|
+
padding-top: 1px;
|
|
300
|
+
display: flex;
|
|
301
|
+
flex-direction: column;
|
|
302
|
+
justify-content: flex-start;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
.cove-gauge-chart__content {
|
|
306
|
+
font-size: 1rem;
|
|
307
|
+
min-height: 1rem; // Ensure minimum height even when empty
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
.cove-waffle-chart__data--primary {
|
|
311
|
+
font-size: 2rem;
|
|
312
|
+
color: var(--colors-cyan-60v);
|
|
313
|
+
font-weight: 400;
|
|
314
|
+
line-height: 1;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
.cove-waffle-chart__data--text {
|
|
318
|
+
margin-top: 0;
|
|
319
|
+
font-size: 1rem;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
.cove-waffle-chart__subtext {
|
|
323
|
+
font-size: 1rem;
|
|
324
|
+
margin-top: auto;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// White background variant (when "Use White Background Style" is checked)
|
|
328
|
+
&.white-background-style {
|
|
329
|
+
.cove-component__content {
|
|
330
|
+
background: white !important;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
.cdc-callout {
|
|
334
|
+
background: transparent !important;
|
|
335
|
+
border: 1px solid #009ec1 !important;
|
|
336
|
+
box-shadow: 0 2px 4px rgb(159 159 159 / 10%);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
}
|
|
215
340
|
}
|
|
341
|
+
|
|
342
|
+
// Center gauge value when there's no message (standalone only, not in dashboard rows)
|
|
343
|
+
.type-waffle-chart.gauge__style--tp5:not(.row *) {
|
|
344
|
+
.cove-gauge-chart__body.d-flex.justify-content-center {
|
|
345
|
+
justify-content: center;
|
|
346
|
+
width: 100%;
|
|
347
|
+
}
|
|
348
|
+
}
|
package/src/types/Config.ts
CHANGED