Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit a413cec

Browse files
Support new object-fit property on individual card cover image
1 parent 8927e8f commit a413cec

File tree

2 files changed

+77
-19
lines changed

2 files changed

+77
-19
lines changed

‎packages/gitbook/src/components/DocumentView/Table/RecordCard.tsx

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,12 @@ export async function RecordCard(
2525
: null;
2626

2727
const [lightCover, darkCover, target] = await Promise.all([
28-
light && context.contentContext ? resolveContentRef(light, context.contentContext) : null,
29-
dark && context.contentContext ? resolveContentRef(dark, context.contentContext) : null,
28+
light.contentRef && context.contentContext
29+
? resolveContentRef(light.contentRef, context.contentContext)
30+
: null,
31+
dark.contentRef && context.contentContext
32+
? resolveContentRef(dark.contentRef, context.contentContext)
33+
: null,
3034
targetRef && context.contentContext
3135
? resolveContentRef(targetRef, context.contentContext)
3236
: null,
@@ -94,7 +98,12 @@ export async function RecordCard(
9498
'min-w-0',
9599
'w-full',
96100
'h-full',
97-
'object-cover',
101+
'bg-tint-subtle',
102+
getObjectFitClass(light.objectFit),
103+
// Apply dark mode object-fit if different from light
104+
dark.objectFit && dark.objectFit !== light.objectFit
105+
? `dark:${getObjectFitClass(dark.objectFit)}`
106+
: '',
98107
lightCoverIsSquareOrPortrait || darkCoverIsSquareOrPortrait
99108
? [
100109
lightCoverIsSquareOrPortrait
@@ -190,3 +199,23 @@ function isSquareOrPortrait(contentRef: ResolvedContentRef | null) {
190199

191200
return file.dimensions?.width / file.dimensions?.height <= 1;
192201
}
202+
203+
/**
204+
* Get the CSS class for object-fit based on the objectFit value.
205+
*/
206+
function getObjectFitClass(objectFit?: string): string {
207+
switch (objectFit) {
208+
case 'contain':
209+
return 'object-contain';
210+
case 'cover':
211+
return 'object-cover';
212+
case 'fill':
213+
return 'object-fill';
214+
case 'none':
215+
return 'object-none';
216+
case 'scale-down':
217+
return 'object-scale-down';
218+
default:
219+
return 'object-cover'; // Default fallback
220+
}
221+
}

‎packages/gitbook/src/components/DocumentView/Table/utils.ts

Lines changed: 45 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,17 @@ import type {
66
DocumentTableRecord,
77
DocumentTableViewCards,
88
} from '@gitbook/api';
9+
10+
/**
11+
* Cover value can be either a direct ContentRef or an object with objectFit and ref
12+
*/
13+
export type CoverValue =
14+
| ContentRefFile
15+
| ContentRefURL
16+
| {
17+
objectFit: string;
18+
ref: ContentRefFile | ContentRefURL;
19+
};
920
import assertNever from 'assert-never';
1021

1122
/**
@@ -21,51 +32,69 @@ export function getRecordValue<T extends number | string | boolean | string[] |
2132

2233
/**
2334
* Get the covers for a record card.
24-
* Returns both the light and dark covers.
35+
* Returns both the light and dark covers with their content refs and optional object fit.
2536
* The light cover is a string or a content ref (image or files column type).
2637
* The dark cover is a content ref (image column type).
2738
*/
2839
export function getRecordCardCovers(
2940
record: DocumentTableRecord,
3041
view: DocumentTableViewCards
31-
): { [key in 'light' | 'dark']: ContentRefFile | ContentRefURL | null } {
42+
): {
43+
[key in 'light' | 'dark']: {
44+
contentRef: ContentRefFile | ContentRefURL | null;
45+
objectFit?: string;
46+
};
47+
} {
3248
return {
3349
light: (() => {
3450
if (!view.coverDefinition) {
35-
return null;
51+
return {contentRef: null};
3652
}
3753

38-
const value = getRecordValue(record, view.coverDefinition) as
39-
| ContentRefFile
40-
| ContentRefURL
41-
| string[];
54+
const value = getRecordValue(record, view.coverDefinition) as CoverValue | string[];
4255

4356
if (Array.isArray(value)) {
4457
if (value.length === 0) {
45-
return null;
58+
return {contentRef: null};
4659
}
4760

4861
if (typeof value[0] === 'string') {
49-
return { kind: 'file', file: value[0] };
62+
return { contentRef: {kind: 'file', file: value[0]} };
5063
}
5164
}
5265

53-
return value as ContentRefFile | ContentRefURL;
66+
// Check if it's the new schema with objectFit
67+
if (value && typeof value === 'object' && 'ref' in value && 'objectFit' in value) {
68+
return {
69+
contentRef: value.ref,
70+
objectFit: value.objectFit,
71+
};
72+
}
73+
74+
// It's a direct ContentRef
75+
return { contentRef: value as ContentRefFile | ContentRefURL };
5476
})(),
5577
dark: (() => {
5678
if (!view.coverDefinitionDark) {
57-
return null;
79+
return {contentRef: null};
5880
}
5981

60-
const value = getRecordValue(record, view.coverDefinitionDark) as
61-
| ContentRefFile
62-
| ContentRefURL;
82+
const value = getRecordValue(record, view.coverDefinitionDark) as CoverValue;
6383

6484
if (!value) {
65-
return null;
85+
return { contentRef: null };
86+
}
87+
88+
// Check if it's the new schema with objectFit
89+
if (typeof value === 'object' && 'ref' in value && 'objectFit' in value) {
90+
return {
91+
contentRef: value.ref,
92+
objectFit: value.objectFit,
93+
};
6694
}
6795

68-
return value;
96+
// It's a direct ContentRef
97+
return { contentRef: value as ContentRefFile | ContentRefURL };
6998
})(),
7099
};
71100
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /