5htp-core 0.4.7 → 0.4.8-2

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 (40) hide show
  1. package/package.json +6 -1
  2. package/src/client/assets/css/components/table.less +2 -0
  3. package/src/client/assets/css/text/titres.less +1 -1
  4. package/src/client/assets/css/utils/layouts.less +8 -2
  5. package/src/client/components/Dialog/Manager.tsx +65 -29
  6. package/src/client/components/Dialog/card.tsx +3 -1
  7. package/src/client/components/Dialog/index.less +1 -2
  8. package/src/client/components/Select/ChoiceSelector.tsx +7 -5
  9. package/src/client/components/Select/index.tsx +162 -130
  10. package/src/client/components/index.ts +2 -1
  11. package/src/client/components/inputv3/Rte/ExampleTheme.tsx +42 -0
  12. package/src/client/components/inputv3/Rte/ToolbarPlugin.tsx +167 -0
  13. package/src/client/components/inputv3/Rte/icons/LICENSE.md +5 -0
  14. package/src/client/components/inputv3/Rte/icons/arrow-clockwise.svg +4 -0
  15. package/src/client/components/inputv3/Rte/icons/arrow-counterclockwise.svg +4 -0
  16. package/src/client/components/inputv3/Rte/icons/journal-text.svg +5 -0
  17. package/src/client/components/inputv3/Rte/icons/justify.svg +3 -0
  18. package/src/client/components/inputv3/Rte/icons/text-center.svg +3 -0
  19. package/src/client/components/inputv3/Rte/icons/text-left.svg +3 -0
  20. package/src/client/components/inputv3/Rte/icons/text-paragraph.svg +3 -0
  21. package/src/client/components/inputv3/Rte/icons/text-right.svg +3 -0
  22. package/src/client/components/inputv3/Rte/icons/type-bold.svg +3 -0
  23. package/src/client/components/inputv3/Rte/icons/type-italic.svg +3 -0
  24. package/src/client/components/inputv3/Rte/icons/type-strikethrough.svg +3 -0
  25. package/src/client/components/inputv3/Rte/icons/type-underline.svg +3 -0
  26. package/src/client/components/inputv3/Rte/index.tsx +163 -0
  27. package/src/client/components/inputv3/Rte/style.less +428 -0
  28. package/src/client/components/inputv3/base.less +20 -33
  29. package/src/client/components/inputv3/base.tsx +36 -2
  30. package/src/client/components/inputv3/file/index.tsx +11 -5
  31. package/src/client/components/inputv3/index.tsx +45 -44
  32. package/src/common/data/rte/index.ts +66 -0
  33. package/src/common/data/rte/nodes.ts +20 -0
  34. package/src/common/validation/validators.ts +49 -4
  35. package/src/server/services/auth/index.ts +0 -2
  36. package/src/server/services/database/index.ts +1 -1
  37. package/src/client/components/input/Rte/index.less +0 -13
  38. package/src/client/components/input/Rte/index.tsx +0 -143
  39. package/src/client/components/input/Rte/selection.ts +0 -34
  40. package/src/common/data/rte.tsx +0 -11
