@@ -13,8 +13,9 @@ defmodule PetalComponents.Input do
13
13
14
14
attr :type , :string ,
15
15
default: "text" ,
16
- values: ~w( checkbox color date datetime-local email file hidden month number password
17
- range radio search select switch tel text textarea time url week)
16
+ values:
17
+ ~w( checkbox color date datetime-local email file hidden month number password
18
+ range range-dual range-numeric radio search select switch tel text textarea time url week)
18
19
19
20
attr :size , :string , default: "md" , values: ~w( xs sm md lg xl) , doc: "the size of the switch"
20
21
@@ -222,6 +223,98 @@ defmodule PetalComponents.Input do
222
223
"""
223
224
end
224
225
226
+ def input ( % { type: "range-dual" } = assigns ) do
227
+ ~H"""
228
+ < div id = { @ id } class = "relative h-12 mt-4 " >
229
+ < div class = "flex flex-row items-center justify-center space-x-2 " >
230
+ < div class = "relative w-full h-1 " >
231
+ < div class = "pc-slider-track " > </ div >
232
+ < div
233
+ class = "pc-slider-range "
234
+ data-slider-id = { @ id }
235
+ id = { @ id <> "_slider-range" }
236
+ style = { "left: #{ calculate_slider_position ( @ min_field . value , @ range_min , @ range_max ) } %; right: #{ 100 - calculate_slider_position ( @ max_field . value , @ range_min , @ range_max ) } %;" }
237
+ >
238
+ </ div >
239
+ < input
240
+ type = "range "
241
+ min = { @ range_min }
242
+ max = { @ range_max }
243
+ step = { @ step }
244
+ name = { @ min_field . name }
245
+ value = { @ min_field . value }
246
+ class = "pc-slider-input "
247
+ id = { @ id <> "_min-range" }
248
+ phx-hook = "DualRangeSliderHook "
249
+ data-slider-id = { @ id }
250
+ data-slider-type = "min "
251
+ data-range-min = { @ range_min }
252
+ data-range-max = { @ range_max }
253
+ />
254
+ < input
255
+ type = "range "
256
+ min = { @ range_min }
257
+ max = { @ range_max }
258
+ step = { @ step }
259
+ name = { @ max_field . name }
260
+ value = { @ max_field . value }
261
+ class = "pc-slider-input "
262
+ id = { @ id <> "_max-range" }
263
+ phx-hook = "DualRangeSliderHook "
264
+ data-slider-id = { @ id }
265
+ data-slider-type = "max "
266
+ data-range-min = { @ range_min }
267
+ data-range-max = { @ range_max }
268
+ />
269
+ </ div >
270
+ </ div >
271
+ < div class = "grid grid-cols-3 mt-4 text-sm " >
272
+ < span class = "flex items-start justify-start text-gray-500 dark:text-gray-400 " >
273
+ { @ range_min_label || @ format_value . ( @ range_min ) }
274
+ </ span >
275
+ < span class = "flex justify-center text-gray-600 dark:text-gray-300 " >
276
+ { @ format_value . ( @ min_field . value ) <> " - " <> @ format_value . ( @ max_field . value ) }
277
+ </ span >
278
+ < span class = "flex items-end justify-end text-gray-500 dark:text-gray-400 " >
279
+ { @ range_max_label || @ format_value . ( @ range_max ) }
280
+ </ span >
281
+ </ div >
282
+ </ div >
283
+ """
284
+ end
285
+
286
+ def input ( % { type: "range-numeric" } = assigns ) do
287
+ ~H"""
288
+ < div class = "flex flex-row gap-2 " >
289
+ < input
290
+ type = "number "
291
+ step = { @ step }
292
+ name = { @ min_field . name }
293
+ value = { @ min_field . value }
294
+ placeholder = "No Min "
295
+ min = { @ range_min }
296
+ max = { @ max_field . value }
297
+ id = { @ id <> "_min" }
298
+ inputmode = "numeric "
299
+ class = "w-full pc-text-input "
300
+ />
301
+ < div class = "flex flex-col items-center justify-center " > -</ div >
302
+ < input
303
+ type = "number "
304
+ step = { @ step }
305
+ name = { @ max_field . name }
306
+ value = { @ max_field . value }
307
+ placeholder = "No Max "
308
+ min = { @ min_field . value }
309
+ max = { @ range_max }
310
+ id = { @ id <> "_max" }
311
+ inputmode = "numeric "
312
+ class = "w-full pc-text-input "
313
+ />
314
+ </ div >
315
+ """
316
+ end
317
+
225
318
def input ( assigns ) do
226
319
~H"""
227
320
< input
@@ -247,4 +340,27 @@ defmodule PetalComponents.Input do
247
340
defp get_icon_for_type ( "month" ) , do: "hero-calendar"
248
341
defp get_icon_for_type ( "week" ) , do: "hero-calendar"
249
342
defp get_icon_for_type ( "time" ) , do: "hero-clock"
343
+
344
+ # Helper functions for input.ex
345
+ defp calculate_slider_position ( nil , _range_min , _range_max ) , do: 0
346
+
347
+ defp calculate_slider_position ( value , range_min , range_max ) when is_integer ( value ) do
348
+ round ( ( value - range_min ) / ( range_max - range_min ) * 100 )
349
+ end
350
+
351
+ defp calculate_slider_position ( value , range_min , range_max ) do
352
+ value =
353
+ case value do
354
+ v when is_binary ( v ) -> String . to_integer ( v )
355
+ v when is_integer ( v ) -> v
356
+ _ -> range_min
357
+ end
358
+
359
+ round ( ( value - range_min ) / ( range_max - range_min ) * 100 )
360
+ end
361
+
362
+ # Add format_value function
363
+ defp format_value ( value ) when is_integer ( value ) , do: Integer . to_string ( value )
364
+ defp format_value ( value ) when is_float ( value ) , do: Float . to_string ( value )
365
+ defp format_value ( _ ) , do: "0"
250
366
end
0 commit comments