Previews

No matching results.

Pages

No matching results.

x
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
<div contents data-controller="dialog">
<button type="button" class="btn" data-action="dialog#showModal">Show command</button>
<dialog class="dialog" style="--dialog-size: 430px;" data-dialog-target="content" data-action="click->dialog#closeOnClickOutside">
<button button="button" class="btn btn--plain dialog__close" data-action="dialog#close">
<span class="icon icon--x" aria-hidden="true"></span>
<span class="sr-only">Close</span>
</button>
<div class="command border-0" data-controller="command" data-action="combobox-commit->command#commit">
<label class="command__input input input--actor flex items-center gap">
<span class="icon icon--search" aria-hidden="true"></span>
<input type="text" name="search" id="search" data-command-target="input" data-action="command#filter" autofocus="autofocus" autocomplete="off" placeholder="Filter..." />
</label>
<div class="command__list" data-command-target="list" role="listbox" aria-label="Commands">
<div class="command__group" role="group" aria-labelledby="suggestions">
<span id="suggestions" class="command__group-header">Suggestions</span>
<div id="0f307ad95f2e48bd9ec47e2e5e0684e5" class="btn command__item" data-command-target="item" data-value="calendar" data-href="" role="option">
<span class="icon icon--calendar" aria-hidden="true"></span>
<span>Calendar</span>
</div>
<div id="bdda84f2f5a7d4ac063a6ad4a63a2496" class="btn command__item" data-command-target="item" data-value="search emoji" data-href="" role="option">
<span class="icon icon--smile" aria-hidden="true"></span>
<span>Seach Emoji</span>
</div>
<div id="4c53d5169df86a0ce46b178b546744f8" class="btn command__item" data-command-target="item" data-value="calculator" data-href="" aria-disabled="true" role="option">
<span class="icon icon--calculator" aria-hidden="true"></span>
<span>Calculator</span>
</div>
</div>
<div class="command__group" role="group" aria-labelledby="settings">
<span id="settings" class="command__group-header">Settings</span>
<div id="6a127ec64fdd92396c60a8380db7c329" class="btn command__item" data-command-target="item" data-value="profile" data-href="" role="option">
<span class="icon icon--user" aria-hidden="true"></span>
<span>Profile</span>
<span class="command__item-key">⌘P</span>
</div>
<div id="4d204f4cc7c8edfe85131047e95102c0" class="btn command__item" data-command-target="item" data-value="billing" data-href="" role="option">
<span class="icon icon--credit-card" aria-hidden="true"></span>
<span>Billing</span>
<span class="command__item-key">⌘B</span>
</div>
<div id="8f073171acaae0ec94443a6931f9a2b8" class="btn command__item" data-command-target="item" data-value="settings" data-href="" role="option">
<span class="icon icon--settings" aria-hidden="true"></span>
<span>Settings</span>
<span class="command__item-key">⌘P</span>
</div>
</div>
</div>
</div>
</dialog>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<div contents data-controller="dialog">
<button type="button" class="btn" data-action="dialog#showModal">Show command</button>
<dialog class="dialog" style="--dialog-size: 430px;" data-dialog-target="content" data-action="click->dialog#closeOnClickOutside">
<button button="button" class="btn btn--plain dialog__close" data-action="dialog#close">
<span class="icon icon--x" aria-hidden="true"></span>
<span class="sr-only">Close</span>
</button>
<div class="command border-0" data-controller="command" data-action="combobox-commit->command#commit">
<label class="command__input input input--actor flex items-center gap">
<span class="icon icon--search" aria-hidden="true"></span>
<%= text_field_tag "search", nil, data: { command_target: "input", action: "command#filter" }, autofocus: true, autocomplete: "off", placeholder: "Filter..." %>
</label>
<div class="command__list" data-command-target="list" role="listbox" aria-label="Commands">
<%= render "command_options" %>
</div>
</div>
</dialog>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
.command {
background-color: var(--color-surface);
border-radius: var(--rounded-lg);
border-width: var(--border);
box-shadow: var(--shadow-xs);
display: flex;
flex-direction: column;
}
.command__input {
--input-background: transparent;
--input-border-color: transparent;
--input-box-shadow: none;
--input-outline-size: 0;
--input-padding: var(--size-2_5);
}
.command__list {
border-block-start-width: var(--border);
max-block-size: 300px;
overflow-y: auto;
&:not(:has(.command__item:not([hidden]))) {
display: none;
}
}
.command__group:not(:first-child) {
border-block-start-width: var(--border);
}
.command__group {
display: flex;
flex-direction: column;
padding: var(--size-1);
row-gap: 1px;
&:not(:has(.command__item:not([hidden]))) {
display: none;
}
}
.command__group-header {
color: var(--color-text-subtle);
font-size: var(--text-xs);
padding: var(--size-1_5) var(--size-2);
}
.command__empty {
display: none;
font-size: var(--text-sm);
justify-content: center;
padding-block: var(--size-6);
}
.command__item {
--btn-border-color: transparent;
--btn-box-shadow: none;
--btn-font-weight: var(--font-normal);
--btn-justify-content: start;
--btn-outline-size: 0;
--btn-padding: var(--size-1_5) var(--size-2);
&[aria-selected="true"] {
--btn-background: var(--color-border-light);
}
}
.command__item-key {
color: var(--color-text-subtle);
font-size: var(--text-xs);
margin-inline-start: auto;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import { Controller } from "@hotwired/stimulus"
import Combobox from "https://esm.sh/@github/combobox-nav@3.0.1?standalone"
export default class extends Controller {
static targets = [ "input", "list", "item" ]
connect() {
this.combobox = new Combobox(this.inputTarget, this.listTarget)
this.combobox.start()
}
disconnect() {
this.combobox.destroy()
}
filter({ target }) {
this.itemTargets.forEach(it => this.#matches(it.dataset.value, target.value) ? it.removeAttribute("hidden") : it.toggleAttribute("hidden", true))
}
commit({ target }) {
Turbo.visit(target.dataset.href, { action: "advance" })
}
#matches(text, potentialMatch) {
return text.toLowerCase().includes(potentialMatch.toLowerCase())
}
}