Class: Proscenium::CssModule::Transformer

Inherits:
Object
  • Object
show all
Defined in:
lib/proscenium/css_module/transformer.rb

Constant Summary collapse

FILE_EXT =
'.module.css'

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(source_path) ⇒ Transformer

Returns a new instance of Transformer.



11
12
13
14
15
16
# File 'lib/proscenium/css_module/transformer.rb', line 11

def initialize(source_path)
  return unless (@source_path = source_path)

  @source_path = Pathname.new(@source_path) unless @source_path.is_a?(Pathname)
  @source_path = @source_path.sub_ext(FILE_EXT) unless @source_path.to_s.end_with?(FILE_EXT)
end

Class Method Details

.class_names(path, *names) ⇒ Object



7
8
9
# File 'lib/proscenium/css_module/transformer.rb', line 7

def self.class_names(path, *names)
  new(path).class_names(*names)
end

Instance Method Details

#class_name!(name, original_name, path: @source_path) ⇒ Object



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/proscenium/css_module/transformer.rb', line 64

def class_name!(name, original_name, path: @source_path)
  unless path
    raise Proscenium::CssModule::TransformError.new(original_name, 'CSS module path not given')
  end

  resolved_path = Resolver.resolve(path.to_s)
  digest = Importer.import(resolved_path)

  transformed_path = ''
  transformed_path = "__#{resolved_path[1..].gsub(%r{[@/.+]}, '-')}" if Rails.env.development?
  transformed_name = name.to_s
  transformed_name = if transformed_name.start_with?('_')
                       "_#{transformed_name[1..]}-#{digest}#{transformed_path}"
                     else
                       "#{transformed_name}-#{digest}#{transformed_path}"
                     end

  [transformed_name, resolved_path]
end

#class_names(*names, require_prefix: true) ⇒ Array<String>

Transform each of the given class ‘names` to their respective CSS module name, which consist of the name, and suffixed with the digest of the resolved source path.

Any name beginning with ‘@’ will be transformed to a CSS module name. If ‘require_prefix` is false, then all names will be transformed to a CSS module name regardless of whether or not they begin with ’@‘.

class_names :@my_module_name, :my_class_name

Note that the generated digest is based on the resolved (URL) path, not the original path.

You can also provide a path specifier and class name. The path will be the URL path to a stylesheet. The class name will be the name of the class to transform.

class_names "/lib/button@default"
class_names "mypackage/button@large"
class_names "@scoped/package/button@small"

Parameters:

  • names (String, Symbol, Array<String,Symbol>)
  • require_prefix: (Boolean) (defaults to: true)

    whether or not to require the ‘@` prefix.

Returns:

  • (Array<String>)

    the transformed CSS module names.



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/proscenium/css_module/transformer.rb', line 39

def class_names(*names, require_prefix: true)
  names.map do |name|
    original_name = name.dup
    name = name.to_s if name.is_a?(Symbol)

    if name.include?('/')
      if name.start_with?('@')
        # Scoped bare specifier (eg. "@scoped/package/lib/button@default").
        _, path, name = name.split('@')
        path = "@#{path}"
      else
        # Local path (eg. /some/path/to/button@default") or bare specifier (eg.
        # "mypackage/lib/button@default").
        path, name = name.split('@')
      end

      class_name! name, original_name, path: "#{path}#{FILE_EXT}"
    elsif name.start_with?('@')
      class_name! name[1..], original_name
    else
      require_prefix ? name : class_name!(name, original_name)
    end
  end
end