dsfr-view-components 0.1.1 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
-

|
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
|