sanity-plugin-utils 0.0.1
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 +21 -0
- package/README.md +154 -0
- package/lib/cjs/index.js +331 -0
- package/lib/cjs/index.js.map +1 -0
- package/lib/esm/index.js +318 -0
- package/lib/esm/index.js.map +1 -0
- package/lib/types/index.d.ts +72 -0
- package/lib/types/index.d.ts.map +1 -0
- package/package.json +75 -0
- package/sanity.json +8 -0
- package/src/components/Feedback.tsx +45 -0
- package/src/components/Table.tsx +79 -0
- package/src/components/UserSelectMenu/index.tsx +133 -0
- package/src/hooks/useListeningQuery.tsx +73 -0
- package/src/hooks/useProjectUsers.tsx +73 -0
- package/src/index.ts +6 -0
- package/v2-incompatible.js +11 -0
package/lib/esm/index.js
ADDED
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
import $gGrEF$react, {useState as $gGrEF$useState, useRef as $gGrEF$useRef, useEffect as $gGrEF$useEffect} from "react";
|
|
2
|
+
import {distinctUntilChanged as $gGrEF$distinctUntilChanged, catchError as $gGrEF$catchError} from "rxjs/operators";
|
|
3
|
+
import $gGrEF$reactfastcompare from "react-fast-compare";
|
|
4
|
+
import {useDocumentStore as $gGrEF$useDocumentStore, UserAvatar as $gGrEF$UserAvatar} from "sanity/_unstable";
|
|
5
|
+
import {useWorkspace as $gGrEF$useWorkspace, useClient as $gGrEF$useClient} from "sanity";
|
|
6
|
+
import {jsx as $gGrEF$jsx, jsxs as $gGrEF$jsxs} from "react/jsx-runtime";
|
|
7
|
+
import {Card as $gGrEF$Card, Flex as $gGrEF$Flex, Box as $gGrEF$Box, Stack as $gGrEF$Stack, Text as $gGrEF$Text, Menu as $gGrEF$Menu, MenuItem as $gGrEF$MenuItem, TextInput as $gGrEF$TextInput, Badge as $gGrEF$Badge} from "@sanity/ui";
|
|
8
|
+
import $gGrEF$styledcomponents, {css as $gGrEF$css} from "styled-components";
|
|
9
|
+
import {RemoveCircleIcon as $gGrEF$RemoveCircleIcon, AddCircleIcon as $gGrEF$AddCircleIcon, RestoreIcon as $gGrEF$RestoreIcon} from "@sanity/icons";
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
const $2130373f599d0e67$var$DEFAULT_PARAMS = {};
|
|
16
|
+
const $2130373f599d0e67$var$DEFAULT_OPTIONS = {
|
|
17
|
+
apiVersion: `v2022-05-09`
|
|
18
|
+
};
|
|
19
|
+
const $2130373f599d0e67$var$DEFAULT_INITIAL_VALUE = null;
|
|
20
|
+
function $2130373f599d0e67$export$3a1bc984843df335(query, { params: params = $2130373f599d0e67$var$DEFAULT_PARAMS , options: options = $2130373f599d0e67$var$DEFAULT_OPTIONS , initialValue: initialValue = $2130373f599d0e67$var$DEFAULT_INITIAL_VALUE }) {
|
|
21
|
+
const [loading, setLoading] = (0, $gGrEF$useState)(true);
|
|
22
|
+
const [error, setError] = (0, $gGrEF$useState)(false);
|
|
23
|
+
const [data, setData] = (0, $gGrEF$useState)(initialValue);
|
|
24
|
+
const subscription = (0, $gGrEF$useRef)(null);
|
|
25
|
+
const documentStore = (0, $gGrEF$useDocumentStore)();
|
|
26
|
+
(0, $gGrEF$useEffect)(()=>{
|
|
27
|
+
if (query) subscription.current = documentStore.listenQuery(query, params, options).pipe((0, $gGrEF$distinctUntilChanged)((0, $gGrEF$reactfastcompare)), (0, $gGrEF$catchError)((err)=>{
|
|
28
|
+
console.error(err);
|
|
29
|
+
setError(err);
|
|
30
|
+
setLoading(false);
|
|
31
|
+
setData(null);
|
|
32
|
+
return err;
|
|
33
|
+
})).subscribe((documents)=>{
|
|
34
|
+
setData((current)=>(0, $gGrEF$reactfastcompare)(current, documents) ? current : documents);
|
|
35
|
+
setLoading(false);
|
|
36
|
+
setError(false);
|
|
37
|
+
});
|
|
38
|
+
return ()=>subscription?.current?.unsubscribe();
|
|
39
|
+
}, [
|
|
40
|
+
query,
|
|
41
|
+
params,
|
|
42
|
+
options,
|
|
43
|
+
documentStore
|
|
44
|
+
]);
|
|
45
|
+
return {
|
|
46
|
+
data: data,
|
|
47
|
+
loading: loading,
|
|
48
|
+
error: error
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
function $b47a7d3337e6d4c7$export$a38963ede7c2ac91() {
|
|
56
|
+
const { currentUser: currentUser } = (0, $gGrEF$useWorkspace)();
|
|
57
|
+
const client = (0, $gGrEF$useClient)();
|
|
58
|
+
const [users, setUsers] = (0, $gGrEF$useState)([]);
|
|
59
|
+
(0, $gGrEF$useEffect)(()=>{
|
|
60
|
+
const { projectId: projectId } = client.config();
|
|
61
|
+
async function getUser(id) {
|
|
62
|
+
const userDetails = await client.request({
|
|
63
|
+
url: `/projects/${projectId}/users/${id}`
|
|
64
|
+
});
|
|
65
|
+
return userDetails;
|
|
66
|
+
}
|
|
67
|
+
async function getUsersWithRoles() {
|
|
68
|
+
const userRoles = await client.request({
|
|
69
|
+
url: `/projects/${projectId}/acl`
|
|
70
|
+
}).then(async (res)=>Promise.all(res.map(async (user)=>({
|
|
71
|
+
isCurrentUser: user.projectUserId === currentUser?.id,
|
|
72
|
+
...await getUser(user.projectUserId)
|
|
73
|
+
})))).catch((err)=>err);
|
|
74
|
+
setUsers(userRoles);
|
|
75
|
+
}
|
|
76
|
+
if (!users.length) getUsersWithRoles();
|
|
77
|
+
}, [
|
|
78
|
+
client,
|
|
79
|
+
currentUser?.id,
|
|
80
|
+
users.length
|
|
81
|
+
]);
|
|
82
|
+
return users;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
const $e183d660634d2ba0$var$DEFAULT_PROPS = {
|
|
90
|
+
tone: "primary"
|
|
91
|
+
};
|
|
92
|
+
function $e183d660634d2ba0$export$175e500a48a60fd2(props) {
|
|
93
|
+
const { title: title , description: description , icon: icon , tone: tone , children: children } = {
|
|
94
|
+
...$e183d660634d2ba0$var$DEFAULT_PROPS,
|
|
95
|
+
...props
|
|
96
|
+
};
|
|
97
|
+
return /*#__PURE__*/ (0, $gGrEF$jsx)((0, $gGrEF$Card), {
|
|
98
|
+
tone: tone,
|
|
99
|
+
padding: 4,
|
|
100
|
+
radius: 3,
|
|
101
|
+
border: true,
|
|
102
|
+
children: /*#__PURE__*/ (0, $gGrEF$jsxs)((0, $gGrEF$Flex), {
|
|
103
|
+
children: [
|
|
104
|
+
icon ? `display icon` : null,
|
|
105
|
+
children ? children : /*#__PURE__*/ (0, $gGrEF$jsx)((0, $gGrEF$Box), {
|
|
106
|
+
flex: 1,
|
|
107
|
+
children: /*#__PURE__*/ (0, $gGrEF$jsxs)((0, $gGrEF$Stack), {
|
|
108
|
+
space: 4,
|
|
109
|
+
children: [
|
|
110
|
+
title ? /*#__PURE__*/ (0, $gGrEF$jsx)((0, $gGrEF$Text), {
|
|
111
|
+
weight: "semibold",
|
|
112
|
+
children: title
|
|
113
|
+
}) : null,
|
|
114
|
+
description ? /*#__PURE__*/ (0, $gGrEF$jsx)((0, $gGrEF$Text), {
|
|
115
|
+
size: 2,
|
|
116
|
+
children: description
|
|
117
|
+
}) : null
|
|
118
|
+
]
|
|
119
|
+
})
|
|
120
|
+
})
|
|
121
|
+
]
|
|
122
|
+
})
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
// Wrappers required because of bug with passing down "as" prop
|
|
132
|
+
// https://github.com/styled-components/styled-components/issues/2449
|
|
133
|
+
// Table
|
|
134
|
+
const $32ee6db03f46d8dd$var$TableWrapper = (props = {})=>{
|
|
135
|
+
return /*#__PURE__*/ (0, $gGrEF$jsx)((0, $gGrEF$Card), {
|
|
136
|
+
as: "table",
|
|
137
|
+
...props
|
|
138
|
+
});
|
|
139
|
+
};
|
|
140
|
+
const $32ee6db03f46d8dd$var$StyledTable = (0, $gGrEF$styledcomponents)($32ee6db03f46d8dd$var$TableWrapper)(()=>(0, $gGrEF$css)`
|
|
141
|
+
display: table;
|
|
142
|
+
width: 100%;
|
|
143
|
+
|
|
144
|
+
&:not([hidden]) {
|
|
145
|
+
display: table;
|
|
146
|
+
}
|
|
147
|
+
`);
|
|
148
|
+
function $32ee6db03f46d8dd$export$54ec01a60f47d33d(props) {
|
|
149
|
+
const { children: children , ...rest } = props;
|
|
150
|
+
return /*#__PURE__*/ (0, $gGrEF$jsx)($32ee6db03f46d8dd$var$StyledTable, {
|
|
151
|
+
...rest,
|
|
152
|
+
children: children
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
// Row
|
|
156
|
+
const $32ee6db03f46d8dd$var$RowWrapper = (props = {})=>{
|
|
157
|
+
return /*#__PURE__*/ (0, $gGrEF$jsx)((0, $gGrEF$Card), {
|
|
158
|
+
as: "tr",
|
|
159
|
+
...props
|
|
160
|
+
});
|
|
161
|
+
};
|
|
162
|
+
const $32ee6db03f46d8dd$var$StyledRow = (0, $gGrEF$styledcomponents)($32ee6db03f46d8dd$var$RowWrapper)(()=>(0, $gGrEF$css)`
|
|
163
|
+
display: table-row;
|
|
164
|
+
|
|
165
|
+
&:not([hidden]) {
|
|
166
|
+
display: table-row;
|
|
167
|
+
}
|
|
168
|
+
`);
|
|
169
|
+
function $32ee6db03f46d8dd$export$b59bdbef9ce70de2(props) {
|
|
170
|
+
const { children: children , ...rest } = props;
|
|
171
|
+
return /*#__PURE__*/ (0, $gGrEF$jsx)($32ee6db03f46d8dd$var$StyledRow, {
|
|
172
|
+
...rest,
|
|
173
|
+
children: children
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
// Cell
|
|
177
|
+
const $32ee6db03f46d8dd$var$CellWrapper = (props = {})=>{
|
|
178
|
+
return /*#__PURE__*/ (0, $gGrEF$jsx)((0, $gGrEF$Card), {
|
|
179
|
+
as: "td",
|
|
180
|
+
...props
|
|
181
|
+
});
|
|
182
|
+
};
|
|
183
|
+
const $32ee6db03f46d8dd$var$StyledCell = (0, $gGrEF$styledcomponents)($32ee6db03f46d8dd$var$CellWrapper)(()=>(0, $gGrEF$css)`
|
|
184
|
+
display: table-cell;
|
|
185
|
+
|
|
186
|
+
&:not([hidden]) {
|
|
187
|
+
display: table-cell;
|
|
188
|
+
}
|
|
189
|
+
`);
|
|
190
|
+
function $32ee6db03f46d8dd$export$f6f0c3fe4ec306ea(props) {
|
|
191
|
+
const { children: children , ...rest } = props;
|
|
192
|
+
return /*#__PURE__*/ (0, $gGrEF$jsx)($32ee6db03f46d8dd$var$StyledCell, {
|
|
193
|
+
...rest,
|
|
194
|
+
children: children
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
function $c0010e70fdfb1cf2$var$searchUsers(users, searchString) {
|
|
205
|
+
return users.filter((user)=>{
|
|
206
|
+
const displayName = (user.displayName || "").toLowerCase();
|
|
207
|
+
if (displayName.startsWith(searchString)) return true;
|
|
208
|
+
const givenName = (user.givenName || "").toLowerCase();
|
|
209
|
+
if (givenName.startsWith(searchString)) return true;
|
|
210
|
+
const middleName = (user.middleName || "").toLowerCase();
|
|
211
|
+
if (middleName.startsWith(searchString)) return true;
|
|
212
|
+
const familyName = (user.familyName || "").toLowerCase();
|
|
213
|
+
if (familyName.startsWith(searchString)) return true;
|
|
214
|
+
return false;
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
function $c0010e70fdfb1cf2$export$4a7d9e0c70b27556(props) {
|
|
218
|
+
const { value: value = [] , userList: userList = [] , onAdd: onAdd , onRemove: onRemove , onClear: onClear , style: style = {} } = props;
|
|
219
|
+
const [searchString, setSearchString] = (0, $gGrEF$react).useState("");
|
|
220
|
+
const searchResults = $c0010e70fdfb1cf2$var$searchUsers(userList || [], searchString);
|
|
221
|
+
const me = userList.find((u)=>u.isCurrentUser);
|
|
222
|
+
const meAssigned = me && value.includes(me.id);
|
|
223
|
+
// Focus input on open
|
|
224
|
+
// TODO: Fix focus, it gets immediately taken away
|
|
225
|
+
const input = (0, $gGrEF$useRef)();
|
|
226
|
+
// useEffect(() => {
|
|
227
|
+
// if (open && input?.current) {
|
|
228
|
+
// input.current.focus()
|
|
229
|
+
// }
|
|
230
|
+
// }, [open])
|
|
231
|
+
const handleSearchChange = (event)=>{
|
|
232
|
+
setSearchString(event.target.value);
|
|
233
|
+
};
|
|
234
|
+
const handleSelect = (isChecked, user)=>{
|
|
235
|
+
if (!isChecked) {
|
|
236
|
+
if (onAdd) onAdd(user.id);
|
|
237
|
+
} else if (onRemove) onRemove(user.id);
|
|
238
|
+
};
|
|
239
|
+
const handleAssignMyself = ()=>{
|
|
240
|
+
if (me && onAdd) onAdd(me.id);
|
|
241
|
+
};
|
|
242
|
+
const handleUnassignMyself = ()=>{
|
|
243
|
+
if (me && onRemove) onRemove(me.id);
|
|
244
|
+
};
|
|
245
|
+
const handleClearAssigneesClick = ()=>{
|
|
246
|
+
if (onClear) onClear();
|
|
247
|
+
};
|
|
248
|
+
return /*#__PURE__*/ (0, $gGrEF$jsxs)((0, $gGrEF$Menu), {
|
|
249
|
+
style: style,
|
|
250
|
+
children: [
|
|
251
|
+
meAssigned ? /*#__PURE__*/ (0, $gGrEF$jsx)((0, $gGrEF$MenuItem), {
|
|
252
|
+
tone: "caution",
|
|
253
|
+
disabled: !me,
|
|
254
|
+
onClick: handleUnassignMyself,
|
|
255
|
+
icon: (0, $gGrEF$RemoveCircleIcon),
|
|
256
|
+
text: "Unassign myself"
|
|
257
|
+
}) : /*#__PURE__*/ (0, $gGrEF$jsx)((0, $gGrEF$MenuItem), {
|
|
258
|
+
tone: "positive",
|
|
259
|
+
onClick: handleAssignMyself,
|
|
260
|
+
icon: (0, $gGrEF$AddCircleIcon),
|
|
261
|
+
text: "Assign myself"
|
|
262
|
+
}),
|
|
263
|
+
/*#__PURE__*/ (0, $gGrEF$jsx)((0, $gGrEF$MenuItem), {
|
|
264
|
+
tone: "critical",
|
|
265
|
+
disabled: value.length === 0,
|
|
266
|
+
onClick: handleClearAssigneesClick,
|
|
267
|
+
icon: (0, $gGrEF$RestoreIcon),
|
|
268
|
+
text: "Clear assignees"
|
|
269
|
+
}),
|
|
270
|
+
/*#__PURE__*/ (0, $gGrEF$jsx)((0, $gGrEF$Box), {
|
|
271
|
+
padding: 1,
|
|
272
|
+
children: /*#__PURE__*/ (0, $gGrEF$jsx)((0, $gGrEF$TextInput), {
|
|
273
|
+
// @ts-ignore TODO: Satisfy ref
|
|
274
|
+
ref: input,
|
|
275
|
+
onChange: handleSearchChange,
|
|
276
|
+
placeholder: "Search members",
|
|
277
|
+
value: searchString
|
|
278
|
+
})
|
|
279
|
+
}),
|
|
280
|
+
searchString && searchResults?.length === 0 && /*#__PURE__*/ (0, $gGrEF$jsx)((0, $gGrEF$MenuItem), {
|
|
281
|
+
disabled: true,
|
|
282
|
+
text: "No matches"
|
|
283
|
+
}),
|
|
284
|
+
searchResults && searchResults.map((user)=>/*#__PURE__*/ (0, $gGrEF$jsx)((0, $gGrEF$MenuItem), {
|
|
285
|
+
pressed: value.includes(user.id),
|
|
286
|
+
onClick: ()=>handleSelect(value.indexOf(user.id) > -1, user),
|
|
287
|
+
children: /*#__PURE__*/ (0, $gGrEF$jsxs)((0, $gGrEF$Flex), {
|
|
288
|
+
align: "center",
|
|
289
|
+
children: [
|
|
290
|
+
/*#__PURE__*/ (0, $gGrEF$jsx)((0, $gGrEF$UserAvatar), {
|
|
291
|
+
user: user,
|
|
292
|
+
size: 1
|
|
293
|
+
}),
|
|
294
|
+
/*#__PURE__*/ (0, $gGrEF$jsx)((0, $gGrEF$Box), {
|
|
295
|
+
paddingX: 2,
|
|
296
|
+
flex: 1,
|
|
297
|
+
children: /*#__PURE__*/ (0, $gGrEF$jsx)((0, $gGrEF$Text), {
|
|
298
|
+
children: user.displayName
|
|
299
|
+
})
|
|
300
|
+
}),
|
|
301
|
+
user.isCurrentUser && /*#__PURE__*/ (0, $gGrEF$jsx)((0, $gGrEF$Badge), {
|
|
302
|
+
fontSize: 1,
|
|
303
|
+
tone: "positive",
|
|
304
|
+
mode: "outline",
|
|
305
|
+
children: "Me"
|
|
306
|
+
})
|
|
307
|
+
]
|
|
308
|
+
})
|
|
309
|
+
}, user.id))
|
|
310
|
+
]
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
|
|
317
|
+
export {$2130373f599d0e67$export$3a1bc984843df335 as useListeningQuery, $b47a7d3337e6d4c7$export$a38963ede7c2ac91 as useProjectUsers, $e183d660634d2ba0$export$175e500a48a60fd2 as Feedback, $32ee6db03f46d8dd$export$54ec01a60f47d33d as Table, $32ee6db03f46d8dd$export$b59bdbef9ce70de2 as Row, $32ee6db03f46d8dd$export$f6f0c3fe4ec306ea as Cell, $c0010e70fdfb1cf2$export$4a7d9e0c70b27556 as UserSelectMenu};
|
|
318
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"mappings":"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","sources":["src/index.ts","src/hooks/useListeningQuery.tsx","src/hooks/useProjectUsers.tsx","src/components/Feedback.tsx","src/components/Table.tsx","src/components/UserSelectMenu/index.tsx"],"sourcesContent":["export {useListeningQuery} from './hooks/useListeningQuery'\nexport {useProjectUsers} from './hooks/useProjectUsers'\n\nexport {Feedback} from './components/Feedback'\nexport {Table, Row, Cell} from './components/Table'\nexport {UserSelectMenu} from './components/UserSelectMenu/index'\n","import {useEffect, useState, useRef} from 'react'\nimport {catchError, distinctUntilChanged} from 'rxjs/operators'\nimport isEqual from 'react-fast-compare'\nimport {useDocumentStore} from 'sanity/_unstable'\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, {useEffect, 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/_unstable'\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":[],"version":3,"file":"index.js.map","sourceRoot":"../../"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import React, { PropsWithChildren } from "react";
|
|
2
|
+
import { CardTone, CardProps } from "@sanity/ui";
|
|
3
|
+
type Params = Record<string, string | number | boolean | string[]>;
|
|
4
|
+
interface ListenQueryOptions {
|
|
5
|
+
tag?: string;
|
|
6
|
+
apiVersion?: string;
|
|
7
|
+
}
|
|
8
|
+
type Value = any;
|
|
9
|
+
interface Config<V> {
|
|
10
|
+
params: Params;
|
|
11
|
+
options?: ListenQueryOptions;
|
|
12
|
+
initialValue?: null | V;
|
|
13
|
+
}
|
|
14
|
+
interface Return<V> {
|
|
15
|
+
loading: boolean;
|
|
16
|
+
error: boolean;
|
|
17
|
+
data: null | V;
|
|
18
|
+
initialValue?: Value;
|
|
19
|
+
}
|
|
20
|
+
export function useListeningQuery<V>(query: string | {
|
|
21
|
+
fetch: string;
|
|
22
|
+
listen: string;
|
|
23
|
+
}, { params, options, initialValue, }: Config<V>): Return<V>;
|
|
24
|
+
type UserExtended = {
|
|
25
|
+
createdAt: string;
|
|
26
|
+
displayName: string;
|
|
27
|
+
email: string;
|
|
28
|
+
familyName: string;
|
|
29
|
+
givenName: string;
|
|
30
|
+
id: string;
|
|
31
|
+
imageUrl: string;
|
|
32
|
+
isCurrentUser: boolean;
|
|
33
|
+
middleName: string;
|
|
34
|
+
projectId: string;
|
|
35
|
+
provider: string;
|
|
36
|
+
sanityUserId: string;
|
|
37
|
+
updatedAt: string;
|
|
38
|
+
};
|
|
39
|
+
export function useProjectUsers(): UserExtended[];
|
|
40
|
+
type FeedbackChildren = {
|
|
41
|
+
children?: React.ReactNode;
|
|
42
|
+
title?: never;
|
|
43
|
+
description?: never;
|
|
44
|
+
};
|
|
45
|
+
type FeedbackTextProps = {
|
|
46
|
+
title?: string;
|
|
47
|
+
description?: React.ReactNode;
|
|
48
|
+
children?: never;
|
|
49
|
+
};
|
|
50
|
+
type FeedbackProps = (FeedbackChildren | FeedbackTextProps) & {
|
|
51
|
+
tone?: CardTone;
|
|
52
|
+
icon?: React.ReactNode;
|
|
53
|
+
};
|
|
54
|
+
export function Feedback(props: FeedbackProps): JSX.Element;
|
|
55
|
+
type TableProps = PropsWithChildren<CardProps>;
|
|
56
|
+
export function Table(props: TableProps): JSX.Element;
|
|
57
|
+
type TableRowProps = PropsWithChildren<CardProps>;
|
|
58
|
+
export function Row(props: TableRowProps): JSX.Element;
|
|
59
|
+
type TableCellProps = PropsWithChildren<CardProps>;
|
|
60
|
+
export function Cell(props: TableCellProps): JSX.Element;
|
|
61
|
+
type UserSelectMenuProps = {
|
|
62
|
+
value: string[];
|
|
63
|
+
userList: UserExtended[];
|
|
64
|
+
onAdd: any;
|
|
65
|
+
onRemove: any;
|
|
66
|
+
onClear: any;
|
|
67
|
+
open: boolean;
|
|
68
|
+
style?: React.CSSProperties;
|
|
69
|
+
};
|
|
70
|
+
export function UserSelectMenu(props: UserSelectMenuProps): JSX.Element;
|
|
71
|
+
|
|
72
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"mappings":";;AAMA,cAAc,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,EAAE,CAAC,CAAA;AAElE;IACE,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,aAAa,GAAG,CAAA;AAEhB,iBAAiB,CAAC;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,kBAAkB,CAAA;IAC5B,YAAY,CAAC,EAAE,IAAI,GAAG,CAAC,CAAA;CACxB;AAED,iBAAiB,CAAC;IAChB,OAAO,EAAE,OAAO,CAAA;IAChB,KAAK,EAAE,OAAO,CAAA;IACd,IAAI,EAAE,IAAI,GAAG,CAAC,CAAA;IACd,YAAY,CAAC,EAAE,KAAK,CAAA;CACrB;AAMD,kCAAkC,CAAC,EACjC,KAAK,EAAE,MAAM,GAAG;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAC,EAC/C,EACE,MAAuB,EACvB,OAAyB,EACzB,YAAoC,GACrC,EAAE,OAAO,CAAC,CAAC,GACX,OAAO,CAAC,CAAC,CAiCX;ACrED,oBAA2B;IACzB,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,MAAM,CAAA;IACnB,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,EAAE,EAAE,MAAM,CAAA;IACV,QAAQ,EAAE,MAAM,CAAA;IAChB,aAAa,EAAE,OAAO,CAAA;IACtB,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,EAAE,MAAM,CAAA;CAClB,CAAA;AAeD,mCAAmC,YAAY,EAAE,CAwChD;ACrED,wBAAwB;IACtB,QAAQ,CAAC,EAAE,MAAM,SAAS,CAAA;IAC1B,KAAK,CAAC,EAAE,KAAK,CAAA;IACb,WAAW,CAAC,EAAE,KAAK,CAAA;CACpB,CAAA;AAED,yBAAyB;IACvB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,MAAM,SAAS,CAAA;IAC7B,QAAQ,CAAC,EAAE,KAAK,CAAA;CACjB,CAAA;AAED,qBAAqB,CAAC,gBAAgB,GAAG,iBAAiB,CAAC,GAAG;IAC5D,IAAI,CAAC,EAAE,QAAQ,CAAA;IACf,IAAI,CAAC,EAAE,MAAM,SAAS,CAAA;CACvB,CAAA;AAMD,yBAAyB,KAAK,EAAE,aAAa,eAoB5C;ACpBD,kBAAkB,kBAAkB,SAAS,CAAC,CAAA;AAE9C,sBAAsB,KAAK,EAAE,UAAU,eAItC;AAkBD,qBAAqB,kBAAkB,SAAS,CAAC,CAAA;AAEjD,oBAAoB,KAAK,EAAE,aAAa,eAIvC;AAkBD,sBAAsB,kBAAkB,SAAS,CAAC,CAAA;AAElD,qBAAqB,KAAK,EAAE,cAAc,eAIzC;ACxDD,2BAA2B;IACzB,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,QAAQ,EAAE,YAAY,EAAE,CAAA;IACxB,KAAK,EAAE,GAAG,CAAA;IACV,QAAQ,EAAE,GAAG,CAAA;IACb,OAAO,EAAE,GAAG,CAAA;IACZ,IAAI,EAAE,OAAO,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,aAAa,CAAA;CAC5B,CAAA;AAED,+BAA+B,KAAK,EAAE,mBAAmB,eAoGxD","sources":["src/src/hooks/useListeningQuery.tsx","src/src/hooks/useProjectUsers.tsx","src/src/components/Feedback.tsx","src/src/components/Table.tsx","src/src/components/UserSelectMenu/index.tsx","src/src/index.ts","src/index.ts"],"sourcesContent":[null,null,null,null,null,null,"export {useListeningQuery} from './hooks/useListeningQuery'\nexport {useProjectUsers} from './hooks/useProjectUsers'\n\nexport {Feedback} from './components/Feedback'\nexport {Table, Row, Cell} from './components/Table'\nexport {UserSelectMenu} from './components/UserSelectMenu/index'\n"],"names":[],"version":3,"file":"index.d.ts.map","sourceRoot":"../../"}
|
package/package.json
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "sanity-plugin-utils",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "A collection of useful Hooks and Components when creating Plugins",
|
|
5
|
+
"author": "Simeon Griggs <simeon@sanity.io>",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"source": "./src/index.ts",
|
|
8
|
+
"main": "./lib/cjs/index.js",
|
|
9
|
+
"module": "./lib/esm/index.js",
|
|
10
|
+
"types": "./lib/types/index.d.ts",
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"require": "./lib/cjs/index.js",
|
|
14
|
+
"default": "./lib/esm/index.js"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"src",
|
|
19
|
+
"lib",
|
|
20
|
+
"v2-incompatible.js",
|
|
21
|
+
"sanity.json"
|
|
22
|
+
],
|
|
23
|
+
"scripts": {
|
|
24
|
+
"clean": "rimraf lib",
|
|
25
|
+
"lint": "eslint .",
|
|
26
|
+
"prebuild": "npm run clean && plugin-kit verify-package --silent",
|
|
27
|
+
"build": "parcel build --no-cache",
|
|
28
|
+
"watch": "parcel watch",
|
|
29
|
+
"link-watch": "plugin-kit link-watch",
|
|
30
|
+
"prepublishOnly": "npm run build"
|
|
31
|
+
},
|
|
32
|
+
"repository": {
|
|
33
|
+
"type": "git",
|
|
34
|
+
"url": "git+ssh://git@github.com/simeongriggs/sanity-plugin-utils.git"
|
|
35
|
+
},
|
|
36
|
+
"engines": {
|
|
37
|
+
"node": ">=14.0.0"
|
|
38
|
+
},
|
|
39
|
+
"dependencies": {
|
|
40
|
+
"@sanity/icons": "^1.3.4",
|
|
41
|
+
"@sanity/incompatible-plugin": "^1.0.0",
|
|
42
|
+
"@sanity/ui": "^0.38.0",
|
|
43
|
+
"styled-components": "^5.3.5"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"@parcel/packager-ts": "^2.7.0",
|
|
47
|
+
"@parcel/transformer-typescript-types": "^2.7.0",
|
|
48
|
+
"@sanity/plugin-kit": "^1.0.1",
|
|
49
|
+
"@types/styled-components": "^5.1.26",
|
|
50
|
+
"@typescript-eslint/eslint-plugin": "^5.36.1",
|
|
51
|
+
"@typescript-eslint/parser": "^5.36.1",
|
|
52
|
+
"eslint": "^8.23.0",
|
|
53
|
+
"eslint-config-prettier": "^8.5.0",
|
|
54
|
+
"eslint-config-sanity": "^6.0.0",
|
|
55
|
+
"eslint-plugin-prettier": "^4.2.1",
|
|
56
|
+
"eslint-plugin-react": "^7.31.1",
|
|
57
|
+
"eslint-plugin-react-hooks": "^4.6.0",
|
|
58
|
+
"parcel": "^2.7.0",
|
|
59
|
+
"prettier": "^2.7.1",
|
|
60
|
+
"react": "^17.0.0 || ^18.0.0",
|
|
61
|
+
"rimraf": "^3.0.2",
|
|
62
|
+
"sanity": "^3.0.0-dev-preview.15",
|
|
63
|
+
"typescript": "4.7.4"
|
|
64
|
+
},
|
|
65
|
+
"peerDependencies": {
|
|
66
|
+
"react": "^17.0.0 || ^18.0.0",
|
|
67
|
+
"react-fast-compare": "^3.2.0",
|
|
68
|
+
"rxjs": "^6.5.3",
|
|
69
|
+
"sanity": "dev-preview"
|
|
70
|
+
},
|
|
71
|
+
"bugs": {
|
|
72
|
+
"url": "https://github.com/simeongriggs/sanity-plugin-utils/issues"
|
|
73
|
+
},
|
|
74
|
+
"homepage": "https://github.com/simeongriggs/sanity-plugin-utils#readme"
|
|
75
|
+
}
|
package/sanity.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import {Box, Card, CardTone, Flex, Stack, Text} from '@sanity/ui'
|
|
3
|
+
|
|
4
|
+
type FeedbackChildren = {
|
|
5
|
+
children?: React.ReactNode
|
|
6
|
+
title?: never
|
|
7
|
+
description?: never
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
type FeedbackTextProps = {
|
|
11
|
+
title?: string
|
|
12
|
+
description?: React.ReactNode
|
|
13
|
+
children?: never
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
type FeedbackProps = (FeedbackChildren | FeedbackTextProps) & {
|
|
17
|
+
tone?: CardTone
|
|
18
|
+
icon?: React.ReactNode
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const DEFAULT_PROPS: FeedbackProps = {
|
|
22
|
+
tone: 'primary',
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function Feedback(props: FeedbackProps) {
|
|
26
|
+
const {title, description, icon, tone, children} = {...DEFAULT_PROPS, ...props}
|
|
27
|
+
|
|
28
|
+
return (
|
|
29
|
+
<Card tone={tone} padding={4} radius={3} border>
|
|
30
|
+
<Flex>
|
|
31
|
+
{icon ? `display icon` : null}
|
|
32
|
+
{children ? (
|
|
33
|
+
children
|
|
34
|
+
) : (
|
|
35
|
+
<Box flex={1}>
|
|
36
|
+
<Stack space={4}>
|
|
37
|
+
{title ? <Text weight="semibold">{title}</Text> : null}
|
|
38
|
+
{description ? <Text size={2}>{description}</Text> : null}
|
|
39
|
+
</Stack>
|
|
40
|
+
</Box>
|
|
41
|
+
)}
|
|
42
|
+
</Flex>
|
|
43
|
+
</Card>
|
|
44
|
+
)
|
|
45
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import React, {PropsWithChildren} from 'react'
|
|
2
|
+
import styled, {css} from 'styled-components'
|
|
3
|
+
import {Card, CardProps} from '@sanity/ui'
|
|
4
|
+
|
|
5
|
+
// Wrappers required because of bug with passing down "as" prop
|
|
6
|
+
// https://github.com/styled-components/styled-components/issues/2449
|
|
7
|
+
|
|
8
|
+
// Table
|
|
9
|
+
const TableWrapper = (props: CardProps = {}) => {
|
|
10
|
+
return <Card as="table" {...props} />
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const StyledTable = styled(TableWrapper)(
|
|
14
|
+
() =>
|
|
15
|
+
css`
|
|
16
|
+
display: table;
|
|
17
|
+
width: 100%;
|
|
18
|
+
|
|
19
|
+
&:not([hidden]) {
|
|
20
|
+
display: table;
|
|
21
|
+
}
|
|
22
|
+
`
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
type TableProps = PropsWithChildren<CardProps>
|
|
26
|
+
|
|
27
|
+
export function Table(props: TableProps) {
|
|
28
|
+
const {children, ...rest} = props
|
|
29
|
+
|
|
30
|
+
return <StyledTable {...rest}>{children}</StyledTable>
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Row
|
|
34
|
+
const RowWrapper = (props: CardProps = {}) => {
|
|
35
|
+
return <Card as="tr" {...props} />
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const StyledRow = styled(RowWrapper)(
|
|
39
|
+
() =>
|
|
40
|
+
css`
|
|
41
|
+
display: table-row;
|
|
42
|
+
|
|
43
|
+
&:not([hidden]) {
|
|
44
|
+
display: table-row;
|
|
45
|
+
}
|
|
46
|
+
`
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
type TableRowProps = PropsWithChildren<CardProps>
|
|
50
|
+
|
|
51
|
+
export function Row(props: TableRowProps) {
|
|
52
|
+
const {children, ...rest} = props
|
|
53
|
+
|
|
54
|
+
return <StyledRow {...rest}>{children}</StyledRow>
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Cell
|
|
58
|
+
const CellWrapper = (props = {}) => {
|
|
59
|
+
return <Card as="td" {...props} />
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const StyledCell = styled(CellWrapper)(
|
|
63
|
+
() =>
|
|
64
|
+
css`
|
|
65
|
+
display: table-cell;
|
|
66
|
+
|
|
67
|
+
&:not([hidden]) {
|
|
68
|
+
display: table-cell;
|
|
69
|
+
}
|
|
70
|
+
`
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
type TableCellProps = PropsWithChildren<CardProps>
|
|
74
|
+
|
|
75
|
+
export function Cell(props: TableCellProps) {
|
|
76
|
+
const {children, ...rest} = props
|
|
77
|
+
|
|
78
|
+
return <StyledCell {...rest}>{children}</StyledCell>
|
|
79
|
+
}
|