@liwe3/webcomponents 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.
- package/LICENSE +21 -0
- package/README.md +383 -0
- package/dist/AITextEditor.js +477 -0
- package/dist/AITextEditor.js.map +1 -0
- package/dist/SmartSelect.js +452 -0
- package/dist/SmartSelect.js.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/package.json +60 -0
- package/src/AITextEditor.ts +708 -0
- package/src/SmartSelect.ts +775 -0
- package/src/index.ts +26 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 OS3 srl - Fabio Rotondo <fabio.rotondo@gmail.com>
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,383 @@
|
|
|
1
|
+
# @liwe3/webcomponents
|
|
2
|
+
|
|
3
|
+
A collection of reusable, framework-agnostic web components built with TypeScript.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **SmartSelect**: A customizable select dropdown with search, multi-select, and keyboard navigation
|
|
8
|
+
- **AITextEditor**: A text editor with AI-powered text continuation suggestions
|
|
9
|
+
- Framework-agnostic (works with vanilla JS, React, Vue, Svelte, Angular, etc.)
|
|
10
|
+
- TypeScript support with full type definitions
|
|
11
|
+
- Zero dependencies (web components only)
|
|
12
|
+
- Tree-shakeable - import only what you need
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install @liwe3/webcomponents
|
|
18
|
+
# or
|
|
19
|
+
pnpm add @liwe3/webcomponents
|
|
20
|
+
# or
|
|
21
|
+
yarn add @liwe3/webcomponents
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Usage
|
|
25
|
+
|
|
26
|
+
### Import All Components
|
|
27
|
+
|
|
28
|
+
```typescript
|
|
29
|
+
import '@liwe3/webcomponents';
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Import Individual Components
|
|
33
|
+
|
|
34
|
+
```typescript
|
|
35
|
+
// Import only SmartSelect
|
|
36
|
+
import '@liwe3/webcomponents/smart-select';
|
|
37
|
+
|
|
38
|
+
// Import only AITextEditor
|
|
39
|
+
import '@liwe3/webcomponents/ai-text-editor';
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Using with TypeScript
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
import { SmartSelectElement, AITextEditorElement, type SelectOption } from '@liwe3/webcomponents';
|
|
46
|
+
|
|
47
|
+
// Access element instances with proper typing
|
|
48
|
+
const select = document.querySelector('liwe3-select') as SmartSelectElement;
|
|
49
|
+
select.setOptions([
|
|
50
|
+
{ value: '1', label: 'Option 1' },
|
|
51
|
+
{ value: '2', label: 'Option 2' }
|
|
52
|
+
]);
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Components
|
|
56
|
+
|
|
57
|
+
### SmartSelect
|
|
58
|
+
|
|
59
|
+
A powerful select dropdown with advanced features.
|
|
60
|
+
|
|
61
|
+
#### Features
|
|
62
|
+
|
|
63
|
+
- Single and multi-select modes
|
|
64
|
+
- Search/filter options
|
|
65
|
+
- Keyboard navigation (Arrow keys, Enter, Escape, Tab)
|
|
66
|
+
- Custom styling via CSS variables
|
|
67
|
+
- Automatic positioning (viewport-aware)
|
|
68
|
+
- Full TypeScript support
|
|
69
|
+
|
|
70
|
+
#### Basic Usage
|
|
71
|
+
|
|
72
|
+
```html
|
|
73
|
+
<liwe3-select
|
|
74
|
+
placeholder="Select an option"
|
|
75
|
+
searchable
|
|
76
|
+
multiple
|
|
77
|
+
></liwe3-select>
|
|
78
|
+
|
|
79
|
+
<script type="module">
|
|
80
|
+
import '@liwe3/webcomponents/smart-select';
|
|
81
|
+
|
|
82
|
+
const select = document.querySelector('liwe3-select');
|
|
83
|
+
|
|
84
|
+
// Set options
|
|
85
|
+
select.options = [
|
|
86
|
+
{ value: 'js', label: 'JavaScript' },
|
|
87
|
+
{ value: 'ts', label: 'TypeScript' },
|
|
88
|
+
{ value: 'py', label: 'Python' }
|
|
89
|
+
];
|
|
90
|
+
|
|
91
|
+
// Listen for changes
|
|
92
|
+
select.addEventListener('change', (e) => {
|
|
93
|
+
console.log('Selected:', e.detail.value);
|
|
94
|
+
});
|
|
95
|
+
</script>
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
#### Attributes
|
|
99
|
+
|
|
100
|
+
- `multiple` - Enable multi-select mode
|
|
101
|
+
- `searchable` - Enable search/filter functionality
|
|
102
|
+
- `placeholder` - Placeholder text (default: "Select an option")
|
|
103
|
+
- `disabled` - Disable the select
|
|
104
|
+
|
|
105
|
+
#### Properties
|
|
106
|
+
|
|
107
|
+
```typescript
|
|
108
|
+
// Get/set value
|
|
109
|
+
select.value; // string | string[]
|
|
110
|
+
select.value = 'js'; // Set single value
|
|
111
|
+
select.value = ['js', 'ts']; // Set multiple values (when multiple=true)
|
|
112
|
+
|
|
113
|
+
// Get/set options
|
|
114
|
+
select.options; // SelectOption[]
|
|
115
|
+
select.setOptions([...]);
|
|
116
|
+
|
|
117
|
+
// Control dropdown
|
|
118
|
+
select.open();
|
|
119
|
+
select.close();
|
|
120
|
+
select.toggle();
|
|
121
|
+
|
|
122
|
+
// Select/deselect options
|
|
123
|
+
select.selectOption('js');
|
|
124
|
+
select.deselectOption('js');
|
|
125
|
+
select.getSelectedOptions(); // SelectOption[]
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
#### Events
|
|
129
|
+
|
|
130
|
+
- `change` - Fired when selection changes (detail: { value })
|
|
131
|
+
- `open` - Fired when dropdown opens
|
|
132
|
+
- `close` - Fired when dropdown closes
|
|
133
|
+
- `search` - Fired when search query changes (detail: { query })
|
|
134
|
+
|
|
135
|
+
#### CSS Variables
|
|
136
|
+
|
|
137
|
+
```css
|
|
138
|
+
liwe3-select {
|
|
139
|
+
--font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
140
|
+
--font-size: 14px;
|
|
141
|
+
--padding: 8px 12px;
|
|
142
|
+
--border: 1px solid #ccc;
|
|
143
|
+
--border-radius: 4px;
|
|
144
|
+
--background: white;
|
|
145
|
+
--focus-color: #007bff;
|
|
146
|
+
|
|
147
|
+
/* Tag styles (multi-select) */
|
|
148
|
+
--tag-background: #e9ecef;
|
|
149
|
+
--tag-border-radius: 12px;
|
|
150
|
+
--tag-color: #495057;
|
|
151
|
+
--remove-color: #6c757d;
|
|
152
|
+
--remove-hover-color: #dc3545;
|
|
153
|
+
|
|
154
|
+
/* Dropdown styles */
|
|
155
|
+
--dropdown-background: white;
|
|
156
|
+
--dropdown-border: 1px solid #ccc;
|
|
157
|
+
--dropdown-border-radius: 4px;
|
|
158
|
+
--dropdown-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
159
|
+
|
|
160
|
+
/* Option styles */
|
|
161
|
+
--option-color: #333;
|
|
162
|
+
--option-hover-background: #f8f9fa;
|
|
163
|
+
--option-focused-background: #007bff;
|
|
164
|
+
--option-focused-color: white;
|
|
165
|
+
--option-selected-background: #e3f2fd;
|
|
166
|
+
--option-selected-color: #1976d2;
|
|
167
|
+
--no-options-color: #6c757d;
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### AITextEditor
|
|
172
|
+
|
|
173
|
+
A text editor with AI-powered suggestions.
|
|
174
|
+
|
|
175
|
+
#### Features
|
|
176
|
+
|
|
177
|
+
- AI-powered text continuation
|
|
178
|
+
- Configurable AI endpoint (OpenAI, LM Studio, etc.)
|
|
179
|
+
- Tab to accept suggestions
|
|
180
|
+
- Escape to dismiss
|
|
181
|
+
- Paragraph-by-paragraph acceptance
|
|
182
|
+
- localStorage API key management
|
|
183
|
+
- Custom system prompts
|
|
184
|
+
- Context support for better suggestions
|
|
185
|
+
|
|
186
|
+
#### Basic Usage
|
|
187
|
+
|
|
188
|
+
```html
|
|
189
|
+
<liwe3-ai-text-editor style="width: 100%; height: 400px;"></liwe3-ai-text-editor>
|
|
190
|
+
|
|
191
|
+
<script type="module">
|
|
192
|
+
import '@liwe3/webcomponents/ai-text-editor';
|
|
193
|
+
|
|
194
|
+
const editor = document.querySelector('liwe3-ai-text-editor');
|
|
195
|
+
|
|
196
|
+
// Configure API
|
|
197
|
+
editor.setApiKey('your-api-key');
|
|
198
|
+
editor.setApiEndpoint('https://api.openai.com/v1/chat/completions');
|
|
199
|
+
editor.setModelName('gpt-3.5-turbo');
|
|
200
|
+
|
|
201
|
+
// Set initial text
|
|
202
|
+
editor.setText('Once upon a time...');
|
|
203
|
+
|
|
204
|
+
// Listen for changes
|
|
205
|
+
editor.addEventListener('change', (e) => {
|
|
206
|
+
console.log('Text:', e.detail.value);
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
// Handle before suggestion (optional - can cancel)
|
|
210
|
+
editor.addEventListener('beforeSuggestion', (e) => {
|
|
211
|
+
// Cancel suggestion if needed
|
|
212
|
+
if (someCondition) {
|
|
213
|
+
e.preventDefault();
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
</script>
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
#### Properties & Methods
|
|
220
|
+
|
|
221
|
+
```typescript
|
|
222
|
+
// Text content
|
|
223
|
+
editor.setText(text: string): void;
|
|
224
|
+
editor.getText(): string;
|
|
225
|
+
|
|
226
|
+
// API configuration
|
|
227
|
+
editor.setApiKey(key: string): void;
|
|
228
|
+
editor.getApiKey(): string;
|
|
229
|
+
editor.setApiEndpoint(endpoint: string): void;
|
|
230
|
+
editor.getApiEndpoint(): string;
|
|
231
|
+
editor.setModelName(modelName: string): void;
|
|
232
|
+
editor.getModelName(): string;
|
|
233
|
+
|
|
234
|
+
// Suggestion settings
|
|
235
|
+
editor.setSuggestionDelay(seconds: number): void; // Default: 1 second
|
|
236
|
+
editor.getSuggestionDelay(): number;
|
|
237
|
+
editor.setSystemPrompt(prompt: string): void;
|
|
238
|
+
editor.getSystemPrompt(): string;
|
|
239
|
+
|
|
240
|
+
// Context for better suggestions
|
|
241
|
+
editor.setContext(context: string): void;
|
|
242
|
+
editor.getContext(): string;
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
#### Events
|
|
246
|
+
|
|
247
|
+
- `change` - Fired when text changes (detail: { value })
|
|
248
|
+
- `beforeSuggestion` - Fired before requesting AI suggestion (cancelable)
|
|
249
|
+
- detail: { text, context, apiEndpoint, modelName, systemPrompt }
|
|
250
|
+
- `error` - Fired when an error occurs (detail: { message })
|
|
251
|
+
|
|
252
|
+
#### Keyboard Shortcuts
|
|
253
|
+
|
|
254
|
+
- `Tab` - Accept current suggestion paragraph
|
|
255
|
+
- `Escape` - Dismiss suggestion
|
|
256
|
+
- Arrow keys/Click - Dismiss suggestion and move cursor
|
|
257
|
+
|
|
258
|
+
#### Using with Local LM Studio
|
|
259
|
+
|
|
260
|
+
```javascript
|
|
261
|
+
editor.setApiEndpoint('http://localhost:1234/v1/chat/completions');
|
|
262
|
+
editor.setModelName('local-model');
|
|
263
|
+
editor.setApiKey(''); // No API key needed for local
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
## Custom Tag Names
|
|
267
|
+
|
|
268
|
+
You can register components with custom tag names:
|
|
269
|
+
|
|
270
|
+
```typescript
|
|
271
|
+
import { defineSmartSelect, defineAITextEditor } from '@liwe3/webcomponents';
|
|
272
|
+
|
|
273
|
+
defineSmartSelect('my-select');
|
|
274
|
+
defineAITextEditor('my-editor');
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
```html
|
|
278
|
+
<my-select></my-select>
|
|
279
|
+
<my-editor></my-editor>
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
## Framework Integration
|
|
283
|
+
|
|
284
|
+
### React
|
|
285
|
+
|
|
286
|
+
```tsx
|
|
287
|
+
import '@liwe3/webcomponents';
|
|
288
|
+
import { useRef, useEffect } from 'react';
|
|
289
|
+
import type { SmartSelectElement } from '@liwe3/webcomponents';
|
|
290
|
+
|
|
291
|
+
function MyComponent() {
|
|
292
|
+
const selectRef = useRef<SmartSelectElement>(null);
|
|
293
|
+
|
|
294
|
+
useEffect(() => {
|
|
295
|
+
if (selectRef.current) {
|
|
296
|
+
selectRef.current.setOptions([
|
|
297
|
+
{ value: '1', label: 'Option 1' },
|
|
298
|
+
{ value: '2', label: 'Option 2' }
|
|
299
|
+
]);
|
|
300
|
+
}
|
|
301
|
+
}, []);
|
|
302
|
+
|
|
303
|
+
return <liwe3-select ref={selectRef} />;
|
|
304
|
+
}
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
### Vue
|
|
308
|
+
|
|
309
|
+
```vue
|
|
310
|
+
<template>
|
|
311
|
+
<liwe3-select ref="select" @change="handleChange" />
|
|
312
|
+
</template>
|
|
313
|
+
|
|
314
|
+
<script setup>
|
|
315
|
+
import '@liwe3/webcomponents';
|
|
316
|
+
import { ref, onMounted } from 'vue';
|
|
317
|
+
|
|
318
|
+
const select = ref(null);
|
|
319
|
+
|
|
320
|
+
onMounted(() => {
|
|
321
|
+
select.value.setOptions([
|
|
322
|
+
{ value: '1', label: 'Option 1' },
|
|
323
|
+
{ value: '2', label: 'Option 2' }
|
|
324
|
+
]);
|
|
325
|
+
});
|
|
326
|
+
|
|
327
|
+
const handleChange = (e) => {
|
|
328
|
+
console.log('Selected:', e.detail.value);
|
|
329
|
+
};
|
|
330
|
+
</script>
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
### Svelte
|
|
334
|
+
|
|
335
|
+
```svelte
|
|
336
|
+
<script>
|
|
337
|
+
import '@liwe3/webcomponents';
|
|
338
|
+
import { onMount } from 'svelte';
|
|
339
|
+
|
|
340
|
+
let selectElement;
|
|
341
|
+
|
|
342
|
+
onMount(() => {
|
|
343
|
+
selectElement.setOptions([
|
|
344
|
+
{ value: '1', label: 'Option 1' },
|
|
345
|
+
{ value: '2', label: 'Option 2' }
|
|
346
|
+
]);
|
|
347
|
+
});
|
|
348
|
+
|
|
349
|
+
const handleChange = (e) => {
|
|
350
|
+
console.log('Selected:', e.detail.value);
|
|
351
|
+
};
|
|
352
|
+
</script>
|
|
353
|
+
|
|
354
|
+
<liwe3-select bind:this={selectElement} on:change={handleChange} />
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
## Browser Support
|
|
358
|
+
|
|
359
|
+
Modern browsers with Web Components support:
|
|
360
|
+
- Chrome/Edge 67+
|
|
361
|
+
- Firefox 63+
|
|
362
|
+
- Safari 10.1+
|
|
363
|
+
|
|
364
|
+
## Development
|
|
365
|
+
|
|
366
|
+
```bash
|
|
367
|
+
# Install dependencies
|
|
368
|
+
pnpm install
|
|
369
|
+
|
|
370
|
+
# Build
|
|
371
|
+
pnpm run build
|
|
372
|
+
|
|
373
|
+
# Build in watch mode
|
|
374
|
+
pnpm run dev
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
## License
|
|
378
|
+
|
|
379
|
+
MIT
|
|
380
|
+
|
|
381
|
+
## Contributing
|
|
382
|
+
|
|
383
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|