playbook_ui 7.8.1 → 7.10.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 (71) hide show
  1. checksums.yaml +4 -4
  2. data/app/helpers/playbook/pb_doc_helper.rb +55 -6
  3. data/app/helpers/playbook/pb_sample_helper.rb +6 -0
  4. data/app/pb_kits/playbook/config/_kit_example.html.erb +18 -4
  5. data/app/pb_kits/playbook/config/_kit_ui.html.erb +21 -21
  6. data/app/pb_kits/playbook/pb_currency/_currency.html.erb +1 -1
  7. data/app/pb_kits/playbook/pb_currency/_currency.jsx +16 -1
  8. data/app/pb_kits/playbook/pb_currency/_currency.scss +23 -1
  9. data/app/pb_kits/playbook/pb_currency/currency.rb +22 -0
  10. data/app/pb_kits/playbook/pb_currency/docs/{_currency_small.html.erb → _currency_alignment.html.erb} +3 -3
  11. data/app/pb_kits/playbook/pb_currency/docs/{_currency_small.jsx → _currency_alignment.jsx} +5 -5
  12. data/app/pb_kits/playbook/pb_currency/docs/_currency_no_symbol.html.erb +7 -0
  13. data/app/pb_kits/playbook/pb_currency/docs/_currency_no_symbol.jsx +17 -0
  14. data/app/pb_kits/playbook/pb_currency/docs/{_currency_large.html.erb → _currency_size.html.erb} +8 -7
  15. data/app/pb_kits/playbook/pb_currency/docs/{_currency_large.jsx → _currency_size.jsx} +9 -8
  16. data/app/pb_kits/playbook/pb_currency/docs/_currency_variants.html.erb +24 -0
  17. data/app/pb_kits/playbook/pb_currency/docs/{_currency_medium.jsx → _currency_variants.jsx} +13 -10
  18. data/app/pb_kits/playbook/pb_currency/docs/example.yml +8 -6
  19. data/app/pb_kits/playbook/pb_currency/docs/index.js +4 -3
  20. data/app/pb_kits/playbook/pb_nav/_horizontal_nav.scss +22 -0
  21. data/app/pb_kits/playbook/pb_nav/_subtle_mixin.scss +47 -0
  22. data/app/pb_kits/playbook/pb_nav/_vertical_nav.scss +2 -46
  23. data/app/pb_kits/playbook/pb_nav/docs/_subtle_horizontal_nav.html.erb +6 -0
  24. data/app/pb_kits/playbook/pb_nav/docs/_subtle_horizontal_nav.jsx +33 -0
  25. data/app/pb_kits/playbook/pb_nav/docs/example.yml +2 -0
  26. data/app/pb_kits/playbook/pb_nav/docs/index.js +1 -0
  27. data/app/pb_kits/playbook/pb_rich_text_editor/_rich_text_editor.scss +1 -1
  28. data/app/pb_kits/playbook/pb_rich_text_editor/_trix_styles.scss +375 -0
  29. data/app/pb_kits/playbook/pb_stat_change/_stat_change.html.erb +1 -1
  30. data/app/pb_kits/playbook/pb_stat_change/_stat_change.jsx +8 -4
  31. data/app/pb_kits/playbook/pb_stat_change/docs/_stat_change_default.html.erb +1 -1
  32. data/app/pb_kits/playbook/pb_stat_change/docs/_stat_change_unit.html.erb +17 -0
  33. data/app/pb_kits/playbook/pb_stat_change/docs/_stat_change_unit.jsx +28 -0
  34. data/app/pb_kits/playbook/pb_stat_change/docs/_stat_change_unit_two.html.erb +20 -0
  35. data/app/pb_kits/playbook/pb_stat_change/docs/_stat_change_unit_two.jsx +31 -0
  36. data/app/pb_kits/playbook/pb_stat_change/docs/_stat_change_unit_two.md +1 -0
  37. data/app/pb_kits/playbook/pb_stat_change/docs/example.yml +6 -4
  38. data/app/pb_kits/playbook/pb_stat_change/docs/index.js +2 -0
  39. data/app/pb_kits/playbook/pb_stat_change/stat_change.rb +12 -7
  40. data/app/pb_kits/playbook/pb_table/_table.scss +1 -57
  41. data/app/pb_kits/playbook/pb_table/docs/_table_alignment_shift_row.html.erb +1 -1
  42. data/app/pb_kits/playbook/pb_table/docs/_table_alignment_shift_row.jsx +1 -1
  43. data/app/pb_kits/playbook/pb_table/styles/_alignment.scss +32 -0
  44. data/app/pb_kits/playbook/pb_table/styles/_all.scss +4 -3
  45. data/app/pb_kits/playbook/pb_table/styles/_side_highlight.scss +24 -0
  46. data/app/pb_kits/playbook/pb_typeahead/_typeahead.jsx +5 -1
  47. data/app/pb_kits/playbook/pb_typeahead/components/Option.jsx +2 -3
  48. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_with_pills_async.html.erb +19 -3
  49. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_with_pills_async.jsx +4 -2
  50. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_with_pills_async.md +10 -2
  51. data/app/pb_kits/playbook/pb_typeahead/typeahead.rb +5 -0
  52. data/app/pb_kits/playbook/react_rails_kits.js +1 -0
  53. data/lib/playbook.rb +1 -0
  54. data/{app/pb_kits → lib}/playbook/props.rb +0 -0
  55. data/{app/pb_kits → lib}/playbook/props/array.rb +0 -0
  56. data/{app/pb_kits → lib}/playbook/props/base.rb +0 -0
  57. data/{app/pb_kits → lib}/playbook/props/boolean.rb +0 -0
  58. data/{app/pb_kits → lib}/playbook/props/date.rb +0 -0
  59. data/{app/pb_kits → lib}/playbook/props/enum.rb +0 -0
  60. data/{app/pb_kits → lib}/playbook/props/hash.rb +0 -0
  61. data/{app/pb_kits → lib}/playbook/props/hash_array.rb +0 -0
  62. data/{app/pb_kits → lib}/playbook/props/number.rb +0 -0
  63. data/{app/pb_kits → lib}/playbook/props/number_array.rb +0 -0
  64. data/{app/pb_kits → lib}/playbook/props/numeric.rb +0 -0
  65. data/{app/pb_kits → lib}/playbook/props/percentage.rb +0 -0
  66. data/{app/pb_kits → lib}/playbook/props/proc.rb +0 -0
  67. data/{app/pb_kits → lib}/playbook/props/string.rb +0 -0
  68. data/lib/playbook/version.rb +1 -1
  69. metadata +38 -26
  70. data/app/pb_kits/playbook/pb_currency/docs/_currency_medium.html.erb +0 -21
  71. data/app/pb_kits/playbook/pb_table/styles/_mixins.scss +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7f1b20f99582094b211e94e5de1f615e7e7948e8e618062e2b77a224d7ffb69b
