kommandant 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
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