orbital_ui 0.3.1

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 (76) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/README.md +224 -0
  4. data/app/assets/config/orbital_ui_manifest.js +2 -0
  5. data/app/assets/javascripts/orbital_ui/index.js +6 -0
  6. data/app/assets/javascripts/orbital_ui/index.js.map +1 -0
  7. data/app/assets/stylesheets/orbital_ui/index.css +3 -0
  8. data/app/assets/stylesheets/orbital_ui/index.css.map +1 -0
  9. data/app/assets/stylesheets/orbital_ui/theme.css +113 -0
  10. data/app/assets/stylesheets/orbital_ui/themes/blue.css +43 -0
  11. data/app/assets/stylesheets/orbital_ui/themes/green.css +43 -0
  12. data/app/assets/stylesheets/orbital_ui/themes/orange.css +43 -0
  13. data/app/assets/stylesheets/orbital_ui/themes/rose.css +43 -0
  14. data/app/assets/stylesheets/orbital_ui/themes/violet.css +43 -0
  15. data/app/components/orbital_ui/accordion/item.rb +32 -0
  16. data/app/components/orbital_ui/accordion.rb +23 -0
  17. data/app/components/orbital_ui/alert.rb +80 -0
  18. data/app/components/orbital_ui/avatar.rb +87 -0
  19. data/app/components/orbital_ui/badge.rb +28 -0
  20. data/app/components/orbital_ui/button.rb +46 -0
  21. data/app/components/orbital_ui/button_group.rb +20 -0
  22. data/app/components/orbital_ui/card/action.rb +17 -0
  23. data/app/components/orbital_ui/card/content.rb +17 -0
  24. data/app/components/orbital_ui/card/description.rb +17 -0
  25. data/app/components/orbital_ui/card/footer.rb +17 -0
  26. data/app/components/orbital_ui/card/header.rb +25 -0
  27. data/app/components/orbital_ui/card/title.rb +17 -0
  28. data/app/components/orbital_ui/card.rb +30 -0
  29. data/app/components/orbital_ui/check_box.rb +59 -0
  30. data/app/components/orbital_ui/component.rb +12 -0
  31. data/app/components/orbital_ui/concerns/icon_prop.rb +14 -0
  32. data/app/components/orbital_ui/confirmation_dialog.rb +142 -0
  33. data/app/components/orbital_ui/delete_dialog.rb +143 -0
  34. data/app/components/orbital_ui/dialog.rb +46 -0
  35. data/app/components/orbital_ui/dialog_frame.rb +17 -0
  36. data/app/components/orbital_ui/dropdown.rb +58 -0
  37. data/app/components/orbital_ui/expander.rb +20 -0
  38. data/app/components/orbital_ui/grid.rb +22 -0
  39. data/app/components/orbital_ui/heading.rb +65 -0
  40. data/app/components/orbital_ui/icon.rb +21 -0
  41. data/app/components/orbital_ui/image.rb +26 -0
  42. data/app/components/orbital_ui/inline_stack.rb +31 -0
  43. data/app/components/orbital_ui/kbd.rb +15 -0
  44. data/app/components/orbital_ui/kbd_group.rb +15 -0
  45. data/app/components/orbital_ui/menu/item.rb +74 -0
  46. data/app/components/orbital_ui/menu/label.rb +20 -0
  47. data/app/components/orbital_ui/menu/separator.rb +21 -0
  48. data/app/components/orbital_ui/menu/sub.rb +68 -0
  49. data/app/components/orbital_ui/menu.rb +36 -0
  50. data/app/components/orbital_ui/modal.rb +36 -0
  51. data/app/components/orbital_ui/modal_frame.rb +17 -0
  52. data/app/components/orbital_ui/navigation_menu.rb +51 -0
  53. data/app/components/orbital_ui/popcard.rb +18 -0
  54. data/app/components/orbital_ui/popover.rb +50 -0
  55. data/app/components/orbital_ui/progress_bar.rb +33 -0
  56. data/app/components/orbital_ui/prose.rb +15 -0
  57. data/app/components/orbital_ui/select.rb +140 -0
  58. data/app/components/orbital_ui/separator.rb +22 -0
  59. data/app/components/orbital_ui/spinner.rb +14 -0
  60. data/app/components/orbital_ui/stack.rb +29 -0
  61. data/app/components/orbital_ui/text.rb +41 -0
  62. data/app/components/orbital_ui/text_field.rb +132 -0
  63. data/app/components/orbital_ui/tooltip.rb +42 -0
  64. data/app/components/orbital_ui/typography.rb +38 -0
  65. data/lib/orbital_ui/attribute_utils.rb +152 -0
  66. data/lib/orbital_ui/components/attributes.rb +164 -0
  67. data/lib/orbital_ui/components/styles.rb +40 -0
  68. data/lib/orbital_ui/engine.rb +7 -0
  69. data/lib/orbital_ui/icons.rb +17312 -0
  70. data/lib/orbital_ui/type/any.rb +17 -0
  71. data/lib/orbital_ui/type/array.rb +27 -0
  72. data/lib/orbital_ui/type/breakpoints.rb +46 -0
  73. data/lib/orbital_ui/type/symbol.rb +17 -0
  74. data/lib/orbital_ui/version.rb +5 -0
  75. data/lib/orbital_ui.rb +49 -0
  76. metadata +162 -0
