polaris_view_components 0.1.0 → 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 (35) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +36 -1
  3. data/app/assets/javascripts/polaris.js +15 -2
  4. data/app/components/polaris/button_component.html.erb +1 -1
  5. data/app/components/polaris/button_component.rb +1 -85
  6. data/app/components/polaris/card/section_component.rb +2 -1
  7. data/app/components/polaris/card_component.html.erb +8 -2
  8. data/app/components/polaris/card_component.rb +2 -0
  9. data/app/components/polaris/headless_button.html.erb +22 -0
  10. data/app/components/polaris/headless_button.rb +95 -0
  11. data/app/components/polaris/resource_item_component.html.erb +27 -0
  12. data/app/components/polaris/resource_item_component.rb +75 -0
  13. data/app/components/polaris/resource_list_component.rb +32 -0
  14. data/app/components/polaris/select_component.html.erb +11 -2
  15. data/app/components/polaris/select_component.rb +2 -0
  16. data/app/components/polaris/shopify_navigation_component.rb +33 -13
  17. data/app/components/polaris/skeleton_body_text_component.html.erb +5 -0
  18. data/app/components/polaris/skeleton_body_text_component.rb +15 -0
  19. data/app/components/polaris/tag_component.html.erb +6 -0
  20. data/app/components/polaris/tag_component.rb +35 -0
  21. data/app/components/polaris/text_field_component.html.erb +4 -4
  22. data/app/components/polaris/text_field_component.rb +3 -1
  23. data/app/helpers/polaris/form_builder.rb +43 -7
  24. data/app/helpers/polaris/url_helper.rb +19 -0
  25. data/app/helpers/polaris/view_helper.rb +4 -0
  26. data/app/javascript/polaris/index.js +3 -1
  27. data/app/javascript/polaris/resource_item_controller.js +15 -0
  28. data/app/javascript/polaris/text_field_controller.js +0 -1
  29. data/lib/generators/polaris_view_components/USAGE +5 -0
  30. data/lib/generators/polaris_view_components/install_generator.rb +35 -0
  31. data/lib/generators/polaris_view_components/templates/README +14 -0
  32. data/lib/generators/polaris_view_components/templates/stimulus_index.js +7 -0
  33. data/lib/polaris/view_components/engine.rb +1 -0
  34. data/lib/polaris/view_components/version.rb +1 -1
  35. metadata +17 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 51731f649164d962ee2859f84197a32a55a08a229d3606682fb57fc2eb0bcbe4
4
- data.tar.gz: c543075f3f75725dac65d466ff817587af90541b0e3e4b399eb84f3fc2e03855
3
+ metadata.gz: 75b9c5e7b5a31ce1a5a549b0315fdbefc308206fd89085a19c8feac044f2884f
4
+ data.tar.gz: c858f559b97a7dfe14c6c303d3f7b000ca428ddc12ee603511f03ebe4ad4ffcc
5
5
  SHA512:
