fluxbit_view_components 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +20 -0
  3. data/README.md +86 -0
  4. data/app/components/fluxbit/alert_component.rb +126 -0
  5. data/app/components/fluxbit/avatar_component.rb +113 -0
  6. data/app/components/fluxbit/avatar_group_component.rb +23 -0
  7. data/app/components/fluxbit/badge_component.rb +79 -0
  8. data/app/components/fluxbit/button_component.rb +97 -0
  9. data/app/components/fluxbit/button_group_component.rb +43 -0
  10. data/app/components/fluxbit/card_component.rb +135 -0
  11. data/app/components/fluxbit/component.rb +86 -0
  12. data/app/components/fluxbit/flex_component.rb +93 -0
  13. data/app/components/fluxbit/form/checkbox_input_component.rb +61 -0
  14. data/app/components/fluxbit/form/component.rb +71 -0
  15. data/app/components/fluxbit/form/datepicker_component.rb +7 -0
  16. data/app/components/fluxbit/form/form_builder_component.rb +117 -0
  17. data/app/components/fluxbit/form/helper_text_component.rb +29 -0
  18. data/app/components/fluxbit/form/label_component.rb +65 -0
  19. data/app/components/fluxbit/form/radio_input_component.rb +21 -0
  20. data/app/components/fluxbit/form/range_input_component.rb +51 -0
  21. data/app/components/fluxbit/form/select_free_input_component.rb +77 -0
  22. data/app/components/fluxbit/form/select_input_component.rb +21 -0
  23. data/app/components/fluxbit/form/spacer_input_component.rb +12 -0
  24. data/app/components/fluxbit/form/text_input_component.rb +225 -0
  25. data/app/components/fluxbit/form/textarea_input_component.rb +57 -0
  26. data/app/components/fluxbit/form/toggle_input_component.rb +166 -0
  27. data/app/components/fluxbit/form/upload_image_input_component.html.erb +48 -0
  28. data/app/components/fluxbit/form/upload_image_input_component.rb +66 -0
  29. data/app/components/fluxbit/form/upload_input_component.html.erb +12 -0
  30. data/app/components/fluxbit/form/upload_input_component.rb +47 -0
  31. data/app/components/fluxbit/gravatar_component.rb +99 -0
  32. data/app/components/fluxbit/heading_component.rb +47 -0
  33. data/app/components/fluxbit/modal_component.rb +141 -0
  34. data/app/components/fluxbit/popover_component.rb +71 -0
  35. data/app/components/fluxbit/tab_component.rb +142 -0
  36. data/app/components/fluxbit/text_component.rb +36 -0
  37. data/app/components/fluxbit/tooltip_component.rb +38 -0
  38. data/app/helpers/fluxbit/classes_helper.rb +21 -0
  39. data/app/helpers/fluxbit/components_helper.rb +75 -0
  40. data/config/deploy.yml +37 -0
  41. data/config/locales/en.yml +6 -0
  42. data/lib/fluxbit/config/alert_component.rb +59 -0
  43. data/lib/fluxbit/config/avatar_component.rb +79 -0
  44. data/lib/fluxbit/config/badge_component.rb +77 -0
  45. data/lib/fluxbit/config/button_component.rb +86 -0
  46. data/lib/fluxbit/config/card_component.rb +32 -0
  47. data/lib/fluxbit/config/flex_component.rb +63 -0
  48. data/lib/fluxbit/config/form/helper_text_component.rb +20 -0
  49. data/lib/fluxbit/config/gravatar_component.rb +19 -0
  50. data/lib/fluxbit/config/heading_component.rb +39 -0
  51. data/lib/fluxbit/config/modal_component.rb +71 -0
  52. data/lib/fluxbit/config/paragraph_component.rb +11 -0
  53. data/lib/fluxbit/config/popover_component.rb +33 -0
  54. data/lib/fluxbit/config/tab_component.rb +131 -0
  55. data/lib/fluxbit/config/text_component.rb +110 -0
  56. data/lib/fluxbit/config/tooltip_component.rb +11 -0
  57. data/lib/fluxbit/view_components/codemods/v3_slot_setters.rb +222 -0
  58. data/lib/fluxbit/view_components/engine.rb +36 -0
  59. data/lib/fluxbit/view_components/version.rb +7 -0
  60. data/lib/fluxbit/view_components.rb +30 -0
  61. data/lib/fluxbit_view_components.rb +3 -0
  62. data/lib/install/install.rb +64 -0
  63. data/lib/tasks/fluxbit_view_components_tasks.rake +22 -0
  64. metadata +238 -0
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ # The `Fluxbit::TooltipComponent` is a component for rendering customizable tooltips.
4
+ # It extends `Fluxbit::Component` and provides options for configuring the tooltip's
5
+ # appearance and behavior. You can control the arrow visibility, and other attributes.
6
+ # The tooltip can display additional information when the user hovers over or focuses
7
+ # on an element.
8
+ class Fluxbit::TooltipComponent < Fluxbit::Component
9
+ include Fluxbit::Config::TooltipComponent
10
+
11
+ # Initializes the tooltip component with the given properties.
12
+ #
13
+ # @param [Hash] props The properties to customize the tooltip.
14
+ # @option props [Boolean] :has_arrow (true) Determines if an arrow should be displayed on the tooltip.
15
+ # @option props [Hash] **props Remaining options declared as HTML attributes, applied to the tooltip container.
16
+ def initialize(**props)
17
+ super
18
+ @props = props
19
+ @has_arrow = options @props.delete(:has_arrow), default: true
20
+ @props["role"] = "tooltip"
21
+
22
+ add(class: styles[:base], to: @props)
23
+ @props[:class] = remove_class(@props.delete(:remove_class) || "", @props[:class])
24
+ end
25
+
26
+ def call
27
+ content_tag(:div, @props) do
28
+ concat content
29
+ concat arrow
30
+ end
31
+ end
32
+
33
+ def arrow
34
+ return "" unless @has_arrow
35
+
36
+ content_tag :div, "", "data-popper-arrow" => true, class: "tooltip-arrow"
37
+ end
38
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Fluxbit
4
+ module ClassesHelper
5
+ def fx_body_class
6
+ "h-full bg-slate-100 dark:bg-slate-900 dark:text-white"
7
+ end
8
+
9
+ def fx_darkmode_js
10
+ <<-SCRIPT.squish
11
+ <script>
12
+ if (localStorage.getItem('color-theme') === 'dark' || (!('color-theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
13
+ document.documentElement.classList.add('dark');
14
+ } else {
15
+ document.documentElement.classList.remove('dark')
16
+ }
17
+ </script>
18
+ SCRIPT
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Fluxbit
4
+ module ComponentsHelper
5
+ # Components
6
+ def fx_avatar(...) = fluxbit_method("Avatar", ...)
7
+ def fx_avatar_group(...) = fluxbit_method("AvatarGroup", ...)
8
+ def fx_gravatar(...) = fluxbit_method("Gravatar", ...)
9
+ def fx_alert(...) = fluxbit_method("Alert", ...)
10
+ def fx_button(...) = fluxbit_method("Button", ...)
11
+ def fx_button_group(...) = fluxbit_method("ButtonGroup", ...)
12
+ def fx_badge(...) = fluxbit_method("Badge", ...)
13
+ def fx_card(...) = fluxbit_method("Card", ...)
14
+ def fx_modal(...) = fluxbit_method("Modal", ...)
15
+ def fx_popover(...) = fluxbit_method("Popover", ...)
16
+ def fx_tooltip(...) = fluxbit_method("Tooltip", ...)
17
+ def fx_flex(...) = fluxbit_method("Flex", ...)
18
+ def fx_tab(...) = fluxbit_method("Tab", ...)
19
+
20
+ # Forms
21
+ def fx_helper_text(...) = fluxbit_method("Form::HelperText", ...)
22
+ def fx_checkbox_input(...) = fluxbit_method("Form::CheckboxInput", ...)
23
+ def fx_form_builder(...) = fluxbit_method("Form::FormBuilder", ...)
24
+ def fx_label(...) = fluxbit_method("Form::Label", ...)
25
+ def fx_range_input(...) = fluxbit_method("Form::RangeInput", ...)
26
+ def fx_select_input(...) = fluxbit_method("Form::SelectInput", ...)
27
+ def fx_select_free_input(...) = fluxbit_method("Form::SelectFreeInput", ...)
28
+ def fx_text_input(...) = fluxbit_method("Form::TextInput", ...)
29
+ def fx_textarea_input(...) = fluxbit_method("Form::TextareaInput", ...)
30
+ def fx_toggle_input(...) = fluxbit_method("Form::ToggleInput", ...)
31
+ def form_builder(...) = fluxbit_method("Form::FormBuilder", ...)
32
+
33
+ # Typography
34
+ def fx_heading(...) = fluxbit_method("Heading", ...)
35
+ def fx_txt(...) = fluxbit_method("Text", ...)
36
+
37
+ def fluxbit_method(method_name, *args, **kwargs, &c)
38
+ component_klass = "Fluxbit::#{method_name}Component".constantize
39
+ if kwargs[:with_content]
40
+ content = kwargs.delete(:with_content)
41
+ render(component_klass.new(*args, **kwargs).with_content(content), &c)
42
+ else
43
+ render(component_klass.new(*args, **kwargs), &c)
44
+ end
45
+ end
46
+
47
+ # # Succint method for render component
48
+ # # from: https://dev.to/abeidahmed/advanced-viewcomponent-patterns-in-rails-2b4m
49
+ # #
50
+ # # Instead of using 'render XComponent'
51
+ # # One can use 'render_component "X", **@options'
52
+ # def render_component(component_path, collection: nil, with_content: nil, **options, &block)
53
+ # component_klass = "#{component_path.classify}Component".constantize
54
+
55
+ # return render component_klass.new(**options).with_content(with_content) if with_content
56
+
57
+ # if collection
58
+ # render component_klass.with_collection(collection, **options), &block
59
+ # else
60
+ # render component_klass.new(**options), &block
61
+ # end
62
+ # end
63
+
64
+ # def method_missing(name, *args, &block)
65
+ # if name == :alert
66
+ # render component_klass.new(**options), &block
67
+ # # do something if the method name is "custom_helper_method"
68
+ # #content_tag(:div, *args, &block)
69
+ # else
70
+ # # call the original method_missing method if the method name is not recognized
71
+ # super
72
+ # end
73
+ # end
74
+ end
75
+ end
data/config/deploy.yml ADDED
@@ -0,0 +1,37 @@
1
+ service: fluxbit_view_components
2
+ image: kirillplatonov/fluxbit_view_components
3
+
4
+ registry:
5
+ username: kirillplatonov
6
+ password:
7
+ - KAMAL_REGISTRY_PASSWORD
8
+
9
+ env:
10
+ secret:
11
+ - RAILS_MASTER_KEY
12
+
13
+ servers:
14
+ web:
15
+ hosts:
16
+ - 195.201.128.126
17
+ labels:
18
+ traefik.http.routers.fluxbit_view_components.entrypoints: websecure
19
+ traefik.http.routers.fluxbit_view_components.rule: "Host(`fluxbitviewcomponents.org`) || Host(`www.fluxbitviewcomponents.org`)"
20
+ traefik.http.routers.fluxbit_view_components.tls.certresolver: letsencrypt
21
+
22
+ traefik:
23
+ options:
24
+ publish:
25
+ - "443:443"
26
+ volume:
27
+ - "/letsencrypt/acme.json:/letsencrypt/acme.json"
28
+ args:
29
+ entryPoints.web.address: ":80"
30
+ entryPoints.websecure.address: ":443"
31
+ entryPoints.web.http.redirections.entryPoint.to: websecure # We want to force https
32
+ entryPoints.web.http.redirections.entryPoint.scheme: https
33
+ entryPoints.web.http.redirections.entrypoint.permanent: true
34
+ certificatesResolvers.letsencrypt.acme.email: "admin@fluxbitviewcomponents.org"
35
+ certificatesResolvers.letsencrypt.acme.storage: "/letsencrypt/acme.json" # Must match the path in `volume`
36
+ certificatesResolvers.letsencrypt.acme.httpchallenge: true
37
+ certificatesResolvers.letsencrypt.acme.httpchallenge.entrypoint: web
@@ -0,0 +1,6 @@
1
+ en:
2
+ fluxbit:
3
+ form_builder:
4
+ errors_summary:
5
+ one: "There is 1 error with this %{model}:"
6
+ other: "There are %{count} errors with this %{model}:"
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Fluxbit::Config::AlertComponent
4
+ mattr_accessor :color, default: :info
5
+ mattr_accessor :icon, default: :default
6
+ mattr_accessor :can_close, default: true
7
+ mattr_accessor :out_animation, default: :fade_out
8
+ mattr_accessor :fade_in_animation, default: true
9
+ mattr_accessor :dismiss_timeout, default: 3000
10
+ mattr_accessor :all_rounded, default: true
11
+
12
+ # rubocop: disable Layout/LineLength, Metrics/BlockLength
13
+ mattr_accessor :styles do
14
+ {
15
+ base: "flex p-4 mb-4 dark:bg-gray-800 ",
16
+ all_rounded: {
17
+ on: "rounded-lg border-2",
18
+ off: "rounded-l-lg border-l-2 border-y-2"
19
+ },
20
+ colors: {
21
+ info: "text-blue-800 border-blue-300 bg-blue-50 dark:text-blue-400 dark:border-blue-800",
22
+ danger: "text-red-800 border-red-300 bg-red-50 dark:text-red-400 dark:border-red-800",
23
+ success: "text-green-800 border-green-300 bg-green-50 dark:text-green-400 dark:border-green-800",
24
+ warning: "text-yellow-800 border-yellow-300 bg-yellow-50 dark:text-yellow-300 dark:border-yellow-800",
25
+ dark: "border-gray-300 bg-gray-50 dark:border-gray-600"
26
+ },
27
+ close_button: {
28
+ base: "ml-auto -mx-1.5 -my-1.5 rounded-lg focus:ring-2 p-1.5 inline-flex justify-center h-8 w-8 dark:bg-gray-800",
29
+ colors: {
30
+ info: "bg-blue-50 text-blue-500 focus:ring-blue-400 hover:bg-blue-200 dark:text-blue-400 dark:hover:bg-gray-700",
31
+ danger: "bg-red-50 text-red-500 focus:ring-red-400 hover:bg-red-200 dark:text-red-400 dark:hover:bg-gray-700",
32
+ success: "bg-green-50 text-green-500 focus:ring-green-400 hover:bg-green-200 dark:text-green-400 dark:hover:bg-gray-700",
33
+ warning: "bg-yellow-50 text-yellow-500 focus:ring-yellow-400 hover:bg-yellow-200 dark:text-yellow-300 dark:hover:bg-gray-700",
34
+ dark: "bg-gray-50 text-gray-500 focus:ring-gray-400 hover:bg-gray-200 dark:text-gray-300 dark:hover:bg-gray-700 dark:hover:text-white"
35
+ }
36
+ },
37
+ default_icons: {
38
+ info: "information-circle",
39
+ danger: "exclamation-triangle",
40
+ success: "check-circle",
41
+ warning: "exclamation-circle",
42
+ dark: "information-circle"
43
+ },
44
+ animations: {
45
+ just_remove: { from: "", to: "" },
46
+ dont_remove: "",
47
+ fade_out: { from: "opacity-100", to: "opacity-0" },
48
+ fade_out_to_right: { from: "opacity-100 translate-x-0", to: "opacity-0 translate-x-6" },
49
+ fade_out_to_left: { from: "opacity-100 translate-x-0", to: "opacity-0 -translate-x-6" },
50
+ fade_out_to_top: { from: "opacity-100 translate-x-0", to: "opacity-0 -translate-y-6" },
51
+ fade_out_to_bottom: { from: "opacity-100 translate-x-0", to: "opacity-0 translate-y-6" },
52
+ fade_out_and_shrink: { from: "opacity-100 scale-100", to: "opacity-0 scale-50" },
53
+ fade_out_and_stretch: { from: "opacity-100 scale-100", to: "opacity-0 scale-150" },
54
+ fade_out_and_rotate: { from: "opacity-100 rotate-0", to: "opacity-0 rotate-45" }
55
+ }
56
+ }
57
+ end
58
+ # rubocop: enable Layout/LineLength, Metrics/BlockLength
59
+ end
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Fluxbit::Config::AvatarComponent
4
+ mattr_accessor :color, default: nil
5
+ mattr_accessor :placeholder_initials, default: false
6
+ mattr_accessor :status, default: false # online, busy, offline, away
7
+ mattr_accessor :status_position, default: :top_right
8
+ mattr_accessor :rounded, default: true
9
+ mattr_accessor :size, default: :md
10
+
11
+ # rubocop: disable Layout/LineLength, Metrics/BlockLength
12
+ mattr_accessor :styles do
13
+ {
14
+ bordered: "p-1 ring-2",
15
+ rounded: {
16
+ base: "rounded-full",
17
+ status_position: {
18
+ top: "top-0",
19
+ bottom: "bottom-0",
20
+ left: { xs: "-left-1", sm: "left-0", md: "left-1", lg: "left-1", xl: "left-6" },
21
+ right: { xs: "left-4", sm: "left-5", md: "left-7", lg: "left-12", xl: "left-24" }
22
+ }
23
+ },
24
+ not_rounded: {
25
+ base: "rounded-sm",
26
+ status_position: {
27
+ top: "-top-1",
28
+ bottom: "-bottom-1",
29
+ left: { xs: "-left-1", sm: "-left-1", md: "-left-1", lg: "-left-1", xl: "-left-1" },
30
+ right: { xs: "left-4", sm: "left-5", md: "left-7", lg: "left-18", xl: "left-32" }
31
+ }
32
+ },
33
+ color: {
34
+ dark: "ring-gray-800 dark:ring-gray-800",
35
+ failure: "ring-red-500 dark:ring-red-700",
36
+ gray: "ring-gray-500 dark:ring-gray-400",
37
+ info: "ring-cyan-400 dark:ring-cyan-800",
38
+ light: "ring-gray-300 dark:ring-gray-500",
39
+ purple: "ring-purple-500 dark:ring-purple-600",
40
+ success: "ring-green-500 dark:ring-green-500",
41
+ warning: "ring-yellow-300 dark:ring-yellow-500",
42
+ pink: "ring-pink-500 dark:ring-pink-500"
43
+ },
44
+ size: {
45
+ xs: "w-6 h-6",
46
+ sm: "w-8 h-8",
47
+ md: "w-10 h-10",
48
+ lg: "w-20 h-20",
49
+ xl: "w-36 h-36"
50
+ },
51
+ placeholder_icon: {
52
+ base: "relative overflow-hidden bg-gray-200 dark:bg-gray-600",
53
+ size: {
54
+ xs: "w-8 h-8",
55
+ sm: "w-10 h-10",
56
+ md: "w-12 h-12",
57
+ lg: "w-22 h-22",
58
+ xl: "w-38 h-38"
59
+ }
60
+ },
61
+ stacked: "ring-2 ring-gray-300 dark:ring-gray-500",
62
+ status: {
63
+ base: "absolute h-3.5 w-3.5 rounded-full border-2 border-white dark:border-gray-800",
64
+ options: {
65
+ away: "bg-yellow-400",
66
+ busy: "bg-red-400",
67
+ offline: "bg-gray-400",
68
+ online: "bg-green-400"
69
+ }
70
+ },
71
+ initials: {
72
+ text: "font-medium text-gray-600 dark:text-gray-300",
73
+ base: "inline-flex overflow-hidden relative justify-center items-center bg-gray-200 dark:bg-gray-600"
74
+ },
75
+ group: "flex -space-x-4 rtl:space-x-reverse"
76
+ }
77
+ end
78
+ # rubocop: enable Layout/LineLength, Metrics/BlockLength
79
+ end
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Fluxbit::Config::BadgeComponent
4
+ mattr_accessor :color, default: :info
5
+ mattr_accessor :border, default: false
6
+ mattr_accessor :pill, default: false
7
+ mattr_accessor :size, default: 0
8
+ mattr_accessor :as, default: :div
9
+ mattr_accessor :perfect_rounded, default: 0
10
+ mattr_accessor :notification, default: ""
11
+
12
+ # rubocop: disable Layout/LineLength, Metrics/BlockLength
13
+ mattr_accessor :styles do
14
+ {
15
+ base: "inline-flex items-center gap-1 font-medium me-2 rounded-sm",
16
+ pill: "rounded-full",
17
+ colors: {
18
+ info: "bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-300",
19
+ dark: "bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-300",
20
+ failure: "bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-300",
21
+ success: "bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-300",
22
+ warning: "bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-300",
23
+ indigo: "bg-indigo-100 text-indigo-800 dark:bg-indigo-900 dark:text-indigo-300",
24
+ purple: "bg-purple-100 text-purple-800 dark:bg-purple-900 dark:text-purple-300",
25
+ pink: "bg-pink-100 text-pink-800 dark:bg-pink-900 dark:text-pink-300",
26
+ cyan: "bg-cyan-100 text-cyan-800 dark:bg-cyan-900 dark:text-cyan-200",
27
+ lime: "bg-lime-100 text-lime-800 dark:bg-lime-900 dark:text-lime-400",
28
+ teal: "bg-teal-100 text-teal-800 dark:bg-teal-900 dark:text-teal-400",
29
+ solid_info: "text-white bg-blue-500 border-1 border-white dark:border-gray-900",
30
+ solid_dark: "text-white bg-gray-500 border-1 border-white dark:border-gray-900",
31
+ solid_failure: "text-white bg-red-500 border-1 border-white dark:border-gray-900",
32
+ solid_success: "text-white bg-green-500 border-1 border-white dark:border-gray-900",
33
+ solid_warning: "text-white bg-yellow-500 border-1 border-white dark:border-gray-900",
34
+ solid_indigo: "text-white bg-indigo-500 border-1 border-white dark:border-gray-900",
35
+ solid_purple: "text-white bg-purple-500 border-1 border-white dark:border-gray-900",
36
+ solid_pink: "text-white bg-pink-500 border-1 border-white dark:border-gray-900",
37
+ solid_cyan: "text-white bg-cyan-500 border-1 border-white dark:border-gray-900",
38
+ solid_lime: "text-white bg-lime-500 border-1 border-white dark:border-gray-900",
39
+ solid_teal: "text-white bg-teal-500 border-1 border-white dark:border-gray-900",
40
+
41
+ info_bordered: "bg-blue-100 text-blue-800 dark:bg-gray-700 dark:text-blue-400 border border-blue-400",
42
+ dark_bordered: "bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-400 border border-gray-500",
43
+ failure_bordered: "bg-red-100 text-red-800 dark:bg-gray-700 dark:text-red-400 border border-red-400",
44
+ success_bordered: "bg-green-100 text-green-800 dark:bg-gray-700 dark:text-green-400 border border-green-400",
45
+ warning_bordered: "bg-yellow-100 text-yellow-800 dark:bg-gray-700 dark:text-yellow-300 border border-yellow-300",
46
+ indigo_bordered: "bg-indigo-100 text-indigo-800 dark:bg-gray-700 dark:text-indigo-400 border border-indigo-400",
47
+ purple_bordered: "bg-purple-100 text-purple-800 dark:bg-gray-700 dark:text-purple-400 border border-purple-400",
48
+ pink_bordered: "bg-pink-100 text-pink-800 dark:bg-gray-700 dark:text-pink-400 border border-pink-400",
49
+ cyan_bordered: "bg-cyan-100 text-cyan-800 dark:bg-cyan-900 dark:text-cyan-200 border border-cyan-400",
50
+ lime_bordered: "bg-lime-100 text-lime-800 dark:bg-lime-900 dark:text-lime-400 border border-lime-400",
51
+ teal_bordered: "bg-teal-100 text-teal-800 dark:bg-teal-900 dark:text-teal-400 border border-teal-400"
52
+ },
53
+ sizes: [
54
+ "p-1 text-xs", "p-1.5 text-sm"
55
+ ],
56
+ perfect_rounded: [
57
+ "h-fit px-2.5 py-0.5",
58
+ "justify-center w-4 h-4",
59
+ "justify-center w-6 h-6",
60
+ "justify-center w-8 h-8",
61
+ "justify-center w-10 h-10",
62
+ "justify-center w-12 h-12"
63
+ ],
64
+ notification: {
65
+ default: "absolute",
66
+ positions: {
67
+ top: "-top-1",
68
+ bottom: "top-5",
69
+ left: "end-4",
70
+ right: "-end-4"
71
+ }
72
+ },
73
+ dismissable: "ml-2 cursor-pointer"
74
+ }
75
+ end
76
+ # rubocop: enable Layout/LineLength, Metrics/BlockLength
77
+ end
@@ -0,0 +1,86 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Fluxbit::Config::ButtonComponent
4
+ mattr_accessor :color, default: :default
5
+ mattr_accessor :pill, default: false
6
+ mattr_accessor :size, default: 1
7
+ mattr_accessor :as, default: :button
8
+
9
+ # TODO: Gradient and Gradient Duotone need their outline version.
10
+ # rubocop: disable Layout/LineLength, Metrics/BlockLength
11
+ mattr_accessor :styles do
12
+ {
13
+ base: "group flex items-center justify-center p-0.5 text-center font-medium relative focus:z-10 focus:outline-hidden",
14
+ full_sized: "w-full",
15
+ colors: {
16
+ transparent: "text-slate-500 hover:text-slate-900 hover:bg-slate-100 dark:text-slate-400 dark:hover:bg-slate-700 dark:hover:text-white",
17
+ default: "text-white bg-blue-700 border border-transparent enabled:hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800",
18
+ success: "text-white bg-green-700 border border-transparent enabled:hover:bg-green-800 focus:ring-4 focus:ring-green-300 dark:bg-green-600 dark:enabled:hover:bg-green-700 dark:focus:ring-green-800",
19
+ failure: "text-white bg-red-700 border border-transparent enabled:hover:bg-red-800 focus:ring-4 focus:ring-red-300 dark:bg-red-600 dark:enabled:hover:bg-red-700 dark:focus:ring-red-900",
20
+ info: "text-white bg-cyan-700 border border-transparent enabled:hover:bg-cyan-800 focus:ring-4 focus:ring-cyan-300 dark:bg-cyan-600 dark:enabled:hover:bg-cyan-700 dark:focus:ring-cyan-800",
21
+ warning: "text-white bg-yellow-400 border border-transparent enabled:hover:bg-yellow-500 focus:ring-4 focus:ring-yellow-300 dark:focus:ring-yellow-900",
22
+ dark: "text-white bg-gray-800 border border-transparent enabled:hover:bg-gray-900 focus:ring-4 focus:ring-gray-300 dark:bg-gray-800 dark:enabled:hover:bg-gray-700 dark:focus:ring-gray-800 dark:border-gray-700",
23
+ light: "text-gray-900 bg-white border border-gray-300 enabled:hover:bg-gray-100 focus:ring-4 focus:ring-cyan-300 dark:bg-gray-600 dark:text-white dark:border-gray-600 dark:enabled:hover:bg-gray-700 dark:enabled:hover:border-gray-700 dark:focus:ring-gray-700",
24
+ purple: "text-white bg-purple-700 border border-transparent enabled:hover:bg-purple-800 focus:ring-4 focus:ring-purple-300 dark:bg-purple-600 dark:enabled:hover:bg-purple-700 dark:focus:ring-purple-900",
25
+
26
+ default_outline: "text-blue-700 hover:text-white border border-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-hidden focus:ring-blue-300 dark:border-blue-500 dark:text-blue-500 dark:hover:text-white dark:hover:bg-blue-500 dark:focus:ring-blue-800",
27
+ success_outline: "text-green-700 hover:text-white border border-green-700 hover:bg-green-800 focus:ring-4 focus:outline-hidden focus:ring-green-300 dark:border-green-500 dark:text-green-500 dark:hover:text-white dark:hover:bg-green-600 dark:focus:ring-green-800",
28
+ failure_outline: "text-red-700 hover:text-white border border-red-700 hover:bg-red-800 focus:ring-4 focus:outline-hidden focus:ring-red-300 dark:border-red-500 dark:text-red-500 dark:hover:text-white dark:hover:bg-red-600 dark:focus:ring-red-900",
29
+ info_outline: "text-cyan-400 hover:text-white border border-cyan-400 hover:bg-cyan-500 focus:ring-4 focus:outline-hidden focus:ring-cyan-300 dark:border-cyan-300 dark:text-cyan-300 dark:hover:text-white dark:hover:bg-cyan-400 dark:focus:ring-cyan-900",
30
+ warning_outline: "text-yellow-400 hover:text-white border border-yellow-400 hover:bg-yellow-500 focus:ring-4 focus:outline-hidden focus:ring-yellow-300 dark:border-yellow-300 dark:text-yellow-300 dark:hover:text-white dark:hover:bg-yellow-400 dark:focus:ring-yellow-900",
31
+ dark_outline: "text-gray-900 hover:text-white border border-gray-800 hover:bg-gray-900 focus:ring-4 focus:outline-hidden focus:ring-gray-300 dark:border-gray-600 dark:text-gray-400 dark:hover:text-white dark:hover:bg-gray-600 dark:focus:ring-gray-800",
32
+ light_outline: "text-gray-900 hover:text-white border border-gray-300 hover:bg-gray-300 focus:ring-4 focus:outline-hidden focus:ring-gray-300 dark:border-gray-600 dark:text-gray-400 dark:hover:text-white dark:hover:bg-gray-600 dark:focus:ring-gray-800",
33
+ purple_outline: "text-purple-700 hover:text-white border border-purple-700 hover:bg-purple-800 focus:ring-4 focus:outline-hidden focus:ring-purple-300 dark:border-purple-400 dark:text-purple-400 dark:hover:text-white dark:hover:bg-purple-500 dark:focus:ring-purple-900",
34
+
35
+ info_gradient: "text-white bg-gradient-to-r from-cyan-500 via-cyan-600 to-cyan-700 enabled:hover:bg-gradient-to-br focus:ring-4 focus:ring-cyan-300 dark:focus:ring-cyan-800 ",
36
+ failure_gradient: "text-white bg-gradient-to-r from-red-400 via-red-500 to-red-600 enabled:hover:bg-gradient-to-br focus:ring-4 focus:ring-red-300 dark:focus:ring-red-800",
37
+ success_gradient: "text-white bg-gradient-to-r from-green-400 via-green-500 to-green-600 enabled:hover:bg-gradient-to-br focus:ring-4 focus:ring-green-300 dark:focus:ring-green-800",
38
+ cyan_gradient: "text-white bg-gradient-to-r from-cyan-400 via-cyan-500 to-cyan-600 enabled:hover:bg-gradient-to-br focus:ring-4 focus:ring-cyan-300 dark:focus:ring-cyan-800",
39
+ lime_gradient: "text-gray-900 bg-gradient-to-r from-lime-200 via-lime-400 to-lime-500 enabled:hover:bg-gradient-to-br focus:ring-4 focus:ring-lime-300 dark:focus:ring-lime-800",
40
+ pink_gradient: "text-white bg-gradient-to-r from-pink-400 via-pink-500 to-pink-600 enabled:hover:bg-gradient-to-br focus:ring-4 focus:ring-pink-300 dark:focus:ring-pink-800",
41
+ purple_gradient: "text-white bg-gradient-to-r from-purple-500 via-purple-600 to-purple-700 enabled:hover:bg-gradient-to-br focus:ring-4 focus:ring-purple-300 dark:focus:ring-purple-800",
42
+ teal_gradient: "text-white bg-gradient-to-r from-teal-400 via-teal-500 to-teal-600 enabled:hover:bg-gradient-to-br focus:ring-4 focus:ring-teal-300 dark:focus:ring-teal-800",
43
+
44
+ cyan_to_blue_gradient: "text-white bg-gradient-to-r from-cyan-500 to-cyan-500 enabled:hover:bg-gradient-to-bl focus:ring-4 focus:ring-cyan-300 dark:focus:ring-cyan-800",
45
+ green_to_blue_gradient: "text-white bg-gradient-to-br from-green-400 to-cyan-600 enabled:hover:bg-gradient-to-bl focus:ring-4 focus:ring-green-200 dark:focus:ring-green-800",
46
+ pink_to_orange_gradient: "text-white bg-gradient-to-br from-pink-500 to-orange-400 enabled:hover:bg-gradient-to-bl focus:ring-4 focus:ring-pink-200 dark:focus:ring-pink-800",
47
+ purple_to_blue_gradient: "text-white bg-gradient-to-br from-purple-600 to-cyan-500 enabled:hover:bg-gradient-to-bl focus:ring-4 focus:ring-cyan-300 dark:focus:ring-cyan-800",
48
+ purple_to_pink_gradient: "text-white bg-gradient-to-r from-purple-500 to-pink-500 enabled:hover:bg-gradient-to-l focus:ring-4 focus:ring-purple-200 dark:focus:ring-purple-800",
49
+ red_to_yellow_gradient: "text-gray-900 bg-gradient-to-r from-red-200 via-red-300 to-yellow-200 enabled:hover:bg-gradient-to-bl focus:ring-4 focus:ring-red-100 dark:focus:ring-red-400",
50
+ teal_to_lime_gradient: "text-gray-900 bg-gradient-to-r from-teal-200 to-lime-200 enabled:hover:bg-gradient-to-l enabled:hover:from-teal-200 enabled:hover:to-lime-200 enabled:hover:text-gray-900 focus:ring-4 focus:ring-lime-200 dark:focus:ring-teal-700"
51
+ },
52
+ disabled: "cursor-not-allowed opacity-50",
53
+ inner: {
54
+ base: "flex items-stretch items-center transition-all duration-200",
55
+ position: {
56
+ none: "",
57
+ start: "rounded-r-none",
58
+ middle: "rounded-none",
59
+ end: "rounded-l-none"
60
+ },
61
+ outline: "border border-transparent"
62
+ },
63
+ outline: {
64
+ off: "",
65
+ on: "justify-center transition-all duration-75 ease-in group-enabled:group-hover:bg-opacity-0 group-enabled:group-hover:text-inherit",
66
+ pill: {
67
+ off: "rounded-md",
68
+ on: "rounded-full"
69
+ }
70
+ },
71
+ pill: {
72
+ off: "rounded-lg",
73
+ on: "rounded-full"
74
+ },
75
+ size: [
76
+ "text-xs p-1",
77
+ "text-sm p-1.5",
78
+ "text-sm p-2",
79
+ "text-base p-2.5",
80
+ "text-base p-3"
81
+ ],
82
+ group: "inline-flex rounded-md shadow-xs"
83
+ }
84
+ end
85
+ # rubocop: enable Layout/LineLength, Metrics/BlockLength
86
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Fluxbit::Config::CardComponent
4
+ mattr_accessor :color, default: :info
5
+ mattr_accessor :icon, default: :default
6
+ mattr_accessor :can_close, default: true
7
+ mattr_accessor :out_animation, default: :fade_out
8
+ mattr_accessor :fade_in_animation, default: true
9
+ mattr_accessor :dismiss_timeout, default: 3000
10
+ mattr_accessor :all_rounded, default: true
11
+
12
+ # rubocop: disable Layout/LineLength, Metrics/BlockLength
13
+ mattr_accessor :styles do
14
+ {
15
+ base: "flex rounded-lg border border-gray-200 bg-white shadow-md dark:border-gray-700 dark:bg-gray-800",
16
+ children: "flex h-full flex-col justify-center gap-4 p-6",
17
+ horizontal: {
18
+ off: "flex-col",
19
+ on: "flex-col md:max-w-xl md:flex-row"
20
+ },
21
+ href: "hover:bg-gray-100 dark:hover:bg-gray-700",
22
+ img: {
23
+ base: "",
24
+ horizontal: {
25
+ off: "rounded-t-lg",
26
+ on: "h-96 w-full rounded-t-lg object-cover md:h-auto md:w-48 md:rounded-none md:rounded-l-lg"
27
+ }
28
+ }
29
+ }
30
+ end
31
+ # rubocop: enable Layout/LineLength, Metrics/BlockLength
32
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Fluxbit::Config::FlexComponent
4
+ # rubocop: disable Layout/LineLength, Metrics/BlockLength
5
+ mattr_accessor :styles do
6
+ {
7
+ resolutions: [ :sm, :md, :lg, :xl, :'2xl' ],
8
+ base: "flex",
9
+ direction: {
10
+ horizontal: "flex-row",
11
+ vertical: "flex-col",
12
+ horizontal_reverse: "flex-row-reverse",
13
+ vertical_reverse: "flex-col-reverse"
14
+ },
15
+ justify_content: {
16
+ start: "justify-start",
17
+ end: "justify-end",
18
+ center: "justify-center",
19
+ baseline: "justify-baseline",
20
+ stretch: "justify-stretch",
21
+ space_around: "justify-around",
22
+ space_between: "justify-between",
23
+ space_evenly: "justify-evenly",
24
+ normal: "justify-normal"
25
+ },
26
+ align_items: {
27
+ start: "items-start",
28
+ end: "items-end",
29
+ center: "items-center",
30
+ baseline: "items-baseline",
31
+ stretch: "items-stretch"
32
+ },
33
+ wrap: {
34
+ wrap: "flex-wrap",
35
+ nowrap: "flex-nowrap",
36
+ wrap_reverse: "flex-wrap-reverse"
37
+ },
38
+ gap: [ "gap-0", "gap-2", "gap-4", "gap-6", "gap-8", "gap-10", "gap-12", "gap-14", "gap-16", "gap-18", "gap-20" ],
39
+ elements: [
40
+ "sm:justify-start", "sm:justify-end", "sm:justify-center", "sm:justify-baseline", "sm:justify-stretch", "sm:justify-around", "sm:justify-between", "sm:justify-evenly", "sm:justify-normal",
41
+ "sm:flex-row", "sm:flex-col", "sm:flex-row-reverse", "sm:flex-col-reverse", "sm:items-start", "sm:items-end", "sm:items-center", "sm:items-baseline", "sm:items-stretch", "sm:flex-wrap", "sm:flex-nowrap", "sm:flex-wrap-reverse",
42
+ "sm:gap-0", "sm:gap-2", "sm:gap-4", "sm:gap-6", "sm:gap-8", "sm:gap-10", "sm:gap-12", "sm:gap-14", "sm:gap-16", "sm:gap-18", "sm:gap-20",
43
+
44
+ "md:justify-start", "md:justify-end", "md:justify-center", "md:justify-baseline", "md:justify-stretch", "md:justify-around", "md:justify-between", "md:justify-evenly", "md:justify-normal",
45
+ "md:flex-row", "md:flex-col", "md:flex-row-reverse", "md:flex-col-reverse", "md:items-start", "md:items-end", "md:items-center", "md:items-baseline", "md:items-stretch", "md:flex-wrap", "md:flex-nowrap", "md:flex-wrap-reverse",
46
+ "md:gap-0", "md:gap-2", "md:gap-4", "md:gap-6", "md:gap-8", "md:gap-10", "md:gap-12", "md:gap-14", "md:gap-16", "md:gap-18", "md:gap-20",
47
+
48
+ "lg:justify-start", "lg:justify-end", "lg:justify-center", "lg:justify-baseline", "lg:justify-stretch", "lg:justify-around", "lg:justify-between", "lg:justify-evenly", "lg:justify-normal",
49
+ "lg:flex-row", "lg:flex-col", "lg:flex-row-reverse", "lg:flex-col-reverse", "lg:items-start", "lg:items-end", "lg:items-center", "lg:items-baseline", "lg:items-stretch", "lg:flex-wrap", "lg:flex-nowrap", "lg:flex-wrap-reverse",
50
+ "lg:gap-0", "lg:gap-2", "lg:gap-4", "lg:gap-6", "lg:gap-8", "lg:gap-10", "lg:gap-12", "lg:gap-14", "lg:gap-16", "lg:gap-18", "lg:gap-20",
51
+
52
+ "xl:justify-start", "xl:justify-end", "xl:justify-center", "xl:justify-baseline", "xl:justify-stretch", "xl:justify-around", "xl:justify-between", "xl:justify-evenly", "xl:justify-normal",
53
+ "xl:flex-row", "xl:flex-col", "xl:flex-row-reverse", "xl:flex-col-reverse", "xl:items-start", "xl:items-end", "xl:items-center", "xl:items-baseline", "xl:items-stretch", "xl:flex-wrap", "xl:flex-nowrap", "xl:flex-wrap-reverse",
54
+ "xl:gap-0", "xl:gap-2", "xl:gap-4", "xl:gap-6", "xl:gap-8", "xl:gap-10", "xl:gap-12", "xl:gap-14", "xl:gap-16", "xl:gap-18", "xl:gap-20",
55
+
56
+ "2xl:justify-start", "2xl:justify-end", "2xl:justify-center", "2xl:justify-baseline", "2xl:justify-stretch", "2xl:justify-around", "2xl:justify-between", "2xl:justify-evenly", "2xl:justify-normal",
57
+ "2xl:flex-row", "2xl:flex-col", "2xl:flex-row-reverse", "2xl:flex-col-reverse", "2xl:items-start", "2xl:items-end", "2xl:items-center", "2xl:items-baseline", "2xl:items-stretch", "2xl:flex-wrap", "2xl:flex-nowrap", "2xl:flex-wrap-reverse",
58
+ "2xl:gap-0", "2xl:gap-2", "2xl:gap-4", "2xl:gap-6", "2xl:gap-8", "2xl:gap-10", "2xl:gap-12", "2xl:gap-14", "2xl:gap-16", "2xl:gap-18", "2xl:gap-20"
59
+ ]
60
+ }
61
+ end
62
+ # rubocop: enable Layout/LineLength, Metrics/BlockLength
63
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Fluxbit::Config::Form::HelperTextComponent
4
+ mattr_accessor :color, default: :default
5
+
6
+ # rubocop: disable Layout/LineLength, Metrics/BlockLength
7
+ mattr_accessor :styles do
8
+ {
9
+ base: "text-sm ",
10
+ colors: {
11
+ default: "text-gray-500 dark:text-gray-400",
12
+ success: "text-green-600 dark:text-green-500",
13
+ failure: "text-red-600 dark:text-red-500",
14
+ info: "text-cyan-600 dark:text-cyan-500",
15
+ warning: "text-yellow-600 dark:text-yellow-500"
16
+ }
17
+ }
18
+ end
19
+ # rubocop: enable Layout/LineLength, Metrics/BlockLength
20
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Fluxbit::Config::GravatarComponent
4
+ mattr_accessor :rating, default: :pg
5
+ mattr_accessor :filetype, default: :png
6
+ mattr_accessor :default, default: :robohash # options: 404, mp (mystery person), identicon, monsterid, wavatar, retro, robohash, blank
7
+
8
+ # rubocop: disable Layout/LineLength, Metrics/BlockLength
9
+ mattr_accessor :gravatar_styles do
10
+ {
11
+ base: "bg-gray-200 dark:bg-gray-600",
12
+ default: %i[404 mp identicon monsterid wavatar retro robohash blank],
13
+ size: { xs: 30, sm: 40, md: 50, lg: 100, xl: 200 },
14
+ rating: %i[g pg r x],
15
+ filetype: %i[jpg jpeg gif png heic]
16
+ }
17
+ end
18
+ # rubocop: enable Layout/LineLength, Metrics/BlockLength
19
+ end