@luscii-healthtech/web-ui 24.1.0 → 25.1.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,32 @@
1
+ import React from "react";
2
+ export type FileUploadProps = {
3
+ /**
4
+ * The file types that the input should accept.
5
+ */
6
+ accept?: string;
7
+ /**
8
+ * The maximum size of the file in MBs.
9
+ */
10
+ maxFileSize?: number;
11
+ /**
12
+ * The name of the field input.
13
+ */
14
+ name?: string;
15
+ /**
16
+ * The id of the field input.
17
+ * To be used with a `<label htmlFor={id}>`.
18
+ */
19
+ id?: string;
20
+ onChange?: (file: File) => void;
21
+ /**
22
+ * Disallow the user to change the file input value.
23
+ */
24
+ isDisabled?: boolean;
25
+ /**
26
+ * The text to be displayed on the button controlling the file input.
27
+ *
28
+ * @default "Upload a file"
29
+ */
30
+ buttonText: string;
31
+ };
32
+ export declare const FileUpload: React.FC<FileUploadProps>;
@@ -1,9 +1,16 @@
1
1
  import React from "react";
2
- import { ReactQuillProps } from "react-quill";
3
- import "react-quill/dist/quill.snow.css";
2
+ import type { Delta, EmitterSource } from "quill/core";
3
+ import "quill/dist/quill.snow.css";
4
4
  import "./TextEditor.scss";
