skeleton-loader 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +401 -0
- data/app/assets/javascripts/skeleton_loader.js +2 -0
- data/app/assets/javascripts/skeleton_loader.js.LICENSE.txt +1 -0
- data/app/assets/stylesheets/skeleton_loader.css +83 -0
- data/app/controllers/skeleton_loader/skeleton_loader_controller.rb +60 -0
- data/app/javascript/client_skeleton_loader.js +234 -0
- data/app/javascript/server_skeleton_loader.js +113 -0
- data/app/javascript/skeleton_loader.js +6 -0
- data/config/routes.rb +5 -0
- data/lib/generators/skeleton_loader/add_templates_generator.rb +16 -0
- data/lib/generators/skeleton_loader/reset_templates_generator.rb +16 -0
- data/lib/generators/skeleton_loader/templates/_card.html.erb +31 -0
- data/lib/generators/skeleton_loader/templates/_comment.html.erb +61 -0
- data/lib/generators/skeleton_loader/templates/_default.html.erb +23 -0
- data/lib/generators/skeleton_loader/templates/_gallery.html.erb +19 -0
- data/lib/generators/skeleton_loader/templates/_paragraph.html.erb +28 -0
- data/lib/generators/skeleton_loader/templates/_product.html.erb +49 -0
- data/lib/generators/skeleton_loader/templates/_profile.html.erb +28 -0
- data/lib/skeleton-loader.rb +7 -0
- data/lib/skeleton_loader/configuration.rb +68 -0
- data/lib/skeleton_loader/engine.rb +42 -0
- data/lib/skeleton_loader/skeleton_element_generator.rb +49 -0
- data/lib/skeleton_loader/template_path_finder.rb +24 -0
- data/lib/skeleton_loader/template_renderer.rb +41 -0
- data/lib/skeleton_loader/version.rb +5 -0
- data/lib/skeleton_loader/view_helpers.rb +19 -0
- data/lib/skeleton_loader.rb +36 -0
- data/lib/tasks/skeleton_loader_tasks.rake +23 -0
- metadata +91 -0
@@ -0,0 +1,68 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SkeletonLoader
|
4
|
+
# Configuration class manages settings for the SkeletonLoader gem.
|
5
|
+
class Configuration
|
6
|
+
TEMPLATE_DEFAULTS = {
|
7
|
+
card: { width: 200, count: 3, per_row: 3 },
|
8
|
+
comment: { width: 900, count: 2, per_row: 1 },
|
9
|
+
default: { width: 900, count: 1, per_row: 1 },
|
10
|
+
gallery: { width: 320, count: 3, per_row: 3 },
|
11
|
+
paragraph: { width: 900, count: 1, per_row: 1 },
|
12
|
+
product: { width: 320, count: 3, per_row: 3 },
|
13
|
+
profile: { width: 320, count: 3, per_row: 3 }
|
14
|
+
}.freeze
|
15
|
+
|
16
|
+
attr_reader :scale, :template_paths, :animation_type,
|
17
|
+
:additional_allowed_tags, :additional_allowed_attributes,
|
18
|
+
:additional_allowed_css_properties, :templates
|
19
|
+
|
20
|
+
def initialize
|
21
|
+
reset!
|
22
|
+
end
|
23
|
+
|
24
|
+
# Resets all configuration options to their defaults.
|
25
|
+
def reset!
|
26
|
+
set_general_defaults
|
27
|
+
set_template_defaults
|
28
|
+
set_animation_defaults
|
29
|
+
set_security_defaults
|
30
|
+
end
|
31
|
+
|
32
|
+
def base_options
|
33
|
+
{
|
34
|
+
scale: @scale,
|
35
|
+
animation_type: @animation_type,
|
36
|
+
additional_allowed_tags: @additional_allowed_tags,
|
37
|
+
additional_allowed_attributes: @additional_allowed_attributes,
|
38
|
+
additional_allowed_css_properties: @additional_allowed_css_properties
|
39
|
+
}
|
40
|
+
end
|
41
|
+
|
42
|
+
# Returns the default options for a specific template type
|
43
|
+
def template_defaults_for(type)
|
44
|
+
@templates[type&.to_sym || :default] || @templates[:default]
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def set_general_defaults
|
50
|
+
@scale = 1.0
|
51
|
+
@template_paths = []
|
52
|
+
end
|
53
|
+
|
54
|
+
def set_template_defaults
|
55
|
+
@templates = TEMPLATE_DEFAULTS.dup
|
56
|
+
end
|
57
|
+
|
58
|
+
def set_animation_defaults
|
59
|
+
@animation_type = "sl-gradient"
|
60
|
+
end
|
61
|
+
|
62
|
+
def set_security_defaults
|
63
|
+
@additional_allowed_tags = []
|
64
|
+
@additional_allowed_attributes = {}
|
65
|
+
@additional_allowed_css_properties = []
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SkeletonLoader
|
4
|
+
# SkeletonLoader::Engine integrates the SkeletonLoader gem with Rails,
|
5
|
+
# configuring asset paths, pre-compiling assets, and including view helpers
|
6
|
+
# in Action View.
|
7
|
+
class Engine < ::Rails::Engine
|
8
|
+
isolate_namespace SkeletonLoader
|
9
|
+
|
10
|
+
initializer "skeleton_loader.assets" do |app|
|
11
|
+
# CSS always through asset pipeline
|
12
|
+
app.config.assets.paths << root.join("app/assets/stylesheets")
|
13
|
+
app.config.assets.precompile += %w[skeleton_loader.css]
|
14
|
+
|
15
|
+
if defined?(Webpacker) || defined?(Shakapacker)
|
16
|
+
# You should use npm package
|
17
|
+
elsif defined?(Importmap::Engine)
|
18
|
+
gem_js_path = root.join("app/assets/javascripts").to_s
|
19
|
+
app.config.assets.paths.reject! { |path| path.to_s == gem_js_path }
|
20
|
+
app.config.assets.paths << root.join("dist")
|
21
|
+
app.config.assets.precompile += %w[skeleton_loader.js]
|
22
|
+
else
|
23
|
+
app.config.assets.paths << root.join("app/assets/javascripts")
|
24
|
+
app.config.assets.precompile += %w[skeleton_loader.js]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
initializer "skeleton_loader.view_helpers" do
|
29
|
+
ActiveSupport.on_load(:action_view) { include SkeletonLoader::ViewHelpers }
|
30
|
+
end
|
31
|
+
|
32
|
+
initializer "skeleton_loader.append_routes" do |app|
|
33
|
+
app.routes.prepend do
|
34
|
+
mount SkeletonLoader::Engine, at: "/skeleton_loader", as: "skeleton_loader_engine"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
initializer "skeleton_loader.append_migrations" do
|
39
|
+
config.paths["app/controllers"] << File.expand_path("../app/controllers", __dir__)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SkeletonLoader
|
4
|
+
#
|
5
|
+
# Generates skeleton loader element
|
6
|
+
#
|
7
|
+
class SkeletonElementGenerator
|
8
|
+
class << self
|
9
|
+
def generate(content_id:, options: {}, context: :view, &block)
|
10
|
+
validate_content_id!(content_id)
|
11
|
+
content = generate_content(options, &block)
|
12
|
+
|
13
|
+
css_class = context == :controller ? "skeleton-loader--client" : "skeleton-loader--server"
|
14
|
+
wrap_content(content, content_id, css_class)
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def validate_content_id!(content_id)
|
20
|
+
raise SkeletonLoader::Error, "content_id is required" if content_id.blank?
|
21
|
+
end
|
22
|
+
|
23
|
+
def generate_content(options, &block)
|
24
|
+
content = if block_given?
|
25
|
+
raise Error, "Options cannot be used with a block" unless options.empty?
|
26
|
+
|
27
|
+
block.call
|
28
|
+
else
|
29
|
+
type = options[:type] || "default"
|
30
|
+
template_path = TemplatePathFinder.find(type)
|
31
|
+
TemplateRenderer.render(template_path, options)
|
32
|
+
end
|
33
|
+
# rubocop:disable Rails/OutputSafety
|
34
|
+
# NOTE: The following use of `html_safe` is intentional
|
35
|
+
content.html_safe
|
36
|
+
# rubocop:enable Rails/OutputSafety
|
37
|
+
end
|
38
|
+
|
39
|
+
def wrap_content(content, content_id, css_class)
|
40
|
+
ActionController::Base.helpers.content_tag(
|
41
|
+
:div,
|
42
|
+
content,
|
43
|
+
class: css_class,
|
44
|
+
data: { content_id: content_id }
|
45
|
+
)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SkeletonLoader
|
4
|
+
#
|
5
|
+
# This class is responsible for locating a specific template file by type.
|
6
|
+
# It searches through configured paths and defaults to searching in
|
7
|
+
# `app/views/skeleton_loader` within the Rails root directory.
|
8
|
+
# Raises an error if the template is not found.
|
9
|
+
#
|
10
|
+
class TemplatePathFinder
|
11
|
+
def self.find(type)
|
12
|
+
template_name = "_#{type}.html.erb"
|
13
|
+
search_paths = SkeletonLoader.configuration.template_paths +
|
14
|
+
[Rails.root.join("app/views/skeleton_loader")]
|
15
|
+
|
16
|
+
search_paths.each do |path|
|
17
|
+
full_path = File.join(path, template_name)
|
18
|
+
return full_path if File.exist?(full_path)
|
19
|
+
end
|
20
|
+
|
21
|
+
raise "Template '#{template_name}' not found in any of the specified paths."
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SkeletonLoader
|
4
|
+
#
|
5
|
+
# This class handles rendering templates for skeleton loaders. It retrieves
|
6
|
+
# template files and prepares them for display as placeholders.
|
7
|
+
#
|
8
|
+
class TemplateRenderer
|
9
|
+
def self.render(template_path, options = {})
|
10
|
+
new(template_path, options).render
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize(template_path, options = {})
|
14
|
+
@template_path = template_path
|
15
|
+
@options = merge_options(options)
|
16
|
+
|
17
|
+
# Dynamically set instance variables for template rendering
|
18
|
+
@options.each do |key, value|
|
19
|
+
instance_variable_set("@#{key}", value)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def render
|
24
|
+
template_content = File.read(@template_path)
|
25
|
+
erb = ERB.new(template_content)
|
26
|
+
erb.result(binding)
|
27
|
+
rescue StandardError => e
|
28
|
+
raise "Error rendering template at #{@template_path}: #{e.message}"
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def merge_options(options)
|
34
|
+
config = SkeletonLoader.configuration
|
35
|
+
|
36
|
+
config.base_options
|
37
|
+
.merge(config.template_defaults_for(options[:type]))
|
38
|
+
.merge(options)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SkeletonLoader
|
4
|
+
# Provides helper methods for rendering skeleton loaders in views.
|
5
|
+
module ViewHelpers
|
6
|
+
def skeleton_loader(content_id:, **options, &block)
|
7
|
+
SkeletonElementGenerator.generate(content_id: content_id, options: options, &block)
|
8
|
+
rescue StandardError => e
|
9
|
+
handle_error(e)
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def handle_error(error)
|
15
|
+
Rails.logger.error "Error in skeleton_loader helper: #{error.message}"
|
16
|
+
raise
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "skeleton_loader/version"
|
4
|
+
require "skeleton_loader/configuration"
|
5
|
+
require "skeleton_loader/view_helpers"
|
6
|
+
require "skeleton_loader/template_path_finder"
|
7
|
+
require "skeleton_loader/template_renderer"
|
8
|
+
require "skeleton_loader/skeleton_element_generator"
|
9
|
+
require "skeleton_loader/engine"
|
10
|
+
|
11
|
+
require "action_view"
|
12
|
+
#
|
13
|
+
# This module serves as the entry point for the SkeletonLoader gem, which provides
|
14
|
+
# configurable skeleton loaders for Rails views. It includes configuration methods,
|
15
|
+
# custom error handling, and auto-loading for key classes and helpers.
|
16
|
+
#
|
17
|
+
# Usage:
|
18
|
+
# Configure by calling `SkeletonLoader.configure` and provide settings, such as
|
19
|
+
# template paths. SkeletonLoader provides view helpers and uses ActionView for
|
20
|
+
# generating HTML components for skeleton loaders.
|
21
|
+
#
|
22
|
+
module SkeletonLoader
|
23
|
+
class Error < StandardError; end
|
24
|
+
|
25
|
+
def self.configuration
|
26
|
+
@configuration ||= Configuration.new
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.configure
|
30
|
+
yield(configuration) if block_given?
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.reset
|
34
|
+
@configuration = Configuration.new
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
namespace :skeleton_loader do
|
4
|
+
desc "Build JavaScript for all targets"
|
5
|
+
task build_js: :environment do
|
6
|
+
# Run webpack build
|
7
|
+
system("yarn build")
|
8
|
+
|
9
|
+
# Ensure assets/javascripts exists
|
10
|
+
FileUtils.mkdir_p("app/assets/javascripts")
|
11
|
+
|
12
|
+
# Copy webpack build to asset pipeline
|
13
|
+
FileUtils.cp(
|
14
|
+
"dist/skeleton-loader.js",
|
15
|
+
"app/assets/javascripts/skeleton_loader.js"
|
16
|
+
)
|
17
|
+
|
18
|
+
puts "✓ Built successfully!"
|
19
|
+
puts " → Source: app/javascript/"
|
20
|
+
puts " → NPM build: dist/skeleton-loader.js"
|
21
|
+
puts " → Asset Pipeline: app/assets/javascripts/skeleton_loader.js"
|
22
|
+
end
|
23
|
+
end
|
metadata
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: skeleton-loader
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Emad Rahimi
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2024-12-07 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 5.0.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 5.0.0
|
27
|
+
description: Provides customizable, responsive skeleton loaders for Rails views.
|
28
|
+
email:
|
29
|
+
- 121079771+ersync@users.noreply.github.com
|
30
|
+
executables: []
|
31
|
+
extensions: []
|
32
|
+
extra_rdoc_files: []
|
33
|
+
files:
|
34
|
+
- LICENSE.txt
|
35
|
+
- README.md
|
36
|
+
- app/assets/javascripts/skeleton_loader.js
|
37
|
+
- app/assets/javascripts/skeleton_loader.js.LICENSE.txt
|
38
|
+
- app/assets/stylesheets/skeleton_loader.css
|
39
|
+
- app/controllers/skeleton_loader/skeleton_loader_controller.rb
|
40
|
+
- app/javascript/client_skeleton_loader.js
|
41
|
+
- app/javascript/server_skeleton_loader.js
|
42
|
+
- app/javascript/skeleton_loader.js
|
43
|
+
- config/routes.rb
|
44
|
+
- lib/generators/skeleton_loader/add_templates_generator.rb
|
45
|
+
- lib/generators/skeleton_loader/reset_templates_generator.rb
|
46
|
+
- lib/generators/skeleton_loader/templates/_card.html.erb
|
47
|
+
- lib/generators/skeleton_loader/templates/_comment.html.erb
|
48
|
+
- lib/generators/skeleton_loader/templates/_default.html.erb
|
49
|
+
- lib/generators/skeleton_loader/templates/_gallery.html.erb
|
50
|
+
- lib/generators/skeleton_loader/templates/_paragraph.html.erb
|
51
|
+
- lib/generators/skeleton_loader/templates/_product.html.erb
|
52
|
+
- lib/generators/skeleton_loader/templates/_profile.html.erb
|
53
|
+
- lib/skeleton-loader.rb
|
54
|
+
- lib/skeleton_loader.rb
|
55
|
+
- lib/skeleton_loader/configuration.rb
|
56
|
+
- lib/skeleton_loader/engine.rb
|
57
|
+
- lib/skeleton_loader/skeleton_element_generator.rb
|
58
|
+
- lib/skeleton_loader/template_path_finder.rb
|
59
|
+
- lib/skeleton_loader/template_renderer.rb
|
60
|
+
- lib/skeleton_loader/version.rb
|
61
|
+
- lib/skeleton_loader/view_helpers.rb
|
62
|
+
- lib/tasks/skeleton_loader_tasks.rake
|
63
|
+
homepage: https://github.com/ersync/skeleton-loader
|
64
|
+
licenses:
|
65
|
+
- MIT
|
66
|
+
metadata:
|
67
|
+
allowed_push_host: https://rubygems.org
|
68
|
+
homepage_uri: https://github.com/ersync/skeleton-loader
|
69
|
+
source_code_uri: https://github.com/ersync/skeleton-loader
|
70
|
+
changelog_uri: https://github.com/ersync/skeleton-loader/blob/main/CHANGELOG.md
|
71
|
+
rubygems_mfa_required: 'true'
|
72
|
+
post_install_message:
|
73
|
+
rdoc_options: []
|
74
|
+
require_paths:
|
75
|
+
- lib
|
76
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
77
|
+
requirements:
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: 2.5.0
|
81
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
82
|
+
requirements:
|
83
|
+
- - ">="
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
requirements: []
|
87
|
+
rubygems_version: 3.1.6
|
88
|
+
signing_key:
|
89
|
+
specification_version: 4
|
90
|
+
summary: A Ruby on Rails gem for skeleton loading screens.
|
91
|
+
test_files: []
|