@luscii-healthtech/web-ui 2.4.1 → 2.5.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 CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "2.4.1",
2
+ "version": "2.5.2",
3
3
  "license": "MIT",
4
4
  "main": "dist/index.js",
5
5
  "typings": "dist/index.d.ts",
@@ -103,6 +103,7 @@
103
103
  "@fontsource/roboto": "^4.5.7",
104
104
  "@hookform/error-message": "^2.0.0",
105
105
  "@reach/router": "^1.3.4",
106
+ "@types/react-dragula": "^1.1.0",
106
107
  "@typescript-eslint/eslint-plugin": "^5.29.0",
107
108
  "classnames": "^2.3.1",
108
109
  "clipboard": "^2.0.11",
@@ -1,82 +1,121 @@
1
1
  import React, { useEffect, useState } from "react";
2
2
  import classNames from "classnames";
3
3
 
4
-
5
4
  import { Text } from "../Text/Text";
6
5
  import { Checkbox } from "../..";
7
6
  import { ChevronRightIcon } from "../Icons/ChevronRightIcon";
8
7
  import { ChevronDownIcon } from "../Icons/ChevronDownIcon";
9
8
 
10
- import {CheckboxGroupProps, CheckboxState } from "./CheckboxList.types";
9
+ import { CheckboxGroupProps, CheckboxState } from "./CheckboxList.types";
11
10
  import { CheckboxListItem } from "./CheckboxListItem";
12
11
 
