@@ -4,6 +4,13 @@ const { langCardLocales } = require("../translations");
4
4
const { createProgressNode } = require ( "../common/createProgressNode" ) ;
5
5
const { clampValue, getCardColors, flexLayout } = require ( "../common/utils" ) ;
6
6
7
+ const DEFAULT_CARD_WIDTH = 300 ;
8
+ const DEFAULT_LANGS_COUNT = 5 ;
9
+ const DEFAULT_LANG_COLOR = "#858585" ;
10
+ const CARD_PADDING = 25 ;
11
+
12
+ const lowercaseTrim = ( name ) => name . toLowerCase ( ) . trim ( ) ;
13
+
7
14
const createProgressTextNode = ( { width, color, name, progress } ) => {
8
15
const paddingRight = 95 ;
9
16
const progressTextX = width - paddingRight + 10 ;
@@ -58,35 +65,99 @@ const createLanguageTextNode = ({ langs, totalSize, x, y }) => {
58
65
} ) ;
59
66
} ;
60
67
61
- const lowercaseTrim = ( name ) => name . toLowerCase ( ) . trim ( ) ;
68
+ /**
69
+ *
70
+ * @param {any[] } langs
71
+ * @param {number } width
72
+ * @param {number } totalLanguageSize
73
+ * @returns {string }
74
+ */
75
+ const renderNormalLayout = ( langs , width , totalLanguageSize ) => {
76
+ return flexLayout ( {
77
+ items : langs . map ( ( lang ) => {
78
+ return createProgressTextNode ( {
79
+ width : width ,
80
+ name : lang . name ,
81
+ color : lang . color || DEFAULT_LANG_COLOR ,
82
+ progress : ( ( lang . size / totalLanguageSize ) * 100 ) . toFixed ( 2 ) ,
83
+ } ) ;
84
+ } ) ,
85
+ gap : 40 ,
86
+ direction : "column" ,
87
+ } ) . join ( "" ) ;
88
+ } ;
62
89
63
- const renderTopLanguages = ( topLangs , options = { } ) => {
64
- const {
65
- hide_title,
66
- hide_border,
67
- card_width,
68
- title_color,
69
- text_color,
70
- bg_color,
71
- hide,
72
- theme,
73
- layout,
74
- custom_title,
75
- locale,
76
- langs_count = 5 ,
77
- border_radius,
78
- border_color,
79
- } = options ;
90
+ /**
91
+ *
92
+ * @param {any[] } langs
93
+ * @param {number } width
94
+ * @param {number } totalLanguageSize
95
+ * @returns {string }
96
+ */
97
+ const renderCompactLayout = ( langs , width , totalLanguageSize ) => {
98
+ const paddingRight = 50 ;
99
+ const offsetWidth = width - paddingRight ;
100
+ // progressOffset holds the previous language's width and used to offset the next language
101
+ // so that we can stack them one after another, like this: [--][----][---]
102
+ let progressOffset = 0 ;
103
+ const compactProgressBar = langs
104
+ . map ( ( lang ) => {
105
+ const percentage = parseFloat (
106
+ ( ( lang . size / totalLanguageSize ) * offsetWidth ) . toFixed ( 2 ) ,
107
+ ) ;
80
108
81
- const i18n = new I18n ( {
82
- locale,
83
- translations : langCardLocales ,
84
- } ) ;
109
+ const progress = percentage < 10 ? percentage + 10 : percentage ;
110
+
111
+ const output = `
112
+ <rect
113
+ mask="url(#rect-mask)"
114
+ data-testid="lang-progress"
115
+ x="${ progressOffset } "
116
+ y="0"
117
+ width="${ progress } "
118
+ height="8"
119
+ fill="${ lang . color || "#858585" } "
120
+ />
121
+ ` ;
122
+ progressOffset += percentage ;
123
+ return output ;
124
+ } )
125
+ . join ( "" ) ;
126
+
127
+ return `
128
+ <mask id="rect-mask">
129
+ <rect x="0" y="0" width="${ offsetWidth } " height="8" fill="white" rx="5" />
130
+ </mask>
131
+ ${ compactProgressBar }
132
+ ${ createLanguageTextNode ( {
133
+ x : 0 ,
134
+ y : 25 ,
135
+ langs,
136
+ totalSize : totalLanguageSize ,
137
+ } ) . join ( "" ) }
138
+ ` ;
139
+ } ;
140
+
141
+ /**
142
+ * @param {number } totalLangs
143
+ * @returns {number }
144
+ */
145
+ const calculateCompactLayoutHeight = ( totalLangs ) => {
146
+ return 90 + Math . round ( totalLangs / 2 ) * 25 ;
147
+ } ;
85
148
149
+ /**
150
+ * @param {number } totalLangs
151
+ * @returns {number }
152
+ */
153
+ const calculateNormalLayoutHeight = ( totalLangs ) => {
154
+ return 45 + ( totalLangs + 1 ) * 40 ;
155
+ } ;
156
+
157
+ const useLanguages = ( topLangs , hide , langs_count ) => {
86
158
let langs = Object . values ( topLangs ) ;
87
159
let langsToHide = { } ;
88
-
89
- langsCount = clampValue ( parseInt ( langs_count ) , 1 , 10 ) ;
160
+ let langsCount = clampValue ( parseInt ( langs_count ) , 1 , 10 ) ;
90
161
91
162
// populate langsToHide map for quick lookup
92
163
// while filtering out
@@ -104,110 +175,80 @@ const renderTopLanguages = (topLangs, options = {}) => {
104
175
} )
105
176
. slice ( 0 , langsCount ) ;
106
177
107
- const totalLanguageSize = langs . reduce ( ( acc , curr ) => {
108
- return acc + curr . size ;
109
- } , 0 ) ;
178
+ const totalLanguageSize = langs . reduce ( ( acc , curr ) => acc + curr . size , 0 ) ;
110
179
111
- // returns theme based colors with proper overrides and defaults
112
- const { titleColor, textColor, bgColor, borderColor } = getCardColors ( {
180
+ return { langs, totalLanguageSize } ;
181
+ } ;
182
+
183
+ const renderTopLanguages = ( topLangs , options = { } ) => {
184
+ const {
185
+ hide_title,
186
+ hide_border,
187
+ card_width,
113
188
title_color,
114
189
text_color,
115
190
bg_color,
116
- border_color ,
191
+ hide ,
117
192
theme,
193
+ layout,
194
+ custom_title,
195
+ locale,
196
+ langs_count = DEFAULT_LANGS_COUNT ,
197
+ border_radius,
198
+ border_color,
199
+ } = options ;
200
+
201
+ const i18n = new I18n ( {
202
+ locale,
203
+ translations : langCardLocales ,
118
204
} ) ;
119
205
120
- let width = isNaN ( card_width ) ? 300 : card_width ;
121
- let height = 45 + ( langs . length + 1 ) * 40 ;
206
+ const { langs, totalLanguageSize } = useLanguages (
207
+ topLangs ,
208
+ hide ,
209
+ langs_count ,
210
+ ) ;
122
211
123
- let finalLayout = "" ;
212
+ let width = isNaN ( card_width ) ? DEFAULT_CARD_WIDTH : card_width ;
213
+ let height = calculateNormalLayoutHeight ( langs . length ) ;
124
214
125
- // RENDER COMPACT LAYOUT
215
+ let finalLayout = "" ;
126
216
if ( layout === "compact" ) {
127
- width = width + 50 ;
128
- height = 90 + Math . round ( langs . length / 2 ) * 25 ;
129
-
130
- // progressOffset holds the previous language's width and used to offset the next language
131
- // so that we can stack them one after another, like this: [--][----][---]
132
- let progressOffset = 0 ;
133
- const compactProgressBar = langs
134
- . map ( ( lang ) => {
135
- const percentage = (
136
- ( lang . size / totalLanguageSize ) *
137
- ( width - 50 )
138
- ) . toFixed ( 2 ) ;
139
-
140
- const progress =
141
- percentage < 10 ? parseFloat ( percentage ) + 10 : percentage ;
142
-
143
- const output = `
144
- <rect
145
- mask="url(#rect-mask)"
146
- data-testid="lang-progress"
147
- x="${ progressOffset } "
148
- y="0"
149
- width="${ progress } "
150
- height="8"
151
- fill="${ lang . color || "#858585" } "
152
- />
153
- ` ;
154
- progressOffset += parseFloat ( percentage ) ;
155
- return output ;
156
- } )
157
- . join ( "" ) ;
158
-
159
- finalLayout = `
160
- <mask id="rect-mask">
161
- <rect x="0" y="0" width="${
162
- width - 50
163
- } " height="8" fill="white" rx="5" />
164
- </mask>
165
- ${ compactProgressBar }
166
- ${ createLanguageTextNode ( {
167
- x : 0 ,
168
- y : 25 ,
169
- langs,
170
- totalSize : totalLanguageSize ,
171
- } ) . join ( "" ) }
172
- ` ;
217
+ width = width + 50 ; // padding
218
+ height = calculateCompactLayoutHeight ( langs . length ) ;
219
+
220
+ finalLayout = renderCompactLayout ( langs , width , totalLanguageSize ) ;
173
221
} else {
174
- finalLayout = flexLayout ( {
175
- items : langs . map ( ( lang ) => {
176
- return createProgressTextNode ( {
177
- width : width ,
178
- name : lang . name ,
179
- color : lang . color || "#858585" ,
180
- progress : ( ( lang . size / totalLanguageSize ) * 100 ) . toFixed ( 2 ) ,
181
- } ) ;
182
- } ) ,
183
- gap : 40 ,
184
- direction : "column" ,
185
- } ) . join ( "" ) ;
222
+ finalLayout = renderNormalLayout ( langs , width , totalLanguageSize ) ;
186
223
}
187
224
225
+ // returns theme based colors with proper overrides and defaults
226
+ const colors = getCardColors ( {
227
+ title_color,
228
+ text_color,
229
+ bg_color,
230
+ border_color,
231
+ theme,
232
+ } ) ;
233
+
188
234
const card = new Card ( {
189
235
customTitle : custom_title ,
190
236
defaultTitle : i18n . t ( "langcard.title" ) ,
191
237
width,
192
238
height,
193
239
border_radius,
194
- colors : {
195
- titleColor,
196
- textColor,
197
- bgColor,
198
- borderColor,
199
- } ,
240
+ colors,
200
241
} ) ;
201
242
202
243
card . disableAnimations ( ) ;
203
244
card . setHideBorder ( hide_border ) ;
204
245
card . setHideTitle ( hide_title ) ;
205
- card . setCSS ( `
206
- .lang-name { font: 400 11px 'Segoe UI', Ubuntu, Sans-Serif; fill: ${ textColor } }
207
- ` ) ;
246
+ card . setCSS (
247
+ ` .lang-name { font: 400 11px 'Segoe UI', Ubuntu, Sans-Serif; fill: ${ colors . textColor } }` ,
248
+ ) ;
208
249
209
250
return card . render ( `
210
- <svg data-testid="lang-items" x="25 ">
251
+ <svg data-testid="lang-items" x="${ CARD_PADDING } ">
211
252
${ finalLayout }
212
253
</svg>
213
254
` ) ;
0 commit comments