primer_view_components 0.0.105 → 0.0.106

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,11 @@
1
+ export declare class XBannerElement extends HTMLElement {
2
+ root: HTMLElement;
3
+ titleText: HTMLElement;
4
+ dismiss(): void;
5
+ private shouldReappear;
6
+ }
7
+ declare global {
8
+ interface Window {
9
+ XBannerElement: typeof XBannerElement;
10
+ }
11
+ }
@@ -0,0 +1,39 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import { controller, target } from '@github/catalyst';
8
+ let XBannerElement = class XBannerElement extends HTMLElement {
9
+ dismiss() {
10
+ if (this.shouldReappear()) {
11
+ this.style.setProperty('visibility', 'hidden');
12
+ setTimeout(() => {
13
+ this.style.setProperty('visibility', 'visible');
14
+ }, 2000);
15
+ return;
16
+ }
17
+ const parentElement = this.parentElement;
18
+ if (!parentElement)
19
+ return;
20
+ parentElement.removeChild(this);
21
+ }
22
+ shouldReappear() {
23
+ return this.root.getAttribute('data-reappear') === 'true';
24
+ }
25
+ };
26
+ __decorate([
27
+ target
28
+ ], XBannerElement.prototype, "root", void 0);
29
+ __decorate([
30
+ target
31
+ ], XBannerElement.prototype, "titleText", void 0);
32
+ XBannerElement = __decorate([
33
+ controller
34
+ ], XBannerElement);
35
+ export { XBannerElement };
36
+ if (!window.customElements.get('x-banner')) {
37
+ window.XBannerElement = XBannerElement;
38
+ window.customElements.define('x-banner', XBannerElement);
39
+ }
@@ -0,0 +1,39 @@
1
+ import {controller, target} from '@github/catalyst'
2
+
3
+ @controller
4
+ export class XBannerElement extends HTMLElement {
5
+ @target root: HTMLElement
6
+ @target titleText: HTMLElement
7
+
8
+ dismiss() {
9
+ if (this.shouldReappear()) {
10
+ this.style.setProperty('visibility', 'hidden')
11
+
12
+ setTimeout(() => {
13
+ this.style.setProperty('visibility', 'visible')
14
+ }, 2000)
15
+
16
+ return
17
+ }
18
+
19
+ const parentElement = this.parentElement
20
+ if (!parentElement) return
21
+
22
+ parentElement.removeChild(this)
23
+ }
24
+
25
+ private shouldReappear(): boolean {
26
+ return this.root.getAttribute('data-reappear') === 'true'
27
+ }
28
+ }
29
+
30
+ declare global {
31
+ interface Window {
32
+ XBannerElement: typeof XBannerElement
33
+ }
34
+ }
35
+
36
+ if (!window.customElements.get('x-banner')) {
37
+ window.XBannerElement = XBannerElement
38
+ window.customElements.define('x-banner', XBannerElement)
39
+ }
@@ -5,6 +5,7 @@ import './alpha/segmented_control';
5
5
  import './alpha/toggle_switch';
6
6
  import './alpha/tool_tip';
7
7
  import './beta/auto_complete/auto_complete';
8
+ import './beta/x_banner';
8
9
  import './clipboard_copy';
9
10
  import './dropdown';
10
11
  import './local_time';
@@ -5,6 +5,7 @@ import './alpha/segmented_control';
5
5
  import './alpha/toggle_switch';
6
6
  import './alpha/tool_tip';
7
7
  import './beta/auto_complete/auto_complete';
8
+ import './beta/x_banner';
8
9
  import './clipboard_copy';
9
10
  import './dropdown';
10
11
  import './local_time';
@@ -1,4 +1,5 @@
1
1
  /* CSS component styles here */
2
+ @import "./beta/banner.pcss";
2
3
  @import "./beta/button.pcss";
3
4
  @import "./alpha/action_list/action-list.pcss";
4
5
  @import './alpha/segmented_control.pcss';
@@ -5,6 +5,7 @@ import './alpha/segmented_control'
5
5
  import './alpha/toggle_switch'
6
6
  import './alpha/tool_tip'
7
7
  import './beta/auto_complete/auto_complete'
8
+ import './beta/x_banner'
8
9
  import './clipboard_copy'
9
10
  import './dropdown'
10
11
  import './local_time'
