primer_view_components 0.0.112 → 0.0.114

Sign up to get free protection for your applications and to get access to all the features.
Files changed (108) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +46 -0
  3. data/app/assets/javascripts/primer_view_components.js +1 -1
  4. data/app/assets/javascripts/primer_view_components.js.map +1 -1
  5. data/app/assets/styles/primer_view_components.css +3 -1
  6. data/app/assets/styles/primer_view_components.css.map +1 -1
  7. data/app/components/primer/alpha/action_list.css +1 -1
  8. data/app/components/primer/alpha/action_list.css.json +1 -1
  9. data/app/components/primer/alpha/action_list.css.map +1 -1
  10. data/app/components/primer/alpha/action_list.pcss +0 -15
  11. data/app/components/primer/alpha/auto_complete.css +1 -1
  12. data/app/components/primer/alpha/auto_complete.css.map +1 -1
  13. data/app/components/primer/alpha/auto_complete.pcss +1 -1
  14. data/app/components/primer/alpha/banner.css +1 -1
  15. data/app/components/primer/alpha/banner.css.map +1 -1
  16. data/app/components/primer/alpha/banner.pcss +2 -2
  17. data/app/components/primer/alpha/dialog/body.rb +3 -0
  18. data/app/components/primer/alpha/dialog/footer.rb +3 -0
  19. data/app/components/primer/alpha/dialog/header.rb +3 -0
  20. data/app/components/primer/alpha/dialog.css +1 -0
  21. data/app/components/primer/alpha/dialog.css.json +1 -0
  22. data/app/components/primer/alpha/dialog.css.map +1 -0
  23. data/app/components/primer/alpha/dialog.pcss +484 -0
  24. data/app/components/primer/alpha/dialog.rb +3 -0
  25. data/app/components/primer/alpha/segmented_control.css +1 -1
  26. data/app/components/primer/alpha/segmented_control.css.map +1 -1
  27. data/app/components/primer/alpha/text_field.css +3 -0
  28. data/app/components/primer/alpha/text_field.css.json +1 -0
  29. data/app/components/primer/alpha/text_field.css.map +1 -0
  30. data/app/components/primer/alpha/text_field.pcss +683 -0
  31. data/app/components/primer/alpha/toggle_switch.d.ts +1 -1
  32. data/app/components/primer/alpha/toggle_switch.js +7 -4
  33. data/app/components/primer/alpha/toggle_switch.ts +7 -3
  34. data/app/components/primer/{clipboard_copy.d.ts → beta/clipboard_copy.d.ts} +0 -0
  35. data/app/components/primer/{clipboard_copy.html.erb → beta/clipboard_copy.html.erb} +0 -0
  36. data/app/components/primer/{clipboard_copy.js → beta/clipboard_copy.js} +0 -0
  37. data/app/components/primer/beta/clipboard_copy.rb +50 -0
  38. data/app/components/primer/{clipboard_copy.ts → beta/clipboard_copy.ts} +0 -0
  39. data/app/components/primer/beta/markdown.rb +290 -0
  40. data/app/components/primer/beta/popover.css.map +1 -1
  41. data/app/components/primer/beta/popover.pcss +5 -5
  42. data/app/components/primer/beta/relative_time.rb +160 -0
  43. data/app/components/primer/button_component.rb +1 -1
  44. data/app/components/primer/clipboard_copy.rb +2 -43
  45. data/app/components/primer/component.rb +4 -0
  46. data/app/components/primer/local_time.d.ts +1 -1
  47. data/app/components/primer/local_time.js +1 -1
  48. data/app/components/primer/local_time.rb +3 -1
  49. data/app/components/primer/local_time.ts +1 -1
  50. data/app/components/primer/markdown.rb +2 -283
  51. data/app/components/primer/primer.d.ts +1 -1
  52. data/app/components/primer/primer.js +1 -1
  53. data/app/components/primer/primer.pcss +8 -0
  54. data/app/components/primer/primer.ts +1 -1
  55. data/app/components/primer/time_ago_component.d.ts +1 -1
  56. data/app/components/primer/time_ago_component.js +1 -1
  57. data/app/components/primer/time_ago_component.rb +2 -1
  58. data/app/components/primer/time_ago_component.ts +1 -1
  59. data/app/forms/submit_button_form.rb +8 -2
  60. data/app/helpers/primer/form_helper.rb +12 -0
  61. data/lib/postcss_mixins/clearfix.pcss +12 -0
  62. data/lib/primer/deprecations.rb +96 -26
  63. data/lib/primer/deprecations.yml +72 -0
  64. data/lib/primer/forms/base.rb +7 -20
  65. data/lib/primer/forms/base_component.rb +15 -1
  66. data/lib/primer/forms/button.html.erb +4 -0
  67. data/lib/primer/forms/button.rb +68 -0
  68. data/lib/primer/forms/check_box.html.erb +2 -2
  69. data/lib/primer/forms/check_box.rb +1 -1
  70. data/lib/primer/forms/check_box_group.html.erb +2 -2
  71. data/lib/primer/forms/dsl/button_input.rb +29 -0
  72. data/lib/primer/forms/dsl/input_methods.rb +7 -2
  73. data/lib/primer/forms/dsl/submit_button_input.rb +1 -0
  74. data/lib/primer/forms/dsl/text_field_input.rb +0 -7
  75. data/lib/primer/forms/radio_button.html.erb +2 -2
  76. data/lib/primer/forms/radio_button.rb +1 -1
  77. data/lib/primer/forms/radio_button_group.html.erb +2 -2
  78. data/lib/primer/forms/select_list.html.erb +1 -1
  79. data/lib/primer/forms/select_list.rb +4 -1
  80. data/lib/primer/forms/submit_button.html.erb +1 -4
  81. data/lib/primer/forms/submit_button.rb +1 -37
  82. data/lib/primer/forms/text_area.html.erb +1 -1
  83. data/lib/primer/forms/text_area.rb +5 -1
  84. data/lib/primer/forms/text_field.html.erb +1 -1
  85. data/lib/primer/forms/text_field.rb +11 -0
  86. data/lib/primer/forms/utils.rb +28 -0
  87. data/lib/primer/view_components/audited.rb +14 -0
  88. data/lib/primer/view_components/engine.rb +1 -0
  89. data/lib/primer/view_components/linters/clipboard_copy_component_migration_counter.rb +2 -2
  90. data/lib/primer/view_components/linters/helpers/deprecated_components_helpers.rb +3 -18
  91. data/lib/primer/view_components/version.rb +1 -1
  92. data/lib/rubocop/cop/primer/component_name_migration.rb +2 -2
  93. data/lib/tasks/docs.rake +4 -3
  94. data/previews/primer/alpha/auto_complete_preview.rb +12 -0
  95. data/previews/primer/alpha/segmented_control_preview.rb +9 -6
  96. data/previews/primer/alpha/text_field_preview.rb +77 -52
  97. data/previews/primer/beta/clipboard_copy_preview/element.html.erb +2 -0
  98. data/previews/primer/beta/clipboard_copy_preview.rb +39 -0
  99. data/previews/primer/{markdown_preview.rb → beta/markdown_preview.rb} +14 -12
  100. data/previews/primer/beta/relative_time_preview.rb +271 -0
  101. data/previews/primer/forms/forms_preview.rb +1 -0
  102. data/static/arguments.json +163 -53
  103. data/static/audited_at.json +7 -4
  104. data/static/constants.json +132 -6
  105. data/static/statuses.json +6 -3
  106. metadata +28 -9
  107. data/previews/primer/clipboard_copy_preview/element.html.erb +0 -2
  108. data/previews/primer/clipboard_copy_preview.rb +0 -37