13
12
  export const CheckboxGroup = ({
14
- title,
15
- items,
16
- onChange,
17
- className
18
- }: CheckboxGroupProps): JSX.Element => {
19
-
20
- const [groupCheckboxState, setGroupCheckboxState] = useState<CheckboxState>(CheckboxState.UNCHECKED);
13
+ title,
14
+ items,
15
+ onChange,
16
+ className,
17
+ isCollapsed = true,
18
+ }: CheckboxGroupProps): JSX.Element => {
19
+ const [groupCheckboxState, setGroupCheckboxState] = useState<CheckboxState>(
20
+ CheckboxState.UNCHECKED
21
+ );
21
22
 
22
- const [collapsed, setCollapsed] = useState(true);
23
+ const [collapsed, setCollapsed] = useState(isCollapsed);
23
24
 
24
- useEffect(() => {
25
- if (items?.length > 0) {
26
- const indeterminate = items.some((item) => item.isChecked !== items[0].isChecked);
27
- if (!indeterminate && items[0].isChecked) {
28
- setGroupCheckboxState(CheckboxState.CHECKED);
29
- } else if (!indeterminate && !items[0].isChecked) {
30
- setGroupCheckboxState(CheckboxState.UNCHECKED);
31
- } else {
32
- setGroupCheckboxState(CheckboxState.INDETERMINATE);
33
- }
34
- } else {
35
- setGroupCheckboxState(CheckboxState.UNCHECKED);
36
- }
37
- }, [items]);
25
+ useEffect(() => {
26
+ if (items?.length > 0) {
27
+ const indeterminate = items.some(
28
+ (item) => item.isChecked !== items[0].isChecked
29
+ );
30
+ if (!indeterminate && items[0].isChecked) {
31
+ setGroupCheckboxState(CheckboxState.CHECKED);
32
+ } else if (!indeterminate && !items[0].isChecked) {
33
+ setGroupCheckboxState(CheckboxState.UNCHECKED);
34
+ } else {
35
+ setGroupCheckboxState(CheckboxState.INDETERMINATE);
36
+ }
37
+ } else {
38
+ setGroupCheckboxState(CheckboxState.UNCHECKED);
39
+ }
40
+ }, [items]);
38
41
 
39
- const handleGroupClick = (event: React.MouseEvent<HTMLDivElement> | React.ChangeEvent<HTMLInputElement>) => {
40
- event.stopPropagation();
42
+ const handleGroupClick = (
43
+ event:
44
+ | React.MouseEvent<HTMLDivElement>
45
+ | React.ChangeEvent<HTMLInputElement>
46
+ ) => {
47
+ event.stopPropagation();
41
48
 
42
- if ((groupCheckboxState === CheckboxState.CHECKED || groupCheckboxState === CheckboxState.INDETERMINATE) && onChange) {
43
- //if checked or indeterminate >> make all items unchecked
44
- items.forEach((item) => onChange({id: item.id, newCheckedValue: false}));
45
- } else if (onChange) {
46
- // else if unchecked >> make all items checked
47
- items.forEach((item) => onChange({id: item.id, newCheckedValue: true}));
48
- }
49
- };
49
+ if (
50
+ (groupCheckboxState === CheckboxState.CHECKED ||
51
+ groupCheckboxState === CheckboxState.INDETERMINATE) &&
52
+ onChange
53
+ ) {
54
+ //if checked or indeterminate >> make all items unchecked
55
+ items.forEach((item) =>
56
+ onChange({ id: item.id, newCheckedValue: false })
57
+ );
58
+ } else if (onChange) {
59
+ // else if unchecked >> make all items checked
60
+ items.forEach((item) => onChange({ id: item.id, newCheckedValue: true }));
61
+ }
62
+ };
50
63
 
51
- const handleGroupCollapse = (event: React.MouseEvent<HTMLDivElement> | React.MouseEvent<SVGSVGElement> | undefined) => {
52
- if (event) {
53
- event.stopPropagation();
54
- }
64
+ const handleGroupCollapse = (
65
+ event:
66
+ | React.MouseEvent<HTMLDivElement>
67
+ | React.MouseEvent<SVGSVGElement>
68
+ | undefined
69
+ ) => {
70
+ if (event) {
71
+ event.stopPropagation();
72
+ }
55
73
 
56
- setCollapsed(!collapsed);
57
- };
74
+ setCollapsed(!collapsed);
75
+ };
58
76
 
59
- const checkedItemsCount = items?.filter(item => item?.isChecked).length;
60
- const groupTitle = checkedItemsCount > 0 ? `${title} (${checkedItemsCount})` : title;
77
+ const checkedItemsCount = items?.filter((item) => item?.isChecked).length;
78
+ const groupTitle =
79
+ checkedItemsCount > 0 ? `${title} (${checkedItemsCount})` : title;
61
80
 
62
- return (
63
- <div className={classNames("flex flex-col", className)}>
64
- {title &&
81
+ return (
82
+ <div className={classNames("flex flex-col", className)}>
83
+ {title && (
65
84
  <div className={"flex flex-row my-1 items-center w-full space-between"}>
66
- <div className={"h-6 cursor-pointer mr-auto flex flex-row items-center text-slate-300 hover:text-slate-500 transition duration-300"} onClick={handleGroupCollapse}>
67
- {collapsed ? <ChevronRightIcon onClick={handleGroupCollapse} /> : <ChevronDownIcon onClick={handleGroupCollapse} />}
68
- <Text type={"strong"} text={groupTitle || ""} className={" ml-4"}/> :
85
+ <div
86
+ className={
87
+ "h-6 cursor-pointer mr-auto flex flex-row items-center text-slate-300 hover:text-slate-500 transition duration-300"
88
+ }
89
+ onClick={handleGroupCollapse}
90
+ >
91
+ {collapsed ? (
92
+ <ChevronRightIcon onClick={handleGroupCollapse} />
93
+ ) : (
94
+ <ChevronDownIcon onClick={handleGroupCollapse} />
95
+ )}
96
+ <Text type={"strong"} text={groupTitle || ""} className={" ml-4"} />{" "}
97
+ :
69
98
  </div>
70
- <Checkbox onChange={handleGroupClick} className={"ml-auto"}
71
- isChecked={groupCheckboxState === CheckboxState.CHECKED}
72
- isIndeterminate={groupCheckboxState === CheckboxState.INDETERMINATE}/>
99
+ <Checkbox
100
+ onChange={handleGroupClick}
101
+ className={"ml-auto"}
102
+ isChecked={groupCheckboxState === CheckboxState.CHECKED}
103
+ isIndeterminate={groupCheckboxState === CheckboxState.INDETERMINATE}
104
+ />
73
105
  </div>
74
- }
75
-
76
- {!collapsed &&
77
- items.map((item) => (<CheckboxListItem key={item.id} id={item.id} label={item.label} onChange={onChange} isChecked={item.isChecked} className={"ml-10 my-1"}/>))
78
- }
106
+ )}
79
107
 
80
- </div>
81
- );
108
+ {!collapsed &&
109
+ items.map((item) => (
110
+ <CheckboxListItem
111
+ key={item.id}
112
+ id={item.id}
113
+ label={item.label}
114
+ onChange={onChange}
115
+ isChecked={item.isChecked}
116
+ className={"ml-10 my-1"}
117
+ />
118
+ ))}
119
+ </div>
120
+ );
82
121
  };
