bulma_x 0.2.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/.rspec +3 -0
  3. data/.rubocop.yml +22 -0
  4. data/CHANGELOG.md +30 -0
  5. data/CONTRIBUTING.md +50 -0
  6. data/LICENSE +661 -0
  7. data/README.md +315 -0
  8. data/Rakefile +12 -0
  9. data/lib/bulma_x/base_component.rb +125 -0
  10. data/lib/bulma_x/base_input.rb +37 -0
  11. data/lib/bulma_x/block.rb +7 -0
  12. data/lib/bulma_x/box.rb +7 -0
  13. data/lib/bulma_x/breadcrumbs.rb +35 -0
  14. data/lib/bulma_x/button.rb +42 -0
  15. data/lib/bulma_x/card.rb +55 -0
  16. data/lib/bulma_x/checkbox.rb +23 -0
  17. data/lib/bulma_x/columns.rb +81 -0
  18. data/lib/bulma_x/component_dsl.rb +19 -0
  19. data/lib/bulma_x/dropdown.rb +65 -0
  20. data/lib/bulma_x/dsl/options.rb +129 -0
  21. data/lib/bulma_x/dsl/slots.rb +234 -0
  22. data/lib/bulma_x/dsl/validations.rb +74 -0
  23. data/lib/bulma_x/field.rb +150 -0
  24. data/lib/bulma_x/figure.rb +27 -0
  25. data/lib/bulma_x/file.rb +54 -0
  26. data/lib/bulma_x/footer.rb +7 -0
  27. data/lib/bulma_x/form.rb +27 -0
  28. data/lib/bulma_x/grid.rb +90 -0
  29. data/lib/bulma_x/help.rb +7 -0
  30. data/lib/bulma_x/hero.rb +36 -0
  31. data/lib/bulma_x/icon.rb +66 -0
  32. data/lib/bulma_x/image.rb +42 -0
  33. data/lib/bulma_x/input.rb +53 -0
  34. data/lib/bulma_x/level.rb +43 -0
  35. data/lib/bulma_x/link.rb +44 -0
  36. data/lib/bulma_x/media.rb +19 -0
  37. data/lib/bulma_x/message.rb +27 -0
  38. data/lib/bulma_x/modal.rb +26 -0
  39. data/lib/bulma_x/navbar.rb +162 -0
  40. data/lib/bulma_x/notification.rb +15 -0
  41. data/lib/bulma_x/pagination.rb +86 -0
  42. data/lib/bulma_x/panel.rb +29 -0
  43. data/lib/bulma_x/paragraph.rb +7 -0
  44. data/lib/bulma_x/progress.rb +36 -0
  45. data/lib/bulma_x/radio.rb +33 -0
  46. data/lib/bulma_x/section.rb +35 -0
  47. data/lib/bulma_x/select.rb +57 -0
  48. data/lib/bulma_x/shared/aria_options.rb +19 -0
  49. data/lib/bulma_x/shared/data_options.rb +19 -0
  50. data/lib/bulma_x/shared/flex_options.rb +57 -0
  51. data/lib/bulma_x/shared/global_options.rb +49 -0
  52. data/lib/bulma_x/shared/spacing_options.rb +80 -0
  53. data/lib/bulma_x/shared/text_options.rb +31 -0
  54. data/lib/bulma_x/slot.rb +13 -0
  55. data/lib/bulma_x/subtitle.rb +9 -0
  56. data/lib/bulma_x/table.rb +78 -0
  57. data/lib/bulma_x/tabs.rb +43 -0
  58. data/lib/bulma_x/tag.rb +25 -0
  59. data/lib/bulma_x/textarea.rb +29 -0
  60. data/lib/bulma_x/title.rb +21 -0
  61. data/lib/bulma_x/version.rb +5 -0
  62. data/lib/bulma_x/vertical_menu.rb +71 -0
  63. data/lib/bulma_x.rb +9 -0
  64. metadata +123 -0
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BulmaX
4
+ module Shared
5
+ module SpacingOptions
6
+ VALID_SPACING_KEYS = %i[x y top right bottom left].freeze
7
+ VALID_SPACING_VALUES = ((0..10).to_a + ['auto']).freeze
8
+
9
+ module ClassMethods
10
+ def spacing_options
11
+ option :margin
12
+ option :padding
13
+ end
14
+ end
15
+
16
+ def self.included(base) = base.extend(ClassMethods)
17
+
18
+ def spacing_classes
19
+ [
20
+ *spacing_normalized(@margin, prefix: 'm'),
21
+ *spacing_normalized(@padding, prefix: 'p')
22
+ ]
23
+ end
24
+
25
+ private
26
+
27
+ # rubocop:disable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
28
+ def spacing_normalized(spacing, prefix:)
29
+ case spacing
30
+ in Hash
31
+ assert_valid_spacing!(spacing)
32
+
33
+ [
34
+ spacing[:x] && "#{prefix}x-#{spacing[:x]}",
35
+ spacing[:y] && "#{prefix}y-#{spacing[:y]}",
36
+ spacing[:top] && "#{prefix}t-#{spacing[:top]}",
37
+ spacing[:right] && "#{prefix}r-#{spacing[:right]}",
38
+ spacing[:bottom] && "#{prefix}b-#{spacing[:bottom]}",
39
+ spacing[:left] && "#{prefix}l-#{spacing[:left]}"
40
+ ]
41
+ in Integer => n
42
+ ["#{prefix}-#{n}"]
43
+ in nil
44
+ []
45
+ end
46
+ end
47
+ # rubocop:enable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
48
+
49
+ # rubocop:disable Metrics/MethodLength
50
+ def assert_valid_spacing!(spacing)
51
+ case spacing
52
+ in Hash
53
+ invalid_keys = spacing.keys - VALID_SPACING_KEYS
54
+
55
+ if invalid_keys.any?
56
+ raise ArgumentError,
57
+ "Expected spacing keys to be one of #{VALID_SPACING_KEYS}, got #{invalid_keys}"
58
+ end
59
+
60
+ invalid_values = spacing.values - VALID_SPACING_VALUES
61
+
62
+ if invalid_values.any?
63
+ raise ArgumentError,
64
+ "Expected spacing values to be one of #{VALID_SPACING_VALUES}, got #{invalid_values}"
65
+ end
66
+ in Integer
67
+ unless VALID_SPACING_VALUES.include?(spacing)
68
+ raise ArgumentError,
69
+ "Expected spacing to be included in #{VALID_SPACING_VALUES}, got #{spacing}"
70
+ end
71
+ in 'auto'
72
+ # no-op
73
+ else
74
+ raise ArgumentError, "Expected spacing to be a 'auto', a Hash or an Integer, got #{spacing}"
75
+ end
76
+ end
77
+ # rubocop:enable Metrics/MethodLength
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BulmaX
4
+ module Shared
5
+ module TextOptions
6
+ module ClassMethods
7
+ def text_options
8
+ option :text_modifier, values: self::MODIFIERS_PALETTE, default: nil
9
+ option :text_alignment, values: %i[left centered right justified], default: nil
10
+ option :text_transform, values: %i[lowercase uppercase capitalize italic underlined] + [nil], default: nil
11
+ option :text_weight, values: %i[light normal medium semibold bold], default: nil
12
+ option :text_family, values: %i[sans-serif monospace primary secondary code], default: nil
13
+ option :text_size, values: [nil, 1, 2, 3, 4, 5, 6, 7].freeze
14
+ end
15
+ end
16
+
17
+ def self.included(base) = base.extend(ClassMethods)
18
+
19
+ def text_classes
20
+ [
21
+ @text_modifier && "has-text-#{@text_modifier}",
22
+ @text_alignment && "has-text-#{@text_alignment}",
23
+ @text_transform && "is-#{@text_transform}",
24
+ @text_weight && "has-text-weight-#{@text_weight}",
25
+ @text_family && "is-family-#{@text_family}",
26
+ @text_size && "is-size-#{@text_size}"
27
+ ]
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BulmaX
4
+ class Slot < BaseComponent
5
+ option :tag, default: :div
6
+ option :classes, default: []
7
+ option :attributes, default: {}
8
+
9
+ def root_classes = super + [*@classes]
10
+ def root_attributes = super.merge(@attributes)
11
+ def root_tag = @tag
12
+ end
13
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BulmaX
4
+ class Subtitle < Title
5
+ def root_classes
6
+ ['subtitle'] + super - ['title']
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BulmaX
4
+ class Table < BaseComponent
5
+ option :bordered, values: BOOLEAN, default: false
6
+ option :striped, values: BOOLEAN, default: false
7
+ option :narrow, values: BOOLEAN, default: false
8
+ option :hoverable, values: BOOLEAN, default: false
9
+ option :scrollable, values: BOOLEAN, default: false
10
+
11
+ slot :table_container, classes: ['table-container']
12
+
13
+ slot :head, component: 'Part'
14
+ slot :body, component: 'Part'
15
+ slot :footer, component: 'Part'
16
+
17
+ root_slot tag: :table
18
+
19
+ def view_template(&)
20
+ if @scrollable
21
+ slot(:table_container) { render_self }
22
+ else
23
+ render_self
24
+ end
25
+ end
26
+
27
+ def render_self
28
+ render_root do
29
+ slot(:head, type: :head) if slot?(:head)
30
+ slot(:body, type: :body)
31
+ slot(:footer, type: :foot) if slot?(:footer)
32
+ end
33
+ end
34
+
35
+ def root_classes
36
+ super +
37
+ [
38
+ 'table',
39
+ @bordered && 'is-bordered',
40
+ @striped && 'is-striped',
41
+ @narrow && 'is-narrow',
42
+ @hoverable && 'is-hoverable'
43
+ ]
44
+ end
45
+
46
+ class Part < BaseComponent
47
+ option :type, values: %i[head body foot]
48
+
49
+ slots :row, component: 'Row'
50
+
51
+ def view_template
52
+ super do
53
+ slots(:row).each { render it }
54
+ end
55
+ end
56
+
57
+ def root_tag = "t#{@type}"
58
+
59
+ class Row < BaseComponent
60
+ root_slot tag: :tr
61
+
62
+ slots :cell, component: 'Cell'
63
+
64
+ def view_template
65
+ super do
66
+ slots(:cell).each { render it }
67
+ end
68
+ end
69
+
70
+ class Cell < BaseComponent
71
+ option :head, values: BOOLEAN, default: false
72
+
73
+ def root_tag = @head ? :th : :td
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BulmaX
4
+ class Tabs < BaseComponent
5
+ option :alignment, values: %i[centered left right], default: :center
6
+ option :size, values: %i[small medium large], default: :medium
7
+ option :boxed, values: BOOLEAN, default: false
8
+ option :toggle, values: BOOLEAN, default: false
9
+ option :toggle_rounded, values: BOOLEAN, default: false
10
+
11
+ slot :tab_list, tag: :ul
12
+ slots :tab, component: 'Tab'
13
+
14
+ def view_template(&)
15
+ super do
16
+ slot(:tab_list) do
17
+ slots(:tab).each_with_index do |tab, _idx|
18
+ render(tab)
19
+ end
20
+ end
21
+ end
22
+ end
23
+
24
+ def root_classes
25
+ super +
26
+ [
27
+ 'tabs',
28
+ "is-#{@alignment}",
29
+ "is-#{@size}",
30
+ @boxed && 'is-boxed',
31
+ @toggle && 'is-toggle',
32
+ @toggle_rounded && 'is-toggle-rounded'
33
+ ]
34
+ end
35
+
36
+ class Tab < BaseComponent
37
+ option :current, values: BOOLEAN, default: false
38
+ root_slot tag: :li
39
+
40
+ def root_classes = super + ['tab', @current && 'is-active']
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BulmaX
4
+ class Tag < BaseComponent
5
+ option :modifier, values: MODIFIERS_DECLINED, default: nil
6
+ option :rounded, values: BOOLEAN, default: false
7
+
8
+ root_slot tag: :span
9
+
10
+ def view_template
11
+ super do
12
+ yield if block_given?
13
+ end
14
+ end
15
+
16
+ def root_classes
17
+ super +
18
+ [
19
+ 'tag',
20
+ @modifier && "is-#{@modifier}",
21
+ @rounded && 'is-rounded'
22
+ ]
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BulmaX
4
+ class Textarea < BaseInput
5
+ option :rows, default: 3
6
+ option :fixed_size, values: BOOLEAN, default: false
7
+ option :name
8
+ option :value
9
+ option :placeholder
10
+
11
+ root_slot tag: :textarea
12
+
13
+ def root_classes
14
+ super + [
15
+ 'textarea',
16
+ @fixed_size && 'has-fixed-size'
17
+ ]
18
+ end
19
+
20
+ def root_attributes
21
+ super.merge(
22
+ rows: @rows,
23
+ name: @name,
24
+ value: @value,
25
+ placeholder: @placeholder
26
+ )
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BulmaX
4
+ class Title < BaseComponent
5
+ option :level, values: [1, 2, 3, 4, 5, 6], default: 1
6
+ option :size, values: (1..7).to_a + [nil], default: nil
7
+ option :spaced, values: BOOLEAN, default: false
8
+ option :tag, values: %i[h div p span], default: :h
9
+
10
+ def root_tag = @tag == :h ? "h#{@level}" : @tag
11
+
12
+ def root_classes
13
+ super +
14
+ [
15
+ 'title',
16
+ @size && "is-#{@size}",
17
+ @spaced && 'is-spaced'
18
+ ]
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BulmaX
4
+ VERSION = '0.2.0'
5
+ end
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BulmaX
4
+ class VerticalMenu < BaseComponent
5
+ root_slot tag: :aside, classes: ['menu'] # It override root_classes
6
+ slots :list, component: 'List'
7
+
8
+ def view_template(&)
9
+ super do
10
+ slots(:list).each do |list|
11
+ render(list)
12
+ end
13
+ end
14
+ end
15
+
16
+ class List < BaseComponent
17
+ slot :label, tag: :p, classes: ['menu-label']
18
+ slots :item, component: 'Item'
19
+
20
+ root_slot tag: :ul, classes: ['menu-list']
21
+
22
+ def view_template(&)
23
+ slot(:label) # must be right before the list
24
+
25
+ super do
26
+ slots(:item).each do |item|
27
+ render(item)
28
+ end
29
+ end
30
+ end
31
+
32
+ class Item < Link
33
+ option :active, values: BOOLEAN, default: false
34
+
35
+ slots :sub_item, component: 'self'
36
+
37
+ def root_classes
38
+ super + [
39
+ @active && 'is-active'
40
+ ]
41
+ end
42
+
43
+ def view_template(&)
44
+ li do
45
+ if slot?(:sub_item)
46
+ render_sub_list
47
+ elsif block_given?
48
+ super do
49
+ render_item(&)
50
+ end
51
+ end
52
+ end
53
+ end
54
+
55
+ private
56
+
57
+ def render_sub_list
58
+ ul do
59
+ slots(:sub_item).each do |sub_item|
60
+ render(sub_item)
61
+ end
62
+ end
63
+ end
64
+
65
+ def render_item(&)
66
+ yield if block_given?
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
data/lib/bulma_x.rb ADDED
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'zeitwerk'
4
+
5
+ module BulmaX
6
+ class Error < StandardError; end
7
+
8
+ Loader = Zeitwerk::Loader.for_gem.tap(&:setup)
9
+ end
metadata ADDED
@@ -0,0 +1,123 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bulma_x
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Team for the Planet
8
+ bindir: exe
9
+ cert_chain: []
10
+ date: 2025-05-15 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: phlex
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: 2.1.2
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
24
+ - !ruby/object:Gem::Version
25
+ version: 2.1.2
26
+ description: |
27
+ BulmaX is a component based library that allows you to use Bulma CSS with
28
+ the power of Phlex. It provides a set of components that can be used to
29
+ build modern web applications with ease and a DSL to create your own
30
+ components.
31
+ email:
32
+ - dev@team-planet.com
33
+ executables: []
34
+ extensions: []
35
+ extra_rdoc_files: []
36
+ files:
37
+ - ".rspec"
38
+ - ".rubocop.yml"
39
+ - CHANGELOG.md
40
+ - CONTRIBUTING.md
41
+ - LICENSE
42
+ - README.md
43
+ - Rakefile
44
+ - lib/bulma_x.rb
45
+ - lib/bulma_x/base_component.rb
46
+ - lib/bulma_x/base_input.rb
47
+ - lib/bulma_x/block.rb
48
+ - lib/bulma_x/box.rb
49
+ - lib/bulma_x/breadcrumbs.rb
50
+ - lib/bulma_x/button.rb
51
+ - lib/bulma_x/card.rb
52
+ - lib/bulma_x/checkbox.rb
53
+ - lib/bulma_x/columns.rb
54
+ - lib/bulma_x/component_dsl.rb
55
+ - lib/bulma_x/dropdown.rb
56
+ - lib/bulma_x/dsl/options.rb
57
+ - lib/bulma_x/dsl/slots.rb
58
+ - lib/bulma_x/dsl/validations.rb
59
+ - lib/bulma_x/field.rb
60
+ - lib/bulma_x/figure.rb
61
+ - lib/bulma_x/file.rb
62
+ - lib/bulma_x/footer.rb
63
+ - lib/bulma_x/form.rb
64
+ - lib/bulma_x/grid.rb
65
+ - lib/bulma_x/help.rb
66
+ - lib/bulma_x/hero.rb
67
+ - lib/bulma_x/icon.rb
68
+ - lib/bulma_x/image.rb
69
+ - lib/bulma_x/input.rb
70
+ - lib/bulma_x/level.rb
71
+ - lib/bulma_x/link.rb
72
+ - lib/bulma_x/media.rb
73
+ - lib/bulma_x/message.rb
74
+ - lib/bulma_x/modal.rb
75
+ - lib/bulma_x/navbar.rb
76
+ - lib/bulma_x/notification.rb
77
+ - lib/bulma_x/pagination.rb
78
+ - lib/bulma_x/panel.rb
79
+ - lib/bulma_x/paragraph.rb
80
+ - lib/bulma_x/progress.rb
81
+ - lib/bulma_x/radio.rb
82
+ - lib/bulma_x/section.rb
83
+ - lib/bulma_x/select.rb
84
+ - lib/bulma_x/shared/aria_options.rb
85
+ - lib/bulma_x/shared/data_options.rb
86
+ - lib/bulma_x/shared/flex_options.rb
87
+ - lib/bulma_x/shared/global_options.rb
88
+ - lib/bulma_x/shared/spacing_options.rb
89
+ - lib/bulma_x/shared/text_options.rb
90
+ - lib/bulma_x/slot.rb
91
+ - lib/bulma_x/subtitle.rb
92
+ - lib/bulma_x/table.rb
93
+ - lib/bulma_x/tabs.rb
94
+ - lib/bulma_x/tag.rb
95
+ - lib/bulma_x/textarea.rb
96
+ - lib/bulma_x/title.rb
97
+ - lib/bulma_x/version.rb
98
+ - lib/bulma_x/vertical_menu.rb
99
+ homepage: https://gitlab.com/tftp/open/bulma_x
100
+ licenses: []
101
+ metadata:
102
+ homepage_uri: https://gitlab.com/tftp/open/bulma_x
103
+ source_code_uri: https://gitlab.com/tftp/open/bulma_x.
104
+ changelog_uri: https://gitlab.com/tftp/open/bulma_x/Changelog.md.
105
+ rubygems_mfa_required: 'true'
106
+ rdoc_options: []
107
+ require_paths:
108
+ - lib
109
+ required_ruby_version: !ruby/object:Gem::Requirement
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ version: 3.4.0
114
+ required_rubygems_version: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ requirements: []
120
+ rubygems_version: 3.6.2
121
+ specification_version: 4
122
+ summary: Merge the power of Phlex into Bulma CSS
123
+ test_files: []