polaris_view_components 0.1.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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