@@ -5,25 +5,42 @@ import { CheckboxListItem } from "./CheckboxListItem";
5
5
  import { CheckboxListProps } from "./CheckboxList.types";
6
6
  import { CheckboxGroup } from "./CheckboxGroup";
7
7
 
8
- export {CheckboxListProps};
8
+ export { CheckboxListProps };
9
9
 
10
10
  export const CheckboxList = ({
11
- groups,
12
- onChange,
13
- className,
14
- }: CheckboxListProps): JSX.Element => {
15
-
16
- return (
17
- <div className={classNames("flex flex-col", className)}>
18
- {groups?.length > 0 && groups.map((group) => {
19
- if (group.title) {
20
- return <CheckboxGroup key={group.title} items={group.items} title={group.title} onChange={onChange}/>;
21
- } else {
22
- return group.items.map((item) => <CheckboxListItem key={item.id} id={item.id} label={item.label} onChange={onChange} isChecked={item.isChecked} className={"my-1"}/>);
23
- }
24
- })}
25
- </div>
26
- );
11
+ groups,
12
+ onChange,
13
+ className,
14
+ }: CheckboxListProps): JSX.Element => {
15
+ return (
16
+ <div className={classNames("flex flex-col", className)}>
17
+ {groups?.length > 0 &&
18
+ groups.map((group) => {
19
+ if (group.title) {
20
+ return (
21
+ <CheckboxGroup
22
+ key={group.title}
23
+ items={group.items}
24
+ title={group.title}
25
+ isCollapsed={group.isCollapsed}
26
+ onChange={onChange}
27
+ />
28
+ );
29
+ } else {
30
+ return group.items.map((item) => (
31
+ <CheckboxListItem
32
+ key={item.id}
33
+ id={item.id}
34
+ label={item.label}
35
+ onChange={onChange}
36
+ isChecked={item.isChecked}
37
+ className={"my-1"}
38
+ />
39
+ ));
40
+ }
41
+ })}
42
+ </div>
43
+ );
27
44
  };
28
45
 
29
46
  export default CheckboxList;
@@ -1,45 +1,47 @@
1
1
  export enum CheckboxState {
2
- CHECKED = "checked",
3
- INDETERMINATE = "indeterminate",
4
- UNCHECKED = "unchecked"
2
+ CHECKED = "checked",
3
+ INDETERMINATE = "indeterminate",
4
+ UNCHECKED = "unchecked",
5
5
  }
6
6
 
7
7
  export interface CheckboxListProps {
8
- groups: CheckboxGroup[];
9
- onChange: (event: CheckboxChangeEvent) => void;
10
- className?: string;
8
+ groups: CheckboxGroup[];
9
+ onChange: (event: CheckboxChangeEvent) => void;
10
+ className?: string;
11
11
  }
12
12
 
13
13
  export interface CheckboxGroupProps {
14
- //If you don't specify a title than it will just be a non-collapsible list
15
- title?: string,
16
- items: CheckboxListItem[],
17
- onChange: (event: CheckboxChangeEvent) => void;
18
- className?: string;
14
+ //If you don't specify a title than it will just be a non-collapsible list
15
+ title?: string;
16
+ items: CheckboxListItem[];
17
+ onChange: (event: CheckboxChangeEvent) => void;
18
+ className?: string;
19
+ isCollapsed?: boolean;
19
20
  }
20
21
 
21
22
  export interface CheckboxGroupItemProps {
22
- id: string,
23
- label: string,
24
- isChecked?: boolean,
25
- onChange: (event: CheckboxChangeEvent) => void;
26
- className?: string;
23
+ id: string;
24
+ label: string;
25
+ isChecked?: boolean;
26
+ onChange: (event: CheckboxChangeEvent) => void;
27
+ className?: string;
27
28
  }
28
29
 
