essence 0.4.0 → 1.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f50eba3dff7653e3e65f0f1e2dabb114782f0e0bf09cb64995118d86427b65b1
4
- data.tar.gz: 21ce8e60063dc1930aa31eb4f3bb22be5045ffefd15fed55db823178dcc0d4da
3
+ metadata.gz: 59a6855e33ea69ca4e5f1847a24cbaf2db2991629c7f3d1cfd25a8c693fd0b2a
4
+ data.tar.gz: 2dc9d1a6297541a6db339295a8526b2572ad27b4d1d2b1e1b908f25002ee2020
5
5
  SHA512:
6
- metadata.gz: 2a6738cd42f2504d0b96be1b711abba2a4788cc6a411e27f2d47d62716cf6051b3f3835e95a68d45103fc47da909f1d02c7fe2c1226fd661362c337d89df4e09
7
- data.tar.gz: ac414b095aa27a017b2438bcf9da0bfd2e8f638c21525b1bf3f749573fbb0771f3250ae418151f5175ef9f8ff44d25ef172d56317e7cc640836e3c25eeddb07d
6
+ metadata.gz: 1667d7a7bf8a96772fc0de875a7db052962d17f7dd7d09bdbb958616124796fd398044bca76753a9ff4797232a40c0aa2e99ac1503e683047e07919354377515
7
+ data.tar.gz: 411224f217aa0e5a0731e5137054650827b6a002a878afcac158725d03cdf2dc954789a449eaf56e18afd94d9231222d9782c337df655d018b6299f42728ba78
@@ -1,34 +1,47 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'fileutils'
4
+
3
5
  module Essence
4
6
  module CLI
5
7
  class Add < Dry::CLI::Command
6
- desc "Add an Essence component to your project"
7
- argument :component_name, required: true, desc: "Component name"
8
+ desc "Add an Essence UI component"
9
+ argument :component, required: true, desc: "Component name"
8
10
  example Essence.component_names
9
11
 
10
12
  def call(*args)
11
- component_name = args[0][:component_name]
12
- key = component_name.to_sym
13
- has_stimulus_controller = Essence.components[key][:stimulus] || false
13
+ puts "[Essence UI] Fetching..."
14
14
 
15
- return puts "> #{component_name}: component unsupported" unless Essence.component_keys.include?(key)
16
- puts "> [Essence] #{Essence.components[key][:name]}"
15
+ slug = args[0][:component].to_sym
16
+ specification = ::Essence::Client.new.get_component(slug:)
17
+ return puts "[Essence UI] Component not found. Stopping" if specification == ""
17
18
 
18
- if has_stimulus_controller
19
- Essence::CLI::Commands.copy_controller(component_name:)
20
- puts "> [Stimulus] #{Essence::CLI::Commands::STIMULUS_CONTROLLERS_DESTINATION_DIR.join("#{component_name}_controller.js")}"
21
- end
22
19
 
23
- Essence::CLI::Commands.copy_component(component_name:)
24
- Essence::CLI::Commands.replace_component_contents(component_name:)
25
- Essence::CLI::Commands.replace_component_contents(
26
- component_name:,
27
- from: Essence::CLI::Commands::COMPONENT_DEFINITION_SUFFIX,
28
- to: Essence::CLI::Commands::PHLEX_COMPONENT_DEFINITION_SUFFIX
29
- )
20
+ files = specification.dig("files")
21
+ return puts "[Essence UI] Something went wrong. Stopping" unless files
22
+
23
+ files.each{ |data| insert_file(slug:, data:) }
24
+ puts "[Essence UI] #{specification.dig("title")} has been successfully added!"
25
+ end
26
+
27
+ private
28
+
29
+ def insert_file(slug:, data:)
30
+ destination_path = build_destination_path(kind: data["kind"], slug:)
31
+ ::FileUtils.mkdir_p(destination_path.dirname)
32
+ ::File.write(destination_path, data.dig("content"))
33
+ puts "[Essence UI] Adding #{destination_path}"
34
+ end
30
35
 
31
- puts "> [Phlex] #{Essence::CLI::Commands::DESTINATION_DIR.join("#{component_name}.rb")}"
36
+ def build_destination_path(kind:, slug:)
37
+ case kind
38
+ when "phlex"
39
+ ::Essence.configuration.phlex_components_dir.join("#{slug}.rb")
40
+ when "stimulus"
41
+ ::Essence.configuration.stimulus_controllers_dir.join("#{slug}_controller.rb")
42
+ else
43
+ nil
44
+ end
32
45
  end
33
46
  end
34
47
  end
@@ -7,21 +7,11 @@ module Essence
7
7
  BASE_DEFINITION_PREFIX = "class Essence::Essence"
8
8
  PHLEX_BASE_DEFINITION_PREFIX = "class Components::Essence"
9
9
 
10
- desc "Install Essence to your project"
10
+ desc "Install Essence UI to your codebase"
11
11
  def call(*)
