feat: Use tailwind for generated templates
This commit is contained in:
parent
35e3c6a608
commit
97eabcc875
13 changed files with 177 additions and 96 deletions
|
@ -1,7 +1,7 @@
|
||||||
defmodule Admin.Kaffy.EditorExtension do
|
defmodule Admin.Kaffy.EditorExtension do
|
||||||
def stylesheets(_conn) do
|
def stylesheets(_conn) do
|
||||||
[
|
[
|
||||||
{:safe, ~s(<link rel="stylesheet" href="/js/css/content-editor.css" />)},
|
{:safe, ~s(<link rel="stylesheet" href="/css/content-editor.css" />)},
|
||||||
{:safe, ~s(<link rel="stylesheet" href="/css/app.css" />)},
|
{:safe, ~s(<link rel="stylesheet" href="/css/app.css" />)},
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,18 +1,19 @@
|
||||||
<div class="ui top padded container">
|
<div class="p-6 mx-auto max-w-2xl">
|
||||||
<div class="ui grid">
|
<div class="flex pb-6">
|
||||||
<div class="row">
|
<div class="w-/12 flex-1 text-4xl">
|
||||||
<div class="eight wide column">
|
<h1 class="ui header">Edit <%= schema.human_singular %></h1>
|
||||||
<h1 class="ui header">Edit <%= schema.human_singular %></h1>
|
|
||||||
</div>
|
|
||||||
<div class="eight wide right aligned column">
|
|
||||||
<span><%%= link "Back", to: Routes.<%= schema.route_helper %>_path(@conn, :index), class: "ui button" %></span>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="w-/12 text-4xl text-right">
|
||||||
|
<%%= styled_button_link "Back", to: Routes.<%= schema.route_helper %>_path(@conn, :index)%>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="centered row">
|
<div class="centered row">
|
||||||
<div class="center aligned column">
|
<div class="center aligned column">
|
||||||
<%%= changeset_error_block(@changeset) %>
|
<%%= changeset_error_block(@changeset) %>
|
||||||
<%%= render "form.html", Map.put(assigns, :action, Routes.<%= schema.route_helper %>_path(@conn, :update, @<%= schema.singular %>)) %>
|
<div class="bg-white shadow rounded px-4 py-6 bg-gray-300">
|
||||||
|
<%%= render "form.html", Map.put(assigns, :action, Routes.<%= schema.route_helper %>_path(@conn, :update, @<%= schema.singular %>)) %>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<%= input %>
|
<%= input %>
|
||||||
<% end %>
|
<% end %>
|
||||||
<div>
|
<div>
|
||||||
<%%= submit "Save", class: "ui primary fluid large submit button" %>
|
<%%= styled_button "Save" %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<%% end %>
|
<%% end %>
|
||||||
|
|
|
@ -1,46 +1,52 @@
|
||||||
<div class="ui top padded container">
|
<div class="p-6">
|
||||||
<div class="ui grid">
|
<div class="flex pb-6">
|
||||||
<div class="row">
|
<div class="w-/12 flex-1 text-4xl">
|
||||||
<div class="eight wide column">
|
<h1 class="px-5 -mb-2 mt-2"><%= schema.human_plural %></h1>
|
||||||
<h1 class="ui header"><%= schema.human_plural %></h1>
|
</div>
|
||||||
</div>
|
<div class="w-/12 text-4xl text-right px-5">
|
||||||
<div class="eight wide right aligned column">
|
<%%= styled_button_link "New <%= schema.human_singular %>", to: Routes.<%= schema.route_helper %>_path(@conn, :new) %>
|
||||||
<span><%%= link "New <%= schema.human_singular %>", to: Routes.<%= schema.route_helper %>_path(@conn, :new), class: "ui primary button" %></span>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<table class="ui celled table">
|
<div class="shadow rounded px-1 py-1 bg-white">
|
||||||
<thead>
|
<table class="min-w-full leading-normal">
|
||||||
<tr>
|
<thead>
|
||||||
<%= for {k, _} <- schema.attrs do %> <th><%= Phoenix.Naming.humanize(Atom.to_string(k)) %></th>
|
<tr>
|
||||||
<% end %>
|
<%= for {k, _} <- schema.attrs do %> <th class="px-5 py-3 border-b-2 border-gray-200 bg-gray-100 text-left text-xs font-semibold text-gray-600 uppercase tracking-wider"><%= Phoenix.Naming.humanize(Atom.to_string(k)) %></th>
|
||||||
<th></th>
|
<% end %>
|
||||||
</tr>
|
<th class="px-5 py-3 border-b-2 border-gray-200 bg-gray-100 text-left text-xs font-semibold text-gray-600 uppercase tracking-wider"></th>
|
||||||
</thead>
|
</tr>
|
||||||
<tbody>
|
</thead>
|
||||||
<%%= case @<%= schema.plural %> do %>
|
<tbody>
|
||||||
<%%= [] -> %>
|
<%%= case @<%= schema.plural %> do %>
|
||||||
<tr>
|
<%%= [] -> %>
|
||||||
<td colspan="<%= schema.attrs |> Enum.count() %>">
|
<tr>
|
||||||
No results.
|
<td class="px-5 py-5 border-b border-gray-200 bg-white text-sm" colspan="<%= (schema.attrs |> Enum.count()) + 1 %>">
|
||||||
</td>
|
No results.
|
||||||
</tr>
|
</td>
|
||||||
<%%= _ -> %>
|
</tr>
|
||||||
<%%= for <%= schema.singular %> <- @<%= schema.plural %> do %>
|
<%%= _ -> %>
|
||||||
<tr>
|
<%%= for <%= schema.singular %> <- @<%= schema.plural %> do %>
|
||||||
<%= for {k, _} <- schema.attrs do %> <td><%%= <%= schema.singular %>.<%= k %> %></td>
|
<tr>
|
||||||
<% end %>
|
<%= for {k, _} <- schema.attrs do %>
|
||||||
<td>
|
<td class="px-5 py-5 border-b border-gray-200 bg-white text-sm">
|
||||||
<div class="ui list">
|
<%%= link <%= schema.singular %>.<%= k %>, to: Routes.<%= schema.route_helper %>_path(@conn, :show, <%= schema.singular %>) %>
|
||||||
<span class="item"><%%= link "Show", to: Routes.<%= schema.route_helper %>_path(@conn, :show, <%= schema.singular %>) %></span>
|
</td>
|
||||||
<span class="item"><%%= link "Edit", to: Routes.<%= schema.route_helper %>_path(@conn, :edit, <%= schema.singular %>) %></span>
|
<% end %>
|
||||||
<span class="item"><%%= link "Delete", to: Routes.<%= schema.route_helper %>_path(@conn, :delete, <%= schema.singular %>), method: :delete, data: [confirm: "Are you sure?"] %></span>
|
<td class="px-5 py-5 border-b border-gray-200 bg-white text-sm">
|
||||||
</div>
|
<label class="relative">
|
||||||
</td>
|
...
|
||||||
</tr>
|
<input type="checkbox" class="hidden hidden-options-toggle">
|
||||||
<%% end %>
|
<div class="hidden absolute right-0 rounded bg-white border shadow-lg py-4 w-48">
|
||||||
<%% end %>
|
<%%= link "Edit", to: Routes.<%= schema.route_helper %>_path(@conn, :edit, <%= schema.singular %>), class: "block px-4 py-2 hover:bg-gray-100" %>
|
||||||
</tbody>
|
<%%= link "Delete", to: Routes.<%= schema.route_helper %>_path(@conn, :delete, <%= schema.singular %>), method: :delete, data: [confirm: "Are you sure?"], class: "text-red-600 block px-4 py-2 hover:bg-gray-100" %>
|
||||||
</table>
|
</div>
|
||||||
|
</label>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<%% end %>
|
||||||
|
<%% end %>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,18 +1,19 @@
|
||||||
<div class="ui top padded container">
|
<div class="p-6 mx-auto max-w-2xl">
|
||||||
<div class="ui grid">
|
<div class="flex pb-6">
|
||||||
<div class="row">
|
<div class="w-/12 flex-1 text-4xl">
|
||||||
<div class="eight wide column">
|
<h1 class="-mb-2 mt-2"><%= schema.human_singular %></h1>
|
||||||
<h1 class="ui header">New <%= schema.human_singular %></h1>
|
|
||||||
</div>
|
|
||||||
<div class="eight wide right aligned column">
|
|
||||||
<span><%%= link "Back", to: Routes.<%= schema.route_helper %>_path(@conn, :index), class: "ui button" %></span>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="w-/12 text-4xl text-right">
|
||||||
|
<%%= styled_button_link "Back", to: Routes.<%= schema.route_helper %>_path(@conn, :index)%>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="centered row">
|
<div class="centered row">
|
||||||
<div class="center aligned column">
|
<div class="center aligned column">
|
||||||
<%%= changeset_error_block(@changeset) %>
|
<%%= changeset_error_block(@changeset) %>
|
||||||
<%%= render "form.html", Map.put(assigns, :action, Routes.<%= schema.route_helper %>_path(@conn, :create)) %>
|
<div class="bg-white shadow rounded px-4 py-6 bg-gray-300">
|
||||||
|
<%%= render "form.html", Map.put(assigns, :action, Routes.<%= schema.route_helper %>_path(@conn, :create)) %>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,26 +1,26 @@
|
||||||
<div class="ui top padded container">
|
<div class="p-6 mx-auto max-w-2xl">
|
||||||
<div class="ui grid">
|
<div class="flex pb-6">
|
||||||
<div class="row">
|
<div class="w-/12 flex-1 text-4xl">
|
||||||
<div class="eight wide column">
|
<h1 class="-mb-2 mt-2"><%= schema.human_singular %></h1>
|
||||||
<h1 class="ui header"><%= schema.human_singular %></h1>
|
</div>
|
||||||
</div>
|
<div class="w-/12 text-4xl text-right">
|
||||||
<div class="eight wide right aligned column">
|
<%%= styled_button_link "Edit", to: Routes.<%= schema.route_helper %>_path(@conn, :edit, @<%= schema.singular %>) %>
|
||||||
<%%= link "Edit", to: Routes.<%= schema.route_helper %>_path(@conn, :edit, @<%= schema.singular %>), class: "ui button primary" %>
|
<%%= styled_button_link "Back", to: Routes.<%= schema.route_helper %>_path(@conn, :index) %>
|
||||||
<span><%%= link "Back", to: Routes.<%= schema.route_helper %>_path(@conn, :index), class: "ui button" %></span>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="ui segment">
|
<div class="centered row">
|
||||||
<div class="ui list">
|
<div class="center aligned column">
|
||||||
<%= for {k, _} <- schema.attrs do %>
|
<div class="bg-white shadow rounded px-4 py-6 bg-white">
|
||||||
<div class="item">
|
<%= for {k, _} <- schema.attrs do %>
|
||||||
<div class="content">
|
<div class="item">
|
||||||
<strong><%= Phoenix.Naming.humanize(Atom.to_string(k)) %>:</strong>
|
<div class="content">
|
||||||
<%%= @<%= schema.singular %>.<%= k %> %>
|
<strong><%= Phoenix.Naming.humanize(Atom.to_string(k)) %>:</strong>
|
||||||
|
<%%= @<%= schema.singular %>.<%= k %> %>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<% end %>
|
||||||
<% end %>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -4,12 +4,11 @@
|
||||||
style="min-height: 75vh;"
|
style="min-height: 75vh;"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="absolute top-0 w-full h-full bg-center bg-cover"
|
class="absolute top-0 w-full h-full bg-center bg-cover bg-gray-700"
|
||||||
style='background-image: url("https://images.unsplash.com/photo-1557804506-669a67965ba0?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1267&q=80");'
|
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
id="blackOverlay"
|
id="blackOverlay"
|
||||||
class="w-full h-full absolute opacity-75 bg-black"
|
class="w-full h-full absolute opacity-75 bg-gray-700"
|
||||||
></span>
|
></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="container relative mx-auto">
|
<div class="container relative mx-auto">
|
||||||
|
|
|
@ -3,3 +3,21 @@
|
||||||
@import "tailwindcss/components";
|
@import "tailwindcss/components";
|
||||||
|
|
||||||
@import "tailwindcss/utilities";
|
@import "tailwindcss/utilities";
|
||||||
|
|
||||||
|
input[type="checkbox"]::after {
|
||||||
|
content: "";
|
||||||
|
color: currentColor;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="checkbox"]:checked::after {
|
||||||
|
content: "✓";
|
||||||
|
}
|
||||||
|
|
||||||
|
.hidden-options-toggle:checked+.hidden {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
|
@ -6,6 +6,8 @@ module.exports = {
|
||||||
theme: {
|
theme: {
|
||||||
extend: {},
|
extend: {},
|
||||||
},
|
},
|
||||||
variants: {},
|
variants: {
|
||||||
|
backgroundColor: ['responsive', 'hover', 'focus', 'checked'],
|
||||||
|
},
|
||||||
plugins: [],
|
plugins: [],
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ module.exports = (env, options) => {
|
||||||
entry: {
|
entry: {
|
||||||
'app': glob.sync('./vendor/**/*.js').concat(['./js/app.js']),
|
'app': glob.sync('./vendor/**/*.js').concat(['./js/app.js']),
|
||||||
'content-editor': ['./js/content-editor.js'],
|
'content-editor': ['./js/content-editor.js'],
|
||||||
|
'tailwind': ['./tailwind.config.js'],
|
||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
filename: 'js/[name].js',
|
filename: 'js/[name].js',
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<nav class="flex items-center justify-between flex-wrap bg-grey-dark p-6 fixed w-full z-10 pin-t">
|
<nav class="flex items-center justify-between flex-wrap bg-grey-dark p-6 w-full z-10 bg-gray-800">
|
||||||
<div class="flex items-center flex-no-shrink text-white mr-6">
|
<div class="flex items-center flex-no-shrink text-white mr-6">
|
||||||
<a class="text-white no-underline hover:text-white hover:no-underline" href="/">
|
<a class="text-white no-underline hover:text-white hover:no-underline" href="/">
|
||||||
<span class="text-2xl pl-2"><i class="em em-grinning"></i> <%= I18n.t! "en", "site.title" %></span>
|
<span class="text-2xl pl-2"><i class="em em-grinning"></i> <%= I18n.t! "en", "site.title" %></span>
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
<body class="text-gray-800 antialiased">
|
<body class="text-gray-800 antialiased">
|
||||||
<main role="main">
|
<main role="main">
|
||||||
<!-- Page Contents -->
|
<!-- Page Contents -->
|
||||||
<div class="pusher">
|
<div class="bg-gray-100 min-h-screen">
|
||||||
<div class="ui inverted vertical masthead center aligned segment">
|
<div class="ui inverted vertical masthead center aligned segment">
|
||||||
<%= render "_menu.html", assigns %>
|
<%= render "_menu.html", assigns %>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -53,8 +53,10 @@ defmodule CoreWeb.Helpers do
|
||||||
end
|
end
|
||||||
|
|
||||||
def styled_input(f, field, opts, options, do: content) do
|
def styled_input(f, field, opts, options, do: content) do
|
||||||
{icon, rest_opts} = Keyword.pop(opts, :icon, "")
|
{type, rest_opts} = Keyword.pop(opts, :type, input_type(f, field))
|
||||||
{classes, rest_opts} = Keyword.pop(rest_opts, :class, "px-3 py-3 placeholder-gray-400 text-gray-700 bg-white rounded text-sm shadow focus:outline-none focus:shadow-outline w-full")
|
IO.inspect(type)
|
||||||
|
{icon, rest_opts} = Keyword.pop(rest_opts, :icon, "")
|
||||||
|
{classes, rest_opts} = Keyword.pop(rest_opts, :class, default_classes_for_type(type))
|
||||||
{label_text, rest_opts} = Keyword.pop(rest_opts, :label)
|
{label_text, rest_opts} = Keyword.pop(rest_opts, :label)
|
||||||
{input_helper, rest_opts} = Keyword.pop(rest_opts, :input_helper, :text_input)
|
{input_helper, rest_opts} = Keyword.pop(rest_opts, :input_helper, :text_input)
|
||||||
|
|
||||||
|
@ -74,11 +76,7 @@ defmodule CoreWeb.Helpers do
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<i class="<%= icon %> icon"></i>
|
<i class="<%= icon %> icon"></i>
|
||||||
<%= if options == nil do %>
|
<%= do_styled_input_tag(type, input_helper, f, field, options, opts, classes, error_classes) %>
|
||||||
<%= apply(Phoenix.HTML.Form, input_helper, [f, field, rest_opts ++ [class: Enum.join([classes, error_classes], " ")]]) %>
|
|
||||||
<% else %>
|
|
||||||
<%= apply(Phoenix.HTML.Form, input_helper, [f, field, options, rest_opts ++ [class: Enum.join([classes, error_classes], " ")]]) %>
|
|
||||||
<% end %>
|
|
||||||
<%= content %>
|
<%= content %>
|
||||||
|
|
||||||
<%= error_tag f, field, class: "text-red-500 italic" %>
|
<%= error_tag f, field, class: "text-red-500 italic" %>
|
||||||
|
@ -86,12 +84,67 @@ defmodule CoreWeb.Helpers do
|
||||||
"""
|
"""
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp do_styled_input_tag(type, input_helper, f, field, nil, opts, classes, error_classes) when type in [:date_select, :time_select, :datetime_select] do
|
||||||
|
default_child_opts = [
|
||||||
|
month: [
|
||||||
|
class: "appearance-none border-b-2 border-dashed",
|
||||||
|
options: [
|
||||||
|
{("Jan"), "1"},
|
||||||
|
{("Feb"), "2"},
|
||||||
|
{("Mar"), "3"},
|
||||||
|
{("Apr"), "4"},
|
||||||
|
{("May"), "5"},
|
||||||
|
{("Jun"), "6"},
|
||||||
|
{("Jul"), "7"},
|
||||||
|
{("Aug"), "8"},
|
||||||
|
{("Sep"), "9"},
|
||||||
|
{("Oct"), "10"},
|
||||||
|
{("Nov"), "11"},
|
||||||
|
{("Dec"), "12"},
|
||||||
|
]
|
||||||
|
],
|
||||||
|
day: [class: "appearance-none border-b-2 border-dashed"],
|
||||||
|
year: [class: "appearance-none border-b-2 border-dashed"],
|
||||||
|
hour: [class: "appearance-none border-b-2 border-dashed"],
|
||||||
|
minute: [class: "appearance-none border-b-2 border-dashed"],
|
||||||
|
second: [class: "appearance-none border-b-2 border-dashed"],
|
||||||
|
]
|
||||||
|
|
||||||
|
{child_opts, rest_opts} = Keyword.pop(opts, :child_opts, default_child_opts)
|
||||||
|
|
||||||
|
~E"""
|
||||||
|
<%= content_tag :div, class: Enum.join([classes, error_classes], " ") do %>
|
||||||
|
<%= apply(Phoenix.HTML.Form, input_helper, [f, field, rest_opts ++ child_opts]) %>
|
||||||
|
<% end %>
|
||||||
|
"""
|
||||||
|
end
|
||||||
|
|
||||||
|
defp do_styled_input_tag(type, input_helper, f, field, nil, opts, classes, error_classes) do
|
||||||
|
apply(Phoenix.HTML.Form, input_helper, [f, field, opts ++ [class: Enum.join([classes, error_classes], " ")]])
|
||||||
|
end
|
||||||
|
|
||||||
|
defp do_styled_input_tag(type, input_helper, f, field, options, opts, classes, error_classes) do
|
||||||
|
apply(Phoenix.HTML.Form, input_helper, [f, field, options, opts ++ [class: Enum.join([classes, error_classes], " ")]])
|
||||||
|
end
|
||||||
|
|
||||||
|
defp default_classes_for_type(type) when type in [:date_select, :time_select, :datetime_select] do
|
||||||
|
"bg-white shadow rounded p-3"
|
||||||
|
end
|
||||||
|
defp default_classes_for_type(:checkbox), do: "appearance-none h-10 w-10 bg-white checked:bg-gray-500 rounded shadow focus:outline-none focus:shadow-outline text-white text-xl font-bold mb-2"
|
||||||
|
defp default_classes_for_type(_), do: "px-3 py-3 placeholder-gray-400 text-gray-700 bg-white rounded text-sm shadow focus:outline-none focus:shadow-outline w-full"
|
||||||
|
|
||||||
def styled_button(text) do
|
def styled_button(text) do
|
||||||
~E"""
|
~E"""
|
||||||
<%= submit text, class: "bg-gray-900 text-white active:bg-gray-700 text-sm font-bold uppercase px-6 py-3 rounded shadow hover:shadow-lg outline-none focus:outline-none mr-1 mb-1 w-full" %>
|
<%= submit text, class: "bg-gray-900 text-white active:bg-gray-700 text-sm font-bold uppercase px-6 py-3 rounded shadow hover:shadow-lg outline-none focus:outline-none mr-1 mb-1 w-full" %>
|
||||||
"""
|
"""
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def styled_button_link(text, opts) do
|
||||||
|
~E"""
|
||||||
|
<%= link text, opts ++ [class: "bg-gray-900 text-white active:bg-gray-700 text-sm font-bold uppercase px-6 py-3 rounded shadow hover:shadow-lg outline-none focus:outline-none mr-1 mb-1 w-full"] %>
|
||||||
|
"""
|
||||||
|
end
|
||||||
|
|
||||||
def floating_form(title, changeset, do: content) do
|
def floating_form(title, changeset, do: content) do
|
||||||
~E"""
|
~E"""
|
||||||
<h1 class="relative text-white text-xl font-semibold text-center pb-6"><%= title %></h1>
|
<h1 class="relative text-white text-xl font-semibold text-center pb-6"><%= title %></h1>
|
||||||
|
|
Loading…
Reference in a new issue