shadcn-phlex 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.
Files changed (113) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +195 -0
  3. data/app.css +20 -0
  4. data/css/shadcn-source.css +3 -0
  5. data/css/shadcn-tailwind.css +160 -0
  6. data/css/themes/mauve.css +62 -0
  7. data/css/themes/mist.css +62 -0
  8. data/css/themes/neutral.css +74 -0
  9. data/css/themes/olive.css +62 -0
  10. data/css/themes/stone.css +62 -0
  11. data/css/themes/taupe.css +62 -0
  12. data/css/themes/zinc.css +62 -0
  13. data/js/controllers/accordion_controller.js +135 -0
  14. data/js/controllers/checkbox_controller.js +52 -0
  15. data/js/controllers/collapsible_controller.js +85 -0
  16. data/js/controllers/combobox_controller.js +168 -0
  17. data/js/controllers/command_controller.js +171 -0
  18. data/js/controllers/context_menu_controller.js +132 -0
  19. data/js/controllers/dark_mode_controller.js +106 -0
  20. data/js/controllers/dialog_controller.js +205 -0
  21. data/js/controllers/drawer_controller.js +161 -0
  22. data/js/controllers/dropdown_menu_controller.js +189 -0
  23. data/js/controllers/hover_card_controller.js +85 -0
  24. data/js/controllers/index.js +89 -0
  25. data/js/controllers/menubar_controller.js +171 -0
  26. data/js/controllers/navigation_menu_controller.js +160 -0
  27. data/js/controllers/popover_controller.js +151 -0
  28. data/js/controllers/radio_group_controller.js +78 -0
  29. data/js/controllers/scroll_area_controller.js +117 -0
  30. data/js/controllers/select_controller.js +198 -0
  31. data/js/controllers/sheet_controller.js +130 -0
  32. data/js/controllers/slider_controller.js +142 -0
  33. data/js/controllers/switch_controller.js +40 -0
  34. data/js/controllers/tabs_controller.js +96 -0
  35. data/js/controllers/toast_controller.js +206 -0
  36. data/js/controllers/toggle_controller.js +30 -0
  37. data/js/controllers/toggle_group_controller.js +73 -0
  38. data/js/controllers/tooltip_controller.js +146 -0
  39. data/lib/generators/shadcn_phlex/component_generator.rb +79 -0
  40. data/lib/generators/shadcn_phlex/install_generator.rb +217 -0
  41. data/lib/shadcn/base.rb +27 -0
  42. data/lib/shadcn/engine.rb +24 -0
  43. data/lib/shadcn/kit.rb +1158 -0
  44. data/lib/shadcn/themes/accent_colors.rb +106 -0
  45. data/lib/shadcn/themes/base_colors.rb +313 -0
  46. data/lib/shadcn/ui/accordion.rb +135 -0
  47. data/lib/shadcn/ui/alert.rb +79 -0
  48. data/lib/shadcn/ui/alert_dialog.rb +220 -0
  49. data/lib/shadcn/ui/aspect_ratio.rb +35 -0
  50. data/lib/shadcn/ui/avatar.rb +134 -0
  51. data/lib/shadcn/ui/badge.rb +48 -0
  52. data/lib/shadcn/ui/breadcrumb.rb +180 -0
  53. data/lib/shadcn/ui/button.rb +63 -0
  54. data/lib/shadcn/ui/button_group.rb +58 -0
  55. data/lib/shadcn/ui/card.rb +133 -0
  56. data/lib/shadcn/ui/checkbox.rb +72 -0
  57. data/lib/shadcn/ui/collapsible.rb +76 -0
  58. data/lib/shadcn/ui/combobox.rb +229 -0
  59. data/lib/shadcn/ui/command.rb +256 -0
  60. data/lib/shadcn/ui/context_menu.rb +319 -0
  61. data/lib/shadcn/ui/dialog.rb +226 -0
  62. data/lib/shadcn/ui/direction.rb +23 -0
  63. data/lib/shadcn/ui/drawer.rb +217 -0
  64. data/lib/shadcn/ui/dropdown_menu.rb +384 -0
  65. data/lib/shadcn/ui/empty.rb +97 -0
  66. data/lib/shadcn/ui/field.rb +126 -0
  67. data/lib/shadcn/ui/hover_card.rb +75 -0
  68. data/lib/shadcn/ui/input.rb +36 -0
  69. data/lib/shadcn/ui/input_group.rb +32 -0
  70. data/lib/shadcn/ui/input_otp.rb +112 -0
  71. data/lib/shadcn/ui/item.rb +115 -0
  72. data/lib/shadcn/ui/kbd.rb +45 -0
  73. data/lib/shadcn/ui/label.rb +28 -0
  74. data/lib/shadcn/ui/menubar.rb +345 -0
  75. data/lib/shadcn/ui/native_select.rb +31 -0
  76. data/lib/shadcn/ui/navigation_menu.rb +238 -0
  77. data/lib/shadcn/ui/pagination.rb +224 -0
  78. data/lib/shadcn/ui/popover.rb +147 -0
  79. data/lib/shadcn/ui/progress.rb +40 -0
  80. data/lib/shadcn/ui/radio_group.rb +92 -0
  81. data/lib/shadcn/ui/resizable.rb +108 -0
  82. data/lib/shadcn/ui/scroll_area.rb +75 -0
  83. data/lib/shadcn/ui/select.rb +235 -0
  84. data/lib/shadcn/ui/separator.rb +36 -0
  85. data/lib/shadcn/ui/sheet.rb +231 -0
  86. data/lib/shadcn/ui/sidebar.rb +420 -0
  87. data/lib/shadcn/ui/skeleton.rb +23 -0
  88. data/lib/shadcn/ui/slider.rb +72 -0
  89. data/lib/shadcn/ui/sonner.rb +177 -0
  90. data/lib/shadcn/ui/spinner.rb +58 -0
  91. data/lib/shadcn/ui/switch.rb +75 -0
  92. data/lib/shadcn/ui/table.rb +154 -0
  93. data/lib/shadcn/ui/tabs.rb +154 -0
  94. data/lib/shadcn/ui/text_field.rb +146 -0
  95. data/lib/shadcn/ui/textarea.rb +32 -0
  96. data/lib/shadcn/ui/theme_toggle.rb +74 -0
  97. data/lib/shadcn/ui/toggle.rb +66 -0
  98. data/lib/shadcn/ui/toggle_group.rb +75 -0
  99. data/lib/shadcn/ui/tooltip.rb +78 -0
  100. data/lib/shadcn/ui/typography.rb +217 -0
  101. data/lib/shadcn/version.rb +5 -0
  102. data/lib/shadcn-phlex.rb +6 -0
  103. data/lib/shadcn.rb +80 -0
  104. data/package.json +14 -0
  105. data/skills/shadcn-phlex/SKILL.md +190 -0
  106. data/skills/shadcn-phlex/evals/evals.json +90 -0
  107. data/skills/shadcn-phlex/references/component-catalog.md +355 -0
  108. data/skills/shadcn-phlex/rules/composition.md +235 -0
  109. data/skills/shadcn-phlex/rules/forms.md +151 -0
  110. data/skills/shadcn-phlex/rules/helpers.md +54 -0
  111. data/skills/shadcn-phlex/rules/stimulus.md +61 -0
  112. data/skills/shadcn-phlex/rules/styling.md +177 -0
  113. metadata +209 -0
