Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: Add support for special characters #131

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 31 additions & 18 deletions example/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
font-weight: bold;
}

h1+p {
h1 + p {
font-size: 1.2em;
}

Expand Down Expand Up @@ -77,56 +77,60 @@
}

.github-corner:hover .octo-arm {
animation: octocat-wave 560ms ease-in-out
animation: octocat-wave 560ms ease-in-out;
}

@keyframes octocat-wave {

0%,
100% {
transform: rotate(0)
transform: rotate(0);
}

20%,
60% {
transform: rotate(-25deg)
transform: rotate(-25deg);
}

40%,
80% {
transform: rotate(10deg)
transform: rotate(10deg);
}
}

@media (max-width:500px) {
@media (max-width: 500px) {
.github-corner:hover .octo-arm {
animation: none
animation: none;
}

.github-corner .octo-arm {
animation: octocat-wave 560ms ease-in-out
animation: octocat-wave 560ms ease-in-out;
}
}

</style>
</head>
<body>
<h1>
<code>tinykeys</code>
</h1>
<p>
A tiny (~400 B) & modern library for keybindings.
</p>
<p>A tiny (~400 B) & modern library for keybindings.</p>

<a href="https://github.com/jamiebuilds/tinykeys" class="github-corner" aria-label="View source on GitHub">
<a
href="https://github.com/jamiebuilds/tinykeys"
class="github-corner"
aria-label="View source on GitHub"
>
<svg width="80" height="80" viewBox="0 0 250 250" aria-hidden="true">
<path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path>
<path
d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2"
fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path>
fill="currentColor"
style="transform-origin: 130px 106px"
class="octo-arm"
></path>
<path
d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z"
fill="currentColor"></path>
fill="currentColor"
></path>
</svg>
</a>

Expand All @@ -140,6 +144,7 @@ <h2>Examples</h2>
<li>
<kbd>Control+D</kbd> (Windows/Linux) or <kbd>Command+D</kbd> (Mac)
</li>
<li><kbd>?</kbd></li>
</ul>

<pre>
Expand All @@ -155,16 +160,24 @@ <h2>Examples</h2>
<strong>"$mod+KeyD"</strong>: () => {
<em>alert("Either 'Control+d' or 'Meta+d' were pressed")</em>
},
<strong>"?"</strong>: () => {
<em>alert("The key '?' was pressed")</em>
},
})
</pre>

<h2>History</h2>
<p>
Logs
<a href="https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key"><code>KeyboardEvent.key</code></a>
<a
href="https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key"
><code>KeyboardEvent.key</code></a
>
and
<a
href="https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code/code_values"><code>KeyboardEvent.code</code></a>
href="https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code/code_values"
><code>KeyboardEvent.code</code></a
>
used by this library
</p>
<pre id="logs">(start typing)</pre>
Expand Down
3 changes: 3 additions & 0 deletions example/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,7 @@ tinykeys(window, {
"$mod+KeyD": () => {
alert("Either 'Control+d' or 'Meta+d' were pressed")
},
"?": () => {
alert("The key '?' was pressed")
},
})
27 changes: 16 additions & 11 deletions src/tinykeys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,20 @@ export interface KeyBindingMap {
/**
* Options to configure the behavior of keybindings.
*/
export interface KeyBindingOptions {
/**
* Key presses will listen to this event (default: "keydown").
*/
event?: "keydown" | "keyup"

/**
* Keybinding sequences will wait this long between key presses before
export interface KeyBindingOptions {
/**
* Key presses will listen to this event (default: "keydown").
*/
event?: "keydown" | "keyup"

/**
* Keybinding sequences will wait this long between key presses before
* cancelling (default: 1000).
*
* **Note:** Setting this value too low (i.e. `300`) will be too fast for many
* of your users.
*/
timeout?: number
*/
timeout?: number
}

/**
Expand All @@ -42,7 +42,7 @@ let DEFAULT_TIMEOUT = 1000
/**
* Keybinding sequences should bind to this event by default.
*/
let DEFAULT_EVENT = "keydown"
let DEFAULT_EVENT = "keydown"

/**
* An alias for creating platform-specific keybinding aliases.
Expand Down Expand Up @@ -88,6 +88,11 @@ function parse(str: string): KeyBindingPress[] {
* partially or exactly.
*/
function match(event: KeyboardEvent, press: KeyBindingPress): boolean {
// match special characters like '?' and '!'
if (/^[^A-Za-z0-9]$/.test(event.key) && press[1] === event.key) {
return true
}
Comment on lines +92 to +94
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm confused why this isn't handled by:

(
  press[1].toUpperCase() !== event.key.toUpperCase() &&
  press[1] !== event.code
) ||
'?'.toUpperCase() === '?' // true

Should we also be comparing:

(
  press[1] !== event.key &&
  press[1].toUpperCase() !== event.key.toUpperCase() &&
  press[1] !== event.code
) ||

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I might be missing something super obvious here but this case:

( press[1].toUpperCase() !== event.key.toUpperCase() && press[1] !== event.code ) ||

is correct, it's properly returning false. However because it returns false, we check the second value, and then third value, which:

KEYBINDING_MODIFIER_KEYS.find(mod => {
  return !press[0].includes(mod) && press[1] !== mod && getModifierState(event, mod)
})

returns Shift, which when we apply !"Shift" it returns false 😅


// prettier-ignore
return !(
// Allow either the `event.key` or the `event.code`
Expand Down