kommandant 0.2.0 → 0.2.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8b3c12cb6c51778cd6575684e3c818960bc1db275aa4f2f5bc4bf1c39c0c57f6
4
- data.tar.gz: 7cbc64969033ebf7170bce6e65fe414db2c2b9e4ccff31f645f6f385b20c27d5
3
+ metadata.gz: a2574c9d2b6dfd75efee2ed6f9af3f92cfbd0b89a5e207d546f1e5979f8226ad
4
+ data.tar.gz: a0451d7914c31befe537e5703a80d22018fb4f60c0abb0faafb7f6c12542dbbe
5
5
  SHA512:
6
- metadata.gz: 4cf20342a6a8a5520652fa2949dea0aef98556c052db6c05ee59cb7203bd192dc7a60020af8e7193857efbbf3d545ad42f2dd1f8fe29d9cbf43b269f02bdf78b
7
- data.tar.gz: 63115cdca2ea3fced0cb93466fd5a6941ed3bf3033fc82a0e03afa695b4be80c05b73ef13216d398a9e61bf606346dfbede225d233a3e30dd90f7213a5629ef9
6
+ metadata.gz: 0eb9c48d8e9c06c8d9d1e905a8b4be846aa347abfba90a24479ce07da98eff5f0fec693fee27a24346ccfdf2701e81268272d7decef58eda0c8e31b01c11457b
7
+ data.tar.gz: afc40b7911d8ee7c02669819b5d331f4500ceec455de4b5ba6a4cbcdf317222b27d5f652886fe976c2e599bacaa3f96ee1a082a70b5e66d6246f9f4f45814776
@@ -1,3 +1,3 @@
1
1
  module Kommandant
2
- VERSION = "0.2.0"
2
+ VERSION = "0.2.1"
3
3
  end
