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 5f6853d

Browse files
Support new object-fit property on individual card cover image (#3594)
1 parent 17dd382 commit 5f6853d

File tree

4 files changed

+85
-46
lines changed

4 files changed

+85
-46
lines changed

‎bun.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@
295295
"react-dom": "^19.0.0",
296296
},
297297
"catalog": {
298-
"@gitbook/api": "^0.138.0",
298+
"@gitbook/api": "^0.139.0",
299299
"bidc": "^0.0.2",
300300
},
301301
"packages": {
@@ -661,7 +661,7 @@
661661

662662
"@fortawesome/fontawesome-svg-core": ["@fortawesome/fontawesome-svg-core@6.6.0", "", { "dependencies": { "@fortawesome/fontawesome-common-types": "6.6.0" } }, "sha512-KHwPkCk6oRT4HADE7smhfsKudt9N/9lm6EJ5BVg0tD1yPA5hht837fB87F8pn15D8JfTqQOjhKTktwmLMiD7Kg=="],
663663

664-
"@gitbook/api": ["@gitbook/api@0.138.0", "", { "dependencies": { "event-iterator": "^2.0.0", "eventsource-parser": "^3.0.0" } }, "sha512-6jYH1R5IpmbFj3qUyDGuUBaABCinKQcqNCtTKtql0MSPaFp9KVnqyBsIaq/s9HohjCpyU1/EoddwzAaJWHWkkw=="],
664+
"@gitbook/api": ["@gitbook/api@0.139.0", "", { "dependencies": { "event-iterator": "^2.0.0", "eventsource-parser": "^3.0.0" } }, "sha512-6VqN4BVvOdaRng2xz5wh0gj6NJmJJZwtswKZ6g9RMWedp2UkeMXi+kcO3fBo2VYJsxhIgbtWikqGEePgHTx67g=="],
665665

666666
"@gitbook/browser-types": ["@gitbook/browser-types@workspace:packages/browser-types"],
667667

‎package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
"workspaces": {
3535
"packages": ["packages/*"],
3636
"catalog": {
37-
"@gitbook/api": "^0.138.0",
37+
"@gitbook/api": "^0.139.0",
3838
"bidc": "^0.0.2"
3939
}
4040
},

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

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { Image } from '@/components/utils';
33
import { type ResolvedContentRef, resolveContentRef } from '@/lib/references';
44
import { tcls } from '@/lib/tailwind';
55
import {
6+
CardsImageObjectFit,
67
type ContentRef,
78
type DocumentTableViewCards,
89
SiteInsightsLinkPosition,
@@ -25,8 +26,12 @@ export async function RecordCard(
2526
: null;
2627

2728
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,
29+
light.contentRef && context.contentContext
30+
? resolveContentRef(light.contentRef, context.contentContext)
31+
: null,
32+
dark.contentRef && context.contentContext
33+
? resolveContentRef(dark.contentRef, context.contentContext)
34+
: null,
3035
targetRef && context.contentContext
3136
? resolveContentRef(targetRef, context.contentContext)
3237
: null,
@@ -35,6 +40,10 @@ export async function RecordCard(
3540
const darkCoverIsSquareOrPortrait = isSquareOrPortrait(darkCover);
3641
const lightCoverIsSquareOrPortrait = isSquareOrPortrait(lightCover);
3742

43+
const darkObjectFit = dark.objectFit ? `dark:${getObjectFitClass(dark.objectFit)}` : '';
44+
const lightObjectFit = light.objectFit ? getObjectFitClass(light.objectFit) : '';
45+
const objectFits = `${lightObjectFit} ${darkObjectFit}`;
46+
3847
const body = (
3948
<div
4049
className={tcls(
@@ -94,7 +103,7 @@ export async function RecordCard(
94103
'min-w-0',
95104
'w-full',
96105
'h-full',
97-
'object-cover',
106+
'bg-tint-subtle',
98107
lightCoverIsSquareOrPortrait || darkCoverIsSquareOrPortrait
99108
? [
100109
lightCoverIsSquareOrPortrait
@@ -104,7 +113,8 @@ export async function RecordCard(
104113
? 'dark:min-[432px]:aspect-video dark:min-[432px]:h-auto'
105114
: '',
106115
].filter(Boolean)
107-
: ['h-auto', 'aspect-video']
116+
: ['h-auto', 'aspect-video'],
117+
objectFits
108118
)}
109119
priority={isOffscreen ? 'lazy' : 'high'}
110120
preload
@@ -190,3 +200,19 @@ function isSquareOrPortrait(contentRef: ResolvedContentRef | null) {
190200

191201
return file.dimensions?.width / file.dimensions?.height <= 1;
192202
}
203+
204+
/**
205+
* Get the CSS class for object-fit based on the objectFit value.
206+
*/
207+
function getObjectFitClass(objectFit: CardsImageObjectFit): string {
208+
switch (objectFit) {
209+
case CardsImageObjectFit.Contain:
210+
return 'object-contain';
211+
case CardsImageObjectFit.Fill:
212+
return 'object-fill';
213+
case CardsImageObjectFit.Cover:
214+
return 'object-cover';
215+
default:
216+
throw new Error(`Unsupported object fit: ${objectFit}`);
217+
}
218+
}

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

Lines changed: 52 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import type {
2+
CardsImageObjectFit,
23
ContentRef,
34
ContentRefFile,
45
ContentRefURL,
56
DocumentTableDefinition,
7+
DocumentTableImageRecord,
68
DocumentTableRecord,
79
DocumentTableViewCards,
810
} from '@gitbook/api';
@@ -21,55 +23,66 @@ export function getRecordValue<T extends number | string | boolean | string[] |
2123

2224
/**
2325
* Get the covers for a record card.
24-
* Returns both the light and dark covers.
26+
* Returns both the light and dark covers with their content refs and optional object fit.
2527
* The light cover is a string or a content ref (image or files column type).
2628
* The dark cover is a content ref (image column type).
2729
*/
2830
export function getRecordCardCovers(
2931
record: DocumentTableRecord,
3032
view: DocumentTableViewCards
31-
): { [key in 'light' | 'dark']: ContentRefFile | ContentRefURL | null } {
33+
): {
34+
[key in 'light' | 'dark']: {
35+
contentRef: ContentRefFile | ContentRefURL | null;
36+
objectFit?: CardsImageObjectFit;
37+
};
38+
} {
39+
const lightValue = view.coverDefinition
40+
? (getRecordValue(record, view.coverDefinition) as DocumentTableImageRecord | string[])
41+
: null;
42+
43+
const darkValue = view.coverDefinitionDark
44+
? (getRecordValue(record, view.coverDefinitionDark) as DocumentTableImageRecord)
45+
: null;
46+
3247
return {
33-
light: (() => {
34-
if (!view.coverDefinition) {
35-
return null;
36-
}
37-
38-
const value = getRecordValue(record, view.coverDefinition) as
39-
| ContentRefFile
40-
| ContentRefURL
41-
| string[];
42-
43-
if (Array.isArray(value)) {
44-
if (value.length === 0) {
45-
return null;
46-
}
47-
48-
if (typeof value[0] === 'string') {
49-
return { kind: 'file', file: value[0] };
50-
}
51-
}
52-
53-
return value as ContentRefFile | ContentRefURL;
54-
})(),
55-
dark: (() => {
56-
if (!view.coverDefinitionDark) {
57-
return null;
58-
}
59-
60-
const value = getRecordValue(record, view.coverDefinitionDark) as
61-
| ContentRefFile
62-
| ContentRefURL;
63-
64-
if (!value) {
65-
return null;
66-
}
67-
68-
return value;
69-
})(),
48+
light: processCoverValue(lightValue),
49+
dark: processCoverValue(darkValue),
7050
};
7151
}
7252

53+
/**
54+
* Process a cover value and return the content ref and object fit.
55+
*/
56+
function processCoverValue(value: DocumentTableImageRecord | string[] | null | undefined): {
57+
contentRef: ContentRefFile | ContentRefURL | null;
58+
objectFit?: CardsImageObjectFit;
59+
} {
60+
if (!value) {
61+
return { contentRef: null };
62+
}
63+
64+
if (Array.isArray(value)) {
65+
if (value.length === 0) {
66+
return { contentRef: null };
67+
}
68+
69+
if (typeof value[0] === 'string') {
70+
return { contentRef: { kind: 'file', file: value[0] } };
71+
}
72+
}
73+
74+
// Check if it's the new schema with objectFit
75+
if (value && typeof value === 'object' && 'ref' in value && 'objectFit' in value) {
76+
return {
77+
contentRef: value.ref,
78+
objectFit: value.objectFit,
79+
};
80+
}
81+
82+
// It's a direct ContentRef
83+
return { contentRef: value as ContentRefFile | ContentRefURL };
84+
}
85+
7386
/**
7487
* Get the text alignment for a column.
7588
*/

0 commit comments

Comments
(0)

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