dsfr-view-components 0.0.1 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +34 -28
- data/app/components/dsfr_component/accordion_component/section_component.html.erb +15 -9
- data/app/components/dsfr_component/accordion_component/section_component.rb +11 -24
- data/app/components/dsfr_component/accordion_component.rb +5 -16
- data/app/components/dsfr_component/alert_component.rb +72 -5
- data/app/components/dsfr_component/badge_component.rb +30 -0
- data/app/components/dsfr_component/stepper_component.html.erb +18 -0
- data/app/components/dsfr_component/stepper_component.rb +26 -0
- data/app/components/dsfr_component/tag_component.rb +60 -31
- data/app/components/dsfr_component/tile_component.html.erb +19 -0
- data/app/components/dsfr_component/tile_component.rb +31 -0
- data/app/helpers/dsfr_components_helper.rb +11 -19
- data/app/helpers/dsfr_link_helper.rb +41 -90
- data/lib/dsfr/components/version.rb +1 -1
- data/lib/generators/dsfr_component/USAGE +28 -0
- data/lib/generators/dsfr_component/dsfr_component_generator.rb +50 -0
- data/lib/generators/dsfr_component/templates/component.haml.erb +13 -0
- data/lib/generators/dsfr_component/templates/component.rb.erb +32 -0
- data/lib/generators/dsfr_component/templates/component_helper.rb.erb +10 -0
- data/lib/generators/dsfr_component/templates/component_spec.rb.erb +5 -0
- metadata +84 -65
- data/app/components/dsfr_component/back_link_component.rb +0 -24
- data/app/components/dsfr_component/breadcrumbs_component.html.erb +0 -7
- data/app/components/dsfr_component/breadcrumbs_component.rb +0 -51
- data/app/components/dsfr_component/cookie_banner_component/message_component.rb +0 -62
- data/app/components/dsfr_component/cookie_banner_component.rb +0 -35
- data/app/components/dsfr_component/details_component.rb +0 -42
- data/app/components/dsfr_component/footer_component.html.erb +0 -49
- data/app/components/dsfr_component/footer_component.rb +0 -87
- data/app/components/dsfr_component/header_component.html.erb +0 -51
- data/app/components/dsfr_component/header_component.rb +0 -145
- data/app/components/dsfr_component/inset_text_component.rb +0 -28
- data/app/components/dsfr_component/notification_banner_component.html.erb +0 -14
- data/app/components/dsfr_component/notification_banner_component.rb +0 -93
- data/app/components/dsfr_component/pagination_component/adjacent_page.rb +0 -59
- data/app/components/dsfr_component/pagination_component/item.rb +0 -77
- data/app/components/dsfr_component/pagination_component/next_page.rb +0 -27
- data/app/components/dsfr_component/pagination_component/previous_page.rb +0 -21
- data/app/components/dsfr_component/pagination_component.rb +0 -129
- data/app/components/dsfr_component/panel_component.rb +0 -56
- data/app/components/dsfr_component/phase_banner_component.html.erb +0 -6
- data/app/components/dsfr_component/phase_banner_component.rb +0 -25
- data/app/components/dsfr_component/section_break_component.rb +0 -49
- data/app/components/dsfr_component/start_button_component.rb +0 -55
- data/app/components/dsfr_component/summary_list_component/action_component.rb +0 -42
- data/app/components/dsfr_component/summary_list_component/key_component.rb +0 -23
- data/app/components/dsfr_component/summary_list_component/row_component.rb +0 -57
- data/app/components/dsfr_component/summary_list_component/value_component.rb +0 -23
- data/app/components/dsfr_component/summary_list_component.html.erb +0 -5
- data/app/components/dsfr_component/summary_list_component.rb +0 -49
- data/app/components/dsfr_component/tab_component.html.erb +0 -11
- data/app/components/dsfr_component/tab_component.rb +0 -61
- data/app/components/dsfr_component/table_component/body_component.html.erb +0 -5
- data/app/components/dsfr_component/table_component/body_component.rb +0 -21
- data/app/components/dsfr_component/table_component/caption_component.rb +0 -37
- data/app/components/dsfr_component/table_component/cell_component.rb +0 -57
- data/app/components/dsfr_component/table_component/head_component.html.erb +0 -5
- data/app/components/dsfr_component/table_component/head_component.rb +0 -23
- data/app/components/dsfr_component/table_component/row_component.html.erb +0 -5
- data/app/components/dsfr_component/table_component/row_component.rb +0 -30
- data/app/components/dsfr_component/table_component.html.erb +0 -7
- data/app/components/dsfr_component/table_component.rb +0 -35
- data/app/components/dsfr_component/warning_text_component.rb +0 -37
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 35d3263e9f55cf1b2f6e8ed013475acb11322715f8982ae24d43d121a5268e30
|
4
|
+
data.tar.gz: 6eb24fccd1294b6096bef1cf43714654a4d9a89174ac7d74c3e4a3c5845487d3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f158d2adc525722af4ff7b3d8819411f0821edba991fb68885ec9142ad819c8d12f380817807c810b48298f09ee5f0c204c611fa35ba6944f69605849f490bca
|
7
|
+
data.tar.gz: 0303b1cded5664bf372c160c27acb619bbbdfb196b276e1ea45596d9c6657bda599e6230b0cecf9ef9be991f2b008ff6b822c901945e7f02b2dc230fe9bfa31d
|
data/README.md
CHANGED
@@ -1,37 +1,35 @@
|
|
1
1
|
# Composants du DSFR
|
2
2
|
|
3
|
+
[![Tests](https://github.com/betagouv/dsfr-view-components/workflows/Tests/badge.svg)](https://github.com/betagouv/dsfr-view-components/actions?query=workflow%3ATests)
|
4
|
+
[![Gem Version](https://badge.fury.io/rb/dsfr-view-components.svg)](https://badge.fury.io/rb/dsfr-view-components)
|
5
|
+
[![Gem](https://img.shields.io/gem/dt/dsfr-view-components?logo=rubygems)](https://rubygems.org/gems/dsfr-view-components)
|
6
|
+
[![GitHub license](https://img.shields.io/github/license/betagouv/dsfr-view-components)](https://github.com/betagouv/dsfr-view-components/blob/main/LICENSE)
|
7
|
+
[![Rails](https://img.shields.io/badge/Rails-6.1.5%20%E2%95%B1%207.0.3-E16D6D)](https://weblog.rubyonrails.org/releases/)
|
8
|
+
[![Ruby](https://img.shields.io/badge/Ruby-2.7.6%20%20%E2%95%B1%203.0.3%20%20%E2%95%B1%203.1.2-E16D6D)](https://www.ruby-lang.org/en/downloads/)
|
9
|
+
|
10
|
+
[![Design Système de lʼÉtat](https://img.shields.io/badge/Design%20Système%20de%20lʼÉtat-1.8.4-brightgreen)](https://www.systeme-de-design.gouv.fr/)
|
11
|
+
|
3
12
|
Cette gem fournit des composants pour le Design Système de l'État (DSFR) en s'appuyant sur le [framework ViewComponent](https://github.com/ViewComponent/view_component).
|
4
13
|
|
5
14
|
C'est un fork de [govuk-components](https://github.com/DFE-Digital/govuk-components) qui propose l'équivalent pour le GOV.UK Design System.
|
6
15
|
|
7
|
-
⚠️ Cette gem est en cours de développement et n'est pas adaptée à un usage en production. N'hésitez pas à contribuer pour nous aider à avancer !
|
8
16
|
|
9
|
-
|
17
|
+
## Développement en cours ⚠️
|
10
18
|
|
11
|
-
|
12
|
-
|
13
|
-
[![Gem Version](https://badge.fury.io/rb/govuk-components.svg)](https://badge.fury.io/rb/govuk-components)
|
14
|
-
[![Gem](https://img.shields.io/gem/dt/govuk-components?logo=rubygems)](https://rubygems.org/gems/govuk-components)
|
15
|
-
[![Test Coverage](https://api.codeclimate.com/v1/badges/cbcbc140f300b920d833/test_coverage)](https://codeclimate.com/github/DFE-Digital/govuk-components/test_coverage)
|
16
|
-
[![GitHub license](https://img.shields.io/github/license/DFE-Digital/govuk-components)](https://github.com/DFE-Digital/govuk-components/blob/main/LICENSE)
|
17
|
-
[![GOV.UK Design System Version](https://img.shields.io/badge/GOV.UK%20Design%20System-4.3.0-brightgreen)](https://design-system.service.gov.uk)
|
18
|
-
[![Rails](https://img.shields.io/badge/Rails-6.1.5%20%E2%95%B1%207.0.3-E16D6D)](https://weblog.rubyonrails.org/releases/)
|
19
|
-
[![Ruby](https://img.shields.io/badge/Ruby-2.7.6%20%20%E2%95%B1%203.0.3%20%20%E2%95%B1%203.1.2-E16D6D)](https://www.ruby-lang.org/en/downloads/)
|
19
|
+
Cette gem est en cours de développement et n'est pas encore
|
20
|
+
recommandée pour un usage en production.
|
20
21
|
|
21
|
-
|
22
|
+
N'hésitez pas à contribuer pour nous aider à avancer, un générateur de
|
23
|
+
composant est même fourni pour vous faciliter la tâche :
|
22
24
|
|
23
|
-
|
25
|
+
```sh
|
26
|
+
bin/rails g dsfr_component FancyButton --params title:String count:Integer
|
27
|
+
```
|
24
28
|
|
25
29
|
## Documentation
|
26
30
|
|
27
|
-
|
28
|
-
covers most aspects of day-to-day use, along with code and output examples. The
|
29
|
-
examples in the guide (and the guide itself) are built using the components,
|
30
|
-
so it will always be up to date.
|
31
|
-
|
32
|
-
[![Netlify Status](https://api.netlify.com/api/v1/badges/d40a5a0a-b086-4c35-b046-97fbcbf9f219/deploy-status)](https://app.netlify.com/sites/govuk-components/deploys)
|
31
|
+
Un [guide complet est disponible](https://betagouv.github.io/dsfr-view-components/). Il contient des instructions pour l'installation et l'usage de cette gem. Les exemples présents éxecutent le code et seront donc toujours à jour.
|
33
32
|
|
34
|
-
-->
|
35
33
|
|
36
34
|
## Composants disponibles
|
37
35
|
|
@@ -39,10 +37,10 @@ Cette gem a pour but de supporter tous les composants proposés par le Design Sy
|
|
39
37
|
|
40
38
|
Les composants disponibles sont :
|
41
39
|
|
42
|
-
- [
|
40
|
+
- [x] Accordéon - Accordion
|
43
41
|
- [ ] Ajout de fichier - File upload
|
44
|
-
- [
|
45
|
-
- [
|
42
|
+
- [x] Alertes - Alert
|
43
|
+
- [x] Badge
|
46
44
|
- [ ] Bandeau d'information importante
|
47
45
|
- [ ] Barre de recherche - Search bar
|
48
46
|
- [ ] Boutons - Buttons
|
@@ -59,10 +57,10 @@ Les composants disponibles sont :
|
|
59
57
|
- [ ] Fil d'Ariane - Breadcrumb
|
60
58
|
- [ ] Gestionnaire de consentement - Consent banner
|
61
59
|
- [ ] Icônes de favoris - Favicons
|
62
|
-
- [
|
60
|
+
- [x] Indicateur d'étape - Stepper
|
63
61
|
- [ ] Interrupteur - Toggle switch
|
64
62
|
- [ ] Lettre d'information et réseaux sociaux - Newsletter & Follow us
|
65
|
-
- [
|
63
|
+
- [x] Liens - Links
|
66
64
|
- [ ] Liens d'évitement - Skiplinks
|
67
65
|
- [ ] Liste déroulante - Select
|
68
66
|
- [ ] Menu latéral - Side menu
|
@@ -80,7 +78,7 @@ Les composants disponibles sont :
|
|
80
78
|
- [ ] Tableau - Table
|
81
79
|
- [ ] Tag
|
82
80
|
- [ ] Téléchargement de fichier
|
83
|
-
- [
|
81
|
+
- [x] Tuile - Tile
|
84
82
|
|
85
83
|
<!--
|
86
84
|
This library also provides helpers for creating [links](https://govuk-components.netlify.app/helpers/link),
|
@@ -191,7 +189,12 @@ bundle install
|
|
191
189
|
bundle exec rspec spec
|
192
190
|
```
|
193
191
|
|
194
|
-
|
192
|
+
Pour développer avec les tests en continu :
|
193
|
+
```sh
|
194
|
+
bundle exec guard
|
195
|
+
```
|
196
|
+
|
197
|
+
Lancer le guide de documentation :
|
195
198
|
|
196
199
|
```sh
|
197
200
|
make watch-guide
|
@@ -207,7 +210,10 @@ bundle exec rails server
|
|
207
210
|
|
208
211
|
Déployer une nouvelle version de la gem :
|
209
212
|
|
210
|
-
|
213
|
+
```sh
|
214
|
+
VERSION=1.3.2 make deploy_gem
|
215
|
+
```
|
216
|
+
|
211
217
|
|
212
218
|
## Licence
|
213
219
|
|
@@ -1,11 +1,17 @@
|
|
1
|
-
<%= tag.
|
2
|
-
<
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
1
|
+
<%= tag.section(**html_attributes) do %>
|
2
|
+
<h3 class="fr-accordion__title">
|
3
|
+
<button
|
4
|
+
class="fr-accordion__btn"
|
5
|
+
aria-expanded="<%= expanded? ? "true" : "false" %>"
|
6
|
+
aria-controls="<%= id %>"
|
7
|
+
>
|
8
|
+
<%= title %>
|
9
|
+
</button>
|
10
|
+
</h3>
|
11
|
+
<div
|
12
|
+
id="<%= id %>"
|
13
|
+
class="fr-collapse <%= "fr-collapse--expanded" if expanded? %>"
|
14
|
+
>
|
15
|
+
<%= content %>
|
9
16
|
</div>
|
10
|
-
<%= tag.div(content, id: id(suffix: 'content'), class: %w(govuk-accordion__section-content), aria: { labelledby: id }) %>
|
11
17
|
<% end %>
|
@@ -1,39 +1,26 @@
|
|
1
1
|
class DsfrComponent::AccordionComponent::SectionComponent < DsfrComponent::Base
|
2
|
-
attr_reader :
|
3
|
-
|
4
|
-
renders_one :heading_html
|
5
|
-
renders_one :summary_html
|
2
|
+
attr_reader :title, :expanded
|
6
3
|
|
7
4
|
alias_method :expanded?, :expanded
|
8
5
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
@
|
6
|
+
# @param title [String] section title
|
7
|
+
# @param expanded [Boolean] toggles section folding
|
8
|
+
# @param id [String] the HTML id, optional if you want to reuse the anchor
|
9
|
+
def initialize(title:, expanded: false, id: nil, classes: [], html_attributes: {})
|
10
|
+
@title = title
|
11
|
+
@expanded = expanded
|
12
|
+
@id = id
|
14
13
|
|
15
14
|
super(classes: classes, html_attributes: html_attributes)
|
16
15
|
end
|
17
16
|
|
18
|
-
def id
|
19
|
-
|
20
|
-
# to parameterize a potentially-huge chunk of HTML
|
21
|
-
@prefix ||= heading_text&.parameterize || SecureRandom.hex(4)
|
22
|
-
|
23
|
-
[@prefix, suffix].compact.join('-')
|
24
|
-
end
|
25
|
-
|
26
|
-
def heading_content
|
27
|
-
heading_html || heading_text || fail(ArgumentError, "no heading_text or heading_html")
|
28
|
-
end
|
29
|
-
|
30
|
-
def summary_content
|
31
|
-
summary_html || summary_text
|
17
|
+
def id
|
18
|
+
@id ||= "accordion-section-#{SecureRandom.hex(4)}"
|
32
19
|
end
|
33
20
|
|
34
21
|
private
|
35
22
|
|
36
23
|
def default_attributes
|
37
|
-
{ class: class_names("
|
24
|
+
{ class: class_names("fr-accordion").split }
|
38
25
|
end
|
39
26
|
end
|
@@ -1,33 +1,22 @@
|
|
1
1
|
class DsfrComponent::AccordionComponent < DsfrComponent::Base
|
2
|
-
renders_many :sections, ->(
|
2
|
+
renders_many :sections, ->(title: nil, expanded: false, id: nil, classes: [], html_attributes: {}, &block) do
|
3
3
|
DsfrComponent::AccordionComponent::SectionComponent.new(
|
4
4
|
classes: classes,
|
5
5
|
expanded: expanded,
|
6
|
-
heading_level: heading_level, # set once at parent level, passed to all children
|
7
6
|
html_attributes: html_attributes,
|
8
|
-
|
9
|
-
|
7
|
+
title: title,
|
8
|
+
id: id,
|
10
9
|
&block
|
11
10
|
)
|
12
11
|
end
|
13
12
|
|
14
|
-
|
15
|
-
|
16
|
-
def initialize(heading_level: 2, classes: [], html_attributes: {})
|
17
|
-
@heading_level = heading_tag(heading_level)
|
18
|
-
|
13
|
+
def initialize(classes: [], html_attributes: {})
|
19
14
|
super(classes: classes, html_attributes: html_attributes)
|
20
15
|
end
|
21
16
|
|
22
17
|
private
|
23
18
|
|
24
19
|
def default_attributes
|
25
|
-
{ class: %w(
|
26
|
-
end
|
27
|
-
|
28
|
-
def heading_tag(level)
|
29
|
-
fail(ArgumentError, "heading_level must be 1-6") unless level.in?(1..6)
|
30
|
-
|
31
|
-
%(h#{level})
|
20
|
+
{ class: %w(fr-accordions-group) }
|
32
21
|
end
|
33
22
|
end
|
@@ -1,22 +1,89 @@
|
|
1
1
|
class DsfrComponent::AlertComponent < DsfrComponent::Base
|
2
|
-
|
2
|
+
TYPES = %i[error success info warning].freeze
|
3
|
+
SIZES = %i[sm md].freeze
|
3
4
|
|
4
|
-
|
5
|
+
# @param type [Symbol] alert type (and matching color) `:success`, `:info`, `:warning` ou `:error`
|
6
|
+
# @param title [String] alert title. cannot be set in size `:sm`
|
7
|
+
# @param size [Symbol] alert size : `:md` (default) or `:sm`
|
8
|
+
# @param close_button [Boolean] display a close button to remove the alert
|
9
|
+
# @note in size MD the title is required but the content is optional. In size SM there should be not title but the content is required
|
10
|
+
def initialize(type:, title: nil, size: :md, close_button: false, classes: [], html_attributes: {})
|
5
11
|
@title = title
|
12
|
+
@type = type
|
13
|
+
@size = size
|
14
|
+
@close_button = close_button
|
6
15
|
|
7
16
|
super(classes: classes, html_attributes: html_attributes)
|
8
17
|
end
|
9
18
|
|
10
19
|
def call
|
20
|
+
raise ArgumentError, "SM alerts cannot have titles but must have a content" if @size == :sm && (@title.present? || content.blank?)
|
21
|
+
raise ArgumentError, "MD Alerts must have a title" if @size == :md && @title.blank?
|
22
|
+
|
11
23
|
tag.div(**html_attributes) do
|
12
|
-
|
13
|
-
tag.p { content }
|
24
|
+
safe_join([title_tag, content_tag, close_button_tag])
|
14
25
|
end
|
15
26
|
end
|
16
27
|
|
17
28
|
private
|
18
29
|
|
30
|
+
attr_reader :title, :type, :size, :close_button
|
31
|
+
|
19
32
|
def default_attributes
|
20
|
-
{ class: %w(fr-alert) }
|
33
|
+
{ class: %w(fr-alert) + [type_class, size_class].compact }
|
34
|
+
end
|
35
|
+
|
36
|
+
def title_tag
|
37
|
+
return nil if title.blank?
|
38
|
+
|
39
|
+
tag.h3(class: "fr-alert__title") { title }
|
40
|
+
end
|
41
|
+
|
42
|
+
def content_tag
|
43
|
+
return nil if content.blank?
|
44
|
+
|
45
|
+
tag.p { content }
|
46
|
+
end
|
47
|
+
|
48
|
+
def close_button_tag
|
49
|
+
return nil unless close_button
|
50
|
+
|
51
|
+
tag.button(
|
52
|
+
class: "fr-btn--close fr-btn",
|
53
|
+
title: "Masquer le message",
|
54
|
+
onclick: "const alert = this.parentNode; alert.parentNode.removeChild(alert)"
|
55
|
+
) do
|
56
|
+
"Masquer le message"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def type_class
|
61
|
+
fail(ArgumentError, type_error_message) unless valid_type?
|
62
|
+
|
63
|
+
"fr-alert--#{type}"
|
64
|
+
end
|
65
|
+
|
66
|
+
def valid_type?
|
67
|
+
type.in?(TYPES)
|
68
|
+
end
|
69
|
+
|
70
|
+
def type_error_message
|
71
|
+
"invalid alert type #{type}, supported types are #{TYPES.to_sentence}"
|
72
|
+
end
|
73
|
+
|
74
|
+
def size_class
|
75
|
+
return nil if size == :md
|
76
|
+
|
77
|
+
fail(ArgumentError, size_error_message) unless valid_size?
|
78
|
+
|
79
|
+
"fr-alert--#{size}"
|
80
|
+
end
|
81
|
+
|
82
|
+
def valid_size?
|
83
|
+
size.in?(SIZES)
|
84
|
+
end
|
85
|
+
|
86
|
+
def size_error_message
|
87
|
+
"invalid alert size #{size}, supported sizes are #{SIZES.to_sentence}"
|
21
88
|
end
|
22
89
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module DsfrComponent
|
2
|
+
class BadgeComponent < DsfrComponent::Base
|
3
|
+
STATUSES = %i[success error info warning new].freeze
|
4
|
+
|
5
|
+
# @param status [BadgeComponent::STATUSES]
|
6
|
+
def initialize(status:, classes: [], html_attributes: {})
|
7
|
+
raise(ArgumentError, "`status` should be one of #{STATUSES}") unless STATUSES.include?(status)
|
8
|
+
|
9
|
+
@status = status
|
10
|
+
|
11
|
+
classes.push("fr-badge--#{@status}")
|
12
|
+
|
13
|
+
super(classes: classes, html_attributes: html_attributes)
|
14
|
+
end
|
15
|
+
|
16
|
+
def call
|
17
|
+
tag.div(**html_attributes) do
|
18
|
+
content
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
attr_reader :status
|
25
|
+
|
26
|
+
def default_attributes
|
27
|
+
{ class: 'fr-badge' }
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
<%= tag.div(**html_attributes) do %>
|
2
|
+
<h2 class="fr-stepper__title">
|
3
|
+
<span class="fr-stepper__state">
|
4
|
+
Étape <%= value %> sur <%= max %>
|
5
|
+
</span>
|
6
|
+
<%= title %>
|
7
|
+
</h2>
|
8
|
+
<div
|
9
|
+
class="fr-stepper__steps"
|
10
|
+
data-fr-current-step="<%= value %>"
|
11
|
+
data-fr-steps="<%= max %>"></div>
|
12
|
+
<% if next_title %>
|
13
|
+
<p class="fr-stepper__details">
|
14
|
+
<span class="fr-text--bold">Étape suivante :</span>
|
15
|
+
<%= next_title %>
|
16
|
+
</p>
|
17
|
+
<% end %>
|
18
|
+
<% end %>
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module DsfrComponent
|
2
|
+
class StepperComponent < DsfrComponent::Base
|
3
|
+
# @param title [String] Titre de l’étape en cours
|
4
|
+
# @param value [Integer] Numéro de l’étape en cours (commence à 1)
|
5
|
+
# @param max [Integer] Nombre d’étapes total
|
6
|
+
# @param next_title [String] Titre de l’étape suivante (sauf pour la dernière étape)
|
7
|
+
def initialize(title:, value:, max:, next_title: nil, classes: [], html_attributes: {})
|
8
|
+
@title = title
|
9
|
+
@value = value
|
10
|
+
@max = max
|
11
|
+
@next_title = next_title
|
12
|
+
|
13
|
+
raise ArgumentError, "Les étapes doivent aller de 1 jusqu´à 8 au maximum" if @value < 1 || @value > @max || @max > 8
|
14
|
+
|
15
|
+
super(classes: classes, html_attributes: html_attributes)
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
attr_reader :title, :value, :max, :next_title
|
21
|
+
|
22
|
+
def default_attributes
|
23
|
+
{ class: 'fr-stepper' }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -1,44 +1,73 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
module DsfrComponent
|
2
|
+
class TagComponent < DsfrComponent::Base
|
3
|
+
SIZES = %i[sm md].freeze
|
3
4
|
|
4
|
-
|
5
|
+
# @param title [String] tag title
|
6
|
+
# @param icon [String] icon name (optional)
|
7
|
+
# @param size [Symbol] tag size : `:md` (default) or `:sm` (optional)
|
8
|
+
# @param url [String] for clickable tags only (optional)
|
9
|
+
# @param selected [Boolean] adds a check, useful for filters list, cannot be used with `url` (optional)
|
10
|
+
# @param dismissable [Boolean] adds a close icon on the right, cannot be used with `url` or `icon` (optional)
|
11
|
+
def initialize(title:, icon: nil, size: nil, url: nil, selected: nil, dismissable: nil, classes: [], html_attributes: {})
|
12
|
+
@title = title
|
13
|
+
@icon = icon
|
14
|
+
@size = size
|
15
|
+
@url = url
|
16
|
+
@selected = selected
|
17
|
+
@dismissable = dismissable
|
5
18
|
|
6
|
-
|
7
|
-
|
8
|
-
@colour = colour
|
19
|
+
super(classes: classes, html_attributes: html_attributes)
|
20
|
+
end
|
9
21
|
|
10
|
-
|
11
|
-
|
22
|
+
def call
|
23
|
+
validate_size && validate_selected && validate_dismissable
|
24
|
+
tag.send(tag_name, **html_attributes) { title }
|
25
|
+
end
|
12
26
|
|
13
|
-
|
14
|
-
tag.strong(tag_content, **html_attributes)
|
15
|
-
end
|
27
|
+
private
|
16
28
|
|
17
|
-
|
29
|
+
attr_reader :title, :icon, :size, :url, :selected, :dismissable
|
18
30
|
|
19
|
-
|
20
|
-
|
21
|
-
|
31
|
+
def validate_size
|
32
|
+
raise(ArgumentError, "`size` should be one of #{SIZES}") if size.present? && SIZES.exclude?(size)
|
33
|
+
end
|
22
34
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
}
|
27
|
-
end
|
35
|
+
def validate_selected
|
36
|
+
raise ArgumentError, "selected cannot be used together with an URL" if !selected.nil? && url.present?
|
37
|
+
end
|
28
38
|
|
29
|
-
|
30
|
-
|
39
|
+
def validate_dismissable
|
40
|
+
raise ArgumentError, "dismissable cannot be used together with url or icon" if \
|
41
|
+
dismissable && (url.present? || icon.present?)
|
42
|
+
end
|
31
43
|
|
32
|
-
|
44
|
+
def default_attributes
|
45
|
+
attrs = { class: css_classes }
|
46
|
+
attrs.merge!(href: url, target: "_self") if url.present?
|
47
|
+
unless selected.nil? # meaningful when false
|
48
|
+
aria_pressed = selected ? "true" : "false"
|
49
|
+
attrs.merge!("aria-pressed": aria_pressed)
|
50
|
+
end
|
51
|
+
attrs.merge!("aria-label": "Retirer #{title}") if dismissable
|
52
|
+
attrs
|
53
|
+
end
|
33
54
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
55
|
+
def css_classes
|
56
|
+
classes = %w[fr-tag]
|
57
|
+
classes += %W[fr-fi-#{icon} fr-tag--icon-left] if icon.present?
|
58
|
+
classes << "fr-tag--sm" if size == :sm
|
59
|
+
classes << "fr-tag--dismiss" if dismissable
|
60
|
+
classes
|
61
|
+
end
|
40
62
|
|
41
|
-
|
42
|
-
|
63
|
+
def tag_name
|
64
|
+
if url.present?
|
65
|
+
:a
|
66
|
+
elsif !selected.nil? || dismissable
|
67
|
+
:button
|
68
|
+
else
|
69
|
+
:p
|
70
|
+
end
|
71
|
+
end
|
43
72
|
end
|
44
73
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
<%= tag.div(**html_attributes) do %>
|
2
|
+
<div class="fr-tile__body">
|
3
|
+
<h4 class="fr-tile__title">
|
4
|
+
<a class="fr-tile__link" href="<%= url %>">
|
5
|
+
<%= title %>
|
6
|
+
</a>
|
7
|
+
</h4>
|
8
|
+
<% if description.present? %>
|
9
|
+
<p class="fr-tile__desc">
|
10
|
+
<%= description %>
|
11
|
+
</p>
|
12
|
+
<% end %>
|
13
|
+
</div>
|
14
|
+
<% if image_src.present? %>
|
15
|
+
<div class="fr-tile__img">
|
16
|
+
<img src="<%= image_src %>" class="fr-responsive-img" alt="<%= image_alt %>">
|
17
|
+
</div>
|
18
|
+
<% end %>
|
19
|
+
<% end %>
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module DsfrComponent
|
2
|
+
class TileComponent < DsfrComponent::Base
|
3
|
+
# @param title [String] title (required)
|
4
|
+
# @param url [String] url (required)
|
5
|
+
# @param image_src [String] chemin vers l'image (optional)
|
6
|
+
# @param image_alt [String] L'alternative de l'image. Doit a priori être vide si l'image est illustrative et n'apporte pas de valeur sémantique.
|
7
|
+
# @param description [String] description (optional)
|
8
|
+
# @param orientation [String] :horizontal or :vertical
|
9
|
+
def initialize(title:, url:, image_src: nil, image_alt: "", description: nil, orientation: :vertical, classes: [], html_attributes: {})
|
10
|
+
@title = title
|
11
|
+
@url = url
|
12
|
+
@image_src = image_src
|
13
|
+
@image_alt = image_alt
|
14
|
+
@description = description
|
15
|
+
@orientation = orientation
|
16
|
+
@background = background
|
17
|
+
|
18
|
+
super(classes: classes, html_attributes: html_attributes)
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
attr_reader :title, :url, :image_src, :image_alt, :description, :orientation, :background
|
24
|
+
|
25
|
+
def default_attributes
|
26
|
+
k = %w[fr-tile fr-enlarge-link]
|
27
|
+
k << "fr-tile--horizontal" if orientation.to_sym == :horizontal
|
28
|
+
{ class: k.join(" ") }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -1,25 +1,16 @@
|
|
1
|
+
# rubocop:disable Style/TrailingCommaInHashLiteral
|
1
2
|
module DsfrComponentsHelper
|
2
|
-
{
|
3
|
+
HELPER_NAME_TO_CLASS_NAME = {
|
4
|
+
dsfr_alert: 'DsfrComponent::AlertComponent',
|
3
5
|
dsfr_accordion: 'DsfrComponent::AccordionComponent',
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
dsfr_details: 'DsfrComponent::DetailsComponent',
|
8
|
-
dsfr_footer: 'DsfrComponent::FooterComponent',
|
9
|
-
dsfr_header: 'DsfrComponent::HeaderComponent',
|
10
|
-
dsfr_inset_text: 'DsfrComponent::InsetTextComponent',
|
11
|
-
dsfr_notification_banner: 'DsfrComponent::NotificationBannerComponent',
|
12
|
-
dsfr_pagination: 'DsfrComponent::PaginationComponent',
|
13
|
-
dsfr_panel: 'DsfrComponent::PanelComponent',
|
14
|
-
dsfr_phase_banner: 'DsfrComponent::PhaseBannerComponent',
|
15
|
-
dsfr_section_break: 'DsfrComponent::SectionBreakComponent',
|
16
|
-
dsfr_start_button: 'DsfrComponent::StartButtonComponent',
|
17
|
-
dsfr_summary_list: 'DsfrComponent::SummaryListComponent',
|
18
|
-
dsfr_table: 'DsfrComponent::TableComponent',
|
19
|
-
dsfr_tabs: 'DsfrComponent::TabComponent',
|
6
|
+
dsfr_accordion_section: 'DsfrComponent::AccordionComponent::SectionComponent',
|
7
|
+
dsfr_tile: 'DsfrComponent::TileComponent',
|
8
|
+
dsfr_badge: 'DsfrComponent::BadgeComponent',
|
20
9
|
dsfr_tag: 'DsfrComponent::TagComponent',
|
21
|
-
|
22
|
-
|
10
|
+
dsfr_stepper: 'DsfrComponent::StepperComponent',
|
11
|
+
# DO NOT REMOVE: new component mapping here
|
12
|
+
}.freeze
|
13
|
+
HELPER_NAME_TO_CLASS_NAME.each do |name, klass|
|
23
14
|
define_method(name) do |*args, **kwargs, &block|
|
24
15
|
capture do
|
25
16
|
render(klass.constantize.new(*args, **kwargs)) do |com|
|
@@ -29,5 +20,6 @@ module DsfrComponentsHelper
|
|
29
20
|
end
|
30
21
|
end
|
31
22
|
end
|
23
|
+
# rubocop:enable Style/TrailingCommaInHashLiteral
|
32
24
|
|
33
25
|
ActiveSupport.on_load(:action_view) { include DsfrComponentsHelper }
|