polaris_view_components 0.1.1 → 0.3.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 (36) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +24 -1
  3. data/app/assets/javascripts/{polaris.js → polaris_view_components.js} +27 -33
  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/dropzone/controller.js +1 -1
  10. data/app/components/polaris/headless_button.html.erb +22 -0
  11. data/app/components/polaris/headless_button.rb +95 -0
  12. data/app/components/polaris/resource_item_component.html.erb +27 -0
  13. data/app/components/polaris/resource_item_component.rb +75 -0
  14. data/app/components/polaris/resource_list_component.rb +32 -0
  15. data/app/components/polaris/select_component.html.erb +11 -2
  16. data/app/components/polaris/select_component.rb +2 -0
  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 → polaris_view_components}/index.js +3 -1
  27. data/app/javascript/polaris_view_components/resource_item_controller.js +15 -0
  28. data/app/javascript/{polaris → polaris_view_components}/select_controller.js +1 -1
  29. data/app/javascript/{polaris → polaris_view_components}/text_field_controller.js +1 -2
  30. data/lib/generators/polaris_view_components/USAGE +5 -0
  31. data/lib/generators/polaris_view_components/install_generator.rb +35 -0
  32. data/lib/generators/polaris_view_components/templates/README +14 -0
  33. data/lib/generators/polaris_view_components/templates/stimulus_index.js +6 -0
  34. data/lib/polaris/view_components/engine.rb +4 -1
  35. data/lib/polaris/view_components/version.rb +1 -1
  36. metadata +23 -8
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1a11eec04f3214877a985fa4b015bbb30aaa11b5ba6bd88728eee58cb457b72c
4
- data.tar.gz: 4fcc63ed09e2a5de504f9006e2564097ccd7c7cf0e2bfc4424762dd24fa1aaf9
3
+ metadata.gz: 1eda78e6803a1783585a9912d600193f29bba781d019204be62bd1cab484e97a
4
+ data.tar.gz: 5b9ba5de1405b1eb089991c7a2db6117d00bddc7787b6484515e35ecddd4b55e
5
5
  SHA512:
6
- metadata.gz: dcf50eb971d01da05634bcc8c9e0c159b131100c42db1ab65e2d22077bcd53d4414772ae992c69e5185553eb32916fe876e9357ccd5fd286af7a0a84b7b60f95
7
- data.tar.gz: eacaf9cf0bf374e2e8d0b625b2ddd9df1aa9e116ddaae67623510df7b8d96f60969b426e51dc2d9544bf6a79005b38c635e716852807bcc3316ac66196460c9e
6
+ metadata.gz: c433aa42655eacf3e55eccb3709d25356e6219a61f9f5880d529dd2c51f41ca8fe019a1f699675f0832efabdae104e2a0e26fb4a0100b1c8e0d0005b7917f0b5
7
+ data.tar.gz: 44ad24c6ff886a6bb9cb11d5fdce9936218f66337924c6474dcd78b4e68357fa08871492f38affb31dac7f19cce81ea4d7151179bba38ef656910ef49b2e0a72
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
@@ -26,6 +28,11 @@ In `Gemfile`, add:
26
28
  gem 'polaris_view_components'
27
29
  ```
28
30
 
31
+ Run install generator:
32
+ ```bash
33
+ rails generate polaris_view_components:install
34
+ ```
35
+
29
36
  Setup Polaris styles in your layouts `<head>` tag:
30
37
 
31
38
  ```erb
@@ -33,6 +40,22 @@ 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
+ ### Importmaps
50
+
51
+ Add to `config/importmap.rb`:
52
+
53
+ ```rb
54
+ pin "polaris-view-components", to: "polaris_view_components.js"
55
+ ```
56
+
57
+ ### NPM
58
+
36
59
  Install NPM package:
37
60
  ```bash
38
61
  yarn add polaris-view-components
@@ -42,7 +65,7 @@ Add to `app/javascript/controllers/index.js`:
42
65
  ```javascript
43
66
  // Polaris ViewComponents
44
67
  import { registerPolarisControllers } from "polaris-view-components"