@@ -0,0 +1,428 @@
1
+ .input.rte {
2
+ .other h2 {
3
+ font-size: 18px;
4
+ color: #444;
5
+ margin-bottom: 7px;
6
+ }
7
+
8
+ .other a {
9
+ color: #777;
10
+ text-decoration: underline;
11
+ font-size: 14px;
12
+ }
13
+
14
+ .other ul {
15
+ padding: 0;
16
+ margin: 0;
17
+ list-style-type: none;
18
+ }
19
+
20
+ .App {
21
+ font-family: sans-serif;
22
+ text-align: center;
23
+ }
24
+
25
+ h1 {
26
+ font-size: 24px;
27
+ color: #333;
28
+ }
29
+
30
+ .ltr {
31
+ text-align: left;
32
+ }
33
+
34
+ .rtl {
35
+ text-align: right;
36
+ }
37
+
38
+ .editor-container {
39
+ margin: 0;
40
+ color: #000;
41
+ position: relative;
42
+ line-height: 20px;
43
+ font-weight: 400;
44
+ text-align: left;
45
+ border-top-left-radius: 10px;
46
+ border-top-right-radius: 10px;
47
+ }
48
+
49
+ .editor-inner {
50
+ background: #fff;
51
+ position: relative;
52
+ }
53
+
54
+ .editor-input {
55
+ min-height: 150px;
56
+ resize: none;
57
+ font-size: 15px;
58
+ caret-color: rgb(5, 5, 5);
59
+ position: relative;
60
+ tab-size: 1;
61
+ outline: 0;
62
+ caret-color: #444;
63
+ }
64
+
65
+ .editor-placeholder {
66
+ color: #999;
67
+ overflow: hidden;
68
+ position: absolute;
69
+ text-overflow: ellipsis;
70
+ top: 3px;
71
+ left: 0px;
72
+ font-size: 15px;
73
+ user-select: none;
74
+ display: inline-block;
75
+ pointer-events: none;
76
+ }
77
+
78
+ .editor-text-bold {
79
+ font-weight: bold;
80
+ }
81
+
82
+ .editor-text-italic {
83
+ font-style: italic;
84
+ }
85
+
86
+ .editor-text-underline {
87
+ text-decoration: underline;
88
+ }
89
+
90
+ .editor-text-strikethrough {
91
+ text-decoration: line-through;
92
+ }
93
+
94
+ .editor-text-underlineStrikethrough {
95
+ text-decoration: underline line-through;
96
+ }
97
+
98
+ .editor-text-code {
99
+ background-color: rgb(240, 242, 245);
100
+ padding: 1px 0.25rem;
101
+ font-family: Menlo, Consolas, Monaco, monospace;
102
+ font-size: 94%;
103
+ }
104
+
105
+ .editor-link {
106
+ color: rgb(33, 111, 219);
107
+ text-decoration: none;
108
+ }
109
+
110
+ .tree-view-output {
111
+ display: block;
112
+ background: #222;
113
+ color: #fff;
114
+ padding: 5px;
115
+ font-size: 12px;
116
+ white-space: pre-wrap;
117
+ margin: 1px auto 10px auto;
118
+ max-height: 250px;
119
+ position: relative;
120
+ border-bottom-left-radius: 10px;
121
+ border-bottom-right-radius: 10px;
122
+ overflow: auto;
123
+ line-height: 14px;
124
+ }
125
+
126
+ .editor-code {
127
+ background-color: rgb(240, 242, 245);
128
+ font-family: Menlo, Consolas, Monaco, monospace;
129
+ display: block;
130
+ padding: 8px 8px 8px 52px;
131
+ line-height: 1.53;
132
+ font-size: 13px;
133
+ margin: 0;
134
+ margin-top: 8px;
135
+ margin-bottom: 8px;
136
+ tab-size: 2;
137
+ /* white-space: pre; */
138
+ overflow-x: auto;
139
+ position: relative;
140
+ }
141
+
142
+ .editor-code:before {
143
+ content: attr(data-gutter);
144
+ position: absolute;
145
+ background-color: #eee;
146
+ left: 0;
147
+ top: 0;
148
+ border-right: 1px solid #ccc;
149
+ padding: 8px;
150
+ color: #777;
151
+ white-space: pre-wrap;
152
+ text-align: right;
153
+ min-width: 25px;
154
+ }
155
+
156
+ .editor-code:after {
157
+ content: attr(data-highlight-language);
158
+ top: 0;
159
+ right: 3px;
160
+ padding: 3px;
161
+ font-size: 10px;
162
+ text-transform: uppercase;
163
+ position: absolute;
164
+ color: rgba(0, 0, 0, 0.5);
165
+ }
166
+
167
+ .editor-tokenComment {
168
+ color: slategray;
169
+ }
170
+
171
+ .editor-tokenPunctuation {
172
+ color: #999;
173
+ }
174
+
175
+ .editor-tokenProperty {
176
+ color: #905;
177
+ }
178
+
179
+ .editor-tokenSelector {
180
+ color: #690;
181
+ }
182
+
183
+ .editor-tokenOperator {
184
+ color: #9a6e3a;
185
+ }
186
+
187
+ .editor-tokenAttr {
188
+ color: #07a;
189
+ }
190
+
191
+ .editor-tokenVariable {
192
+ color: #e90;
193
+ }
194
+
195
+ .editor-tokenFunction {
196
+ color: #dd4a68;
197
+ }
198
+
199
+ .editor-paragraph {
200
+ margin: 0;
201
+ margin-bottom: 8px;
202
+ position: relative;
203
+ }
204
+
205
+ .editor-paragraph:last-child {
206
+ margin-bottom: 0;
207
+ }
208
+
209
+ .editor-heading-h1 {
210
+ font-size: 24px;
211
+ color: rgb(5, 5, 5);
212
+ font-weight: 400;
213
+ margin: 0;
214
+ margin-bottom: 12px;
215
+ padding: 0;
216
+ }
217
+
218
+ .editor-heading-h2 {
219
+ font-size: 15px;
220
+ color: rgb(101, 103, 107);
221
+ font-weight: 700;
222
+ margin: 0;
223
+ margin-top: 10px;
224
+ padding: 0;
225
+ text-transform: uppercase;
226
+ }
227
+
228
+ .editor-quote {
229
+ margin: 0;
230
+ margin-left: 20px;
231
+ font-size: 15px;
232
+ color: rgb(101, 103, 107);
233
+ border-left-color: rgb(206, 208, 212);
234
+ border-left-width: 4px;
235
+ border-left-style: solid;
236
+ padding-left: 16px;
237
+ }
238
+
239
+ .editor-list-ol {
240
+ padding: 0;
241
+ margin: 0;
242
+ margin-left: 16px;
243
+ }
244
+
245
+ .editor-list-ul {
246
+ padding: 0;
247
+ margin: 0;
248
+ margin-left: 16px;
249
+ }
250
+
251
+ .editor-listitem {
252
+ margin: 8px 32px 8px 32px;
253
+ }
254
+
255
+ .editor-nested-listitem {
256
+ list-style-type: none;
257
+ }
258
+
259
+ pre::-webkit-scrollbar {
260
+ background: transparent;
261
+ width: 10px;
262
+ }
263
+
264
+ pre::-webkit-scrollbar-thumb {
265
+ background: #999;
266
+ }
267
+
268
+ .debug-timetravel-panel {
269
+ overflow: hidden;
270
+ padding: 0 0 10px 0;
271
+ margin: auto;
272
+ display: flex;
273
+ }
274
+
275
+ .debug-timetravel-panel-slider {
276
+ padding: 0;
277
+ flex: 8;
278
+ }
279
+
280
+ .debug-timetravel-panel-button {
281
+ padding: 0;
282
+ border: 0;
283
+ background: none;
284
+ flex: 1;
285
+ color: #fff;
286
+ font-size: 12px;
287
+ }
288
+
289
+ .debug-timetravel-panel-button:hover {
290
+ text-decoration: underline;
291
+ }
292
+
293
+ .debug-timetravel-button {
294
+ border: 0;
295
+ padding: 0;
296
+ font-size: 12px;
297
+ top: 10px;
298
+ right: 15px;
299
+ position: absolute;
300
+ background: none;
301
+ color: #fff;
302
+ }
303
+
304
+ .debug-timetravel-button:hover {
305
+ text-decoration: underline;
306
+ }
307
+
308
+ .toolbar {
309
+ display: flex;
310
+ background: #fff;
311
+ vertical-align: middle;
312
+ }
313
+
314
+ .toolbar button.toolbar-item {
315
+ border: 0;
316
+ display: flex;
317
+ background: none;
318
+ border-radius: 10px;
319
+ padding: 8px;
320
+ cursor: pointer;
321
+ vertical-align: middle;
322
+ }
323
+
324
+ .toolbar button.toolbar-item:disabled {
325
+ cursor: not-allowed;
326
+ }
327
+
328
+ .toolbar button.toolbar-item.spaced {
329
+ margin-right: 2px;
330
+ }
331
+
332
+ .toolbar button.toolbar-item i.format {
333
+ background-size: contain;
334
+ display: inline-block;
335
+ height: 18px;
336
+ width: 18px;
337
+ margin-top: 2px;
338
+ vertical-align: -0.25em;
339
+ display: flex;
340
+ opacity: 0.6;
341
+ }
342
+
343
+ .toolbar button.toolbar-item:disabled i.format {
344
+ opacity: 0.2;
345
+ }
346
+
347
+ .toolbar button.toolbar-item.active {
348
+ background-color: rgba(223, 232, 250, 0.3);
349
+ }
350
+
351
+ .toolbar button.toolbar-item.active i {
352
+ opacity: 1;
353
+ }
354
+
355
+ .toolbar .toolbar-item:hover:not([disabled]) {
356
+ background-color: #eee;
357
+ }
358
+
359
+ .toolbar .divider {
360
+ width: 1px;
361
+ background-color: #eee;
362
+ margin: 0 4px;
363
+ }
364
+
365
+ .toolbar .toolbar-item .text {
366
+ display: flex;
367
+ line-height: 20px;
368
+ width: 200px;
369
+ vertical-align: middle;
370
+ font-size: 14px;
371
+ color: #777;
372
+ text-overflow: ellipsis;
373
+ width: 70px;
374
+ overflow: hidden;
375
+ height: 20px;
376
+ text-align: left;
377
+ }
378
+
379
+ .toolbar .toolbar-item .icon {
380
+ display: flex;
381
+ width: 20px;
382
+ height: 20px;
383
+ user-select: none;
384
+ margin-right: 8px;
385
+ line-height: 16px;
386
+ background-size: contain;
387
+ }
388
+
389
+ i.undo {
390
+ background-image: url(icons/arrow-counterclockwise.svg);
391
+ }
392
+
393
+ i.redo {
394
+ background-image: url(icons/arrow-clockwise.svg);
395
+ }
396
+
397
+ i.bold {
398
+ background-image: url(icons/type-bold.svg);
399
+ }
400
+
401
+ i.italic {
402
+ background-image: url(icons/type-italic.svg);
403
+ }
404
+
405
+ i.underline {
406
+ background-image: url(icons/type-underline.svg);
407
+ }
408
+
409
+ i.strikethrough {
410
+ background-image: url(icons/type-strikethrough.svg);
411
+ }
412
+
413
+ i.left-align {
414
+ background-image: url(icons/text-left.svg);
415
+ }
416
+
417
+ i.center-align {
418
+ background-image: url(icons/text-center.svg);
419
+ }
420
+
421
+ i.right-align {
422
+ background-image: url(icons/text-right.svg);
423
+ }
424
+
425
+ i.justify-align {
426
+ background-image: url(icons/justify.svg);
427
+ }
428
+ }
@@ -1,7 +1,6 @@
1
1
  @import (reference) "@/client/assets/vars.less";
