bullet_train-themes-tailwind_css 1.0.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 +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +28 -0
- data/Rakefile +8 -0
- data/app/assets/config/bullet_train_themes_tailwind_css_manifest.js +0 -0
- data/app/views/themes/tailwind_css/attributes/_attempt.html.erb +24 -0
- data/app/views/themes/tailwind_css/fields/_buttons.html.erb +35 -0
- data/app/views/themes/tailwind_css/fields/_cloudinary_image.html.erb +61 -0
- data/app/views/themes/tailwind_css/fields/_color_picker.html.erb +48 -0
- data/app/views/themes/tailwind_css/fields/_date_and_time_field.html.erb +49 -0
- data/app/views/themes/tailwind_css/fields/_date_field.html.erb +31 -0
- data/app/views/themes/tailwind_css/fields/_field.html.erb +79 -0
- data/app/views/themes/tailwind_css/fields/_file_field.html.erb +39 -0
- data/app/views/themes/tailwind_css/fields/_options.html.erb +45 -0
- data/config/routes.rb +2 -0
- data/lib/bullet_train/themes/tailwind_css/engine.rb +10 -0
- data/lib/bullet_train/themes/tailwind_css/path_snitch.rb +9 -0
- data/lib/bullet_train/themes/tailwind_css/version.rb +7 -0
- data/lib/bullet_train/themes/tailwind_css.rb +10 -0
- data/lib/tasks/bullet_train/themes/tailwind_css_tasks.rake +4 -0
- metadata +78 -0
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
File without changes
|
@@ -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 %>"> </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 %>"> </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,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
|
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: []
|