revotech-ui-kit 0.0.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/.editorconfig +29 -0
- package/.eslintrc +10 -0
- package/.storybook/main.ts +17 -0
- package/.storybook/preview-head.html +1 -0
- package/.storybook/preview.ts +17 -0
- package/LICENSE +21 -0
- package/README.md +30 -0
- package/assets/fonts/Geist/Geist-Black.otf +0 -0
- package/assets/fonts/Geist/Geist-Black.woff2 +0 -0
- package/assets/fonts/Geist/Geist-Bold.otf +0 -0
- package/assets/fonts/Geist/Geist-Bold.woff2 +0 -0
- package/assets/fonts/Geist/Geist-Light.otf +0 -0
- package/assets/fonts/Geist/Geist-Light.woff2 +0 -0
- package/assets/fonts/Geist/Geist-Medium.otf +0 -0
- package/assets/fonts/Geist/Geist-Medium.woff2 +0 -0
- package/assets/fonts/Geist/Geist-Regular.otf +0 -0
- package/assets/fonts/Geist/Geist-Regular.woff2 +0 -0
- package/assets/fonts/Geist/Geist-SemiBold.otf +0 -0
- package/assets/fonts/Geist/Geist-SemiBold.woff2 +0 -0
- package/assets/fonts/Geist/Geist-Thin.otf +0 -0
- package/assets/fonts/Geist/Geist-Thin.woff2 +0 -0
- package/assets/fonts/Geist/Geist-UltraBlack.otf +0 -0
- package/assets/fonts/Geist/Geist-UltraBlack.woff2 +0 -0
- package/assets/fonts/Geist/Geist-UltraLight.otf +0 -0
- package/assets/fonts/Geist/Geist-UltraLight.woff2 +0 -0
- package/assets/fonts/Geist/GeistVariableVF.ttf +0 -0
- package/assets/fonts/Geist/GeistVariableVF.woff2 +0 -0
- package/assets/fonts/Geist/LICENSE.TXT +92 -0
- package/assets/open-wc-logo.svg +29 -0
- package/index.html +362 -0
- package/package.json +117 -0
- package/rollup.config.js +71 -0
- package/src/components/atoms/button/button.atom.ts +39 -0
- package/src/components/atoms/button/button.stories.ts +186 -0
- package/src/components/atoms/button/button.style.ts +31 -0
- package/src/components/atoms/button/button.type.ts +10 -0
- package/src/components/atoms/checkbox/checkbox.atom.ts +62 -0
- package/src/components/atoms/checkbox/checkbox.stories.ts +42 -0
- package/src/components/atoms/command-empty/command-empty.atom.ts +44 -0
- package/src/components/atoms/command-group/command-group.atom.ts +60 -0
- package/src/components/atoms/command-item/command-item.atom.ts +74 -0
- package/src/components/atoms/command-list/command-list.atom.ts +37 -0
- package/src/components/atoms/command-separator/command-separator.atom.ts +42 -0
- package/src/components/atoms/dialog/dialog.atom.ts +301 -0
- package/src/components/atoms/dialog/dialog.stories.ts +86 -0
- package/src/components/atoms/index.ts +10 -0
- package/src/components/atoms/input/input.atom.ts +34 -0
- package/src/components/atoms/input/input.stories.ts +89 -0
- package/src/components/atoms/input/input.type.ts +24 -0
- package/src/components/atoms/label/label.atom.ts +40 -0
- package/src/components/atoms/label/label.stories.ts +18 -0
- package/src/components/atoms/label/label.style.ts +5 -0
- package/src/components/command/command.stories.ts +154 -0
- package/src/components/command/command.ts +391 -0
- package/src/components/index.ts +2 -0
- package/src/components/molecules/command/command.molecules.ts +31 -0
- package/src/components/molecules/command-input/command-input.atom.ts +130 -0
- package/src/components/molecules/index.ts +1 -0
- package/src/components/popover.ts +247 -0
- package/src/globals.css +1806 -0
- package/src/helpers/index.ts +2 -0
- package/src/helpers/mouse-conroller.helper.ts +42 -0
- package/src/helpers/style.helpers.ts +6 -0
- package/src/interfaces/actionable.interface.ts +6 -0
- package/src/interfaces/atomic.interface.ts +6 -0
- package/src/interfaces/changeable.interface.ts +14 -0
- package/src/interfaces/child-support-atomic.interface.ts +5 -0
- package/src/interfaces/index.ts +6 -0
- package/src/interfaces/intractable.interface.ts +6 -0
- package/src/interfaces/variant.interface.ts +3 -0
- package/src/lib/index.ts +0 -0
- package/src/lib/next/next.lib.ts +0 -0
- package/src/lib/react/react.lib.ts +0 -0
- package/src/styles/index.ts +1 -0
- package/src/styles/tw.styles.ts +1867 -0
- package/src/tailwind-lib.css +95 -0
- package/src/wc-ui-app.ts +81 -0
- package/tailwind.config.js +81 -0
- package/test/wc-ui-app.test.ts +22 -0
- package/tsconfig.json +25 -0
- package/web-dev-server.config.mjs +26 -0
- package/web-test-runner.config.mjs +41 -0
@@ -0,0 +1,154 @@
|
|
1
|
+
import { html } from 'lit';
|
2
|
+
// eslint-disable-next-line import/extensions
|
3
|
+
import './command';
|
4
|
+
import { Meta } from '@storybook/web-components';
|
5
|
+
|
6
|
+
export default {
|
7
|
+
title: 'Components/command',
|
8
|
+
component: 'rtg-command',
|
9
|
+
tags: ['autodocs'],
|
10
|
+
} as Meta;
|
11
|
+
export const Default = () => html`
|
12
|
+
<rtg-command class="w-full max-w-md">
|
13
|
+
<rtg-command-input placeholder="Search ...."></rtg-command-input>
|
14
|
+
<rtg-command-list>
|
15
|
+
<rtg-command-empty>No items found!</rtg-command-empty>
|
16
|
+
<rtg-command-group heading="Suggestions">
|
17
|
+
<rtg-command-item>
|
18
|
+
<svg
|
19
|
+
xmlns="http://www.w3.org/2000/svg"
|
20
|
+
width="24"
|
21
|
+
height="24"
|
22
|
+
viewBox="0 0 24 24"
|
23
|
+
fill="none"
|
24
|
+
stroke="currentColor"
|
25
|
+
stroke-width="2"
|
26
|
+
stroke-linecap="round"
|
27
|
+
stroke-linejoin="round"
|
28
|
+
class="mr-2 h-4 w-4"
|
29
|
+
>
|
30
|
+
<rect width="18" height="18" x="3" y="4" rx="2" ry="2"></rect>
|
31
|
+
<line x1="16" x2="16" y1="2" y2="6"></line>
|
32
|
+
<line x1="8" x2="8" y1="2" y2="6"></line>
|
33
|
+
<line x1="3" x2="21" y1="10" y2="10"></line>
|
34
|
+
</svg>
|
35
|
+
<span>Calendar</span>
|
36
|
+
</rtg-command-item>
|
37
|
+
<rtg-command-item>
|
38
|
+
<svg
|
39
|
+
xmlns="http://www.w3.org/2000/svg"
|
40
|
+
width="24"
|
41
|
+
height="24"
|
42
|
+
viewBox="0 0 24 24"
|
43
|
+
fill="none"
|
44
|
+
stroke="currentColor"
|
45
|
+
stroke-width="2"
|
46
|
+
stroke-linecap="round"
|
47
|
+
stroke-linejoin="round"
|
48
|
+
class="mr-2 h-4 w-4"
|
49
|
+
>
|
50
|
+
<circle cx="12" cy="12" r="10"></circle>
|
51
|
+
<path d="M8 14s1.5 2 4 2 4-2 4-2"></path>
|
52
|
+
<line x1="9" x2="9.01" y1="9" y2="9"></line>
|
53
|
+
<line x1="15" x2="15.01" y1="9" y2="9"></line>
|
54
|
+
</svg>
|
55
|
+
<span>Search Emoji</span>
|
56
|
+
</rtg-command-item>
|
57
|
+
<rtg-command-item>
|
58
|
+
<svg
|
59
|
+
xmlns="http://www.w3.org/2000/svg"
|
60
|
+
width="24"
|
61
|
+
height="24"
|
62
|
+
viewBox="0 0 24 24"
|
63
|
+
fill="none"
|
64
|
+
stroke="currentColor"
|
65
|
+
stroke-width="2"
|
66
|
+
stroke-linecap="round"
|
67
|
+
stroke-linejoin="round"
|
68
|
+
class="mr-2 h-4 w-4"
|
69
|
+
>
|
70
|
+
<rect width="16" height="20" x="4" y="2" rx="2"></rect>
|
71
|
+
<line x1="8" x2="16" y1="6" y2="6"></line>
|
72
|
+
<line x1="16" x2="16" y1="14" y2="18"></line>
|
73
|
+
<path d="M16 10h.01"></path>
|
74
|
+
<path d="M12 10h.01"></path>
|
75
|
+
<path d="M8 10h.01"></path>
|
76
|
+
<path d="M12 14h.01"></path>
|
77
|
+
<path d="M8 14h.01"></path>
|
78
|
+
<path d="M12 18h.01"></path>
|
79
|
+
<path d="M8 18h.01"></path>
|
80
|
+
</svg>
|
81
|
+
<span>Calculator</span>
|
82
|
+
</rtg-command-item>
|
83
|
+
</rtg-command-group>
|
84
|
+
<rtg-command-separator></rtg-command-separator>
|
85
|
+
<rtg-command-group heading="Settings">
|
86
|
+
<rtg-command-item onclick="javascript:alert('Profile Clicked!')">
|
87
|
+
<svg
|
88
|
+
xmlns="http://www.w3.org/2000/svg"
|
89
|
+
width="24"
|
90
|
+
height="24"
|
91
|
+
viewBox="0 0 24 24"
|
92
|
+
fill="none"
|
93
|
+
stroke="currentColor"
|
94
|
+
stroke-width="2"
|
95
|
+
stroke-linecap="round"
|
96
|
+
stroke-linejoin="round"
|
97
|
+
class="mr-2 h-4 w-4"
|
98
|
+
>
|
99
|
+
<path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"></path>
|
100
|
+
<circle cx="12" cy="7" r="4"></circle>
|
101
|
+
</svg>
|
102
|
+
<span>Profile</span>
|
103
|
+
<span class="ml-auto text-xs tracking-widest text-muted-foreground"
|
104
|
+
>⌘P</span
|
105
|
+
>
|
106
|
+
</rtg-command-item>
|
107
|
+
<rtg-command-item>
|
108
|
+
<svg
|
109
|
+
xmlns="http://www.w3.org/2000/svg"
|
110
|
+
width="24"
|
111
|
+
height="24"
|
112
|
+
viewBox="0 0 24 24"
|
113
|
+
fill="none"
|
114
|
+
stroke="currentColor"
|
115
|
+
stroke-width="2"
|
116
|
+
stroke-linecap="round"
|
117
|
+
stroke-linejoin="round"
|
118
|
+
class="mr-2 h-4 w-4"
|
119
|
+
>
|
120
|
+
<rect width="20" height="14" x="2" y="5" rx="2"></rect>
|
121
|
+
<line x1="2" x2="22" y1="10" y2="10"></line>
|
122
|
+
</svg>
|
123
|
+
<span>Billing</span
|
124
|
+
><span class="ml-auto text-xs tracking-widest text-muted-foreground"
|
125
|
+
>⌘B</span
|
126
|
+
>
|
127
|
+
</rtg-command-item>
|
128
|
+
<rtg-command-item>
|
129
|
+
<svg
|
130
|
+
xmlns="http://www.w3.org/2000/svg"
|
131
|
+
width="24"
|
132
|
+
height="24"
|
133
|
+
viewBox="0 0 24 24"
|
134
|
+
fill="none"
|
135
|
+
stroke="currentColor"
|
136
|
+
stroke-width="2"
|
137
|
+
stroke-linecap="round"
|
138
|
+
stroke-linejoin="round"
|
139
|
+
class="mr-2 h-4 w-4"
|
140
|
+
>
|
141
|
+
<path
|
142
|
+
d="M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z"
|
143
|
+
></path>
|
144
|
+
<circle cx="12" cy="12" r="3"></circle>
|
145
|
+
</svg>
|
146
|
+
<span>Settings</span>
|
147
|
+
<span class="ml-auto text-xs tracking-widest text-muted-foreground">
|
148
|
+
⌘S</span
|
149
|
+
>
|
150
|
+
</rtg-command-item>
|
151
|
+
</rtg-command-group></rtg-command-list
|
152
|
+
>
|
153
|
+
</rtg-command>
|
154
|
+
`;
|
@@ -0,0 +1,391 @@
|
|
1
|
+
import { LitElement, html, css, nothing } from 'lit';
|
2
|
+
import {
|
3
|
+
property,
|
4
|
+
customElement,
|
5
|
+
queryAssignedElements,
|
6
|
+
} from 'lit/decorators.js';
|
7
|
+
import { cn } from '../../helpers';
|
8
|
+
import { TWStyles } from '../../styles';
|
9
|
+
|
10
|
+
@customElement('rtg-command')
|
11
|
+
export class Command extends LitElement {
|
12
|
+
static styles = [css``, TWStyles];
|
13
|
+
|
14
|
+
@queryAssignedElements({ selector: 'input[rtgcmd-input]' })
|
15
|
+
_input!: Array<HTMLElement>;
|
16
|
+
|
17
|
+
render() {
|
18
|
+
return html`
|
19
|
+
<div
|
20
|
+
class="${cn(
|
21
|
+
'flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground border shadow-md',
|
22
|
+
this.className
|
23
|
+
)}"
|
24
|
+
id="rtgcmdr1"
|
25
|
+
rtgcmd-root
|
26
|
+
>
|
27
|
+
<slot></slot>
|
28
|
+
</div>
|
29
|
+
`;
|
30
|
+
}
|
31
|
+
}
|
32
|
+
|
33
|
+
@customElement('rtg-command-list')
|
34
|
+
export class CommandList extends LitElement {
|
35
|
+
static styles = [css``, TWStyles];
|
36
|
+
|
37
|
+
private get identifier() {
|
38
|
+
const parent =
|
39
|
+
this.parentElement?.shadowRoot?.querySelector('div[rtgcmd-root]');
|
40
|
+
if (parent) {
|
41
|
+
return `${parent.getAttribute('id')}l`;
|
42
|
+
}
|
43
|
+
return `rtgcmdrxl`;
|
44
|
+
}
|
45
|
+
|
46
|
+
render() {
|
47
|
+
return html`
|
48
|
+
<div
|
49
|
+
class="${cn(
|
50
|
+
'max-h-[300px] overflow-y-auto overflow-x-hidden',
|
51
|
+
this.className
|
52
|
+
)}"
|
53
|
+
role="listbox"
|
54
|
+
id="${this.identifier}"
|
55
|
+
style="--rtgcmd-list-height: 265.0px;"
|
56
|
+
rtgcmd-list
|
57
|
+
>
|
58
|
+
<div>
|
59
|
+
<slot></slot>
|
60
|
+
</div>
|
61
|
+
</div>
|
62
|
+
`;
|
63
|
+
}
|
64
|
+
}
|
65
|
+
|
66
|
+
@customElement('rtg-command-group')
|
67
|
+
export class CommandGroup extends LitElement {
|
68
|
+
@property({ type: String }) heading = '';
|
69
|
+
|
70
|
+
@property({ attribute: 'id', type: String }) _id = '';
|
71
|
+
|
72
|
+
@property({ attribute: 'aria-hidden', type: String }) _hidden = '';
|
73
|
+
|
74
|
+
private static _counter = 0;
|
75
|
+
|
76
|
+
static styles = [css``, TWStyles];
|
77
|
+
|
78
|
+
private get identifier() {
|
79
|
+
if (this._id !== '') {
|
80
|
+
return this._id;
|
81
|
+
}
|
82
|
+
const parent =
|
83
|
+
this.parentElement?.shadowRoot?.querySelector('div[rtgcmd-list]');
|
84
|
+
if (parent) {
|
85
|
+
this._id = `${parent.getAttribute('id')}g${CommandGroup._counter++}`;
|
86
|
+
} else {
|
87
|
+
this._id = `rtgcmdrxlxg${CommandGroup._counter++}`;
|
88
|
+
}
|
89
|
+
return this._id;
|
90
|
+
}
|
91
|
+
|
92
|
+
render() {
|
93
|
+
// eslint-disable-next-line lit/attribute-value-entities
|
94
|
+
const c =
|
95
|
+
'overflow-hidden p-1 text-foreground [&_[rtgcmd-group-heading]]:px-2 [&_[rtgcmd-group-heading]]:py-1.5 [&_[rtgcmd-group-heading]]:text-xs [&_[rtgcmd-group-heading]]:font-medium [&_[rtgcmd-group-heading]]:text-muted-foreground';
|
96
|
+
return html`${this._hidden === 'true'
|
97
|
+
? nothing
|
98
|
+
: html`
|
99
|
+
<div
|
100
|
+
class="${c}"
|
101
|
+
rtgcmd-group
|
102
|
+
role="presentation"
|
103
|
+
id="${this.identifier}"
|
104
|
+
>
|
105
|
+
<div
|
106
|
+
rtgcmd-group-heading
|
107
|
+
aria-hidden="true"
|
108
|
+
id="${this.identifier}h"
|
109
|
+
>
|
110
|
+
${this.heading}
|
111
|
+
</div>
|
112
|
+
<div
|
113
|
+
rtgcmd-group-items
|
114
|
+
role="group"
|
115
|
+
aria-labelledby="${this.identifier}h"
|
116
|
+
>
|
117
|
+
<slot></slot>
|
118
|
+
</div>
|
119
|
+
</div>
|
120
|
+
`}`;
|
121
|
+
}
|
122
|
+
}
|
123
|
+
|
124
|
+
@customElement('rtg-command-separator')
|
125
|
+
export class CommandSeparator extends LitElement {
|
126
|
+
@property({ type: String }) _id = '';
|
127
|
+
|
128
|
+
@property({ attribute: 'aria-hidden', type: String }) _hidden = '';
|
129
|
+
|
130
|
+
private static _counter = 0;
|
131
|
+
|
132
|
+
static styles = [css``, TWStyles];
|
133
|
+
|
134
|
+
private get identifier() {
|
135
|
+
if (this._id !== '') {
|
136
|
+
return this._id;
|
137
|
+
}
|
138
|
+
const parent =
|
139
|
+
this.parentElement?.shadowRoot?.querySelector('div[rtgcmd-list]');
|
140
|
+
if (parent) {
|
141
|
+
this._id = `${parent.getAttribute('id')}s${CommandSeparator._counter++}`;
|
142
|
+
} else {
|
143
|
+
this._id = `rtgcmdrxlxs${CommandSeparator._counter++}`;
|
144
|
+
}
|
145
|
+
return this._id;
|
146
|
+
}
|
147
|
+
|
148
|
+
render() {
|
149
|
+
return html`${this._hidden === 'true'
|
150
|
+
? nothing
|
151
|
+
: html`
|
152
|
+
<div
|
153
|
+
class="${cn('-mx-1 h-px bg-border', this.className)}"
|
154
|
+
rtgcmd-separator
|
155
|
+
role="separator"
|
156
|
+
id="${this.identifier}"
|
157
|
+
></div>
|
158
|
+
`}`;
|
159
|
+
}
|
160
|
+
}
|
161
|
+
|
162
|
+
@customElement('rtg-command-empty')
|
163
|
+
export class CommandEmpty extends LitElement {
|
164
|
+
@property({ type: String }) _id = '';
|
165
|
+
|
166
|
+
@property({ attribute: 'aria-hidden', type: String }) _hidden = 'true';
|
167
|
+
|
168
|
+
private static _counter = 0;
|
169
|
+
|
170
|
+
static styles = [css``, TWStyles];
|
171
|
+
|
172
|
+
private get identifier() {
|
173
|
+
if (this._id !== '') {
|
174
|
+
return this._id;
|
175
|
+
}
|
176
|
+
const parent =
|
177
|
+
this.parentElement?.shadowRoot?.querySelector('div[rtgcmd-list]');
|
178
|
+
if (parent) {
|
179
|
+
this._id = `${parent.getAttribute('id')}e${CommandEmpty._counter++}`;
|
180
|
+
} else {
|
181
|
+
this._id = `rtgcmdrxlxe${CommandEmpty._counter++}`;
|
182
|
+
}
|
183
|
+
return this._id;
|
184
|
+
}
|
185
|
+
|
186
|
+
render() {
|
187
|
+
return html`${this._hidden === 'true'
|
188
|
+
? nothing
|
189
|
+
: html`
|
190
|
+
<div
|
191
|
+
class="${cn('py-6 text-center text-sm', this.className)}"
|
192
|
+
rtgcmd-empty
|
193
|
+
role="presentation"
|
194
|
+
id="${this.identifier}"
|
195
|
+
>
|
196
|
+
<slot></slot>
|
197
|
+
</div>
|
198
|
+
`}`;
|
199
|
+
}
|
200
|
+
}
|
201
|
+
|
202
|
+
@customElement('rtg-command-item')
|
203
|
+
export class CommandItem extends LitElement {
|
204
|
+
@property({ type: String }) _id = '';
|
205
|
+
|
206
|
+
@property({ attribute: 'aria-hidden', type: String }) _hidden = '';
|
207
|
+
|
208
|
+
private static _counter = 0;
|
209
|
+
|
210
|
+
static styles = [css``, TWStyles];
|
211
|
+
|
212
|
+
private get identifier() {
|
213
|
+
if (this._id !== '') {
|
214
|
+
return this._id;
|
215
|
+
}
|
216
|
+
const parent =
|
217
|
+
this.parentElement?.shadowRoot?.querySelector('div[rtgcmd-group]');
|
218
|
+
if (parent) {
|
219
|
+
this._id = `${parent.getAttribute('id')}li${CommandItem._counter++}`;
|
220
|
+
} else {
|
221
|
+
this._id = `rtgcmdrxgxli${CommandItem._counter++}`;
|
222
|
+
}
|
223
|
+
return this._id;
|
224
|
+
}
|
225
|
+
|
226
|
+
@property({ attribute: 'data-value', type: String })
|
227
|
+
public get value() {
|
228
|
+
return this.textContent?.trim() || '';
|
229
|
+
}
|
230
|
+
|
231
|
+
@property({ type: Boolean }) selected = false;
|
232
|
+
|
233
|
+
private handleMouseEvent(e: Event) {
|
234
|
+
if (e.type === 'mouseover' || e.type === 'focus') {
|
235
|
+
this.selected = true;
|
236
|
+
}
|
237
|
+
if (e.type === 'mouseleave') {
|
238
|
+
this.selected = false;
|
239
|
+
}
|
240
|
+
}
|
241
|
+
|
242
|
+
render() {
|
243
|
+
return html` ${this._hidden === 'true'
|
244
|
+
? nothing
|
245
|
+
: html`
|
246
|
+
<div
|
247
|
+
class="${cn(
|
248
|
+
'relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none aria-selected:bg-accent aria-selected:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
|
249
|
+
this.className
|
250
|
+
)}"
|
251
|
+
@mouseover="${this.handleMouseEvent}"
|
252
|
+
@mouseleave="${this.handleMouseEvent}"
|
253
|
+
@focus="${this.handleMouseEvent}"
|
254
|
+
rtgcmd-item
|
255
|
+
role="option"
|
256
|
+
aria-selected="${this.selected}"
|
257
|
+
data-selected="${this.selected}"
|
258
|
+
data-value="${this.value}"
|
259
|
+
id="${this.identifier}"
|
260
|
+
aria-hidden="${this.hidden}"
|
261
|
+
>
|
262
|
+
<slot></slot>
|
263
|
+
</div>
|
264
|
+
`}`;
|
265
|
+
}
|
266
|
+
}
|
267
|
+
|
268
|
+
@customElement('rtg-command-input')
|
269
|
+
export class CommandInput extends LitElement {
|
270
|
+
@property({ type: String }) placeholder = 'Type a command or search...';
|
271
|
+
|
272
|
+
@property({ attribute: 'value', type: String }) _value = '';
|
273
|
+
|
274
|
+
static styles = [css``, TWStyles];
|
275
|
+
|
276
|
+
private get identifier() {
|
277
|
+
const parent =
|
278
|
+
this.parentElement?.shadowRoot?.querySelector('div[rtgcmd-root]');
|
279
|
+
if (parent) {
|
280
|
+
return `${parent.getAttribute('id')}i`;
|
281
|
+
}
|
282
|
+
return `rtgcmdrxi`;
|
283
|
+
}
|
284
|
+
|
285
|
+
private filterItems() {
|
286
|
+
const parent = this.parentElement;
|
287
|
+
if (parent) {
|
288
|
+
let isEmpty = true;
|
289
|
+
const groups = parent.querySelectorAll(
|
290
|
+
'rtg-command-list > rtg-command-group'
|
291
|
+
);
|
292
|
+
if (groups) {
|
293
|
+
groups.forEach(group => {
|
294
|
+
let hidden = true;
|
295
|
+
const items = group.querySelectorAll('rtg-command-item');
|
296
|
+
if (items) {
|
297
|
+
items.forEach(item => {
|
298
|
+
const value = (item as CommandItem)?.value || '';
|
299
|
+
if (value.toLowerCase().includes(this._value.toLowerCase())) {
|
300
|
+
hidden = false;
|
301
|
+
isEmpty = false;
|
302
|
+
item.setAttribute('aria-hidden', 'false');
|
303
|
+
} else {
|
304
|
+
item.setAttribute('aria-hidden', 'true');
|
305
|
+
}
|
306
|
+
});
|
307
|
+
}
|
308
|
+
group.setAttribute('aria-hidden', hidden ? 'true' : 'false');
|
309
|
+
let separator = group.previousElementSibling as CommandSeparator;
|
310
|
+
if (separator) {
|
311
|
+
separator.setAttribute(
|
312
|
+
'aria-hidden',
|
313
|
+
hidden ||
|
314
|
+
separator.previousElementSibling?.getAttribute(
|
315
|
+
'aria-hidden'
|
316
|
+
) === 'true'
|
317
|
+
? 'true'
|
318
|
+
: 'false'
|
319
|
+
);
|
320
|
+
}
|
321
|
+
separator = group.nextElementSibling as CommandSeparator;
|
322
|
+
if (separator) {
|
323
|
+
separator.setAttribute(
|
324
|
+
'aria-hidden',
|
325
|
+
hidden ||
|
326
|
+
separator.nextElementSibling?.getAttribute('aria-hidden') ===
|
327
|
+
'true'
|
328
|
+
? 'true'
|
329
|
+
: 'false'
|
330
|
+
);
|
331
|
+
}
|
332
|
+
});
|
333
|
+
}
|
334
|
+
|
335
|
+
const empty = parent.querySelector('rtg-command-empty');
|
336
|
+
if (empty) {
|
337
|
+
empty.setAttribute('aria-hidden', isEmpty ? 'false' : 'true');
|
338
|
+
}
|
339
|
+
}
|
340
|
+
}
|
341
|
+
|
342
|
+
private handleChange(e: Event) {
|
343
|
+
const input = e.target as HTMLInputElement;
|
344
|
+
if (input) {
|
345
|
+
this._value = input.value;
|
346
|
+
this.filterItems();
|
347
|
+
}
|
348
|
+
}
|
349
|
+
|
350
|
+
render() {
|
351
|
+
return html`
|
352
|
+
<div
|
353
|
+
class="${cn('flex items-center border-b px-3', this.className)}"
|
354
|
+
name="rtgcmd-input-container"
|
355
|
+
>
|
356
|
+
<svg
|
357
|
+
xmlns="http://www.w3.org/2000/svg"
|
358
|
+
width="24"
|
359
|
+
height="24"
|
360
|
+
viewBox="0 0 24 24"
|
361
|
+
fill="none"
|
362
|
+
stroke="currentColor"
|
363
|
+
stroke-width="2"
|
364
|
+
stroke-linecap="round"
|
365
|
+
stroke-linejoin="round"
|
366
|
+
class="mr-2 h-4 w-4 shrink-0 opacity-50"
|
367
|
+
>
|
368
|
+
<circle cx="11" cy="11" r="8"></circle>
|
369
|
+
<path d="m21 21-4.3-4.3"></path>
|
370
|
+
</svg>
|
371
|
+
<input
|
372
|
+
class="flex h-11 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50"
|
373
|
+
placeholder="${this.placeholder}"
|
374
|
+
rtgcmd-input
|
375
|
+
@input="${this.handleChange}"
|
376
|
+
autocomplete="off"
|
377
|
+
autocorrect="off"
|
378
|
+
spellcheck="false"
|
379
|
+
aria-autocomplete="list"
|
380
|
+
role="combobox"
|
381
|
+
aria-expanded="true"
|
382
|
+
aria-controls=":r1oe:"
|
383
|
+
aria-labelledby=":r1of:"
|
384
|
+
id="${this.identifier}"
|
385
|
+
type="text"
|
386
|
+
data-value="${this._value}"
|
387
|
+
/>
|
388
|
+
</div>
|
389
|
+
`;
|
390
|
+
}
|
391
|
+
}
|
@@ -0,0 +1,31 @@
|
|
1
|
+
import { LitElement, html, css, nothing } from 'lit';
|
2
|
+
import {
|
3
|
+
property,
|
4
|
+
customElement,
|
5
|
+
queryAssignedElements,
|
6
|
+
} from 'lit/decorators.js';
|
7
|
+
import { cn } from '@/helpers';
|
8
|
+
import { TWStyles } from '@/styles';
|
9
|
+
|
10
|
+
@customElement('rtg-command')
|
11
|
+
export class Command extends LitElement {
|
12
|
+
static styles = [css``, TWStyles];
|
13
|
+
|
14
|
+
@queryAssignedElements({ selector: 'input[rtgcmd-input]' })
|
15
|
+
_input!: Array<HTMLElement>;
|
16
|
+
|
17
|
+
render() {
|
18
|
+
return html`
|
19
|
+
<div
|
20
|
+
class="${cn(
|
21
|
+
'flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground border shadow-md',
|
22
|
+
this.className
|
23
|
+
)}"
|
24
|
+
id="rtgcmdr1"
|
25
|
+
rtgcmd-root
|
26
|
+
>
|
27
|
+
<slot></slot>
|
28
|
+
</div>
|
29
|
+
`;
|
30
|
+
}
|
31
|
+
}
|