@profoundry-us/loco_motion 0.0.8 → 0.5.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.
package/README.md
CHANGED
|
@@ -6,19 +6,45 @@ ViewComponent, TailwindCSS, DaisyUI and more!
|
|
|
6
6
|
|
|
7
7
|
<img src="//loco-motion-docs.profoundry.us/images/loco-chats.png" width="500px" style="border: 1px solid #bbb; padding: 2px; border-radius: 10px;">
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
<!-- omit from toc -->
|
|
10
|
+
## DISCLAIMER / CURRENT STATUS
|
|
10
11
|
|
|
11
12
|
This project is in active development and many changes occur with every release!
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
to
|
|
13
|
+
|
|
14
|
+
We've added a very basic / untested version of all DaisyUI 4 components. While
|
|
15
|
+
we originally intended to take some time to flesh out and attempt to use these
|
|
16
|
+
components, with the recent release of Tailwind 4 and DaisyUI 5, we feel our
|
|
17
|
+
time is best spent updating all of the components and dependencies for these
|
|
18
|
+
new releases.
|
|
19
|
+
|
|
20
|
+
This means that we will **NOT** be making any bug fixes to the current branch
|
|
21
|
+
(0.4.0), and will instead include any bug fixes / improvements into the 0.5.0
|
|
22
|
+
branch which will also upgrade to Tailwind 4 and DaisyUI 5.
|
|
23
|
+
|
|
24
|
+
- Current Release **(0.4.0)** - Works with DaisyUI 4 and Tailwind 3
|
|
25
|
+
- Next Release **(0.5.0)** - Will work with DaisyUI 5 and Tailwind 4
|
|
26
|
+
|
|
27
|
+
<!-- omit from toc -->
|
|
28
|
+
## Additional Notes
|
|
29
|
+
|
|
30
|
+
### DataInput Components
|
|
31
|
+
|
|
32
|
+
Many of the DataInput elements (file input, text input, select dropdown, etc)
|
|
33
|
+
were built rather hastily so that we would have a base version to start from.
|
|
34
|
+
|
|
35
|
+
However, the new DaisyUI 5 components are implemented in a much cleaner way and
|
|
36
|
+
we didn't want to invest too much time building these out and making them more
|
|
37
|
+
ideal since we're about to change them.
|
|
38
|
+
|
|
39
|
+
### Hosting / Sites
|
|
15
40
|
|
|
16
41
|
We expect to settle on and purchase a real domain name in the near future, but
|
|
17
42
|
for the time being, the latest documentation is available at the links below.
|
|
18
43
|
|
|
19
|
-
- [
|
|
20
|
-
- [
|
|
21
|
-
|
|
44
|
+
- [Latest Release][1]
|
|
45
|
+
- [Main / Staging][3]
|
|
46
|
+
|
|
47
|
+
### Getting Help
|
|
22
48
|
|
|
23
49
|
Please reach out by opening an
|
|
24
50
|
[Issue](https://github.com/profoundry-us/loco_motion/issues) if you've found a
|
|
@@ -47,6 +73,8 @@ your solution is aligned with our goals.
|
|
|
47
73
|
- [Install](#install)
|
|
48
74
|
- [Using Components](#using-components)
|
|
49
75
|
- [Developing](#developing)
|
|
76
|
+
- [Contributing](#contributing)
|
|
77
|
+
- [Releasing](#releasing)
|
|
50
78
|
- [Tooling](#tooling)
|
|
51
79
|
- [TODO / Next Steps](#todo--next-steps)
|
|
52
80
|
|
|
@@ -731,7 +759,7 @@ gem "loco_motion", github: "profoundry-us/loco_motion", branch: "main", require:
|
|
|
731
759
|
|
|
732
760
|
# or
|
|
733
761
|
|
|
734
|
-
gem "loco_motion-rails", "0.0
|
|
762
|
+
gem "loco_motion-rails", "0.4.0", require: "loco_motion"
|
|
735
763
|
```
|
|
736
764
|
|
|
737
765
|
Next add the following lines to the `contents` section of your
|
|
@@ -856,6 +884,20 @@ See the `Makefile` for all available commands.
|
|
|
856
884
|
> make demo-restart
|
|
857
885
|
> ```
|
|
858
886
|
|
|
887
|
+
### Contributing
|
|
888
|
+
|
|
889
|
+
If you're interested in contributing to LocoMotion, please check out our
|
|
890
|
+
[CONTRIBUTING guide](docs/dev_guides/CONTRIBUTING.md) which provides detailed
|
|
891
|
+
information about the contribution process, code standards, documentation
|
|
892
|
+
requirements, and testing procedures.
|
|
893
|
+
|
|
894
|
+
### Releasing
|
|
895
|
+
|
|
896
|
+
For core team members who need to release new versions of LocoMotion, please
|
|
897
|
+
refer to our [RELEASING guide](docs/dev_guides/RELEASING.md) for step-by-step
|
|
898
|
+
instructions on version updates, building, testing, and publishing both the Ruby
|
|
899
|
+
gem and NPM package.
|
|
900
|
+
|
|
859
901
|
### Tooling
|
|
860
902
|
|
|
861
903
|
For VSCode, you may want to add the following to your settings to get
|
|
@@ -919,9 +961,9 @@ the GitHub Discussions feature and let us know!
|
|
|
919
961
|
- [x] Basic versions of DaisyUI Data Display
|
|
920
962
|
- [x] Basic versions of DaisyUI Navigation
|
|
921
963
|
- [x] Basic versions of DaisyUI Feedback
|
|
922
|
-
- [
|
|
923
|
-
- [
|
|
924
|
-
- [
|
|
964
|
+
- [x] Basic versions of DaisyUI Data Input
|
|
965
|
+
- [x] Basic versions of DaisyUI Layout
|
|
966
|
+
- [x] Basic versions of DaisyUI Mockup
|
|
925
967
|
- [x] ~~Get YARD docs rendering with (better) Markdown~~ _**Working for now**_
|
|
926
968
|
- [x] Extract relevant pieces into a yard-loco_motion plugin
|
|
927
969
|
- [x] Publish Gem
|
|
@@ -932,9 +974,9 @@ the GitHub Discussions feature and let us know!
|
|
|
932
974
|
- [ ] Choose, recommend, and document a pagination gem
|
|
933
975
|
- [ ] Discuss caching techniques / setup
|
|
934
976
|
- [x] Create / publish a staging version of the demo site ([Demo Staging][2])
|
|
935
|
-
- [
|
|
936
|
-
- [
|
|
937
|
-
- [
|
|
977
|
+
- [x] Create / publish a staging version of the docs site
|
|
978
|
+
- [x] Create / publish a production version of the demo site
|
|
979
|
+
- [x] Create / publish a production version of the docs site
|
|
938
980
|
- [x] Update demo site to allow for a different docs site using ENV var
|
|
939
981
|
- [x] Update README to suggest Playwright
|
|
940
982
|
- [ ] Build some have docs / guides / examples for using playwright-ruby-client
|
|
@@ -946,6 +988,12 @@ the GitHub Discussions feature and let us know!
|
|
|
946
988
|
- [ ] See if we can update the Join component to auto-add the `join-item` CSS
|
|
947
989
|
under certain conditions
|
|
948
990
|
- [ ] Add title and description content_for blocks to all examples for SEO purposes
|
|
991
|
+
- [ ] Update to Tailwind 4 and DaisyUI 5
|
|
992
|
+
- [ ] Rename the `Dockerfile` to `Dockerfile.loco` to be more concise
|
|
993
|
+
- [x] See if we can remove all of the `set_loco_parent` calls in favor of using
|
|
994
|
+
the `lib/loco_motion/patches/view_component/slot_loco_parent_patch.rb`
|
|
995
|
+
- [ ] Make the tooltips documentation button a component and use it for the
|
|
996
|
+
Labelable concern docs too
|
|
949
997
|
|
|
950
998
|
[1]: https://loco-motion.profoundry.us/
|
|
951
999
|
[2]: https://loco-motion-demo-staging.profoundry.us/
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Theme Controller
|
|
3
|
+
*
|
|
4
|
+
* A Stimulus controller that manages theme selection and persistence.
|
|
5
|
+
* It handles theme switching, localStorage persistence, and synchronization
|
|
6
|
+
* across multiple theme selectors on the same page.
|
|
7
|
+
*/
|
|
8
|
+
import { Controller } from "@hotwired/stimulus"
|
|
9
|
+
|
|
10
|
+
export default class extends Controller {
|
|
11
|
+
/**
|
|
12
|
+
* Called when the controller is connected to the DOM.
|
|
13
|
+
* Sets the initial theme input state and sets up event listeners.
|
|
14
|
+
*/
|
|
15
|
+
connect() {
|
|
16
|
+
this.setInput()
|
|
17
|
+
|
|
18
|
+
// Setup a custom listener to watch for changes on the page in case the
|
|
19
|
+
// page has multiple theme selectors
|
|
20
|
+
this.storageChangeListener = this.storageChanged.bind(this)
|
|
21
|
+
|
|
22
|
+
window.addEventListener('localstorage-update', this.storageChangeListener)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Called when the controller is disconnected from the DOM.
|
|
27
|
+
* Removes event listeners to prevent memory leaks.
|
|
28
|
+
*/
|
|
29
|
+
disconnect() {
|
|
30
|
+
window.removeEventListener('localstorage-update', this.storageChangeListener)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Sets the appropriate radio input as checked based on the current theme.
|
|
35
|
+
* This ensures the UI reflects the active theme.
|
|
36
|
+
*/
|
|
37
|
+
setInput() {
|
|
38
|
+
const theme = this.getCurrentTheme()
|
|
39
|
+
const input = this.element.querySelector(`input[value='${theme}']`);
|
|
40
|
+
|
|
41
|
+
if (input) {
|
|
42
|
+
input.checked = true;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Clears the user's theme preference from localStorage.
|
|
48
|
+
* Removes the saved theme and dispatches an event to notify other controllers.
|
|
49
|
+
*
|
|
50
|
+
* @param {Event} event - The triggering click event
|
|
51
|
+
*/
|
|
52
|
+
clearTheme(event) {
|
|
53
|
+
// If we are passed a themeName parameter, clear all inputs with that theme
|
|
54
|
+
if (event && event.params && event.params.themeName) {
|
|
55
|
+
const inputs = document.querySelectorAll(`input[name='${event.params.themeName}']`)
|
|
56
|
+
|
|
57
|
+
if (inputs) {
|
|
58
|
+
inputs.forEach(input => {
|
|
59
|
+
input.checked = false
|
|
60
|
+
})
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Remove the savedTheme from local storage
|
|
65
|
+
localStorage.removeItem("savedTheme")
|
|
66
|
+
|
|
67
|
+
// Fire off an update
|
|
68
|
+
const updateEvent = new CustomEvent('localstorage-update', { detail: { key: 'savedTheme', newValue: null } })
|
|
69
|
+
window.dispatchEvent(updateEvent)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Changes the theme based on user selection.
|
|
74
|
+
* Updates localStorage and dispatches a custom event to notify other controllers.
|
|
75
|
+
*
|
|
76
|
+
* @param {Event} event - The triggering click event
|
|
77
|
+
*/
|
|
78
|
+
setTheme(event) {
|
|
79
|
+
const input = event.currentTarget.querySelector('input')
|
|
80
|
+
|
|
81
|
+
if (input) {
|
|
82
|
+
localStorage.setItem("savedTheme", input.value)
|
|
83
|
+
|
|
84
|
+
const updateEvent = new CustomEvent('localstorage-update', { detail: { key: 'savedTheme', newValue: input.value } })
|
|
85
|
+
window.dispatchEvent(updateEvent)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
event.preventDefault();
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Retrieves the current theme from localStorage.
|
|
93
|
+
*
|
|
94
|
+
* @returns {string} The current theme name
|
|
95
|
+
*/
|
|
96
|
+
getCurrentTheme() {
|
|
97
|
+
const savedTheme = localStorage.getItem('savedTheme')
|
|
98
|
+
|
|
99
|
+
if (savedTheme) {
|
|
100
|
+
return savedTheme
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Event handler for 'localstorage-update' events.
|
|
106
|
+
* Updates the input state when theme changes in another controller.
|
|
107
|
+
*
|
|
108
|
+
* @param {CustomEvent} event - The storage changed event
|
|
109
|
+
*/
|
|
110
|
+
storageChanged(event) {
|
|
111
|
+
this.setInput()
|
|
112
|
+
}
|
|
113
|
+
}
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
import { Controller } from "@hotwired/stimulus"
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Controller for handling calendar input interactions.
|
|
5
|
+
* Manages the popover calendar UI and synchronization between input and calendar elements.
|
|
6
|
+
*/
|
|
7
|
+
export default class extends Controller {
|
|
8
|
+
static targets = ["calendar", "input", "popover"]
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Initializes the controller and sets up event listeners.
|
|
12
|
+
* Binds all methods to ensure proper 'this' context.
|
|
13
|
+
*
|
|
14
|
+
* @returns {void}
|
|
15
|
+
*/
|
|
16
|
+
connect() {
|
|
17
|
+
|
|
18
|
+
// Save the bound functions so we can remove them later
|
|
19
|
+
this.boundUpdateInput = this.updateInput.bind(this)
|
|
20
|
+
this.boundUpdateCalendar = this.updateCalendar.bind(this)
|
|
21
|
+
this.boundOpenCalendar = this.openCalendar.bind(this)
|
|
22
|
+
this.boundCloseCalendar = this.closeCalendar.bind(this)
|
|
23
|
+
this.boundHandleKeydown = this.handleKeydown.bind(this)
|
|
24
|
+
this.boundHandleToggle = this.handleToggle.bind(this)
|
|
25
|
+
|
|
26
|
+
// Bind all of our functions
|
|
27
|
+
this.calendarTarget.addEventListener("change", this.boundUpdateInput)
|
|
28
|
+
this.calendarTarget.addEventListener("blur", this.boundCloseCalendar)
|
|
29
|
+
|
|
30
|
+
this.inputTarget.addEventListener("change", this.boundUpdateCalendar)
|
|
31
|
+
this.inputTarget.addEventListener("keyup", this.boundUpdateCalendar)
|
|
32
|
+
this.inputTarget.addEventListener("click", this.boundOpenCalendar)
|
|
33
|
+
this.inputTarget.addEventListener("keydown", this.boundHandleKeydown)
|
|
34
|
+
|
|
35
|
+
this.popoverTarget.addEventListener("toggle", this.boundHandleToggle)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Cleans up event listeners when the controller is disconnected.
|
|
40
|
+
* Prevents memory leaks by removing all bound event handlers.
|
|
41
|
+
*
|
|
42
|
+
* @returns {void}
|
|
43
|
+
*/
|
|
44
|
+
disconnect() {
|
|
45
|
+
this.calendarTarget.removeEventListener("change", this.boundUpdateInput)
|
|
46
|
+
this.calendarTarget.removeEventListener("blur", this.boundCloseCalendar)
|
|
47
|
+
|
|
48
|
+
this.inputTarget.removeEventListener("change", this.boundUpdateCalendar)
|
|
49
|
+
this.inputTarget.removeEventListener("keyup", this.boundUpdateCalendar)
|
|
50
|
+
this.inputTarget.removeEventListener("keydown", this.boundHandleKeydown)
|
|
51
|
+
this.inputTarget.removeEventListener("click", this.boundOpenCalendar)
|
|
52
|
+
this.popoverTarget.removeEventListener("toggle", this.boundHandleToggle)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Opens the calendar popover.
|
|
57
|
+
*
|
|
58
|
+
* @returns {void}
|
|
59
|
+
*/
|
|
60
|
+
openCalendar() {
|
|
61
|
+
// Open the popover
|
|
62
|
+
this.popoverTarget.togglePopover(true)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Closes the calendar popover if the blur event is not related to calendar elements.
|
|
67
|
+
*
|
|
68
|
+
* @param {FocusEvent} event - The blur event object.
|
|
69
|
+
*
|
|
70
|
+
* @returns {void}
|
|
71
|
+
*/
|
|
72
|
+
closeCalendar(event) {
|
|
73
|
+
// Don't close if we're still in the calendar elements
|
|
74
|
+
if (event?.relatedTarget && this.calendarTarget.contains(event.relatedTarget)) {
|
|
75
|
+
return
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
this.popoverTarget.togglePopover(false)
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Opens the calendar if it is closed, or closes it if it is open.
|
|
83
|
+
*
|
|
84
|
+
* @returns {void}
|
|
85
|
+
*/
|
|
86
|
+
toggleCalendar() {
|
|
87
|
+
this.popoverTarget.togglePopover()
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Handles the popover toggle event.
|
|
92
|
+
* - When opening: Sets a zero-width space in empty inputs to prevent floating label flicker
|
|
93
|
+
* - When closing: Clears the single-space input to ensure proper floating label behavior
|
|
94
|
+
*
|
|
95
|
+
* @param {Event} event - The toggle event object with newState property
|
|
96
|
+
* @returns {void}
|
|
97
|
+
*/
|
|
98
|
+
handleToggle(event) {
|
|
99
|
+
const hasFloatingLabel = this.inputTarget.parentElement.classList.contains("floating-label")
|
|
100
|
+
const isOpen = event.newState == 'open'
|
|
101
|
+
|
|
102
|
+
if (isOpen) {
|
|
103
|
+
// Make sure the calendar is visible
|
|
104
|
+
this.scrollCalendarIntoView()
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (hasFloatingLabel) {
|
|
108
|
+
const ZERO_WIDTH_SPACE = '\u200B'
|
|
109
|
+
|
|
110
|
+
if (isOpen) {
|
|
111
|
+
// Set the input to a zero-width space if it is empty to prevent a floating label
|
|
112
|
+
// flicker when the calendar loses focus while setting the date
|
|
113
|
+
if (this.inputTarget.value == null || this.inputTarget.value === '') {
|
|
114
|
+
this.inputTarget.value = ZERO_WIDTH_SPACE;
|
|
115
|
+
}
|
|
116
|
+
} else {
|
|
117
|
+
// Unset the zero-width space input on close so the floating label works again
|
|
118
|
+
if (this.inputTarget.value === ZERO_WIDTH_SPACE) {
|
|
119
|
+
this.inputTarget.value = null
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Ensures the calendar popover is visible within the viewport.
|
|
127
|
+
*
|
|
128
|
+
* If the popover extends beyond the viewport edges, scrolls the window to
|
|
129
|
+
* bring it into view adding any data-auto-scroll-padding.
|
|
130
|
+
*
|
|
131
|
+
* @returns {void}
|
|
132
|
+
*/
|
|
133
|
+
scrollCalendarIntoView() {
|
|
134
|
+
const rect = this.popoverTarget.getBoundingClientRect()
|
|
135
|
+
const autoScrollPadding = parseInt(this.popoverTarget.dataset.autoScrollPadding, 10)
|
|
136
|
+
const padding = isNaN(autoScrollPadding) ? 0 : autoScrollPadding
|
|
137
|
+
|
|
138
|
+
if (rect.bottom > window.innerHeight) {
|
|
139
|
+
window.scrollBy({ top: rect.bottom - window.innerHeight + padding, behavior: 'smooth' })
|
|
140
|
+
} else if (rect.top < 0) {
|
|
141
|
+
window.scrollBy({ top: rect.top - padding, behavior: 'smooth' })
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Updates the input value from the calendar and closes the popover.
|
|
147
|
+
* Synchronizes the input field with the selected date.
|
|
148
|
+
*
|
|
149
|
+
* @returns {void}
|
|
150
|
+
*/
|
|
151
|
+
updateInput() {
|
|
152
|
+
// Update the input value and close the popover
|
|
153
|
+
this.inputTarget.value = this.calendarTarget.value
|
|
154
|
+
this.closeCalendar()
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Handles keyboard navigation for the calendar input.
|
|
159
|
+
* - SPACE: Toggles the popover
|
|
160
|
+
* - ENTER: Closes an open popover
|
|
161
|
+
* - ARROW DOWN / ARROW UP: Opens the popover and focuses the calendar
|
|
162
|
+
*
|
|
163
|
+
* @param {KeyboardEvent} event - The keyboard event object.
|
|
164
|
+
*
|
|
165
|
+
* @returns {void}
|
|
166
|
+
*/
|
|
167
|
+
handleKeydown(event) {
|
|
168
|
+
const hasModifierKeys = event.ctrlKey || event.shiftKey || event.altKey || event.metaKey;
|
|
169
|
+
const isOpen = this.popoverTarget.matches(':popover-open')
|
|
170
|
+
|
|
171
|
+
//
|
|
172
|
+
// SPACE - Toggles the popover.
|
|
173
|
+
//
|
|
174
|
+
if (event.key === ' ' || event.code === 'Space') {
|
|
175
|
+
event.preventDefault()
|
|
176
|
+
|
|
177
|
+
this.toggleCalendar()
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
//
|
|
181
|
+
// ENTER - Closes an open popover
|
|
182
|
+
//
|
|
183
|
+
else if (isOpen && (event.key === 'Enter' || event.code === 'Enter')) {
|
|
184
|
+
// Stop the enter key from triggering the form submission
|
|
185
|
+
event.preventDefault()
|
|
186
|
+
|
|
187
|
+
this.closeCalendar()
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
//
|
|
191
|
+
// ARROW DOWN / ARROW UP - Opens the popover and focuses the calendar
|
|
192
|
+
//
|
|
193
|
+
else if ((event.key === 'ArrowDown' || event.code === 'ArrowUp') && !hasModifierKeys) {
|
|
194
|
+
event.preventDefault()
|
|
195
|
+
|
|
196
|
+
// If the calendar is not already open, open it
|
|
197
|
+
if (!isOpen) {
|
|
198
|
+
this.openCalendar()
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Focus the calendar element
|
|
202
|
+
this.calendarTarget.focus()
|
|
203
|
+
|
|
204
|
+
// Forward the keydown event to the calendar
|
|
205
|
+
const forwardedEvent = new KeyboardEvent('keydown', {
|
|
206
|
+
key: event.key,
|
|
207
|
+
code: event.code,
|
|
208
|
+
bubbles: true,
|
|
209
|
+
cancelable: true,
|
|
210
|
+
})
|
|
211
|
+
|
|
212
|
+
// Dispatch the forwarded event to the calendar
|
|
213
|
+
this.calendarTarget.dispatchEvent(forwardedEvent)
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Updates the calendar's value based on the input field.
|
|
219
|
+
* Only updates if the input contains a valid ISO 8601 date.
|
|
220
|
+
*
|
|
221
|
+
* @returns {void}
|
|
222
|
+
*/
|
|
223
|
+
updateCalendar() {
|
|
224
|
+
// Only update the calendar if we have a full / valid ISO 8601 date
|
|
225
|
+
let newDate = this.inputTarget.value
|
|
226
|
+
|
|
227
|
+
if (newDate.length !== 10 || new Date(newDate).toString() === "Invalid Date") {
|
|
228
|
+
return
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// Set the calendar value and focused-date attributes
|
|
232
|
+
this.calendarTarget.value = newDate
|
|
233
|
+
this.calendarTarget.setAttribute('focused-date', newDate)
|
|
234
|
+
}
|
|
235
|
+
}
|
package/index.js
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
import CallyInputController from './app/components/daisy/data_input/cally_input_controller';
|
|
1
2
|
import CountdownController from './app/components/daisy/data_display/countdown_controller';
|
|
3
|
+
import ThemeController from './app/components/daisy/actions/theme_controller';
|
|
2
4
|
|
|
3
|
-
export {
|
|
5
|
+
export {
|
|
6
|
+
CallyInputController,
|
|
7
|
+
CountdownController,
|
|
8
|
+
ThemeController,
|
|
9
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@profoundry-us/loco_motion",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Crazy fast Rails development!",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"repository": {
|
|
@@ -14,6 +14,8 @@
|
|
|
14
14
|
},
|
|
15
15
|
"files": [
|
|
16
16
|
"index.js",
|
|
17
|
-
"app/components/daisy/
|
|
17
|
+
"app/components/daisy/data_input/cally_input_controller.js",
|
|
18
|
+
"app/components/daisy/data_display/countdown_controller.js",
|
|
19
|
+
"app/components/daisy/actions/theme_controller.js"
|
|
18
20
|
]
|
|
19
21
|
}
|