sanity-plugin-utils 1.0.1 → 1.0.3

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/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2022 Simeon Griggs
3
+ Copyright (c) 2023 Simeon Griggs
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -1,3 +1,11 @@
1
+ > This is a **Sanity Studio v3** plugin.
2
+
3
+ ## Installation
4
+
5
+ ```sh
6
+ npm install sanity-plugin-utils
7
+ ```
8
+
1
9
  > This is exclusively a **Sanity Studio v3** plugin.
2
10
 
3
11
  # sanity-plugin-utils
@@ -61,7 +69,7 @@ Hook for getting extended details on all Users in the project. Such as name.
61
69
  import {useProjectUsers} from 'sanity-plugin-utils'
62
70
 
63
71
  export default function DocumentList() {
64
- const users = useProjectUsers()
72
+ const users = useProjectUsers({apiVersion: `2023-01-01`})
65
73
 
66
74
  return (
67
75
  <Stack>
@@ -30,6 +30,10 @@ declare type FeedbackTextProps = {
30
30
  children?: never
31
31
  }
32
32
 
33
+ declare type HookConfig = {
34
+ apiVersion?: string
35
+ }
36
+
33
37
  declare interface ListenQueryOptions {
34
38
  tag?: string
35
39
  apiVersion?: string
@@ -64,9 +68,11 @@ export declare function useListeningQuery<V>(
64
68
  {params, options, initialValue}: Config<V>
65
69
  ): Return<V>
66
70
 
67
- export declare function useProjectUsers(): UserExtended[]
71
+ export declare function useProjectUsers({
72
+ apiVersion,
73
+ }: HookConfig): UserExtended[]
68
74
 
69
- declare type UserExtended = {
75
+ export declare type UserExtended = {
70
76
  createdAt: string
71
77
  displayName: string
72
78
  email: string
@@ -90,7 +96,6 @@ declare type UserSelectMenuProps = {
90
96
  onAdd: any
91
97
  onRemove: any
92
98
  onClear: any
93
- open: boolean
94
99
  style?: React_2.CSSProperties
95
100
  }
96
101
 
package/lib/index.esm.js CHANGED
@@ -1,2 +1,277 @@
1
- const e=["children"],n=["children"],t=["children"];var r,i,o;function l(e,n){if(null==e)return{};var t,r,i=function(e,n){if(null==e)return{};var t,r,i={},o=Object.keys(e);for(r=0;r<o.length;r++)t=o[r],n.indexOf(t)>=0||(i[t]=e[t]);return i}(e,n);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r<o.length;r++)t=o[r],n.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}function c(e,n){return n||(n=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(n)}}))}function s(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function a(e){for(var n=1;n<arguments.length;n++){var t=null!=arguments[n]?arguments[n]:{};n%2?s(Object(t),!0).forEach((function(n){d(e,n,t[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):s(Object(t)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(t,n))}))}return e}function d(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}import u,{useState as p,useRef as f,useEffect as h}from"react";import{distinctUntilChanged as m,catchError as b}from"rxjs/operators";import y from"react-fast-compare";import{useDocumentStore as g,useWorkspace as O,useClient as v,UserAvatar as j}from"sanity";import{jsx as w,jsxs as C}from"react/jsx-runtime";import{Card as P,Flex as x,Box as S,Stack as U,Text as k,Menu as N,MenuItem as z,TextInput as L,Badge as D}from"@sanity/ui";import I,{css as W}from"styled-components";import{RemoveCircleIcon as E,AddCircleIcon as q,RestoreIcon as A}from"@sanity/icons";const V={},M={apiVersion:"v2022-05-09"},Q=null;function R(e,n){let{params:t=V,options:r=M,initialValue:i=Q}=n;const[o,l]=p(!0),[c,s]=p(!1),[a,d]=p(i),u=f(null),O=g();return h((()=>(e&&(u.current=O.listenQuery(e,t,r).pipe(m(y),b((e=>(console.error(e),s(e),l(!1),d(null),e)))).subscribe((e=>{d((n=>y(n,e)?n:e)),l(!1),s(!1)}))),()=>{var e;return null==(e=null==u?void 0:u.current)?void 0:e.unsubscribe()})),[e,t,r,O]),{data:a,loading:o,error:c}}function X(){const{currentUser:e}=O(),n=v(),[t,r]=p([]);return h((()=>{const{projectId:i}=n.config();t.length||async function(){const t=await n.request({url:"/projects/".concat(i,"/acl")}).then((async t=>Promise.all(t.map((async t=>a({isCurrentUser:t.projectUserId===(null==e?void 0:e.id)},await async function(e){return await n.request({url:"/projects/".concat(i,"/users/").concat(e)})}(t.projectUserId))))))).catch((e=>e));r(t)}()}),[n,null==e?void 0:e.id,t.length]),t}const B={tone:"primary"};function F(e){const{title:n,description:t,icon:r,tone:i,children:o}=a(a({},B),e);return w(P,{tone:i,padding:4,radius:3,border:!0,children:C(x,{children:[r?"display icon":null,o||w(S,{flex:1,children:C(U,{space:4,children:[n?w(k,{weight:"semibold",children:n}):null,t?w(k,{size:2,children:t}):null]})})]})})}const G=I((function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return w(P,a({as:"table"},e))}))((()=>W(r||(r=c(["\n display: table;\n width: 100%;\n\n &:not([hidden]) {\n display: table;\n }\n "])))));function H(n){const{children:t}=n,r=l(n,e);return w(G,a(a({},r),{},{children:t}))}const J=I((function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return w(P,a({as:"tr"},e))}))((()=>W(i||(i=c(["\n display: table-row;\n\n &:not([hidden]) {\n display: table-row;\n }\n "])))));function K(e){const{children:t}=e,r=l(e,n);return w(J,a(a({},r),{},{children:t}))}const T=I((function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return w(P,a({as:"td"},e))}))((()=>W(o||(o=c(["\n display: table-cell;\n\n &:not([hidden]) {\n display: table-cell;\n }\n "])))));function Y(e){const{children:n}=e,r=l(e,t);return w(T,a(a({},r),{},{children:n}))}function Z(e){const{value:n=[],userList:t=[],onAdd:r,onRemove:i,onClear:o,style:l={}}=e,[c,s]=u.useState(""),a=function(e,n){return e.filter((e=>!!(e.displayName||"").toLowerCase().startsWith(n)||(!!(e.givenName||"").toLowerCase().startsWith(n)||(!!(e.middleName||"").toLowerCase().startsWith(n)||!!(e.familyName||"").toLowerCase().startsWith(n)))))}(t||[],c),d=t.find((e=>e.isCurrentUser)),p=d&&n.includes(d.id),h=f();return C(N,{style:l,children:[w(z,p?{tone:"caution",disabled:!d,onClick:()=>{d&&i&&i(d.id)},icon:E,text:"Unassign myself"}:{tone:"positive",onClick:()=>{d&&r&&r(d.id)},icon:q,text:"Assign myself"}),w(z,{tone:"critical",disabled:0===n.length,onClick:()=>{o&&o()},icon:A,text:"Clear assignees"}),w(S,{padding:1,children:w(L,{ref:h,onChange:e=>{s(e.target.value)},placeholder:"Search members",value:c})}),c&&0===(null==a?void 0:a.length)&&w(z,{disabled:!0,text:"No matches"}),a&&a.map((e=>w(z,{pressed:n.includes(e.id),onClick:()=>((e,n)=>{e?i&&i(n.id):r&&r(n.id)})(n.indexOf(e.id)>-1,e),children:C(x,{align:"center",children:[w(j,{user:e,size:1}),w(S,{paddingX:2,flex:1,children:w(k,{children:e.displayName})}),e.isCurrentUser&&w(D,{fontSize:1,tone:"positive",mode:"outline",children:"Me"})]})},e.id)))]})}export{Y as Cell,F as Feedback,K as Row,H as Table,Z as UserSelectMenu,R as useListeningQuery,X as useProjectUsers};
1
+ var _templateObject, _templateObject2, _templateObject3;
2
+ function _taggedTemplateLiteral(strings, raw) { if (!raw) { raw = strings.slice(0); } return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); }
3
+ import React, { useState, useRef, useEffect } from 'react';
4
+ import { distinctUntilChanged, catchError } from 'rxjs/operators';
5
+ import isEqual from 'react-fast-compare';
6
+ import { useDocumentStore, useWorkspace, useClient, UserAvatar } from 'sanity';
7
+ import { jsx, jsxs } from 'react/jsx-runtime';
8
+ import { Card, Flex, Box, Stack, Text, Menu, MenuItem, TextInput, Badge } from '@sanity/ui';
9
+ import styled, { css } from 'styled-components';
10
+ import { RemoveCircleIcon, AddCircleIcon, RestoreIcon } from '@sanity/icons';
11
+ const DEFAULT_PARAMS = {};
12
+ const DEFAULT_OPTIONS = {
13
+ apiVersion: "v2022-05-09"
14
+ };
15
+ const DEFAULT_INITIAL_VALUE = null;
16
+ function useListeningQuery(query, _ref) {
17
+ let {
18
+ params = DEFAULT_PARAMS,
19
+ options = DEFAULT_OPTIONS,
20
+ initialValue = DEFAULT_INITIAL_VALUE
21
+ } = _ref;
22
+ const [loading, setLoading] = useState(true);
23
+ const [error, setError] = useState(false);
24
+ const [data, setData] = useState(initialValue);
25
+ const subscription = useRef(null);
26
+ const documentStore = useDocumentStore();
27
+ useEffect(() => {
28
+ if (query) {
29
+ subscription.current = documentStore.listenQuery(query, params, options).pipe(distinctUntilChanged(isEqual), catchError(err => {
30
+ console.error(err);
31
+ setError(err);
32
+ setLoading(false);
33
+ setData(null);
34
+ return err;
35
+ })).subscribe(documents => {
36
+ setData(current => isEqual(current, documents) ? current : documents);
37
+ setLoading(false);
38
+ setError(false);
39
+ });
40
+ }
41
+ return () => {
42
+ var _a;
43
+ return (_a = subscription == null ? void 0 : subscription.current) == null ? void 0 : _a.unsubscribe();
44
+ };
45
+ }, [query, params, options, documentStore]);
46
+ return {
47
+ data,
48
+ loading,
49
+ error
50
+ };
51
+ }
52
+ function useProjectUsers(_ref2) {
53
+ let {
54
+ apiVersion
55
+ } = _ref2;
56
+ const {
57
+ currentUser
58
+ } = useWorkspace();
59
+ const client = useClient({
60
+ apiVersion: apiVersion != null ? apiVersion : "2023-01-01"
61
+ });
62
+ const [users, setUsers] = useState([]);
63
+ useEffect(() => {
64
+ const {
65
+ projectId
66
+ } = client.config();
67
+ async function getUser(id) {
68
+ const userDetails = await client.request({
69
+ url: "/projects/".concat(projectId, "/users/").concat(id)
70
+ });
71
+ return userDetails;
72
+ }
73
+ async function getUsersWithRoles() {
74
+ const userRoles = await client.request({
75
+ url: "/projects/".concat(projectId, "/acl")
76
+ }).then(async res => Promise.all(res.map(async user => ({
77
+ isCurrentUser: user.projectUserId === (currentUser == null ? void 0 : currentUser.id),
78
+ ...(await getUser(user.projectUserId))
79
+ })))).catch(err => err);
80
+ setUsers(userRoles);
81
+ }
82
+ if (!users.length) {
83
+ getUsersWithRoles();
84
+ }
85
+ }, [client, currentUser == null ? void 0 : currentUser.id, users.length]);
86
+ return users;
87
+ }
88
+ const DEFAULT_PROPS = {
89
+ tone: "primary"
90
+ };
91
+ function Feedback(props) {
92
+ const {
93
+ title,
94
+ description,
95
+ icon,
96
+ tone,
97
+ children
98
+ } = {
99
+ ...DEFAULT_PROPS,
100
+ ...props
101
+ };
102
+ return /* @__PURE__ */jsx(Card, {
103
+ tone,
104
+ padding: 4,
105
+ radius: 3,
106
+ border: true,
107
+ children: /* @__PURE__ */jsxs(Flex, {
108
+ children: [icon ? "display icon" : null, children ? children : /* @__PURE__ */jsx(Box, {
109
+ flex: 1,
110
+ children: /* @__PURE__ */jsxs(Stack, {
111
+ space: 4,
112
+ children: [title ? /* @__PURE__ */jsx(Text, {
113
+ weight: "semibold",
114
+ children: title
115
+ }) : null, description ? /* @__PURE__ */jsx(Text, {
116
+ size: 2,
117
+ children: description
118
+ }) : null]
119
+ })
120
+ })]
121
+ })
122
+ });
123
+ }
124
+ const TableWrapper = function () {
125
+ let props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
126
+ return /* @__PURE__ */jsx(Card, {
127
+ as: "table",
128
+ ...props
129
+ });
130
+ };
131
+ const StyledTable = styled(TableWrapper)(() => css(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n display: table;\n width: 100%;\n\n &:not([hidden]) {\n display: table;\n }\n "]))));
132
+ function Table(props) {
133
+ const {
134
+ children,
135
+ ...rest
136
+ } = props;
137
+ return /* @__PURE__ */jsx(StyledTable, {
138
+ ...rest,
139
+ children
140
+ });
141
+ }
142
+ const RowWrapper = function () {
143
+ let props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
144
+ return /* @__PURE__ */jsx(Card, {
145
+ as: "tr",
146
+ ...props
147
+ });
148
+ };
149
+ const StyledRow = styled(RowWrapper)(() => css(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n display: table-row;\n\n &:not([hidden]) {\n display: table-row;\n }\n "]))));
150
+ function Row(props) {
151
+ const {
152
+ children,
153
+ ...rest
154
+ } = props;
155
+ return /* @__PURE__ */jsx(StyledRow, {
156
+ ...rest,
157
+ children
158
+ });
159
+ }
160
+ const CellWrapper = function () {
161
+ let props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
162
+ return /* @__PURE__ */jsx(Card, {
163
+ as: "td",
164
+ ...props
165
+ });
166
+ };
167
+ const StyledCell = styled(CellWrapper)(() => css(_templateObject3 || (_templateObject3 = _taggedTemplateLiteral(["\n display: table-cell;\n\n &:not([hidden]) {\n display: table-cell;\n }\n "]))));
168
+ function Cell(props) {
169
+ const {
170
+ children,
171
+ ...rest
172
+ } = props;
173
+ return /* @__PURE__ */jsx(StyledCell, {
174
+ ...rest,
175
+ children
176
+ });
177
+ }
178
+ function searchUsers(users, searchString) {
179
+ return users.filter(user => {
180
+ const displayName = (user.displayName || "").toLowerCase();
181
+ if (displayName.startsWith(searchString)) return true;
182
+ const givenName = (user.givenName || "").toLowerCase();
183
+ if (givenName.startsWith(searchString)) return true;
184
+ const middleName = (user.middleName || "").toLowerCase();
185
+ if (middleName.startsWith(searchString)) return true;
186
+ const familyName = (user.familyName || "").toLowerCase();
187
+ if (familyName.startsWith(searchString)) return true;
188
+ return false;
189
+ });
190
+ }
191
+ function UserSelectMenu(props) {
192
+ const {
193
+ value = [],
194
+ userList = [],
195
+ onAdd,
196
+ onRemove,
197
+ onClear,
198
+ style = {}
199
+ } = props;
200
+ const [searchString, setSearchString] = React.useState("");
201
+ const searchResults = searchUsers(userList || [], searchString);
202
+ const me = userList.find(u => u.isCurrentUser);
203
+ const meAssigned = me && value.includes(me.id);
204
+ const input = useRef();
205
+ const handleSearchChange = event => {
206
+ setSearchString(event.target.value);
207
+ };
208
+ const handleSelect = (isChecked, user) => {
209
+ if (!isChecked) {
210
+ if (onAdd) onAdd(user.id);
211
+ } else if (onRemove) onRemove(user.id);
212
+ };
213
+ const handleAssignMyself = () => {
214
+ if (me && onAdd) onAdd(me.id);
215
+ };
216
+ const handleUnassignMyself = () => {
217
+ if (me && onRemove) onRemove(me.id);
218
+ };
219
+ const handleClearAssigneesClick = () => {
220
+ if (onClear) onClear();
221
+ };
222
+ return /* @__PURE__ */jsxs(Menu, {
223
+ style,
224
+ children: [meAssigned ? /* @__PURE__ */jsx(MenuItem, {
225
+ tone: "caution",
226
+ disabled: !me,
227
+ onClick: handleUnassignMyself,
228
+ icon: RemoveCircleIcon,
229
+ text: "Unassign myself"
230
+ }) : /* @__PURE__ */jsx(MenuItem, {
231
+ tone: "positive",
232
+ onClick: handleAssignMyself,
233
+ icon: AddCircleIcon,
234
+ text: "Assign myself"
235
+ }), /* @__PURE__ */jsx(MenuItem, {
236
+ tone: "critical",
237
+ disabled: value.length === 0,
238
+ onClick: handleClearAssigneesClick,
239
+ icon: RestoreIcon,
240
+ text: "Clear assignees"
241
+ }), /* @__PURE__ */jsx(Box, {
242
+ padding: 1,
243
+ children: /* @__PURE__ */jsx(TextInput, {
244
+ ref: input,
245
+ onChange: handleSearchChange,
246
+ placeholder: "Search members",
247
+ value: searchString
248
+ })
249
+ }), searchString && (searchResults == null ? void 0 : searchResults.length) === 0 && /* @__PURE__ */jsx(MenuItem, {
250
+ disabled: true,
251
+ text: "No matches"
252
+ }), searchResults && searchResults.map(user => /* @__PURE__ */jsx(MenuItem, {
253
+ pressed: value.includes(user.id),
254
+ onClick: () => handleSelect(value.indexOf(user.id) > -1, user),
255
+ children: /* @__PURE__ */jsxs(Flex, {
256
+ align: "center",
257
+ children: [/* @__PURE__ */jsx(UserAvatar, {
258
+ user,
259
+ size: 1
260
+ }), /* @__PURE__ */jsx(Box, {
261
+ paddingX: 2,
262
+ flex: 1,
263
+ children: /* @__PURE__ */jsx(Text, {
264
+ children: user.displayName
265
+ })
266
+ }), user.isCurrentUser && /* @__PURE__ */jsx(Badge, {
267
+ fontSize: 1,
268
+ tone: "positive",
269
+ mode: "outline",
270
+ children: "Me"
271
+ })]
272
+ })
273
+ }, user.id))]
274
+ });
275
+ }
276
+ export { Cell, Feedback, Row, Table, UserSelectMenu, useListeningQuery, useProjectUsers };
2
277
  //# sourceMappingURL=index.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.esm.js","sources":["../src/hooks/useListeningQuery.tsx","../src/hooks/useProjectUsers.tsx","../src/components/Feedback.tsx","../src/components/Table.tsx","../src/components/UserSelectMenu/index.tsx"],"sourcesContent":["import {useEffect, useState, useRef} from 'react'\nimport {catchError, distinctUntilChanged} from 'rxjs/operators'\nimport isEqual from 'react-fast-compare'\nimport {useDocumentStore} from 'sanity'\nimport {Subscription} from 'rxjs'\n\ntype Params = Record<string, string | number | boolean | string[]>\n\ninterface ListenQueryOptions {\n tag?: string\n apiVersion?: string\n}\n\ntype Value = any\n\ninterface Config<V> {\n params: Params\n options?: ListenQueryOptions\n initialValue?: null | V\n}\n\ninterface Return<V> {\n loading: boolean\n error: boolean\n data: null | V\n initialValue?: Value\n}\n\nconst DEFAULT_PARAMS = {}\nconst DEFAULT_OPTIONS = {apiVersion: `v2022-05-09`}\nconst DEFAULT_INITIAL_VALUE = null\n\nexport function useListeningQuery<V>(\n query: string | {fetch: string; listen: string},\n {\n params = DEFAULT_PARAMS,\n options = DEFAULT_OPTIONS,\n initialValue = DEFAULT_INITIAL_VALUE,\n }: Config<V>\n): Return<V> {\n const [loading, setLoading] = useState(true)\n const [error, setError] = useState(false)\n const [data, setData] = useState(initialValue)\n const subscription = useRef<null | Subscription>(null)\n const documentStore = useDocumentStore()\n\n useEffect(() => {\n if (query) {\n subscription.current = documentStore\n .listenQuery(query, params, options)\n .pipe(\n distinctUntilChanged(isEqual),\n catchError((err) => {\n console.error(err)\n setError(err)\n setLoading(false)\n setData(null)\n\n return err\n })\n )\n .subscribe((documents) => {\n setData((current: Value) => (isEqual(current, documents) ? current : documents))\n setLoading(false)\n setError(false)\n })\n }\n\n return () => subscription?.current?.unsubscribe()\n }, [query, params, options, documentStore])\n\n return {data, loading, error}\n}\n","import {useState, useEffect} from 'react'\nimport {useClient, useWorkspace} from 'sanity'\n\nexport type UserExtended = {\n createdAt: string\n displayName: string\n email: string\n familyName: string\n givenName: string\n id: string\n imageUrl: string\n isCurrentUser: boolean\n middleName: string\n projectId: string\n provider: string\n sanityUserId: string\n updatedAt: string\n}\n\ntype UserRole = {\n name: string\n title: string\n}\n\ntype UserResponse = {\n isRobot: boolean\n projectUserId: string\n roles: UserRole[]\n}\n\n// Custom hook to fetch user details\n// Built-in hook doesn't fetch all user details\nexport function useProjectUsers(): UserExtended[] {\n const {currentUser} = useWorkspace()\n const client = useClient()\n const [users, setUsers] = useState([])\n\n useEffect(() => {\n const {projectId} = client.config()\n\n async function getUser(id: string) {\n const userDetails = await client.request({\n url: `/projects/${projectId}/users/${id}`,\n })\n\n return userDetails\n }\n\n async function getUsersWithRoles() {\n const userRoles = await client\n .request({\n url: `/projects/${projectId}/acl`,\n })\n .then(async (res) =>\n Promise.all(\n res.map(async (user: UserResponse) => ({\n isCurrentUser: user.projectUserId === currentUser?.id,\n ...(await getUser(user.projectUserId)),\n }))\n )\n )\n .catch((err) => err)\n\n setUsers(userRoles)\n }\n\n if (!users.length) {\n getUsersWithRoles()\n }\n }, [client, currentUser?.id, users.length])\n\n return users\n}\n","import React from 'react'\nimport {Box, Card, CardTone, Flex, Stack, Text} from '@sanity/ui'\n\ntype FeedbackChildren = {\n children?: React.ReactNode\n title?: never\n description?: never\n}\n\ntype FeedbackTextProps = {\n title?: string\n description?: React.ReactNode\n children?: never\n}\n\ntype FeedbackProps = (FeedbackChildren | FeedbackTextProps) & {\n tone?: CardTone\n icon?: React.ReactNode\n}\n\nconst DEFAULT_PROPS: FeedbackProps = {\n tone: 'primary',\n}\n\nexport function Feedback(props: FeedbackProps) {\n const {title, description, icon, tone, children} = {...DEFAULT_PROPS, ...props}\n\n return (\n <Card tone={tone} padding={4} radius={3} border>\n <Flex>\n {icon ? `display icon` : null}\n {children ? (\n children\n ) : (\n <Box flex={1}>\n <Stack space={4}>\n {title ? <Text weight=\"semibold\">{title}</Text> : null}\n {description ? <Text size={2}>{description}</Text> : null}\n </Stack>\n </Box>\n )}\n </Flex>\n </Card>\n )\n}\n","import React, {PropsWithChildren} from 'react'\nimport styled, {css} from 'styled-components'\nimport {Card, CardProps} from '@sanity/ui'\n\n// Wrappers required because of bug with passing down \"as\" prop\n// https://github.com/styled-components/styled-components/issues/2449\n\n// Table\nconst TableWrapper = (props: CardProps = {}) => {\n return <Card as=\"table\" {...props} />\n}\n\nconst StyledTable = styled(TableWrapper)(\n () =>\n css`\n display: table;\n width: 100%;\n\n &:not([hidden]) {\n display: table;\n }\n `\n)\n\ntype TableProps = PropsWithChildren<CardProps>\n\nexport function Table(props: TableProps) {\n const {children, ...rest} = props\n\n return <StyledTable {...rest}>{children}</StyledTable>\n}\n\n// Row\nconst RowWrapper = (props: CardProps = {}) => {\n return <Card as=\"tr\" {...props} />\n}\n\nconst StyledRow = styled(RowWrapper)(\n () =>\n css`\n display: table-row;\n\n &:not([hidden]) {\n display: table-row;\n }\n `\n)\n\ntype TableRowProps = PropsWithChildren<CardProps>\n\nexport function Row(props: TableRowProps) {\n const {children, ...rest} = props\n\n return <StyledRow {...rest}>{children}</StyledRow>\n}\n\n// Cell\nconst CellWrapper = (props = {}) => {\n return <Card as=\"td\" {...props} />\n}\n\nconst StyledCell = styled(CellWrapper)(\n () =>\n css`\n display: table-cell;\n\n &:not([hidden]) {\n display: table-cell;\n }\n `\n)\n\ntype TableCellProps = PropsWithChildren<CardProps>\n\nexport function Cell(props: TableCellProps) {\n const {children, ...rest} = props\n\n return <StyledCell {...rest}>{children}</StyledCell>\n}\n","import React, {useRef} from 'react'\nimport {Box, Text, Menu, MenuItem, TextInput, Flex, Badge} from '@sanity/ui'\nimport {AddCircleIcon, RemoveCircleIcon, RestoreIcon} from '@sanity/icons'\nimport {UserAvatar} from 'sanity'\n\nimport {UserExtended} from '../../hooks/useProjectUsers'\n\nfunction searchUsers(users: UserExtended[], searchString: string): UserExtended[] {\n return users.filter((user) => {\n const displayName = (user.displayName || '').toLowerCase()\n if (displayName.startsWith(searchString)) return true\n const givenName = (user.givenName || '').toLowerCase()\n if (givenName.startsWith(searchString)) return true\n const middleName = (user.middleName || '').toLowerCase()\n if (middleName.startsWith(searchString)) return true\n const familyName = (user.familyName || '').toLowerCase()\n if (familyName.startsWith(searchString)) return true\n\n return false\n })\n}\n\ntype UserSelectMenuProps = {\n value: string[]\n userList: UserExtended[]\n onAdd: any\n onRemove: any\n onClear: any\n open: boolean\n style?: React.CSSProperties\n}\n\nexport function UserSelectMenu(props: UserSelectMenuProps) {\n const {value = [], userList = [], onAdd, onRemove, onClear, style = {}} = props\n const [searchString, setSearchString] = React.useState('')\n const searchResults = searchUsers(userList || [], searchString)\n\n const me = userList.find((u) => u.isCurrentUser)\n const meAssigned = me && value.includes(me.id)\n\n // Focus input on open\n // TODO: Fix focus, it gets immediately taken away\n const input = useRef<HTMLInputElement>()\n // useEffect(() => {\n // if (open && input?.current) {\n // input.current.focus()\n // }\n // }, [open])\n\n const handleSearchChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n setSearchString(event.target.value)\n }\n\n const handleSelect = (isChecked: boolean, user: UserExtended) => {\n if (!isChecked) {\n if (onAdd) onAdd(user.id)\n } else if (onRemove) onRemove(user.id)\n }\n\n const handleAssignMyself = () => {\n if (me && onAdd) onAdd(me.id)\n }\n\n const handleUnassignMyself = () => {\n if (me && onRemove) onRemove(me.id)\n }\n\n const handleClearAssigneesClick = () => {\n if (onClear) onClear()\n }\n\n return (\n <Menu style={style}>\n {meAssigned ? (\n <MenuItem\n tone=\"caution\"\n disabled={!me}\n onClick={handleUnassignMyself}\n icon={RemoveCircleIcon}\n text=\"Unassign myself\"\n />\n ) : (\n <MenuItem\n tone=\"positive\"\n onClick={handleAssignMyself}\n icon={AddCircleIcon}\n text=\"Assign myself\"\n />\n )}\n\n <MenuItem\n tone=\"critical\"\n disabled={value.length === 0}\n onClick={handleClearAssigneesClick}\n icon={RestoreIcon}\n text=\"Clear assignees\"\n />\n\n <Box padding={1}>\n <TextInput\n // @ts-ignore TODO: Satisfy ref\n ref={input}\n onChange={handleSearchChange}\n placeholder=\"Search members\"\n value={searchString}\n />\n </Box>\n\n {searchString && searchResults?.length === 0 && <MenuItem disabled text=\"No matches\" />}\n\n {searchResults &&\n searchResults.map((user) => (\n <MenuItem\n key={user.id}\n pressed={value.includes(user.id)}\n onClick={() => handleSelect(value.indexOf(user.id) > -1, user)}\n >\n <Flex align=\"center\">\n <UserAvatar user={user} size={1} />\n <Box paddingX={2} flex={1}>\n <Text>{user.displayName}</Text>\n </Box>\n {user.isCurrentUser && (\n <Badge fontSize={1} tone=\"positive\" mode=\"outline\">\n Me\n </Badge>\n )}\n </Flex>\n </MenuItem>\n ))}\n </Menu>\n )\n}\n"],"names":["DEFAULT_PARAMS","DEFAULT_OPTIONS","apiVersion","DEFAULT_INITIAL_VALUE","useListeningQuery","query","_ref","params","options","initialValue","loading","setLoading","useState","error","setError","data","setData","subscription","useRef","documentStore","useDocumentStore","useEffect","current","listenQuery","pipe","distinctUntilChanged","isEqual","catchError","err","console","subscribe","documents","_a","unsubscribe","useProjectUsers","currentUser","useWorkspace","client","useClient","users","setUsers","projectId","config","length","async","userRoles","request","url","then","Promise","all","res","map","_objectSpread","isCurrentUser","user","projectUserId","id","concat","getUser","catch","getUsersWithRoles","DEFAULT_PROPS","tone","Feedback","props","title","description","icon","children","jsx","Card","padding","radius","border","jsxs","Flex","Box","flex","Stack","space","Text","weight","size","StyledTable","styled","arguments","undefined","as","css","_templateObject","_taggedTemplateLiteral","Table","rest","_excluded","StyledRow","_templateObject2","Row","_excluded2","StyledCell","_templateObject3","Cell","_excluded3","UserSelectMenu","value","userList","onAdd","onRemove","onClear","style","searchString","setSearchString","React","searchResults","filter","displayName","toLowerCase","startsWith","givenName","middleName","familyName","searchUsers","me","find","u","meAssigned","includes","input","Menu","MenuItem","disabled","onClick","RemoveCircleIcon","text","AddCircleIcon","RestoreIcon","TextInput","ref","onChange","event","target","placeholder","pressed","isChecked","handleSelect","indexOf","align","UserAvatar","paddingX","Badge","fontSize","mode"],"mappings":"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"}
1
+ {"version":3,"file":"index.esm.js","sources":["../src/hooks/useListeningQuery.tsx","../src/hooks/useProjectUsers.tsx","../src/components/Feedback.tsx","../src/components/Table.tsx","../src/components/UserSelectMenu/index.tsx"],"sourcesContent":["import {useEffect, useState, useRef} from 'react'\nimport {catchError, distinctUntilChanged} from 'rxjs/operators'\nimport isEqual from 'react-fast-compare'\nimport {useDocumentStore} from 'sanity'\nimport {Subscription} from 'rxjs'\n\ntype Params = Record<string, string | number | boolean | string[]>\n\ninterface ListenQueryOptions {\n tag?: string\n apiVersion?: string\n}\n\ntype Value = any\n\ninterface Config<V> {\n params: Params\n options?: ListenQueryOptions\n initialValue?: null | V\n}\n\ninterface Return<V> {\n loading: boolean\n error: boolean\n data: null | V\n initialValue?: Value\n}\n\nconst DEFAULT_PARAMS = {}\nconst DEFAULT_OPTIONS = {apiVersion: `v2022-05-09`}\nconst DEFAULT_INITIAL_VALUE = null\n\nexport function useListeningQuery<V>(\n query: string | {fetch: string; listen: string},\n {\n params = DEFAULT_PARAMS,\n options = DEFAULT_OPTIONS,\n initialValue = DEFAULT_INITIAL_VALUE,\n }: Config<V>\n): Return<V> {\n const [loading, setLoading] = useState(true)\n const [error, setError] = useState(false)\n const [data, setData] = useState(initialValue)\n const subscription = useRef<null | Subscription>(null)\n const documentStore = useDocumentStore()\n\n useEffect(() => {\n if (query) {\n subscription.current = documentStore\n .listenQuery(query, params, options)\n .pipe(\n distinctUntilChanged(isEqual),\n catchError((err) => {\n console.error(err)\n setError(err)\n setLoading(false)\n setData(null)\n\n return err\n })\n )\n .subscribe((documents) => {\n setData((current: Value) => (isEqual(current, documents) ? current : documents))\n setLoading(false)\n setError(false)\n })\n }\n\n return () => subscription?.current?.unsubscribe()\n }, [query, params, options, documentStore])\n\n return {data, loading, error}\n}\n","import {useState, useEffect} from 'react'\nimport {useClient, useWorkspace} from 'sanity'\n\nexport type UserExtended = {\n createdAt: string\n displayName: string\n email: string\n familyName: string\n givenName: string\n id: string\n imageUrl: string\n isCurrentUser: boolean\n middleName: string\n projectId: string\n provider: string\n sanityUserId: string\n updatedAt: string\n}\n\ntype UserRole = {\n name: string\n title: string\n}\n\ntype UserResponse = {\n isRobot: boolean\n projectUserId: string\n roles: UserRole[]\n}\n\ntype HookConfig = {\n apiVersion?: string\n}\n\n// Custom hook to fetch user details\n// Built-in hook doesn't fetch all user details\nexport function useProjectUsers({apiVersion}: HookConfig): UserExtended[] {\n const {currentUser} = useWorkspace()\n const client = useClient({apiVersion: apiVersion ?? '2023-01-01'})\n const [users, setUsers] = useState([])\n\n useEffect(() => {\n const {projectId} = client.config()\n\n async function getUser(id: string) {\n const userDetails = await client.request({\n url: `/projects/${projectId}/users/${id}`,\n })\n\n return userDetails\n }\n\n async function getUsersWithRoles() {\n const userRoles = await client\n .request({\n url: `/projects/${projectId}/acl`,\n })\n .then(async (res) =>\n Promise.all(\n res.map(async (user: UserResponse) => ({\n isCurrentUser: user.projectUserId === currentUser?.id,\n ...(await getUser(user.projectUserId)),\n }))\n )\n )\n .catch((err) => err)\n\n setUsers(userRoles)\n }\n\n if (!users.length) {\n getUsersWithRoles()\n }\n }, [client, currentUser?.id, users.length])\n\n return users\n}\n","import React from 'react'\nimport {Box, Card, CardTone, Flex, Stack, Text} from '@sanity/ui'\n\ntype FeedbackChildren = {\n children?: React.ReactNode\n title?: never\n description?: never\n}\n\ntype FeedbackTextProps = {\n title?: string\n description?: React.ReactNode\n children?: never\n}\n\ntype FeedbackProps = (FeedbackChildren | FeedbackTextProps) & {\n tone?: CardTone\n icon?: React.ReactNode\n}\n\nconst DEFAULT_PROPS: FeedbackProps = {\n tone: 'primary',\n}\n\nexport function Feedback(props: FeedbackProps) {\n const {title, description, icon, tone, children} = {...DEFAULT_PROPS, ...props}\n\n return (\n <Card tone={tone} padding={4} radius={3} border>\n <Flex>\n {icon ? `display icon` : null}\n {children ? (\n children\n ) : (\n <Box flex={1}>\n <Stack space={4}>\n {title ? <Text weight=\"semibold\">{title}</Text> : null}\n {description ? <Text size={2}>{description}</Text> : null}\n </Stack>\n </Box>\n )}\n </Flex>\n </Card>\n )\n}\n","import React, {PropsWithChildren} from 'react'\nimport styled, {css} from 'styled-components'\nimport {Card, CardProps} from '@sanity/ui'\n\n// Wrappers required because of bug with passing down \"as\" prop\n// https://github.com/styled-components/styled-components/issues/2449\n\n// Table\nconst TableWrapper = (props: CardProps = {}) => {\n return <Card as=\"table\" {...props} />\n}\n\nconst StyledTable = styled(TableWrapper)(\n () =>\n css`\n display: table;\n width: 100%;\n\n &:not([hidden]) {\n display: table;\n }\n `\n)\n\ntype TableProps = PropsWithChildren<CardProps>\n\nexport function Table(props: TableProps) {\n const {children, ...rest} = props\n\n return <StyledTable {...rest}>{children}</StyledTable>\n}\n\n// Row\nconst RowWrapper = (props: CardProps = {}) => {\n return <Card as=\"tr\" {...props} />\n}\n\nconst StyledRow = styled(RowWrapper)(\n () =>\n css`\n display: table-row;\n\n &:not([hidden]) {\n display: table-row;\n }\n `\n)\n\ntype TableRowProps = PropsWithChildren<CardProps>\n\nexport function Row(props: TableRowProps) {\n const {children, ...rest} = props\n\n return <StyledRow {...rest}>{children}</StyledRow>\n}\n\n// Cell\nconst CellWrapper = (props = {}) => {\n return <Card as=\"td\" {...props} />\n}\n\nconst StyledCell = styled(CellWrapper)(\n () =>\n css`\n display: table-cell;\n\n &:not([hidden]) {\n display: table-cell;\n }\n `\n)\n\ntype TableCellProps = PropsWithChildren<CardProps>\n\nexport function Cell(props: TableCellProps) {\n const {children, ...rest} = props\n\n return <StyledCell {...rest}>{children}</StyledCell>\n}\n","import React, {useRef} from 'react'\nimport {Box, Text, Menu, MenuItem, TextInput, Flex, Badge} from '@sanity/ui'\nimport {AddCircleIcon, RemoveCircleIcon, RestoreIcon} from '@sanity/icons'\nimport {UserAvatar} from 'sanity'\n\nimport {UserExtended} from '../../hooks/useProjectUsers'\n\nfunction searchUsers(\n users: UserExtended[],\n searchString: string\n): UserExtended[] {\n return users.filter((user) => {\n const displayName = (user.displayName || '').toLowerCase()\n if (displayName.startsWith(searchString)) return true\n const givenName = (user.givenName || '').toLowerCase()\n if (givenName.startsWith(searchString)) return true\n const middleName = (user.middleName || '').toLowerCase()\n if (middleName.startsWith(searchString)) return true\n const familyName = (user.familyName || '').toLowerCase()\n if (familyName.startsWith(searchString)) return true\n\n return false\n })\n}\n\ntype UserSelectMenuProps = {\n value: string[]\n userList: UserExtended[]\n onAdd: any\n onRemove: any\n onClear: any\n style?: React.CSSProperties\n}\n\nexport function UserSelectMenu(props: UserSelectMenuProps) {\n const {\n value = [],\n userList = [],\n onAdd,\n onRemove,\n onClear,\n style = {},\n } = props\n const [searchString, setSearchString] = React.useState('')\n const searchResults = searchUsers(userList || [], searchString)\n\n const me = userList.find((u) => u.isCurrentUser)\n const meAssigned = me && value.includes(me.id)\n\n // Focus input on open\n // TODO: Fix focus, it gets immediately taken away\n const input = useRef<HTMLInputElement>()\n // useEffect(() => {\n // if (open && input?.current) {\n // input.current.focus()\n // }\n // }, [open])\n\n const handleSearchChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n setSearchString(event.target.value)\n }\n\n const handleSelect = (isChecked: boolean, user: UserExtended) => {\n if (!isChecked) {\n if (onAdd) onAdd(user.id)\n } else if (onRemove) onRemove(user.id)\n }\n\n const handleAssignMyself = () => {\n if (me && onAdd) onAdd(me.id)\n }\n\n const handleUnassignMyself = () => {\n if (me && onRemove) onRemove(me.id)\n }\n\n const handleClearAssigneesClick = () => {\n if (onClear) onClear()\n }\n\n return (\n <Menu style={style}>\n {meAssigned ? (\n <MenuItem\n tone=\"caution\"\n disabled={!me}\n onClick={handleUnassignMyself}\n icon={RemoveCircleIcon}\n text=\"Unassign myself\"\n />\n ) : (\n <MenuItem\n tone=\"positive\"\n onClick={handleAssignMyself}\n icon={AddCircleIcon}\n text=\"Assign myself\"\n />\n )}\n\n <MenuItem\n tone=\"critical\"\n disabled={value.length === 0}\n onClick={handleClearAssigneesClick}\n icon={RestoreIcon}\n text=\"Clear assignees\"\n />\n\n <Box padding={1}>\n <TextInput\n // @ts-ignore TODO: Satisfy ref\n ref={input}\n onChange={handleSearchChange}\n placeholder=\"Search members\"\n value={searchString}\n />\n </Box>\n\n {searchString && searchResults?.length === 0 && (\n <MenuItem disabled text=\"No matches\" />\n )}\n\n {searchResults &&\n searchResults.map((user) => (\n <MenuItem\n key={user.id}\n pressed={value.includes(user.id)}\n onClick={() => handleSelect(value.indexOf(user.id) > -1, user)}\n >\n <Flex align=\"center\">\n <UserAvatar user={user} size={1} />\n <Box paddingX={2} flex={1}>\n <Text>{user.displayName}</Text>\n </Box>\n {user.isCurrentUser && (\n <Badge fontSize={1} tone=\"positive\" mode=\"outline\">\n Me\n </Badge>\n )}\n </Flex>\n </MenuItem>\n ))}\n </Menu>\n )\n}\n"],"names":["DEFAULT_PARAMS","DEFAULT_OPTIONS","apiVersion","DEFAULT_INITIAL_VALUE","useListeningQuery","query","params","options","initialValue","loading","setLoading","useState","error","setError","data","setData","subscription","useRef","documentStore","useDocumentStore","useEffect","current","listenQuery","pipe","distinctUntilChanged","isEqual","catchError","err","console","subscribe","documents","_a","unsubscribe","useProjectUsers","currentUser","useWorkspace","client","useClient","users","setUsers","projectId","config","getUser","id","userDetails","request","url","getUsersWithRoles","userRoles","then","res","Promise","all","map","user","isCurrentUser","projectUserId","catch","length","DEFAULT_PROPS","tone","Feedback","props","title","description","icon","children","jsx","Card","padding","radius","border","jsxs","Flex","Box","flex","Stack","space","Text","weight","size","TableWrapper","as","StyledTable","styled","css","Table","rest","RowWrapper","StyledRow","Row","CellWrapper","StyledCell","Cell","searchUsers","searchString","filter","displayName","toLowerCase","startsWith","givenName","middleName","familyName","UserSelectMenu","value","userList","onAdd","onRemove","onClear","style","setSearchString","React","searchResults","me","find","u","meAssigned","includes","input","handleSearchChange","event","target","handleSelect","isChecked","handleAssignMyself","handleUnassignMyself","handleClearAssigneesClick","Menu","MenuItem","disabled","onClick","RemoveCircleIcon","text","AddCircleIcon","RestoreIcon","TextInput","ref","onChange","placeholder","pressed","indexOf","align","UserAvatar","paddingX","Badge","fontSize","mode"],"mappings":"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"}
package/lib/index.js CHANGED
@@ -1,2 +1,296 @@
1
- "use strict";const e=["children"],t=["children"],n=["children"];var r,s,i;function o(e,t){if(null==e)return{};var n,r,s=function(e,t){if(null==e)return{};var n,r,s={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(s[n]=e[n]);return s}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(s[n]=e[n])}return s}function c(e,t){return t||(t=e.slice(0)),Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(t)}}))}function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?l(Object(n),!0).forEach((function(t){u(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):l(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function u(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}Object.defineProperty(exports,"__esModule",{value:!0});var d=require("react"),f=require("rxjs/operators"),p=require("react-fast-compare"),j=require("sanity"),h=require("react/jsx-runtime"),x=require("@sanity/ui"),b=require("styled-components"),y=require("@sanity/icons");function m(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var g=m(d),v=m(p),O=m(b);const C={},w={apiVersion:"v2022-05-09"},P=null;const S={tone:"primary"};const I=O.default((function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return h.jsx(x.Card,a({as:"table"},e))}))((()=>b.css(r||(r=c(["\n display: table;\n width: 100%;\n\n &:not([hidden]) {\n display: table;\n }\n "])))));const U=O.default((function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return h.jsx(x.Card,a({as:"tr"},e))}))((()=>b.css(s||(s=c(["\n display: table-row;\n\n &:not([hidden]) {\n display: table-row;\n }\n "])))));const q=O.default((function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return h.jsx(x.Card,a({as:"td"},e))}))((()=>b.css(i||(i=c(["\n display: table-cell;\n\n &:not([hidden]) {\n display: table-cell;\n }\n "])))));exports.Cell=function(e){const{children:t}=e,r=o(e,n);return h.jsx(q,a(a({},r),{},{children:t}))},exports.Feedback=function(e){const{title:t,description:n,icon:r,tone:s,children:i}=a(a({},S),e);return h.jsx(x.Card,{tone:s,padding:4,radius:3,border:!0,children:h.jsxs(x.Flex,{children:[r?"display icon":null,i||h.jsx(x.Box,{flex:1,children:h.jsxs(x.Stack,{space:4,children:[t?h.jsx(x.Text,{weight:"semibold",children:t}):null,n?h.jsx(x.Text,{size:2,children:n}):null]})})]})})},exports.Row=function(e){const{children:n}=e,r=o(e,t);return h.jsx(U,a(a({},r),{},{children:n}))},exports.Table=function(t){const{children:n}=t,r=o(t,e);return h.jsx(I,a(a({},r),{},{children:n}))},exports.UserSelectMenu=function(e){const{value:t=[],userList:n=[],onAdd:r,onRemove:s,onClear:i,style:o={}}=e,[c,l]=g.default.useState(""),a=function(e,t){return e.filter((e=>!!(e.displayName||"").toLowerCase().startsWith(t)||(!!(e.givenName||"").toLowerCase().startsWith(t)||(!!(e.middleName||"").toLowerCase().startsWith(t)||!!(e.familyName||"").toLowerCase().startsWith(t)))))}(n||[],c),u=n.find((e=>e.isCurrentUser)),f=u&&t.includes(u.id),p=d.useRef();return h.jsxs(x.Menu,{style:o,children:[f?h.jsx(x.MenuItem,{tone:"caution",disabled:!u,onClick:()=>{u&&s&&s(u.id)},icon:y.RemoveCircleIcon,text:"Unassign myself"}):h.jsx(x.MenuItem,{tone:"positive",onClick:()=>{u&&r&&r(u.id)},icon:y.AddCircleIcon,text:"Assign myself"}),h.jsx(x.MenuItem,{tone:"critical",disabled:0===t.length,onClick:()=>{i&&i()},icon:y.RestoreIcon,text:"Clear assignees"}),h.jsx(x.Box,{padding:1,children:h.jsx(x.TextInput,{ref:p,onChange:e=>{l(e.target.value)},placeholder:"Search members",value:c})}),c&&0===(null==a?void 0:a.length)&&h.jsx(x.MenuItem,{disabled:!0,text:"No matches"}),a&&a.map((e=>h.jsx(x.MenuItem,{pressed:t.includes(e.id),onClick:()=>((e,t)=>{e?s&&s(t.id):r&&r(t.id)})(t.indexOf(e.id)>-1,e),children:h.jsxs(x.Flex,{align:"center",children:[h.jsx(j.UserAvatar,{user:e,size:1}),h.jsx(x.Box,{paddingX:2,flex:1,children:h.jsx(x.Text,{children:e.displayName})}),e.isCurrentUser&&h.jsx(x.Badge,{fontSize:1,tone:"positive",mode:"outline",children:"Me"})]})},e.id)))]})},exports.useListeningQuery=function(e,t){let{params:n=C,options:r=w,initialValue:s=P}=t;const[i,o]=d.useState(!0),[c,l]=d.useState(!1),[a,u]=d.useState(s),p=d.useRef(null),h=j.useDocumentStore();return d.useEffect((()=>(e&&(p.current=h.listenQuery(e,n,r).pipe(f.distinctUntilChanged(v.default),f.catchError((e=>(console.error(e),l(e),o(!1),u(null),e)))).subscribe((e=>{u((t=>v.default(t,e)?t:e)),o(!1),l(!1)}))),()=>{var e;return null==(e=null==p?void 0:p.current)?void 0:e.unsubscribe()})),[e,n,r,h]),{data:a,loading:i,error:c}},exports.useProjectUsers=function(){const{currentUser:e}=j.useWorkspace(),t=j.useClient(),[n,r]=d.useState([]);return d.useEffect((()=>{const{projectId:s}=t.config();n.length||async function(){const n=await t.request({url:"/projects/".concat(s,"/acl")}).then((async n=>Promise.all(n.map((async n=>a({isCurrentUser:n.projectUserId===(null==e?void 0:e.id)},await async function(e){return await t.request({url:"/projects/".concat(s,"/users/").concat(e)})}(n.projectUserId))))))).catch((e=>e));r(n)}()}),[t,null==e?void 0:e.id,n.length]),n};
1
+ 'use strict';
2
+
3
+ var _templateObject, _templateObject2, _templateObject3;
4
+ function _taggedTemplateLiteral(strings, raw) { if (!raw) { raw = strings.slice(0); } return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); }
5
+ Object.defineProperty(exports, '__esModule', {
6
+ value: true
7
+ });
8
+ var React = require('react');
9
+ var operators = require('rxjs/operators');
10
+ var isEqual = require('react-fast-compare');
11
+ var sanity = require('sanity');
12
+ var jsxRuntime = require('react/jsx-runtime');
13
+ var ui = require('@sanity/ui');
14
+ var styled = require('styled-components');
15
+ var icons = require('@sanity/icons');
16
+ function _interopDefaultCompat(e) {
17
+ return e && typeof e === 'object' && 'default' in e ? e : {
18
+ default: e
19
+ };
20
+ }
21
+ var React__default = /*#__PURE__*/_interopDefaultCompat(React);
22
+ var isEqual__default = /*#__PURE__*/_interopDefaultCompat(isEqual);
23
+ var styled__default = /*#__PURE__*/_interopDefaultCompat(styled);
24
+ const DEFAULT_PARAMS = {};
25
+ const DEFAULT_OPTIONS = {
26
+ apiVersion: "v2022-05-09"
27
+ };
28
+ const DEFAULT_INITIAL_VALUE = null;
29
+ function useListeningQuery(query, _ref) {
30
+ let {
31
+ params = DEFAULT_PARAMS,
32
+ options = DEFAULT_OPTIONS,
33
+ initialValue = DEFAULT_INITIAL_VALUE
34
+ } = _ref;
35
+ const [loading, setLoading] = React.useState(true);
36
+ const [error, setError] = React.useState(false);
37
+ const [data, setData] = React.useState(initialValue);
38
+ const subscription = React.useRef(null);
39
+ const documentStore = sanity.useDocumentStore();
40
+ React.useEffect(() => {
41
+ if (query) {
42
+ subscription.current = documentStore.listenQuery(query, params, options).pipe(operators.distinctUntilChanged(isEqual__default.default), operators.catchError(err => {
43
+ console.error(err);
44
+ setError(err);
45
+ setLoading(false);
46
+ setData(null);
47
+ return err;
48
+ })).subscribe(documents => {
49
+ setData(current => isEqual__default.default(current, documents) ? current : documents);
50
+ setLoading(false);
51
+ setError(false);
52
+ });
53
+ }
54
+ return () => {
55
+ var _a;
56
+ return (_a = subscription == null ? void 0 : subscription.current) == null ? void 0 : _a.unsubscribe();
57
+ };
58
+ }, [query, params, options, documentStore]);
59
+ return {
60
+ data,
61
+ loading,
62
+ error
63
+ };
64
+ }
65
+ function useProjectUsers(_ref2) {
66
+ let {
67
+ apiVersion
68
+ } = _ref2;
69
+ const {
70
+ currentUser
71
+ } = sanity.useWorkspace();
72
+ const client = sanity.useClient({
73
+ apiVersion: apiVersion != null ? apiVersion : "2023-01-01"
74
+ });
75
+ const [users, setUsers] = React.useState([]);
76
+ React.useEffect(() => {
77
+ const {
78
+ projectId
79
+ } = client.config();
80
+ async function getUser(id) {
81
+ const userDetails = await client.request({
82
+ url: "/projects/".concat(projectId, "/users/").concat(id)
83
+ });
84
+ return userDetails;
85
+ }
86
+ async function getUsersWithRoles() {
87
+ const userRoles = await client.request({
88
+ url: "/projects/".concat(projectId, "/acl")
89
+ }).then(async res => Promise.all(res.map(async user => ({
90
+ isCurrentUser: user.projectUserId === (currentUser == null ? void 0 : currentUser.id),
91
+ ...(await getUser(user.projectUserId))
92
+ })))).catch(err => err);
93
+ setUsers(userRoles);
94
+ }
95
+ if (!users.length) {
96
+ getUsersWithRoles();
97
+ }
98
+ }, [client, currentUser == null ? void 0 : currentUser.id, users.length]);
99
+ return users;
100
+ }
101
+ const DEFAULT_PROPS = {
102
+ tone: "primary"
103
+ };
104
+ function Feedback(props) {
105
+ const {
106
+ title,
107
+ description,
108
+ icon,
109
+ tone,
110
+ children
111
+ } = {
112
+ ...DEFAULT_PROPS,
113
+ ...props
114
+ };
115
+ return /* @__PURE__ */jsxRuntime.jsx(ui.Card, {
116
+ tone,
117
+ padding: 4,
118
+ radius: 3,
119
+ border: true,
120
+ children: /* @__PURE__ */jsxRuntime.jsxs(ui.Flex, {
121
+ children: [icon ? "display icon" : null, children ? children : /* @__PURE__ */jsxRuntime.jsx(ui.Box, {
122
+ flex: 1,
123
+ children: /* @__PURE__ */jsxRuntime.jsxs(ui.Stack, {
124
+ space: 4,
125
+ children: [title ? /* @__PURE__ */jsxRuntime.jsx(ui.Text, {
126
+ weight: "semibold",
127
+ children: title
128
+ }) : null, description ? /* @__PURE__ */jsxRuntime.jsx(ui.Text, {
129
+ size: 2,
130
+ children: description
131
+ }) : null]
132
+ })
133
+ })]
134
+ })
135
+ });
136
+ }
137
+ const TableWrapper = function () {
138
+ let props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
139
+ return /* @__PURE__ */jsxRuntime.jsx(ui.Card, {
140
+ as: "table",
141
+ ...props
142
+ });
143
+ };
144
+ const StyledTable = styled__default.default(TableWrapper)(() => styled.css(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n display: table;\n width: 100%;\n\n &:not([hidden]) {\n display: table;\n }\n "]))));
145
+ function Table(props) {
146
+ const {
147
+ children,
148
+ ...rest
149
+ } = props;
150
+ return /* @__PURE__ */jsxRuntime.jsx(StyledTable, {
151
+ ...rest,
152
+ children
153
+ });
154
+ }
155
+ const RowWrapper = function () {
156
+ let props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
157
+ return /* @__PURE__ */jsxRuntime.jsx(ui.Card, {
158
+ as: "tr",
159
+ ...props
160
+ });
161
+ };
162
+ const StyledRow = styled__default.default(RowWrapper)(() => styled.css(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n display: table-row;\n\n &:not([hidden]) {\n display: table-row;\n }\n "]))));
163
+ function Row(props) {
164
+ const {
165
+ children,
166
+ ...rest
167
+ } = props;
168
+ return /* @__PURE__ */jsxRuntime.jsx(StyledRow, {
169
+ ...rest,
170
+ children
171
+ });
172
+ }
173
+ const CellWrapper = function () {
174
+ let props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
175
+ return /* @__PURE__ */jsxRuntime.jsx(ui.Card, {
176
+ as: "td",
177
+ ...props
178
+ });
179
+ };
180
+ const StyledCell = styled__default.default(CellWrapper)(() => styled.css(_templateObject3 || (_templateObject3 = _taggedTemplateLiteral(["\n display: table-cell;\n\n &:not([hidden]) {\n display: table-cell;\n }\n "]))));
181
+ function Cell(props) {
182
+ const {
183
+ children,
184
+ ...rest
185
+ } = props;
186
+ return /* @__PURE__ */jsxRuntime.jsx(StyledCell, {
187
+ ...rest,
188
+ children
189
+ });
190
+ }
191
+ function searchUsers(users, searchString) {
192
+ return users.filter(user => {
193
+ const displayName = (user.displayName || "").toLowerCase();
194
+ if (displayName.startsWith(searchString)) return true;
195
+ const givenName = (user.givenName || "").toLowerCase();
196
+ if (givenName.startsWith(searchString)) return true;
197
+ const middleName = (user.middleName || "").toLowerCase();
198
+ if (middleName.startsWith(searchString)) return true;
199
+ const familyName = (user.familyName || "").toLowerCase();
200
+ if (familyName.startsWith(searchString)) return true;
201
+ return false;
202
+ });
203
+ }
204
+ function UserSelectMenu(props) {
205
+ const {
206
+ value = [],
207
+ userList = [],
208
+ onAdd,
209
+ onRemove,
210
+ onClear,
211
+ style = {}
212
+ } = props;
213
+ const [searchString, setSearchString] = React__default.default.useState("");
214
+ const searchResults = searchUsers(userList || [], searchString);
215
+ const me = userList.find(u => u.isCurrentUser);
216
+ const meAssigned = me && value.includes(me.id);
217
+ const input = React.useRef();
218
+ const handleSearchChange = event => {
219
+ setSearchString(event.target.value);
220
+ };
221
+ const handleSelect = (isChecked, user) => {
222
+ if (!isChecked) {
223
+ if (onAdd) onAdd(user.id);
224
+ } else if (onRemove) onRemove(user.id);
225
+ };
226
+ const handleAssignMyself = () => {
227
+ if (me && onAdd) onAdd(me.id);
228
+ };
229
+ const handleUnassignMyself = () => {
230
+ if (me && onRemove) onRemove(me.id);
231
+ };
232
+ const handleClearAssigneesClick = () => {
233
+ if (onClear) onClear();
234
+ };
235
+ return /* @__PURE__ */jsxRuntime.jsxs(ui.Menu, {
236
+ style,
237
+ children: [meAssigned ? /* @__PURE__ */jsxRuntime.jsx(ui.MenuItem, {
238
+ tone: "caution",
239
+ disabled: !me,
240
+ onClick: handleUnassignMyself,
241
+ icon: icons.RemoveCircleIcon,
242
+ text: "Unassign myself"
243
+ }) : /* @__PURE__ */jsxRuntime.jsx(ui.MenuItem, {
244
+ tone: "positive",
245
+ onClick: handleAssignMyself,
246
+ icon: icons.AddCircleIcon,
247
+ text: "Assign myself"
248
+ }), /* @__PURE__ */jsxRuntime.jsx(ui.MenuItem, {
249
+ tone: "critical",
250
+ disabled: value.length === 0,
251
+ onClick: handleClearAssigneesClick,
252
+ icon: icons.RestoreIcon,
253
+ text: "Clear assignees"
254
+ }), /* @__PURE__ */jsxRuntime.jsx(ui.Box, {
255
+ padding: 1,
256
+ children: /* @__PURE__ */jsxRuntime.jsx(ui.TextInput, {
257
+ ref: input,
258
+ onChange: handleSearchChange,
259
+ placeholder: "Search members",
260
+ value: searchString
261
+ })
262
+ }), searchString && (searchResults == null ? void 0 : searchResults.length) === 0 && /* @__PURE__ */jsxRuntime.jsx(ui.MenuItem, {
263
+ disabled: true,
264
+ text: "No matches"
265
+ }), searchResults && searchResults.map(user => /* @__PURE__ */jsxRuntime.jsx(ui.MenuItem, {
266
+ pressed: value.includes(user.id),
267
+ onClick: () => handleSelect(value.indexOf(user.id) > -1, user),
268
+ children: /* @__PURE__ */jsxRuntime.jsxs(ui.Flex, {
269
+ align: "center",
270
+ children: [/* @__PURE__ */jsxRuntime.jsx(sanity.UserAvatar, {
271
+ user,
272
+ size: 1
273
+ }), /* @__PURE__ */jsxRuntime.jsx(ui.Box, {
274
+ paddingX: 2,
275
+ flex: 1,
276
+ children: /* @__PURE__ */jsxRuntime.jsx(ui.Text, {
277
+ children: user.displayName
278
+ })
279
+ }), user.isCurrentUser && /* @__PURE__ */jsxRuntime.jsx(ui.Badge, {
280
+ fontSize: 1,
281
+ tone: "positive",
282
+ mode: "outline",
283
+ children: "Me"
284
+ })]
285
+ })
286
+ }, user.id))]
287
+ });
288
+ }
289
+ exports.Cell = Cell;
290
+ exports.Feedback = Feedback;
291
+ exports.Row = Row;
292
+ exports.Table = Table;
293
+ exports.UserSelectMenu = UserSelectMenu;
294
+ exports.useListeningQuery = useListeningQuery;
295
+ exports.useProjectUsers = useProjectUsers;
2
296
  //# sourceMappingURL=index.js.map
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/hooks/useListeningQuery.tsx","../src/components/Feedback.tsx","../src/components/Table.tsx","../src/components/UserSelectMenu/index.tsx","../src/hooks/useProjectUsers.tsx"],"sourcesContent":["import {useEffect, useState, useRef} from 'react'\nimport {catchError, distinctUntilChanged} from 'rxjs/operators'\nimport isEqual from 'react-fast-compare'\nimport {useDocumentStore} from 'sanity'\nimport {Subscription} from 'rxjs'\n\ntype Params = Record<string, string | number | boolean | string[]>\n\ninterface ListenQueryOptions {\n tag?: string\n apiVersion?: string\n}\n\ntype Value = any\n\ninterface Config<V> {\n params: Params\n options?: ListenQueryOptions\n initialValue?: null | V\n}\n\ninterface Return<V> {\n loading: boolean\n error: boolean\n data: null | V\n initialValue?: Value\n}\n\nconst DEFAULT_PARAMS = {}\nconst DEFAULT_OPTIONS = {apiVersion: `v2022-05-09`}\nconst DEFAULT_INITIAL_VALUE = null\n\nexport function useListeningQuery<V>(\n query: string | {fetch: string; listen: string},\n {\n params = DEFAULT_PARAMS,\n options = DEFAULT_OPTIONS,\n initialValue = DEFAULT_INITIAL_VALUE,\n }: Config<V>\n): Return<V> {\n const [loading, setLoading] = useState(true)\n const [error, setError] = useState(false)\n const [data, setData] = useState(initialValue)\n const subscription = useRef<null | Subscription>(null)\n const documentStore = useDocumentStore()\n\n useEffect(() => {\n if (query) {\n subscription.current = documentStore\n .listenQuery(query, params, options)\n .pipe(\n distinctUntilChanged(isEqual),\n catchError((err) => {\n console.error(err)\n setError(err)\n setLoading(false)\n setData(null)\n\n return err\n })\n )\n .subscribe((documents) => {\n setData((current: Value) => (isEqual(current, documents) ? current : documents))\n setLoading(false)\n setError(false)\n })\n }\n\n return () => subscription?.current?.unsubscribe()\n }, [query, params, options, documentStore])\n\n return {data, loading, error}\n}\n","import React from 'react'\nimport {Box, Card, CardTone, Flex, Stack, Text} from '@sanity/ui'\n\ntype FeedbackChildren = {\n children?: React.ReactNode\n title?: never\n description?: never\n}\n\ntype FeedbackTextProps = {\n title?: string\n description?: React.ReactNode\n children?: never\n}\n\ntype FeedbackProps = (FeedbackChildren | FeedbackTextProps) & {\n tone?: CardTone\n icon?: React.ReactNode\n}\n\nconst DEFAULT_PROPS: FeedbackProps = {\n tone: 'primary',\n}\n\nexport function Feedback(props: FeedbackProps) {\n const {title, description, icon, tone, children} = {...DEFAULT_PROPS, ...props}\n\n return (\n <Card tone={tone} padding={4} radius={3} border>\n <Flex>\n {icon ? `display icon` : null}\n {children ? (\n children\n ) : (\n <Box flex={1}>\n <Stack space={4}>\n {title ? <Text weight=\"semibold\">{title}</Text> : null}\n {description ? <Text size={2}>{description}</Text> : null}\n </Stack>\n </Box>\n )}\n </Flex>\n </Card>\n )\n}\n","import React, {PropsWithChildren} from 'react'\nimport styled, {css} from 'styled-components'\nimport {Card, CardProps} from '@sanity/ui'\n\n// Wrappers required because of bug with passing down \"as\" prop\n// https://github.com/styled-components/styled-components/issues/2449\n\n// Table\nconst TableWrapper = (props: CardProps = {}) => {\n return <Card as=\"table\" {...props} />\n}\n\nconst StyledTable = styled(TableWrapper)(\n () =>\n css`\n display: table;\n width: 100%;\n\n &:not([hidden]) {\n display: table;\n }\n `\n)\n\ntype TableProps = PropsWithChildren<CardProps>\n\nexport function Table(props: TableProps) {\n const {children, ...rest} = props\n\n return <StyledTable {...rest}>{children}</StyledTable>\n}\n\n// Row\nconst RowWrapper = (props: CardProps = {}) => {\n return <Card as=\"tr\" {...props} />\n}\n\nconst StyledRow = styled(RowWrapper)(\n () =>\n css`\n display: table-row;\n\n &:not([hidden]) {\n display: table-row;\n }\n `\n)\n\ntype TableRowProps = PropsWithChildren<CardProps>\n\nexport function Row(props: TableRowProps) {\n const {children, ...rest} = props\n\n return <StyledRow {...rest}>{children}</StyledRow>\n}\n\n// Cell\nconst CellWrapper = (props = {}) => {\n return <Card as=\"td\" {...props} />\n}\n\nconst StyledCell = styled(CellWrapper)(\n () =>\n css`\n display: table-cell;\n\n &:not([hidden]) {\n display: table-cell;\n }\n `\n)\n\ntype TableCellProps = PropsWithChildren<CardProps>\n\nexport function Cell(props: TableCellProps) {\n const {children, ...rest} = props\n\n return <StyledCell {...rest}>{children}</StyledCell>\n}\n","import React, {useRef} from 'react'\nimport {Box, Text, Menu, MenuItem, TextInput, Flex, Badge} from '@sanity/ui'\nimport {AddCircleIcon, RemoveCircleIcon, RestoreIcon} from '@sanity/icons'\nimport {UserAvatar} from 'sanity'\n\nimport {UserExtended} from '../../hooks/useProjectUsers'\n\nfunction searchUsers(users: UserExtended[], searchString: string): UserExtended[] {\n return users.filter((user) => {\n const displayName = (user.displayName || '').toLowerCase()\n if (displayName.startsWith(searchString)) return true\n const givenName = (user.givenName || '').toLowerCase()\n if (givenName.startsWith(searchString)) return true\n const middleName = (user.middleName || '').toLowerCase()\n if (middleName.startsWith(searchString)) return true\n const familyName = (user.familyName || '').toLowerCase()\n if (familyName.startsWith(searchString)) return true\n\n return false\n })\n}\n\ntype UserSelectMenuProps = {\n value: string[]\n userList: UserExtended[]\n onAdd: any\n onRemove: any\n onClear: any\n open: boolean\n style?: React.CSSProperties\n}\n\nexport function UserSelectMenu(props: UserSelectMenuProps) {\n const {value = [], userList = [], onAdd, onRemove, onClear, style = {}} = props\n const [searchString, setSearchString] = React.useState('')\n const searchResults = searchUsers(userList || [], searchString)\n\n const me = userList.find((u) => u.isCurrentUser)\n const meAssigned = me && value.includes(me.id)\n\n // Focus input on open\n // TODO: Fix focus, it gets immediately taken away\n const input = useRef<HTMLInputElement>()\n // useEffect(() => {\n // if (open && input?.current) {\n // input.current.focus()\n // }\n // }, [open])\n\n const handleSearchChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n setSearchString(event.target.value)\n }\n\n const handleSelect = (isChecked: boolean, user: UserExtended) => {\n if (!isChecked) {\n if (onAdd) onAdd(user.id)\n } else if (onRemove) onRemove(user.id)\n }\n\n const handleAssignMyself = () => {\n if (me && onAdd) onAdd(me.id)\n }\n\n const handleUnassignMyself = () => {\n if (me && onRemove) onRemove(me.id)\n }\n\n const handleClearAssigneesClick = () => {\n if (onClear) onClear()\n }\n\n return (\n <Menu style={style}>\n {meAssigned ? (\n <MenuItem\n tone=\"caution\"\n disabled={!me}\n onClick={handleUnassignMyself}\n icon={RemoveCircleIcon}\n text=\"Unassign myself\"\n />\n ) : (\n <MenuItem\n tone=\"positive\"\n onClick={handleAssignMyself}\n icon={AddCircleIcon}\n text=\"Assign myself\"\n />\n )}\n\n <MenuItem\n tone=\"critical\"\n disabled={value.length === 0}\n onClick={handleClearAssigneesClick}\n icon={RestoreIcon}\n text=\"Clear assignees\"\n />\n\n <Box padding={1}>\n <TextInput\n // @ts-ignore TODO: Satisfy ref\n ref={input}\n onChange={handleSearchChange}\n placeholder=\"Search members\"\n value={searchString}\n />\n </Box>\n\n {searchString && searchResults?.length === 0 && <MenuItem disabled text=\"No matches\" />}\n\n {searchResults &&\n searchResults.map((user) => (\n <MenuItem\n key={user.id}\n pressed={value.includes(user.id)}\n onClick={() => handleSelect(value.indexOf(user.id) > -1, user)}\n >\n <Flex align=\"center\">\n <UserAvatar user={user} size={1} />\n <Box paddingX={2} flex={1}>\n <Text>{user.displayName}</Text>\n </Box>\n {user.isCurrentUser && (\n <Badge fontSize={1} tone=\"positive\" mode=\"outline\">\n Me\n </Badge>\n )}\n </Flex>\n </MenuItem>\n ))}\n </Menu>\n )\n}\n","import {useState, useEffect} from 'react'\nimport {useClient, useWorkspace} from 'sanity'\n\nexport type UserExtended = {\n createdAt: string\n displayName: string\n email: string\n familyName: string\n givenName: string\n id: string\n imageUrl: string\n isCurrentUser: boolean\n middleName: string\n projectId: string\n provider: string\n sanityUserId: string\n updatedAt: string\n}\n\ntype UserRole = {\n name: string\n title: string\n}\n\ntype UserResponse = {\n isRobot: boolean\n projectUserId: string\n roles: UserRole[]\n}\n\n// Custom hook to fetch user details\n// Built-in hook doesn't fetch all user details\nexport function useProjectUsers(): UserExtended[] {\n const {currentUser} = useWorkspace()\n const client = useClient()\n const [users, setUsers] = useState([])\n\n useEffect(() => {\n const {projectId} = client.config()\n\n async function getUser(id: string) {\n const userDetails = await client.request({\n url: `/projects/${projectId}/users/${id}`,\n })\n\n return userDetails\n }\n\n async function getUsersWithRoles() {\n const userRoles = await client\n .request({\n url: `/projects/${projectId}/acl`,\n })\n .then(async (res) =>\n Promise.all(\n res.map(async (user: UserResponse) => ({\n isCurrentUser: user.projectUserId === currentUser?.id,\n ...(await getUser(user.projectUserId)),\n }))\n )\n )\n .catch((err) => err)\n\n setUsers(userRoles)\n }\n\n if (!users.length) {\n getUsersWithRoles()\n }\n }, [client, currentUser?.id, users.length])\n\n return users\n}\n"],"names":["DEFAULT_PARAMS","DEFAULT_OPTIONS","apiVersion","DEFAULT_INITIAL_VALUE","DEFAULT_PROPS","tone","StyledTable","styled","props","arguments","length","undefined","jsx","Card","_objectSpread","as","css","StyledRow","StyledCell","children","rest","_excluded3","title","description","icon","padding","radius","border","jsxs","Flex","Box","flex","Stack","space","Text","weight","size","_excluded2","_excluded","value","userList","onAdd","onRemove","onClear","style","searchString","setSearchString","React","useState","searchResults","users","filter","user","displayName","toLowerCase","startsWith","givenName","middleName","familyName","searchUsers","me","find","u","isCurrentUser","meAssigned","includes","id","input","useRef","Menu","MenuItem","disabled","onClick","RemoveCircleIcon","text","AddCircleIcon","RestoreIcon","TextInput","ref","onChange","event","target","placeholder","map","pressed","isChecked","handleSelect","indexOf","align","UserAvatar","paddingX","Badge","fontSize","mode","query","_ref","params","options","initialValue","loading","setLoading","error","setError","data","setData","subscription","documentStore","useDocumentStore","useEffect","current","listenQuery","pipe","distinctUntilChanged","isEqual","catchError","err","console","subscribe","documents","_a","unsubscribe","currentUser","useWorkspace","client","useClient","setUsers","projectId","config","async","userRoles","request","url","then","Promise","all","res","projectUserId","concat","getUser","catch","getUsersWithRoles"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/hooks/useListeningQuery.tsx","../src/hooks/useProjectUsers.tsx","../src/components/Feedback.tsx","../src/components/Table.tsx","../src/components/UserSelectMenu/index.tsx"],"sourcesContent":["import {useEffect, useState, useRef} from 'react'\nimport {catchError, distinctUntilChanged} from 'rxjs/operators'\nimport isEqual from 'react-fast-compare'\nimport {useDocumentStore} from 'sanity'\nimport {Subscription} from 'rxjs'\n\ntype Params = Record<string, string | number | boolean | string[]>\n\ninterface ListenQueryOptions {\n tag?: string\n apiVersion?: string\n}\n\ntype Value = any\n\ninterface Config<V> {\n params: Params\n options?: ListenQueryOptions\n initialValue?: null | V\n}\n\ninterface Return<V> {\n loading: boolean\n error: boolean\n data: null | V\n initialValue?: Value\n}\n\nconst DEFAULT_PARAMS = {}\nconst DEFAULT_OPTIONS = {apiVersion: `v2022-05-09`}\nconst DEFAULT_INITIAL_VALUE = null\n\nexport function useListeningQuery<V>(\n query: string | {fetch: string; listen: string},\n {\n params = DEFAULT_PARAMS,\n options = DEFAULT_OPTIONS,\n initialValue = DEFAULT_INITIAL_VALUE,\n }: Config<V>\n): Return<V> {\n const [loading, setLoading] = useState(true)\n const [error, setError] = useState(false)\n const [data, setData] = useState(initialValue)\n const subscription = useRef<null | Subscription>(null)\n const documentStore = useDocumentStore()\n\n useEffect(() => {\n if (query) {\n subscription.current = documentStore\n .listenQuery(query, params, options)\n .pipe(\n distinctUntilChanged(isEqual),\n catchError((err) => {\n console.error(err)\n setError(err)\n setLoading(false)\n setData(null)\n\n return err\n })\n )\n .subscribe((documents) => {\n setData((current: Value) => (isEqual(current, documents) ? current : documents))\n setLoading(false)\n setError(false)\n })\n }\n\n return () => subscription?.current?.unsubscribe()\n }, [query, params, options, documentStore])\n\n return {data, loading, error}\n}\n","import {useState, useEffect} from 'react'\nimport {useClient, useWorkspace} from 'sanity'\n\nexport type UserExtended = {\n createdAt: string\n displayName: string\n email: string\n familyName: string\n givenName: string\n id: string\n imageUrl: string\n isCurrentUser: boolean\n middleName: string\n projectId: string\n provider: string\n sanityUserId: string\n updatedAt: string\n}\n\ntype UserRole = {\n name: string\n title: string\n}\n\ntype UserResponse = {\n isRobot: boolean\n projectUserId: string\n roles: UserRole[]\n}\n\ntype HookConfig = {\n apiVersion?: string\n}\n\n// Custom hook to fetch user details\n// Built-in hook doesn't fetch all user details\nexport function useProjectUsers({apiVersion}: HookConfig): UserExtended[] {\n const {currentUser} = useWorkspace()\n const client = useClient({apiVersion: apiVersion ?? '2023-01-01'})\n const [users, setUsers] = useState([])\n\n useEffect(() => {\n const {projectId} = client.config()\n\n async function getUser(id: string) {\n const userDetails = await client.request({\n url: `/projects/${projectId}/users/${id}`,\n })\n\n return userDetails\n }\n\n async function getUsersWithRoles() {\n const userRoles = await client\n .request({\n url: `/projects/${projectId}/acl`,\n })\n .then(async (res) =>\n Promise.all(\n res.map(async (user: UserResponse) => ({\n isCurrentUser: user.projectUserId === currentUser?.id,\n ...(await getUser(user.projectUserId)),\n }))\n )\n )\n .catch((err) => err)\n\n setUsers(userRoles)\n }\n\n if (!users.length) {\n getUsersWithRoles()\n }\n }, [client, currentUser?.id, users.length])\n\n return users\n}\n","import React from 'react'\nimport {Box, Card, CardTone, Flex, Stack, Text} from '@sanity/ui'\n\ntype FeedbackChildren = {\n children?: React.ReactNode\n title?: never\n description?: never\n}\n\ntype FeedbackTextProps = {\n title?: string\n description?: React.ReactNode\n children?: never\n}\n\ntype FeedbackProps = (FeedbackChildren | FeedbackTextProps) & {\n tone?: CardTone\n icon?: React.ReactNode\n}\n\nconst DEFAULT_PROPS: FeedbackProps = {\n tone: 'primary',\n}\n\nexport function Feedback(props: FeedbackProps) {\n const {title, description, icon, tone, children} = {...DEFAULT_PROPS, ...props}\n\n return (\n <Card tone={tone} padding={4} radius={3} border>\n <Flex>\n {icon ? `display icon` : null}\n {children ? (\n children\n ) : (\n <Box flex={1}>\n <Stack space={4}>\n {title ? <Text weight=\"semibold\">{title}</Text> : null}\n {description ? <Text size={2}>{description}</Text> : null}\n </Stack>\n </Box>\n )}\n </Flex>\n </Card>\n )\n}\n","import React, {PropsWithChildren} from 'react'\nimport styled, {css} from 'styled-components'\nimport {Card, CardProps} from '@sanity/ui'\n\n// Wrappers required because of bug with passing down \"as\" prop\n// https://github.com/styled-components/styled-components/issues/2449\n\n// Table\nconst TableWrapper = (props: CardProps = {}) => {\n return <Card as=\"table\" {...props} />\n}\n\nconst StyledTable = styled(TableWrapper)(\n () =>\n css`\n display: table;\n width: 100%;\n\n &:not([hidden]) {\n display: table;\n }\n `\n)\n\ntype TableProps = PropsWithChildren<CardProps>\n\nexport function Table(props: TableProps) {\n const {children, ...rest} = props\n\n return <StyledTable {...rest}>{children}</StyledTable>\n}\n\n// Row\nconst RowWrapper = (props: CardProps = {}) => {\n return <Card as=\"tr\" {...props} />\n}\n\nconst StyledRow = styled(RowWrapper)(\n () =>\n css`\n display: table-row;\n\n &:not([hidden]) {\n display: table-row;\n }\n `\n)\n\ntype TableRowProps = PropsWithChildren<CardProps>\n\nexport function Row(props: TableRowProps) {\n const {children, ...rest} = props\n\n return <StyledRow {...rest}>{children}</StyledRow>\n}\n\n// Cell\nconst CellWrapper = (props = {}) => {\n return <Card as=\"td\" {...props} />\n}\n\nconst StyledCell = styled(CellWrapper)(\n () =>\n css`\n display: table-cell;\n\n &:not([hidden]) {\n display: table-cell;\n }\n `\n)\n\ntype TableCellProps = PropsWithChildren<CardProps>\n\nexport function Cell(props: TableCellProps) {\n const {children, ...rest} = props\n\n return <StyledCell {...rest}>{children}</StyledCell>\n}\n","import React, {useRef} from 'react'\nimport {Box, Text, Menu, MenuItem, TextInput, Flex, Badge} from '@sanity/ui'\nimport {AddCircleIcon, RemoveCircleIcon, RestoreIcon} from '@sanity/icons'\nimport {UserAvatar} from 'sanity'\n\nimport {UserExtended} from '../../hooks/useProjectUsers'\n\nfunction searchUsers(\n users: UserExtended[],\n searchString: string\n): UserExtended[] {\n return users.filter((user) => {\n const displayName = (user.displayName || '').toLowerCase()\n if (displayName.startsWith(searchString)) return true\n const givenName = (user.givenName || '').toLowerCase()\n if (givenName.startsWith(searchString)) return true\n const middleName = (user.middleName || '').toLowerCase()\n if (middleName.startsWith(searchString)) return true\n const familyName = (user.familyName || '').toLowerCase()\n if (familyName.startsWith(searchString)) return true\n\n return false\n })\n}\n\ntype UserSelectMenuProps = {\n value: string[]\n userList: UserExtended[]\n onAdd: any\n onRemove: any\n onClear: any\n style?: React.CSSProperties\n}\n\nexport function UserSelectMenu(props: UserSelectMenuProps) {\n const {\n value = [],\n userList = [],\n onAdd,\n onRemove,\n onClear,\n style = {},\n } = props\n const [searchString, setSearchString] = React.useState('')\n const searchResults = searchUsers(userList || [], searchString)\n\n const me = userList.find((u) => u.isCurrentUser)\n const meAssigned = me && value.includes(me.id)\n\n // Focus input on open\n // TODO: Fix focus, it gets immediately taken away\n const input = useRef<HTMLInputElement>()\n // useEffect(() => {\n // if (open && input?.current) {\n // input.current.focus()\n // }\n // }, [open])\n\n const handleSearchChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n setSearchString(event.target.value)\n }\n\n const handleSelect = (isChecked: boolean, user: UserExtended) => {\n if (!isChecked) {\n if (onAdd) onAdd(user.id)\n } else if (onRemove) onRemove(user.id)\n }\n\n const handleAssignMyself = () => {\n if (me && onAdd) onAdd(me.id)\n }\n\n const handleUnassignMyself = () => {\n if (me && onRemove) onRemove(me.id)\n }\n\n const handleClearAssigneesClick = () => {\n if (onClear) onClear()\n }\n\n return (\n <Menu style={style}>\n {meAssigned ? (\n <MenuItem\n tone=\"caution\"\n disabled={!me}\n onClick={handleUnassignMyself}\n icon={RemoveCircleIcon}\n text=\"Unassign myself\"\n />\n ) : (\n <MenuItem\n tone=\"positive\"\n onClick={handleAssignMyself}\n icon={AddCircleIcon}\n text=\"Assign myself\"\n />\n )}\n\n <MenuItem\n tone=\"critical\"\n disabled={value.length === 0}\n onClick={handleClearAssigneesClick}\n icon={RestoreIcon}\n text=\"Clear assignees\"\n />\n\n <Box padding={1}>\n <TextInput\n // @ts-ignore TODO: Satisfy ref\n ref={input}\n onChange={handleSearchChange}\n placeholder=\"Search members\"\n value={searchString}\n />\n </Box>\n\n {searchString && searchResults?.length === 0 && (\n <MenuItem disabled text=\"No matches\" />\n )}\n\n {searchResults &&\n searchResults.map((user) => (\n <MenuItem\n key={user.id}\n pressed={value.includes(user.id)}\n onClick={() => handleSelect(value.indexOf(user.id) > -1, user)}\n >\n <Flex align=\"center\">\n <UserAvatar user={user} size={1} />\n <Box paddingX={2} flex={1}>\n <Text>{user.displayName}</Text>\n </Box>\n {user.isCurrentUser && (\n <Badge fontSize={1} tone=\"positive\" mode=\"outline\">\n Me\n </Badge>\n )}\n </Flex>\n </MenuItem>\n ))}\n </Menu>\n )\n}\n"],"names":["DEFAULT_PARAMS","DEFAULT_OPTIONS","apiVersion","DEFAULT_INITIAL_VALUE","useListeningQuery","query","params","options","initialValue","loading","setLoading","useState","error","setError","data","setData","subscription","useRef","documentStore","useDocumentStore","useEffect","current","listenQuery","pipe","distinctUntilChanged","isEqual","catchError","err","console","subscribe","documents","_a","unsubscribe","useProjectUsers","currentUser","useWorkspace","client","useClient","users","setUsers","projectId","config","getUser","id","userDetails","request","url","getUsersWithRoles","userRoles","then","res","Promise","all","map","user","isCurrentUser","projectUserId","catch","length","DEFAULT_PROPS","tone","Feedback","props","title","description","icon","children","jsx","Card","padding","radius","border","jsxs","Flex","Box","flex","Stack","space","Text","weight","size","TableWrapper","as","StyledTable","styled","css","Table","rest","RowWrapper","StyledRow","Row","CellWrapper","StyledCell","Cell","searchUsers","searchString","filter","displayName","toLowerCase","startsWith","givenName","middleName","familyName","UserSelectMenu","value","userList","onAdd","onRemove","onClear","style","setSearchString","React","searchResults","me","find","u","meAssigned","includes","input","handleSearchChange","event","target","handleSelect","isChecked","handleAssignMyself","handleUnassignMyself","handleClearAssigneesClick","Menu","MenuItem","disabled","onClick","RemoveCircleIcon","text","AddCircleIcon","RestoreIcon","TextInput","ref","onChange","placeholder","pressed","indexOf","align","UserAvatar","paddingX","Badge","fontSize","mode"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sanity-plugin-utils",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "A collection of useful Hooks and Components when creating Plugins",
5
5
  "keywords": [
6
6
  "sanity",
@@ -18,10 +18,10 @@
18
18
  "author": "Simeon Griggs <simeon@sanity.io>",
19
19
  "exports": {
20
20
  ".": {
21
- "types": "./lib/src/index.d.ts",
21
+ "types": "./lib/index.d.ts",
22
22
  "source": "./src/index.ts",
23
- "import": "./lib/index.esm.js",
24
23
  "require": "./lib/index.js",
24
+ "import": "./lib/index.esm.js",
25
25
  "default": "./lib/index.esm.js"
26
26
  },
27
27
  "./package.json": "./package.json"
@@ -29,59 +29,69 @@
29
29
  "main": "./lib/index.js",
30
30
  "module": "./lib/index.esm.js",
31
31
  "source": "./src/index.ts",
32
- "types": "./lib/src/index.d.ts",
32
+ "types": "./lib/index.d.ts",
33
33
  "files": [
34
- "src",
35
34
  "lib",
36
- "v2-incompatible.js",
37
- "sanity.json"
35
+ "sanity.json",
36
+ "src",
37
+ "v2-incompatible.js"
38
38
  ],
39
39
  "scripts": {
40
40
  "prebuild": "npm run clean && plugin-kit verify-package --silent && pkg-utils",
41
- "build": "pkg-utils build",
41
+ "build": "run-s clean && plugin-kit verify-package --silent && pkg-utils build --strict && pkg-utils --strict",
42
42
  "clean": "rimraf lib",
43
+ "compile": "tsc --noEmit",
44
+ "eslint": "eslint --ext=.js,.jsx,.mjs,.ts,.tsx --quiet",
43
45
  "link-watch": "plugin-kit link-watch",
44
46
  "lint": "eslint .",
47
+ "lint:fix": "eslint . --quiet --fix",
45
48
  "prepare": "husky install",
46
- "prepublishOnly": "npm run build",
47
- "watch": "pkg-utils watch"
49
+ "prepublishOnly": "run-s build",
50
+ "watch": "pkg-utils watch --strict",
51
+ "format": "prettier --write --cache --ignore-unknown ."
48
52
  },
49
53
  "dependencies": {
50
- "@sanity/icons": "^1.3.6",
54
+ "@sanity/icons": "^2.2.2",
51
55
  "@sanity/incompatible-plugin": "^1.0.4",
52
56
  "styled-components": "^5.3.6"
53
57
  },
54
58
  "devDependencies": {
55
- "@commitlint/cli": "^17.2.0",
56
- "@commitlint/config-conventional": "^17.2.0",
57
- "@sanity/pkg-utils": "^1.18.0",
58
- "@sanity/plugin-kit": "^2.2.0",
59
- "@sanity/semantic-release-preset": "^2.0.3",
60
- "@sanity/ui": "1.0.1",
59
+ "@commitlint/cli": "^17.4.2",
60
+ "@commitlint/config-conventional": "^17.4.2",
61
+ "@sanity/pkg-utils": "^2.2.4",
62
+ "@sanity/plugin-kit": "^3.1.4",
63
+ "@sanity/semantic-release-preset": "^4.0.0",
64
+ "@sanity/ui": "^1.2.2",
65
+ "@types/react": "^18.0.27",
61
66
  "@types/styled-components": "^5.1.26",
62
- "@typescript-eslint/eslint-plugin": "^5.43.0",
63
- "@typescript-eslint/parser": "^5.43.0",
64
- "eslint": "^8.27.0",
65
- "eslint-config-prettier": "^8.5.0",
67
+ "@typescript-eslint/eslint-plugin": "^5.51.0",
68
+ "@typescript-eslint/parser": "^5.51.0",
69
+ "eslint": "^8.33.0",
70
+ "eslint-config-prettier": "^8.6.0",
66
71
  "eslint-config-sanity": "^6.0.0",
67
72
  "eslint-plugin-prettier": "^4.2.1",
68
- "eslint-plugin-react": "^7.31.10",
73
+ "eslint-plugin-react": "^7.32.2",
69
74
  "eslint-plugin-react-hooks": "^4.6.0",
70
- "husky": "^8.0.2",
71
- "lint-staged": "^13.0.3",
72
- "prettier": "^2.7.1",
73
- "prettier-plugin-packagejson": "^2.3.0",
74
- "react": "^18",
75
- "rimraf": "^3.0.2",
76
- "sanity": "^3.0.0",
77
- "typescript": "^4.9.3"
75
+ "husky": "^8.0.3",
76
+ "lint-staged": "^13.1.1",
77
+ "npm-run-all": "^4.1.5",
78
+ "prettier": "^2.8.4",
79
+ "prettier-plugin-packagejson": "^2.4.2",
80
+ "react": "^18.2.0",
81
+ "react-dom": "^18.2.0",
82
+ "react-is": "^18.2.0",
83
+ "rimraf": "^4.1.2",
84
+ "sanity": "^3.3.1",
85
+ "semantic-release": "^20.1.0",
86
+ "styled-components": "^5.3.6",
87
+ "typescript": "^4.9.5"
78
88
  },
79
89
  "peerDependencies": {
80
- "@sanity/ui": "1.0.1",
90
+ "@sanity/ui": "1.2.2",
81
91
  "react": "^18",
82
92
  "react-fast-compare": "^3.2.0",
83
- "rxjs": "^6.0.0",
84
- "sanity": "^3.0.0"
93
+ "rxjs": "^7.0.0",
94
+ "sanity": "^3"
85
95
  },
86
96
  "engines": {
87
97
  "node": ">=14"
@@ -5,7 +5,10 @@ import {UserAvatar} from 'sanity'
5
5
 
6
6
  import {UserExtended} from '../../hooks/useProjectUsers'
7
7
 
8
- function searchUsers(users: UserExtended[], searchString: string): UserExtended[] {
8
+ function searchUsers(
9
+ users: UserExtended[],
10
+ searchString: string
11
+ ): UserExtended[] {
9
12
  return users.filter((user) => {
10
13
  const displayName = (user.displayName || '').toLowerCase()
11
14
  if (displayName.startsWith(searchString)) return true
@@ -26,12 +29,18 @@ type UserSelectMenuProps = {
26
29
  onAdd: any
27
30
  onRemove: any
28
31
  onClear: any
29
- open: boolean
30
32
  style?: React.CSSProperties
31
33
  }
32
34
 
33
35
  export function UserSelectMenu(props: UserSelectMenuProps) {
34
- const {value = [], userList = [], onAdd, onRemove, onClear, style = {}} = props
36
+ const {
37
+ value = [],
38
+ userList = [],
39
+ onAdd,
40
+ onRemove,
41
+ onClear,
42
+ style = {},
43
+ } = props
35
44
  const [searchString, setSearchString] = React.useState('')
36
45
  const searchResults = searchUsers(userList || [], searchString)
37
46
 
@@ -106,7 +115,9 @@ export function UserSelectMenu(props: UserSelectMenuProps) {
106
115
  />
107
116
  </Box>
108
117
 
109
- {searchString && searchResults?.length === 0 && <MenuItem disabled text="No matches" />}
118
+ {searchString && searchResults?.length === 0 && (
119
+ <MenuItem disabled text="No matches" />
120
+ )}
110
121
 
111
122
  {searchResults &&
112
123
  searchResults.map((user) => (
@@ -28,11 +28,15 @@ type UserResponse = {
28
28
  roles: UserRole[]
29
29
  }
30
30
 
31
+ type HookConfig = {
32
+ apiVersion?: string
33
+ }
34
+
31
35
  // Custom hook to fetch user details
32
36
  // Built-in hook doesn't fetch all user details
33
- export function useProjectUsers(): UserExtended[] {
37
+ export function useProjectUsers({apiVersion}: HookConfig): UserExtended[] {
34
38
  const {currentUser} = useWorkspace()
35
- const client = useClient()
39
+ const client = useClient({apiVersion: apiVersion ?? '2023-01-01'})
36
40
  const [users, setUsers] = useState([])
37
41
 
38
42
  useEffect(() => {
package/src/index.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export {useListeningQuery} from './hooks/useListeningQuery'
2
2
  export {useProjectUsers} from './hooks/useProjectUsers'
3
+ export type {UserExtended} from './hooks/useProjectUsers'
3
4
 
4
5
  export {Feedback} from './components/Feedback'
5
6
  export {Table, Row, Cell} from './components/Table'