diff --git a/src/addons/block/myoverview/components/myoverview/myoverview.scss b/src/addons/block/myoverview/components/myoverview/myoverview.scss index 257242306..50bb3c00a 100644 --- a/src/addons/block/myoverview/components/myoverview/myoverview.scss +++ b/src/addons/block/myoverview/components/myoverview/myoverview.scss @@ -1,3 +1,5 @@ +@use "theme/globals" as *; + :host { ion-row.addon-block-myoverview-filter { margin: 8px; @@ -39,4 +41,14 @@ color: var(--subdued-text-color); } } + + ion-item-divider .core-button-spinner { + display: flex; + align-items: center; + @include margin-horizontal(10px); + + ion-badge.core-course-download-courses-progress { + @include margin(null, 12px, null, null); + } + } } diff --git a/src/addons/calendar/pages/edit-event/edit-event.html b/src/addons/calendar/pages/edit-event/edit-event.html index b16a3baa0..c100ad69c 100644 --- a/src/addons/calendar/pages/edit-event/edit-event.html +++ b/src/addons/calendar/pages/edit-event/edit-event.html @@ -141,12 +141,12 @@ -

{{ 'addon.calendar.durationnone' | translate }}

+ {{ 'addon.calendar.durationnone' | translate }}
-

+
@@ -163,7 +163,7 @@ -

+
@@ -194,14 +194,14 @@

{{ 'addon.calendar.repeatedevents' | translate }}

- - -

{{ 'addon.calendar.repeateditall' | translate:{$a: otherEventsCount} }}

+ + + {{ 'addon.calendar.repeateditall' | translate:{$a: otherEventsCount} }} - - -

{{ 'addon.calendar.repeateditthis' | translate }}