@@ -0,0 +1,120 @@
1
+ import { Controller } from "@hotwired/stimulus"
2
+ import { enter, leave, toggle } from "./transition"
3
+
4
+ export default class extends Controller {
5
+ static targets = ["background", "panel", "input", "content", "loadingMessage", "previousPageLink", "nextPageLink"]
6
+ static values = {
7
+ open: { type: Boolean, default: false },
8
+ loadingMessageDelay: { type: Number, default: 100 },
9
+ animationDuration: { type: Number, default: 200 },
10
+ modifierKeyDown: { type: Boolean, default: false }
11
+ }
12
+
13
+ initialize() {
14
+ this.submit = this.debounce(this.submit, 500).bind(this);
15
+ }
16
+
17
+ toggle(event) {
18
+ event.preventDefault()
19
+
20
+ toggle(this.backgroundTarget)
21
+ toggle(this.panelTarget)
22
+ this.openValue = !this.openValue
23
+ }
24
+
25
+ show(event) {
26
+ event.preventDefault()
27
+
28
+ enter(this.backgroundTarget)
29
+ enter(this.panelTarget)
30
+ this.openValue = true
31
+ }
32
+
33
+ hide(event) {
34
+ event.preventDefault()
35
+
36
+ leave(this.backgroundTarget)
37
+ leave(this.panelTarget)
38
+ this.openValue = false
39
+ }
40
+
41
+ hideWithBackgroundOverlay(event) {
42
+ if (event.target === this.panelTarget) {
43
+ this.hide(event)
44
+ }
45
+ }
46
+
47
+ submit(event) {
48
+ const ignoreKeys = ["Enter", "Tab", "Escape", "ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight", "Home", "End", "Alt", "Control", "Meta", "Shift"]
49
+ const modifierKeyPressed = event.ctrlKey || event.metaKey
50
+
51
+ if (!modifierKeyPressed && !ignoreKeys.includes(event.key) && this.inputTarget.value !== "") {
52
+ this.inputTarget.form.requestSubmit()
53
+ }
54
+ }
55
+
56
+ reset() {
57
+ setTimeout(() => {
58
+ Turbo.visit("/kommandant/searches/new", { frame: "command_palette" })
59
+ }, this.animationDurationValue)
60
+ }
61
+
62
+ showLoadingMessage() {
63
+ this.loadingTimeout = setTimeout(() => {
64
+ this.contentTarget.classList.add("hidden")
65
+ this.loadingMessageTarget.classList.remove("hidden")
66
+ }, this.loadingMessageDelayValue)
67
+ }
68
+
69
+ nextPage(event) {
70
+ event.preventDefault()
71
+
72
+ if (this.hasNextPageLinkTarget) {
73
+ this.nextPageLinkTarget.click()
74
+ }
75
+ }
76
+
77
+ previousPage(event) {
78
+ event.preventDefault()
79
+
80
+ if (this.hasPreviousPageLinkTarget) {
81
+ this.previousPageLinkTarget.click()
82
+ }
83
+ }
84
+
85
+ // Private
86
+
87
+ openValueChanged(value, previousValue) {
88
+ this.focusInputTarget()
89
+
90
+ if (value === false && previousValue !== undefined) {
91
+ this.reset()
92
+ }
93
+ }
94
+
95
+ inputTargetConnected() {
96
+ this.focusInputTarget()
97
+ clearTimeout(this.loadingTimeout)
98
+ }
99
+
100
+ focusInputTarget() {
101
+ if (this.openValue) {
102
+ this.inputTarget.focus()
103
+
104
+ // Set cursor at end of inputted text
105
+ let temp = this.inputTarget.value
106
+ this.inputTarget.value = ""
107
+ this.inputTarget.value = temp
108
+ }
109
+ }
110
+
111
+ debounce(func, delay) {
112
+ let timeoutId;
113
+ return function (...args) {
114
+ clearTimeout(timeoutId);
115
+ timeoutId = setTimeout(() => {
116
+ func.apply(this, args);
117
+ }, delay);
118
+ };
119
+ }
120
+ }
@@ -0,0 +1,72 @@
1
+ import { Controller } from "@hotwired/stimulus"
2
+
3
+ export default class extends Controller {
4
+ static targets = ["focusable"]
5
+ static values = { activeOptionIndex: { type: Number, default: 0 } }
6
+
7
+ connect() {
8
+ if (this.activeOption) {
9
+ this.activateOption()
10
+ }
11
+ }
12
+
13
+ down(event) {
14
+ event.preventDefault()
15
+
16
+ if (this.activeOptionIndexValue < (this.focusableTargets.length - 1)) {
17
+ this.deactivateOption()
18
+ this.activeOptionIndexValue++
19
+ this.activateOption()
20
+ }
21
+ }
22
+
23
+ up(event) {
24
+ event.preventDefault()
25
+
26
+ if (this.activeOptionIndexValue > 0) {
27
+ this.deactivateOption()
28
+ this.activeOptionIndexValue--
29
+ this.activateOption()
30
+ }
31
+ }
32
+
33
+ focus(event) {
34
+ this.deactivateOption()
35
+ this.activeOptionIndexValue = this.focusableTargets.indexOf(event.currentTarget)
36
+ this.activateOption()
37
+ }
38
+
39
+ select(event) {
40
+ if (this.hasFocusableTarget && this.focusableTargetIsVisible) {
41
+ event.preventDefault()
42
+
43
+ this.activeOption.click()
44
+ }
45
+ }
46
+
47
+ // Private
48
+
49
+ deactivateOption() {
50
+ this.activeOption.dataset.active = false
51
+ }
52
+
53
+ activateOption() {
54
+ this.activeOption.dataset.active = true
55
+ }
56
+
57
+ focusableTargetDisconnected() {
58
+ this.activeOptionIndexValue = 0
59
+ }
60
+
61
+ focusableTargetConnected() {
62
+ this.activateOption()
63
+ }
64
+
65
+ get activeOption() {
66
+ return this.focusableTargets[this.activeOptionIndexValue]
67
+ }
68
+
69
+ get focusableTargetIsVisible() {
70
+ return this.focusableTarget.offsetParent !== null
71
+ }
72
+ }
@@ -0,0 +1,2 @@
1
+ export { default as CommandPalette } from './command_palette'
2
+ export { default as KeyboardNavigation } from './keyboard_navigation'
@@ -0,0 +1,57 @@
1
+ // This was taken from https://github.com/mmccall10/el-transition but is included here to avoid the need for a separate package
2
+
3
+ export async function enter(element, transitionName = null) {
4
+ element.classList.remove('hidden')
5
+ await transition('enter', element, transitionName)
6
+ }
7
+
8
+ export async function leave(element, transitionName = null) {
9
+ await transition('leave', element, transitionName)
10
+ element.classList.add('hidden')
11
+ }
12
+
13
+ export async function toggle(element, transitionName = null) {
14
+ if (element.classList.contains('hidden')) {
15
+ await enter(element, transitionName)
16
+ } else {
17
+ await leave(element, transitionName)
18
+ }
19
+ }
20
+
21
+ async function transition(direction, element, animation) {
22
+ const dataset = element.dataset
23
+ const animationClass = animation ? `${animation}-${direction}` : direction
24
+ let transition = `transition${direction.charAt(0).toUpperCase() + direction.slice(1)}`
25
+ const genesis = dataset[transition] ? dataset[transition].split(" ") : [animationClass]
26
+ const start = dataset[`${transition}Start`] ? dataset[`${transition}Start`].split(" ") : [`${animationClass}-start`]
27
+ const end = dataset[`${transition}End`] ? dataset[`${transition}End`].split(" ") : [`${animationClass}-end`]
28
+
29
+ addClasses(element, genesis)
30
+ addClasses(element, start)
31
+ await nextFrame()
32
+ removeClasses(element, start)
33
+ addClasses(element, end);
34
+ await afterTransition(element)
35
+ removeClasses(element, end)
36
+ removeClasses(element, genesis)
37
+ }
38
+
39
+ function addClasses(element, classes) {
40
+ element.classList.add(...classes)
41
+ }
42
+
43
+ function removeClasses(element, classes) {
44
+ element.classList.remove(...classes)
45
+ }
46
+
47
+ function nextFrame() {
48
+ return new Promise(resolve => {
49
+ requestAnimationFrame(() => {
50
+ requestAnimationFrame(resolve)
51
+ });
52
+ });
53
+ }
54
+
55
+ function afterTransition(element) {
56
+ return Promise.all(element.getAnimations().map(animation => animation.finished));
57
+ }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kommandant
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nicolai Bach Woller
@@ -133,6 +133,10 @@ files:
133
133
  - lib/kommandant/engine.rb
134
134
  - lib/kommandant/version.rb
135
135
  - lib/tasks/kommandant_tasks.rake
136
+ - vendor/assets/javascripts/command_palette.js
137
+ - vendor/assets/javascripts/keyboard_navigation.js
138
+ - vendor/assets/javascripts/kommandant.js
139
+ - vendor/assets/javascripts/transition.js
136
140
  homepage: https://traels.it
137
141
  licenses:
138
142
  - MIT