@@ -7,11 +7,11 @@ module ERBLint
7
7
  module ArgumentMappers
8
8
  # Maps classes in a flash element to arguments for the Flash component.
9
9
  class Flash < Base
10
- SCHEME_MAPPINGS = Primer::ViewComponents::Constants.get(
11
- component: "Primer::Beta::Flash",
12
- constant: "SCHEME_MAPPINGS",
13
- symbolize: true
14
- ).freeze
10
+ SCHEME_MAPPINGS = {
11
+ "flash-success" => ":success",
12
+ "flash-warn" => ":warning",
13
+ "flash-error" => ":danger"
14
+ }.freeze
15
15
 
16
16
  def classes_to_args(classes)
17
17
  classes.each_with_object({ classes: [] }) do |class_name, acc|
@@ -0,0 +1,140 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "helpers/rubocop_helpers"
4
+
5
+ module ERBLint
6
+ module Linters
7
+ # Migrates deprecated arguments in Primer::Beta::Flash components to their equivalents.
8
+ class MigrateDeprecatedFlashArguments < Linter
9
+ # Taken from https://github.com/rails/rails/blob/main/actionview/lib/action_view/template/handlers/erb/erubi.rb#L45
10
+ BLOCK_EXPR = /\s*((\s+|\))do|\{)(\s*\|[^|]*\|)?\s*\Z/.freeze
11
+
12
+ include ERBLint::LinterRegistry
13
+ include Helpers::RubocopHelpers
14
+
15
+ def run(processed_source)
16
+ processed_source.ast.descendants(:erb).each do |erb_node|
17
+ indicator_node, _, code_node = *erb_node
18
+ code = code_node.children.first
19
+ ast = erb_ast(maybe_close_block(code))
20
+ next unless ast
21
+
22
+ constructor_arg_hashes = find_new_flash_instances(ast)
23
+ next if constructor_arg_hashes.empty?
24
+
25
+ indicator, = *indicator_node
26
+ indicator ||= ""
27
+
28
+ # +2 to account for the leading "<%" characters
29
+ code_start_pos = erb_node.location.begin_pos + indicator.size + 2
30
+
31
+ constructor_arg_hashes.each do |constructor_arg_hash|
32
+ spacious_arg = constructor_arg_hash.include?(:spacious)
33
+ next unless spacious_arg
34
+
35
+ orig_loc = code_node.location
36
+ key_node, value_node = constructor_arg_hash[:spacious]
37
+
38
+ new_loc = orig_loc.with(
39
+ begin_pos: key_node.location.expression.begin_pos + code_start_pos,
40
+ end_pos: value_node.location.expression.end_pos + code_start_pos
41
+ )
42
+
43
+ if value_node.source == "true"
44
+ add_offense(
45
+ new_loc,
46
+ "The :spacious argument is deprecated. Use `mb: 4` instead.",
47
+ "mb: 4"
48
+ )
49
+ else
50
+ new_loc = adjust_to_preceding_comma(new_loc)
51
+
52
+ add_offense(
53
+ new_loc,
54
+ "The :spacious argument is deprecated; `spacious: false` can be removed.",
55
+ ""
56
+ )
57
+ end
58
+ end
59
+ end
60
+ end
61
+
62
+ def autocorrect(_, offense)
63
+ return unless offense.context
64
+
65
+ lambda do |corrector|
66
+ corrector.replace(offense.source_range, offense.context)
67
+ end
68
+ end
69
+
70
+ private
71
+
72
+ def adjust_to_preceding_comma(loc)
73
+ comma_pos = loc.source_buffer.source.rindex(/\s*,/, loc.begin_pos)
74
+ return loc unless comma_pos
75
+
76
+ loc.with(begin_pos: comma_pos)
77
+ end
78
+
79
+ def find_new_flash_instances(ast)
80
+ if (instance = find_new_flash_instance(ast))
81
+ return [instance]
82
+ end
83
+
84
+ ast.each_child_node.flat_map do |child_ast|
85
+ find_new_flash_instances(child_ast)
86
+ end
87
+ end
88
+
89
+ def find_new_flash_instance(ast)
90
+ render_body = unwrap_render(ast)
91
+ return nil unless render_body
92
+
93
+ constructor_args = unwrap_constructor(render_body)
94
+ return nil unless constructor_args
95
+
96
+ arg1, = *render_body
97
+ return nil unless arg1.type == :const
98
+ return nil unless arg1.source == "Primer::Beta::Flash"
99
+
100
+ parse_args(constructor_args)
101
+ end
102
+
103
+ def parse_args(arg_node)
104
+ arg_node.children.each_with_object({}) do |child, memo|
105
+ key_node, value_node = *child.children
106
+ memo[key_node.source.to_sym] = [key_node, value_node]
107
+ end
108
+ end
109
+
110
+ def unwrap_render(ast)
111
+ unwrap_method_call(ast, :render)
112
+ end
113
+
114
+ def unwrap_constructor(ast)
115
+ unwrap_method_call(ast, :new)
116
+ end
117
+
118
+ def unwrap_method_call(ast, method_name)
119
+ return nil unless ast
120
+ return nil unless ast.type == :send
121
+
122
+ _, name, body = *ast
123
+ return nil if name != method_name
124
+
125
+ body
126
+ end
127
+
128
+ def maybe_close_block(code)
129
+ match = code.match(BLOCK_EXPR)
130
+ return code unless match
131
+
132
+ if match.captures[0].strip == "do"
133
+ "#{code}; end"
134
+ else
135
+ "#{code} }"
136
+ end
137
+ end
138
+ end
139
+ end
140
+ end
@@ -6,7 +6,7 @@ module Primer
6
6
  module VERSION