6
- metadata.gz: 1b458cf6a17a5ebbd23e2b663a8f9bb52269a3bd68c14fd225dd1a316813a4d8eb88ee7999c8be0099934af21a3b56cf462ddc97348e184a41b245a5359410d5
7
- data.tar.gz: 2dfbe9e93bf4cd04b5ef1752204d691dc560d85cf9f8aa9a7b34fc191b0856b0ba3c511a572260ef690d40cf66cc24032e72f3afcb740c5741a8cfcae3205f56
6
+ metadata.gz: 0577b317bffc512104e90a023eab9d2a674b9f6ce852eb2e8324a77e1723f97029d30545053e29f72ad7da1da14ebb5c2c1f3eee5afa2a50f4ed7bca7afce4b7
7
+ data.tar.gz: 1cfb3676d22713e1e6f5d47a4a521683faa1d5a7bc2f94db6731da47e0834b359bdd7f91670c294b6f20e11445089ad08c51111c226c7f77ba2563f417a9b4d3
data/README.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  Polaris ViewComponents is an implementation of the Polaris Design System using [ViewComponent](https://github.com/github/view_component).
4
4
 
5
+ ![Polaris ViewComponents](.github/assets/preview.png)
6
+
5
7
  > **This library is under active development. Breaking changes are likely until stable release.**
6
8
 
7
9
  ## Preview
@@ -23,7 +25,12 @@ Render Polaris ViewComponents:
23
25
  In `Gemfile`, add:
24
26
 
25
27
  ```ruby
26
- gem 'polaris_view_components', github: 'baoagency/polaris_view_components', branch: 'main'
28
+ gem 'polaris_view_components'
29
+ ```
30
+
31
+ Run install generator:
32
+ ```bash
33
+ rails generate polaris_view_components:install
27
34
  ```
28
35
 
29
36
  Setup Polaris styles in your layouts `<head>` tag:
@@ -33,6 +40,24 @@ Setup Polaris styles in your layouts `<head>` tag:
33
40
  <%= stylesheet_link_tag 'polaris_view_components' %>
34
41
  ```
35
42
 
43
+ Define Polaris style on your `<body>` tag:
44
+
45
+ ```erb
46
+ <body style="<%= polaris_body_styles %>">
47
+ ```
48
+
49
+ Install NPM package:
50
+ ```bash
51
+ yarn add polaris-view-components
52
+ ```
53
+
54
+ Add to `app/javascript/controllers/index.js`:
55
+ ```javascript
56
+ // Polaris ViewComponents
57
+ import { registerPolarisControllers } from "polaris-view-components"
58
+ registerPolarisControllers(application)
59
+ ```
60
+
36
61
  ## Dependencies
37
62
 
38
63
  In addition to the dependencies declared in the `gemspec`, Polaris ViewComponents assumes the presence of Polaris CSS.
@@ -46,6 +71,16 @@ To get started:
46
71
 
47
72
  It will open demo app with component previews on `localhost:4000`. You can change components and they will be updated on page reload. Component previews located in `demo/test/components/previews`.
48
73
 
74
+ To release gem run:
75
+ ```bash
76
+ script/release
77
+ ```
78
+
79
+ To release npm package run:
80
+ ```bash
81
+ yarn release
82
+ ```
83
+
49
84
  ## License
50
85
 
51
86
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -14,6 +14,19 @@ function _defineProperty(obj, key, value) {
14
14
  return obj;
15
15
  }
16
16
 
17
+ class _class$2 extends Controller {
18
+ open(event) {
19
+ if (this.hasLinkTarget && this.targetNotClickable(event.target)) {
20
+ this.linkTarget.click();
21
+ }
22
+ }
23
+ targetNotClickable(element) {
24
+ return !element.closest("a") && !element.closest("button") && element.nodeName !== "INPUT";
25
+ }
26
+ }
27
+
28
+ _defineProperty(_class$2, "targets", [ "link" ]);
29
+
17
30
  class _class$1 extends Controller {
18
31
  update(event) {
19
32
  const select = event.currentTarget;
@@ -85,7 +98,6 @@ class _class extends Controller {
85
98
  if (isNaN(numericValue)) {
86
99
  return;
87
100
  }
88
- console.log(numericValue, this.stepValue);
89
101
  const decimalPlaces = Math.max(dpl(numericValue), dpl(this.stepValue));
90
102
  const newValue = Math.min(Number(this.maxValue), Math.max(numericValue + steps * this.stepValue, Number(this.minValue)));
91
103
  this.value = String(newValue.toFixed(decimalPlaces));
@@ -106,8 +118,9 @@ _defineProperty(_class, "values", {
106
118
  });
107
119
 
108
120
  function registerPolarisControllers(application) {
121
+ application.register("polaris-resource-item", _class$2);
109
122
  application.register("polaris-select", _class$1);
110
123
  application.register("polaris-text-field", _class);
111
124
  }
112
125
 
113
- export { _class$1 as Select, _class as TextField, registerPolarisControllers };
126
+ export { _class$2 as ResourceItem, _class$1 as Select, _class as TextField, registerPolarisControllers };
@@ -1,4 +1,4 @@
1
- <%= render Polaris::BaseComponent.new(tag: @tag, **dynamic_arguments) do %>
1
+ <%= render Polaris::BaseComponent.new(tag: @tag, **system_arguments) do %>
2
2
  <span class="Polaris-Button__Content">
3
3
  <% if @loading %>
4
4
  <span class="Polaris-Button__Spinner">
@@ -1,90 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Polaris
4
- class ButtonComponent < Polaris::NewComponent
5
- SIZE_DEFAULT = :medium
6
- SIZE_MAPPINGS = {
7
- SIZE_DEFAULT => "",
8
- :slim => "Polaris-Button--sizeSlim",
9
- :large => "Polaris-Button--sizeLarge",
10
- }
11
- SIZE_OPTIONS = SIZE_MAPPINGS.keys
12
-
13
- TEXT_ALIGN_DEFAULT = :default
14
- TEXT_ALIGN_MAPPINGS = {
15
- TEXT_ALIGN_DEFAULT => "",
16
- :left => "Polaris-Button--textAlignLeft",
17
- :center => "Polaris-Button--textAlignCenter",
18
- :right => "Polaris-Button--textAlignRight",
19
- }
20
- TEXT_ALIGN_OPTIONS = TEXT_ALIGN_MAPPINGS.keys
21
-
22
- renders_one :icon, IconComponent
23
-
24
- def initialize(
25
- url: nil,
26
- outline: false,
27
- plain: false,
28
- primary: false,
29
- pressed: false,
30
- monochrome: false,
31
- loading: false,
32
- destructive: false,
33
- disabled: false,
34
- external: false,
35
- full_width: false,
36
- submit: false,
37
- remove_underline: false,
38
- size: SIZE_DEFAULT,
39
- text_align: TEXT_ALIGN_DEFAULT,
40
- **system_arguments
41
- )
42
- @tag = url.present? ? 'a' : 'button'
43
- @text_classes = class_names(
44
- "Polaris-Button__Text",
45
- "Polaris-Button--removeUnderline": plain && monochrome && remove_underline
46
- )
47
- @loading = loading
48
-
49
- @system_arguments = system_arguments
50
- @system_arguments[:type] = submit ? 'submit' : 'button'
51
- if loading
52
- @system_arguments[:disabled] = true
53
- end
54
- if url.present?
55
- @system_arguments.delete(:type)
56
- @system_arguments[:href] = url
57
- @system_arguments[:target] = "_blank" if external
58
- end
59
- if disabled
60
- @system_arguments[:disabled] = disabled
61
- end
62
- @system_arguments[:classes] = class_names(
63
- @system_arguments[:classes],
64
- "Polaris-Button",
65
- SIZE_MAPPINGS[fetch_or_fallback(SIZE_OPTIONS, size, SIZE_DEFAULT)],
66
- TEXT_ALIGN_MAPPINGS[fetch_or_fallback(TEXT_ALIGN_OPTIONS, text_align, TEXT_ALIGN_DEFAULT)],
67
- "Polaris-Button--destructive": destructive,
68
- "Polaris-Button--disabled": disabled || loading,
69
- "Polaris-Button--loading": loading,
70
- "Polaris-Button--fullWidth": full_width,
71
- "Polaris-Button--monochrome": monochrome,
72
- "Polaris-Button--outline": outline,
73
- "Polaris-Button--plain": plain,
74
- "Polaris-Button--primary": primary,
75
- "Polaris-Button--pressed": pressed,
76
- "Polaris-Button--removeUnderline": (plain && monochrome && remove_underline)
77
- )
78
- end
79
-
80
- private
81
-
82
- def dynamic_arguments
83
- @system_arguments[:classes] = class_names(
84
- @system_arguments[:classes],
85
- "Polaris-Button--iconOnly": icon.present? && content.blank?,
86
- )
87
- @system_arguments
88
- end
4
+ class ButtonComponent < HeadlessButton
89
5
  end
90
6
  end
@@ -6,6 +6,7 @@ class Polaris::Card::SectionComponent < Polaris::NewComponent
6
6
  subdued: false,
7
7
  flush: false,
8
8
  full_width: false,
9
+ unstyled: false,
9
10
  actions: [],
10
11
  **system_arguments
11
12
  )
@@ -13,10 +14,10 @@ class Polaris::Card::SectionComponent < Polaris::NewComponent
13
14
  @system_arguments[:tag] = :div
14
15
  @system_arguments[:classes] = class_names(
15
16
  @system_arguments[:classes],
16
- "Polaris-Card__Section",
17
17
  "Polaris-Card__Section--flush": flush,
18
18
  "Polaris-Card__Section--subdued": subdued,
19
19
  "Polaris-Card__Section--fullWidth": full_width,
20
+ "Polaris-Card__Section": !unstyled,
20
21
  )
21
22
 
22
23
  @title = title
@@ -11,8 +11,14 @@
11
11
  <% sections.each do |section| %>
12
12
  <%= section %>
13
13
  <% end %>
14
- <% else %>
15
- <%= render Polaris::Card::SectionComponent.new do %>
14
+ <% end %>
15
+
16
+ <% if content.present? %>
17
+ <% if @sectioned %>
18
+ <%= render Polaris::Card::SectionComponent.new do %>
19
+ <%= content %>
20
+ <% end %>
21
+ <% else %>
16
22
  <%= content %>
17
23
  <% end %>
18
24
  <% end %>
@@ -21,12 +21,14 @@ module Polaris
21
21
  def initialize(
22
22
  title: "",
23
23
  actions: [],
24
+ sectioned: true,
24
25
  subdued: false,
25
26
  footer_action_alignment: FOOTER_ACTION_ALIGNMENT_DEFAULT,
26
27
  **system_arguments
27
28
  )
28
29
  @title = title
29
30
  @actions = actions
31
+ @sectioned = sectioned
30
32
  @footer_action_alignment = footer_action_alignment
31
33
 
32
34
  @system_arguments = system_arguments
@@ -0,0 +1,22 @@
1
+ <span class="Polaris-Button__Content">
2
+ <% if @loading %>
3
+ <span class="Polaris-Button__Spinner">
4
+ <%= polaris_spinner(size: :small) %>
5
+ </span>
6
+ <% end %>
7
+
8
+ <% if icon.present? %>
9
+ <div class="Polaris-Button__Icon">
10
+ <%= icon %>
11
+ </div>
12
+ <% if content.present? %>
13
+ &nbsp;
14
+ <% end %>
15
+ <% end %>
16
+
17
+ <% if content.present? %>
18
+ <div class="<%= @text_classes %>">
19
+ <%= content %>
20
+ </div>
21
+ <% end %>
22
+ </span>
@@ -0,0 +1,95 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Polaris
4
+ class HeadlessButton < Polaris::NewComponent
5
+ SIZE_DEFAULT = :medium
6
+ SIZE_MAPPINGS = {
7
+ SIZE_DEFAULT => "",
8
+ :slim => "Polaris-Button--sizeSlim",
9
+ :large => "Polaris-Button--sizeLarge",
10
+ }
11
+ SIZE_OPTIONS = SIZE_MAPPINGS.keys
12
+
13
+ TEXT_ALIGN_DEFAULT = :default
14
+ TEXT_ALIGN_MAPPINGS = {
15
+ TEXT_ALIGN_DEFAULT => "",
16
+ :left => "Polaris-Button--textAlignLeft",
17
+ :center => "Polaris-Button--textAlignCenter",
18
+ :right => "Polaris-Button--textAlignRight",
19
+ }
20
+ TEXT_ALIGN_OPTIONS = TEXT_ALIGN_MAPPINGS.keys
21
+
22
+ renders_one :icon, IconComponent
23
+
24
+ def initialize(
25
+ url: nil,
26
+ outline: false,
27
+ plain: false,
28
+ primary: false,
29
+ pressed: false,
30
+ monochrome: false,
31
+ loading: false,
32
+ destructive: false,
33
+ disabled: false,
34
+ external: false,
35
+ full_width: false,
36
+ submit: false,
37
+ remove_underline: false,
38
+ size: SIZE_DEFAULT,
39
+ text_align: TEXT_ALIGN_DEFAULT,
40
+ **system_arguments
41
+ )
42
+ @tag = url.present? ? 'a' : 'button'
43
+ @text_classes = class_names(
44
+ "Polaris-Button__Text",
45
+ "Polaris-Button--removeUnderline": plain && monochrome && remove_underline
46
+ )
47
+ @loading = loading
48
+
49
+ @system_arguments = system_arguments
50
+ @system_arguments[:type] = submit ? 'submit' : 'button'
51
+ if loading
52
+ @system_arguments[:disabled] = true
53
+ end
54
+ if url.present?
55
+ @system_arguments.delete(:type)
56
+ @system_arguments[:href] = url
57
+ @system_arguments[:target] = "_blank" if external
58
+ end
59
+ if disabled
60
+ @system_arguments[:disabled] = disabled
61
+ end
62
+ @system_arguments[:classes] = class_names(
63
+ @system_arguments[:classes],
64
+ "Polaris-Button",
65
+ SIZE_MAPPINGS[fetch_or_fallback(SIZE_OPTIONS, size, SIZE_DEFAULT)],
66
+ TEXT_ALIGN_MAPPINGS[fetch_or_fallback(TEXT_ALIGN_OPTIONS, text_align, TEXT_ALIGN_DEFAULT)],
67
+ "Polaris-Button--destructive": destructive,
68
+ "Polaris-Button--disabled": disabled || loading,
69
+ "Polaris-Button--loading": loading,
70
+ "Polaris-Button--fullWidth": full_width,
71
+ "Polaris-Button--monochrome": monochrome,
72
+ "Polaris-Button--outline": outline,
73
+ "Polaris-Button--plain": plain,
74
+ "Polaris-Button--primary": primary,
75
+ "Polaris-Button--pressed": pressed,
76
+ "Polaris-Button--removeUnderline": (plain && monochrome && remove_underline)
77
+ )
78
+ end
79
+
80
+ def system_arguments
81
+ @system_arguments[:classes] = class_names(
82
+ @system_arguments[:classes],
83
+ "Polaris-Button--iconOnly": icon.present? && content.blank?,
84
+ )
85
+ @system_arguments
86
+ end
87
+
88
+ def html_options
89
+ options = system_arguments
90
+ options[:class] = options[:classes]
91
+ options.delete(:classes)
92
+ options
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,27 @@
1
+ <%= render(Polaris::BaseComponent.new(**wrapper_arguments)) do %>
2
+ <div class="Polaris-ResourceItem__ItemWrapper">
3
+ <%= render(Polaris::BaseComponent.new(**system_arguments)) do %>
4
+ <% if @url %>
5
+ <a
6
+ class="Polaris-ResourceItem__Link"
7
+ tabindex="0"
8
+ href="<%= @url %>"
9
+ data-polaris-unstyled="true"
10
+ data-polaris-resource-item-target="link"></a>
11
+ <% end %>
12
+
13
+ <%= render(Polaris::BaseComponent.new(**container_arguments)) do %>
14
+ <% if media.present? %>
15
+ <div class="Polaris-ResourceItem__Owned">
16
+ <div class="Polaris-ResourceItem__Media">
17
+ <%= media %>
18
+ </div>
19
+ </div>
20
+ <% end %>
21
+ <div class="Polaris-ResourceItem__Content">
22
+ <%= content %>
23
+ </div>
24
+ <% end %>
25
+ <% end %>
26
+ </div>
27
+ <% end %>
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Polaris
4
+ class ResourceItemComponent < Polaris::NewComponent
5
+ CURSOR_DEFAULT = :default
6
+ CURSOR_OPTIONS = %i[default pointer]
7
+
8
+ ALIGNMENT_DEFAULT = :default
9
+ ALIGNMENT_MAPPINGS = {
10
+ ALIGNMENT_DEFAULT => "",
11
+ center: "Polaris-ResourceItem--alignmentCenter",
12
+ }
13
+ ALIGNMENT_OPTIONS = ALIGNMENT_MAPPINGS.keys
14
+
15
+ renders_one :media
16
+
17
+ def initialize(
18
+ url: nil,
19
+ vertical_alignment: ALIGNMENT_DEFAULT,
20
+ wrapper_arguments: {},
21
+ container_arguments: {},
22
+ **system_arguments
23
+ )
24
+ @url = url
25
+ @vertical_alignment = vertical_alignment
26
+ @wrapper_arguments = wrapper_arguments
27
+ @container_arguments = container_arguments
28
+ @system_arguments = system_arguments
29
+ end
30
+
31
+ def wrapper_arguments
32
+ {
33
+ tag: "li",
34
+ data: {},
35
+ }.deep_merge(@wrapper_arguments).tap do |args|
36
+ args[:classes] = class_names(
37
+ args[:classes],
38
+ "Polaris-ResourceItem__ListItem",
39
+ )
40
+ prepend_option(args[:data], :controller, "polaris-resource-item")
41
+ end
42
+ end
43
+
44
+ def container_arguments
45
+ {
46
+ tag: "div",
47
+ }.deep_merge(@container_arguments).tap do |args|
48
+ args[:classes] = class_names(
49
+ args[:classes],
50
+ "Polaris-ResourceItem__Container",
51
+ ALIGNMENT_MAPPINGS[fetch_or_fallback(ALIGNMENT_OPTIONS, @vertical_alignment, ALIGNMENT_DEFAULT)],
52
+ )
53
+ end
54
+ end
55
+
56
+ def system_arguments
57
+ {
58
+ tag: "div",
59
+ data: {},
60
+ }.deep_merge(@system_arguments).tap do |args|
61
+ args[:classes] = class_names(
62
+ args[:classes],
63
+ "Polaris-ResourceItem",
64
+ )
65
+ prepend_option(args, :style, "cursor: #{cursor};")
66
+ prepend_option(args[:data], :action, "click->polaris-resource-item#open")
67
+ end
68
+ end
69
+
70
+ private
71
+ def cursor
72
+ @url.present? ? "pointer" : "default"
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Polaris
4
+ class ResourceListComponent < Polaris::NewComponent
5
+ def initialize(
6
+ wrapper_arguments: {},
7
+ **system_arguments
8
+ )
9
+ @wrapper_arguments = wrapper_arguments
10
+ @wrapper_arguments[:tag] = "div"
11
+ @wrapper_arguments[:classes] = class_names(
12
+ @wrapper_arguments[:classes],
13
+ "Polaris-ResourceList__ResourceListWrapper",
14
+ )
15
+
16
+ @system_arguments = system_arguments
17
+ @system_arguments[:tag] = "ul"
18
+ @system_arguments[:classes] = class_names(
19
+ @system_arguments[:classes],
20
+ "Polaris-ResourceList",
21
+ )
22
+ end
23
+
24
+ def call
25
+ render(Polaris::BaseComponent.new(**@wrapper_arguments)) do
26
+ render(Polaris::BaseComponent.new(**@system_arguments)) do
27
+ content
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -1,9 +1,18 @@
1
1
  <%= render Polaris::LabelledComponent.new(**@wrapper_arguments) do %>
2
2
  <%= render Polaris::BaseComponent.new(**@system_arguments) do %>
3
3
  <% if @form.present? && @attribute.present? %>
4
- <%= @form.select(@attribute, options_for_select(@options, @selected), @select_options, @input_options) %>
4
+ <%= @form.select(
5
+ @attribute,
6
+ options_for_select(@options, selected: @selected, disabled: @disabled_options),
7
+ @select_options,
8
+ @input_options,
9
+ ) %>
5
10
  <% else %>
6
- <%= select_tag(@name, options_for_select(@options, @selected), @input_options) %>
11
+ <%= select_tag(
12
+ @name,
13
+ options_for_select(@options, selected: @selected, disabled: @disabled_options),
14
+ @input_options,
15
+ ) %>
7
16
  <% end %>
8
17
 
9
18
  <div
@@ -8,6 +8,7 @@ module Polaris
8
8
  name: nil,
9
9
  options:,
10
10
  selected: nil,
11
+ disabled_options: nil,
11
12
  label: nil,
12
13
  label_hidden: false,
13
14
  label_inline: false,
@@ -26,6 +27,7 @@ module Polaris
26
27
  @name = name
27
28
  @options = options
28
29
  @selected = selected
30
+ @disabled_options = disabled_options
29
31
  @label = label
30
32
  @label_hidden = label_hidden
31
33
  @label_inline = label_inline
@@ -2,9 +2,13 @@
2
2
 
3
3
  module Polaris
4
4
  class ShopifyNavigationComponent < Polaris::NewComponent
5
- renders_many :links, "ShopifyNavigationLinkComponent"
5
+ renders_many :links, -> (**system_arguments) do
6
+ ShopifyNavigationLinkComponent.new(auto_detect_active: @auto_detect_active, **system_arguments)
7
+ end
8
+
9
+ def initialize(auto_detect_active: false, **system_arguments)
10
+ @auto_detect_active = auto_detect_active
6
11
 
7
- def initialize(**system_arguments)
8
12
  @system_arguments = system_arguments
9
13
  @system_arguments[:tag] = "div"
10
14
  @system_arguments[:classes] = class_names(
@@ -18,26 +22,42 @@ module Polaris
18
22
  end
19
23
 
20
24
  class ShopifyNavigationLinkComponent < Polaris::NewComponent
21
- def initialize(url:, active: false, **system_arguments)
25
+ def initialize(url:, auto_detect_active:, active: false, **system_arguments)
26
+ @url = url
27
+ @auto_detect_active = auto_detect_active
28
+ @active = active
22
29
  @system_arguments = system_arguments
23
- @system_arguments[:tag] = "a"
24
- @system_arguments[:href] = url
25
- @system_arguments[:role] = "tab"
26
- @system_arguments["data-polaris-unstyled"] = true
27
- @system_arguments["aria-selected"] = active
28
- @system_arguments[:classes] = class_names(
29
- @system_arguments[:classes],
30
- "shp-Navigation_Link",
31
- )
32
30
  end
33
31
 
34
32
  def call
35
33
  tag.li(class: "shp-Navigation_Item", role: "presentation") do
36
- render(Polaris::BaseComponent.new(**@system_arguments)) do
34
+ render(Polaris::BaseComponent.new(**system_arguments)) do
37
35
  tag.span(class: "shp-Navigation_LinkText") { content }
38
36
  end
39
37
  end
40
38
  end
39
+
40
+ def system_arguments
41
+ {
42
+ tag: "a",
43
+ href: @url,
44
+ role: "tab",
45
+ data: { polaris_unstyled: true },
46
+ aria: {},
47
+ }.deep_merge(@system_arguments).tap do |args|
48
+ args[:aria][:selected] = @active || detect_active(@url)
49
+ args[:classes] = class_names(
50
+ args[:classes],
51
+ "shp-Navigation_Link",
52
+ )
53
+ end
54
+ end
55
+
56
+ def detect_active(url)
57
+ return unless @auto_detect_active
58
+
59
+ request.path.include?(url.split('?').first)
60
+ end
41
61
  end
42
62
  end
43
63
  end
@@ -0,0 +1,5 @@
1
+ <%= render Polaris::BaseComponent.new(**@system_arguments) do %>
2
+ <% @lines.times do %>
3
+ <div class="Polaris-SkeletonBodyText"></div>
4
+ <% end %>
5
+ <% end %>
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Polaris
4
+ class SkeletonBodyTextComponent < Polaris::NewComponent
5
+ def initialize(lines: 3, **system_arguments)
6
+ @lines = lines
7
+ @system_arguments = system_arguments
8
+ @system_arguments[:tag] = "div"
9
+ @system_arguments[:classes] = class_names(
10
+ @system_arguments[:classes],
11
+ "Polaris-SkeletonBodyText__SkeletonBodyTextContainer",
12
+ )
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,6 @@
1
+ <%= render Polaris::BaseComponent.new(**system_arguments) do %>
2
+ <span class="Polaris-TagText">
3
+ <%= content %>
4
+ </span>
5
+ <%= remove_button %>
6
+ <% end %>
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Polaris
4
+ class TagComponent < Polaris::NewComponent
5
+ renders_one :remove_button, lambda { |**system_arguments|
6
+ render Polaris::BaseButton.new(
7
+ classes: "Polaris-Tag__Button",
8
+ disabled: @disabled,
9
+ **system_arguments
10
+ ) do |button|
11
+ polaris_icon(name: "CancelSmallMinor")
12
+ end
13
+ }
14
+
15
+ def initialize(clickable: false, disabled: false, **system_arguments)
16
+ @clickable = clickable
17
+ @disabled = disabled
18
+
19
+ @system_arguments = system_arguments
20
+ end
21
+
22
+ def system_arguments
23
+ @system_arguments.tap do |opts|
24
+ opts[:tag] = @clickable ? "button" : "span"
25
+ opts[:classes] = class_names(
26
+ @system_arguments[:classes],
27
+ "Polaris-Tag",
28
+ "Polaris-Tag--clickable" => @clickable,
29
+ "Polaris-Tag--disabled" => @disabled,
30
+ "Polaris-Tag--removable" => remove_button.present?
31
+ )
32
+ end
33
+ end
34
+ end
35
+ end
@@ -8,9 +8,9 @@
8
8
 
9
9
  <div class="Polaris-Connected__Item Polaris-Connected__Item--primary">
10
10
  <%= render Polaris::BaseComponent.new(**system_arguments) do %>
11
- <% if @prefix.present? %>
11
+ <% if prefix.present? || @prefix.present? %>
12
12
  <div class="Polaris-TextField__Prefix">
13
- <%= @prefix %>
13
+ <%= prefix || @prefix %>
14
14
  </div>
15
15
  <% end %>
16
16
 
@@ -20,9 +20,9 @@
20
20
  <%= public_send(input_tag, @name, @value, input_options) %>
21
21
  <% end %>
22
22
 
23
- <% if @suffix.present? %>
23
+ <% if suffix.present? || @suffix.present? %>
24
24
  <div class="Polaris-TextField__Suffix">
25
- <%= @suffix %>
25
+ <%= suffix || @suffix %>
26
26
  </div>
27
27
  <% end %>
28
28
 
@@ -19,6 +19,8 @@ module Polaris
19
19
 
20
20
  attr_reader :value
21
21
 
22
+ renders_one :prefix
23
+ renders_one :suffix
22
24
  renders_one :connected_left
23
25
  renders_one :connected_right
24
26
 
@@ -143,7 +145,7 @@ module Polaris
143
145
  default_options[:rows] = @rows
144
146
  end
145
147
 
146
- default_options.deep_merge(@input_options).tap do |opts|
148
+ default_options.deep_merge(@input_options).compact.tap do |opts|
147
149
  opts[:class] = class_names(
148
150
  opts[:class],
149
151
  "Polaris-TextField__Input",
@@ -1,16 +1,52 @@
1
1
  module Polaris
2
2
  class FormBuilder < ActionView::Helpers::FormBuilder
3
- def polaris_text_field(method, **options, &block)
4
- options[:error] ||= errors_for(method)
5
- @template.render(
6
- Polaris::TextFieldComponent.new(form: self, attribute: method, **options, &block)
7
- )
3
+ attr_reader :template
4
+
5
+ delegate :render, :pluralize, to: :template
6
+
7
+ def errors_summary
8
+ return if object.blank?
9
+ return unless object.errors.any?
10
+
11
+ model_name = object.class.model_name.human.downcase
12
+
13
+ render Polaris::BannerComponent.new(
14
+ title: "There's #{pluralize(object.errors.count, "error")} with this #{model_name}:",
15
+ status: :critical,
16
+ ) do
17
+ render(Polaris::ListComponent.new) do |list|
18
+ object.errors.each do |error|
19
+ list.item { error.full_message }
20
+ end
21
+ end
22
+ end
8
23
  end
9
24
 
10
- def errors_for(method)
25
+ def error_for(method)
11
26
  return if object.blank?
12
27
  return unless object.errors.key?(method)
13
- object.errors[method].join(', ').html_safe
28
+
29
+ object.errors.full_messages_for(method)&.first
30
+ end
31
+
32
+ def polaris_text_field(method, **options, &block)
33
+ options[:error] ||= error_for(method)
34
+ if options[:error_hidden] && options[:error]
35
+ options[:error] = !!options[:error]
36
+ end
37
+ render Polaris::TextFieldComponent.new(form: self, attribute: method, **options, &block)
38
+ end
39
+
40
+ def polaris_select(method, **options, &block)
41
+ options[:error] ||= error_for(method)
42
+ if options[:error_hidden] && options[:error]
43
+ options[:error] = !!options[:error]
44
+ end
45
+ value = object&.public_send(method)
46
+ if value.present?
47
+ options[:selected] = value
48
+ end
49
+ render Polaris::SelectComponent.new(form: self, attribute: method, **options, &block)
14
50
  end
15
51
  end
16
52
  end
@@ -0,0 +1,19 @@
1
+ module Polaris
2
+ module UrlHelper
3
+ def polaris_button_to(name = nil, options = nil, html_options = nil, &block)
4
+ html_options, options = options, name if block_given?
5
+ options ||= {}
6
+ html_options ||= {}
7
+ html_options[:classes] = html_options[:class]
8
+ html_options.delete(:class)
9
+
10
+ button = Polaris::HeadlessButton.new(submit: true, **html_options)
11
+ button = button.with_content(name) unless block_given?
12
+ content = render(button, &block)
13
+
14
+ button_to(options, button.html_options) do
15
+ content
16
+ end
17
+ end
18
+ end
19
+ end
@@ -30,11 +30,15 @@ module Polaris
30
30
  pagination: "Polaris::PaginationComponent",
31
31
  progress_bar: "Polaris::ProgressBarComponent",
32
32
  radio_button: "Polaris::RadioButtonComponent",
33
+ resource_list: "Polaris::ResourceListComponent",
34
+ resource_item: "Polaris::ResourceItemComponent",
33
35
  select: "Polaris::SelectComponent",
34
36
  shopify_navigation: "Polaris::ShopifyNavigationComponent",
35
37
  stack: "Polaris::StackComponent",
36
38
  subheading: "Polaris::SubheadingComponent",
37
39
  spinner: "Polaris::SpinnerComponent",
40
+ skeleton_body_text: "Polaris::SkeletonBodyTextComponent",
41
+ tag: "Polaris::TagComponent",
38
42
  text_container: "Polaris::TextContainerComponent",
39
43
  text_field: "Polaris::TextFieldComponent",
40
44
  text_style: "Polaris::TextStyleComponent",
@@ -1,9 +1,11 @@
1
+ import ResourceItem from './resource_item_controller'
1
2
  import Select from './select_controller'
2
3
  import TextField from './text_field_controller'
3
4
 
4
- export { Select, TextField }
5
+ export { ResourceItem, Select, TextField }
5
6
 
6
7
  export function registerPolarisControllers(application) {
8
+ application.register('polaris-resource-item', ResourceItem)
7
9
  application.register('polaris-select', Select)
8
10
  application.register('polaris-text-field', TextField)
9
11
  }
@@ -0,0 +1,15 @@
1
+ import { Controller } from 'stimulus'
2
+
3
+ export default class extends Controller {
4
+ static targets = ['link']
5
+
6
+ open(event) {
7
+ if (this.hasLinkTarget && this.targetNotClickable(event.target)) {
8
+ this.linkTarget.click()
9
+ }
10
+ }
11
+
12
+ targetNotClickable(element) {
13
+ return !element.closest('a') && !element.closest('button') && element.nodeName !== "INPUT"
14
+ }
15
+ }
@@ -99,7 +99,6 @@ export default class extends Controller {
99
99
 
100
100
  // Making sure the new value has the same length of decimal places as the
101
101
  // step / value has.
102
- console.log(numericValue, this.stepValue)
103
102
  const decimalPlaces = Math.max(dpl(numericValue), dpl(this.stepValue))
104
103
 
105
104
  const newValue = Math.min(
@@ -0,0 +1,5 @@
1
+ Description:
2
+ Creates or adds import of NPM package to your application + additional installation steps.
3
+
4
+ Example:
5
+ rails generate polaris_view_components:install
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails/generators/active_record'
4
+
5
+ module PolarisViewComponents
6
+ class InstallGenerator < Rails::Generators::Base
7
+ source_root File.expand_path('templates', __dir__)
8
+
9
+ def add_npm_package
10
+ say "Adding NPM package", :green
11
+ run "yarn add polaris-view-components"
12
+ end
13
+
14
+ def add_to_stimulus_controller
15
+ say "Adding import to to Stimulus controller", :green
16
+ dir_path = "app/javascript/controllers"
17
+ empty_directory('app/javascript')
18
+ empty_directory(dir_path)
19
+
20
+ file_path = "#{dir_path}/index.js"
21
+
22
+ unless File.exist?(file_path)
23
+ copy_file 'stimulus_index.js', file_path
24
+ end
25
+
26
+ append_to_file file_path do
27
+ "import { registerPolarisControllers } from 'polaris-view-components'\nregisterPolarisControllers(application)"
28
+ end
29
+ end
30
+
31
+ def show_readme
32
+ readme 'README'
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,14 @@
1
+ ===============================================================================
2
+
3
+ Some manual setup is still required:
4
+
5
+ 1. Setup Polaris styles in your layouts <head> tag:
6
+
7
+ <link rel="stylesheet" href="https://unpkg.com/@shopify/polaris@6.6.0/dist/styles.css" />
8
+ <%= stylesheet_link_tag 'polaris_view_components' %>
9
+
10
+ 2. Define Polaris style on your <body> tag:
11
+
12
+ <body style="<%= polaris_body_styles %>">
13
+
14
+ ===============================================================================
@@ -0,0 +1,7 @@
1
+ import { Application } from 'stimulus'
2
+ import { definitionsFromContext } from 'stimulus/webpack-helpers'
3
+
4
+ const application = Application.start(document.documentElement)
5
+ const context = require.context('.', true, /_controller\.js$/)
6
+ application.load(definitionsFromContext(context))
7
+
@@ -20,6 +20,7 @@ module Polaris
20
20
  initializer "polaris_view_components.helpers" do
21
21
  ActiveSupport.on_load(:action_controller_base) do
22
22
  helper Polaris::ViewHelper
23
+ helper Polaris::UrlHelper
23
24
  helper Polaris::ActionHelper
24
25
  helper Polaris::ConditionalHelper
25
26
  end
@@ -1,5 +1,5 @@
1
1
  module Polaris
2
2
  module ViewComponents
3
- VERSION = "0.1.0"
3
+ VERSION = "0.2.0"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: polaris_view_components
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dan Gamble
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2021-08-08 00:00:00.000000000 Z
12
+ date: 2021-09-08 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -503,6 +503,8 @@ files:
503
503
  - app/components/polaris/form_layout_component.html.erb
504
504
  - app/components/polaris/form_layout_component.rb
505
505
  - app/components/polaris/heading_component.rb
506
+ - app/components/polaris/headless_button.html.erb
507
+ - app/components/polaris/headless_button.rb
506
508
  - app/components/polaris/icon_component.html.erb
507
509
  - app/components/polaris/icon_component.rb
508
510
  - app/components/polaris/inline_error_component.html.erb
@@ -530,15 +532,22 @@ files:
530
532
  - app/components/polaris/progress_bar_component.rb
531
533
  - app/components/polaris/radio_button_component.html.erb
532
534
  - app/components/polaris/radio_button_component.rb
535
+ - app/components/polaris/resource_item_component.html.erb
536
+ - app/components/polaris/resource_item_component.rb
537
+ - app/components/polaris/resource_list_component.rb
533
538
  - app/components/polaris/select_component.html.erb
534
539
  - app/components/polaris/select_component.rb
535
540
  - app/components/polaris/shopify_navigation_component.html.erb
536
541
  - app/components/polaris/shopify_navigation_component.rb
542
+ - app/components/polaris/skeleton_body_text_component.html.erb
543
+ - app/components/polaris/skeleton_body_text_component.rb
537
544
  - app/components/polaris/spinner_component.html.erb
538
545
  - app/components/polaris/spinner_component.rb
539
546
  - app/components/polaris/stack_component.html.erb
540
547
  - app/components/polaris/stack_component.rb
541
548
  - app/components/polaris/subheading_component.rb
549
+ - app/components/polaris/tag_component.html.erb
550
+ - app/components/polaris/tag_component.rb
542
551
  - app/components/polaris/text_container_component.rb
543
552
  - app/components/polaris/text_field_component.html.erb
544
553
  - app/components/polaris/text_field_component.rb
@@ -552,11 +561,17 @@ files:
552
561
  - app/helpers/polaris/fetch_or_fallback_helper.rb
553
562
  - app/helpers/polaris/form_builder.rb
554
563
  - app/helpers/polaris/option_helper.rb
564
+ - app/helpers/polaris/url_helper.rb
555
565
  - app/helpers/polaris/view_helper.rb
556
566
  - app/javascript/polaris/index.js
567
+ - app/javascript/polaris/resource_item_controller.js
557
568
  - app/javascript/polaris/select_controller.js
558
569
  - app/javascript/polaris/text_field_controller.js
559
570
  - app/validators/type_validator.rb
571
+ - lib/generators/polaris_view_components/USAGE
572
+ - lib/generators/polaris_view_components/install_generator.rb
573
+ - lib/generators/polaris_view_components/templates/README
574
+ - lib/generators/polaris_view_components/templates/stimulus_index.js
560
575
  - lib/polaris/view_components.rb
561
576
  - lib/polaris/view_components/engine.rb
562
577
  - lib/polaris/view_components/version.rb