A music player that connects to your cloud/distributed storage.
1module Themes.Sunrise.Kit exposing (..)
2
3import Chunky exposing (..)
4import Color
5import Conditional exposing (ifThenElse)
6import Html exposing (Html)
7import Html.Attributes as A exposing (href, style)
8import Html.Events exposing (onClick, onInput)
9import Icons exposing (Icon)
10import Material.Icons.Round as Icons
11import Material.Icons.Types exposing (Coloring(..))
12import Svg
13
14
15
16-- COLORS
17
18
19colorKit =
20 { base00 = rgb 45 45 45
21 , base01 = rgb 63 63 63
22 , base02 = rgb 79 79 79
23 , base03 = rgb 119 119 119
24 , base04 = rgb 140 140 140
25 , base05 = rgb 163 163 163
26 , base06 = rgb 186 186 186
27 , base07 = rgb 232 232 232
28 , base08 = rgb 239 97 85
29 , base09 = rgb 249 155 21
30 , base0A = rgb 254 196 24
31 , base0B = rgb 72 182 133
32 , base0C = rgb 91 196 191
33 , base0D = rgb 6 182 239
34 , base0E = rgb 129 91 164
35 , base0F = rgb 233 107 168
36 }
37
38
39colors =
40 { -- States
41 success = colorKit.base0B
42 , error = colorKit.base08
43 , warning = colorKit.base0A
44
45 -- Gray
46 , gray_100 = Color.hsl 0 0 0.988
47 , gray_200 = Color.hsl 0 0 0.973
48 , gray_300 = Color.hsl 0 0 0.933
49 , gray_400 = Color.hsl 0 0 0.882
50 , gray_500 = Color.hsl 0 0 0.863
51 , gray_600 = Color.hsl 0 0 0.776
52
53 -- Other
54 , background = rgb 2 7 14
55 , selection = colorKit.base04
56 , text = colorKit.base01
57 }
58
59
60rgb =
61 Color.rgb255
62
63
64
65-- 🍱 ░░ BUTTON
66
67
68type ButtonColor
69 = Accent
70 | Blank
71 | Gray
72
73
74type ButtonType
75 = Filled
76 | IconOnly
77 | Normal
78
79
80button : ButtonType -> msg -> Html msg -> Html msg
81button =
82 buttonWithColor Gray
83
84
85buttonLink : String -> ButtonType -> Html msg -> Html msg
86buttonLink theHref buttonType =
87 buttonWithOptions Html.a [ href theHref ] Accent buttonType Nothing
88
89
90buttonLinkWithColor : ButtonColor -> String -> ButtonType -> Html msg -> Html msg
91buttonLinkWithColor color theHref buttonType =
92 buttonWithOptions Html.a [ href theHref ] color buttonType Nothing
93
94
95buttonWithColor : ButtonColor -> ButtonType -> msg -> Html msg -> Html msg
96buttonWithColor color buttonType msg =
97 buttonWithOptions Html.button [] color buttonType (Just msg)
98
99
100buttonWithOptions :
101 (List (Html.Attribute msg) -> List (Html msg) -> Html msg)
102 -> List (Html.Attribute msg)
103 -> ButtonColor
104 -> ButtonType
105 -> Maybe msg
106 -> Html msg
107 -> Html msg
108buttonWithOptions tag attributes buttonColor buttonType maybeMsg child =
109 let
110 defaultClasses =
111 [ "antialiased"
112 , "border-2"
113 , "cursor-pointer"
114 , "font-semibold"
115 , "inline-block"
116 , "leading-relaxed"
117 , "no-underline"
118 , "py-2"
119 , "px-4"
120 , "rounded"
121 , "text-center"
122 , "text-sm"
123
124 --
125 , "fixate:bg-white"
126 , "fixate:border-black"
127 , "fixate:text-black"
128 ]
129
130 specificClasses =
131 case buttonType of
132 Filled ->
133 case buttonColor of
134 Accent ->
135 [ "bg-accent-btn"
136 , "border-transparent"
137 , "text-white-90"
138 ]
139
140 Blank ->
141 [ "bg-white"
142 , "border-transparent"
143 , "text-accent-light"
144
145 -- Dark mode
146 ------------
147 , "dark:bg-darkest-hour"
148 , "dark:text-accent-dark"
149 ]
150
151 Gray ->
152 [ "bg-base04"
153 , "border-transparent"
154 , "text-white"
155
156 -- Dark mode
157 ------------
158 , "dark:bg-base05"
159 ]
160
161 _ ->
162 case buttonColor of
163 Accent ->
164 [ "bg-transparent"
165 , "border-accent-btn"
166 , "text-accent-btn"
167 ]
168
169 Blank ->
170 [ "bg-transparent"
171 , "border-white"
172 , "text-white"
173 ]
174
175 Gray ->
176 [ "bg-transparent"
177 , "border-base04"
178 , "text-base04"
179
180 -- Dark mode
181 ------------
182 , "dark:border-base05"
183 , "dark:text-base05"
184 ]
185 in
186 slab
187 tag
188 (case maybeMsg of
189 Just msg ->
190 attributes ++ [ onClick msg ]
191
192 Nothing ->
193 attributes
194 )
195 (List.append
196 defaultClasses
197 specificClasses
198 )
199 [ case buttonType of
200 IconOnly ->
201 inline
202 [ "align-middle"
203 , "inline-block"
204 , "leading-none"
205 , "pointer-events-none"
206 , "text-0"
207 ]
208 [ child ]
209
210 _ ->
211 inline
212 [ "align-middle"
213 , "inline-block"
214 , "leading-none"
215 , "pointer-events-none"
216 ]
217 [ child ]
218 ]
219
220
221
222-- 🍱 ░░ OTHER
223
224
225askForInput : { question : String, info : List (Html msg) } -> Html msg
226askForInput { question, info } =
227 Html.span
228 []
229 [ chunk
230 [ "font-semibold", "pt-1" ]
231 [ Html.text question ]
232 , case info of
233 [] ->
234 Html.text ""
235
236 _ ->
237 chunk
238 [ "italic", "mt-2", "text-sm" ]
239 info
240 ]
241
242
243canister : List (Html msg) -> Html msg
244canister children =
245 chunk
246 [ "mx-1", "px-4", "pb-4" ]
247 children
248
249
250canisterForm : List (Html msg) -> Html msg
251canisterForm children =
252 chunk
253 [ "mx-1", "px-4", "pb-4", "w-full" ]
254 children
255
256
257centeredContent : List (Html msg) -> Html msg
258centeredContent children =
259 chunk
260 [ "flex"
261 , "flex-grow"
262 , "items-stretch"
263 , "overflow-hidden"
264 , "relative"
265 ]
266 [ Html.map never logoBackdrop
267 , chunk
268 [ "flex"
269 , "flex-col"
270 , "flex-grow"
271 , "items-center"
272 , "justify-center"
273 , "max-w-full"
274 , "relative"
275 , "z-10"
276 ]
277 children
278 ]
279
280
281checkbox : { checked : Bool, toggleMsg : msg } -> Html msg
282checkbox opts =
283 brick
284 [ onClick opts.toggleMsg
285 , style "left" "-3px"
286 ]
287 [ "inline-block", "cursor-pointer", "relative" ]
288 [ if opts.checked then
289 Icons.check_box 22 Inherit
290
291 else
292 Icons.check_box_outline_blank 22 Inherit
293 ]
294
295
296focusScreen : { icon : Icon msg, iconHref : Maybe String, text : List (Html msg), textHref : Maybe String } -> List (Html msg) -> Html msg
297focusScreen { icon, iconHref, text, textHref } nodes =
298 [ slab
299 (case iconHref of
300 Just _ ->
301 Html.a
302
303 Nothing ->
304 Html.div
305 )
306 (case iconHref of
307 Just h ->
308 [ href h ]
309
310 Nothing ->
311 []
312 )
313 [ "block"
314 , "opacity-30"
315 , "text-inherit"
316 ]
317 [ icon 64 Inherit ]
318 , slab
319 (case iconHref of
320 Just _ ->
321 Html.a
322
323 Nothing ->
324 Html.div
325 )
326 (case textHref of
327 Just h ->
328 [ href h ]
329
330 Nothing ->
331 []
332 )
333 [ "block"
334 , "leading-normal"
335 , "mt-2"
336 , "opacity-40"
337 , "text-center"
338 , "text-inherit"
339 ]
340 text
341 , chunk
342 [ "max-w-full"
343 , "mt-4"
344 ]
345 nodes
346 ]
347 |> chunk
348 [ "flex"
349 , "flex-col"
350 , "items-center"
351 , "max-h-full"
352 , "overflow-y-auto"
353 , "px-4"
354 , "py-8"
355 , "w-full"
356 ]
357 |> List.singleton
358 |> centeredContent
359
360
361h1 : String -> Html msg
362h1 text =
363 slab
364 Html.h1
365 [ style "font-size" "13.5px" ]
366 [ "all-small-caps"
367 , "antialiased"
368 , "bg-base06"
369 , "inline-block"
370 , "font-semibold"
371 , "leading-tight"
372 , "m-0"
373 , "-top-px"
374 , "overflow-hidden"
375 , "pointer-events-none"
376 , "px-2"
377 , "py-1"
378 , "relative"
379 , "rounded-b"
380 , "uppercase"
381 , "text-sm"
382 , "text-white"
383
384 -- Dark mode
385 ------------
386 , "dark:bg-base01"
387 , "dark:text-base05"
388 ]
389 [ Html.text text ]
390
391
392h2 : String -> Html msg
393h2 text =
394 slab
395 Html.h2
396 []
397 [ "font-bold"
398 , "font-display"
399 , "leading-tight"
400 , "mb-8"
401 , "mt-4"
402 , "mx-auto"
403 , "text-2xl"
404 , "text-center"
405 ]
406 [ Html.text text ]
407
408
409h3 : String -> Html msg
410h3 text =
411 slab
412 Html.h2
413 []
414 [ "antialiased"
415 , "font-bold"
416 , "font-display"
417 , "leading-tight"
418 , "mb-8"
419 , "mt-4"
420 , "text-xl"
421 ]
422 [ Html.text text ]
423
424
425inlineIcon : (Int -> Coloring -> Svg.Svg msg) -> Html msg
426inlineIcon icon =
427 inline
428 [ "align-sub"
429 , "inline-block"
430 , "leading-0"
431 , "mr-1"
432 , "text-0"
433 ]
434 [ icon 14 Inherit ]
435
436
437intro : Html msg -> Html msg
438intro child =
439 slab
440 Html.p
441 [ style "line-height" "1.75" ]
442 [ "mb-6"
443 , "mt-3"
444 , "text-base05"
445 , "text-sm"
446
447 -- Dark mode
448 ------------
449 , "dark:text-base03"
450 ]
451 [ child ]
452
453
454label : List (Html.Attribute msg) -> String -> Html msg
455label attributes t =
456 slab
457 Html.label
458 (style "font-size" "11.25px" :: attributes)
459 [ "antialiased"
460 , "block"
461 , "font-bold"
462 , "leading-normal"
463 , "opacity-90"
464 , "uppercase"
465 ]
466 [ Html.text t ]
467
468
469link : { label : String, url : String } -> Html msg
470link params =
471 slab
472 Html.a
473 [ A.href params.url
474 , A.target "_blank"
475 ]
476 [ "border-b-2"
477 , "border-base04"
478 , "inline-block"
479 , "leading-none"
480 , "no-underline"
481 , "text-inherit"
482 ]
483 [ Html.text params.label ]
484
485
486logoBackdrop : Html Never
487logoBackdrop =
488 chunk
489 [ "logo-backdrop"
490
491 --
492 , "absolute"
493 , "bg-cover"
494 , "bg-no-repeat"
495 , "h-0"
496 , "left-full"
497 , "opacity-025"
498 , "pt-full"
499 , "top-0"
500 , "z-0"
501
502 -- Dark mode
503 ------------
504 , "dark:opacity-40"
505 ]
506 []
507
508
509receptacle : { scrolling : Bool } -> List (Html msg) -> Html msg
510receptacle { scrolling } =
511 chunk
512 [ "absolute"
513 , "bg-white"
514 , "flex"
515 , "flex-col"
516 , "inset-0"
517 , "overflow-x-hidden"
518 , "scrolling-touch"
519 , "z-50"
520
521 -- Dark mode
522 ------------
523 , "dark:bg-darkest-hour"
524
525 --
526 , ifThenElse scrolling "overflow-y-auto" "overflow-y-hidden"
527 ]
528
529
530select : (String -> msg) -> List (Html msg) -> Html msg
531select inputHandler options =
532 chunk
533 [ "max-w-md"
534 , "mx-auto"
535 , "relative"
536 , "text-base05"
537 , "w-full"
538
539 --
540 , "focus-within:text-black"
541
542 -- Dark mode
543 ------------
544 , "dark:text-gray-600"
545 , "dark:focus-within:text-base07"
546 ]
547 [ slab
548 Html.select
549 [ onInput inputHandler ]
550 [ "appearance-none"
551 , "border-b"
552 , "border-l-0"
553 , "border-r-0"
554 , "border-t-0"
555 , "border-gray-400"
556 , "bg-transparent"
557 , "block"
558 , "leading-normal"
559 , "m-0"
560 , "outline-none"
561 , "py-2"
562 , "px-0"
563 , "rounded-none"
564 , "text-base01"
565 , "text-lg"
566 , "w-full"
567
568 --
569 , "focus:border-black"
570
571 -- Dark mode
572 ------------
573 , "dark:border-base02"
574 , "dark:text-gray-600"
575
576 --
577 , "dark:focus:border-base07"
578 ]
579 options
580 , chunk
581 [ "absolute"
582 , "-translate-y-1/2"
583 , "mt-px"
584 , "right-0"
585 , "text-0"
586 , "top-1/2"
587 , "transform"
588 ]
589 [ Icons.keyboard_arrow_down 20 Inherit ]
590 ]
591
592
593textArea : List (Html.Attribute msg) -> Html msg
594textArea attributes =
595 slab
596 Html.textarea
597 attributes
598 [ "bg-white"
599 , "block"
600 , "leading-normal"
601 , "mb-4"
602 , "p-4"
603 , "resize-none"
604 , "rounded"
605 , "text-base01"
606 , "text-sm"
607 , "w-full"
608
609 --
610 , "placeholder:text-base01"
611 , "placeholder:text-opacity-40"
612
613 -- Dark mode
614 ------------
615 , "dark:bg-darkest-hour"
616 , "dark:text-gray-600"
617
618 --
619 , "dark:placeholder:text-gray-600"
620 , "dark:placeholder:text-opacity-30"
621 ]
622 []
623
624
625textButton : { label : String, onClick : msg } -> Html msg
626textButton params =
627 slab
628 Html.button
629 [ onClick params.onClick ]
630 [ "appearance-none"
631 , "bg-transparent"
632 , "border-base04"
633 , "border-b-2"
634 , "text-inherit"
635 , "leading-tight"
636 , "m-0"
637 , "p-0"
638 , "cursor-pointer"
639 ]
640 [ Html.text params.label ]
641
642
643textField : List (Html.Attribute msg) -> Html msg
644textField attributes =
645 slab
646 Html.input
647 attributes
648 [ "appearance-none"
649 , "border-b"
650 , "border-l-0"
651 , "border-r-0"
652 , "border-t-0"
653 , "border-gray-400"
654 , "bg-transparent"
655 , "block"
656 , "leading-normal"
657 , "mt-1"
658 , "py-2"
659 , "rounded-none"
660 , "text-base01"
661 , "text-sm"
662 , "w-full"
663
664 --
665 , "focus:border-black"
666 , "focus:outline-none"
667 , "placeholder:text-base01"
668 , "placeholder:text-opacity-40"
669
670 -- Dark mode
671 ------------
672 , "dark:border-base02"
673 , "dark:text-gray-600"
674
675 --
676 , "dark:focus:border-base07"
677 , "dark:placeholder:text-gray-600"
678 , "dark:placeholder:text-opacity-30"
679 ]
680 []
681
682
683textFieldAlt : List (Html.Attribute msg) -> Html msg
684textFieldAlt attributes =
685 slab
686 Html.input
687 attributes
688 [ "bg-white"
689 , "block"
690 , "leading-normal"
691 , "mb-3"
692 , "p-3"
693 , "resize-none"
694 , "rounded"
695 , "text-base01"
696 , "text-sm"
697 , "w-full"
698
699 -- Dark mode
700 ------------
701 , "dark:bg-darkest-hour"
702 , "dark:text-gray-600"
703 ]
704 []