7
7
  MAJOR = 0
8
8
  MINOR = 0
9
- PATCH = 105
9
+ PATCH = 106
10
10
 
11
11
  STRING = [MAJOR, MINOR, PATCH].join(".")
12
12
  end
data/lib/tasks/docs.rake CHANGED
@@ -44,6 +44,7 @@ namespace :docs do
44
44
  Primer::Beta::Avatar,
45
45
  Primer::Beta::AvatarStack,
46
46
  Primer::Beta::BaseButton,
47
+ Primer::Beta::Banner,
47
48
  Primer::Beta::Blankslate,
48
49
  Primer::Beta::BorderBox,
49
50
  Primer::Beta::BorderBox::Header,
@@ -102,6 +103,7 @@ namespace :docs do
102
103
  Primer::LocalTime,
103
104
  Primer::Alpha::ImageCrop,
104
105
  Primer::Beta::AutoComplete,
106
+ Primer::Beta::Banner,
105
107
  Primer::ClipboardCopy,
106
108
  Primer::TabContainerComponent,
107
109
  Primer::TimeAgoComponent,
@@ -0,0 +1,4 @@
1
+ <%= render(Primer::Beta::Banner.new(full: full, dismissible: dismissible, icon: icon, scheme: scheme, reappear: reappear)) do |component| %>
2
+ <% component.with_action_button(size: :medium) { "Take action" } %>
3
+ <%= content %>
4
+ <% end %>
@@ -0,0 +1,6 @@
1
+ <%= render(Primer::Beta::Banner.new(full: full, dismissible: dismissible, icon: icon, scheme: scheme, reappear: reappear)) do |component| %>
2
+ <% component.with_action_content do %>
3
+ <%= render(Primer::Beta::IconButton.new(icon: :pencil, mr: 1, "aria-label": "Edit")) %>
4
+ <% end %>
5
+ <%= content %>
6
+ <% end %>
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Primer
4
+ module Beta
5
+ # @label Banner
6
+ class BannerPreview < ViewComponent::Preview
7
+ # @label Playground
8
+ #
9
+ # @param full toggle
10
+ # @param full_when_narrow toggle
11
+ # @param dismissible toggle
12
+ # @param icon [Symbol] octicon
13
+ # @param scheme [Symbol] select [default, warning, danger, success]
14
+ # @param content text
15
+ # @param description text
16
+ # @param reappear [Boolean]
17
+ def playground(full: false, full_when_narrow: false, dismissible: false, icon: :people, scheme: Primer::Beta::Banner::DEFAULT_SCHEME, reappear: true, content: "This is a banner!", description: nil)
18
+ icon = nil if icon == :none
19
+ render(Primer::Beta::Banner.new(full: full, full_when_narrow: full_when_narrow, dismissible: dismissible, icon: icon == :none ? nil : icon, scheme: scheme, description: description, reappear: reappear)) { content }
20
+ end
21
+
22
+ # @label Default
23
+ def default
24
+ render(Primer::Beta::Banner.new) { "This is a banner!" }
25
+ end
26
+
27
+ # @label With action button
28
+ #
29
+ # @param full toggle
30
+ # @param dismissible toggle
31
+ # @param icon [Symbol] octicon
32
+ # @param scheme [Symbol] select [default, warning, danger, success]
33
+ # @param content text
34
+ # @param reappear [Boolean]
35
+ def with_action_button(full: false, dismissible: false, icon: :people, scheme: Primer::Beta::Banner::DEFAULT_SCHEME, reappear: true, content: "This is a banner with an action!")
36
+ icon = nil if icon == :none
37
+ render_with_template(locals: { full: full, dismissible: dismissible, icon: icon == :none ? nil : icon, scheme: scheme, content: content, reappear: reappear })
38
+ end
39
+
40
+ # @label With action content
41
+ #
42
+ # @param full toggle
43
+ # @param dismissible toggle
44
+ # @param icon [Symbol] octicon
45
+ # @param scheme [Symbol] select [default, warning, danger, success]
46
+ # @param content text
47
+ # @param reappear [Boolean]
48
+ def with_action_content(full: false, dismissible: false, icon: :people, scheme: Primer::Beta::Banner::DEFAULT_SCHEME, reappear: true, content: "Did you know? Comments can be edited.")
49
+ icon = nil if icon == :none
50
+ render_with_template(locals: { full: full, dismissible: dismissible, icon: icon == :none ? nil : icon, scheme: scheme, content: content, reappear: reappear })
51
+ end
52
+ end
53
+ end
54
+ end
@@ -1117,6 +1117,62 @@
1117
1117
  }