45
- registerPolarisControllers(application)
68
+ registerPolarisControllers(Stimulus)
46
69
  ```
47
70
 
48
71
  ## Dependencies
@@ -1,20 +1,19 @@
1
- import { Controller } from "stimulus";
1
+ import { Controller } from "@hotwired/stimulus";
2
2
 
3
- function _defineProperty(obj, key, value) {
4
- if (key in obj) {
5
- Object.defineProperty(obj, key, {
6
- value: value,
7
- enumerable: true,
8
- configurable: true,
9
- writable: true
10
- });
11
- } else {
12
- obj[key] = value;
3
+ class ResourceItem extends Controller {
4
+ static targets=[ "link" ];
5
+ open(event) {
6
+ if (this.hasLinkTarget && this.targetNotClickable(event.target)) {
7
+ this.linkTarget.click();
8
+ }
9
+ }
10
+ targetNotClickable(element) {
11
+ return !element.closest("a") && !element.closest("button") && element.nodeName !== "INPUT";
13
12
  }
14
- return obj;
15
13
  }
16
14
 
17
- class _class$1 extends Controller {
15
+ class Select extends Controller {
16
+ static targets=[ "selectedOption" ];
18
17
  update(event) {
19
18
  const select = event.currentTarget;
20
19
  const option = select.options[select.selectedIndex];
@@ -22,9 +21,17 @@ class _class$1 extends Controller {
22
21
  }
23
22
  }
24
23
 
25
- _defineProperty(_class$1, "targets", [ "selectedOption" ]);
26
-
27
- class _class extends Controller {
24
+ class TextField extends Controller {
25
+ static targets=[ "input", "clearButton", "characterCount" ];
26
+ static classes=[ "hasValue", "clearButtonHidden" ];
27
+ static values={
28
+ value: String,
29
+ labelTemplate: String,
30
+ textTemplate: String,
31
+ step: Number,
32
+ min: Number,
33
+ max: Number
34
+ };
28
35
  connect() {
29
36
  this.syncValue();
30
37
  this.stepValue = this.inputTarget.getAttribute("step");
@@ -85,29 +92,16 @@ class _class extends Controller {
85
92
  if (isNaN(numericValue)) {
86
93
  return;
87
94
  }
88
- console.log(numericValue, this.stepValue);
89
95
  const decimalPlaces = Math.max(dpl(numericValue), dpl(this.stepValue));
90
96
  const newValue = Math.min(Number(this.maxValue), Math.max(numericValue + steps * this.stepValue, Number(this.minValue)));
91
97
  this.value = String(newValue.toFixed(decimalPlaces));
92
98
  }
93
99
  }
94
100
 
95
- _defineProperty(_class, "targets", [ "input", "clearButton", "characterCount" ]);
96
-
97
- _defineProperty(_class, "classes", [ "hasValue", "clearButtonHidden" ]);
98
-
99
- _defineProperty(_class, "values", {
100
- value: String,
101
- labelTemplate: String,
102
- textTemplate: String,
103
- step: Number,
104
- min: Number,
105
- max: Number
106
- });
107
-
108
101
  function registerPolarisControllers(application) {
109
- application.register("polaris-select", _class$1);
110
- application.register("polaris-text-field", _class);
102
+ application.register("polaris-resource-item", ResourceItem);
103
+ application.register("polaris-select", Select);
104
+ application.register("polaris-text-field", TextField);
111
105
  }
112
106
 
113
- export { _class$1 as Select, _class as TextField, registerPolarisControllers };
107
+ export { ResourceItem, Select, 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
@@ -1,4 +1,4 @@
1
- import { Controller } from 'stimulus'
1
+ import { Controller } from "@hotwired/stimulus"
2
2
 
3
3
  import { fileAccepted, getDataTransferFiles } from './utils'
4
4
 
@@ -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
@@ -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 "@hotwired/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
+ }
@@ -1,4 +1,4 @@
1
- import { Controller } from 'stimulus'
1
+ import { Controller } from "@hotwired/stimulus"
2
2
 
3
3
  export default class extends Controller {
4
4
  static targets = ['selectedOption']
@@ -1,4 +1,4 @@
1
- import { Controller } from 'stimulus'
1
+ import { Controller } from "@hotwired/stimulus"
2
2
 
3
3
  export default class extends Controller {
4
4
  static targets = ['input', 'clearButton', 'characterCount']
@@ -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(Stimulus)"
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,6 @@
1
+ import { Application } from "@hotwired/stimulus"
2
+ import { definitionsFromContext } from "@hotwired/stimulus-webpack-helpers"
3
+
4
+ window.Stimulus = Application.start()
5
+ const context = require.context("./", true, /\.js$/)
6
+ Stimulus.load(definitionsFromContext(context))
@@ -13,13 +13,16 @@ module Polaris
13
13
 
14
14
  initializer "polaris_view_components.assets" do |app|
15
15
  if app.config.respond_to?(:assets)
16
- app.config.assets.precompile += %w[polaris_view_components.css]
16
+ app.config.assets.precompile += %w[
17
+ polaris_view_components.js polaris_view_components.css
18
+ ]
17
19
  end
18
20
  end
19
21
 
20
22
  initializer "polaris_view_components.helpers" do
21
23
  ActiveSupport.on_load(:action_controller_base) do
22
24
  helper Polaris::ViewHelper
25
+ helper Polaris::UrlHelper
23
26
  helper Polaris::ActionHelper
24
27
  helper Polaris::ConditionalHelper
25
28
  end
@@ -1,5 +1,5 @@
1
1
  module Polaris
2
2
  module ViewComponents
3
- VERSION = "0.1.1"
3
+ VERSION = "0.3.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.1
4
+ version: 0.3.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-09 00:00:00.000000000 Z
12
+ date: 2021-10-05 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -20,7 +20,7 @@ dependencies:
20
20
  version: 5.0.0
21
21
  - - "<"
22
22
  - !ruby/object:Gem::Version
23
- version: 7.0.0
23
+ version: 8.0.0
24
24
  type: :runtime
25
25
  prerelease: false
26
26
  version_requirements: !ruby/object:Gem::Requirement
@@ -30,7 +30,7 @@ dependencies:
30
30
  version: 5.0.0
31
31
  - - "<"
32
32
  - !ruby/object:Gem::Version
33
- version: 7.0.0
33
+ version: 8.0.0
34
34
  - !ruby/object:Gem::Dependency
35
35
  name: view_component
36
36
  requirement: !ruby/object:Gem::Requirement
@@ -447,7 +447,7 @@ files:
447
447
  - app/assets/icons/polaris/WearableMajor.svg
448
448
  - app/assets/icons/polaris/WholesaleMajor.svg
449
449
  - app/assets/icons/polaris/WifiMajor.svg
450
- - app/assets/javascripts/polaris.js
450
+ - app/assets/javascripts/polaris_view_components.js
451
451
  - app/assets/stylesheets/polaris_view_components.css
452
452
  - app/components/polaris/action.rb
453
453
  - app/components/polaris/application_component.rb
@@ -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
- - app/javascript/polaris/index.js
557
- - app/javascript/polaris/select_controller.js
558
- - app/javascript/polaris/text_field_controller.js
566
+ - app/javascript/polaris_view_components/index.js
567
+ - app/javascript/polaris_view_components/resource_item_controller.js
568
+ - app/javascript/polaris_view_components/select_controller.js
569
+ - app/javascript/polaris_view_components/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