Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -728,6 +728,7 @@ GEM
zeitwerk (2.7.3)

PLATFORMS
arm64-darwin-23
arm64-darwin-24
x86_64-linux

Expand Down
9 changes: 9 additions & 0 deletions app/assets/svgs/avo/paperclip.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions app/components/avo/u_i/badge_component.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<span class="<%= badge_classes %>" style="<%= badge_style %>"<%= tag.attributes(options) %>>
<%= render_icon_content if icon.present? && icon_position == "left" %>

<% if label.present? %>
<span class="truncate"><%= label %></span>
<% end %>

<%= render_icon_content_right if icon.present? && icon_position == "right" %>
</span>
110 changes: 110 additions & 0 deletions app/components/avo/u_i/badge_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
# frozen_string_literal: true

class Avo::UI::BadgeComponent < Avo::BaseComponent
STYLES = %w[solid subtle].freeze

# Use centralized color definitions
COLOR_DEFINITIONS = Avo::UI::Colors::DEFINITIONS
COLOR_ALIASES = Avo::UI::Colors::ALIASES
VALID_COLORS = Avo::UI::Colors::ALL

def initialize(
label: '',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[rubocop] reported by reviewdog 🐶
[Corrected] Style/StringLiterals: Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.

color: 'secondary',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[rubocop] reported by reviewdog 🐶
[Corrected] Style/StringLiterals: Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.

style: 'subtle',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[rubocop] reported by reviewdog 🐶
[Corrected] Style/StringLiterals: Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.

icon: nil,
icon_position: 'left',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[rubocop] reported by reviewdog 🐶
[Corrected] Style/StringLiterals: Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.

rounded: true,
**options
)
@label = label.to_s
@color = normalize_color(color.to_s)
@style = style.to_s
@icon = icon&.to_s
@icon_position = icon_position.to_s
@rounded = rounded
@options = options

validate_params!

super()
end

private

attr_reader :label, :color, :style, :icon, :icon_position, :rounded, :options

def normalize_color(value)
# Map aliases to their canonical color names
normalized = COLOR_ALIASES[value] || value

# Fallback to 'secondary' if color is invalid
VALID_COLORS.include?(normalized) ? normalized : 'secondary'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[rubocop] reported by reviewdog 🐶
[Corrected] Style/StringLiterals: Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.

end

def color_definition
# For solid style, use -secondary variant if it exists (dark bg, light text)
if @style == 'solid'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[rubocop] reported by reviewdog 🐶
[Corrected] Style/StringLiterals: Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.

secondary_color = "#{color}-secondary"
return COLOR_DEFINITIONS[secondary_color] if COLOR_DEFINITIONS.key?(secondary_color)
end

# Default: use the base color (always valid due to normalize_color)
COLOR_DEFINITIONS[color]
end

def text_color
color_definition[:text]
end

def bg_color
color_definition[:bg]
end

def validate_params!
raise ArgumentError, "Invalid style: #{style}. Must be one of #{STYLES.join(', ')}" unless STYLES.include?(style)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[rubocop] reported by reviewdog 🐶
[Corrected] Style/StringLiteralsInInterpolation: Prefer double-quoted strings inside interpolations.


return if %w[left right].include?(icon_position)

raise ArgumentError, "Invalid icon_position: #{icon_position}. Must be 'left' or 'right'"
end

def badge_classes
classes = [
'inline-flex items-center justify-center transition-colors',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[rubocop] reported by reviewdog 🐶
[Corrected] Style/StringLiterals: Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.

'focus:outline-none focus:ring-2 focus:ring-offset-2',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[rubocop] reported by reviewdog 🐶
[Corrected] Style/StringLiterals: Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.

'px-2 py-0.5 text-xs gap-0.5 text-center' # x:8px, y:2px, gap:2px, height:24px
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[rubocop] reported by reviewdog 🐶
[Corrected] Style/StringLiterals: Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.

]

classes << 'rounded-md' if rounded
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[rubocop] reported by reviewdog 🐶
[Corrected] Style/StringLiterals: Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.


classes.compact.join(' ')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[rubocop] reported by reviewdog 🐶
[Corrected] Style/StringLiterals: Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.

end

def badge_style
# Figma specs: height:24px, font-size:12px, font-weight:500, line-height:16px
"height: 24px; font-size: 12px; font-weight: 500; line-height: 16px; background-color: #{bg_color}; color: #{text_color};"
end

def icon_classes
'shrink-0 w-3 h-3'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[rubocop] reported by reviewdog 🐶
[Corrected] Style/StringLiterals: Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.

