shadcn_phlexcomponents 0.1.17 → 0.1.19
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/README.md +321 -23
- data/app/javascript/controllers/accordion_controller.js +1 -0
- data/app/javascript/controllers/alert_dialog_controller.js +1 -0
- data/app/javascript/controllers/avatar_controller.js +1 -0
- data/app/javascript/controllers/checkbox_controller.js +1 -0
- data/app/javascript/controllers/collapsible_controller.js +1 -0
- data/app/javascript/controllers/combobox_controller.js +1 -1
- data/app/javascript/controllers/command_controller.js +1 -0
- data/app/javascript/controllers/date_picker_controller.js +21 -5
- data/app/javascript/controllers/date_range_picker_controller.js +1 -0
- data/app/javascript/controllers/dialog_controller.js +1 -0
- data/app/javascript/controllers/dropdown_menu_controller.js +1 -0
- data/app/javascript/controllers/dropdown_menu_sub_controller.js +1 -0
- data/app/javascript/controllers/form_field_controller.js +1 -0
- data/app/javascript/controllers/hover_card_controller.js +1 -0
- data/app/javascript/controllers/loading_button_controller.js +1 -0
- data/app/javascript/controllers/popover_controller.js +1 -0
- data/app/javascript/controllers/progress_controller.js +1 -0
- data/app/javascript/controllers/radio_group_controller.js +1 -0
- data/app/javascript/controllers/select_controller.js +1 -0
- data/app/javascript/controllers/slider_controller.js +1 -0
- data/app/javascript/controllers/switch_controller.js +1 -0
- data/app/javascript/controllers/tabs_controller.js +1 -0
- data/app/javascript/controllers/theme_switcher_controller.js +1 -0
- data/app/javascript/controllers/toast_container_controller.js +1 -0
- data/app/javascript/controllers/toast_controller.js +1 -0
- data/app/javascript/controllers/toggle_controller.js +1 -0
- data/app/javascript/controllers/toggle_group_controller.js +1 -0
- data/app/javascript/controllers/tooltip_controller.js +2 -1
- data/app/javascript/shadcn_phlexcomponents.js +27 -60
- data/app/javascript/utils/command.js +0 -2
- data/app/javascript/utils/floating_ui.js +10 -17
- data/app/stylesheets/date_picker.css +1 -1
- data/app/stylesheets/shadcn_phlexcomponents.css +173 -0
- data/app/typescript/controllers/accordion_controller.ts +2 -0
- data/app/typescript/controllers/alert_dialog_controller.ts +2 -0
- data/app/typescript/controllers/avatar_controller.ts +2 -0
- data/app/typescript/controllers/checkbox_controller.ts +2 -0
- data/app/typescript/controllers/collapsible_controller.ts +2 -0
- data/app/typescript/controllers/combobox_controller.ts +2 -1
- data/app/typescript/controllers/command_controller.ts +2 -0
- data/app/typescript/controllers/date_picker_controller.ts +27 -7
- data/app/typescript/controllers/date_range_picker_controller.ts +2 -0
- data/app/typescript/controllers/dialog_controller.ts +2 -0
- data/app/typescript/controllers/dropdown_menu_controller.ts +2 -0
- data/app/typescript/controllers/dropdown_menu_sub_controller.ts +2 -0
- data/app/typescript/controllers/form_field_controller.ts +2 -0
- data/app/typescript/controllers/hover_card_controller.ts +2 -0
- data/app/typescript/controllers/loading_button_controller.ts +2 -0
- data/app/typescript/controllers/popover_controller.ts +2 -0
- data/app/typescript/controllers/progress_controller.ts +2 -0
- data/app/typescript/controllers/radio_group_controller.ts +2 -0
- data/app/typescript/controllers/select_controller.ts +2 -0
- data/app/typescript/controllers/slider_controller.ts +2 -0
- data/app/typescript/controllers/switch_controller.ts +2 -0
- data/app/typescript/controllers/tabs_controller.ts +2 -0
- data/app/typescript/controllers/theme_switcher_controller.ts +2 -0
- data/app/typescript/controllers/toast_container_controller.ts +2 -0
- data/app/typescript/controllers/toast_controller.ts +2 -0
- data/app/typescript/controllers/toggle_controller.ts +2 -0
- data/app/typescript/controllers/toggle_group_controller.ts +2 -0
- data/app/typescript/controllers/tooltip_controller.ts +3 -1
- data/app/typescript/shadcn_phlexcomponents.ts +27 -61
- data/app/typescript/utils/command.ts +0 -2
- data/app/typescript/utils/floating_ui.ts +11 -20
- data/app/typescript/utils/index.ts +1 -1
- data/lib/install/upgrade_shadcn_phlexcomponents.rb +28 -0
- data/lib/shadcn_phlexcomponents/components/accordion.rb +56 -13
- data/lib/shadcn_phlexcomponents/components/alert.rb +35 -16
- data/lib/shadcn_phlexcomponents/components/alert_dialog.rb +58 -18
- data/lib/shadcn_phlexcomponents/components/aspect_ratio.rb +33 -2
- data/lib/shadcn_phlexcomponents/components/avatar.rb +24 -7
- data/lib/shadcn_phlexcomponents/components/badge.rb +23 -18
- data/lib/shadcn_phlexcomponents/components/base.rb +2 -2
- data/lib/shadcn_phlexcomponents/components/breadcrumb.rb +46 -6
- data/lib/shadcn_phlexcomponents/components/button.rb +32 -27
- data/lib/shadcn_phlexcomponents/components/card.rb +59 -10
- data/lib/shadcn_phlexcomponents/components/checkbox.rb +51 -30
- data/lib/shadcn_phlexcomponents/components/checkbox_group.rb +24 -4
- data/lib/shadcn_phlexcomponents/components/combobox.rb +224 -81
- data/lib/shadcn_phlexcomponents/components/command.rb +167 -63
- data/lib/shadcn_phlexcomponents/components/date_picker.rb +140 -48
- data/lib/shadcn_phlexcomponents/components/date_range_picker.rb +26 -44
- data/lib/shadcn_phlexcomponents/components/dialog.rb +86 -32
- data/lib/shadcn_phlexcomponents/components/dropdown_menu.rb +74 -25
- data/lib/shadcn_phlexcomponents/components/dropdown_menu_sub.rb +52 -24
- data/lib/shadcn_phlexcomponents/components/form/form_checkbox.rb +1 -1
- data/lib/shadcn_phlexcomponents/components/form/form_checkbox_group.rb +1 -1
- data/lib/shadcn_phlexcomponents/components/form/form_combobox.rb +1 -1
- data/lib/shadcn_phlexcomponents/components/form/form_date_picker.rb +1 -1
- data/lib/shadcn_phlexcomponents/components/form/form_date_range_picker.rb +1 -1
- data/lib/shadcn_phlexcomponents/components/form/form_error.rb +8 -1
- data/lib/shadcn_phlexcomponents/components/form/form_helpers.rb +3 -2
- data/lib/shadcn_phlexcomponents/components/form/form_hint.rb +8 -1
- data/lib/shadcn_phlexcomponents/components/form/form_input.rb +1 -1
- data/lib/shadcn_phlexcomponents/components/form/form_radio_group.rb +1 -1
- data/lib/shadcn_phlexcomponents/components/form/form_select.rb +1 -1
- data/lib/shadcn_phlexcomponents/components/form/form_slider.rb +1 -1
- data/lib/shadcn_phlexcomponents/components/form/form_switch.rb +1 -1
- data/lib/shadcn_phlexcomponents/components/form/form_textarea.rb +1 -1
- data/lib/shadcn_phlexcomponents/components/form.rb +22 -6
- data/lib/shadcn_phlexcomponents/components/hover_card.rb +48 -18
- data/lib/shadcn_phlexcomponents/components/input.rb +13 -8
- data/lib/shadcn_phlexcomponents/components/label.rb +9 -4
- data/lib/shadcn_phlexcomponents/components/link.rb +8 -1
- data/lib/shadcn_phlexcomponents/components/pagination.rb +34 -6
- data/lib/shadcn_phlexcomponents/components/popover.rb +43 -13
- data/lib/shadcn_phlexcomponents/components/progress.rb +37 -6
- data/lib/shadcn_phlexcomponents/components/radio_group.rb +41 -15
- data/lib/shadcn_phlexcomponents/components/select.rb +99 -42
- data/lib/shadcn_phlexcomponents/components/separator.rb +9 -4
- data/lib/shadcn_phlexcomponents/components/sheet.rb +94 -28
- data/lib/shadcn_phlexcomponents/components/skeleton.rb +8 -1
- data/lib/shadcn_phlexcomponents/components/switch.rb +45 -17
- data/lib/shadcn_phlexcomponents/components/table.rb +84 -17
- data/lib/shadcn_phlexcomponents/components/tabs.rb +36 -12
- data/lib/shadcn_phlexcomponents/components/textarea.rb +12 -7
- data/lib/shadcn_phlexcomponents/components/toast.rb +46 -20
- data/lib/shadcn_phlexcomponents/components/toast_container.rb +19 -14
- data/lib/shadcn_phlexcomponents/components/toggle.rb +29 -24
- data/lib/shadcn_phlexcomponents/components/tooltip.rb +49 -14
- data/lib/shadcn_phlexcomponents/configuration.rb +46 -0
- data/lib/shadcn_phlexcomponents/initializers/shadcn_phlexcomponents.rb +28 -0
- data/lib/shadcn_phlexcomponents/version.rb +1 -1
- data/lib/shadcn_phlexcomponents.rb +12 -1
- data/lib/tasks/upgrade.rake +10 -0
- metadata +16 -14
- data/app/typescript/controllers/sidebar_controller.ts +0 -39
- data/app/typescript/controllers/sidebar_trigger_controller.ts +0 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1ff13d0989535d069db406d2c9f930cdae7f68500c828c1027263a053559eefd
|
4
|
+
data.tar.gz: 14f27e9c3ab82a23e1dc9e018cf1605703a49a3d43b27291e2cf98917740f042
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9f5c507e1b4777d8c0f8f456b5746350fcaadc7590e20e743a3ce70daece80edafb7fda632e369f768d1a9032de6cce0ef913a94c190f9478997dbc5ebb743b5
|
7
|
+
data.tar.gz: 68bb596923e049534b656793da8d944802c16da9c248216699cc4c98c6609a45496a8fd5cdb7c42e973d068f2fab3aee401c1c9585cc205eb8289d4a77633eab
|
data/README.md
CHANGED
@@ -1,53 +1,351 @@
|
|
1
1
|
# ShadcnPhlexcomponents
|
2
2
|
|
3
|
-
|
3
|
+
A modern UI component library for Ruby on Rails applications, built with [Phlex](https://www.phlex.fun/) and styled with [Tailwind CSS](https://tailwindcss.com/). Inspired by [shadcn/ui](https://ui.shadcn.com/), this gem provides beautiful, accessible, and highly customizable components for Ruby developers.
|
4
4
|
|
5
|
-
|
5
|
+
## ✨ Features
|
6
6
|
|
7
|
-
|
7
|
+
- 🎨 **50+ Beautiful Components** - Complete UI component library with consistent design
|
8
|
+
- ⚡ **Phlex-Powered** - Fast, type-safe Ruby components
|
9
|
+
- 🎯 **Stimulus Integration** - Interactive components with modern JavaScript
|
10
|
+
- 🎪 **Tailwind CSS** - Utility-first styling with full customization
|
11
|
+
- ♿ **Accessibility First** - ARIA-compliant and keyboard navigation support
|
12
|
+
- 🌙 **Dark Mode Ready** - Built-in theme switching support
|
13
|
+
- 📱 **Responsive Design** - Mobile-first approach
|
14
|
+
- 🔧 **Highly Customizable** - Extensive configuration options
|
15
|
+
- 🚀 **Easy Installation** - Simple setup with Rails integration
|
8
16
|
|
9
|
-
|
17
|
+
## 📦 Installation
|
10
18
|
|
11
|
-
|
19
|
+
Add this line to your application's Gemfile:
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
gem 'shadcn_phlexcomponents'
|
23
|
+
```
|
24
|
+
|
25
|
+
And then execute:
|
12
26
|
|
13
27
|
```bash
|
14
|
-
bundle
|
28
|
+
bundle install
|
15
29
|
```
|
16
30
|
|
17
|
-
|
31
|
+
Or install it yourself as:
|
18
32
|
|
19
33
|
```bash
|
20
|
-
gem install
|
34
|
+
gem install shadcn_phlexcomponents
|
35
|
+
```
|
36
|
+
|
37
|
+
### Rails Integration
|
38
|
+
|
39
|
+
After installing the gem, run the installer to set up the necessary files:
|
40
|
+
|
41
|
+
```bash
|
42
|
+
rails generate install:shadcn_phlexcomponents
|
43
|
+
```
|
44
|
+
|
45
|
+
This will:
|
46
|
+
- Copy JavaScript controllers and utilities
|
47
|
+
- Set up Tailwind CSS configuration
|
48
|
+
- Add Stimulus integration
|
49
|
+
- Configure component stylesheets
|
50
|
+
|
51
|
+
## 🚀 Quick Start
|
52
|
+
|
53
|
+
### Basic Usage
|
54
|
+
|
55
|
+
```ruby
|
56
|
+
# In your view or component
|
57
|
+
class MyView < Phlex::HTML
|
58
|
+
def view_template
|
59
|
+
render ShadcnPhlexcomponents::Button.new(variant: :primary) do
|
60
|
+
"Click me!"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
```
|
65
|
+
|
66
|
+
### With Rails Helpers
|
67
|
+
|
68
|
+
```erb
|
69
|
+
<%# In your ERB templates %>
|
70
|
+
<%= render ShadcnPhlexcomponents::Card.new do %>
|
71
|
+
<%= render ShadcnPhlexcomponents::Card::Header.new do %>
|
72
|
+
<h3>Card Title</h3>
|
73
|
+
<% end %>
|
74
|
+
<%= render ShadcnPhlexcomponents::Card::Content.new do %>
|
75
|
+
<p>Card content goes here.</p>
|
76
|
+
<% end %>
|
77
|
+
<% end %>
|
78
|
+
```
|
79
|
+
|
80
|
+
## 🧩 Available Components
|
81
|
+
|
82
|
+
### Layout & Structure
|
83
|
+
- **Aspect Ratio** - Maintain aspect ratios for media content
|
84
|
+
- **Card** - Flexible content containers with header, content, and footer
|
85
|
+
- **Separator** - Visual dividers for content sections
|
86
|
+
- **Sheet** - Slide-out panels and drawers
|
87
|
+
- **Skeleton** - Loading placeholders
|
88
|
+
|
89
|
+
### Navigation
|
90
|
+
- **Breadcrumb** - Navigation hierarchy display
|
91
|
+
- **Pagination** - Page navigation controls
|
92
|
+
- **Tabs** - Tabbed content organization
|
93
|
+
|
94
|
+
### Form Components
|
95
|
+
- **Button** - Primary action triggers with multiple variants
|
96
|
+
- **Input** - Text input fields with validation states
|
97
|
+
- **Textarea** - Multi-line text input
|
98
|
+
- **Label** - Accessible form labels
|
99
|
+
- **Checkbox** - Single and grouped checkboxes
|
100
|
+
- **Radio Group** - Radio button selections
|
101
|
+
- **Select** - Dropdown selections
|
102
|
+
- **Switch** - Toggle switches
|
103
|
+
- **Slider** - Range input controls
|
104
|
+
- **Date Picker** - Single date selection
|
105
|
+
- **Date Range Picker** - Date range selection
|
106
|
+
- **Combobox** - Searchable select dropdowns
|
107
|
+
|
108
|
+
### Interactive Components
|
109
|
+
- **Accordion** - Collapsible content sections
|
110
|
+
- **Alert Dialog** - Modal confirmations and alerts
|
111
|
+
- **Dialog** - Modal dialogs and overlays
|
112
|
+
- **Dropdown Menu** - Context menus and actions
|
113
|
+
- **Hover Card** - Contextual information on hover
|
114
|
+
- **Popover** - Floating content containers
|
115
|
+
- **Tooltip** - Helpful text on hover
|
116
|
+
- **Command** - Command palette interface
|
117
|
+
- **Collapsible** - Expandable content areas
|
118
|
+
|
119
|
+
### Feedback & Status
|
120
|
+
- **Alert** - Status messages and notifications
|
121
|
+
- **Badge** - Labels and status indicators
|
122
|
+
- **Progress** - Progress bars and indicators
|
123
|
+
- **Toast** - Notification messages
|
124
|
+
- **Loading Button** - Buttons with loading states
|
125
|
+
|
126
|
+
### Display Components
|
127
|
+
- **Avatar** - User profile images with fallbacks
|
128
|
+
- **Table** - Data tables with sorting and styling
|
129
|
+
- **Toggle** - Binary state toggles
|
130
|
+
|
131
|
+
### Utilities
|
132
|
+
- **Link** - Styled navigation links
|
133
|
+
- **Theme Switcher** - Light/dark mode toggle
|
134
|
+
|
135
|
+
## 🎨 Customization
|
136
|
+
|
137
|
+
### Component Variants
|
138
|
+
|
139
|
+
Most components support multiple variants for different use cases:
|
140
|
+
|
141
|
+
```ruby
|
142
|
+
# Button variants
|
143
|
+
render ShadcnPhlexcomponents::Button.new(variant: :default) { "Default" }
|
144
|
+
render ShadcnPhlexcomponents::Button.new(variant: :destructive) { "Delete" }
|
145
|
+
render ShadcnPhlexcomponents::Button.new(variant: :outline) { "Cancel" }
|
146
|
+
render ShadcnPhlexcomponents::Button.new(variant: :ghost) { "Ghost" }
|
147
|
+
render ShadcnPhlexcomponents::Button.new(variant: :link) { "Link" }
|
148
|
+
|
149
|
+
# Button sizes
|
150
|
+
render ShadcnPhlexcomponents::Button.new(size: :sm) { "Small" }
|
151
|
+
render ShadcnPhlexcomponents::Button.new(size: :default) { "Default" }
|
152
|
+
render ShadcnPhlexcomponents::Button.new(size: :lg) { "Large" }
|
153
|
+
render ShadcnPhlexcomponents::Button.new(size: :icon) { icon(:plus) }
|
154
|
+
```
|
155
|
+
|
156
|
+
### Global Configuration
|
157
|
+
|
158
|
+
Configure default component styles in an initializer:
|
159
|
+
|
160
|
+
```ruby
|
161
|
+
# config/initializers/shadcn_phlexcomponents.rb
|
162
|
+
ShadcnPhlexcomponents.configure do |config|
|
163
|
+
config.button = {
|
164
|
+
base: "custom-base-classes",
|
165
|
+
variants: {
|
166
|
+
variant: {
|
167
|
+
primary: "bg-blue-600 text-white hover:bg-blue-700",
|
168
|
+
secondary: "bg-gray-200 text-gray-900 hover:bg-gray-300"
|
169
|
+
}
|
170
|
+
}
|
171
|
+
}
|
172
|
+
end
|
173
|
+
```
|
174
|
+
|
175
|
+
### CSS Customization
|
176
|
+
|
177
|
+
Override component styles using Tailwind CSS:
|
178
|
+
|
179
|
+
```css
|
180
|
+
/* app/assets/stylesheets/application.css */
|
181
|
+
.shadcn-button {
|
182
|
+
@apply font-semibold transition-all duration-200;
|
183
|
+
}
|
184
|
+
|
185
|
+
.shadcn-button--primary {
|
186
|
+
@apply bg-brand-primary hover:bg-brand-primary-dark;
|
187
|
+
}
|
188
|
+
```
|
189
|
+
|
190
|
+
## 🎯 Interactive Components
|
191
|
+
|
192
|
+
Components with JavaScript functionality automatically include Stimulus controllers:
|
193
|
+
|
194
|
+
```ruby
|
195
|
+
# Accordion with automatic JavaScript behavior
|
196
|
+
render ShadcnPhlexcomponents::Accordion.new do
|
197
|
+
render ShadcnPhlexcomponents::Accordion::Item.new(value: "item-1") do
|
198
|
+
render ShadcnPhlexcomponents::Accordion::Trigger.new { "Section 1" }
|
199
|
+
render ShadcnPhlexcomponents::Accordion::Content.new do
|
200
|
+
"Content for section 1"
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
# Dialog with modal behavior
|
206
|
+
render ShadcnPhlexcomponents::Dialog.new do
|
207
|
+
render ShadcnPhlexcomponents::Dialog::Trigger.new do
|
208
|
+
render ShadcnPhlexcomponents::Button.new { "Open Dialog" }
|
209
|
+
end
|
210
|
+
render ShadcnPhlexcomponents::Dialog::Content.new do
|
211
|
+
render ShadcnPhlexcomponents::Dialog::Header.new do
|
212
|
+
render ShadcnPhlexcomponents::Dialog::Title.new { "Dialog Title" }
|
213
|
+
end
|
214
|
+
"Dialog content goes here"
|
215
|
+
end
|
216
|
+
end
|
217
|
+
```
|
218
|
+
|
219
|
+
## 🌙 Dark Mode
|
220
|
+
|
221
|
+
Enable dark mode support by adding the theme switcher:
|
222
|
+
|
223
|
+
```ruby
|
224
|
+
# In your layout
|
225
|
+
render ShadcnPhlexcomponents::ThemeSwitcher.new
|
21
226
|
```
|
22
227
|
|
23
|
-
|
228
|
+
Components automatically adapt to dark mode using Tailwind's `dark:` classes.
|
24
229
|
|
25
|
-
|
230
|
+
## 📋 Form Integration
|
26
231
|
|
27
|
-
|
232
|
+
Components work seamlessly with Rails form helpers:
|
233
|
+
|
234
|
+
```ruby
|
235
|
+
# Using with Rails forms
|
236
|
+
form_with model: @user do |form|
|
237
|
+
div(class: "space-y-4") do
|
238
|
+
render ShadcnPhlexcomponents::Form::FormField.new(form: form, name: :name) do
|
239
|
+
render ShadcnPhlexcomponents::Label.new { "Name" }
|
240
|
+
render ShadcnPhlexcomponents::Input.new(
|
241
|
+
name: "user[name]",
|
242
|
+
value: @user.name,
|
243
|
+
placeholder: "Enter your name"
|
244
|
+
)
|
245
|
+
end
|
246
|
+
|
247
|
+
render ShadcnPhlexcomponents::Button.new(type: :submit) { "Save" }
|
248
|
+
end
|
249
|
+
end
|
250
|
+
```
|
251
|
+
|
252
|
+
## 🛠️ Development
|
28
253
|
|
29
254
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
30
255
|
|
31
|
-
|
256
|
+
### Available Commands
|
257
|
+
|
258
|
+
```bash
|
259
|
+
# Run tests
|
260
|
+
rake test
|
261
|
+
|
262
|
+
# Run linting
|
263
|
+
rake rubocop
|
264
|
+
rubocop
|
265
|
+
|
266
|
+
# Build JavaScript assets
|
267
|
+
yarn build
|
268
|
+
|
269
|
+
# Install gem locally
|
270
|
+
bundle exec rake install
|
271
|
+
|
272
|
+
# Release new version
|
273
|
+
bundle exec rake release
|
274
|
+
```
|
275
|
+
|
276
|
+
### Component Development
|
277
|
+
|
278
|
+
When creating new components:
|
279
|
+
|
280
|
+
1. Inherit from `ShadcnPhlexcomponents::Base`
|
281
|
+
2. Use `class_variants` for styling variations
|
282
|
+
3. Add Stimulus controllers for interactivity
|
283
|
+
4. Include comprehensive tests
|
284
|
+
5. Follow existing naming conventions
|
285
|
+
|
286
|
+
## 🧪 Testing
|
287
|
+
|
288
|
+
The gem includes comprehensive test coverage:
|
289
|
+
|
290
|
+
```bash
|
291
|
+
# Run all tests
|
292
|
+
rake test
|
293
|
+
|
294
|
+
# Run specific test file
|
295
|
+
ruby test/test_button.rb
|
296
|
+
|
297
|
+
# Run with coverage
|
298
|
+
rake test
|
299
|
+
```
|
300
|
+
|
301
|
+
## 📚 Dependencies
|
302
|
+
|
303
|
+
### Ruby Dependencies
|
304
|
+
- **Rails** (~> 8.0) - Web framework
|
305
|
+
- **Phlex Rails** (~> 2.1) - Component framework
|
306
|
+
- **Class Variants** (~> 1.1) - CSS class management
|
307
|
+
- **Lucide Rails** (~> 0.5.1) - Icon library
|
308
|
+
- **Tailwind Merge** (~> 1.0) - CSS class merging
|
309
|
+
|
310
|
+
### JavaScript Dependencies
|
311
|
+
- **Stimulus** (^3.2.2) - JavaScript framework
|
312
|
+
- **Floating UI** (^1.7.2) - Positioning library
|
313
|
+
- **Day.js** (^1.11.13) - Date manipulation
|
314
|
+
- **Fuse.js** (^7.1.0) - Fuzzy searching
|
315
|
+
- **DOMPurify** (^3.2.6) - HTML sanitization
|
316
|
+
|
317
|
+
## 🤝 Contributing
|
32
318
|
|
33
|
-
|
319
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/sean-yeoh/shadcn_phlexcomponents. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/sean-yeoh/shadcn_phlexcomponents/blob/main/CODE_OF_CONDUCT.md).
|
34
320
|
|
35
|
-
|
321
|
+
### Contributing Guidelines
|
36
322
|
|
37
|
-
|
323
|
+
1. Fork the repository
|
324
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
325
|
+
3. Add tests for your changes
|
326
|
+
4. Ensure all tests pass (`rake test`)
|
327
|
+
5. Run the linter (`rake rubocop`)
|
328
|
+
6. Commit your changes (`git commit -am 'Add some feature'`)
|
329
|
+
7. Push to the branch (`git push origin my-new-feature`)
|
330
|
+
8. Create a new Pull Request
|
38
331
|
|
39
|
-
|
332
|
+
## 📄 License
|
40
333
|
|
41
|
-
|
334
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
42
335
|
|
43
|
-
|
336
|
+
## 🙏 Acknowledgments
|
44
337
|
|
45
|
-
|
338
|
+
- Inspired by [shadcn/ui](https://ui.shadcn.com/) - The original React component library
|
339
|
+
- Built with [Phlex](https://www.phlex.fun/) - Ruby HTML components
|
340
|
+
- Styled with [Tailwind CSS](https://tailwindcss.com/) - Utility-first CSS framework
|
341
|
+
- Icons provided by [Lucide](https://lucide.dev/) - Beautiful open source icons
|
46
342
|
|
47
|
-
|
343
|
+
## 📞 Support
|
48
344
|
|
49
|
-
|
345
|
+
- 📖 [Documentation](https://github.com/sean-yeoh/shadcn_phlexcomponents)
|
346
|
+
- 🐛 [Issues](https://github.com/sean-yeoh/shadcn_phlexcomponents/issues)
|
347
|
+
- 💬 [Discussions](https://github.com/sean-yeoh/shadcn_phlexcomponents/discussions)
|
50
348
|
|
51
|
-
|
349
|
+
---
|
52
350
|
|
53
|
-
|
351
|
+
Made with ❤️ by [Sean Yeoh](https://github.com/sean-yeoh)
|
@@ -23,6 +23,7 @@ import {
|
|
23
23
|
} from "../utils/command";
|
24
24
|
import { useClickOutside, useDebounce } from "stimulus-use";
|
25
25
|
const ComboboxController = class extends Controller {
|
26
|
+
static name = "combobox";
|
26
27
|
// targets
|
27
28
|
static targets = [
|
28
29
|
"trigger",
|
@@ -79,7 +80,6 @@ const ComboboxController = class extends Controller {
|
|
79
80
|
setTimeout(() => {
|
80
81
|
this.searchInputTarget.focus();
|
81
82
|
let index = 0;
|
82
|
-
console.log("this.selectedValue", this.selectedValue);
|
83
83
|
if (this.selectedValue) {
|
84
84
|
const item = this.filteredItems.find(
|
85
85
|
(i) => i.dataset.value === this.selectedValue,
|
@@ -18,8 +18,13 @@ import customParseFormat from "dayjs/plugin/customParseFormat";
|
|
18
18
|
import utc from "dayjs/plugin/utc";
|
19
19
|
dayjs.extend(customParseFormat);
|
20
20
|
dayjs.extend(utc);
|
21
|
+
const SMALL_SCREEN_BREAKPOINT = 768;
|
22
|
+
const isSmallScreen = () => {
|
23
|
+
return window.innerWidth < SMALL_SCREEN_BREAKPOINT;
|
24
|
+
};
|
21
25
|
const DAYJS_FORMAT = "YYYY-MM-DD";
|
22
26
|
const DatePickerController = class extends Controller {
|
27
|
+
static name = "date-picker";
|
23
28
|
// targets
|
24
29
|
static targets = [
|
25
30
|
"trigger",
|
@@ -52,9 +57,20 @@ const DatePickerController = class extends Controller {
|
|
52
57
|
});
|
53
58
|
}
|
54
59
|
contentContainerTargetConnected() {
|
55
|
-
|
56
|
-
|
57
|
-
|
60
|
+
if (isSmallScreen()) {
|
61
|
+
const windowHeight = window.innerHeight;
|
62
|
+
const datePickerHeight = this.identifier === "date-picker" ? 300 : 600;
|
63
|
+
let topOffset = 0;
|
64
|
+
if (windowHeight > datePickerHeight) {
|
65
|
+
topOffset = (windowHeight - datePickerHeight) / 2;
|
66
|
+
}
|
67
|
+
Object.assign(this.contentContainerTarget.style, {
|
68
|
+
top: `${topOffset}px`,
|
69
|
+
left: "50%",
|
70
|
+
transform: "translateX(-50%)",
|
71
|
+
pointerEvents: "auto",
|
72
|
+
});
|
73
|
+
}
|
58
74
|
}
|
59
75
|
toggle() {
|
60
76
|
if (this.isOpenValue) {
|
@@ -119,7 +135,7 @@ const DatePickerController = class extends Controller {
|
|
119
135
|
this.contentTarget.style.maxWidth = `${contentWidth}px`;
|
120
136
|
this.contentTarget.style.minWidth = `${contentWidth}px`;
|
121
137
|
}
|
122
|
-
if (
|
138
|
+
if (isSmallScreen()) {
|
123
139
|
lockScroll(this.contentTarget.id);
|
124
140
|
this.overlayTarget.style.display = "";
|
125
141
|
this.overlayTarget.dataset.state = "open";
|
@@ -156,7 +172,7 @@ const DatePickerController = class extends Controller {
|
|
156
172
|
content: this.contentTarget,
|
157
173
|
contentContainer: this.contentContainerTarget,
|
158
174
|
});
|
159
|
-
if (
|
175
|
+
if (isSmallScreen()) {
|
160
176
|
unlockScroll(this.contentTarget.id);
|
161
177
|
this.overlayTarget.style.display = "none";
|
162
178
|
this.overlayTarget.dataset.state = "closed";
|
@@ -38,6 +38,7 @@ const focusItemByIndex = (controller, event = null, index = null) => {
|
|
38
38
|
}
|
39
39
|
};
|
40
40
|
const DropdownMenuController = class extends Controller {
|
41
|
+
static name = "dropdown-menu";
|
41
42
|
// targets
|
42
43
|
static targets = ["trigger", "contentContainer", "content", "item"];
|
43
44
|
// values
|
@@ -1,5 +1,6 @@
|
|
1
1
|
import { Controller } from "@hotwired/stimulus";
|
2
2
|
const FormFieldController = class extends Controller {
|
3
|
+
static name = "form-field";
|
3
4
|
connect() {
|
4
5
|
const hintContainer = this.element.querySelector("[data-remove-label]");
|
5
6
|
const labelContainer = this.element.querySelector("[data-remove-hint]");
|
@@ -3,6 +3,7 @@ import { useHover } from "stimulus-use";
|
|
3
3
|
import { initFloatingUi } from "../utils/floating_ui";
|
4
4
|
import { showContent, hideContent } from "../utils";
|
5
5
|
const HoverCardController = class extends Controller {
|
6
|
+
static name = "hover-card";
|
6
7
|
// targets
|
7
8
|
static targets = ["trigger", "content", "contentContainer"];
|
8
9
|
// values
|