12
- puts "> Installing Essence..."
13
- puts "> Copying base component to your project"
14
- Essence::CLI::Commands.copy_component(component_name: BASE_COMPONENT_NAME)
15
- Essence::CLI::Commands.replace_component_contents(
16
- component_name: BASE_COMPONENT_NAME,
17
- from: BASE_DEFINITION_PREFIX,
18
- to: PHLEX_BASE_DEFINITION_PREFIX
19
- )
20
- # Essence::CLI::Commands.rename_component_file(
21
- # from: Essence::CLI::Commands::DESTINATION_DIR.join("#{BASE_COMPONENT_NAME}.rb"),
22
- # to: Essence::CLI::Commands::DESTINATION_DIR.join("essence.rb")
23
- # )
24
- puts "> Essence has been successfully installed!"
12
+ puts "[Essence UI] Installing..."
13
+ ::Essence::CLI::Add.new.call(*[{component: "essence"}])
14
+ puts "[Essence UI] Done!"
25
15
  end
26
16
  end
27
17
  end
@@ -3,7 +3,7 @@
3
3
  module Essence
4
4
  module CLI
5
5
  class Version < Dry::CLI::Command
6
- desc "Print Essence version"
6
+ desc "Print version of Essence UI CLI"
7
7
 
8
8
  def call(*)
9
9
  puts Essence::VERSION
data/lib/essence/cli.rb CHANGED
@@ -16,62 +16,9 @@ module Essence
16
16
  module Commands
17
17
  extend Dry::CLI::Registry
18
18
 
19
- # Constants
20
- STIMULUS_CONTROLLERS_DIR = Pathname.new(File.expand_path("stimulus", __dir__))
21
- STIMULUS_CONTROLLERS_DESTINATION_DIR = Pathname.new(File.expand_path(Dir.pwd)).join(::Essence.configuration.stimulus_controller_path)
22
-
23
- COMPONENTS_DIR = Pathname.new(File.expand_path("components", __dir__))
24
- DESTINATION_DIR = Pathname.new(File.expand_path(Dir.pwd)).join(::Essence.configuration.phlex_components_path)
25
-
26
- COMPONENT_DEFINITION_PREFIX = "class Essence::"
27
- COMPONENT_DEFINITION_SUFFIX = "< Essence::Essence"
28
- PHLEX_COMPONENT_DEFINITION_PREFIX = "class Components::"
29
- PHLEX_COMPONENT_DEFINITION_SUFFIX = "< Components::Essence"
30
-
31
- # Registering commands
32
19
  register "add", Add, aliases: ["a", "generate", "g"]
33
20
  register "install", Install, aliases: ["i"]
34
21
  register "version", Version, aliases: ["v", "-v", "--version"]
35
-
36
- private
37
-
38
- # UTILITIES
39
- # PHLEX COMPONENTS
40
- def self.copy_component(component_name:)
41
- source_path = COMPONENTS_DIR.join("#{component_name}.rb")
42
- destination_path = DESTINATION_DIR.join("#{component_name}.rb")
43
-
44
- FileUtils.mkdir_p(DESTINATION_DIR)
45
- FileUtils.copy(source_path, destination_path)
46
- end
47
-
48
- def self.replace_component_contents(
49
- component_name:,
50
- from: COMPONENT_DEFINITION_PREFIX,
51
- to: PHLEX_COMPONENT_DEFINITION_PREFIX
52
- )
53
- component_file = DESTINATION_DIR.join("#{component_name}.rb")
54
- return unless File.exist?(component_file)
55
-
56
- replaced_content = File.read(component_file).gsub(from, to)
57
- File.write(component_file, replaced_content)
58
- end
59
-
60
- def self.rename_component_file(from:, to:)
61
- return if from.nil? || to.nil?
62
- return unless File.exist?(from)
63
-
64
- FileUtils.mv(from, to)
65
- end
66
-
67
- # STIMULUS CONTROLLERS
68
- def self.copy_controller(component_name:)
69
- source_path = STIMULUS_CONTROLLERS_DIR.join("#{component_name}_controller.js")
70
- destination_path = STIMULUS_CONTROLLERS_DESTINATION_DIR.join("#{component_name}_controller.js")
71
-
72
- FileUtils.mkdir_p(STIMULUS_CONTROLLERS_DESTINATION_DIR)
73
- FileUtils.copy(source_path, destination_path)
74
- end
75
22
  end
76
23
  end
77
24
  end
@@ -0,0 +1,22 @@
1
+ require "faraday"
2
+
3
+ module Essence
4
+ class Client
5
+ attr_reader :client
6
+
7
+ def initialize(**attributes)
8
+ @client = ::Faraday.new(url: "https://essenceui.com/") do |f|
9
+ f.request :authorization, "Bearer", -> { ::Essence.configuration.licence_key }
10
+ f.request :json
11
+ f.response :json
12
+ end
13
+ end
14
+
15
+ def get_component(slug: nil)
16
+ return if nil
17
+ client.get("api/v1/components/#{slug}").body
18
+ rescue Faraday::Error => error
19
+ puts error
20
+ end
21
+ end
22
+ end
@@ -1,13 +1,19 @@
1
1
  module Essence
2
2
  class Configuration
