richie-education 2.34.1-dev5 → 2.34.1-dev52

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/js/components/ContractFrame/AbstractContractFrame.spec.tsx +1 -1
  2. package/js/components/CourseGlimpse/CourseGlimpseFooter.tsx +84 -13
  3. package/js/components/CourseGlimpse/index.spec.tsx +80 -5
  4. package/js/components/CourseGlimpse/index.tsx +92 -76
  5. package/js/components/CourseGlimpse/utils.ts +31 -1
  6. package/js/components/Icon/index.tsx +7 -0
  7. package/js/components/OpenEdxFullNameForm/index.spec.tsx +17 -7
  8. package/js/components/OpenEdxFullNameForm/index.tsx +13 -16
  9. package/js/components/SaleTunnel/index.full-process.spec.tsx +1 -1
  10. package/js/pages/DashboardCreditCardsManagement/index.spec.tsx +9 -8
  11. package/js/types/Course.ts +18 -0
  12. package/js/types/index.ts +5 -0
  13. package/js/utils/test/expectAlert.ts +63 -0
  14. package/js/utils/test/factories/richie.ts +31 -1
  15. package/js/widgets/Slider/components/Slide.tsx +20 -0
  16. package/js/widgets/Slider/components/SlidePanel.tsx +83 -0
  17. package/js/widgets/Slider/components/Slideshow.tsx +58 -0
  18. package/js/widgets/Slider/index.spec.tsx +167 -0
  19. package/js/widgets/Slider/index.tsx +119 -0
  20. package/js/widgets/Slider/types/index.ts +8 -0
  21. package/js/widgets/SyllabusCourseRunsList/components/SyllabusCourseRun/index.tsx +107 -0
  22. package/js/widgets/SyllabusCourseRunsList/components/SyllabusCourseRunCompacted/index.tsx +107 -0
  23. package/js/widgets/SyllabusCourseRunsList/index.spec.tsx +450 -5
  24. package/js/widgets/index.tsx +3 -0
  25. package/package.json +45 -43
  26. package/scss/colors/_theme.scss +26 -7
  27. package/scss/components/_header.scss +108 -14
  28. package/scss/components/_subheader.scss +35 -0
  29. package/scss/components/templates/courses/cms/_program_detail.scss +71 -0
  30. package/scss/components/templates/richie/slider/_slider.scss +165 -99
  31. package/scss/objects/_course_glimpses.scss +109 -10
  32. package/scss/objects/_selector.scss +1 -0
  33. package/scss/settings/_variables.scss +4 -0
@@ -1,142 +1,208 @@
1
- $r-slider-title-fontsize: $h1-font-size !default;
1
+ $r-slider-slide-height: clamp(400px, 50vh, 600px) !default;
2
+ $r-slider-title-fontsize: $h2-font-size !default;
2
3
  $r-slider-title-fontweight: $font-weight-bold !default;
3
4
  $r-slider-title-fontfamily: $headings-font-family !default;
4
- $r-slider-content-fontsize: $h4-font-size !default;
5
+ $r-slider-content-fontsize: 1rem !default;
5
6
  $r-slider-content-line-height: 1.1 !default;
7
+ $r-slider-content-line-clamp: 4 !default;
8
+ .richie-react--slider {
9
+ min-height: $r-slider-slide-height;
10
+ }
6
11
 
7
12
  .slider {
13
+ overflow: hidden;
8
14
  position: relative;
9
- width: 100%;
10
- // Reserved space for slide indexes
11
- padding-bottom: 1.75rem;
15
+ }
12
16
 
