turbo_material 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +247 -0
- data/Rakefile +8 -0
- data/app/assets/config/turbo_material_manifest.js +3 -0
- data/app/assets/dist/turbo_material/tailwind.css +1 -0
- data/app/assets/javascripts/turbo_material/material_checkbox_controller.js +12 -0
- data/app/assets/javascripts/turbo_material/material_chips_input_controller.js +140 -0
- data/app/assets/javascripts/turbo_material/material_chips_select_controller.js +111 -0
- data/app/assets/javascripts/turbo_material/material_dialog_controller.js +27 -0
- data/app/assets/javascripts/turbo_material/material_input_controller.js +10 -0
- data/app/assets/javascripts/turbo_material/material_list_controller.js +57 -0
- data/app/assets/javascripts/turbo_material/material_menu_surface_controller.js +11 -0
- data/app/assets/javascripts/turbo_material/material_radio_controller.js +10 -0
- data/app/assets/javascripts/turbo_material/material_ripple_controller.js +10 -0
- data/app/assets/javascripts/turbo_material/material_select_controller.js +10 -0
- data/app/assets/javascripts/turbo_material/material_switch_controller.js +14 -0
- data/app/assets/stylesheets/turbo_material/application.css +15 -0
- data/app/assets/stylesheets/turbo_material/application.tailwind.css +3 -0
- data/app/controllers/turbo_material/application_controller.rb +4 -0
- data/app/helpers/turbo_material/application_helper.rb +7 -0
- data/app/helpers/turbo_material/checkbox_helper.rb +7 -0
- data/app/helpers/turbo_material/chips_input_helper.rb +7 -0
- data/app/helpers/turbo_material/chips_select_helper.rb +7 -0
- data/app/helpers/turbo_material/input_helper.rb +7 -0
- data/app/helpers/turbo_material/modal_helper.rb +7 -0
- data/app/helpers/turbo_material/radio_helper.rb +7 -0
- data/app/helpers/turbo_material/select_helper.rb +7 -0
- data/app/helpers/turbo_material/switch_helper.rb +7 -0
- data/app/helpers/turbo_material/textarea_helper.rb +7 -0
- data/app/jobs/turbo_material/application_job.rb +4 -0
- data/app/mailers/turbo_material/application_mailer.rb +6 -0
- data/app/models/turbo_material/application_record.rb +5 -0
- data/app/views/components/_checkbox.html.erb +25 -0
- data/app/views/components/_chips_input.html.erb +36 -0
- data/app/views/components/_chips_input_options.html.erb +20 -0
- data/app/views/components/_chips_select.html.erb +56 -0
- data/app/views/components/_input.html.erb +32 -0
- data/app/views/components/_modal.html.erb +37 -0
- data/app/views/components/_radio.html.erb +28 -0
- data/app/views/components/_select.html.erb +67 -0
- data/app/views/components/_switch.html.erb +34 -0
- data/app/views/components/_textarea.html.erb +30 -0
- data/app/views/layouts/turbo_material/application.html.erb +21 -0
- data/config/importmap.rb +4 -0
- data/config/routes.rb +2 -0
- data/config/tailwind.config.js +26 -0
- data/lib/tasks/turbo_material_tasks.rake +4 -0
- data/lib/turbo_material/engine.rb +44 -0
- data/lib/turbo_material/version.rb +3 -0
- data/lib/turbo_material.rb +6 -0
- metadata +164 -0
@@ -0,0 +1,27 @@
|
|
1
|
+
import { Controller } from "@hotwired/stimulus";
|
2
|
+
|
3
|
+
export default class extends Controller {
|
4
|
+
dialog = undefined;
|
5
|
+
|
6
|
+
static values = {
|
7
|
+
opened: Boolean
|
8
|
+
}
|
9
|
+
|
10
|
+
connect() {
|
11
|
+
this.dialog = mdc.dialog.MDCDialog.attachTo(this.element);
|
12
|
+
if (this.openedValue) {
|
13
|
+
this.dialog.open();
|
14
|
+
}
|
15
|
+
}
|
16
|
+
|
17
|
+
close() {
|
18
|
+
this.dialog.close();
|
19
|
+
}
|
20
|
+
|
21
|
+
open() {
|
22
|
+
this.dialog.open();
|
23
|
+
}
|
24
|
+
|
25
|
+
disconnect() {
|
26
|
+
}
|
27
|
+
}
|
@@ -0,0 +1,57 @@
|
|
1
|
+
import { Controller } from "@hotwired/stimulus";
|
2
|
+
|
3
|
+
export default class extends Controller {
|
4
|
+
connect() {
|
5
|
+
this.list = mdc.list.MDCList.attachTo(this.element);
|
6
|
+
this.list.listen('MDCList:action', (event) => {
|
7
|
+
this.focusElement(event.detail.index);
|
8
|
+
this.element.dispatchEvent(new CustomEvent('country-select-focus', {
|
9
|
+
bubbles: true,
|
10
|
+
cancelable: true,
|
11
|
+
detail: {
|
12
|
+
index: event.detail.index
|
13
|
+
}
|
14
|
+
}));
|
15
|
+
});
|
16
|
+
}
|
17
|
+
|
18
|
+
selected() {
|
19
|
+
return this.list.listElements[this.list.selectedIndex];
|
20
|
+
}
|
21
|
+
|
22
|
+
focusNext() {
|
23
|
+
if (this.list.selectedIndex === undefined ) {
|
24
|
+
this.list.selectedIndex = 0;
|
25
|
+
} else if (this.list.selectedIndex < this.list.listElements.length - 1) {
|
26
|
+
this.list.selectedIndex++;
|
27
|
+
} else {
|
28
|
+
this.list.selectedIndex = 0;
|
29
|
+
}
|
30
|
+
this.element.querySelector(".mdc-deprecated-list-item--selected").scrollIntoView({
|
31
|
+
behavior: 'smooth'
|
32
|
+
});
|
33
|
+
}
|
34
|
+
|
35
|
+
focusPrevious() {
|
36
|
+
if (this.list.selectedIndex === undefined ) {
|
37
|
+
this.list.selectedIndex = this.list.listElements.length - 1;
|
38
|
+
} else if (this.list.selectedIndex > 0) {
|
39
|
+
this.list.selectedIndex--;
|
40
|
+
} else {
|
41
|
+
this.list.selectedIndex = this.list.listElements.length - 1;
|
42
|
+
}
|
43
|
+
this.element.querySelector(".mdc-deprecated-list-item--selected").scrollIntoView({
|
44
|
+
behavior: 'smooth'
|
45
|
+
});
|
46
|
+
}
|
47
|
+
|
48
|
+
focusElement(index) {
|
49
|
+
this.list.selectedIndex = index;
|
50
|
+
this.element.querySelector(".mdc-deprecated-list-item--selected").scrollIntoView({
|
51
|
+
behavior: 'smooth'
|
52
|
+
});
|
53
|
+
}
|
54
|
+
|
55
|
+
disconnect() {
|
56
|
+
}
|
57
|
+
}
|
@@ -0,0 +1,14 @@
|
|
1
|
+
import { Controller } from "@hotwired/stimulus";
|
2
|
+
|
3
|
+
export default class extends Controller {
|
4
|
+
connect() {
|
5
|
+
const switchControl = mdc.switchControl.MDCSwitch.attachTo(this.element.querySelector('.mdc-switch'));
|
6
|
+
const hidden = this.element.querySelector('input[type=hidden]');
|
7
|
+
switchControl.listen('click', () => {
|
8
|
+
hidden.value = switchControl.selected;
|
9
|
+
});
|
10
|
+
}
|
11
|
+
|
12
|
+
disconnect() {
|
13
|
+
}
|
14
|
+
}
|
@@ -0,0 +1,15 @@
|
|
1
|
+
/*
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
3
|
+
* listed below.
|
4
|
+
*
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
6
|
+
* or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
|
7
|
+
*
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
|
9
|
+
* compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
|
10
|
+
* files in this directory. Styles in this file should be added after the last require_* statement.
|
11
|
+
* It is generally better to create a new file per style scope.
|
12
|
+
*
|
13
|
+
*= require_tree .
|
14
|
+
*= require_self
|
15
|
+
*/
|
@@ -0,0 +1,25 @@
|
|
1
|
+
<%# locals: (form:, disabled: false, name:, label: nil, id:, checked: false, checked_value: '1', unchecked_value: '0', frame: nil, source_override: nil) %>
|
2
|
+
<div class="mdc-form-field" data-controller="material-checkbox">
|
3
|
+
<div class="mdc-checkbox <%= disabled ? 'mdc-checkbox--disabled' : '' %>">
|
4
|
+
<%= form.check_box name.to_sym, {
|
5
|
+
id: id, class: "mdc-checkbox__native-control",
|
6
|
+
disabled: disabled,
|
7
|
+
checked: checked || form&.object&.[](source_override || name.to_sym),
|
8
|
+
data: { frame: frame }.compact
|
9
|
+
}, checked_value, unchecked_value %>
|
10
|
+
<div class="mdc-checkbox__background">
|
11
|
+
<svg class="mdc-checkbox__checkmark"
|
12
|
+
viewBox="0 0 24 24">
|
13
|
+
<path class="mdc-checkbox__checkmark-path"
|
14
|
+
fill="none"
|
15
|
+
d="M1.73,12.91 8.1,19.28 22.79,4.59"/>
|
16
|
+
</svg>
|
17
|
+
<div class="mdc-checkbox__mixedmark"></div>
|
18
|
+
</div>
|
19
|
+
<div class="mdc-checkbox__ripple"></div>
|
20
|
+
<div class="mdc-checkbox__focus-ring"></div>
|
21
|
+
</div>
|
22
|
+
<label for="<%= id %>">
|
23
|
+
<%= label || name.capitalize %>
|
24
|
+
</label>
|
25
|
+
</div>
|
@@ -0,0 +1,36 @@
|
|
1
|
+
<%# locals: (form:, disabled: false, required: false, name:, label: nil, id:, frame: nil, suffix: nil, type: 'text', url: nil, selected: [], options: [], value: nil) %>
|
2
|
+
<%- id = [name, suffix].compact_blank.join('-') -%>
|
3
|
+
<div data-controller="material-chips-input"
|
4
|
+
data-material-chips-input-url-value="<%= url %>"
|
5
|
+
data-material-chips-input-name-value="<%= name %>"
|
6
|
+
data-material-chips-input-material-list-outlet="#<%= "#{id}-list" %>"
|
7
|
+
<% if suffix.present? %>data-material-chips-input-suffix-value="<%= suffix %>"<% end %>
|
8
|
+
data-action="keydown.esc->material-chips-input#close keydown.enter->prevent-default country-select-focus->material-chips-input#confirmSelection"
|
9
|
+
>
|
10
|
+
<label class="mdc-text-field mdc-text-field--filled w-full !h-max !h-full">
|
11
|
+
<span class="mdc-text-field__ripple"></span>
|
12
|
+
<span class="mdc-floating-label !top-6"><%= label %></span>
|
13
|
+
<div class="mdc-chip-set mdc-chip-set--input !pt-8 w-full" role="grid">
|
14
|
+
<%- selected.each do |chip| -%>
|
15
|
+
<div class="mdc-chip">
|
16
|
+
<div class="mdc-chip__text"><%= chip[:label] %></div>
|
17
|
+
<!-- <i class="material-icons mdc-chip__icon mdc-chip__icon--trailing" tabindex="0" role="button">cancel</i>-->
|
18
|
+
</div>
|
19
|
+
<%- end -%>
|
20
|
+
<%= form.hidden_field name.to_sym, value: value, data: { 'material-chips-input-target': 'hidden' } %>
|
21
|
+
<%= form.text_field "#{name}_".to_sym,
|
22
|
+
class: 'mdc-text-field__input', value: value || form&.object&.[](name.to_sym),
|
23
|
+
id: id, 'aria-labelledby' => id + '-label',
|
24
|
+
required: required,
|
25
|
+
disabled: disabled,
|
26
|
+
type: type, autocomplete: "off",
|
27
|
+
data: { 'material-chips-input-target': 'input',
|
28
|
+
action: 'input->material-chips-input#search mousedown->material-chips-input#toggle keydown.down->material-chips-input#focusNext keydown.up->material-chips-input#focusPrevious keydown.enter->material-chips-input#confirmSelection keydown->material-chips-input#open' }
|
29
|
+
%>
|
30
|
+
</div>
|
31
|
+
<span class="mdc-line-ripple"></span>
|
32
|
+
</label>
|
33
|
+
<div class="mdc-menu-surface--anchor">
|
34
|
+
<%= render partial: 'components/chips_input_options', locals: { options: options, suffix: suffix, name: name, label: label } %>
|
35
|
+
</div>
|
36
|
+
</div>
|
@@ -0,0 +1,20 @@
|
|
1
|
+
<%# locals: (suffix:, options: [], label:, name:, opened: 'false') %>
|
2
|
+
<%- id = [name, suffix].compact_blank.join('-') -%>
|
3
|
+
<div id="<%= "#{id}-panel" %>"
|
4
|
+
class="mdc-menu-surface <%= (opened != 'true' || options.size.zero?) ? '' : 'mdc-menu-surface--open' %> !z-100 mdc-menu-surface--fullwidth"
|
5
|
+
data-controller="material-menu-surface"
|
6
|
+
data-material-chips-input-target="panel" data-size="<%= options.size %>">
|
7
|
+
<ul class="mdc-deprecated-list max-h-64 overflow-y-auto"
|
8
|
+
id="<%= "#{id}-list" %>"
|
9
|
+
role="listbox"
|
10
|
+
aria-label="<%= label %>"
|
11
|
+
data-controller="material-list"
|
12
|
+
>
|
13
|
+
<%- options.each_with_index do |option, idx| -%>
|
14
|
+
<li class="mdc-deprecated-list-item" data-value="<%= option[:id] %>" data-name="<%= option[:label] %>" <% if idx.zero? %> tabindex="0"<% end %>>
|
15
|
+
<span class="mdc-deprecated-list-item__ripple"></span>
|
16
|
+
<span class="mdc-deprecated-list-item__text"><%= option[:label] %></span>
|
17
|
+
</li>
|
18
|
+
<%- end -%>
|
19
|
+
</ul>
|
20
|
+
</div>
|
@@ -0,0 +1,56 @@
|
|
1
|
+
<%# locals: (form:, disabled: false, required: false, name:, label: nil, id:, value: nil, url: nil, frame: nil, source_override: nil, options: [], confirmable: false, query_string: nil, modal_name: nil, modal_url: nil, chip_css: nil, fixed: false) %>
|
2
|
+
<div class="mdc-select mdc-select--filled w-full"
|
3
|
+
data-controller="material-chips-select"
|
4
|
+
data-material-chips-select-selected-value="<%= value %>"
|
5
|
+
data-material-chips-select-url-value="<%= url %>"
|
6
|
+
data-material-chips-select-confirmable-value="<%= confirmable %>"
|
7
|
+
data-material-chips-select-query-string-value="<%= query_string %>"
|
8
|
+
data-material-chips-select-modal-name-value="<%= modal_name %>"
|
9
|
+
data-material-chips-select-modal-url-value="<%= modal_url %>"
|
10
|
+
data-material-chips-select-chip-css-value="<%= chip_css %>"
|
11
|
+
>
|
12
|
+
<div class="mdc-select__anchor"
|
13
|
+
role="button"
|
14
|
+
aria-haspopup="listbox"
|
15
|
+
aria-expanded="false"
|
16
|
+
aria-expanded="false"
|
17
|
+
aria-labelledby="<%= id %>-label <%= id %>-selected-text"
|
18
|
+
<% if disabled %>aria-disabled="true"<% end %>
|
19
|
+
<% if required %>aria-required="true"<% end %>
|
20
|
+
>
|
21
|
+
<span class="mdc-select__ripple"></span>
|
22
|
+
<span id="<%= id %>-label" class="mdc-floating-label pb-1"><%= label || name.capitalize %></span>
|
23
|
+
<div class="mdc-chip-set mdc-chip-set--input"></div>
|
24
|
+
<span class="mdc-select__selected-text-container"><span id="<%= id %>-selected-text" class="mdc-select__selected-text !hidden"></span></span>
|
25
|
+
<span class="mdc-select__dropdown-icon">
|
26
|
+
<svg
|
27
|
+
class="mdc-select__dropdown-icon-graphic"
|
28
|
+
viewBox="7 10 10 5" focusable="false">
|
29
|
+
<polygon
|
30
|
+
class="mdc-select__dropdown-icon-inactive"
|
31
|
+
stroke="none"
|
32
|
+
fill-rule="evenodd"
|
33
|
+
points="7 10 12 15 17 10">
|
34
|
+
</polygon>
|
35
|
+
<polygon
|
36
|
+
class="mdc-select__dropdown-icon-active"
|
37
|
+
stroke="none"
|
38
|
+
fill-rule="evenodd"
|
39
|
+
points="7 15 12 10 17 15">
|
40
|
+
</polygon>
|
41
|
+
</svg>
|
42
|
+
</span>
|
43
|
+
<span class="mdc-line-ripple"></span>
|
44
|
+
</div>
|
45
|
+
<%= form.hidden_field name.to_sym, value: value, data: { 'material-chips-select-target': 'hidden' } if form %>
|
46
|
+
<div class="mdc-select__menu mdc-menu mdc-menu-surface <%= fixed ? 'mdc-menu-surface--fixed' : 'mdc-menu-surface--fullwidth' %>">
|
47
|
+
<ul class="mdc-deprecated-list" role="listbox" aria-label="<%= label %> listbox">
|
48
|
+
<% options.each do |option| %>
|
49
|
+
<li class="mdc-deprecated-list-item" aria-selected="false" data-value="<%= option[:value] %>" data-label="<%= option[:label] %>" <% if option[:confirmed].in? [true, false] %>data-confirmed="<%= option[:confirmed] %>"<% end %> role="option">
|
50
|
+
<span class="mdc-deprecated-list-item__ripple"></span>
|
51
|
+
<span class="mdc-deprecated-list-item__text"><%= option[:label] %></span>
|
52
|
+
</li>
|
53
|
+
<% end %>
|
54
|
+
</ul>
|
55
|
+
</div>
|
56
|
+
</div>
|
@@ -0,0 +1,32 @@
|
|
1
|
+
<%# locals: (form:, custom_controller: nil, custom_css: nil, disabled: false, required: false, name:, label: nil, id:, checked: false, frame: nil, provide_hidden: false, value: nil, type: 'text', data: {}, min: nil, max: nil, helper: nil, parent: nil) %>
|
2
|
+
<label class="mdc-text-field mdc-text-field--filled w-full <%= custom_css %>"
|
3
|
+
data-controller="<%= custom_controller || 'material-input' %>" <% if frame %>data-frame="<%= frame %>"<% end %>>
|
4
|
+
<span class="mdc-text-field__ripple"></span>
|
5
|
+
<span class="mdc-floating-label" id="<%= id %>-label">
|
6
|
+
<%= label || name.capitalize %>
|
7
|
+
</span>
|
8
|
+
<%= form.text_field provide_hidden ? "#{name}_".to_sym : name.to_sym,
|
9
|
+
class: 'mdc-text-field__input', value: value || form&.object&.[](name.to_sym),
|
10
|
+
id: id, 'aria-labelledby' => id + '-label',
|
11
|
+
required: required, disabled: disabled,
|
12
|
+
type: type, autocomplete: "off", data: { frame: frame, **(data) }.compact,
|
13
|
+
min: min, max: max
|
14
|
+
%>
|
15
|
+
<span class="mdc-line-ripple"></span>
|
16
|
+
<%- if provide_hidden -%>
|
17
|
+
<%= form.hidden_field name.to_sym, value: value, data: { frame: frame }.compact %>
|
18
|
+
<%- end -%>
|
19
|
+
</label>
|
20
|
+
<div class="mdc-text-field-helper-line">
|
21
|
+
<%- if helper -%>
|
22
|
+
<div class="mdc-text-field-helper-text" aria-hidden="true"><%= helper %></div>
|
23
|
+
<%- end -%>
|
24
|
+
<div class="mdc-text-field-helper-text--validation-msg text-sm text-red-500 hidden jserror">
|
25
|
+
</div>
|
26
|
+
<%- parent&.errors&.[](name.to_sym)&.each do |msg| -%>
|
27
|
+
<div class="mdc-text-field-helper-text--validation-msg text-sm text-red-500"
|
28
|
+
aria-hidden="true">
|
29
|
+
<%= msg %>
|
30
|
+
</div>
|
31
|
+
<%- end -%>
|
32
|
+
</div>
|
@@ -0,0 +1,37 @@
|
|
1
|
+
<%# locals: (title:) %>
|
2
|
+
<turbo-frame id="modal">
|
3
|
+
<div class="mdc-dialog" data-controller="material-dialog" data-material-dialog-opened-value="true">
|
4
|
+
<div class="mdc-dialog__container">
|
5
|
+
<div class="mdc-dialog__surface !min-w-[36rem] !min-h-[14rem]"
|
6
|
+
role="alertdialog"
|
7
|
+
aria-modal="true"
|
8
|
+
aria-labelledby="my-dialog-title"
|
9
|
+
aria-describedby="my-dialog-content">
|
10
|
+
<h2 class="mdc-dialog__title">
|
11
|
+
<div class="flex items-center justify-between">
|
12
|
+
<span><%= title %></span>
|
13
|
+
<button type="button" class="mdc-icon-button mdc-dialog__close" data-mdc-ripple-is-unbounded data-action="click->material-dialog#close">
|
14
|
+
<div class="mdc-icon-button__ripple"></div>
|
15
|
+
<span class="mdc-icon-button__focus-ring"></span>
|
16
|
+
<i class="material-icons !text-white">close</i>
|
17
|
+
</button>
|
18
|
+
</div>
|
19
|
+
</h2>
|
20
|
+
<div class="mdc-dialog__content">
|
21
|
+
Contents
|
22
|
+
</div>
|
23
|
+
<div class="mdc-dialog__actions">
|
24
|
+
<button type="button" class="mdc-button mdc-dialog__button mdc-dialog__close" data-action="click->material-dialog#close">
|
25
|
+
<div class="mdc-button__ripple"></div>
|
26
|
+
<span class="mdc-button__label">Cancel</span>
|
27
|
+
</button>
|
28
|
+
<button type="button" class="mdc-button mdc-dialog__button" data-controller="material-ripple">
|
29
|
+
<div class="mdc-button__ripple"></div>
|
30
|
+
<span class="mdc-button__label">OK</span>
|
31
|
+
</button>
|
32
|
+
</div>
|
33
|
+
</div>
|
34
|
+
</div>
|
35
|
+
<div class="mdc-dialog__scrim"></div>
|
36
|
+
</div>
|
37
|
+
</turbo-frame>
|
@@ -0,0 +1,28 @@
|
|
1
|
+
<%# locals: (form:, disabled: false, required: false, name:, label: nil, id:, checked: false, value: nil, parent: nil) %>
|
2
|
+
<div class="mdc-form-field flex flex-col">
|
3
|
+
<label>
|
4
|
+
<%= label || name.capitalize %>
|
5
|
+
</label>
|
6
|
+
<div class="flex flex-row items-center w-full">
|
7
|
+
<div class="mdc-radio <%= disabled ? 'mdc-radio--disabled' : '' %>" data-controller="material-radio">
|
8
|
+
<%= form.radio_button name.to_sym, 'true', class: 'mdc-radio__native-control', id: id + '-1', checked: value, disabled: disabled %>
|
9
|
+
<div class="mdc-radio__background">
|
10
|
+
<div class="mdc-radio__outer-circle"></div>
|
11
|
+
<div class="mdc-radio__inner-circle"></div>
|
12
|
+
</div>
|
13
|
+
<div class="mdc-radio__ripple"></div>
|
14
|
+
<div class="mdc-radio__focus-ring"></div>
|
15
|
+
</div>
|
16
|
+
<label for="<%= id %>-1">Yes</label>
|
17
|
+
<div class="mdc-radio <%= disabled ? 'mdc-radio--disabled' : '' %>">
|
18
|
+
<%= form.radio_button name.to_sym, 'false', class: 'mdc-radio__native-control', id: id + '-2', checked: !value, disabled: disabled %>
|
19
|
+
<div class="mdc-radio__background">
|
20
|
+
<div class="mdc-radio__outer-circle"></div>
|
21
|
+
<div class="mdc-radio__inner-circle"></div>
|
22
|
+
</div>
|
23
|
+
<div class="mdc-radio__ripple"></div>
|
24
|
+
<div class="mdc-radio__focus-ring"></div>
|
25
|
+
</div>
|
26
|
+
<label for="<%= id %>-2">No</label>
|
27
|
+
</div>
|
28
|
+
</div>
|
@@ -0,0 +1,67 @@
|
|
1
|
+
<%# locals: (form:, disabled: false, required: false, name:, label: nil, id:, checked: false, value: nil, parent: nil, frame: nil, selected_text: nil, fixed: false, options: [], hint: nil, helper: nil) %>
|
2
|
+
<div class="mdc-select mdc-select--filled w-full<%= disabled ? ' mdc-select--disabled' : '' %><%= required ? ' mdc-select--required' : '' %>"
|
3
|
+
data-controller="material-select" <% if frame %> data-frame="<%= frame %>"<% end %> id="<%= id %>">
|
4
|
+
<%= form.hidden_field name.to_sym, value: value %>
|
5
|
+
<div class="mdc-select__anchor"
|
6
|
+
role="button"
|
7
|
+
aria-haspopup="listbox"
|
8
|
+
aria-expanded="false"
|
9
|
+
aria-labelledby="<%= id %>-label <%= id %>-selected-text"
|
10
|
+
<% if disabled %>aria-disabled="true"<% end %>
|
11
|
+
<% if required %>aria-required="true"<% end %>
|
12
|
+
>
|
13
|
+
<span class="mdc-select__ripple"></span>
|
14
|
+
<span id="<%= id %>-label" class="mdc-floating-label"><%= label || name.capitalize %></span>
|
15
|
+
<span class="mdc-select__selected-text-container">
|
16
|
+
<span id="<%= id %>-selected-text" class="mdc-select__selected-text">
|
17
|
+
<%= selected_text || value %>
|
18
|
+
</span>
|
19
|
+
</span>
|
20
|
+
<span class="mdc-select__dropdown-icon">
|
21
|
+
<svg
|
22
|
+
class="mdc-select__dropdown-icon-graphic"
|
23
|
+
viewBox="7 10 10 5" focusable="false">
|
24
|
+
<polygon
|
25
|
+
class="mdc-select__dropdown-icon-inactive"
|
26
|
+
stroke="none"
|
27
|
+
fill-rule="evenodd"
|
28
|
+
points="7 10 12 15 17 10">
|
29
|
+
</polygon>
|
30
|
+
<polygon
|
31
|
+
class="mdc-select__dropdown-icon-active"
|
32
|
+
stroke="none"
|
33
|
+
fill-rule="evenodd"
|
34
|
+
points="7 15 12 10 17 15">
|
35
|
+
</polygon>
|
36
|
+
</svg>
|
37
|
+
</span>
|
38
|
+
<span class="mdc-line-ripple"></span>
|
39
|
+
</div>
|
40
|
+
|
41
|
+
<div class="mdc-select__menu mdc-menu mdc-menu-surface !z-100 <%= fixed ? 'mdc-menu-surface--fixed' : 'mdc-menu-surface--fullwidth' %>" id="<%= id %>-surface">
|
42
|
+
<ul class="mdc-deprecated-list" role="listbox" aria-label="<%= label %> listbox">
|
43
|
+
<% options.each do |option| %>
|
44
|
+
<li class="mdc-deprecated-list-item<%= value == option[:value] ? ' mdc-deprecated-list-item--selected' : '' %>" aria-selected="<%= (value == option[:value]).to_s %>" data-value="<%= option[:value] %>" role="option">
|
45
|
+
<span class="mdc-deprecated-list-item__ripple"></span>
|
46
|
+
<span class="mdc-deprecated-list-item__text"><%= option[:label] %></span>
|
47
|
+
</li>
|
48
|
+
<% end %>
|
49
|
+
</ul>
|
50
|
+
</div>
|
51
|
+
</div>
|
52
|
+
<%- if hint.present? -%>
|
53
|
+
<div class="font-sans text-xs p-2"><%= hint %></div>
|
54
|
+
<%- end -%>
|
55
|
+
<%- if helper.present? || parent&.errors.present? -%>
|
56
|
+
<div class="mdc-text-field-helper-line">
|
57
|
+
<%- if helper -%>
|
58
|
+
<div class="mdc-text-field-helper-text" aria-hidden="true"><%= helper %></div>
|
59
|
+
<%- end -%>
|
60
|
+
<%- parent&.errors&.[](name.to_sym)&.each do |msg| -%>
|
61
|
+
<div class="mdc-text-field-helper-text--validation-msg text-sm text-red-500"
|
62
|
+
aria-hidden="true">
|
63
|
+
<%= msg %>
|
64
|
+
</div>
|
65
|
+
<%- end -%>
|
66
|
+
</div>
|
67
|
+
<%- end -%>
|
@@ -0,0 +1,34 @@
|
|
1
|
+
<%# locals: (form:, disabled: false, name:, label: nil, id:, value: nil, true_label: nil, false_label: nil, frame: nil) %>
|
2
|
+
<div data-controller="material-switch" <% if frame %> data-frame="<%= frame %>"<% end %>>
|
3
|
+
<button id="selected-switch" class="mdc-switch <%= cast_boolean(value) ? 'mdc-switch--selected' : '' %>"
|
4
|
+
type="button" role="switch" aria-checked="<%= cast_boolean(value) ? 'true' : 'false' %>" <% if disabled %>disabled<% end %>>
|
5
|
+
<div class="mdc-switch__track"></div>
|
6
|
+
<div class="mdc-switch__handle-track">
|
7
|
+
<div class="mdc-switch__handle">
|
8
|
+
<div class="mdc-switch__shadow">
|
9
|
+
<div class="mdc-elevation-overlay"></div>
|
10
|
+
</div>
|
11
|
+
<div class="mdc-switch__ripple"></div>
|
12
|
+
<div class="mdc-switch__icons">
|
13
|
+
<svg class="mdc-switch__icon mdc-switch__icon--on" viewBox="0 0 24 24">
|
14
|
+
<path d="M19.69,5.23L8.96,15.96l-4.23-4.23L2.96,13.5l6,6L21.46,7L19.69,5.23z"/>
|
15
|
+
</svg>
|
16
|
+
<svg class="mdc-switch__icon mdc-switch__icon--off" viewBox="0 0 24 24">
|
17
|
+
<path d="M20 13H4v-2h16v2z"/>
|
18
|
+
</svg>
|
19
|
+
</div>
|
20
|
+
</div>
|
21
|
+
</div>
|
22
|
+
<span class="mdc-switch__focus-ring-wrapper">
|
23
|
+
<div class="mdc-switch__focus-ring"></div>
|
24
|
+
</span>
|
25
|
+
</button>
|
26
|
+
<label for="selected-switch">
|
27
|
+
<% if cast_boolean(value) %>
|
28
|
+
<%= true_label || label %>
|
29
|
+
<% else %>
|
30
|
+
<%= false_label || label %>
|
31
|
+
<% end %>
|
32
|
+
</label>
|
33
|
+
<%= form.hidden_field name.to_sym, value: value %>
|
34
|
+
</div>
|