diff --git a/README.md b/README.md
index 2e56dd8..dd5b657 100644
--- a/README.md
+++ b/README.md
@@ -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.
diff --git a/app/components/itacomp/alert_component.rb b/app/components/itacomp/alert_component.rb
index 6cfea9f..28256bb 100644
--- a/app/components/itacomp/alert_component.rb
+++ b/app/components/itacomp/alert_component.rb
@@ -6,9 +6,6 @@ module Itacomp
# @example with no options
# <%= render ItacompAlertComponent.new %>
#
- # @example with text as params
- # <%= render ItacompAlertComponent.new('text') %>
- #
text
# @example with text as block
# <%= render ItacompAlertComponent.new do %>
# text
@@ -31,19 +28,17 @@ module Itacomp
# <%= render ItacompAlertComponent.new(id: 'my-id', data: {test: 'test'}) %>
#
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
diff --git a/app/components/itacomp/alert_component/alert_component.html.erb b/app/components/itacomp/alert_component/alert_component.html.erb
index 82b30ae..dfaa71a 100644
--- a/app/components/itacomp/alert_component/alert_component.html.erb
+++ b/app/components/itacomp/alert_component/alert_component.html.erb
@@ -1,4 +1,4 @@
<%= tag.div **@opts do %>
- <%= content || @text%>
+ <%= content %>
<%= close_button %>
<% end %>
diff --git a/app/components/itacomp/avatar_component.rb b/app/components/itacomp/avatar_component.rb
index fcd9c48..6b6970b 100644
--- a/app/components/itacomp/avatar_component.rb
+++ b/app/components/itacomp/avatar_component.rb
@@ -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 %>
#
# With content
@@ -33,7 +33,7 @@ module Itacomp
#
a
# With other options
# <%= render itacomp::avatar(id: "my_avatar", data: {turbo_frame: 'main'}).new.with_content('a') %>
- #
a
+ #
a
class AvatarComponent < BaseComponent
# Initialize avatar component
#
@@ -43,8 +43,8 @@ class AvatarComponent < BaseComponent
# * class [String,Array] default nil if present is add class style after avatar
# * **opts each key is delegated as tag options
# * yield 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
diff --git a/app/components/itacomp/notification_component.rb b/app/components/itacomp/notification_component.rb
new file mode 100644
index 0000000..f79da83
--- /dev/null
+++ b/app/components/itacomp/notification_component.rb
@@ -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') %>
+ #
test
+ # Mo dismissable and no show
+ # <%= render Itacomp::NotificationComponent.new(title: 'test', dismissable: false, show: false) %>
+ #
test
+ class NotificationComponent < BaseComponent
+ # Initialize notification component
+ #
+ # ==== Options
+ # * title [String], mandatory, default: nil, Notification title;
+ # * show [Boolean], default true, if true set notification visible
+ # * icon [String] default nil if present is add nontification icon
+ # * dismissable [Boolean] default true if true add dismiss button
+ # * **opts each key is delegated as tag options. Default: {class: 'notification', id: Time.now.strftime("%H%M%S%L"), aria: {role: 'alert'}}
+ # * yield 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
diff --git a/app/components/itacomp/notification_component/notification_component.html.erb b/app/components/itacomp/notification_component/notification_component.html.erb
new file mode 100644
index 0000000..4b17f4e
--- /dev/null
+++ b/app/components/itacomp/notification_component/notification_component.html.erb
@@ -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 %>
diff --git a/app/components/itacomp/notification_component/notification_component.yml b/app/components/itacomp/notification_component/notification_component.yml
new file mode 100644
index 0000000..1be780c
--- /dev/null
+++ b/app/components/itacomp/notification_component/notification_component.yml
@@ -0,0 +1,7 @@
+---
+en:
+ close: "close notification:"
+fr:
+ close: "fermer la notification:"
+it:
+ close: "Chiudi la notifica:"
diff --git a/app/components/itacomp/turbo_frame_component.rb b/app/components/itacomp/turbo_frame_component.rb
index dfd63a8..c070496 100644
--- a/app/components/itacomp/turbo_frame_component.rb
+++ b/app/components/itacomp/turbo_frame_component.rb
@@ -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
#
@@ -40,7 +40,9 @@ class TurboFrameComponent < BaseComponent
# * * [Symbol], each key going as tag option
# * yield optional turbo frame content
def initialize(**keys)
+ @busy = keys[:href].present? && content.blank?
@keys = keys
+ @keys[:aria] = { busy: true } if @busy
end
end
end
diff --git a/app/components/itacomp/turbo_frame_component/turbo_frame_component.html.erb b/app/components/itacomp/turbo_frame_component/turbo_frame_component.html.erb
index fdbd888..e2759b0 100644
--- a/app/components/itacomp/turbo_frame_component/turbo_frame_component.html.erb
+++ b/app/components/itacomp/turbo_frame_component/turbo_frame_component.html.erb
@@ -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 %>
diff --git a/app/helpers/itacomp/common_helper.rb b/app/helpers/itacomp/common_helper.rb
index 30c137c..f018589 100644
--- a/app/helpers/itacomp/common_helper.rb
+++ b/app/helpers/itacomp/common_helper.rb
@@ -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
@@ -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
@@ -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
diff --git a/lib/itacomp.rb b/lib/itacomp.rb
index a0e54e9..d77e1e0 100644
--- a/lib/itacomp.rb
+++ b/lib/itacomp.rb
@@ -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
diff --git a/test/components/itacomp/alert_component_test.rb b/test/components/itacomp/alert_component_test.rb
index f992f70..733ec60 100644
--- a/test/components/itacomp/alert_component_test.rb
+++ b/test/components/itacomp/alert_component_test.rb
@@ -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
diff --git a/test/components/itacomp/avatar_component_test.rb b/test/components/itacomp/avatar_component_test.rb
index b4a710c..f8f389c 100644
--- a/test/components/itacomp/avatar_component_test.rb
+++ b/test/components/itacomp/avatar_component_test.rb
@@ -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
diff --git a/test/components/itacomp/notification_component_test.rb b/test/components/itacomp/notification_component_test.rb
new file mode 100644
index 0000000..b3ec466
--- /dev/null
+++ b/test/components/itacomp/notification_component_test.rb
@@ -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
diff --git a/test/components/previews/itacomp/alert_component_preview.rb b/test/components/previews/itacomp/alert_component_preview.rb
index 01d9040..6b47088 100644
--- a/test/components/previews/itacomp/alert_component_preview.rb
+++ b/test/components/previews/itacomp/alert_component_preview.rb
@@ -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
diff --git a/test/components/previews/itacomp/notification_component_preview.rb b/test/components/previews/itacomp/notification_component_preview.rb
new file mode 100644
index 0000000..8f0cd2d
--- /dev/null
+++ b/test/components/previews/itacomp/notification_component_preview.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+module Itacomp
+ class NotificationComponentPreview < ViewComponent::Preview
+ def default
+ render(NotificationComponent.new(title: "text"))
+ end
+ end
+end