kozenet_ui 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/CHANGELOG.md +5 -0
- data/CODE_OF_CONDUCT.md +132 -0
- data/LICENSE.txt +21 -0
- data/README.md +76 -0
- data/app/assets/images/kozenet_ui/icons/cart.svg +1 -0
- data/app/assets/images/kozenet_ui/icons/heart.svg +1 -0
- data/app/assets/javascripts/kozenet_ui/controllers/dropdown_controller.js +55 -0
- data/app/assets/javascripts/kozenet_ui/controllers/header_controller.js +32 -0
- data/app/assets/javascripts/kozenet_ui/controllers/mobile_nav_controller.js +43 -0
- data/app/assets/javascripts/kozenet_ui/controllers/user_menu_controller.js +60 -0
- data/app/assets/javascripts/kozenet_ui/index.js +23 -0
- data/app/assets/stylesheets/kozenet_ui/base.css +69 -0
- data/app/assets/stylesheets/kozenet_ui/components/avatar.css +88 -0
- data/app/assets/stylesheets/kozenet_ui/components/badge.css +101 -0
- data/app/assets/stylesheets/kozenet_ui/components/button.css +230 -0
- data/app/assets/stylesheets/kozenet_ui/components/header.css +389 -0
- data/app/assets/stylesheets/kozenet_ui/components/utilities.css +270 -0
- data/app/assets/stylesheets/kozenet_ui/components.css +8 -0
- data/app/assets/stylesheets/kozenet_ui/tokens.css +168 -0
- data/app/components/kozenet_ui/avatar_component.rb +72 -0
- data/app/components/kozenet_ui/badge_component.rb +62 -0
- data/app/components/kozenet_ui/base_component.rb +84 -0
- data/app/components/kozenet_ui/button_component.rb +156 -0
- data/app/components/kozenet_ui/header_component/action_button_component.html.erb +11 -0
- data/app/components/kozenet_ui/header_component/action_button_component.rb +29 -0
- data/app/components/kozenet_ui/header_component/brand_component.rb +32 -0
- data/app/components/kozenet_ui/header_component/cta_component.html.erb +5 -0
- data/app/components/kozenet_ui/header_component/cta_component.rb +23 -0
- data/app/components/kozenet_ui/header_component/nav_item_component.html.erb +8 -0
- data/app/components/kozenet_ui/header_component/nav_item_component.rb +28 -0
- data/app/components/kozenet_ui/header_component/search_component.html.erb +17 -0
- data/app/components/kozenet_ui/header_component/search_component.rb +29 -0
- data/app/components/kozenet_ui/header_component/user_menu_component.html.erb +18 -0
- data/app/components/kozenet_ui/header_component/user_menu_component.rb +21 -0
- data/app/components/kozenet_ui/header_component.html.erb +81 -0
- data/app/components/kozenet_ui/header_component.rb +40 -0
- data/app/helpers/kozenet_ui/component_helper.rb +59 -0
- data/app/helpers/kozenet_ui/icon_helper.rb +16 -0
- data/lib/generators/kozenet_ui/install/install_generator.rb +67 -0
- data/lib/generators/kozenet_ui/install/templates/kozenet_ui.rb +39 -0
- data/lib/generators/kozenet_ui/install/templates/tailwind.config.js +19 -0
- data/lib/kozenet_ui/configuration.rb +21 -0
- data/lib/kozenet_ui/engine.rb +94 -0
- data/lib/kozenet_ui/theme/palette.rb +132 -0
- data/lib/kozenet_ui/theme/tokens.rb +100 -0
- data/lib/kozenet_ui/theme/variants.rb +51 -0
- data/lib/kozenet_ui/version.rb +5 -0
- data/lib/kozenet_ui.rb +30 -0
- metadata +308 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
KozenetUi.configure do |config|
|
|
4
|
+
# Customize your brand colors and gradients
|
|
5
|
+
# config.customize_colors(
|
|
6
|
+
# primary: "#6366f1", # Indigo
|
|
7
|
+
# secondary: "#8b5cf6", # Purple
|
|
8
|
+
# accent: "#06b6d4", # Cyan
|
|
9
|
+
# success: "#10b981", # Green
|
|
10
|
+
# warning: "#f59e0b", # Amber
|
|
11
|
+
# error: "#ef4444", # Red
|
|
12
|
+
# gradient_from: "#f0f9ff", # Light gradient start
|
|
13
|
+
# gradient_to: "#e0f2fe", # Light gradient end
|
|
14
|
+
# gradient_accent_from: "#6366f1", # Accent gradient start
|
|
15
|
+
# gradient_accent_via: "#0ea5e9", # Accent gradient mid
|
|
16
|
+
# gradient_accent_to: "#06b6d4", # Accent gradient end
|
|
17
|
+
# gradient_spot_1: "rgba(99,102,241,0.35)",
|
|
18
|
+
# gradient_spot_2: "rgba(14,165,233,0.30)",
|
|
19
|
+
# gradient_from_dark: "#181c2a", # Dark gradient start
|
|
20
|
+
# gradient_to_dark: "#23283a", # Dark gradient end
|
|
21
|
+
# gradient_accent_from_dark: "#1e40af", # Dark accent gradient start
|
|
22
|
+
# gradient_accent_via_dark: "#0369a1", # Dark accent gradient mid
|
|
23
|
+
# gradient_accent_to_dark: "#0891b2", # Dark accent gradient end
|
|
24
|
+
# gradient_spot_1_dark: "rgba(56,189,248,0.20)",
|
|
25
|
+
# gradient_spot_2_dark: "rgba(99,102,241,0.18)"
|
|
26
|
+
# )
|
|
27
|
+
|
|
28
|
+
# Default variant for components
|
|
29
|
+
# config.default_variant = :primary
|
|
30
|
+
|
|
31
|
+
# Default size for components
|
|
32
|
+
# config.default_size = :md
|
|
33
|
+
|
|
34
|
+
# Theme mode: :light, :dark, or :system (follows OS/browser)
|
|
35
|
+
# config.theme = :system
|
|
36
|
+
|
|
37
|
+
# Stimulus controller prefix
|
|
38
|
+
# config.stimulus_prefix = "kz"
|
|
39
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
content: [
|
|
3
|
+
'./app/views/**/*.html.erb',
|
|
4
|
+
'./app/helpers/**/*.rb',
|
|
5
|
+
'./app/javascript/**/*.js',
|
|
6
|
+
'./app/components/**/*.{rb,erb}',
|
|
7
|
+
// Include Kozenet UI components
|
|
8
|
+
'./vendor/bundle/ruby/**/kozenet_ui-*/app/{components,helpers,views}/**/*.{rb,erb}'
|
|
9
|
+
],
|
|
10
|
+
darkMode: ['class', '[data-theme="dark"]'],
|
|
11
|
+
theme: {
|
|
12
|
+
extend: {
|
|
13
|
+
colors: {
|
|
14
|
+
// Your custom colors will be available via CSS variables
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
plugins: []
|
|
19
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module KozenetUi
|
|
4
|
+
# Configuration for Kozenet UI gem
|
|
5
|
+
class Configuration
|
|
6
|
+
attr_accessor :palette, :default_variant, :default_size, :theme, :stimulus_prefix
|
|
7
|
+
|
|
8
|
+
def initialize
|
|
9
|
+
@palette = Theme::Palette.new
|
|
10
|
+
@default_variant = :primary
|
|
11
|
+
@default_size = :md
|
|
12
|
+
@theme = :system
|
|
13
|
+
@stimulus_prefix = "kz"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Allow custom color overrides including gradients
|
|
17
|
+
def customize_colors(colors = {})
|
|
18
|
+
@palette = Theme::Palette.new(colors)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "rails/engine"
|
|
4
|
+
require "view_component"
|
|
5
|
+
|
|
6
|
+
module KozenetUi
|
|
7
|
+
# Rails engine for Kozenet UI gem
|
|
8
|
+
class Engine < ::Rails::Engine
|
|
9
|
+
isolate_namespace KozenetUi
|
|
10
|
+
|
|
11
|
+
# Add generators path
|
|
12
|
+
config.generators do |g|
|
|
13
|
+
g.test_framework :rspec
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# This is CRITICAL - tells Rails where to find generators
|
|
17
|
+
config.app_generators.scaffold_controller = :scaffold_controller
|
|
18
|
+
|
|
19
|
+
initializer "kozenet_ui.generators" do
|
|
20
|
+
# Explicitly add generators path
|
|
21
|
+
config.generators do |g|
|
|
22
|
+
g.templates.unshift File.expand_path("../generators", __dir__)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Configure where to look for components
|
|
27
|
+
config.view_component.preview_paths << "#{root}/spec/components/previews" if Rails.env.development?
|
|
28
|
+
|
|
29
|
+
# Add assets paths (for Rails 7/Sprockets only)
|
|
30
|
+
if config.respond_to?(:assets) && config.assets.respond_to?(:paths)
|
|
31
|
+
config.assets.paths << root.join("app/assets/stylesheets")
|
|
32
|
+
config.assets.paths << root.join("app/assets/javascripts")
|
|
33
|
+
|
|
34
|
+
# Precompile assets
|
|
35
|
+
config.assets.precompile += %w[
|
|
36
|
+
kozenet_ui/tokens.css
|
|
37
|
+
kozenet_ui/base.css
|
|
38
|
+
kozenet_ui/components.css
|
|
39
|
+
kozenet_ui/index.js
|
|
40
|
+
]
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Auto-load components
|
|
44
|
+
config.autoload_paths << root.join("app/components")
|
|
45
|
+
config.eager_load_paths << root.join("app/components")
|
|
46
|
+
|
|
47
|
+
# Make helpers available
|
|
48
|
+
initializer "kozenet_ui.helpers" do
|
|
49
|
+
ActiveSupport.on_load(:action_controller_base) do
|
|
50
|
+
helper KozenetUi::ComponentHelper
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Inject CSS variables into layout
|
|
55
|
+
initializer "kozenet_ui.theme_injection", after: :load_config_initializers do
|
|
56
|
+
ActiveSupport.on_load(:action_view) do
|
|
57
|
+
ActiveSupport.on_load(:action_view) { prepend ThemeHelper }
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
initializer "kozenet_ui.assets" do |app|
|
|
62
|
+
if app.config.respond_to?(:assets) && app.config.assets.respond_to?(:paths)
|
|
63
|
+
app.config.assets.paths << root.join("app/assets/stylesheets/kozenet_ui")
|
|
64
|
+
app.config.assets.paths << root.join("app/assets/stylesheets/kozenet_ui/components")
|
|
65
|
+
app.config.assets.paths << root.join("app/assets/images/kozenet_ui/icons")
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Helper methods for injecting Kozenet UI theme variables into views
|
|
71
|
+
module ThemeHelper
|
|
72
|
+
def kozenet_ui_theme_tag
|
|
73
|
+
content_tag(:style, kozenet_ui_theme_variables, nonce: content_security_policy_nonce)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# rubocop:disable Rails/OutputSafety
|
|
77
|
+
def kozenet_ui_theme_variables
|
|
78
|
+
<<~CSS.html_safe
|
|
79
|
+
:root {
|
|
80
|
+
/* Design Tokens */
|
|
81
|
+
#{KozenetUi::Theme::Tokens.to_css_variables}
|
|
82
|
+
/* Color Palette (Light Mode) */
|
|
83
|
+
#{KozenetUi.configuration.palette.to_css_variables(mode: :light)}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
[data-theme="dark"], .dark {
|
|
87
|
+
/* Color Palette (Dark Mode) */
|
|
88
|
+
#{KozenetUi.configuration.palette.to_css_variables(mode: :dark)}
|
|
89
|
+
}
|
|
90
|
+
CSS
|
|
91
|
+
end
|
|
92
|
+
# rubocop:enable Rails/OutputSafety
|
|
93
|
+
end
|
|
94
|
+
end
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "color"
|
|
4
|
+
|
|
5
|
+
module KozenetUi
|
|
6
|
+
module Theme
|
|
7
|
+
# Dynamic color palette system with auto-generated shades
|
|
8
|
+
# Supports light/dark modes and custom brand colors
|
|
9
|
+
#
|
|
10
|
+
# @example
|
|
11
|
+
# KozenetUi::Theme::Palette.new(primary: "#123456")
|
|
12
|
+
class Palette
|
|
13
|
+
DEFAULT_COLORS = {
|
|
14
|
+
primary: "#6366f1", # Indigo
|
|
15
|
+
secondary: "#8b5cf6", # Purple
|
|
16
|
+
accent: "#06b6d4", # Cyan
|
|
17
|
+
success: "#10b981", # Green
|
|
18
|
+
warning: "#f59e0b", # Amber
|
|
19
|
+
error: "#ef4444", # Red
|
|
20
|
+
info: "#0ea5e9" # Sky
|
|
21
|
+
}.freeze
|
|
22
|
+
|
|
23
|
+
# Neutral colors (semantic)
|
|
24
|
+
NEUTRALS_LIGHT = {
|
|
25
|
+
bg_base: "#ffffff",
|
|
26
|
+
bg_elevated: "#f8fafc",
|
|
27
|
+
bg_muted: "#f1f5f9",
|
|
28
|
+
text_default: "#0f172a",
|
|
29
|
+
text_muted: "#64748b",
|
|
30
|
+
border_default: "#e2e8f0",
|
|
31
|
+
border_muted: "#f1f5f9"
|
|
32
|
+
}.freeze
|
|
33
|
+
|
|
34
|
+
NEUTRALS_DARK = {
|
|
35
|
+
bg_base: "#0f172a",
|
|
36
|
+
bg_elevated: "#1e293b",
|
|
37
|
+
bg_muted: "#334155",
|
|
38
|
+
text_default: "#f1f5f9",
|
|
39
|
+
text_muted: "#94a3b8",
|
|
40
|
+
border_default: "#334155",
|
|
41
|
+
border_muted: "#1e293b"
|
|
42
|
+
}.freeze
|
|
43
|
+
|
|
44
|
+
attr_reader :colors
|
|
45
|
+
|
|
46
|
+
def initialize(custom_colors = {})
|
|
47
|
+
@colors = DEFAULT_COLORS.merge(custom_colors)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
|
51
|
+
def to_css_variables(mode: :light)
|
|
52
|
+
variables = []
|
|
53
|
+
|
|
54
|
+
# Brand colors with shades (only for valid hex colors)
|
|
55
|
+
@colors.each do |name, hex|
|
|
56
|
+
next if name.to_s.start_with?("gradient_spot_")
|
|
57
|
+
next if name.to_s.end_with?("_dark")
|
|
58
|
+
|
|
59
|
+
if hex.is_a?(String) && hex.match?(/^#(?:[0-9a-fA-F]{3}){1,2}$/)
|
|
60
|
+
shades = generate_shades(hex)
|
|
61
|
+
shades.each do |shade, color|
|
|
62
|
+
variables << "--kz-#{name}-#{shade}: #{color};"
|
|
63
|
+
end
|
|
64
|
+
else
|
|
65
|
+
# For non-hex, just output as a base variable
|
|
66
|
+
variables << "--kz-#{name}: #{hex};"
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Semantic neutrals
|
|
71
|
+
neutrals = mode == :dark ? NEUTRALS_DARK : NEUTRALS_LIGHT
|
|
72
|
+
neutrals.each do |name, value|
|
|
73
|
+
variables << "--kz-#{name.to_s.tr("_", "-")}: #{value};"
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Gradient tokens (allow user to override or fallback to palette)
|
|
77
|
+
if mode == :dark
|
|
78
|
+
variables << "--gradient-base-from: #{@colors[:gradient_from_dark] || "#181c2a"};"
|
|
79
|
+
variables << "--gradient-base-to: #{@colors[:gradient_to_dark] || "#23283a"};"
|
|
80
|
+
variables << "--gradient-accent-from: #{@colors[:gradient_accent_from_dark] || "#1e40af"};"
|
|
81
|
+
variables << "--gradient-accent-via: #{@colors[:gradient_accent_via_dark] || "#0369a1"};"
|
|
82
|
+
variables << "--gradient-accent-to: #{@colors[:gradient_accent_to_dark] || "#0891b2"};"
|
|
83
|
+
variables << "--gradient-spot-1: #{@colors[:gradient_spot_1_dark] || "rgba(56,189,248,0.20)"};"
|
|
84
|
+
variables << "--gradient-spot-2: #{@colors[:gradient_spot_2_dark] || "rgba(99,102,241,0.18)"};"
|
|
85
|
+
else
|
|
86
|
+
variables << "--gradient-base-from: #{@colors[:gradient_from] || "#f0f9ff"};"
|
|
87
|
+
variables << "--gradient-base-to: #{@colors[:gradient_to] || "#e0f2fe"};"
|
|
88
|
+
variables << "--gradient-accent-from: #{@colors[:gradient_accent_from] || "#6366f1"};"
|
|
89
|
+
variables << "--gradient-accent-via: #{@colors[:gradient_accent_via] || "#0ea5e9"};"
|
|
90
|
+
variables << "--gradient-accent-to: #{@colors[:gradient_accent_to] || "#06b6d4"};"
|
|
91
|
+
# rubocop:disable Naming/VariableNumber
|
|
92
|
+
variables << "--gradient-spot-1: #{@colors[:gradient_spot_1] || "rgba(99,102,241,0.35)"};"
|
|
93
|
+
variables << "--gradient-spot-2: #{@colors[:gradient_spot_2] || "rgba(14,165,233,0.30)"};"
|
|
94
|
+
# rubocop:enable Naming/VariableNumber
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
variables.join("\n ")
|
|
98
|
+
end
|
|
99
|
+
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
|
100
|
+
|
|
101
|
+
private
|
|
102
|
+
|
|
103
|
+
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
|
104
|
+
# Generate 50-900 shades from a base color
|
|
105
|
+
def generate_shades(hex)
|
|
106
|
+
base = Color::RGB.by_hex(hex)
|
|
107
|
+
|
|
108
|
+
{
|
|
109
|
+
50 => lighten(base, 0.45).html,
|
|
110
|
+
100 => lighten(base, 0.35).html,
|
|
111
|
+
200 => lighten(base, 0.25).html,
|
|
112
|
+
300 => lighten(base, 0.15).html,
|
|
113
|
+
400 => lighten(base, 0.08).html,
|
|
114
|
+
500 => hex, # Base color
|
|
115
|
+
600 => darken(base, 0.08).html,
|
|
116
|
+
700 => darken(base, 0.15).html,
|
|
117
|
+
800 => darken(base, 0.25).html,
|
|
118
|
+
900 => darken(base, 0.35).html
|
|
119
|
+
}
|
|
120
|
+
end
|
|
121
|
+
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
|
|
122
|
+
|
|
123
|
+
def lighten(color, amount)
|
|
124
|
+
color.lighten_by(amount * 100)
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def darken(color, amount)
|
|
128
|
+
color.darken_by(amount * 100)
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
end
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module KozenetUi
|
|
4
|
+
module Theme
|
|
5
|
+
# Design tokens for the Kozenet UI system
|
|
6
|
+
class Tokens
|
|
7
|
+
# Spacing scale (in rem)
|
|
8
|
+
SPACING = {
|
|
9
|
+
xs: "0.25rem", # 4px
|
|
10
|
+
sm: "0.5rem", # 8px
|
|
11
|
+
md: "1rem", # 16px
|
|
12
|
+
lg: "1.5rem", # 24px
|
|
13
|
+
xl: "2rem", # 32px
|
|
14
|
+
"2xl": "3rem", # 48px
|
|
15
|
+
"3xl": "4rem" # 64px
|
|
16
|
+
}.freeze
|
|
17
|
+
|
|
18
|
+
# Border radius (Apple-style rounded)
|
|
19
|
+
RADIUS = {
|
|
20
|
+
sm: "12px",
|
|
21
|
+
md: "16px",
|
|
22
|
+
lg: "20px",
|
|
23
|
+
xl: "24px",
|
|
24
|
+
"2xl": "28px",
|
|
25
|
+
full: "9999px"
|
|
26
|
+
}.freeze
|
|
27
|
+
|
|
28
|
+
# Typography scale
|
|
29
|
+
FONT_SIZE = {
|
|
30
|
+
xs: "0.65rem", # 10.4px
|
|
31
|
+
sm: "0.75rem", # 12px
|
|
32
|
+
base: "0.875rem", # 14px
|
|
33
|
+
lg: "1rem", # 16px
|
|
34
|
+
xl: "1.25rem", # 20px
|
|
35
|
+
"2xl": "1.5rem", # 24px
|
|
36
|
+
"3xl": "2rem" # 32px
|
|
37
|
+
}.freeze
|
|
38
|
+
|
|
39
|
+
FONT_WEIGHT = {
|
|
40
|
+
normal: "400",
|
|
41
|
+
medium: "500",
|
|
42
|
+
semibold: "600",
|
|
43
|
+
bold: "700"
|
|
44
|
+
}.freeze
|
|
45
|
+
|
|
46
|
+
# Shadows for depth effects
|
|
47
|
+
SHADOW = {
|
|
48
|
+
sm: "0 1px 2px rgba(0,0,0,.05), 0 2px 6px -2px rgba(0,0,0,.08)",
|
|
49
|
+
md: "0 4px 14px -6px rgba(0,0,0,.25)",
|
|
50
|
+
lg: "0 10px 30px -12px rgba(0,0,0,.45)",
|
|
51
|
+
xl: "0 20px 60px -26px rgba(0,0,0,.28)"
|
|
52
|
+
}.freeze
|
|
53
|
+
|
|
54
|
+
# Transitions
|
|
55
|
+
TRANSITION = {
|
|
56
|
+
fast: "0.15s ease",
|
|
57
|
+
base: "0.25s ease",
|
|
58
|
+
slow: "0.35s ease"
|
|
59
|
+
}.freeze
|
|
60
|
+
|
|
61
|
+
# Z-index layers
|
|
62
|
+
Z_INDEX = {
|
|
63
|
+
dropdown: "50",
|
|
64
|
+
sticky: "60",
|
|
65
|
+
modal: "70",
|
|
66
|
+
popover: "80",
|
|
67
|
+
toast: "90"
|
|
68
|
+
}.freeze
|
|
69
|
+
|
|
70
|
+
class << self
|
|
71
|
+
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
|
|
72
|
+
def to_css_variables
|
|
73
|
+
variables = []
|
|
74
|
+
|
|
75
|
+
# Spacing
|
|
76
|
+
SPACING.each { |key, value| variables << "--kz-spacing-#{key}: #{value};" }
|
|
77
|
+
|
|
78
|
+
# Radius
|
|
79
|
+
RADIUS.each { |key, value| variables << "--kz-radius-#{key}: #{value};" }
|
|
80
|
+
|
|
81
|
+
# Typography
|
|
82
|
+
FONT_SIZE.each { |key, value| variables << "--kz-font-size-#{key}: #{value};" }
|
|
83
|
+
FONT_WEIGHT.each { |key, value| variables << "--kz-font-weight-#{key}: #{value};" }
|
|
84
|
+
|
|
85
|
+
# Shadows
|
|
86
|
+
SHADOW.each { |key, value| variables << "--kz-shadow-#{key}: #{value};" }
|
|
87
|
+
|
|
88
|
+
# Transitions
|
|
89
|
+
TRANSITION.each { |key, value| variables << "--kz-transition-#{key}: #{value};" }
|
|
90
|
+
|
|
91
|
+
# Z-index
|
|
92
|
+
Z_INDEX.each { |key, value| variables << "--kz-z-#{key}: #{value};" }
|
|
93
|
+
|
|
94
|
+
variables.join("\n ")
|
|
95
|
+
end
|
|
96
|
+
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module KozenetUi
|
|
4
|
+
module Theme
|
|
5
|
+
# Variant mappings for components
|
|
6
|
+
# Maps semantic variants to Tailwind classes
|
|
7
|
+
class Variants
|
|
8
|
+
BUTTON = {
|
|
9
|
+
primary: "kz-variant-primary",
|
|
10
|
+
secondary: "kz-variant-secondary",
|
|
11
|
+
accent: "kz-variant-accent",
|
|
12
|
+
success: "kz-variant-success",
|
|
13
|
+
warning: "kz-variant-warning",
|
|
14
|
+
error: "kz-variant-error",
|
|
15
|
+
ghost: "kz-variant-ghost",
|
|
16
|
+
outline: "kz-variant-outline"
|
|
17
|
+
}.freeze
|
|
18
|
+
|
|
19
|
+
BADGE = {
|
|
20
|
+
primary: "kz-badge-primary",
|
|
21
|
+
secondary: "kz-badge-secondary",
|
|
22
|
+
success: "kz-badge-success",
|
|
23
|
+
warning: "kz-badge-warning",
|
|
24
|
+
error: "kz-badge-error",
|
|
25
|
+
info: "kz-badge-info"
|
|
26
|
+
}.freeze
|
|
27
|
+
|
|
28
|
+
SIZES = {
|
|
29
|
+
xs: "kz-size-xs",
|
|
30
|
+
sm: "kz-size-sm",
|
|
31
|
+
md: "kz-size-md",
|
|
32
|
+
lg: "kz-size-lg",
|
|
33
|
+
xl: "kz-size-xl"
|
|
34
|
+
}.freeze
|
|
35
|
+
|
|
36
|
+
class << self
|
|
37
|
+
def button(variant)
|
|
38
|
+
BUTTON[variant] || BUTTON[:primary]
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def badge(variant)
|
|
42
|
+
BADGE[variant] || BADGE[:primary]
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def size(size)
|
|
46
|
+
SIZES[size] || SIZES[:md]
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
data/lib/kozenet_ui.rb
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "kozenet_ui/version"
|
|
4
|
+
require_relative "kozenet_ui/engine"
|
|
5
|
+
require_relative "kozenet_ui/configuration"
|
|
6
|
+
require_relative "kozenet_ui/theme/tokens"
|
|
7
|
+
require_relative "kozenet_ui/theme/palette"
|
|
8
|
+
require_relative "kozenet_ui/theme/variants"
|
|
9
|
+
|
|
10
|
+
# Main entry point for Kozenet UI gem
|
|
11
|
+
module KozenetUi
|
|
12
|
+
class Error < StandardError; end
|
|
13
|
+
|
|
14
|
+
class << self
|
|
15
|
+
attr_writer :configuration
|
|
16
|
+
|
|
17
|
+
def configuration
|
|
18
|
+
@configuration ||= Configuration.new
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def configure
|
|
22
|
+
yield(configuration)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Reset configuration (useful for testing)
|
|
26
|
+
def reset_configuration!
|
|
27
|
+
@configuration = Configuration.new
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|