3
- attr_accessor :api_key
3
+ attr_accessor :licence_key
4
4
  attr_accessor :phlex_components_path
5
- attr_accessor :stimulus_controller_path
5
+ attr_accessor :stimulus_controllers_path
6
+
7
+ attr_reader :phlex_components_dir
8
+ attr_reader :stimulus_controllers_dir
6
9
 
7
10
  def initialize
8
- @api_key = nil
11
+ @licence_key = nil
9
12
  @phlex_components_path = "app/components"
10
- @stimulus_controller_path = "app/javascript/controllers/essence"
13
+ @stimulus_controllers_path = "app/javascript/controllers/essence"
14
+
15
+ @phlex_components_dir = Pathname.new(File.expand_path(Dir.pwd)).join(@phlex_components_path)
16
+ @stimulus_controllers_dir = Pathname.new(File.expand_path(Dir.pwd)).join(@stimulus_controllers_path)
11
17
  end
12
18
  end
13
19
  end
@@ -1,3 +1,3 @@
1
1
  module Essence
2
- VERSION = "0.4.0"
2
+ VERSION = "1.0.0"
3
3
  end
data/lib/essence.rb CHANGED
@@ -1,12 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "tailwind_merge"
3
+ # require "tailwind_merge"
4
4
 
5
5
  require_relative "essence/configuration"
6
6
  require_relative "essence/definitions"
7
7
 
8
8
  module Essence
9
9
  autoload :CLI, "essence/cli"
10
+ autoload :Client, "essence/client"
10
11
 
11
12
  class << self
12
13
  def root_path
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: essence
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Elvinas Predkelis
8
- autorequire:
9
8
  bindir: exe
10
9
  cert_chain: []
11
- date: 2025-04-15 00:00:00.000000000 Z
10
+ date: 2025-05-11 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: dry-cli
@@ -31,33 +30,19 @@ dependencies:
31
30
  - !ruby/object:Gem::Version
32
31
  version: '2'
33
32
  - !ruby/object:Gem::Dependency
34
- name: phlex
33
+ name: faraday
35
34
  requirement: !ruby/object:Gem::Requirement
36
35
  requirements:
37
- - - ">="
36
+ - - "~>"
38
37
  - !ruby/object:Gem::Version
39
- version: 2.0.0.rc1
38
+ version: '2.13'
40
39
  type: :runtime
41
40
  prerelease: false
42
41
  version_requirements: !ruby/object:Gem::Requirement
43
42
  requirements:
44
- - - ">="
45
- - !ruby/object:Gem::Version
46
- version: 2.0.0.rc1
47
- - !ruby/object:Gem::Dependency
48
- name: tailwind_merge
49
- requirement: !ruby/object:Gem::Requirement
50
- requirements:
51
- - - ">="
52
- - !ruby/object:Gem::Version
53
- version: 0.13.3
54
- type: :runtime
55
- prerelease: false
56
- version_requirements: !ruby/object:Gem::Requirement
57
- requirements:
58
- - - ">="
43
+ - - "~>"
59
44
  - !ruby/object:Gem::Version
60
- version: 0.13.3
45
+ version: '2.13'
61
46
  description: Component library for Ruby applications using Phlex
62
47
  email:
63
48
  - elvinas@primevise.com
@@ -73,30 +58,9 @@ files:
73
58
  - lib/essence/cli/add.rb
74
59
  - lib/essence/cli/install.rb
75
60
  - lib/essence/cli/version.rb
76
- - lib/essence/components/accordion.rb
77
- - lib/essence/components/alert.rb
78
- - lib/essence/components/avatar.rb
79
- - lib/essence/components/badge.rb
80
- - lib/essence/components/button.rb
81
- - lib/essence/components/checkbox.rb
82
- - lib/essence/components/dialog.rb
83
- - lib/essence/components/dropdown.rb
84
- - lib/essence/components/essence.rb
85
- - lib/essence/components/heading.rb
86
- - lib/essence/components/input.rb
87
- - lib/essence/components/label.rb
88
- - lib/essence/components/link.rb
89
- - lib/essence/components/metric.rb
90
- - lib/essence/components/row.rb
91
- - lib/essence/components/separator.rb
92
- - lib/essence/components/skeleton.rb
93
- - lib/essence/components/switch.rb
94
- - lib/essence/components/tabs.rb
95
- - lib/essence/components/text.rb
61
+ - lib/essence/client.rb
96
62
  - lib/essence/configuration.rb
97
63
  - lib/essence/definitions.rb
98
- - lib/essence/stimulus/switch_controller.js
99
- - lib/essence/stimulus/tabs_controller.js
100
64
  - lib/essence/version.rb
101
65
  homepage: https://rubygems.org/gems/essence
102
66
  licenses:
@@ -104,7 +68,6 @@ licenses:
104
68
  metadata:
105
69
  homepage_uri: https://rubygems.org/gems/essence
106
70
  source_code_uri: https://github.com/primevise/essence
107
- post_install_message:
108
71
  rdoc_options: []
109
72
  require_paths:
110
73
  - lib
