72
72
}
73
73
}
74
74
75
- .color-picker .hidden {
76
- opacity : 0 ;
77
- pointer-events : none;
78
- }
79
-
80
75
.color-picker [positioned ]{
81
76
--x : calc (var (--pos-left ) + var (--window-scroll-x ));
82
77
--y : calc (var (--pos-top ) + var (--window-scroll-y ));
89
84
background : white;
90
85
top : 0 ;
91
86
left : 0 ;
87
+ animation : .15s reveal-picker ease-out forwards;
92
88
transform : translate (calc (var (--x ) * 1px ),
93
- calc (var (--y ) * 1px ));
89
+ calc (var (--y ) * 1px ));
94
90
95
91
@media only screen and (max-device-width : 640px ) {
96
92
max-width : 70% ;
97
93
}
98
94
}
95
+
96
+ .color-picker [data-placement ~= left ]{ --left : 15px ; }
97
+ .color-picker [data-placement ~= right ]{ --left : -15px ; }
98
+ .color-picker [data-placement ~= below ]{ --top : -15px ; }
99
+ .color-picker [data-placement ~= above ]{ --top : 15px ; }
100
+
101
+ @keyframes reveal-picker {
102
+ from { opacity : 0 ; top : var (--top , 0 ); left : var (--left , 0 ); }
103
+ }
99
104
</ style >
100
105
</ head >
101
106
< body >
@@ -110,85 +115,92 @@ <h1>Color Picker</h1>
110
115
< input class ='myColor ' inputmode ='none ' value ='HSLA(244, 64%, 62%, 100%) ' style ='--color:HSLA(244, 64%, 62%, 100%) ' data-swatches ='["LightCoral", "MediumSeaGreen", "#3680FA99"] ' data-placement ='center below '/>
111
116
< input class ='myColor ' inputmode ='none ' value ='RGBA(255,0,170,.30 ' style ='--color:rgba(255,0,170,.3) ' data-swatches ='["rgba(50,250,80,.5)"] ' data-placement ='right center ' />
112
117
</ div >
113
- < script >
114
- /* https://www.npmjs.com/package/@yaireo/position */
115
- ( function ( a , b ) { if ( "function" == typeof define && define . amd ) define ( [ "exports" ] , b ) ; else if ( "undefined" != typeof exports ) b ( exports ) ; else { var c = { exports :{ } } ; b ( c . exports ) , a . position = c . exports } } ) ( "undefined" == typeof globalThis ?"undefined" == typeof self ?this :self :globalThis , function ( a ) { "use strict" ; var b = Math . round ; Object . defineProperty ( a , "__esModule" , { value :! 0 } ) , a . default = void 0 ; /**
116
- * positions a DOM element next to a certain position
117
- * @param {HTMLElement } target DOM element node
118
- * @param {Object } ref node reference for positioning or just {x,y} coordinates
119
- * @param {String } placement [above/below/center & left/right/center] or mix of two (only works if "ref" is an HTML Element)
120
- * @param {Array } prevPlacement used when calculated new position overflows
121
- * @param {Array } offset distance (in pixels) from original placement position ("10px 20px" or just "10px" for both horizontal & vertical)
122
- */ const c = a => { var { target :e , ref :f , offset :g , placement :h , prevPlacement :i , useRaf :j = ! 0 } = a , k = { x :f . x , y :f . y } , l = f && f . x ?{ ...f } :{ } , m = document . documentElement , n = { w :m . clientWidth , h :m . clientHeight } , o = { w :e . clientWidth , h :e . clientHeight } ; d = j ?d :a => a ( ) , i = i || [ ] , h = ( h || " " ) . split ( " " ) . map ( ( b , a ) => b ?b :[ "center" , "below" ] [ a ] ) , g = g ?[ g [ 0 ] || 0 , g [ 1 ] || g [ 0 ] || 0 ] :[ 0 , 0 ] , f instanceof Element && ( l = f . getBoundingClientRect ( ) , k . x = l . x , k . y = l . y , k . w = l . width , k . h = l . height , "left" == h [ 0 ] ?k . x -= o . w + g [ 0 ] :"right" == h [ 0 ] ?k . x += k . w + g [ 0 ] :k . x -= o . w / 2 - k . w / 2 , "above" == h [ 1 ] ?k . y -= o . h + g [ 1 ] :"below" == h [ 1 ] ?k . y += k . h + g [ 1 ] :k . y -= o . h / 2 - k . h / 2 ) ; const p = { top :0 > k . y , bottom :k . y + o . h > n . h , left :0 > k . x , right :k . x + o . w > n . w } , q = b => c ( { ...a , placement :b . join ( " " ) , prevPlacement :h } ) ; // horizontal fix for overflows
123
- return p . left && "right" != i [ 0 ] ?q ( [ "right" , h [ 1 ] ] ) :p . right && "left" != i [ 0 ] ?q ( [ "left" , h [ 1 ] ] ) :p . bottom && "above" != i [ 1 ] ?q ( [ h [ 0 ] , "above" ] ) :p . top && "below" != i [ 1 ] ?q ( [ h [ 0 ] , "below" ] ) :( d ( ( ) => { e . setAttribute ( "positioned" , ! 0 ) , e . setAttribute ( "data-placement" , h . join ( " " ) ) , e . setAttribute ( "data-pos-overflow" , Object . entries ( p ) . reduce ( ( a , [ b , c ] ) => c ?`${ a } ${ b } ` :a , "" ) . trim ( ) ) , [ [ "pos-left" , k . x ] , // overflow.right ? vpSize.w - targetSize.w : pos.x
124
- [ "pos-top" , k . y ] , // pos.y > offset[1] ? pos.y : 0
125
- [ "pos-target-width" , o . w ] , [ "pos-target-height" , o . h ] , [ "pos-ref-width" , l . width || 0 ] , [ "pos-ref-height" , l . height || 0 ] , [ "pos-ref-left" , l . x ] , [ "pos-ref-top" , l . y ] , [ "window-scroll-y" , window . scrollY ] , [ "window-scroll-x" , window . scrollX ] ] . forEach ( ( [ a , c ] ) => e . style . setProperty ( "--" + a , b ( c ) ) ) } ) , { pos :k , placement :h } ) ; // vertical fix for overflows
126
- // update target's position
127
- } ; let d = requestAnimationFrame || ( a => setTimeout ( a , 1e3 / 60 ) ) ; a . default = c } ) ;
128
- </ script >
129
118
130
- < script src ="./dist/color-picker.js "> </ script >
119
+ < script src ='https://cdn.jsdelivr.net/npm/@yaireo/position '> </ script >
120
+ < script src ='./dist/color-picker.js '> </ script >
131
121
132
122
< script >
123
+ // because "@yaireo/position" is used (in this demo) as a script file and not an node module (ES export)
133
124
position = position . default ;
125
+
126
+ // get the ColorPicker & some helper functions for color format transformations
134
127
const { default :ColorPicker , any_to_hex, changeColorFormat } = window . ColorPicker
135
128
136
129
// let the delayed (non-blocking) CSS a chance to load first
137
130
setTimeout ( init , 200 )
138
131
139
132
function init ( ) {
140
- // iterate all color inputs and instantiate an new ColorPicker instance for each
133
+ // iterate all color inputs and instantiate new ColorPicker instances ( for each one)
141
134
document . querySelectorAll ( '.myColor' ) . forEach ( colorInput => {
142
- const observerCallback = ( entries ) => {
143
- ! cPicker . DOM . scope . classList . contains ( 'hidden' ) &&
144
- position ( { target :cPicker . DOM . scope , ref :colorInput , placement :colorInput . dataset . placement || 'center above' , offset :[ 20 ] } ) ;
145
- }
146
- const resizeObserver = new ResizeObserver ( observerCallback )
147
- const intersectionObserver = new IntersectionObserver ( observerCallback , { root :document , threshold :1 } ) ;
135
+ const observerCallback = ( entries ) => {
136
+ ! cPicker . DOM . scope . classList . contains ( 'hidden' ) &&
137
+ position ( { target :cPicker . DOM . scope , ref :colorInput , placement :colorInput . dataset . placement || 'center above' , offset :[ 20 ] } ) ;
138
+ }
139
+ const resizeObserver = new ResizeObserver ( observerCallback )
140
+ const intersectionObserver = new IntersectionObserver ( observerCallback , { root :document , threshold :1 } ) ;
148
141
149
- const cPicker = new ColorPicker ( {
150
- color : colorInput . value , // accepts formats: HEX(A), RGB(A), HSL(A)
142
+ const cPicker = new ColorPicker ( {
143
+ color : colorInput . value , // accepts formats: HEX(A), RGB(A), HSL(A)
151
144
152
- className : 'hidden ' ,
145
+ defaultFormat : 'hsla ' ,
153
146
154
- defaultFormat : 'hsla' ,
147
+ swatches : colorInput . dataset . swatches == 'false'
148
+ ? false
149
+ : JSON . parse ( colorInput . dataset . swatches ) ,
155
150
156
- swatches : colorInput . dataset . swatches == 'false'
157
- ? false
158
- : JSON . parse ( colorInput . dataset . swatches ) ,
151
+ swatchesLocalStorage : true ,
159
152
160
- swatchesLocalStorage : true ,
153
+ // when clicking anywhere that is not within the color picker.
154
+ // use special logic if clicked on the color-input which is
155
+ // assosiacated with this specific picker
156
+ onClickOutside ( e ) {
157
+ let showPicker = false ,
158
+ isTargetColorInput = e . target == colorInput ;
161
159
162
- onClickOutside ( e ) {
163
- let action = 'add' ,
164
- isTargetColorInput = e . target == colorInput
160
+ const pickerElem = cPicker . DOM . scope ;
165
161
166
- if ( isTargetColorInput ) action = 'toggle'
167
- if ( e . key == 'Escape' ) action = 'add'
162
+ if ( isTargetColorInput ) showPicker = true
163
+ if ( e . key == 'Escape' ) showPicker = false
168
164
169
- cPicker . DOM . scope . classList [ action ] ( 'hidden' )
165
+ // remove the color-picker from the DOM
166
+ if ( showPicker ) { }
167
+ showColorPicker ( pickerElem )
168
+ else
169
+ hideColorPicker ( pickerElem ) ;
170
170
171
- isTargetColorInput && observerCallback ( )
172
- } ,
171
+ isTargetColorInput && observerCallback ( )
172
+ } ,
173
173
174
- onInput ( c ) {
175
- colorInput . value = c ;
176
- colorInput . style . setProperty ( '--color' , c )
177
- } ,
174
+ onInput ( c ) {
175
+ colorInput . value = c ;
176
+ colorInput . style . setProperty ( '--color' , c )
177
+ } ,
178
178
179
- // onChange: console.log
180
- } )
179
+ // onChange: console.log
180
+ } )
181
181
182
- cPicker . DOM . scope . setAttribute ( 'positioned' , true )
183
- document . body . appendChild ( cPicker . DOM . scope )
182
+ cPicker . DOM . scope . setAttribute ( 'positioned' , true )
183
+ // document.body.appendChild(cPicker.DOM.scope)
184
184
185
- resizeObserver . observe ( document . body )
186
- intersectionObserver . observe ( cPicker . DOM . scope )
187
- observerCallback ( )
185
+ resizeObserver . observe ( document . body )
186
+ intersectionObserver . observe ( cPicker . DOM . scope )
187
+ observerCallback ( )
188
188
189
- colorInput . _colorPicker = cPicker
189
+ // assign a custom property to color-input element
190
+ // which points to the corresponding color-picker instance
191
+ colorInput . _colorPicker = cPicker
190
192
} )
191
193
194
+ function showColorPicker ( pickerElem ) {
195
+ // if picker isn't already in the DOM:
196
+ if ( ! document . body . contains ( pickerElem ) )
197
+ document . body . appendChild ( pickerElem ) ; // inject to DOM
198
+ }
199
+
200
+ function hideColorPicker ( pickerElem ) {
201
+ pickerElem . remove ( ) ;
202
+ }
203
+
192
204
// setTimeout(() => {
193
205
// document.querySelector('.myColor')._colorPicker.setColor( 'red' )
194
206
// }, 2000)
0 commit comments