end

def icon_style
"color: #{text_color};"
end

def render_icon_content
return unless icon.present?

return unless icon_position == 'left'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[rubocop] reported by reviewdog 🐶
[Corrected] Style/StringLiterals: Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.


helpers.svg(icon, class: icon_classes, style: icon_style)
end

def render_icon_content_right
return unless icon.present? && icon_position == 'right'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[rubocop] reported by reviewdog 🐶
[Corrected] Style/StringLiterals: Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.


helpers.svg(icon, class: icon_classes, style: icon_style)
end
end
57 changes: 57 additions & 0 deletions lib/avo/u_i/colors.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# frozen_string_literal: true

module Avo
module UI
# Centralized color definitions for Avo UI components
# Colors are based on Figma design system specifications
module Colors
# Badge and UI component color definitions with exact hex codes
DEFINITIONS = {
'secondary' => { text: '#171717', bg: '#F6F6F6' },
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[rubocop] reported by reviewdog 🐶
[Corrected] Style/StringLiterals: Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[rubocop] reported by reviewdog 🐶
[Corrected] Layout/SpaceInsideHashLiteralBraces: Space inside { detected.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[rubocop] reported by reviewdog 🐶
[Corrected] Style/StringLiterals: Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[rubocop] reported by reviewdog 🐶
[Corrected] Style/StringLiterals: Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[rubocop] reported by reviewdog 🐶
[Corrected] Layout/SpaceInsideHashLiteralBraces: Space inside } detected.

'success' => { text: '#0D8E54', bg: '#D3F8E0' },
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[rubocop] reported by reviewdog 🐶
[Corrected] Style/StringLiterals: Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[rubocop] reported by reviewdog 🐶
[Corrected] Layout/SpaceInsideHashLiteralBraces: Space inside { detected.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[rubocop] reported by reviewdog 🐶
[Corrected] Style/StringLiterals: Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[rubocop] reported by reviewdog 🐶
[Corrected] Style/StringLiterals: Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[rubocop] reported by reviewdog 🐶
[Corrected] Layout/SpaceInsideHashLiteralBraces: Space inside } detected.

'informative' => { text: '#068AFF', bg: '#D6F1FF' },
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[rubocop] reported by reviewdog 🐶
[Corrected] Style/StringLiterals: Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[rubocop] reported by reviewdog 🐶
[Corrected] Layout/SpaceInsideHashLiteralBraces: Space inside { detected.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[rubocop] reported by reviewdog 🐶
[Corrected] Style/StringLiterals: Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[rubocop] reported by reviewdog 🐶
[Corrected] Style/StringLiterals: Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[rubocop] reported by reviewdog 🐶
[Corrected] Layout/SpaceInsideHashLiteralBraces: Space inside } detected.

'warning' => { text: '#DB6704', bg: '#FFEFC6' },
'error' => { text: '#DE3024', bg: '#FEE4E2' },

'orange' => { text: '#C2410C', bg: '#FFEDD5' },
'orange-secondary' => { text: '#F6F6F6', bg: '#FB923C' },
'yellow' => { text: '#FB923C', bg: '#FEF9C3' },
'yellow-secondary' => { text: '#F6F6F6', bg: '#FACC15' },
'green' => { text: '#15803D', bg: '#DCFCE7' },
'green-secondary' => { text: '#F6F6F6', bg: '#22C55E' },
'teal' => { text: '#0F766E', bg: '#CCFBF1' },
'teal-secondary' => { text: '#F6F6F6', bg: '#2DD4BF' },
'blue' => { text: '#1D4ED8', bg: '#DBEAFE' },
'blue-secondary' => { text: '#F6F6F6', bg: '#3B82F6' },
'purple' => { text: '#7E22CE', bg: '#F3E8FF' },
'purple-secondary' => { text: '#F6F6F6', bg: '#A855F7' }
}.freeze

# Color name aliases for backward compatibility
ALIASES = {
'info' => 'informative',
'danger' => 'error'
}.freeze

# All valid color names (including aliases)
ALL = (DEFINITIONS.keys + ALIASES.keys).freeze

# Normalize a color name (resolve aliases)
def self.normalize(color_name)
ALIASES[color_name.to_s] || color_name.to_s
end

# Get color definition for a given color name
def self.get(color_name, fallback: 'secondary')
normalized = normalize(color_name)
DEFINITIONS[normalized] || DEFINITIONS[fallback]
end

# Check if a color is valid
def self.valid?(color_name)
ALL.include?(color_name.to_s)
end
end
end
end

Loading
Loading