bullet_train-themes-tailwind_css 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 5c566ea84afbb658c67d730da4e7bd56d7974b43054cec8315627b8b0347c73c
4
+ data.tar.gz: 95f4456fe0f50644eed4664d861950e1517d9e0b373de71f26f3977b7d1a6d3d
5
+ SHA512:
6
+ metadata.gz: 03b7499166adc33e60b5feb21cc92db6c2620ccec6a6dd916702e360db56172d7f37574b9b575257cd06307cff4d39e0a016b967e15d56990183363ecfdfd1ef
7
+ data.tar.gz: d2f7740e557dc8f3174bfbc1d37098fb18311b934128ca2b7c3d1566a6258e7448d64b31e349732364be98ed26796c79642c36d897e7c90837d10a45832565d8
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2022 Andrew Culver
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,28 @@
1
+ # BulletTrain::Themes::TailwindCss
2
+ Short description and motivation.
3
+
4
+ ## Usage
5
+ How to use my plugin.
6
+
7
+ ## Installation
8
+ Add this line to your application's Gemfile:
9
+
10
+ ```ruby
11
+ gem "bullet_train-themes-tailwind_css"
12
+ ```
13
+
14
+ And then execute:
15
+ ```bash
16
+ $ bundle
17
+ ```
18
+
19
+ Or install it yourself as:
20
+ ```bash
21
+ $ gem install bullet_train-themes-tailwind_css
22
+ ```
23
+
24
+ ## Contributing
25
+ Contribution directions go here.
26
+
27
+ ## License
28
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require "bundler/setup"
2
+
3
+ APP_RAKEFILE = File.expand_path("test/dummy/Rakefile", __dir__)
4
+ load "rails/tasks/engine.rake"
5
+
6
+ load "rails/tasks/statistics.rake"
7
+
8
+ require "bundler/gem_tasks"
@@ -0,0 +1,24 @@
1
+ <% object ||= current_attributes_object %>
2
+ <% strategy ||= current_attributes_strategy || :none %>
3
+ <% url ||= nil %>
4
+
5
+ <%= render 'shared/attributes/attribute', attribute: attribute, strategy: strategy, url: url do %>
6
+ <span class="inline-block">
7
+ <% if object.send(success_method) %>
8
+ <i class="fal fa-check ti ti-check text-green"></i>
9
+ <% elsif object.send(attempting_method) %>
10
+ <style>
11
+ <% if font_awesome? %>
12
+ @keyframes spinner { 100% { transform:rotate(360deg); } };
13
+ <% else %>
14
+ @keyframes spinner { 100% { transform:rotate(-360deg); } };
15
+ <% end %>
16
+ </style>
17
+ <span class="inline-block" style="animation: spinner 4s linear infinite;">
18
+ <i class="fal fa-sync ti ti-reload"></i>
19
+ </span>
20
+ <% elsif object.send(failure_method) %>
21
+ <i class="fal fa-close ti ti-close text-red"></i>
22
+ <% end %>
23
+ </span>
24
+ <% end %>
@@ -0,0 +1,35 @@
1
+ <% yield %>
2
+
3
+ <%
4
+ stimulus_controller = 'fields--button-toggle'
5
+
6
+ form ||= current_fields_form
7
+ html_options ||= {}
8
+ html_options[:id] ||= id_for(form, method)
9
+ multiple ||= false
10
+ other_options ||= {}
11
+ options ||= options_for(form, method)
12
+ %>
13
+
14
+ <% content = render 'shared/fields/field', form: form, method: method, options: html_options, other_options: other_options do %>
15
+ <% content_for :field do %>
16
+ <div>
17
+ <% options.each do |value, label| %>
18
+ <% checked = form.object.send(method).is_a?(Array) ? form.object.send(method).map(&:to_s).include?(value.to_s) : form.object.send(method).to_s == value.to_s %>
19
+ <label class="btn-toggle" data-controller="<%= stimulus_controller %>">
20
+ <% if multiple %>
21
+ <%= form.check_box method, {multiple: multiple, checked: checked, data: { "#{stimulus_controller}-target": 'shadowField' }}, value, "" %>
22
+ <% else %>
23
+ <%= form.radio_button method, value, { data: { "#{stimulus_controller}-target": 'shadowField' }, checked: checked} %>
24
+ <% end %>
25
+ <button type="button" class="button-alternative mb-1.5 mr-1" data-action="<%= stimulus_controller %>#clickShadowField">
26
+ <%= label %>
27
+ </button>
28
+ </label>
29
+ <% end %>
30
+ </div>
31
+ <% end %>
32
+ <% end %>
33
+
34
+ <%# The `-mb-1.5` is making up for the `mb-1.5` on each of the buttons. This allows them to wrap with appropriate vertical spacing. %>
35
+ <div class="-mb-1.5"><%= content %></div>
@@ -0,0 +1,61 @@
1
+ <% yield %>
2
+
3
+ <% if cloudinary_enabled? %>
4
+
5
+ <%
6
+ stimulus_controller = 'fields--cloudinary-image'
7
+
8
+ form ||= current_fields_form
9
+ options ||= {}
10
+ options[:id] ||= id_for(form, method)
11
+ options[:width] ||= 100
12
+ options[:height] ||= 100
13
+ options[:cloud_name] ||= Cloudinary.config.cloud_name
14
+ options[:api_key] ||= Cloudinary.config.api_key
15
+ options[:google_search_key] ||= ENV['CLOUDINARY_GOOGLE_API_KEY']
16
+ other_options ||= {}
17
+ %>
18
+
19
+ <%
20
+ cloudinary_id = if_present(form.object.send(method))
21
+ preview_image_options = {width: options[:width]&.*(2), height: options[:height]&.*(2), crop: :fill}
22
+ cloudinary_url = cl_image_path(cloudinary_id, preview_image_options) if cloudinary_id
23
+ cloudinary_url_format = cl_image_path('CLOUDINARY_ID', preview_image_options)
24
+ %>
25
+
26
+ <%
27
+ thumbnail_shown_class = 'present'
28
+ wrapper_options = { data: {
29
+ controller: stimulus_controller,
30
+ "#{stimulus_controller}-signatures-url-value": new_account_cloudinary_upload_signature_path,
31
+ "#{stimulus_controller}-height-value": options[:height],
32
+ "#{stimulus_controller}-width-value": options[:width],
33
+ "#{stimulus_controller}-cloud-name-value": options[:cloud_name],
34
+ "#{stimulus_controller}-api-key-value": options[:api_key],
35
+ "#{stimulus_controller}-upload-preset-value": options[:upload_preset],
36
+ "#{stimulus_controller}-url-format-value": cloudinary_url_format,
37
+ "#{stimulus_controller}-thumbnail-shown-class": thumbnail_shown_class,
38
+ }}
39
+ wrapper_options[:data]["#{stimulus_controller}-google-api-key-value"] = options[:google_search_key] unless options[:google_search_key].blank?
40
+ %>
41
+
42
+
43
+ <%= render 'shared/fields/field', form: form, method: method, options: options, other_options: other_options do %>
44
+ <% content_for :field do %>
45
+ <%= content_tag :div, class: 'cloudinary-field', data: wrapper_options[:data] do %>
46
+ <%= form.hidden_field method, data: { "#{stimulus_controller}-target": 'hiddenField' } %>
47
+ <button type="button" class="upload <%= thumbnail_shown_class if cloudinary_url %>"
48
+ data-<%= stimulus_controller %>-target="uploadButton"
49
+ data-action="<%= stimulus_controller %>#pickImageAndUpload"
50
+ >
51
+ <%= image_tag cloudinary_url, width: options[:width], height: options[:height], data: { "#{stimulus_controller}-target": 'thumbnail' } if cloudinary_url %>
52
+ <i class="ti ti-cloud-up"></i>
53
+ </button>
54
+ <button type="button" class="clear" data-action="<%= stimulus_controller %>#clearImage">
55
+ <i class="ti ti-trash"></i>
56
+ </button>
57
+ <% end %>
58
+ <% end %>
59
+ <% end %>
60
+
61
+ <% end %>
@@ -0,0 +1,48 @@
1
+ <% yield %>
2
+
3
+ <%
4
+ stimulus_controller = 'fields--color-picker'
5
+
6
+ form ||= current_fields_form
7
+ html_options ||= {}
8
+ html_options[:id] ||= id_for(form, method)
9
+ multiple ||= false
10
+ other_options ||= {}
11
+ options ||= options_for(form, method)
12
+ value = form.object.color_picker_value
13
+ %>
14
+
15
+ <% content = render 'shared/fields/field', form: form, method: method, options: html_options, other_options: other_options do %>
16
+ <% content_for :field do %>
17
+ <div class="space-x-1" data-controller="<%= stimulus_controller %>" data-<%= stimulus_controller %>-initial-color-value="<%= form.object.color_picker_value %>">
18
+ <%= form.hidden_field method, value: value, data: {"#{stimulus_controller}-target": "colorPickerValue"} %>
19
+ <div class="inline space-x-1" data-<%= stimulus_controller %>-target="colorOptions">
20
+ <% options.each do |color| %>
21
+ <label class="btn-toggle btn-color-picker">
22
+ <button type="button" class="button-color mb-1.5 dark:ring-offset-sealBlue-400 <%= color == value ? 'ring-2 ring-offset-2' : '' %>" style="background-color: <%= color %>; --tw-ring-color: <%= color %>" data-action="<%= stimulus_controller %>#pickColor" data-color="<%= color %>">&nbsp;</button>
23
+ </label>
24
+ <% end %>
25
+ </div>
26
+ <label class="btn-toggle btn-color-picker">
27
+ <button type="button" class="button-color mr-1 dark:ring-offset-sealBlue-400 <%= value.blank? || options.include?(value) ? 'hidden' : 'ring-2 ring-offset-2' %>" data-action="<%= stimulus_controller %>#pickColor" data-<%= stimulus_controller %>-target="userSelectedColor" data-color="<%= value %>" style="background-color: <%= value %>; --tw-ring-color: <%= value %>">&nbsp;</button>
28
+ </label>
29
+ <span class="relative">
30
+ <input type="text" disabled="disabled" class="rounded-md shadow-sm font-light font-mono text-sm focus:ring-blue focus:border-blue border-gray-300 w-48 dark:bg-sealBlue-300 dark:border-sealBlue-100" value="<%= value %>" data-<%= stimulus_controller %>-target="colorInput"/>
31
+ <span class="absolute right-0">
32
+ <button type="button" class="py-2 px-1 border border-transparent inline-flex items-center whitespace-nowrap rounded-md text-lg" data-action="<%= stimulus_controller %>#pickRandomColor">
33
+ <i class="leading-5 ti ti-reload dark:text-blue-500"></i>
34
+ </button>
35
+ <button type="button" class="py-2 px-1 border border-transparent inline-flex items-center whitespace-nowrap rounded-md btn-pickr text-lg" data-action="<%= stimulus_controller %>#togglePickr">
36
+ <i class="leading-5 ti ti-pencil dark:text-blue-500"></i>
37
+ </button>
38
+ <button type="button" class="py-2 px-1 pr-3.5 border border-transparent inline-flex items-center whitespace-nowrap rounded-md text-lg" data-action="<%= stimulus_controller %>#unpickColor">
39
+ <i class="leading-5 ti ti-trash dark:text-blue-500"></i>
40
+ </button>
41
+ </span>
42
+ </span>
43
+ </div>
44
+ <% end %>
45
+ <% end %>
46
+
47
+ <%# The `-mb-1` is making up for the `mb-1` on each of the buttons. This allows them to wrap with appropriate vertical spacing. %>
48
+ <div class="-mb-1.5"><%= content %></div>
@@ -0,0 +1,49 @@
1
+ <% yield %>
2
+
3
+ <%
4
+ form ||= current_fields_form
5
+ options ||= {}
6
+ options[:id] ||= id_for(form, method)
7
+ options[:class] = "form-control single-daterange w-full dark:bg-sealBlue-300 dark:border-sealBlue-100 #{options[:class]}".strip
8
+ options[:value] = form.object.send(method)&.in_time_zone(current_team.time_zone)&.strftime(t('global.formats.date_and_time'))
9
+ options = options.merge({ data: {'fields--date-target': 'field' }})
10
+ other_options ||= {}
11
+ %>
12
+
13
+ <%= render 'shared/fields/field', form: form, method: method, options: options, other_options: other_options do %>
14
+ <% content_for :field do %>
15
+ <div class="date-input relative" data-controller="fields--date" data-fields--date-include-time-value="true" data-fields--date-default-time-zones-value="<%= "[\"#{current_user.current_team.time_zone}\",\"#{current_user.time_zone}\"]" %>">
16
+ <%= form.text_field method, options %>
17
+ <% unless options[:disabled] %>
18
+ <button type="button" class="clear py-2 px-3 border border-transparent inline-flex items-center whitespace-nowrap absolute rounded-md"
19
+ style="top: 2px; right: 2px;"
20
+ data-fields--date-target="clearButton"
21
+ data-action="fields--date#clearDate"
22
+ >
23
+ <i class="leading-4 text-lg ti ti-trash dark:text-blue-500"></i>
24
+ </button>
25
+ <% end %>
26
+ <% if current_user.time_zone != current_user.current_team.time_zone %>
27
+ <div class="mt-1.5 text-xs text-gray-500">
28
+ <%= form.hidden_field "#{method}_time_zone".to_sym, value: current_user.current_team.time_zone, data: {'fields--date-target': 'timeZoneField'} %>
29
+ <div data-fields--date-target="currentTimeZoneWrapper">
30
+ <%= link_to current_user.current_team.time_zone, '#', class: 'button-secondary p-0', data: {action: 'fields--date#showTimeZoneButtons'} %>
31
+ </div>
32
+ <div class="space-x-1 hidden" data-fields--date-target="timeZoneButtons">
33
+ <%= link_to '', '#', hidden: true, class: 'time-zone-button button-alternative button-smaller selected-option-time-zone-button hidden', data: {action: 'fields--date#setTimeZone', value: ''} %>
34
+ <%= link_to current_user.current_team.time_zone, '#', class: 'time-zone-button button button-smaller', data: {action: 'fields--date#setTimeZone', value: current_user.current_team.time_zone} %>
35
+ <%= link_to current_user.time_zone, '#', class: 'time-zone-button button-alternative button-smaller', data: {action: 'fields--date#setTimeZone', value: current_user.time_zone} %>
36
+ <%= link_to t('global.buttons.other'), '#', class: 'button-alternative button-smaller', data: {action: 'fields--date#showTimeZoneSelectWrapper'} %>
37
+ <%= link_to t('global.buttons.cancel'), '#', class: 'button-secondary button-smaller', data: {action: 'fields--date#resetTimeZoneUI'} %>
38
+ </div>
39
+ <div class="hidden flex flex-row items-center mt-3 text-sm" data-fields--date-target="timeZoneSelectWrapper">
40
+ <div class="flex-grow">
41
+ <%= select_tag :time_zone, options_from_collection_for_select(ActiveSupport::TimeZone.all, "name", "to_s", current_user.current_team.time_zone), {class: 'form-control select2'} %>
42
+ </div>
43
+ <%= link_to t('global.buttons.cancel'), '#', class: 'button-secondary ml-1.5', data: {action: 'fields--date#resetTimeZoneUI'} %>
44
+ </div>
45
+ </div>
46
+ <% end %>
47
+ </div>
48
+ <% end %>
49
+ <% end %>
@@ -0,0 +1,31 @@
1
+ <% yield %>
2
+
3
+ <%
4
+ stimulus_controller = 'fields--date'
5
+
6
+ form ||= current_fields_form
7
+ options ||= {}
8
+ options[:id] ||= id_for(form, method)
9
+ options[:class] = "form-control single-daterange w-full border-gray-300 dark:bg-sealBlue-300 dark:border-sealBlue-100 #{options[:class]}".strip
10
+ options[:value] = form.object.send(method)&.strftime(t('global.formats.date'))
11
+ options = options.merge({ data: {"#{stimulus_controller}-target": 'field' }})
12
+ other_options ||= {}
13
+
14
+ %>
15
+
16
+ <%= render 'shared/fields/field', form: form, method: method, options: options, other_options: other_options do %>
17
+ <% content_for :field do %>
18
+ <div class="date-input relative" data-controller="<%= stimulus_controller %>">
19
+ <%= form.text_field method, options %>
20
+ <% unless options[:disabled] %>
21
+ <button type="button" class="clear py-2 px-3 border border-transparent inline-flex items-center whitespace-nowrap absolute rounded-md"
22
+ style="top: 2px; right: 2px;"
23
+ data-<%= stimulus_controller %>-target="clearButton"
24
+ data-action="<%= stimulus_controller %>#clearDate"
25
+ >
26
+ <i class="leading-4 text-lg ti ti-trash dark:text-blue-500"></i>
27
+ </button>
28
+ <% end %>
29
+ </div>
30
+ <% end %>
31
+ <% end %>
@@ -0,0 +1,79 @@
1
+ <% yield %>
2
+
3
+ <%
4
+ form ||= current_fields_form
5
+ # returns a struct with `label`, `placeholder`, and `help` methods.
6
+ labels = labels_for(form, method)
7
+ options ||= {}
8
+ options[:id] ||= id_for(form, method)
9
+ # options[:disabled] ||= !field_editable?(form.object, method) if user_signed_in?
10
+ options[:placeholder] ||= labels.placeholder if labels.placeholder
11
+ other_options ||= {}
12
+ other_options[:help] = [other_options[:help], labels.help].compact.join(" ")
13
+
14
+ errors = [method, method.to_s.gsub(/_id$/, '').to_sym].uniq.map { |attribute| form.object.errors.full_messages_for(attribute) }.flatten
15
+ has_errors = errors.any? || content_for(:error).present? || other_options[:error].present?
16
+
17
+ options[:class] = "#{options[:class]} block w-full rounded-md shadow-sm font-light text-sm"
18
+
19
+ options[:class] += if has_errors
20
+ " pr-10 border-red text-red-darker placeholder-red focus:outline-none focus:ring-red focus:border-red"
21
+ else
22
+ " focus:ring-blue focus:border-blue border-gray-300"
23
+ end
24
+
25
+ %>
26
+
27
+ <div class="<%= 'required' if presence_validated?(form.object, method) %>">
28
+
29
+ <% # the label. %>
30
+ <% unless other_options[:hide_label] == true %>
31
+ <% if content_for? :label %>
32
+ <%= yield :label %>
33
+ <% flush_content_for :label %>
34
+ <% else %>
35
+ <% # allow the label to be defined via an inline option or else one of the locale yaml definitions. %>
36
+ <% label = (other_options[:label].presence || labels.label || legacy_label_for(form, method)) %>
37
+ <%= form.label method, label&.html_safe, class: 'block', for: options[:id] %>
38
+ <% end %>
39
+ <% end %>
40
+
41
+ <div class="mt-1.5">
42
+
43
+ <% # the actual field. %>
44
+ <% if content_for? :field %>
45
+ <%= yield :field %>
46
+ <% flush_content_for :field %>
47
+ <% else %>
48
+ <% # e.g. form.text_field(method, options) %>
49
+ <%= form.send(helper, method, options) %>
50
+ <% end %>
51
+
52
+ </div>
53
+
54
+ <% # any error messages. %>
55
+ <% if has_errors %>
56
+ <p class="mt-1.5 text-xs text-red">
57
+ <%= errors.map { |error| error + ". " }.join %>
58
+ <%= yield :error %>
59
+ <% flush_content_for :error %>
60
+ <%= other_options[:error]&.html_safe %>
61
+ </p>
62
+ <% end %>
63
+
64
+ <% # any help text. %>
65
+ <% if content_for?(:help) || other_options[:help] || content_for?(:after_help) %>
66
+ <p class="mt-1.5 text-xs text-gray-500">
67
+ <%= yield :help %>
68
+ <% flush_content_for :help %>
69
+ <%= other_options[:help]&.html_safe %>
70
+ <%= yield :after_help %>
71
+ <% flush_content_for :after_help %>
72
+ </p>
73
+ <% end %>
74
+
75
+ <% if other_options[:icon] %>
76
+ <div class="pre-icon os-icon <%= other_options[:icon] %>"></div>
77
+ <% end %>
78
+
79
+ </div>
@@ -0,0 +1,39 @@
1
+ <% yield %>
2
+
3
+ <%
4
+ form ||= current_fields_form
5
+ options ||= {}
6
+ other_options ||= {}
7
+ %>
8
+
9
+ <%= render 'shared/fields/field', form: form, method: method, helper: :file_field, options: options, other_options: other_options do %>
10
+ <% content_for :field do %>
11
+ <div class="file-field" data-controller="fields--file-field">
12
+ <%= form.hidden_field "#{method}_removal".to_sym, value: nil, data: {'fields--file-field-target': 'removeFileFlag'} %>
13
+ <%= form.file_field method, class: 'file-upload hidden', direct_upload: true, data: {'fields--file-field-target': 'fileField', action: 'change->fields--file-field#handleFileSelected'} %>
14
+ <div>
15
+ <% if form.object.send(method).attached? %>
16
+ <%= link_to url_for(form.object.send(method)), class: 'button download-file mr-3', data: {'fields--file-field-target': 'downloadFileButton'} do %>
17
+ <i class="leading-none mr-2 text-base ti ti-download"></i>
18
+ <span>Download Current Document</span>
19
+ <% end %>
20
+ <% end %>
21
+ <% if form.object.send(method).attached? %>
22
+ <div class="button-alternative cursor-pointer mr-3" data-action="click->fields--file-field#removeFile" data-fields--file-field-target="removeFileButton">
23
+ <i class="leading-none mr-2 text-base ti ti-trash"></i>
24
+ <span>Remove Current Document</span>
25
+ </div>
26
+ <% end %>
27
+ </div>
28
+ <div class="mt-2">
29
+ <div class="button-alternative cursor-pointer" data-action="click->fields--file-field#uploadFile" data-fields--file-field-target="selectFileButton">
30
+ <i class="leading-none mr-2 text-base ti ti-upload dark:text-white"></i>
31
+ <span class="dark:text-white">Upload New Document</span>
32
+ </div>
33
+ <div class="mt-2 hidden flex overflow-hidden text-xs rounded bg-black-400">
34
+ <div data-fields--file-field-target="progressBar" aria-valuemax="100" aria-valuemin="0" aria-valuenow="0" class="flex flex-col justify-center text-white text-center whitespace-nowrap overflow-hidden bg-sealBlue-300" role="progressbar" style="width: 0%;"> 0%</div>
35
+ </div>
36
+ </div>
37
+ </div>
38
+ <% end %>
39
+ <% end %>
@@ -0,0 +1,45 @@
1
+ <% yield %>
2
+
3
+ <%
4
+ form ||= current_fields_form
5
+ html_options ||= {}
6
+ html_options[:id] ||= id_for(form, method)
7
+ multiple ||= false
8
+ other_options ||= {}
9
+ options ||= options_for(form, method)
10
+ labels = labels_for(form, method)
11
+ %>
12
+
13
+ <%= render 'shared/fields/field', form: form, method: method, options: html_options, other_options: other_options do %>
14
+ <% content_for :field do %>
15
+ <div class="pt-1.5 pb-1 sm:col-span-2">
16
+ <div class="max-w-lg space-y-3">
17
+
18
+ <% options.each do |value, label| %>
19
+
20
+ <label class="relative flex items-start">
21
+ <div class="flex items-center h-5">
22
+
23
+ <% if multiple %>
24
+ <%= form.check_box method, {multiple: multiple, checked: form.object.send(method).map(&:to_s).include?(value.to_s), class: "focus:ring-blue h-4 w-4 text-blue border-gray-300 rounded"}, value, "" %>
25
+ <% else %>
26
+ <%= form.radio_button method, value, {class: "focus:ring-blue h-4 w-4 text-blue border-gray-300"} %>
27
+ <% end %>
28
+
29
+ </div>
30
+ <div class="ml-2.5 text-sm">
31
+ <div class="select-none"><%= label %></div>
32
+ <% if labels.options_help&.dig(value)&.present? %>
33
+ <p class="mt-0.5 text-xs text-gray-500">
34
+ <%= labels.options_help.dig(value) %>
35
+ </p>
36
+ <% end %>
37
+ </div>
38
+ </label>
39
+
40
+ <% end %>
41
+
42
+ </div>
43
+ </div>
44
+ <% end %>
45
+ <% end %>
data/config/routes.rb ADDED
@@ -0,0 +1,2 @@
1
+ Rails.application.routes.draw do
2
+ end
@@ -0,0 +1,10 @@
1
+ require_relative "path_snitch"
2
+
3
+ module BulletTrain
4
+ module Themes
5
+ module TailwindCss
6
+ class Engine < ::Rails::Engine
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,9 @@
1
+ # TODO This is my best attempt at allowing us to figure out where theme partials might be getting served from.
2
+ # We can only inspect the source location of a class (not a module), and this gem has no other classes, so we need this.
3
+ # See https://stackoverflow.com/questions/13012109/get-class-location-from-class-object for context.
4
+ class BulletTrain::Themes::TailwindCss::PathSnitch
5
+ def self.confess
6
+ # This method allows us to call `BulletTrain::Themes::PathSnitch.method(:confess).source_location` and see where
7
+ # this gem is being served from... which allows us to check it's `view/themes` directory for partials.
8
+ end
9
+ end
@@ -0,0 +1,7 @@
1
+ module BulletTrain
2
+ module Themes
3
+ module TailwindCss
4
+ VERSION = "1.0.0"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,10 @@
1
+ require "bullet_train/themes/tailwind_css/version"
2
+ require "bullet_train/themes/tailwind_css/engine"
3
+
4
+ module BulletTrain
5
+ module Themes
6
+ module TailwindCss
7
+ # Your code goes here...
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :bullet_train_themes_tailwind_css do
3
+ # # Task goes here
4
+ # end
metadata ADDED
@@ -0,0 +1,78 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bullet_train-themes-tailwind_css
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Andrew Culver
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-01-24 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 7.0.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 7.0.0
27
+ description: Bullet Train Themes Tailwind CSS Base
28
+ email:
29
+ - andrew.culver@gmail.com
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - MIT-LICENSE
35
+ - README.md
36
+ - Rakefile
37
+ - app/assets/config/bullet_train_themes_tailwind_css_manifest.js
38
+ - app/views/themes/tailwind_css/attributes/_attempt.html.erb
39
+ - app/views/themes/tailwind_css/fields/_buttons.html.erb
40
+ - app/views/themes/tailwind_css/fields/_cloudinary_image.html.erb
41
+ - app/views/themes/tailwind_css/fields/_color_picker.html.erb
42
+ - app/views/themes/tailwind_css/fields/_date_and_time_field.html.erb
43
+ - app/views/themes/tailwind_css/fields/_date_field.html.erb
44
+ - app/views/themes/tailwind_css/fields/_field.html.erb
45
+ - app/views/themes/tailwind_css/fields/_file_field.html.erb
46
+ - app/views/themes/tailwind_css/fields/_options.html.erb
47
+ - config/routes.rb
48
+ - lib/bullet_train/themes/tailwind_css.rb
49
+ - lib/bullet_train/themes/tailwind_css/engine.rb
50
+ - lib/bullet_train/themes/tailwind_css/path_snitch.rb
51
+ - lib/bullet_train/themes/tailwind_css/version.rb
52
+ - lib/tasks/bullet_train/themes/tailwind_css_tasks.rake
53
+ homepage: https://github.com/bullet-train-co/bullet_train-themes-tailwind_css
54
+ licenses:
55
+ - MIT
56
+ metadata:
57
+ homepage_uri: https://github.com/bullet-train-co/bullet_train-themes-tailwind_css
58
+ source_code_uri: https://github.com/bullet-train-co/bullet_train-themes-tailwind_css
59
+ post_install_message:
60
+ rdoc_options: []
61
+ require_paths:
62
+ - lib
63
+ required_ruby_version: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ required_rubygems_version: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: '0'
73
+ requirements: []
74
+ rubygems_version: 3.2.22
75
+ signing_key:
76
+ specification_version: 4
77
+ summary: Bullet Train Themes Tailwind CSS Base
78
+ test_files: []