Skip to content

Commit fdb5bb6

Browse files
authored
Merge pull request NotionX#386 from NotionX/card-to-property-link
added feature where collection cards can link out to the url property
2 parents 635e1e4 + bcc9b82 commit fdb5bb6

File tree

3 files changed

+124
-53
lines changed

3 files changed

+124
-53
lines changed

packages/react-notion-x/src/context.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ export interface NotionContext {
3434
showTableOfContents: boolean
3535
minTableOfContentsItems: number
3636
linkTableTitleProperties: boolean
37+
isLinkCollectionToUrlProperty: boolean
3738

3839
defaultPageIcon?: string
3940
defaultPageCover?: string
@@ -61,6 +62,7 @@ export interface PartialNotionContext {
6162
forceCustomImages?: boolean
6263
showCollectionViewDropdown?: boolean
6364
linkTableTitleProperties?: boolean
65+
isLinkCollectionToUrlProperty?: boolean
6466

6567
showTableOfContents?: boolean
6668
minTableOfContentsItems?: number
@@ -161,6 +163,7 @@ const defaultNotionContext: NotionContext = {
161163
forceCustomImages: false,
162164
showCollectionViewDropdown: true,
163165
linkTableTitleProperties: true,
166+
isLinkCollectionToUrlProperty: false,
164167

165168
showTableOfContents: false,
166169
minTableOfContentsItems: 3,

packages/react-notion-x/src/styles.css

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2792,3 +2792,11 @@ svg.notion-page-icon {
27922792
.notion-collection-view-dropdown-content[data-state='open'] {
27932793
animation-name: slideDownAndFade;
27942794
}
2795+
2796+
.nested-form-link {
2797+
background: none!important;
2798+
border: none;
2799+
padding: 0!important;
2800+
text-decoration: underline;
2801+
cursor: pointer;
2802+
}

packages/react-notion-x/src/third-party/collection-card.tsx

Lines changed: 113 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,13 @@ export const CollectionCard: React.FC<CollectionCardProps> = ({
1919
...rest
2020
}) => {
2121
const ctx = useNotionContext()
22-
const { components, recordMap, mapPageUrl, mapImageUrl } = ctx
22+
const {
23+
components,
24+
recordMap,
25+
mapPageUrl,
26+
mapImageUrl,
27+
isLinkCollectionToUrlProperty
28+
} = ctx
2329
let coverContent = null
2430

2531
const { page_cover_position = 0.5 } = block.format || {}
@@ -110,6 +116,76 @@ export const CollectionCard: React.FC<CollectionCardProps> = ({
110116
}
111117
}
112118
}
119+
let linkProperties = []
120+
//check if a visible property has a url and we settings are for linking to it for the card
121+
if (isLinkCollectionToUrlProperty) {
122+
linkProperties = properties
123+
?.filter(
124+
(p) =>
125+
p.visible && p.property !== 'title' && collection.schema[p.property]
126+
)
127+
.filter((p) => {
128+
if (!block.properties) return null
129+
const schema = collection.schema[p.property]
130+
131+
return schema.type == 'url'
132+
})
133+
.map((p) => {
134+
return block.properties[p.property]
135+
})
136+
}
137+
let url = null
138+
if (
139+
linkProperties.length > 0 &&
140+
linkProperties[0].length > 0 &&
141+
linkProperties[0][0].length > 0
142+
) {
143+
url = linkProperties[0][0][0]
144+
}
145+
146+
const innerCard = (
147+
<>
148+
{(coverContent || cover?.type !== 'none') && (
149+
<div className='notion-collection-card-cover'>{coverContent}</div>
150+
)}
151+
152+
<div className='notion-collection-card-body'>
153+
<div className='notion-collection-card-property'>
154+
<Property
155+
schema={collection.schema.title}
156+
data={block?.properties?.title}
157+
block={block}
158+
collection={collection}
159+
/>
160+
</div>
161+
162+
{properties
163+
?.filter(
164+
(p) =>
165+
p.visible &&
166+
p.property !== 'title' &&
167+
collection.schema[p.property]
168+
)
169+
.map((p) => {
170+
if (!block.properties) return null
171+
const schema = collection.schema[p.property]
172+
const data = block.properties[p.property]
173+
174+
return (
175+
<div className='notion-collection-card-property' key={p.property}>
176+
<Property
177+
schema={schema}
178+
data={data}
179+
block={block}
180+
collection={collection}
181+
inline
182+
/>
183+
</div>
184+
)
185+
})}
186+
</div>
187+
</>
188+
)
113189

114190
return (
115191
<NotionContextProvider
@@ -118,61 +194,45 @@ export const CollectionCard: React.FC<CollectionCardProps> = ({
118194
...ctx.components,
119195
// Disable <a> tabs in all child components so we don't create invalid DOM
120196
// trees with stacked <a> tags.
197+
Link: (props) => {
198+
return (
199+
<form action={props.href} target='_blank'>
200+
<input
201+
type='submit'
202+
value={props?.children?.props?.children ?? props.href}
203+
className='nested-form-link notion-link'
204+
/>
205+
</form>
206+
)
207+
},
121208
PageLink: dummyLink
122209
}}
123210
>
124-
<components.PageLink
125-
className={cs(
126-
'notion-collection-card',
127-
`notion-collection-card-size-${coverSize}`,
128-
className
129-
)}
130-
href={mapPageUrl(block.id)}
131-
{...rest}
132-
>
133-
{(coverContent || cover?.type !== 'none') && (
134-
<div className='notion-collection-card-cover'>{coverContent}</div>
135-
)}
136-
137-
<div className='notion-collection-card-body'>
138-
<div className='notion-collection-card-property'>
139-
<Property
140-
schema={collection.schema.title}
141-
data={block?.properties?.title}
142-
block={block}
143-
collection={collection}
144-
/>
145-
</div>
146-
147-
{properties
148-
?.filter(
149-
(p) =>
150-
p.visible &&
151-
p.property !== 'title' &&
152-
collection.schema[p.property]
153-
)
154-
.map((p) => {
155-
if (!block.properties) return null
156-
const schema = collection.schema[p.property]
157-
const data = block.properties[p.property]
158-
159-
return (
160-
<div
161-
className='notion-collection-card-property'
162-
key={p.property}
163-
>
164-
<Property
165-
schema={schema}
166-
data={data}
167-
block={block}
168-
collection={collection}
169-
inline
170-
/>
171-
</div>
172-
)
173-
})}
174-
</div>
175-
</components.PageLink>
211+
{isLinkCollectionToUrlProperty && url ? (
212+
<components.Link
213+
className={cs(
214+
'notion-collection-card',
215+
`notion-collection-card-size-${coverSize}`,
216+
className
217+
)}
218+
href={url}
219+
{...rest}
220+
>
221+
{innerCard}
222+
</components.Link>
223+
) : (
224+
<components.PageLink
225+
className={cs(
226+
'notion-collection-card',
227+
`notion-collection-card-size-${coverSize}`,
228+
className
229+
)}
230+
href={mapPageUrl(block.id)}
231+
{...rest}
232+
>
233+
{innerCard}
234+
</components.PageLink>
235+
)}
176236
</NotionContextProvider>
177237
)
178238
}

0 commit comments

Comments
 (0)