1118
1118
  ]
1119
1119
  },
1120
+ {
1121
+ "component": "Banner",
1122
+ "status": "beta",
1123
+ "source": "https://github.com/primer/view_components/tree/main/app/components/primer/beta/banner.rb",
1124
+ "lookbook": "https://primer.style/view-components/lookbook/inspect/primer/beta/banner/default/",
1125
+ "parameters": [
1126
+ {
1127
+ "name": "full",
1128
+ "type": "Boolean",
1129
+ "default": "`false`",
1130
+ "description": "Whether the component should take up the full width of the screen."
1131
+ },
1132
+ {
1133
+ "name": "full_when_narrow",
1134
+ "type": "Boolean",
1135
+ "default": "`false`",
1136
+ "description": "Whether the component should take up the full width of the screen when rendered inside smaller viewports."
1137
+ },
1138
+ {
1139
+ "name": "dismissible",
1140
+ "type": "Boolean",
1141
+ "default": "`false`",
1142
+ "description": "Whether the component can be dismissed with an \"x\" button."
1143
+ },
1144
+ {
1145
+ "name": "description",
1146
+ "type": "String",
1147
+ "default": "`nil`",
1148
+ "description": "Description text rendered underneath the message."
1149
+ },
1150
+ {
1151
+ "name": "icon",
1152
+ "type": "Symbol",
1153
+ "default": "`nil`",
1154
+ "description": "The name of an [Octicon](https://primer.style/octicons/) icon to use. If no icon is provided, a default one will be chosen based on the scheme."
1155
+ },
1156
+ {
1157
+ "name": "scheme",
1158
+ "type": "Symbol",
1159
+ "default": "`:default`",
1160
+ "description": "One of `:danger`, `:default`, `:success`, or `:warning`."
1161
+ },
1162
+ {
1163
+ "name": "reappear",
1164
+ "type": "Boolean",
1165
+ "default": "`false`",
1166
+ "description": "Whether or not the flash banner should reappear after being dismissed. Only for use in test and preview environments."
1167
+ },
1168
+ {
1169
+ "name": "system_arguments",
1170
+ "type": "Hash",
1171
+ "default": "N/A",
1172
+ "description": "[System arguments](/system-arguments)"
1173
+ }
1174
+ ]
1175
+ },
1120
1176
  {
1121
1177
  "component": "BaseButton",
1122
1178
  "status": "beta",
@@ -33,6 +33,7 @@
33
33
  "Primer::Beta::AutoComplete::Item": "",
34
34
  "Primer::Beta::Avatar": "",
35
35
  "Primer::Beta::AvatarStack": "",
36
+ "Primer::Beta::Banner": "",
36
37
  "Primer::Beta::BaseButton": "",
37
38
  "Primer::Beta::Blankslate": "",
38
39
  "Primer::Beta::BorderBox": "",
@@ -396,6 +396,21 @@
396
396
  "span"
397
397
  ]
