@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.
Files changed (178) hide show
  1. package/dist/accordion/README.md +169 -0
  2. package/dist/accordion/README_CN.md +176 -0
  3. package/dist/action-bar/README.md +275 -0
  4. package/dist/action-bar/README_CN.md +285 -0
  5. package/dist/app-layout/README.md +374 -0
  6. package/dist/app-layout/README_CN.md +381 -0
  7. package/dist/app-top-bar/README.md +357 -0
  8. package/dist/app-top-bar/README_CN.md +365 -0
  9. package/dist/attachment-files/AttachmentFilesField.svelte +67 -1
  10. package/dist/attachment-files/AttachmentFilesField.svelte.d.ts +8 -1
  11. package/dist/base-calendar/CalendarBase.svelte +0 -3
  12. package/dist/box/README.md +385 -0
  13. package/dist/box/README_CN.md +393 -0
  14. package/dist/breadcrumbs/README.md +442 -0
  15. package/dist/breadcrumbs/README_CN.md +442 -0
  16. package/dist/button/Button.svelte +27 -7
  17. package/dist/button/Button.svelte.d.ts +3 -1
  18. package/dist/button/IconButton.svelte +26 -6
  19. package/dist/button/IconButton.svelte.d.ts +3 -1
  20. package/dist/button/IconButton_README.md +513 -0
  21. package/dist/button/IconButton_README_CN.md +513 -0
  22. package/dist/button/README.md +428 -0
  23. package/dist/button/README_CN.md +428 -0
  24. package/dist/button/TextButton.svelte +26 -6
  25. package/dist/button/TextButton.svelte.d.ts +3 -1
  26. package/dist/button/TextButton_README.md +571 -0
  27. package/dist/button/TextButton_README_CN.md +571 -0
  28. package/dist/card/README.md +666 -0
  29. package/dist/card/README_CN.md +666 -0
  30. package/dist/cascade-options-select/CascadeOptionSelect.svelte +43 -7
  31. package/dist/cascade-options-select/CascadeOptionSelect.svelte.d.ts +3 -4
  32. package/dist/cascade-options-select/README.md +663 -2
  33. package/dist/cascade-options-select/README_CN.md +664 -0
  34. package/dist/checkbox/CheckBox.svelte +20 -6
  35. package/dist/checkbox/CheckBox.svelte.d.ts +4 -2
  36. package/dist/checkbox/README.md +562 -0
  37. package/dist/checkbox/README_CN.md +727 -0
  38. package/dist/common-editor/NumberInput.svelte +39 -26
  39. package/dist/common-editor/NumberInput.svelte.d.ts +5 -1
  40. package/dist/concise-data-table/ConciseListTable.svelte +133 -36
  41. package/dist/concise-data-table/ConciseListTable.svelte.d.ts +8 -1
  42. package/dist/concise-data-table/DataCell.svelte +5 -6
  43. package/dist/concise-data-table/DataRow.svelte +22 -2
  44. package/dist/concise-data-table/DataRow.svelte.d.ts +1 -0
  45. package/dist/concise-data-table/README.md +606 -0
  46. package/dist/concise-data-table/README_CN.md +611 -0
  47. package/dist/context-menu/ContextMenu.svelte +138 -21
  48. package/dist/context-menu/ContextMenu.svelte.d.ts +5 -0
  49. package/dist/context-menu/ContextMenuItem.d.ts +20 -4
  50. package/dist/context-menu/README.md +551 -0
  51. package/dist/context-menu/README_CN.md +551 -0
  52. package/dist/criteria-field/CriteriaField.svelte +3 -5
  53. package/dist/criteria-field/README.md +532 -0
  54. package/dist/criteria-field/README_CN.md +532 -0
  55. package/dist/data-table/README.md +712 -0
  56. package/dist/data-table/README_CN.md +712 -0
  57. package/dist/date-picker/DatePicker.svelte +44 -7
  58. package/dist/date-picker/DatePicker.svelte.d.ts +3 -4
  59. package/dist/date-picker/DateTimePicker.svelte +32 -8
  60. package/dist/date-picker/DateTimePicker.svelte.d.ts +3 -4
  61. package/dist/date-picker/README.md +326 -0
  62. package/dist/date-picker/README_CN.md +316 -0
  63. package/dist/date-picker/ScrollBar.svelte +18 -8
  64. package/dist/date-picker/ScrollBar.svelte.d.ts +1 -1
  65. package/dist/date-picker/TimePanel.svelte +5 -5
  66. package/dist/date-picker/TimePanel.svelte.d.ts +1 -1
  67. package/dist/date-range/README.md +374 -0
  68. package/dist/date-range/README_CN.md +374 -0
  69. package/dist/dialog/DialogBoard.svelte +1 -1
  70. package/dist/dialog/README.md +596 -0
  71. package/dist/dialog/README_CN.md +596 -0
  72. package/dist/drawer/README.md +679 -1
  73. package/dist/drawer/README_CN.md +679 -0
  74. package/dist/group-box/group-check-box/GroupCheckBox.svelte +62 -5
  75. package/dist/group-box/group-check-box/GroupCheckBox.svelte.d.ts +7 -2
  76. package/dist/group-box/group-check-box/README.md +749 -0
  77. package/dist/group-box/group-check-box/README_CN.md +750 -0
  78. package/dist/group-box/group-radio-box/GroupRadioBox.svelte +69 -4
  79. package/dist/group-box/group-radio-box/GroupRadioBox.svelte.d.ts +8 -2
  80. package/dist/group-box/group-radio-box/README.md +920 -0
  81. package/dist/group-box/group-radio-box/README_CN.md +920 -0
  82. package/dist/image-files/README.md +1346 -0
  83. package/dist/image-files/README_CN.md +1346 -0
  84. package/dist/input-options-select/InputOptionsSelect.svelte +161 -65
  85. package/dist/input-options-select/InputOptionsSelect.svelte.d.ts +4 -1
  86. package/dist/lib/forwardAllEvents.d.ts +3 -0
  87. package/dist/lib/forwardAllEvents.js +24 -0
  88. package/dist/list-box/README.md +579 -0
  89. package/dist/list-box/README_CN.md +682 -0
  90. package/dist/lookup-editor/LookupEditor.svelte +15 -3
  91. package/dist/lookup-editor/LookupEditor.svelte.d.ts +3 -4
  92. package/dist/lookup-editor/README.md +684 -0
  93. package/dist/lookup-editor/README_CN.md +684 -0
  94. package/dist/memo-editor/MemoEditor.svelte +77 -27
  95. package/dist/memo-editor/MemoEditor.svelte.d.ts +6 -3
  96. package/dist/memo-editor/README.md +819 -0
  97. package/dist/memo-editor/README_CN.md +819 -0
  98. package/dist/message-box/README.md +398 -0
  99. package/dist/message-box/README_CN.md +398 -0
  100. package/dist/number-editor/NumberEditor.svelte +2 -2
  101. package/dist/number-editor/NumberEditor.svelte.d.ts +1 -1
  102. package/dist/number-editor/README.md +353 -22
  103. package/dist/number-editor/README_CN.md +357 -0
  104. package/dist/number-range/README.md +443 -0
  105. package/dist/number-range/README_CN.md +443 -0
  106. package/dist/options-multi-select/OptionsMultiSelect.svelte +87 -12
  107. package/dist/options-multi-select/OptionsMultiSelect.svelte.d.ts +3 -1
  108. package/dist/options-multi-select/README.md +480 -0
  109. package/dist/options-multi-select/README_CN.md +480 -0
  110. package/dist/options-select/OptionsSelect.svelte +36 -5
  111. package/dist/options-select/OptionsSelect.svelte.d.ts +3 -4
  112. package/dist/options-select/README.md +632 -0
  113. package/dist/options-select/README_CN.md +632 -0
  114. package/dist/page/README.md +605 -0
  115. package/dist/page/README_CN.md +605 -0
  116. package/dist/pagination/README.md +946 -0
  117. package/dist/pagination/README_CN.md +946 -0
  118. package/dist/pagination-panel/README.md +1075 -0
  119. package/dist/pagination-panel/README_CN.md +1075 -0
  120. package/dist/popup-hint/README.md +841 -0
  121. package/dist/popup-hint/README_CN.md +840 -0
  122. package/dist/progress-bar/README.md +242 -0
  123. package/dist/progress-bar/README_CN.md +242 -0
  124. package/dist/progress-step-bar/README.md +316 -0
  125. package/dist/progress-step-bar/README_CN.md +316 -0
  126. package/dist/prompts-text-editor/PromptsTextEditor.svelte +6 -3
  127. package/dist/prompts-text-editor/PromptsTextEditor.svelte.d.ts +3 -1
  128. package/dist/prompts-text-editor/README.md +329 -0
  129. package/dist/prompts-text-editor/README_CN.md +329 -0
  130. package/dist/property-editor/README.md +969 -0
  131. package/dist/property-editor/README_CN.md +969 -0
  132. package/dist/radio-button/README.md +372 -0
  133. package/dist/radio-button/README_CN.md +372 -0
  134. package/dist/radio-button/RadioButton.svelte +32 -3
  135. package/dist/radio-button/RadioButton.svelte.d.ts +12 -1
  136. package/dist/search-box/README.md +425 -0
  137. package/dist/search-box/README_CN.md +424 -0
  138. package/dist/search-box/SearchBox.svelte +22 -6
  139. package/dist/search-box/SearchBox.svelte.d.ts +4 -1
  140. package/dist/tabs/README.md +919 -0
  141. package/dist/tabs/README_CN.md +920 -0
  142. package/dist/tag/README.md +922 -0
  143. package/dist/tag/README_CN.md +922 -0
  144. package/dist/text-editor/PasswordEditor.svelte +17 -2
  145. package/dist/text-editor/PasswordEditor.svelte.d.ts +3 -3
  146. package/dist/text-editor/PasswordEditor_README.md +551 -0
  147. package/dist/text-editor/PasswordEditor_README_CN.md +551 -0
  148. package/dist/text-editor/README.md +466 -0
  149. package/dist/text-editor/README_CN.md +466 -0
  150. package/dist/text-editor/TextEditor.svelte +51 -19
  151. package/dist/text-editor/TextEditor.svelte.d.ts +0 -1
  152. package/dist/ticatec-uniface-web.css +1 -0
  153. package/dist/time-editor/README.md +498 -24
  154. package/dist/time-editor/README_CN.md +498 -0
  155. package/dist/time-editor/TimeEditor.svelte +7 -3
  156. package/dist/time-editor/TimeEditor.svelte.d.ts +3 -1
  157. package/dist/toast/README.md +667 -0
  158. package/dist/toast/README_CN.md +667 -0
  159. package/dist/transfer/README.md +795 -0
  160. package/dist/transfer/Transfer.svelte +6 -4
  161. package/dist/transfer/Transfer.svelte.d.ts +3 -1
  162. package/dist/tree-view/README.md +761 -0
  163. package/dist/tree-view/README_CN.md +761 -0
  164. package/dist/tree-view/TreeView.svelte +5 -3
  165. package/dist/tree-view/TreeView.svelte.d.ts +3 -1
  166. package/dist/unit-number-editor/README.md +546 -20
  167. package/dist/unit-number-editor/README_CN.md +525 -0
  168. package/dist/unit-number-editor/UnitNumberEditor.svelte +62 -8
  169. package/dist/unit-number-editor/UnitNumberEditor.svelte.d.ts +5 -1
  170. package/docs/form-field/cn/README_CN.md +364 -0
  171. package/docs/form-field/en/README.md +364 -0
  172. package/docs/form-panel/flex-form/cn/README_CN.md +586 -0
  173. package/docs/form-panel/flex-form/en/README.md +586 -0
  174. package/docs/form-panel/flex-row-form/cn/README_CN.md +787 -0
  175. package/docs/form-panel/flex-row-form/en/README.md +787 -0
  176. package/docs/form-panel/grid-form/en/README.md +744 -0
  177. package/package.json +1 -1
  178. 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.