primer_view_components 0.0.17 → 0.0.22

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +102 -0
  3. data/app/assets/javascripts/primer_view_components.js +2 -0
  4. data/app/assets/javascripts/primer_view_components.js.map +1 -0
  5. data/app/components/primer/avatar_component.rb +27 -9
  6. data/app/components/primer/avatar_stack_component.html.erb +10 -0
  7. data/app/components/primer/avatar_stack_component.rb +81 -0
  8. data/app/components/primer/base_component.rb +8 -5
  9. data/app/components/primer/blankslate_component.html.erb +3 -3
  10. data/app/components/primer/blankslate_component.rb +18 -25
  11. data/app/components/primer/border_box_component.html.erb +4 -18
  12. data/app/components/primer/border_box_component.rb +75 -68
  13. data/app/components/primer/box_component.rb +10 -0
  14. data/app/components/primer/breadcrumb_component.rb +3 -2
  15. data/app/components/primer/button_component.rb +3 -3
  16. data/app/components/primer/button_group_component.html.erb +5 -0
  17. data/app/components/primer/button_group_component.rb +37 -0
  18. data/app/components/primer/button_marketing_component.rb +73 -0
  19. data/app/components/primer/component.rb +16 -0
  20. data/app/components/primer/counter_component.rb +16 -9
  21. data/app/components/primer/details_component.html.erb +2 -6
  22. data/app/components/primer/details_component.rb +28 -37
  23. data/app/components/primer/dropdown/menu_component.html.erb +12 -0
  24. data/app/components/primer/dropdown/menu_component.rb +48 -0
  25. data/app/components/primer/dropdown_component.html.erb +9 -0
  26. data/app/components/primer/dropdown_component.rb +75 -0
  27. data/app/components/primer/dropdown_menu_component.rb +35 -3
  28. data/app/components/primer/flash_component.html.erb +4 -7
  29. data/app/components/primer/flash_component.rb +18 -17
  30. data/app/components/primer/flex_component.rb +47 -9
  31. data/app/components/primer/flex_item_component.rb +16 -1
  32. data/app/components/primer/heading_component.rb +9 -0
  33. data/app/components/primer/label_component.rb +6 -6
  34. data/app/components/primer/layout_component.rb +2 -2
  35. data/app/components/primer/link_component.rb +6 -2
  36. data/app/components/primer/markdown_component.rb +293 -0
  37. data/app/components/primer/menu_component.html.erb +6 -0
  38. data/app/components/primer/menu_component.rb +71 -0
  39. data/app/components/primer/octicon_component.rb +13 -6
  40. data/app/components/primer/popover_component.rb +5 -3
  41. data/app/components/primer/primer.js +1 -0
  42. data/app/components/primer/primer.ts +1 -0
  43. data/app/components/primer/progress_bar_component.rb +6 -6
  44. data/app/components/primer/spinner_component.rb +8 -5
  45. data/app/components/primer/state_component.rb +23 -12
  46. data/app/components/primer/subhead_component.rb +6 -3
  47. data/app/components/primer/tab_container_component.js +1 -0
  48. data/app/components/primer/tab_container_component.rb +41 -0
  49. data/app/components/primer/tab_container_component.ts +1 -0
  50. data/app/components/primer/tab_nav_component.html.erb +17 -0
  51. data/app/components/primer/tab_nav_component.rb +108 -0
  52. data/app/components/primer/text_component.rb +1 -1
  53. data/app/components/primer/timeline_item_component.html.erb +4 -16
  54. data/app/components/primer/timeline_item_component.rb +41 -49
  55. data/app/components/primer/tooltip_component.rb +88 -0
  56. data/app/components/primer/truncate_component.rb +41 -0
  57. data/app/components/primer/underline_nav_component.rb +26 -1
  58. data/{lib → app/lib}/primer/class_name_helper.rb +1 -0
  59. data/app/lib/primer/classify.rb +280 -0
  60. data/app/lib/primer/classify/cache.rb +125 -0
  61. data/{lib → app/lib}/primer/fetch_or_fallback_helper.rb +1 -0
  62. data/{lib → app/lib}/primer/join_style_arguments_helper.rb +1 -0
  63. data/app/lib/primer/view_helper.rb +22 -0
  64. data/app/lib/primer/view_helper/dsl.rb +34 -0
  65. data/lib/primer/view_components.rb +32 -0
  66. data/lib/primer/view_components/engine.rb +11 -2
  67. data/lib/primer/view_components/version.rb +5 -1
  68. data/lib/yard/renders_many_handler.rb +19 -0
  69. data/lib/yard/renders_one_handler.rb +19 -0
  70. data/static/statuses.json +1 -0
  71. metadata +94 -24
  72. data/app/components/primer/view_components.rb +0 -52
  73. data/lib/primer/classify.rb +0 -250
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 70daa13e7909487e01c01f4759a88740922070c985ac9604df738614d48c57a1
4
- data.tar.gz: 257383c54d408d94c8aac723804a1db9b75dee88527f60ce101f70514259567c
3
+ metadata.gz: 3155227cd7ba3d3c02063d1021e1430df8d514a7feabe0b5fad0680c593ffc3c
4
+ data.tar.gz: 344362c292977c1dd6b84d283b1a5b5fea8894d2dd0aa5be0c1007fdbf4bf397
5
5
  SHA512:
