phlex 0.3.2 → 0.5.0
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/.editorconfig +8 -0
- data/.rubocop.yml +21 -5
- data/Gemfile +26 -12
- data/Procfile.dev +3 -0
- data/README.md +1 -1
- data/Rakefile +3 -5
- data/SECURITY.md +1 -1
- data/bench.rb +7 -0
- data/config/sus.rb +15 -0
- data/docs/assets/application.css +6 -0
- data/docs/build.rb +17 -10
- data/docs/components/callout.rb +1 -1
- data/docs/components/code_block.rb +2 -2
- data/docs/components/code_span.rb +9 -0
- data/docs/components/example.rb +5 -5
- data/docs/components/heading.rb +2 -2
- data/docs/components/layout.rb +62 -17
- data/docs/components/markdown.rb +14 -15
- data/docs/components/nav/item.rb +33 -0
- data/docs/components/nav.rb +6 -0
- data/docs/components/tabs/tab.rb +4 -2
- data/docs/components/tabs.rb +1 -1
- data/docs/components/title.rb +2 -2
- data/docs/page_builder.rb +3 -0
- data/docs/pages/application_page.rb +1 -1
- data/docs/pages/helpers.rb +97 -0
- data/docs/pages/index.rb +6 -17
- data/docs/pages/library/collections.rb +83 -0
- data/docs/pages/rails/getting_started.rb +53 -0
- data/docs/pages/rails/helpers.rb +55 -0
- data/docs/pages/rails/layouts.rb +61 -0
- data/docs/pages/rails/migrating.rb +37 -0
- data/docs/pages/rails/rendering_views.rb +35 -0
- data/docs/pages/templates.rb +53 -151
- data/docs/pages/testing/capybara.rb +48 -0
- data/docs/pages/testing/getting_started.rb +44 -0
- data/docs/pages/testing/nokogiri.rb +83 -0
- data/docs/pages/testing/rails.rb +17 -0
- data/docs/pages/translations.rb +81 -0
- data/docs/pages/views.rb +87 -78
- data/fixtures/compiler_test_helpers.rb +19 -0
- data/fixtures/content.rb +60 -0
- data/fixtures/dummy/app/components/comment_component.html.erb +14 -0
- data/fixtures/dummy/app/components/comment_component.rb +8 -0
- data/fixtures/dummy/app/components/reaction_component.html.erb +3 -0
- data/fixtures/dummy/app/components/reaction_component.rb +7 -0
- data/fixtures/dummy/app/controllers/comments_controller.rb +4 -0
- data/fixtures/dummy/app/views/application_view.rb +8 -0
- data/fixtures/dummy/app/views/articles/form.rb +3 -1
- data/fixtures/dummy/app/views/card.rb +4 -2
- data/fixtures/dummy/app/views/comments/comment.rb +25 -0
- data/fixtures/dummy/app/views/comments/index.html.erb +3 -0
- data/fixtures/dummy/app/views/comments/reaction.rb +17 -0
- data/fixtures/dummy/app/views/comments/show.html.erb +3 -0
- data/fixtures/dummy/app/views/heading.rb +1 -1
- data/fixtures/layout.rb +5 -5
- data/fixtures/page.rb +18 -24
- data/fixtures/{test_helper.rb → rails_helper.rb} +3 -7
- data/fixtures/standard_element.rb +87 -0
- data/fixtures/view_helper.rb +1 -1
- data/fixtures/void_element.rb +31 -0
- data/lib/generators/phlex/collection/USAGE +8 -0
- data/lib/generators/phlex/collection/collection_generator.rb +13 -0
- data/lib/generators/phlex/collection/templates/collection.rb.erb +16 -0
- data/lib/generators/phlex/controller/USAGE +10 -0
- data/lib/generators/phlex/controller/controller_generator.rb +54 -0
- data/lib/generators/phlex/controller/templates/controller.rb.erb +10 -0
- data/lib/generators/phlex/controller/templates/view.rb.erb +14 -0
- data/lib/generators/phlex/layout/USAGE +8 -0
- data/lib/generators/phlex/layout/layout_generator.rb +13 -0
- data/lib/generators/phlex/layout/templates/layout.rb.erb +31 -0
- data/lib/generators/phlex/page/USAGE +8 -0
- data/lib/generators/phlex/page/page_generator.rb +13 -0
- data/lib/generators/phlex/page/templates/page.rb.erb +13 -0
- data/lib/generators/phlex/table/USAGE +8 -0
- data/lib/generators/phlex/table/table_generator.rb +14 -0
- data/lib/generators/phlex/table/templates/table.rb.erb +11 -0
- data/lib/generators/phlex/view/templates/view.rb.erb +7 -1
- data/lib/generators/phlex/view/view_generator.rb +9 -1
- data/lib/install/phlex.rb +10 -1
- data/lib/phlex/block.rb +2 -4
- data/lib/phlex/buffered.rb +6 -8
- data/lib/phlex/callable.rb +9 -0
- data/lib/phlex/collection.rb +33 -0
- data/lib/phlex/compiler/elements.rb +49 -0
- data/lib/phlex/compiler/generators/content.rb +103 -0
- data/lib/phlex/compiler/generators/element.rb +61 -0
- data/lib/phlex/compiler/nodes/base.rb +19 -0
- data/lib/phlex/compiler/nodes/call.rb +9 -0
- data/lib/phlex/compiler/nodes/command.rb +13 -0
- data/lib/phlex/compiler/nodes/fcall.rb +18 -0
- data/lib/phlex/compiler/nodes/method_add_block.rb +33 -0
- data/lib/phlex/compiler/nodes/vcall.rb +9 -0
- data/lib/phlex/compiler/optimizer.rb +66 -0
- data/lib/phlex/compiler/visitors/base.rb +15 -0
- data/lib/phlex/compiler/visitors/file.rb +23 -11
- data/lib/phlex/compiler/visitors/stable_scope.rb +28 -0
- data/lib/phlex/compiler/visitors/statements.rb +36 -0
- data/lib/phlex/compiler/visitors/view.rb +19 -0
- data/lib/phlex/compiler/visitors/view_method.rb +59 -0
- data/lib/phlex/compiler.rb +23 -3
- data/lib/phlex/elements.rb +57 -0
- data/lib/phlex/engine.rb +0 -3
- data/lib/phlex/helpers.rb +59 -0
- data/lib/phlex/html/callbacks.rb +11 -0
- data/lib/phlex/html.rb +209 -54
- data/lib/phlex/markdown.rb +76 -0
- data/lib/phlex/rails/form.rb +67 -0
- data/lib/phlex/rails/helpers.rb +118 -0
- data/lib/phlex/rails/layout.rb +15 -0
- data/lib/phlex/rails.rb +10 -0
- data/lib/phlex/renderable.rb +9 -3
- data/lib/phlex/table.rb +104 -0
- data/lib/phlex/testing/capybara.rb +25 -0
- data/lib/phlex/testing/nokogiri.rb +24 -0
- data/lib/phlex/testing/rails.rb +19 -0
- data/lib/phlex/testing/view_helper.rb +15 -0
- data/lib/phlex/translation.rb +23 -0
- data/lib/phlex/turbo/frame.rb +21 -0
- data/lib/phlex/turbo/stream.rb +18 -0
- data/lib/phlex/version.rb +1 -1
- data/lib/phlex.rb +22 -24
- metadata +112 -15
- data/.rspec +0 -1
- data/fixtures/compilation/vcall.rb +0 -38
- data/lib/phlex/compiler/generators/standard_element.rb +0 -30
- data/lib/phlex/compiler/generators/void_element.rb +0 -29
- data/lib/phlex/compiler/optimizers/base_optimizer.rb +0 -34
- data/lib/phlex/compiler/optimizers/vcall.rb +0 -29
- data/lib/phlex/compiler/visitors/base_visitor.rb +0 -19
- data/lib/phlex/compiler/visitors/component.rb +0 -28
- data/lib/phlex/compiler/visitors/component_method.rb +0 -28
- data/lib/phlex/rails/tag_helpers.rb +0 -29
- data/lib/phlex/view.rb +0 -223
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6db4c22ebfaa77371b1d2bc5faaa48bc93056c3c57e2233fc19a9191850f52f9
|
4
|
+
data.tar.gz: b6fc151034426d7ccede55fdd2c73a1244fdf47c440cdb9c59850853cc2cec30
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 888e31c18af9de0230970228e1ab20aab4d08d6b2236187ec06fbe2690813032c3af1e9a675bc737016c3c51f3c522be9a4e87bf868882778ff02482ca4c742f
|
7
|
+
data.tar.gz: 6a999b53c9e54a1159ee0ce34e135d3e5f4c3e73a6207f3d5dbec4f208387c165a83e66cc39f26d582d8ff5fe1d32bb7667b3cfae33a3b16d8a69179dcab4131
|
data/.editorconfig
CHANGED
data/.rubocop.yml
CHANGED
@@ -1,10 +1,26 @@
|
|
1
|
-
inherit_from:
|
1
|
+
inherit_from:
|
2
|
+
- "https://www.goodcop.style/rubocop.yml"
|
3
|
+
- "https://www.goodcop.style/tabs.yml"
|
2
4
|
|
3
5
|
AllCops:
|
4
6
|
TargetRubyVersion: 2.7
|
5
7
|
|
6
|
-
|
7
|
-
|
8
|
+
Style/PercentLiteralDelimiters:
|
9
|
+
Enabled: false
|
8
10
|
|
9
|
-
Layout/
|
10
|
-
|
11
|
+
Layout/CaseIndentation:
|
12
|
+
Enabled: false
|
13
|
+
|
14
|
+
Style/StringConcatenation:
|
15
|
+
Enabled: false
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
Security/Eval:
|
20
|
+
Enabled: false
|
21
|
+
|
22
|
+
Style/MethodCallWithoutArgsParentheses:
|
23
|
+
Enabled: false
|
24
|
+
|
25
|
+
Style/MixinUsage:
|
26
|
+
Enabled: false
|
data/Gemfile
CHANGED
@@ -5,18 +5,32 @@ git_source(:github) { |repo| "https://github.com/#{repo}.git" }
|
|
5
5
|
|
6
6
|
gemspec
|
7
7
|
|
8
|
-
gem "rake"
|
9
|
-
|
10
|
-
gem "sus", group: [:test]
|
11
|
-
gem "rails", group: [:test]
|
12
|
-
gem "rouge", group: [:docs]
|
13
|
-
gem "listen", group: [:docs]
|
14
|
-
gem "webrick", group: [:docs]
|
15
|
-
gem "zeitwerk", group: [:docs]
|
16
|
-
gem "redcarpet", group: [:docs]
|
17
|
-
gem "combustion", group: [:test]
|
18
8
|
gem "benchmark-ips"
|
19
|
-
gem "htmlbeautifier", group: [:docs]
|
20
9
|
gem "benchmark-memory"
|
21
|
-
gem "
|
10
|
+
gem "capybara"
|
11
|
+
gem "rails"
|
12
|
+
gem "rubocop"
|
13
|
+
gem "solargraph"
|
14
|
+
gem "sus"
|
22
15
|
gem "syntax_suggest"
|
16
|
+
gem "zeitwerk"
|
17
|
+
|
18
|
+
group :test do
|
19
|
+
gem "i18n"
|
20
|
+
gem "memory_profiler"
|
21
|
+
gem "covered"
|
22
|
+
end
|
23
|
+
|
24
|
+
group :rails do
|
25
|
+
gem "combustion"
|
26
|
+
end
|
27
|
+
|
28
|
+
group :docs do
|
29
|
+
gem "filewatcher"
|
30
|
+
gem "htmlbeautifier"
|
31
|
+
gem "redcarpet"
|
32
|
+
gem "commonmarker", "~> 0.23"
|
33
|
+
gem "webrick"
|
34
|
+
gem "rouge"
|
35
|
+
gem "kramdown"
|
36
|
+
end
|
data/Procfile.dev
ADDED
data/README.md
CHANGED
@@ -20,7 +20,7 @@ Maintaining a library is a lot of work. If your company benefits from this work
|
|
20
20
|
|
21
21
|
### Security 🚨
|
22
22
|
|
23
|
-
If you’ve found a potential security issue, please email [
|
23
|
+
If you’ve found a potential security issue, please email [security@phlex.fun](mailto:security@phlex.fun).
|
24
24
|
|
25
25
|
### Thanks 🙏
|
26
26
|
|
data/Rakefile
CHANGED
data/SECURITY.md
CHANGED
data/bench.rb
CHANGED
@@ -9,6 +9,13 @@ require_relative "fixtures/layout"
|
|
9
9
|
|
10
10
|
puts RUBY_DESCRIPTION
|
11
11
|
|
12
|
+
a = Example::Page.new.call
|
13
|
+
# Example::Page.compile
|
14
|
+
# Example::LayoutComponent.compile
|
15
|
+
b = Example::Page.new.call
|
16
|
+
|
17
|
+
raise unless a == b
|
18
|
+
|
12
19
|
Benchmark.ips do |x|
|
13
20
|
x.report("Page") { Example::Page.new.call }
|
14
21
|
end
|
data/config/sus.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "covered/sus"
|
4
|
+
include Covered::Sus
|
5
|
+
|
6
|
+
require "phlex"
|
7
|
+
require "bundler"
|
8
|
+
require "view_component"
|
9
|
+
|
10
|
+
Bundler.require :test
|
11
|
+
|
12
|
+
require_relative "../fixtures/view_helper"
|
13
|
+
require_relative "../fixtures/compiler_test_helpers"
|
14
|
+
|
15
|
+
Zeitwerk::Loader.eager_load_all
|
data/docs/assets/application.css
CHANGED
data/docs/build.rb
CHANGED
@@ -1,22 +1,29 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
+
$stdout.sync = true
|
5
|
+
|
4
6
|
require "phlex"
|
5
7
|
require "bundler"
|
6
8
|
require "fileutils"
|
9
|
+
require "i18n"
|
7
10
|
|
8
11
|
Bundler.require :docs
|
9
12
|
|
10
|
-
Zeitwerk::Loader.new
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
FileUtils.mkdir_p("#{__dir__}/dist")
|
18
|
-
FileUtils.cp_r("#{__dir__}/assets", "#{__dir__}/dist")
|
13
|
+
loader = Zeitwerk::Loader.new
|
14
|
+
loader.push_dir(__dir__)
|
15
|
+
loader.ignore(__FILE__)
|
16
|
+
loader.inflector.inflect("rspec" => "RSpec")
|
17
|
+
loader.enable_reloading
|
18
|
+
loader.setup
|
19
|
+
loader.eager_load
|
19
20
|
|
20
21
|
PageBuilder.build_all
|
21
22
|
|
22
|
-
|
23
|
+
if ARGV.include? "--watch"
|
24
|
+
Filewatcher.new("#{__dir__}/**/*rb").watch do |_changes|
|
25
|
+
loader.reload
|
26
|
+
loader.eager_load
|
27
|
+
PageBuilder.build_all
|
28
|
+
end
|
29
|
+
end
|
data/docs/components/callout.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Components
|
4
|
-
class CodeBlock < Phlex::
|
4
|
+
class CodeBlock < Phlex::HTML
|
5
5
|
FORMATTER = Rouge::Formatters::HTML.new
|
6
6
|
|
7
7
|
def initialize(code, syntax:)
|
@@ -11,7 +11,7 @@ module Components
|
|
11
11
|
|
12
12
|
def template
|
13
13
|
pre(class: "highlight p-5 whitespace-pre-wrap bg-stone-50") {
|
14
|
-
|
14
|
+
unsafe_raw FORMATTER.format(
|
15
15
|
lexer.lex(@code)
|
16
16
|
)
|
17
17
|
}
|
data/docs/components/example.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Components
|
4
|
-
class Example < Phlex::
|
4
|
+
class Example < Phlex::HTML
|
5
5
|
def initialize
|
6
6
|
@sandbox = Module.new
|
7
7
|
end
|
@@ -13,18 +13,18 @@ module Components
|
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
|
-
def tab(name, code)
|
16
|
+
def tab(name, code, syntax: :ruby)
|
17
17
|
@t.tab(name) do
|
18
|
-
render CodeBlock.new(code, syntax:
|
18
|
+
render CodeBlock.new(code, syntax: syntax)
|
19
19
|
end
|
20
20
|
|
21
|
-
@sandbox.class_eval(code)
|
21
|
+
@sandbox.class_eval(code) if syntax == :ruby
|
22
22
|
end
|
23
23
|
|
24
24
|
def execute(code)
|
25
25
|
output = @sandbox.class_eval(code)
|
26
26
|
|
27
|
-
@t.tab("
|
27
|
+
@t.tab("👀 Output") do
|
28
28
|
render CodeBlock.new(HtmlBeautifier.beautify(output), syntax: :html)
|
29
29
|
end
|
30
30
|
end
|
data/docs/components/heading.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Components
|
4
|
-
class Heading < Phlex::
|
4
|
+
class Heading < Phlex::HTML
|
5
5
|
def template(&block)
|
6
|
-
h2(class: "text-
|
6
|
+
h2(class: "text-2xl font-semibold mt-10 mb-5", &block)
|
7
7
|
end
|
8
8
|
end
|
9
9
|
end
|
data/docs/components/layout.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Components
|
4
|
-
class Layout < Phlex::
|
4
|
+
class Layout < Phlex::HTML
|
5
5
|
register_element :style
|
6
6
|
|
7
7
|
def initialize(title:)
|
@@ -14,30 +14,75 @@ module Components
|
|
14
14
|
html do
|
15
15
|
head do
|
16
16
|
meta charset: "utf-8"
|
17
|
-
|
17
|
+
meta name: "viewport", content: "width=device-width, initial-scale=1"
|
18
|
+
title { @title }
|
18
19
|
link href: "/application.css", rel: "stylesheet"
|
19
|
-
style {
|
20
|
+
style { unsafe_raw Rouge::Theme.find("github").render(scope: ".highlight") }
|
20
21
|
end
|
21
22
|
|
22
|
-
body class: "
|
23
|
-
div class: "
|
24
|
-
header class: "
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
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" } }
|
34
38
|
end
|
35
39
|
end
|
36
40
|
end
|
37
41
|
|
38
|
-
|
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" }
|
39
67
|
|
40
|
-
|
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
|
41
86
|
end
|
42
87
|
end
|
43
88
|
end
|
data/docs/components/markdown.rb
CHANGED
@@ -1,26 +1,25 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Components
|
4
|
-
class Markdown < Phlex::
|
5
|
-
|
6
|
-
|
7
|
-
case level
|
8
|
-
when 1
|
9
|
-
Title.new.call { text }
|
10
|
-
else
|
11
|
-
Heading.new.call { text }
|
12
|
-
end
|
13
|
-
end
|
4
|
+
class Markdown < Phlex::Markdown
|
5
|
+
def code(&content)
|
6
|
+
render CodeSpan.new, &content
|
14
7
|
end
|
15
8
|
|
16
|
-
|
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
|
17
16
|
|
18
|
-
def
|
19
|
-
|
17
|
+
def h2(&content)
|
18
|
+
render Heading.new, &content
|
20
19
|
end
|
21
20
|
|
22
|
-
def
|
23
|
-
|
21
|
+
def a(**attributes, &content)
|
22
|
+
super(class: "font-bold text-red-600 underline underline-offset-4", **attributes, &content)
|
24
23
|
end
|
25
24
|
end
|
26
25
|
end
|
@@ -0,0 +1,33 @@
|
|
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/tabs/tab.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module Components
|
4
4
|
class Tabs
|
5
|
-
class Tab < Phlex::
|
5
|
+
class Tab < Phlex::HTML
|
6
6
|
def initialize(name:, checked:)
|
7
7
|
@name = name
|
8
8
|
@checked = checked
|
@@ -11,7 +11,9 @@ module Components
|
|
11
11
|
def template(&block)
|
12
12
|
input class: "opacity-0 fixed peer", type: "radio", name: @_parent.unique_identifier, id: unique_identifier, checked: @checked
|
13
13
|
|
14
|
-
label
|
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
|
15
17
|
|
16
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
|
17
19
|
@_parent.instance_exec(&block)
|
data/docs/components/tabs.rb
CHANGED
data/docs/components/title.rb
CHANGED
data/docs/page_builder.rb
CHANGED
@@ -4,6 +4,8 @@ class PageBuilder
|
|
4
4
|
ROOT = Pages::ApplicationPage
|
5
5
|
|
6
6
|
def self.build_all
|
7
|
+
FileUtils.mkdir_p("#{__dir__}/dist")
|
8
|
+
FileUtils.cp_r("#{__dir__}/assets", "#{__dir__}/dist")
|
7
9
|
ROOT.subclasses.each { |page| new(page).call }
|
8
10
|
end
|
9
11
|
|
@@ -12,6 +14,7 @@ class PageBuilder
|
|
12
14
|
end
|
13
15
|
|
14
16
|
def call
|
17
|
+
puts "Building #{@page.name}"
|
15
18
|
FileUtils.mkdir_p(directory)
|
16
19
|
File.write(file, @page.new.call)
|
17
20
|
end
|
@@ -0,0 +1,97 @@
|
|
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
|