投稿画面のモーダル化
This commit is contained in:
parent
e7bee77eea
commit
6dd33e849b
13 changed files with 122 additions and 83 deletions
app
|
@ -14,3 +14,30 @@
|
|||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
.modal {
|
||||
display: none;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
z-index: 1000;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.modal-dialog {
|
||||
position: relative;
|
||||
margin: 1.75rem auto;
|
||||
max-width: 500px;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
position: relative;
|
||||
background-color: #fff;
|
||||
border-radius: 0.5rem;
|
||||
padding: 1rem;
|
||||
margin: 2rem;
|
||||
}
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
import { application } from "./application";
|
||||
import SearchController from "./search_controller";
|
||||
import MemoCardController from "./memo_card_controller";
|
||||
import MemoFormController from "./memo_form_controller";
|
||||
// This file is auto-generated by ./bin/rails stimulus:manifest:update
|
||||
// Run that command whenever you add a new controller or create them with
|
||||
// ./bin/rails generate stimulus controllerName
|
||||
|
||||
import { application } from "./application";
|
||||
|
||||
import ModalController from "./modal_controller";
|
||||
application.register("modal", ModalController);
|
||||
|
||||
import SearchController from "./search_controller";
|
||||
application.register("search", SearchController);
|
||||
application.register("memo_card", MemoCardController);
|
||||
application.register("memo_form", MemoFormController);
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
import { Controller } from "@hotwired/stimulus";
|
||||
|
||||
export default class extends Controller {
|
||||
connect() {
|
||||
this.element.classList.add("opacity-0");
|
||||
this.element.classList.add("translate-y-4");
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
this.element.classList.remove("opacity-0");
|
||||
this.element.classList.remove("translate-y-4");
|
||||
this.element.classList.add("transition-all");
|
||||
this.element.classList.add("duration-300");
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
import { Controller } from "@hotwired/stimulus";
|
||||
|
||||
export default class extends Controller {
|
||||
static targets = ["textarea"];
|
||||
|
||||
connect() {
|
||||
if (this.hasTextareaTarget) {
|
||||
this.textareaTarget.focus();
|
||||
}
|
||||
}
|
||||
}
|
24
app/javascript/controllers/modal_controller.js
Normal file
24
app/javascript/controllers/modal_controller.js
Normal file
|
@ -0,0 +1,24 @@
|
|||
import { Controller } from "@hotwired/stimulus";
|
||||
|
||||
export default class extends Controller {
|
||||
connect() {
|
||||
this.element.style.display = "none";
|
||||
}
|
||||
|
||||
open() {
|
||||
this.element.style.display = "block";
|
||||
}
|
||||
|
||||
close() {
|
||||
this.element.style.display = "none";
|
||||
const frame = document.getElementById("modal");
|
||||
frame.removeAttribute("src");
|
||||
frame.innerHTML = "";
|
||||
}
|
||||
|
||||
clickOutside(event) {
|
||||
if (event.target === this.element) {
|
||||
this.close();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,33 +3,42 @@
|
|||
<head>
|
||||
<title>rails8-memoapp</title>
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<meta name="turbo-cache-control" content="no-cache">
|
||||
<%= csrf_meta_tags %>
|
||||
<%= csp_meta_tag %>
|
||||
<%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
|
||||
<%= stylesheet_link_tag "tailwind", "data-turbo-track": "reload" %>
|
||||
<%= javascript_include_tag "application", "data-turbo-track": "reload", type: "module", as: "script" %>
|
||||
</head>
|
||||
|
||||
<% if current_user %>
|
||||
<div class="fixed top-4 left-4 text-sm text-gray-600 bg-gray-100 px-3 py-1 rounded-full">
|
||||
<%= current_user.email %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<body class="bg-gray-50">
|
||||
<% if user_signed_in? %>
|
||||
<div class="fixed top-4 right-4">
|
||||
<%= button_to destroy_user_session_path,
|
||||
method: :delete,
|
||||
class: "bg-gray-500 hover:bg-gray-600 text-white font-bold py-2 px-4 rounded-lg transition-colors duration-200" do %>
|
||||
退出
|
||||
<% end %>
|
||||
<% if current_user %>
|
||||
<div class="fixed top-4 left-4 text-sm text-gray-600 bg-gray-100 px-3 py-1 rounded-full">
|
||||
<%= current_user.email %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<% if user_signed_in? %>
|
||||
<div class="fixed top-4 right-4">
|
||||
<%= button_to destroy_user_session_path,
|
||||
method: :delete,
|
||||
class: "bg-gray-500 hover:bg-gray-600 text-white font-bold py-2 px-4 rounded-lg transition-colors duration-200" do %>
|
||||
退出
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<div class="max-w-2xl mx-auto px-4">
|
||||
<%= yield %>
|
||||
</div>
|
||||
<div class="modal"
|
||||
tabindex="-1"
|
||||
data-controller="modal"
|
||||
data-action="click->modal#clickOutside turbo:frame-load->modal#open turbo:submit-end->modal#close">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<%= turbo_frame_tag "modal" %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<div class="max-w-2xl mx-auto px-4">
|
||||
<%= yield %>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
<div class="space-y-6">
|
||||
<%= turbo_frame_tag "modal" do %>
|
||||
<div class="space-y-6">
|
||||
<%= form_with(model: memo,
|
||||
class: "space-y-6",
|
||||
data: { turbo: false }) do |f| %>
|
||||
data: { turbo: true }) do |f| %>
|
||||
<% if memo.errors.any? %>
|
||||
<div class="bg-red-50 p-4 rounded-md">
|
||||
<div class="text-red-700">
|
||||
|
@ -14,7 +15,6 @@
|
|||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<div>
|
||||
<%= f.text_area :content,
|
||||
class: "w-full h-64 p-4 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500",
|
||||
|
@ -27,12 +27,16 @@
|
|||
<p class="mt-2 text-sm text-gray-500">現在の画像: <%= memo.image.filename %></p>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-4 items-center">
|
||||
<%= f.submit memo.new_record? ? "出力" : "修正",
|
||||
class: "bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded" %>
|
||||
<%= link_to "終了", memos_path,
|
||||
class: "bg-gray-500 hover:bg-gray-700 text-white font-bold py-2 px-4 rounded" %>
|
||||
class: "bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded" %>
|
||||
<%= link_to "終了", "#",
|
||||
class: "bg-gray-500 hover:bg-gray-700 text-white font-bold py-2 px-4 rounded",
|
||||
data: {
|
||||
action: "modal#close",
|
||||
turbo_frame: "modal"
|
||||
} %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
<%= turbo_frame_tag dom_id(memo) do %>
|
||||
<div data-controller="memo-card"
|
||||
class="relative bg-white p-6 rounded-lg shadow-md hover:shadow-lg transition-all duration-200 transform hover:-translate-y-1">
|
||||
<%= link_to edit_memo_path(memo), class: "h-full flex flex-col", data: { turbo_frame: "_top" } do %>
|
||||
<div class="relative bg-white p-6 rounded-lg shadow-md hover:shadow-lg transition-all duration-200 transform hover:-translate-y-1">
|
||||
<%= link_to edit_memo_path(memo), class: "h-full flex flex-col", data: { turbo_frame: "modal" } do %>
|
||||
<h2 class="text-xl font-semibold text-gray-800 mb-2 line-clamp-2">
|
||||
<%= memo.content.lines.first.try(:strip) || "無題" %>
|
||||
</h2>
|
||||
|
@ -19,7 +18,6 @@
|
|||
</span>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<div class="absolute top-4 right-4">
|
||||
<%= button_to memo_path(memo),
|
||||
method: :delete,
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
<turbo-stream action="redirect" url="<%= memos_path %>"></turbo-stream>
|
|
@ -1,4 +1,5 @@
|
|||
<div class="max-w-2xl mx-auto">
|
||||
<h1 class="text-2xl font-bold text-gray-900 mb-6">修正</h1>
|
||||
<%= render 'form', memo: @memo %>
|
||||
</div>
|
||||
<%= turbo_frame_tag "modal" do %>
|
||||
<div class="modal-body">
|
||||
<%= render "form", memo: @memo %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
|
|
@ -8,20 +8,20 @@
|
|||
data: { action: "input->search#search" } %>
|
||||
</div>
|
||||
<% end %>
|
||||
<%= link_to new_memo_path, class: "bg-blue-500 hover:bg-blue-600 text-white font-bold py-2 px-4 rounded-lg transition-colors duration-200" do %>
|
||||
<span class="flex items-center">
|
||||
+ 出力開始
|
||||
</span>
|
||||
<% end %>
|
||||
<%= link_to new_memo_path,
|
||||
class: "bg-blue-500 hover:bg-blue-600 text-white font-bold py-2 px-4 rounded-lg transition-colors duration-200",
|
||||
data: { turbo_frame: "modal" } do %>
|
||||
<span class="flex items-center">
|
||||
+ 出力開始
|
||||
</span>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<%= turbo_frame_tag "memos" do %>
|
||||
<%= turbo_frame_tag "memos", data: { turbo_action: :advance } do %>
|
||||
<div id="memos-container" class="flex flex-col gap-4">
|
||||
<%= render @memos %>
|
||||
<%= render "empty_results", query: @q&.content_cont if @memos.empty? %>
|
||||
</div>
|
||||
|
||||
<div class="text-center mt-8">
|
||||
<%= link_to_next_page @memos, "気力十分😤",
|
||||
class: "inline-flex items-center px-4 py-2 bg-blue-500 hover:bg-blue-600 text-white font-medium rounded-lg transition-colors duration-200",
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<div class="max-w-2xl mx-auto">
|
||||
<h1 class="text-2xl font-bold text-gray-900 mb-6">出力</h1>
|
||||
<%= render 'form', memo: @memo %>
|
||||
</div>
|
||||
<%= turbo_frame_tag "modal" do %>
|
||||
<div class="modal-body">
|
||||
<%= render "form", memo: @memo %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
<turbo-stream action="redirect" url="<%= memos_path %>"></turbo-stream>
|
Loading…
Reference in a new issue