@ticatec/uniface-element 0.2.3 → 0.3.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/dist/accordion/README.md +169 -0
- package/dist/accordion/README_CN.md +176 -0
- package/dist/action-bar/README.md +275 -0
- package/dist/action-bar/README_CN.md +285 -0
- package/dist/app-layout/README.md +374 -0
- package/dist/app-layout/README_CN.md +381 -0
- package/dist/app-top-bar/README.md +357 -0
- package/dist/app-top-bar/README_CN.md +365 -0
- package/dist/attachment-files/AttachmentFilesField.svelte +67 -1
- package/dist/attachment-files/AttachmentFilesField.svelte.d.ts +8 -1
- package/dist/base-calendar/CalendarBase.svelte +0 -3
- package/dist/box/README.md +385 -0
- package/dist/box/README_CN.md +393 -0
- package/dist/breadcrumbs/README.md +442 -0
- package/dist/breadcrumbs/README_CN.md +442 -0
- package/dist/button/Button.svelte +27 -7
- package/dist/button/Button.svelte.d.ts +3 -1
- package/dist/button/IconButton.svelte +26 -6
- package/dist/button/IconButton.svelte.d.ts +3 -1
- package/dist/button/IconButton_README.md +513 -0
- package/dist/button/IconButton_README_CN.md +513 -0
- package/dist/button/README.md +428 -0
- package/dist/button/README_CN.md +428 -0
- package/dist/button/TextButton.svelte +26 -6
- package/dist/button/TextButton.svelte.d.ts +3 -1
- package/dist/button/TextButton_README.md +571 -0
- package/dist/button/TextButton_README_CN.md +571 -0
- package/dist/card/README.md +666 -0
- package/dist/card/README_CN.md +666 -0
- package/dist/cascade-options-select/CascadeOptionSelect.svelte +43 -7
- package/dist/cascade-options-select/CascadeOptionSelect.svelte.d.ts +3 -4
- package/dist/cascade-options-select/README.md +663 -2
- package/dist/cascade-options-select/README_CN.md +664 -0
- package/dist/checkbox/CheckBox.svelte +20 -6
- package/dist/checkbox/CheckBox.svelte.d.ts +4 -2
- package/dist/checkbox/README.md +562 -0
- package/dist/checkbox/README_CN.md +727 -0
- package/dist/common-editor/NumberInput.svelte +39 -26
- package/dist/common-editor/NumberInput.svelte.d.ts +5 -1
- package/dist/concise-data-table/ConciseListTable.svelte +133 -36
- package/dist/concise-data-table/ConciseListTable.svelte.d.ts +8 -1
- package/dist/concise-data-table/DataCell.svelte +5 -6
- package/dist/concise-data-table/DataRow.svelte +22 -2
- package/dist/concise-data-table/DataRow.svelte.d.ts +1 -0
- package/dist/concise-data-table/README.md +606 -0
- package/dist/concise-data-table/README_CN.md +611 -0
- package/dist/context-menu/ContextMenu.svelte +138 -21
- package/dist/context-menu/ContextMenu.svelte.d.ts +5 -0
- package/dist/context-menu/ContextMenuItem.d.ts +20 -4
- package/dist/context-menu/README.md +551 -0
- package/dist/context-menu/README_CN.md +551 -0
- package/dist/criteria-field/CriteriaField.svelte +3 -5
- package/dist/criteria-field/README.md +532 -0
- package/dist/criteria-field/README_CN.md +532 -0
- package/dist/data-table/README.md +712 -0
- package/dist/data-table/README_CN.md +712 -0
- package/dist/date-picker/DatePicker.svelte +44 -7
- package/dist/date-picker/DatePicker.svelte.d.ts +3 -4
- package/dist/date-picker/DateTimePicker.svelte +32 -8
- package/dist/date-picker/DateTimePicker.svelte.d.ts +3 -4
- package/dist/date-picker/README.md +326 -0
- package/dist/date-picker/README_CN.md +316 -0
- package/dist/date-picker/ScrollBar.svelte +18 -8
- package/dist/date-picker/ScrollBar.svelte.d.ts +1 -1
- package/dist/date-picker/TimePanel.svelte +5 -5
- package/dist/date-picker/TimePanel.svelte.d.ts +1 -1
- package/dist/date-range/README.md +374 -0
- package/dist/date-range/README_CN.md +374 -0
- package/dist/dialog/DialogBoard.svelte +1 -1
- package/dist/dialog/README.md +596 -0
- package/dist/dialog/README_CN.md +596 -0
- package/dist/drawer/README.md +679 -1
- package/dist/drawer/README_CN.md +679 -0
- package/dist/group-box/group-check-box/GroupCheckBox.svelte +62 -5
- package/dist/group-box/group-check-box/GroupCheckBox.svelte.d.ts +7 -2
- package/dist/group-box/group-check-box/README.md +749 -0
- package/dist/group-box/group-check-box/README_CN.md +750 -0
- package/dist/group-box/group-radio-box/GroupRadioBox.svelte +69 -4
- package/dist/group-box/group-radio-box/GroupRadioBox.svelte.d.ts +8 -2
- package/dist/group-box/group-radio-box/README.md +920 -0
- package/dist/group-box/group-radio-box/README_CN.md +920 -0
- package/dist/image-files/README.md +1346 -0
- package/dist/image-files/README_CN.md +1346 -0
- package/dist/input-options-select/InputOptionsSelect.svelte +161 -65
- package/dist/input-options-select/InputOptionsSelect.svelte.d.ts +4 -1
- package/dist/lib/forwardAllEvents.d.ts +3 -0
- package/dist/lib/forwardAllEvents.js +24 -0
- package/dist/list-box/README.md +579 -0
- package/dist/list-box/README_CN.md +682 -0
- package/dist/lookup-editor/LookupEditor.svelte +15 -3
- package/dist/lookup-editor/LookupEditor.svelte.d.ts +3 -4
- package/dist/lookup-editor/README.md +684 -0
- package/dist/lookup-editor/README_CN.md +684 -0
- package/dist/memo-editor/MemoEditor.svelte +77 -27
- package/dist/memo-editor/MemoEditor.svelte.d.ts +6 -3
- package/dist/memo-editor/README.md +819 -0
- package/dist/memo-editor/README_CN.md +819 -0
- package/dist/message-box/README.md +398 -0
- package/dist/message-box/README_CN.md +398 -0
- package/dist/number-editor/NumberEditor.svelte +2 -2
- package/dist/number-editor/NumberEditor.svelte.d.ts +1 -1
- package/dist/number-editor/README.md +353 -22
- package/dist/number-editor/README_CN.md +357 -0
- package/dist/number-range/README.md +443 -0
- package/dist/number-range/README_CN.md +443 -0
- package/dist/options-multi-select/OptionsMultiSelect.svelte +87 -12
- package/dist/options-multi-select/OptionsMultiSelect.svelte.d.ts +3 -1
- package/dist/options-multi-select/README.md +480 -0
- package/dist/options-multi-select/README_CN.md +480 -0
- package/dist/options-select/OptionsSelect.svelte +36 -5
- package/dist/options-select/OptionsSelect.svelte.d.ts +3 -4
- package/dist/options-select/README.md +632 -0
- package/dist/options-select/README_CN.md +632 -0
- package/dist/page/README.md +605 -0
- package/dist/page/README_CN.md +605 -0
- package/dist/pagination/README.md +946 -0
- package/dist/pagination/README_CN.md +946 -0
- package/dist/pagination-panel/README.md +1075 -0
- package/dist/pagination-panel/README_CN.md +1075 -0
- package/dist/popup-hint/README.md +841 -0
- package/dist/popup-hint/README_CN.md +840 -0
- package/dist/progress-bar/README.md +242 -0
- package/dist/progress-bar/README_CN.md +242 -0
- package/dist/progress-step-bar/README.md +316 -0
- package/dist/progress-step-bar/README_CN.md +316 -0
- package/dist/prompts-text-editor/PromptsTextEditor.svelte +6 -3
- package/dist/prompts-text-editor/PromptsTextEditor.svelte.d.ts +3 -1
- package/dist/prompts-text-editor/README.md +329 -0
- package/dist/prompts-text-editor/README_CN.md +329 -0
- package/dist/property-editor/README.md +969 -0
- package/dist/property-editor/README_CN.md +969 -0
- package/dist/radio-button/README.md +372 -0
- package/dist/radio-button/README_CN.md +372 -0
- package/dist/radio-button/RadioButton.svelte +32 -3
- package/dist/radio-button/RadioButton.svelte.d.ts +12 -1
- package/dist/search-box/README.md +425 -0
- package/dist/search-box/README_CN.md +424 -0
- package/dist/search-box/SearchBox.svelte +22 -6
- package/dist/search-box/SearchBox.svelte.d.ts +4 -1
- package/dist/tabs/README.md +919 -0
- package/dist/tabs/README_CN.md +920 -0
- package/dist/tag/README.md +922 -0
- package/dist/tag/README_CN.md +922 -0
- package/dist/text-editor/PasswordEditor.svelte +17 -2
- package/dist/text-editor/PasswordEditor.svelte.d.ts +3 -3
- package/dist/text-editor/PasswordEditor_README.md +551 -0
- package/dist/text-editor/PasswordEditor_README_CN.md +551 -0
- package/dist/text-editor/README.md +466 -0
- package/dist/text-editor/README_CN.md +466 -0
- package/dist/text-editor/TextEditor.svelte +51 -19
- package/dist/text-editor/TextEditor.svelte.d.ts +0 -1
- package/dist/ticatec-uniface-web.css +1 -0
- package/dist/time-editor/README.md +498 -24
- package/dist/time-editor/README_CN.md +498 -0
- package/dist/time-editor/TimeEditor.svelte +7 -3
- package/dist/time-editor/TimeEditor.svelte.d.ts +3 -1
- package/dist/toast/README.md +667 -0
- package/dist/toast/README_CN.md +667 -0
- package/dist/transfer/README.md +795 -0
- package/dist/transfer/Transfer.svelte +6 -4
- package/dist/transfer/Transfer.svelte.d.ts +3 -1
- package/dist/tree-view/README.md +761 -0
- package/dist/tree-view/README_CN.md +761 -0
- package/dist/tree-view/TreeView.svelte +5 -3
- package/dist/tree-view/TreeView.svelte.d.ts +3 -1
- package/dist/unit-number-editor/README.md +546 -20
- package/dist/unit-number-editor/README_CN.md +525 -0
- package/dist/unit-number-editor/UnitNumberEditor.svelte +62 -8
- package/dist/unit-number-editor/UnitNumberEditor.svelte.d.ts +5 -1
- package/docs/form-field/cn/README_CN.md +364 -0
- package/docs/form-field/en/README.md +364 -0
- package/docs/form-panel/flex-form/cn/README_CN.md +586 -0
- package/docs/form-panel/flex-form/en/README.md +586 -0
- package/docs/form-panel/flex-row-form/cn/README_CN.md +787 -0
- package/docs/form-panel/flex-row-form/en/README.md +787 -0
- package/docs/form-panel/grid-form/en/README.md +744 -0
- package/package.json +1 -1
- package/dist/drawer/README-CN.md +0 -1
|
@@ -0,0 +1,819 @@
|
|
|
1
|
+
# MemoEditor
|
|
2
|
+
|
|
3
|
+
A multi-line text area component with advanced features including character counting, resizing options, and multiple display modes.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Multi-line Text Input**: Rich textarea with configurable rows and text wrapping
|
|
8
|
+
- **Character Counter**: Optional character count indicator with maximum length validation
|
|
9
|
+
- **Resize Options**: Configurable resize behavior (none, horizontal, vertical, both)
|
|
10
|
+
- **Multiple Variants**: Support for plain, outlined, and filled styles
|
|
11
|
+
- **Display Modes**: Edit and view modes with proper HTML formatting
|
|
12
|
+
- **Auto-resize Handling**: Automatic width calculation and resize observation
|
|
13
|
+
- **Clear Button**: Optional clear functionality for easy text removal
|
|
14
|
+
- **Form Integration**: Works seamlessly with forms and validation
|
|
15
|
+
- **Event Forwarding**: Comprehensive event handling and forwarding
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install @ticatec/uniface-element
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Usage
|
|
24
|
+
|
|
25
|
+
### Basic Usage
|
|
26
|
+
|
|
27
|
+
```svelte
|
|
28
|
+
<script>
|
|
29
|
+
import MemoEditor from '@ticatec/uniface-element/memo-editor';
|
|
30
|
+
|
|
31
|
+
let description = '';
|
|
32
|
+
</script>
|
|
33
|
+
|
|
34
|
+
<MemoEditor
|
|
35
|
+
bind:value={description}
|
|
36
|
+
placeholder="Enter your description here..."
|
|
37
|
+
variant="outlined"
|
|
38
|
+
input$rows={4}
|
|
39
|
+
/>
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### With Character Counter
|
|
43
|
+
|
|
44
|
+
```svelte
|
|
45
|
+
<script>
|
|
46
|
+
import MemoEditor from '@ticatec/uniface-element/memo-editor';
|
|
47
|
+
|
|
48
|
+
let notes = '';
|
|
49
|
+
</script>
|
|
50
|
+
|
|
51
|
+
<MemoEditor
|
|
52
|
+
bind:value={notes}
|
|
53
|
+
variant="filled"
|
|
54
|
+
input$rows={5}
|
|
55
|
+
maxLength={500}
|
|
56
|
+
showIndicator
|
|
57
|
+
placeholder="Enter notes (max 500 characters)"
|
|
58
|
+
/>
|
|
59
|
+
|
|
60
|
+
<p>Current length: {notes.length}</p>
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Resizable Editor
|
|
64
|
+
|
|
65
|
+
```svelte
|
|
66
|
+
<script>
|
|
67
|
+
import MemoEditor from '@ticatec/uniface-element/memo-editor';
|
|
68
|
+
|
|
69
|
+
let content = '';
|
|
70
|
+
</script>
|
|
71
|
+
|
|
72
|
+
<MemoEditor
|
|
73
|
+
bind:value={content}
|
|
74
|
+
variant="outlined"
|
|
75
|
+
input$rows={6}
|
|
76
|
+
resize="both"
|
|
77
|
+
placeholder="This editor can be resized in both directions"
|
|
78
|
+
/>
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Read-only and View Modes
|
|
82
|
+
|
|
83
|
+
```svelte
|
|
84
|
+
<script>
|
|
85
|
+
import MemoEditor from '@ticatec/uniface-element/memo-editor';
|
|
86
|
+
import { DisplayMode } from '@ticatec/uniface-element';
|
|
87
|
+
|
|
88
|
+
let text = 'This is some sample text\nwith multiple lines\nfor demonstration.';
|
|
89
|
+
</script>
|
|
90
|
+
|
|
91
|
+
<!-- Read-only mode -->
|
|
92
|
+
<MemoEditor
|
|
93
|
+
value={text}
|
|
94
|
+
readonly
|
|
95
|
+
variant="outlined"
|
|
96
|
+
input$rows={4}
|
|
97
|
+
/>
|
|
98
|
+
|
|
99
|
+
<!-- View mode (displays as formatted HTML) -->
|
|
100
|
+
<MemoEditor
|
|
101
|
+
value={text}
|
|
102
|
+
displayMode={DisplayMode.View}
|
|
103
|
+
/>
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## API Reference
|
|
107
|
+
|
|
108
|
+
### Props
|
|
109
|
+
|
|
110
|
+
| Prop | Type | Default | Description |
|
|
111
|
+
|------|------|---------|-------------|
|
|
112
|
+
| `value` | `string` | `''` | The text content of the editor |
|
|
113
|
+
| `variant` | `'' \| 'plain' \| 'outlined' \| 'filled'` | `''` | Visual style variant |
|
|
114
|
+
| `disabled` | `boolean` | `false` | Whether the editor is disabled |
|
|
115
|
+
| `readonly` | `boolean` | `false` | Whether the editor is read-only |
|
|
116
|
+
| `style` | `string` | `''` | Custom CSS styles |
|
|
117
|
+
| `class` | `string` | `''` | Additional CSS classes |
|
|
118
|
+
| `wrap` | `'hard' \| 'soft'` | `'hard'` | Text wrapping behavior |
|
|
119
|
+
| `resize` | `'none' \| 'horizontal' \| 'vertical' \| 'both'` | `'none'` | Resize handle behavior |
|
|
120
|
+
| `displayMode` | `DisplayMode` | `DisplayMode.Edit` | Display mode (edit or view) |
|
|
121
|
+
| `input$rows` | `number` | `3` | Number of visible text lines |
|
|
122
|
+
| `showIndicator` | `boolean` | `false` | Whether to show character count indicator |
|
|
123
|
+
| `maxLength` | `number \| null` | `null` | Maximum number of characters allowed |
|
|
124
|
+
|
|
125
|
+
### Input Props
|
|
126
|
+
|
|
127
|
+
All props prefixed with `input$` are forwarded to the underlying textarea element:
|
|
128
|
+
|
|
129
|
+
| Prop | Type | Description |
|
|
130
|
+
|------|------|-------------|
|
|
131
|
+
| `input$placeholder` | `string` | Placeholder text |
|
|
132
|
+
| `input$maxLength` | `number` | Maximum character length |
|
|
133
|
+
| `input$minLength` | `number` | Minimum character length |
|
|
134
|
+
| `input$required` | `boolean` | Whether the field is required |
|
|
135
|
+
| `input$autofocus` | `boolean` | Whether to auto-focus on mount |
|
|
136
|
+
| `input$spellcheck` | `boolean` | Enable/disable spell checking |
|
|
137
|
+
| `input$autocomplete` | `string` | Autocomplete behavior |
|
|
138
|
+
|
|
139
|
+
### Events
|
|
140
|
+
|
|
141
|
+
The component forwards all standard textarea events:
|
|
142
|
+
|
|
143
|
+
- `on:input` - Text input events
|
|
144
|
+
- `on:change` - Value change events
|
|
145
|
+
- `on:focus` - Focus events
|
|
146
|
+
- `on:blur` - Blur events
|
|
147
|
+
- `on:keydown` - Keyboard events
|
|
148
|
+
- `on:keyup` - Keyboard events
|
|
149
|
+
- `on:keypress` - Keyboard events
|
|
150
|
+
- `on:compositionstart` - IME composition events
|
|
151
|
+
- `on:compositionend` - IME composition events
|
|
152
|
+
- `on:compositionupdate` - IME composition events
|
|
153
|
+
|
|
154
|
+
## Examples
|
|
155
|
+
|
|
156
|
+
### Comment Editor
|
|
157
|
+
|
|
158
|
+
```svelte
|
|
159
|
+
<script>
|
|
160
|
+
import MemoEditor from '@ticatec/uniface-element/memo-editor';
|
|
161
|
+
import FormField from '@ticatec/uniface-element/form-field';
|
|
162
|
+
|
|
163
|
+
let comment = '';
|
|
164
|
+
let errors = {};
|
|
165
|
+
|
|
166
|
+
function validateComment() {
|
|
167
|
+
if (!comment.trim()) {
|
|
168
|
+
errors.comment = 'Comment is required';
|
|
169
|
+
return false;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
if (comment.length < 10) {
|
|
173
|
+
errors.comment = 'Comment must be at least 10 characters';
|
|
174
|
+
return false;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
errors.comment = null;
|
|
178
|
+
return true;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
function handleSubmit() {
|
|
182
|
+
if (validateComment()) {
|
|
183
|
+
console.log('Comment submitted:', comment);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
</script>
|
|
187
|
+
|
|
188
|
+
<FormField label="Comment" required error={errors.comment}>
|
|
189
|
+
<MemoEditor
|
|
190
|
+
bind:value={comment}
|
|
191
|
+
variant="outlined"
|
|
192
|
+
input$rows={4}
|
|
193
|
+
maxLength={1000}
|
|
194
|
+
showIndicator
|
|
195
|
+
input$placeholder="Enter your comment here..."
|
|
196
|
+
on:blur={validateComment}
|
|
197
|
+
/>
|
|
198
|
+
</FormField>
|
|
199
|
+
|
|
200
|
+
<button on:click={handleSubmit} disabled={!comment.trim()}>
|
|
201
|
+
Submit Comment
|
|
202
|
+
</button>
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### Article Editor
|
|
206
|
+
|
|
207
|
+
```svelte
|
|
208
|
+
<script>
|
|
209
|
+
import MemoEditor from '@ticatec/uniface-element/memo-editor';
|
|
210
|
+
|
|
211
|
+
let article = {
|
|
212
|
+
title: '',
|
|
213
|
+
content: '',
|
|
214
|
+
summary: ''
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
let wordCount = 0;
|
|
218
|
+
|
|
219
|
+
$: wordCount = article.content.split(/\s+/).filter(word => word.length > 0).length;
|
|
220
|
+
</script>
|
|
221
|
+
|
|
222
|
+
<div class="article-editor">
|
|
223
|
+
<h2>Article Editor</h2>
|
|
224
|
+
|
|
225
|
+
<div class="field-group">
|
|
226
|
+
<label>Title</label>
|
|
227
|
+
<input
|
|
228
|
+
bind:value={article.title}
|
|
229
|
+
placeholder="Enter article title"
|
|
230
|
+
maxlength="100"
|
|
231
|
+
/>
|
|
232
|
+
</div>
|
|
233
|
+
|
|
234
|
+
<div class="field-group">
|
|
235
|
+
<label>Summary</label>
|
|
236
|
+
<MemoEditor
|
|
237
|
+
bind:value={article.summary}
|
|
238
|
+
variant="filled"
|
|
239
|
+
input$rows={3}
|
|
240
|
+
maxLength={300}
|
|
241
|
+
showIndicator
|
|
242
|
+
input$placeholder="Brief summary of the article..."
|
|
243
|
+
/>
|
|
244
|
+
</div>
|
|
245
|
+
|
|
246
|
+
<div class="field-group">
|
|
247
|
+
<label>Content</label>
|
|
248
|
+
<MemoEditor
|
|
249
|
+
bind:value={article.content}
|
|
250
|
+
variant="outlined"
|
|
251
|
+
input$rows={15}
|
|
252
|
+
resize="vertical"
|
|
253
|
+
input$placeholder="Write your article content here..."
|
|
254
|
+
/>
|
|
255
|
+
<div class="word-count">
|
|
256
|
+
Words: {wordCount}
|
|
257
|
+
</div>
|
|
258
|
+
</div>
|
|
259
|
+
</div>
|
|
260
|
+
|
|
261
|
+
<style>
|
|
262
|
+
.article-editor {
|
|
263
|
+
max-width: 800px;
|
|
264
|
+
margin: 0 auto;
|
|
265
|
+
padding: 2rem;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
.field-group {
|
|
269
|
+
margin-bottom: 1.5rem;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
.field-group label {
|
|
273
|
+
display: block;
|
|
274
|
+
margin-bottom: 0.5rem;
|
|
275
|
+
font-weight: 600;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
.field-group input {
|
|
279
|
+
width: 100%;
|
|
280
|
+
padding: 0.75rem;
|
|
281
|
+
border: 1px solid #d1d5db;
|
|
282
|
+
border-radius: 0.375rem;
|
|
283
|
+
font-size: 1rem;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
.word-count {
|
|
287
|
+
text-align: right;
|
|
288
|
+
font-size: 0.875rem;
|
|
289
|
+
color: #6b7280;
|
|
290
|
+
margin-top: 0.25rem;
|
|
291
|
+
}
|
|
292
|
+
</style>
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
### Feedback Form
|
|
296
|
+
|
|
297
|
+
```svelte
|
|
298
|
+
<script>
|
|
299
|
+
import MemoEditor from '@ticatec/uniface-element/memo-editor';
|
|
300
|
+
import FormField from '@ticatec/uniface-element/form-field';
|
|
301
|
+
|
|
302
|
+
let feedback = {
|
|
303
|
+
category: '',
|
|
304
|
+
description: '',
|
|
305
|
+
suggestions: ''
|
|
306
|
+
};
|
|
307
|
+
|
|
308
|
+
let isSubmitting = false;
|
|
309
|
+
|
|
310
|
+
async function submitFeedback() {
|
|
311
|
+
isSubmitting = true;
|
|
312
|
+
|
|
313
|
+
try {
|
|
314
|
+
// Simulate API call
|
|
315
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
316
|
+
|
|
317
|
+
console.log('Feedback submitted:', feedback);
|
|
318
|
+
|
|
319
|
+
// Reset form
|
|
320
|
+
feedback = { category: '', description: '', suggestions: '' };
|
|
321
|
+
alert('Thank you for your feedback!');
|
|
322
|
+
} catch (error) {
|
|
323
|
+
console.error('Failed to submit feedback:', error);
|
|
324
|
+
alert('Failed to submit feedback. Please try again.');
|
|
325
|
+
} finally {
|
|
326
|
+
isSubmitting = false;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
</script>
|
|
330
|
+
|
|
331
|
+
<form on:submit|preventDefault={submitFeedback}>
|
|
332
|
+
<h2>Feedback Form</h2>
|
|
333
|
+
|
|
334
|
+
<FormField label="Category" required>
|
|
335
|
+
<select bind:value={feedback.category} required>
|
|
336
|
+
<option value="">Select a category</option>
|
|
337
|
+
<option value="bug">Bug Report</option>
|
|
338
|
+
<option value="feature">Feature Request</option>
|
|
339
|
+
<option value="general">General Feedback</option>
|
|
340
|
+
</select>
|
|
341
|
+
</FormField>
|
|
342
|
+
|
|
343
|
+
<FormField label="Description" required>
|
|
344
|
+
<MemoEditor
|
|
345
|
+
bind:value={feedback.description}
|
|
346
|
+
variant="outlined"
|
|
347
|
+
input$rows={5}
|
|
348
|
+
maxLength={1000}
|
|
349
|
+
showIndicator
|
|
350
|
+
input$placeholder="Please describe your feedback in detail..."
|
|
351
|
+
input$required
|
|
352
|
+
/>
|
|
353
|
+
</FormField>
|
|
354
|
+
|
|
355
|
+
<FormField label="Suggestions">
|
|
356
|
+
<MemoEditor
|
|
357
|
+
bind:value={feedback.suggestions}
|
|
358
|
+
variant="filled"
|
|
359
|
+
input$rows={3}
|
|
360
|
+
maxLength={500}
|
|
361
|
+
showIndicator
|
|
362
|
+
input$placeholder="Any suggestions for improvement? (optional)"
|
|
363
|
+
/>
|
|
364
|
+
</FormField>
|
|
365
|
+
|
|
366
|
+
<div class="form-actions">
|
|
367
|
+
<button
|
|
368
|
+
type="submit"
|
|
369
|
+
disabled={isSubmitting || !feedback.category || !feedback.description}
|
|
370
|
+
>
|
|
371
|
+
{isSubmitting ? 'Submitting...' : 'Submit Feedback'}
|
|
372
|
+
</button>
|
|
373
|
+
</div>
|
|
374
|
+
</form>
|
|
375
|
+
|
|
376
|
+
<style>
|
|
377
|
+
form {
|
|
378
|
+
max-width: 600px;
|
|
379
|
+
margin: 0 auto;
|
|
380
|
+
padding: 2rem;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
h2 {
|
|
384
|
+
margin-bottom: 2rem;
|
|
385
|
+
color: #1f2937;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
select {
|
|
389
|
+
width: 100%;
|
|
390
|
+
padding: 0.75rem;
|
|
391
|
+
border: 1px solid #d1d5db;
|
|
392
|
+
border-radius: 0.375rem;
|
|
393
|
+
font-size: 1rem;
|
|
394
|
+
background: white;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
.form-actions {
|
|
398
|
+
margin-top: 2rem;
|
|
399
|
+
text-align: right;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
button {
|
|
403
|
+
padding: 0.75rem 2rem;
|
|
404
|
+
background: #3b82f6;
|
|
405
|
+
color: white;
|
|
406
|
+
border: none;
|
|
407
|
+
border-radius: 0.375rem;
|
|
408
|
+
font-size: 1rem;
|
|
409
|
+
cursor: pointer;
|
|
410
|
+
transition: background-color 0.2s;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
button:hover:not(:disabled) {
|
|
414
|
+
background: #2563eb;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
button:disabled {
|
|
418
|
+
background: #9ca3af;
|
|
419
|
+
cursor: not-allowed;
|
|
420
|
+
}
|
|
421
|
+
</style>
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
### Chat Message Editor
|
|
425
|
+
|
|
426
|
+
```svelte
|
|
427
|
+
<script>
|
|
428
|
+
import MemoEditor from '@ticatec/uniface-element/memo-editor';
|
|
429
|
+
|
|
430
|
+
let message = '';
|
|
431
|
+
let messages = [];
|
|
432
|
+
|
|
433
|
+
function sendMessage() {
|
|
434
|
+
if (message.trim()) {
|
|
435
|
+
messages = [...messages, {
|
|
436
|
+
id: Date.now(),
|
|
437
|
+
text: message,
|
|
438
|
+
timestamp: new Date().toLocaleTimeString()
|
|
439
|
+
}];
|
|
440
|
+
message = '';
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
function handleKeydown(event) {
|
|
445
|
+
if (event.key === 'Enter' && (event.ctrlKey || event.metaKey)) {
|
|
446
|
+
event.preventDefault();
|
|
447
|
+
sendMessage();
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
</script>
|
|
451
|
+
|
|
452
|
+
<div class="chat-container">
|
|
453
|
+
<div class="messages">
|
|
454
|
+
{#each messages as msg}
|
|
455
|
+
<div class="message">
|
|
456
|
+
<div class="message-text">{msg.text}</div>
|
|
457
|
+
<div class="message-time">{msg.timestamp}</div>
|
|
458
|
+
</div>
|
|
459
|
+
{/each}
|
|
460
|
+
</div>
|
|
461
|
+
|
|
462
|
+
<div class="message-input">
|
|
463
|
+
<MemoEditor
|
|
464
|
+
bind:value={message}
|
|
465
|
+
variant="outlined"
|
|
466
|
+
input$rows={3}
|
|
467
|
+
maxLength={500}
|
|
468
|
+
showIndicator
|
|
469
|
+
input$placeholder="Type your message... (Ctrl+Enter to send)"
|
|
470
|
+
on:keydown={handleKeydown}
|
|
471
|
+
/>
|
|
472
|
+
|
|
473
|
+
<div class="input-actions">
|
|
474
|
+
<button
|
|
475
|
+
on:click={sendMessage}
|
|
476
|
+
disabled={!message.trim()}
|
|
477
|
+
>
|
|
478
|
+
Send
|
|
479
|
+
</button>
|
|
480
|
+
</div>
|
|
481
|
+
</div>
|
|
482
|
+
</div>
|
|
483
|
+
|
|
484
|
+
<style>
|
|
485
|
+
.chat-container {
|
|
486
|
+
max-width: 500px;
|
|
487
|
+
margin: 0 auto;
|
|
488
|
+
border: 1px solid #e5e7eb;
|
|
489
|
+
border-radius: 0.5rem;
|
|
490
|
+
overflow: hidden;
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
.messages {
|
|
494
|
+
height: 300px;
|
|
495
|
+
overflow-y: auto;
|
|
496
|
+
padding: 1rem;
|
|
497
|
+
background: #f9fafb;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
.message {
|
|
501
|
+
margin-bottom: 1rem;
|
|
502
|
+
padding: 0.75rem;
|
|
503
|
+
background: white;
|
|
504
|
+
border-radius: 0.375rem;
|
|
505
|
+
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
.message-text {
|
|
509
|
+
white-space: pre-wrap;
|
|
510
|
+
margin-bottom: 0.25rem;
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
.message-time {
|
|
514
|
+
font-size: 0.75rem;
|
|
515
|
+
color: #6b7280;
|
|
516
|
+
text-align: right;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
.message-input {
|
|
520
|
+
padding: 1rem;
|
|
521
|
+
background: white;
|
|
522
|
+
border-top: 1px solid #e5e7eb;
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
.input-actions {
|
|
526
|
+
margin-top: 0.5rem;
|
|
527
|
+
text-align: right;
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
button {
|
|
531
|
+
padding: 0.5rem 1rem;
|
|
532
|
+
background: #10b981;
|
|
533
|
+
color: white;
|
|
534
|
+
border: none;
|
|
535
|
+
border-radius: 0.25rem;
|
|
536
|
+
cursor: pointer;
|
|
537
|
+
font-size: 0.875rem;
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
button:hover:not(:disabled) {
|
|
541
|
+
background: #059669;
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
button:disabled {
|
|
545
|
+
background: #d1d5db;
|
|
546
|
+
cursor: not-allowed;
|
|
547
|
+
}
|
|
548
|
+
</style>
|
|
549
|
+
```
|
|
550
|
+
|
|
551
|
+
## Styling
|
|
552
|
+
|
|
553
|
+
### CSS Variables
|
|
554
|
+
|
|
555
|
+
The MemoEditor component uses CSS variables for consistent theming:
|
|
556
|
+
|
|
557
|
+
```css
|
|
558
|
+
:root {
|
|
559
|
+
--uniface-editor-border-color: #d1d5db;
|
|
560
|
+
--uniface-editor-focus-border-color: #3b82f6;
|
|
561
|
+
--uniface-editor-background: white;
|
|
562
|
+
--uniface-editor-text-color: #374151;
|
|
563
|
+
--uniface-editor-placeholder-color: #9ca3af;
|
|
564
|
+
--uniface-editor-indicator-color: #6b7280;
|
|
565
|
+
--uniface-editor-indicator-background: rgba(255, 255, 255, 0.9);
|
|
566
|
+
}
|
|
567
|
+
```
|
|
568
|
+
|
|
569
|
+
### Custom Styling
|
|
570
|
+
|
|
571
|
+
```css
|
|
572
|
+
.custom-memo-editor {
|
|
573
|
+
--uniface-editor-border-color: #e2e8f0;
|
|
574
|
+
--uniface-editor-focus-border-color: #2563eb;
|
|
575
|
+
--uniface-editor-background: #f8fafc;
|
|
576
|
+
border-radius: 8px;
|
|
577
|
+
font-family: 'Monaco', 'Menlo', monospace;
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
.custom-memo-editor textarea {
|
|
581
|
+
line-height: 1.6;
|
|
582
|
+
font-size: 14px;
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
.custom-memo-editor .uniface-memo-indicator {
|
|
586
|
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
587
|
+
color: white;
|
|
588
|
+
border-radius: 4px;
|
|
589
|
+
padding: 2px 8px;
|
|
590
|
+
}
|
|
591
|
+
```
|
|
592
|
+
|
|
593
|
+
### Variant Styles
|
|
594
|
+
|
|
595
|
+
```svelte
|
|
596
|
+
<!-- Outlined variant -->
|
|
597
|
+
<MemoEditor variant="outlined" />
|
|
598
|
+
|
|
599
|
+
<!-- Filled variant -->
|
|
600
|
+
<MemoEditor variant="filled" />
|
|
601
|
+
|
|
602
|
+
<!-- Plain variant -->
|
|
603
|
+
<MemoEditor variant="plain" />
|
|
604
|
+
|
|
605
|
+
<!-- Default variant -->
|
|
606
|
+
<MemoEditor />
|
|
607
|
+
```
|
|
608
|
+
|
|
609
|
+
## Advanced Features
|
|
610
|
+
|
|
611
|
+
### Auto-save Functionality
|
|
612
|
+
|
|
613
|
+
```svelte
|
|
614
|
+
<script>
|
|
615
|
+
import MemoEditor from '@ticatec/uniface-element/memo-editor';
|
|
616
|
+
|
|
617
|
+
let content = '';
|
|
618
|
+
let lastSaved = null;
|
|
619
|
+
let saveStatus = 'saved'; // 'saving', 'saved', 'error'
|
|
620
|
+
|
|
621
|
+
let saveTimeout;
|
|
622
|
+
|
|
623
|
+
async function saveContent() {
|
|
624
|
+
saveStatus = 'saving';
|
|
625
|
+
|
|
626
|
+
try {
|
|
627
|
+
// Simulate API save
|
|
628
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
629
|
+
|
|
630
|
+
localStorage.setItem('draft-content', content);
|
|
631
|
+
lastSaved = new Date();
|
|
632
|
+
saveStatus = 'saved';
|
|
633
|
+
} catch (error) {
|
|
634
|
+
console.error('Save failed:', error);
|
|
635
|
+
saveStatus = 'error';
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
function handleInput() {
|
|
640
|
+
saveStatus = 'saving';
|
|
641
|
+
|
|
642
|
+
// Debounce auto-save
|
|
643
|
+
clearTimeout(saveTimeout);
|
|
644
|
+
saveTimeout = setTimeout(saveContent, 2000);
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
// Load saved content on mount
|
|
648
|
+
import { onMount } from 'svelte';
|
|
649
|
+
|
|
650
|
+
onMount(() => {
|
|
651
|
+
const saved = localStorage.getItem('draft-content');
|
|
652
|
+
if (saved) {
|
|
653
|
+
content = saved;
|
|
654
|
+
}
|
|
655
|
+
});
|
|
656
|
+
</script>
|
|
657
|
+
|
|
658
|
+
<div class="auto-save-editor">
|
|
659
|
+
<div class="editor-header">
|
|
660
|
+
<h3>Document Editor</h3>
|
|
661
|
+
<div class="save-status">
|
|
662
|
+
{#if saveStatus === 'saving'}
|
|
663
|
+
<span class="status saving">Saving...</span>
|
|
664
|
+
{:else if saveStatus === 'saved'}
|
|
665
|
+
<span class="status saved">
|
|
666
|
+
Saved {lastSaved ? lastSaved.toLocaleTimeString() : ''}
|
|
667
|
+
</span>
|
|
668
|
+
{:else if saveStatus === 'error'}
|
|
669
|
+
<span class="status error">Save failed</span>
|
|
670
|
+
{/if}
|
|
671
|
+
</div>
|
|
672
|
+
</div>
|
|
673
|
+
|
|
674
|
+
<MemoEditor
|
|
675
|
+
bind:value={content}
|
|
676
|
+
variant="outlined"
|
|
677
|
+
input$rows={15}
|
|
678
|
+
resize="vertical"
|
|
679
|
+
input$placeholder="Start typing your document..."
|
|
680
|
+
on:input={handleInput}
|
|
681
|
+
/>
|
|
682
|
+
</div>
|
|
683
|
+
|
|
684
|
+
<style>
|
|
685
|
+
.auto-save-editor {
|
|
686
|
+
max-width: 800px;
|
|
687
|
+
margin: 0 auto;
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
.editor-header {
|
|
691
|
+
display: flex;
|
|
692
|
+
justify-content: space-between;
|
|
693
|
+
align-items: center;
|
|
694
|
+
margin-bottom: 1rem;
|
|
695
|
+
padding: 0 0.5rem;
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
.editor-header h3 {
|
|
699
|
+
margin: 0;
|
|
700
|
+
color: #1f2937;
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
.save-status .status {
|
|
704
|
+
font-size: 0.875rem;
|
|
705
|
+
padding: 0.25rem 0.5rem;
|
|
706
|
+
border-radius: 0.25rem;
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
.status.saving {
|
|
710
|
+
background: #fef3c7;
|
|
711
|
+
color: #92400e;
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
.status.saved {
|
|
715
|
+
background: #d1fae5;
|
|
716
|
+
color: #065f46;
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
.status.error {
|
|
720
|
+
background: #fee2e2;
|
|
721
|
+
color: #991b1b;
|
|
722
|
+
}
|
|
723
|
+
</style>
|
|
724
|
+
```
|
|
725
|
+
|
|
726
|
+
## Best Practices
|
|
727
|
+
|
|
728
|
+
### 1. Use Appropriate Row Counts
|
|
729
|
+
|
|
730
|
+
Set `input$rows` based on expected content length:
|
|
731
|
+
|
|
732
|
+
```svelte
|
|
733
|
+
<!-- Short descriptions -->
|
|
734
|
+
<MemoEditor input$rows={3} maxLength={200} />
|
|
735
|
+
|
|
736
|
+
<!-- Medium content -->
|
|
737
|
+
<MemoEditor input$rows={6} maxLength={1000} />
|
|
738
|
+
|
|
739
|
+
<!-- Long articles -->
|
|
740
|
+
<MemoEditor input$rows={15} resize="vertical" />
|
|
741
|
+
```
|
|
742
|
+
|
|
743
|
+
### 2. Implement Character Limits
|
|
744
|
+
|
|
745
|
+
Always set reasonable character limits with indicators:
|
|
746
|
+
|
|
747
|
+
```svelte
|
|
748
|
+
<MemoEditor
|
|
749
|
+
maxLength={500}
|
|
750
|
+
showIndicator
|
|
751
|
+
variant="outlined"
|
|
752
|
+
/>
|
|
753
|
+
```
|
|
754
|
+
|
|
755
|
+
### 3. Handle Validation
|
|
756
|
+
|
|
757
|
+
Provide clear validation feedback:
|
|
758
|
+
|
|
759
|
+
```svelte
|
|
760
|
+
<script>
|
|
761
|
+
let content = '';
|
|
762
|
+
let error = '';
|
|
763
|
+
|
|
764
|
+
function validate() {
|
|
765
|
+
if (content.length < 10) {
|
|
766
|
+
error = 'Content must be at least 10 characters';
|
|
767
|
+
} else {
|
|
768
|
+
error = '';
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
</script>
|
|
772
|
+
|
|
773
|
+
<MemoEditor
|
|
774
|
+
bind:value={content}
|
|
775
|
+
on:blur={validate}
|
|
776
|
+
style={error ? 'border-color: #ef4444;' : ''}
|
|
777
|
+
/>
|
|
778
|
+
|
|
779
|
+
{#if error}
|
|
780
|
+
<div class="error">{error}</div>
|
|
781
|
+
{/if}
|
|
782
|
+
```
|
|
783
|
+
|
|
784
|
+
### 4. Enable Resize for Long Content
|
|
785
|
+
|
|
786
|
+
Allow users to resize editors for better usability:
|
|
787
|
+
|
|
788
|
+
```svelte
|
|
789
|
+
<MemoEditor
|
|
790
|
+
resize="vertical"
|
|
791
|
+
input$rows={8}
|
|
792
|
+
placeholder="This editor can be resized vertically"
|
|
793
|
+
/>
|
|
794
|
+
```
|
|
795
|
+
|
|
796
|
+
## Accessibility Features
|
|
797
|
+
|
|
798
|
+
- **Keyboard Navigation**: Full keyboard support for text editing
|
|
799
|
+
- **Screen Reader Support**: Proper labeling and announcements
|
|
800
|
+
- **Focus Management**: Clear focus indicators and tab navigation
|
|
801
|
+
- **ARIA Attributes**: Appropriate roles and properties
|
|
802
|
+
- **Character Limit Announcements**: Screen reader feedback for character limits
|
|
803
|
+
|
|
804
|
+
## Browser Support
|
|
805
|
+
|
|
806
|
+
- **Modern Browsers**: Chrome, Firefox, Safari, Edge (latest versions)
|
|
807
|
+
- **Mobile Browsers**: iOS Safari, Chrome Mobile, Firefox Mobile
|
|
808
|
+
- **ResizeObserver**: Required for auto-width calculation (polyfill available)
|
|
809
|
+
- **Textarea Features**: All standard textarea functionality supported
|
|
810
|
+
|
|
811
|
+
## Related Components
|
|
812
|
+
|
|
813
|
+
- **TextEditor**: Single-line text input component
|
|
814
|
+
- **FormField**: Form field wrapper for labels and validation
|
|
815
|
+
- **ListBox**: List selection for text templates or snippets
|
|
816
|
+
|
|
817
|
+
## License
|
|
818
|
+
|
|
819
|
+
MIT License - see LICENSE file for details.
|