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.
- package/package.json +6 -1
- package/src/client/assets/css/components/table.less +2 -0
- package/src/client/assets/css/text/titres.less +1 -1
- package/src/client/assets/css/utils/layouts.less +8 -2
- package/src/client/components/Dialog/Manager.tsx +65 -29
- package/src/client/components/Dialog/card.tsx +3 -1
- package/src/client/components/Dialog/index.less +1 -2
- package/src/client/components/Select/ChoiceSelector.tsx +7 -5
- package/src/client/components/Select/index.tsx +162 -130
- package/src/client/components/index.ts +2 -1
- package/src/client/components/inputv3/Rte/ExampleTheme.tsx +42 -0
- package/src/client/components/inputv3/Rte/ToolbarPlugin.tsx +167 -0
- package/src/client/components/inputv3/Rte/icons/LICENSE.md +5 -0
- package/src/client/components/inputv3/Rte/icons/arrow-clockwise.svg +4 -0
- package/src/client/components/inputv3/Rte/icons/arrow-counterclockwise.svg +4 -0
- package/src/client/components/inputv3/Rte/icons/journal-text.svg +5 -0
- package/src/client/components/inputv3/Rte/icons/justify.svg +3 -0
- package/src/client/components/inputv3/Rte/icons/text-center.svg +3 -0
- package/src/client/components/inputv3/Rte/icons/text-left.svg +3 -0
- package/src/client/components/inputv3/Rte/icons/text-paragraph.svg +3 -0
- package/src/client/components/inputv3/Rte/icons/text-right.svg +3 -0
- package/src/client/components/inputv3/Rte/icons/type-bold.svg +3 -0
- package/src/client/components/inputv3/Rte/icons/type-italic.svg +3 -0
- package/src/client/components/inputv3/Rte/icons/type-strikethrough.svg +3 -0
- package/src/client/components/inputv3/Rte/icons/type-underline.svg +3 -0
- package/src/client/components/inputv3/Rte/index.tsx +163 -0
- package/src/client/components/inputv3/Rte/style.less +428 -0
- package/src/client/components/inputv3/base.less +20 -33
- package/src/client/components/inputv3/base.tsx +36 -2
- package/src/client/components/inputv3/file/index.tsx +11 -5
- package/src/client/components/inputv3/index.tsx +45 -44
- package/src/common/data/rte/index.ts +66 -0
- package/src/common/data/rte/nodes.ts +20 -0
- package/src/common/validation/validators.ts +49 -4
- package/src/server/services/auth/index.ts +0 -2
- package/src/server/services/database/index.ts +1 -1
- package/src/client/components/input/Rte/index.less +0 -13
- package/src/client/components/input/Rte/index.tsx +0 -143
- package/src/client/components/input/Rte/selection.ts +0 -34
- package/src/common/data/rte.tsx +0 -11
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "5htp-core",
|
|
3
3
|
"description": "Convenient TypeScript framework designed for Performance and Productivity.",
|
|
4
|
-
"version": "0.4.
|
|
4
|
+
"version": "0.4.8-2",
|
|
5
5
|
"author": "Gaetan Le Gac (https://github.com/gaetanlegac)",
|
|
6
6
|
"repository": "git://github.com/gaetanlegac/5htp-core.git",
|
|
7
7
|
"license": "MIT",
|
|
@@ -13,6 +13,9 @@
|
|
|
13
13
|
"framework"
|
|
14
14
|
],
|
|
15
15
|
"dependencies": {
|
|
16
|
+
"@lexical/headless": "^0.18.0",
|
|
17
|
+
"@lexical/html": "^0.18.0",
|
|
18
|
+
"@lexical/react": "^0.18.0",
|
|
16
19
|
"accepts": "^1.3.7",
|
|
17
20
|
"activity-detector": "^3.0.0",
|
|
18
21
|
"ansi-to-html": "^0.7.1",
|
|
@@ -44,7 +47,9 @@
|
|
|
44
47
|
"intl": "^1.2.5",
|
|
45
48
|
"iso-639-1": "^2.1.9",
|
|
46
49
|
"js-cookie": "^3.0.1",
|
|
50
|
+
"jsdom": "^25.0.1",
|
|
47
51
|
"jsonwebtoken": "^8.5.1",
|
|
52
|
+
"lexical": "^0.18.0",
|
|
48
53
|
"load-script": "^2.0.0",
|
|
49
54
|
"locale": "^0.1.0",
|
|
50
55
|
"markdown-it": "^13.0.1",
|
|
@@ -57,7 +57,10 @@
|
|
|
57
57
|
justify-content: flex-start;
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
&.sep-1
|
|
60
|
+
&.sep-1 {
|
|
61
|
+
gap: 0;
|
|
62
|
+
> * + * { border-left: solid 1px var(--cLine); }
|
|
63
|
+
}
|
|
61
64
|
|
|
62
65
|
&.menu {
|
|
63
66
|
|
|
@@ -146,7 +149,10 @@
|
|
|
146
149
|
&.al-right { align-items: flex-end; }
|
|
147
150
|
&, &.al-fill { align-items: stretch; }
|
|
148
151
|
|
|
149
|
-
&.sep-1
|
|
152
|
+
&.sep-1 {
|
|
153
|
+
gap: 0;
|
|
154
|
+
> * + * { border-top: solid 1px var(--cLine); }
|
|
155
|
+
}
|
|
150
156
|
|
|
151
157
|
> .col-1 { align-self: stretch; }
|
|
152
158
|
|
|
@@ -27,7 +27,11 @@ type TParams = { [cle: string]: unknown }
|
|
|
27
27
|
|
|
28
28
|
type ComposantToast = React.FunctionComponent<{ close?: any }> & { data?: object };
|
|
29
29
|
|
|
30
|
-
type TOptsToast = (CardInfos & {
|
|
30
|
+
type TOptsToast = (CardInfos & {
|
|
31
|
+
content?: ComponentChild,
|
|
32
|
+
data?: {},
|
|
33
|
+
className?: string,
|
|
34
|
+
})
|
|
31
35
|
|
|
32
36
|
type TOnCloseCallback<TReturnType extends any> = (returnedValue: TReturnType) => void
|
|
33
37
|
|
|
@@ -43,16 +47,25 @@ export type TDialogControls = {
|
|
|
43
47
|
then: (cb: TOnCloseCallback<any>) => any
|
|
44
48
|
}
|
|
45
49
|
|
|
50
|
+
type TDialogContentArg = ComposantToast | Promise<{ default: ComposantToast }> | TOptsToast;
|
|
51
|
+
|
|
52
|
+
type TDialogShowArgs = [
|
|
53
|
+
// On utilise une fonction pour pouvoir accéder aux fonctions (close, ...) lors de la déclaration des infos de la toast
|
|
54
|
+
Content: TDialogContentArg,
|
|
55
|
+
paramsInit?: TParams
|
|
56
|
+
] | [
|
|
57
|
+
title: string,
|
|
58
|
+
// On utilise une fonction pour pouvoir accéder aux fonctions (close, ...) lors de la déclaration des infos de la toast
|
|
59
|
+
Content: TDialogContentArg,
|
|
60
|
+
paramsInit?: TParams
|
|
61
|
+
]
|
|
62
|
+
|
|
46
63
|
type DialogActions = {
|
|
47
64
|
|
|
48
65
|
setToasts: ( setter: (old: ComponentChild[]) => ComponentChild[]) => void,
|
|
49
66
|
setModals: ( setter: (old: ComponentChild[]) => ComponentChild[]) => void,
|
|
50
67
|
|
|
51
|
-
show: (
|
|
52
|
-
// On utilise une fonction pour pouvoir accéder aux fonctions (close, ...) lors de la déclaration des infos de la toast
|
|
53
|
-
Content: ComposantToast | Promise<{ default: ComposantToast }> | TOptsToast,
|
|
54
|
-
paramsInit?: TParams
|
|
55
|
-
) => TDialogControls,
|
|
68
|
+
show: (...args: TDialogShowArgs ) => TDialogControls,
|
|
56
69
|
|
|
57
70
|
confirm: (title: string, content: string | ComponentChild, defaultBtn: 'Yes'|'No') => TDialogControls,
|
|
58
71
|
|
|
@@ -73,26 +86,33 @@ type DialogActions = {
|
|
|
73
86
|
let idA: number = 0;
|
|
74
87
|
export const createDialog = (app: Application, isToast: boolean): DialogActions => {
|
|
75
88
|
|
|
76
|
-
const show = <TReturnType extends any = true>(
|
|
77
|
-
// On utilise une fonction pour pouvoir accéder aux fonctions (close, ...) lors de la déclaration des infos de la toast
|
|
78
|
-
Content: ComposantToast | Promise<{ default: ComposantToast }> | TOptsToast,
|
|
79
|
-
paramsInit?: TParams
|
|
80
|
-
): TDialogControls => {
|
|
89
|
+
const show = <TReturnType extends any = true>( ...args: TDialogShowArgs ): TDialogControls => {
|
|
81
90
|
|
|
82
91
|
let onClose: TOnCloseCallback<TReturnType>;
|
|
83
92
|
const id = idA++;
|
|
84
93
|
|
|
94
|
+
// Parse args
|
|
95
|
+
let title: string | undefined;
|
|
96
|
+
let Content: TDialogContentArg;
|
|
97
|
+
let paramsInit: TParams = {};
|
|
98
|
+
if (typeof args[0] === 'string') {
|
|
99
|
+
[title, Content, paramsInit] = args;
|
|
100
|
+
} else {
|
|
101
|
+
[Content, paramsInit] = args;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Set instance management function
|
|
85
105
|
const setDialog = isToast
|
|
86
106
|
? instance.setToasts
|
|
87
107
|
: instance.setModals;
|
|
88
108
|
|
|
109
|
+
// Close function
|
|
89
110
|
const close = (retour: TReturnType) => {
|
|
90
111
|
|
|
91
112
|
setDialog(q => q.filter(m => m.id !== id))
|
|
92
113
|
|
|
93
114
|
if (onClose !== undefined)
|
|
94
115
|
onClose(retour);
|
|
95
|
-
|
|
96
116
|
};
|
|
97
117
|
|
|
98
118
|
const promise = new Promise(async (resolve: TOnCloseCallback<TReturnType>) => {
|
|
@@ -101,33 +121,49 @@ export const createDialog = (app: Application, isToast: boolean): DialogActions
|
|
|
101
121
|
let render: ComponentChild;
|
|
102
122
|
let propsRendu: CardInfos = {
|
|
103
123
|
...paramsInit,
|
|
104
|
-
close: close
|
|
105
|
-
|
|
106
|
-
|
|
124
|
+
close: close
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
// modal.show( import('./modalSupprimer') )
|
|
128
|
+
// -> Fetch component
|
|
129
|
+
if (Content.constructor === Promise)
|
|
130
|
+
Content = (await Content).default;
|
|
131
|
+
|
|
132
|
+
// modal.show('Supprimer', import('./modalSupprimer'))
|
|
133
|
+
// -> Shortcut for modal.show({ title: 'Suoorimer', content: <Component> })
|
|
134
|
+
if (title !== undefined) {
|
|
135
|
+
Content = {
|
|
136
|
+
title: title,
|
|
137
|
+
content: Content
|
|
138
|
+
}
|
|
139
|
+
}
|
|
107
140
|
|
|
108
|
-
//
|
|
141
|
+
// modal.show({ title: 'supprimer', content: <>...</> })
|
|
109
142
|
if (Content.constructor === Object) {
|
|
110
143
|
|
|
111
|
-
const { content, ...propsToast } = Content as TOptsToast;
|
|
144
|
+
const { content: CardContent, data = {}, ...propsToast } = Content as TOptsToast;
|
|
145
|
+
|
|
146
|
+
let cardContent: ComponentChild;
|
|
147
|
+
if (typeof CardContent === 'function') {
|
|
148
|
+
cardContent = <CardContent {...propsRendu} {...data} />
|
|
149
|
+
propsToast.boutons = null; // Component content = advanced content = should include buttons
|
|
150
|
+
} else {
|
|
151
|
+
cardContent = CardContent;
|
|
152
|
+
}
|
|
153
|
+
|
|
112
154
|
render = (
|
|
113
|
-
<Card {...propsRendu}
|
|
155
|
+
<Card {...propsRendu} {...propsToast} isToast={isToast}>
|
|
156
|
+
{cardContent}
|
|
157
|
+
</Card>
|
|
114
158
|
)
|
|
115
159
|
|
|
116
|
-
//
|
|
117
|
-
//
|
|
160
|
+
// modal.show( ToastSupprimer )
|
|
161
|
+
// -> Content is a component rendering a Card
|
|
118
162
|
} else {
|
|
119
163
|
|
|
120
|
-
let DialogCard;
|
|
121
|
-
if (Content.constructor === Promise) {
|
|
122
|
-
DialogCard = (await Content).default;
|
|
123
|
-
} else {
|
|
124
|
-
DialogCard = Content as typeof Card;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
164
|
render = (
|
|
128
|
-
<
|
|
165
|
+
<Content {...propsRendu} isToast={isToast} />
|
|
129
166
|
)
|
|
130
|
-
|
|
131
167
|
}
|
|
132
168
|
|
|
133
169
|
// Chargeur de données
|
|
@@ -27,6 +27,7 @@ export type Props = {
|
|
|
27
27
|
cover?: string,
|
|
28
28
|
icon?: ComponentChild,
|
|
29
29
|
title?: string | ComponentChild,
|
|
30
|
+
className?: string,
|
|
30
31
|
|
|
31
32
|
children?: ComponentChild,
|
|
32
33
|
isToast?: boolean,
|
|
@@ -49,6 +50,7 @@ export default ({
|
|
|
49
50
|
cover,
|
|
50
51
|
icon,
|
|
51
52
|
title,
|
|
53
|
+
className = '',
|
|
52
54
|
|
|
53
55
|
children,
|
|
54
56
|
isToast,
|
|
@@ -149,7 +151,7 @@ export default ({
|
|
|
149
151
|
|
|
150
152
|
</div>
|
|
151
153
|
) : (
|
|
152
|
-
<div class={"card pd-2 col al-top"} style={width === undefined
|
|
154
|
+
<div class={"card pd-2 col al-top " + className} style={width === undefined
|
|
153
155
|
? {}
|
|
154
156
|
: { minWidth: width + "px", maxWidth: width + "px" }
|
|
155
157
|
}>
|
|
@@ -18,9 +18,7 @@ import type { TDialogControls } from '@client/components/dropdown';
|
|
|
18
18
|
|
|
19
19
|
export type Choice = { label: ComponentChild, value: string }
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
type ChoicesFunc = (search: string) => Promise<Choices>
|
|
21
|
+
type ChoicesFunc = (search: string) => Promise<Choice[]>
|
|
24
22
|
|
|
25
23
|
export type Props = (
|
|
26
24
|
{
|
|
@@ -37,10 +35,14 @@ export type Props = (
|
|
|
37
35
|
validator?: StringValidator
|
|
38
36
|
}
|
|
39
37
|
) & {
|
|
40
|
-
choices:
|
|
38
|
+
choices: Choice[] | ChoicesFunc | string[],
|
|
41
39
|
enableSearch?: boolean,
|
|
42
40
|
required?: boolean,
|
|
43
41
|
noneSelection?: false | string,
|
|
42
|
+
addNew?: (search?: string) => Promise<Choice>
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
type SelectorProps = Props & {
|
|
44
46
|
currentList: Choice[],
|
|
45
47
|
refDropdown?: RefObject<TDialogControls>
|
|
46
48
|
}
|
|
@@ -67,7 +69,7 @@ export default React.forwardRef<HTMLDivElement, Props>(({
|
|
|
67
69
|
currentList,
|
|
68
70
|
refDropdown,
|
|
69
71
|
...otherProps
|
|
70
|
-
}:
|
|
72
|
+
}: SelectorProps, ref) => {
|
|
71
73
|
|
|
72
74
|
|
|
73
75
|
|
|
@@ -8,6 +8,7 @@ import React from 'react';
|
|
|
8
8
|
// Core
|
|
9
9
|
import { Props as DropdownProps } from '@client/components/dropdown';
|
|
10
10
|
import { Popover, Button, Input } from '@client/components';
|
|
11
|
+
import { InputWrapper, InputBaseProps } from '@client/components/inputv3/base';
|
|
11
12
|
|
|
12
13
|
// Specific
|
|
13
14
|
import {
|
|
@@ -21,10 +22,8 @@ import ChoiceElement from './ChoiceElement';
|
|
|
21
22
|
- TYPES
|
|
22
23
|
----------------------------------*/
|
|
23
24
|
|
|
24
|
-
export type Props = SelectorProps & {
|
|
25
|
-
dropdown
|
|
26
|
-
title: string,
|
|
27
|
-
errors?: string[],
|
|
25
|
+
export type Props = SelectorProps & Omit<InputBaseProps<Choice>, 'value'> & {
|
|
26
|
+
dropdown?: boolean | DropdownProps,
|
|
28
27
|
}
|
|
29
28
|
|
|
30
29
|
export type { Choice } from './ChoiceSelector';
|
|
@@ -51,24 +50,28 @@ const ensureChoice = (choice: Choice | string, choices: Choice[]): Choice => {
|
|
|
51
50
|
/*----------------------------------
|
|
52
51
|
- COMONENT
|
|
53
52
|
----------------------------------*/
|
|
54
|
-
export default ({
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
53
|
+
export default (props: Props) => {
|
|
54
|
+
|
|
55
|
+
let {
|
|
56
|
+
// Input basics
|
|
57
|
+
title,
|
|
58
|
+
errors,
|
|
59
|
+
icon,
|
|
60
|
+
required,
|
|
61
|
+
validator,
|
|
62
|
+
wrapper = true,
|
|
63
|
+
|
|
64
|
+
// Choice selection
|
|
65
|
+
choices: initChoices,
|
|
66
|
+
noneSelection,
|
|
67
|
+
enableSearch,
|
|
68
|
+
value: current,
|
|
69
|
+
onChange: onChangeCallback,
|
|
70
|
+
multiple,
|
|
71
|
+
dropdown,
|
|
72
|
+
addNew,
|
|
73
|
+
...otherProps
|
|
74
|
+
} = props;
|
|
72
75
|
|
|
73
76
|
/*----------------------------------
|
|
74
77
|
- INIT
|
|
@@ -77,8 +80,10 @@ export default ({
|
|
|
77
80
|
const popoverState = React.useState(false);
|
|
78
81
|
|
|
79
82
|
const choicesViaFunc = typeof initChoices === 'function';
|
|
80
|
-
if (choicesViaFunc
|
|
83
|
+
if (choicesViaFunc)
|
|
81
84
|
enableSearch = true;
|
|
85
|
+
else if (typeof initChoices[0] === 'string')
|
|
86
|
+
initChoices = initChoices.map( c => ({ label: c, value: c }));
|
|
82
87
|
|
|
83
88
|
const refInputSearch = React.useRef<HTMLInputElement | null>(null);
|
|
84
89
|
|
|
@@ -144,6 +149,17 @@ export default ({
|
|
|
144
149
|
}
|
|
145
150
|
}
|
|
146
151
|
|
|
152
|
+
const clickAddNew = () => addNew(search.keywords).then( newItem => {
|
|
153
|
+
|
|
154
|
+
if (!newItem)
|
|
155
|
+
return;
|
|
156
|
+
|
|
157
|
+
onChange( current => multiple
|
|
158
|
+
? [...(current || []), newItem]
|
|
159
|
+
: newItem
|
|
160
|
+
)
|
|
161
|
+
})
|
|
162
|
+
|
|
147
163
|
/*----------------------------------
|
|
148
164
|
- RENDER
|
|
149
165
|
----------------------------------*/
|
|
@@ -152,126 +168,142 @@ export default ({
|
|
|
152
168
|
|
|
153
169
|
const Search = enableSearch && (
|
|
154
170
|
<Input
|
|
171
|
+
icon="search"
|
|
155
172
|
placeholder="Type your search here"
|
|
156
173
|
value={search.keywords}
|
|
157
174
|
onChange={keywords => setSearch(s => ({ ...s, loading: true, keywords }))}
|
|
158
175
|
inputRef={refInputSearch}
|
|
176
|
+
wrapper={false}
|
|
177
|
+
className="bg white"
|
|
159
178
|
/>
|
|
160
179
|
)
|
|
161
180
|
|
|
162
|
-
return
|
|
163
|
-
<
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
{selectedItems.length !== 0 && (
|
|
171
|
-
<ul class="row al-left wrap sp-05">
|
|
172
|
-
{selectedItems.map( choice => (
|
|
173
|
-
<ChoiceElement format='badge' choice={choice}
|
|
174
|
-
currentList={currentList}
|
|
175
|
-
onChange={onChange}
|
|
176
|
-
multiple={multiple}
|
|
177
|
-
includeCurrent
|
|
178
|
-
/>
|
|
179
|
-
))}
|
|
180
|
-
</ul>
|
|
181
|
-
)}
|
|
182
|
-
|
|
183
|
-
{search.loading ? (
|
|
184
|
-
<div class="row al-center h-2">
|
|
185
|
-
<i src="spin" />
|
|
186
|
-
</div>
|
|
187
|
-
) : (
|
|
188
|
-
<ul class="menu col">
|
|
189
|
-
{choices.map( choice => (
|
|
190
|
-
<ChoiceElement format='list' choice={choice}
|
|
191
|
-
currentList={currentList}
|
|
192
|
-
onChange={onChange}
|
|
193
|
-
multiple={multiple}
|
|
194
|
-
includeCurrent
|
|
195
|
-
/>
|
|
196
|
-
))}
|
|
197
|
-
</ul>
|
|
198
|
-
)}
|
|
199
|
-
</div>
|
|
200
|
-
)} state={popoverState}>
|
|
201
|
-
<Button type="secondary" icon={icon} iconR="chevron-down" {...otherProps}>
|
|
202
|
-
|
|
203
|
-
{currentList.length === 0 ? <>
|
|
204
|
-
{title}
|
|
205
|
-
</> : multiple ? <>
|
|
206
|
-
{title} <span class="badge s bg accent">{currentList.length}</span>
|
|
207
|
-
</> : <>
|
|
208
|
-
{currentList[0].label}
|
|
209
|
-
</>}
|
|
210
|
-
|
|
211
|
-
{errors?.length && (
|
|
212
|
-
<div class="bubble bg error bottom">
|
|
213
|
-
{errors.join('. ')}
|
|
214
|
-
</div>
|
|
215
|
-
)}
|
|
216
|
-
|
|
217
|
-
</Button>
|
|
218
|
-
</Popover>
|
|
219
|
-
) : (
|
|
220
|
-
|
|
221
|
-
<div class="col sp-05">
|
|
222
|
-
<div class={className} onMouseDown={() => refInputSearch.current?.focus()}>
|
|
223
|
-
|
|
224
|
-
<div class="row al-left wrap pd-1">
|
|
225
|
-
|
|
226
|
-
{icon !== undefined && (
|
|
227
|
-
<i src={icon} />
|
|
228
|
-
)}
|
|
181
|
+
return (
|
|
182
|
+
<InputWrapper {...props}>
|
|
183
|
+
{dropdown ? (
|
|
184
|
+
<Popover {...(dropdown === true ? {
|
|
185
|
+
width: '200px',
|
|
186
|
+
} : dropdown)} content={(
|
|
187
|
+
<div class="bg white col al-top">
|
|
229
188
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
<label>{title}{isRequired && (
|
|
233
|
-
<span class="fg error"> *</span>
|
|
234
|
-
)}</label>
|
|
235
|
-
|
|
236
|
-
<div class="row al-left wrap sp-05">
|
|
237
|
-
|
|
238
|
-
{selectedItems.map( choice => (
|
|
239
|
-
<ChoiceElement format='badge' choice={choice}
|
|
240
|
-
currentList={currentList}
|
|
241
|
-
onChange={onChange}
|
|
242
|
-
multiple={multiple}
|
|
243
|
-
includeCurrent
|
|
244
|
-
/>
|
|
245
|
-
))}
|
|
246
|
-
|
|
247
|
-
{Search}
|
|
189
|
+
<div class="bb-1" style={{ position: 'sticky', top: 0, zIndex: 5 }}>
|
|
190
|
+
{Search}
|
|
248
191
|
</div>
|
|
192
|
+
|
|
193
|
+
{(multiple && selectedItems.length !== 0) && (
|
|
194
|
+
<ul class="row al-left wrap sp-05">
|
|
195
|
+
{selectedItems.map( choice => (
|
|
196
|
+
<ChoiceElement format='badge' choice={choice}
|
|
197
|
+
currentList={currentList}
|
|
198
|
+
onChange={onChange}
|
|
199
|
+
multiple={multiple}
|
|
200
|
+
includeCurrent
|
|
201
|
+
/>
|
|
202
|
+
))}
|
|
203
|
+
</ul>
|
|
204
|
+
)}
|
|
205
|
+
|
|
206
|
+
{search.loading ? (
|
|
207
|
+
<div class="row al-center h-2">
|
|
208
|
+
<i src="spin" />
|
|
209
|
+
</div>
|
|
210
|
+
) : (
|
|
211
|
+
<ul class="menu col">
|
|
212
|
+
{choices.map( choice => (
|
|
213
|
+
<ChoiceElement format='list' choice={choice}
|
|
214
|
+
currentList={currentList}
|
|
215
|
+
onChange={onChange}
|
|
216
|
+
multiple={multiple}
|
|
217
|
+
includeCurrent
|
|
218
|
+
/>
|
|
219
|
+
))}
|
|
220
|
+
</ul>
|
|
221
|
+
)}
|
|
222
|
+
|
|
223
|
+
{addNew && (
|
|
224
|
+
<div class="col" style={{ position: 'sticky', bottom: '0px', zIndex: 5 }}>
|
|
225
|
+
<Button type="primary" icon="plus" onClick={clickAddNew}>
|
|
226
|
+
Add new
|
|
227
|
+
</Button>
|
|
228
|
+
</div>
|
|
229
|
+
)}
|
|
249
230
|
</div>
|
|
231
|
+
)} state={popoverState}>
|
|
232
|
+
<Button type="secondary" icon={icon} iconR="chevron-down" {...otherProps}>
|
|
233
|
+
|
|
234
|
+
{currentList.length === 0 ? <>
|
|
235
|
+
{title}
|
|
236
|
+
</> : multiple ? <>
|
|
237
|
+
{title} <span class="badge s bg accent">{currentList.length}</span>
|
|
238
|
+
</> : <>
|
|
239
|
+
{currentList[0].label}
|
|
240
|
+
</>}
|
|
241
|
+
|
|
242
|
+
{errors?.length && (
|
|
243
|
+
<div class="bubble bg error bottom">
|
|
244
|
+
{errors.join('. ')}
|
|
245
|
+
</div>
|
|
246
|
+
)}
|
|
247
|
+
|
|
248
|
+
</Button>
|
|
249
|
+
</Popover>
|
|
250
|
+
) : (
|
|
251
|
+
<div class="col sp-05">
|
|
252
|
+
<div class={className} onMouseDown={() => refInputSearch.current?.focus()}>
|
|
253
|
+
|
|
254
|
+
<div class="row al-left wrap pd-1">
|
|
255
|
+
|
|
256
|
+
{icon !== undefined && (
|
|
257
|
+
<i src={icon} />
|
|
258
|
+
)}
|
|
259
|
+
|
|
260
|
+
<div class="col al-left sp-05">
|
|
261
|
+
|
|
262
|
+
<label>{title}{isRequired && (
|
|
263
|
+
<span class="fg error"> *</span>
|
|
264
|
+
)}</label>
|
|
265
|
+
|
|
266
|
+
<div class="row al-left wrap sp-05">
|
|
267
|
+
|
|
268
|
+
{selectedItems.map( choice => (
|
|
269
|
+
<ChoiceElement format='badge' choice={choice}
|
|
270
|
+
currentList={currentList}
|
|
271
|
+
onChange={onChange}
|
|
272
|
+
multiple={multiple}
|
|
273
|
+
includeCurrent
|
|
274
|
+
/>
|
|
275
|
+
))}
|
|
276
|
+
|
|
277
|
+
{Search}
|
|
278
|
+
</div>
|
|
279
|
+
</div>
|
|
250
280
|
|
|
251
|
-
|
|
281
|
+
</div>
|
|
252
282
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
283
|
+
<div class="pd-1">
|
|
284
|
+
<ul class="row al-left wrap sp-05" style={{
|
|
285
|
+
maxHeight: '30vh',
|
|
286
|
+
overflowY: 'auto'
|
|
287
|
+
}}>
|
|
288
|
+
{choices.map( choice => (
|
|
289
|
+
<ChoiceElement format='badge' choice={choice}
|
|
290
|
+
currentList={currentList}
|
|
291
|
+
onChange={onChange}
|
|
292
|
+
multiple={multiple}
|
|
293
|
+
includeCurrent
|
|
294
|
+
/>
|
|
295
|
+
))}
|
|
296
|
+
</ul>
|
|
297
|
+
</div>
|
|
298
|
+
|
|
299
|
+
</div>
|
|
300
|
+
{errors?.length && (
|
|
301
|
+
<div class="bubble bg error bottom">
|
|
302
|
+
{errors.join('. ')}
|
|
303
|
+
</div>
|
|
304
|
+
)}
|
|
273
305
|
</div>
|
|
274
306
|
)}
|
|
275
|
-
</
|
|
307
|
+
</InputWrapper>
|
|
276
308
|
)
|
|
277
309
|
}
|
|
@@ -27,4 +27,5 @@ export { default as Select } from './Select';
|
|
|
27
27
|
export { default as Input } from './inputv3';
|
|
28
28
|
export { default as Checkbox } from './inputv3/Checkbox';
|
|
29
29
|
export { default as File } from './inputv3/file';
|
|
30
|
-
export { default as DateRangeInput } from './inputv3/Date';
|
|
30
|
+
export { default as DateRangeInput } from './inputv3/Date';
|
|
31
|
+
export { default as Rte } from './inputv3/Rte';
|