tailwindcss-rb 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.rspec +3 -0
- data/.rubocop.yml +13 -0
- data/CHANGELOG.md +5 -0
- data/CODE_OF_CONDUCT.md +84 -0
- data/Gemfile +16 -0
- data/Gemfile.lock +110 -0
- data/LICENSE.txt +21 -0
- data/README.md +244 -0
- data/Rakefile +15 -0
- data/lib/tailwindcss/arbitrary_value.rb +15 -0
- data/lib/tailwindcss/asset_helper.rb +15 -0
- data/lib/tailwindcss/compiler/channel.rb +18 -0
- data/lib/tailwindcss/compiler/connection.rb +6 -0
- data/lib/tailwindcss/compiler/file_classes_extractor.rb +24 -0
- data/lib/tailwindcss/compiler/file_parser.rb +55 -0
- data/lib/tailwindcss/compiler/hash_args_extractor.rb +93 -0
- data/lib/tailwindcss/compiler/output.rb +48 -0
- data/lib/tailwindcss/compiler/runner.rb +64 -0
- data/lib/tailwindcss/constants.rb +322 -0
- data/lib/tailwindcss/helpers.rb +26 -0
- data/lib/tailwindcss/installer.rb +17 -0
- data/lib/tailwindcss/installers/config_file_generator.rb +37 -0
- data/lib/tailwindcss/style.rb +29 -0
- data/lib/tailwindcss/style_attributes_to_list_converter.rb +44 -0
- data/lib/tailwindcss/version.rb +3 -0
- data/lib/tailwindcss.rb +78 -0
- data/lib/tasks/tailwindcss.rake +28 -0
- data/sig/tailwindcss.rbs +4 -0
- metadata +130 -0
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'active_support/core_ext/object/blank'
|
2
|
+
require 'tailwindcss/helpers'
|
3
|
+
|
4
|
+
module Tailwindcss
|
5
|
+
module Compiler
|
6
|
+
class HashArgsExtractor
|
7
|
+
def call(ast:)
|
8
|
+
extract_hash_arguments_from_ast_nodes(ast)
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def extract_hash_arguments_from_ast_nodes(node)
|
14
|
+
hash_args = []
|
15
|
+
return unless node.is_a?(Parser::AST::Node)
|
16
|
+
|
17
|
+
if node.type == :send
|
18
|
+
hash_args += extract_hashes(node).flatten(10)
|
19
|
+
end
|
20
|
+
|
21
|
+
node.children.each do |child|
|
22
|
+
next unless child.is_a?(Parser::AST::Node)
|
23
|
+
|
24
|
+
hash_args += extract_hash_arguments_from_ast_nodes(child)
|
25
|
+
end
|
26
|
+
|
27
|
+
hash_args.flatten.compact
|
28
|
+
end
|
29
|
+
|
30
|
+
def extract_hashes(node)
|
31
|
+
scan_for_hash_children(node).each_with_object([]) { |hash_node, acc| extract_value(hash_node, acc) }.compact
|
32
|
+
end
|
33
|
+
|
34
|
+
def scan_for_hash_children(node)
|
35
|
+
node.children[2..].select { |child| child.type == :hash }
|
36
|
+
end
|
37
|
+
|
38
|
+
def extract_value(node, acc)
|
39
|
+
node.children.select { |n| n.type == :pair }.each do |key_value_node|
|
40
|
+
key_node = key_value_node.children.first
|
41
|
+
value_node = key_value_node.children.last
|
42
|
+
value = pair_node_value(key_node, value_node)
|
43
|
+
|
44
|
+
acc << value if value.present?
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def pair_node_value(key_node, value_node)
|
49
|
+
key = source_code(key_node)
|
50
|
+
case value_node.type
|
51
|
+
when :hash
|
52
|
+
hashes = []
|
53
|
+
extract_value(value_node, hashes)
|
54
|
+
hashes.flatten.map { |h| { key.to_sym => h } }
|
55
|
+
when :int, :str, :sym, :float
|
56
|
+
{ key.to_sym => node_text(value_node) }
|
57
|
+
when :true
|
58
|
+
{ key.to_sym => true }
|
59
|
+
when :false
|
60
|
+
{ key.to_sym => false }
|
61
|
+
else
|
62
|
+
extract_color_scheme_calls(key_node, value_node)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def extract_color_scheme_calls(key_node, value_node)
|
67
|
+
value = source_code(value_node)
|
68
|
+
return unless value.include?('color_scheme_token') || value.include?('color_token')
|
69
|
+
|
70
|
+
weight_node = value_node.children[3]
|
71
|
+
weight = weight_node ? eval(source_code(weight_node)) : 500
|
72
|
+
|
73
|
+
if value.include?('color_scheme_token')
|
74
|
+
color_scheme_token = eval(source_code(value_node.children[2]))
|
75
|
+
color = Tailwindcss::Helpers.color_scheme_token(color_scheme_token, weight)
|
76
|
+
elsif value.include?('color_token')
|
77
|
+
color_token = eval(source_code(value_node.children[2]))
|
78
|
+
color = Tailwindcss::Helpers.color_token(color_token, weight)
|
79
|
+
end
|
80
|
+
|
81
|
+
{ source_code(key_node).to_sym => color }
|
82
|
+
end
|
83
|
+
|
84
|
+
def node_text(node)
|
85
|
+
source_code(node).delete(':').delete('\'').to_s
|
86
|
+
end
|
87
|
+
|
88
|
+
def source_code(node)
|
89
|
+
node.location.expression.source
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require "fileutils"
|
2
|
+
|
3
|
+
module Tailwindcss
|
4
|
+
module Compiler
|
5
|
+
class Output
|
6
|
+
def add_entry(file_path:, classes:)
|
7
|
+
file_path = absolute_path(file_path)
|
8
|
+
return if classes.blank?
|
9
|
+
|
10
|
+
path = output_file_path(file_path:)
|
11
|
+
folder = create_output_folder(file_path: path)
|
12
|
+
|
13
|
+
path += ".classes"
|
14
|
+
File.open(path, "wb") do |file|
|
15
|
+
file << classes.join("\n")
|
16
|
+
end
|
17
|
+
File.delete(path) if File.empty?(path)
|
18
|
+
end
|
19
|
+
|
20
|
+
def compile_classes_dir
|
21
|
+
absolute_path(Tailwindcss.config.compiler.compile_classes_dir.call)
|
22
|
+
end
|
23
|
+
|
24
|
+
def create_output_folder(file_path:)
|
25
|
+
dir_name = File.dirname(file_path)
|
26
|
+
FileUtils.mkdir_p(dir_name)
|
27
|
+
end
|
28
|
+
|
29
|
+
def output_file_path(file_path:)
|
30
|
+
content.each do |folder|
|
31
|
+
if file_path.start_with?(folder)
|
32
|
+
return File.join(compile_classes_dir, file_path.delete_prefix(folder.to_s))
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
return nil
|
37
|
+
end
|
38
|
+
|
39
|
+
def content
|
40
|
+
Tailwindcss.config.content.call.map { |path| absolute_path(path) }
|
41
|
+
end
|
42
|
+
|
43
|
+
def absolute_path(path)
|
44
|
+
File.expand_path(path)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
|
2
|
+
require "listen"
|
3
|
+
require "tailwindcss"
|
4
|
+
require "tailwindcss/compiler/file_classes_extractor"
|
5
|
+
require "tailwindcss/compiler/output"
|
6
|
+
require "tailwindcss/compiler/connection" if defined?(ActionCable)
|
7
|
+
require "tailwindcss/compiler/channel" if defined?(ActionCable)
|
8
|
+
|
9
|
+
module Tailwindcss
|
10
|
+
module Compiler
|
11
|
+
class Runner
|
12
|
+
def initialize(watch: nil)
|
13
|
+
@watch = watch
|
14
|
+
end
|
15
|
+
|
16
|
+
def call # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
17
|
+
output = Output.new
|
18
|
+
file_classes_extractor = FileClassesExtractor.new
|
19
|
+
|
20
|
+
content.each do |location|
|
21
|
+
if watch || (watch.nil? && Tailwindcss.config.watch_content)
|
22
|
+
listener = Listen.to(File.dirname(location.to_s), only: /\.(rb|erb)$/) do |modified, added, removed|
|
23
|
+
Tailwindcss.logger.info "Recompiling Tailwindcss..."
|
24
|
+
Tailwindcss.logger.info "Modified: #{modified}"
|
25
|
+
Tailwindcss.logger.info "Added: #{added}"
|
26
|
+
Tailwindcss.logger.info "Removed: #{removed}"
|
27
|
+
(modified + added + removed).compact.each do |file_path|
|
28
|
+
next unless File.file?(file_path)
|
29
|
+
|
30
|
+
classes = file_classes_extractor.call(file_path:)
|
31
|
+
next unless classes.present?
|
32
|
+
|
33
|
+
output.add_entry(file_path:, classes:)
|
34
|
+
end
|
35
|
+
|
36
|
+
Tailwindcss.compile_css!
|
37
|
+
end
|
38
|
+
|
39
|
+
listener.start
|
40
|
+
end
|
41
|
+
|
42
|
+
Dir.glob("#{location}/**/*").each do |file_path|
|
43
|
+
next unless File.file?(file_path)
|
44
|
+
|
45
|
+
classes = file_classes_extractor.call(file_path:)
|
46
|
+
next unless classes.present?
|
47
|
+
|
48
|
+
output.add_entry(file_path:, classes:)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
Tailwindcss.compile_css!
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
attr_reader :watch
|
58
|
+
|
59
|
+
def content
|
60
|
+
Tailwindcss.config.content.respond_to?(:call) ? Tailwindcss.config.content.call : Tailwindcss.config.content
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,322 @@
|
|
1
|
+
module Tailwindcss
|
2
|
+
module Constants
|
3
|
+
COLOR_WEIGHTS = ([nil] + %i[50 100 200 300 400 500 600 700 800 900]).freeze
|
4
|
+
BREAKPOINTS = %i[xs sm md lg xl 2xl].freeze
|
5
|
+
PSEUDO_SELECTORS = %i[hover focus active visited disabled first last first_of_type last_of_type odd even group_hover].freeze
|
6
|
+
PSEUDO_ELEMENTS = %i[before after file first_letter first_line selection backdrop marker].freeze
|
7
|
+
|
8
|
+
ALIGN_CONTENT = %i[normal center start end between around evenly baseline stretch].freeze
|
9
|
+
ALIGN_ITEMS = %i[start end center baseline stretch].freeze
|
10
|
+
BACKFACE_VISIBILITY = %i[visible hidden].freeze
|
11
|
+
BACKGROUND_ATTACHMENT = %i[fixed local scroll].freeze
|
12
|
+
BACKGROUND_BLEND_MODE = %i[normal multiply screen overlay darken lighten color-dodge color-burn hard-light
|
13
|
+
soft-light difference exclusion hue saturation color luminosity].freeze
|
14
|
+
BACKGROUND_CLIP = %i[border padding content].freeze
|
15
|
+
BACKGROUND_IMAGE = %i[none gradient-to-t gradient-to-tr gradient-to-r gradient-to-br gradient-to-b gradient-to-bl
|
16
|
+
gradient-to-l gradient-to-tl].freeze
|
17
|
+
BACKGROUND_ORIGIN = %i[border padding content].freeze
|
18
|
+
BACKGROUND_POSITION = %i[bottom center left left-bottom left-top right right-bottom right-top
|
19
|
+
top].freeze
|
20
|
+
BACKGROUND_REPEAT = %i[repeat repeat-x repeat-y no-repeat round space].freeze
|
21
|
+
BORDER_RADIUSES = %i[none sm md lg full].freeze
|
22
|
+
BACKGROUND_SIZE = %i[auto cover contain].freeze
|
23
|
+
BORDER_COLLAPSE = %i[collapse separate].freeze
|
24
|
+
BORDER_RADIUS = %i[none sm true md lg xl 2xl 3xl full] + [true].freeze
|
25
|
+
CONTENT = %i[none].freeze
|
26
|
+
SPACING = %i[0 px 0.5 1 1.5 2 2.5 3 3.5 4 5 6 7 8 9 10 11 12 14 16 20 24 28 32 36 40 44 48 52 56 60 64 72
|
27
|
+
80 96 auto].freeze
|
28
|
+
BORDER_STYLE = %i[solid dashed dotted double none].freeze
|
29
|
+
BORDER = [true, false].freeze
|
30
|
+
BORDER_WIDTH = %i[0 1 2 4 8].freeze
|
31
|
+
BOX_DECORATION_BREAK = %i[slice clone].freeze
|
32
|
+
BOX_SHADOW = (%i[sm md lg xl 2xl inner none] + [true]).freeze
|
33
|
+
BOX_SIZING = %i[border content].freeze
|
34
|
+
CAPTION_SIDE = %i[top bottom].freeze
|
35
|
+
CLEAR = %i[left right both none].freeze
|
36
|
+
COLORS = %i[transparent current inherit black white neutral zync stone gray red amber yellow lime green blue indigo
|
37
|
+
violet purple pink slate emerald fuchsia rose cyan teal sky].freeze
|
38
|
+
COLOR_SCHEME = {
|
39
|
+
primary: :purple,
|
40
|
+
secondary: :indigo,
|
41
|
+
success: :emerald,
|
42
|
+
danger: :rose,
|
43
|
+
warning: :yellow,
|
44
|
+
info: :teal,
|
45
|
+
neutral: :gray,
|
46
|
+
dark: :black,
|
47
|
+
light: :white
|
48
|
+
}.freeze
|
49
|
+
COLUMNS = %i[auto 1 2 3 4 5 6 7 8 9 10 11 12 3xs 2xs xs sm md lg xl 2xl 3xl 4xl 5xl 6xl 7xl].freeze
|
50
|
+
COLUMN_SPAN = %i[auto 1 2 3 4 5 6 7 8 9 10 11 12 all].freeze
|
51
|
+
COLUMN_START = %i[auto 1 2 3 4 5 6 7 8 9 10 11 12 13].freeze
|
52
|
+
COLUMN_END = %i[auto 1 2 3 4 5 6 7 8 9 10 11 12 13].freeze
|
53
|
+
CURSOR = %i[auto default pointer wait text move help not-allowed].freeze
|
54
|
+
DISPLAY = %i[block inline-block inline inline-table table table-caption table-cell table-column table-column-group
|
55
|
+
table-footer-group table-header-group table-row table-row-group flow-root grid inline-grid contents
|
56
|
+
list-item hidden flex inline-flex].freeze
|
57
|
+
EMPTY_CELLS = %i[show hide].freeze
|
58
|
+
FLEX_BASIS = %i[auto 0].freeze
|
59
|
+
FLEX_DIRECTION = %i[row row-reverse col col-reverse].freeze
|
60
|
+
FLEX_GROW = [0, true].freeze
|
61
|
+
FLEX_SHRINK = [0, true].freeze
|
62
|
+
FLEX_WRAP = %i[wrap nowrap wrap-reverse].freeze
|
63
|
+
FLEX = %i[1 auto initial none].freeze
|
64
|
+
FONT_FAMILY = %i[sans serif mono].freeze
|
65
|
+
FONT_SIZE = %i[xs sm base lg xl 2xl 3xl 4xl 5xl 6xl 7xl 8xl 9xl].freeze
|
66
|
+
FONT_STYLE = %i[italic non-italic].freeze
|
67
|
+
FONT_VARIANT_NUMERIC = %i[normal-nums ordinal slashed-zero lining-nums oldstyle-nums proportional-nums
|
68
|
+
tabular-nums diagonal-fractions stacked-fractions].freeze
|
69
|
+
FONT_WEIGHT = %i[hairline thin light normal medium semibold bold extrabold black].freeze
|
70
|
+
GRID_AUTO_COLUMNS = %i[auto min max fr].freeze
|
71
|
+
GRID_AUTO_FLOW = %i[row column dense row-dense column-dense].freeze
|
72
|
+
GRID_AUTO_ROWS = %i[auto min max fr].freeze
|
73
|
+
GRID_TEMPLATE_COLUMNS = %i[none 1 2 3 4 5 6 7 8 9 10 11 12].freeze
|
74
|
+
GRID_TEMPLATE_ROWS = %i[none 1 2 3 4 5 6].freeze
|
75
|
+
GROUP = [true, false].freeze
|
76
|
+
SIZES = %i[0 px 0.5 1 1.5 2 2.5 3 3.5 4 5 6 7 8 9 10 11 12 14 16 20 24 28 32 36 40 44 48 52 56 60 64 72
|
77
|
+
80 96 auto 1/2 1/3 2/3 1/4 2/4 3/4 1/5 2/5 3/5 4/5 1/6 2/6 3/6 4/6 5/6 full screen min max fit].freeze
|
78
|
+
HYPHENS = %i[none manual auto].freeze
|
79
|
+
ISOLATION = %i[isolate auto].freeze
|
80
|
+
JUSTIFY_CONTENT = %i[start end center between around evenly].freeze
|
81
|
+
JUSTIFY_ITEMS = %i[start end center baseline stretch].freeze
|
82
|
+
JUSTIFY_SELF = %i[start end center auto stretch].freeze
|
83
|
+
LETTER_SPACING = %i[tighter tight normal wide wider widest].freeze
|
84
|
+
LINE_HEIGHT = %i[none tight snug normal relaxed loose 3 4 5 6 7 8 9 10].freeze
|
85
|
+
LIST_STYLE_IMAGE = %i[none].freeze
|
86
|
+
LIST_STYLE_POSITION = %i[inside outside].freeze
|
87
|
+
LIST_STYLE_TYPE = %i[none disc decimal].freeze
|
88
|
+
MAX_SIZE = %i[0 xs sm md lg xl 2xl 3xl 4xl 5xl 6xl 7xl full screen min max fit prose screen-sm screen-md
|
89
|
+
screen-lg screen-xl screen-2xl].freeze
|
90
|
+
MIN_SIZE = [0, :full, :min, :max, :fit].freeze
|
91
|
+
MIX_BLEND_MODE = %i[normal multiply screen overlay darken lighten color-dodge color-burn hard-light soft-light
|
92
|
+
difference exclusion hue saturation color luminosity].freeze
|
93
|
+
OBJECT_FIT = %i[contain cover fill none scale-down].freeze
|
94
|
+
OBJECT_POSITION = %i[top right bottom left center].freeze
|
95
|
+
OPACITY = %i[0 5 10 20 25 30 40 50 60 70 75 80 90 95 100].freeze
|
96
|
+
ORDER = %i[first last none 1 2 3 4 5 6 7 8 9 10 11 12].freeze
|
97
|
+
OUTLINE_STYLE = %i[dotted dashed solid double none].freeze
|
98
|
+
OUTLINE_WIDTH = %i[0 1 2 4 8].freeze
|
99
|
+
OVERFLOW = %i[auto hidden visible scroll x-hidden y-hidden x-scroll y-scroll x-auto y-auto].freeze
|
100
|
+
PLACE_ITEMS = %i[start end center stretch].freeze
|
101
|
+
PLACE_SELF = %i[start end center stretch].freeze
|
102
|
+
POINTER_EVENTS = %i[none auto].freeze
|
103
|
+
POSITION = %i[static fixed absolute relative sticky].freeze
|
104
|
+
RESIZE = %i[true false none x y].freeze
|
105
|
+
ROTATE = %i[0 1 2 3 6 12 45 90 180].map { [_1, :"-#{_1}"] }.flatten.freeze
|
106
|
+
ROW_SPAN = %i[auto 1 2 3 4 5 6 full].freeze
|
107
|
+
ROW_START = %i[auto 1 2 3 4 5 6 7].freeze
|
108
|
+
ROW_END = %i[auto 1 2 3 4 5 6 7].freeze
|
109
|
+
SCALE = %i[0 50 75 90 95 100 105 110 125 150 200].freeze
|
110
|
+
SCROLL_BEHAVIOR = %i[auto smooth].freeze
|
111
|
+
SCROLL_SNAP_ALIGN = %i[start end center none].freeze
|
112
|
+
SCROLL_SNAP_STOP = %i[always normal].freeze
|
113
|
+
SCROLL_SNAP_TYPE = %i[none mandatory proximity].freeze
|
114
|
+
TABLE_LAYOUT = %i[auto fixed].freeze
|
115
|
+
TEXT_ALIGN = %i[left center right justify start end].freeze
|
116
|
+
TEXT_DECORATION = %i[underline line-through no-underline].freeze
|
117
|
+
TEXT_DECORATION_STYLE = %i[solid double dotted dashed wavy].freeze
|
118
|
+
TEXT_DECORATION_THICKNESS = %i[auto from-font 0 1 2 4 8].freeze
|
119
|
+
TEXT_OVERFLOW = %i[ellipsis truncate].freeze
|
120
|
+
TEXT_TRANSFORM = %i[uppercase lowercase capitalize normal].freeze
|
121
|
+
TEXT_UNDERLINE_OFFSET = %i[auto 0 1 2 4 8].freeze
|
122
|
+
TRANSFORM_ORIGIN = %i[center top-right top top-left right bottom-right bottom bottom-left left].freeze
|
123
|
+
TRANSITION = %i[none all colors opacity shadow transform].freeze
|
124
|
+
TRANSLATE = %i[0 0.5 px 1 1.5 2 2.5 3 3.5 4 5 6 7 8 9 10 11 12 14 16 20 24 28 32 36 40 44 48 52 56 60 64 72 80 96 1/2 1/3 2/3 1/4 2/3 2/4 3/4 full].map { [_1, :"-#{_1}"] }.flatten.freeze
|
125
|
+
USER_SELECT = %i[none text all auto].freeze
|
126
|
+
VERTICAL_ALIGN = %i[top middle bottom baseline text-top text-bottom sub super].freeze
|
127
|
+
VISIBILITY = %i[visible invisible collapse].freeze
|
128
|
+
WHITESPACE = %i[normal nowrap pre pre-line pre-wrap break-words].freeze
|
129
|
+
WILL_CHANGE = %i[auto scroll contents opacity transform].freeze
|
130
|
+
WORD_BREAK = %i[normal words all keep].freeze
|
131
|
+
Z_INDEX = %i[0 10 20 30 40 50 auto].freeze
|
132
|
+
|
133
|
+
COLOR_WITH_WEIGHTS = proc {
|
134
|
+
COLORS.map do |color|
|
135
|
+
COLOR_WEIGHTS.map { |weight| [color, weight].compact.join("-") }
|
136
|
+
end.flatten.freeze
|
137
|
+
}
|
138
|
+
|
139
|
+
THEME = {
|
140
|
+
align_content: {values: ALIGN_CONTENT, token: "content"},
|
141
|
+
align_items: {values: ALIGN_ITEMS, token: "items", alias: :items},
|
142
|
+
backface_visibility: {values: BACKFACE_VISIBILITY, token: "backface"},
|
143
|
+
background: {values: COLOR_WITH_WEIGHTS, token: "bg", alias: :bg},
|
144
|
+
background_attachment: {values: BACKGROUND_ATTACHMENT, token: "bg"},
|
145
|
+
background_blend_mode: {values: BACKGROUND_BLEND_MODE, token: "bg"},
|
146
|
+
background_clip: {values: BACKGROUND_CLIP, token: "bg"},
|
147
|
+
background_color: {values: COLOR_WITH_WEIGHTS, token: "bg"},
|
148
|
+
background_image: {values: BACKGROUND_IMAGE, token: "bg"},
|
149
|
+
background_origin: {values: BACKGROUND_ORIGIN, token: "bg"},
|
150
|
+
background_position: {values: BACKGROUND_POSITION, token: "bg"},
|
151
|
+
background_repeat: {values: BACKGROUND_REPEAT, token: "bg"},
|
152
|
+
background_size: {values: BACKGROUND_SIZE, token: "bg"},
|
153
|
+
border_bottom_left_radius: {values: BORDER_RADIUS, token: "rounded-bl"},
|
154
|
+
border_bottom_right_radius: {values: BORDER_RADIUS, token: "rounded-br"},
|
155
|
+
border_top_left_radius: {values: BORDER_RADIUS, token: "rounded-tl"},
|
156
|
+
border_top_right_radius: {values: BORDER_RADIUS, token: "rounded-tr"},
|
157
|
+
border_top_radius: {values: BORDER_RADIUS, token: "rounded-t"},
|
158
|
+
border_bottom_radius: {values: BORDER_RADIUS, token: "rounded-b"},
|
159
|
+
border_left_radius: {values: BORDER_RADIUS, token: "rounded-l"},
|
160
|
+
border_right_radius: {values: BORDER_RADIUS, token: "rounded-r"},
|
161
|
+
border_collapse: {values: BORDER_COLLAPSE, token: "border"},
|
162
|
+
border_color: {values: COLOR_WITH_WEIGHTS, token: "border"},
|
163
|
+
border_radius: {values: BORDER_RADIUS, token: "rounded", alias: :rounded},
|
164
|
+
border_spacing: {values: SPACING, token: "border-spacing"},
|
165
|
+
border_spacing_x: {values: SPACING, token: "border-spacing-x"},
|
166
|
+
border_spacing_y: {values: SPACING, token: "border-spacing-y"},
|
167
|
+
border_style: {values: BORDER_STYLE, token: "border"},
|
168
|
+
border: {values: BORDER, token: "border"},
|
169
|
+
border_top: {values: BORDER + BORDER_WIDTH, token: "border-t"},
|
170
|
+
border_bottom: {values: BORDER + BORDER_WIDTH, token: "border-b"},
|
171
|
+
border_left: {values: BORDER + BORDER_WIDTH, token: "border-l"},
|
172
|
+
border_right: {values: BORDER + BORDER_WIDTH, token: "border-r"},
|
173
|
+
border_width: {values: BORDER_WIDTH, token: "border"},
|
174
|
+
border_y: {values: BORDER_WIDTH, token: "border-y"},
|
175
|
+
border_x: {values: BORDER_WIDTH, token: "border-x"},
|
176
|
+
border_start: {values: BORDER_WIDTH, token: "border-s"},
|
177
|
+
border_end: {values: BORDER_WIDTH, token: "border-e"},
|
178
|
+
bottom: {values: SIZES, token: "bottom"},
|
179
|
+
box_decoration_break: {values: BOX_DECORATION_BREAK, token: "box-decoration-break"},
|
180
|
+
box_shadow: {values: BOX_SHADOW, token: "shadow", alias: :shadow},
|
181
|
+
box_sizing: {values: BOX_SIZING, token: "box"},
|
182
|
+
caption_side: {values: CAPTION_SIDE, token: "caption"},
|
183
|
+
clear: {values: CLEAR, token: "clear"},
|
184
|
+
color: {values: COLOR_WITH_WEIGHTS, token: "text"},
|
185
|
+
column_gap: {values: SPACING, token: "gap"},
|
186
|
+
column_span: {values: COLUMN_SPAN, token: "col-span", alias: :col_span},
|
187
|
+
column_start: {values: COLUMN_START, token: "col-start", alias: :col_start},
|
188
|
+
column_end: {values: COLUMN_END, token: "col-end", alias: :col_end},
|
189
|
+
columns: {values: COLUMNS, token: "columns"},
|
190
|
+
content: {values: CONTENT, token: "content"},
|
191
|
+
cursor: {values: CURSOR, token: "cursor"},
|
192
|
+
display: {values: DISPLAY, token: nil, alias: :d},
|
193
|
+
empty_cells: {values: EMPTY_CELLS, token: "empty"},
|
194
|
+
end: {values: SIZES, token: "end"},
|
195
|
+
fill: {values: COLOR_WITH_WEIGHTS, token: "fill"},
|
196
|
+
flex_basis: {values: FLEX_BASIS, token: "flex"},
|
197
|
+
flex_direction: {values: FLEX_DIRECTION, token: "flex", alias: :direction},
|
198
|
+
flex_grow: {values: FLEX_GROW, token: "flex", alias: :grow},
|
199
|
+
flex_shrink: {values: FLEX_SHRINK, token: "flex", alias: :shrink},
|
200
|
+
flex_wrap: {values: FLEX_WRAP, token: "flex"},
|
201
|
+
flex: {values: FLEX, token: "flex"},
|
202
|
+
font_family: {values: FONT_FAMILY, token: "font"},
|
203
|
+
font_size: {values: FONT_SIZE, token: "text"},
|
204
|
+
font_style: {values: FONT_STYLE, token: nil},
|
205
|
+
font_variant_numeric: {values: FONT_VARIANT_NUMERIC, token: nil},
|
206
|
+
font_weight: {values: FONT_WEIGHT, token: "font"},
|
207
|
+
grid_auto_columns: {values: GRID_AUTO_COLUMNS, token: "auto-cols"},
|
208
|
+
grid_auto_flow: {values: GRID_AUTO_FLOW, token: "grid-flow"},
|
209
|
+
grid_auto_rows: {values: GRID_AUTO_ROWS, token: "auto-rows"},
|
210
|
+
group: {values: GROUP, token: "group"},
|
211
|
+
gap: {values: SPACING, token: "gap"},
|
212
|
+
gap_x: {values: SPACING, token: "gap-x"},
|
213
|
+
gap_y: {values: SPACING, token: "gap-y"},
|
214
|
+
grid_template_columns: {values: GRID_TEMPLATE_COLUMNS, token: "grid-cols", alias: :grid_cols},
|
215
|
+
grid_template_rows: {values: GRID_TEMPLATE_ROWS, token: "grid-rows"},
|
216
|
+
height: {values: SIZES, token: "h", alias: :h},
|
217
|
+
hyphens: {values: HYPHENS, token: "hyphens"},
|
218
|
+
inset: {values: SIZES, token: "inset"},
|
219
|
+
inset_x: {values: SIZES, token: "inset-x"},
|
220
|
+
inset_y: {values: SIZES, token: "inset-y"},
|
221
|
+
isolation: {values: ISOLATION, token: "isolation"},
|
222
|
+
justify_content: {values: JUSTIFY_CONTENT, token: "justify", alias: :justify},
|
223
|
+
justify_items: {values: JUSTIFY_ITEMS, token: "justify"},
|
224
|
+
justify_self: {values: JUSTIFY_SELF, token: "justify"},
|
225
|
+
left: {values: SIZES, token: "left"},
|
226
|
+
letter_spacing: {values: LETTER_SPACING, token: "tracking"},
|
227
|
+
line_height: {values: LINE_HEIGHT, token: "leading"},
|
228
|
+
list_style_image: {values: LIST_STYLE_IMAGE, token: "list-image"},
|
229
|
+
list_style_position: {values: LIST_STYLE_POSITION, token: "list"},
|
230
|
+
list_style_type: {values: LIST_STYLE_TYPE, token: "list"},
|
231
|
+
margin_bottom: {values: SPACING, token: "mb", alias: :mb},
|
232
|
+
margin_end: {values: SPACING, token: "me", alias: :me},
|
233
|
+
margin_left: {values: SPACING, token: "ml", alias: :ml},
|
234
|
+
margin_right: {values: SPACING, token: "mr", alias: :mr},
|
235
|
+
margin_start: {values: SPACING, token: "ms", alias: :ms},
|
236
|
+
margin_top: {values: SPACING, token: "mt", alias: :mt},
|
237
|
+
margin_x: {values: SPACING, token: "mx", alias: :mx},
|
238
|
+
margin_y: {values: SPACING, token: "my", alias: :my},
|
239
|
+
margin: {values: SPACING, token: "m", alias: :m},
|
240
|
+
max_height: {values: SIZES, token: "max-h", alias: :max_h},
|
241
|
+
max_width: {values: SIZES, token: "max-w", alias: :max_w},
|
242
|
+
min_height: {values: SIZES, token: "min-h", alias: :min_h},
|
243
|
+
min_width: {values: SIZES, token: "min-w", alias: :min_w},
|
244
|
+
mix_blend_mode: {values: MIX_BLEND_MODE, token: "mix-blend"},
|
245
|
+
object_fit: {values: OBJECT_FIT, token: "object"},
|
246
|
+
object_position: {values: OBJECT_POSITION, token: "object"},
|
247
|
+
opacity: {values: OPACITY, token: "opacity"},
|
248
|
+
order: {values: ORDER, token: "order"},
|
249
|
+
outline_color: {values: COLOR_WITH_WEIGHTS, token: "outline"},
|
250
|
+
outline_style: {values: OUTLINE_STYLE, token: "outline", alias: :outline},
|
251
|
+
outline_width: {values: OUTLINE_WIDTH, token: "outline"},
|
252
|
+
overflow: {values: OVERFLOW, token: "overflow"},
|
253
|
+
overflow_x: {values: OVERFLOW, token: "overflow-x"},
|
254
|
+
overflow_y: {values: OVERFLOW, token: "overflow-y"},
|
255
|
+
padding: {values: SPACING, token: "p", alias: :p},
|
256
|
+
padding_bottom: {values: SPACING, token: "pb", alias: :pb},
|
257
|
+
padding_left: {values: SPACING, token: "pl", alias: :pl},
|
258
|
+
padding_right: {values: SPACING, token: "pr", alias: :pr},
|
259
|
+
padding_top: {values: SPACING, token: "pt", alias: :pt},
|
260
|
+
padding_x: {values: SPACING, token: "px", alias: :px},
|
261
|
+
padding_y: {values: SPACING, token: "py", alias: :py},
|
262
|
+
place_items: {values: PLACE_ITEMS, token: "place"},
|
263
|
+
place_self: {values: PLACE_SELF, token: "place"},
|
264
|
+
pointer_events: {values: POINTER_EVENTS, token: "pointer"},
|
265
|
+
position: {values: POSITION, token: nil},
|
266
|
+
resize: {values: RESIZE, token: "resize"},
|
267
|
+
right: {values: SIZES, token: "right"},
|
268
|
+
rotate: {values: ROTATE, token: proc { _1.to_s.start_with?("-") ? "-rotate-#{_1.to_s[1..-1]}" : "rotate-#{_1}" }},
|
269
|
+
row_gap: {values: SPACING, token: "gap"},
|
270
|
+
row_span: {values: ROW_SPAN, token: "row-span"},
|
271
|
+
row_start: {values: ROW_START, token: "row-start"},
|
272
|
+
row_end: {values: ROW_END, token: "row-end"},
|
273
|
+
scale: {values: SCALE, token: "scale"},
|
274
|
+
scale_x: {values: SCALE, token: "scale-x"},
|
275
|
+
scale_y: {values: SCALE, token: "scale-y"},
|
276
|
+
scroll_behavior: {values: SCROLL_BEHAVIOR, token: "scroll"},
|
277
|
+
scroll_margin_bottom: {values: SPACING, token: "scroll-mb"},
|
278
|
+
scroll_margin_left: {values: SPACING, token: "scroll-ml"},
|
279
|
+
scroll_margin_right: {values: SPACING, token: "scroll-mr"},
|
280
|
+
scroll_margin_top: {values: SPACING, token: "scroll-mt"},
|
281
|
+
scroll_margin_x: {values: SPACING, token: "scroll-mx"},
|
282
|
+
scroll_margin_y: {values: SPACING, token: "scroll-my"},
|
283
|
+
scroll_margin_start: {values: SPACING, token: "scroll-ms"},
|
284
|
+
scroll_margin_end: {values: SPACING, token: "scroll-me"},
|
285
|
+
scroll_padding_bottom: {values: SPACING, token: "scroll-pb"},
|
286
|
+
scroll_padding_left: {values: SPACING, token: "scroll-pl"},
|
287
|
+
scroll_padding_right: {values: SPACING, token: "scroll-pr"},
|
288
|
+
scroll_padding_top: {values: SPACING, token: "scroll-pt"},
|
289
|
+
scroll_padding_x: {values: SPACING, token: "scroll-px"},
|
290
|
+
scroll_padding_y: {values: SPACING, token: "scroll-py"},
|
291
|
+
scroll_padding_start: {values: SPACING, token: "scroll-ps"},
|
292
|
+
scroll_padding_end: {values: SPACING, token: "scroll-pe"},
|
293
|
+
scroll_snap_align: {values: SCROLL_SNAP_ALIGN, token: "snap"},
|
294
|
+
scroll_snap_stop: {values: SCROLL_SNAP_STOP, token: "snap"},
|
295
|
+
scroll_snap_type: {values: SCROLL_SNAP_TYPE, token: "snap"},
|
296
|
+
start: {values: SIZES, token: "start"},
|
297
|
+
table_layout: {values: TABLE_LAYOUT, token: "table"},
|
298
|
+
text_align: {values: TEXT_ALIGN, token: "text"},
|
299
|
+
text_decoration_color: {values: COLOR_WITH_WEIGHTS, token: "decoration"},
|
300
|
+
text_decoration_style: {values: TEXT_DECORATION_STYLE, token: "decoration"},
|
301
|
+
text_decoration_thickness: {values: TEXT_DECORATION_THICKNESS, token: "decoration"},
|
302
|
+
text_decoration: {values: TEXT_DECORATION, token: proc { _1 }},
|
303
|
+
text_indent: {values: SPACING, token: "indent"},
|
304
|
+
text_overflow: {values: TEXT_OVERFLOW, token: proc { |v| (v == "truncate") ? "truncate" : "text-#{v}" }},
|
305
|
+
text_transform: {values: TEXT_TRANSFORM, token: nil},
|
306
|
+
text_underline_offset: {values: TEXT_UNDERLINE_OFFSET, token: "underline-offset"},
|
307
|
+
top: {values: SIZES, token: "top"},
|
308
|
+
transform_origin: {values: TRANSFORM_ORIGIN, token: "origin"},
|
309
|
+
transition: {values: TRANSITION + [true], token: "transition"},
|
310
|
+
translate_x: {values: TRANSLATE, token: proc { _1.to_s.start_with?("-") ? "-translate-#{_1.to_s[1..-1]}" : "translate-#{_1}" }},
|
311
|
+
translate_y: {values: TRANSLATE, token: proc { _1.to_s.start_with?("-") ? "-translate-y-#{_1.to_s[1..-1]}" : "translate-y-#{_1}" }},
|
312
|
+
user_select: {values: USER_SELECT, token: "select"},
|
313
|
+
vertical_align: {values: VERTICAL_ALIGN, token: "align"},
|
314
|
+
visibility: {values: VISIBILITY, token: nil},
|
315
|
+
whitespace: {values: WHITESPACE, token: "whitespace", alias: :white_space},
|
316
|
+
width: {values: SIZES, token: "w", alias: :w},
|
317
|
+
will_change: {values: WILL_CHANGE, token: "will-change"},
|
318
|
+
word_break: {values: WORD_BREAK, token: "break"},
|
319
|
+
z_index: {values: Z_INDEX, token: "z", alias: :z}
|
320
|
+
}.freeze
|
321
|
+
end
|
322
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Tailwindcss
|
2
|
+
module Helpers
|
3
|
+
extend self
|
4
|
+
|
5
|
+
def tailwind(**style_attributes)
|
6
|
+
Style.new(**style_attributes).to_s
|
7
|
+
end
|
8
|
+
alias tw tailwind
|
9
|
+
|
10
|
+
def ab(value)
|
11
|
+
ArbitraryValue.new(value)
|
12
|
+
end
|
13
|
+
|
14
|
+
# @param token [String] A value your Tailwindcss.theme.color_scheme keys
|
15
|
+
# @param weight [Integer] A value between 100 and 900
|
16
|
+
def color_scheme_token(token, weight = 500)
|
17
|
+
color_token(Tailwindcss.theme.color_scheme[token.to_sym], weight)
|
18
|
+
end
|
19
|
+
|
20
|
+
# @param color_token [String] A value your of any of tailwinds color tokens
|
21
|
+
# @param weight [Integer] A value between 100 and 900
|
22
|
+
def color_token(color_token, weight = 500)
|
23
|
+
"#{color_token}-#{weight}"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require "tailwindcss/installers/config_file_generator"
|
2
|
+
|
3
|
+
module Tailwindcss
|
4
|
+
class Installer
|
5
|
+
def call
|
6
|
+
Installers::ConfigFileGenerator.new.call
|
7
|
+
install_packages
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def install_packages
|
13
|
+
system("yarn init -y") unless File.exist?('./package.json')
|
14
|
+
system("yarn add -D tailwindcss autoprefixer postcss")
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require "tailwindcss"
|
2
|
+
require "json"
|
3
|
+
|
4
|
+
module Tailwindcss
|
5
|
+
module Installers
|
6
|
+
class ConfigFileGenerator
|
7
|
+
def call
|
8
|
+
File.write("./tailwind.config.js", tailwind_config_file_content)
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def content
|
14
|
+
value = Tailwindcss.config.content
|
15
|
+
return value unless value.respond_to?(:call)
|
16
|
+
|
17
|
+
value.call
|
18
|
+
end
|
19
|
+
|
20
|
+
def tailwind_config_file_content
|
21
|
+
content_option = (content + ["./tmp/tailwindcss"]).map { "#{_1}/**/*" }
|
22
|
+
<<~TAILWIND_CONFIG
|
23
|
+
/** @type {import('tailwindcss').Config} */
|
24
|
+
|
25
|
+
/** this file was generated automatically, please do not modify it directly!! */
|
26
|
+
/** instead change your tailwindcss-rb config and run `bundle exec rake tailwindcss:generate_config_file` */
|
27
|
+
|
28
|
+
export default {
|
29
|
+
content: #{content_option.to_json},
|
30
|
+
prefix: '#{Tailwindcss.config.prefix}',
|
31
|
+
#{Tailwindcss.config.tailwind_config_overrides.call.map { |k, v| "#{k}: #{v}," }.join("\n")}
|
32
|
+
}
|
33
|
+
TAILWIND_CONFIG
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require "ostruct"
|
2
|
+
require "tailwindcss/style_attributes_to_list_converter"
|
3
|
+
|
4
|
+
module Tailwindcss
|
5
|
+
class Style < ::OpenStruct
|
6
|
+
def initialize(attributes = {})
|
7
|
+
super
|
8
|
+
@attributes = attributes
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_a
|
12
|
+
to_string_converter.call(**@attributes)
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_s
|
16
|
+
to_a.join(" ")
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_html_attributes
|
20
|
+
{class: to_s}
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def to_string_converter
|
26
|
+
@to_string_converter ||= StyleAttributesToListConverter.new
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|