+ + + {{ 'addon.calendar.repeateditthis' | translate }} diff --git a/src/addons/calendar/pages/edit-event/edit-event.ts b/src/addons/calendar/pages/edit-event/edit-event.ts index a48ff91e7..fee6ccb9f 100644 --- a/src/addons/calendar/pages/edit-event/edit-event.ts +++ b/src/addons/calendar/pages/edit-event/edit-event.ts @@ -118,7 +118,7 @@ export class AddonCalendarEditEventPage implements OnInit, OnDestroy, CanLeave { this.form.addControl('duration', this.fb.control(0)); this.form.addControl('timedurationminutes', this.fb.control('')); this.form.addControl('repeat', this.fb.control(false)); - this.form.addControl('repeats', this.fb.control('1')); + this.form.addControl('repeats', this.fb.control({ value: '1', disabled: true })); this.form.addControl('repeateditall', this.fb.control(1)); this.maxDate = CoreTimeUtils.getDatetimeDefaultMax(); diff --git a/src/addons/mod/data/data.scss b/src/addons/mod/data/data.scss index 70ceb7dd0..f994af4ad 100644 --- a/src/addons/mod/data/data.scss +++ b/src/addons/mod/data/data.scss @@ -49,7 +49,7 @@ $grid-column-paddings: ( position: relative; flex-basis: 0; flex-grow: 1; - width: 100%; + width: 100% !important; max-width: 100%; min-height: auto; } diff --git a/src/core/directives/format-text.ts b/src/core/directives/format-text.ts index a790499db..8ac3ea96f 100644 --- a/src/core/directives/format-text.ts +++ b/src/core/directives/format-text.ts @@ -876,7 +876,7 @@ export class CoreFormatTextDirective implements OnChanges, OnDestroy, AsyncDirec if (iframe.contentDocument) { const css = document.createElement('style'); css.setAttribute('type', 'text/css'); - css.innerHTML = 'iframe {width: 100%;height: 100%;}'; + css.innerHTML = 'iframe {width: 100%;height: 100%;position:absolute;top:0; left:0;}'; iframe.contentDocument.head.appendChild(css); } }); diff --git a/src/core/services/utils/iframe.ts b/src/core/services/utils/iframe.ts index 6837b2625..93e9a0933 100644 --- a/src/core/services/utils/iframe.ts +++ b/src/core/services/utils/iframe.ts @@ -344,7 +344,8 @@ export class CoreIframeUtilsProvider { element.classList.add('core-loading'); - const treatElement = (sendResizeEvent: boolean = false) => { + const treatElement = (sendResizeEvent = false) => { + this.checkOnlineFrameInOffline(element, isSubframe); const { window, document } = this.getContentWindowAndDocument(element); @@ -361,10 +362,12 @@ export class CoreIframeUtilsProvider { // Iframe content has been loaded. // Send a resize events to the iframe so it calculates the right size if needed. - if (window && sendResizeEvent) { + if (sendResizeEvent) { element.classList.remove('core-loading'); - setTimeout(() => window.dispatchEvent && window.dispatchEvent(new Event('resize')), 1000); + if (window) { + setTimeout(() => window.dispatchEvent && window.dispatchEvent(new Event('resize')), 1000); + } } }; diff --git a/src/theme/components/collapsible-header.scss b/src/theme/components/collapsible-header.scss index 7196c833c..f9f2eda82 100644 --- a/src/theme/components/collapsible-header.scss +++ b/src/theme/components/collapsible-header.scss @@ -33,7 +33,6 @@ body:not(.core-iframe-fullscreen) .collapsible-header-page { &:not(.collapsible-header-page-is-collapsed) .collapsible-header-collapsed { --core-header-toolbar-border-width: 0; - --core-header-buttons-background: var(--ion-background-color); --core-header-buttons-color: var(--text-color); ion-toolbar { --background: transparent; diff --git a/src/theme/components/format-text.scss b/src/theme/components/format-text.scss index 5cce7f8f1..6c315f262 100644 --- a/src/theme/components/format-text.scss +++ b/src/theme/components/format-text.scss @@ -70,7 +70,7 @@ core-format-text { display: inline-block; max-width: 100%; - .core-image-viewer-icon { + button.core-image-viewer-icon { position: absolute; @include position(null, 10px, 10px, null); color: var(--ion-text-color); diff --git a/src/theme/components/iframe.scss b/src/theme/components/iframe.scss new file mode 100644 index 000000000..824bed517 --- /dev/null +++ b/src/theme/components/iframe.scss @@ -0,0 +1,94 @@ +iframe { + flex-grow: 1; + border: 0; + display: block; + max-width: 100%; + background-color: var(--ion-background-color); +} + +.core-iframe-offline-disabled { + display: none !important; +} + +// Iframe fullscreen manage. +body.core-iframe-fullscreen { + + // Using router outlet to avoid changing styles on modals. + ion-router-outlet { + .core-course-header, + ion-tab-bar { + display: none !important; + } + + ion-tab-bar.mainmenu-tabs { + display: none; + + // Restore original safe area. + .tabs-inner { + @supports (padding-left: constant(safe-area-inset-left)) { + --ion-safe-area-left: constant(safe-area-inset-left); + } + + @supports (padding-left: env(safe-area-inset-left)) { + --ion-safe-area-left: env(safe-area-inset-left); + } + } + } + + .ion-page ion-header { + --core-header-toolbar-height: 48px; + --core-header-toolbar-color: white; + --core-header-toolbar-background: black; + --core-header-buttons-color: var(--core-header-toolbar-color); + --core-header-toolbar-border-width: 0px; + + ion-toolbar { + h1, ion-back-button { + display: none; + } + } + } + + @media screen and (orientation: landscape) { + // Place ion-header on the side and hide text + .ion-page { + flex-direction: row-reverse; + ion-header { + width: calc(var(--core-header-toolbar-height) + var(--ion-safe-area-right)); + @include safe-area-padding-horizontal(null, 0px); + background: var(--core-header-toolbar-background); + + ion-toolbar { + padding: 0; + height: 100%; + --padding-start: 0px; + --padding-end: 0px; + } + + ion-buttons { + flex-direction: column-reverse; + } + } + } + + core-tabs-outlet { + width: 100%; + } + } + } + + // Hide cards and items with colors on fullscreen iframes. + @each $color-name, $unused in $colors { + ion-card.core-#{$color-name}-card, + .item.core-#{$color-name}-item { + opacity: 0 !important; + height: 0 !important; + } + } + + // Hide collapsible footer on fullscreen iframes. + [collapsible-footer] { + opacity: 0 !important; + height: 0 !important; + } +} diff --git a/src/theme/components/ion-avatar.scss b/src/theme/components/ion-avatar.scss new file mode 100644 index 000000000..bd576267a --- /dev/null +++ b/src/theme/components/ion-avatar.scss @@ -0,0 +1,27 @@ + +// Avatar +// ------------------------- +// Large centered avatar +img.large-avatar, +.large-avatar img { + display: block; + margin: 8px auto; + width: var(--core-large-avatar-size); + height: var(--core-large-avatar-size); + max-width: var(--core-large-avatar-size); + max-height: var(--core-large-avatar-size); + border-radius: 50%; + background-color: transparent; +} + +ion-avatar { + &.large-avatar { + width: var(--core-large-avatar-size); + height: var(--core-large-avatar-size); + } + + img { + text-indent: -99999px; + background-color: var(--gray-200); + } +} diff --git a/src/theme/components/ion-badge.scss b/src/theme/components/ion-badge.scss new file mode 100644 index 000000000..837a8496a --- /dev/null +++ b/src/theme/components/ion-badge.scss @@ -0,0 +1,5 @@ +ion-badge { + line-height: 1.1; + padding: 2px 8px; + border-radius: var(--mdl-shape-borderRadius-lg); +} diff --git a/src/theme/components/ion-card.scss b/src/theme/components/ion-card.scss index 68ab6edce..175d852d2 100644 --- a/src/theme/components/ion-card.scss +++ b/src/theme/components/ion-card.scss @@ -36,10 +36,49 @@ ion-card { justify-content: flex-end; margin: 0px 8px 8px 8px; - ion-button { - &[fill="outline"] { + ion-button.button { + --color: var(--gray-900); + + &.button-outline { --background: transparent; } } } + + // Coloured cards. + @each $color-name, $unused in $colors { + &.core-#{$color-name}-card { + --color-tint: var(--ion-color-#{$color-name}-tint); + --color-shade: var(--ion-color-#{$color-name}-shade); + --border-width: 0; + + --border-color: var(--color-tint); + --border-radius: var(--mdl-shape-borderRadius-sm); + --background: var(--color-tint); + --color: var(--color-shade); + + ion-item.item { + --background: var(--color-tint); + --color: var(--color-shade); + --inner-border-width: 0px; + --border-width: 0px; + font-size: var(--text-size); + + &.item-label > ion-label, + &.item-label > ion-label > p { + --color: var(--color-shade); + } + + > ion-icon[slot] { + color: var(--color-shade); + @include margin-horizontal(null, 16px); + } + } + + ion-label { + white-space: normal !important; + } + } + } + } diff --git a/src/theme/components/ion-checkbox.scss b/src/theme/components/ion-checkbox.scss index 80afa1d8f..6fb4053a0 100644 --- a/src/theme/components/ion-checkbox.scss +++ b/src/theme/components/ion-checkbox.scss @@ -15,6 +15,10 @@ input[type=checkbox] { } } +ion-checkbox::part(label) { + white-space: normal; +} + ion-checkbox { &.checkbox-disabled { @include pointer-events-on-buttons(); diff --git a/src/theme/components/ion-header.scss b/src/theme/components/ion-header.scss index 597306033..8a82ca47d 100644 --- a/src/theme/components/ion-header.scss +++ b/src/theme/components/ion-header.scss @@ -132,7 +132,6 @@ ion-header.header-md { --core-header-toolbar-border-width: 0; --core-header-toolbar-background: transparent; --core-header-shadow: none !important; - --core-header-buttons-background: var(--ion-background-color); --core-header-buttons-color: var(--text-color); } } diff --git a/src/theme/components/ion-icon.scss b/src/theme/components/ion-icon.scss index 3abb46455..9b9c8eaa9 100644 --- a/src/theme/components/ion-icon.scss +++ b/src/theme/components/ion-icon.scss @@ -19,6 +19,14 @@ ion-icon { -webkit-transform: scale(-1, 1); transform: scale(-1, 1); } + + // Coloured icons. + @each $color-name, $unused in $colors { + &.ion-color-#{$color-name} { + --ion-color-base: var(--ion-color-#{$color-name}); + color: var(--ion-color-base); + } + } } // The following code is part of the Fontawesome css file that can be found diff --git a/src/theme/components/ion-item.scss b/src/theme/components/ion-item.scss index 7665540e2..47048d7b3 100644 --- a/src/theme/components/ion-item.scss +++ b/src/theme/components/ion-item.scss @@ -232,3 +232,21 @@ ion-item.item.item-file { --background: var(--light); } } + +// Coloured items. +@each $color-name, $unused in $colors { + + ion-item.item.core-#{$color-name}-item, + .item.core-#{$color-name}-item { + --color-base: var(--ion-color-#{$color-name}); + --color-shade: var(--ion-color-#{$color-name}-shade); + + --border-width: 0 0 3px 0; + --border-color: var(--color-base); + --inner-border-width: 0px; + + > ion-icon[slot] { + color: var(--color-base); + } + } +} diff --git a/src/theme/components/ion-radio.scss b/src/theme/components/ion-radio.scss index 3050b1711..ebab14798 100644 --- a/src/theme/components/ion-radio.scss +++ b/src/theme/components/ion-radio.scss @@ -22,6 +22,10 @@ input[type=radio], --outer-border-width: 1px; } +ion-radio::part(label) { + white-space: normal; +} + .ios ion-radio { &::part(container) { width: var(--size); diff --git a/src/theme/components/table.scss b/src/theme/components/table.scss new file mode 100644 index 000000000..d94099888 --- /dev/null +++ b/src/theme/components/table.scss @@ -0,0 +1,82 @@ + +// Table App styles +table.core-table { + border-collapse: collapse; + line-height: 20px; + width: 98%; + margin: 1em auto; + color: var(--text-color); + + thead th { + vertical-align: bottom; + font-weight: bold; + font-size: var(--mdl-typography-body-fontSize-md); + background-color: var(--core-table-header-background); + } + + tbody { + th { + font-weight: normal; + } + td { + font-size: var(--mdl-typography-body-fontSize-lg); + } + } + + th, td { + padding: 8px; + white-space: normal; + text-align: start; + } + + tr { + border-bottom: 1px solid var(--core-table-border-color); + } + + .odd { + --cell-background: var(--core-table-odd-cell-background); + --cell-hover: var(--core-table-odd-cell-hover); + } + + .even { + --cell-background: var(--core-table-even-cell-background); + --cell-hover: var(--core-table-even-cell-hover); + } + + .odd, .even { + td, th, th[aria-current="page"] { + background-color: var(--cell-background); + + &:hover { + background-color: var(--cell-hover); + } + } + } + + tbody.auto-striped { + tr:nth-child(odd) { + background-color: var(--core-table-odd-cell-background); + + &:hover { + background-color: var(--core-table-even-odd-hover); + } + } + + tr:nth-child(even) { + background-color: var(--core-table-even-cell-background); + + &:hover { + background-color: var(--core-table-even-cell-hover); + } + } + } + + .ion-no-border { + border: 0 !important; + } + + .dimmed_text, + .hidden { + opacity: .7; + } +} diff --git a/src/theme/theme.base.scss b/src/theme/theme.base.scss index 34f7b1ec6..c7f4cf3e9 100644 --- a/src/theme/theme.base.scss +++ b/src/theme/theme.base.scss @@ -161,73 +161,6 @@ core-split-view.menu-and-content { } } -// Iframe fullscreen manage. -// Using router outlet to avoid changing styles on modals. -body.core-iframe-fullscreen ion-router-outlet { - - .core-course-header, - ion-tab-bar { - display: none !important; - } - - ion-tab-bar.mainmenu-tabs { - display: none; - - // Restore original safe area. - .tabs-inner { - @supports (padding-left: constant(safe-area-inset-left)) { - --ion-safe-area-left: constant(safe-area-inset-left); - } - - @supports (padding-left: env(safe-area-inset-left)) { - --ion-safe-area-left: env(safe-area-inset-left); - } - } - } - - .ion-page ion-header { - --core-header-toolbar-height: 48px; - --core-header-toolbar-color: white; - --core-header-toolbar-background: black; - --core-header-buttons-background: var(--core-header-toolbar-background); - --core-header-buttons-color: var(--core-header-toolbar-color); - --core-header-toolbar-border-width: 0px; - - ion-toolbar { - h1, ion-back-button { - display: none; - } - } - } - - @media screen and (orientation: landscape) { - // Place ion-header on the side and hide text - .ion-page { - flex-direction: row-reverse; - ion-header { - width: calc(var(--core-header-toolbar-height) + var(--ion-safe-area-right)); - @include safe-area-padding-horizontal(null, 0px); - background: var(--core-header-toolbar-background); - - ion-toolbar { - padding: 0; - height: 100%; - --padding-start: 0px; - --padding-end: 0px; - } - - ion-buttons { - flex-direction: column-reverse; - } - } - } - - core-tabs-outlet { - width: 100%; - } - } -} - // Hidden submit button. .core-submit-hidden-enter { position: absolute; @@ -262,105 +195,6 @@ body.core-iframe-fullscreen ion-router-outlet { color: var(--gray-500); } -// Card styles -@each $color-name, $unused in $colors { - - // Message cards. - ion-card.core-#{$color-name}-card { - --color-tint: var(--ion-color-#{$color-name}-tint); - --color-shade: var(--ion-color-#{$color-name}-shade); - --border-width: 0; - - --border-color: var(--color-tint); - --border-radius: var(--mdl-shape-borderRadius-sm); - --background: var(--color-tint); - --color: var(--color-shade); - - ion-item.item { - --background: var(--color-tint); - --color: var(--color-shade); - --inner-border-width: 0px; - --border-width: 0px; - font-size: var(--text-size); - - &.item-label > ion-label, - &.item-label > ion-label > p { - --color: var(--color-shade); - } - - > ion-icon[slot] { - color: var(--color-shade); - @include margin-horizontal(null, 16px); - } - } - - ion-label { - white-space: normal !important; - } - } - - ion-item.item.core-#{$color-name}-item { - --color-base: var(--ion-color-#{$color-name}); - --color-shade: var(--ion-color-#{$color-name}-shade); - - --border-width: 0 0 3px 0; - --border-color: var(--color-base); - --inner-border-width: 0px; - - > ion-icon[slot] { - color: var(--color-base); - } - } - - .item.core-#{$color-name}-item { - --color-base: var(--ion-color-#{$color-name}); - --color-shade: var(--ion-color-#{$color-name}-shade); - - --border-width: 0 0 3px 0; - --border-color: var(--color-base); - --inner-border-width: 0px; - > ion-icon[slot] { - color: var(--color-base); - } - } - - .core-iframe-fullscreen ion-card.core-#{$color-name}-card, - .core-iframe-fullscreen .item.core-#{$color-name}-item { - opacity: 0 !important; - height: 0 !important; - } - - ion-icon.ion-color-#{$color-name} { - --ion-color-base: var(--ion-color-#{$color-name}); - color: var(--ion-color-base); - } -} - -// Avatar -// ------------------------- -// Large centered avatar -img.large-avatar, -.large-avatar img { - display: block; - margin: 8px auto; - width: var(--core-large-avatar-size); - height: var(--core-large-avatar-size); - max-width: var(--core-large-avatar-size); - max-height: var(--core-large-avatar-size); - border-radius: 50%; - background-color: transparent; -} - -ion-avatar.large-avatar { - width: var(--core-large-avatar-size); - height: var(--core-large-avatar-size); -} - -ion-avatar ion-img, ion-avatar img { - text-indent: -99999px; - background-color: var(--gray-200); -} - // Wait to load before showing the image. img[core-external-content]:not([src]) { visibility: hidden; @@ -398,27 +232,12 @@ ion-content.limited-width > :not([slot]) { min-height: 100%; } -ion-badge { - line-height: 1.1; - padding: 2px 8px; - border-radius: var(--mdl-shape-borderRadius-lg); -} - .core-anchor, core-format-text a { color: var(--core-link-color); cursor: pointer; text-decoration: underline; } -core-block ion-item-divider .core-button-spinner { - display: flex; - align-items: center; - @include margin-horizontal(10px); - - ion-badge.core-course-download-courses-progress { - @include margin(null, 12px, null, null); - } -} // Horizontal scrolling elements .core-horizontal-scroll { @@ -443,10 +262,6 @@ mark, .matchtext { font-family: var(--mdl-typography-monospace-font); } -.core-iframe-offline-disabled { - display: none !important; -} - .core-scanning-qr { .ion-page, ion-modal::part(content) { background-color: transparent !important; @@ -538,14 +353,6 @@ ion-content.disable-scroll-y::part(scroll) { will-change: auto; } -iframe { - flex-grow: 1; - border: 0; - display: block; - max-width: 100%; - background-color: var(--ion-background-color); -} - @if ($core-login-hide-need-help) { .core-login-need-help { display: none !important; @@ -556,17 +363,11 @@ ion-grid.core-no-grid > ion-row { display: block; } -.core-underheader { - position: absolute; - top: 0; - left: 0; - right: 0; -} - .core-footer-shadow [collapsible-footer] { box-shadow: var(--drop-shadow-top, none); clip-path: inset(-8px 0px 0px 0px); // Only show shadow at top. } + [collapsible-footer] { transition: box-shadow 0.5s; width: 100%; @@ -611,11 +412,6 @@ ion-grid.core-no-grid > ion-row { } } -.core-iframe-fullscreen [collapsible-footer] { - opacity: 0 !important; - height: 0 !important; -} - @include media-breakpoint-up(md) { .adaptable-buttons-row, .adaptable-buttons-row-reverse { @@ -701,85 +497,3 @@ video::-webkit-media-text-track-display { overflow-x: auto; display: block; } - -// Table App styles -table.core-table { - border-collapse: collapse; - line-height: 20px; - width: 98%; - margin: 1em auto; - color: var(--text-color); - - thead th { - vertical-align: bottom; - font-weight: bold; - font-size: var(--mdl-typography-body-fontSize-md); - background-color: var(--core-table-header-background); - } - - tbody { - th { - font-weight: normal; - } - td { - font-size: var(--mdl-typography-body-fontSize-lg); - } - } - - th, td { - padding: 8px; - white-space: normal; - text-align: start; - } - - tr { - border-bottom: 1px solid var(--core-table-border-color); - } - - .odd { - --cell-background: var(--core-table-odd-cell-background); - --cell-hover: var(--core-table-odd-cell-hover); - } - - .even { - --cell-background: var(--core-table-even-cell-background); - --cell-hover: var(--core-table-even-cell-hover); - } - - .odd, .even { - td, th, th[aria-current="page"] { - background-color: var(--cell-background); - - &:hover { - background-color: var(--cell-hover); - } - } - } - - tbody.auto-striped { - tr:nth-child(odd) { - background-color: var(--core-table-odd-cell-background); - - &:hover { - background-color: var(--core-table-even-odd-hover); - } - } - - tr:nth-child(even) { - background-color: var(--core-table-even-cell-background); - - &:hover { - background-color: var(--core-table-even-cell-hover); - } - } - } - - .ion-no-border { - border: 0 !important; - } - - .dimmed_text, - .hidden { - opacity: .7; - } -} diff --git a/src/theme/theme.light.scss b/src/theme/theme.light.scss index 4a0a03940..74bb7b704 100644 --- a/src/theme/theme.light.scss +++ b/src/theme/theme.light.scss @@ -93,7 +93,7 @@ html { --core-header-toolbar-background: var(--white); --core-header-toolbar-border-color: var(--stroke); --core-header-toolbar-color: var(--text-color); - --core-header-buttons-background: var(--core-header-toolbar-background); + --core-header-buttons-background: transparent; --core-header-buttons-color: var(--core-header-toolbar-color); --ion-searchbar-background: var(--ion-background-color); diff --git a/src/theme/theme.scss b/src/theme/theme.scss index c0b1d291f..4596a0cf2 100644 --- a/src/theme/theme.scss +++ b/src/theme/theme.scss @@ -22,8 +22,10 @@ @import "components/collapsible-item.scss"; @import "components/error-accordion.scss"; @import "components/format-text.scss"; +@import "components/iframe.scss"; @import "components/mod-label.scss"; @import "components/rubrics.scss"; +@import "components/table.scss"; @import "components/videojs.scss"; /* Ionic components overrides */ @@ -31,7 +33,9 @@ html { @import "components/ion-accordion.scss"; @import "components/ion-action-sheet.scss"; @import "components/ion-alert.scss"; + @import "components/ion-avatar.scss"; @import "components/ion-back-button.scss"; + @import "components/ion-badge.scss"; @import "components/ion-button.scss"; @import "components/ion-card.scss"; @import "components/ion-checkbox.scss";