tybo 0.0.1 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (136) hide show
  1. checksums.yaml +4 -4
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +23 -0
  4. data/Rakefile +8 -0
  5. data/app/assets/config/tybo_manifest.js +1 -0
  6. data/app/assets/stylesheets/tybo/application.css +15 -0
  7. data/{lib/app → app}/components/attachment_card_component.html.erb +0 -0
  8. data/{lib/app → app}/components/attachment_card_component.rb +0 -0
  9. data/{lib/app → app}/components/attachments_list_component.html.erb +0 -0
  10. data/{lib/app → app}/components/attachments_list_component.rb +0 -0
  11. data/{lib/app → app}/components/current_user_mini_card_component.html.erb +2 -2
  12. data/{lib/app → app}/components/current_user_mini_card_component.rb +0 -0
  13. data/{lib/app → app}/components/form_component.html.erb +1 -1
  14. data/{lib/app → app}/components/form_component.rb +0 -0
  15. data/{lib/app → app}/components/forms/breadcrumb_component.html.erb +0 -0
  16. data/{lib/app → app}/components/forms/breadcrumb_component.rb +0 -0
  17. data/{lib/app → app}/components/forms/delete_button_component.html.erb +0 -0
  18. data/{lib/app → app}/components/forms/delete_button_component.rb +0 -0
  19. data/{lib/app → app}/components/forms/divider_component.html.erb +0 -0
  20. data/{lib/app → app}/components/forms/divider_component.rb +0 -0
  21. data/{lib/app → app}/components/forms/submit_button_component.html.erb +0 -0
  22. data/{lib/app → app}/components/forms/submit_button_component.rb +0 -0
  23. data/app/components/forms/subtitle_component.html.erb +5 -0
  24. data/{lib/app → app}/components/forms/subtitle_component.rb +0 -0
  25. data/{lib/app → app}/components/forms/title_component.html.erb +0 -0
  26. data/{lib/app → app}/components/forms/title_component.rb +0 -0
  27. data/{lib/app → app}/components/icons/collection_component.html.erb +0 -0
  28. data/{lib/app → app}/components/icons/collection_component.rb +0 -0
  29. data/{lib/app → app}/components/icons/home_component.html.erb +0 -0
  30. data/{lib/app → app}/components/icons/home_component.rb +0 -0
  31. data/{lib/app → app}/components/icons/mic_component.html.erb +0 -0
  32. data/{lib/app → app}/components/icons/mic_component.rb +0 -0
  33. data/{lib/app → app}/components/icons/news_paper_component.html.erb +0 -0
  34. data/{lib/app → app}/components/icons/news_paper_component.rb +0 -0
  35. data/{lib/app → app}/components/icons/office_building_component.html.erb +0 -0
  36. data/{lib/app → app}/components/icons/office_building_component.rb +0 -0
  37. data/{lib/app → app}/components/icons/question_mark_circle_component.html.erb +0 -0
  38. data/{lib/app → app}/components/icons/question_mark_circle_component.rb +0 -0
  39. data/{lib/app → app}/components/icons/trash_component.html.erb +0 -0
  40. data/{lib/app → app}/components/icons/trash_component.rb +0 -0
  41. data/{lib/app → app}/components/icons/users_component.html.erb +0 -0
  42. data/{lib/app → app}/components/icons/users_component.rb +0 -0
  43. data/{lib/app → app}/components/index_component.html.erb +0 -0
  44. data/{lib/app → app}/components/index_component.rb +0 -0
  45. data/app/components/index_header_add_component.html.erb +3 -0
  46. data/{lib/app → app}/components/index_header_add_component.rb +0 -0
  47. data/{lib/app → app}/components/index_header_component.html.erb +0 -0
  48. data/{lib/app → app}/components/index_header_component.rb +0 -0
  49. data/{lib/app → app}/components/input/file_component.html.erb +0 -0
  50. data/{lib/app → app}/components/input/file_component.rb +0 -0
  51. data/{lib/app → app}/components/sidebar_component.html.erb +2 -2
  52. data/{lib/app → app}/components/sidebar_component.rb +0 -0
  53. data/{lib/app → app}/components/sidebar_item_component.html.erb +0 -0
  54. data/{lib/app → app}/components/sidebar_item_component.rb +0 -0
  55. data/{lib/app → app}/components/sign_out_button_component.html.erb +1 -1
  56. data/{lib/app → app}/components/sign_out_button_component.rb +3 -0
  57. data/app/components/tables/active_record_th_component.html.erb +3 -0
  58. data/app/components/tables/active_record_th_component.rb +18 -0
  59. data/{lib/app → app}/components/tables/table_component.html.erb +0 -0
  60. data/{lib/app → app}/components/tables/table_component.rb +0 -0
  61. data/{lib/app → app}/components/tables/tbody_component.html.erb +0 -0
  62. data/{lib/app → app}/components/tables/tbody_component.rb +0 -0
  63. data/{lib/app → app}/components/tables/td_component.html.erb +1 -1
  64. data/{lib/app → app}/components/tables/td_component.rb +0 -0
  65. data/{lib/app → app}/components/tables/th_component.html.erb +0 -0
  66. data/{lib/app → app}/components/tables/th_component.rb +0 -0
  67. data/{lib/app → app}/components/tables/thead_component.html.erb +3 -0
  68. data/{lib/app → app}/components/tables/thead_component.rb +1 -0
  69. data/{lib/app → app}/components/tables/tr_component.html.erb +0 -0
  70. data/{lib/app → app}/components/tables/tr_component.rb +0 -0
  71. data/app/controllers/tybo/application_controller.rb +4 -0
  72. data/app/controllers/tybo/login_controller.rb +8 -0
  73. data/app/helpers/tybo/application_helper.rb +5 -0
  74. data/app/helpers/tybo/flash_helper.rb +12 -0
  75. data/app/jobs/tybo/application_job.rb +4 -0
  76. data/app/mailers/tybo/application_mailer.rb +6 -0
  77. data/app/models/tybo/application_record.rb +5 -0
  78. data/app/views/devise/confirmations/new.html.erb +20 -0
  79. data/app/views/devise/login/home.html.erb +20 -0
  80. data/app/views/devise/mailer/_reset_password_instructions.html.erb +8 -0
  81. data/app/views/devise/mailer/confirmation_instructions.html.erb +5 -0
  82. data/app/views/devise/mailer/email_changed.html.erb +7 -0
  83. data/app/views/devise/mailer/password_change.html.erb +3 -0
  84. data/app/views/devise/mailer/unlock_instructions.html.erb +7 -0
  85. data/app/views/devise/passwords/edit.html.erb +36 -0
  86. data/app/views/devise/passwords/new.html.erb +34 -0
  87. data/app/views/devise/registrations/edit.html.erb +35 -0
  88. data/app/views/devise/registrations/new.html.erb +25 -0
  89. data/app/views/devise/sessions/new.html.erb +50 -0
  90. data/app/views/devise/shared/_devise_errors.html.erb +26 -0
  91. data/app/views/devise/shared/_error_messages.html.erb +15 -0
  92. data/app/views/devise/shared/_links.html.erb +65 -0
  93. data/app/views/devise/unlocks/new.html.erb +19 -0
  94. data/app/views/layouts/_errors.html.erb +22 -0
  95. data/app/views/layouts/_flash.html.erb +24 -0
  96. data/app/views/layouts/devise_admin.html.erb +16 -0
  97. data/app/views/layouts/tybo/application.html.erb +14 -0
  98. data/app/views/login/home.html.erb +19 -0
  99. data/app/views/shared/_pagination.html.erb +36 -0
  100. data/config/initializers/devise.rb +311 -0
  101. data/config/initializers/pagy.rb +246 -0
  102. data/config/initializers/ransack.rb +13 -0
  103. data/config/locales/devise.en.yml +65 -0
  104. data/config/routes.rb +3 -0
  105. data/lib/generators/bo/USAGE +12 -0
  106. data/lib/generators/bo/bo_generator.rb +88 -0
  107. data/lib/generators/bo/templates/_form.html.erb +32 -0
  108. data/lib/generators/bo/templates/_search_bar.html.erb +96 -0
  109. data/lib/generators/bo/templates/_table.html.erb +29 -0
  110. data/lib/generators/bo/templates/controller.rb +66 -0
  111. data/lib/generators/bo/templates/index.html.erb +19 -0
  112. data/lib/generators/bo/templates/item.html.erb +17 -0
  113. data/lib/generators/bo/templates/new.html.erb +1 -0
  114. data/lib/generators/bo/templates/show.html.erb +1 -0
  115. data/lib/generators/bo/utils/files/fr.json +19 -0
  116. data/lib/generators/bo/utils/translations.rb +47 -0
  117. data/lib/generators/bo_namespace/USAGE +11 -0
  118. data/lib/generators/bo_namespace/bo_namespace_generator.rb +50 -0
  119. data/lib/generators/bo_namespace/templates/admin.html.erb +27 -0
  120. data/lib/generators/bo_namespace/templates/admin_controller.rb +7 -0
  121. data/lib/generators/bo_namespace/templates/seeds.rb +9 -0
  122. data/lib/generators/bo_namespace/templates/side_bar.html.erb +4 -0
  123. data/lib/generators/tybo_install/templates/application.tailwind.css +112 -0
  124. data/lib/generators/tybo_install/templates/simple_form_tailwind.rb +147 -0
  125. data/lib/generators/tybo_install/templates/tailwind.config.js +40 -0
  126. data/lib/generators/tybo_install/templates/tom-select.css +458 -0
  127. data/lib/generators/tybo_install/tybo_install_generator.rb +44 -0
  128. data/lib/tybo/engine.rb +19 -0
  129. data/lib/tybo/version.rb +3 -0
  130. data/lib/tybo.rb +4 -43
  131. metadata +186 -89
  132. data/lib/app/components/forms/subtitle_component.html.erb +0 -5
  133. data/lib/app/components/index_header_add_component.html.erb +0 -3
  134. data/lib/app/helpers/application_helper.rb +0 -5
  135. data/lib/app/helpers/flash_helper.rb +0 -16
  136. data/lib/app/javascript/controllers/flash_controller.js +0 -7
