senren-ui 0.1.5 → 0.2.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 +4 -4
- data/CHANGELOG.md +124 -2
- data/CONTRIBUTING.md +79 -9
- data/README.md +149 -14
- data/Rakefile +14 -1
- data/docs/components.md +222 -0
- data/docs/hot_reload.md +103 -0
- data/docs/performance_testing.md +38 -0
- data/lib/commands/senren/add/add_command.rb +35 -0
- data/lib/generators/senren/component/templates/controller.js.tt +7 -4
- data/lib/generators/senren/install/install_generator.rb +74 -0
- data/lib/generators/senren/install/templates/base_component.rb.tt +89 -8
- data/lib/generators/senren/install/templates/conventions.md.tt +26 -7
- data/lib/senren/rails/agent_rules_writer.rb +62 -19
- data/lib/senren/rails/asset_path_guard.rb +128 -0
- data/lib/senren/rails/base_component_patch.rb +64 -0
- data/lib/senren/rails/component_copier.rb +138 -18
- data/lib/senren/rails/component_installer.rb +73 -0
- data/lib/senren/rails/doctor.rb +7 -4
- data/lib/senren/rails/engine.rb +23 -0
- data/lib/senren/rails/host_paths.rb +11 -2
- data/lib/senren/rails/marker_block.rb +81 -0
- data/lib/senren/rails/registry.rb +73 -35
- data/lib/senren/rails/safe_write.rb +169 -0
- data/lib/senren/rails/skill_writer.rb +48 -12
- data/lib/senren/rails/version.rb +1 -1
- data/lib/senren/rails.rb +2 -1
- data/lib/senren-ui.rb +15 -0
- data/lib/tasks/senren.rake +53 -34
- data/registry/components.yml +45 -0
- data/registry/recipes.yml +12 -0
- data/templates/components/alert_dialog/alert_dialog_component.rb +1 -1
- data/templates/components/api_key_field/api_key_field_component.html.erb +1 -1
- data/templates/components/aspect_ratio/aspect_ratio_component.rb +7 -0
- data/templates/components/avatar/avatar_component.rb +8 -1
- data/templates/components/billing_plan_card/billing_plan_card_component.html.erb +1 -1
- data/templates/components/breadcrumb/breadcrumb_component.rb +2 -2
- data/templates/components/button/button_component.html.erb +1 -1
- data/templates/components/carousel/carousel_component.rb +1 -1
- data/templates/components/cart/cart_component.html.erb +61 -0
- data/templates/components/cart/cart_component.rb +71 -0
- data/templates/components/checkbox/checkbox_component.rb +1 -1
- data/templates/components/clipboard/clipboard_component.html.erb +1 -1
- data/templates/components/command/command_component.rb +2 -2
- data/templates/components/date_picker/date_picker_component.html.erb +1 -1
- data/templates/components/dialog/dialog_component.rb +1 -1
- data/templates/components/dropdown_menu/dropdown_menu_component.rb +10 -7
- data/templates/components/form/form_component.html.erb +8 -1
- data/templates/components/form/form_component.rb +12 -2
- data/templates/components/input/input_component.html.erb +1 -1
- data/templates/components/input/input_component.rb +19 -0
- data/templates/components/invite_member_dialog/invite_member_dialog_component.rb +1 -1
- data/templates/components/label/label_component.html.erb +1 -2
- data/templates/components/label/label_component.rb +12 -2
- data/templates/components/link/link_component.html.erb +1 -1
- data/templates/components/native_select/native_select_component.html.erb +19 -5
- data/templates/components/native_select/native_select_component.rb +17 -5
- data/templates/components/pagination/pagination_component.rb +2 -1
- data/templates/components/product_card/product_card_component.html.erb +38 -0
- data/templates/components/product_card/product_card_component.rb +49 -0
- data/templates/components/rich_text_editor_lite/rich_text_editor_lite_component.html.erb +1 -1
- data/templates/components/rich_text_editor_lite/rich_text_editor_lite_component.rb +1 -1
- data/templates/components/separator/separator_component.rb +7 -0
- data/templates/components/sheet/sheet_component.rb +1 -1
- data/templates/components/sidebar/sidebar_component.rb +2 -2
- data/templates/components/switch/switch_component.html.erb +2 -2
- data/templates/components/tooltip/tooltip_component.rb +2 -2
- data/templates/components/top_nav/top_nav_component.rb +2 -2
- data/templates/components/typography/typography_component.rb +7 -0
- data/templates/controllers/accordion_controller.js +1 -1
- data/templates/controllers/alert_dialog_controller.js +31 -7
- data/templates/controllers/cart_controller.js +83 -0
- data/templates/controllers/clipboard_controller.js +12 -1
- data/templates/controllers/command_controller.js +3 -4
- data/templates/controllers/context_menu_controller.js +38 -11
- data/templates/controllers/data_table_controller.js +8 -3
- data/templates/controllers/dialog_controller.js +47 -21
- data/templates/controllers/dropdown_menu_controller.js +40 -27
- data/templates/controllers/hover_card_controller.js +8 -0
- data/templates/controllers/invite_member_dialog_controller.js +6 -0
- data/templates/controllers/masked_input_controller.js +8 -1
- data/templates/controllers/popover_controller.js +25 -10
- data/templates/controllers/rich_text_editor_lite_controller.js +175 -28
- data/templates/controllers/sheet_controller.js +41 -11
- metadata +20 -6
- data/lib/senren/rails/installer.rb +0 -84
|
@@ -2,33 +2,63 @@ import { Controller } from "@hotwired/stimulus"
|
|
|
2
2
|
|
|
3
3
|
// senren--sheet
|
|
4
4
|
// Side panel; behaves like a dialog.
|
|
5
|
+
//
|
|
6
|
+
// State lives in `openValue`. Actions assign it; openValueChanged performs every
|
|
7
|
+
// DOM change, so the panel can be opened from the server and survives a morph.
|
|
5
8
|
export default class extends Controller {
|
|
6
9
|
static targets = ["overlay", "panel", "trigger"]
|
|
10
|
+
static values = { open: Boolean }
|
|
11
|
+
|
|
12
|
+
connect() {
|
|
13
|
+
this._onKey = this._onKey.bind(this)
|
|
14
|
+
this._onBeforeCache = this._onBeforeCache.bind(this)
|
|
15
|
+
document.addEventListener("turbo:before-cache", this._onBeforeCache)
|
|
16
|
+
}
|
|
7
17
|
|
|
8
|
-
connect() { this._onKey = this._onKey.bind(this) }
|
|
9
18
|
disconnect() {
|
|
10
19
|
document.removeEventListener("keydown", this._onKey)
|
|
20
|
+
document.removeEventListener("turbo:before-cache", this._onBeforeCache)
|
|
11
21
|
document.body.style.overflow = ""
|
|
12
22
|
}
|
|
13
23
|
|
|
14
24
|
open(event) {
|
|
15
25
|
event?.preventDefault()
|
|
16
|
-
this.
|
|
17
|
-
this.panelTarget.hidden = false
|
|
18
|
-
this.panelTarget.dataset.open = "true"
|
|
19
|
-
document.addEventListener("keydown", this._onKey)
|
|
20
|
-
document.body.style.overflow = "hidden"
|
|
21
|
-
queueMicrotask(() => this.panelTarget?.focus())
|
|
26
|
+
this.openValue = true
|
|
22
27
|
}
|
|
23
28
|
|
|
24
29
|
close(event) {
|
|
25
30
|
event?.preventDefault()
|
|
26
|
-
this.
|
|
27
|
-
|
|
28
|
-
|
|
31
|
+
this.openValue = false
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
openValueChanged(isOpen, wasOpen) {
|
|
35
|
+
if (this.hasOverlayTarget) this.overlayTarget.hidden = !isOpen
|
|
36
|
+
if (this.hasPanelTarget) {
|
|
37
|
+
this.panelTarget.hidden = !isOpen
|
|
38
|
+
this.panelTarget.dataset.open = isOpen ? "true" : "false"
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (isOpen) {
|
|
42
|
+
document.addEventListener("keydown", this._onKey)
|
|
43
|
+
document.body.style.overflow = "hidden"
|
|
44
|
+
queueMicrotask(() => this.panelTarget?.focus())
|
|
45
|
+
this.dispatch("opened")
|
|
46
|
+
return
|
|
47
|
+
}
|
|
48
|
+
|
|
29
49
|
document.removeEventListener("keydown", this._onKey)
|
|
30
50
|
document.body.style.overflow = ""
|
|
51
|
+
if (wasOpen !== undefined) this.dispatch("closed")
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
_onKey(event) {
|
|
55
|
+
if (event.key === "Escape") this.close()
|
|
31
56
|
}
|
|
32
57
|
|
|
33
|
-
|
|
58
|
+
// Turbo snapshots the page before navigating away; without this the scroll
|
|
59
|
+
// lock is captured while applied and a back navigation restores a page that
|
|
60
|
+
// cannot be scrolled.
|
|
61
|
+
_onBeforeCache() {
|
|
62
|
+
this.openValue = false
|
|
63
|
+
}
|
|
34
64
|
}
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: senren-ui
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- vutt
|
|
@@ -29,14 +29,14 @@ dependencies:
|
|
|
29
29
|
requirements:
|
|
30
30
|
- - ">="
|
|
31
31
|
- !ruby/object:Gem::Version
|
|
32
|
-
version:
|
|
32
|
+
version: 4.9.0
|
|
33
33
|
type: :runtime
|
|
34
34
|
prerelease: false
|
|
35
35
|
version_requirements: !ruby/object:Gem::Requirement
|
|
36
36
|
requirements:
|
|
37
37
|
- - ">="
|
|
38
38
|
- !ruby/object:Gem::Version
|
|
39
|
-
version:
|
|
39
|
+
version: 4.9.0
|
|
40
40
|
description: |
|
|
41
41
|
Senren UI is a Rails-native UI component library inspired by the developer
|
|
42
42
|
experience of shadcn/ui. It ships generators, a registry, and a centralized
|
|
@@ -53,7 +53,11 @@ files:
|
|
|
53
53
|
- LICENSE
|
|
54
54
|
- README.md
|
|
55
55
|
- Rakefile
|
|
56
|
+
- docs/components.md
|
|
57
|
+
- docs/hot_reload.md
|
|
58
|
+
- docs/performance_testing.md
|
|
56
59
|
- docs/visual_style.md
|
|
60
|
+
- lib/commands/senren/add/add_command.rb
|
|
57
61
|
- lib/generators/senren/component/component_generator.rb
|
|
58
62
|
- lib/generators/senren/component/templates/component.html.erb.tt
|
|
59
63
|
- lib/generators/senren/component/templates/component.rb.tt
|
|
@@ -65,15 +69,20 @@ files:
|
|
|
65
69
|
- lib/generators/senren/install/templates/conventions.md.tt
|
|
66
70
|
- lib/generators/senren/install/templates/installed_components.yml.tt
|
|
67
71
|
- lib/generators/senren/install/templates/senren.css.tt
|
|
72
|
+
- lib/senren-ui.rb
|
|
68
73
|
- lib/senren/rails.rb
|
|
69
74
|
- lib/senren/rails/agent_rules_writer.rb
|
|
75
|
+
- lib/senren/rails/asset_path_guard.rb
|
|
76
|
+
- lib/senren/rails/base_component_patch.rb
|
|
70
77
|
- lib/senren/rails/component_copier.rb
|
|
78
|
+
- lib/senren/rails/component_installer.rb
|
|
71
79
|
- lib/senren/rails/doctor.rb
|
|
72
80
|
- lib/senren/rails/engine.rb
|
|
73
81
|
- lib/senren/rails/host_paths.rb
|
|
74
|
-
- lib/senren/rails/installer.rb
|
|
75
82
|
- lib/senren/rails/llms_writer.rb
|
|
83
|
+
- lib/senren/rails/marker_block.rb
|
|
76
84
|
- lib/senren/rails/registry.rb
|
|
85
|
+
- lib/senren/rails/safe_write.rb
|
|
77
86
|
- lib/senren/rails/skill_writer.rb
|
|
78
87
|
- lib/senren/rails/version.rb
|
|
79
88
|
- lib/tasks/senren.rake
|
|
@@ -112,6 +121,8 @@ files:
|
|
|
112
121
|
- templates/components/card/card_component.rb
|
|
113
122
|
- templates/components/carousel/carousel_component.html.erb
|
|
114
123
|
- templates/components/carousel/carousel_component.rb
|
|
124
|
+
- templates/components/cart/cart_component.html.erb
|
|
125
|
+
- templates/components/cart/cart_component.rb
|
|
115
126
|
- templates/components/checkbox/checkbox_component.html.erb
|
|
116
127
|
- templates/components/checkbox/checkbox_component.rb
|
|
117
128
|
- templates/components/checkbox_group/checkbox_group_component.html.erb
|
|
@@ -162,6 +173,8 @@ files:
|
|
|
162
173
|
- templates/components/pagination/pagination_component.rb
|
|
163
174
|
- templates/components/popover/popover_component.html.erb
|
|
164
175
|
- templates/components/popover/popover_component.rb
|
|
176
|
+
- templates/components/product_card/product_card_component.html.erb
|
|
177
|
+
- templates/components/product_card/product_card_component.rb
|
|
165
178
|
- templates/components/progress/progress_component.html.erb
|
|
166
179
|
- templates/components/progress/progress_component.rb
|
|
167
180
|
- templates/components/radio_button/radio_button_component.html.erb
|
|
@@ -209,6 +222,7 @@ files:
|
|
|
209
222
|
- templates/controllers/api_key_field_controller.js
|
|
210
223
|
- templates/controllers/calendar_controller.js
|
|
211
224
|
- templates/controllers/carousel_controller.js
|
|
225
|
+
- templates/controllers/cart_controller.js
|
|
212
226
|
- templates/controllers/clipboard_controller.js
|
|
213
227
|
- templates/controllers/collapsible_controller.js
|
|
214
228
|
- templates/controllers/combobox_controller.js
|
|
@@ -245,14 +259,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
245
259
|
requirements:
|
|
246
260
|
- - ">="
|
|
247
261
|
- !ruby/object:Gem::Version
|
|
248
|
-
version: 3.
|
|
262
|
+
version: 3.2.0
|
|
249
263
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
250
264
|
requirements:
|
|
251
265
|
- - ">="
|
|
252
266
|
- !ruby/object:Gem::Version
|
|
253
267
|
version: '0'
|
|
254
268
|
requirements: []
|
|
255
|
-
rubygems_version: 4.0.
|
|
269
|
+
rubygems_version: 4.0.6
|
|
256
270
|
specification_version: 4
|
|
257
271
|
summary: Rails-native UI component library with ViewComponent, Hotwire, Tailwind,
|
|
258
272
|
and AI-agent skill files.
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'fileutils'
|
|
4
|
-
|
|
5
|
-
module Senren
|
|
6
|
-
module Rails
|
|
7
|
-
# Idempotent installer that lays down the .senren directory, base
|
|
8
|
-
# component, stylesheet, and agent instruction files. Reused by the install
|
|
9
|
-
# generator and by ad-hoc rake task entry points.
|
|
10
|
-
class Installer
|
|
11
|
-
attr_reader :paths, :stdout
|
|
12
|
-
|
|
13
|
-
def initialize(paths: HostPaths.new, stdout: $stdout)
|
|
14
|
-
@paths = paths
|
|
15
|
-
@stdout = stdout
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def run!(force: false)
|
|
19
|
-
paths.ensure_dirs!
|
|
20
|
-
install_static_files(force: force)
|
|
21
|
-
mirror_registry
|
|
22
|
-
SkillWriter.new(paths: paths).sync!
|
|
23
|
-
AgentRulesWriter.new(paths: paths).sync!
|
|
24
|
-
print_next_steps
|
|
25
|
-
true
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
INSTALL_GENERATOR_TEMPLATES = File.expand_path(
|
|
29
|
-
'../../generators/senren/install/templates', __dir__
|
|
30
|
-
).freeze
|
|
31
|
-
|
|
32
|
-
STATIC_FILES = {
|
|
33
|
-
'conventions.md.tt' => :conventions_file,
|
|
34
|
-
'installed_components.yml.tt' => :installed_components,
|
|
35
|
-
'base_component.rb.tt' => :base_component_path,
|
|
36
|
-
'senren.css.tt' => :stylesheet_path
|
|
37
|
-
}.freeze
|
|
38
|
-
|
|
39
|
-
private
|
|
40
|
-
|
|
41
|
-
def install_static_files(force:)
|
|
42
|
-
STATIC_FILES.each do |template_basename, paths_method|
|
|
43
|
-
src = File.join(INSTALL_GENERATOR_TEMPLATES, template_basename)
|
|
44
|
-
dest = paths.public_send(paths_method)
|
|
45
|
-
copy_template(src, dest, force: force)
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
def copy_template(src, dest, force:)
|
|
50
|
-
unless File.exist?(src)
|
|
51
|
-
stdout.puts " warn template missing: #{src}"
|
|
52
|
-
return
|
|
53
|
-
end
|
|
54
|
-
if File.exist?(dest) && !force
|
|
55
|
-
stdout.puts " skip #{dest}"
|
|
56
|
-
return
|
|
57
|
-
end
|
|
58
|
-
FileUtils.mkdir_p(File.dirname(dest))
|
|
59
|
-
FileUtils.cp(src, dest)
|
|
60
|
-
stdout.puts " copy #{dest}"
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
def mirror_registry
|
|
64
|
-
FileUtils.mkdir_p(paths.registry_mirror.dirname)
|
|
65
|
-
FileUtils.cp(Senren::Rails.registry_path, paths.registry_mirror)
|
|
66
|
-
stdout.puts " mirror #{paths.registry_mirror}"
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
def print_next_steps
|
|
70
|
-
stdout.puts <<~MSG
|
|
71
|
-
|
|
72
|
-
Senren installed. Next steps:
|
|
73
|
-
|
|
74
|
-
bin/rails senren:add button card badge alert
|
|
75
|
-
bin/rails senren:add dialog dropdown_menu
|
|
76
|
-
bin/rails senren:agents:sync
|
|
77
|
-
bin/rails senren:doctor
|
|
78
|
-
|
|
79
|
-
Read .senren/skill.md and .senren/conventions.md to get oriented.
|
|
80
|
-
MSG
|
|
81
|
-
end
|
|
82
|
-
end
|
|
83
|
-
end
|
|
84
|
-
end
|