@grantbii/design-system 1.0.56 → 1.0.58

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.
@@ -107,10 +107,7 @@ export const useFileDrop = (initialFiles = [], maxFiles = DEFAULT_MAX_FILES, max
107
107
  errorMessage,
108
108
  };
109
109
  };
110
- const anyFileTooLarge = (files, maxSizeMB) => files.some((file) => {
111
- console.log("file size:", file.size);
112
- return file.size > convertMegabytesToBytes(maxSizeMB);
113
- });
110
+ const anyFileTooLarge = (files, maxSizeMB) => files.some((file) => file.size > convertMegabytesToBytes(maxSizeMB));
114
111
  const convertMegabytesToBytes = (megabytes) => megabytes * 1024 * 1024;
115
112
  const combineFilesWithoutDuplicates = (oldFiles, newFiles) => {
116
113
  const newFileNames = newFiles.map((file) => file.name);
@@ -1,18 +1,14 @@
1
1
  import { GrantMatchQuery } from "@grantbii/ui-base/match/models";
2
- type GrantMatchProps = {
3
- query: GrantMatchQuery;
4
- onPerformGrantMatch: (newQuery: GrantMatchQuery) => void;
5
- removeQueryFile: (fileName: string) => void;
6
- removeQueryText: () => void;
7
- resetQuery: () => void;
8
- isModalFullScreen?: boolean;
2
+ type GrantMatchProps = GrantMatchQueryProps & {
3
+ isSmallerThanLaptop?: boolean;
9
4
  };
10
- declare const GrantMatch: ({ query, onPerformGrantMatch, removeQueryFile, removeQueryText, resetQuery, isModalFullScreen, }: GrantMatchProps) => import("react/jsx-runtime").JSX.Element;
5
+ declare const GrantMatch: ({ query, updateQuery, removeQueryFile, removeQueryText, resetQuery, isSmallerThanLaptop, }: GrantMatchProps) => import("react/jsx-runtime").JSX.Element;
11
6
  export default GrantMatch;
12
- export declare const useGrantMatchQueryItems: () => {
7
+ type GrantMatchQueryProps = {
13
8
  query: GrantMatchQuery;
14
9
  updateQuery: (newQuery: GrantMatchQuery) => void;
15
10
  removeQueryFile: (fileName: string) => void;
16
11
  removeQueryText: () => void;
17
12
  resetQuery: () => void;
18
13
  };
14
+ export declare const useGrantMatchQueryItems: (performGrantMatch: (newQuery: GrantMatchQuery) => void, resetGrantMatch: () => void) => GrantMatchQueryProps;
@@ -5,26 +5,54 @@ import styled from "styled-components";
5
5
  import { Badge, Button, Textarea } from "../atoms";
6
6
  import { Colors, Icons } from "../foundations";
7
7
  import { FileDrop, Modal, useFileDrop, useModal } from "../molecules";
8
- const GrantMatch = ({ query, onPerformGrantMatch, removeQueryFile, removeQueryText, resetQuery, isModalFullScreen, }) => {
8
+ const GrantMatch = ({ query, updateQuery, removeQueryFile, removeQueryText, resetQuery, isSmallerThanLaptop, }) => {
9
9
  const { showModal, openModal, closeModal } = useModal();
10
10
  const isActive = isGrantMatchActive(query);
11
- const performGrantMatch = (newQuery) => {
12
- onPerformGrantMatch(newQuery);
11
+ const updateActiveQuery = (newQuery) => {
12
+ updateQuery(newQuery);
13
13
  closeModal();
14
14
  };
15
- return (_jsxs(Container, { children: [_jsx(GrantMatchButtons, { isActive: isActive, onClickMatch: () => openModal(), onClickReset: () => resetQuery() }), isActive ? (_jsx(QueryItems, { queryFiles: query.files, removeQueryFile: removeQueryFile, queryText: query.text, removeQueryText: removeQueryText })) : (_jsx(_Fragment, {})), showModal ? (_jsx(GrantMatchModal, { activeFiles: query.files, activeText: query.text, performGrantMatch: performGrantMatch, onClickCancel: () => closeModal(), isFullScreen: isModalFullScreen })) : (_jsx(_Fragment, {}))] }));
15
+ return (_jsxs(BaseGrantMatch, { children: [_jsx(GrantMatchButtons, { isActive: isActive, onClickMatch: () => openModal(), onClickReset: () => resetQuery(), isSmallerThanLaptop: isSmallerThanLaptop }), isActive ? (_jsxs(QueryItemsRow, { children: [_jsx(QueryItems, { activeQuery: query, removeQueryFile: removeQueryFile, removeQueryText: removeQueryText }), isSmallerThanLaptop ? (_jsx(ResetButton, { onClick: () => resetQuery() })) : (_jsx(_Fragment, {}))] })) : (_jsx(_Fragment, {})), showModal ? (_jsx(GrantMatchModal, { activeQuery: query, updateActiveQuery: updateActiveQuery, onClickCancel: () => closeModal(), isFullScreen: isSmallerThanLaptop })) : (_jsx(_Fragment, {}))] }));
16
16
  };
17
17
  export default GrantMatch;
18
- const BLANK_GRANT_MATCH_QUERY = { files: [], text: "" };
19
- export const useGrantMatchQueryItems = () => {
18
+ export const useGrantMatchQueryItems = (performGrantMatch, resetGrantMatch) => {
20
19
  const [query, setQuery] = useState(() => (Object.assign({}, BLANK_GRANT_MATCH_QUERY)));
21
- const updateQuery = (newQuery) => setQuery(Object.assign({}, newQuery));
22
- const removeQueryFile = (fileName) => setQuery(({ files, text }) => ({
23
- files: files.filter((file) => file.name !== fileName),
24
- text,
25
- }));
26
- const removeQueryText = () => setQuery(({ files }) => ({ files, text: "" }));
27
- const resetQuery = () => setQuery(Object.assign({}, BLANK_GRANT_MATCH_QUERY));
20
+ const updateQuery = (newQuery) => {
21
+ setQuery(Object.assign({}, newQuery));
22
+ if (isGrantMatchActive(newQuery)) {
23
+ performGrantMatch(newQuery);
24
+ }
25
+ else {
26
+ resetGrantMatch();
27
+ }
28
+ };
29
+ const removeQueryFile = (fileName) => {
30
+ const newQuery = {
31
+ files: query.files.filter((file) => file.name !== fileName),
32
+ text: query.text,
33
+ };
34
+ updateQuery(newQuery);
35
+ if (isGrantMatchActive(newQuery)) {
36
+ performGrantMatch(newQuery);
37
+ }
38
+ else {
39
+ resetGrantMatch();
40
+ }
41
+ };
42
+ const removeQueryText = () => {
43
+ const newQuery = { files: query.files, text: "" };
44
+ updateQuery(newQuery);
45
+ if (isGrantMatchActive(newQuery)) {
46
+ performGrantMatch(newQuery);
47
+ }
48
+ else {
49
+ resetGrantMatch();
50
+ }
51
+ };
52
+ const resetQuery = () => {
53
+ setQuery(Object.assign({}, BLANK_GRANT_MATCH_QUERY));
54
+ resetGrantMatch();
55
+ };
28
56
  return {
29
57
  query,
30
58
  updateQuery,
@@ -33,49 +61,65 @@ export const useGrantMatchQueryItems = () => {
33
61
  resetQuery,
34
62
  };
35
63
  };
36
- const Container = styled.div `
64
+ const BLANK_GRANT_MATCH_QUERY = { files: [], text: "" };
65
+ const BaseGrantMatch = styled.div `
37
66
  display: flex;
38
67
  flex-direction: column;
39
68
  gap: 8px;
40
69
 
41
- padding: 16px 16px 0px 16px;
42
-
43
70
  width: 100%;
44
71
  max-width: 100vw;
45
72
  `;
46
- const GrantMatchButtons = ({ isActive, onClickMatch, onClickReset, }) => (_jsxs(Buttons, { children: [_jsx(GrantMatchButton, { isActive: isActive, onClick: onClickMatch }), isActive ? (_jsx(Button, { text: "Reset", onClick: onClickReset, color: Colors.typography.blackMedium, underline: true })) : (_jsx(_Fragment, {}))] }));
73
+ const GrantMatchButtons = ({ isActive, onClickMatch, onClickReset, isSmallerThanLaptop, }) => (_jsxs(Buttons, { children: [_jsx(GrantMatchButton, { isActive: isActive, isSmallerThanLaptop: isSmallerThanLaptop, onClick: onClickMatch }), !isSmallerThanLaptop && isActive ? (_jsx(ResetButton, { onClick: onClickReset })) : (_jsx(_Fragment, {}))] }));
47
74
  const Buttons = styled.div `
48
75
  display: flex;
49
76
  align-items: center;
50
77
  gap: 8px;
51
78
  `;
52
- const GrantMatchButton = ({ isActive, onClick }) => (_jsxs(BaseGrantMatchButton, { type: "button", "$isActive": isActive, onClick: onClick, children: [_jsx(Icons.GrantMatchIcon, { size: 20 }), _jsx("p", { children: "Find grants that match your needs" }), _jsx(Icons.MagnifyingGlassIcon, { size: 20 })] }));
79
+ const GrantMatchButton = ({ isActive, onClick, isSmallerThanLaptop, }) => (_jsxs(BaseGrantMatchButton, { type: "button", "$isSmallerThanLaptop": isSmallerThanLaptop, "$isActive": isActive, onClick: onClick, children: [_jsxs(GrantMatchButtonContent, { children: [_jsx(Icons.GrantMatchIcon, { size: 20 }), _jsx("p", { children: "Find grants that match your needs" })] }), _jsx(Icons.MagnifyingGlassIcon, { size: 20 })] }));
53
80
  const BaseGrantMatchButton = styled.button `
54
81
  display: flex;
55
82
  align-items: center;
56
- gap: 8px;
83
+ justify-content: space-between;
84
+ gap: 16px;
57
85
 
58
- height: 20px;
59
86
  padding: 10px 16px;
60
- border-radius: 200px;
87
+
88
+ height: 20px;
89
+ width: ${({ $isSmallerThanLaptop = false }) => $isSmallerThanLaptop ? "100%" : "auto"};
61
90
 
62
91
  font-size: 14px;
63
92
  font-weight: 500;
64
93
 
65
- color: ${Colors.typography.blackMedium};
66
94
  background-color: ${Colors.base.white};
95
+ color: ${Colors.typography.blackMedium};
96
+
67
97
  border: 1px solid
68
98
  ${({ $isActive }) => $isActive ? Colors.accent.yellow1 : Colors.neutral.grey3};
99
+ border-radius: 200px;
100
+ `;
101
+ const GrantMatchButtonContent = styled.div `
102
+ display: flex;
103
+ align-items: center;
104
+ gap: 8px;
69
105
  `;
70
- const QueryItems = ({ queryFiles, removeQueryFile, queryText, removeQueryText, }) => (_jsxs(BaseQueryItems, { children: [queryFiles.map((file) => {
106
+ const ResetButton = ({ onClick }) => (_jsx(Button, { text: "Reset", onClick: onClick, color: Colors.typography.blackMedium, underline: true }));
107
+ const QueryItemsRow = styled.div `
108
+ display: flex;
109
+ align-items: center;
110
+ justify-content: space-between;
111
+ `;
112
+ const QueryItems = ({ activeQuery, removeQueryFile, removeQueryText, }) => (_jsxs(BaseQueryItems, { children: [activeQuery.files.map((file) => {
71
113
  var _a;
72
114
  return (_jsx(Badge, { text: file.name, Icon: (_a = FILE_TYPE_ICON_MAP[file.type]) !== null && _a !== void 0 ? _a : Icons.FileIcon, onClickClose: () => removeQueryFile(file.name), textWidthPixels: 160 }, file.name));
73
- }), queryText === "" ? (_jsx(_Fragment, {})) : (_jsx(Badge, { text: "Additional Information", Icon: Icons.TextAaIcon, onClickClose: () => removeQueryText(), textWidthPixels: 180 }, "additional-information-query-item"))] }));
115
+ }), activeQuery.text === "" ? (_jsx(_Fragment, {})) : (_jsx(Badge, { text: "Additional Information", Icon: Icons.TextAaIcon, onClickClose: () => removeQueryText(), textWidthPixels: 180 }, "additional-information-query-item"))] }));
74
116
  const BaseQueryItems = styled.div `
75
117
  display: flex;
76
118
  align-items: center;
77
119
  gap: 8px;
78
120
 
121
+ width: 100%;
122
+
79
123
  overflow-x: auto;
80
124
 
81
125
  /* hide scrollbar but still allow for scrolling */
@@ -84,14 +128,16 @@ const BaseQueryItems = styled.div `
84
128
  ::-webkit-scrollbar {
85
129
  display: none;
86
130
  }
131
+
132
+ /* TODO: fade effect on overflow-x */
87
133
  `;
88
134
  const FILE_TYPE_ICON_MAP = {
89
135
  "application/pdf": Icons.FilePdfIcon,
90
136
  };
91
- const GrantMatchModal = ({ activeFiles, activeText, performGrantMatch, onClickCancel, isFullScreen, }) => {
92
- const { files, uploadFiles, removeFile } = useFileDrop(activeFiles);
93
- const [text, setText] = useState(activeText);
94
- return (_jsx(Modal, { header: _jsx(Header, {}), content: _jsx(Content, { files: files, uploadFiles: uploadFiles, removeFile: removeFile, queryText: text, updateQueryText: (newText) => setText(newText) }), footer: _jsx(Button, { text: "Find My Grants", onClick: () => performGrantMatch({ files, text }), backgroundColor: Colors.accent.yellow1 }), onClickCancel: onClickCancel, isFullScreen: isFullScreen }));
137
+ const GrantMatchModal = ({ activeQuery, updateActiveQuery, onClickCancel, isFullScreen, }) => {
138
+ const { files, uploadFiles, removeFile } = useFileDrop(activeQuery.files);
139
+ const [text, setText] = useState(activeQuery.text);
140
+ return (_jsx(Modal, { header: _jsx(Header, {}), content: _jsx(Content, { files: files, uploadFiles: uploadFiles, removeFile: removeFile, queryText: text, updateQueryText: (newText) => setText(newText) }), footer: _jsx(Button, { text: "Find My Grants", onClick: () => updateActiveQuery({ files, text }), backgroundColor: Colors.accent.yellow1 }), onClickCancel: onClickCancel, isFullScreen: isFullScreen, width: "480px" }));
95
141
  };
96
142
  const Header = () => (_jsxs(BaseHeader, { children: [_jsx(Icons.GrantMatchIcon, { size: 24 }), _jsx("div", { children: "Grant Match" })] }));
97
143
  const BaseHeader = styled.div `
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@grantbii/design-system",
3
- "version": "1.0.56",
3
+ "version": "1.0.58",
4
4
  "description": "Grantbii's Design System",
5
5
  "homepage": "https://design.grantbii.com",
6
6
  "repository": {
@@ -1,10 +1,10 @@
1
1
  import { Meta, StoryObj } from "@storybook/nextjs-vite";
2
2
  type GrantMatchExampleProps = {
3
- isModalFullScreen?: boolean;
3
+ isMobile?: boolean;
4
4
  };
5
- declare const GrantMatchExample: ({ isModalFullScreen }: GrantMatchExampleProps) => import("react/jsx-runtime").JSX.Element;
5
+ declare const GrantMatchExample: ({ isMobile }: GrantMatchExampleProps) => import("react/jsx-runtime").JSX.Element;
6
6
  declare const meta: Meta<typeof GrantMatchExample>;
7
7
  export default meta;
8
8
  type Story = StoryObj<typeof meta>;
9
- export declare const PopUp: Story;
10
- export declare const FullScreen: Story;
9
+ export declare const Desktop: Story;
10
+ export declare const Mobile: Story;
@@ -1,17 +1,31 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { GrantMatch } from "@/.";
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Colors, GrantMatch } from "@/.";
3
3
  import { useGrantMatchQueryItems } from "@/core/organisms/GrantMatch";
4
+ import { useState } from "react";
4
5
  import styled from "styled-components";
5
- const GrantMatchExample = ({ isModalFullScreen }) => {
6
- const { query, updateQuery, removeQueryFile, removeQueryText, resetQuery } = useGrantMatchQueryItems();
7
- const onPerformGrantMatch = (newQuery) => {
8
- updateQuery(newQuery);
9
- console.log("finding grants...");
6
+ const GrantMatchExample = ({ isMobile }) => {
7
+ const [status, setStatus] = useState("pending query");
8
+ const performGrantMatch = (newQuery) => {
9
+ const fileNames = newQuery.files.map((file) => file.name).join(", ");
10
+ setStatus(`finding grants using files [${fileNames}] and text [${newQuery.text}]`);
11
+ setTimeout(() => setStatus("found grants"), 3000);
10
12
  };
11
- return (_jsx(Container, { children: _jsx(GrantMatch, { query: query, onPerformGrantMatch: onPerformGrantMatch, removeQueryFile: removeQueryFile, removeQueryText: removeQueryText, resetQuery: resetQuery, isModalFullScreen: isModalFullScreen }) }));
13
+ const resetGrantMatch = () => setStatus("pending query");
14
+ const grantMatchQueryProps = useGrantMatchQueryItems(performGrantMatch, resetGrantMatch);
15
+ return (_jsxs(Container, { "$isMobile": isMobile, children: [_jsx(GrantMatch, Object.assign({}, grantMatchQueryProps, { isSmallerThanLaptop: isMobile })), _jsxs("p", { children: ["Status: ", status] })] }));
12
16
  };
13
17
  const Container = styled.div `
14
- width: 90vw;
18
+ display: flex;
19
+ flex-direction: column;
20
+ gap: 8px;
21
+
22
+ padding: 16px;
23
+
24
+ width: ${({ $isMobile = false }) => ($isMobile ? "360px" : "90vw")};
25
+ height: ${({ $isMobile = false }) => ($isMobile ? "600px" : "100vh")};
26
+
27
+ border: ${({ $isMobile = false }) => $isMobile ? `1px solid ${Colors.neutral.grey2}` : "none"};
28
+ border-radius: 32px;
15
29
  `;
16
30
  const meta = {
17
31
  title: "Organisms/Grant Match",
@@ -22,9 +36,9 @@ const meta = {
22
36
  },
23
37
  };
24
38
  export default meta;
25
- export const PopUp = {
26
- args: {},
39
+ export const Desktop = {
40
+ args: { isMobile: false },
27
41
  };
28
- export const FullScreen = {
29
- args: { isModalFullScreen: true },
42
+ export const Mobile = {
43
+ args: { isMobile: true },
30
44
  };