turbo_material 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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>
|