@@ -27,9 +27,12 @@ let ToggleSwitchElement = class ToggleSwitchElement extends HTMLElement {
27
27
  return this.src != null;
28
28
  }
29
29
  toggle() {
30
+ if (this.isDisabled()) {
31
+ return;
32
+ }
30
33
  if (this.isRemote()) {
31
34
  this.setLoadingState();
32
- this.check();
35
+ this.submitForm();
33
36
  }
34
37
  else {
35
38
  this.performToggle();
@@ -90,12 +93,12 @@ let ToggleSwitchElement = class ToggleSwitchElement extends HTMLElement {
90
93
  this.loadingSpinner.setAttribute('hidden', 'hidden');
91
94
  this.enable();
92
95
  }
93
- async check() {
96
+ async submitForm() {
94
97
  const body = new FormData();
95
98
  if (this.csrf) {
96
99
  body.append(this.csrfField, this.csrf);
97
100
  }
98
- body.append('value', this.isOn() ? '1' : '0');
101
+ body.append('value', this.isOn() ? '0' : '1');
99
102
  try {
100
103
  if (!this.src)
101
104
  throw new Error('invalid src');
@@ -131,7 +134,7 @@ __decorate([
131
134
  ], ToggleSwitchElement.prototype, "errorIcon", void 0);
132
135
  __decorate([
133
136
  debounce(300)
134
- ], ToggleSwitchElement.prototype, "check", null);
137
+ ], ToggleSwitchElement.prototype, "submitForm", null);
135
138
  ToggleSwitchElement = __decorate([
136
139
  controller
137
140
  ], ToggleSwitchElement);
@@ -32,9 +32,13 @@ class ToggleSwitchElement extends HTMLElement {
32
32
  }
33
33
 
34
34
  toggle() {
35
+ if (this.isDisabled()) {
36
+ return
37
+ }
38
+
35
39
  if (this.isRemote()) {
36
40
  this.setLoadingState()
37
- this.check()
41
+ this.submitForm()
38
42
  } else {
39
43
  this.performToggle()
40
44
  }
@@ -110,14 +114,14 @@ class ToggleSwitchElement extends HTMLElement {
110
114
  }
111
115
 
112
116
  @debounce(300)
113
- private async check() {
117
+ private async submitForm() {
114
118
  const body = new FormData()
115
119
 
116
120
  if (this.csrf) {
117
121
  body.append(this.csrfField, this.csrf)
118
122
  }
119
123
 
120
- body.append('value', this.isOn() ? '1' : '0')
124
+ body.append('value', this.isOn() ? '0' : '1')
121
125
 
122
126
  try {
123
127
  if (!this.src) throw new Error('invalid src')
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Primer
4
+ module Beta
5
+ # Use `ClipboardCopy` to copy element text content or input values to the clipboard.
6
+ #
7
+ # @accessibility
8
+ # Always set an accessible label to help the user interact with the component.
9
+ class ClipboardCopy < Primer::Component
10
+ status :beta
11
+
12
+ # @example Default
13
+ # <%= render(Primer::Beta::ClipboardCopy.new(value: "Text to copy", "aria-label": "Copy text to the system clipboard")) %>
14
+ #
15
+ # @example With text instead of icons
16
+ # <%= render(Primer::Beta::ClipboardCopy.new(value: "Text to copy")) do %>
17
+ # Click to copy!
18
+ # <% end %>
19
+ #
20
+ # @example Copying from an element
21
+ # <%= render(Primer::Beta::ClipboardCopy.new(for: "blob-path", "aria-label": "Copy text to the system clipboard")) %>
22
+ # <div id="blob-path">src/index.js</div>
23
+ #
24
+ # @param aria-label [String] String that will be read to screenreaders when the component is focused
25
+ # @param value [String] Text to copy into the users clipboard when they click the component.
26
+ # @param for [String] Element id from where to get the copied value.
27
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
28
+ def initialize(value: nil, **system_arguments)
29
+ @system_arguments = deny_tag_argument(**system_arguments)
30
+ @value = value
31
+
32
+ validate!
33
+
34
+ @system_arguments[:tag] = "clipboard-copy"
35
+ @system_arguments[:value] = value if value.present?
36
+ end
37
+
38
+ # :nodoc:
39
+ def before_render
40
+ validate_aria_label if content.blank?
41
+ end
42
+
43
+ private
44
+
45
+ def validate!
46
+ raise ArgumentError, "Must provide either `value` or `for`" if @value.nil? && @system_arguments[:for].nil?
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,290 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Primer
4
+ module Beta
5
+ # Use `Markdown` to wrap markdown content.
6
+ class Markdown < Primer::Component
7
+ status :beta
8
+
9
+ DEFAULT_TAG = :div
10
+ TAG_OPTIONS = [DEFAULT_TAG, :article, :td].freeze
11
+ # @example Default
12
+ # <%= render(Primer::Beta::Markdown.new) do %>
13
+ # <p>Text can be <b>bold</b>, <i>italic</i>, or <s>strikethrough</s>. <a href="https://github.com">Links </a> should be blue with no underlines (unless hovered over).</p>
14
+ #
15
+ # <p>There should be whitespace between paragraphs. There should be whitespace between paragraphs. There should be whitespace between paragraphs. There should be whitespace between paragraphs.</p>
16
+ #
17
+ # <p>There should be whitespace between paragraphs. There should be whitespace between paragraphs. There should be whitespace between paragraphs. There should be whitespace between paragraphs.</p>
18
+ #
19
+ # <blockquote>
20
+ # <p>There should be no margin above this first sentence.</p>
21
+ # <p>Blockquotes should be a lighter gray with a gray border along the left side.</p>
22
+ # <p>There should be no margin below this final sentence.</p>
23
+ # </blockquote>
24
+ #
25
+ # <h1>Header 1</h1>
26
+ #
27
+ # <p>This is a normal paragraph following a header. Bacon ipsum dolor sit amet t-bone doner shank drumstick, pork belly porchetta chuck sausage brisket ham hock rump pig. Chuck kielbasa leberkas, pork bresaola ham hock filet mignon cow shoulder short ribs biltong.</p>
28
+ #
29
+ # <h2>Header 2</h2>
30
+ #
31
+ # <blockquote>This is a blockquote following a header. Bacon ipsum dolor sit amet t-bone doner shank drumstick, pork belly porchetta chuck sausage brisket ham hock rump pig. Chuck kielbasa leberkas, pork bresaola ham hock filet mignon cow shoulder short ribs biltong.</blockquote>
32
+ #
33
+ # <h3>Header 3</h3>
34
+ #
35
+ # <pre><code>This is a code block following a header.</code></pre>
36
+ #
37
+ # <h4>Header 4</h4>
38
+ #
39
+ # <ul>
40
+ # <li>This is an unordered list following a header.</li>
41
+ # <li>This is an unordered list following a header.</li>
42
+ # <li>This is an unordered list following a header.</li>
43
+ # </ul>
44
+ #
45
+ # <h5>Header 5</h5>
46
+ #
47
+ # <ol>
48
+ # <li>This is an ordered list following a header.</li>
49
+ # <li>This is an ordered list following a header.</li>
50
+ # <li>This is an ordered list following a header.</li>
51
+ # </ol>
52
+ #
53
+ # <h6>Header 6</h6>
54
+ #
55
+ # <table>
56
+ # <thead>
57
+ # <tr>
58
+ # <th>What</th>
59
+ # <th>Follows</th>
60
+ # </tr>
61
+ # </thead>
62
+ # <tbody>
63
+ # <tr>
64
+ # <td>A table</td>
65
+ # <td>A header</td>
66
+ # </tr>
67
+ # <tr>
68
+ # <td>A table</td>
69
+ # <td>A header</td>
70
+ # </tr>
71
+ # <tr>
72
+ # <td>A table</td>
73
+ # <td>A header</td>
74
+ # </tr>
75
+ # </tbody>
76
+ # </table>
77
+ #
78
+ # <hr />
79
+ #
80
+ # <p>There's a horizontal rule above and below this.</p>
81
+ #
82
+ # <hr />
83
+ #
84
+ # <p>Here is an unordered list:</p>
85
+ #
86
+ # <ul>
87
+ # <li>Salt-n-Pepa</li>
88
+ # <li>Bel Biv DeVoe</li>
89
+ # <li>Kid 'N Play</li>
90
+ # </ul>
91
+ #
92
+ # <p>And an ordered list:</p>
93
+ #
94
+ # <ol>
95
+ # <li>Michael Jackson</li>
96
+ # <li>Michael Bolton</li>
97
+ # <li>Michael Bublé</li>
98
+ # </ol>
99
+ #
100
+ # <p>And an unordered task list:</p>
101
+ #
102
+ # <ul>
103
+ # <li><input type="checkbox" id="create-markdown" checked /><label for="create-markdown">Create a sample markdown document</label><br></li>
104
+ # <li><input type="checkbox" id="tasks-list" checked /><label for="tasks-list">Add tasks list to it</label><br></li>
105
+ # <li><input type="checkbox" id="take-vacation" checked /><label for="take-vacation">Take a vacation</label><br></li>
106
+ # </ul>
107
+ #
108
+ # <p>And a "mixed" task list:</p>
109
+ #
110
+ # <ul>
111
+ # <li><input type="checkbox"id="steal-underpants"/><label for="steal-underpants">Steal underpants</label></li>
112
+ # <li>?</li>
113
+ # <li><input type="checkbox"id="profit"/><label for="profit">Profit!</label></li>
114
+ # </ul>
115
+ #
116
+ # And a nested list:
117
+ #
118
+ # <ul>
119
+ # <li>Jackson 5
120
+ # <ul>
121
+ # <li>Michael</li>
122
+ # <li>Tito</li>
123
+ # <li>Jackie</li>
124
+ # <li>Marlon</li>
125
+ # <li>Jermaine</li>
126
+ # </ul>
127
+ # </li>
128
+ # <li>TMNT
129
+ # <ul>
130
+ # <li>Leonardo</li>
131
+ # <li>Michelangelo</li>
132
+ # <li>Donatello</li>
133
+ # <li>Raphael</li>
134
+ # </ul>
135
+ # </li>
136
+ # </ul>
137
+ #
138
+ # <p>Definition lists can be used with HTML syntax. Definition terms are bold and italic.</p>
139
+ #
140
+ # <dl>
141
+ # <dt>Name</dt>
142
+ # <dd>Godzilla</dd>
143
+ # <dt>Born</dt>
144
+ # <dd>1952</dd>
145
+ # <dt>Birthplace</dt>
146
+ # <dd>Japan</dd>
147
+ # <dt>Color</dt>
148
+ # <dd>Green</dd>
149
+ # </dl>
150
+ #
151
+ # <hr />
152
+ #
153
+ # <p>Tables should have bold headings and alternating shaded rows.</p>
154
+ #
155
+ # <table>
156
+ # <thead>
157
+ # <tr>
158
+ # <th>Artist</th>
159
+ # <th>Album</th>
160
+ # <th>Year</th>
161
+ # </tr>
162
+ # </thead>
163
+ # <tbody>
164
+ # <tr>
165
+ # <td>David Bowie</td>
166
+ # <td>Scary Monsters</td>
167
+ # <td>1980</td>
168
+ # </tr>
169
+ # <tr>
170
+ # <td>Prince</td>
171
+ # <td>Purple Rain</td>
172
+ # <td>1982</td>
173
+ # </tr>
174
+ # <tr>
175
+ # <td>Beastie Boys</td>
176
+ # <td>License to Ill</td>
177
+ # <td>1986</td>
178
+ # </tr>
179
+ # <tr>
180
+ # <td>Janet Jackson</td>
181
+ # <td>Rhythm Nation 1814</td>
182
+ # <td>1989</td>
183
+ # </tr>
184
+ # </tbody>
185
+ # </table>
186
+ #
187
+ # <p>If a table is too wide, it should condense down and/or scroll horizontally.</p>
188
+ #
189
+ # <table>
190
+ # <thead>
191
+ # <tr>
192
+ # <th>Artist</th>
193
+ # <th>Album</th>
194
+ # <th>Year</th>
195
+ # <th>Label</th>
196
+ # <th>Songs</th>
197
+ # </tr>
198
+ # </thead>
199
+ # <tbody>
200
+ # <tr>
201
+ # <td>David Bowie</td>
202
+ # <td>Scary Monsters</td>
203
+ # <td>1980</td>
204
+ # <td>RCA Records</td>
205
+ # <td>It's No Game (No. 1), Up the Hill Backwards, Scary Monsters (And Super Creeps), Ashes to Ashes, Fashion, Teenage Wildlife, Scream Like a Baby, Kingdom Come, Because You're Young, It's No Game (No. 2)</td>
206
+ # </tr>
207
+ # <tr>
208
+ # <td>Prince</td>
209
+ # <td>Purple Rain</td>
210
+ # <td>1982</td>
211
+ # <td>Warner Brothers Records</td>
212
+ # <td>Let's Go Crazy, Take Me With U, The Beautiful Ones, Computer Blue, Darling Nikki, When Doves Cry, I Would Die 4 U, Baby I'm a Star, Purple Rain</td>
213
+ # </tr>
214
+ # <tr>
215
+ # <td>Beastie Boys</td>
216
+ # <td>License to Ill</td>
217
+ # <td>1986</td>
218
+ # <td>Def Jam</td>
219
+ # <td>Rhymin &amp; Stealin, The New Style, She's Crafty, Posse in Effect, Slow Ride, Girls, Fight for Your Right, No Sleep till Brooklyn, Paul Revere, "Hold It Now, Hit It", Brass Monkey, Slow and Low, Time to Get Ill</td>
220
+ # </tr>
221
+ # <tr>
222
+ # <td>Janet Jackson</td>
223
+ # <td>Rhythm Nation 1814</td>
224
+ # <td>1989</td>
225
+ # <td>A&amp;M</td>
226
+ # <td>Interlude: Pledge, Rhythm Nation, Interlude: T.V., State of the World, Interlude: Race, The Knowledge, Interlude: Let's Dance, Miss You Much, Interlude: Come Back, Love Will Never Do (Without You), Livin' in a World (They Didn't Make), Alright, Interlude: Hey Baby, Escapade, Interlude: No Acid, Black Cat, Lonely, Come Back to Me, Someday Is Tonight, Interlude: Livin'...In Complete Darkness</td>
227
+ # </tr>
228
+ # </tbody>
229
+ # </table>
230
+ #
231
+ # <hr />
232
+ #
233
+ # <p>Code snippets like <code>var foo = "bar";</code> can be shown inline.</p>
234
+ #
235
+ # <p>Also, <code>this should vertically align</code> <s><code>with this</code></s> <s>and this</s>.</p>
236
+ #
237
+ # <p>Code can also be shown in a block element.</p>
238
+ #
239
+ # <pre><code>var foo = "bar";</code></pre>
240
+ #
241
+ # <p>Code can also use syntax highlighting.</p>
242
+ #
243
+ # <pre><code>var foo = "bar";</code></pre>
244
+ #
245
+ # <pre tabindex="0"><code>Long, single-line code blocks should not wrap. They should horizontally scroll if they are too long. This line should be long enough to demonstrate this.</code></pre>
246
+ #
247
+ # <pre tabindex="0"><code>var foo = "The same thing is true for code with syntax highlighting. A single line of code should horizontally scroll if it is really long.";</code></pre>
248
+ #
249
+ # <p>Inline code inside table cells should still be distinguishable.</p>
250
+ #
251
+ # <table>
252
+ # <thead>
253
+ # <tr>
254
+ # <th>Language</th>
255
+ # <th>Code</th>
256
+ # </tr>
257
+ # </thead>
258
+ # <tbody>
259
+ # <tr>
260
+ # <td>JavasScript</td>
261
+ # <td><code>var foo = "bar";</code></td>
262
+ # </tr>
263
+ # <tr>
264
+ # <td>Ruby</td>
265
+ # <td><code>foo = "bar"</code></td>
266
+ # </tr>
267
+ # </tbody>
268
+ # </table>
269
+ #
270
+ # <pre><code>This is the final element on the page and there should be no margin below this.</code></pre>
271
+ # <% end %>
272
+ #
273
+ # @param tag [Symbol] <%= one_of(Primer::Beta::Markdown::TAG_OPTIONS) %>
274
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
275
+ def initialize(tag: DEFAULT_TAG, **system_arguments)
276
+ @system_arguments = system_arguments
277
+ @system_arguments[:tag] = fetch_or_fallback(TAG_OPTIONS, tag, DEFAULT_TAG)
278
+
279
+ @system_arguments[:classes] = class_names(
280
+ "markdown-body",
281
+ system_arguments[:classes]
282
+ )
283
+ end
284
+
285
+ def call
286
+ render(Primer::BaseComponent.new(**@system_arguments)) { content }
287
+ end
288
+ end
289
+ end
290
+ end
@@ -1 +1 @@
1
- {"version":3,"sources":["popover.pcss"],"names":[],"mappings":"AAEA,SACE,iBAAkB,CAClB,WACF,CAEA,iBAKE,4CAA6C,CAC7C,2EAA6E,CAC7E,mDAAqD,CAHrD,gBAAiB,CADjB,iBAAkB,CAFlB,iBAAkB,CAClB,WA6BF,CArBE,+CAKE,UAAW,CADX,oBAAqB,CADrB,QAAS,CADT,iBAIF,CAEA,wBAIE,sBAAgD,CAAhD,mDAAgD,CAFhD,gBAAiB,CADjB,SAIF,CAEA,uBAIE,sBAAgD,CAAhD,mDAAgD,CAFhD,gBAAiB,CADjB,SAIF,CAKA,mEAEE,YACF,CAOA,mNAGE,yBAAgC,CADhC,QAEF,CAEA,2GAEE,4CAA6C,CAD7C,YAEF,CAEA,wGAEE,4CAA6C,CAD7C,YAEF,CAIF,2DAGE,cAAe,CADf,UAgBF,CAbE,gJAEE,SAAU,CACV,aACF,CAEA,yEACE,UACF,CAEA,uEACE,UACF,CAIF,yDAEE,SAAU,CACV,aAWF,CATE,4IAEE,SAAU,CACV,aACF,CAEA,qEACE,SACF,CAUA,oZAKE,yBAAgC,CAFhC,SAAU,CACV,aAAc,CAFd,OAIF,CAEA,6MACE,eACF,CAEA,uMACE,eACF,CAOA,wGAEE,6CAA8C,CAD9C,WAEF,CAEA,qGAEE,6CAA8C,CAD9C,WAEF,CAOA,qGAEE,8CAA+C,CAD/C,UAEF,CAEA,kGAEE,8CAA+C,CAD/C,UAEF,CAMA,wIAEE,QACF,CAMA,oJAEE,QACF,CAEA,2EACE,WACF,CAEA,yEACE,WACF,CAGF,yBACE,wBACE,eACF,CACF,CAKA,4BACE,SAIE,kBAAoB,CACpB,gBAAkB,CAJlB,cAAe,CAEf,iBAAmB,CADnB,kBAIF,CAEA,iBAGE,WAAY,CACZ,SAAU,CAEV,4CAA8C,CAJ9C,UAAW,CADX,QAAS,CAIT,oBAEF,CAGA,8BACE,wEACF,CAGA,+CAEE,YACF,CACF","file":"popover.css","sourcesContent":["/* Popover */\n\n.Popover {\n position: absolute;\n z-index: 100;\n}\n\n.Popover-message {\n position: relative;\n width: 232px;\n margin-right: auto;\n margin-left: auto;\n background-color: var(--color-canvas-overlay);\n border: var(--primer-borderWidth-thin, 1px) solid var(--color-border-default);\n border-radius: var(--primer-borderRadius-medium, 6px);\n\n /* Carets */\n &::before,\n &::after {\n position: absolute;\n left: 50%;\n display: inline-block;\n content: '';\n }\n\n &::before {\n top: -16px;\n margin-left: -9px;\n border: 8px solid transparent;\n border-bottom-color: var(--color-border-default);\n }\n\n &::after {\n top: -14px;\n margin-left: -8px;\n border: 7px solid transparent;\n border-bottom-color: var(--color-canvas-overlay);\n }\n}\n\n/* No caret */\n.Popover-message--no-caret {\n &::before,\n &::after {\n display: none;\n }\n}\n\n/* Bottom-oriented carets */\n.Popover-message--bottom,\n.Popover-message--bottom-right,\n.Popover-message--bottom-left {\n &::before,\n &::after {\n top: auto;\n border-bottom-color: transparent;\n }\n\n &::before {\n bottom: -16px;\n border-top-color: var(--color-border-default);\n }\n\n &::after {\n bottom: -14px;\n border-top-color: var(--color-canvas-overlay);\n }\n}\n\n/* Top & Bottom: Right-oriented carets */\n.Popover-message--top-right,\n.Popover-message--bottom-right {\n right: -9px;\n margin-right: 0;\n\n &::before,\n &::after {\n left: auto;\n margin-left: 0;\n }\n\n &::before {\n right: 20px;\n }\n\n &::after {\n right: 21px;\n }\n}\n\n/* Top & Bottom: Left-oriented carets */\n.Popover-message--top-left,\n.Popover-message--bottom-left {\n left: -9px;\n margin-left: 0;\n\n &::before,\n &::after {\n left: 24px;\n margin-left: 0;\n }\n\n &::after {\n left: 25px;\n }\n}\n\n/* Right- & Left-oriented carets */\n.Popover-message--right,\n.Popover-message--right-top,\n.Popover-message--right-bottom,\n.Popover-message--left,\n.Popover-message--left-top,\n.Popover-message--left-bottom {\n &::before,\n &::after {\n top: 50%;\n left: auto;\n margin-left: 0;\n border-bottom-color: transparent;\n }\n\n &::before {\n margin-top: -9px;\n }\n\n &::after {\n margin-top: -8px;\n }\n}\n\n/* Right-oriented carets */\n.Popover-message--right,\n.Popover-message--right-top,\n.Popover-message--right-bottom {\n &::before {\n right: -16px;\n border-left-color: var(--color-border-default);\n }\n\n &::after {\n right: -14px;\n border-left-color: var(--color-canvas-overlay);\n }\n}\n\n/* Left-oriented carets */\n.Popover-message--left,\n.Popover-message--left-top,\n.Popover-message--left-bottom {\n &::before {\n left: -16px;\n border-right-color: var(--color-border-default);\n }\n\n &::after {\n left: -14px;\n border-right-color: var(--color-canvas-overlay);\n }\n}\n\n/* Right & Left: Top-oriented carets */\n.Popover-message--right-top,\n.Popover-message--left-top {\n &::before,\n &::after {\n top: 24px;\n }\n}\n\n/* Right & Left: Bottom-oriented carets */\n.Popover-message--right-bottom,\n.Popover-message--left-bottom {\n &::before,\n &::after {\n top: auto;\n }\n\n &::before {\n bottom: 16px;\n }\n\n &::after {\n bottom: 17px;\n }\n}\n\n@media (min-width: 544px) {\n .Popover-message--large {\n min-width: 320px;\n }\n}\n\n/* Responsive Popover\n** For < md it will show full-width anchored to the bottom */\n\n@media (max-width: 767.98px) {\n .Popover {\n position: fixed;\n top: auto !important;\n right: 0 !important;\n bottom: 0 !important;\n left: 0 !important;\n }\n\n .Popover-message {\n top: auto;\n right: auto;\n bottom: auto;\n left: auto;\n width: auto !important;\n margin: var(--primer-stack-gap-condensed, 8px);\n }\n\n /* Increase tap area for touch input */\n .Popover-message > .btn-octicon {\n padding: var(--primer-control-medium-paddingInline-normal, 12px) !important;\n }\n\n /* Remove caret */\n .Popover-message::after,\n .Popover-message::before {\n display: none;\n }\n}\n"]}
1
+ {"version":3,"sources":["popover.pcss"],"names":[],"mappings":"AAEA,SACE,iBAAkB,CAClB,WACF,CAEA,iBAKE,4CAA6C,CAC7C,2EAA6E,CAC7E,mDAAqD,CAHrD,gBAAiB,CADjB,iBAAkB,CAFlB,iBAAkB,CAClB,WA6BF,CArBE,+CAKE,UAAW,CADX,oBAAqB,CADrB,QAAS,CADT,iBAIF,CAEA,wBAIE,sBAAgD,CAAhD,mDAAgD,CAFhD,gBAAiB,CADjB,SAIF,CAEA,uBAIE,sBAAgD,CAAhD,mDAAgD,CAFhD,gBAAiB,CADjB,SAIF,CAKA,mEAEE,YACF,CAOA,mNAGE,yBAAgC,CADhC,QAEF,CAEA,2GAEE,4CAA6C,CAD7C,YAEF,CAEA,wGAEE,4CAA6C,CAD7C,YAEF,CAIF,2DAGE,cAAe,CADf,UAgBF,CAbE,gJAEE,SAAU,CACV,aACF,CAEA,yEACE,UACF,CAEA,uEACE,UACF,CAIF,yDAEE,SAAU,CACV,aAWF,CATE,4IAEE,SAAU,CACV,aACF,CAEA,qEACE,SACF,CAUA,oZAKE,yBAAgC,CAFhC,SAAU,CACV,aAAc,CAFd,OAIF,CAEA,6MACE,eACF,CAEA,uMACE,eACF,CAOA,wGAEE,6CAA8C,CAD9C,WAEF,CAEA,qGAEE,6CAA8C,CAD9C,WAEF,CAOA,qGAEE,8CAA+C,CAD/C,UAEF,CAEA,kGAEE,8CAA+C,CAD/C,UAEF,CAMA,wIAEE,QACF,CAMA,oJAEE,QACF,CAEA,2EACE,WACF,CAEA,yEACE,WACF,CAGF,yBACE,wBACE,eACF,CACF,CAKA,4BACE,SAIE,kBAAoB,CACpB,gBAAkB,CAJlB,cAAe,CAEf,iBAAmB,CADnB,kBAIF,CAEA,iBAGE,WAAY,CACZ,SAAU,CAEV,4CAA8C,CAJ9C,UAAW,CADX,QAAS,CAIT,oBAEF,CAGA,8BACE,wEACF,CAGA,+CAEE,YACF,CACF","file":"popover.css","sourcesContent":["/* Popover */\n\n.Popover {\n position: absolute;\n z-index: 100;\n}\n\n.Popover-message {\n position: relative;\n width: 232px;\n margin-right: auto;\n margin-left: auto;\n background-color: var(--color-canvas-overlay);\n border: var(--primer-borderWidth-thin, 1px) solid var(--color-border-default);\n border-radius: var(--primer-borderRadius-medium, 6px);\n\n /* Carets */\n &::before,\n &::after {\n position: absolute;\n left: 50%;\n display: inline-block;\n content: '';\n }\n\n &::before {\n top: -16px;\n margin-left: -9px;\n border: 8px solid transparent;\n border-bottom-color: var(--color-border-default);\n }\n\n &::after {\n top: -14px;\n margin-left: -8px;\n border: 7px solid transparent;\n border-bottom-color: var(--color-canvas-overlay);\n }\n}\n\n/* No caret */\n.Popover-message--no-caret {\n &::before,\n &::after {\n display: none;\n }\n}\n\n/* Bottom-oriented carets */\n.Popover-message--bottom,\n.Popover-message--bottom-right,\n.Popover-message--bottom-left {\n &::before,\n &::after {\n top: auto;\n border-bottom-color: transparent;\n }\n\n &::before {\n bottom: -16px;\n border-top-color: var(--color-border-default);\n }\n\n &::after {\n bottom: -14px;\n border-top-color: var(--color-canvas-overlay);\n }\n}\n\n/* Top and Bottom: Right-oriented carets */\n.Popover-message--top-right,\n.Popover-message--bottom-right {\n right: -9px;\n margin-right: 0;\n\n &::before,\n &::after {\n left: auto;\n margin-left: 0;\n }\n\n &::before {\n right: 20px;\n }\n\n &::after {\n right: 21px;\n }\n}\n\n/* Top and Bottom: Left-oriented carets */\n.Popover-message--top-left,\n.Popover-message--bottom-left {\n left: -9px;\n margin-left: 0;\n\n &::before,\n &::after {\n left: 24px;\n margin-left: 0;\n }\n\n &::after {\n left: 25px;\n }\n}\n\n/* Right- and Left-oriented carets */\n.Popover-message--right,\n.Popover-message--right-top,\n.Popover-message--right-bottom,\n.Popover-message--left,\n.Popover-message--left-top,\n.Popover-message--left-bottom {\n &::before,\n &::after {\n top: 50%;\n left: auto;\n margin-left: 0;\n border-bottom-color: transparent;\n }\n\n &::before {\n margin-top: -9px;\n }\n\n &::after {\n margin-top: -8px;\n }\n}\n\n/* Right-oriented carets */\n.Popover-message--right,\n.Popover-message--right-top,\n.Popover-message--right-bottom {\n &::before {\n right: -16px;\n border-left-color: var(--color-border-default);\n }\n\n &::after {\n right: -14px;\n border-left-color: var(--color-canvas-overlay);\n }\n}\n\n/* Left-oriented carets */\n.Popover-message--left,\n.Popover-message--left-top,\n.Popover-message--left-bottom {\n &::before {\n left: -16px;\n border-right-color: var(--color-border-default);\n }\n\n &::after {\n left: -14px;\n border-right-color: var(--color-canvas-overlay);\n }\n}\n\n/* Right and Left: Top-oriented carets */\n.Popover-message--right-top,\n.Popover-message--left-top {\n &::before,\n &::after {\n top: 24px;\n }\n}\n\n/* Right and Left: Bottom-oriented carets */\n.Popover-message--right-bottom,\n.Popover-message--left-bottom {\n &::before,\n &::after {\n top: auto;\n }\n\n &::before {\n bottom: 16px;\n }\n\n &::after {\n bottom: 17px;\n }\n}\n\n@media (min-width: 544px) {\n .Popover-message--large {\n min-width: 320px;\n }\n}\n\n/* Responsive Popover\n** For < md it will show full-width anchored to the bottom */\n\n@media (max-width: 767.98px) {\n .Popover {\n position: fixed;\n top: auto !important;\n right: 0 !important;\n bottom: 0 !important;\n left: 0 !important;\n }\n\n .Popover-message {\n top: auto;\n right: auto;\n bottom: auto;\n left: auto;\n width: auto !important;\n margin: var(--primer-stack-gap-condensed, 8px);\n }\n\n /* Increase tap area for touch input */\n .Popover-message > .btn-octicon {\n padding: var(--primer-control-medium-paddingInline-normal, 12px) !important;\n }\n\n /* Remove caret */\n .Popover-message::after,\n .Popover-message::before {\n display: none;\n }\n}\n"]}
@@ -67,7 +67,7 @@
67
67
  }
68
68
  }
69
69
 
70
- /* Top & Bottom: Right-oriented carets */
70
+ /* Top and Bottom: Right-oriented carets */
71
71
  .Popover-message--top-right,
72
72
  .Popover-message--bottom-right {
73
73
  right: -9px;
@@ -88,7 +88,7 @@
88
88
  }
89
89
  }
90
90
 
91
- /* Top & Bottom: Left-oriented carets */
91
+ /* Top and Bottom: Left-oriented carets */
92
92
  .Popover-message--top-left,
93
93
  .Popover-message--bottom-left {
94
94
  left: -9px;
@@ -105,7 +105,7 @@
105
105
  }
106
106
  }
107
107
 
108
- /* Right- & Left-oriented carets */
108
+ /* Right- and Left-oriented carets */
109
109
  .Popover-message--right,
110
110
  .Popover-message--right-top,
111
111
  .Popover-message--right-bottom,
@@ -159,7 +159,7 @@
159
159
  }
160
160
  }
161
161
 
162
- /* Right & Left: Top-oriented carets */
162
+ /* Right and Left: Top-oriented carets */
163
163
  .Popover-message--right-top,
164
164
  .Popover-message--left-top {
165
165
  &::before,
@@ -168,7 +168,7 @@
168
168
  }
169
169
  }