4
- data.tar.gz: 2d3195399d5eb4a17b30f9b9e26c1420ff7cb7263d95fc3e32c2a7800a3f9e58
3
+ metadata.gz: 2dded8961e6cc6308b1d07c4ddc00b8be69244d92b120ab3d1a370f566a7cd37
4
+ data.tar.gz: ac06d5ca306f7ba1103a2d68c7e179a8cabd2984e56c73d9a358a25ebb65213f
5
5
  SHA512:
6
- metadata.gz: 264ab30755326f86f13566ff437797dc37775801c31bee01584c9fc2cc607656cc00f8fb045dea32bf89582b437f2e1efaca4f68c339be12c39b081351b94f8f
7
- data.tar.gz: a8fa83550b31847d8739f1248e800305969ff698ea198a05becb7cd5299bc2e3057309ad30be2b3bd7120fec1a6e16c592d0169d281947a5b2bf79090b8ebb9f
6
+ metadata.gz: d726cb9073d2bf80830ed397990203f1faf674b7f2e04e8da01d70a7ac3ad590a111a373904d4b756ff964eb55ef7829454a10313f370f0310f690298c15a85a
7
+ data.tar.gz: d18d68afbb27818521cc240f52d6f05c025f0c23745bf3095a7ec1c848c97e73a784049e4db873ad51f874320b32e5d6dc93e441ce6df62025d23031cf1de5a4
@@ -25,6 +25,28 @@ module Playbook
25
25
  end
