@hakumi-dev/hakumi-components 0.1.16-pre → 0.1.18-pre
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.
- package/README.md +196 -28
- package/app/javascript/hakumi_components/controllers/base/registry_controller.js +83 -3
- package/app/javascript/hakumi_components/controllers/hakumi/affix_controller.js +0 -23
- package/app/javascript/hakumi_components/controllers/hakumi/alert_controller.js +2 -1
- package/app/javascript/hakumi_components/controllers/hakumi/button_controller.js +0 -7
- package/app/javascript/hakumi_components/controllers/hakumi/calendar_controller.js +0 -2
- package/app/javascript/hakumi_components/controllers/hakumi/color_picker_controller.js +1 -6
- package/app/javascript/hakumi_components/controllers/hakumi/date_picker_controller.js +28 -34
- package/app/javascript/hakumi_components/controllers/hakumi/drawer_controller.js +2 -1
- package/app/javascript/hakumi_components/controllers/hakumi/form_item_controller.js +9 -63
- package/app/javascript/hakumi_components/controllers/hakumi/mentions_controller.js +4 -11
- package/app/javascript/hakumi_components/controllers/hakumi/message_controller.js +1 -1
- package/app/javascript/hakumi_components/controllers/hakumi/modal_controller.js +4 -20
- package/app/javascript/hakumi_components/controllers/hakumi/notification_controller.js +1 -1
- package/app/javascript/hakumi_components/controllers/hakumi/popconfirm_controller.js +33 -27
- package/app/javascript/hakumi_components/controllers/hakumi/popover_controller.js +2 -23
- package/app/javascript/hakumi_components/controllers/hakumi/qr_code_controller.js +0 -20
- package/app/javascript/hakumi_components/controllers/hakumi/segmented_controller.js +0 -2
- package/app/javascript/hakumi_components/controllers/hakumi/spin_controller.js +1 -19
- package/app/javascript/hakumi_components/controllers/hakumi/statistic_controller.js +0 -2
- package/app/javascript/hakumi_components/controllers/hakumi/table_controller.js +48 -74
- package/app/javascript/hakumi_components/controllers/hakumi/tag_controller.js +15 -14
- package/app/javascript/hakumi_components/controllers/hakumi/tag_group_controller.js +14 -13
- package/app/javascript/hakumi_components/controllers/hakumi/theme_controller.js +24 -1
- package/app/javascript/hakumi_components/controllers/hakumi/time_picker_controller.js +3 -7
- package/app/javascript/hakumi_components/controllers/hakumi/timeline_controller.js +0 -16
- package/app/javascript/hakumi_components/controllers/hakumi/transfer_controller.js +2 -2
- package/app/javascript/hakumi_components/controllers/hakumi/tree_controller.js +0 -2
- package/app/javascript/hakumi_components/controllers/hakumi/tree_select_controller.js +3 -3
- package/app/javascript/hakumi_components/controllers/hakumi/upload_controller.js +12 -26
- package/app/javascript/hakumi_components/core/persistence.js +3 -3
- package/app/javascript/hakumi_components/core/render_component.js +3 -1
- package/app/javascript/lib/validation_manager.js +101 -0
- package/app/javascript/stylesheets/_theme-tokens.scss +2 -1
- package/app/javascript/stylesheets/components/_modal.scss +13 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -20,10 +20,10 @@
|
|
|
20
20
|
|
|
21
21
|
## About The Project
|
|
22
22
|
|
|
23
|
-
Hakumi Components is a comprehensive UI component library for Ruby on Rails applications, inspired by Ant Design. It provides
|
|
23
|
+
Hakumi Components is a comprehensive UI component library for Ruby on Rails applications, inspired by Ant Design. It provides 65 production-ready, accessible components with light/dark theme support, combining the power of ViewComponent, Stimulus, and modern CSS.
|
|
24
24
|
|
|
25
25
|
**✨ Key Features:**
|
|
26
|
-
- 🎨 **
|
|
26
|
+
- 🎨 **65 Components** - Button, Form, Table, Modal, Menu, Calendar, and more
|
|
27
27
|
- 🌓 **Light/Dark Theme** - Built-in theme support with CSS variables
|
|
28
28
|
- 📦 **Rails Engine** - Drop-in integration with ViewComponent
|
|
29
29
|
- ⚡ **Modern Stack** - Stimulus controllers with clean JavaScript API
|
|
@@ -64,7 +64,11 @@ Hakumi Components is a comprehensive UI component library for Ruby on Rails appl
|
|
|
64
64
|
**1. Add the gem to your Gemfile:**
|
|
65
65
|
|
|
66
66
|
```ruby
|
|
67
|
-
|
|
67
|
+
# Always use the latest pre-release version (recommended during development)
|
|
68
|
+
gem 'hakumi_components', '>= 0.1.0.pre'
|
|
69
|
+
|
|
70
|
+
# Or pin to a specific version for stability
|
|
71
|
+
gem 'hakumi_components', '0.1.16.pre'
|
|
68
72
|
```
|
|
69
73
|
|
|
70
74
|
**2. Run the installer:**
|
|
@@ -92,7 +96,11 @@ If you prefer manual setup or the generator doesn't work for your setup:
|
|
|
92
96
|
**1. Add the gem:**
|
|
93
97
|
|
|
94
98
|
```ruby
|
|
95
|
-
|
|
99
|
+
# Always use the latest pre-release version
|
|
100
|
+
gem 'hakumi_components', '>= 0.1.0.pre'
|
|
101
|
+
|
|
102
|
+
# Or pin to a specific version
|
|
103
|
+
gem 'hakumi_components', '0.1.16.pre'
|
|
96
104
|
```
|
|
97
105
|
|
|
98
106
|
**2. Install dependencies:**
|
|
@@ -100,11 +108,17 @@ gem 'hakumi_components', '~> 0.1.0.pre'
|
|
|
100
108
|
```bash
|
|
101
109
|
bundle install
|
|
102
110
|
|
|
103
|
-
# Using Yarn
|
|
111
|
+
# Using Yarn - latest pre-release
|
|
104
112
|
yarn add @hakumi-dev/hakumi-components@pre
|
|
105
113
|
|
|
106
|
-
# Using
|
|
114
|
+
# Using Yarn - specific version
|
|
115
|
+
yarn add @hakumi-dev/hakumi-components@0.1.16-pre
|
|
116
|
+
|
|
117
|
+
# Using npm - latest pre-release
|
|
107
118
|
npm install @hakumi-dev/hakumi-components@pre
|
|
119
|
+
|
|
120
|
+
# Using npm - specific version
|
|
121
|
+
npm install @hakumi-dev/hakumi-components@0.1.16-pre
|
|
108
122
|
```
|
|
109
123
|
|
|
110
124
|
**3. Setup JavaScript:**
|
|
@@ -131,11 +145,33 @@ registerHakumiControllers(application)
|
|
|
131
145
|
@import "@hakumi-dev/hakumi-components/styles";
|
|
132
146
|
```
|
|
133
147
|
|
|
134
|
-
|
|
148
|
+
## Configuration
|
|
149
|
+
|
|
150
|
+
You can configure HakumiComponents in an initializer:
|
|
135
151
|
|
|
136
152
|
```ruby
|
|
137
153
|
# config/initializers/hakumi_components.rb
|
|
138
|
-
|
|
154
|
+
HakumiComponents.configure do |config|
|
|
155
|
+
config.default_form_builder = true # Use HakumiComponents::FormBuilder as default
|
|
156
|
+
config.base_path = "hakumi/components" # Base URL path for component routes
|
|
157
|
+
end
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Available Configuration Options
|
|
161
|
+
|
|
162
|
+
| Option | Default | Description |
|
|
163
|
+
|--------|---------|-------------|
|
|
164
|
+
| `default_form_builder` | `false` | Use `HakumiComponents::FormBuilder` as the default form builder |
|
|
165
|
+
| `base_path` | `"hakumi/components"` | Base URL path for component routes (modals, drawers, etc.) |
|
|
166
|
+
|
|
167
|
+
### Accessing Configuration
|
|
168
|
+
|
|
169
|
+
```ruby
|
|
170
|
+
HakumiComponents.config.default_form_builder
|
|
171
|
+
# => true
|
|
172
|
+
|
|
173
|
+
HakumiComponents.config.base_path
|
|
174
|
+
# => "hakumi/components"
|
|
139
175
|
```
|
|
140
176
|
|
|
141
177
|
## Usage
|
|
@@ -144,19 +180,19 @@ Rails.application.config.action_view.default_form_builder = Hakumi::FormBuilder
|
|
|
144
180
|
|
|
145
181
|
```erb
|
|
146
182
|
<%# Simple button %>
|
|
147
|
-
<%= render
|
|
183
|
+
<%= render HakumiComponents::Button::Component.new(type: :primary) do %>
|
|
148
184
|
Click me
|
|
149
185
|
<% end %>
|
|
150
186
|
|
|
151
187
|
<%# Form with automatic validation detection %>
|
|
152
|
-
<%= form_with model: @user, builder:
|
|
188
|
+
<%= form_with model: @user, builder: HakumiComponents::FormBuilder do |f| %>
|
|
153
189
|
<%= f.text_field :email %>
|
|
154
190
|
<%= f.text_field :name %>
|
|
155
191
|
<%= f.submit "Save", type: :primary %>
|
|
156
192
|
<% end %>
|
|
157
193
|
|
|
158
194
|
<%# Modal with programmatic control %>
|
|
159
|
-
<%= render
|
|
195
|
+
<%= render HakumiComponents::Modal::Component.new(
|
|
160
196
|
id: "my-modal",
|
|
161
197
|
title: "Confirm Action"
|
|
162
198
|
) do %>
|
|
@@ -164,16 +200,88 @@ Rails.application.config.action_view.default_form_builder = Hakumi::FormBuilder
|
|
|
164
200
|
<% end %>
|
|
165
201
|
```
|
|
166
202
|
|
|
167
|
-
### Component
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
-
|
|
173
|
-
-
|
|
174
|
-
-
|
|
175
|
-
|
|
176
|
-
|
|
203
|
+
### Component Reference
|
|
204
|
+
|
|
205
|
+
Browse all **65 components** organized by category. Each component includes detailed documentation, examples, and API reference.
|
|
206
|
+
|
|
207
|
+
#### General (4)
|
|
208
|
+
- [Button](./app/components/hakumi_components/button/docs/README.md) - Clickable button element
|
|
209
|
+
- [Float Button](./app/components/hakumi_components/float_button/docs/README.md) - Floating action button
|
|
210
|
+
- [Icon](./app/components/hakumi_components/icon/docs/README.md) - Icon display component
|
|
211
|
+
- [Typography](./app/components/hakumi_components/typography/docs/README.md) - Text styling and formatting
|
|
212
|
+
|
|
213
|
+
#### Layout (6)
|
|
214
|
+
- [Divider](./app/components/hakumi_components/divider/docs/README.md) - Horizontal or vertical divider line
|
|
215
|
+
- [Flex](./app/components/hakumi_components/flex/docs/README.md) - Flexbox layout container
|
|
216
|
+
- [Grid](./app/components/hakumi_components/grid/docs/README.md) - Grid layout system
|
|
217
|
+
- [Layout](./app/components/hakumi_components/layout/docs/README.md) - Page layout structure
|
|
218
|
+
- [Space](./app/components/hakumi_components/space/docs/README.md) - Spacing between elements
|
|
219
|
+
- [Splitter](./app/components/hakumi_components/splitter/docs/README.md) - Resizable split panels
|
|
220
|
+
|
|
221
|
+
#### Navigation (6)
|
|
222
|
+
- [Anchor](./app/components/hakumi_components/anchor/docs/README.md) - Anchor navigation for page sections
|
|
223
|
+
- [Breadcrumb](./app/components/hakumi_components/breadcrumb/docs/README.md) - Breadcrumb navigation trail
|
|
224
|
+
- [Dropdown](./app/components/hakumi_components/dropdown/docs/README.md) - Dropdown menu
|
|
225
|
+
- [Menu](./app/components/hakumi_components/menu/docs/README.md) - Navigation menu
|
|
226
|
+
- [Pagination](./app/components/hakumi_components/pagination/docs/README.md) - Pagination controls
|
|
227
|
+
- [Steps](./app/components/hakumi_components/steps/docs/README.md) - Step-by-step navigation
|
|
228
|
+
|
|
229
|
+
#### Data Entry (18)
|
|
230
|
+
- [Autocomplete](./app/components/hakumi_components/autocomplete/docs/README.md) - Input with autocomplete suggestions
|
|
231
|
+
- [Cascader](./app/components/hakumi_components/cascader/docs/README.md) - Cascading selection dropdown
|
|
232
|
+
- [Checkbox](./app/components/hakumi_components/checkbox/docs/README.md) - Checkbox input
|
|
233
|
+
- [Color Picker](./app/components/hakumi_components/color_picker/docs/README.md) - Color selection input
|
|
234
|
+
- [Date Picker](./app/components/hakumi_components/date_picker/docs/README.md) - Date selection input
|
|
235
|
+
- [Form](./app/components/hakumi_components/form/docs/README.md) - Form wrapper with validation
|
|
236
|
+
- [Input](./app/components/hakumi_components/input/docs/README.md) - Text input field
|
|
237
|
+
- [Input Number](./app/components/hakumi_components/input_number/docs/README.md) - Numeric input field
|
|
238
|
+
- [Mentions](./app/components/hakumi_components/mentions/docs/README.md) - @mentions input
|
|
239
|
+
- [Radio](./app/components/hakumi_components/radio/docs/README.md) - Radio button input
|
|
240
|
+
- [Rate](./app/components/hakumi_components/rate/docs/README.md) - Star rating input
|
|
241
|
+
- [Select](./app/components/hakumi_components/select/docs/README.md) - Dropdown select input
|
|
242
|
+
- [Slider](./app/components/hakumi_components/slider/docs/README.md) - Range slider input
|
|
243
|
+
- [Switch](./app/components/hakumi_components/switch/docs/README.md) - Toggle switch input
|
|
244
|
+
- [Time Picker](./app/components/hakumi_components/time_picker/docs/README.md) - Time selection input
|
|
245
|
+
- [Transfer](./app/components/hakumi_components/transfer/docs/README.md) - Dual list transfer
|
|
246
|
+
- [Tree Select](./app/components/hakumi_components/tree_select/docs/README.md) - Tree structure select
|
|
247
|
+
- [Upload](./app/components/hakumi_components/upload/docs/README.md) - File upload component
|
|
248
|
+
|
|
249
|
+
#### Data Display (20)
|
|
250
|
+
- [Avatar](./app/components/hakumi_components/avatar/docs/README.md) - User avatar display
|
|
251
|
+
- [Badge](./app/components/hakumi_components/badge/docs/README.md) - Badge and status dot
|
|
252
|
+
- [Calendar](./app/components/hakumi_components/calendar/docs/README.md) - Calendar display
|
|
253
|
+
- [Card](./app/components/hakumi_components/card/docs/README.md) - Card container
|
|
254
|
+
- [Carousel](./app/components/hakumi_components/carousel/docs/README.md) - Image/content carousel
|
|
255
|
+
- [Collapse](./app/components/hakumi_components/collapse/docs/README.md) - Collapsible accordion panels
|
|
256
|
+
- [Descriptions](./app/components/hakumi_components/descriptions/docs/README.md) - Description list display
|
|
257
|
+
- [Empty](./app/components/hakumi_components/empty/docs/README.md) - Empty state placeholder
|
|
258
|
+
- [Image](./app/components/hakumi_components/image/docs/README.md) - Image display with preview
|
|
259
|
+
- [Popover](./app/components/hakumi_components/popover/docs/README.md) - Popover overlay
|
|
260
|
+
- [QR Code](./app/components/hakumi_components/qr_code/docs/README.md) - QR code generator
|
|
261
|
+
- [Segmented](./app/components/hakumi_components/segmented/docs/README.md) - Segmented control
|
|
262
|
+
- [Statistic](./app/components/hakumi_components/statistic/docs/README.md) - Statistic display
|
|
263
|
+
- [Table](./app/components/hakumi_components/table/docs/README.md) - Data table
|
|
264
|
+
- [Tabs](./app/components/hakumi_components/tabs/docs/README.md) - Tab navigation
|
|
265
|
+
- [Tag](./app/components/hakumi_components/tag/docs/README.md) - Tag label
|
|
266
|
+
- [Timeline](./app/components/hakumi_components/timeline/docs/README.md) - Timeline display
|
|
267
|
+
- [Tooltip](./app/components/hakumi_components/tooltip/docs/README.md) - Tooltip overlay
|
|
268
|
+
- [Tour](./app/components/hakumi_components/tour/docs/README.md) - Guided tour
|
|
269
|
+
- [Tree](./app/components/hakumi_components/tree/docs/README.md) - Tree structure display
|
|
270
|
+
|
|
271
|
+
#### Feedback (10)
|
|
272
|
+
- [Alert](./app/components/hakumi_components/alert/docs/README.md) - Alert message display
|
|
273
|
+
- [Drawer](./app/components/hakumi_components/drawer/docs/README.md) - Slide-out drawer panel
|
|
274
|
+
- [Message](./app/components/hakumi_components/message/docs/README.md) - Global message notification
|
|
275
|
+
- [Modal](./app/components/hakumi_components/modal/docs/README.md) - Modal dialog
|
|
276
|
+
- [Notification](./app/components/hakumi_components/notification/docs/README.md) - Notification message
|
|
277
|
+
- [Popconfirm](./app/components/hakumi_components/popconfirm/docs/README.md) - Confirmation popover
|
|
278
|
+
- [Progress](./app/components/hakumi_components/progress/docs/README.md) - Progress indicator
|
|
279
|
+
- [Result](./app/components/hakumi_components/result/docs/README.md) - Result status page
|
|
280
|
+
- [Skeleton](./app/components/hakumi_components/skeleton/docs/README.md) - Skeleton loading placeholder
|
|
281
|
+
- [Spin](./app/components/hakumi_components/spin/docs/README.md) - Loading spinner
|
|
282
|
+
|
|
283
|
+
#### Other (1)
|
|
284
|
+
- [Affix](./app/components/hakumi_components/affix/docs/README.md) - Pin element to viewport
|
|
177
285
|
|
|
178
286
|
## JavaScript API
|
|
179
287
|
|
|
@@ -261,13 +369,24 @@ If components don't respond to interactions:
|
|
|
261
369
|
### Version mismatches
|
|
262
370
|
|
|
263
371
|
Keep gem and npm versions in sync:
|
|
372
|
+
|
|
264
373
|
```ruby
|
|
265
|
-
# Gemfile
|
|
266
|
-
gem 'hakumi_components', '
|
|
374
|
+
# Gemfile - pin to specific version
|
|
375
|
+
gem 'hakumi_components', '0.1.16.pre'
|
|
267
376
|
```
|
|
268
377
|
```bash
|
|
269
|
-
# package.json
|
|
270
|
-
yarn add @hakumi-dev/hakumi-components@0.1.
|
|
378
|
+
# package.json - matching version
|
|
379
|
+
yarn add @hakumi-dev/hakumi-components@0.1.16-pre
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
Or use dynamic versioning to always get the latest:
|
|
383
|
+
```ruby
|
|
384
|
+
# Gemfile - always latest pre-release
|
|
385
|
+
gem 'hakumi_components', '>= 0.1.0.pre'
|
|
386
|
+
```
|
|
387
|
+
```bash
|
|
388
|
+
# package.json - always latest pre-release
|
|
389
|
+
yarn add @hakumi-dev/hakumi-components@pre
|
|
271
390
|
```
|
|
272
391
|
|
|
273
392
|
## Updating
|
|
@@ -278,13 +397,62 @@ To update to the latest version:
|
|
|
278
397
|
# Update Ruby gem
|
|
279
398
|
bundle update hakumi_components
|
|
280
399
|
|
|
281
|
-
# Update npm package
|
|
400
|
+
# Update npm package to latest pre-release
|
|
282
401
|
yarn add @hakumi-dev/hakumi-components@pre
|
|
283
402
|
# or
|
|
284
|
-
npm install @hakumi-dev/hakumi-components@pre
|
|
403
|
+
npm install @hakumi-dev/hakumi-components@pre
|
|
285
404
|
```
|
|
286
405
|
|
|
287
|
-
**
|
|
406
|
+
**Version Strategy:**
|
|
407
|
+
- **During development:** Use `>= 0.1.0.pre` (gem) and `@pre` (npm) to always get the latest features
|
|
408
|
+
- **For production:** Pin to a specific version like `0.1.16.pre` for stability
|
|
409
|
+
|
|
410
|
+
**Note:** Currently in pre-release (`0.1.x.pre`). Stable `1.0.0` release coming soon.
|
|
411
|
+
|
|
412
|
+
## Development
|
|
413
|
+
|
|
414
|
+
### Local Playground
|
|
415
|
+
|
|
416
|
+
Want to see and test components locally? We have a built-in playground:
|
|
417
|
+
|
|
418
|
+
```bash
|
|
419
|
+
# From the gem root directory
|
|
420
|
+
bin/playground
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
Then visit http://localhost:3000 to browse all components and examples.
|
|
424
|
+
|
|
425
|
+
**Features:**
|
|
426
|
+
- 📋 Browse all 65 components
|
|
427
|
+
- 🎨 See examples in action
|
|
428
|
+
- 🔍 Test component behavior
|
|
429
|
+
- 💻 Perfect for development
|
|
430
|
+
|
|
431
|
+
The playground is located in `test/dummy/` and is **not included** in the published gem.
|
|
432
|
+
|
|
433
|
+
### Adding Examples
|
|
434
|
+
|
|
435
|
+
To add a new example for testing:
|
|
436
|
+
|
|
437
|
+
```bash
|
|
438
|
+
# Create a new example partial
|
|
439
|
+
touch test/dummy/app/views/test_examples/[component]/_[example_name].html.erb
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
It will automatically appear in the playground at `/test/[component]/[example_name]`.
|
|
443
|
+
|
|
444
|
+
### Running Tests
|
|
445
|
+
|
|
446
|
+
```bash
|
|
447
|
+
# All tests
|
|
448
|
+
bundle exec rake test
|
|
449
|
+
|
|
450
|
+
# Specific test file
|
|
451
|
+
bundle exec rake test TEST=test/components/hakumi/button/component_test.rb
|
|
452
|
+
|
|
453
|
+
# System tests (browser tests)
|
|
454
|
+
bundle exec rake test:system
|
|
455
|
+
```
|
|
288
456
|
|
|
289
457
|
## Contributing
|
|
290
458
|
|
|
@@ -3,6 +3,14 @@ import { ensureId } from "../../core/dom.js"
|
|
|
3
3
|
import { register, unregister } from "../../core/registry.js"
|
|
4
4
|
|
|
5
5
|
export default class RegistryController extends Controller {
|
|
6
|
+
/**
|
|
7
|
+
* Declarative actions supported by this component.
|
|
8
|
+
* Each component must explicitly declare which actions it supports.
|
|
9
|
+
* Actions map to methods: 'close' -> close(), 'confirm' -> handleConfirm()
|
|
10
|
+
* @type {string[]}
|
|
11
|
+
*/
|
|
12
|
+
static declarativeActions = []
|
|
13
|
+
|
|
6
14
|
connect() {
|
|
7
15
|
const isComponentController = this.isHakumiController()
|
|
8
16
|
|
|
@@ -21,6 +29,8 @@ export default class RegistryController extends Controller {
|
|
|
21
29
|
|
|
22
30
|
if (typeof this.setup === "function") this.setup()
|
|
23
31
|
|
|
32
|
+
this.setupDeclarativeActions()
|
|
33
|
+
|
|
24
34
|
this.validateContract()
|
|
25
35
|
register(this.element.id, this.element.hakumiComponent.api)
|
|
26
36
|
|
|
@@ -28,12 +38,17 @@ export default class RegistryController extends Controller {
|
|
|
28
38
|
if (this.element.hakumiComponent.singleton && typeof window !== "undefined" && window.HakumiComponents) {
|
|
29
39
|
window.HakumiComponents[this.element.hakumiComponent.name] = this.element.hakumiComponent.api
|
|
30
40
|
}
|
|
41
|
+
|
|
42
|
+
// Mark component as ready for testing
|
|
43
|
+
this.element.dataset.hakumiReady = "true"
|
|
31
44
|
}
|
|
32
45
|
|
|
33
46
|
|
|
34
47
|
disconnect() {
|
|
35
48
|
if (typeof this.teardown === "function") this.teardown()
|
|
36
49
|
|
|
50
|
+
this.teardownDeclarativeActions()
|
|
51
|
+
|
|
37
52
|
const c = this.element?.hakumiComponent
|
|
38
53
|
if (c?.singleton && typeof window !== "undefined" && window.HakumiComponents) {
|
|
39
54
|
if (window.HakumiComponents[c.name] === c.api) {
|
|
@@ -84,18 +99,83 @@ export default class RegistryController extends Controller {
|
|
|
84
99
|
return String(this.identifier || "").startsWith("hakumi--")
|
|
85
100
|
}
|
|
86
101
|
|
|
87
|
-
|
|
102
|
+
|
|
88
103
|
setup() {
|
|
89
104
|
|
|
90
105
|
}
|
|
91
106
|
|
|
92
|
-
|
|
107
|
+
|
|
93
108
|
teardown() {
|
|
94
109
|
|
|
95
110
|
}
|
|
96
111
|
|
|
97
|
-
|
|
112
|
+
|
|
98
113
|
registerApi() {
|
|
99
114
|
|
|
100
115
|
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Sets up declarative action handling for data-hakumi-action attributes.
|
|
119
|
+
* Listens for clicks on elements with data-hakumi-action and routes to
|
|
120
|
+
* the appropriate handler method (close, open, toggle, confirm, cancel).
|
|
121
|
+
*/
|
|
122
|
+
setupDeclarativeActions() {
|
|
123
|
+
this.boundHandleDeclarativeAction = this.handleDeclarativeAction.bind(this)
|
|
124
|
+
this.element.addEventListener("click", this.boundHandleDeclarativeAction)
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Cleans up declarative action event listener.
|
|
129
|
+
*/
|
|
130
|
+
teardownDeclarativeActions() {
|
|
131
|
+
if (this.boundHandleDeclarativeAction) {
|
|
132
|
+
this.element.removeEventListener("click", this.boundHandleDeclarativeAction)
|
|
133
|
+
this.boundHandleDeclarativeAction = null
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Handles clicks on elements with data-hakumi-action attribute.
|
|
139
|
+
* Routes to the appropriate method based on the action value.
|
|
140
|
+
* Supported actions: close, open, toggle, confirm, cancel
|
|
141
|
+
* @param {Event} event - The click event
|
|
142
|
+
*/
|
|
143
|
+
handleDeclarativeAction(event) {
|
|
144
|
+
const actionElement = event.target.closest("[data-hakumi-action]")
|
|
145
|
+
if (!actionElement || !this.element.contains(actionElement)) return
|
|
146
|
+
|
|
147
|
+
const action = actionElement.dataset.hakumiAction
|
|
148
|
+
const actionMethod = this.getActionMethod(action)
|
|
149
|
+
|
|
150
|
+
if (typeof actionMethod === "function") {
|
|
151
|
+
event.preventDefault()
|
|
152
|
+
actionMethod.call(this, event, actionElement)
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Returns the method to call for a given action name.
|
|
158
|
+
* Only returns methods for actions declared in static declarativeActions.
|
|
159
|
+
* @param {string} action - The action name
|
|
160
|
+
* @returns {Function|undefined} The method to call
|
|
161
|
+
*/
|
|
162
|
+
getActionMethod(action) {
|
|
163
|
+
const allowedActions = this.constructor.declarativeActions || []
|
|
164
|
+
if (!allowedActions.includes(action)) {
|
|
165
|
+
return undefined
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Try direct method name: close, open, toggle
|
|
169
|
+
if (typeof this[action] === "function") {
|
|
170
|
+
return this[action]
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// Try handleX pattern: confirm -> handleConfirm, cancel -> handleCancel
|
|
174
|
+
const handlerName = `handle${action.charAt(0).toUpperCase()}${action.slice(1)}`
|
|
175
|
+
if (typeof this[handlerName] === "function") {
|
|
176
|
+
return this[handlerName]
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return undefined
|
|
180
|
+
}
|
|
101
181
|
}
|
|
@@ -41,13 +41,6 @@ export default class extends RegistryController {
|
|
|
41
41
|
setOffsetBottom: (value) => this.setOffsetBottom(value)
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
|
-
|
|
45
|
-
this.#exposeApi()
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
disconnect() {
|
|
49
|
-
delete this.element.hakumiAffix
|
|
50
|
-
super.disconnect()
|
|
51
44
|
}
|
|
52
45
|
|
|
53
46
|
updatePosition() {
|
|
@@ -187,20 +180,4 @@ export default class extends RegistryController {
|
|
|
187
180
|
if (this.hasOffsetBottomValue) return Number(this.offsetBottomValue)
|
|
188
181
|
return null
|
|
189
182
|
}
|
|
190
|
-
|
|
191
|
-
#exposeApi() {
|
|
192
|
-
this.element.hakumiAffix = {
|
|
193
|
-
check: () => this.updatePosition(),
|
|
194
|
-
update: () => this.updatePosition(),
|
|
195
|
-
isAffixed: () => this.affixed,
|
|
196
|
-
getState: () => ({
|
|
197
|
-
affixed: this.affixed,
|
|
198
|
-
offsetTop: this.offsetTop,
|
|
199
|
-
offsetBottom: this.offsetBottom,
|
|
200
|
-
targetSelector: this.targetSelectorValue || null
|
|
201
|
-
}),
|
|
202
|
-
setOffsetTop: (value) => this.setOffsetTop(value),
|
|
203
|
-
setOffsetBottom: (value) => this.setOffsetBottom(value)
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
183
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import RegistryController from "../base/registry_controller.js"
|
|
2
2
|
|
|
3
3
|
export default class extends RegistryController {
|
|
4
|
+
static declarativeActions = ["close"]
|
|
4
5
|
static targets = ["message", "description"]
|
|
5
6
|
|
|
6
7
|
registerApi() {
|
|
@@ -20,7 +21,7 @@ export default class extends RegistryController {
|
|
|
20
21
|
|
|
21
22
|
close(event) {
|
|
22
23
|
if (event) event.preventDefault()
|
|
23
|
-
this.
|
|
24
|
+
this.dispatch("hidden")
|
|
24
25
|
this.element.remove()
|
|
25
26
|
}
|
|
26
27
|
|
|
@@ -14,13 +14,6 @@ export default class extends RegistryController {
|
|
|
14
14
|
this.element.removeEventListener('click', this.boundRipple)
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
handleClick(event) {
|
|
18
|
-
if (this.loadingValue || this.element.disabled) {
|
|
19
|
-
event.preventDefault()
|
|
20
|
-
event.stopImmediatePropagation()
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
17
|
createRipple(event) {
|
|
25
18
|
const button = event.currentTarget
|
|
26
19
|
const circle = document.createElement("span")
|
|
@@ -41,7 +41,6 @@ export default class extends RegistryController {
|
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
teardown() {
|
|
44
|
-
delete this.element.hakumiCalendar
|
|
45
44
|
}
|
|
46
45
|
|
|
47
46
|
#bindNestedEvents() {
|
|
@@ -1096,6 +1095,5 @@ export default class extends RegistryController {
|
|
|
1096
1095
|
}
|
|
1097
1096
|
|
|
1098
1097
|
|
|
1099
|
-
this.element.hakumiCalendar = api
|
|
1100
1098
|
}
|
|
1101
1099
|
}
|
|
@@ -725,11 +725,6 @@ export default class extends RegistryController {
|
|
|
725
725
|
}
|
|
726
726
|
|
|
727
727
|
dispatchEvent(name, detail) {
|
|
728
|
-
this.
|
|
729
|
-
new CustomEvent(`hakumi:color-picker:${name}`, {
|
|
730
|
-
detail,
|
|
731
|
-
bubbles: true
|
|
732
|
-
})
|
|
733
|
-
)
|
|
728
|
+
this.dispatch(name, { detail })
|
|
734
729
|
}
|
|
735
730
|
}
|