2
2
 
3
3
  @hInput: @sizeComponent;
4
- @labelH: 0.6em;
5
4
 
6
5
  // TODO: Adapter textarea à input/basev2
7
6
  .contChamp textarea {
@@ -12,6 +11,22 @@
12
11
  padding-top: @spacing * 2 !important;
13
12
  }
14
13
 
14
+ .inputWrapper {
15
+ display: flex;
16
+ flex-direction: column;
17
+ gap: 0.5em;
18
+ align-items: stretch;
19
+
20
+ > label {
21
+ font-weight: 700;
22
+ }
23
+
24
+ > p.hint {
25
+ text-align: left;
26
+ color: var(--cTxtDesc);
27
+ }
28
+ }
29
+
15
30
  .input {
16
31
  &.text,
17
32
  &.select {
@@ -22,15 +37,6 @@
22
37
  > i {
23
38
  color: var(--cTxtDesc);
24
39
  }
25
-
26
- label {
27
- display: flex;
28
- align-items: center;
29
- color: var(--cTxtImportant);
30
- font-size: 0.9em;
31
- font-weight: 600;
32
- transition: all .1s ease-out;
33
- }
34
40
  }
35
41
 
36
42
  // Error bubble
@@ -72,28 +78,9 @@
72
78
  --cBg2: #eee;
73
79
  //box-shadow: 1px 3px 0 fade(#000,4%), 0 1px 2px 0 fade(#000,2%);
74
80
 
75
- @gapAround: (@hInput - @labelH) / 2;
81
+ @gapAround: @spacing;
76
82
  > .btn:first-child { margin-left: 0 - @gapAround / 2; }
77
83
 
78
- label {
79
- position: absolute;
80
- left: 0; width: 100%;
81
- top: 0;
82
- height: @labelH;
83
- font-size: 0.8em;
84
- line-height: 0.8em;
85
-
86
- color: var(--cTxtImportant);
87
- }
88
-
89
- &.empty:not(.focus) {
90
- label {
91
- height: 100%;
92
- font-size: 1em;
93
- color: var(--cTxtBase);
94
- }
95
- }
96
-
97
84
  .contValue {
98
85
  position: relative;
99
86
  flex: 1;
@@ -114,7 +101,7 @@
114
101
  border: none;
115
102
  font-family: inherit;
116
103
  width: 100%;
117
- padding: @labelH 0 0 0;
104
+ padding: 0;
118
105
  font-size: 1rem;
119
106
  color: inherit;
120
107
  }
@@ -128,7 +115,7 @@
128
115
  }
