@qoretechnologies/reqraft 0.6.12 → 0.7.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.
@@ -0,0 +1,17 @@
1
+ import { IReqoreButtonProps } from '@qoretechnologies/reqore/dist/components/Button';
2
+ import { IReqorePanelProps } from '@qoretechnologies/reqore/dist/components/Panel';
3
+ import { DropzoneOptions } from 'react-dropzone';
4
+ export interface IReqraftFileFormFieldValue {
5
+ name: string;
6
+ content: string;
7
+ size?: number;
8
+ }
9
+ export interface IReqraftFileFormFieldProps extends Omit<IReqorePanelProps, 'onChange'> {
10
+ value: IReqraftFileFormFieldValue;
11
+ onChange(value: IReqraftFileFormFieldValue): void;
12
+ readonly?: boolean;
13
+ options?: DropzoneOptions;
14
+ valueButtonProps?: IReqoreButtonProps;
15
+ }
16
+ export declare const ReqraftFileFormField: ({ value, onChange, options, valueButtonProps, ...rest }: IReqraftFileFormFieldProps) => import("react/jsx-runtime").JSX.Element;
17
+ //# sourceMappingURL=File.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"File.d.ts","sourceRoot":"","sources":["../../../../../src/components/form/fields/file/File.tsx"],"names":[],"mappings":"AAQA,OAAO,EAAE,kBAAkB,EAAE,MAAM,iDAAiD,CAAC;AACrF,OAAO,EAAE,iBAAiB,EAAE,MAAM,gDAAgD,CAAC;AAInF,OAAO,EAAU,eAAe,EAAe,MAAM,gBAAgB,CAAC;AAEtE,MAAM,WAAW,0BAA0B;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AACD,MAAM,WAAW,0BAA2B,SAAQ,IAAI,CAAC,iBAAiB,EAAE,UAAU,CAAC;IACrF,KAAK,EAAE,0BAA0B,CAAC;IAClC,QAAQ,CAAC,KAAK,EAAE,0BAA0B,GAAG,IAAI,CAAC;IAClD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,gBAAgB,CAAC,EAAE,kBAAkB,CAAC;CACvC;AAED,eAAO,MAAM,oBAAoB,4DAM9B,0BAA0B,4CAmG5B,CAAC"}
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ var __rest = (this && this.__rest) || function (s, e) {
14
+ var t = {};
15
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
16
+ t[p] = s[p];
17
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
18
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
19
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
20
+ t[p[i]] = s[p[i]];
21
+ }
22
+ return t;
23
+ };
24
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
25
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
26
+ if (ar || !(i in from)) {
27
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
28
+ ar[i] = from[i];
29
+ }
30
+ }
31
+ return to.concat(ar || Array.prototype.slice.call(from));
32
+ };
33
+ Object.defineProperty(exports, "__esModule", { value: true });
34
+ exports.ReqraftFileFormField = void 0;
35
+ var jsx_runtime_1 = require("react/jsx-runtime");
36
+ var reqore_1 = require("@qoretechnologies/reqore");
37
+ var filesize_1 = require("filesize");
38
+ var lodash_1 = require("lodash");
39
+ var react_1 = require("react");
40
+ var react_dropzone_1 = require("react-dropzone");
41
+ var ReqraftFileFormField = function (_a) {
42
+ var value = _a.value, onChange = _a.onChange, _b = _a.options, options = _b === void 0 ? {} : _b, _c = _a.valueButtonProps, valueButtonProps = _c === void 0 ? {} : _c, rest = __rest(_a, ["value", "onChange", "options", "valueButtonProps"]);
43
+ var contentStyle = (0, react_1.useMemo)(function () { return ({
44
+ display: 'flex',
45
+ flexDirection: 'column',
46
+ justifyContent: 'center',
47
+ alignItems: 'center',
48
+ }); }, []);
49
+ var _d = (0, react_dropzone_1.useDropzone)(__assign({ disabled: rest.disabled || rest.readonly, maxFiles: 1 }, options)), acceptedFiles = _d.acceptedFiles, getRootProps = _d.getRootProps, getInputProps = _d.getInputProps;
50
+ var extensions = (0, react_1.useMemo)(function () {
51
+ if (!options.accept) {
52
+ return [];
53
+ }
54
+ return (0, lodash_1.reduce)(options.accept, function (acc, ext) {
55
+ return __spreadArray(__spreadArray([], acc, true), ext, true);
56
+ }, []);
57
+ }, [options.accept]);
58
+ var renderExtensions = (0, react_1.useCallback)(function (asString) {
59
+ if ((0, lodash_1.size)(extensions) === 0) {
60
+ return '';
61
+ }
62
+ if (asString) {
63
+ return extensions.join(', ');
64
+ }
65
+ return ((0, jsx_runtime_1.jsx)(reqore_1.ReqoreP, { intent: 'muted', size: 'small', children: extensions.join(', ') }));
66
+ }, [extensions]);
67
+ (0, react_1.useEffect)(function () {
68
+ if (acceptedFiles.length === 0) {
69
+ return;
70
+ }
71
+ var reader = new FileReader();
72
+ reader.onload = function () {
73
+ onChange({
74
+ name: acceptedFiles[0].name,
75
+ content: reader.result,
76
+ size: acceptedFiles[0].size,
77
+ });
78
+ };
79
+ reader.readAsDataURL(acceptedFiles[0]);
80
+ }, [acceptedFiles]);
81
+ if (value) {
82
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("input", __assign({}, getInputProps())), (0, jsx_runtime_1.jsx)(reqore_1.ReqoreButton, __assign({ label: value.name, minimal: true, intent: 'info', icon: 'FileLine', rightIcon: 'FileUploadLine', badge: (0, filesize_1.filesize)(value.size || 0), description: "Click here to upload a different ".concat(renderExtensions(true), " file") }, valueButtonProps, getRootProps()))] }));
83
+ }
84
+ return ((0, jsx_runtime_1.jsxs)(reqore_1.ReqorePanel, __assign({ contentStyle: contentStyle }, rest, getRootProps(), { size: 'huge', children: [(0, jsx_runtime_1.jsx)("input", __assign({}, getInputProps())), (0, jsx_runtime_1.jsxs)(reqore_1.ReqoreControlGroup, { vertical: true, horizontalAlign: 'center', children: [(0, jsx_runtime_1.jsxs)(reqore_1.ReqoreH4, { size: 'small', children: [(0, jsx_runtime_1.jsx)(reqore_1.ReqoreIcon, { icon: 'FileAddLine', size: 'small' }), " Click or drop files here to upload"] }), renderExtensions()] })] })));
85
+ };
86
+ exports.ReqraftFileFormField = ReqraftFileFormField;
87
+ //# sourceMappingURL=File.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"File.js","sourceRoot":"","sources":["../../../../../src/components/form/fields/file/File.tsx"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"LongString.d.ts","sourceRoot":"","sources":["../../../../../src/components/form/fields/long-string/LongString.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,mDAAmD,CAAC;AACzF,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAE7D,MAAM,WAAW,yBAA0B,SAAQ,IAAI,CAAC,oBAAoB,EAAE,UAAU,CAAC;IACvF,QAAQ,CAAC,EAAE,CACT,KAAK,CAAC,EAAE,mBAAmB,CAAC,QAAQ,CAAC,EACrC,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,mBAAmB,CAAC,KACzC,IAAI,CAAC;CACX;AAED,eAAO,MAAM,mBAAmB,wCAI7B,yBAAyB,4CAc3B,CAAC;AAEF,eAAe,mBAAmB,CAAC"}
1
+ {"version":3,"file":"LongString.d.ts","sourceRoot":"","sources":["../../../../../src/components/form/fields/long-string/LongString.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,mDAAmD,CAAC;AAEzF,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAE7D,MAAM,WAAW,yBAA0B,SAAQ,IAAI,CAAC,oBAAoB,EAAE,UAAU,CAAC;IACvF,QAAQ,CAAC,EAAE,CACT,KAAK,CAAC,EAAE,mBAAmB,CAAC,QAAQ,CAAC,EACrC,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,mBAAmB,CAAC,KACzC,IAAI,CAAC;CACX;AAED,eAAO,MAAM,mBAAmB,wCAI7B,yBAAyB,4CAuB3B,CAAC;AAEF,eAAe,mBAAmB,CAAC"}
@@ -25,12 +25,17 @@ Object.defineProperty(exports, "__esModule", { value: true });
25
25
  exports.LongStringFormField = void 0;
26
26
  var jsx_runtime_1 = require("react/jsx-runtime");
27
27
  var reqore_1 = require("@qoretechnologies/reqore");
28
+ var react_1 = require("react");
28
29
  var LongStringFormField = function (_a) {
29
30
  var onChange = _a.onChange, onClearClick = _a.onClearClick, rest = __rest(_a, ["onChange", "onClearClick"]);
30
- return ((0, jsx_runtime_1.jsx)(reqore_1.ReqoreTextarea, __assign({ scaleWithContent: true, fluid: true, onClearClick: function () {
31
- onClearClick === null || onClearClick === void 0 ? void 0 : onClearClick();
32
- onChange === null || onChange === void 0 ? void 0 : onChange('');
33
- }, onChange: function (event) { return onChange(event.currentTarget.value, event); }, rows: 4 }, rest)));
31
+ var handleClearClick = (0, react_1.useCallback)(function () {
32
+ onClearClick === null || onClearClick === void 0 ? void 0 : onClearClick();
33
+ onChange === null || onChange === void 0 ? void 0 : onChange('');
34
+ }, [onClearClick, onChange]);
35
+ var handleChange = (0, react_1.useCallback)(function (event) {
36
+ onChange === null || onChange === void 0 ? void 0 : onChange(event.currentTarget.value, event);
37
+ }, [onChange]);
38
+ return ((0, jsx_runtime_1.jsx)(reqore_1.ReqoreTextarea, __assign({ scaleWithContent: true, fluid: true, onClearClick: handleClearClick, onChange: handleChange, rows: 4 }, rest)));
34
39
  };
35
40
  exports.LongStringFormField = LongStringFormField;
36
41
  exports.default = exports.LongStringFormField;
@@ -1 +1 @@
1
- {"version":3,"file":"LongString.js","sourceRoot":"","sources":["../../../../../src/components/form/fields/long-string/LongString.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,mDAA0D;AAWnD,IAAM,mBAAmB,GAAG,UAAC,EAIR;IAH1B,IAAA,QAAQ,cAAA,EACR,YAAY,kBAAA,EACT,IAAI,cAH2B,4BAInC,CADQ;IAEP,OAAO,CACL,uBAAC,uBAAc,aACb,gBAAgB,QAChB,KAAK,QACL,YAAY,EAAE;YACZ,YAAY,aAAZ,YAAY,uBAAZ,YAAY,EAAI,CAAC;YACjB,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAG,EAAE,CAAC,CAAC;QACjB,CAAC,EACD,QAAQ,EAAE,UAAC,KAAK,IAAK,OAAA,QAAQ,CAAC,KAAK,CAAC,aAAa,CAAC,KAAK,EAAE,KAAK,CAAC,EAA1C,CAA0C,EAC/D,IAAI,EAAE,CAAC,IACH,IAAI,EACR,CACH,CAAC;AACJ,CAAC,CAAC;AAlBW,QAAA,mBAAmB,uBAkB9B;AAEF,kBAAe,2BAAmB,CAAC"}
1
+ {"version":3,"file":"LongString.js","sourceRoot":"","sources":["../../../../../src/components/form/fields/long-string/LongString.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,mDAA0D;AAE1D,+BAAoC;AAU7B,IAAM,mBAAmB,GAAG,UAAC,EAIR;IAH1B,IAAA,QAAQ,cAAA,EACR,YAAY,kBAAA,EACT,IAAI,cAH2B,4BAInC,CADQ;IAEP,IAAM,gBAAgB,GAAG,IAAA,mBAAW,EAAC;QACnC,YAAY,aAAZ,YAAY,uBAAZ,YAAY,EAAI,CAAC;QACjB,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAG,EAAE,CAAC,CAAC;IACjB,CAAC,EAAE,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC,CAAC;IAE7B,IAAM,YAAY,GAAG,IAAA,mBAAW,EAC9B,UAAC,KAA6C;QAC5C,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAG,KAAK,CAAC,aAAa,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAC/C,CAAC,EACD,CAAC,QAAQ,CAAC,CACX,CAAC;IAEF,OAAO,CACL,uBAAC,uBAAc,aACb,gBAAgB,QAChB,KAAK,QACL,YAAY,EAAE,gBAAgB,EAC9B,QAAQ,EAAE,YAAY,EACtB,IAAI,EAAE,CAAC,IACH,IAAI,EACR,CACH,CAAC;AACJ,CAAC,CAAC;AA3BW,QAAA,mBAAmB,uBA2B9B;AAEF,kBAAe,2BAAmB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qoretechnologies/reqraft",
3
- "version": "0.6.12",
3
+ "version": "0.7.0",
4
4
  "description": "ReQraft is a collection of React components and hooks that are used across Qore Technologies' products made using the ReQore component library from Qore.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -111,10 +111,12 @@
111
111
  "classnames": "^2.2.6",
112
112
  "cronstrue": "^2.50.0",
113
113
  "epoch-timeago": "^1.1.9",
114
+ "filesize": "^10.1.6",
114
115
  "js-yaml": "^4.1.0",
115
116
  "lodash": "^4.17.21",
116
117
  "polished": "^4.2.2",
117
118
  "react-color": "^2.19.3",
119
+ "react-dropzone": "^14.3.5",
118
120
  "react-markdown": "^9.0.1",
119
121
  "react-use": "^17.4.0",
120
122
  "scheduler": "^0.23.0",
@@ -0,0 +1,60 @@
1
+ import { StoryObj } from '@storybook/react';
2
+ import { fn } from '@storybook/test';
3
+ import { useState } from 'react';
4
+
5
+ import { StoryMeta } from '../../../../types';
6
+ import { ReqraftFileFormField } from './File';
7
+
8
+ const meta = {
9
+ component: ReqraftFileFormField,
10
+ title: 'Components/Form/File',
11
+ args: {
12
+ onChange: fn(),
13
+ },
14
+ render(args) {
15
+ const [value, setValue] = useState(args.value);
16
+ return (
17
+ <ReqraftFileFormField
18
+ {...args}
19
+ value={value}
20
+ onChange={(value) => {
21
+ args.onChange?.(value);
22
+ setValue(value);
23
+ }}
24
+ />
25
+ );
26
+ },
27
+ } as StoryMeta<typeof ReqraftFileFormField>;
28
+
29
+ export default meta;
30
+ type Story = StoryObj<typeof meta>;
31
+
32
+ export const Default: Story = {};
33
+ export const WithSpecifiedExtensions: Story = {
34
+ args: {
35
+ options: {
36
+ accept: {
37
+ 'image/png': ['.png'],
38
+ 'image/jpeg': ['.jpg', '.jpeg'],
39
+ 'application/pdf': ['.pdf'],
40
+ },
41
+ },
42
+ },
43
+ };
44
+
45
+ export const WithValue: Story = {
46
+ args: {
47
+ options: {
48
+ accept: {
49
+ 'image/png': ['.png'],
50
+ 'image/jpeg': ['.jpg', '.jpeg'],
51
+ 'application/pdf': ['.pdf'],
52
+ },
53
+ },
54
+ value: {
55
+ name: 'MyFile.pdf',
56
+ content: 'test',
57
+ size: 28736,
58
+ },
59
+ },
60
+ };
@@ -0,0 +1,134 @@
1
+ import {
2
+ ReqoreButton,
3
+ ReqoreControlGroup,
4
+ ReqoreH4,
5
+ ReqoreIcon,
6
+ ReqoreP,
7
+ ReqorePanel,
8
+ } from '@qoretechnologies/reqore';
9
+ import { IReqoreButtonProps } from '@qoretechnologies/reqore/dist/components/Button';
10
+ import { IReqorePanelProps } from '@qoretechnologies/reqore/dist/components/Panel';
11
+ import { filesize } from 'filesize';
12
+ import { reduce, size } from 'lodash';
13
+ import { useCallback, useEffect, useMemo } from 'react';
14
+ import { Accept, DropzoneOptions, useDropzone } from 'react-dropzone';
15
+
16
+ export interface IReqraftFileFormFieldValue {
17
+ name: string;
18
+ content: string;
19
+ size?: number;
20
+ }
21
+ export interface IReqraftFileFormFieldProps extends Omit<IReqorePanelProps, 'onChange'> {
22
+ value: IReqraftFileFormFieldValue;
23
+ onChange(value: IReqraftFileFormFieldValue): void;
24
+ readonly?: boolean;
25
+ options?: DropzoneOptions;
26
+ valueButtonProps?: IReqoreButtonProps;
27
+ }
28
+
29
+ export const ReqraftFileFormField = ({
30
+ value,
31
+ onChange,
32
+ options = {},
33
+ valueButtonProps = {},
34
+ ...rest
35
+ }: IReqraftFileFormFieldProps) => {
36
+ const contentStyle: React.CSSProperties = useMemo(
37
+ (): React.CSSProperties => ({
38
+ display: 'flex',
39
+ flexDirection: 'column',
40
+ justifyContent: 'center',
41
+ alignItems: 'center',
42
+ }),
43
+ []
44
+ );
45
+
46
+ const { acceptedFiles, getRootProps, getInputProps } = useDropzone({
47
+ disabled: rest.disabled || rest.readonly,
48
+ maxFiles: 1,
49
+
50
+ ...options,
51
+ });
52
+
53
+ const extensions = useMemo(() => {
54
+ if (!options.accept) {
55
+ return [];
56
+ }
57
+
58
+ return reduce<Accept, string[]>(
59
+ options.accept,
60
+ (acc, ext) => {
61
+ return [...acc, ...ext];
62
+ },
63
+ []
64
+ );
65
+ }, [options.accept]);
66
+
67
+ const renderExtensions = useCallback(
68
+ (asString?: boolean) => {
69
+ if (size(extensions) === 0) {
70
+ return '';
71
+ }
72
+
73
+ if (asString) {
74
+ return extensions.join(', ');
75
+ }
76
+
77
+ return (
78
+ <ReqoreP intent='muted' size='small'>
79
+ {extensions.join(', ')}
80
+ </ReqoreP>
81
+ );
82
+ },
83
+ [extensions]
84
+ );
85
+
86
+ useEffect(() => {
87
+ if (acceptedFiles.length === 0) {
88
+ return;
89
+ }
90
+
91
+ const reader = new FileReader();
92
+
93
+ reader.onload = () => {
94
+ onChange({
95
+ name: acceptedFiles[0].name,
96
+ content: reader.result as string,
97
+ size: acceptedFiles[0].size,
98
+ });
99
+ };
100
+
101
+ reader.readAsDataURL(acceptedFiles[0]);
102
+ }, [acceptedFiles]);
103
+
104
+ if (value) {
105
+ return (
106
+ <>
107
+ <input {...getInputProps()} />
108
+ <ReqoreButton
109
+ label={value.name}
110
+ minimal
111
+ intent='info'
112
+ icon='FileLine'
113
+ rightIcon='FileUploadLine'
114
+ badge={filesize(value.size || 0)}
115
+ description={`Click here to upload a different ${renderExtensions(true)} file`}
116
+ {...valueButtonProps}
117
+ {...getRootProps()}
118
+ />
119
+ </>
120
+ );
121
+ }
122
+
123
+ return (
124
+ <ReqorePanel contentStyle={contentStyle} {...rest} {...getRootProps()} size='huge'>
125
+ <input {...getInputProps()} />
126
+ <ReqoreControlGroup vertical horizontalAlign='center'>
127
+ <ReqoreH4 size='small'>
128
+ <ReqoreIcon icon='FileAddLine' size='small' /> Click or drop files here to upload
129
+ </ReqoreH4>
130
+ {renderExtensions()}
131
+ </ReqoreControlGroup>
132
+ </ReqorePanel>
133
+ );
134
+ };
@@ -1,5 +1,6 @@
1
1
  import { ReqoreTextarea } from '@qoretechnologies/reqore';
2
2
  import { IReqoreTextareaProps } from '@qoretechnologies/reqore/dist/components/Textarea';
3
+ import { useCallback } from 'react';
3
4
  import { TFormFieldValueType } from '../../../../types/Form';
4
5
 
5
6
  export interface ILongStringFormFieldProps extends Omit<IReqoreTextareaProps, 'onChange'> {
@@ -14,15 +15,24 @@ export const LongStringFormField = ({
14
15
  onClearClick,
15
16
  ...rest
16
17
  }: ILongStringFormFieldProps) => {
18
+ const handleClearClick = useCallback(() => {
19
+ onClearClick?.();
20
+ onChange?.('');
21
+ }, [onClearClick, onChange]);
22
+
23
+ const handleChange = useCallback(
24
+ (event: React.ChangeEvent<HTMLTextAreaElement>) => {
25
+ onChange?.(event.currentTarget.value, event);
26
+ },
27
+ [onChange]
28
+ );
29
+
17
30
  return (
18
31
  <ReqoreTextarea
19
32
  scaleWithContent
20
33
  fluid
21
- onClearClick={() => {
22
- onClearClick?.();
23
- onChange?.('');
24
- }}
25
- onChange={(event) => onChange(event.currentTarget.value, event)}
34
+ onClearClick={handleClearClick}
35
+ onChange={handleChange}
26
36
  rows={4}
27
37
  {...rest}
28
38
  />