silex_ui 0.1.0 → 0.2.0
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/CHANGELOG.md +17 -0
- data/README.md +24 -0
- data/app/controllers/silex_ui/catalogue_controller.rb +47 -0
- data/app/views/silex_ui/catalogue/_specimen.html.erb +15 -0
- data/app/views/silex_ui/catalogue/show.html.erb +251 -0
- data/config/routes.rb +7 -0
- data/lib/silex_ui/version.rb +1 -1
- data/lib/silex_ui.rb +30 -1
- metadata +5 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c8c471e84ca4f41561bb7daa42d18669287be88e7d278d82ea79566f0baeaf46
|
|
4
|
+
data.tar.gz: 6af9d732ec1b5188374e38ff7d06d771540886e7ea64f826dea89b0a876bd248
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1ef386b477752142f8e2d2ec94a89e5256c03aab117693f3e945e6b3cfc223d1402ba29defb027ae5b3a4fa05ba17336c00006a159994f8a29e48327a134d2e7
|
|
7
|
+
data.tar.gz: 4a4fef0ccf67d57b6f4efbddd7338ad9655a0c1ded3a1e2649820b5f640a926b4c5c892f336e72fb00fe70a55af5f149d1352a8d6f7312aa8a4ea649e49de1be
|
data/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,23 @@ Toutes les évolutions notables de silex_ui. Le format suit
|
|
|
6
6
|
|
|
7
7
|
## [Non publié]
|
|
8
8
|
|
|
9
|
+
## [0.2.0] — 2026-09-10
|
|
10
|
+
|
|
11
|
+
### Ajouté
|
|
12
|
+
|
|
13
|
+
- Page catalogue : tous les composants dans toutes leurs variantes, montée par
|
|
14
|
+
l'application hôte (`mount SilexUi::Engine => "/design"`), en développement
|
|
15
|
+
seulement. Un composant qu'on ne peut voir qu'en trouvant la page qui l'utilise
|
|
16
|
+
est un composant qu'on finit par recopier à la main.
|
|
17
|
+
- `SilexUi.configure` : `catalogue_layout` pour les applications dont le layout
|
|
18
|
+
exige une session, `catalogue_enabled` pour ouvrir ou fermer la page ailleurs
|
|
19
|
+
qu'en développement.
|
|
20
|
+
|
|
21
|
+
### Modifié
|
|
22
|
+
|
|
23
|
+
- `silex_ui:sync` recopie aussi `app/views`, sans quoi les nuanciers du catalogue
|
|
24
|
+
se rendraient sans leurs couleurs.
|
|
25
|
+
|
|
9
26
|
## [0.1.0] — 2026-09-10
|
|
10
27
|
|
|
11
28
|
Première version.
|
data/README.md
CHANGED
|
@@ -61,6 +61,30 @@ registerSilexUiControllers(application)
|
|
|
61
61
|
Ils sont enregistrés sous le préfixe `silex-ui--`, hors de portée des
|
|
62
62
|
contrôleurs de l'application.
|
|
63
63
|
|
|
64
|
+
## Le catalogue
|
|
65
|
+
|
|
66
|
+
Tous les composants, dans toutes leurs variantes, sur une page. À monter dans
|
|
67
|
+
l'application hôte — en développement seulement :
|
|
68
|
+
|
|
69
|
+
```ruby
|
|
70
|
+
# config/routes.rb
|
|
71
|
+
mount SilexUi::Engine => "/design" if Rails.env.development?
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Puis http://localhost:3000/design.
|
|
75
|
+
|
|
76
|
+
La page emprunte le layout de l'application, parce que c'est lui qui sait où sont
|
|
77
|
+
sa feuille de style et son importmap. Si ce layout exige une session, désignez-en
|
|
78
|
+
un autre :
|
|
79
|
+
|
|
80
|
+
```ruby
|
|
81
|
+
# config/initializers/silex_ui.rb
|
|
82
|
+
SilexUi.configure do |config|
|
|
83
|
+
config.catalogue_layout = "silex_ui/bare" # ou false
|
|
84
|
+
config.catalogue_enabled = false # pour le fermer même en dev
|
|
85
|
+
end
|
|
86
|
+
```
|
|
87
|
+
|
|
64
88
|
## Tokens
|
|
65
89
|
|
|
66
90
|
| Famille | Rôle | Nuances |
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SilexUi
|
|
4
|
+
# Le catalogue : tous les composants du design system sur une page, dans
|
|
5
|
+
# toutes leurs variantes. Un composant qu'on ne peut voir qu'en trouvant la
|
|
6
|
+
# page qui l'utilise est un composant qu'on finit par recopier à la main.
|
|
7
|
+
#
|
|
8
|
+
# Monté par l'application hôte, en développement seulement :
|
|
9
|
+
#
|
|
10
|
+
# mount SilexUi::Engine => "/design" if Rails.env.development?
|
|
11
|
+
class CatalogueController < ActionController::Base
|
|
12
|
+
# Le catalogue emprunte le layout de l'application : c'est lui qui sait où
|
|
13
|
+
# sont sa feuille de style et son importmap. Une application dont le layout
|
|
14
|
+
# exige une session peut en désigner un autre.
|
|
15
|
+
layout -> { SilexUi.configuration.catalogue_layout }
|
|
16
|
+
|
|
17
|
+
before_action :ensure_available
|
|
18
|
+
|
|
19
|
+
# Assez de données pour que chaque composant ait quelque chose à montrer,
|
|
20
|
+
# et rien qui touche à la base de l'application.
|
|
21
|
+
Site = Struct.new(:domain, :registrar, :expired, keyword_init: true)
|
|
22
|
+
Pages = Struct.new(:page, :series, :previous_page, :next_page, :from, :to, :count, keyword_init: true) do
|
|
23
|
+
def many? = true
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def show
|
|
27
|
+
@sites = [
|
|
28
|
+
Site.new(domain: "bali-surf-camp.fr", registrar: "ovh", expired: false),
|
|
29
|
+
Site.new(domain: "voyage-indonesie.com", registrar: "netim", expired: true),
|
|
30
|
+
Site.new(domain: "location-villa-bali.fr", registrar: "gandi", expired: false)
|
|
31
|
+
]
|
|
32
|
+
|
|
33
|
+
@pagination = Pages.new(page: 6, series: [ 1, :gap, 4, 5, 6, 7, 8, :gap, 26 ],
|
|
34
|
+
previous_page: 5, next_page: 7, from: 251, to: 300, count: 1_300)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
private
|
|
38
|
+
|
|
39
|
+
# Le catalogue n'a rien à faire en production : il n'y sert personne et il
|
|
40
|
+
# décrit l'interface à qui la regarde.
|
|
41
|
+
def ensure_available
|
|
42
|
+
return if SilexUi.configuration.catalogue_enabled?
|
|
43
|
+
|
|
44
|
+
raise ActionController::RoutingError, "Le catalogue silex_ui n'est disponible qu'en développement"
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<%# Un spécimen : ce qu'on regarde, et la ligne à recopier pour l'obtenir. %>
|
|
2
|
+
<div class="border-t border-sand-100 py-6">
|
|
3
|
+
<div class="mb-4 flex flex-wrap items-baseline justify-between gap-3">
|
|
4
|
+
<h3 class="text-sm font-light text-ink-900"><%= title %></h3>
|
|
5
|
+
<% if local_assigns[:note].present? %>
|
|
6
|
+
<p class="text-xs font-light text-ink-400"><%= note %></p>
|
|
7
|
+
<% end %>
|
|
8
|
+
</div>
|
|
9
|
+
|
|
10
|
+
<div class="mb-4"><%= yield %></div>
|
|
11
|
+
|
|
12
|
+
<% if local_assigns[:code].present? %>
|
|
13
|
+
<pre class="overflow-x-auto rounded-sm bg-sand-100 p-3 text-xs text-ink-600"><code><%= code %></code></pre>
|
|
14
|
+
<% end %>
|
|
15
|
+
</div>
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
<% content_for :title, "Catalogue — silex_ui #{SilexUi::VERSION}" %>
|
|
2
|
+
|
|
3
|
+
<div class="mx-auto min-h-screen max-w-6xl px-6 pb-24">
|
|
4
|
+
<%= render SilexUi::PageHeaderComponent.new(
|
|
5
|
+
title: "silex_ui",
|
|
6
|
+
subtitle: "Le design system des applications Le Silex — version #{SilexUi::VERSION}.",
|
|
7
|
+
document_title: false) do |header| %>
|
|
8
|
+
<% header.with_meta do %>
|
|
9
|
+
<p class="text-xs text-ink-400">
|
|
10
|
+
Cette page n'existe qu'en développement. Chaque composant y figure dans toutes ses variantes :
|
|
11
|
+
ce qui manque ici manque au design system.
|
|
12
|
+
</p>
|
|
13
|
+
<% end %>
|
|
14
|
+
<% end %>
|
|
15
|
+
|
|
16
|
+
<%= render SilexUi::SectionComponent.new(title: "Palette", class: "mt-4") do %>
|
|
17
|
+
<div class="grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
|
|
18
|
+
<% {
|
|
19
|
+
"sand — le sol" => %w[bg-sand-50 bg-sand-100 bg-sand-200 bg-sand-300],
|
|
20
|
+
"ink — le texte" => %w[bg-ink-300 bg-ink-400 bg-ink-600 bg-ink-900],
|
|
21
|
+
"alert — ce qui a lapsé" => %w[bg-alert-50 bg-alert-100 bg-alert-300 bg-alert-700],
|
|
22
|
+
"warn — ce qui bascule" => %w[bg-warn-50 bg-warn-100 bg-warn-300 bg-warn-700],
|
|
23
|
+
"ok — ce qui est en règle" => %w[bg-ok-50 bg-ok-100 bg-ok-300 bg-ok-700],
|
|
24
|
+
"info — sans urgence" => %w[bg-info-50 bg-info-100 bg-info-300 bg-info-700]
|
|
25
|
+
}.each do |family, swatches| %>
|
|
26
|
+
<div>
|
|
27
|
+
<p class="mb-2 text-xs font-light tracking-widest text-ink-400 uppercase"><%= family %></p>
|
|
28
|
+
<div class="flex overflow-hidden rounded-sm border border-sand-200">
|
|
29
|
+
<% swatches.each do |swatch| %>
|
|
30
|
+
<div class="h-12 flex-1 <%= swatch %>" title="<%= swatch %>"></div>
|
|
31
|
+
<% end %>
|
|
32
|
+
</div>
|
|
33
|
+
<p class="mt-1 text-xs font-light text-ink-300"><%= swatches.map { |s| s.split("-").last }.join(" · ") %></p>
|
|
34
|
+
</div>
|
|
35
|
+
<% end %>
|
|
36
|
+
</div>
|
|
37
|
+
<% end %>
|
|
38
|
+
|
|
39
|
+
<%= render SilexUi::SectionComponent.new(title: "Typographie", class: "mt-12") do %>
|
|
40
|
+
<div class="space-y-3">
|
|
41
|
+
<p class="text-lg font-light tracking-[0.2em] text-ink-900 uppercase">Titre de page</p>
|
|
42
|
+
<p class="text-xs font-light tracking-widest text-ink-400 uppercase">Titre de section</p>
|
|
43
|
+
<p class="text-sm font-light text-ink-600">Texte courant — la graisse légère est la graisse par défaut.</p>
|
|
44
|
+
<p class="text-xs font-light text-ink-400">Mention secondaire, pour ce qui accompagne sans appeler.</p>
|
|
45
|
+
</div>
|
|
46
|
+
<% end %>
|
|
47
|
+
|
|
48
|
+
<%= render SilexUi::SectionComponent.new(title: "Boutons", class: "mt-12") do %>
|
|
49
|
+
<%= render layout: "silex_ui/catalogue/specimen",
|
|
50
|
+
locals: { title: "Variantes", code: 'SilexUi::ButtonComponent.new(label: "Ajouter", href: "#", variant: :primary)' } do %>
|
|
51
|
+
<div class="flex flex-wrap items-center gap-3">
|
|
52
|
+
<% SilexUi::ButtonComponent::VARIANTS.each_key do |variant| %>
|
|
53
|
+
<%= render SilexUi::ButtonComponent.new(label: variant.to_s.titleize, href: "#", variant: variant) %>
|
|
54
|
+
<% end %>
|
|
55
|
+
</div>
|
|
56
|
+
<% end %>
|
|
57
|
+
|
|
58
|
+
<%= render layout: "silex_ui/catalogue/specimen", locals: { title: "Tailles" } do %>
|
|
59
|
+
<div class="flex flex-wrap items-center gap-3">
|
|
60
|
+
<% SilexUi::ButtonComponent::SIZES.each_key do |size| %>
|
|
61
|
+
<%= render SilexUi::ButtonComponent.new(label: size.to_s, href: "#", size: size) %>
|
|
62
|
+
<% end %>
|
|
63
|
+
</div>
|
|
64
|
+
<% end %>
|
|
65
|
+
<% end %>
|
|
66
|
+
|
|
67
|
+
<%= render SilexUi::SectionComponent.new(title: "Badges et pastilles", class: "mt-12") do %>
|
|
68
|
+
<%= render layout: "silex_ui/catalogue/specimen",
|
|
69
|
+
locals: { title: "Tons", note: "Sémantiques, jamais chromatiques",
|
|
70
|
+
code: 'SilexUi::BadgeComponent.new(label: "expiré", tone: :alert)' } do %>
|
|
71
|
+
<div class="flex flex-wrap items-center gap-2">
|
|
72
|
+
<% SilexUi::BaseComponent::TONES.each do |tone| %>
|
|
73
|
+
<%= render SilexUi::BadgeComponent.new(label: tone.to_s, tone: tone) %>
|
|
74
|
+
<% end %>
|
|
75
|
+
<%= render SilexUi::BadgeComponent.new(label: "cliquable", href: "#") %>
|
|
76
|
+
</div>
|
|
77
|
+
<% end %>
|
|
78
|
+
|
|
79
|
+
<%= render layout: "silex_ui/catalogue/specimen",
|
|
80
|
+
locals: { title: "Bouton de copie", note: "Confirme, puis reprend son libellé",
|
|
81
|
+
code: 'SilexUi::CopyButtonComponent.new(value: website.domain)' } do %>
|
|
82
|
+
<%= render SilexUi::CopyButtonComponent.new(value: "bali-surf-camp.fr", label: "Copier le domaine") %>
|
|
83
|
+
<% end %>
|
|
84
|
+
<% end %>
|
|
85
|
+
|
|
86
|
+
<%= render SilexUi::SectionComponent.new(title: "Compteurs", class: "mt-12") do %>
|
|
87
|
+
<%= render layout: "silex_ui/catalogue/specimen",
|
|
88
|
+
locals: { title: "Grille de statistiques",
|
|
89
|
+
code: 'grid.with_stat(value: 12, label: "Expirés", tone: :alert, href: "#")' } do %>
|
|
90
|
+
<%= render SilexUi::StatGridComponent.new do |grid| %>
|
|
91
|
+
<% grid.with_stat value: number_with_delimiter(1_240), label: "Domaines", href: "#" %>
|
|
92
|
+
<% grid.with_stat value: 37, label: "Expirent sous 30 j", tone: :warn, href: "#" %>
|
|
93
|
+
<% grid.with_stat value: 12, label: "Expirés", tone: :alert, href: "#",
|
|
94
|
+
trend: { value: 3, positive: false } %>
|
|
95
|
+
<% grid.with_stat value: 96, label: "Sans repo", hint: "sur 1 240" %>
|
|
96
|
+
<% end %>
|
|
97
|
+
<% end %>
|
|
98
|
+
|
|
99
|
+
<%= render layout: "silex_ui/catalogue/specimen",
|
|
100
|
+
locals: { title: "Répartition", code: 'SilexUi::BreakdownComponent.new(title: "Par registrar", items: [...])' } do %>
|
|
101
|
+
<div class="max-w-xs">
|
|
102
|
+
<%= render SilexUi::BreakdownComponent.new(title: "Par registrar", items: [
|
|
103
|
+
{ label: "OVH", count: 612, href: "#" },
|
|
104
|
+
{ label: "Netim", count: 428, href: "#" },
|
|
105
|
+
{ label: "Gandi", count: 200 }
|
|
106
|
+
]) %>
|
|
107
|
+
</div>
|
|
108
|
+
<% end %>
|
|
109
|
+
<% end %>
|
|
110
|
+
|
|
111
|
+
<%= render SilexUi::SectionComponent.new(title: "Tableaux", class: "mt-12") do %>
|
|
112
|
+
<%= render layout: "silex_ui/catalogue/specimen",
|
|
113
|
+
locals: { title: "Colonnes déclarées, tri, lignes colorées",
|
|
114
|
+
code: 'table.with_column(header: "Domaine", sort: url, direction: :asc) { |site| site.domain }' } do %>
|
|
115
|
+
<%= render SilexUi::TableComponent.new(rows: @sites,
|
|
116
|
+
row_class: ->(site) { "bg-alert-50" if site.expired }) do |table| %>
|
|
117
|
+
<% table.with_column(header: "Domaine", sort: "#", direction: :asc) do |site| %>
|
|
118
|
+
<span class="text-ink-900"><%= site.domain %></span>
|
|
119
|
+
<% end %>
|
|
120
|
+
<% table.with_column(header: "Registrar", sort: "#", cell_class: "text-ink-600") do |site| %>
|
|
121
|
+
<%= site.registrar.titleize %>
|
|
122
|
+
<% end %>
|
|
123
|
+
<% table.with_column(header: "État") do |site| %>
|
|
124
|
+
<%= render SilexUi::BadgeComponent.new(label: site.expired ? "expiré" : "actif",
|
|
125
|
+
tone: site.expired ? :alert : :ok) %>
|
|
126
|
+
<% end %>
|
|
127
|
+
<% table.with_column(align: :right) do |site| %>
|
|
128
|
+
<%= render SilexUi::ButtonComponent.new(label: "Éditer", href: "#", variant: :ghost, size: :sm) %>
|
|
129
|
+
<% end %>
|
|
130
|
+
<% end %>
|
|
131
|
+
<% end %>
|
|
132
|
+
|
|
133
|
+
<%= render layout: "silex_ui/catalogue/specimen",
|
|
134
|
+
locals: { title: "Tableau vide", note: "L'état vide remplace le tableau, il ne le décore pas" } do %>
|
|
135
|
+
<%= render SilexUi::TableComponent.new(rows: [], empty_message: "Aucun domaine ne correspond.") do |table| %>
|
|
136
|
+
<% table.with_column(header: "Domaine") { |site| site.domain } %>
|
|
137
|
+
<% end %>
|
|
138
|
+
<% end %>
|
|
139
|
+
|
|
140
|
+
<%= render layout: "silex_ui/catalogue/specimen",
|
|
141
|
+
locals: { title: "Pagination",
|
|
142
|
+
code: 'SilexUi::PaginationComponent.new(pagination: @pagination, page_url: ->(page) { path(page:) })' } do %>
|
|
143
|
+
<%= render SilexUi::PaginationComponent.new(pagination: @pagination, page_url: ->(_page) { "#" }) %>
|
|
144
|
+
<% end %>
|
|
145
|
+
<% end %>
|
|
146
|
+
|
|
147
|
+
<%= render SilexUi::SectionComponent.new(title: "Messages", class: "mt-12") do %>
|
|
148
|
+
<%= render layout: "silex_ui/catalogue/specimen",
|
|
149
|
+
locals: { title: "Bandeaux", code: 'SilexUi::AlertComponent.new(tone: :warn, title: "…", text: "…")' } do %>
|
|
150
|
+
<div class="space-y-3">
|
|
151
|
+
<%= render SilexUi::AlertComponent.new(tone: :info, title: "Synchronisation",
|
|
152
|
+
text: "Le dernier passage remonte à trois heures.") %>
|
|
153
|
+
<%= render SilexUi::AlertComponent.new(tone: :warn, title: "Registrar muet",
|
|
154
|
+
text: "OVH n'a pas répondu au dernier passage ; les dates d'expiration datent d'hier.") %>
|
|
155
|
+
<%= render SilexUi::AlertComponent.new(tone: :alert, title: "Jeton refusé",
|
|
156
|
+
text: "La clé NETIM a expiré, plus aucune disponibilité n'est vérifiée.") %>
|
|
157
|
+
<%= render SilexUi::AlertComponent.new(tone: :ok, text: "Catalogue à jour.") %>
|
|
158
|
+
</div>
|
|
159
|
+
<% end %>
|
|
160
|
+
|
|
161
|
+
<%= render layout: "silex_ui/catalogue/specimen",
|
|
162
|
+
locals: { title: "État vide", code: 'SilexUi::EmptyStateComponent.new(message: "…")' } do %>
|
|
163
|
+
<%= render SilexUi::EmptyStateComponent.new(message: "Rien à afficher pour le moment.") do %>
|
|
164
|
+
<%= render SilexUi::ButtonComponent.new(label: "Ajouter le premier", href: "#", variant: :secondary) %>
|
|
165
|
+
<% end %>
|
|
166
|
+
<% end %>
|
|
167
|
+
<% end %>
|
|
168
|
+
|
|
169
|
+
<%= render SilexUi::SectionComponent.new(title: "Surfaces", class: "mt-12") do %>
|
|
170
|
+
<%= render layout: "silex_ui/catalogue/specimen",
|
|
171
|
+
locals: { title: "Cartes", code: 'SilexUi::CardComponent.new(title: "…", href: "…")' } do %>
|
|
172
|
+
<div class="grid gap-4 md:grid-cols-3">
|
|
173
|
+
<%= render SilexUi::CardComponent.new(title: "Simple") do %>
|
|
174
|
+
Une surface blanche sur le sable, pour ce qui doit se détacher du flux.
|
|
175
|
+
<% end %>
|
|
176
|
+
|
|
177
|
+
<%= render SilexUi::CardComponent.new(title: "Avec pied") do |card| %>
|
|
178
|
+
<% card.with_footer do %>Dernière synchro il y a 3 h<% end %>
|
|
179
|
+
Le pied porte ce qui date ou qualifie le contenu.
|
|
180
|
+
<% end %>
|
|
181
|
+
|
|
182
|
+
<%= render SilexUi::CardComponent.new(title: "Cliquable", href: "#") do %>
|
|
183
|
+
Toute la carte devient la cible, pas seulement son titre.
|
|
184
|
+
<% end %>
|
|
185
|
+
</div>
|
|
186
|
+
<% end %>
|
|
187
|
+
|
|
188
|
+
<%= render layout: "silex_ui/catalogue/specimen",
|
|
189
|
+
locals: { title: "Modale", note: "Bâtie sur <dialog> : focus, Échap et fond inerte gérés par le navigateur" } do %>
|
|
190
|
+
<%= render SilexUi::ModalComponent.new(id: "catalogue-modal", title: "Supprimer le domaine ?") do |modal| %>
|
|
191
|
+
<% modal.with_trigger do %>
|
|
192
|
+
<%= render SilexUi::ButtonComponent.new(label: "Ouvrir la modale", variant: :secondary) %>
|
|
193
|
+
<% end %>
|
|
194
|
+
|
|
195
|
+
<p>Cette action est définitive. Le domaine sortira du catalogue et de toutes ses répartitions.</p>
|
|
196
|
+
|
|
197
|
+
<% modal.with_footer do %>
|
|
198
|
+
<%= render SilexUi::ButtonComponent.new(label: "Annuler", variant: :ghost,
|
|
199
|
+
data: { action: "silex-ui--modal#close" }) %>
|
|
200
|
+
<%= render SilexUi::ButtonComponent.new(label: "Supprimer", variant: :danger) %>
|
|
201
|
+
<% end %>
|
|
202
|
+
<% end %>
|
|
203
|
+
<% end %>
|
|
204
|
+
<% end %>
|
|
205
|
+
|
|
206
|
+
<%= render SilexUi::SectionComponent.new(title: "Formulaires", class: "mt-12") do %>
|
|
207
|
+
<%= form_with url: "#", method: :get do |f| %>
|
|
208
|
+
<%= render layout: "silex_ui/catalogue/specimen",
|
|
209
|
+
locals: { title: "Champs", note: "Deux densités : md pour les barres de filtres, lg pour les pages de formulaire",
|
|
210
|
+
code: 'SilexUi::FieldComponent.new(form: f, attribute: :domain, label: "Domaine", size: :lg)' } do %>
|
|
211
|
+
<div class="grid max-w-2xl gap-5 md:grid-cols-2">
|
|
212
|
+
<%= render SilexUi::FieldComponent.new(form: f, attribute: :domain, label: "Domaine", size: :lg,
|
|
213
|
+
input_html: { placeholder: "exemple.fr" }) %>
|
|
214
|
+
<%= render SilexUi::FieldComponent.new(form: f, attribute: :registrar, label: "Registrar", size: :lg,
|
|
215
|
+
type: :select, collection: %w[OVH Netim Gandi], include_blank: "—") %>
|
|
216
|
+
<%= render SilexUi::FieldComponent.new(form: f, attribute: :expires_at, label: "Expiration",
|
|
217
|
+
type: :date, hint: "Densité md, celle des barres de filtres") %>
|
|
218
|
+
<%= render SilexUi::FieldComponent.new(form: f, attribute: :active, label: "Rattaché à une lune",
|
|
219
|
+
type: :boolean) %>
|
|
220
|
+
<%= render SilexUi::FieldComponent.new(form: f, attribute: :notes, label: "Notes", size: :lg,
|
|
221
|
+
type: :textarea, input_html: { rows: 2 }, class: "md:col-span-2") %>
|
|
222
|
+
</div>
|
|
223
|
+
<% end %>
|
|
224
|
+
<% end %>
|
|
225
|
+
<% end %>
|
|
226
|
+
|
|
227
|
+
<%= render SilexUi::SectionComponent.new(title: "Navigation", class: "mt-12") do %>
|
|
228
|
+
<%= render layout: "silex_ui/catalogue/specimen",
|
|
229
|
+
locals: { title: "Barre de navigation", code: 'nav.with_item(label: "Sites", href: path, active: true)' } do %>
|
|
230
|
+
<%= render SilexUi::NavComponent.new(brand: "Network", brand_href: "#") do |nav| %>
|
|
231
|
+
<% nav.with_item label: "Tableau de bord", href: "#", active: true %>
|
|
232
|
+
<% nav.with_item label: "Sites", href: "#" %>
|
|
233
|
+
<% nav.with_item label: "Réglages", href: "#" %>
|
|
234
|
+
<% nav.with_aside do %>
|
|
235
|
+
<span>theo@le-silex.com</span>
|
|
236
|
+
<%= render SilexUi::ButtonComponent.new(label: "Déconnexion", variant: :ghost, size: :sm) %>
|
|
237
|
+
<% end %>
|
|
238
|
+
<% end %>
|
|
239
|
+
<% end %>
|
|
240
|
+
|
|
241
|
+
<%= render layout: "silex_ui/catalogue/specimen",
|
|
242
|
+
locals: { title: "En-tête de page", code: 'SilexUi::PageHeaderComponent.new(title: "Sites", subtitle: "…")' } do %>
|
|
243
|
+
<%= render SilexUi::PageHeaderComponent.new(title: "Sites", subtitle: "1 240 domaines",
|
|
244
|
+
document_title: false, class: "py-0") do |header| %>
|
|
245
|
+
<% header.with_actions do %>
|
|
246
|
+
<%= render SilexUi::ButtonComponent.new(label: "Ajouter un domaine", href: "#") %>
|
|
247
|
+
<% end %>
|
|
248
|
+
<% end %>
|
|
249
|
+
<% end %>
|
|
250
|
+
<% end %>
|
|
251
|
+
</div>
|
data/config/routes.rb
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
SilexUi::Engine.routes.draw do
|
|
4
|
+
# Chemin complet du contrôleur : le moteur n'isole pas son espace de noms, il
|
|
5
|
+
# n'expose qu'une page et n'a aucune raison de cloisonner les helpers de l'app.
|
|
6
|
+
root to: "silex_ui/catalogue#show"
|
|
7
|
+
end
|
data/lib/silex_ui/version.rb
CHANGED
data/lib/silex_ui.rb
CHANGED
|
@@ -11,9 +11,38 @@ require "silex_ui/engine" if defined?(Rails::Engine)
|
|
|
11
11
|
module SilexUi
|
|
12
12
|
# Répertoires dont le contenu doit être visible du scanner Tailwind de
|
|
13
13
|
# l'application hôte. `rails silex_ui:sync` recopie ces sources dans l'app.
|
|
14
|
-
|
|
14
|
+
# `app/views` en fait partie pour le catalogue : ses nuanciers utilisent des
|
|
15
|
+
# classes qu'aucun composant n'emploie, et sans elles la page se rend nue.
|
|
16
|
+
SOURCE_DIRECTORIES = %w[app/components app/views app/assets/javascripts].freeze
|
|
17
|
+
|
|
18
|
+
# Réglages de l'application hôte. Les valeurs par défaut conviennent à une
|
|
19
|
+
# application Rails + Tailwind ordinaire ; on n'y touche que si le layout de
|
|
20
|
+
# l'application exige une session, ou pour ouvrir le catalogue hors dev.
|
|
21
|
+
class Configuration
|
|
22
|
+
attr_accessor :catalogue_layout
|
|
23
|
+
attr_writer :catalogue_enabled
|
|
24
|
+
|
|
25
|
+
def initialize
|
|
26
|
+
@catalogue_layout = "application"
|
|
27
|
+
@catalogue_enabled = nil
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def catalogue_enabled?
|
|
31
|
+
return @catalogue_enabled unless @catalogue_enabled.nil?
|
|
32
|
+
|
|
33
|
+
defined?(Rails) && Rails.env.development?
|
|
34
|
+
end
|
|
35
|
+
end
|
|
15
36
|
|
|
16
37
|
class << self
|
|
38
|
+
def configuration
|
|
39
|
+
@configuration ||= Configuration.new
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def configure
|
|
43
|
+
yield configuration
|
|
44
|
+
end
|
|
45
|
+
|
|
17
46
|
def root
|
|
18
47
|
@root ||= Pathname.new(File.expand_path("..", __dir__))
|
|
19
48
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: silex_ui
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Théo Galais
|
|
@@ -95,7 +95,11 @@ files:
|
|
|
95
95
|
- app/components/silex_ui/stat_grid_component.rb
|
|
96
96
|
- app/components/silex_ui/table_component.html.erb
|
|
97
97
|
- app/components/silex_ui/table_component.rb
|
|
98
|
+
- app/controllers/silex_ui/catalogue_controller.rb
|
|
99
|
+
- app/views/silex_ui/catalogue/_specimen.html.erb
|
|
100
|
+
- app/views/silex_ui/catalogue/show.html.erb
|
|
98
101
|
- config/importmap.rb
|
|
102
|
+
- config/routes.rb
|
|
99
103
|
- lib/generators/silex_ui/install/install_generator.rb
|
|
100
104
|
- lib/silex_ui.rb
|
|
101
105
|
- lib/silex_ui/engine.rb
|