129
116
 
130
117
  textarea {
131
- padding: @labelH + @spacing 0 @spacing 0;
132
- min-height: 4em;
118
+ padding: 0;
119
+ min-height: 6em;
133
120
  }
134
121
  }
@@ -4,6 +4,7 @@
4
4
 
5
5
  // Npm
6
6
  import React from 'react';
7
+ import type { ComponentChild } from 'preact';
7
8
  import type { StateUpdater } from 'preact/hooks';
8
9
 
9
10
  // Core libs
@@ -16,10 +17,13 @@ import { useState } from '@client/hooks';
16
17
  export type InputBaseProps<TValue> = {
17
18
 
18
19
  title: string, // Now mandatory
20
+ hint?: ComponentChild,
19
21
  required?: boolean,
20
22
  errors?: string[],
21
23
  size?: TComponentSize,
22
24
 
25
+ wrapper?: boolean,
26
+
23
27
  value: TValue,
24
28
  onChange?: (value: TValue) => void,
25
29
  }
@@ -64,7 +68,7 @@ export function useInput<TValue>(
64
68
  if (state.changed === false)
65
69
  return;
66
70
 
67
- console.log(`[input] Commit value:`, state.value, externalValue);
71
+ //console.log(`[input] Commit value:`, state.value, externalValue);
68
72
  if (onChange !== undefined)
69
73
  onChange(state.value);
70
74
  }
