Skip to content
Merged
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
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,15 @@ Itacomp is a [View Component](https://viewcomponent.org/) and [Helper](https://a
* [ita_progress](app/helpers/itacomp/common_helper.rb)
* [ita_spinner](app/helpers/itacomp/common_helper.rb)
* [ita_visually_hidden](app/helpers/itacomp/common_helper.rb)
* [ita_size](app/helpers/itacomp/common_helper.rb)
* [ita_bg](app/helpers/itacomp/common_helper.rb)
* [ita_text](app/helpers/itacomp/common_helper.rb)

### Components
* [TurboFrameComponent](app/components/itacomp/turbo_frame_component.rb)
* [AlertComponent](app/components/itacomp/alert_component.rb)
* [AvatorComponent](app/components/itacomp/avator_component.rb)
* [NotificationComponent](app/components/itacomp/notification_component.rb)
* [TurboFrameComponent](app/components/itacomp/turbo_frame_component.rb)

## Installation
Itacomp is in a rapid development phase and the gem will not be released on Rubygem until the [first project](https://github.com/orgs/isprambiente/projects/1) will be completed.
Expand Down
7 changes: 1 addition & 6 deletions app/components/itacomp/alert_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@ module Itacomp
# @example with no options
# <%= render ItacompAlertComponent.new %>
# <div class="alert alert-primary" role="alert"></div>
# @example with text as params
# <%= render ItacompAlertComponent.new('text') %>
# <div class="alert alert-primary" role="alert">text</div>
# @example with text as block
# <%= render ItacompAlertComponent.new do %>
# text
Expand All @@ -31,19 +28,17 @@ module Itacomp
# <%= render ItacompAlertComponent.new(id: 'my-id', data: {test: 'test'}) %>
# <div class="alert alert-primary" id="my-id" data-test="test" role="alert"></div>
class AlertComponent < BaseComponent
# @param [String] text content for alert component, default nil
# @param [String,Sym] :type of alert, default 'primary'
# @param [Boolean] :close if true is added close button
# @param [String] :class add other class after "alsert alert-#{type}" classes
# @param [Hash] **opts each other oprion is delegated to container tag
# @yield [optional] turbo frame content
def initialize(text = nil, type: :primary, close: false, **opts)
def initialize(type: :primary, close: false, **opts)
@close = close
@opts = opts
@opts[:class] = [ "alert", "alert-#{ITA_TYPES[type]}", @opts[:class] ]
@opts[:class] << "alert-dismissible fade show" if close
@opts[:role] = "alert"
@text = text
end

# @return html for close button if @close is true
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<%= tag.div **@opts do %>
<%= content || @text%>
<%= content %>
<%= close_button %>
<% end %>
8 changes: 4 additions & 4 deletions app/components/itacomp/avatar_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ module Itacomp
# Make a bootstrap-italia compatible [Avatar](https://italia.github.io/bootstrap-italia/docs/componenti/avatar/) tag.
#
# ==== Example
# With no params
# With no params
# <%= render Itacomp::Avatar.new %>
# <div class=\"avatar\"></div>
# With content
Expand Down Expand Up @@ -33,7 +33,7 @@ module Itacomp
# <div class="avatar test">a</div>
# With other options
# <%= render itacomp::avatar(id: "my_avatar", data: {turbo_frame: 'main'}).new.with_content('a') %>
# <div id="my_avatar" class="avatar" data-turbo-frame="main">a</div>
# <div id="my_avatar" class="avatar" data-turbo-frame="main">a</div>
class AvatarComponent < BaseComponent
# Initialize avatar component
#
Expand All @@ -43,8 +43,8 @@ class AvatarComponent < BaseComponent
# * <tt>class</tt> [String,Array] default <tt>nil</tt> if present is add class style after <tt>avatar</tt>
# * <tt>**opts</tt> each key is delegated as tag options
# * <tt>yield</tt> avatar content
def initialize(size: nil, bg: nil, class: nil ,**opts)
opts[:class] = ["avatar", opts[:class]]
def initialize(size: nil, bg: nil, class: nil, **opts)
opts[:class] = [ "avatar", opts[:class] ]
opts[:class] << ita_size(size) if size.present?
opts[:class] << avatar_bg(bg) if bg.present?
@opts = opts
Expand Down
44 changes: 44 additions & 0 deletions app/components/itacomp/notification_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# frozen_string_literal: true

module Itacomp
# make a strcture for [notification component](https://italia.github.io/bootstrap-italia/docs/componenti/notification/)
# ==== Example
# With only required title (default show and dismissable)
# <%= render Itacomp::NotificationComponent.new(title: 'test') %>
# <div class="notification dismissable show" id="not-172739516" aria-labelledby="not-172739516-title" role="alert" style="display: block;"> <h2 id="not-172739516-title" class="h5">test</h2> <button class="btn notification-close" data-bs-toggle="notification" data-bs-target="#not-172739516"> <svg class="icon"><use href="/itacomp/sprites.svg#it-close" xlink:href="/itacomp/sprites.svg#it-close" /></svg> <span class="visually-hidden">close notification: test</span></button></div>
# Mo dismissable and no show
# <%= render Itacomp::NotificationComponent.new(title: 'test', dismissable: false, show: false) %>
# <div class="notification" id="not-171959203" aria-labelledby="not-171959203-title" role="alert"> <h2 id="not-171959203-title" class="h5">test</h2> </div>
class NotificationComponent < BaseComponent
# Initialize notification component
#
# ==== Options
# * <tt>title</tt> [String], mandatory, default: <tt>nil</tt>, Notification title;
# * <tt>show</tt> [Boolean], default <tt>true</tt>, if true set notification visible
# * <tt>icon</tt> [String] default <tt>nil</tt> if present is add nontification icon
# * <tt>dismissable</tt> [Boolean] default <tt>true</tt> if true add dismiss button
# * <tt>**opts</tt> each key is delegated as tag options. Default: {class: 'notification', id: Time.now.strftime("%H%M%S%L"), aria: {role: 'alert'}}
# * <tt>yield</tt> notification content (content is automarically added in a `p` tag)
def initialize(title:, show: true, icon: nil, dismissable: true, **opts)
opts[:class] = [ "notification", opts[:class] ]
opts[:class] << "with-icon" if icon.present?
opts[:class] << "dismissable" if dismissable == true
opts[:id] = "not-#{Time.now.strftime("%H%M%S%L")}" if opts[:id].blank?
opts[:aria] = { labelledby: "#{opts[:id]}-title" } if opts[:aria].blank?
opts[:role] = "alert"
if show == true
opts[:class] << "show"
opts[:style] = "display: block;"
end
@title = title
@icon = icon
@dismissable = dismissable
@opts = opts
end

# return full title: text and optional icon
def full_title
@icon.present? ? safe_join([ ita_icon(@icon), @title ]) : @title
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<%= tag.div **@opts do %>
<%= tag.h2 full_title, id: @opts[:aria][:labelledby], class: 'h5' %>
<%= tag.p content if content.present? %>
<% if @dismissable == true %>
<%= tag.button class: "btn notification-close", data: {bs_toggle: "notification", bs_target: "##{@opts[:id]}"} do %>
<%= ita_icon "it-close" %>
<%= ita_visually_hidden "#{t(".close")} #{@title}" %>
<% end %>
<% end %>
<% end %>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
en:
close: "close notification:"
fr:
close: "fermer la notification:"
it:
close: "Chiudi la notifica:"
4 changes: 3 additions & 1 deletion app/components/itacomp/turbo_frame_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
module Itacomp
# Make a bootstrap-italia compatible structure for a [turbo Frame](https://turbo.hotwired.dev/handbook/frames) tag.
#
# ==== Example
# ==== Example
# Empty turbo frame
# = render Itacomp::TurboFrameComponent.new
#
Expand Down Expand Up @@ -40,7 +40,9 @@ class TurboFrameComponent < BaseComponent
# * <tt>*</tt> [Symbol], each key going as tag option
# * <tt>yield</yy> optional turbo frame content
def initialize(**keys)
@busy = keys[:href].present? && content.blank?
@keys = keys
@keys[:aria] = { busy: true } if @busy
end
end
end
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
<%= tag.turbo_frame **@keys do %>
<% if @keys[:href].present? && content.blank? %>
<%= ita_spinner t('.loading') %>
<% else %>
<%= content %>
<% end %>
<%= @busy ? ita_spinner(t('.loading')) : content %>
<% end %>
6 changes: 3 additions & 3 deletions app/helpers/itacomp/common_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ def ita_progress(value = nil, type: nil)
# with invalid params
# ira_size(:other)
# # => "size-md"
def ita_size(type=nil)
def ita_size(type = nil)
"size-#{ITA_SIZES[type]}"
end

Expand All @@ -167,7 +167,7 @@ def ita_size(type=nil)
# with invalid params
# ira_size(:other)
# # => "size-primary"
def ita_bg(type=nil)
def ita_bg(type = nil)
"bg-#{ITA_TYPES[type]}"
end

Expand All @@ -186,7 +186,7 @@ def ita_bg(type=nil)
# with invalid params
# ira_text(:other)
# # => "text-primary"
def ita_text(type=nil)
def ita_text(type = nil)
"text-#{ITA_TYPES[type]}"
end
end
Expand Down
4 changes: 2 additions & 2 deletions lib/itacomp.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@

module Itacomp
# this constant define available bootstrap-italia type
ITA_TYPES = Hash.new { :primary }.with_indifferent_access.merge(primary: "primary", secondary: "secondary", info: "info", success: "success", warning: "warning", danger: "danger", white: "white", dark: "dark", black: 'black')
ITA_SIZES = Hash.new { :md}.with_indifferent_access.merge(xs: "xs", sm: "sm", md: "md", lg: "md", xl: "xl", xxl: "xxl")
ITA_TYPES = Hash.new { :primary }.with_indifferent_access.merge(primary: "primary", secondary: "secondary", info: "info", success: "success", warning: "warning", danger: "danger", white: "white", dark: "dark", black: "black")
ITA_SIZES = Hash.new { :md }.with_indifferent_access.merge(xs: "xs", sm: "sm", md: "md", lg: "md", xl: "xl", xxl: "xxl")
end
7 changes: 1 addition & 6 deletions test/components/itacomp/alert_component_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,7 @@ class Itacomp::AlertComponentTest < ViewComponent::TestCase
assert_selector "div.alert.alert-primary[role='alert']", text: nil
end

test "render text as params" do
render_inline Itacomp::AlertComponent.new("test")
assert_selector "div.alert.alert-primary[role='alert']", text: "test"
end

test "render text as block" do
test "render with content" do
render_inline Itacomp::AlertComponent.new.with_content("test")
assert_selector "div.alert.alert-primary[role='alert']", text: "test"
end
Expand Down
18 changes: 9 additions & 9 deletions test/components/itacomp/avatar_component_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,27 +9,27 @@ class Itacomp::AvatarComponentTest < ViewComponent::TestCase
end

test "avatar with content" do
render_inline Itacomp::AvatarComponent.new.with_content('test')
assert_selector "div.avatar", text: 'test'
render_inline Itacomp::AvatarComponent.new.with_content("test")
assert_selector "div.avatar", text: "test"
end

test "set size" do
render_inline Itacomp::AvatarComponent.new(size: 'md')
assert_selector "div.avatar.size-md", text: nil
render_inline Itacomp::AvatarComponent.new(size: "md")
assert_selector "div.avatar.size-md", text: nil
end

test "set bg" do
render_inline Itacomp::AvatarComponent.new(bg: 'md')
assert_selector "div.avatar.avatar-primary", text: nil
render_inline Itacomp::AvatarComponent.new(bg: "md")
assert_selector "div.avatar.avatar-primary", text: nil
end

test "add id" do
render_inline Itacomp::AvatarComponent.new(id: 'test')
render_inline Itacomp::AvatarComponent.new(id: "test")
assert_selector "div#test.avatar", text: nil
end

test "add data" do
render_inline Itacomp::AvatarComponent.new(data: {test: 'tost'})
assert_selector "div.avatar[data-test='tost']", text: nil
render_inline Itacomp::AvatarComponent.new(data: { test: "tost" })
assert_selector "div.avatar[data-test='tost']", text: nil
end
end
23 changes: 23 additions & 0 deletions test/components/itacomp/notification_component_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# frozen_string_literal: true

require "test_helper"

class Itacomp::NotificationComponentTest < ViewComponent::TestCase
test "only required title" do
render_inline Itacomp::NotificationComponent.new(title: "test")
assert_selector "div.notification.dismissable.show[role='alert']", text: "test"
assert_selector "div.notification.dismissable.show h2.h5", text: "test"
assert_selector "div.notification.dismissable.show button.btn.notification-close svg.icon"
assert_selector "div.notification.dismissable.show button.btn.notification-close span.visually-hidden", text: "close notification: test"
end

test "with id can be set ids and aria-labelledid" do
render_inline Itacomp::NotificationComponent.new(title: "test", id: "test")
assert_selector "div.notification.dismissable.show#test[aria-labelledby='test-title'] h2.h5#test-title", text: "test"
end

test "can render with icon" do
render_inline Itacomp::NotificationComponent.new(title: "test", icon: "test")
assert_selector "div.notification.dismissable.show.with-icon h2.h5 svg.icon"
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
module Itacomp
class AlertComponentPreview < ViewComponent::Preview
def default
render(AlertComponent.new(text: "text", type: "type", close: "close"))
render(AlertComponent.new(type: "primary", close: true))
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# frozen_string_literal: true

module Itacomp
class NotificationComponentPreview < ViewComponent::Preview
def default
render(NotificationComponent.new(title: "text"))
end
end
end