@kodaris/krubble-components 1.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.
Files changed (46) hide show
  1. package/custom-elements.json +2156 -0
  2. package/dist/accordion/accordion.d.ts +35 -0
  3. package/dist/accordion/accordion.d.ts.map +1 -0
  4. package/dist/accordion/accordion.js +120 -0
  5. package/dist/accordion/accordion.js.map +1 -0
  6. package/dist/alert.d.ts +35 -0
  7. package/dist/alert.d.ts.map +1 -0
  8. package/dist/alert.js +204 -0
  9. package/dist/alert.js.map +1 -0
  10. package/dist/button/button.d.ts +30 -0
  11. package/dist/button/button.d.ts.map +1 -0
  12. package/dist/button/button.js +133 -0
  13. package/dist/button/button.js.map +1 -0
  14. package/dist/code-demo/code-demo.d.ts +44 -0
  15. package/dist/code-demo/code-demo.d.ts.map +1 -0
  16. package/dist/code-demo/code-demo.js +277 -0
  17. package/dist/code-demo/code-demo.js.map +1 -0
  18. package/dist/context-menu/context-menu.d.ts +54 -0
  19. package/dist/context-menu/context-menu.d.ts.map +1 -0
  20. package/dist/context-menu/context-menu.js +179 -0
  21. package/dist/context-menu/context-menu.js.map +1 -0
  22. package/dist/dialog/dialog.d.ts +58 -0
  23. package/dist/dialog/dialog.d.ts.map +1 -0
  24. package/dist/dialog/dialog.js +142 -0
  25. package/dist/dialog/dialog.js.map +1 -0
  26. package/dist/form/index.d.ts +2 -0
  27. package/dist/form/index.d.ts.map +1 -0
  28. package/dist/form/index.js +3 -0
  29. package/dist/form/index.js.map +1 -0
  30. package/dist/form/text-field/text-field.d.ts +91 -0
  31. package/dist/form/text-field/text-field.d.ts.map +1 -0
  32. package/dist/form/text-field/text-field.js +281 -0
  33. package/dist/form/text-field/text-field.js.map +1 -0
  34. package/dist/index.d.ts +10 -0
  35. package/dist/index.d.ts.map +1 -0
  36. package/dist/index.js +10 -0
  37. package/dist/index.js.map +1 -0
  38. package/dist/krubble.bundled.js +1402 -0
  39. package/dist/krubble.bundled.js.map +1 -0
  40. package/dist/krubble.bundled.min.js +739 -0
  41. package/dist/krubble.bundled.min.js.map +1 -0
  42. package/dist/krubble.umd.js +1411 -0
  43. package/dist/krubble.umd.js.map +1 -0
  44. package/dist/krubble.umd.min.js +739 -0
  45. package/dist/krubble.umd.min.js.map +1 -0
  46. package/package.json +51 -0