26
26
  end
27
27
 
28
+ def delete_dark_mode_cookie
29
+ cookies.delete :dark_mode
30
+ end
31
+
32
+ def get_samples(kit)
33
+ sample_yaml = YAML.load_file("#{Playbook::Engine.root}/app/pb_kits/playbook/data/samples.yml")
34
+ all_samples = []
35
+
36
+ sample_yaml.each do |_category, sample|
37
+ all_samples.push(sample)
38
+ end
39
+
40
+ output = ""
41
+ samples_using_kit = []
42
+ all_samples[0].each do |sample|
43
+ filepath = "#{Playbook::Engine.root}/app/views/playbook/samples/#{sample}/index.html.erb"
44
+ output = `grep -l 'pb_rails(\"#{kit}' #{filepath}`
45
+ samples_using_kit.push(sample) if output.chomp == filepath
46
+ end
47
+ samples_using_kit
48
+ end
49
+
28
50
  def kit_path(kit)
29
51
  "#{Playbook::Engine.root}/app/pb_kits/playbook/pb_#{kit}"
30
52
  end
@@ -44,23 +66,24 @@ module Playbook
44
66
  read_file(filename)
45
67
  end
46
68
 
47
- def pb_kit(kit: "", type: "rails", show_code: true)
69
+ def pb_kit(kit: "", type: "rails", show_code: true, limit_examples: false)
48
70
  @type = type
49
71
  @kit_examples = get_kit_examples(kit, type)
72
+ @limit_examples = limit_examples
50
73
  @show_code = show_code
51
74
  render partial: "config/kit_example"
52
75
  end
53
76
 
54
- def pb_kits(type: "rails")
77
+ def pb_kits(type: "rails", limit_examples: false)
55
78
  display_kits = []
56
79
  kits = get_kits
57
80
  kits.each do |kit|
58
81
  if kit.is_a?(Hash)
59
82
  nav_hash_array(kit).each do |sub_kit|
60
- display_kits << render_pb_doc_kit(sub_kit, type, false)
83
+ display_kits << render_pb_doc_kit(sub_kit, type, false, limit_examples)
61
84
  end
62
85
  else
63
- display_kits << render_pb_doc_kit(kit, type, false)
86
+ display_kits << render_pb_doc_kit(kit, type, false, limit_examples)
64
87
  end
65
88
  end
66
89
  raw("<div class='pb--docItem'>" + display_kits.join("</div><div class='pb--docItem'>") + "</div>")
@@ -79,10 +102,10 @@ module Playbook
79
102
  raw("<div class='pb--docItem'>" + display_kits.join("</div><div class='pb--docItem'>") + "</div>")
80
103
  end
81
104
 
82
- def render_pb_doc_kit(kit, type, code = true)
105
+ def render_pb_doc_kit(kit, type, code = true, limit_examples)
83
106
  title = render_clickable_title(kit, type)
