Skip to content
This repository was archived by the owner on Feb 6, 2024. It is now read-only.

Commit eff8b69

Browse files
merge: rtl, code scrolling and isMobile
2 parents 390bc99 + 7db6284 commit eff8b69

File tree

19 files changed

+215
-61
lines changed

19 files changed

+215
-61
lines changed

README.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,23 @@ In order to lazy load the images of your presentation, provide their url using t
124124

125125
*Note: If you would miss or need further theming options, don't hesitate to open an issue and/or submit a PR, it would be my pleasure to add more theming flexibility and options*
126126

127-
### Send me your slides
127+
### RTL Support
128+
129+
[DeckDeckGo] offers full LTR and RTL support. The deck inherits its parent text direction.
130+
131+
Commonly, if you wish to use RTL for your all page respectively presentation, you could set the attribute `dir` of the root `html` tag to `rtl`.
132+
133+
```
134+
<!DOCTYPE html>
135+
<html dir="rtl">
136+
<body>
137+
<deckgo-deck>
138+
</deckgo-deck>
139+
</body>
140+
</html>
141+
```
142+
143+
## Send me your slides
128144

129145
If you would publish online a presentation or talk you would have built with [DeckDeckGo], reach me out, I would be super duper happy to add it to the [list of talks and presentations](doc/talks/talks.md) ❤️
130146

