gitlab-org--gitlab-foss/app/helpers/icons_helper.rb

193 lines
5.8 KiB
Ruby

# frozen_string_literal: true
require 'json'
module IconsHelper
extend self
DEFAULT_ICON_SIZE = 16
def custom_icon(icon_name, size: DEFAULT_ICON_SIZE)
memoized_icon("#{icon_name}_#{size}") do
render partial: "shared/icons/#{icon_name}", formats: :svg, locals: { size: size }
end
end
def sprite_icon_path
@sprite_icon_path ||= begin
# SVG Sprites currently don't work across domains, so in the case of a CDN
# we have to set the current path deliberately to prevent addition of asset_host
sprite_base_url = Gitlab.config.gitlab.url if ActionController::Base.asset_host
ActionController::Base.helpers.image_path('icons.svg', host: sprite_base_url)
end
end
def sprite_file_icons_path
# SVG Sprites currently don't work across domains, so in the case of a CDN
# we have to set the current path deliberately to prevent addition of asset_host
sprite_base_url = Gitlab.config.gitlab.url if ActionController::Base.asset_host
ActionController::Base.helpers.image_path('file_icons.svg', host: sprite_base_url)
end
def sprite_icon(icon_name, size: DEFAULT_ICON_SIZE, css_class: nil)
memoized_icon("#{icon_name}_#{size}_#{css_class}") do
if known_sprites&.exclude?(icon_name)
exception = ArgumentError.new("#{icon_name} is not a known icon in @gitlab-org/gitlab-svg")
Gitlab::ErrorTracking.track_and_raise_for_dev_exception(exception)
end
css_classes = []
css_classes << "s#{size}" if size
css_classes << "#{css_class}" unless css_class.blank?
content_tag(
:svg,
content_tag(:use, '', { 'href' => "#{sprite_icon_path}##{icon_name}" }),
class: css_classes.empty? ? nil : css_classes.join(' '),
data: { testid: "#{icon_name}-icon" }
)
end
end
# Creates a GitLab UI loading icon/spinner.
#
# Examples:
# # Default
# gl_loading_icon
#
# # Sizes
# gl_loading_icon(size: 'md')
# gl_loading_icon(size: 'lg')
# gl_loading_icon(size: 'xl')
#
# # Colors
# gl_loading_icon(color: 'light')
#
# # Block/Inline
# gl_loading_icon(inline: true)
#
# # Custom classes
# gl_loading_icon(css_class: "foo-bar")
#
# See also https://gitlab-org.gitlab.io/gitlab-ui/?path=/story/base-loading-icon--default
def gl_loading_icon(inline: false, color: 'dark', size: 'sm', css_class: nil, data: nil)
spinner = content_tag(:span, "", {
class: %[gl-spinner gl-spinner-#{color} gl-spinner-#{size} gl-vertical-align-text-bottom!],
aria: { label: _('Loading') },
data: data
})
container_classes = ['gl-spinner-container']
container_classes << css_class unless css_class.blank?
content_tag(inline ? :span : :div, spinner, {
class: container_classes,
role: 'status'
})
end
def external_snippet_icon(name)
content_tag(:span, "", class: "gl-snippet-icon gl-snippet-icon-#{name}")
end
def audit_icon(name, css_class: nil)
case name
when "standard"
name = "key"
when "two-factor"
name = "key"
when "google_oauth2"
name = "google"
end
sprite_icon(name, css_class: css_class)
end
def boolean_to_icon(value)
if value
sprite_icon('check', css_class: 'gl-text-green-500')
else
sprite_icon('power', css_class: 'gl-text-gray-500')
end
end
def visibility_level_icon(level, options: {})
name =
case level
when Gitlab::VisibilityLevel::PRIVATE
'lock'
when Gitlab::VisibilityLevel::INTERNAL
'shield'
else # Gitlab::VisibilityLevel::PUBLIC
'earth'
end
css_class = options.delete(:class)
sprite_icon(name, size: DEFAULT_ICON_SIZE, css_class: css_class)
end
def file_type_icon_class(type, mode, name)
if type == 'folder'
icon_class = 'folder-o'
elsif type == 'archive'
icon_class = 'archive'
elsif mode == '120000'
icon_class = 'share'
else
# Guess which icon to choose based on file extension.
# If you think a file extension is missing, feel free to add it on PR
case File.extname(name).downcase
when '.pdf'
icon_class = 'document'
when '.jpg', '.jpeg', '.jif', '.jfif',
'.jp2', '.jpx', '.j2k', '.j2c',
'.apng', '.png', '.gif', '.tif', '.tiff',
'.svg', '.ico', '.bmp', '.webp'
icon_class = 'doc-image'
when '.zip', '.zipx', '.tar', '.gz', '.gzip', '.tgz', '.bz', '.bzip',
'.bz2', '.bzip2', '.car', '.tbz', '.xz', 'txz', '.rar', '.7z',
'.lz', '.lzma', '.tlz'
icon_class = 'doc-compressed'
when '.mp3', '.wma', '.ogg', '.oga', '.wav', '.flac', '.aac', '.3ga',
'.ac3', '.midi', '.m4a', '.ape', '.mpa'
icon_class = 'volume-up'
when '.mp4', '.m4p', '.m4v',
'.mpg', '.mp2', '.mpeg', '.mpe', '.mpv',
'.mpg', '.mpeg', '.m2v', '.m2ts',
'.avi', '.mkv', '.flv', '.ogv', '.mov',
'.3gp', '.3g2'
icon_class = 'live-preview'
when '.doc', '.dot', '.docx', '.docm', '.dotx', '.dotm', '.docb',
'.odt', '.ott', '.uot', '.rtf'
icon_class = 'doc-text'
when '.xls', '.xlt', '.xlm', '.xlsx', '.xlsm', '.xltx', '.xltm',
'.xlsb', '.xla', '.xlam', '.xll', '.xlw', '.ots', '.ods', '.uos'
icon_class = 'document'
when '.ppt', '.pot', '.pps', '.pptx', '.pptm', '.potx', '.potm',
'.ppam', '.ppsx', '.ppsm', '.sldx', '.sldm', '.odp', '.otp', '.uop'
icon_class = 'doc-chart'
else
icon_class = 'doc-text'
end
end
icon_class
end
private
def known_sprites
return if Rails.env.production?
@known_sprites ||= Gitlab::Json.parse(File.read(Rails.root.join('node_modules/@gitlab/svgs/dist/icons.json')))['icons']
end
def memoized_icon(key)
@rendered_icons ||= {}
@rendered_icons[key] || (
@rendered_icons[key] = yield
)
end
end