13
- &__items {
14
- display: flex;
15
- overflow-x: hidden;
17
+ .slider__slideshow {
18
+ display: flex;
19
+ height: $r-slider-slide-height;
20
+ position: relative;
21
+ }
22
+
23
+ .slider__slide {
24
+ flex: 0 0 100%;
25
+ min-width: 0;
26
+
27
+ img {
28
+ width: 100%;
29
+ height: 100%;
30
+ object-fit: cover;
16
31
  }
32
+ }
17
33
 
18
- &__tools {
19
- @include make-container-max-widths();
20
- margin: 0 auto;
21
- padding: 0;
22
- display: flex;
23
- justify-content: center;
24
- align-content: center;
34
+ .slider__slideshow-overlay {
35
+ @include make-container();
36
+ @include make-container-max-widths();
37
+ height: clamp(400px, 50vh, 600px);
38
+ position: absolute;
39
+ top: 0;
40
+ left: 50%;
41
+ transform: translateX(-50%);
42
+ display: flex;
43
+ align-items: center;
44
+ justify-content: space-between;
45
+ pointer-events: none;
46
+
47
+ // Re-enable pointer events for children
48
+ & > * {
49
+ pointer-events: auto;
25
50
  }
51
+ }
26
52
 
27
- &__next,
28
- &__previous {
53
+ .slider__navigation-button {
54
+ @include button-reset-style();
55
+ cursor: pointer;
56
+ margin: 0;
57
+ height: 100%;
58
+ padding: 0;
59
+ position: relative;
60
+ display: inline-block;
61
+ text-align: right;
62
+
63
+ $width: 50vw;
64
+ &:before {
65
+ content: '';
66
+ display: block;
67
+ width: $width;
68
+ height: 100%;
29
69
  position: absolute;
30
- top: 25%;
31
- left: 0;
32
- right: 0;
33
- background: none;
34
- border: 0;
35
-
36
- svg {
37
- width: 5rem;
38
- height: 5rem;
39
- color: r-theme-val(slider-plugin, arrows-color);
40
- }
70
+ top: 0;
71
+ z-index: -1;
72
+ }
41
73
 
42
- &:hover {
43
- svg {
44
- color: r-theme-val(slider-plugin, arrows-hover-color);
45
- }
74
+ &:first-child {
75
+ --hover-offet-x: -10%;
76
+ &:before {
77
+ left: $width * -1;
78
+ }
79
+ }
80
+ &:last-child {
81
+ --hover-offet-x: 10%;
82
+ &:before {
83
+ right: $width * -1;
46
84
  }
47
85
  }
48
86
 
49
- &__next {
50
- left: auto;
51
- right: 0;
87
+ &:hover > .icon {
88
+ transform: scale(1.2) translateX(var(--hover-offet-x));
52
89
  }
53
90
 
54
- &__previous {
55
- left: 0;
56
- right: auto;
91
+ & > .icon {
92
+ transition: transform 300ms $r-ease-out;
93
+ color: r-theme-val(slider-plugin, arrows-fill-color);
94
+ stroke: r-theme-val(slider-plugin, arrows-stroke-color);
95
+ stroke-width: r-theme-val(slider-plugin, arrows-stroke-width);
96
+ height: 4rem;
97
+ width: 4rem;
57
98
  }
99
+ }
58
100
 
59
- &__indexes {
60
- @include make-container-max-widths();
61
- margin: 0 auto;
62
- width: 100%;
63
- padding: 0.5rem;
64
- position: absolute;
65
- bottom: 0;
101
+ .slider__panel {
102
+ @include make-container();
103
+ @include make-container-max-widths();
104
+
105
+ display: flex;
106
+ flex-direction: column-reverse;
107
+ }
108
+
109
+ .slider__bullet {
110
+ &-list {
66
111
  display: flex;
67
- justify-content: flex-end;
112
+ flex-direction: row;
113
+ gap: 6px;
68
114
  align-items: center;
115
+ justify-content: flex-end;
69
116
  }
70
117
 
71
- &__index {
72
- @include sv-flex(1, 0, 1.9rem);
73
- padding: 0;
74
- height: 1rem;
75
- background: transparent;
76
- border: 0;
118
+ &-item {
119
+ @include button-reset-style();
120
+ cursor: pointer;
121
+ width: 2rem;
122
+ transform-origin: left center;
123
+ padding-block: 1rem;
124
+ position: relative;
125
+ display: block;
77
126
 
78
- &::before {
127
+ &:before {
79
128
  content: '';
80
129
  display: block;
81
- height: 0.2rem;
82
- background: r-theme-val(slider-plugin, index-color);
83
- border: 0;
130
+ width: 100%;
131
+ height: 3px;
132
+ border-radius: 50vw;
133
+ background-color: r-theme-val(slider-plugin, index-color);
134
+ position: absolute;
135
+ transform-origin: left center;
136
+ transition: height 400ms $r-ease-out;
137
+ translate: 0 -50%;
138
+ transform: scaleY(1);
84
139
  }
85
140
 
86
- &--active {
87
- pointer-events: none;
88
-
89
- &::before {
90
- height: 0.5rem;
91
- }
141
+ &:hover:before,
142
+ &:focus:before,
143
+ &--active:before {
144
+ height: 7px;
92
145
  }
93
146
 
94
- &:hover {
95
- &::before {
96
- background: r-theme-val(slider-plugin, index-hover-color);
97
- }
147
+ &:hover:before,
148
+ &:focus:before {
149
+ background-color: r-theme-val(slider-plugin, index-hover-color);
98
150
  }
99
- }
100
151
 
101
- &__index + &__index {
102
- margin-left: 0.3rem;
152
+ &--active:before {
153
+ background-color: r-theme-val(slider-plugin, index-active-color);
154
+ }
103
155
  }
104
156
  }
105
157
 
106
- .slider-item {
107
- @include sv-flex(1, 0, 100%);
108
- display: block;
109
- color: inherit;
110
- text-decoration: none;
111
-
112
- // Disable any hover event on content since it can be in a link
113
- &:hover,
114
- *:hover {
115
- color: inherit !important;
116
- text-decoration: none !important;
117
- }
158
+ .slide__content {
159
+ max-width: 680px;
118
160
 
119
- &__image {
120
- display: block;
121
- margin: 0 0 1rem 0;
122
- width: 100%;
123
- }
161
+ &--transitioning {
162
+ .slide__title > span,
163
+ .slide__description {
164
+ transition: inherit;
165
+ }
124
166
 
125
- &__container {
126
- @include make-container-max-widths();
127
- position: relative;
128
- margin: 0 auto;
129
- }
167
+ .slide__title > span {
168
+ transform: translateY(150%);
169
+ opacity: 0;
170
+ }
130
171
 
131
- &__title {
132
- @include font-size($r-slider-title-fontsize);
133
- font-family: $r-slider-title-fontfamily;
134
- font-weight: $r-slider-title-fontweight;
135
- margin: 0 0 0.5rem 0;
172
+ .slide__description {
173
+ opacity: 0;
174
+ }
136
175
  }
176
+ }
137
177
 
138
- &__content {
139
- @include font-size($r-slider-content-fontsize);
140
- line-height: $r-slider-content-line-height;
178
+ .slide__title {
179
+ overflow: hidden;
180
+ display: inline-block;
181
+ font-size: $r-slider-title-fontsize;
182
+ font-weight: $r-slider-title-fontweight;
183
+ font-family: $r-slider-title-fontfamily;
184
+
185
+ & > span {
186
+ display: inline-block;
187
+ transform: translateY(0%);
188
+ opacity: 1;
189
+ transition-property: transform, opacity;
190
+ transition-duration: 0.8s, 0.4s;
191
+ transition-delay: 0s, 0.1s;
192
+ transition-timing-function: $r-ease-out, $r-ease-in;
141
193
  }
142
194
  }
195
+
196
+ .slide__description {
197
+ -webkit-box-orient: vertical;
198
+ -webkit-line-clamp: $r-slider-content-line-clamp;
199
+ line-clamp: $r-slider-content-line-clamp;
200
+ display: -webkit-box;
201
+ overflow: hidden;
202
+ min-height: $r-slider-content-line-clamp *
203
+ ($r-slider-content-fontsize * $r-slider-content-line-height);
204
+ opacity: 1;
205
+ transition: opacity 0.3s 0.4s $r-ease-in;
206
+ font-size: $r-slider-content-fontsize;
207
+ line-height: $r-slider-content-line-height;
208
+ }
@@ -4,6 +4,7 @@
4
4
 
5
5
  // Course-glimpse-list related variables
6
6
  $r-course-glimpse-gutter: 0.8rem !default;
7
+ $r-course-glimpse-title-line-height: 1.3em;
7
8
 
8
9
  .course-glimpse-list {
9
10
  @include make-container-max-widths();
@@ -46,7 +47,6 @@ $course-glimpse-content-padding-sides: 0.7rem !default;
46
47
  // Apply card styles for elements
47
48
  @include m-o-card(
48
49
  $border: 0,
49
- $background: r-theme-val(course-glimpse, card-background),
50
50
  $media-margin: 0,
51
51
  $wrapper-padding: 1.7rem $course-glimpse-content-padding-sides 0.5rem,
52
52
  $foot-divider: null
@@ -57,10 +57,8 @@ $course-glimpse-content-padding-sides: 0.7rem !default;
57
57
 
58
58
  position: relative;
59
59
  margin: $r-course-glimpse-gutter;
60
- border-radius: $border-radius-lg;
61
- box-shadow: r-theme-val(course-glimpse, base-shadow);
60
+
62
61
  min-width: 16rem;
63
- overflow: hidden;
64
62
 
65
63
  @include media-breakpoint-up(sm) {
66
64
  @include sv-flex(1, 0, calc(50% - #{$r-course-glimpse-gutter * 2}));
@@ -83,8 +81,16 @@ $course-glimpse-content-padding-sides: 0.7rem !default;
83
81
  pointer-events: auto;
84
82
  }
85
83
 
86
- &:hover,
87
- &:focus-within {
84
+ &__body {
85
+ box-shadow: r-theme-val(course-glimpse, base-shadow);
86
+ border-radius: $border-radius-lg;
87
+ overflow: hidden;
88
+ transition: box-shadow 0.5s $r-ease-out;
89
+ z-index: 1;
90
+ }
91
+
92
+ &:hover &__body,
93
+ &:focus-within &__body {
88
94
  color: inherit;
89
95
  text-decoration: none;
90
96
  border: 0;
@@ -149,6 +155,7 @@ $course-glimpse-content-padding-sides: 0.7rem !default;
149
155
  &__content {
150
156
  font-size: 0.9rem;
151
157
  color: r-theme-val(course-glimpse, content-color);
158
+ background: map-get(r-theme-val(course-glimpse, footer), 'background');
152
159
  }
153
160
 
154
161
  &__wrapper {
@@ -156,6 +163,9 @@ $course-glimpse-content-padding-sides: 0.7rem !default;
156
163
  display: flex;
157
164
  flex-direction: column;
158
165
  position: relative;
166
+ color: r-theme-val(course-glimpse, card-background);
167
+ border-radius: 0 0 $border-radius-lg $border-radius-lg;
168
+ background-color: r-theme-val(course-glimpse, card-background);
159
169
  }
160
170
 
161
171
  &__title,
@@ -165,7 +175,7 @@ $course-glimpse-content-padding-sides: 0.7rem !default;
165
175
  font-family: $r-font-family-montserrat;
166
176
  font-weight: $font-weight-boldest;
167
177
  flex: 1 0 1.3em * 3; // 3 lines;
168
- line-height: 1.3em;
178
+ line-height: $r-course-glimpse-title-line-height;
169
179
  margin-bottom: 1rem;
170
180
  }
171
181
 
@@ -190,11 +200,14 @@ $course-glimpse-content-padding-sides: 0.7rem !default;
190
200
  }
191
201
 
192
202
  &__title-text {
203
+ --max-lines: 3;
193
204
  -webkit-box-orient: vertical;
194
- -webkit-line-clamp: 3;
205
+ -webkit-line-clamp: var(--max-lines);
206
+ line-clamp: var(--max-lines);
195
207
  display: block;
196
208
  display: -webkit-box;
197
209
  overflow: hidden;
210
+ min-height: calc($r-course-glimpse-title-line-height * var(--max-lines));
198
211
  }
199
212
 
200
213
  &__link:focus &__title-text {
@@ -322,9 +335,26 @@ $course-glimpse-content-padding-sides: 0.7rem !default;
322
335
  border-bottom-left-radius: $border-radius-lg;
323
336
  border-bottom-right-radius: $border-radius-lg;
324
337
  font-size: 0.7rem;
338
+ justify-content: space-between;
339
+ flex-wrap: wrap;
340
+ position: relative;
341
+ z-index: 0;
342
+ transition: transform 0.25s $r-ease-out;
325
343
 
326
- &__date {
327
- @include sv-flex(1, 0, auto);
344
+ &:after {
345
+ content: '';
346
+ position: absolute;
347
+ display: block;
348
+ top: -15px;
349
+ height: 30px;
350
+ left: 0;
351
+ right: 0;
352
+ @include r-button-colors(r-theme-val(course-glimpse, footer), $apply-border: true);
353
+ z-index: -1;
354
+ }
355
+
356
+ &__column {
357
+ @include sv-flex(0, 130px, auto);
328
358
  display: flex;
329
359
  margin: 0;
330
360
  padding: 0.45rem 0;
@@ -335,7 +365,54 @@ $course-glimpse-content-padding-sides: 0.7rem !default;
335
365
  .icon {
336
366
  margin-right: 0.5rem;
337
367
  }
368
+
369
+ span {
370
+ display: inline-block;
371
+ max-width: 15ch;
372
+ font-variant-numeric: tabular-nums;
373
+ }
338
374
  }
375
+
376
+ &__price {
377
+ .offer-certificate__icon {
378
+ $visibility: r-theme-val(course-glimpse, offer-certificate-icon-visibility);
379
+ @if $visibility == hidden {
380
+ display: none;
381
+ }
382
+ visibility: $visibility;
383
+ }
384
+ .offer__icon {
385
+ $visibility: r-theme-val(course-glimpse, offer-icon-visibility);
386
+ @if $visibility == hidden {
387
+ display: none;
388
+ }
389
+ visibility: $visibility;
390
+ }
391
+
392
+ .offer__icon {
393
+ margin-right: 0;
394
+ & + .offer__price {
395
+ margin-left: 0.25rem;
396
+ }
397
+ }
398
+
399
+ .offer__price {
400
+ $visibility: r-theme-val(course-glimpse, offer-price-visibility);
401
+ @if $visibility == hidden {
402
+ display: none;
403
+ }
404
+ visibility: $visibility;
405
+ // Align vertically the price with the icon
406
+ margin-top: calc(1ex - 1cap);
407
+ }
408
+ }
409
+ }
410
+
411
+ .course-glimpse:hover .course-glimpse-footer,
412
+ .course-glimpse:hover .course-glimpse__large-footer,
413
+ .course-glimpse:focus-within .course-glimpse-footer,
414
+ .course-glimpse:focus-within .course-glimpse__large-footer {
415
+ transform: translateY(4px);
339
416
  }
340
417
 
341
418
  //
@@ -346,3 +423,25 @@ $course-glimpse-content-padding-sides: 0.7rem !default;
346
423
  @include sv-flex(1, 0, calc(33.33333% - #{$r-course-glimpse-gutter * 2}));
347
424
  }
348
425
  }
426
+
427
+ // Course Glimpse Variant according to the offer
428
+ $offer-schemes: (
429
+ certificate: r-theme-val(course-glimpse, footer-offer-certificate),
430
+ free: r-theme-val(course-glimpse, footer-offer-free),
431
+ paid: r-theme-val(course-glimpse, footer-offer-paid),
432
+ partially_free: r-theme-val(course-glimpse, footer-offer-partially_free),
433
+ subscription: r-theme-val(course-glimpse, footer-offer-subscription),
434
+ );
435
+
436
+ @each $offer, $scheme in $offer-schemes {
437
+ @if $scheme != null {
438
+ .course-glimpse--offer-#{$offer} {
439
+ .course-glimpse-footer {
440
+ @include r-button-colors($scheme, $apply-border: true);
441
+ &:after {
442
+ background: map-get($scheme, 'background');
443
+ }
444
+ }
445
+ }
446
+ }
447
+ }
@@ -1,5 +1,6 @@
1
1
  .selector {
2
2
  position: relative;
3
+ z-index: 200;
3
4
 
4
5
  &__button {
5
6
  appearance: none;
@@ -152,11 +152,13 @@ $r-footer-logo-width-lg: 11.875rem !default;
152
152
  // full width like common blocks. Usefull if you plan to remove course run from
153
153
  // template
154
154
  $r-course-aside: 35% !default;
155
+ $r-program-aside: 25% !default;
155
156
 
156
157
  // Subheader aside column width in course detail. Unlike, $r-course-aside this
157
158
  // variable cannot be null. Otherwise to homegenize layout, it should have the
158
159
  // same value than $r-course-aside.
159
160
  $r-course-subheader-aside: 35% !default;
161
+ $r-program-subheader-aside: 25% !default;
160
162
 
161
163
  // Course search page shared variables
162
164
  $r-search-filters-gutter: 0.2rem !default;
@@ -173,6 +175,8 @@ $r-section-grid-sizes: (
173
175
  '33x33x33': 1fr 1fr 1fr,
174
176
  '25x75': 25% 2fr,
175
177
  '75x25': 2fr 25%,
178
+ '35x65': 35% 2fr,
179
+ '65x35': 2fr 35%,
176
180
  );
177
181
 
178
182
  // Define gutter size to apply on Section grid