@@ -0,0 +1,226 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Shadcn
4
+ module UI
5
+ # Port of shadcn/ui Dialog
6
+ # Wired to shadcn--dialog Stimulus controller
7
+ class Dialog < Base
8
+ def initialize(**attrs)
9
+ @attrs = attrs
10
+ end
11
+
12
+ def view_template(&block)
13
+ div(**build_attrs, &block)
14
+ end
15
+
16
+ private
17
+
18
+ def build_attrs
19
+ @attrs.merge(
20
+ data_slot: "dialog",
21
+ data_controller: "shadcn--dialog",
22
+ data_shadcn__dialog_open_value: false
23
+ )
24
+ end
25
+ end
26
+
27
+ class DialogTrigger < Base
28
+ def initialize(**attrs)
29
+ @attrs = attrs
30
+ end
31
+
32
+ def view_template(&block)
33
+ div(**build_attrs, &block)
34
+ end
35
+
36
+ private
37
+
38
+ def build_attrs
39
+ @attrs.merge(
40
+ data_slot: "dialog-trigger",
41
+ data_shadcn__dialog_target: "trigger",
42
+ data_action: "click->shadcn--dialog#show",
43
+ role: "button",
44
+ style: "display: inline-block"
45
+ )
46
+ end
47
+ end
48
+
49
+ class DialogOverlay < Base
50
+ def initialize(**attrs)
51
+ @attrs = attrs
52
+ end
53
+
54
+ def view_template
55
+ div(**build_attrs)
56
+ end
57
+
58
+ private
59
+
60
+ def build_attrs
61
+ classes = cn(
62
+ "fixed inset-0 z-50 bg-black/50",
63
+ "data-[state=closed]:animate-out data-[state=closed]:fade-out-0",
64
+ "data-[state=open]:animate-in data-[state=open]:fade-in-0",
65
+ @attrs.delete(:class)
66
+ )
67
+ @attrs.merge(
68
+ data_slot: "dialog-overlay",
69
+ data_shadcn__dialog_target: "overlay",
70
+ data_action: "click->shadcn--dialog#clickOverlay",
71
+ hidden: true,
72
+ class: classes
73
+ )
74
+ end
75
+ end
76
+
77
+ class DialogContent < Base
78
+ def initialize(show_close_button: true, **attrs)
79
+ @show_close_button = show_close_button
80
+ @attrs = attrs
81
+ end
82
+
83
+ def view_template(&block)
84
+ render DialogOverlay.new
85
+
86
+ div(**build_attrs) do
87
+ yield if block_given?
88
+
89
+ if @show_close_button
90
+ button(
91
+ data_slot: "dialog-close",
92
+ data_shadcn__dialog_target: "close",
93
+ data_action: "click->shadcn--dialog#hide",
94
+ type: "button",
95
+ class: "absolute top-4 right-4 rounded-xs opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4"
96
+ ) do
97
+ svg(
98
+ xmlns: "http://www.w3.org/2000/svg",
99
+ width: "16", height: "16",
100
+ viewbox: "0 0 24 24",
101
+ fill: "none",
102
+ stroke: "currentColor",
103
+ stroke_width: "2",
104
+ stroke_linecap: "round",
105
+ stroke_linejoin: "round",
106
+ class: "size-4"
107
+ ) do |s|
108
+ s.path(d: "M18 6 6 18")
109
+ s.path(d: "m6 6 12 12")
110
+ end
111
+ span(class: "sr-only") { "Close" }
112
+ end
113
+ end
114
+ end
115
+ end
116
+
117
+ private
118
+
119
+ def build_attrs
120
+ classes = cn(
121
+ "fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%]",
122
+ "gap-4 rounded-lg border bg-background p-6 shadow-lg duration-200 outline-none",
123
+ "data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
124
+ "data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
125
+ "sm:max-w-lg",
126
+ @attrs.delete(:class)
127
+ )
128
+ @attrs.merge(
129
+ data_slot: "dialog-content",
130
+ data_shadcn__dialog_target: "content",
131
+ role: "dialog",
132
+ hidden: true,
133
+ class: classes
134
+ )
135
+ end
136
+ end
137
+
138
+ class DialogHeader < Base
139
+ def initialize(**attrs)
140
+ @attrs = attrs
141
+ end
142
+
143
+ def view_template(&block)
144
+ div(**build_attrs, &block)
145
+ end
146
+
147
+ private
148
+
149
+ def build_attrs
150
+ classes = cn("flex flex-col gap-2 text-center sm:text-left", @attrs.delete(:class))
151
+ @attrs.merge(data_slot: "dialog-header", class: classes)
152
+ end
153
+ end
154
+
155
+ class DialogFooter < Base
156
+ def initialize(**attrs)
157
+ @attrs = attrs
158
+ end
159
+
160
+ def view_template(&block)
161
+ div(**build_attrs, &block)
162
+ end
163
+
164
+ private
165
+
166
+ def build_attrs
167
+ classes = cn("flex flex-col-reverse gap-2 sm:flex-row sm:justify-end", @attrs.delete(:class))
168
+ @attrs.merge(data_slot: "dialog-footer", class: classes)
169
+ end
170
+ end
171
+
172
+ class DialogTitle < Base
173
+ def initialize(**attrs)
174
+ @attrs = attrs
175
+ end
176
+
177
+ def view_template(&block)
178
+ h2(**build_attrs, &block)
179
+ end
180
+
181
+ private
182
+
183
+ def build_attrs
184
+ classes = cn("text-lg leading-none font-semibold", @attrs.delete(:class))
185
+ @attrs.merge(data_slot: "dialog-title", data_shadcn__dialog_target: "title", class: classes)
186
+ end
187
+ end
188
+
189
+ class DialogDescription < Base
190
+ def initialize(**attrs)
191
+ @attrs = attrs
192
+ end
193
+
194
+ def view_template(&block)
195
+ p(**build_attrs, &block)
196
+ end
197
+
198
+ private
199
+
200
+ def build_attrs
201
+ classes = cn("text-sm text-muted-foreground", @attrs.delete(:class))
202
+ @attrs.merge(data_slot: "dialog-description", data_shadcn__dialog_target: "description", class: classes)
203
+ end
204
+ end
205
+
206
+ class DialogClose < Base
207
+ def initialize(**attrs)
208
+ @attrs = attrs
209
+ end
210
+
211
+ def view_template(&block)
212
+ button(**build_attrs, &block)
213
+ end
214
+
215
+ private
216
+
217
+ def build_attrs
218
+ @attrs.merge(
219
+ data_slot: "dialog-close",
220
+ data_action: "click->shadcn--dialog#hide",
221
+ type: "button"
222
+ )
223
+ end
224
+ end
225
+ end
226
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Shadcn
4
+ module UI
5
+ # Port of shadcn/ui Direction (RTL/LTR wrapper)
6
+ class Direction < Base
7
+ def initialize(dir: :ltr, **attrs)
8
+ @dir = dir
9
+ @attrs = attrs
10
+ end
11
+
12
+ def view_template(&block)
13
+ div(**build_attrs, &block)
14
+ end
15
+
16
+ private
17
+
18
+ def build_attrs
19
+ @attrs.merge(data_slot: "direction", dir: @dir.to_s)
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,217 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Shadcn
4
+ module UI
5
+ # Port of shadcn/ui Drawer
6
+ class Drawer < Base
7
+ def initialize(**attrs)
8
+ @attrs = attrs
9
+ end
10
+
11
+ def view_template(&block)
12
+ div(**build_attrs, &block)
13
+ end
14
+
15
+ private
16
+
17
+ def build_attrs
18
+ @attrs.merge(
19
+ data_slot: "drawer",
20
+ data_controller: "shadcn--drawer"
21
+ )
22
+ end
23
+ end
24
+
25
+ class DrawerTrigger < Base
26
+ def initialize(**attrs)
27
+ @attrs = attrs
28
+ end
29
+
30
+ def view_template(&block)
31
+ div(**build_attrs, &block)
32
+ end
33
+
34
+ private
35
+
36
+ def build_attrs
37
+ @attrs.merge(
38
+ data_slot: "drawer-trigger",
39
+ data_shadcn__drawer_target: "trigger",
40
+ data_action: "click->shadcn--drawer#show",
41
+ role: "button",
42
+ style: "display: inline-block"
43
+ )
44
+ end
45
+ end
46
+
47
+ class DrawerClose < Base
48
+ def initialize(**attrs)
49
+ @attrs = attrs
50
+ end
51
+
52
+ def view_template(&block)
53
+ button(**build_attrs, &block)
54
+ end
55
+
56
+ private
57
+
58
+ def build_attrs
59
+ @attrs.merge(
60
+ data_slot: "drawer-close",
61
+ data_action: "click->shadcn--drawer#hide",
62
+ type: "button"
63
+ )
64
+ end
65
+ end
66
+
67
+ class DrawerOverlay < Base
68
+ def initialize(**attrs)
69
+ @attrs = attrs
70
+ end
71
+
72
+ def view_template
73
+ div(**build_attrs)
74
+ end
75
+
76
+ private
77
+
78
+ def build_attrs
79
+ classes = cn(
80
+ "fixed inset-0 z-50 bg-black/50",
81
+ "data-[state=closed]:animate-out data-[state=closed]:fade-out-0",
82
+ "data-[state=open]:animate-in data-[state=open]:fade-in-0",
83
+ @attrs.delete(:class)
84
+ )
85
+ @attrs.merge(
86
+ data_slot: "drawer-overlay",
87
+ data_shadcn__drawer_target: "overlay",
88
+ data_action: "click->shadcn--drawer#clickOverlay",
89
+ hidden: true,
90
+ class: classes
91
+ )
92
+ end
93
+ end
94
+
95
+ class DrawerContent < Base
96
+ def initialize(direction: :bottom, **attrs)
97
+ @direction = direction.to_sym
98
+ @attrs = attrs
99
+ end
100
+
101
+ def view_template(&block)
102
+ render DrawerOverlay.new
103
+
104
+ div(**build_attrs) do
105
+ if @direction == :bottom
106
+ div(class: "mx-auto mt-4 hidden h-2 w-[100px] shrink-0 rounded-full bg-muted group-data-[vaul-drawer-direction=bottom]/drawer-content:block")
107
+ end
108
+ yield if block_given?
109
+ end
110
+ end
111
+
112
+ private
113
+
114
+ def build_attrs
115
+ classes = cn(
116
+ "group/drawer-content fixed z-50 flex h-auto flex-col bg-background",
117
+ direction_classes,
118
+ @attrs.delete(:class)
119
+ )
120
+ @attrs.merge(
121
+ data_slot: "drawer-content",
122
+ data_shadcn__drawer_target: "content",
123
+ data_vaul_drawer_direction: @direction,
124
+ hidden: true,
125
+ class: classes
126
+ )
127
+ end
128
+
129
+ def direction_classes
130
+ case @direction
131
+ when :top
132
+ "inset-x-0 top-0 mb-24 max-h-[80vh] rounded-b-lg border-b"
133
+ when :bottom
134
+ "inset-x-0 bottom-0 mt-24 max-h-[80vh] rounded-t-lg border-t"
135
+ when :right
136
+ "inset-y-0 right-0 w-3/4 border-l sm:max-w-sm"
137
+ when :left
138
+ "inset-y-0 left-0 w-3/4 border-r sm:max-w-sm"
139
+ end
140
+ end
141
+ end
142
+
143
+ class DrawerHeader < Base
144
+ def initialize(**attrs)
145
+ @attrs = attrs
146
+ end
147
+
148
+ def view_template(&block)
149
+ div(**build_attrs, &block)
150
+ end
151
+
152
+ private
153
+
154
+ def build_attrs
155
+ classes = cn(
156
+ "flex flex-col gap-0.5 p-4",
157
+ "group-data-[vaul-drawer-direction=bottom]/drawer-content:text-center",
158
+ "group-data-[vaul-drawer-direction=top]/drawer-content:text-center",
159
+ "md:gap-1.5 md:text-left",
160
+ @attrs.delete(:class)
161
+ )
162
+ @attrs.merge(data_slot: "drawer-header", class: classes)
163
+ end
164
+ end
165
+
166
+ class DrawerFooter < Base
167
+ def initialize(**attrs)
168
+ @attrs = attrs
169
+ end
170
+
171
+ def view_template(&block)
172
+ div(**build_attrs, &block)
173
+ end
174
+
175
+ private
176
+
177
+ def build_attrs
178
+ classes = cn("mt-auto flex flex-col gap-2 p-4", @attrs.delete(:class))
179
+ @attrs.merge(data_slot: "drawer-footer", class: classes)
180
+ end
181
+ end
182
+
183
+ class DrawerTitle < Base
184
+ def initialize(**attrs)
185
+ @attrs = attrs
186
+ end
187
+
188
+ def view_template(&block)
189
+ h2(**build_attrs, &block)
190
+ end
191
+
192
+ private
193
+
194
+ def build_attrs
195
+ classes = cn("font-semibold text-foreground", @attrs.delete(:class))
196
+ @attrs.merge(data_slot: "drawer-title", class: classes)
197
+ end
198
+ end
199
+
200
+ class DrawerDescription < Base
201
+ def initialize(**attrs)
202
+ @attrs = attrs
203
+ end
204
+
205
+ def view_template(&block)
206
+ p(**build_attrs, &block)
207
+ end
208
+
209
+ private
210
+
211
+ def build_attrs
212
+ classes = cn("text-sm text-muted-foreground", @attrs.delete(:class))
213
+ @attrs.merge(data_slot: "drawer-description", class: classes)
214
+ end
215
+ end
216
+ end
217
+ end