dsfr-view-components 0.1.1 → 0.2.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 +14 -96
- data/app/components/dsfr_component/base.rb +2 -0
- data/app/components/dsfr_component/button_component.rb +63 -0
- data/app/components/dsfr_component/header_component/direct_link_component.rb +22 -0
- data/app/components/dsfr_component/header_component/direct_link_dropdown_component.rb +34 -0
- data/app/components/dsfr_component/header_component/tool_link_component.rb +20 -0
- data/app/components/dsfr_component/header_component.html.erb +94 -0
- data/app/components/dsfr_component/header_component.rb +27 -0
- data/app/components/dsfr_component/modal_component.html.erb +30 -0
- data/app/components/dsfr_component/modal_component.rb +33 -0
- data/app/components/dsfr_component/tile_component.html.erb +2 -2
- data/app/components/dsfr_component/tile_component.rb +10 -3
- data/app/helpers/dsfr_components_helper.rb +6 -0
- data/lib/dsfr/components/version.rb +1 -1
- data/lib/generators/dsfr_component/dsfr_component_generator.rb +1 -1
- metadata +10 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 26127e695550fca9861568104cb2e15f13f81c77d8ab97788db823215bdcd43e
|
4
|
+
data.tar.gz: 90059e2796a0b0e63f6fed13bb9183866dd01ec796d190e342fd9f458d5a1bdf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f14bbd9482cf8dfa9473d024c388a30db71225c31fcee52bf69d2dfed43802892dc3cfb56e21f1273d187378cf0e905e801ed9092958839ed3ec9329fc58ece9
|
7
|
+
data.tar.gz: 30e838fb64e6e0fb1fb11adea4967aaf4cdeed2fc8763d8e46ffe4823f1e3a98c4512e974a001e86fcefe47b113dec303e49e3e7e4517727098edda9439c498f
|
data/README.md
CHANGED
@@ -30,30 +30,32 @@ bin/rails g dsfr_component FancyButton --params title:String count:Integer
|
|
30
30
|
|
31
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.
|
32
32
|
|
33
|
+
## Installation
|
34
|
+
|
35
|
+
Pour utiliser cette gem dans votre application Rails, il faut ajouter cette ligne dans `config/application.rb`:
|
36
|
+
|
37
|
+
```ruby
|
38
|
+
require "dsfr/components"
|
39
|
+
```
|
33
40
|
|
34
41
|
## Composants disponibles
|
35
42
|
|
36
43
|
Cette gem a pour but de supporter tous les composants proposés par le Design Système de l'État hormis ceux concernant les formulaires. Ceux-ci seront fournis dans une gem indépendante dans le futur.
|
37
44
|
|
38
|
-
|
45
|
+
10/36 composants sont disponibles :
|
39
46
|
|
40
47
|
- [x] Accordéon - Accordion
|
41
|
-
- [ ] Ajout de fichier - File upload
|
42
48
|
- [x] Alertes - Alert
|
43
49
|
- [x] Badge
|
44
50
|
- [ ] Bandeau d'information importante
|
45
51
|
- [ ] Barre de recherche - Search bar
|
46
|
-
- [
|
52
|
+
- [x] Boutons - Buttons
|
47
53
|
- [ ] Groupe de bouton
|
48
54
|
- [ ] Bouton FranceConnect
|
49
|
-
- [ ] Boutons radio
|
50
|
-
- [ ] Boutons radio 'riches'
|
51
|
-
- [ ] Case à cocher - Checkbox
|
52
55
|
- [ ] Cartes - Cards
|
53
|
-
- [ ] Champ de saisie - Input
|
54
56
|
- [ ] Citation - Quote
|
55
57
|
- [ ] Contenu médias - Responsive médias
|
56
|
-
- [
|
58
|
+
- [x] En-tête - Header
|
57
59
|
- [ ] Fil d'Ariane - Breadcrumb
|
58
60
|
- [ ] Gestionnaire de consentement - Consent banner
|
59
61
|
- [ ] Icônes de favoris - Favicons
|
@@ -62,11 +64,10 @@ Les composants disponibles sont :
|
|
62
64
|
- [ ] Lettre d'information et réseaux sociaux - Newsletter & Follow us
|
63
65
|
- [x] Liens - Links
|
64
66
|
- [ ] Liens d'évitement - Skiplinks
|
65
|
-
- [ ] Liste déroulante - Select
|
66
67
|
- [ ] Menu latéral - Side menu
|
67
68
|
- [ ] Mise en avant - Call out
|
68
69
|
- [ ] Mise en exergue - Highlight
|
69
|
-
- [
|
70
|
+
- [x] Modale - Modal
|
70
71
|
- [ ] Navigation principale - Main navigation
|
71
72
|
- [ ] Onglets - Tabs
|
72
73
|
- [ ] Pagination
|
@@ -76,7 +77,7 @@ Les composants disponibles sont :
|
|
76
77
|
- [ ] Sélecteur de langue
|
77
78
|
- [ ] Sommaire - Summary
|
78
79
|
- [ ] Tableau - Table
|
79
|
-
- [
|
80
|
+
- [x] Tag
|
80
81
|
- [ ] Téléchargement de fichier
|
81
82
|
- [x] Tuile - Tile
|
82
83
|
|
@@ -86,92 +87,9 @@ This library also provides helpers for creating [links](https://govuk-components
|
|
86
87
|
and [back to top links](https://govuk-components.netlify.app/helpers/back-to-top-link).
|
87
88
|
-->
|
88
89
|
|
89
|
-
|
90
|
-
## Alternative syntax
|
91
|
-
|
92
|
-
All of the components can be rendered in two ways:
|
93
|
-
|
94
|
-
* directly using Rails’ `#render` method:
|
95
|
-
|
96
|
-
```erb
|
97
|
-
<%= render DsfrComponent::WarningTextComponent.new do %>
|
98
|
-
A serious warning
|
99
|
-
<% end %>
|
100
|
-
```
|
101
|
-
|
102
|
-
* via the helper wrapper:
|
103
|
-
|
104
|
-
```erb
|
105
|
-
<%= dsfr_warning_text do %>
|
106
|
-
A serious warning
|
107
|
-
<% end %>
|
108
|
-
```
|
109
|
-
|
110
|
-
The naming convention for helpers is `dsfr_` followed by the component’s name in snake case. You can see the full list in [DsfrComponentsHelper](app/helpers/dsfr_components_helper.rb).
|
111
|
-
|
112
|
-
## Example use
|
113
|
-
|
114
|
-
This library allows components to be rendered with Rails’ `render` method or via the provided helpers. Here we’ll use the `dsfr_tabs` to render three tabbed sections:
|
115
|
-
|
116
|
-
```erb
|
117
|
-
<%= dsfr_tabs(title: 'Days of the week') do |component| %>
|
118
|
-
<% component.tab(label: 'Monday') do %>
|
119
|
-
<p>Monday’s child is fair of face</p>
|
120
|
-
<% end %>
|
121
|
-
|
122
|
-
<% component.tab(label: 'Tuesday') do %>
|
123
|
-
<p>Tuesday’s child is full of grace</p>
|
124
|
-
<% end %>
|
125
|
-
|
126
|
-
<% component.tab(label: 'Wednesday') do %>
|
127
|
-
<p>Wednesday’s child is full of woe</p>
|
128
|
-
<% end %>
|
129
|
-
<% end %>
|
130
|
-
```
|
131
|
-
|
132
|
-
Here are the rendered tabs:
|
133
|
-
|
134
|
-
![Tabs preview](docs/images/tabs.png)
|
135
|
-
|
136
|
-
For examples on usage see the [guide page](https://govuk-components.netlify.app/).
|
90
|
+
## Services utilisant cette gem
|
137
91
|
|
138
|
-
|
139
|
-
|
140
|
-
Add this line to your `config/application.rb`:
|
141
|
-
|
142
|
-
```ruby
|
143
|
-
require "govuk/components"
|
144
|
-
```
|
145
|
-
|
146
|
-
## Services using this library
|
147
|
-
|
148
|
-
* [Apply for teacher training](https://github.com/DFE-Digital/apply-for-teacher-training)
|
149
|
-
* [Find postgraduate teacher training](https://github.com/DFE-Digital/find-teacher-training)
|
150
|
-
* [Get help with technology](https://github.com/DFE-Digital/get-help-with-tech)
|
151
|
-
* [Publish teacher training courses](https://github.com/DFE-Digital/publish-teacher-training)
|
152
|
-
* [Register trainee teachers](https://github.com/DFE-Digital/register-trainee-teachers)
|
153
|
-
* [Teaching Vacancies](https://github.com/DFE-Digital/teaching-vacancies)
|
154
|
-
|
155
|
-
## Installation
|
156
|
-
|
157
|
-
Ajouter cette ligne à votre Gemfile:
|
158
|
-
|
159
|
-
```ruby
|
160
|
-
gem 'dsfr-components'
|
161
|
-
```
|
162
|
-
|
163
|
-
And then execute:
|
164
|
-
|
165
|
-
```sh
|
166
|
-
bundle
|
167
|
-
```
|
168
|
-
|
169
|
-
Or install it yourself as:
|
170
|
-
|
171
|
-
```sh
|
172
|
-
gem install govuk-components
|
173
|
-
```
|
174
|
-
-->
|
92
|
+
- [Collectif Objets](https://collectif-objets.beta.gouv.fr/) - [code source](https://github.com/betagouv/collectif-objets)
|
175
93
|
|
176
94
|
## Contribuer
|
177
95
|
|
@@ -5,6 +5,8 @@ class DsfrComponent::Base < ViewComponent::Base
|
|
5
5
|
|
6
6
|
delegate :config, to: Dsfr::Components
|
7
7
|
|
8
|
+
HEADING_LEVELS = [1, 2, 3, 4, 5, 6].freeze
|
9
|
+
|
8
10
|
def initialize(classes:, html_attributes:)
|
9
11
|
if classes.nil?
|
10
12
|
Rails.logger.warn("classes is nil, if no custom classes are needed omit the param")
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module DsfrComponent
|
2
|
+
class ButtonComponent < DsfrComponent::Base
|
3
|
+
SIZES = %i[sm md lg].freeze
|
4
|
+
ICON_POSITIONS = %i[left right].freeze
|
5
|
+
ICON_LEVELS = %i[primary secondary tertiary].freeze
|
6
|
+
|
7
|
+
# @param label [String] Le label du bouton (optionnel si un icône présent)
|
8
|
+
# @param icon [String] Le nom de l’icône à afficher (exemple `arrow-right-line`) (optionnel)
|
9
|
+
# @param icon_position [String] Position de l’icône : :left (défaut) ou :right (optionnel)
|
10
|
+
# @param title [String] Le titre du bouton permettant d’afficher une infobulle (optionnel)
|
11
|
+
# @param level [String] Le niveau du bouton : :primary (défaut), :secondary ou :tertiary (optionnel)
|
12
|
+
# @param size [String] La taille du bouton : :sm, :md (défaut), :lg (optionnel)
|
13
|
+
def initialize(label: nil, title: nil, icon: nil, icon_position: :left, level: nil, size: nil, classes: [], html_attributes: {})
|
14
|
+
@label = label
|
15
|
+
@title = title
|
16
|
+
@icon = icon
|
17
|
+
@icon_position = icon_position
|
18
|
+
@level = level
|
19
|
+
@outline = outline
|
20
|
+
@size = size
|
21
|
+
|
22
|
+
validate_size
|
23
|
+
validate_icon_position
|
24
|
+
validate_level
|
25
|
+
validate_label
|
26
|
+
|
27
|
+
super(classes: classes, html_attributes: html_attributes)
|
28
|
+
end
|
29
|
+
|
30
|
+
def call
|
31
|
+
tag.button(**html_attributes) { label }
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
attr_reader :label, :icon, :icon_position, :level, :outline, :size
|
37
|
+
|
38
|
+
def default_attributes
|
39
|
+
classes = ["fr-btn"]
|
40
|
+
classes << "fr-btn--#{level}" if level.present?
|
41
|
+
classes << "fr-btn--#{size}" if size.present?
|
42
|
+
classes << "fr-icon-#{icon}" if icon.present?
|
43
|
+
classes << "fr-btn--icon-#{icon_position}" if icon.present? && label.present?
|
44
|
+
{ class: classes }
|
45
|
+
end
|
46
|
+
|
47
|
+
def validate_size
|
48
|
+
raise(ArgumentError, "`size` should be one of #{SIZES}") if size.present? && SIZES.exclude?(size)
|
49
|
+
end
|
50
|
+
|
51
|
+
def validate_icon_position
|
52
|
+
raise(ArgumentError, "`icon_position` should be one of #{ICON_POSITIONS}") if icon_position.present? && ICON_POSITIONS.exclude?(icon_position)
|
53
|
+
end
|
54
|
+
|
55
|
+
def validate_level
|
56
|
+
raise(ArgumentError, "`level` should be one of #{ICON_LEVELS}") if level.present? && ICON_LEVELS.exclude?(level)
|
57
|
+
end
|
58
|
+
|
59
|
+
def validate_label
|
60
|
+
raise(ArgumentError, "`label` is required unless an icon is specified") if label.blank? && icon.blank?
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
class DsfrComponent::HeaderComponent::DirectLinkComponent < DsfrComponent::Base
|
2
|
+
def initialize(title:, path:, active: false, classes: [], html_attributes: {})
|
3
|
+
@title = title
|
4
|
+
@path = path
|
5
|
+
@active = active
|
6
|
+
|
7
|
+
super(classes: classes, html_attributes: html_attributes)
|
8
|
+
end
|
9
|
+
|
10
|
+
def call
|
11
|
+
tag.a(title, **html_attributes)
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
attr_reader :title, :path, :active
|
17
|
+
|
18
|
+
def default_attributes
|
19
|
+
{ href: path, class: 'fr-nav__link', target: "_self" } \
|
20
|
+
.merge(active ? { "aria-current": 'page' } : {})
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
class DsfrComponent::HeaderComponent::DirectLinkDropdownComponent < DsfrComponent::Base
|
2
|
+
renders_many :links, DsfrComponent::HeaderComponent::DirectLinkComponent
|
3
|
+
|
4
|
+
def initialize(title:, active: false, classes: [], html_attributes: {})
|
5
|
+
@title = title
|
6
|
+
@active = active
|
7
|
+
|
8
|
+
super(classes: classes, html_attributes: html_attributes)
|
9
|
+
end
|
10
|
+
|
11
|
+
def call
|
12
|
+
tag.button(title, **html_attributes) +
|
13
|
+
tag.div(class: 'fr-collapse fr-menu', id: menu_id) do
|
14
|
+
tag.ul(class: 'fr-menu__list') do
|
15
|
+
links.map do |link|
|
16
|
+
tag.li link.call
|
17
|
+
end.join.html_safe
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
attr_reader :title, :active
|
25
|
+
|
26
|
+
def default_attributes
|
27
|
+
{ class: 'fr-nav__btn', "aria-expanded": "false", "aria-controls": menu_id } \
|
28
|
+
.merge(active ? { "aria-current": 'true' } : {})
|
29
|
+
end
|
30
|
+
|
31
|
+
def menu_id
|
32
|
+
@menu_id ||= "menu-#{title.parameterize}"
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
class DsfrComponent::HeaderComponent::ToolLinkComponent < DsfrComponent::Base
|
2
|
+
def initialize(title:, path:, classes: [], html_attributes: {})
|
3
|
+
@title = title
|
4
|
+
@path = path
|
5
|
+
|
6
|
+
super(classes: classes, html_attributes: html_attributes)
|
7
|
+
end
|
8
|
+
|
9
|
+
def call
|
10
|
+
tag.a title, href: path, **html_attributes
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
attr_reader :title, :path
|
16
|
+
|
17
|
+
def default_attributes
|
18
|
+
{ class: 'fr-btn' }
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
<%= tag.header(**html_attributes) do %>
|
2
|
+
<div class="fr-header__body">
|
3
|
+
<div class="fr-container">
|
4
|
+
<div class="fr-header__body-row">
|
5
|
+
<div class="fr-header__brand fr-enlarge-link">
|
6
|
+
<div class="fr-header__brand-top">
|
7
|
+
<div class="fr-header__logo">
|
8
|
+
<p class="fr-logo"><%= logo_text %></p>
|
9
|
+
</div>
|
10
|
+
|
11
|
+
<% if search? || tool_links? || direct_links? %>
|
12
|
+
<div class="fr-header__navbar">
|
13
|
+
<% if search? %>
|
14
|
+
<button class="fr-btn--search fr-btn" data-fr-opened="false" aria-controls="modal-header-search" id="button-header-search" title="Rechercher">
|
15
|
+
Rechercher
|
16
|
+
</button>
|
17
|
+
<% end %>
|
18
|
+
|
19
|
+
<% if tool_links? || direct_links? %>
|
20
|
+
<button class="fr-btn--menu fr-btn" data-fr-opened="false" aria-controls="modal-header-menu" aria-haspopup="menu" id="button-header-menu" title="Menu">
|
21
|
+
Menu
|
22
|
+
</button>
|
23
|
+
<% end %>
|
24
|
+
</div>
|
25
|
+
<% end %>
|
26
|
+
</div>
|
27
|
+
|
28
|
+
<div class="fr-header__service">
|
29
|
+
<a href="/" title="Accueil - <%= title %>">
|
30
|
+
<p class="fr-header__service-title"><%= title %></p>
|
31
|
+
</a>
|
32
|
+
<% if tagline %>
|
33
|
+
<p class="fr-header__service-tagline"><%= tagline %></p>
|
34
|
+
<% end %>
|
35
|
+
</div>
|
36
|
+
</div>
|
37
|
+
|
38
|
+
<% if tool_links? || search? %>
|
39
|
+
<div class="fr-header__tools">
|
40
|
+
<% if tool_links? %>
|
41
|
+
<div class="fr-header__tools-links">
|
42
|
+
<ul class="fr-btns-group">
|
43
|
+
<% tool_links.each do |tool_link| %>
|
44
|
+
<li>
|
45
|
+
<%= tool_link %>
|
46
|
+
</li>
|
47
|
+
<% end %>
|
48
|
+
</ul>
|
49
|
+
</div>
|
50
|
+
<% end %>
|
51
|
+
|
52
|
+
<% if search? %>
|
53
|
+
<div class="fr-header__search fr-modal" id="modal-header-search">
|
54
|
+
<div class="fr-container fr-container-lg--fluid">
|
55
|
+
<button class="fr-btn--close fr-btn" aria-controls="modal-header-search" title="Fermer">
|
56
|
+
Fermer
|
57
|
+
</button>
|
58
|
+
<div role="search" id="header-search">
|
59
|
+
<%= search %>
|
60
|
+
</div>
|
61
|
+
</div>
|
62
|
+
</div>
|
63
|
+
<% end %>
|
64
|
+
</div>
|
65
|
+
<% end %>
|
66
|
+
</div>
|
67
|
+
</div>
|
68
|
+
</div>
|
69
|
+
|
70
|
+
<% if tool_links? || direct_links? %>
|
71
|
+
<div class="fr-header__menu fr-modal" id="modal-header-menu" aria-labelledby="button-header-menu">
|
72
|
+
<div class="fr-container">
|
73
|
+
<button class="fr-btn--close fr-btn" aria-controls="modal-header-menu" title="Fermer">
|
74
|
+
Fermer
|
75
|
+
</button>
|
76
|
+
<div class="fr-header__menu-links">
|
77
|
+
<!-- this seems to get autopopulated with the tool links with JS -->
|
78
|
+
</div>
|
79
|
+
|
80
|
+
<% if direct_links? %>
|
81
|
+
<nav class="fr-nav" id="navigation-direct-links" role="navigation" aria-label="Menu principal">
|
82
|
+
<ul class="fr-nav__list">
|
83
|
+
<% direct_links.each do |direct_link| %>
|
84
|
+
<li class="fr-nav__item">
|
85
|
+
<%= direct_link %>
|
86
|
+
</li>
|
87
|
+
<% end %>
|
88
|
+
</ul>
|
89
|
+
</nav>
|
90
|
+
<% end %>
|
91
|
+
</div>
|
92
|
+
</div>
|
93
|
+
<% end %>
|
94
|
+
<% end %>
|
@@ -0,0 +1,27 @@
|
|
1
|
+
class DsfrComponent::HeaderComponent < DsfrComponent::Base
|
2
|
+
renders_one :search
|
3
|
+
renders_many :tool_links, "DsfrComponent::HeaderComponent::ToolLinkComponent"
|
4
|
+
renders_many :direct_links, types: {
|
5
|
+
simple: "DsfrComponent::HeaderComponent::DirectLinkComponent",
|
6
|
+
dropdown: "DsfrComponent::HeaderComponent::DirectLinkDropdownComponent"
|
7
|
+
}
|
8
|
+
|
9
|
+
# @param logo_text [String] Ce texte obligatoire sera affiché en dessous de la Marianne et au dessus de la devise française. C’est généralement un nom de ministère ou d’administration.
|
10
|
+
# @param title [String] Le nom du service numérique, titre principal du site.
|
11
|
+
# @param tagline [String] La description du service numérique, sous-titre du site (optionnelle).
|
12
|
+
def initialize(logo_text:, title:, tagline: nil, classes: [], html_attributes: {})
|
13
|
+
@logo_text = logo_text
|
14
|
+
@title = title
|
15
|
+
@tagline = tagline
|
16
|
+
|
17
|
+
super(classes: classes, html_attributes: html_attributes)
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
attr_reader :logo_text, :title, :tagline
|
23
|
+
|
24
|
+
def default_attributes
|
25
|
+
{ class: 'fr-header', role: 'banner' }
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
<%= tag.dialog(**html_attributes) do %>
|
2
|
+
<div class="fr-container fr-container--fluid fr-container-md">
|
3
|
+
<div class="fr-grid-row fr-grid-row--center">
|
4
|
+
<div class="fr-col-12 fr-col-md-8 fr-col-lg-6">
|
5
|
+
<div class="fr-modal__body">
|
6
|
+
<div class="fr-modal__header">
|
7
|
+
<% if header? %>
|
8
|
+
<%= header %>
|
9
|
+
<% else %>
|
10
|
+
<button class="fr-link--close fr-link" aria-controls="<%= id %>" type="button">Fermer</button>
|
11
|
+
<% end %>
|
12
|
+
</div>
|
13
|
+
<div class="fr-modal__content">
|
14
|
+
<%= content_tag(:h1, title, class: "fr-modal__title", id: title_id) %>
|
15
|
+
<%= content %>
|
16
|
+
</div>
|
17
|
+
<% if buttons? %>
|
18
|
+
<div class="fr-modal__footer">
|
19
|
+
<ul class="fr-btns-group fr-btns-group--right fr-btns-group--inline-reverse fr-btns-group--inline-lg fr-btns-group--icon-left">
|
20
|
+
<% buttons.each do |button| %>
|
21
|
+
<%= button %>
|
22
|
+
<% end %>
|
23
|
+
</ul>
|
24
|
+
</div>
|
25
|
+
<% end %>
|
26
|
+
</div>
|
27
|
+
</div>
|
28
|
+
</div>
|
29
|
+
</div>
|
30
|
+
<% end %>
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module DsfrComponent
|
2
|
+
class ModalComponent < DsfrComponent::Base
|
3
|
+
renders_one :header
|
4
|
+
renders_many :buttons
|
5
|
+
|
6
|
+
# @param title [String] Titre de la modale
|
7
|
+
# @param opened [Boolean] Ouvre la modale dès le chargement de la page
|
8
|
+
def initialize(title:, opened: false, classes: [], html_attributes: {})
|
9
|
+
@title = title
|
10
|
+
@opened = opened
|
11
|
+
|
12
|
+
@id = html_attributes[:id]
|
13
|
+
super(classes: classes, html_attributes: html_attributes)
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
attr_reader :title, :title_icon, :id
|
19
|
+
|
20
|
+
def default_attributes
|
21
|
+
{
|
22
|
+
class: "fr-modal #{@opened ? 'fr-modal--opened' : ''}",
|
23
|
+
role: "dialog",
|
24
|
+
id: @id,
|
25
|
+
"aria-labelledby": title_id
|
26
|
+
}.compact
|
27
|
+
end
|
28
|
+
|
29
|
+
def title_id
|
30
|
+
"#{@id}-title" if @id.present?
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -1,10 +1,10 @@
|
|
1
1
|
<%= tag.div(**html_attributes) do %>
|
2
2
|
<div class="fr-tile__body">
|
3
|
-
|
3
|
+
<%= title_tag(class: "fr-tile__title") do %>
|
4
4
|
<a class="fr-tile__link" href="<%= url %>">
|
5
5
|
<%= title %>
|
6
6
|
</a>
|
7
|
-
|
7
|
+
<% end %>
|
8
8
|
<% if description.present? %>
|
9
9
|
<p class="fr-tile__desc">
|
10
10
|
<%= description %>
|
@@ -6,26 +6,33 @@ module DsfrComponent
|
|
6
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
7
|
# @param description [String] description (optional)
|
8
8
|
# @param orientation [String] :horizontal or :vertical
|
9
|
-
|
9
|
+
# @param heading_level [Integer] 1, 2, 3, 4 (default), 5, 6
|
10
|
+
def initialize(title:, url:, image_src: nil, image_alt: "", description: nil, orientation: :vertical, heading_level: 4, classes: [], html_attributes: {})
|
10
11
|
@title = title
|
11
12
|
@url = url
|
12
13
|
@image_src = image_src
|
13
14
|
@image_alt = image_alt
|
14
15
|
@description = description
|
15
16
|
@orientation = orientation
|
16
|
-
@
|
17
|
+
@heading_level = heading_level
|
18
|
+
|
19
|
+
raise ArgumentError if HEADING_LEVELS.exclude?(heading_level)
|
17
20
|
|
18
21
|
super(classes: classes, html_attributes: html_attributes)
|
19
22
|
end
|
20
23
|
|
21
24
|
private
|
22
25
|
|
23
|
-
attr_reader :title, :url, :image_src, :image_alt, :description, :orientation, :
|
26
|
+
attr_reader :title, :url, :image_src, :image_alt, :description, :orientation, :heading_level
|
24
27
|
|
25
28
|
def default_attributes
|
26
29
|
k = %w[fr-tile fr-enlarge-link]
|
27
30
|
k << "fr-tile--horizontal" if orientation.to_sym == :horizontal
|
28
31
|
{ class: k.join(" ") }
|
29
32
|
end
|
33
|
+
|
34
|
+
def title_tag(*args, **kwargs, &block)
|
35
|
+
content_tag("h#{heading_level}", *args, **kwargs, &block)
|
36
|
+
end
|
30
37
|
end
|
31
38
|
end
|
@@ -8,6 +8,12 @@ module DsfrComponentsHelper
|
|
8
8
|
dsfr_badge: 'DsfrComponent::BadgeComponent',
|
9
9
|
dsfr_tag: 'DsfrComponent::TagComponent',
|
10
10
|
dsfr_stepper: 'DsfrComponent::StepperComponent',
|
11
|
+
dsfr_button: 'DsfrComponent::ButtonComponent',
|
12
|
+
dsfr_modal: 'DsfrComponent::ModalComponent',
|
13
|
+
dsfr_header: 'DsfrComponent::HeaderComponent',
|
14
|
+
dsfr_header_tool_link: 'DsfrComponent::HeaderComponent::ToolLinkComponent',
|
15
|
+
dsfr_header_direct_link: 'DsfrComponent::HeaderComponent::DirectLinkComponent',
|
16
|
+
dsfr_header_direct_dropdown_link: 'DsfrComponent::HeaderComponent::DirectLinkDropdownComponent',
|
11
17
|
# DO NOT REMOVE: new component mapping here
|
12
18
|
}.freeze
|
13
19
|
HELPER_NAME_TO_CLASS_NAME.each do |name, klass|
|
@@ -34,7 +34,7 @@ class DsfrComponentGenerator < Rails::Generators::NamedBase
|
|
34
34
|
def append_guide_helper
|
35
35
|
destination = "guide/lib/helpers.rb"
|
36
36
|
|
37
|
-
append_to_file destination, "use_helper Examples::#{name}Helpers"
|
37
|
+
append_to_file destination, "use_helper Examples::#{name}Helpers\n" # trailing new line
|
38
38
|
end
|
39
39
|
|
40
40
|
def map_component_helper
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dsfr-view-components
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- BetaGouv developers
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-03-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: actionpack
|
@@ -451,6 +451,14 @@ files:
|
|
451
451
|
- app/components/dsfr_component/alert_component.rb
|
452
452
|
- app/components/dsfr_component/badge_component.rb
|
453
453
|
- app/components/dsfr_component/base.rb
|
454
|
+
- app/components/dsfr_component/button_component.rb
|
455
|
+
- app/components/dsfr_component/header_component.html.erb
|
456
|
+
- app/components/dsfr_component/header_component.rb
|
457
|
+
- app/components/dsfr_component/header_component/direct_link_component.rb
|
458
|
+
- app/components/dsfr_component/header_component/direct_link_dropdown_component.rb
|
459
|
+
- app/components/dsfr_component/header_component/tool_link_component.rb
|
460
|
+
- app/components/dsfr_component/modal_component.html.erb
|
461
|
+
- app/components/dsfr_component/modal_component.rb
|
454
462
|
- app/components/dsfr_component/stepper_component.html.erb
|
455
463
|
- app/components/dsfr_component/stepper_component.rb
|
456
464
|
- app/components/dsfr_component/tag_component.rb
|