pixel-react 1.1.1 → 1.1.3
Sign up to get free protection for your applications and to get access to all the features.
- package/.yarn/install-state.gz +0 -0
- package/lib/components/Charts/DashboardDonutChart/DashboardDonutChart.d.ts +5 -0
- package/lib/components/Charts/DashboardDonutChart/DashboardDonutChart.stories.d.ts +7 -0
- package/lib/components/Charts/DashboardDonutChart/index.d.ts +1 -0
- package/lib/components/Charts/DashboardDonutChart/types.d.ts +21 -0
- package/lib/components/Charts/PieChart/PieChart.d.ts +5 -0
- package/lib/components/Charts/PieChart/PieChart.stories.d.ts +7 -0
- package/lib/components/Charts/PieChart/index.d.ts +1 -0
- package/lib/components/Charts/PieChart/types.d.ts +27 -0
- package/lib/components/MultiSelect/MultiSelect.d.ts +1 -1
- package/lib/components/MultiSelect/MultiSelectTypes.d.ts +1 -1
- package/lib/components/NLPInput/NlpInput.d.ts +4 -0
- package/lib/components/NLPInput/NlpInput.stories.d.ts +7 -0
- package/lib/components/NLPInput/components/NlpDropDown/NlpDropDownType.d.ts +19 -0
- package/lib/components/NLPInput/components/NlpDropDown/NlpDropdown.d.ts +4 -0
- package/lib/components/NLPInput/index.d.ts +1 -0
- package/lib/components/NLPInput/type.d.ts +70 -0
- package/lib/components/Paper/Paper.d.ts +4 -0
- package/lib/components/Paper/Paper.stories.d.ts +11 -0
- package/lib/components/Paper/index.d.ts +1 -0
- package/lib/components/Paper/types.d.ts +15 -0
- package/lib/components/Table/Table.d.ts +1 -1
- package/lib/components/VariableInput/VariableInput.d.ts +4 -0
- package/lib/components/VariableInput/VariableInput.stories.d.ts +6 -0
- package/lib/components/VariableInput/index.d.ts +1 -0
- package/lib/components/VariableInput/types.d.ts +53 -0
- package/lib/index.css +404 -0
- package/lib/index.d.ts +187 -18
- package/lib/index.esm.css +404 -0
- package/lib/index.esm.js +7040 -762
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +7052 -761
- package/lib/index.js.map +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/lib/utils/ffID/ffID.stories.d.ts +1 -1
- package/lib/utils/ffID/ffid.d.ts +1 -2
- package/lib/utils/findAndInsert/findAndInsert.d.ts +7 -0
- package/lib/utils/findAndInsert/findAndInsert.stories.d.ts +7 -0
- package/lib/utils/getEncryptedData/getEncryptedData.d.ts +1 -0
- package/lib/utils/getEncryptedData/getEncryptedData.stories.d.ts +6 -0
- package/package.json +2 -1
- package/rollup.config.mjs +8 -2
- package/src/StyleGuide/ColorPalette/ColorPalette.tsx +2 -4
- package/src/StyleGuide/ColorPalette/colorPaletteList.ts +95 -20
- package/src/assets/Themes/BaseTheme.scss +4 -3
- package/src/assets/Themes/DarkTheme.scss +11 -8
- package/src/assets/icons/wswb_delete_icon.svg +4 -0
- package/src/assets/icons/wswb_plus_icon.svg +5 -0
- package/src/components/AllProjectsDropdown/AllProjectsDropdown.tsx +1 -1
- package/src/components/Button/index.ts +1 -1
- package/src/components/Charts/DashboardDonutChart/DashboardDonutChart.scss +145 -0
- package/src/components/Charts/DashboardDonutChart/DashboardDonutChart.stories.tsx +52 -0
- package/src/components/Charts/DashboardDonutChart/DashboardDonutChart.tsx +335 -0
- package/src/components/Charts/DashboardDonutChart/index.ts +1 -0
- package/src/components/Charts/DashboardDonutChart/types.ts +33 -0
- package/src/components/Charts/PieChart/PieChart.scss +39 -0
- package/src/components/Charts/PieChart/PieChart.stories.tsx +46 -0
- package/src/components/Charts/PieChart/PieChart.tsx +193 -0
- package/src/components/Charts/PieChart/index.ts +1 -0
- package/src/components/Charts/PieChart/types.ts +28 -0
- package/src/components/Icon/iconList.ts +6 -0
- package/src/components/Modal/modal.scss +1 -1
- package/src/components/MultiSelect/MultiSelect.stories.tsx +2 -3
- package/src/components/MultiSelect/MultiSelect.tsx +35 -23
- package/src/components/MultiSelect/MultiSelectTypes.ts +1 -1
- package/src/components/NLPInput/NLPInput.scss +246 -0
- package/src/components/NLPInput/NlpInput.stories.tsx +136 -0
- package/src/components/NLPInput/NlpInput.tsx +374 -0
- package/src/components/NLPInput/components/NlpDropDown/NlpDropDownType.ts +60 -0
- package/src/components/NLPInput/components/NlpDropDown/NlpDropdown.scss +83 -0
- package/src/components/NLPInput/components/NlpDropDown/NlpDropdown.tsx +180 -0
- package/src/components/NLPInput/index.ts +1 -0
- package/src/components/NLPInput/type.tsx +124 -0
- package/src/components/Paper/Paper.scss +13 -0
- package/src/components/Paper/Paper.stories.tsx +77 -0
- package/src/components/Paper/Paper.tsx +14 -0
- package/src/components/Paper/index.ts +1 -0
- package/src/components/Paper/types.ts +19 -0
- package/src/components/Select/components/Dropdown/Dropdown.tsx +1 -1
- package/src/components/Table/Table.scss +5 -0
- package/src/components/Table/Table.stories.tsx +12 -0
- package/src/components/Table/Table.tsx +25 -14
- package/src/components/TextArea/Textarea.scss +1 -1
- package/src/components/VariableInput/VariableInput.scss +128 -0
- package/src/components/VariableInput/VariableInput.stories.tsx +32 -0
- package/src/components/VariableInput/VariableInput.tsx +352 -0
- package/src/components/VariableInput/index.ts +1 -0
- package/src/components/VariableInput/types.ts +56 -0
- package/src/index.ts +32 -2
- package/src/utils/ffID/ffID.stories.tsx +1 -1
- package/src/utils/ffID/ffid.ts +1 -3
- package/src/utils/getEncryptedData/getEncryptedData.stories.tsx +55 -0
- package/src/utils/getEncryptedData/getEncryptedData.ts +8 -0
- package/lib/components/AddButton/AddButton.d.ts +0 -5
- package/lib/components/AddButton/AddButton.stories.d.ts +0 -6
- package/lib/components/AddButton/index.d.ts +0 -1
- package/lib/components/AddButton/types.d.ts +0 -4
- /package/src/utils/{find → findAndInsert}/findAndInsert.stories.tsx +0 -0
- /package/src/utils/{find → findAndInsert}/findAndInsert.ts +0 -0
@@ -0,0 +1,352 @@
|
|
1
|
+
import classNames from 'classnames';
|
2
|
+
import React, { useState, useRef, useEffect } from 'react';
|
3
|
+
import './VariableInput.scss';
|
4
|
+
import { VariableInputProps } from './types';
|
5
|
+
import Typography from '../Typography';
|
6
|
+
|
7
|
+
interface ParsedPart {
|
8
|
+
text: string;
|
9
|
+
textType: string;
|
10
|
+
}
|
11
|
+
|
12
|
+
const VariableInput = ({
|
13
|
+
type = 'url',
|
14
|
+
name = '',
|
15
|
+
label,
|
16
|
+
disabled = false,
|
17
|
+
required = false,
|
18
|
+
placeholder = '',
|
19
|
+
value = '',
|
20
|
+
error,
|
21
|
+
className = '',
|
22
|
+
onChange,
|
23
|
+
onKeyDown,
|
24
|
+
onBlur,
|
25
|
+
onFocus,
|
26
|
+
list=[],
|
27
|
+
...props
|
28
|
+
}: VariableInputProps) => {
|
29
|
+
const [inputValue, setInputValue] = useState<string>('');
|
30
|
+
const [cursorPosition, setCursorPosition] = useState<number>(0);
|
31
|
+
const [isAddingText, setIsAddingText] = useState<boolean>(true);
|
32
|
+
const [suggestions, setSuggestions] = useState<string[]>([]);
|
33
|
+
const [showSuggestions, setShowSuggestions] = useState<boolean>(false);
|
34
|
+
const contentEditableRef = useRef<HTMLDivElement>(null);
|
35
|
+
const undoStack = useRef<string[]>([]);
|
36
|
+
const redoStack = useRef<string[]>([]);
|
37
|
+
|
38
|
+
useEffect(() => {
|
39
|
+
if (value) {
|
40
|
+
setInputValue(value);
|
41
|
+
}
|
42
|
+
}, [value]);
|
43
|
+
|
44
|
+
const parseUrl = (url: string): ParsedPart[] => {
|
45
|
+
const regex = /\$\{(\w+)\}/g; //checking the text variable or not
|
46
|
+
const parts: ParsedPart[] = [];
|
47
|
+
let lastIndex = 0;
|
48
|
+
let match;
|
49
|
+
|
50
|
+
while ((match = regex.exec(url)) !== null) {
|
51
|
+
const [fullMatch, variable] = match;
|
52
|
+
const isInList = list?.includes(variable ?? '');
|
53
|
+
|
54
|
+
if (match.index > lastIndex) {
|
55
|
+
parts.push({ text: url.slice(lastIndex, match.index), textType: 'normal' });
|
56
|
+
}
|
57
|
+
|
58
|
+
parts.push({
|
59
|
+
text: fullMatch,
|
60
|
+
textType: isInList ? 'variable' : 'nonVariable',
|
61
|
+
});
|
62
|
+
|
63
|
+
lastIndex = match.index + fullMatch.length;
|
64
|
+
}
|
65
|
+
|
66
|
+
if (lastIndex < url.length) {
|
67
|
+
parts.push({ text: url.slice(lastIndex), textType: 'normal' });
|
68
|
+
}
|
69
|
+
|
70
|
+
return parts;
|
71
|
+
};
|
72
|
+
|
73
|
+
const updateContentEditable = () => {
|
74
|
+
const parsedParts = parseUrl(inputValue);
|
75
|
+
const contentEditableElement = contentEditableRef.current;
|
76
|
+
|
77
|
+
if (contentEditableElement) {
|
78
|
+
contentEditableElement.innerHTML = parsedParts
|
79
|
+
.map((part) => {
|
80
|
+
const varClassName = classNames({
|
81
|
+
['ff_var_red']: part.textType === 'nonVariable',
|
82
|
+
['ff_var_green']: part.textType === 'variable',
|
83
|
+
['ff_var_def_textType']:
|
84
|
+
part.textType !== 'nonVariable' && part.textType !== 'variable',
|
85
|
+
});
|
86
|
+
|
87
|
+
return `<Typography class="${varClassName}">${part.text}</Typography>`;
|
88
|
+
})
|
89
|
+
.join('');
|
90
|
+
restoreCursorPosition(contentEditableElement);
|
91
|
+
}
|
92
|
+
};
|
93
|
+
|
94
|
+
const restoreCursorPosition = (element: HTMLDivElement) => {
|
95
|
+
const selection = window.getSelection();
|
96
|
+
const range = document.createRange();
|
97
|
+
const textNodes = getTextNodes(element);
|
98
|
+
|
99
|
+
if (textNodes.length > 0) {
|
100
|
+
const lastNode = textNodes[textNodes.length - 1];
|
101
|
+
const positionAdjustment = isAddingText ? 1 : -1;
|
102
|
+
|
103
|
+
const newOffset = Math.max(
|
104
|
+
0,
|
105
|
+
Math.min(
|
106
|
+
cursorPosition + positionAdjustment,
|
107
|
+
(lastNode as Text).length || 0
|
108
|
+
)
|
109
|
+
);
|
110
|
+
if (lastNode) {
|
111
|
+
range.setStart(lastNode, newOffset);
|
112
|
+
}
|
113
|
+
range.collapse(true);
|
114
|
+
} else {
|
115
|
+
range.selectNodeContents(element);
|
116
|
+
range.collapse(false);
|
117
|
+
}
|
118
|
+
|
119
|
+
selection?.removeAllRanges();
|
120
|
+
selection?.addRange(range);
|
121
|
+
element.focus();
|
122
|
+
};
|
123
|
+
|
124
|
+
const getTextNodes = (element: HTMLDivElement): Node[] => {
|
125
|
+
const nodes: Node[] = [];
|
126
|
+
const walker = document.createTreeWalker(
|
127
|
+
element,
|
128
|
+
NodeFilter.SHOW_TEXT,
|
129
|
+
null
|
130
|
+
);
|
131
|
+
let node;
|
132
|
+
while ((node = walker.nextNode())) {
|
133
|
+
nodes.push(node);
|
134
|
+
}
|
135
|
+
return nodes;
|
136
|
+
};
|
137
|
+
|
138
|
+
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
139
|
+
const text = e.currentTarget.innerText.split('\n').join('');
|
140
|
+
setInputValue(text);
|
141
|
+
undoStack.current.push(text);
|
142
|
+
redoStack.current = [];
|
143
|
+
|
144
|
+
if (required && !text.trim()) {
|
145
|
+
e.currentTarget.classList.add('ff_required_empty');
|
146
|
+
} else {
|
147
|
+
e.currentTarget.classList.remove('ff_required_empty');
|
148
|
+
}
|
149
|
+
|
150
|
+
if (type === 'url') {
|
151
|
+
const urlPattern = new RegExp(
|
152
|
+
'^(https?://)?([\\w.-]+)\\.([a-zA-Z]{2,})(/([\\w.-]+|\\$\\{[\\w.-]+\\}))*/?$'
|
153
|
+
);
|
154
|
+
|
155
|
+
if (!urlPattern.test(text)) {
|
156
|
+
e.currentTarget.classList.add('ff_invalid_input');
|
157
|
+
} else {
|
158
|
+
e.currentTarget.classList.remove('ff_invalid_input');
|
159
|
+
e.currentTarget.classList.remove('ff_required_empty');
|
160
|
+
}
|
161
|
+
} else {
|
162
|
+
e.currentTarget.classList.add('ff_invalid_input');
|
163
|
+
}
|
164
|
+
|
165
|
+
if (onChange) {
|
166
|
+
onChange(text);
|
167
|
+
}
|
168
|
+
|
169
|
+
const match = /\$\{(\w*)$/.exec(text);
|
170
|
+
if (match) {
|
171
|
+
const query = match[1];
|
172
|
+
const filteredSuggestions = list?.filter((item: string) =>
|
173
|
+
item.startsWith(query ?? '')
|
174
|
+
);
|
175
|
+
setSuggestions(filteredSuggestions);
|
176
|
+
setShowSuggestions(true);
|
177
|
+
} else {
|
178
|
+
setShowSuggestions(false);
|
179
|
+
}
|
180
|
+
};
|
181
|
+
|
182
|
+
const handleKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {
|
183
|
+
const cursorPos = getCursorPosition();
|
184
|
+
setCursorPosition(cursorPos);
|
185
|
+
setIsAddingText(true);
|
186
|
+
|
187
|
+
const currentText = contentEditableRef.current
|
188
|
+
? contentEditableRef.current.textContent || ''
|
189
|
+
: '';
|
190
|
+
|
191
|
+
if (e.key === 'Backspace' || e.key === 'Delete') {
|
192
|
+
setIsAddingText(false);
|
193
|
+
if (!currentText.trim()) {
|
194
|
+
e.preventDefault();
|
195
|
+
if (contentEditableRef.current) {
|
196
|
+
contentEditableRef.current.textContent = '';
|
197
|
+
contentEditableRef.current.blur();
|
198
|
+
}
|
199
|
+
return;
|
200
|
+
}
|
201
|
+
}
|
202
|
+
|
203
|
+
if (e.key === 'Enter') {
|
204
|
+
e.preventDefault();
|
205
|
+
insertTextAtCursor('\n');
|
206
|
+
} else if (e.ctrlKey && e.key === 'z') {
|
207
|
+
e.preventDefault();
|
208
|
+
undo();
|
209
|
+
} else if (e.ctrlKey && e.key === 'y') {
|
210
|
+
e.preventDefault();
|
211
|
+
redo();
|
212
|
+
}
|
213
|
+
|
214
|
+
if (onKeyDown) {
|
215
|
+
onKeyDown(e as React.KeyboardEvent<HTMLInputElement>);
|
216
|
+
}
|
217
|
+
};
|
218
|
+
|
219
|
+
const getCursorPosition = (): number => {
|
220
|
+
const selection = window.getSelection();
|
221
|
+
if (selection && selection.rangeCount > 0) {
|
222
|
+
const range = selection.getRangeAt(0);
|
223
|
+
return range.startOffset;
|
224
|
+
}
|
225
|
+
return 0;
|
226
|
+
};
|
227
|
+
|
228
|
+
const undo = () => {
|
229
|
+
if (undoStack.current.length > 1) {
|
230
|
+
redoStack.current.push(undoStack.current.pop()!);
|
231
|
+
setInputValue(undoStack.current[undoStack.current.length - 1] ?? '');
|
232
|
+
setIsAddingText(false);
|
233
|
+
}
|
234
|
+
};
|
235
|
+
|
236
|
+
const redo = () => {
|
237
|
+
if (redoStack.current.length > 0) {
|
238
|
+
const textToRedo = redoStack.current.pop()!;
|
239
|
+
setInputValue(textToRedo);
|
240
|
+
undoStack.current.push(textToRedo);
|
241
|
+
setIsAddingText(true);
|
242
|
+
}
|
243
|
+
};
|
244
|
+
|
245
|
+
const insertTextAtCursor = (text: string) => {
|
246
|
+
const selection = window.getSelection();
|
247
|
+
const range = selection?.getRangeAt(0);
|
248
|
+
if (range) {
|
249
|
+
range.deleteContents();
|
250
|
+
const newTextNode = document.createTextNode(text);
|
251
|
+
range.insertNode(newTextNode);
|
252
|
+
|
253
|
+
const lineBreak = document.createElement('br');
|
254
|
+
range.insertNode(lineBreak);
|
255
|
+
|
256
|
+
range.setStartAfter(lineBreak);
|
257
|
+
range.collapse(true);
|
258
|
+
|
259
|
+
selection?.removeAllRanges();
|
260
|
+
selection?.addRange(range);
|
261
|
+
contentEditableRef.current?.focus();
|
262
|
+
setInputValue(contentEditableRef.current?.innerText || '');
|
263
|
+
}
|
264
|
+
};
|
265
|
+
|
266
|
+
const handleSuggestionClick = (suggestion: string) => {
|
267
|
+
const newText = inputValue.replace(/\$\{\w*$/, `\$\{${suggestion}`);
|
268
|
+
setInputValue(newText);
|
269
|
+
setShowSuggestions(false);
|
270
|
+
};
|
271
|
+
|
272
|
+
useEffect(() => {
|
273
|
+
updateContentEditable();
|
274
|
+
}, [inputValue]);
|
275
|
+
|
276
|
+
const inputClasses = classNames('ff_content_editable', {
|
277
|
+
['ff_placeholder']: !inputValue,
|
278
|
+
['ff_disabled']: disabled,
|
279
|
+
['ff_required']: required,
|
280
|
+
['ff_invalid_input']: error,
|
281
|
+
});
|
282
|
+
|
283
|
+
return (
|
284
|
+
<div className={'ff_variable_input_container'}>
|
285
|
+
{label && (
|
286
|
+
<label
|
287
|
+
htmlFor={name}
|
288
|
+
className={classNames('ff_label_container', {
|
289
|
+
['ff_labelDanger']: error,
|
290
|
+
})}
|
291
|
+
>
|
292
|
+
{required && (
|
293
|
+
<Typography className={'ff_required_asterisk'}>*</Typography>
|
294
|
+
)}
|
295
|
+
<Typography
|
296
|
+
className={classNames('ff_input_label', {
|
297
|
+
['ff_no_hover']: value,
|
298
|
+
['ff_disabled_label']: disabled,
|
299
|
+
['ff_danger_label']: error,
|
300
|
+
})}
|
301
|
+
>
|
302
|
+
{label}
|
303
|
+
</Typography>
|
304
|
+
</label>
|
305
|
+
)}
|
306
|
+
<div
|
307
|
+
id={name}
|
308
|
+
contentEditable={!disabled}
|
309
|
+
ref={contentEditableRef}
|
310
|
+
onInput={handleInputChange}
|
311
|
+
onKeyDown={handleKeyDown}
|
312
|
+
onFocus={(e) => {
|
313
|
+
e.currentTarget.style.outline = 'none';
|
314
|
+
if (onFocus) onFocus(e as React.FocusEvent<HTMLInputElement>);
|
315
|
+
}}
|
316
|
+
onBlur={(e) => {
|
317
|
+
e.currentTarget.style.outline = 'none';
|
318
|
+
if (onBlur) onBlur(e as React.FocusEvent<HTMLInputElement>);
|
319
|
+
|
320
|
+
if (required && !inputValue.trim()) {
|
321
|
+
e.currentTarget.classList.add('ff_required_empty');
|
322
|
+
} else {
|
323
|
+
e.currentTarget.classList.remove('ff_required_empty');
|
324
|
+
}
|
325
|
+
}}
|
326
|
+
className={inputClasses}
|
327
|
+
suppressContentEditableWarning
|
328
|
+
aria-required={required ? 'true' : 'false'}
|
329
|
+
data-name={name}
|
330
|
+
data-type={type}
|
331
|
+
data-placeholder={placeholder}
|
332
|
+
spellCheck={false}
|
333
|
+
{...props}
|
334
|
+
/>
|
335
|
+
{showSuggestions && (
|
336
|
+
<ul className={'ff_suggestions'}>
|
337
|
+
{suggestions.map((suggestion) => (
|
338
|
+
<li
|
339
|
+
key={suggestion}
|
340
|
+
onClick={() => handleSuggestionClick(suggestion)}
|
341
|
+
className={'ff_suggestion_item'}
|
342
|
+
>
|
343
|
+
{suggestion}
|
344
|
+
</li>
|
345
|
+
))}
|
346
|
+
</ul>
|
347
|
+
)}
|
348
|
+
</div>
|
349
|
+
);
|
350
|
+
};
|
351
|
+
|
352
|
+
export default VariableInput;
|
@@ -0,0 +1 @@
|
|
1
|
+
export {default} from './VariableInput'
|
@@ -0,0 +1,56 @@
|
|
1
|
+
export interface VariableInputProps {
|
2
|
+
/**
|
3
|
+
* Name | name of the input field
|
4
|
+
*/
|
5
|
+
name: string;
|
6
|
+
/**
|
7
|
+
* Label | field label to be displayed
|
8
|
+
*/
|
9
|
+
label: string;
|
10
|
+
/**
|
11
|
+
* value | input field value
|
12
|
+
*/
|
13
|
+
value: string | null;
|
14
|
+
/**
|
15
|
+
* type to set color/style of the input field
|
16
|
+
*/
|
17
|
+
type: 'text' | 'password' | 'number' | 'email' | 'url' | 'time';
|
18
|
+
/**
|
19
|
+
* error | If true, error message will be displayed
|
20
|
+
*/
|
21
|
+
error?: boolean;
|
22
|
+
/**
|
23
|
+
* to disable the input field
|
24
|
+
*/
|
25
|
+
disabled?: boolean;
|
26
|
+
/**
|
27
|
+
* if true, input field will be mandatory
|
28
|
+
*/
|
29
|
+
required?: boolean;
|
30
|
+
/**
|
31
|
+
* placeholder for the input field
|
32
|
+
*/
|
33
|
+
placeholder?: string;
|
34
|
+
/**
|
35
|
+
* classnames to style the input field
|
36
|
+
*/
|
37
|
+
className?: string;
|
38
|
+
/**
|
39
|
+
* onChange, onKeyDown, onBlur, onFocus actions
|
40
|
+
*/
|
41
|
+
onChange?: (value: string) => void | undefined;
|
42
|
+
|
43
|
+
onKeyDown?: (event: React.KeyboardEvent<HTMLInputElement>) => void;
|
44
|
+
|
45
|
+
onBlur?: (event: React.FocusEvent<HTMLInputElement>) => void;
|
46
|
+
|
47
|
+
onFocus?: (event: React.FocusEvent<HTMLInputElement>) => void;
|
48
|
+
/**
|
49
|
+
* id to select the input field uniquely
|
50
|
+
*/
|
51
|
+
id?: string;
|
52
|
+
/**
|
53
|
+
* list of variables
|
54
|
+
*/
|
55
|
+
list?: string[];
|
56
|
+
}
|
package/src/index.ts
CHANGED
@@ -38,9 +38,14 @@ import StateDropdown from './components/StateDropdown';
|
|
38
38
|
import IconButton from './components/IconButton';
|
39
39
|
import Modal from './components/Modal';
|
40
40
|
import DragAndDrop from './components/DragAndDrop/DragAndDrop';
|
41
|
+
import VariableInput from './components/VariableInput';
|
41
42
|
import AllProjectsDropdown from './components/AllProjectsDropdown';
|
43
|
+
import PieChart from './components/Charts/PieChart';
|
42
44
|
import AppHeader from './components/AppHeader';
|
45
|
+
import Paper from './components/Paper';
|
46
|
+
import DashboardDonutChart from './components/Charts/DashboardDonutChart';
|
43
47
|
import Recaptcha from './components/FF_Captcha/Recaptcha';
|
48
|
+
import NLPInput from './components/NLPInput';
|
44
49
|
|
45
50
|
// Utils imports
|
46
51
|
import { checkEmpty } from './utils/checkEmpty/checkEmpty';
|
@@ -49,6 +54,20 @@ import {
|
|
49
54
|
getExtensionWithPeriod,
|
50
55
|
} from './utils/getExtension/getExtension';
|
51
56
|
|
57
|
+
import { findAndInsert } from './utils/findAndInsert/findAndInsert';
|
58
|
+
import { ffid } from './utils/ffID/ffid';
|
59
|
+
|
60
|
+
import { debounce } from './utils/debounce/debounce';
|
61
|
+
import { compareArrays } from './utils/compareArrays/compareArrays';
|
62
|
+
|
63
|
+
import { compareObjects } from './utils/compareObjects/compareObjects';
|
64
|
+
|
65
|
+
import { getEncryptedData } from './utils/getEncryptedData/getEncryptedData';
|
66
|
+
|
67
|
+
import { throttle } from './utils/throttle/throttle';
|
68
|
+
|
69
|
+
import { truncateText } from './utils/truncateText/truncateText';
|
70
|
+
|
52
71
|
export {
|
53
72
|
Button,
|
54
73
|
Tooltip,
|
@@ -91,14 +110,25 @@ export {
|
|
91
110
|
StatusButton,
|
92
111
|
IconButton,
|
93
112
|
Modal,
|
94
|
-
|
113
|
+
PieChart,
|
114
|
+
DashboardDonutChart,
|
95
115
|
DragAndDrop,
|
96
116
|
AllProjectsDropdown,
|
97
117
|
AppHeader,
|
118
|
+
VariableInput,
|
119
|
+
Paper,
|
98
120
|
Recaptcha,
|
99
|
-
|
121
|
+
NLPInput,
|
100
122
|
// utils exports
|
101
123
|
checkEmpty,
|
102
124
|
getExtension,
|
103
125
|
getExtensionWithPeriod,
|
126
|
+
findAndInsert,
|
127
|
+
ffid,
|
128
|
+
compareArrays,
|
129
|
+
compareObjects,
|
130
|
+
debounce,
|
131
|
+
throttle,
|
132
|
+
getEncryptedData,
|
133
|
+
truncateText,
|
104
134
|
};
|
package/src/utils/ffID/ffid.ts
CHANGED
@@ -1,9 +1,7 @@
|
|
1
|
-
const ffid = (): string =>
|
1
|
+
export const ffid = (): string =>
|
2
2
|
'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (char) =>
|
3
3
|
(
|
4
4
|
(char === 'x' ? Math.random() * 16 : ((Math.random() * 16) & 0x3) | 0x8) |
|
5
5
|
0
|
6
6
|
).toString(16)
|
7
7
|
);
|
8
|
-
|
9
|
-
export default ffid;
|
@@ -0,0 +1,55 @@
|
|
1
|
+
// getEncryptData.stories.tsx
|
2
|
+
import { useState } from 'react';
|
3
|
+
import { getEncryptedData } from './getEncryptedData';
|
4
|
+
|
5
|
+
export default {
|
6
|
+
title: 'Utils/getEncryptedData',
|
7
|
+
component: getEncryptedData,
|
8
|
+
};
|
9
|
+
|
10
|
+
export const InteractivePlayground = () => {
|
11
|
+
const [data, setData] = useState<string>('Sensitive information');
|
12
|
+
const [publicKey, setPublicKey] = useState<string>(`Add your public key`);
|
13
|
+
const [encryptedData, setEncryptedData] = useState<string | null>(null);
|
14
|
+
|
15
|
+
const handleEncrypt = () => {
|
16
|
+
const result = getEncryptedData(data, publicKey);
|
17
|
+
setEncryptedData(result.toString());
|
18
|
+
};
|
19
|
+
|
20
|
+
return (
|
21
|
+
<div>
|
22
|
+
<h1>Interactive Playground for getEncryptData</h1>
|
23
|
+
|
24
|
+
<div>
|
25
|
+
<label htmlFor="data">Data to Encrypt:</label>
|
26
|
+
<input
|
27
|
+
type="text"
|
28
|
+
id="data"
|
29
|
+
value={data}
|
30
|
+
onChange={(e) => setData(e.target.value)}
|
31
|
+
/>
|
32
|
+
</div>
|
33
|
+
|
34
|
+
<div>
|
35
|
+
<label htmlFor="publicKey">Public Key:</label>
|
36
|
+
<textarea
|
37
|
+
id="publicKey"
|
38
|
+
value={publicKey}
|
39
|
+
onChange={(e) => setPublicKey(e.target.value)}
|
40
|
+
rows={5}
|
41
|
+
cols={50}
|
42
|
+
/>
|
43
|
+
</div>
|
44
|
+
|
45
|
+
<button onClick={handleEncrypt}>Encrypt Data</button>
|
46
|
+
|
47
|
+
<h2>Encrypted Data:</h2>
|
48
|
+
{encryptedData ? (
|
49
|
+
<pre>{encryptedData}</pre>
|
50
|
+
) : (
|
51
|
+
<p>No encrypted data yet. Click "Encrypt Data" to generate it.</p>
|
52
|
+
)}
|
53
|
+
</div>
|
54
|
+
);
|
55
|
+
};
|
@@ -1 +0,0 @@
|
|
1
|
-
export { default } from './AddButton';
|
File without changes
|
File without changes
|