primer_view_components 0.0.36 → 0.0.41
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +220 -24
- data/app/assets/javascripts/primer_view_components.js +1 -1
- data/app/assets/javascripts/primer_view_components.js.map +1 -1
- data/app/components/primer/auto_complete.rb +3 -1
- data/app/components/primer/auto_complete/item.rb +1 -1
- data/app/components/primer/avatar_component.rb +22 -3
- data/app/components/primer/avatar_stack_component.rb +8 -5
- data/app/components/primer/base_button.rb +47 -0
- data/app/components/primer/base_component.rb +14 -10
- data/app/components/primer/blankslate_component.rb +10 -7
- data/app/components/primer/border_box_component.rb +1 -1
- data/app/components/primer/box_component.rb +1 -1
- data/app/components/primer/breadcrumb_component.rb +1 -1
- data/app/components/primer/button_component.html.erb +9 -0
- data/app/components/primer/button_component.rb +39 -21
- data/app/components/primer/{button_group_component.html.erb → button_group.html.erb} +0 -0
- data/app/components/primer/button_group.rb +61 -0
- data/app/components/primer/button_marketing_component.rb +4 -9
- data/app/components/primer/clipboard_copy.html.erb +8 -0
- data/app/components/primer/clipboard_copy.rb +26 -0
- data/app/components/primer/clipboard_copy_component.d.ts +1 -0
- data/app/components/primer/clipboard_copy_component.js +34 -0
- data/app/components/primer/clipboard_copy_component.ts +39 -0
- data/app/components/primer/close_button.rb +11 -2
- data/app/components/primer/component.rb +21 -2
- data/app/components/primer/counter_component.rb +6 -1
- data/app/components/primer/details_component.rb +1 -1
- data/app/components/primer/dropdown/menu_component.rb +1 -1
- data/app/components/primer/dropdown_component.rb +1 -1
- data/app/components/primer/flash_component.rb +3 -3
- data/app/components/primer/flex_component.rb +28 -1
- data/app/components/primer/flex_item_component.rb +20 -1
- data/app/components/primer/heading_component.rb +25 -4
- data/app/components/primer/hidden_text_expander.rb +2 -4
- data/app/components/primer/icon_button.rb +65 -0
- data/app/components/primer/image.rb +46 -0
- data/app/components/primer/image_crop.d.ts +1 -0
- data/app/components/primer/image_crop.html.erb +12 -0
- data/app/components/primer/image_crop.js +1 -0
- data/app/components/primer/image_crop.rb +36 -0
- data/app/components/primer/image_crop.ts +1 -0
- data/app/components/primer/label_component.rb +7 -3
- data/app/components/primer/layout_component.rb +1 -1
- data/app/components/primer/link_component.rb +1 -1
- data/app/components/primer/local_time.d.ts +1 -0
- data/app/components/primer/local_time.js +1 -0
- data/app/components/primer/local_time.rb +59 -0
- data/app/components/primer/local_time.ts +1 -0
- data/app/components/primer/{markdown_component.rb → markdown.rb} +6 -5
- data/app/components/primer/menu_component.rb +1 -1
- data/app/components/primer/navigation/tab_component.rb +8 -1
- data/app/components/primer/octicon_component.html.erb +7 -0
- data/app/components/primer/octicon_component.rb +53 -19
- data/app/components/primer/octicon_symbols_component.html.erb +3 -0
- data/app/components/primer/octicon_symbols_component.rb +61 -0
- data/app/components/primer/popover_component.rb +1 -1
- data/app/components/primer/primer.d.ts +3 -0
- data/app/components/primer/primer.js +3 -0
- data/app/components/primer/primer.ts +3 -0
- data/app/components/primer/progress_bar_component.rb +1 -1
- data/app/components/primer/spinner_component.rb +3 -3
- data/app/components/primer/state_component.rb +2 -2
- data/app/components/primer/subhead_component.rb +34 -4
- data/app/components/primer/tab_container_component.rb +1 -1
- data/app/components/primer/tab_nav_component.html.erb +2 -0
- data/app/components/primer/tab_nav_component.rb +23 -10
- data/app/components/primer/text_component.rb +6 -3
- data/app/components/primer/time_ago_component.rb +1 -1
- data/app/components/primer/timeline_item_component.rb +1 -1
- data/app/components/primer/{tooltip_component.rb → tooltip.rb} +11 -9
- data/app/components/primer/truncate.rb +1 -1
- data/app/components/primer/underline_nav_component.rb +1 -1
- data/app/lib/primer/classify.rb +11 -36
- data/app/lib/primer/classify/cache.rb +20 -15
- data/app/lib/primer/classify/flex.rb +111 -0
- data/app/lib/primer/classify/functional_border_colors.rb +1 -2
- data/app/lib/primer/fetch_or_fallback_helper.rb +2 -2
- data/app/lib/primer/octicon/cache.rb +42 -0
- data/app/lib/primer/view_helper.rb +2 -1
- data/lib/primer/view_components.rb +1 -1
- data/lib/primer/view_components/version.rb +1 -1
- data/lib/tasks/coverage.rake +14 -0
- data/lib/tasks/docs.rake +315 -0
- data/lib/tasks/statuses.rake +12 -0
- data/lib/yard/docs_helper.rb +57 -0
- data/static/statuses.json +54 -1
- metadata +50 -11
- data/app/components/primer/button_group_component.rb +0 -35
- data/app/components/primer/foo_bar.d.ts +0 -1
- data/app/components/primer/foo_bar.js +0 -1
@@ -0,0 +1,34 @@
|
|
1
|
+
import '@github/clipboard-copy-element';
|
2
|
+
const CLIPBOARD_COPY_TIMER_DURATION = 2000;
|
3
|
+
function toggleSVG(svg) {
|
4
|
+
if (svg.style.display === '' || svg.style.display === 'block') {
|
5
|
+
svg.style.display = 'none';
|
6
|
+
}
|
7
|
+
else {
|
8
|
+
svg.style.display = 'block';
|
9
|
+
}
|
10
|
+
}
|
11
|
+
// Toggle a copy button.
|
12
|
+
function toggleCopyButton(button) {
|
13
|
+
const [clippyIcon, checkIcon] = button.querySelectorAll('.octicon');
|
14
|
+
if (!clippyIcon || !checkIcon)
|
15
|
+
return;
|
16
|
+
toggleSVG(clippyIcon);
|
17
|
+
toggleSVG(checkIcon);
|
18
|
+
}
|
19
|
+
const clipboardCopyElementTimers = new WeakMap();
|
20
|
+
document.addEventListener('clipboard-copy', function ({ target }) {
|
21
|
+
if (!(target instanceof HTMLElement))
|
22
|
+
return;
|
23
|
+
if (!target.hasAttribute('data-view-component'))
|
24
|
+
return;
|
25
|
+
const currentTimeout = clipboardCopyElementTimers.get(target);
|
26
|
+
if (currentTimeout) {
|
27
|
+
clearTimeout(currentTimeout);
|
28
|
+
clipboardCopyElementTimers.delete(target);
|
29
|
+
}
|
30
|
+
else {
|
31
|
+
toggleCopyButton(target);
|
32
|
+
}
|
33
|
+
clipboardCopyElementTimers.set(target, setTimeout(toggleCopyButton, CLIPBOARD_COPY_TIMER_DURATION, target));
|
34
|
+
});
|
@@ -0,0 +1,39 @@
|
|
1
|
+
import '@github/clipboard-copy-element'
|
2
|
+
|
3
|
+
const CLIPBOARD_COPY_TIMER_DURATION = 2000
|
4
|
+
|
5
|
+
function toggleSVG(svg: SVGElement) {
|
6
|
+
if (svg.style.display === '' || svg.style.display === 'block') {
|
7
|
+
svg.style.display = 'none'
|
8
|
+
} else {
|
9
|
+
svg.style.display = 'block'
|
10
|
+
}
|
11
|
+
}
|
12
|
+
|
13
|
+
// Toggle a copy button.
|
14
|
+
function toggleCopyButton(button: HTMLElement) {
|
15
|
+
const [clippyIcon, checkIcon] = button.querySelectorAll<SVGElement>('.octicon')
|
16
|
+
|
17
|
+
if (!clippyIcon || !checkIcon) return
|
18
|
+
|
19
|
+
toggleSVG(clippyIcon)
|
20
|
+
toggleSVG(checkIcon)
|
21
|
+
}
|
22
|
+
|
23
|
+
const clipboardCopyElementTimers = new WeakMap<HTMLElement, number>()
|
24
|
+
|
25
|
+
document.addEventListener('clipboard-copy', function ({target}) {
|
26
|
+
if (!(target instanceof HTMLElement)) return
|
27
|
+
if (!target.hasAttribute('data-view-component')) return
|
28
|
+
|
29
|
+
const currentTimeout = clipboardCopyElementTimers.get(target)
|
30
|
+
|
31
|
+
if (currentTimeout) {
|
32
|
+
clearTimeout(currentTimeout)
|
33
|
+
clipboardCopyElementTimers.delete(target)
|
34
|
+
} else {
|
35
|
+
toggleCopyButton(target)
|
36
|
+
}
|
37
|
+
|
38
|
+
clipboardCopyElementTimers.set(target, setTimeout(toggleCopyButton, CLIPBOARD_COPY_TIMER_DURATION, target))
|
39
|
+
})
|
@@ -1,8 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Primer
|
4
|
-
# Use CloseButton to render an `×` without default button styles.
|
4
|
+
# Use `CloseButton` to render an `×` without default button styles.
|
5
|
+
#
|
6
|
+
# @accessibility
|
7
|
+
# `CloseButton` has a default `aria-label` of "Close" to provides assistive technologies with an accessible label.
|
8
|
+
# You may choose to override this label with something more descriptive via [system_arguments][0].
|
9
|
+
# [0]: https://primer.style/view-components/system-arguments#html-attributes
|
5
10
|
class CloseButton < Primer::Component
|
11
|
+
status :beta
|
12
|
+
|
6
13
|
DEFAULT_TYPE = :button
|
7
14
|
TYPE_OPTIONS = [DEFAULT_TYPE, :submit].freeze
|
8
15
|
|
@@ -14,15 +21,17 @@ module Primer
|
|
14
21
|
def initialize(type: DEFAULT_TYPE, **system_arguments)
|
15
22
|
@system_arguments = system_arguments
|
16
23
|
@system_arguments[:tag] = :button
|
24
|
+
@system_arguments[:block] = false
|
17
25
|
@system_arguments[:type] = fetch_or_fallback(TYPE_OPTIONS, type, DEFAULT_TYPE)
|
18
26
|
@system_arguments[:classes] = class_names(
|
19
27
|
"close-button",
|
20
28
|
system_arguments[:classes]
|
21
29
|
)
|
30
|
+
@system_arguments[:"aria-label"] ||= "Close"
|
22
31
|
end
|
23
32
|
|
24
33
|
def call
|
25
|
-
render(Primer::
|
34
|
+
render(Primer::BaseButton.new(**@system_arguments)) do
|
26
35
|
render(Primer::OcticonComponent.new("x"))
|
27
36
|
end
|
28
37
|
end
|
@@ -1,6 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "octicons_helper/helper"
|
4
3
|
require "view_component/version"
|
5
4
|
|
6
5
|
module Primer
|
@@ -9,10 +8,30 @@ module Primer
|
|
9
8
|
include ViewComponent::SlotableV2 unless ViewComponent::VERSION::STRING.to_f >= 2.28
|
10
9
|
include ClassNameHelper
|
11
10
|
include FetchOrFallbackHelper
|
12
|
-
include OcticonsHelper
|
13
11
|
include TestSelectorHelper
|
14
12
|
include JoinStyleArgumentsHelper
|
15
13
|
include ViewHelper
|
16
14
|
include Status::Dsl
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def deprecated_component_warning(new_class: nil, version: nil)
|
19
|
+
return if Rails.env.production? || silence_deprecations?
|
20
|
+
|
21
|
+
message = "#{self.class.name} is deprecated"
|
22
|
+
message += " and will be removed in v#{version}." if version
|
23
|
+
message += " Use #{new_class.name} instead." if new_class
|
24
|
+
|
25
|
+
ActiveSupport::Deprecation.warn(message)
|
26
|
+
end
|
27
|
+
|
28
|
+
def validate_aria_label
|
29
|
+
aria_label = @system_arguments[:"aria-label"] || @system_arguments.dig(:aria, :label)
|
30
|
+
raise ArgumentError, "`aria-label` is required." if aria_label.nil? && !Rails.env.production?
|
31
|
+
end
|
32
|
+
|
33
|
+
def silence_deprecations?
|
34
|
+
Rails.application.config.primer_view_components.silence_deprecations
|
35
|
+
end
|
17
36
|
end
|
18
37
|
end
|
@@ -1,7 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Primer
|
4
|
-
# Use
|
4
|
+
# Use `Counter` to add a count to navigational elements and buttons.
|
5
|
+
#
|
6
|
+
# @accessibility
|
7
|
+
# Always use `Counter` with adjacent text that provides supplementary information regarding what the count is for. For instance, `Counter`
|
8
|
+
# should be accompanied with text such as `issues` or `pull requests`.
|
9
|
+
#
|
5
10
|
class CounterComponent < Primer::Component
|
6
11
|
status :beta
|
7
12
|
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module Primer
|
4
4
|
module Dropdown
|
5
|
-
# This component is part of `
|
5
|
+
# This component is part of `Dropdown` and should not be
|
6
6
|
# used as a standalone component.
|
7
7
|
class MenuComponent < Primer::Component
|
8
8
|
SCHEME_DEFAULT = :default
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Primer
|
4
|
-
#
|
4
|
+
# `Dropdown` is a lightweight context menu for housing navigation and actions.
|
5
5
|
# They're great for instances where you don't need the full power (and code) of the select menu.
|
6
6
|
class DropdownComponent < Primer::Component
|
7
7
|
# Required trigger for the dropdown. Only accepts a content.
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Primer
|
4
|
-
# Use
|
4
|
+
# Use `Flash` to inform users of successful or pending actions.
|
5
5
|
class FlashComponent < Primer::Component
|
6
6
|
status :beta
|
7
7
|
|
@@ -35,7 +35,7 @@ module Primer
|
|
35
35
|
# <%= render(Primer::FlashComponent.new(dismissible: true)) { "This is a dismissible flash message!" } %>
|
36
36
|
#
|
37
37
|
# @example Icon
|
38
|
-
# <%= render(Primer::FlashComponent.new(icon:
|
38
|
+
# <%= render(Primer::FlashComponent.new(icon: :people)) { "This is a flash message with an icon!" } %>
|
39
39
|
#
|
40
40
|
# @example With actions
|
41
41
|
# <%= render(Primer::FlashComponent.new) do |component| %>
|
@@ -48,7 +48,7 @@ module Primer
|
|
48
48
|
# @param full [Boolean] Whether the component should take up the full width of the screen.
|
49
49
|
# @param spacious [Boolean] Whether to add margin to the bottom of the component.
|
50
50
|
# @param dismissible [Boolean] Whether the component can be dismissed with an X button.
|
51
|
-
# @param icon [
|
51
|
+
# @param icon [Symbol] Name of Octicon icon to use.
|
52
52
|
# @param scheme [Symbol] <%= one_of(Primer::FlashComponent::SCHEME_MAPPINGS.keys) %>
|
53
53
|
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
54
54
|
def initialize(full: false, spacious: false, dismissible: false, icon: nil, scheme: DEFAULT_SCHEME, **system_arguments)
|
@@ -1,11 +1,36 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Primer
|
4
|
-
# Use
|
4
|
+
# Use `Flex` to make an element lay out its content using the flexbox model.
|
5
5
|
# Before using these utilities, you should be familiar with CSS3 Flexible Box
|
6
6
|
# spec. If you are not, check out MDN's guide [Using CSS Flexible
|
7
7
|
# Boxes](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout/Basic_Concepts_of_Flexbox).
|
8
|
+
#
|
9
|
+
# @deprecated
|
10
|
+
# Use <%= link_to_component(Primer::BoxComponent) %> instead.
|
11
|
+
#
|
12
|
+
# **Before**:
|
13
|
+
#
|
14
|
+
# ```erb
|
15
|
+
# <%%= render Primer::FlexComponent.new(justify_content: :center) %>
|
16
|
+
# <%%= render Primer::FlexComponent.new(inline: true) %>
|
17
|
+
# <%%= render Primer::FlexComponent.new(flex_wrap: true) %>
|
18
|
+
# <%%= render Primer::FlexComponent.new(align_items: :start) %>
|
19
|
+
# <%%= render Primer::FlexComponent.new(direction: :column) %>
|
20
|
+
# ```
|
21
|
+
#
|
22
|
+
# **After**:
|
23
|
+
#
|
24
|
+
# ```erb
|
25
|
+
# <%%= render Primer::BoxComponent.new(display: :flex, justify_content: :center) %>
|
26
|
+
# <%%= render Primer::BoxComponent.new(display: :inline_flex) %>
|
27
|
+
# <%%= render Primer::BoxComponent.new(display: :flex, flex_wrap: :wrap) %>
|
28
|
+
# <%%= render Primer::BoxComponent.new(display: :flex, align_items: :start) %>
|
29
|
+
# <%%= render Primer::BoxComponent.new(display: :flex, direction: :column) %>
|
30
|
+
# ```
|
8
31
|
class FlexComponent < Primer::Component
|
32
|
+
status :deprecated
|
33
|
+
|
9
34
|
JUSTIFY_CONTENT_DEFAULT = nil
|
10
35
|
JUSTIFY_CONTENT_MAPPINGS = {
|
11
36
|
flex_start: "flex-justify-start",
|
@@ -77,6 +102,8 @@ module Primer
|
|
77
102
|
direction: nil,
|
78
103
|
**system_arguments
|
79
104
|
)
|
105
|
+
deprecated_component_warning(new_class: Primer::BoxComponent, version: "0.0.40")
|
106
|
+
|
80
107
|
@align_items = fetch_or_fallback(ALIGN_ITEMS_OPTIONS, align_items, ALIGN_ITEMS_DEFAULT)
|
81
108
|
@justify_content = fetch_or_fallback(JUSTIFY_CONTENT_OPTIONS, justify_content, JUSTIFY_CONTENT_DEFAULT)
|
82
109
|
@flex_wrap = fetch_or_fallback(FLEX_WRAP_OPTIONS, flex_wrap, FLEX_WRAP_DEFAULT)
|
@@ -1,9 +1,26 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Primer
|
4
|
-
# Use
|
4
|
+
# Use `FlexItem` to specify the ability of a flex item to alter its
|
5
5
|
# dimensions to fill available space
|
6
|
+
#
|
7
|
+
# @deprecated
|
8
|
+
# Use <%= link_to_component(Primer::BoxComponent) %> instead.
|
9
|
+
#
|
10
|
+
# **Before**:
|
11
|
+
#
|
12
|
+
# ```erb
|
13
|
+
# <%%= render Primer::FlexItemComponent.new(flex_auto: :auto) %>
|
14
|
+
# ```
|
15
|
+
#
|
16
|
+
# **After**:
|
17
|
+
#
|
18
|
+
# ```erb
|
19
|
+
# <%%= render Primer::BoxComponent.new(flex: :auto) %>
|
20
|
+
# ```
|
6
21
|
class FlexItemComponent < Primer::Component
|
22
|
+
status :deprecated
|
23
|
+
|
7
24
|
FLEX_AUTO_DEFAULT = false
|
8
25
|
FLEX_AUTO_ALLOWED_VALUES = [FLEX_AUTO_DEFAULT, true].freeze
|
9
26
|
|
@@ -21,6 +38,8 @@ module Primer
|
|
21
38
|
# @param flex_auto [Boolean] Fills available space and auto-sizes based on the content. Defaults to <%= Primer::FlexItemComponent::FLEX_AUTO_DEFAULT %>
|
22
39
|
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
23
40
|
def initialize(flex_auto: FLEX_AUTO_DEFAULT, **system_arguments)
|
41
|
+
deprecated_component_warning(new_class: Primer::BoxComponent, version: "0.0.40")
|
42
|
+
|
24
43
|
@system_arguments = system_arguments
|
25
44
|
@system_arguments[:classes] =
|
26
45
|
class_names(
|
@@ -1,19 +1,40 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Primer
|
4
|
-
#
|
4
|
+
# `Heading` should be used to communicate page organization and hierarchy.
|
5
|
+
#
|
6
|
+
# - Set tag to one of `:h1`, `:h2`, `:h3`, `:h4`, `:h5`, `:h6` based on what is appropriate for the page context.
|
7
|
+
# - Use `Heading` as the title of a section or sub section.
|
8
|
+
# - Do not use `Heading` for styling alone. For simply styling text, consider using <%= link_to_component(Primer::TextComponent) %> with relevant <%= link_to_typography_docs %>
|
9
|
+
# such as `font_size` and `font_weight`.
|
10
|
+
# - Do not jump heading levels. For instance, do not follow a `<h1>` with an `<h3>`. Heading levels should increase by one in ascending order.
|
11
|
+
#
|
12
|
+
# @accessibility
|
13
|
+
# While sighted users rely on visual cues such as font size changes to determine what the heading is, assistive technology users rely on programatic cues that can be read out.
|
14
|
+
# When text on a page is visually implied to be a heading, ensure that it is coded as a heading. Additionally, visually implied heading level and coded heading level should be
|
15
|
+
# consistent. [See WCAG success criteria: 1.3.1: Info and Relationships](https://www.w3.org/WAI/WCAG21/Understanding/info-and-relationships.html)
|
16
|
+
#
|
17
|
+
# Headings allow assistive technology users to quickly navigate around a page. Navigation to text that is not meant to be a heading can be a confusing experience.
|
18
|
+
# <%= link_to_heading_practices %>
|
5
19
|
class HeadingComponent < Primer::Component
|
6
20
|
status :beta
|
7
21
|
|
22
|
+
TAG_FALLBACK = :h2
|
23
|
+
TAG_OPTIONS = [:h1, TAG_FALLBACK, :h3, :h4, :h5, :h6].freeze
|
24
|
+
|
8
25
|
# @example Default
|
9
|
-
# <%= render(Primer::HeadingComponent.new) { "H1 Text" } %>
|
26
|
+
# <%= render(Primer::HeadingComponent.new(tag: :h1)) { "H1 Text" } %>
|
10
27
|
# <%= render(Primer::HeadingComponent.new(tag: :h2)) { "H2 Text" } %>
|
11
28
|
# <%= render(Primer::HeadingComponent.new(tag: :h3)) { "H3 Text" } %>
|
29
|
+
# <%= render(Primer::HeadingComponent.new(tag: :h4)) { "H4 Text" } %>
|
30
|
+
# <%= render(Primer::HeadingComponent.new(tag: :h5)) { "H5 Text" } %>
|
31
|
+
# <%= render(Primer::HeadingComponent.new(tag: :h6)) { "H6 Text" } %>
|
12
32
|
#
|
33
|
+
# @param tag [String] <%= one_of(Primer::HeadingComponent::TAG_OPTIONS) %>
|
13
34
|
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
14
|
-
def initialize(**system_arguments)
|
35
|
+
def initialize(tag:, **system_arguments)
|
15
36
|
@system_arguments = system_arguments
|
16
|
-
@system_arguments[:tag]
|
37
|
+
@system_arguments[:tag] = fetch_or_fallback(TAG_OPTIONS, tag, TAG_FALLBACK)
|
17
38
|
end
|
18
39
|
|
19
40
|
def call
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Primer
|
4
|
-
# Use HiddenTextExpander to indicate and toggle hidden text.
|
4
|
+
# Use `HiddenTextExpander` to indicate and toggle hidden text.
|
5
5
|
class HiddenTextExpander < Primer::Component
|
6
6
|
# @example Default
|
7
7
|
# <%= render(Primer::HiddenTextExpander.new) %>
|
@@ -25,8 +25,6 @@ module Primer
|
|
25
25
|
)
|
26
26
|
|
27
27
|
@button_arguments = button_arguments
|
28
|
-
@button_arguments[:tag] = :button
|
29
|
-
@button_arguments[:type] = :button
|
30
28
|
@button_arguments[:"aria-expanded"] = false
|
31
29
|
@button_arguments[:classes] = class_names(
|
32
30
|
"ellipsis-expander",
|
@@ -36,7 +34,7 @@ module Primer
|
|
36
34
|
|
37
35
|
def call
|
38
36
|
render(Primer::BaseComponent.new(**@system_arguments)) do
|
39
|
-
render(Primer::
|
37
|
+
render(Primer::BaseButton.new(**@button_arguments)) { "…".html_safe }
|
40
38
|
end
|
41
39
|
end
|
42
40
|
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Primer
|
4
|
+
# Use `IconButton` to render Icon-only buttons without the default button styles.
|
5
|
+
#
|
6
|
+
# @accessibility
|
7
|
+
# `IconButton` requires an `aria-label`, which will provide assistive technologies with an accessible label.
|
8
|
+
# The `aria-label` should describe the action to be invoked rather than the icon itself. For instance,
|
9
|
+
# if your `IconButton` renders a magnifying glass icon and invokves a search action, the `aria-label` should be
|
10
|
+
# `"Search"` instead of `"Magnifying glass"`.
|
11
|
+
# [Learn more about best functional image practices (WAI Images)](https://www.w3.org/WAI/tutorials/images/functional)
|
12
|
+
class IconButton < Primer::Component
|
13
|
+
status :beta
|
14
|
+
|
15
|
+
DEFAULT_SCHEME = :default
|
16
|
+
SCHEME_MAPPINGS = {
|
17
|
+
DEFAULT_SCHEME => "",
|
18
|
+
:danger => "btn-octicon-danger"
|
19
|
+
}.freeze
|
20
|
+
SCHEME_OPTIONS = SCHEME_MAPPINGS.keys
|
21
|
+
# @example Default
|
22
|
+
#
|
23
|
+
# <%= render(Primer::IconButton.new(icon: :search, "aria-label": "Search")) %>
|
24
|
+
#
|
25
|
+
# @example Schemes
|
26
|
+
#
|
27
|
+
# <%= render(Primer::IconButton.new(icon: :search, "aria-label": "Search")) %>
|
28
|
+
# <%= render(Primer::IconButton.new(icon: :trash, "aria-label": "Delete", scheme: :danger)) %>
|
29
|
+
#
|
30
|
+
# @example In a BorderBox
|
31
|
+
#
|
32
|
+
# <%= render(Primer::BorderBoxComponent.new) do |component| %>
|
33
|
+
# <% component.body do %>
|
34
|
+
# <%= render(Primer::TextComponent.new(pr: 2)) { "Body" } %>
|
35
|
+
# <%= render(Primer::IconButton.new(icon: :pencil, box: true, "aria-label": "Edit")) %>
|
36
|
+
# <% end %>
|
37
|
+
# <% end %>
|
38
|
+
#
|
39
|
+
# @param scheme [Symbol] <%= one_of(Primer::IconButton::SCHEME_OPTIONS) %>
|
40
|
+
# @param icon [String] Name of <%= link_to_octicons %> to use.
|
41
|
+
# @param tag [Symbol] <%= one_of(Primer::BaseButton::TAG_OPTIONS) %>
|
42
|
+
# @param type [Symbol] <%= one_of(Primer::BaseButton::TYPE_OPTIONS) %>
|
43
|
+
# @param box [Boolean] Whether the button is in a <%= link_to_component(Primer::BorderBoxComponent) %>. If `true`, the button will have the `Box-btn-octicon` class.
|
44
|
+
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
45
|
+
def initialize(scheme: DEFAULT_SCHEME, icon:, box: false, **system_arguments)
|
46
|
+
@icon = icon
|
47
|
+
|
48
|
+
@system_arguments = system_arguments
|
49
|
+
@system_arguments[:classes] = class_names(
|
50
|
+
"btn-octicon",
|
51
|
+
SCHEME_MAPPINGS[fetch_or_fallback(SCHEME_OPTIONS, scheme, DEFAULT_SCHEME)],
|
52
|
+
system_arguments[:classes],
|
53
|
+
"Box-btn-octicon" => box
|
54
|
+
)
|
55
|
+
|
56
|
+
validate_aria_label
|
57
|
+
end
|
58
|
+
|
59
|
+
def call
|
60
|
+
render(Primer::BaseButton.new(**@system_arguments)) do
|
61
|
+
render(Primer::OcticonComponent.new(icon: @icon))
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|