398
398
  },
399
+ "Primer::Beta::Banner": {
400
+ "DEFAULT_ICONS": {
401
+ "default": "bell",
402
+ "warning": "alert",
403
+ "danger": "stop",
404
+ "success": "check-circle"
405
+ },
406
+ "DEFAULT_SCHEME": "default",
407
+ "SCHEME_MAPPINGS": {
408
+ "default": "",
409
+ "warning": "Banner--warning",
410
+ "danger": "Banner--error",
411
+ "success": "Banner--success"
412
+ }
413
+ },
399
414
  "Primer::Beta::BaseButton": {
400
415
  "DEFAULT_TAG": "button",
401
416
  "DEFAULT_TYPE": "button",
data/static/statuses.json CHANGED
@@ -33,6 +33,7 @@
33
33
  "Primer::Beta::AutoComplete::Item": "beta",
34
34
  "Primer::Beta::Avatar": "beta",
35
35
  "Primer::Beta::AvatarStack": "beta",
36
+ "Primer::Beta::Banner": "beta",
36
37
  "Primer::Beta::BaseButton": "beta",
37
38
  "Primer::Beta::Blankslate": "beta",
38
39
  "Primer::Beta::BorderBox": "beta",
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: primer_view_components
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.105
4
+ version: 0.0.106
5
5
  platform: ruby
6
6
  authors:
7
7
  - GitHub Open Source
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-10-24 00:00:00.000000000 Z
11
+ date: 2022-10-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: actionview
@@ -491,6 +491,11 @@ files:
491
491
  - app/components/primer/beta/avatar.rb
492
492
  - app/components/primer/beta/avatar_stack.html.erb
493
493
  - app/components/primer/beta/avatar_stack.rb
494
+ - app/components/primer/beta/banner.css
495
+ - app/components/primer/beta/banner.css.map
496
+ - app/components/primer/beta/banner.html.erb
497
+ - app/components/primer/beta/banner.pcss
498
+ - app/components/primer/beta/banner.rb
494
499
  - app/components/primer/beta/base_button.rb
495
500
  - app/components/primer/beta/blankslate.html.erb
496
501
  - app/components/primer/beta/blankslate.rb
@@ -521,6 +526,9 @@ files:
521
526
  - app/components/primer/beta/text.rb
522
527
  - app/components/primer/beta/truncate.html.erb
523
528
  - app/components/primer/beta/truncate.rb
529
+ - app/components/primer/beta/x_banner.d.ts
530
+ - app/components/primer/beta/x_banner.js
531
+ - app/components/primer/beta/x_banner.ts
524
532
  - app/components/primer/blankslate_component.html.erb
525
533
  - app/components/primer/blankslate_component.rb
526
534
  - app/components/primer/box.rb
@@ -729,6 +737,7 @@ files:
729
737
  - lib/primer/view_components/linters/helpers/deprecated_components_helpers.rb
730
738
  - lib/primer/view_components/linters/helpers/rubocop_helpers.rb
731
739
  - lib/primer/view_components/linters/label_component_migration_counter.rb
740
+ - lib/primer/view_components/linters/migrate_deprecated_flash_arguments.rb
732
741
  - lib/primer/view_components/linters/subhead_component_migration_counter.rb
733
742
  - lib/primer/view_components/linters/super_in_component_templates.rb
734
743
  - lib/primer/view_components/linters/tag_tree_helpers.rb
@@ -792,6 +801,9 @@ files:
792
801
  - previews/primer/beta/auto_complete_preview/with_submit_button.html.erb
793
802
  - previews/primer/beta/avatar_preview.rb
794
803
  - previews/primer/beta/avatar_stack_preview.rb
804
+ - previews/primer/beta/banner_preview.rb
805
+ - previews/primer/beta/banner_preview/with_action_button.html.erb
806
+ - previews/primer/beta/banner_preview/with_action_content.html.erb
795
807
  - previews/primer/beta/base_button_preview.rb
796
808
  - previews/primer/beta/blankslate_preview.rb
797
809
  - previews/primer/beta/border_box_preview.rb