5
- type TextEditorProps = Pick<ReactQuillProps, "defaultValue" | "placeholder"> & {
6
- onValueChange: ReactQuillProps["onChange"];
5
+ type Props = React.HTMLAttributes<HTMLDivElement> & {
6
+ /**
7
+ * Called when the value of the editor changes.
8
+ *
9
+ * @param html string of html
10
+ * @param delta Quill Delta object
11
+ * @param source source of the change
12
+ */
13
+ onValueChange: (html: string, delta: Delta, source: EmitterSource) => void;
7
14
  /**
8
15
  * Which formats to allow in the editor, like "bold" and "italic".
9
16
  *
@@ -42,6 +49,14 @@ type TextEditorProps = Pick<ReactQuillProps, "defaultValue" | "placeholder"> & {
42
49
  * See: https://github.com/zenoamaro/react-quill#custom-toolbar
43
50
  */
44
51
  toolbar?: TextEditorToolbarOption[][];
52
+ /**
53
+ * A string of html.
54
+ */
55
+ defaultValue?: string;
56
+ /**
57
+ * Placeholder text to show in the editor when it is empty.
58
+ */
59
+ placeholder?: string;
45
60
  };
46
61
  type TextEditorToolbarOption = "bold" | "italic" | "underline" | "strike" | "link" | "video" | {
47
62
  list: "ordered";
@@ -49,5 +64,5 @@ type TextEditorToolbarOption = "bold" | "italic" | "underline" | "strike" | "lin
49
64
  list: "bullet";
50
65
  };
51
66
  type TextEditorFormat = "background" | "bold" | "color" | "font" | "code" | "italic" | "link" | "size" | "strike" | "script" | "underline" | "blockquote" | "header" | "list" | "align";
52
- export declare const TextEditor: React.FC<TextEditorProps>;
67
+ export declare const TextEditor: React.FC<Props>;
53
68
  export default TextEditor;
package/dist/index.d.ts CHANGED
@@ -92,4 +92,5 @@ export { Dropzone, type DropzoneProps } from "./components/Dropzone";
92
92
  export { FilterBar, FilterBarUtils } from "./components/FilterBar";
93
93
  export { type Weekday, WeekdaysPicker, } from "./components/WeekdaysPicker/WeekdaysPicker";
94
94
  export { default as DragHandle, type DragHandleProps, } from "./components/DragHandle";
95
+ export { FileUpload as File, type FileUploadProps as FileProps, } from "./components/FileUpload/FileUpload";
95
96
  export { StatusIndicator } from "./components/StatusIndicator/StatusIndicator";
@@ -31,8 +31,8 @@ var ReactSelect = require('react-select');
31
31
  var groupBy = require('lodash/groupBy');
32
32
  var debounce = require('lodash.debounce');
33
33
  var reactLazyLoadImageComponent = require('react-lazy-load-image-component');
34
- var ReactQuill = require('react-quill');
35
- require('react-quill/dist/quill.snow.css');
34
+ var Quill = require('quill');
35
+ require('quill/dist/quill.snow.css');
36
36
  var react = require('@headlessui/react');
37
37
  var solid = require('@heroicons/react/20/solid');
38
38
  var ToggleGroup = require('@radix-ui/react-toggle-group');
@@ -72,7 +72,7 @@ var FlyOutMenuPrimitive__namespace = /*#__PURE__*/_interopNamespace(FlyOutMenuPr
72
72
  var ReactSelect__default = /*#__PURE__*/_interopDefault(ReactSelect);
73
73
  var groupBy__default = /*#__PURE__*/_interopDefault(groupBy);
74
74
  var debounce__default = /*#__PURE__*/_interopDefault(debounce);
75
- var ReactQuill__default = /*#__PURE__*/_interopDefault(ReactQuill);
75
+ var Quill__default = /*#__PURE__*/_interopDefault(Quill);
76
76
  var ToggleGroup__namespace = /*#__PURE__*/_interopNamespace(ToggleGroup);
77
77
 
78
78
  /******************************************************************************
@@ -5284,32 +5284,38 @@ const Textarea = React__namespace.default.forwardRef((_a, ref) => {
5284
5284
  var css_248z = "/**\n * --- DEPRECATED ---\n * DON'T USE ANYTHING FROM THIS FILE IN FUTURE CHANGES. WE SHOULD BE\n * USING TAILWIND CLASSES DIRECTLY IN OUR COMPONENTS.\n */\n.ql-editor {\n resize: vertical;\n min-height: 10rem;\n}\n\n.ql-snow.ql-toolbar {\n display: block;\n background: #f1f5f9;\n border-top-left-radius: 0.5em;\n border-top-right-radius: 0.5em;\n margin-top: 0.5em;\n}";
5285
5285
  styleInject(css_248z);
5286
5286
 
5287
- const TextEditor = ({ defaultValue, onValueChange, placeholder, toolbar = [
5288
- ["bold", "italic", "underline", "strike"],
5289
- [{ list: "ordered" }, { list: "bullet" }],
5290
- ["link"]
5291
- ], formats = ["bold", "italic", "underline", "strike", "list", "link"] }) => {
5287
+ const TextEditor = (_a) => {
5288
+ var { defaultValue, formats, toolbar = [
5289
+ ["bold", "italic", "underline", "strike"],
5290
+ [{ list: "ordered" }, { list: "bullet" }],
5291
+ ["link"]
5292
+ ], placeholder, onValueChange } = _a, attrs = __rest(_a, ["defaultValue", "formats", "toolbar", "placeholder", "onValueChange"]);
5293
+ const editorRef = React.useRef(null);
5292
5294
  const quillRef = React.useRef(null);
5293
5295
  React.useEffect(() => {
5294
- var _a, _b, _c;
5295
- if (quillRef.current) {
5296
- const tooltip = (_c = (_b = (_a = quillRef.current) === null || _a === void 0 ? void 0 : _a.editor) === null || _b === void 0 ? void 0 : _b.theme) === null || _c === void 0 ? void 0 : _c.tooltip;
5297
- if (typeof tooltip === "object" && tooltip !== null && "save" in tooltip) {
5298
- const save = tooltip.save;
5299
- tooltip.save = function() {
5300
- let url = this.textbox.value;
5301
- if (url.indexOf("http") === -1 || url.indexOf("https") === -1) {
5302
- url = `https://${url}`;
5303
- this.textbox.value = url;
5304
- }
5305
- save.call(this);
5306
- };
5307
- }
5296
+ if (editorRef.current) {
5297
+ const quill = new Quill__default.default(editorRef.current, {
5298
+ theme: "snow",
5299
+ formats,
5300
+ modules: {
5301
+ toolbar
5302
+ },
5303
+ placeholder
5304
+ });
5305
+ quill.on("text-change", (value, _, source) => {
5306
+ onValueChange(quill.getSemanticHTML(), value, source);
5307
+ });
5308
+ quill.setContents(quill.clipboard.convert({
5309
+ html: defaultValue
5310
+ }));
5311
+ quillRef.current = quill;
5308
5312
  }
5309
5313
  }, []);
5310
- return React__namespace.default.createElement(ReactQuill__default.default, { ref: quillRef, theme: "snow", modules: {
5311
- toolbar: { container: toolbar }
5312
- }, placeholder, formats, value: defaultValue, onChange: onValueChange });
5314
+ return React__namespace.default.createElement(
5315
+ "div",
5316
+ Object.assign({}, attrs),
5317
+ React__namespace.default.createElement("div", { ref: editorRef })
5318
+ );
5313
5319
  };
5314
5320
 
5315
5321
  function Link(props) {
@@ -6010,6 +6016,60 @@ const WeekdaysPicker = (props) => {
6010
6016
  WeekdaysPicker.weekdayNameToIndex = weekdayNameToIndex;
6011
6017
  WeekdaysPicker.indexToWeekdayName = indexToWeekdayName;
6012
6018
 
6019
+ const FileUpload = React.forwardRef((props, ref) => {
6020
+ const { accept, maxFileSize, name, id, onChange, isDisabled = false, buttonText = "Upload a file" } = props, otherProps = __rest(props, ["accept", "maxFileSize", "name", "id", "onChange", "isDisabled", "buttonText"]);
6021
+ const [selectedFile, setSelectedFile] = React.useState(null);
6022
+ const fileUploadRef = React.useRef(null);
6023
+ const handleOnUploadClick = () => {
6024
+ var _a;
6025
+ (_a = fileUploadRef.current) === null || _a === void 0 ? void 0 : _a.click();
6026
+ };
6027
+ const handleChangeEvent = (event) => {
6028
+ var _a;
6029
+ const uploadedFile = (_a = event.target.files) === null || _a === void 0 ? void 0 : _a[0];
6030
+ if (uploadedFile) {
6031
+ onChange === null || onChange === void 0 ? void 0 : onChange(uploadedFile);
6032
+ setSelectedFile(uploadedFile);
6033
+ }
6034
+ };
6035
+ const handleOnUnselectFile = () => {
6036
+ setSelectedFile(null);
6037
+ if (fileUploadRef.current) {
6038
+ fileUploadRef.current.value = "";
6039
+ }
6040
+ };
6041
+ if (selectedFile) {
6042
+ return React__namespace.default.createElement(UploadedFileSection, { file: selectedFile, onRemove: handleOnUnselectFile });
6043
+ }
6044
+ return React__namespace.default.createElement(
6045
+ FlexRow,
6046
+ null,
6047
+ React__namespace.default.createElement(SecondaryButton, { onClick: handleOnUploadClick }, buttonText),
6048
+ React__namespace.default.createElement("input", Object.assign({ type: "file", className: "ui-hidden", accept, size: maxFileSize ? maxFileSize * 1024 * 1024 : void 0, name, id, ref: (element) => {
6049
+ fileUploadRef.current = element;
6050
+ if (ref) {
6051
+ if (typeof ref === "function") {
6052
+ ref(element);
6053
+ } else {
6054
+ ref.current = element;
6055
+ }
6056
+ }
6057
+ }, onChange: handleChangeEvent, disabled: isDisabled }, otherProps))
6058
+ );
6059
+ });
6060
+ const UploadedFileSection = ({ file, onRemove }) => {
6061
+ return React__namespace.default.createElement(
6062
+ "div",
6063
+ { className: "ui-inline-block ui-flex-row ui-rounded-lg ui-bg-blue-100" },
6064
+ React__namespace.default.createElement(
6065
+ Stack,
6066
+ { axis: "x", justify: "center", align: "center", gap: "xxxs", py: "xxs", px: "m", title: file.name },
6067
+ React__namespace.default.createElement(Text, { truncate: true, className: "ui-max-w-55" }, file.name),
6068
+ React__namespace.default.createElement(TertiaryButton, { icon: "TrashBinIcon", onClick: onRemove })
6069
+ )
6070
+ );
6071
+ };
6072
+
6013
6073
  const StatusIndicator = (props) => {
6014
6074
  const { status, children } = props;
6015
6075
  return React__namespace.default.createElement(
@@ -6094,6 +6154,7 @@ exports.EyeClosedIcon = EyeClosedIcon;
6094
6154
  exports.EyeIcon = EyeOpenIcon;
6095
6155
  exports.EyeIconSlashed = EyeClosedIcon;
6096
6156
  exports.EyeOpenIcon = EyeOpenIcon;
6157
+ exports.File = FileUpload;
6097
6158
  exports.FilterBar = FilterBar;
6098
6159
  exports.FilterBarUtils = FilterBar_utils;
6099
6160
  exports.FilterIcon = FilterIcon;