@@ -73,7 +77,7 @@ export function useInput<TValue>(
73
77
  React.useEffect(() => {
74
78
 
75
79
  if (externalValue !== undefined && externalValue !== state.value) {
76
- console.log("External value change", externalValue);
80
+ //console.log("External value change", externalValue);
77
81
  setState({ value: externalValue, valueSource: 'external', changed: true })
78
82
  }
79
83
 
@@ -91,4 +95,34 @@ export function useInput<TValue>(
91
95
  /*----------------------------------
92
96
  - COMPONENT
93
97
  ----------------------------------*/
98
+ export const InputWrapper = ({ children, wrapper = true, title, hint, required }: InputBaseProps<unknown> & {
99
+ children: ComponentChild
100
+ }) => {
101
+
102
+ /*----------------------------------
103
+ - INIT
104
+ ----------------------------------*/
105
+
106
+ /*----------------------------------
107
+ - ACTIONS
108
+ ----------------------------------*/
109
+
110
+ /*----------------------------------
111
+ - RENDER
112
+ ----------------------------------*/
113
+ return wrapper === false ? <>{children}</> : (
114
+ <div class="inputWrapper">
115
+
116
+ <label>{title}{required && (
117
+ <span class="fg error">&nbsp;*</span>
118
+ )}</label>
119
+
120
+ {hint && <p class="hint">{hint}</p>}
121
+
122
+ {children}
123
+
124
+ </div>
125
+ )
126
+ }
127
+
94
128
  import './base.less';
@@ -60,7 +60,7 @@ export type Props = {
60
60
 
61
61
  // Input
62
62
  title: ComponentChild,
63
- value?: FileToUpload,
63
+ value?: string | FileToUpload, // string = already registered
64
64
 
65
65
  // Display
66
66
  emptyText?: ComponentChild,
@@ -96,7 +96,7 @@ export default ({
96
96
 
97
97
  const [previewUrl, setPreviewUrl] = React.useState<string | undefined>(previewUrlInit);
98
98
 
99
- className = 'input upload ' + (className === undefined ? '' : ' ' + className)
99
+ className = 'input upload ' + (className === undefined ? '' : ' ' + className);
100
100
 
101
101
  /*----------------------------------
102
102
  - ACTIONS
@@ -115,7 +115,7 @@ export default ({
115
115
  React.useEffect(() => {
116
116
 
117
117
  // Image = decode & display preview
118
- if (file !== undefined && file.type.startsWith('image/'))
118
+ if (file !== undefined && typeof file === 'object' && file.type.startsWith('image/'))
119
119
  createImagePreview(file.data).then(setPreviewUrl);
120
120
  else
121
121
  setPreviewUrl(undefined);
@@ -135,14 +135,20 @@ export default ({
135
135
 
136
136
  {previewUrl ? (
137
137
  <img src={previewUrl} />
138
- ) : file ? <>
138
+ ) : typeof file === 'string' ? <>
139
+ <strong>A file has been selected</strong>
140
+ </> : file ? <>
139
141
  <strong>{file.name}</strong>
140
142
  </> : null}
141
143
  </div>
142
144
 
143
145
  <div class="row actions sp-05">
146
+
147
+ {typeof file === 'string' && <>
148
+ <Bouton type="secondary" icon="eye" shape="pill" size="s" link={file} />
149
+ </>}
144
150
 
145
- <Bouton class='fg error' icon="trash" shape="pill" size="s"
151
+ <Bouton class='bg error' icon="trash" shape="pill" size="s"
146
152
  async onClick={() => onChange(undefined)} />
147
153
  </div>
148
154
  </>}