@@ -23,7 +23,7 @@ export default async function initProject() {
23
23
if ( parseInt ( $ ( column ) . data ( 'sorting' ) ) !== i ) {
24
24
$ . ajax ( {
25
25
url : $ ( column ) . data ( 'url' ) ,
26
- data : JSON . stringify ( { sorting : i } ) ,
26
+ data : JSON . stringify ( { sorting : i , color : rgbToHex ( $ ( column ) . css ( 'backgroundColor' ) ) } ) ,
27
27
headers : {
28
28
'X-Csrf-Token' : csrf ,
29
29
'X-Remote' : true ,
@@ -62,10 +62,17 @@ export default async function initProject() {
62
62
}
63
63
64
64
$ ( '.edit-project-board' ) . each ( function ( ) {
65
- const projectTitleLabel = $ ( this ) . closest ( '.board-column-header' ) . find ( '.board-label' ) ;
65
+ const projectHeader = $ ( this ) . closest ( '.board-column-header' ) ;
66
+ const projectTitleLabel = projectHeader . find ( '.board-label' ) ;
66
67
const projectTitleInput = $ ( this ) . find (
67
68
'.content > .form > .field > .project-board-title' ,
68
69
) ;
70
+ const projectColorInput = $ ( this ) . find ( '.content > .form > .field #new_board_color' ) ;
71
+ const boardColumn = $ ( this ) . closest ( '.board-column' ) ;
72
+
73
+ if ( boardColumn . css ( 'backgroundColor' ) ) {
74
+ setLabelColor ( projectHeader , rgbToHex ( boardColumn . css ( 'backgroundColor' ) ) ) ;
75
+ }
69
76
70
77
$ ( this )
71
78
. find ( '.content > .form > .actions > .red' )
@@ -74,7 +81,7 @@ export default async function initProject() {
74
81
75
82
$ . ajax ( {
76
83
url : $ ( this ) . data ( 'url' ) ,
77
- data : JSON . stringify ( { title : projectTitleInput . val ( ) } ) ,
84
+ data : JSON . stringify ( { title : projectTitleInput . val ( ) , color : projectColorInput . val ( ) } ) ,
78
85
headers : {
79
86
'X-Csrf-Token' : csrf ,
80
87
'X-Remote' : true ,
@@ -84,6 +91,10 @@ export default async function initProject() {
84
91
} ) . done ( ( ) => {
85
92
projectTitleLabel . text ( projectTitleInput . val ( ) ) ;
86
93
projectTitleInput . closest ( 'form' ) . removeClass ( 'dirty' ) ;
94
+ if ( projectColorInput . val ( ) ) {
95
+ setLabelColor ( projectHeader , projectColorInput . val ( ) ) ;
96
+ }
97
+ boardColumn . attr ( 'style' , `background: ${ projectColorInput . val ( ) } !important` ) ;
87
98
$ ( '.ui.modal' ) . modal ( 'hide' ) ;
88
99
} ) ;
89
100
} ) ;
@@ -127,10 +138,11 @@ export default async function initProject() {
127
138
e . preventDefault ( ) ;
128
139
129
140
const boardTitle = $ ( '#new_board' ) ;
141
+ const projectColorInput = $ ( '#new_board_color_picker' ) ;
130
142
131
143
$ . ajax ( {
132
144
url : $ ( this ) . data ( 'url' ) ,
133
- data : JSON . stringify ( { title : boardTitle . val ( ) } ) ,
145
+ data : JSON . stringify ( { title : boardTitle . val ( ) , color : projectColorInput . val ( ) } ) ,
134
146
headers : {
135
147
'X-Csrf-Token' : csrf ,
136
148
'X-Remote' : true ,
@@ -143,3 +155,34 @@ export default async function initProject() {
143
155
} ) ;
144
156
} ) ;
145
157
}
158
+
159
+ function setLabelColor ( label , color ) {
160
+ const red = getRelativeColor ( parseInt ( color . substr ( 1 , 2 ) , 16 ) ) ;
161
+ const green = getRelativeColor ( parseInt ( color . substr ( 3 , 2 ) , 16 ) ) ;
162
+ const blue = getRelativeColor ( parseInt ( color . substr ( 5 , 2 ) , 16 ) ) ;
163
+ const luminance = 0.2126 * red + 0.7152 * green + 0.0722 * blue ;
164
+
165
+ if ( luminance > 0.179 ) {
166
+ label . removeClass ( 'light-label' ) . addClass ( 'dark-label' ) ;
167
+ } else {
168
+ label . removeClass ( 'dark-label' ) . addClass ( 'light-label' ) ;
169
+ }
170
+ }
171
+
172
+ /**
173
+ * Inspired by W3C recommandation https://www.w3.org/TR/WCAG20/#relativeluminancedef
174
+ */
175
+ function getRelativeColor ( color ) {
176
+ color /= 255 ;
177
+ return color <= 0.03928 ? color / 12.92 : ( ( color + 0.055 ) / 1.055 ) ** 2.4 ;
178
+ }
179
+
180
+ function rgbToHex ( rgb ) {
181
+ rgb = rgb . match ( / ^ r g b \( ( \d + ) , \s * ( \d + ) , \s * ( \d + ) \) $ / ) ;
182
+ return `#${ hex ( rgb [ 1 ] ) } ${ hex ( rgb [ 2 ] ) } ${ hex ( rgb [ 3 ] ) } ` ;
183
+ }
184
+
185
+ function hex ( x ) {
186
+ const hexDigits = [ '0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' , 'a' , 'b' , 'c' , 'd' , 'e' , 'f' ] ;
187
+ return Number . isNaN ( x ) ? '00' : hexDigits [ ( x - x % 16 ) / 16 ] + hexDigits [ x % 16 ] ;
188
+ }
0 commit comments