doc/features/extra.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ The [DeckDeckGo] deck expose a couple of extra features which could be added to
77
- [Extra features](#extra-features)
88
- [Toggle on/off the full screen mode](#toggle-onoff-the-full-screen-mode)
99
- [Print the presentation](#print-the-presentation)
10+
- [Mobile](#mobile)
1011
- [Extra events](#extra-events)
1112

1213
## Extra features
@@ -31,6 +32,14 @@ await deck.toggleFullScreen();
3132
await deck.print();
3233
```
3334

35+
### Mobile
36+
37+
A util method to know if the current presentation is browsed on a mobile device or not.
38+
39+
```
40+
await deck.isMobile(); // resolve a boolean
41+
```
42+
3443
## Extra events
3544

3645
[DeckDeckGo] triggers the following events:

doc/slides/slides.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,8 @@ You could provide a file URI to the code you want to display or provide it with
548548

549549
The slots `title` and `code` are optional.
550550

551+
This template also exposes a slot `info` which would let you display an information over your code on mobile devices, useful to explain your reader that they should click to switch between vertical and horizontal scrolling. Find an example of the use of that slot on the [DeckDeckGo] website.
552+
551553
##### Notes
552554

553555
Optionally a slot `notes` could be use to add some notes regarding the particular slide. These will be automatically `displayed` in the [remote control](https://deckdeckgo.app).

src/components.d.ts

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export namespace Components {
1818
'getLength': () => Promise<number>;
1919
'isBeginning': () => Promise<boolean>;
2020
'isEnd': () => Promise<boolean>;
21+
'isMobile': () => Promise<boolean>;
2122
'keyboard': boolean;
2223
'pager': boolean;
2324
'pagerPercentage': boolean;
@@ -96,7 +97,7 @@ export namespace Components {
9697

9798
interface DeckgoSlideAuthor {
9899
'afterSwipe': () => Promise<void>;
99-
'beforeSwipe': (_swipeLeft: boolean) => Promise<boolean>;
100+
'beforeSwipe': (_enter: boolean) => Promise<boolean>;
100101
'imgAlt': string;
101102
'imgSrc': string;
102103
'lazyLoadContent': () => Promise<void>;
@@ -110,7 +111,7 @@ export namespace Components {
110111
interface DeckgoSlideChart {
111112
'afterSwipe': () => Promise<void>;
112113
'area': boolean;
113-
'beforeSwipe': (_swipeLeft: boolean) => Promise<boolean>;
114+
'beforeSwipe': (_enter: boolean) => Promise<boolean>;
114115
'datePattern': string;
115116
'grid': boolean;
116117
'height': number;
@@ -154,7 +155,7 @@ export namespace Components {
154155
'afterSwipe': () => Promise<void>;
155156
'anchor': string;
156157
'anchorZoom': string;
157-
'beforeSwipe': (_swipeLeft: boolean) => Promise<boolean>;
158+
'beforeSwipe': (_enter: boolean) => Promise<boolean>;
158159
'hideAnchor': boolean;
159160
'language': string;
160161
'lazyLoadContent': () => Promise<void>;
@@ -172,7 +173,7 @@ export namespace Components {
172173

173174
interface DeckgoSlideContent {
174175
'afterSwipe': () => Promise<void>;
175-
'beforeSwipe': (_swipeLeft: boolean) => Promise<boolean>;
176+
'beforeSwipe': (enter: boolean) => Promise<boolean>;
176177
'lazyLoadContent': () => Promise<void>;
177178
'reveal': boolean;
178179
'revealShowFirst': boolean;
@@ -186,7 +187,7 @@ export namespace Components {
186187
interface DeckgoSlideGif {
187188
'afterSwipe': () => Promise<void>;
188189
'alt': string;
189-
'beforeSwipe': (_swipeLeft: boolean) => Promise<boolean>;
190+
'beforeSwipe': (_enter: boolean) => Promise<boolean>;
190191
'fullscreen': boolean;
191192
'lazyLoadContent': () => Promise<void>;
192193
'src': string;
@@ -200,7 +201,7 @@ export namespace Components {
200201

201202
interface DeckgoSlideQrcode {
202203
'afterSwipe': () => Promise<void>;
203-
'beforeSwipe': (_swipeLeft: boolean) => Promise<boolean>;
204+
'beforeSwipe': (_enter: boolean) => Promise<boolean>;
204205
'content': string;
205206
'lazyLoadContent': () => Promise<void>;
206207
}
@@ -211,7 +212,7 @@ export namespace Components {
211212

212213
interface DeckgoSlideSplit {
213214
'afterSwipe': () => Promise<void>;
214-
'beforeSwipe': (_swipeLeft: boolean) => Promise<boolean>;
215+
'beforeSwipe': (enter: boolean) => Promise<boolean>;
215216
'lazyLoadContent': () => Promise<void>;
216217
'reveal': boolean;
217218
'revealShowFirst': boolean;
@@ -224,7 +225,7 @@ export namespace Components {
224225

225226
interface DeckgoSlideTitle {
226227
'afterSwipe': () => Promise<void>;
227-
'beforeSwipe': (_swipeLeft: boolean) => Promise<boolean>;
228+
'beforeSwipe': (enter: boolean) => Promise<boolean>;
228229
'lazyLoadContent': () => Promise<void>;
229230
'reveal': boolean;
230231
'revealShowFirst': boolean;
@@ -237,7 +238,7 @@ export namespace Components {
237238

238239
interface DeckgoSlideYoutube {
239240
'afterSwipe': () => Promise<void>;
240-
'beforeSwipe': (_swipeLeft: boolean) => Promise<boolean>;
241+
'beforeSwipe': (_enter: boolean) => Promise<boolean>;
241242
'height': number;
242243
'lazyLoadContent': () => Promise<void>;
243244
'pause': () => Promise<void>;

src/components/deck/deckdeckgo-deck/deckdeckgo-deck.tsx

Lines changed: 48 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ export class DeckdeckgoDeck {
2727
@Prop() pager: boolean = true;
2828
@Prop() pagerPercentage: boolean = true;
2929

30+
@State()
31+
private rtl: boolean = false;
32+
3033
private startX: number = null;
3134
private deckTranslateX: number = 0;
3235
private autoSwipeRatio: number = 10;
@@ -50,13 +53,28 @@ export class DeckdeckgoDeck {
5053
private cursorHidden: boolean = false;
5154
private idleMouseTimer: number;
5255

56+
async componentWillLoad() {
57+
await this.initRtl();
58+
}
59+
5360
async componentDidLoad() {
5461
this.initWindowResize();
5562
this.initKeyboardAssist();
5663

5764
await this.lazyBackgroungImages();
5865
}
5966

67+
private initRtl(): Promise<void> {
68+
return new Promise<void>((resolve) => {
69+
if (document && document.documentElement) {
70+
const htmlDir: string = document.documentElement.getAttribute('dir');
71+
this.rtl = htmlDir && htmlDir === 'rtl';
72+
}
73+
74+
resolve();
75+
});
76+
}
77+
6078
private initWindowResize() {
6179
if (window) {
6280
window.addEventListener('resize', DeckdeckgoUtils.debounce(async () => {
@@ -74,10 +92,10 @@ export class DeckdeckgoDeck {
7492

7593
if (e.key === 'ArrowLeft') {
7694
e.preventDefault();
77-
await this.slidePrev();
95+
await this.slideNextPrev(false, true);
7896
} else if (e.key === 'ArrowRight') {
7997
e.preventDefault();
80-
await this.slideNext();
98+
await this.slideNextPrev(true, true);
8199
}
82100
});
83101
}
@@ -142,7 +160,7 @@ export class DeckdeckgoDeck {
142160
return;
143161
}
144162

145-
let transformX: number = deltaX.swipeLeft ? this.deckTranslateX - deltaX.deltaX : this.deckTranslateX + deltaX.deltaX;
163+
const transformX: number = deltaX.swipeLeft ? this.deckTranslateX - deltaX.deltaX : this.deckTranslateX + deltaX.deltaX;
146164

147165
deltaX.slider.style.setProperty('--transformX', transformX + 'px');
148166
deltaX.slider.style.setProperty('--transformXDuration', '0ms');
@@ -169,15 +187,20 @@ export class DeckdeckgoDeck {
169187
return;
170188
}
171189

172-
const couldSwipeLeft: boolean = deltaX.swipeLeft && this.activeIndex < this.length - 1;
173-
const couldSwipeRight: boolean = !deltaX.swipeLeft && this.activeIndex > 0;
190+
let couldSwipeLeft: boolean = deltaX.swipeLeft && this.activeIndex < this.length - 1;
191+
let couldSwipeRight: boolean = !deltaX.swipeLeft && this.activeIndex > 0;
192+
193+
if (this.rtl) {
194+
couldSwipeLeft = deltaX.swipeLeft && this.activeIndex > 0;
195+
couldSwipeRight = !deltaX.swipeLeft && this.activeIndex < this.length - 1;
196+
}
174197

175198
if (couldSwipeLeft || couldSwipeRight) {
176199
const windowWidth: number = window.innerWidth;
177200
if (deltaX.deltaX > (windowWidth / this.autoSwipeRatio)) {
178201
this.deckTranslateX = deltaX.swipeLeft ? this.deckTranslateX - windowWidth : this.deckTranslateX + windowWidth;
179202

180-
if (deltaX.swipeLeft) {
203+
if (this.isNextChange(deltaX.swipeLeft)) {
181204
this.activeIndex++;
182205

183206
if (emitEvent) {
@@ -202,6 +225,10 @@ export class DeckdeckgoDeck {
202225
});
203226
}
204227

228+
private isNextChange(swipeLeft: boolean): boolean {
229+
return (swipeLeft && !this.rtl) || (!swipeLeft && this.rtl);
230+
}
231+
205232
private doSwipeSlide(slider: HTMLElement, speed?: number | undefined): Promise<void> {
206233
return new Promise<void>((resolve) => {
207234
slider.style.setProperty('--transformX', this.deckTranslateX + 'px');
@@ -347,12 +374,12 @@ export class DeckdeckgoDeck {
347374

348375
@Method()
349376
async slideNext(slideAnimation?: boolean, emitEvent?: boolean) {
350-
await this.slideNextPrev(true, slideAnimation, emitEvent);
377+
await this.slideNextPrev(!this.rtl, slideAnimation, emitEvent);
351378
}
352379

353380
@Method()
354381
async slidePrev(slideAnimation?: boolean, emitEvent?: boolean) {
355-
await this.slideNextPrev(false, slideAnimation, emitEvent);
382+
await this.slideNextPrev(this.rtl, slideAnimation, emitEvent);
356383
}
357384

358385
private async slideNextPrev(swipeLeft: boolean, slideAnimation: boolean = true, emitEvent?: boolean) {
@@ -367,7 +394,7 @@ export class DeckdeckgoDeck {
367394
if (!slideAnimation) {
368395
couldSwipe = true;
369396
} else {
370-
couldSwipe = await this.beforeSwipe(swipeLeft);
397+
couldSwipe = await this.beforeSwipe(this.isNextChange(swipeLeft));
371398
}
372399

373400
// We might want first to show hide stuffs in the slide before swiping
@@ -384,15 +411,15 @@ export class DeckdeckgoDeck {
384411
}
385412
}
386413

387-
private beforeSwipe(swipeLeft: boolean): Promise<boolean> {
414+
private beforeSwipe(enter: boolean): Promise<boolean> {
388415
return new Promise<boolean>(async (resolve) => {
389416
const slide: HTMLElement = this.el.querySelector('.deckgo-slide-container:nth-child(' + (this.activeIndex + 1) + ')');
390417

391418
if (!slide) {
392419
// If we find no slide, we are cool something went wrong but the talk/show must go on
393420
resolve(true);
394421
} else {
395-
const result: boolean = await (slide as any).beforeSwipe(swipeLeft);
422+
const result: boolean = await (slide as any).beforeSwipe(enter);
396423
resolve(result);
397424
}
398425
});
@@ -457,7 +484,7 @@ export class DeckdeckgoDeck {
457484
return;
458485
}
459486

460-
this.deckTranslateX = index * -1 * window.innerWidth;
487+
this.deckTranslateX = index * window.innerWidth * (this.rtl ? 1 : -1);
461488
this.activeIndex = index;
462489

463490
await this.lazyLoadContent(this.activeIndex);
@@ -556,7 +583,7 @@ export class DeckdeckgoDeck {
556583

557584
/* END: Full screen */
558585

559-
/* BEGIN: Full screen */
586+
/* BEGIN: Utils */
560587

561588
@Method()
562589
doPrint(): Promise<void> {
@@ -581,7 +608,14 @@ export class DeckdeckgoDeck {
581608
return Promise.all(promises);
582609
}
583610

584-
/* END: Full screen */
611+
@Method()
612+
isMobile(): Promise<boolean> {
613+
return new Promise<boolean>((resolve) => {
614+
resolve(DeckdeckgoUtils.isMobile());
615+
});
616+
}
617+
618+
/* END: Utils */
585619

586620
render() {
587621
return [

src/components/slides/deckdeckgo-slide-author/deckdeckgo-slide-author.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ export class DeckdeckgoSlideAuthor implements DeckdeckgoSlide {
2424
}
2525

2626
@Method()
27-
beforeSwipe(_swipeLeft: boolean): Promise<boolean> {
27+
beforeSwipe(_enter: boolean): Promise<boolean> {
2828
return new Promise<boolean>((resolve) => {
2929
resolve(true)
3030
});

src/components/slides/deckdeckgo-slide-chart/deckdeckgo-slide-chart.scss

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,14 @@ div.deckgo-slide {
77
}
88

99
div.deckgo-chart-container {
10-
margin: var(--slide-chart-margin-top, 32px) var(--slide-chart-margin-end, 96px) var(--slide-chart-margin-bottom, 32px) var(--slide-chart-margin-start, 32px);
10+
margin: var(--slide-chart-margin-top, 32px) var(--slide-chart-margin-end, 32px) var(--slide-chart-margin-bottom, 32px) var(--slide-chart-margin-start, 32px);
1111

12-
width: calc(100vw - var(--slide-chart-margin-end, 96px) - var(--slide-chart-margin-start, 32px));
12+
width: calc(100vw - var(--slide-chart-margin-end, 32px) - var(--slide-chart-margin-start, 32px));
1313
height: calc(100vw - var(--slide-chart-margin-top, 32px) - var(--slide-chart-margin-bottom, 32px));
1414

1515
display: flex;
1616
align-items: center;
1717
justify-content: center;
18+
19+
align-self: center;
1820
}

src/components/slides/deckdeckgo-slide-chart/deckdeckgo-slide-chart.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ export class DeckdeckgoSlideChart implements DeckdeckgoSlide {
6161
}
6262

6363
@Method()
64-
beforeSwipe(_swipeLeft: boolean): Promise<boolean> {
64+
beforeSwipe(_enter: boolean): Promise<boolean> {
6565
return new Promise<boolean>((resolve) => {
6666
resolve(true)
6767
});

0 commit comments

Comments
 (0)