170
170
 
171
- /* Right & Left: Bottom-oriented carets */
171
+ /* Right and Left: Bottom-oriented carets */
172
172
  .Popover-message--right-bottom,
173
173
  .Popover-message--left-bottom {
174
174
  &::before,
@@ -0,0 +1,160 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Primer
4
+ module Beta
5
+ # Formats a timestamp as a localized string or as relative text that auto-updates in the user's browser.
6
+ class RelativeTime < Primer::Component
7
+ status :beta
8
+
9
+ TENSE_DEFAULT = :auto
10
+ TENSE_OPTIONS = [TENSE_DEFAULT, :past, :future].freeze
11
+
12
+ FORMAT_DEFAULT = :auto
13
+ FORMAT_OPTIONS = [FORMAT_DEFAULT, :micro, :elapsed].freeze
14
+
15
+ SECOND_DEFAULT = nil
16
+ SECOND_MAPPINGS = {
17
+ SECOND_DEFAULT => nil,
18
+ :numeric => "numeric",
19
+ :two_digit => "2-digit"
20
+ }.freeze
21
+ SECOND_OPTIONS = SECOND_MAPPINGS.keys
22
+
23
+ MINUTE_DEFAULT = nil
24
+ MINUTE_MAPPINGS = {
25
+ MINUTE_DEFAULT => nil,
26
+ :numeric => "numeric",
27
+ :two_digit => "2-digit"
28
+ }.freeze
29
+ MINUTE_OPTIONS = MINUTE_MAPPINGS.keys
30
+
31
+ HOUR_DEFAULT = nil
32
+ HOUR_MAPPINGS = {
33
+ HOUR_DEFAULT => nil,
34
+ :numeric => "numeric",
35
+ :two_digit => "2-digit"
36
+ }.freeze
37
+ HOUR_OPTIONS = HOUR_MAPPINGS.keys
38
+
39
+ WEEKDAY_DEFAULT = nil
40
+ WEEKDAY_OPTIONS = [WEEKDAY_DEFAULT, :long, :short, :narrow].freeze
41
+
42
+ DAY_DEFAULT = nil
43
+ DAY_MAPPINGS = {
44
+ DAY_DEFAULT => nil,
45
+ :numeric => "numeric",
46
+ :two_digit => "2-digit"
47
+ }.freeze
48
+ DAY_OPTIONS = DAY_MAPPINGS.keys
49
+
50
+ MONTH_DEFAULT = nil
51
+ MONTH_MAPPINGS = {
52
+ DAY_DEFAULT => nil,
53
+ :numeric => "numeric",
54
+ :two_digit => "2-digit",
55
+ :short => "short",
56
+ :long => "long",
57
+ :narrow => "narrow"
58
+ }.freeze
59
+ MONTH_OPTIONS = MONTH_MAPPINGS.keys
60
+
61
+ YEAR_DEFAULT = nil
62
+ YEAR_MAPPINGS = {
63
+ DAY_DEFAULT => nil,
64
+ :numeric => "numeric",
65
+ :two_digit => "2-digit"
66
+ }.freeze
67
+ YEAR_OPTIONS = YEAR_MAPPINGS.keys
68
+
69
+ TIMEZONENAME_DEFAULT = nil
70
+ TIMEZONE_MAPPINGS = {
71
+ DAY_DEFAULT => nil,
72
+ :long => "long",
73
+ :short => "short",
74
+ :short_offset => "shortOffset",
75
+ :long_offset => "longOffset",
76
+ :short_generic => "shortGeneric",
77
+ :long_generic => "longGeneric"
78
+ }.freeze
79
+ TIMEZONENAME_OPTIONS = TIMEZONE_MAPPINGS.keys
80
+
81
+ PRECISION_DEFAULT = nil
82
+ PRECISION_OPTIONS = [PRECISION_DEFAULT, :second, :minute, :hour, :day, :month, :year].freeze
83
+
84
+ # @example Default
85
+ # <%= render(Primer::Beta::RelativeTime.new(datetime: Time.at(628232400))) %>
86
+ #
87
+ # @example Past Time
88
+ # <%= render(Primer::Beta::RelativeTime.new(datetime: Time.at(628232400), tense: :past)) %>
89
+ #
90
+ # @example Elapsed Time
91
+ # <%= render(Primer::Beta::RelativeTime.new(datetime: Time.at(628232400), format: :elapsed)) %>
92
+ #
93
+ # @param datetime [Time] The time to be formatted.
94
+ # @param tense [Symbol] Which tense to use. <%= one_of(Primer::Beta::RelativeTime::TENSE_OPTIONS) %>
95
+ # @param prefix [sring] What to prefix the relative ime display with.
96
+ # @param second [Symbol] What format seconds should take. <%= one_of(Primer::Beta::RelativeTime::SECOND_OPTIONS) %>
97
+ # @param minute [Symbol] What format minues should take. <%= one_of(Primer::Beta::RelativeTime::MINUTE_OPTIONS) %>
98
+ # @param hour [Symbol] What format hours should take. <%= one_of(Primer::Beta::RelativeTime::HOUR_OPTIONS) %>
99
+ # @param weekday [Symbol] What format weekdays should take. <%= one_of(Primer::Beta::RelativeTime::WEEKDAY_OPTIONS) %>
100
+ # @param day [Symbol] What format days should take. <%= one_of(Primer::Beta::RelativeTime::DAY_OPTIONS) %>
101
+ # @param month [Symbol] What format months should take. <%= one_of(Primer::Beta::RelativeTime::MONTH_OPTIONS) %>
102
+ # @param year [Symbol] What format years should take. <%= one_of(Primer::Beta::RelativeTime::YEAR_OPTIONS) %>
103
+ # @param time_zone_name [Symbol] What format the time zone should take. <%= one_of(Primer::Beta::RelativeTime::TIMEZONENAME_OPTIONS) %>
104
+ # @param threshold [string] The threshold at which relative time displays become absolute.
105
+ # @param precision [Symbol] The precision elapsed time should display. <%= one_of(Primer::Beta::RelativeTime::PRECISION_OPTIONS) %>
106
+ # @param format [Symbol] The format the display should take. <%= one_of(Primer::Beta::RelativeTime::FORMAT_OPTIONS) %>
107
+ # @param lang [string] The language to use.
108
+ # @param title [string] Provide a custom title to the element.
109
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
110
+ def initialize(
111
+ datetime:,
112
+ tense: TENSE_DEFAULT,
113
+ prefix: nil,
114
+ second: SECOND_DEFAULT,
115
+ minute: MINUTE_DEFAULT,
116
+ hour: HOUR_DEFAULT,
117
+ weekday: WEEKDAY_DEFAULT,
118
+ day: DAY_DEFAULT,
119
+ month: MONTH_DEFAULT,
120
+ year: YEAR_DEFAULT,
121
+ time_zone_name: TIMEZONENAME_DEFAULT,
122
+ threshold: nil,
123
+ precision: PRECISION_DEFAULT,
124
+ format: nil,
125
+ lang: nil,
126
+ title: nil,
127
+ **system_arguments
128
+ )
129
+ @system_arguments = deny_tag_argument(**system_arguments)
130
+ @system_arguments[:tag] = "relative-time"
131
+ @system_arguments[:tense] = tense if tense.present?
132
+ @system_arguments[:prefix] = prefix if prefix.present?
133
+ @system_arguments[:second] = fetch_or_fallback(SECOND_OPTIONS, second, SECOND_DEFAULT) if second.present?
134
+ @system_arguments[:minute] = fetch_or_fallback(MINUTE_OPTIONS, minute, MINUTE_DEFAULT) if minute.present?
135
+ @system_arguments[:hour] = fetch_or_fallback(HOUR_OPTIONS, hour, HOUR_DEFAULT) if hour.present?
136
+ @system_arguments[:weekday] = fetch_or_fallback(WEEKDAY_OPTIONS, weekday, WEEKDAY_DEFAULT) if weekday.present?
137
+ @system_arguments[:day] = fetch_or_fallback(DAY_OPTIONS, day, DAY_DEFAULT) if day.present?
138
+ @system_arguments[:month] = fetch_or_fallback(MONTH_DEFAULT, month, MONTH_DEFAULT) if month.present?
139
+ @system_arguments[:year] = fetch_or_fallback(YEAR_OPTIONS, year, YEAR_DEFAULT) if year.present?
140
+ @system_arguments[:"time-zone-name"] = fetch_or_fallback(TIMEZONENAME_OPTIONS, time_zone_name, TIMEZONENAME_DEFAULT) if time_zone_name.present?
141
+ @system_arguments[:threshold] = threshold if threshold.present?
142
+ @system_arguments[:precision] = precision if precision.present?
143
+ @system_arguments[:title] = title if title.present?
144
+ @system_arguments[:lang] = lang if lang.present?
145
+ @system_arguments[:format] = fetch_or_fallback(FORMAT_OPTIONS, format, FORMAT_DEFAULT) if format.present?
146
+ if datetime.present? && datetime.respond_to?(:iso8601)
147
+ @datetime = datetime
148
+ @system_arguments[:datetime] = datetime.iso8601
149
+ elsif datetime.present?
150
+ @datetime = Time.iso8601 datetime
151
+ @system_arguments[:datetime] = @datetime
152
+ end
153
+ end
154
+
155
+ def call
156
+ render(Primer::BaseComponent.new(**@system_arguments).with_content(@datetime.strftime("%B %-d, %Y %H:%M")))
157
+ end
158
+ end
159
+ end
160
+ end
@@ -3,7 +3,7 @@
3
3
  module Primer
4
4
  # Use `Button` for actions (e.g. in forms). Use links for destinations, or moving from one page to another.
5
5
  class ButtonComponent < Primer::Component
6
- status :beta
6
+ status :deprecated
7
7
 
8
8
  DEFAULT_SCHEME = :default
9
9
  LINK_SCHEME = :link