phlex 0.5.3 → 1.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of phlex might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Gemfile +1 -20
- data/config/sus.rb +0 -5
- data/lib/phlex/buffered.rb +2 -0
- data/lib/phlex/collection.rb +2 -0
- data/lib/phlex/elements.rb +1 -5
- data/lib/phlex/experimental.rb +10 -0
- data/lib/phlex/helpers.rb +2 -0
- data/lib/phlex/html.rb +73 -86
- data/lib/phlex/table.rb +1 -0
- data/lib/phlex/turbo/frame.rb +2 -0
- data/lib/phlex/turbo/stream.rb +2 -0
- data/lib/phlex/version.rb +1 -1
- data/lib/phlex.rb +2 -19
- metadata +6 -166
- data/Procfile.dev +0 -3
- data/Rakefile +0 -8
- data/config.ru +0 -9
- data/docs/assets/application.css +0 -32
- data/docs/assets/logo.png +0 -0
- data/docs/build.rb +0 -30
- data/docs/components/callout.rb +0 -9
- data/docs/components/code_block.rb +0 -26
- data/docs/components/code_span.rb +0 -9
- data/docs/components/example.rb +0 -32
- data/docs/components/heading.rb +0 -9
- data/docs/components/layout.rb +0 -91
- data/docs/components/markdown.rb +0 -25
- data/docs/components/nav/item.rb +0 -33
- data/docs/components/nav.rb +0 -6
- data/docs/components/tabs/tab.rb +0 -28
- data/docs/components/tabs.rb +0 -30
- data/docs/components/title.rb +0 -9
- data/docs/page_builder.rb +0 -39
- data/docs/pages/application_page.rb +0 -7
- data/docs/pages/helpers.rb +0 -97
- data/docs/pages/index.rb +0 -27
- data/docs/pages/library/collections.rb +0 -83
- data/docs/pages/rails/getting_started.rb +0 -57
- data/docs/pages/rails/helpers.rb +0 -55
- data/docs/pages/rails/layouts.rb +0 -61
- data/docs/pages/rails/migrating.rb +0 -37
- data/docs/pages/rails/rendering_views.rb +0 -35
- data/docs/pages/rails_integration.rb +0 -58
- data/docs/pages/templates.rb +0 -144
- data/docs/pages/testing/capybara.rb +0 -48
- data/docs/pages/testing/getting_started.rb +0 -44
- data/docs/pages/testing/nokogiri.rb +0 -83
- data/docs/pages/testing/rails.rb +0 -17
- data/docs/pages/translations.rb +0 -81
- data/docs/pages/views.rb +0 -184
- data/fixtures/compiler_test_helpers.rb +0 -19
- data/fixtures/content.rb +0 -60
- data/fixtures/dummy/app/assets/config/manifest.js +0 -0
- data/fixtures/dummy/app/components/comment_component.html.erb +0 -14
- data/fixtures/dummy/app/components/comment_component.rb +0 -8
- data/fixtures/dummy/app/components/reaction_component.html.erb +0 -3
- data/fixtures/dummy/app/components/reaction_component.rb +0 -7
- data/fixtures/dummy/app/controllers/articles_controller.rb +0 -4
- data/fixtures/dummy/app/controllers/comments_controller.rb +0 -4
- data/fixtures/dummy/app/views/application_view.rb +0 -8
- data/fixtures/dummy/app/views/articles/form.rb +0 -15
- data/fixtures/dummy/app/views/articles/index.html.erb +0 -14
- data/fixtures/dummy/app/views/articles/new.html.erb +0 -1
- data/fixtures/dummy/app/views/card.rb +0 -15
- data/fixtures/dummy/app/views/comments/comment.rb +0 -25
- data/fixtures/dummy/app/views/comments/index.html.erb +0 -3
- data/fixtures/dummy/app/views/comments/reaction.rb +0 -17
- data/fixtures/dummy/app/views/comments/show.html.erb +0 -3
- data/fixtures/dummy/app/views/heading.rb +0 -9
- data/fixtures/dummy/config/database.yml +0 -3
- data/fixtures/dummy/config/routes.rb +0 -5
- data/fixtures/dummy/config/storage.yml +0 -3
- data/fixtures/dummy/db/schema.rb +0 -6
- data/fixtures/dummy/log/.gitignore +0 -1
- data/fixtures/dummy/public/favicon.ico +0 -0
- data/fixtures/rails_helper.rb +0 -11
- data/fixtures/standard_element.rb +0 -87
- data/fixtures/void_element.rb +0 -31
- data/lib/generators/phlex/collection/USAGE +0 -8
- data/lib/generators/phlex/collection/collection_generator.rb +0 -13
- data/lib/generators/phlex/collection/templates/collection.rb.erb +0 -16
- data/lib/generators/phlex/controller/USAGE +0 -10
- data/lib/generators/phlex/controller/controller_generator.rb +0 -54
- data/lib/generators/phlex/controller/templates/controller.rb.erb +0 -10
- data/lib/generators/phlex/controller/templates/view.rb.erb +0 -14
- data/lib/generators/phlex/layout/USAGE +0 -8
- data/lib/generators/phlex/layout/layout_generator.rb +0 -13
- data/lib/generators/phlex/layout/templates/layout.rb.erb +0 -31
- data/lib/generators/phlex/page/USAGE +0 -8
- data/lib/generators/phlex/page/page_generator.rb +0 -13
- data/lib/generators/phlex/page/templates/page.rb.erb +0 -13
- data/lib/generators/phlex/table/USAGE +0 -8
- data/lib/generators/phlex/table/table_generator.rb +0 -14
- data/lib/generators/phlex/table/templates/table.rb.erb +0 -11
- data/lib/generators/phlex/view/USAGE +0 -8
- data/lib/generators/phlex/view/templates/view.rb.erb +0 -14
- data/lib/generators/phlex/view/view_generator.rb +0 -21
- data/lib/install/phlex.rb +0 -39
- data/lib/phlex/block.rb +0 -16
- data/lib/phlex/compiler/elements.rb +0 -49
- data/lib/phlex/compiler/formatter.rb +0 -91
- data/lib/phlex/compiler/generators/content.rb +0 -103
- data/lib/phlex/compiler/generators/element.rb +0 -61
- data/lib/phlex/compiler/nodes/base.rb +0 -19
- data/lib/phlex/compiler/nodes/call.rb +0 -9
- data/lib/phlex/compiler/nodes/command.rb +0 -13
- data/lib/phlex/compiler/nodes/fcall.rb +0 -18
- data/lib/phlex/compiler/nodes/method_add_block.rb +0 -33
- data/lib/phlex/compiler/nodes/vcall.rb +0 -9
- data/lib/phlex/compiler/optimizer.rb +0 -66
- data/lib/phlex/compiler/visitors/base.rb +0 -15
- data/lib/phlex/compiler/visitors/file.rb +0 -29
- data/lib/phlex/compiler/visitors/stable_scope.rb +0 -28
- data/lib/phlex/compiler/visitors/statements.rb +0 -36
- data/lib/phlex/compiler/visitors/view.rb +0 -19
- data/lib/phlex/compiler/visitors/view_method.rb +0 -59
- data/lib/phlex/compiler.rb +0 -70
- data/lib/phlex/html/callbacks.rb +0 -11
- data/lib/phlex/markdown.rb +0 -76
- data/lib/phlex/rails/engine.rb +0 -10
- data/lib/phlex/rails/form.rb +0 -67
- data/lib/phlex/rails/helpers.rb +0 -118
- data/lib/phlex/rails/layout.rb +0 -15
- data/lib/phlex/rails.rb +0 -11
- data/lib/phlex/renderable.rb +0 -47
- data/lib/phlex/testing/capybara.rb +0 -25
- data/lib/phlex/testing/nokogiri.rb +0 -24
- data/lib/phlex/testing/rails.rb +0 -19
- data/lib/phlex/translation.rb +0 -23
- data/lib/tasks/phlex_tasks.rake +0 -11
- data/package-lock.json +0 -1195
- data/package.json +0 -5
- data/tailwind.config.js +0 -7
data/docs/assets/application.css
DELETED
@@ -1,32 +0,0 @@
|
|
1
|
-
@tailwind base;
|
2
|
-
@tailwind components;
|
3
|
-
@tailwind utilities;
|
4
|
-
|
5
|
-
pre { tab-size: 2; }
|
6
|
-
|
7
|
-
.tabs input[type="radio"]:checked + label {
|
8
|
-
background: #f8f8f8;
|
9
|
-
z-index: 1;
|
10
|
-
margin-bottom: -1px;
|
11
|
-
padding-bottom: 1px;
|
12
|
-
}
|
13
|
-
|
14
|
-
.tabs input[type="radio"]:focus + label {
|
15
|
-
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
|
16
|
-
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color);
|
17
|
-
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
|
18
|
-
}
|
19
|
-
|
20
|
-
.tabs input[type="radio"]:checked + label + .tab {
|
21
|
-
display: block;
|
22
|
-
}
|
23
|
-
|
24
|
-
p {
|
25
|
-
@apply my-5
|
26
|
-
}
|
27
|
-
|
28
|
-
.prose ol, .prose ul {
|
29
|
-
list-style: revert;
|
30
|
-
margin: 0 0 0 1rem;
|
31
|
-
padding: 0 0 0 1rem;
|
32
|
-
}
|
data/docs/assets/logo.png
DELETED
Binary file
|
data/docs/build.rb
DELETED
@@ -1,30 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
$stdout.sync = true
|
5
|
-
|
6
|
-
require "phlex"
|
7
|
-
require "phlex/markdown"
|
8
|
-
require "bundler"
|
9
|
-
require "fileutils"
|
10
|
-
require "i18n"
|
11
|
-
|
12
|
-
Bundler.require :docs
|
13
|
-
|
14
|
-
loader = Zeitwerk::Loader.new
|
15
|
-
loader.push_dir(__dir__)
|
16
|
-
loader.ignore(__FILE__)
|
17
|
-
loader.inflector.inflect("rspec" => "RSpec")
|
18
|
-
loader.enable_reloading
|
19
|
-
loader.setup
|
20
|
-
loader.eager_load
|
21
|
-
|
22
|
-
PageBuilder.build_all
|
23
|
-
|
24
|
-
if ARGV.include? "--watch"
|
25
|
-
Filewatcher.new("#{__dir__}/**/*rb").watch do |_changes|
|
26
|
-
loader.reload
|
27
|
-
loader.eager_load
|
28
|
-
PageBuilder.build_all
|
29
|
-
end
|
30
|
-
end
|
data/docs/components/callout.rb
DELETED
@@ -1,26 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Components
|
4
|
-
class CodeBlock < Phlex::HTML
|
5
|
-
FORMATTER = Rouge::Formatters::HTML.new
|
6
|
-
|
7
|
-
def initialize(code, syntax:)
|
8
|
-
@code = code
|
9
|
-
@syntax = syntax
|
10
|
-
end
|
11
|
-
|
12
|
-
def template
|
13
|
-
pre(class: "highlight p-5 whitespace-pre-wrap bg-stone-50") {
|
14
|
-
unsafe_raw FORMATTER.format(
|
15
|
-
lexer.lex(@code)
|
16
|
-
)
|
17
|
-
}
|
18
|
-
end
|
19
|
-
|
20
|
-
private
|
21
|
-
|
22
|
-
def lexer
|
23
|
-
Rouge::Lexer.find(@syntax)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
data/docs/components/example.rb
DELETED
@@ -1,32 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Components
|
4
|
-
class Example < Phlex::HTML
|
5
|
-
def initialize
|
6
|
-
@sandbox = Module.new
|
7
|
-
end
|
8
|
-
|
9
|
-
def template(&block)
|
10
|
-
render Tabs.new do |t|
|
11
|
-
@t = t
|
12
|
-
yield self
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
def tab(name, code, syntax: :ruby)
|
17
|
-
@t.tab(name) do
|
18
|
-
render CodeBlock.new(code, syntax: syntax)
|
19
|
-
end
|
20
|
-
|
21
|
-
@sandbox.class_eval(code) if syntax == :ruby
|
22
|
-
end
|
23
|
-
|
24
|
-
def execute(code)
|
25
|
-
output = @sandbox.class_eval(code)
|
26
|
-
|
27
|
-
@t.tab("👀 Output") do
|
28
|
-
render CodeBlock.new(HtmlBeautifier.beautify(output), syntax: :html)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
data/docs/components/heading.rb
DELETED
data/docs/components/layout.rb
DELETED
@@ -1,91 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Components
|
4
|
-
class Layout < Phlex::HTML
|
5
|
-
register_element :style
|
6
|
-
|
7
|
-
def initialize(title:)
|
8
|
-
@title = title
|
9
|
-
end
|
10
|
-
|
11
|
-
def template(&block)
|
12
|
-
doctype
|
13
|
-
|
14
|
-
html do
|
15
|
-
head do
|
16
|
-
meta charset: "utf-8"
|
17
|
-
meta name: "viewport", content: "width=device-width, initial-scale=1"
|
18
|
-
title { @title }
|
19
|
-
link href: "/application.css", rel: "stylesheet"
|
20
|
-
style { unsafe_raw Rouge::Theme.find("github").render(scope: ".highlight") }
|
21
|
-
end
|
22
|
-
|
23
|
-
body class: "text-stone-700" do
|
24
|
-
div class: "flex flex-col" do
|
25
|
-
header class: "border-b py-4 px-4 lg:px-10 flex justify-between items-center sticky top-0 left-0 bg-white z-50" do
|
26
|
-
div class: "flex flex-row items-center gap-2" do
|
27
|
-
label for: "nav-toggle", class: "cursor-pointer lg:hidden" do
|
28
|
-
unsafe_raw '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-8 h-8"> <path fill-rule="evenodd" d="M3 6.75A.75.75 0 013.75 6h16.5a.75.75 0 010 1.5H3.75A.75.75 0 013 6.75zM3 12a.75.75 0 01.75-.75h16.5a.75.75 0 010 1.5H3.75A.75.75 0 013 12zm0 5.25a.75.75 0 01.75-.75h16.5a.75.75 0 010 1.5H3.75a.75.75 0 01-.75-.75z" clip-rule="evenodd" /> </svg>'
|
29
|
-
end
|
30
|
-
|
31
|
-
a(href: "/", class: "block") { img src: "/assets/logo.png", width: "100" }
|
32
|
-
end
|
33
|
-
|
34
|
-
nav(class: "text-stone-500 font-medium") do
|
35
|
-
ul(class: "flex space-x-8") do
|
36
|
-
li { a(href: "https://github.com/sponsors/joeldrapper") { "💖️ Sponsor" } }
|
37
|
-
li { a(href: "https://github.com/joeldrapper/phlex") { "GitHub" } }
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
div do
|
43
|
-
div class: "flex flex-row" do
|
44
|
-
input type: "checkbox", id: "nav-toggle", class: "flex-0 peer hidden"
|
45
|
-
label for: "nav-toggle", class: "top-0 bottom-0 left-0 right-0 bg-gray-900 opacity-0 transition-all peer-checked:fixed peer-checked:z-30 peer-checked:block peer-checked:opacity-50 lg:hidden lg:peer-checked:hidden"
|
46
|
-
nav class: "fixed lg:relative w-3/4 border-r-2 border-gray-100 lg:border-0 lg:w-1/4 text-lg lg:text-base h-full z-40 px-10 py-5 -left-full transition-all peer-checked:left-0 lg:left-0 bg-white" do
|
47
|
-
h2(class: "text-lg font-semibold pt-5") { "Guide" }
|
48
|
-
|
49
|
-
ul do
|
50
|
-
render Nav::Item.new("Introduction", to: Pages::Index, active_page: @_parent)
|
51
|
-
render Nav::Item.new("Views", to: Pages::Views, active_page: @_parent)
|
52
|
-
render Nav::Item.new("Templates", to: Pages::Templates, active_page: @_parent)
|
53
|
-
render Nav::Item.new("Helpers", to: Pages::Helpers, active_page: @_parent)
|
54
|
-
render Nav::Item.new("Translations", to: Pages::Translations, active_page: @_parent)
|
55
|
-
end
|
56
|
-
|
57
|
-
h2(class: "text-lg font-semibold pt-5") { "Testing" }
|
58
|
-
|
59
|
-
ul do
|
60
|
-
render Nav::Item.new("Getting Started", to: Pages::Testing::GettingStarted, active_page: @_parent)
|
61
|
-
render Nav::Item.new("Nokogiri", to: Pages::Testing::Nokogiri, active_page: @_parent)
|
62
|
-
render Nav::Item.new("Capybara", to: Pages::Testing::Capybara, active_page: @_parent)
|
63
|
-
render Nav::Item.new("Rails", to: Pages::Testing::Rails, active_page: @_parent)
|
64
|
-
end
|
65
|
-
|
66
|
-
h2(class: "text-lg font-semibold pt-5") { "Rails" }
|
67
|
-
|
68
|
-
ul do
|
69
|
-
render Nav::Item.new("Getting started", to: Pages::Rails::GettingStarted, active_page: @_parent)
|
70
|
-
render Nav::Item.new("Rendering views", to: Pages::Rails::RenderingViews, active_page: @_parent)
|
71
|
-
render Nav::Item.new("Layouts", to: Pages::Rails::Layouts, active_page: @_parent)
|
72
|
-
render Nav::Item.new("Helpers", to: Pages::Rails::Helpers, active_page: @_parent)
|
73
|
-
render Nav::Item.new("Migrating to Phlex", to: Pages::Rails::Migrating, active_page: @_parent)
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
main class: "w-full lg:w-3/4 px-6 lg:px-20 py-5 border-0 lg:border-l-2 border-gray-100" do
|
78
|
-
div(class: "max-w-full lg:max-w-prose prose", &block)
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
footer class: "border-t p-20 flex justify-center text-stone-500 text-lg font-medium" do
|
83
|
-
a(href: "https://github.com/sponsors/joeldrapper") { "Sponsor this project 💖" }
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
91
|
-
end
|
data/docs/components/markdown.rb
DELETED
@@ -1,25 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Components
|
4
|
-
class Markdown < Phlex::Markdown
|
5
|
-
def code(&content)
|
6
|
-
render CodeSpan.new, &content
|
7
|
-
end
|
8
|
-
|
9
|
-
def code_block(code, language:)
|
10
|
-
render CodeBlock.new(code.gsub(/(?:^|\G) {4}/m, " "), syntax: language)
|
11
|
-
end
|
12
|
-
|
13
|
-
def h1(&content)
|
14
|
-
render Title.new, &content
|
15
|
-
end
|
16
|
-
|
17
|
-
def h2(&content)
|
18
|
-
render Heading.new, &content
|
19
|
-
end
|
20
|
-
|
21
|
-
def a(**attributes, &content)
|
22
|
-
super(class: "font-bold text-red-600 underline underline-offset-4", **attributes, &content)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
data/docs/components/nav/item.rb
DELETED
@@ -1,33 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Components
|
4
|
-
class Nav::Item < Phlex::HTML
|
5
|
-
def initialize(text, to:, active_page:)
|
6
|
-
@text = text
|
7
|
-
@to = to
|
8
|
-
@active_page = active_page
|
9
|
-
end
|
10
|
-
|
11
|
-
def template
|
12
|
-
li do
|
13
|
-
a(**link_classes, href: "/#{link}") { @text }
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
def link_classes
|
18
|
-
classes("pb-1 block font-medium text-stone-500", active?: "text-red-600 font-bold")
|
19
|
-
end
|
20
|
-
|
21
|
-
def link
|
22
|
-
path == "index" ? "" : path
|
23
|
-
end
|
24
|
-
|
25
|
-
def path
|
26
|
-
@to.name.split("::")[1..].map { _1.gsub(/(.)([A-Z])/, '\1-\2') }.map(&:downcase).join("/")
|
27
|
-
end
|
28
|
-
|
29
|
-
def active?
|
30
|
-
@active_page.instance_of?(@to)
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
data/docs/components/nav.rb
DELETED
data/docs/components/tabs/tab.rb
DELETED
@@ -1,28 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Components
|
4
|
-
class Tabs
|
5
|
-
class Tab < Phlex::HTML
|
6
|
-
def initialize(name:, checked:)
|
7
|
-
@name = name
|
8
|
-
@checked = checked
|
9
|
-
end
|
10
|
-
|
11
|
-
def template(&block)
|
12
|
-
input class: "opacity-0 fixed peer", type: "radio", name: @_parent.unique_identifier, id: unique_identifier, checked: @checked
|
13
|
-
|
14
|
-
label id: "#{unique_identifier}-label", for: unique_identifier, role: "tab", aria_controls: "#{unique_identifier}-panel", class: "order-1 py-2 px-5 bg-white text-sm border border-b-0 border-l-0 font-medium first-of-type:border-l first-of-type:rounded-tl last-of-type:rounded-tr before:absolute before:pointer-events-none before:w-full before:ring before:h-full before:left-0 before:top-0 before:hidden before:rounded peer-focus:before:block cursor-pointer" do
|
15
|
-
@name
|
16
|
-
end
|
17
|
-
|
18
|
-
div id: "#{unique_identifier}-panel", role: "tabpanel", aria_labelledby: "#{unique_identifier}-label", class: "tab hidden order-2 w-full border rounded-b rounded-tr overflow-hidden" do
|
19
|
-
@_parent.instance_exec(&block)
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
def unique_identifier
|
24
|
-
@unique_identifier ||= SecureRandom.hex
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
data/docs/components/tabs.rb
DELETED
@@ -1,30 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Components
|
4
|
-
class Tabs < Phlex::HTML
|
5
|
-
def initialize
|
6
|
-
@index = 1
|
7
|
-
end
|
8
|
-
|
9
|
-
def template(&block)
|
10
|
-
div class: "tabs flex flex-wrap relative my-5", role: "tablist" do
|
11
|
-
yield_content(&block)
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
def tab(name, &block)
|
16
|
-
render(Tab.new(name: name, checked: first?), &block)
|
17
|
-
@index += 1
|
18
|
-
end
|
19
|
-
|
20
|
-
def unique_identifier
|
21
|
-
@unique_identifier ||= SecureRandom.hex
|
22
|
-
end
|
23
|
-
|
24
|
-
private
|
25
|
-
|
26
|
-
def first?
|
27
|
-
@index == 1
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
data/docs/components/title.rb
DELETED
data/docs/page_builder.rb
DELETED
@@ -1,39 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
class PageBuilder
|
4
|
-
ROOT = Pages::ApplicationPage
|
5
|
-
|
6
|
-
def self.build_all
|
7
|
-
FileUtils.mkdir_p("#{__dir__}/dist")
|
8
|
-
FileUtils.cp_r("#{__dir__}/assets", "#{__dir__}/dist")
|
9
|
-
ROOT.subclasses.each { |page| new(page).call }
|
10
|
-
end
|
11
|
-
|
12
|
-
def initialize(page)
|
13
|
-
@page = page
|
14
|
-
end
|
15
|
-
|
16
|
-
def call
|
17
|
-
puts "Building #{@page.name}"
|
18
|
-
FileUtils.mkdir_p(directory)
|
19
|
-
File.write(file, @page.new.call)
|
20
|
-
end
|
21
|
-
|
22
|
-
private
|
23
|
-
|
24
|
-
def file
|
25
|
-
"#{directory}/index.html"
|
26
|
-
end
|
27
|
-
|
28
|
-
def directory
|
29
|
-
if path == "index"
|
30
|
-
"#{__dir__}/dist"
|
31
|
-
else
|
32
|
-
"#{__dir__}/dist/#{path}"
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
def path
|
37
|
-
@page.name.split("::")[1..].map { _1.gsub(/(.)([A-Z])/, '\1-\2') }.map(&:downcase).join("/")
|
38
|
-
end
|
39
|
-
end
|
data/docs/pages/helpers.rb
DELETED
@@ -1,97 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Pages
|
4
|
-
class Helpers < ApplicationPage
|
5
|
-
def template
|
6
|
-
render Layout.new(title: "Helpers") do
|
7
|
-
render Markdown.new(<<~MD)
|
8
|
-
# Helpers
|
9
|
-
|
10
|
-
## Conditional tokens and classes
|
11
|
-
|
12
|
-
The `tokens` method helps you define conditional HTML attribute tokens (such as CSS classes). It accepts a splat of tokens that should always be output as well as optional keyword arguments for conditional tokens.
|
13
|
-
|
14
|
-
The keyword arguments allow you to specify under which conditions certain tokens are applicable. The keys are the conditions and the values are the tokens. Conditions can be Procs which are evaluated, or Symbols that map to an instance method. The `:active?` Symbol, for example, maps to the `active?` instance method.
|
15
|
-
|
16
|
-
Here we have a `Link` view that produces an `<a>` tag with the CSS class `nav-item`. If the link is _active_, we also apply the CSS class `nav-item-active`.
|
17
|
-
MD
|
18
|
-
|
19
|
-
render Example.new do |e|
|
20
|
-
e.tab "link.rb", <<~RUBY
|
21
|
-
class Link < Phlex::HTML
|
22
|
-
def initialize(text, to:, active:)
|
23
|
-
@text = text
|
24
|
-
@to = to
|
25
|
-
@active = active
|
26
|
-
end
|
27
|
-
|
28
|
-
def template
|
29
|
-
a(href: @to, class: tokens("nav-item",
|
30
|
-
active?: "nav-item-active")) { @text }
|
31
|
-
end
|
32
|
-
|
33
|
-
private
|
34
|
-
|
35
|
-
def active? = @active
|
36
|
-
end
|
37
|
-
RUBY
|
38
|
-
|
39
|
-
e.tab "example.rb", <<~RUBY
|
40
|
-
class Example < Phlex::HTML
|
41
|
-
def template
|
42
|
-
nav do
|
43
|
-
ul do
|
44
|
-
li { render Link.new("Home", to: "/", active: true) }
|
45
|
-
li { render Link.new("About", to: "/about", active: false) }
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
RUBY
|
51
|
-
|
52
|
-
e.execute "Example.new.call"
|
53
|
-
end
|
54
|
-
|
55
|
-
render Markdown.new(<<~MD)
|
56
|
-
You can also use the `classes` helper method to create a token list of classes. Since this method returns a hash, e.g. `{ class: "your CSS classes here" }`, you can destructure it into a `class:` keyword argument using the `**` prefix operator.
|
57
|
-
MD
|
58
|
-
|
59
|
-
render Example.new do |e|
|
60
|
-
e.tab "link.rb", <<~RUBY
|
61
|
-
class Link < Phlex::HTML
|
62
|
-
def initialize(text, to:, active:)
|
63
|
-
@text = text
|
64
|
-
@to = to
|
65
|
-
@active = active
|
66
|
-
end
|
67
|
-
|
68
|
-
def template
|
69
|
-
a(href: @to, **classes("nav-item",
|
70
|
-
active?: "nav-item-active")) { @text }
|
71
|
-
end
|
72
|
-
|
73
|
-
private
|
74
|
-
|
75
|
-
def active? = @active
|
76
|
-
end
|
77
|
-
RUBY
|
78
|
-
|
79
|
-
e.tab "example.rb", <<~RUBY
|
80
|
-
class Example < Phlex::HTML
|
81
|
-
def template
|
82
|
-
nav do
|
83
|
-
ul do
|
84
|
-
li { render Link.new("Home", to: "/", active: true) }
|
85
|
-
li { render Link.new("About", to: "/about", active: false) }
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
90
|
-
RUBY
|
91
|
-
|
92
|
-
e.execute "Example.new.call"
|
93
|
-
end
|
94
|
-
end
|
95
|
-
end
|
96
|
-
end
|
97
|
-
end
|
data/docs/pages/index.rb
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Pages
|
4
|
-
class Index < ApplicationPage
|
5
|
-
def template
|
6
|
-
render Layout.new(title: "Introduction to Phlex, a fast, object-oriented view framework for Ruby") do
|
7
|
-
render Markdown.new(<<~MD)
|
8
|
-
# Introduction
|
9
|
-
|
10
|
-
Phlex is a framework for building fast, reusable, testable views in pure Ruby.
|
11
|
-
|
12
|
-
## Better developer experience 💃
|
13
|
-
|
14
|
-
Phlex views are plain old Ruby objects. View classes are just Ruby classes, templates are just methods, and HTML tags are just method calls. If you know how to define a method that calls another method, you pretty much already know how to use Phlex.
|
15
|
-
|
16
|
-
## Better safety 🥽
|
17
|
-
|
18
|
-
Phlex view templates render in an isolated execution context where only the instance variables and methods for the specific view are exposed.
|
19
|
-
|
20
|
-
## Better performance 🔥
|
21
|
-
|
22
|
-
Rendering a Phlex view is ~4.35× faster than an ActionView partial and ~2× faster than ViewComponent component.
|
23
|
-
MD
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
@@ -1,83 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Pages
|
4
|
-
module Library
|
5
|
-
class Collections < ApplicationPage
|
6
|
-
def template
|
7
|
-
render Layout.new(title: "Getting started with Rails") do
|
8
|
-
render Markdown.new <<~MD
|
9
|
-
# Collections
|
10
|
-
|
11
|
-
Phlex comes with an abstract pattern for views that represent collections of resources — lists, grids, tables, etc. Collections have two parts: one part wraps the whole collection, the other part is repeated once for each item in that collection.
|
12
|
-
|
13
|
-
When you include `Phlex::Collection` in a `Phlex::HTML`, the `template` and `initialize` methods are defined for you. You don't need to define these. Instead, you define a `collection_template` and `item_template`.
|
14
|
-
|
15
|
-
## Collection template
|
16
|
-
|
17
|
-
The `collection_template` method should accept a content block which is used to yield the items. We can yield this block or pass it to another element, such as `<ul>`.
|
18
|
-
|
19
|
-
```ruby
|
20
|
-
def collection_template(&)
|
21
|
-
ul(&)
|
22
|
-
end
|
23
|
-
```
|
24
|
-
|
25
|
-
## Item template
|
26
|
-
|
27
|
-
From the `item_template` method, you can access a single item with the `@item` instance variable.
|
28
|
-
|
29
|
-
```ruby
|
30
|
-
def item_template
|
31
|
-
li { @item }
|
32
|
-
end
|
33
|
-
```
|
34
|
-
|
35
|
-
## Rendering a collection
|
36
|
-
|
37
|
-
Putting it all together, we can create a `List` view that renders each item in an `<li>`, all wrapped up in an outer `<ul>`.
|
38
|
-
|
39
|
-
We can render the list by passing any Enumerable as the `collection` keyword argument. Here, we pass the array `["A", "B", "C"]`.
|
40
|
-
MD
|
41
|
-
|
42
|
-
render Example.new do |e|
|
43
|
-
e.tab "list.rb", <<~RUBY
|
44
|
-
class List < Phlex::HTML
|
45
|
-
include Phlex::Collection
|
46
|
-
|
47
|
-
def collection_template(&content)
|
48
|
-
ul(&content)
|
49
|
-
end
|
50
|
-
|
51
|
-
def item_template
|
52
|
-
li { @item }
|
53
|
-
end
|
54
|
-
end
|
55
|
-
RUBY
|
56
|
-
|
57
|
-
e.tab "example.rb", <<~RUBY
|
58
|
-
class Example < Phlex::HTML
|
59
|
-
def template
|
60
|
-
render List.new(
|
61
|
-
collection: ["A", "B", "C"]
|
62
|
-
)
|
63
|
-
end
|
64
|
-
end
|
65
|
-
RUBY
|
66
|
-
|
67
|
-
e.execute "Example.new.call"
|
68
|
-
end
|
69
|
-
|
70
|
-
render Markdown.new <<~MD
|
71
|
-
## Rendering a single item
|
72
|
-
|
73
|
-
Sometimes you need to render one item of a collection on its own. This is especially handy if you're using Hotwire to append an item to the end of an existing collection. You can render an individual item without the collection wrapper by passing an `item` keyword argument to the collection view.
|
74
|
-
|
75
|
-
```ruby
|
76
|
-
render List.new(item: "A")
|
77
|
-
```
|
78
|
-
MD
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|