84
107
  ui = raw("<div class='pb--docItem-ui'>
85
- #{pb_kit(kit: kit, type: type, show_code: code)}</div>")
108
+ #{pb_kit(kit: kit, type: type, show_code: code, limit_examples: limit_examples)}</div>")
86
109
  title + ui
87
110
  end
88
111
 
@@ -148,6 +171,32 @@ module Playbook
148
171
  (!kit.nil? && @kit == link)
149
172
  end
150
173
 
174
+ def format_search_hash(kit)
175
+ label_value_hash = {
176
+ label: kit.to_s.titleize,
177
+ value: @type == "react" || @type.nil? ? "/kits/#{kit}/react" : "/kits/#{kit}",
178
+ }
179
+ label_value_hash
180
+ end
181
+
182
+ def search_list
183
+ all_kits = []
184
+ formatted_kits = []
185
+ MENU["kits"].each do |kit|
186
+ if kit.is_a? Hash
187
+ kit.values[0].each do |sub_kit|
188
+ all_kits.push(sub_kit)
189
+ end
190
+ else
191
+ all_kits.push(kit)
192
+ end
193
+ end
194
+ all_kits.sort!.each do |sorted_kit|
195
+ formatted_kits.push(format_search_hash(sorted_kit))
196
+ end
197
+ formatted_kits
198
+ end
199
+
151
200
  private
152
201
 
153
202
  def get_kit_examples(kit, type)
@@ -11,6 +11,12 @@ module Playbook
11
11
  end
12
12
  end
13
13
 
14
+ def kits_used(sample)
15
+ code = get_raw_code(sample, "rails")
16
+ kits_array = code.scan(/pb_rails\("(\w+)(?:"|\/)/)
17
+ kits_array.uniq
18
+ end
19
+
14
20
  def pb_sample(sample: "", type: "rails")
15
21
  @type = type
16
22
  @sample = sample
@@ -1,8 +1,22 @@
1
1
  <%if !@kit_examples[:examples].nil? %>
2
- <% @kit_examples[:examples].each do |kit_example| %>
3
- <% kit_example.each do |key, item| %>
4
- <%=pb_rails("card", props:{classname: "pb--doc", padding:"none"})do%>
5
- <%= render partial: "config/kit_ui", locals: { key: key, type: @type, item: item, show_code: @show_code } %>
2
+ <% if @limit_examples %>
3
+ <% @kit_examples[:examples].each_with_index do |kit_example, index| %>
4
+ <% kit_example.each do |key, item| %>
5
+ <% if index == 0 %>
6
+ <%= pb_rails("card", props: { classname: "pb--doc", padding:"none" }) do %>
7
+ <%= render partial: "config/kit_ui", locals: { key: key, type: @type, item: item, show_code: @show_code } %>
8
+ <% end %>
9
+ <% elsif index > 0 %>
10
+ <% break %>
11
+ <% end %>
12
+ <% end %>
13
+ <% end %>
14
+ <% else %>
15
+ <% @kit_examples[:examples].each do |kit_example| %>
16
+ <% kit_example.each do |key, item| %>
17
+ <%= pb_rails("card", props: { classname: "pb--doc", padding:"none" }) do %>
18
+ <%= render partial: "config/kit_ui", locals: { key: key, type: @type, item: item, show_code: @show_code } %>
19
+ <% end %>
6
20
  <% end %>
7
21
  <% end %>
8
22
  <% end %>
@@ -18,24 +18,24 @@
18
18
  <br>
19
19
  </div>
20
20
 
21
- <% if @show_code%>
22
- <div class="markdown pb--kit-example-markdown <%= cookies[:dark_mode] == "true" ? "dark" : "" %>">
23
- <%= markdown(get_per_sample_descriptions(@kit_examples[:kit], key)) %>
24
- </div>
25
- <div class="pb--codeControls">
26
- <ul>
27
- <li>
28
- <a href="#" data-toggle="code_example">Code Example</a>
29
- </li>
30
- </ul>
31
- </div>
32
- <div class="pb--codeCopy" data-action="toggle" data-togglable="code_example" style="display: none" >
33
- <%= pb_rails("section_separator")%>
34
- <a href="#" data-toggle="false" class="pb--close-toggle">Close</a>
35
- <% if type == "rails" %>
36
- <pre class="highlight"><%= raw rouge(contents, "erb") %></pre>
37
- <% elsif type == "react" %>
38
- <pre class="highlight"><%= raw rouge(contents, "react")%></pre>
39
- <% end %>
40
- </div>
41
- <% end %>
21
+ <% if @show_code %>
22
+ <div class="markdown pb--kit-example-markdown <%= cookies[:dark_mode] == "true" ? "dark" : "" %>">
23
+ <%= markdown(get_per_sample_descriptions(@kit_examples[:kit], key)) %>
24
+ </div>
25
+ <div class="pb--codeControls">
26
+ <ul>
27
+ <li>
28
+ <a href="#" data-toggle="code_example">Code Example</a>
29
+ </li>
30
+ </ul>
31
+ </div>
32
+ <div class="pb--codeCopy" data-action="toggle" data-togglable="code_example" style="display: none" >
33
+ <%= pb_rails("section_separator")%>
34
+ <a href="#" data-toggle="false" class="pb--close-toggle">Close</a>
35
+ <% if type == "rails" %>
36
+ <pre class="highlight"><%= raw rouge(contents, "erb") %></pre>
37
+ <% elsif type == "react" %>
38
+ <pre class="highlight"><%= raw rouge(contents, "react")%></pre>
39
+ <% end %>
40
+ </div>
41
+ <% end %>
@@ -6,7 +6,7 @@
6
6
 
7
7
  <%= pb_rails("caption", props: { text: object.label }) %>
8
8
 
9
- <div class="pb_currency_wrapper">
9
+ <div class=<%= "pb_currency_wrapper#{object.variant_class || object.emphasized_class}" %>>
10
10
  <%= pb_rails("body", props: object.currency_wrapper_props) do %>
11
11
  <%= object.symbol %>
12
12
  <% end %>
@@ -14,10 +14,12 @@ type CurrencyProps = {
14
14
  className?: string,
15
15
  dark?: boolean,
16
16
  data?: object,
17
+ emphasized?: boolean,
17
18
  id?: string,
18
19
  label?: string,
19
20
  size?: 'sm' | 'md' | 'lg',
20
21
  symbol?: string,
22
+ variant?: 'default' | 'light' | 'bold',
21
23
  unit?: string,
22
24
  }
23
25
 
@@ -33,15 +35,28 @@ const Currency = (props: CurrencyProps) => {
33
35
  aria = {},
34
36
  amount,
35
37
  data = {},
38
+ emphasized = true,
36
39
  id,
37
40
  unit,
38
41
  className,
39
42
  label = '',
40
43
  size = 'sm',
41
44
  symbol = '$',
45
+ variant = 'default',
42
46
  dark = false,
43
47
  } = props
44
48
 
49
+ const emphasizedClass = emphasized ? '' : '_deemphasized'
50
+
51
+ let variantClass
52
+ if (size === 'sm') {
53
+ if (variant === 'light') {
54
+ variantClass = '_light'
55
+ } else if (variant === 'bold') {
56
+ variantClass = '_bold'
57
+ }
58
+ }
59
+
45
60
  const [whole, decimal = '00'] = amount.split('.')
46
61
  const ariaProps = buildAriaProps(aria)
47
62
  const dataProps = buildDataProps(data)
@@ -60,7 +75,7 @@ const Currency = (props: CurrencyProps) => {
60
75
  >
61
76
  <Caption>{label}</Caption>
62
77
 
63
- <div className="pb_currency_wrapper">
78
+ <div className={`pb_currency_wrapper${variantClass || emphasizedClass}`}>
64
79
  <Body
65
80
  className="dollar_sign"
66
81
  color="light"
@@ -24,6 +24,28 @@
24
24
  [class^=pb_currency_wrapper] {
25
25
  display: flex;
26
26
 
27
+ &[class*=_deemphasized] [class^=pb_body_kit][class*=_light] {
28
+ color: $text_lt_default;
29
+ }
30
+
31
+ &[class*=_deemphasized] [class^=pb_title_kit][class*=_4] {
32
+ font-weight: $regular;
33
+ }
34
+
35
+ &[class*=_light] [class^=pb_body_kit][class*=_light] {
36
+ color: $text_lt_light;
37
+ }
38
+
39
+ &[class*=_light] [class^=pb_title_kit][class*=_4] {
40
+ color: $text_lt_light;
41
+ font-weight: $regular;
42
+ }
43
+
44
+ &[class*=_bold] [class^=pb_body_kit][class*=_light] {
45
+ color: $text_lt_default;
46
+ font-weight: $bolder;
47
+ }
48
+
27
49
  & > [class*=dollar_sign] {
28
50
  display: flex;
29
51
  align-items: flex-start;
@@ -45,7 +67,7 @@
45
67
  padding-left: $space_xs - 7px;
46
68
  padding-right: $space_xs - 7px;
47
69
  }
48
-
70
+
49
71
  &[class*=_sm] [class^=pb_currency_wrapper] [class*=pb_currency_value] {
50
72
  line-height: 1.4;
51
73
  padding-left: $space_xs - 7px;
@@ -28,6 +28,13 @@ module Playbook
28
28
  prop :unit, type: Playbook::Props::String,
29
29
  required: false
30
30
 
31
+ prop :emphasized, type: Playbook::Props::Boolean,
32
+ default: true
33
+
34
+ prop :variant, type: Playbook::Props::Enum,
35
+ values: %w[default light bold],
36
+ default: "default"
37
+
31
38
  prop :dark, type: Playbook::Props::Boolean,
32
39
  default: false
33
40
 
@@ -61,6 +68,21 @@ module Playbook
61
68
  }
62
69
  end
63
70
 
71
+ def emphasized_class
72
+ emphasized ? "" : "_deemphasized"
73
+ end
74
+
75
+ def variant_class
76
+ return unless size == "sm"
77
+
78
+ case variant
79
+ when "light"
80
+ "_light"
81
+ when "bold"
82
+ "_bold"
83
+ end
84
+ end
85
+
64
86
  private
65
87
 
66
88
  def whole_value
@@ -1,13 +1,13 @@
1
1
  <%= pb_rails("currency", props: {
2
- label: "Caption",
3
2
  amount: "2,000.50",
3
+ label: "Left",
4
4
  size: "sm",
5
5
  }) %>
6
6
 
7
7
  <%= pb_rails("currency", props: {
8
8
  align: "center",
9
9
  amount: "342",
10
- label: "Caption",
10
+ label: "Center",
11
11
  size: "sm",
12
12
  symbol: "€",
13
13
  }) %>
@@ -15,7 +15,7 @@
15
15
  <%= pb_rails("currency", props: {
16
16
  align: "right",
17
17
  amount: "45",
18
- label: "Caption",
18
+ label: "Right",
19
19
  unit: "/mo",
20
20
  size: "sm",
21
21
  }) %>
@@ -1,20 +1,20 @@
1
1
  import React from 'react'
2
2
  import { Currency } from '../../'
3
3
 
4
- const CurrencySmall = (props) => {
4
+ const CurrencyAlignment = (props) => {
5
5
  return (
6
6
  <>
7
7
  <Currency
8
8
  {...props}
9
9
  amount="2,000.50"
10
- label="Caption"
10
+ label="Left"
11
11
  size="sm"
12
12
  />
13
13
  <Currency
14
14
  {...props}
15
15
  align="center"
16
16
  amount="342"
17
- label="Caption"
17
+ label="Center"
18
18
  size="sm"
19
19
  symbol="€"
20
20
  />
@@ -22,7 +22,7 @@ const CurrencySmall = (props) => {
22
22
  {...props}
23
23
  align="right"
24
24
  amount="45"
25
- label="Caption"
25
+ label="Right"
26
26
  size="sm"
27
27
  unit="/mo"
28
28
  />
@@ -30,4 +30,4 @@ const CurrencySmall = (props) => {
30
30
  )
31
31
  }
32
32
 
33
- export default CurrencySmall
33
+ export default CurrencyAlignment
@@ -0,0 +1,7 @@
1
+ <%= pb_rails("currency", props: {
2
+ amount: "309",
3
+ label: "Sales",
4
+ size: "md",
5
+ symbol: "",
6
+ unit: "/week"
7
+ }) %>
@@ -0,0 +1,17 @@
1
+ import React from 'react'
2
+ import { Currency } from '../../'
3
+
4
+ const CurrencyNoSymbol = (props) => {
5
+ return (
6
+ <Currency
7
+ {...props}
8
+ amount="309"
9
+ label="Sales"
10
+ size="md"
11
+ symbol=""
12
+ unit="/week"
13
+ />
14
+ )
15
+ }
16
+
17
+ export default CurrencyNoSymbol
@@ -1,20 +1,21 @@
1
1
  <%= pb_rails("currency", props: {
2
2
  amount: "2,000.50",
3
- size: "lg"
3
+ label: "Small",
4
+ margin_bottom: "md",
5
+ size: "sm",
4
6
  }) %>
5
7
 
6
8
  <%= pb_rails("currency", props: {
7
- align: "center",
8
9
  amount: "342",
9
- label: "Caption",
10
- size: "lg",
10
+ label: "Medium",
11
+ margin_bottom: "md",
12
+ size: "md",
11
13
  symbol: "€",
12
14
  }) %>
13
15
 
14
16
  <%= pb_rails("currency", props: {
15
- align: "right",
16
17
  amount: "45",
17
- label: "Caption",
18
- unit: "/mo",
18
+ label: "Large",
19
19
  size: "lg",
20
+ unit: "/mo",
20
21
  }) %>