@@ -0,0 +1,277 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import { LitElement, html, css } from 'lit';
8
+ import { customElement, property, state } from 'lit/decorators.js';
9
+ import { classMap } from 'lit/directives/class-map.js';
10
+ import { unsafeHTML } from 'lit/directives/unsafe-html.js';
11
+ /**
12
+ * Code demo component with Preview/Code tabs and syntax highlighting.
13
+ *
14
+ * Usage:
15
+ * ```html
16
+ * <kr-code-demo language="html">
17
+ * <div slot="preview">
18
+ * <kr-button>Click me</kr-button>
19
+ * </div>
20
+ * <script slot="code" type="text/plain">
21
+ * <kr-button>Click me</kr-button>
22
+ * </script>
23
+ * </kr-code-demo>
24
+ * ```
25
+ *
26
+ * Requires Prism.js to be loaded globally for syntax highlighting.
27
+ */
28
+ let KRCodeDemo = class KRCodeDemo extends LitElement {
29
+ constructor() {
30
+ super(...arguments);
31
+ this.language = 'html';
32
+ this.code = '';
33
+ this.activeTab = 'preview';
34
+ this.copied = false;
35
+ }
36
+ setTab(tab) {
37
+ this.activeTab = tab;
38
+ }
39
+ getHighlightedCode() {
40
+ if (!this.code)
41
+ return '';
42
+ if (window.Prism && window.Prism.languages[this.language]) {
43
+ return window.Prism.highlight(this.code, window.Prism.languages[this.language], this.language);
44
+ }
45
+ // Fallback: escape HTML and return plain text
46
+ return this.escapeHtml(this.code);
47
+ }
48
+ escapeHtml(text) {
49
+ const div = document.createElement('div');
50
+ div.textContent = text;
51
+ return div.innerHTML;
52
+ }
53
+ async copyCode() {
54
+ if (!this.code)
55
+ return;
56
+ try {
57
+ await navigator.clipboard.writeText(this.code);
58
+ this.copied = true;
59
+ setTimeout(() => {
60
+ this.copied = false;
61
+ }, 2000);
62
+ }
63
+ catch (err) {
64
+ console.error('Failed to copy code:', err);
65
+ }
66
+ }
67
+ render() {
68
+ return html `
69
+ <div class="tabs">
70
+ <button
71
+ class=${classMap({ tab: true, 'tab--active': this.activeTab === 'preview' })}
72
+ @click=${() => this.setTab('preview')}
73
+ >
74
+ Preview
75
+ </button>
76
+ <button
77
+ class=${classMap({ tab: true, 'tab--active': this.activeTab === 'code' })}
78
+ @click=${() => this.setTab('code')}
79
+ >
80
+ Code
81
+ </button>
82
+ </div>
83
+
84
+ <div class=${classMap({ panel: true, 'panel--active': this.activeTab === 'preview', preview: true })}>
85
+ <slot name="preview"></slot>
86
+ </div>
87
+
88
+ <div class=${classMap({ panel: true, 'panel--active': this.activeTab === 'code', 'code-container': true })}>
89
+ <button
90
+ class=${classMap({ 'copy-btn': true, 'copy-btn--copied': this.copied })}
91
+ @click=${this.copyCode}
92
+ >
93
+ ${this.copied ? 'Copied!' : 'Copy'}
94
+ </button>
95
+ <pre class="code"><code>${unsafeHTML(this.getHighlightedCode())}</code></pre>
96
+ </div>
97
+
98
+ `;
99
+ }
100
+ };
101
+ KRCodeDemo.styles = css `
102
+ :host {
103
+ display: block;
104
+ border: 1px solid #e9ecef;
105
+ border-radius: 8px;
106
+ overflow: hidden;
107
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
108
+ }
109
+
110
+ .tabs {
111
+ display: flex;
112
+ background: #f8f9fa;
113
+ border-bottom: 1px solid #e9ecef;
114
+ }
115
+
116
+ .tab {
117
+ padding: 10px 20px;
118
+ background: none;
119
+ border: none;
120
+ color: #6c757d;
121
+ font-size: 14px;
122
+ font-weight: 500;
123
+ font-family: inherit;
124
+ cursor: pointer;
125
+ position: relative;
126
+ transition: color 0.15s;
127
+ }
128
+
129
+ .tab:hover {
130
+ color: #495057;
131
+ }
132
+
133
+ .tab--active {
134
+ color: #1a1a2e;
135
+ }
136
+
137
+ .tab--active::after {
138
+ content: '';
139
+ position: absolute;
140
+ bottom: -1px;
141
+ left: 0;
142
+ right: 0;
143
+ height: 2px;
144
+ background: #4f46e5;
145
+ }
146
+
147
+ .panel {
148
+ display: none;
149
+ }
150
+
151
+ .panel--active {
152
+ display: block;
153
+ }
154
+
155
+ .preview {
156
+ padding: 24px;
157
+ background: #ffffff;
158
+ }
159
+
160
+ .code-container {
161
+ position: relative;
162
+ }
163
+
164
+ .code {
165
+ margin: 0;
166
+ padding: 20px;
167
+ background: #1e1e2e;
168
+ overflow-x: auto;
169
+ font-family: 'SF Mono', 'Fira Code', 'Monaco', 'Consolas', monospace;
170
+ font-size: 13px;
171
+ line-height: 1.6;
172
+ color: #cdd6f4;
173
+ }
174
+
175
+ .code code {
176
+ font-family: inherit;
177
+ }
178
+
179
+ .copy-btn {
180
+ position: absolute;
181
+ top: 12px;
182
+ right: 12px;
183
+ padding: 6px 12px;
184
+ background: rgba(255, 255, 255, 0.1);
185
+ border: 1px solid rgba(255, 255, 255, 0.1);
186
+ border-radius: 6px;
187
+ color: rgba(255, 255, 255, 0.7);
188
+ font-size: 12px;
189
+ font-family: inherit;
190
+ cursor: pointer;
191
+ transition: background 0.15s, color 0.15s;
192
+ }
193
+
194
+ .copy-btn:hover {
195
+ background: rgba(255, 255, 255, 0.15);
196
+ color: white;
197
+ }
198
+
199
+ .copy-btn--copied {
200
+ background: rgba(34, 197, 94, 0.2);
201
+ border-color: rgba(34, 197, 94, 0.3);
202
+ color: #4ade80;
203
+ }
204
+
205
+ /* Prism.js theme overrides for dark mode */
206
+ .code .token.comment,
207
+ .code .token.prolog,
208
+ .code .token.doctype,
209
+ .code .token.cdata {
210
+ color: #6c7086;
211
+ }
212
+
213
+ .code .token.punctuation {
214
+ color: #9399b2;
215
+ }
216
+
217
+ .code .token.property,
218
+ .code .token.tag,
219
+ .code .token.boolean,
220
+ .code .token.number,
221
+ .code .token.constant,
222
+ .code .token.symbol,
223
+ .code .token.deleted {
224
+ color: #f38ba8;
225
+ }
226
+
227
+ .code .token.selector,
228
+ .code .token.attr-name,
229
+ .code .token.string,
230
+ .code .token.char,
231
+ .code .token.builtin,
232
+ .code .token.inserted {
233
+ color: #a6e3a1;
234
+ }
235
+
236
+ .code .token.operator,
237
+ .code .token.entity,
238
+ .code .token.url,
239
+ .code .language-css .token.string,
240
+ .code .style .token.string {
241
+ color: #94e2d5;
242
+ }
243
+
244
+ .code .token.atrule,
245
+ .code .token.attr-value,
246
+ .code .token.keyword {
247
+ color: #cba6f7;
248
+ }
249
+
250
+ .code .token.function,
251
+ .code .token.class-name {
252
+ color: #89b4fa;
253
+ }
254
+
255
+ .code .token.regex,
256
+ .code .token.important,
257
+ .code .token.variable {
258
+ color: #fab387;
259
+ }
260
+ `;
261
+ __decorate([
262
+ property({ type: String })
263
+ ], KRCodeDemo.prototype, "language", void 0);
264
+ __decorate([
265
+ property({ type: String })
266
+ ], KRCodeDemo.prototype, "code", void 0);
267
+ __decorate([
268
+ state()
269
+ ], KRCodeDemo.prototype, "activeTab", void 0);
270
+ __decorate([
271
+ state()
272
+ ], KRCodeDemo.prototype, "copied", void 0);
273
+ KRCodeDemo = __decorate([
274
+ customElement('kr-code-demo')
275
+ ], KRCodeDemo);
276
+ export { KRCodeDemo };
277
+ //# sourceMappingURL=code-demo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"code-demo.js","sourceRoot":"","sources":["../../src/code-demo/code-demo.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ import { LitElement } from 'lit';
2
+ export interface ContextMenuItem {
3
+ id: string;
4
+ label: string;
5
+ icon?: string;
6
+ disabled?: boolean;
7
+ divider?: boolean;
8
+ }
9
+ export interface ContextMenuOptions {
10
+ x: number;
11
+ y: number;
12
+ items: ContextMenuItem[];
13
+ }
14
+ /**
15
+ * Context menu component that can be opened programmatically.
16
+ *
17
+ * Usage:
18
+ * ```ts
19
+ * const result = await ContextMenu.open({
20
+ * x: event.clientX,
21
+ * y: event.clientY,
22
+ * items: [
23
+ * { id: 'edit', label: 'Edit Item' },
24
+ * { id: 'divider', label: '', divider: true },
25
+ * { id: 'add-above', label: 'Add Item Above' },
26
+ * { id: 'add-below', label: 'Add Item Below' },
27
+ * ]
28
+ * });
29
+ *
30
+ * if (result) {
31
+ * console.log('Selected:', result.id);
32
+ * }
33
+ * ```
34
+ */
35
+ export declare class KRContextMenu extends LitElement {
36
+ static styles: import("lit").CSSResult;
37
+ private items;
38
+ private resolvePromise;
39
+ private boundHandleOutsideClick;
40
+ private boundHandleKeyDown;
41
+ static open(options: ContextMenuOptions): Promise<ContextMenuItem | null>;
42
+ show(options: ContextMenuOptions): Promise<ContextMenuItem | null>;
43
+ private handleOutsideClick;
44
+ private handleKeyDown;
45
+ private handleItemClick;
46
+ private close;
47
+ render(): import("lit-html").TemplateResult<1>;
48
+ }
49
+ declare global {
50
+ interface HTMLElementTagNameMap {
51
+ 'kr-context-menu': KRContextMenu;
52
+ }
53
+ }
54
+ //# sourceMappingURL=context-menu.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-menu.d.ts","sourceRoot":"","sources":["../../src/context-menu/context-menu.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,MAAM,KAAK,CAAC;AAG5C,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,eAAe,EAAE,CAAC;CAC1B;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBACa,aAAc,SAAQ,UAAU;IAC3C,OAAgB,MAAM,0BAuDpB;IAGF,OAAO,CAAC,KAAK,CAAyB;IAEtC,OAAO,CAAC,cAAc,CAA0D;IAEhF,OAAO,CAAC,uBAAuB,CAAsC;IACrE,OAAO,CAAC,kBAAkB,CAAiC;WAE9C,IAAI,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;IAczE,IAAI,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;IA4BxE,OAAO,CAAC,kBAAkB;IAM1B,OAAO,CAAC,aAAa;IAMrB,OAAO,CAAC,eAAe;IAMvB,OAAO,CAAC,KAAK;IAaJ,MAAM;CAoBhB;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,iBAAiB,EAAE,aAAa,CAAC;KAClC;CACF"}
@@ -0,0 +1,179 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import { LitElement, html, css } from 'lit';
8
+ import { customElement, state } from 'lit/decorators.js';
9
+ /**
10
+ * Context menu component that can be opened programmatically.
11
+ *
12
+ * Usage:
13
+ * ```ts
14
+ * const result = await ContextMenu.open({
15
+ * x: event.clientX,
16
+ * y: event.clientY,
17
+ * items: [
18
+ * { id: 'edit', label: 'Edit Item' },
19
+ * { id: 'divider', label: '', divider: true },
20
+ * { id: 'add-above', label: 'Add Item Above' },
21
+ * { id: 'add-below', label: 'Add Item Below' },
22
+ * ]
23
+ * });
24
+ *
25
+ * if (result) {
26
+ * console.log('Selected:', result.id);
27
+ * }
28
+ * ```
29
+ */
30
+ let KRContextMenu = class KRContextMenu extends LitElement {
31
+ constructor() {
32
+ super(...arguments);
33
+ this.items = [];
34
+ this.resolvePromise = null;
35
+ this.boundHandleOutsideClick = this.handleOutsideClick.bind(this);
36
+ this.boundHandleKeyDown = this.handleKeyDown.bind(this);
37
+ }
38
+ static async open(options) {
39
+ // Remove any existing context menu
40
+ const existing = document.querySelector('kr-context-menu');
41
+ if (existing) {
42
+ existing.remove();
43
+ }
44
+ // Create and position the menu
45
+ const menu = document.createElement('kr-context-menu');
46
+ document.body.appendChild(menu);
47
+ return menu.show(options);
48
+ }
49
+ async show(options) {
50
+ this.items = options.items;
51
+ this.style.left = `${options.x}px`;
52
+ this.style.top = `${options.y}px`;
53
+ // Adjust position if menu would go off screen
54
+ await this.updateComplete;
55
+ const rect = this.getBoundingClientRect();
56
+ if (rect.right > window.innerWidth) {
57
+ this.style.left = `${options.x - rect.width}px`;
58
+ }
59
+ if (rect.bottom > window.innerHeight) {
60
+ this.style.top = `${options.y - rect.height}px`;
61
+ }
62
+ // Add event listeners after a microtask to avoid the current event triggering close
63
+ requestAnimationFrame(() => {
64
+ document.addEventListener('click', this.boundHandleOutsideClick);
65
+ document.addEventListener('contextmenu', this.boundHandleOutsideClick);
66
+ document.addEventListener('keydown', this.boundHandleKeyDown);
67
+ });
68
+ return new Promise((resolve) => {
69
+ this.resolvePromise = resolve;
70
+ });
71
+ }
72
+ handleOutsideClick(e) {
73
+ if (!this.contains(e.target)) {
74
+ this.close(null);
75
+ }
76
+ }
77
+ handleKeyDown(e) {
78
+ if (e.key === 'Escape') {
79
+ this.close(null);
80
+ }
81
+ }
82
+ handleItemClick(item) {
83
+ if (!item.disabled && !item.divider) {
84
+ this.close(item);
85
+ }
86
+ }
87
+ close(result) {
88
+ document.removeEventListener('click', this.boundHandleOutsideClick);
89
+ document.removeEventListener('contextmenu', this.boundHandleOutsideClick);
90
+ document.removeEventListener('keydown', this.boundHandleKeyDown);
91
+ if (this.resolvePromise) {
92
+ this.resolvePromise(result);
93
+ this.resolvePromise = null;
94
+ }
95
+ this.remove();
96
+ }
97
+ render() {
98
+ return html `
99
+ <div class="menu">
100
+ ${this.items.map(item => item.divider
101
+ ? html `<div class="menu__divider"></div>`
102
+ : html `
103
+ <button
104
+ class="menu__item"
105
+ ?disabled=${item.disabled}
106
+ @click=${() => this.handleItemClick(item)}
107
+ >
108
+ ${item.icon ? html `<span class="menu__item-icon">${item.icon}</span>` : null}
109
+ ${item.label}
110
+ </button>
111
+ `)}
112
+ </div>
113
+ `;
114
+ }
115
+ };
116
+ KRContextMenu.styles = css `
117
+ :host {
118
+ position: fixed;
119
+ z-index: 10000;
120
+ }
121
+
122
+ .menu {
123
+ background: #1a1a2e;
124
+ border: 1px solid rgba(255, 255, 255, 0.1);
125
+ border-radius: 8px;
126
+ padding: 4px;
127
+ min-width: 180px;
128
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
129
+ }
130
+
131
+ .menu__item {
132
+ display: flex;
133
+ align-items: center;
134
+ gap: 12px;
135
+ width: 100%;
136
+ padding: 10px 12px;
137
+ background: none;
138
+ border: none;
139
+ color: rgba(255, 255, 255, 0.8);
140
+ font-size: 13px;
141
+ font-family: inherit;
142
+ text-align: left;
143
+ cursor: pointer;
144
+ border-radius: 6px;
145
+ transition: background 0.15s ease;
146
+ }
147
+
148
+ .menu__item:hover:not(:disabled) {
149
+ background: rgba(255, 255, 255, 0.05);
150
+ color: #ffffff;
151
+ }
152
+
153
+ .menu__item:disabled {
154
+ opacity: 0.5;
155
+ cursor: not-allowed;
156
+ }
157
+
158
+ .menu__item-icon {
159
+ width: 16px;
160
+ height: 16px;
161
+ display: flex;
162
+ align-items: center;
163
+ justify-content: center;
164
+ }
165
+
166
+ .menu__divider {
167
+ height: 1px;
168
+ background: rgba(255, 255, 255, 0.1);
169
+ margin: 4px 0;
170
+ }
171
+ `;
172
+ __decorate([
173
+ state()
174
+ ], KRContextMenu.prototype, "items", void 0);
175
+ KRContextMenu = __decorate([
176
+ customElement('kr-context-menu')
177
+ ], KRContextMenu);
178
+ export { KRContextMenu };
179
+ //# sourceMappingURL=context-menu.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-menu.js","sourceRoot":"","sources":["../../src/context-menu/context-menu.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ import { LitElement } from 'lit';
2
+ export interface DialogConfig<T = unknown> {
3
+ data?: T;
4
+ }
5
+ export declare class DialogRef<R = unknown> {
6
+ private resolvePromise;
7
+ private promise;
8
+ private dialogElement;
9
+ constructor();
10
+ /** @internal */
11
+ setDialogElement(el: KRDialog): void;
12
+ close(result?: R): void;
13
+ afterClosed(): Promise<R | undefined>;
14
+ }
15
+ /**
16
+ * Generic dialog component that renders a Lit component inside a dialog shell.
17
+ *
18
+ * Usage:
19
+ * ```ts
20
+ * // Define your dialog content component
21
+ * class EditItemDialog extends LitElement {
22
+ * // Injected by KRDialog
23
+ * dialogRef: DialogRef<{ label: string }>;
24
+ * data: { label: string };
25
+ *
26
+ * save() {
27
+ * this.dialogRef.close({ label: this.label });
28
+ * }
29
+ * }
30
+ *
31
+ * // Open the dialog
32
+ * const dialogRef = KRDialog.open(EditItemDialog, {
33
+ * data: { label: 'Dashboard' }
34
+ * });
35
+ *
36
+ * const result = await dialogRef.afterClosed();
37
+ * if (result) {
38
+ * console.log('Saved:', result.label);
39
+ * }
40
+ * ```
41
+ */
42
+ export declare class KRDialog extends LitElement {
43
+ static styles: import("lit").CSSResult;
44
+ private contentElement;
45
+ private dialogRef;
46
+ private boundHandleKeyDown;
47
+ static open(component: new () => LitElement, config?: DialogConfig): DialogRef;
48
+ private handleKeyDown;
49
+ private handleBackdropClick;
50
+ disconnectedCallback(): void;
51
+ render(): import("lit-html").TemplateResult<1>;
52
+ }
53
+ declare global {
54
+ interface HTMLElementTagNameMap {
55
+ 'kr-dialog': KRDialog;
56
+ }
57
+ }
58
+ //# sourceMappingURL=dialog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dialog.d.ts","sourceRoot":"","sources":["../../src/dialog/dialog.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,MAAM,KAAK,CAAC;AAG5C,MAAM,WAAW,YAAY,CAAC,CAAC,GAAG,OAAO;IACvC,IAAI,CAAC,EAAE,CAAC,CAAC;CACV;AAED,qBAAa,SAAS,CAAC,CAAC,GAAG,OAAO;IAChC,OAAO,CAAC,cAAc,CAAiD;IACvE,OAAO,CAAC,OAAO,CAAyB;IACxC,OAAO,CAAC,aAAa,CAAyB;;IAQ9C,gBAAgB;IAChB,gBAAgB,CAAC,EAAE,EAAE,QAAQ;IAI7B,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;IAQhB,WAAW,IAAI,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;CAGtC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,qBACa,QAAS,SAAQ,UAAU;IACtC,OAAgB,MAAM,0BAyBpB;IAGF,OAAO,CAAC,cAAc,CAA2B;IAEjD,OAAO,CAAC,SAAS,CAA0B;IAC3C,OAAO,CAAC,kBAAkB,CAAiC;IAE3D,MAAM,CAAC,IAAI,CACT,SAAS,EAAE,UAAU,UAAU,EAC/B,MAAM,CAAC,EAAE,YAAY,GACpB,SAAS;IA0BZ,OAAO,CAAC,aAAa;IAMrB,OAAO,CAAC,mBAAmB;IAMlB,oBAAoB;IAKpB,MAAM;CAQhB;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,WAAW,EAAE,QAAQ,CAAC;KACvB;CACF"}