29
30
  export interface CheckboxListItem {
30
- id: string,
31
- label: string,
32
- isChecked?: boolean,
33
- className?: string,
31
+ id: string;
32
+ label: string;
33
+ isChecked?: boolean;
34
+ className?: string;
34
35
  }
35
36
 
36
37
  export interface CheckboxGroup {
37
- //If you don't specify a title than it will just be a non-collapsible list
38
- title?: string,
39
- items: CheckboxListItem[],
38
+ //If you don't specify a title than it will just be a non-collapsible list
39
+ title?: string;
40
+ items: CheckboxListItem[];
41
+ isCollapsed?: boolean;
40
42
  }
41
43
 
42
44
  export interface CheckboxChangeEvent {
43
- id: string,
44
- newCheckedValue: boolean
45
+ id: string;
46
+ newCheckedValue: boolean;
45
47
  }
@@ -0,0 +1,23 @@
1
+ li {
2
+ &.gu-mirror {
3
+ @apply shadow-xl m-0 fixed z-9999;
4
+ }
5
+
6
+ &.gu-hide {
7
+ @apply hidden;
8
+ }
9
+
10
+ &.gu-unselectable {
11
+ @apply select-none;
12
+ }
13
+
14
+ &.gu-transit {
15
+ @apply bg-blue-50;
16
+ @apply outline-dropTarget;
17
+ filter: none;
18
+ @apply opacity-100 rounded-none border-none; // TODO we only need these to override them in cVitals-Web
19
+ }
20
+ &.gu-transit > * {
21
+ @apply invisible;
22
+ }
23
+ }
@@ -10,10 +10,11 @@ import {
10
10
  ListProps,
11
11
  ListItemProps,
12
12
  OnAssetLoadErrorPayload,
13
- Dragula,
14
13
  } from "./List.types";
15
14
  import { ListSkeleton } from "./ListSkeleton";
16
15
 
16
+ import "./List.scss";
17
+
17
18
  export { ListProps, ListItemProps, OnAssetLoadErrorPayload };
18
19
 
19
20
  export const List = ({
@@ -27,19 +28,19 @@ export const List = ({
27
28
  isLoading,
28
29
  }: ListProps): JSX.Element => {
29
30
  const listRef = useRef<HTMLUListElement | null>(null);
30
- const dragulaRef = useRef<Dragula | null>(null);
31
+ const dragulaRef = useRef<dragula.Drake | null>(null);
31
32
  const hasHeader = !!(title || headerButton);
32
33
 
33
34
  useEffect(() => {
34
35
  dragulaRef.current?.destroy?.();
35
- if (onDragEnd && items.length) {
36
+ if (listRef.current && onDragEnd && items.length) {
36
37
  dragulaRef.current = setupDragging();
37
38
  }
38
39
 
39
40
  return () => {
40
41
  dragulaRef.current?.destroy?.();
41
42
  };
42
- }, [items]);
43
+ }, [items, listRef]);
43
44
 
44
45
  const handleDragEnd = (element: HTMLElement) => {
45
46
  const draggedItemId = element.dataset["id"];
@@ -61,11 +62,14 @@ export const List = ({
61
62
  }
62
63
  };
63
64
 
64
- const setupDragging = (): Dragula => {
65
+ const setupDragging = (): dragula.Drake | null => {
66
+ if (!listRef.current) {
67
+ return null;
68
+ }
65
69
  const dragulaInstance = dragula([listRef.current], {
66
70
  revertOnSpill: true,
67
71
  });
68
- dragulaInstance.on("dragend", handleDragEnd);
72
+ dragulaInstance.on("dragend", handleDragEnd as (Element) => void);
69
73
 
70
74
  return dragulaInstance;
71
75
  };
@@ -39,7 +39,3 @@ export type ListProps = {
39
39
  emptyStateMessage?: string;
40
40
  isLoading?: boolean;
41
41
  };
42
-
43
- export interface Dragula {
44
- destroy?: () => void;
45
- }
@@ -2,7 +2,7 @@
2
2
  position: fixed;
3
3
  left: 50%;
4
4
  transform: translate(-50%, 150%);
5
- bottom: 15px;
5
+ bottom: 48px;
6
6
 
7
7
  // https://easings.net/#easeInOutBack
8
8
  transition: transform 0.3s cubic-bezier(0.68, -0.6, 0.32, 1.6);