@@ -0,0 +1,142 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OrbitalUi
4
+ class ConfirmationDialog < Component
5
+ attribute :open, :boolean, default: false
6
+ attribute :dismissible, :boolean, default: true
7
+ attribute :size, :symbol, default: :default, only: [:sm, :default, :lg, :xl, :full]
8
+ attribute :title, :string, default: "Are you sure?"
9
+ attribute :description, :string, default: nil
10
+ attribute :cancel_text, :string, default: "Cancel"
11
+ attribute :confirm_text, :string, default: "Confirm"
12
+ attribute :action_url, :string, default: nil
13
+ attribute :method, :symbol, default: :post, only: [:get, :post, :patch, :put, :delete]
14
+ attribute :loading, :boolean, default: false
15
+
16
+ renders_one :cancel_action
17
+ renders_one :confirm_action
18
+
19
+ def call
20
+ render OrbitalUi::Modal.new(open: @open, dismissible: @dismissible, size: @size, **html_attributes) do
21
+ content_tag(:div, class: "Orbital-Dialog") do
22
+ safe_join([
23
+ dismissible_close_button,
24
+ header_section,
25
+ body_section,
26
+ footer_section
27
+ ].compact)
28
+ end
29
+ end
30
+ end
31
+
32
+ private
33
+
34
+ def dismissible_close_button
35
+ return nil unless @dismissible
36
+
37
+ content_tag(:button, type: "button", data: { action: "orbital-modal#close" },
38
+ class: "Orbital-Dialog-Close", "aria-label": "Close") do
39
+ close_icon
40
+ end
41
+ end
42
+
43
+ def close_icon
44
+ tag.svg(class: "Orbital-Icon", width: "16", height: "16", viewBox: "0 0 24 24",
45
+ fill: "none", stroke: "currentColor", "stroke-width": "2",
46
+ "stroke-linecap": "round", "stroke-linejoin": "round") do
47
+ safe_join([
48
+ tag.line(x1: "18", y1: "6", x2: "6", y2: "18"),
49
+ tag.line(x1: "6", y1: "6", x2: "18", y2: "18")
50
+ ])
51
+ end
52
+ end
53
+
54
+ def header_section
55
+ content_tag(:div, class: "Orbital-Dialog-Header") do
56
+ content_tag(:div) do
57
+ safe_join([
58
+ content_tag(:h2, @title, class: "Orbital-Dialog-Title"),
59
+ (@description ? content_tag(:p, @description, class: "Orbital-Dialog-Description") : nil)
60
+ ].compact)
61
+ end
62
+ end
63
+ end
64
+
65
+ def body_section
66
+ return nil unless content?
67
+
68
+ content_tag(:div, content, class: "Orbital-Dialog-Body")
69
+ end
70
+
71
+ def footer_section
72
+ if @action_url
73
+ form_footer
74
+ else
75
+ div_footer
76
+ end
77
+ end
78
+
79
+ def form_footer
80
+ content_tag(:form, action: @action_url, method: "post", class: "Orbital-Dialog-Footer") do
81
+ safe_join([
82
+ csrf_hidden_field,
83
+ method_hidden_field,
84
+ cancel_button,
85
+ confirm_button(:submit)
86
+ ].compact)
87
+ end
88
+ end
89
+
90
+ def div_footer
91
+ content_tag(:div, class: "Orbital-Dialog-Footer") do
92
+ safe_join([cancel_button, confirm_button(:button)])
93
+ end
94
+ end
95
+
96
+ def cancel_button
97
+ if cancel_action?
98
+ cancel_action
99
+ else
100
+ content_tag(:button, @cancel_text, type: "button",
101
+ data: { action: "orbital-modal#close" },
102
+ class: "Orbital-Button", "data-variant": "outline", "data-size": "default")
103
+ end
104
+ end
105
+
106
+ def confirm_button(type)
107
+ if confirm_action?
108
+ confirm_action
109
+ else
110
+ opts = { class: "Orbital-Button", "data-variant": "default", "data-size": "default", type: type }
111
+ opts[:disabled] = true if @loading
112
+ content_tag(:button, **opts) do
113
+ safe_join([spinner_icon, @confirm_text].compact)
114
+ end
115
+ end
116
+ end
117
+
118
+ def spinner_icon
119
+ return nil unless @loading
120
+
121
+ content_tag(:span, class: "Orbital-ConfirmationDialog-Spinner") do
122
+ tag.svg(class: "Orbital-Icon animate-spin", width: "16", height: "16", viewBox: "0 0 24 24",
123
+ fill: "none", stroke: "currentColor", "stroke-width": "2",
124
+ "stroke-linecap": "round", "stroke-linejoin": "round") do
125
+ tag.path(d: "M21 12a9 9 0 1 1-6.219-8.56")
126
+ end
127
+ end
128
+ end
129
+
130
+ def csrf_hidden_field
131
+ return nil unless defined?(Rails) && helpers.respond_to?(:form_authenticity_token)
132
+
133
+ tag.input(type: "hidden", name: "authenticity_token", value: helpers.form_authenticity_token)
134
+ end
135
+
136
+ def method_hidden_field
137
+ return nil if @method == :post || @method.nil?
138
+
139
+ tag.input(type: "hidden", name: "_method", value: @method)
140
+ end
141
+ end
142
+ end
@@ -0,0 +1,143 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OrbitalUi
4
+ class DeleteDialog < Component
5
+ attribute :open, :boolean, default: false
6
+ attribute :dismissible, :boolean, default: true
7
+ attribute :size, :symbol, default: :default, only: [:sm, :default, :lg, :xl, :full]
8
+ attribute :title, :string, default: "Delete item?"
9
+ attribute :description, :string, default: nil
10
+ attribute :cancel_text, :string, default: "Cancel"
11
+ attribute :confirm_text, :string, default: "Delete"
12
+ attribute :action_url, :string, default: nil
13
+ attribute :method, :symbol, default: :delete, only: [:get, :post, :patch, :put, :delete]
14
+ attribute :loading, :boolean, default: false
15
+ attribute :destructive, :boolean, default: true
16
+
17
+ renders_one :cancel_action
18
+ renders_one :confirm_action
19
+
20
+ def call
21
+ render OrbitalUi::Modal.new(open: @open, dismissible: @dismissible, size: @size, **html_attributes) do
22
+ content_tag(:div, class: "Orbital-Dialog", "data-destructive": @destructive || nil) do
23
+ safe_join([
24
+ dismissible_close_button,
25
+ header_section,
26
+ body_section,
27
+ footer_section
28
+ ].compact)
29
+ end
30
+ end
31
+ end
32
+
33
+ private
34
+
35
+ def dismissible_close_button
36
+ return nil unless @dismissible
37
+
38
+ content_tag(:button, type: "button", data: { action: "orbital-modal#close" },
39
+ class: "Orbital-Dialog-Close", "aria-label": "Close") do
40
+ close_icon
41
+ end
42
+ end
43
+
44
+ def close_icon
45
+ tag.svg(class: "Orbital-Icon", width: "16", height: "16", viewBox: "0 0 24 24",
46
+ fill: "none", stroke: "currentColor", "stroke-width": "2",
47
+ "stroke-linecap": "round", "stroke-linejoin": "round") do
48
+ safe_join([
49
+ tag.line(x1: "18", y1: "6", x2: "6", y2: "18"),
50
+ tag.line(x1: "6", y1: "6", x2: "18", y2: "18")
51
+ ])
52
+ end
53
+ end
54
+
55
+ def header_section
56
+ content_tag(:div, class: "Orbital-Dialog-Header") do
57
+ content_tag(:div) do
58
+ safe_join([
59
+ content_tag(:h2, @title, class: "Orbital-Dialog-Title"),
60
+ (@description ? content_tag(:p, @description, class: "Orbital-Dialog-Description") : nil)
61
+ ].compact)
62
+ end
63
+ end
64
+ end
65
+
66
+ def body_section
67
+ return nil unless content?
68
+
69
+ content_tag(:div, content, class: "Orbital-Dialog-Body")
70
+ end
71
+
72
+ def footer_section
73
+ if @action_url
74
+ form_footer
75
+ else
76
+ div_footer
77
+ end
78
+ end
79
+
80
+ def form_footer
81
+ content_tag(:form, action: @action_url, method: "post", class: "Orbital-Dialog-Footer") do
82
+ safe_join([
83
+ csrf_hidden_field,
84
+ method_hidden_field,
85
+ cancel_button,
86
+ confirm_button(:submit)
87
+ ].compact)
88
+ end
89
+ end
90
+
91
+ def div_footer
92
+ content_tag(:div, class: "Orbital-Dialog-Footer") do
93
+ safe_join([cancel_button, confirm_button(:button)])
94
+ end
95
+ end
96
+
97
+ def cancel_button
98
+ if cancel_action?
99
+ cancel_action
100
+ else
101
+ content_tag(:button, @cancel_text, type: "button",
102
+ data: { action: "orbital-modal#close" },
103
+ class: "Orbital-Button", "data-variant": "outline", "data-size": "default")
104
+ end
105
+ end
106
+
107
+ def confirm_button(type)
108
+ if confirm_action?
109
+ confirm_action
110
+ else
111
+ opts = { class: "Orbital-Button", "data-variant": "destructive", "data-size": "default", type: type }
112
+ opts[:disabled] = true if @loading
113
+ content_tag(:button, **opts) do
114
+ safe_join([spinner_icon, @confirm_text].compact)
115
+ end
116
+ end
117
+ end
118
+
119
+ def spinner_icon
120
+ return nil unless @loading
121
+
122
+ content_tag(:span, class: "Orbital-ConfirmationDialog-Spinner") do
123
+ tag.svg(class: "Orbital-Icon animate-spin", width: "16", height: "16", viewBox: "0 0 24 24",
124
+ fill: "none", stroke: "currentColor", "stroke-width": "2",
125
+ "stroke-linecap": "round", "stroke-linejoin": "round") do
126
+ tag.path(d: "M21 12a9 9 0 1 1-6.219-8.56")
127
+ end
128
+ end
129
+ end
130
+
131
+ def csrf_hidden_field
132
+ return nil unless defined?(Rails) && helpers.respond_to?(:form_authenticity_token)
133
+
134
+ tag.input(type: "hidden", name: "authenticity_token", value: helpers.form_authenticity_token)
135
+ end
136
+
137
+ def method_hidden_field
138
+ return nil if @method == :post || @method.nil?
139
+
140
+ tag.input(type: "hidden", name: "_method", value: @method)
141
+ end
142
+ end
143
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OrbitalUi
4
+ class Dialog < Component
5
+ attribute :open, :boolean, default: false
6
+ attribute :dismissible, :boolean, default: true
7
+ attribute :size, :symbol, default: :default, only: [:sm, :default, :lg, :xl, :full]
8
+
9
+ renders_one :header
10
+ renders_one :body
11
+ renders_one :footer
12
+
13
+ orb_template <<-ORB
14
+ <Modal open={@open} dismissible={@dismissible} size={@size} **html_attributes>
15
+ <div class="Orbital-Dialog">
16
+ <button :if={@dismissible}
17
+ type="button"
18
+ data-action="orbital-modal#close"
19
+ class="Orbital-Dialog-Close"
20
+ aria-label="Close">
21
+ <svg class="Orbital-Icon" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
22
+ <line x1="18" y1="6" x2="6" y2="18"></line>
23
+ <line x1="6" y1="6" x2="18" y2="18"></line>
24
+ </svg>
25
+ </button>
26
+
27
+ <div class="Orbital-Dialog-Header" :if={header}>
28
+ {{header}}
29
+ </div>
30
+
31
+ <div class="Orbital-Dialog-Body" :if={body}>
32
+ {{body}}
33
+ </div>
34
+
35
+ <div class="Orbital-Dialog-Body" :if={!body}>
36
+ {{content}}
37
+ </div>
38
+
39
+ <div class="Orbital-Dialog-Footer" :if={footer}>
40
+ {{footer}}
41
+ </div>
42
+ </div>
43
+ </Modal>
44
+ ORB
45
+ end
46
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OrbitalUi
4
+ class DialogFrame < Component
5
+ orb_template <<-ORB
6
+ <turbo-frame id={portal_id}>
7
+ {{content}}
8
+ </turbo-frame>
9
+ ORB
10
+
11
+ private
12
+
13
+ def portal_id
14
+ OrbitalUi.configuration.dialog_portal_id
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OrbitalUi
4
+ class Dropdown < Component
5
+ attribute :id, :string, default: -> { "popover-#{SecureRandom.hex(4)}" }
6
+ attribute :on, :symbol, default: :click, only: [:click, :hover]
7
+ attribute :position, :symbol, default: :s, only: [:auto, :n, :ne, :e, :se, :s, :sw, :w, :nw]
8
+ attribute :label, :string
9
+ attribute :variant, :symbol, default: :nil
10
+ attribute :fullwidth, :boolean, default: false
11
+
12
+ renders_one :trigger
13
+
14
+ orb_template <<-ORB
15
+ <div **html_attributes>
16
+
17
+ <div data-orbital-popover-target="trigger" :if={trigger}>
18
+ {{trigger}}
19
+ </div>
20
+
21
+ <Button
22
+ variant={@variant}
23
+ size={@label.blank? ? :icon : :default}
24
+ data-orbital-popover-target="trigger"
25
+ :if={!trigger}>
26
+ <span :if={@label}>{{@label}}</span>
27
+ <Icon name="chevron-down" size="sm"/>
28
+ </Button>
29
+
30
+ <div
31
+ popover
32
+ id={@id}
33
+ data-orbital-popover-target="content"
34
+ class="Orbital-Popover Orbital-Dropdown"
35
+ data-position={@position} :if={content}>
36
+ {{content}}
37
+ </div>
38
+ </div>
39
+ ORB
40
+
41
+ private
42
+
43
+ def default_attributes
44
+ super.merge({
45
+ class: class_names(
46
+ "Orbital-Dropdown",
47
+ "Orbital-Dropdown--fullwidth": @fullwidth
48
+ ),
49
+ data: {
50
+ controller: "orbital-popover",
51
+ "orbital-popover-trigger-value": @on,
52
+ "orbital-popover-position-value": @position,
53
+ state: "closed"
54
+ }
55
+ })
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ class OrbitalUi::Expander < OrbitalUi::Component
4
+ attribute :vertical, type: :boolean, default: false
5
+
6
+ orb_template <<-ORB
7
+ <div **html_attributes></div>
8
+ ORB
9
+
10
+ private
11
+
12
+ def default_attributes
13
+ super.merge(
14
+ class: class_names(
15
+ "Orbital-Expander",
16
+ "Orbital-Expander--vertical": @vertical
17
+ )
18
+ )
19
+ end
20
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OrbitalUi
4
+ class Grid < Component
5
+ attribute :columns, :string, default: "1"
6
+ attribute :gap, :string, default: "4"
7
+
8
+ orb_template <<-ORB
9
+ <div **html_attributes>{{content}}</div>
10
+ ORB
11
+
12
+ private
13
+
14
+ def default_attributes
15
+ super.merge(
16
+ class: "Orbital-Grid",
17
+ "data-columns": @columns,
18
+ "data-gap": @gap
19
+ )
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ class OrbitalUi::Heading < OrbitalUi::Component
4
+ attribute :size, :string, only: %w[xs sm md lg xl 2xl 3xl 4xl], default: "md"
5
+ attribute :weight, :symbol, only: %i[light normal medium semibold bold], default: :semibold
6
+ attribute :align, :symbol, only: %i[left center right], default: :left
7
+ attribute :tone, :symbol, only: %i[default subdued], default: :default
8
+ attribute :as, :string, default: "span"
9
+
10
+ def call
11
+ content_tag @as, **html_attributes do
12
+ content
13
+ end
14
+ end
15
+
16
+ private
17
+
18
+ def default_attributes
19
+ super.merge(
20
+ class: class_names(
21
+ 'Orbital-Heading',
22
+ size_classes,
23
+ weight_classes
24
+ ),
25
+ "data-tone": @tone,
26
+ "data-align": @align
27
+ )
28
+ end
29
+
30
+ def size_classes
31
+ case @size
32
+ when 'xs'
33
+ "text-heading-xs"
34
+ when 'sm'
35
+ "text-heading-sm"
36
+ when 'md'
37
+ "text-heading-md"
38
+ when 'lg'
39
+ "text-heading-lg"
40
+ when 'xl'
41
+ "text-heading-xl"
42
+ when '2xl'
43
+ "text-heading-2xl"
44
+ when '3xl'
45
+ "text-heading-3xl"
46
+ when '4xl'
47
+ "text-heading-4xl"
48
+ end
49
+ end
50
+
51
+ def weight_classes
52
+ case @weight
53
+ when :light
54
+ "font-light"
55
+ when :normal
56
+ "font-normal"
57
+ when :medium
58
+ "font-medium"
59
+ when :semibold
60
+ "font-semibold"
61
+ when :bold
62
+ "font-bold"
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ class OrbitalUi::Icon < OrbitalUi::Component
4
+ attribute :name, :string, required: true
5
+ attribute :size, :symbol, only: %i[xs sm md lg xl], default: :md
6
+
7
+ def call
8
+ tag.div(**html_attributes) do
9
+ OrbitalUi::Icons.render(@name)
10
+ end
11
+ end
12
+
13
+ private
14
+
15
+ def default_attributes
16
+ super.merge(
17
+ class: 'Orbital-Icon',
18
+ "data-size": @size
19
+ )
20
+ end
21
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ class OrbitalUi::Image < OrbitalUi::Component
4
+ attribute :asset, :string
5
+ attribute :src, :string
6
+ attribute :alt, :string, default: ""
7
+ attribute :width, :integer, default: 32
8
+ attribute :height, :integer, default: 32
9
+
10
+ def initialize(kwargs = {})
11
+ super
12
+ return if @asset.present? ^ @src.present?
13
+
14
+ raise ArgumentError, "Image requires exactly one of :asset or :src"
15
+ end
16
+
17
+ def call
18
+ tag.img(src: @src.presence || asset_path(@asset), alt: @alt, width: @width, height: @height, **html_attributes)
19
+ end
20
+
21
+ private
22
+
23
+ def default_attributes
24
+ super.merge(class: 'Orbital-Image')
25
+ end
26
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OrbitalUi
4
+ class InlineStack < Component
5
+ attribute :gap, :string, default: "4"
6
+ attribute :align, :symbol, default: :stretch, only: %i[start center end stretch]
7
+ attribute :justify, :symbol, default: :start, only: %i[start center end between around evenly]
8
+ attribute :padding, :string
9
+ attribute :wrap, :string
10
+
11
+ orb_template <<-ORB
12
+ <div **html_attributes>{{content}}</div>
13
+ ORB
14
+
15
+ private
16
+
17
+ def default_attributes
18
+ attrs = super.merge(
19
+ class: "Orbital-InlineStack",
20
+ "data-gap": @gap,
21
+ "data-align": @align,
22
+ "data-justify": @justify,
23
+ "data-padding": @padding
24
+ )
25
+ if @wrap
26
+ attrs[:"data-wrap"] = @wrap == "reverse" ? "reverse" : true
27
+ end
28
+ attrs
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ class OrbitalUi::Kbd < OrbitalUi::Component
4
+ orb_template <<-ORB
5
+ <kbd **html_attributes>
6
+ {{content}}
7
+ </kbd>
8
+ ORB
9
+
10
+ private
11
+
12
+ def default_attributes
13
+ super.merge(class: 'Orbital-Kbd')
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ class OrbitalUi::KbdGroup < OrbitalUi::Component
4
+ orb_template <<-ORB
5
+ <span **html_attributes>
6
+ {{content}}
7
+ </span>
8
+ ORB
9
+
10
+ private
11
+
12
+ def default_attributes
13
+ super.merge(class: 'Orbital-KbdGroup')
14
+ end
15
+ end