shadcn_phlexcomponents 0.1.18 → 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 +4 -4
- data/README.md +203 -22
- data/app/javascript/controllers/accordion_controller.js +101 -90
- data/app/javascript/controllers/alert_dialog_controller.js +5 -4
- data/app/javascript/controllers/avatar_controller.js +12 -11
- data/app/javascript/controllers/checkbox_controller.js +26 -26
- data/app/javascript/controllers/collapsible_controller.js +35 -36
- data/app/javascript/controllers/combobox_controller.js +262 -231
- data/app/javascript/controllers/command_controller.js +205 -184
- data/app/javascript/controllers/date_picker_controller.js +252 -253
- data/app/javascript/controllers/date_range_picker_controller.js +189 -200
- data/app/javascript/controllers/dialog_controller.js +79 -78
- data/app/javascript/controllers/dropdown_menu_controller.js +229 -208
- data/app/javascript/controllers/dropdown_menu_sub_controller.js +111 -97
- data/app/javascript/controllers/form_field_controller.js +17 -16
- data/app/javascript/controllers/hover_card_controller.js +69 -71
- data/app/javascript/controllers/loading_button_controller.js +11 -10
- data/app/javascript/controllers/popover_controller.js +85 -78
- data/app/javascript/controllers/progress_controller.js +12 -11
- data/app/javascript/controllers/radio_group_controller.js +75 -74
- data/app/javascript/controllers/select_controller.js +247 -232
- data/app/javascript/controllers/sidebar_controller.js +26 -27
- data/app/javascript/controllers/sidebar_trigger_controller.js +12 -9
- data/app/javascript/controllers/slider_controller.js +74 -74
- data/app/javascript/controllers/switch_controller.js +23 -23
- data/app/javascript/controllers/tabs_controller.js +61 -61
- data/app/javascript/controllers/theme_switcher_controller.js +28 -27
- data/app/javascript/controllers/toast_container_controller.js +45 -31
- data/app/javascript/controllers/toast_controller.js +19 -18
- data/app/javascript/controllers/toggle_controller.js +17 -17
- data/app/javascript/controllers/toggle_group_controller.js +17 -17
- data/app/javascript/controllers/tooltip_controller.js +75 -77
- data/app/javascript/shadcn_phlexcomponents.js +27 -60
- data/app/javascript/utils/command.js +390 -334
- data/app/javascript/utils/floating_ui.js +139 -107
- data/app/javascript/utils/index.js +253 -190
- 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 -0
- data/app/typescript/controllers/command_controller.ts +2 -0
- data/app/typescript/controllers/date_picker_controller.ts +2 -0
- 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 +2 -0
- data/app/typescript/shadcn_phlexcomponents.ts +27 -61
- data/app/typescript/utils/index.ts +7 -0
- data/lib/install/install_shadcn_phlexcomponents.rb +1 -1
- data/lib/install/upgrade_shadcn_phlexcomponents.rb +28 -0
- data/lib/shadcn_phlexcomponents/components/accordion.rb +55 -12
- data/lib/shadcn_phlexcomponents/components/alert.rb +35 -16
- data/lib/shadcn_phlexcomponents/components/alert_dialog.rb +52 -12
- 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/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 +212 -69
- data/lib/shadcn_phlexcomponents/components/command.rb +156 -52
- data/lib/shadcn_phlexcomponents/components/date_picker.rb +134 -48
- data/lib/shadcn_phlexcomponents/components/date_range_picker.rb +20 -42
- data/lib/shadcn_phlexcomponents/components/dialog.rb +80 -26
- 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 +87 -21
- 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 +28 -23
- 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 +15 -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: c5d377669ac71723876caba8ecac23f1820237a773053cdfc6b5e20ad6b642eb
|
4
|
+
data.tar.gz: f374614e4bb89df3f3be0e27576e78f9563d2e9523ae00958d87b0406c5b6b19
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 45d78d035a55520fe8e8492c77c6ff756f95cbd206a99dc13763d48e0f947cc1b1a16297257c188475c2206492ba098fae5602a41374bcb2c4a50b2f30c73e7a
|
7
|
+
data.tar.gz: 2c7faa2124cb6ad5515f974227dfaf6c26d428e294292f493fc2f96a1f3790254c5fa014677a93d989fc4d25eaa51a56f9916aec1bee2a1ed2fc7f884d795a9d
|
data/README.md
CHANGED
@@ -1,53 +1,234 @@
|
|
1
1
|
# ShadcnPhlexcomponents
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/shadcn_phlexcomponents`. To experiment with that code, run `bin/console` for an interactive prompt.
|
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.
|
6
4
|
|
7
5
|
## Installation
|
8
6
|
|
9
|
-
|
7
|
+
Install gem and required gems:
|
8
|
+
|
9
|
+
```bash
|
10
|
+
bundle add shadcn_phlexcomponents phlex-rails tailwindcss-rails \
|
11
|
+
tailwind_merge lucide-rails class_variants
|
12
|
+
```
|
13
|
+
|
14
|
+
Or install it yourself as:
|
15
|
+
|
16
|
+
```ruby
|
17
|
+
gem "shadcn_phlexcomponents"
|
18
|
+
gem "phlex-rails", "~> 2.1"
|
19
|
+
gem "tailwindcss-rails", "~> 4.2"
|
20
|
+
gem "tailwind_merge", "~> 1.0"
|
21
|
+
gem "lucide-rails", "~> 0.5.1"
|
22
|
+
gem "class_variants", "~> 1.1"
|
23
|
+
```
|
10
24
|
|
11
|
-
|
25
|
+
After installing the gems, run the installer to set up the necessary files:
|
12
26
|
|
13
27
|
```bash
|
14
|
-
|
28
|
+
rails install:shadcn_phlexcomponents
|
15
29
|
```
|
16
30
|
|
17
|
-
|
31
|
+
This will:
|
32
|
+
|
33
|
+
- Copy all Phlex component files to `vendor/shadcn_phlexcomponents/components`
|
34
|
+
- Copy all Stimulus controller files (either TypeScript or JavaScript) to `vendor/shadcn_phlexcomponents/javascript`
|
35
|
+
- Copy all CSS files to `vendor/shadcn_phlexcomponents/stylesheets`
|
36
|
+
- Copy an initializer file to `config/initializers/shadcn_phlexcomponents.rb`
|
37
|
+
|
38
|
+
## Upgrading
|
18
39
|
|
19
40
|
```bash
|
20
|
-
|
41
|
+
rails upgrade:shadcn_phlexcomponents
|
21
42
|
```
|
22
43
|
|
23
|
-
|
44
|
+
This will:
|
45
|
+
|
46
|
+
- Copy all Phlex component files to `vendor/shadcn_phlexcomponents/components`
|
47
|
+
- Copy all Stimulus controller files (either TypeScript or JavaScript) to `vendor/shadcn_phlexcomponents/javascript`
|
48
|
+
- Copy all CSS files to `vendor/shadcn_phlexcomponents/stylesheets`
|
49
|
+
|
50
|
+
## Quick Start
|
51
|
+
|
52
|
+
### Basic Usage
|
53
|
+
|
54
|
+
```erb
|
55
|
+
<%= render Button.new { "Default" } %>
|
56
|
+
```
|
57
|
+
|
58
|
+
See [https://shadcn-phlexcomponents.seanysx.com/](https://shadcn-phlexcomponents.seanysx.com/) for more examples.
|
59
|
+
|
60
|
+
### Demo Rails App
|
61
|
+
|
62
|
+
Please follow instructions in [https://github.com/sean-yeoh/shadcn_phlexcomponents_demo](https://github.com/sean-yeoh/shadcn_phlexcomponents_demo) to setup a rails app locally.
|
63
|
+
|
64
|
+
## Available Components
|
65
|
+
|
66
|
+
### Layout & Structure
|
67
|
+
|
68
|
+
- **Aspect Ratio**
|
69
|
+
- **Card**
|
70
|
+
- **Separator**
|
71
|
+
- **Sheet**
|
72
|
+
- **Skeleton**
|
73
|
+
|
74
|
+
### Navigation
|
75
|
+
|
76
|
+
- **Breadcrumb**
|
77
|
+
- **Pagination**
|
78
|
+
- **Tabs**
|
79
|
+
|
80
|
+
### Form Components
|
81
|
+
|
82
|
+
- **Button**
|
83
|
+
- **Input**
|
84
|
+
- **Textarea**
|
85
|
+
- **Label**
|
86
|
+
- **Checkbox**
|
87
|
+
- **Radio Group**
|
88
|
+
- **Select**
|
89
|
+
- **Switch**
|
90
|
+
- **Slider**
|
91
|
+
- **Date Picker**
|
92
|
+
- **Date Range Picker**
|
93
|
+
- **Combobox**
|
94
|
+
|
95
|
+
### Interactive Components
|
96
|
+
|
97
|
+
- **Accordion**
|
98
|
+
- **Alert Dialog**
|
99
|
+
- **Dialog**
|
100
|
+
- **Dropdown Menu**
|
101
|
+
- **Hover Card**
|
102
|
+
- **Popover**
|
103
|
+
- **Tooltip**
|
104
|
+
- **Command**
|
105
|
+
- **Collapsible**
|
106
|
+
|
107
|
+
### Feedback & Status
|
24
108
|
|
25
|
-
|
109
|
+
- **Alert**
|
110
|
+
- **Badge**
|
111
|
+
- **Progress**
|
112
|
+
- **Toast**
|
113
|
+
- **Loading Button**
|
114
|
+
|
115
|
+
### Display Components
|
116
|
+
|
117
|
+
- **Avatar**
|
118
|
+
- **Table**
|
119
|
+
- **Toggle**
|
120
|
+
|
121
|
+
### Utilities
|
122
|
+
|
123
|
+
- **Link**
|
124
|
+
- **Theme Switcher**
|
125
|
+
|
126
|
+
## Customization
|
127
|
+
|
128
|
+
### Global Configuration
|
129
|
+
|
130
|
+
Configure default component styles in an initializer:
|
131
|
+
|
132
|
+
```ruby
|
133
|
+
# config/initializers/shadcn_phlexcomponents.rb
|
134
|
+
ShadcnPhlexcomponents.configure do |config|
|
135
|
+
config.button = {
|
136
|
+
base: "custom-base-classes",
|
137
|
+
variants: {
|
138
|
+
variant: {
|
139
|
+
primary: "bg-blue-600 text-white hover:bg-blue-700",
|
140
|
+
secondary: "bg-gray-200 text-gray-900 hover:bg-gray-300"
|
141
|
+
}
|
142
|
+
}
|
143
|
+
}
|
144
|
+
end
|
145
|
+
```
|
146
|
+
|
147
|
+
Components automatically adapt to dark mode using Tailwind's `dark:` classes.
|
148
|
+
|
149
|
+
## Form Integration
|
150
|
+
|
151
|
+
Components work with Rails form helpers:
|
152
|
+
|
153
|
+
```erb
|
154
|
+
<%= render Form.new(model: @user, class: "space-y-6") do |f| %>
|
155
|
+
<%= f.input(:email) %>
|
156
|
+
<%= f.submit %>
|
157
|
+
<% end %>
|
158
|
+
```
|
26
159
|
|
27
160
|
## Development
|
28
161
|
|
29
162
|
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
163
|
|
31
|
-
|
164
|
+
### Component Development
|
32
165
|
|
33
|
-
|
166
|
+
When creating new components:
|
34
167
|
|
35
|
-
|
168
|
+
1. Inherit from `ShadcnPhlexcomponents::Base`
|
169
|
+
2. Use `class_variants` for styling variations
|
170
|
+
3. Add Stimulus controllers for interactivity
|
171
|
+
4. Include comprehensive tests
|
172
|
+
5. Follow existing naming conventions
|
36
173
|
|
37
|
-
|
174
|
+
### Available Commands
|
175
|
+
|
176
|
+
```bash
|
177
|
+
# Run tests
|
178
|
+
rake test
|
38
179
|
|
39
|
-
|
180
|
+
# Run linting
|
181
|
+
rake rubocop
|
182
|
+
rubocop
|
183
|
+
|
184
|
+
# Install JavaScript dependencies
|
185
|
+
yarn install
|
186
|
+
|
187
|
+
```
|
40
188
|
|
41
|
-
##
|
189
|
+
## Dependencies
|
190
|
+
|
191
|
+
### Ruby Dependencies
|
192
|
+
|
193
|
+
- **rails** (~> 8.0) - Web framework
|
194
|
+
- **Phlex Rails** (~> 2.1) - Component framework
|
195
|
+
- **Class Variants** (~> 1.1) - CSS class management
|
196
|
+
- **Lucide Rails** (~> 0.5.1) - Icon library
|
197
|
+
- **Tailwind Merge** (~> 1.0) - CSS class merging
|
198
|
+
|
199
|
+
### JavaScript Dependencies
|
200
|
+
|
201
|
+
- **@hotwired/stimulus** (^3.2.2) - JavaScript framework
|
202
|
+
- **@floating-ui/dom** (^1.7.2) - Positioning library
|
203
|
+
- **dayjs** (^1.11.13) - Date manipulation
|
204
|
+
- **fuse.js** (^7.1.0) - Fuzzy searching
|
205
|
+
- **dompurify** (^3.2.6) - HTML sanitization
|
206
|
+
- **inputmask** (^5.0.9) - Input masking
|
207
|
+
- **hotkeys-js** (^3.13.14) - Keyboard shortcuts
|
208
|
+
- **nouislider** (^15.8.1) - Slider input
|
209
|
+
- **vanilla-calendar-pro** (^3.0.4) - Calendar component
|
210
|
+
|
211
|
+
## Contributing
|
42
212
|
|
43
|
-
|
213
|
+
1. Fork the repository
|
214
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
215
|
+
3. Add tests for your changes
|
216
|
+
4. Ensure all tests pass (`rake test`)
|
217
|
+
5. Run the linter (`rake rubocop`)
|
218
|
+
6. Commit your changes (`git commit -am 'Add some feature'`)
|
219
|
+
7. Push to the branch (`git push origin my-new-feature`)
|
220
|
+
8. Create a new Pull Request
|
44
221
|
|
45
|
-
|
222
|
+
## License
|
46
223
|
|
47
|
-
|
224
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
48
225
|
|
49
|
-
|
226
|
+
## Acknowledgments
|
50
227
|
|
51
|
-
|
228
|
+
- Inspired by [shadcn/ui](https://ui.shadcn.com/) - The original React component library
|
229
|
+
- Built with [Phlex](https://www.phlex.fun/) - Ruby HTML components
|
230
|
+
- Styled with [Tailwind CSS](https://tailwindcss.com/) - Utility-first CSS framework
|
231
|
+
- Icons provided by [Lucide](https://lucide.dev/) - Beautiful open source icons
|
232
|
+
- [@JacobAlexander](https://github.com/JacobAlexander) - For testing and providing feedback
|
52
233
|
|
53
|
-
|
234
|
+
---
|
@@ -1,97 +1,108 @@
|
|
1
|
-
import { Controller } from
|
2
|
-
import {
|
1
|
+
import { Controller } from "@hotwired/stimulus";
|
2
|
+
import {
|
3
|
+
showContent,
|
4
|
+
hideContent,
|
5
|
+
getNextEnabledIndex,
|
6
|
+
getPreviousEnabledIndex,
|
7
|
+
} from "../utils";
|
3
8
|
const AccordionController = class extends Controller {
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
9
|
+
static name = "accordion";
|
10
|
+
// targets
|
11
|
+
static targets = ["item", "trigger", "content"];
|
12
|
+
// values
|
13
|
+
static values = { openItems: Array };
|
14
|
+
connect() {
|
15
|
+
this.multiple = this.element.dataset.multiple === "true";
|
16
|
+
}
|
17
|
+
contentTargetConnected(content) {
|
18
|
+
setTimeout(() => {
|
19
|
+
this.setContentHeight(content);
|
20
|
+
}, 100);
|
21
|
+
}
|
22
|
+
toggle(event) {
|
23
|
+
const trigger = event.currentTarget;
|
24
|
+
const item = this.itemTargets.find((item) => {
|
25
|
+
return item.contains(trigger);
|
26
|
+
});
|
27
|
+
if (!item) return;
|
28
|
+
const value = item.dataset.value;
|
29
|
+
const isOpen = this.openItemsValue.includes(value);
|
30
|
+
if (isOpen) {
|
31
|
+
this.openItemsValue = this.openItemsValue.filter((v) => v !== value);
|
32
|
+
} else {
|
33
|
+
if (this.multiple) {
|
34
|
+
this.openItemsValue = [...this.openItemsValue, value];
|
35
|
+
} else {
|
36
|
+
this.openItemsValue = [value];
|
37
|
+
}
|
10
38
|
}
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
39
|
+
}
|
40
|
+
focusTrigger(event) {
|
41
|
+
const trigger = event.currentTarget;
|
42
|
+
const key = event.key;
|
43
|
+
const focusableTriggers = this.triggerTargets.filter(
|
44
|
+
(trigger) => !trigger.disabled,
|
45
|
+
);
|
46
|
+
const index = focusableTriggers.indexOf(trigger);
|
47
|
+
let newIndex = 0;
|
48
|
+
if (key === "ArrowUp") {
|
49
|
+
newIndex = getPreviousEnabledIndex({
|
50
|
+
items: focusableTriggers,
|
51
|
+
currentIndex: index,
|
52
|
+
wrapAround: true,
|
53
|
+
});
|
54
|
+
} else {
|
55
|
+
newIndex = getNextEnabledIndex({
|
56
|
+
items: focusableTriggers,
|
57
|
+
currentIndex: index,
|
58
|
+
wrapAround: true,
|
59
|
+
});
|
15
60
|
}
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
61
|
+
focusableTriggers[newIndex].focus();
|
62
|
+
}
|
63
|
+
openItemsValueChanged(openItems) {
|
64
|
+
this.itemTargets.forEach((item) => {
|
65
|
+
const itemValue = item.dataset.value;
|
66
|
+
const trigger = this.triggerTargets.find((trigger) =>
|
67
|
+
item.contains(trigger),
|
68
|
+
);
|
69
|
+
const content = this.contentTargets.find((content) =>
|
70
|
+
item.contains(content),
|
71
|
+
);
|
72
|
+
if (openItems.includes(itemValue)) {
|
73
|
+
showContent({
|
74
|
+
trigger,
|
75
|
+
content: content,
|
76
|
+
contentContainer: content,
|
20
77
|
});
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
this.openItemsValue = this.openItemsValue.filter((v) => v !== value);
|
27
|
-
}
|
28
|
-
else {
|
29
|
-
if (this.multiple) {
|
30
|
-
this.openItemsValue = [...this.openItemsValue, value];
|
31
|
-
}
|
32
|
-
else {
|
33
|
-
this.openItemsValue = [value];
|
34
|
-
}
|
35
|
-
}
|
36
|
-
}
|
37
|
-
focusTrigger(event) {
|
38
|
-
const trigger = event.currentTarget;
|
39
|
-
const key = event.key;
|
40
|
-
const focusableTriggers = this.triggerTargets.filter((trigger) => !trigger.disabled);
|
41
|
-
const index = focusableTriggers.indexOf(trigger);
|
42
|
-
let newIndex = 0;
|
43
|
-
if (key === 'ArrowUp') {
|
44
|
-
newIndex = getPreviousEnabledIndex({
|
45
|
-
items: focusableTriggers,
|
46
|
-
currentIndex: index,
|
47
|
-
wrapAround: true,
|
48
|
-
});
|
49
|
-
}
|
50
|
-
else {
|
51
|
-
newIndex = getNextEnabledIndex({
|
52
|
-
items: focusableTriggers,
|
53
|
-
currentIndex: index,
|
54
|
-
wrapAround: true,
|
55
|
-
});
|
56
|
-
}
|
57
|
-
focusableTriggers[newIndex].focus();
|
58
|
-
}
|
59
|
-
openItemsValueChanged(openItems) {
|
60
|
-
this.itemTargets.forEach((item) => {
|
61
|
-
const itemValue = item.dataset.value;
|
62
|
-
const trigger = this.triggerTargets.find((trigger) => item.contains(trigger));
|
63
|
-
const content = this.contentTargets.find((content) => item.contains(content));
|
64
|
-
if (openItems.includes(itemValue)) {
|
65
|
-
showContent({
|
66
|
-
trigger,
|
67
|
-
content: content,
|
68
|
-
contentContainer: content,
|
69
|
-
});
|
70
|
-
}
|
71
|
-
else {
|
72
|
-
hideContent({
|
73
|
-
trigger,
|
74
|
-
content: content,
|
75
|
-
contentContainer: content,
|
76
|
-
});
|
77
|
-
}
|
78
|
-
});
|
79
|
-
}
|
80
|
-
setContentHeight(element) {
|
81
|
-
const height = this.getContentHeight(element) || element.getBoundingClientRect().height;
|
82
|
-
element.style.setProperty('--radix-accordion-content-height', `${height}px`);
|
83
|
-
}
|
84
|
-
getContentHeight(el) {
|
85
|
-
const clone = el.cloneNode(true);
|
86
|
-
Object.assign(clone.style, {
|
87
|
-
display: 'block',
|
88
|
-
position: 'absolute',
|
89
|
-
visibility: 'hidden',
|
78
|
+
} else {
|
79
|
+
hideContent({
|
80
|
+
trigger,
|
81
|
+
content: content,
|
82
|
+
contentContainer: content,
|
90
83
|
});
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
84
|
+
}
|
85
|
+
});
|
86
|
+
}
|
87
|
+
setContentHeight(element) {
|
88
|
+
const height =
|
89
|
+
this.getContentHeight(element) || element.getBoundingClientRect().height;
|
90
|
+
element.style.setProperty(
|
91
|
+
"--radix-accordion-content-height",
|
92
|
+
`${height}px`,
|
93
|
+
);
|
94
|
+
}
|
95
|
+
getContentHeight(el) {
|
96
|
+
const clone = el.cloneNode(true);
|
97
|
+
Object.assign(clone.style, {
|
98
|
+
display: "block",
|
99
|
+
position: "absolute",
|
100
|
+
visibility: "hidden",
|
101
|
+
});
|
102
|
+
document.body.appendChild(clone);
|
103
|
+
const height = clone.getBoundingClientRect().height;
|
104
|
+
document.body.removeChild(clone);
|
105
|
+
return height;
|
106
|
+
}
|
96
107
|
};
|
97
108
|
export { AccordionController };
|
@@ -1,7 +1,8 @@
|
|
1
|
-
import { DialogController } from
|
1
|
+
import { DialogController } from "./dialog_controller";
|
2
2
|
const AlertDialogController = class extends DialogController {
|
3
|
-
|
4
|
-
|
5
|
-
|
3
|
+
static name = "alert-dialog";
|
4
|
+
onDOMClick() {
|
5
|
+
return;
|
6
|
+
}
|
6
7
|
};
|
7
8
|
export { AlertDialogController };
|
@@ -1,14 +1,15 @@
|
|
1
|
-
import { Controller } from
|
1
|
+
import { Controller } from "@hotwired/stimulus";
|
2
2
|
const AvatarController = class extends Controller {
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
}
|
3
|
+
static name = "avatar";
|
4
|
+
// targets
|
5
|
+
static targets = ["image", "fallback"];
|
6
|
+
connect() {
|
7
|
+
this.imageTarget.onerror = () => {
|
8
|
+
if (this.hasFallbackTarget) {
|
9
|
+
this.fallbackTarget.classList.remove("hidden");
|
10
|
+
}
|
11
|
+
this.imageTarget.classList.add("hidden");
|
12
|
+
};
|
13
|
+
}
|
13
14
|
};
|
14
15
|
export { AvatarController };
|
@@ -1,30 +1,30 @@
|
|
1
|
-
import { Controller } from
|
1
|
+
import { Controller } from "@hotwired/stimulus";
|
2
2
|
const CheckboxController = class extends Controller {
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
}
|
3
|
+
static name = "checkbox";
|
4
|
+
// targets
|
5
|
+
static targets = ["input", "indicator"];
|
6
|
+
// values
|
7
|
+
static values = {
|
8
|
+
isChecked: Boolean,
|
9
|
+
};
|
10
|
+
toggle() {
|
11
|
+
this.isCheckedValue = !this.isCheckedValue;
|
12
|
+
}
|
13
|
+
preventDefault(event) {
|
14
|
+
event.preventDefault();
|
15
|
+
}
|
16
|
+
isCheckedValueChanged(isChecked) {
|
17
|
+
if (isChecked) {
|
18
|
+
this.element.ariaChecked = "true";
|
19
|
+
this.element.dataset.state = "checked";
|
20
|
+
this.inputTarget.checked = true;
|
21
|
+
this.indicatorTarget.classList.remove("hidden");
|
22
|
+
} else {
|
23
|
+
this.element.ariaChecked = "false";
|
24
|
+
this.element.dataset.state = "unchecked";
|
25
|
+
this.inputTarget.checked = false;
|
26
|
+
this.indicatorTarget.classList.add("hidden");
|
28
27
|
}
|
28
|
+
}
|
29
29
|
};
|
30
30
|
export { CheckboxController };
|
@@ -1,41 +1,40 @@
|
|
1
|
-
import { Controller } from
|
2
|
-
import { hideContent, showContent } from
|
1
|
+
import { Controller } from "@hotwired/stimulus";
|
2
|
+
import { hideContent, showContent } from "../utils";
|
3
3
|
const CollapsibleController = class extends Controller {
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
}
|
4
|
+
static name = "collapsible";
|
5
|
+
// targets
|
6
|
+
static targets = ["trigger", "content"];
|
7
|
+
// values
|
8
|
+
static values = {
|
9
|
+
isOpen: Boolean,
|
10
|
+
};
|
11
|
+
toggle() {
|
12
|
+
if (this.isOpenValue) {
|
13
|
+
this.close();
|
14
|
+
} else {
|
15
|
+
this.open();
|
17
16
|
}
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
}
|
17
|
+
}
|
18
|
+
open() {
|
19
|
+
this.isOpenValue = true;
|
20
|
+
}
|
21
|
+
close() {
|
22
|
+
this.isOpenValue = false;
|
23
|
+
}
|
24
|
+
isOpenValueChanged(isOpen) {
|
25
|
+
if (isOpen) {
|
26
|
+
showContent({
|
27
|
+
trigger: this.triggerTarget,
|
28
|
+
content: this.contentTarget,
|
29
|
+
contentContainer: this.contentTarget,
|
30
|
+
});
|
31
|
+
} else {
|
32
|
+
hideContent({
|
33
|
+
trigger: this.triggerTarget,
|
34
|
+
content: this.contentTarget,
|
35
|
+
contentContainer: this.contentTarget,
|
36
|
+
});
|
39
37
|
}
|
38
|
+
}
|
40
39
|
};
|
41
40
|
export { CollapsibleController };
|