@@ -119,8 +82,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
119
82
  - !ruby/object:Gem::Version
120
83
  version: '0'
121
84
  requirements: []
122
- rubygems_version: 3.5.9
123
- signing_key:
85
+ rubygems_version: 3.6.2
124
86
  specification_version: 4
125
87
  summary: Component library for Ruby applications using Phlex
126
88
  test_files: []
@@ -1,36 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Essence::Accordion < Essence::Essence
4
- BASE = "group py-4"
5
- TRIGGER_BASE = "cursor-pointer list-none flex items-center justify-between text-base font-medium"
6
- CONTENT_BASE = "py-2 transform transition-all duration-500 not-open:-mt-4 opacity-0 group-open:opacity-100 group-open:mt-0 text-sm"
7
- CHEVRON_BASE = "transform transition-all duration-300 rotate-90 group-open:-rotate-90 text-lg text-gray-700"
8
-
9
- attr_reader :attributes
10
-
11
- def initialize(**attributes)
12
- super(**attributes)
13
- @attributes[:class] = merge_classes([ BASE, @attributes[:class]])
14
- end
15
-
16
- def view_template(&)
17
- details(class: "w-full group py-4", &) if block_given?
18
- end
19
-
20
- def trigger(**tattributes, &)
21
- summary(class: merge_classes(TRIGGER_BASE, tattributes[:class])) do
22
- p(class: "inline", &)
23
- span(class: CHEVRON_BASE) { "›" }
24
- end
25
- end
26
-
27
- def content(**cattributes, &)
28
- p(class: merge_classes(CONTENT_BASE, cattributes[:class]), &)
29
- end
30
-
31
- private
32
-
33
- def merge_classes(*classes)
34
- TAILWIND_MERGER.merge([ *classes ].compact)
35
- end
36
- end
@@ -1,50 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Essence::Alert < Essence::Essence
4
- BASE = "bg-white border-l-2 flex flex-col p-3 sm:p-4 bg-gray-50/50"
5
- TITLE_BASE = "text-gray-900 text-sm sm:text-base font-medium w-full"
6
- DESCRIPTION_BASE = "text-gray-700 flex text-xs sm:text-sm w-full"
7
- ICON_BASE = "inline-flex items-center justify-center w-fit size-7 rounded-xs"
8
-
9
- KINDS = {
10
- primary: "border-blue-500",
11
- critical: "border-rose-600",
12
- warning: "border-orange-400",
13
- success: "border-emerald-500"
14
- }
15
-
16
- ICON_KINDS = {
17
- primary: "bg-blue-500 text-white",
18
- critical: "bg-rose-600 text-white",
19
- warning: "bg-orange-400 text-gray-900",
20
- success: "bg-emerald-500 text-white"
21
- }
22
-
23
- attr_reader :kind
24
- attr_reader :attributes
25
-
26
- def initialize(kind: :primary, **attributes)
27
- @kind = kind
28
- super(**attributes)
29
- @attributes[:class] = merge_classes([ BASE, KINDS[kind], attributes[:class] ])
30
- end
31
-
32
- def view_template(&)
33
- div(**attributes, &)
34
- end
35
-
36
- def title(**mattributes, &)
37
- mattributes[:class] = merge_classes([ TITLE_BASE, mattributes[:class] ])
38
- h5(**mattributes, &)
39
- end
40
-
41
- def description(**mattributes, &)
42
- mattributes[:class] = merge_classes([ DESCRIPTION_BASE, mattributes[:class] ])
43
- p(**mattributes, &)
44
- end
45
-
46
- def icon(**mattributes, &)
47
- mattributes[:class] = merge_classes([ ICON_BASE, ICON_KINDS[kind], mattributes[:class] ])
48
- div(**mattributes, &)
49
- end
50
- end
@@ -1,31 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Essence::Avatar < Essence::Essence
4
- BASE = "border border-transparent rounded-full bg-gray-100 aspect-square inline-flex items-center justify-center font-medium text-gray-700 overflow-hidden"
5
-
6
- SIZES = {
7
- sm: "size-6 text-[0.5rem]",
8
- md: "size-8 text-xs",
9
- lg: "size-12 text-sm"
10
- }
11
-
12
- attr_reader :attributes
13
- attr_reader :size
14
-
15
- def initialize(size: :md, **attributes)
16
- super(**attributes)
17
- @size = size
18
- @attributes[:class] = merge_classes([ BASE, SIZES[size], @attributes[:class]])
19
- end
20
-
21
- def view_template(&)
22
- div(**attributes) do
23
- img(src: attributes[:src], alt: attributes[:alt]) if attributes[:src]
24
- yield if block_given?
25
- end
26
- end
27
-
28
- def fallback(**attrs, &)
29
- div(**attrs, &)
30
- end
31
- end
@@ -1,35 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Essence::Badge < Essence::Essence
4
- BASE = "inline-flex items-center justify-center w-fit rounded-full border border-transparent font-medium transition duration-150 hover:opacity-90"
5
- SIZES = {
6
- none: "",
7
- sm: "text-[0.65rem] px-2 py-0.5 gap-1 min-w-8",
8
- md: "text-xs px-2.5 py-1 gap-2 min-w-12",
9
- lg: "text-sm px-4 py-1 gap-2 min-w-16"
10
- }
11
- KINDS = {
12
- primary: "text-gray-900 border-gray-200",
13
- success: "text-white bg-emerald-500",
14
- critical: "text-white bg-rose-500",
15
- warning: "text-white bg-amber-500",
16
- info: "text-white bg-blue-500",
17
- dark: "text-white bg-gray-900",
18
- white: "text-gray-900 bg-white"
19
- }
20
-
21
- attr_reader :size
22
- attr_reader :kind
23
- attr_reader :attributes
24
-
25
- def initialize(size: :md, kind: :primary, **attributes)
26
- @size = size
27
- @kind = kind
28
- super(**attributes)
29
- @attributes[:class] = merge_classes([ BASE, SIZES[size], KINDS[kind], @attributes[:class]])
30
- end
31
-
32
- def view_template(&)
33
- div(**attributes, &)
34
- end
35
- end
@@ -1,45 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Essence::Button < Essence::Essence
4
- BASE = "inline-flex items-center justify-center w-fit rounded-xs border border-transparent font-medium transition duration-150 cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed hover:opacity-90"
5
- SIZES = {
6
- none: "",
7
- xs: "text-[0.6rem] px-2 py-1.5 gap-1",
8
- sm: "text-xs px-3 py-2 gap-1.5",
9
- md: "text-sm px-4 py-2 gap-2",
10
- lg: "text-base px-6 py-2.5 gap-2.5",
11
- xl: "text-base px-8 py-3 gap-3"
12
- }
13
- KINDS = {
14
- primary: "text-white bg-indigo-500 hover:bg-indigo-500",
15
- secondary: "text-gray-700 bg-gray-100 hover:bg-gray-200",
16
- critical: "text-white bg-rose-500 hover:bg-rose-400",
17
- warning: "text-white bg-amber-500 hover:bg-amber-400",
18
- success: "text-white bg-emerald-500 hover:bg-emerald-400",
19
- info: "text-white bg-blue-500 hover:bg-blue-400",
20
- dark: "text-white bg-gray-900 hover:bg-gray-800",
21
- white: "text-gray-900 bg-white hover:bg-gray-200",
22
- ghost: "text-gray-900 hover:bg-gray-200 hover:text-gray-800"
23
- }
24
-
25
- attr_reader :size
26
- attr_reader :kind
27
- attr_reader :attributes
28
-
29
- def initialize(size: :md, kind: :primary, **attributes)
30
- @size = size
31
- @kind = kind
32
- super(**attributes)
33
- @attributes[:class] = merge_classes([ BASE, SIZES[size], KINDS[kind], @attributes[:class]])
34
- end
35
-
36
- def view_template(&)
37
- element_tag(**attributes, &)
38
- end
39
-
40
- private
41
-
42
- def element_tag(...)
43
- attributes[:href] ? a(...) : button(...)
44
- end
45
- end
@@ -1,17 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Essence::Checkbox < Essence::Essence
4
- BASE = "appearance-none size-3.5 cursor-pointer transition duration-100 rounded-xs border border-gray-300 focus:ring-0 checked:border-indigo-600 checked:bg-indigo-500 indeterminate:border-indigo-600 indeterminate:bg-indigo-500 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600 disabled:border-gray-300 disabled:bg-gray-100 disabled:checked:bg-gray-100 forced-colors:appearance-auto"
5
-
6
- attr_reader :attributes
7
-
8
- def initialize(**attributes)
9
- super(**attributes)
10
- @attributes[:class] = merge_classes(BASE, attributes[:class])
11
- end
12
-
13
- def view_template
14
- attributes[:type] = :checkbox
15
- input(**attributes)
16
- end
17
- end
@@ -1,21 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Essence::Dialog < Essence::Essence
4
- BASE = ""
5
-
6
- attr_reader :attributes
7
-
8
- def initialize(**attributes)
9
- super(**attributes)
10
- @attributes[:class] = merge_classes([ BASE, @attributes[:class]])
11
- end
12
-
13
- def view_template(&)
14
- dialog(**attributes) do
15
- yield if block_given?
16
- end
17
- end
18
-
19
- def footer(&)
20
- end
21
- end
@@ -1,18 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Essence::Dropdown < Essence::Essence
4
- BASE = ""
5
-
6
- attr_reader :attributes
7
-
8
- def initialize(**attributes)
9
- super(**attributes)
10
- @attributes[:class] = merge_classes([ BASE, @attributes[:class]])
11
- end
12
-
13
- def view_template(&)
14
- div(**attributes) do
15
- yield if block_given?
16
- end
17
- end
18
- end
@@ -1,14 +0,0 @@
1
- class Essence::Essence < Phlex::HTML
2
- TAILWIND_MERGER = ::TailwindMerge::Merger.new.freeze unless defined?(TAILWIND_MERGER)
3
-
4
- attr_reader :attributes
5
-
6
- def initialize(**attributes)
7
- @attributes = default_attributes.deep_merge(attributes)
8
- end
9
-
10
- private
11
-
12
- def default_attributes = {}
13
- def merge_classes(*classes) = TAILWIND_MERGER.merge([ *classes ].compact)
14
- end
@@ -1,28 +0,0 @@
1
- class Essence::Heading < Essence::Essence
2
- ALLOWED_TAGS = [ :h1, :h2, :h3, :h4, :h5, :h6 ]
3
- BASE = "font-medium text-gray-900 leading-normal"
4
- SIZES = {
5
- xs: "text-base lg:text-lg",
6
- sm: "text-lg lg:text-xl",
7
- md: "text-xl lg:text-2xl",
8
- lg: "text-2xl lg:text-3xl",
9
- xl: "text-3xl lg:text-4xl",
10
- "2xl": "text-4xl lg:text-5xl",
11
- "3xl": "text-5xl lg:text-6xl"
12
- }
13
-
14
- attr_reader :as
15
- attr_reader :size
16
- attr_reader :attributes
17
-
18
- def initialize(as: :h2, size: :xs, **attributes)
19
- super(**attributes)
20
- @as = ALLOWED_TAGS.include?(as.to_sym) ? as.to_sym : :h1
21
- @size = SIZES.keys.include?(size.to_sym) ? size.to_sym : :xs
22
- @attributes[:class] = merge_classes([ BASE, SIZES[size], attributes[:class] ])
23
- end
24
-
25
- def view_template(&)
26
- tag(as, **attributes, &)
27
- end
28
- end
@@ -1,14 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Essence::Input < Essence::Essence
4
- BASE = "flex px-4 h-10 md:h-12 rounded-sm border border-gray-200/80 focus:outline-none focus:ring-offset-2 focus-visible:ring-2"
5
-
6
- def initialize(**attributes)
7
- super(**attributes)
8
- @attributes[:class] = merge_classes([ BASE, @attributes[:class] ])
9
- end
10
-
11
- def view_template(&)
12
- input(**attributes)
13
- end
14
- end
@@ -1,28 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Essence::Label < Essence::Essence
4
- BASE = "flex text-sm font-medium text-gray-700"
5
- HELPER_BASE = "text-xs font-normal text-gray-500"
6
- ASTERISK_BASE = "text-rose-500 font-normal mx-0.5"
7
-
8
- attr_reader :attributes
9
-
10
- def initialize(**attributes)
11
- super(**attributes)
12
- @attributes[:class] = merge_classes([ BASE, attributes[:class], !!attributes[:for] ? "cursor-pointer" : "" ])
13
- end
14
-
15
- def view_template(&)
16
- label(**@attributes, &)
17
- end
18
-
19
- def asterisk(**mattributes)
20
- mattributes[:class] = merge_classes([ ASTERISK_BASE, mattributes[:class] ])
21
- span(**mattributes) { "*" }
22
- end
23
-
24
- def helper_text(**mattributes, &)
25
- mattributes[:class] = merge_classes([ HELPER_BASE, mattributes[:class] ])
26
- p(**mattributes, &)
27
- end
28
- end
@@ -1,20 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Essence::Link < Essence::Essence
4
- BASE = "inline-flex w-fit items-center gap-1 font-medium text-gray-900 border-b-2 hover:border-gray-900 transition-colors"
5
- KINDS = {
6
- regular: "border-transparent",
7
- underline: "border-gray-200"
8
- }
9
-
10
- attr_reader :attributes
11
-
12
- def initialize(kind: :regular, **attributes)
13
- super(**attributes)
14
- @attributes[:class] = merge_classes([ BASE, @attributes[:class]])
15
- end
16
-
17
- def view_template(&)
18
- a(**attributes, &)
19
- end
20
- end
@@ -1,40 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Essence::Metric < Essence::Essence
4
- BASE = "p-4 border rounded-xs"
5
- HELPER_BASE = "text-xs uppercase font-medium text-gray-500"
6
- TITLE_BASE = "text-2xl text-gray-900 font-medium"
7
- BODY_BASE = "text-sm text-gray-700"
8
-
9
- KINDS = {
10
- primary: "",
11
- secondary: "border-transparent bg-gray-100"
12
- }
13
-
14
- attr_reader :kind
15
-
16
- def initialize(kind: :primary, **attributes)
17
- @kind = kind
18
- super(**attributes)
19
- @attributes[:class] = merge_classes([ BASE, KINDS[kind], @attributes[:class] ])
20
- end
21
-
22
- def view_template(&)
23
- div(**attributes, &)
24
- end
25
-
26
- def title(**mattributes, &)
27
- mattributes[:class] = merge_classes([ TITLE_BASE, mattributes[:class] ])
28
- h5(**mattributes, &)
29
- end
30
-
31
- def helper(**mattributes, &)
32
- mattributes[:class] = merge_classes([ HELPER_BASE, mattributes[:class] ])
33
- p(**mattributes, &)
34
- end
35
-
36
- def body(**mattributes, &)
37
- mattributes[:class] = merge_classes([ BODY_BASE, mattributes[:class] ])
38
- p(**mattributes, &)
39
- end
40
- end
@@ -1,28 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Essence::Row < Essence::Essence
4
- BASE = "flex gap-4"
5
- KINDS = {
6
- default: "flex-col md:flex-row md:items-center md:justify-between",
7
- center: "flex-col md:flex-row md:items-center md:justify-center",
8
- start: "flex-col md:flex-row md:items-center md:justify-start",
9
- end: "flex-col md:flex-row md:items-center md:justify-end",
10
- }
11
-
12
- attr_reader :kind
13
- attr_reader :attributes
14
-
15
- def initialize(kind: :default, **attributes)
16
- @kind = kind
17
- super(**attributes)
18
- @attributes[:class] = merge_classes([ BASE, KINDS[kind], @attributes[:class]])
19
- end
20
-
21
- def view_template(&)
22
- div(**attributes, &)
23
- end
24
-
25
- def item(**attrs, &)
26
- div(class: TAILWIND_MERGER.merge([ "flex items-center gap-2 flex-wrap", attrs[:class] ]), **attrs, &)
27
- end
28
- end
@@ -1,29 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Essence::Separator < Essence::Essence
4
- BASE = "border-gray-200/50"
5
-
6
- KINDS = {
7
- horizontal: "border-t",
8
- vertical: "border-l h-full"
9
- }
10
-
11
- attr_reader :kind
12
- attr_reader :attributes
13
-
14
- def initialize(kind: :horizontal, **attributes)
15
- @kind = kind
16
- super(**attributes)
17
- @attributes[:class] = merge_classes([ BASE, KINDS[kind], @attributes[:class] ])
18
- end
19
-
20
- def view_template
21
- element_tag(**attributes)
22
- end
23
-
24
- private
25
-
26
- def element_tag(...)
27
- kind.to_sym == :horizontal ? hr(...) : div(...)
28
- end
29
- end
@@ -1,24 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # A skeleton component is used to show a loading state.
4
- #
5
- # ==== Examples
6
- #
7
- # render Skeleton.new(class: "w-32 h-6")
8
- #
9
- # ==== Documentation
10
- #
11
- # https://essence.primevise.com/components/skeleton
12
- #
13
- class Essence::Skeleton < Essence::Essence
14
- BASE = "animate-pulse bg-gray-200/55 rounded-xs"
15
-
16
- def initialize(**attributes)
17
- super(**attributes)
18
- @attributes[:class] = merge_classes([ BASE, @attributes[:class]])
19
- end
20
-
21
- def view_template(&)
22
- div(**@attributes, &)
23
- end
24
- end
@@ -1,69 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # A switch component that can be toggled on and off.
4
- #
5
- # ==== Examples
6
- #
7
- # render Switch.new
8
- #
9
- # ==== Documentation
10
- #
11
- # https://essence.primevise.com/components/switch
12
- #
13
- class Essence::Switch < Essence::Essence
14
- BASE = "relative inline-flex h-6 w-12 shrink-0 cursor-pointer rounded-full border-2 border-transparent bg-gray-200 transition-colors duration-200 ease-in-out focus:ring-2 focus:ring-indigo-200 focus:ring-offset-2 focus:outline-hidden"
15
- LEVER_BASE = "pointer-events-none inline-block size-5 translate-x-0 transform rounded-full bg-white ring-0 transition duration-200 ease-in-out"
16
-
17
- ACTIVE_CLASSES = "bg-indigo-600"
18
- INACTIVE_CLASSES = "bg-gray-200"
19
-
20
- ACTIVE_LEVER_CLASSES = "translate-x-6"
21
- INACTIVE_LEVER_CLASSES = "translate-x-0"
22
-
23
- def initialize(**attributes)
24
- super(**attributes)
25
- @attributes[:class] = merge_classes([ BASE, @attributes[:class] ])
26
- end
27
-
28
- def view_template(&)
29
- button(**attributes) do
30
- span(class: "sr-only") { "Use setting" }
31
- span(
32
- aria_hidden: "true",
33
- class: LEVER_BASE,
34
- data: {
35
- essence__switch_target: "lever"
36
- },
37
- )
38
- yield if block_given?
39
- end
40
- end
41
-
42
- def hidden_input(**mattributes)
43
- mattributes[:type] = "hidden"
44
- mattributes[:name] = mattributes[:name] || "enabled"
45
- mattributes[:value] = mattributes[:value] || false
46
- mattributes[:data] = { essence__switch_target: "input" }
47
-
48
- input(**mattributes)
49
- end
50
-
51
- private
52
-
53
- def default_attributes
54
- {
55
- type: "button",
56
- role: "switch",
57
- aria_checked: false,
58
- data: {
59
- controller: "essence--switch",
60
- action: "click->essence--switch#toggle",
61
- essence__switch_active_class: ACTIVE_CLASSES,
62
- essence__switch_inactive_class: INACTIVE_CLASSES,
63
- essence__switch_active_lever_class: ACTIVE_LEVER_CLASSES,
64
- essence__switch_inactive_lever_class: INACTIVE_LEVER_CLASSES
65
- }
66
- }
67
- end
68
-
69
- end
@@ -1,58 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Essence::Tabs < Essence::Essence
4
- BASE = "rounded-lg overflow-hidden"
5
- TAB_BASE = "inline-flex items-center justify-center w-fit rounded-xs border border-transparent font-medium transition duration-150 cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed hover:opacity-90 text-xs px-3 py-2 gap-1.5 text-gray-900 bg-transparent hover:bg-gray-200 hover:text-gray-800"
6
- TAB_LIST_BASE = "flex items-center gap-2 py-2 border-b"
7
- PANEL_BASE = "aria-hidden:hidden p-4"
8
-
9
- attr_reader :attributes
10
-
11
- def initialize(**attributes)
12
- super(**attributes)
13
- @attributes[:class] = merge_classes([ BASE, @attributes[:class] ])
14
- end
15
-
16
- def view_template(&)
17
- div(**attributes, &)
18
- end
19
-
20
- def menu(**mattributes, &)
21
- mattributes[:class] = merge_classes([ TAB_LIST_BASE, mattributes[:class] ])
22
-
23
- div(**mattributes, &)
24
- end
25
-
26
- def tab(key: :general, **mattributes, &)
27
- mattributes[:id] = "tab-#{key}"
28
- mattributes[:class] = merge_classes([ TAB_BASE, mattributes[:class] ])
29
- mattributes[:data] = {
30
- essence__tabs_target: "tab",
31
- essence__tabs_panel_id_param: "panel-#{key}",
32
- action: "essence--tabs#setActiveTab keydown.left->essence--tabs#previous keydown.right->essence--tabs#next"
33
- }
34
-
35
- button(**mattributes, &)
36
- end
37
-
38
- def panel(key: :general, **mattributes, &)
39
- mattributes[:id] = "panel-#{key}"
40
- mattributes[:class] = merge_classes([ PANEL_BASE, mattributes[:class] ])
41
- mattributes[:data] = {
42
- essence__tabs_target: "panel"
43
- }
44
-
45
- div(**mattributes, &)
46
- end
47
-
48
- private
49
-
50
- def default_attributes
51
- {
52
- data: {
53
- controller: "essence--tabs",
54
- essence__tabs_active_value: "panel-general"
55
- }
56
- }
57
- end
58
- end
@@ -1,21 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Essence::Text < Essence::Essence
4
- BASE = "text-base text-gray-500 dark:text-gray-400"
5
- SIZES = {
6
- sm: "text-sm",
7
- md: "text-base",
8
- lg: "text-lg"
9
- }
10
-
11
- attr_reader :size
12
-
13
- def initialize(size: :md, **attributes)
14
- super(**attributes)
15
- @attributes[:class] = merge_classes([ BASE, SIZES[size], attributes[:class] ])
16
- end
17
-
18
- def view_template(&)
19
- p(**attributes, &)
20
- end
21
- end
@@ -1,32 +0,0 @@
1
- import { Controller } from "@hotwired/stimulus";
2
-
3
- export default class extends Controller {
4
- static targets = ["input", "lever"];
5
-
6
- static classes = ["active", "inactive", "activeLever", "inactiveLever"];
7
-
8
- static values = {
9
- checked: {
10
- type: Boolean,
11
- default: false,
12
- },
13
- };
14
-
15
- connect() {
16
- if (this.checkedValue) this.toggle();
17
- }
18
-
19
- toggle(event) {
20
- this.element.ariaChecked =
21
- this.element.ariaChecked == "true" ? false : true;
22
-
23
- if (this.hasInputTarget)
24
- this.inputTarget.value = this.element.ariaChecked == "true";
25
-
26
- this.element.classList.toggle(...this.activeClasses);
27
- this.element.classList.toggle(...this.inactiveClasses);
28
-
29
- this.leverTarget.classList.toggle(...this.activeLeverClasses);
30
- this.leverTarget.classList.toggle(...this.inactiveLeverClasses);
31
- }
32
- }
@@ -1,40 +0,0 @@
1
- import { Controller } from "@hotwired/stimulus";
2
-
3
- export default class extends Controller {
4
- static targets = ["tab", "panel"];
5
- static values = { active: String };
6
-
7
- setActiveTab(event) {
8
- this.activeValue = event.params.panelId;
9
- }
10
-
11
- activeValueChanged() {
12
- this.tabTargets.forEach((tab) => {
13
- tab.ariaSelected = tab.id === this.activeValue;
14
- });
15
-
16
- this.panelTargets.forEach((panel) => {
17
- panel.ariaHidden = panel.id !== this.activeValue;
18
- });
19
- }
20
-
21
- next(event) {
22
- this.navigate(event, "next");
23
- }
24
-
25
- previous(event) {
26
- this.navigate(event, "previous");
27
- }
28
-
29
- navigate(event, direction) {
30
- const tab =
31
- direction === "next"
32
- ? event.target.nextElementSibling
33
- : event.target.previousElementSibling;
34
-
35
- if (!tab) return;
36
-
37
- tab.click();
38
- tab.focus();
39
- }
40
- }