Skip to content

Commit a06236e

Browse files
authored
Add virtual-field as a banner example (#9652)
Co-authored-by: Daniel Cousens <[email protected]>
1 parent d7882fb commit a06236e

File tree

10 files changed

+419
-3
lines changed

10 files changed

+419
-3
lines changed

examples/custom-field/3-pair-field/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ export function pair<ListTypeInfo extends BaseListTypeInfo>(
9999
}),
100100
views: './3-pair-field/views',
101101
getAdminMeta() {
102-
return {} as Parameters<typeof controller>[0]['fieldMeta']
102+
return {} satisfies Parameters<typeof controller>[0]['fieldMeta']
103103
},
104104
})
105105
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { VStack } from '@keystar/ui/layout'
2+
import { Notice } from '@keystar/ui/notice'
3+
import { Content } from '@keystar/ui/slots'
4+
import { Heading, Text } from '@keystar/ui/typography'
5+
import { type controller } from '@keystone-6/core/fields/types/virtual/views'
6+
7+
import type { FieldProps } from '@keystone-6/core/types'
8+
9+
export function Field({
10+
value,
11+
}: FieldProps<typeof controller> & { value: { messages: string[] } }) {
12+
const { messages } = value ?? {}
13+
if (!messages?.length) return null
14+
15+
return (
16+
<Notice tone="neutral">
17+
<Heading>A neutral heading</Heading>
18+
<Content>
19+
<VStack elementType="ul" gap="large">
20+
{[
21+
...(function* () {
22+
let i = 0
23+
for (const message of messages) {
24+
const lines = message.split('\n')
25+
for (const line of lines) {
26+
yield (
27+
<Text key={i++} elementType="li">
28+
{line}
29+
</Text>
30+
)
31+
}
32+
}
33+
})(),
34+
]}
35+
</VStack>
36+
</Content>
37+
</Notice>
38+
)
39+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { config } from '@keystone-6/core'
2+
import { lists } from './schema'
3+
4+
export default config({
5+
db: {
6+
provider: 'sqlite',
7+
url: process.env.DATABASE_URL || 'file:./keystone-example.db',
8+
9+
// WARNING: this is only needed for our monorepo examples, dont do this
10+
prismaClientPath: 'node_modules/myprisma',
11+
},
12+
lists,
13+
})
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"name": "@keystone-6/example-virtual-field-banner",
3+
"version": null,
4+
"private": true,
5+
"license": "MIT",
6+
"scripts": {
7+
"dev": "keystone dev",
8+
"start": "keystone start",
9+
"build": "keystone build",
10+
"postinstall": "keystone postinstall"
11+
},
12+
"dependencies": {
13+
"@keystone-6/core": "^6.5.1",
14+
"@prisma/client": "6.5.0",
15+
"@keystar/ui": "^0.7.16"
16+
},
17+
"devDependencies": {
18+
"prisma": "6.5.0",
19+
"typescript": "^5.5.0"
20+
}
21+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"template": "node",
3+
"container": {
4+
"startScript": "keystone dev",
5+
"node": "22"
6+
}
7+
}
Lines changed: 248 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,248 @@
1+
# This file is automatically generated by Keystone, do not modify it manually.
2+
# Modify your Keystone config when you want to change this.
3+
4+
type Post {
5+
id: ID!
6+
banner: Banner
7+
title: String
8+
content: String
9+
archived: Boolean
10+
}
11+
12+
type Banner {
13+
messages: [String]
14+
}
15+
16+
input PostWhereUniqueInput {
17+
id: ID
18+
}
19+
20+
input PostWhereInput {
21+
AND: [PostWhereInput!]
22+
OR: [PostWhereInput!]
23+
NOT: [PostWhereInput!]
24+
id: IDFilter
25+
title: StringFilter
26+
content: StringFilter
27+
archived: BooleanFilter
28+
}
29+
30+
input IDFilter {
31+
equals: ID
32+
in: [ID!]
33+
notIn: [ID!]
34+
lt: ID
35+
lte: ID
36+
gt: ID
37+
gte: ID
38+
not: IDFilter
39+
}
40+
41+
input StringFilter {
42+
equals: String
43+
in: [String!]
44+
notIn: [String!]
45+
lt: String
46+
lte: String
47+
gt: String
48+
gte: String
49+
contains: String
50+
startsWith: String
51+
endsWith: String
52+
not: NestedStringFilter
53+
}
54+
55+
input NestedStringFilter {
56+
equals: String
57+
in: [String!]
58+
notIn: [String!]
59+
lt: String
60+
lte: String
61+
gt: String
62+
gte: String
63+
contains: String
64+
startsWith: String
65+
endsWith: String
66+
not: NestedStringFilter
67+
}
68+
69+
input BooleanFilter {
70+
equals: Boolean
71+
not: BooleanFilter
72+
}
73+
74+
input PostOrderByInput {
75+
id: OrderDirection
76+
title: OrderDirection
77+
content: OrderDirection
78+
archived: OrderDirection
79+
}
80+
81+
enum OrderDirection {
82+
asc
83+
desc
84+
}
85+
86+
input PostUpdateInput {
87+
title: String
88+
content: String
89+
archived: Boolean
90+
}
91+
92+
input PostUpdateArgs {
93+
where: PostWhereUniqueInput!
94+
data: PostUpdateInput!
95+
}
96+
97+
input PostCreateInput {
98+
title: String
99+
content: String
100+
archived: Boolean
101+
}
102+
103+
"""
104+
The `JSON` scalar type represents JSON values as specified by [ECMA-404](http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf).
105+
"""
106+
scalar JSON @specifiedBy(url: "http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf")
107+
108+
type Mutation {
109+
createPost(data: PostCreateInput!): Post
110+
createPosts(data: [PostCreateInput!]!): [Post]
111+
updatePost(where: PostWhereUniqueInput!, data: PostUpdateInput!): Post
112+
updatePosts(data: [PostUpdateArgs!]!): [Post]
113+
deletePost(where: PostWhereUniqueInput!): Post
114+
deletePosts(where: [PostWhereUniqueInput!]!): [Post]
115+
}
116+
117+
type Query {
118+
post(where: PostWhereUniqueInput!): Post
119+
posts(where: PostWhereInput! = {}, orderBy: [PostOrderByInput!]! = [], take: Int, skip: Int! = 0, cursor: PostWhereUniqueInput): [Post!]
120+
postsCount(where: PostWhereInput! = {}): Int
121+
keystone: KeystoneMeta!
122+
}
123+
124+
type KeystoneMeta {
125+
adminMeta: KeystoneAdminMeta!
126+
}
127+
128+
type KeystoneAdminMeta {
129+
lists: [KeystoneAdminUIListMeta!]!
130+
list(key: String!): KeystoneAdminUIListMeta
131+
}
132+
133+
type KeystoneAdminUIListMeta {
134+
key: String!
135+
path: String!
136+
description: String
137+
label: String!
138+
labelField: String!
139+
singular: String!
140+
plural: String!
141+
fields: [KeystoneAdminUIFieldMeta!]!
142+
groups: [KeystoneAdminUIFieldGroupMeta!]!
143+
graphql: KeystoneAdminUIGraphQL!
144+
pageSize: Int!
145+
initialColumns: [String!]!
146+
initialSearchFields: [String!]!
147+
initialSort: KeystoneAdminUISort
148+
initialFilter: JSON
149+
isSingleton: Boolean!
150+
hideNavigation: Boolean!
151+
hideCreate: Boolean!
152+
hideDelete: Boolean!
153+
}
154+
155+
type KeystoneAdminUIFieldMeta {
156+
path: String!
157+
label: String!
158+
description: String
159+
isOrderable: Boolean!
160+
isFilterable: Boolean!
161+
isNonNull: [KeystoneAdminUIFieldMetaIsNonNull!]
162+
fieldMeta: JSON
163+
viewsIndex: Int!
164+
customViewsIndex: Int
165+
createView: KeystoneAdminUIFieldMetaCreateView!
166+
listView: KeystoneAdminUIFieldMetaListView!
167+
itemView(id: ID): KeystoneAdminUIFieldMetaItemView
168+
search: QueryMode
169+
}
170+
171+
enum KeystoneAdminUIFieldMetaIsNonNull {
172+
read
173+
create
174+
update
175+
}
176+
177+
type KeystoneAdminUIFieldMetaCreateView {
178+
fieldMode: JSON!
179+
isRequired: JSON!
180+
}
181+
182+
type KeystoneAdminUIFieldMetaListView {
183+
fieldMode: KeystoneAdminUIFieldMetaListViewFieldMode!
184+
}
185+
186+
enum KeystoneAdminUIFieldMetaListViewFieldMode {
187+
read
188+
hidden
189+
}
190+
191+
type KeystoneAdminUIFieldMetaItemView {
192+
fieldMode: JSON!
193+
fieldPosition: KeystoneAdminUIFieldMetaItemViewFieldPosition!
194+
isRequired: JSON!
195+
}
196+
197+
enum KeystoneAdminUIFieldMetaItemViewFieldPosition {
198+
form
199+
sidebar
200+
}
201+
202+
enum QueryMode {
203+
default
204+
insensitive
205+
}
206+
207+
type KeystoneAdminUIFieldGroupMeta {
208+
label: String!
209+
description: String
210+
fields: [KeystoneAdminUIFieldMeta!]!
211+
}
212+
213+
type KeystoneAdminUIGraphQL {
214+
names: KeystoneAdminUIGraphQLNames!
215+
}
216+
217+
type KeystoneAdminUIGraphQLNames {
218+
outputTypeName: String!
219+
whereInputName: String!
220+
whereUniqueInputName: String!
221+
createInputName: String!
222+
createMutationName: String!
223+
createManyMutationName: String!
224+
relateToOneForCreateInputName: String!
225+
relateToManyForCreateInputName: String!
226+
itemQueryName: String!
227+
listOrderName: String!
228+
listQueryCountName: String!
229+
listQueryName: String!
230+
updateInputName: String!
231+
updateMutationName: String!
232+
updateManyInputName: String!
233+
updateManyMutationName: String!
234+
relateToOneForUpdateInputName: String!
235+
relateToManyForUpdateInputName: String!
236+
deleteMutationName: String!
237+
deleteManyMutationName: String!
238+
}
239+
240+
type KeystoneAdminUISort {
241+
field: String!
242+
direction: KeystoneAdminUISortDirection!
243+
}
244+
245+
enum KeystoneAdminUISortDirection {
246+
ASC
247+
DESC
248+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// This file is automatically generated by Keystone, do not modify it manually.
2+
// Modify your Keystone config when you want to change this.
3+
4+
datasource sqlite {
5+
url = env("DATABASE_URL")
6+
shadowDatabaseUrl = env("SHADOW_DATABASE_URL")
7+
provider = "sqlite"
8+
}
9+
10+
generator client {
11+
provider = "prisma-client-js"
12+
output = "node_modules/myprisma"
13+
}
14+
15+
model Post {
16+
id String @id @default(cuid())
17+
title String @default("")
18+
content String @default("")
19+
archived Boolean @default(false)
20+
}

0 commit comments

Comments
 (0)