6
- metadata.gz: 65bef1719944f20523e8670d382474fa15a49cd03eab6a39578ad3901933668c3d2bcfdff9da7e46ba9fdac8587447b92984a6e4c67028732f9ba2f18dc9cf52
7
- data.tar.gz: b578660620dc448087463fd24361c652a8fd9ead88cd6693a658af94f497eb68361e3236cb43386da66f58666c72051d5728bb67b4be6c832ee815c54f59e4c8
6
+ metadata.gz: 76e300f1f5cd3cf5e861f48246f6124ad2432014a003b4b8dffe3b373415d47c43af118965c879f8fe58bfd111dded1a9270c7e2f824020022b14990028210dd
7
+ data.tar.gz: 899f5cf473acde6ff778bd2a86ded0bbb90aea6d8bce9fca0483c455aefc3b8c68388cb0eec578129d6b5703ae53eeeacc14701d4b2fcbdaaba47fd447b117f6
data/CHANGELOG.md CHANGED
@@ -1,6 +1,108 @@
1
1
  # CHANGELOG
2
2
 
3
3
  ## main
4
+
5
+ ## 0.0.22
6
+
7
+ * Add view helpers to easily render Primer components.
8
+
9
+ *Manuel Puyol*
10
+
11
+ * Add `TabContainer` and `TabNav` components.
12
+
13
+ *Manuel Puyol*
14
+
15
+ * Promote `StateComponent` to beta.
16
+
17
+ *Simon Taranto*
18
+
19
+ * **Breaking change**: Upgrade `BorderBoxComponent` to use Slots V2.
20
+
21
+ *Manuel Puyol*
22
+
23
+ * **Breaking change**: Upgrade `StateComponent` to support functional colors. This change requires using [@primer/css-next](https://www.npmjs.com/package/@primer/css-next). The required changes will be upstreamed to @primer/css at a later date.
24
+
25
+ *Simon Taranto*
26
+
27
+ * **Breaking change**: Upgrade `DetailsComponent` to use Slots V2.
28
+
29
+ *Simon Taranto*
30
+
31
+ ## 0.0.21
32
+
33
+ * **Breaking change**: Upgrade `FlashComponent` to use Slots V2.
34
+
35
+ *Joel Hawksley, Simon Taranto*
36
+
37
+ * **Breaking change**: Upgrade `BlankslateComponent` to use Slots V2.
38
+
39
+ *Manuel Puyol*
40
+
41
+ * **Breaking change**: Upgrade `TimelineItemComponent` to use Slots V2.
42
+
43
+ *Manuel Puyol*
44
+
45
+ ## 0.0.20
46
+
47
+ * Fix bug when empty string was passed to Classify.
48
+
49
+ *Manuel Puyol*
50
+
51
+ ## 0.0.19
52
+
53
+ * Add support for functional colors to `color` system argument.
54
+
55
+ *Jake Shorty*
56
+
57
+ * Add `AvatarStack`, `Dropdown`, `Markdown` and `Menu` components.
58
+
59
+ *Manuel Puyol*
60
+
61
+ * Deprecate `DropdownMenuComponent`.
62
+
63
+ *Manuel Puyol*
64
+
65
+ * Fix `Avatar` bug when used with links.
66
+
67
+ *Manuel Puyol*
68
+
69
+ * Add cache for common Primer values.
70
+
71
+ *Blake Williams*
72
+
73
+ * Add support for `octicons_helper` v12.
74
+
75
+ *Cole Bemis*
76
+
77
+ * Add support for `border: true` to apply the `border` class.
78
+
79
+ *Simon Taranto*
80
+
81
+ * Promote `Avatar`, `Link`, and `Counter` components to beta.
82
+
83
+ *Simon Taranto*
84
+
85
+ * **Breaking change**: Drop support for Ruby 2.4.
86
+
87
+ *Simon Taranto*
88
+
89
+ ## 0.0.18
90
+
91
+ * Add `border_radius` system argument.
92
+
93
+ *Ash Guillaume*
94
+
95
+ * Add `animation` system argument.
96
+
97
+ *Manuel Puyol*
98
+
99
+ * Add `Truncate`, `ButtonGroup` and `ButtonMarketing` components.
100
+
101
+ *Manuel Puyol*
102
+
103
+ * Add `Tooltip` component.
104
+
105
+ *Simon Taranto*
4
106
 
5
107
  ## 0.0.17
6
108
 
@@ -0,0 +1,2 @@
1
+ class t extends HTMLElement{constructor(){super(),this.addEventListener("keydown",(t=>{const r=t.target;if(!(r instanceof HTMLElement))return;if("tab"!==r.getAttribute("role")&&!r.closest('[role="tablist"]'))return;const a=Array.from(this.querySelectorAll('[role="tablist"] [role="tab"]')),n=a.indexOf(a.find((t=>t.matches('[aria-selected="true"]'))));if("ArrowRight"===t.code){let t=n+1;t>=a.length&&(t=0),e(this,t)}else if("ArrowLeft"===t.code){let t=n-1;t<0&&(t=a.length-1),e(this,t)}else"Home"===t.code?(e(this,0),t.preventDefault()):"End"===t.code&&(e(this,a.length-1),t.preventDefault())})),this.addEventListener("click",(t=>{const r=Array.from(this.querySelectorAll('[role="tablist"] [role="tab"]'));if(!(t.target instanceof Element))return;const a=t.target.closest('[role="tab"]');if(!a||!a.closest('[role="tablist"]'))return;e(this,r.indexOf(a))}))}connectedCallback(){for(const t of this.querySelectorAll('[role="tablist"] [role="tab"]'))t.hasAttribute("aria-selected")||t.setAttribute("aria-selected","false"),t.hasAttribute("tabindex")||("true"===t.getAttribute("aria-selected")?t.setAttribute("tabindex","0"):t.setAttribute("tabindex","-1"))}}function e(t,e){const r=t.querySelectorAll('[role="tablist"] [role="tab"]'),a=t.querySelectorAll('[role="tabpanel"]'),n=r[e],i=a[e];if(!!t.dispatchEvent(new CustomEvent("tab-container-change",{bubbles:!0,cancelable:!0,detail:{relatedTarget:i}}))){for(const t of r)t.setAttribute("aria-selected","false"),t.setAttribute("tabindex","-1");for(const t of a)t.hidden=!0,t.hasAttribute("tabindex")||t.hasAttribute("data-tab-container-no-tabstop")||t.setAttribute("tabindex","0");n.setAttribute("aria-selected","true"),n.setAttribute("tabindex","0"),n.focus(),i.hidden=!1,t.dispatchEvent(new CustomEvent("tab-container-changed",{bubbles:!0,detail:{relatedTarget:i}}))}}window.customElements.get("tab-container")||(window.TabContainerElement=t,window.customElements.define("tab-container",t));
2
+ //# sourceMappingURL=primer_view_components.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"primer_view_components.js","sources":["../../../node_modules/@github/tab-container-element/dist/index.js"],"sourcesContent":["export default class TabContainerElement extends HTMLElement {\n constructor() {\n super();\n this.addEventListener('keydown', (event) => {\n const target = event.target;\n if (!(target instanceof HTMLElement))\n return;\n if (target.getAttribute('role') !== 'tab' && !target.closest('[role=\"tablist\"]'))\n return;\n const tabs = Array.from(this.querySelectorAll('[role=\"tablist\"] [role=\"tab\"]'));\n const currentIndex = tabs.indexOf(tabs.find(tab => tab.matches('[aria-selected=\"true\"]')));\n if (event.code === 'ArrowRight') {\n let index = currentIndex + 1;\n if (index >= tabs.length)\n index = 0;\n selectTab(this, index);\n }\n else if (event.code === 'ArrowLeft') {\n let index = currentIndex - 1;\n if (index < 0)\n index = tabs.length - 1;\n selectTab(this, index);\n }\n else if (event.code === 'Home') {\n selectTab(this, 0);\n event.preventDefault();\n }\n else if (event.code === 'End') {\n selectTab(this, tabs.length - 1);\n event.preventDefault();\n }\n });\n this.addEventListener('click', (event) => {\n const tabs = Array.from(this.querySelectorAll('[role=\"tablist\"] [role=\"tab\"]'));\n if (!(event.target instanceof Element))\n return;\n const tab = event.target.closest('[role=\"tab\"]');\n if (!tab || !tab.closest('[role=\"tablist\"]'))\n return;\n const index = tabs.indexOf(tab);\n selectTab(this, index);\n });\n }\n connectedCallback() {\n for (const tab of this.querySelectorAll('[role=\"tablist\"] [role=\"tab\"]')) {\n if (!tab.hasAttribute('aria-selected')) {\n tab.setAttribute('aria-selected', 'false');\n }\n if (!tab.hasAttribute('tabindex')) {\n if (tab.getAttribute('aria-selected') === 'true') {\n tab.setAttribute('tabindex', '0');\n }\n else {\n tab.setAttribute('tabindex', '-1');\n }\n }\n }\n }\n}\nfunction selectTab(tabContainer, index) {\n const tabs = tabContainer.querySelectorAll('[role=\"tablist\"] [role=\"tab\"]');\n const panels = tabContainer.querySelectorAll('[role=\"tabpanel\"]');\n const selectedTab = tabs[index];\n const selectedPanel = panels[index];\n const cancelled = !tabContainer.dispatchEvent(new CustomEvent('tab-container-change', {\n bubbles: true,\n cancelable: true,\n detail: { relatedTarget: selectedPanel }\n }));\n if (cancelled)\n return;\n for (const tab of tabs) {\n tab.setAttribute('aria-selected', 'false');\n tab.setAttribute('tabindex', '-1');\n }\n for (const panel of panels) {\n panel.hidden = true;\n if (!panel.hasAttribute('tabindex') && !panel.hasAttribute('data-tab-container-no-tabstop')) {\n panel.setAttribute('tabindex', '0');\n }\n }\n selectedTab.setAttribute('aria-selected', 'true');\n selectedTab.setAttribute('tabindex', '0');\n selectedTab.focus();\n selectedPanel.hidden = false;\n tabContainer.dispatchEvent(new CustomEvent('tab-container-changed', {\n bubbles: true,\n detail: { relatedTarget: selectedPanel }\n }));\n}\nif (!window.customElements.get('tab-container')) {\n window.TabContainerElement = TabContainerElement;\n window.customElements.define('tab-container', TabContainerElement);\n}\n//# sourceMappingURL=index.js.map"],"names":["TabContainerElement","HTMLElement","[object Object]","super","this","addEventListener","event","target","getAttribute","closest","tabs","Array","from","querySelectorAll","currentIndex","indexOf","find","tab","matches","code","index","length","selectTab","preventDefault","Element","hasAttribute","setAttribute","tabContainer","panels","selectedTab","selectedPanel","dispatchEvent","CustomEvent","bubbles","cancelable","detail","relatedTarget","panel","hidden","focus","window","customElements","get","define"],"mappings":"AAAe,MAAMA,UAA4BC,YAC7CC,cACIC,QACAC,KAAKC,iBAAiB,WAAYC,IAC9B,MAAMC,EAASD,EAAMC,OACrB,KAAMA,aAAkBN,aACpB,OACJ,GAAoC,QAAhCM,EAAOC,aAAa,UAAsBD,EAAOE,QAAQ,oBACzD,OACJ,MAAMC,EAAOC,MAAMC,KAAKR,KAAKS,iBAAiB,kCACxCC,EAAeJ,EAAKK,QAAQL,EAAKM,MAAKC,GAAOA,EAAIC,QAAQ,6BAC/D,GAAmB,eAAfZ,EAAMa,KAAuB,CAC7B,IAAIC,EAAQN,EAAe,EACvBM,GAASV,EAAKW,SACdD,EAAQ,GACZE,EAAUlB,KAAMgB,QAEf,GAAmB,cAAfd,EAAMa,KAAsB,CACjC,IAAIC,EAAQN,EAAe,EACvBM,EAAQ,IACRA,EAAQV,EAAKW,OAAS,GAC1BC,EAAUlB,KAAMgB,OAEI,SAAfd,EAAMa,MACXG,EAAUlB,KAAM,GAChBE,EAAMiB,kBAEc,QAAfjB,EAAMa,OACXG,EAAUlB,KAAMM,EAAKW,OAAS,GAC9Bf,EAAMiB,qBAGdnB,KAAKC,iBAAiB,SAAUC,IAC5B,MAAMI,EAAOC,MAAMC,KAAKR,KAAKS,iBAAiB,kCAC9C,KAAMP,EAAMC,kBAAkBiB,SAC1B,OACJ,MAAMP,EAAMX,EAAMC,OAAOE,QAAQ,gBACjC,IAAKQ,IAAQA,EAAIR,QAAQ,oBACrB,OAEJa,EAAUlB,KADIM,EAAKK,QAAQE,OAInCf,oBACI,IAAK,MAAMe,KAAOb,KAAKS,iBAAiB,iCAC/BI,EAAIQ,aAAa,kBAClBR,EAAIS,aAAa,gBAAiB,SAEjCT,EAAIQ,aAAa,cACwB,SAAtCR,EAAIT,aAAa,iBACjBS,EAAIS,aAAa,WAAY,KAG7BT,EAAIS,aAAa,WAAY,QAMjD,SAASJ,EAAUK,EAAcP,GAC7B,MAAMV,EAAOiB,EAAad,iBAAiB,iCACrCe,EAASD,EAAad,iBAAiB,qBACvCgB,EAAcnB,EAAKU,GACnBU,EAAgBF,EAAOR,GAM7B,KALmBO,EAAaI,cAAc,IAAIC,YAAY,uBAAwB,CAClFC,SAAS,EACTC,YAAY,EACZC,OAAQ,CAAEC,cAAeN,MAE7B,CAEA,IAAK,MAAMb,KAAOP,EACdO,EAAIS,aAAa,gBAAiB,SAClCT,EAAIS,aAAa,WAAY,MAEjC,IAAK,MAAMW,KAAST,EAChBS,EAAMC,QAAS,EACVD,EAAMZ,aAAa,aAAgBY,EAAMZ,aAAa,kCACvDY,EAAMX,aAAa,WAAY,KAGvCG,EAAYH,aAAa,gBAAiB,QAC1CG,EAAYH,aAAa,WAAY,KACrCG,EAAYU,QACZT,EAAcQ,QAAS,EACvBX,EAAaI,cAAc,IAAIC,YAAY,wBAAyB,CAChEC,SAAS,EACTE,OAAQ,CAAEC,cAAeN,OAG5BU,OAAOC,eAAeC,IAAI,mBAC3BF,OAAOxC,oBAAsBA,EAC7BwC,OAAOC,eAAeE,OAAO,gBAAiB3C"}
@@ -7,15 +7,23 @@ module Primer
7
7
  class AvatarComponent < Primer::Component
8
8
  SMALL_THRESHOLD = 24
9
9
 
10
- #
11
- # @example 34|Default
10
+ # @example Default
12
11
  # <%= render(Primer::AvatarComponent.new(src: "http://placekitten.com/200/200", alt: "@kittenuser")) %>
13
12
  #
14
- # @param src [String] The source url of the avatar image
15
- # @param alt [String] Passed through to alt on img tag
16
- # @param size [Integer] Adds the avatar-small class if less than 24
13
+ # @example Square
14
+ # <%= render(Primer::AvatarComponent.new(src: "http://placekitten.com/200/200", alt: "@kittenuser", square: true)) %>
15
+ #
16
+ # @example Link
17
+ # <%= render(Primer::AvatarComponent.new(href: "#", src: "http://placekitten.com/200/200", alt: "@kittenuser")) %>
18
+ #
19
+ # @param src [String] The source url of the avatar image.
20
+ # @param alt [String] Passed through to alt on img tag.
21
+ # @param size [Integer] Adds the avatar-small class if less than 24.
17
22
  # @param square [Boolean] Used to create a square avatar.
18
- def initialize(src:, alt:, size: 20, square: false, **system_arguments)
23
+ # @param href [String] The URL to link to. If used, component will be wrapped by an `<a>` tag.
24
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
25
+ def initialize(src:, alt:, size: 20, square: false, href: nil, **system_arguments)
26
+ @href = href
19
27
  @system_arguments = system_arguments
20
28
  @system_arguments[:tag] = :img
21
29
  @system_arguments[:src] = src
@@ -25,15 +33,25 @@ module Primer
25
33
  @system_arguments[:width] = size
26
34
 
27
35
  @system_arguments[:classes] = class_names(
28
- "avatar",
29
36
  system_arguments[:classes],
37
+ "avatar" => !href,
30
38
  "avatar--small" => size < SMALL_THRESHOLD,
31
- "CircleBadge" => !square
39
+ "circle" => !square
32
40
  )
33
41
  end
34
42
 
35
43
  def call
36
- render(Primer::BaseComponent.new(**@system_arguments)) { content }
44
+ if @href
45
+ render(Primer::LinkComponent.new(href: @href, classes: "avatar")) do
46
+ render(Primer::BaseComponent.new(**@system_arguments)) { content }
47
+ end
48
+ else
49
+ render(Primer::BaseComponent.new(**@system_arguments)) { content }
50
+ end
51
+ end
52
+
53
+ def self.status
54
+ Primer::Component::STATUSES[:beta]
37
55
  end
38
56
  end
39
57
  end
@@ -0,0 +1,10 @@
1
+ <%= render Primer::BaseComponent.new(**@system_arguments) do %>
2
+ <%= render body_component do %>
3
+ <% avatars.each_with_index do |avatar, i| %>
4
+ <% if i == 2 %>
5
+ <div class="avatar avatar-more"></div>
6
+ <% end %>
7
+ <%= avatar %>
8
+ <% end %>
9
+ <% end %>
10
+ <% end %>
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Primer
4
+ # Use AvatarStack to stack multiple avatars together.
5
+ class AvatarStackComponent < Primer::Component
6
+ include ViewComponent::SlotableV2
7
+
8
+ ALIGN_DEFAULT = :left
9
+ ALIGN_OPTIONS = [ALIGN_DEFAULT, :right].freeze
10
+
11
+ # Required list of stacked avatars.
12
+ #
13
+ # @param kwargs [Hash] The same arguments as <%= link_to_component(Primer::AvatarComponent) %>.
14
+ renders_many :avatars, Primer::AvatarComponent
15
+
16
+ # @example Default
17
+ # <%= render(Primer::AvatarStackComponent.new) do |c| %>
18
+ # <%= c.avatar(src: "http://placekitten.com/200/200", alt: "@kittenuser") %>
19
+ # <%= c.avatar(src: "http://placekitten.com/200/200", alt: "@kittenuser") %>
20
+ # <%= c.avatar(src: "http://placekitten.com/200/200", alt: "@kittenuser") %>
21
+ # <% end %>
22
+ #
23
+ # @example Align right
24
+ # <%= render(Primer::AvatarStackComponent.new(align: :right)) do |c| %>
25
+ # <%= c.avatar(src: "http://placekitten.com/200/200", alt: "@kittenuser") %>
26
+ # <%= c.avatar(src: "http://placekitten.com/200/200", alt: "@kittenuser") %>
27
+ # <%= c.avatar(src: "http://placekitten.com/200/200", alt: "@kittenuser") %>
28
+ # <% end %>
29
+ #
30
+ # @example With tooltip
31
+ # <%= render(Primer::AvatarStackComponent.new(tooltipped: true, body_arguments: { label: 'This is a tooltip!' })) do |c| %>
32
+ # <%= c.avatar(src: "http://placekitten.com/200/200", alt: "@kittenuser") %>
33
+ # <%= c.avatar(src: "http://placekitten.com/200/200", alt: "@kittenuser") %>
34
+ # <%= c.avatar(src: "http://placekitten.com/200/200", alt: "@kittenuser") %>
35
+ # <% end %>
36
+ #
37
+ # @param align [Symbol] <%= one_of(Primer::AvatarStackComponent::ALIGN_OPTIONS) %>
38
+ # @param tooltipped [Boolean] Whether to add a tooltip to the stack or not.
39
+ # @param body_arguments [Hash] Parameters to add to the Body. If `tooltipped` is set, has the same arguments as <%= link_to_component(Primer::TooltipComponent) %>.
40
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
41
+ def initialize(align: ALIGN_DEFAULT, tooltipped: false, body_arguments: {}, **system_arguments)
42
+ @align = fetch_or_fallback(ALIGN_OPTIONS, align, ALIGN_DEFAULT)
43
+ @system_arguments = system_arguments
44
+ @tooltipped = tooltipped
45
+ @body_arguments = body_arguments
46
+
47
+ @body_arguments[:tag] ||= :div
48
+ @body_arguments[:classes] = class_names(
49
+ "AvatarStack-body",
50
+ @body_arguments[:classes]
51
+ )
52
+
53
+ @system_arguments[:tag] ||= :div
54
+ @system_arguments[:classes] = class_names(
55
+ "AvatarStack",
56
+ system_arguments[:classes],
57
+ "AvatarStack--right" => @align == :right
58
+ )
59
+ end
60
+
61
+ def body_component
62
+ if @tooltipped
63
+ Primer::TooltipComponent.new(**@body_arguments)
64
+ else
65
+ Primer::BaseComponent.new(**@body_arguments)
66
+ end
67
+ end
68
+
69
+ def before_render
70
+ @system_arguments[:classes] = class_names(
71
+ @system_arguments[:classes],
72
+ "AvatarStack--two" => avatars.size == 2,
73
+ "AvatarStack--three-plus" => avatars.size > 2
74
+ )
75
+ end
76
+
77
+ def render?
78
+ avatars.any?
79
+ end
80
+ end
81
+ end
@@ -41,7 +41,7 @@ module Primer
41
41
  # @param test_selector [String] Adds `data-test-selector='given value'` in non-Production environments for testing purposes.
42
42
  #
43
43
  # @param m [Integer] Margin. <%= one_of((-6..6).to_a) %>
44
- # @param mt [Integer] Margin left. <%= one_of((-6..6).to_a) %>
44
+ # @param mt [Integer] Margin top. <%= one_of((-6..6).to_a) %>
45
45
  # @param mr [Integer] Margin right. <%= one_of((-6..6).to_a) %>
46
46
  # @param mb [Integer] Margin bottom. <%= one_of((-6..6).to_a) %>
47
47
  # @param ml [Integer] Margin left. <%= one_of((-6..6).to_a) %>
@@ -62,7 +62,7 @@ module Primer
62
62
  # @param bottom [Boolean] If `false`, sets `bottom: 0`.
63
63
  # @param left [Boolean] If `false`, sets `left: 0`.
64
64
  #
65
- # @param display [Symbol] <%= one_of([:block, :none, :inline, :inline_block, :table, :table_cell]) %>
65
+ # @param display [Symbol] <%= one_of([:none, :block, :flex, :inline, :inline_block, :table, :table_cell]) %>
66
66
  #
67
67
  # @param v [Symbol] Visibility. <%= one_of([:hidden, :visible]) %>
68
68
  #
@@ -76,16 +76,17 @@ module Primer
76
76
  #
77
77
  # @param underline [Boolean] Whether text should be underlined.
78
78
  #
79
- # @param color [Symbol] Text color. <%= one_of([:blue, :red, :gray_light, :gray, :gray_dark, :green, :orange, :orange_light, :purple, :pink, :white, :inherit]) %> Note: this API is subject to change as we move to functional colors.
79
+ # @param color [Symbol] Text color. <%= one_of([:blue, :red, :gray_light, :gray, :gray_dark, :green, :orange, :orange_light, :purple, :pink, :white, :inherit, :text_primary, :text_secondary, :text_tertiary, :text_link, :text_success, :text_warning, :text_danger, :icon_primary, :icon_secondary, :icon_tertiary, :icon_info, :icon_success, :icon_warning, :icon_danger]) %>
80
80
  # @param bg [String, Symbol] Background color. Accepts either a hex value as a String or a color name as a Symbol.
81
81
  #
82
82
  # @param box_shadow [Boolean, Symbol] Box shadow. <%= one_of([true, :medium, :large, :extra_large, :none]) %>
83
- # @param border [Symbol] <%= one_of([:left, :top, :bottom, :right, :y, :x]) %>
83
+ # @param border [Symbol] <%= one_of([:left, :top, :bottom, :right, :y, :x, true]) %>
84
84
  # @param border_color [Symbol] <%= one_of([:blue, :blue_light, :gray, :gray_dark, :green, :purple, :red, :red_light, :white, :yellow, :black_fade]) %> Note: this API is subject to change as we move to functional colors.
85
85
  # @param border_top [Integer] Set to `0` to remove the top border.
86
86
  # @param border_bottom [Integer] Set to `0` to remove the bottom border.
87
87
  # @param border_left [Integer] Set to `0` to remove the left border.
88
88
  # @param border_right [Integer] Set to `0` to remove the right border.
89
+ # @param border_radius [Integer] <%= one_of([0, 1, 2, 3]) %>
89
90
  #
90
91
  # @param font_size [String, Integer] <%= one_of(["00", 0, 1, 2, 3, 4, 5, 6]) %>
91
92
  # @param text_align [Symbol] Text alignment. <%= one_of([:left, :right, :center]) %>
@@ -102,6 +103,8 @@ module Primer
102
103
  #
103
104
  # @param word_break [Symbol] Whether to break words on line breaks. Can only be `:break_all`.
104
105
  #
106
+ # @param animation [Symbol] <%= one_of([:fade_in, :fade_out, :fade_up, :fade_down, :scale_in, :pulse, :grow_x, :grow]) %>
107
+ #
105
108
  # @param tag [Symbol] HTML tag name to be passed to `tag.send`.
106
109
  # @param classes [String] CSS class name value to be concatenated with generated Primer CSS classes.
107
110
  def initialize(tag:, classes: nil, **system_arguments)
@@ -113,7 +116,7 @@ module Primer
113
116
  end
114
117
 
115
118
  def call
116
- content_tag(@tag, content, **@content_tag_args.merge(@result))
119
+ content_tag(@tag, content, @content_tag_args.merge(@result))
117
120
  end
118
121
 
119
122
  private
@@ -1,12 +1,12 @@
1
1
  <%= render Primer::BaseComponent.new(**@system_arguments) do %>
2
2
  <% if spinner.present? %>
3
- <%= render spinner.component %>
3
+ <%= spinner %>
4
4
  <% elsif @icon.present? %>
5
- <%= render(Primer::OcticonComponent.new(
5
+ <%= primer(:octicon,
6
6
  icon: @icon,
7
7
  size: @icon_size,
8
8
  classes: "blankslate-icon"
9
- )) %>
9
+ ) %>
10
10
  <% elsif @image_src.present? && @image_alt.present? %>
11
11
  <%= image_tag "#{@image_src}", class: "mb-3", size: "56x56", alt: "#{@image_alt}" %>
12
12
  <% end %>
@@ -3,40 +3,46 @@
3
3
  module Primer
4
4
  # Use Primer::BlankslateComponent when there is a lack of content within a page or section. Use as placeholder to tell users why something isn't there.
5
5
  class BlankslateComponent < Primer::Component
6
- include ViewComponent::Slotable
6
+ include ViewComponent::SlotableV2
7
7
 
8
- with_slot :spinner, class_name: "Spinner"
8
+ # Optional Spinner.
9
+ #
10
+ # @param kwargs [Hash] The same arguments as <%= link_to_component(Primer::SpinnerComponent) %>.
11
+ renders_one :spinner, lambda { |**system_arguments|
12
+ system_arguments[:mb] ||= 3
13
+ Primer::SpinnerComponent.new(**system_arguments)
14
+ }
9
15
 
10
16
  #
11
- # @example 150|Basic
17
+ # @example Basic
12
18
  # <%= render Primer::BlankslateComponent.new(
13
19
  # title: "Title",
14
20
  # description: "Description",
15
21
  # ) %>
16
22
  #
17
- # @example 190|Icon|Add an `icon` to give additional context. Refer to the [Octicons](https://primer.style/octicons/) documentation to choose an icon.
23
+ # @example Icon|Add an `icon` to give additional context. Refer to the [Octicons](https://primer.style/octicons/) documentation to choose an icon.
18
24
  # <%= render Primer::BlankslateComponent.new(
19
25
  # icon: "octoface",
20
26
  # title: "Title",
21
27
  # description: "Description",
22
28
  # ) %>
23
29
  #
24
- # @example 220|Loading|Add a [SpinnerComponent](https://primer.style/view-components/components/spinner) to the blankslate in place of an icon.
30
+ # @example Loading|Add a [SpinnerComponent](https://primer.style/view-components/components/spinner) to the blankslate in place of an icon.
25
31
  # <%= render Primer::BlankslateComponent.new(
26
32
  # title: "Title",
27
33
  # description: "Description",
28
34
  # ) do |component| %>
29
- # <% component.slot(:spinner, size: :large) %>
35
+ # <% component.spinner(size: :large) %>
30
36
  # <% end %>
31
37
  #
32
- # @example 150|Custom content|Pass custom content as a block in place of `description`.
38
+ # @example Custom content|Pass custom content as a block in place of `description`.
33
39
  # <%= render Primer::BlankslateComponent.new(
34
40
  # title: "Title",
35
41
  # ) do %>
36
42
  # <em>Your custom content here</em>
37
43
  # <% end %>
38
44
  #
39
- # @example 270|Action button|Provide a button to guide users to take action from the blankslate. The button appears below the description and custom content.
45
+ # @example Action button|Provide a button to guide users to take action from the blankslate. The button appears below the description and custom content.
40
46
  # <%= render Primer::BlankslateComponent.new(
41
47
  # icon: "book",
42
48
  # title: "Welcome to the mona wiki!",
@@ -46,7 +52,7 @@ module Primer
46
52
  # button_url: "https://github.com/monalisa/mona/wiki/_new",
47
53
  # ) %>
48
54
  #
49
- # @example 225|Link|Add an additional link to help users learn more about a feature. The link will be shown at the very bottom:
55
+ # @example Link|Add an additional link to help users learn more about a feature. The link will be shown at the very bottom:
50
56
  # <%= render Primer::BlankslateComponent.new(
51
57
  # icon: "book",
52
58
  # title: "Welcome to the mona wiki!",
@@ -55,7 +61,7 @@ module Primer
55
61
  # link_url: "https://docs.github.com/en/github/building-a-strong-community/about-wikis",
56
62
  # ) %>
57
63
  #
58
- # @example 340|Variations|There are a few variations of how the Blankslate appears: `narrow` adds a maximum width, `large` increases the font size, and `spacious` adds extra padding.
64
+ # @example Variations|There are a few variations of how the Blankslate appears: `narrow` adds a maximum width, `large` increases the font size, and `spacious` adds extra padding.
59
65
  # <%= render Primer::BlankslateComponent.new(
60
66
  # icon: "book",
61
67
  # title: "Welcome to the mona wiki!",
@@ -94,7 +100,7 @@ module Primer
94
100
  link_text: "",
95
101
  link_url: "",
96
102
 
97
- #variations
103
+ # variations
98
104
  narrow: false,
99
105
  large: false,
100
106
  spacious: false,
@@ -108,7 +114,7 @@ module Primer
108
114
  "blankslate",
109
115
  "blankslate-narrow": narrow,
110
116
  "blankslate-large": large,
111
- "blankslate-spacious": spacious,
117
+ "blankslate-spacious": spacious
112
118
  )
113
119
 
114
120
  @title_tag = title_tag
@@ -124,18 +130,5 @@ module Primer
124
130
  @link_text = link_text
125
131
  @link_url = link_url
126
132
  end
127
-
128
- class Spinner < Primer::Slot
129
- # @param size [Symbol] <%= one_of(Primer::SpinnerComponent::SIZE_MAPPINGS) %>
130
- # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
131
- def initialize(**system_arguments)
132
- @system_arguments = system_arguments
133
- @system_arguments[:mb] ||= 3
134
- end
135
-
136
- def component
137
- Primer::SpinnerComponent.new(**@system_arguments)
138
- end
139
- end
140
133
  end
141
134
  end