Skip to content

Commit b0d9f87

Browse files
YPE-1001: Add dark mode ability to BibleTextView React component
* feat(ui): add dark mode theme support to BibleTextView and BibleReader - Add theme prop (light/dark) to BibleTextView for text theme control - Implement theme inheritance from YouVersionProvider via useTheme hook - Add data-yv-sdk and data-yv-theme attributes for CSS styling - Pass theme prop from BibleReader to BibleTextView - Add yv:bg-background wrapper to all BibleTextView Storybook stories - Rename prop from 'background' to 'theme' for semantic clarity * feat(ui): add dark mode theme support to BibleTextView and BibleReader Added changeset for adding dark mode theme support to BibleTextView and BibleReader --------- Co-authored-by: Brenden Manquen <[email protected]>
1 parent 155d103 commit b0d9f87

File tree

4 files changed

+84
-23
lines changed

4 files changed

+84
-23
lines changed

.changeset/slick-worlds-rule.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
---
2+
'@youversion/platform-react-ui': minor
3+
'@youversion/platform-core': minor
4+
'@youversion/platform-react-hooks': minor
5+
---
6+
7+
feat(ui): add dark mode theme support to BibleTextView and BibleReader
8+
9+
- Add theme prop (light/dark) to BibleTextView for text theme control
10+
- Implement theme inheritance from YouVersionProvider via useTheme hook
11+
- Add data-yv-sdk and data-yv-theme attributes for CSS styling
12+
- Pass theme prop from BibleReader to BibleTextView
13+
- Add yv:bg-background wrapper to all BibleTextView Storybook stories
14+
- Rename prop from 'background' to 'theme' for semantic clarity

packages/ui/src/components/bible-reader.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ function Content() {
158158
currentFontFamily,
159159
lineHeight,
160160
showVerseNumbers,
161+
background,
161162
} = useBibleReaderContext();
162163
const { books } = useBooks(versionId);
163164
const { version } = useVersion(versionId);
@@ -185,6 +186,7 @@ function Content() {
185186
</h1>
186187

187188
<BibleTextView
189+
theme={background}
188190
reference={usfmReference}
189191
versionId={versionId}
190192
fontFamily={currentFontFamily}

packages/ui/src/components/verse.stories.tsx

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,11 @@ const meta = {
111111
},
112112
tags: ['autodocs'],
113113
argTypes: {
114+
theme: {
115+
table: {
116+
disable: true,
117+
},
118+
},
114119
reference: {
115120
control: 'text',
116121
description: 'USFM reference (e.g., "JHN.3.16", "JHN.3.16-17", "JHN.3")',
@@ -226,3 +231,33 @@ export const FootnoteInteraction: Story = {
226231
});
227232
},
228233
};
234+
235+
export const DarkMode: Story = {
236+
args: {
237+
reference: 'JHN.3.16',
238+
versionId: 111,
239+
renderNotes: true,
240+
theme: 'dark',
241+
},
242+
argTypes: {
243+
// The `theme` control is disabled across all of the Bible verse text
244+
// components, stories, except the dark mode one.
245+
theme: {
246+
table: {
247+
disable: false,
248+
},
249+
},
250+
},
251+
render: (args) => (
252+
<section className="yv:flex yv:flex-col yv:gap-4 yv:max-w-lg">
253+
<p className="yv:text-muted-foreground yv:font-sm">
254+
Important: The background and padding for this Story was added manually to showcase the text
255+
being influenced by the theme prop for the BibleTextView component. Otherwise, the text on a
256+
light theme would be white on white (aka unreadable)
257+
</p>
258+
<div className="yv:[&>div]:bg-background yv:[&>div]:p-4 yv:[&>div]:rounded-[8px]">
259+
<BibleTextView {...args} />
260+
</div>
261+
</section>
262+
),
263+
};

packages/ui/src/components/verse.tsx

Lines changed: 33 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import { useEffect, forwardRef, useState, useRef, type ReactNode } from 'react';
44
import { createRoot, type Root } from 'react-dom/client';
55
import DOMPurify from 'isomorphic-dompurify';
6-
import { usePassage } from '@youversion/platform-react-hooks';
6+
import { usePassage, useTheme } from '@youversion/platform-react-hooks';
77
import { Popover, PopoverContent, PopoverTrigger, PopoverClose } from '@/components/ui/popover';
88
import { Button } from './ui/button';
99
import { Footnote } from './icons/footnote';
@@ -416,6 +416,7 @@ export type BibleTextViewProps = {
416416
versionId: number;
417417
showVerseNumbers?: boolean;
418418
renderNotes?: boolean;
419+
theme?: 'light' | 'dark';
419420
};
420421

421422
/**
@@ -429,49 +430,58 @@ export const BibleTextView = ({
429430
versionId,
430431
showVerseNumbers,
431432
renderNotes,
433+
theme,
432434
}: BibleTextViewProps): React.ReactElement => {
433435
const { passage, loading, error } = usePassage({
434436
versionId,
435437
usfm: reference,
436438
include_headings: true,
437439
include_notes: true,
438440
});
441+
const providerTheme = useTheme();
442+
const currentTheme = theme || providerTheme;
439443

440444
if (loading) {
441445
return (
442-
<Verse.Html
443-
html={'<span>Loading...</span>'}
444-
fontFamily={fontFamily}
445-
fontSize={fontSize}
446-
lineHeight={lineHeight}
447-
showVerseNumbers={showVerseNumbers}
448-
renderNotes={renderNotes}
449-
/>
446+
<div data-yv-sdk data-yv-theme={currentTheme}>
447+
<Verse.Html
448+
html={'<span>Loading...</span>'}
449+
fontFamily={fontFamily}
450+
fontSize={fontSize}
451+
lineHeight={lineHeight}
452+
showVerseNumbers={showVerseNumbers}
453+
renderNotes={renderNotes}
454+
/>
455+
</div>
450456
);
451457
}
452458

453459
if (error) {
454460
return (
461+
<div data-yv-sdk data-yv-theme={currentTheme}>
462+
<Verse.Html
463+
html={'<span class="wj">We have run into an error...</span>'}
464+
fontFamily={fontFamily}
465+
fontSize={fontSize}
466+
lineHeight={lineHeight}
467+
showVerseNumbers={showVerseNumbers}
468+
renderNotes={renderNotes}
469+
/>
470+
</div>
471+
);
472+
}
473+
474+
return (
475+
<div data-yv-sdk data-yv-theme={currentTheme}>
455476
<Verse.Html
456-
html={'<span class="wj">We have run into an error...</span>'}
477+
html={passage?.content || ''}
457478
fontFamily={fontFamily}
458479
fontSize={fontSize}
459480
lineHeight={lineHeight}
460481
showVerseNumbers={showVerseNumbers}
461482
renderNotes={renderNotes}
483+
reference={passage?.reference}
462484
/>
463-
);
464-
}
465-
466-
return (
467-
<Verse.Html
468-
html={passage?.content || ''}
469-
fontFamily={fontFamily}
470-
fontSize={fontSize}
471-
lineHeight={lineHeight}
472-
showVerseNumbers={showVerseNumbers}
473-
renderNotes={renderNotes}
474-
reference={passage?.reference}
475-
/>
485+
</div>
476486
);
477487
};

0 commit comments

Comments
 (0)