@@ -0,0 +1,19 @@
1
+ <%%= render(IndexComponent.new) do |index| %>
2
+ <!-- Header -->
3
+ <%%= index.with_header(
4
+ title: I18n.t('bo.<%= class_name.underscore %>.others').capitalize,
5
+ subtitle: I18n.t('bo.<%= class_name.underscore %>.subtitle').capitalize,
6
+ ) do |header| %>
7
+ <%%= header.with_add_button(path: <%="new_#{options[:namespace]}_#{class_name.underscore}_path" %>) %>
8
+ <%% end %>
9
+
10
+ <!-- Search Bar -->
11
+ <%%= render('search_bar') %>
12
+ <!-- Table -->
13
+ <%%= turbo_frame_tag "<%= class_name.underscore.pluralize %>", class: "shadow overflow-hidden rounded border-b border-gray-200" do %>
14
+ <%%= render('table') %>
15
+ <div class="py-2">
16
+ <%%== render partial: 'shared/pagination', locals: { pagy: @pagy } %>
17
+ </div>
18
+ <%% end %>
19
+ <%% end %>
@@ -0,0 +1,17 @@
1
+ <%%= render(FormComponent.new(item: <%= class_name.underscore %>)) do |form| %>
2
+ <%%
3
+ current_page = if <%= class_name.underscore
4
+ %>.persisted?
5
+ { label: "Détails", path: <%= "#{options[:namespace]}_#{class_name.underscore}_path(#{class_name.underscore})"%> }
6
+ else
7
+ { label: "Nouvelle <%= class_name.underscore %>", path: <%= "new_#{options[:namespace]}_#{class_name.underscore}_path" %> }
8
+ end
9
+ form.with_title(<%= class_name.underscore %>.persisted? ? <%= class_name.underscore %>.<%=bo_model_title(bo_model)%> : 'Nouvelle <%= class_name.underscore %>')
10
+ form.with_breadcrumb([
11
+ { label: I18n.t('bo.<%= class_name.underscore %>.others').capitalize, path: <%= "#{options[:namespace]}_#{class_name.pluralize.underscore}_path"%> },
12
+ current_page
13
+ ])
14
+ %>
15
+ <br>
16
+ <%%= render "form", <%= class_name.underscore %>: @<%= class_name.underscore %> %>
17
+ <%% end %>
@@ -0,0 +1 @@
1
+ <%%= render "<%= class_name.underscore %>", <%= class_name.underscore %>: @<%= class_name.underscore %> %>
@@ -0,0 +1 @@
1
+ <%%= render "<%= class_name.underscore %>", <%= class_name.underscore %>: @<%= class_name.underscore %> %>
@@ -0,0 +1,19 @@
1
+ {
2
+ "id": "identifiant",
3
+ "email": "email",
4
+ "password": "mot de passe",
5
+ "created_at": "date de création",
6
+ "updated_at": "date de modification",
7
+ "title": "titre",
8
+ "content": "contenu",
9
+ "description": "description",
10
+ "name": "nom",
11
+ "position": "position",
12
+ "first_name": "prénom",
13
+ "last_name": "nom",
14
+ "full_name": "nom complet",
15
+ "updated": "modification effectuée",
16
+ "created": "création effectuée",
17
+ "destroyed": "suppression effectuée",
18
+ "filters": "filtres"
19
+ }
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ def create_translations
4
+ %w[en fr].each do |local|
5
+ locale_file = "config/locales/bo.#{local}.yml"
6
+ unless File.exist?(locale_file)
7
+ File.write(locale_file, {
8
+ local => {
9
+ 'bo' => {
10
+ 'filters' => find_existing_translation('filters', local),
11
+ 'record' => {
12
+ 'created' => find_existing_translation('created', local),
13
+ 'updated' => find_existing_translation('updated', local),
14
+ 'destroyed' => find_existing_translation('destroyed', local)
15
+ }
16
+ }
17
+ }
18
+ }.to_yaml)
19
+ end
20
+
21
+ yaml_string = File.open locale_file
22
+ data = YAML.load yaml_string
23
+ data[local]['bo'][file_name.underscore.to_s] = {
24
+ 'one' => find_existing_translation(bo_model.to_s.downcase, local),
25
+ 'others' => find_existing_translation(bo_model.to_s.pluralize.downcase, local),
26
+ 'subtitle' => find_existing_translation("list of #{bo_model.to_s.pluralize.downcase}", local),
27
+ 'attributes' => model_attributes(local)
28
+ }
29
+ output = YAML.dump data
30
+ File.write(locale_file, output)
31
+ end
32
+ end
33
+
34
+ def model_attributes(local)
35
+ hash = {}
36
+ model_columns.each do |col|
37
+ hash[col.to_s] = find_existing_translation(col, local)
38
+ end
39
+ hash
40
+ end
41
+
42
+ def find_existing_translation(col, local)
43
+ return col.to_s.humanize.downcase if local == 'en'
44
+
45
+ json = JSON.parse(File.read("#{__dir__}/files/#{local}.json"))
46
+ json[col.to_s]
47
+ end
@@ -0,0 +1,11 @@
1
+ Description:
2
+ Explain the generator
3
+ Example:
4
+ rails g bo_namespace Employer
5
+ This will create:
6
+ - a models Employer
7
+ - devise routes and namespace `employers`
8
+ - a base controller employer (base controller for this namespace)
9
+ - a controllers employers ( manage employers )
10
+ - a namespace for views
11
+ - a namespace for controllers
@@ -0,0 +1,50 @@
1
+ class BoNamespaceGenerator < Rails::Generators::NamedBase
2
+ source_root File.expand_path("templates", __dir__)
3
+
4
+ def create_bo_namespace_files
5
+ run "bundle exec rails g devise #{file_name.capitalize}"
6
+ run 'bundle exec rails db:migrate'
7
+ create_routes_and_views
8
+ template 'admin.html.erb', File.join('app/views/layouts/', "#{singular_name}.html.erb")
9
+ template 'admin_controller.rb', File.join('app/controllers/', "#{singular_name}_controller.rb")
10
+ template 'seeds.rb', File.join('db/seeds/', "#{plural_name}.rb")
11
+ template 'side_bar.html.erb', File.join('app/views/', "#{plural_name}/layouts/_side_bar.html.erb")
12
+ #remove_devise_registration
13
+ end
14
+
15
+ def create_directories
16
+ ["app/views/#{plural_name}", "app/controllers/#{plural_name}"].each do |dir|
17
+ FileUtils.mkdir(dir) unless File.directory?(dir)
18
+ end
19
+ end
20
+
21
+ def add_seed_file
22
+ inject_into_file 'db/seeds.rb' do
23
+ "require_relative 'seeds/#{plural_name}.rb'\n"
24
+ end
25
+ end
26
+
27
+ private
28
+
29
+ def plural_name
30
+ singular_name.pluralize
31
+ end
32
+
33
+ def singular_name
34
+ file_name.underscore
35
+ end
36
+
37
+ def create_routes_and_views
38
+ run "rails g bo #{singular_name.camelize} --namespace #{plural_name}"
39
+ # devise_route = "devise_for :#{singular_name},\n path: '#{plural_name}',\n controllers: {\n sessions: 'custom_devise/sessions',\n passwords: 'custom_devise/passwords',\n registrations: 'custom_devise/registrations'\n }"
40
+ gsub_file('config/routes.rb', /devise_for :#{plural_name}/, "devise_for :#{plural_name}, path: '#{plural_name}'")
41
+ # route devise_route
42
+ route "# #{plural_name.capitalize}\nnamespace :#{plural_name} do\n root to: '#{plural_name}#index'\n resources :#{plural_name}\nend"
43
+ end
44
+
45
+ def remove_devise_registration
46
+ file = "app/models/#{singular_name}.rb"
47
+ gsub_file(file, / :registerable,/, '')
48
+ end
49
+ end
50
+
@@ -0,0 +1,27 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>BO-<%= class_name %></title>
5
+ <meta name="viewport" content="width=device-width,initial-scale=1">
6
+ <%%= csrf_meta_tags %>
7
+ <%%= csp_meta_tag %>
8
+ <%%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
9
+ <%%= stylesheet_link_tag "tailwind", "inter-font", "data-turbo-track": "reload" %>
10
+ <%%= javascript_importmap_tags %>
11
+ <%%= hotwire_livereload_tags if Rails.env.development? %>
12
+ </head>
13
+
14
+ <body class="h-full bg-home">
15
+ <%% if <%= class_name.underscore %>_signed_in? %>
16
+ <%%= render('<%= class_name.underscore.pluralize %>/layouts/side_bar') %>
17
+ <%% end %>
18
+ <div class="<%%= 'md:pl-64' if <%= class_name.underscore %>_signed_in? %> flex flex-col flex-1">
19
+ <main>
20
+ <div class="py-6">
21
+ <%%= render('layouts/flash') %>
22
+ <%%= yield %>
23
+ </div>
24
+ </main>
25
+ </div>
26
+ </body>
27
+ </html>
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class <%= class_name %>Controller < ApplicationController
4
+ include Pagy::Backend
5
+ layout '<%= class_name.underscore %>'
6
+ before_action :authenticate_<%= class_name.underscore %>!
7
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ if Rails.env.development?
4
+ %w[dev@tymate.com admin@tymate.com michel@tymate.com].each do |email|
5
+ <%= class_name %>.find_or_create_by(
6
+ email:
7
+ ).update!(password: 'password')
8
+ end
9
+ end
@@ -0,0 +1,4 @@
1
+ <%%= render(SidebarComponent.new) do |sidebar| %>
2
+ <%%= sidebar.with_item(path: <%="#{plural_name}_#{plural_name}_path"%>, icon: Icons::UsersComponent, label: I18n.t('bo.<%= singular_name %>.others').capitalize) %>
3
+ <%%= sidebar.with_current_user_card(user: current_<%= singular_name %>) %>
4
+ <%% end %>
@@ -0,0 +1,112 @@
1
+ @tailwind base;
2
+ @tailwind components;
3
+ @tailwind utilities;
4
+ @import 'actiontext.css';
5
+
6
+ /* pagination */
7
+ .pagy-nav,
8
+ .pagy-nav-js {
9
+ @apply flex space-x-2;
10
+ }
11
+
12
+ .pagy-nav .page a,
13
+ .pagy-nav .page.active,
14
+ .pagy-nav .page.prev.disabled,
15
+ .pagy-nav .page.next.disabled,
16
+ .pagy-nav-js .page a,
17
+ .pagy-nav-js .page.active,
18
+ .pagy-nav-js .page.prev.disabled,
19
+ .pagy-nav-js .page.next.disabled {
20
+ @apply block rounded-lg px-3 py-1 text-sm text-indigo-500 font-semibold bg-indigo-200 shadow-md;
21
+
22
+ &:hover {
23
+ @apply bg-indigo-300;
24
+ }
25
+
26
+ &:active {
27
+ @apply bg-indigo-400 text-white;
28
+ }
29
+ }
30
+
31
+ .pagy-nav .page.prev.disabled,
32
+ .pagy-nav .page.next.disabled,
33
+ .pagy-nav-js .page.prev.disabled,
34
+ .pagy-nav-js .page.next.disabled {
35
+ @apply text-indigo-400 cursor-default;
36
+
37
+ &:hover {
38
+ @apply text-indigo-400 bg-indigo-200;
39
+ }
40
+
41
+ &:active {
42
+ @apply text-indigo-400 bg-indigo-200;
43
+ }
44
+ }
45
+
46
+ .pagy-nav .page.active,
47
+ .pagy-nav-js .page.active {
48
+ @apply text-white cursor-default bg-indigo-400;
49
+
50
+ &:hover {
51
+ @apply text-white bg-indigo-400;
52
+ }
53
+
54
+ &:active {
55
+ @apply bg-indigo-400 text-white;
56
+ }
57
+ }
58
+
59
+
60
+ .pagy-combo-nav-js {
61
+ @apply flex max-w-max rounded-full px-3 py-1 text-sm text-indigo-500 font-semibold bg-indigo-200 shadow-md;
62
+ }
63
+
64
+ .pagy-combo-nav-js .pagy-combo-input {
65
+ @apply bg-white px-2 rounded-sm
66
+ }
67
+
68
+ .pagy-combo-nav-js .page.prev,
69
+ .pagy-combo-nav-js .page.next {
70
+ &:hover {
71
+ @apply text-indigo-800;
72
+ }
73
+
74
+ &:active {
75
+ @apply text-indigo-800;
76
+ }
77
+ }
78
+
79
+ .pagy-combo-nav-js .page.prev.disabled,
80
+ .pagy-combo-nav-js .page.next.disabled {
81
+ @apply text-indigo-400 cursor-default;
82
+ }
83
+
84
+ /* tom-select */
85
+ ts-wrapper {
86
+ @apply w-full !ml-0;
87
+ }
88
+
89
+ .ts-control {
90
+ @apply shadow-sm rounded-lg my-5 border-indigo-300 bg-white py-2 px-3 text-base;
91
+ }
92
+
93
+ .ts-dropdown {
94
+ @apply rounded-md border border-solid border-t border-indigo-300 text-base;
95
+ }
96
+
97
+ .ts-dropdown [data-selectable].option:first-child {
98
+ @apply rounded-t-lg;
99
+ }
100
+
101
+ .ts-dropdown [data-selectable].option:last-child {
102
+ @apply rounded-b-lg;
103
+ }
104
+
105
+ .ts-dropdown .create:hover,
106
+ .ts-dropdown .option:hover {
107
+ @apply bg-sky-50 text-sky-900;
108
+ }
109
+
110
+ .ts-dropdown .active {
111
+ @apply bg-indigo-100 text-indigo-900;
112
+ }
@@ -0,0 +1,147 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Use this setup block to configure all options available in SimpleForm.
4
+ SimpleForm.setup do |config|
5
+ # Default class for buttons
6
+ config.button_class = 'my-2 bg-blue-500 hover:bg-blue-700 text-white font-bold text-sm py-2 px-4 rounded'
7
+
8
+ # Define the default class of the input wrapper of the boolean input.
9
+ config.boolean_label_class = ''
10
+
11
+ # How the label text should be generated altogether with the required text.
12
+ config.label_text = ->(label, required, _explicit_label) { "#{label} #{required}" }
13
+
14
+ # Define the way to render check boxes / radio buttons with labels.
15
+ config.boolean_style = :inline
16
+
17
+ # You can wrap each item in a collection of radio/check boxes with a tag
18
+ config.item_wrapper_tag = :div
19
+
20
+ # Defines if the default input wrapper class should be included in radio
21
+ # collection wrappers.
22
+ config.include_default_input_wrapper_class = false
23
+
24
+ # CSS class to add for error notification helper.
25
+ config.error_notification_class = 'text-white px-6 py-4 border-0 rounded relative mb-4 bg-red-400'
26
+
27
+ # Method used to tidy up errors. Specify any Rails Array method.
28
+ # :first lists the first message for each field.
29
+ # :to_sentence to list all errors for each field.
30
+ config.error_method = :to_sentence
31
+
32
+ # add validation classes to `input_field`
33
+ config.input_field_error_class = 'border-red-500'
34
+ config.input_field_valid_class = 'border-green-400'
35
+ config.label_class = 'text-sm font-medium text-gray-600'
36
+
37
+ # vertical forms
38
+ #
39
+ # vertical default_wrapper
40
+ config.wrappers :vertical_form, tag: 'div', class: 'my-5' do |b|
41
+ b.use :html5
42
+ b.use :placeholder
43
+ b.optional :maxlength
44
+ b.optional :minlength
45
+ b.optional :pattern
46
+ b.optional :min_max
47
+ b.optional :readonly
48
+ b.use :label, class: 'block text-sm font-medium text-gray-700', error_class: 'text-red-500'
49
+ b.use :input,
50
+ class: 'mt-1 block w-full border border-gray-300 rounded-md shadow-sm py-2 px-3 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm', error_class: 'border-red-500', valid_class: 'border-green-400'
51
+ b.use :full_error, wrap_with: { tag: 'p', class: 'mt-2 text-red-500 text-xs italic' }
52
+ b.use :hint, wrap_with: { tag: 'p', class: 'mt-2 text-grey-700 text-xs italic' }
53
+ end
54
+
55
+ # vertical input for boolean (aka checkboxes)
56
+ config.wrappers :vertical_boolean, tag: 'div', class: 'mb-4 flex items-start', error_class: '' do |b|
57
+ b.use :html5
58
+ b.optional :readonly
59
+ b.wrapper tag: 'div', class: 'flex items-center h-5' do |ba|
60
+ ba.use :input,
61
+ class: 'focus:ring-2 focus:ring-indigo-500:focus ring-offset-2 h-4 w-4 text-indigo-600 border-gray-300 rounded'
62
+ end
63
+ b.wrapper tag: 'div', class: 'ml-3 text-sm' do |bb|
64
+ bb.use :label, class: 'block', error_class: 'text-red-500'
65
+ bb.use :hint, wrap_with: { tag: 'p', class: 'block text-grey-700 text-xs italic' }
66
+ bb.use :full_error, wrap_with: { tag: 'p', class: 'block text-red-500 text-xs italic' }
67
+ end
68
+ end
69
+
70
+ # vertical input for radio buttons and check boxes
71
+ config.wrappers :vertical_collection, item_wrapper_class: 'flex items-center',
72
+ item_label_class: 'my-1 ml-3 block text-sm font-medium text-gray-400', tag: 'div', class: 'my-4' do |b|
73
+ b.use :html5
74
+ b.optional :readonly
75
+ b.wrapper :legend_tag, tag: 'legend', class: 'text-sm font-medium text-gray-600',
76
+ error_class: 'text-red-500' do |ba|
77
+ ba.use :label_text
78
+ end
79
+ b.use :input,
80
+ class: 'focus:ring-2 focus:ring-indigo-500 ring-offset-2 h-4 w-4 text-indigo-600 border-gray-300 rounded', error_class: 'text-red-500', valid_class: 'text-green-400'
81
+ b.use :full_error, wrap_with: { tag: 'p', class: 'block mt-2 text-red-500 text-xs italic' }
82
+ b.use :hint, wrap_with: { tag: 'p', class: 'mt-2 text-grey-700 text-xs italic' }
83
+ end
84
+
85
+ # vertical file input
86
+ config.wrappers :vertical_file, tag: 'div', class: '' do |b|
87
+ b.use :html5
88
+ b.use :placeholder
89
+ b.optional :maxlength
90
+ b.optional :minlength
91
+ b.optional :readonly
92
+ b.use :label, class: 'text-sm font-medium text-gray-600 block', error_class: 'text-red-500'
93
+ b.use :input, class: 'w-full text-gray-500 px-3 py-2 border rounded', error_class: 'text-red-500 border-red-500',
94
+ valid_class: 'text-green-400'
95
+ b.use :full_error, wrap_with: { tag: 'p', class: 'mt-2 text-red-500 text-xs italic' }
96
+ b.use :hint, wrap_with: { tag: 'p', class: 'mt-2 text-grey-700 text-xs italic' }
97
+ end
98
+
99
+ # vertical multi select
100
+ config.wrappers :vertical_multi_select, tag: 'div', class: 'my-4', error_class: 'f', valid_class: '' do |b|
101
+ b.use :html5
102
+ b.optional :readonly
103
+ b.wrapper :legend_tag, tag: 'legend', class: 'text-sm font-medium text-gray-600',
104
+ error_class: 'text-red-500' do |ba|
105
+ ba.use :label_text
106
+ end
107
+ b.wrapper tag: 'div', class: 'inline-flex space-x-1' do |ba|
108
+ # ba.use :input, class: 'flex w-auto w-auto text-gray-500 text-sm border-gray-300 rounded p-2', error_class: 'text-red-500', valid_class: 'text-green-400'
109
+ ba.use :input,
110
+ class: 'flex w-auto w-auto shadow appearance-none border border-gray-300 rounded w-full p-2 bg-white focus:outline-none focus:border-blue-500 text-gray-400 leading-4 transition-colors duration-200 ease-in-out'
111
+ end
112
+ b.use :full_error, wrap_with: { tag: 'p', class: 'mt-2 text-red-500 text-xs italic' }
113
+ b.use :hint, wrap_with: { tag: 'p', class: 'mt-2 text-grey-700 text-xs italic' }
114
+ end
115
+
116
+ # vertical range input
117
+ config.wrappers :vertical_range, tag: 'div', class: 'my-4', error_class: 'text-red-500',
118
+ valid_class: 'text-green-400' do |b|
119
+ b.use :html5
120
+ b.use :placeholder
121
+ b.optional :readonly
122
+ b.optional :step
123
+ b.use :label, class: 'text-sm font-medium text-gray-600 block', error_class: 'text-red-500'
124
+ b.wrapper tag: 'div', class: 'flex items-center h-5 my-100' do |ba|
125
+ ba.use :input, class: 'rounded-lg overflow-hidden appearance-none bg-gray-400 h-3 w-full text-gray-300',
126
+ error_class: 'text-red-500', valid_class: 'text-green-400'
127
+ end
128
+ b.use :full_error, wrap_with: { tag: 'p', class: 'mt-2 text-red-500 text-xs italic' }
129
+ b.use :hint, wrap_with: { tag: 'p', class: 'mt-2 text-grey-700 text-xs italic' }
130
+ end
131
+
132
+ # The default wrapper to be used by the FormBuilder.
133
+ config.default_wrapper = :vertical_form
134
+
135
+ # Custom wrappers for input types. This should be a hash containing an input
136
+ # type as key and the wrapper that will be used for all inputs with specified type.
137
+ config.wrapper_mappings = {
138
+ boolean: :vertical_boolean,
139
+ check_boxes: :vertical_collection,
140
+ date: :vertical_multi_select,
141
+ datetime: :vertical_multi_select,
142
+ file: :vertical_file,
143
+ radio_buttons: :vertical_collection,
144
+ range: :vertical_range,
145
+ time: :vertical_multi_select
146
+ }
147
+ end
@@ -0,0 +1,40 @@
1
+ const defaultTheme = require('tailwindcss/defaultTheme')
2
+ const execSync = require('child_process').execSync;
3
+ const output = execSync('bundle show tybo', { encoding: 'utf-8' });
4
+
5
+
6
+ module.exports = {
7
+ content: [
8
+ './app/helpers/**/*.rb',
9
+ './app/javascript/**/*.js',
10
+ './app/views/**/*.{erb,haml,html,slim}',
11
+ './app/components/**/*.html.erb',
12
+ output.trim() + '/app/**/*.{erb,haml,html,rb}'
13
+ ],
14
+ theme: {
15
+ extend: {
16
+ fontFamily: {
17
+ sans: ['Inter var', ...defaultTheme.fontFamily.sans],
18
+ },
19
+ colors: {
20
+ sidebar: {
21
+ DEFAULT: '#11072C',
22
+ 50: 'rgba(255, 255, 255, 0.5)',
23
+ 200: 'rgba(255, 255, 255, 0.2)',
24
+ 900: 'rgba(0, 0, 0, 0.2)',
25
+ },
26
+ custom: {
27
+ DEFAULT: '#11072C',
28
+ },
29
+ home: {
30
+ DEFAULT: '#F5F5F5'
31
+ }
32
+ }
33
+ },
34
+ },
35
+ plugins: [
36
+ require('@tailwindcss/forms'),
37
+ require('@tailwindcss/aspect-ratio'),
38
+ require('@tailwindcss/typography'),
39
+ ]
40
+ }