feat!: add design tokens support (#1737)

BREAKING CHANGE: Pre-design-tokens theming is no longer supported.

Co-authored-by: Diana Olarte <diana.olarte@edunext.co>
This commit is contained in:
Brian Smith
2025-06-18 12:07:01 -04:00
committed by GitHub
parent 462e75f6a6
commit ddbc2124ef
24 changed files with 1315 additions and 164 deletions

View File

@@ -22,7 +22,6 @@
justify-content: center;
button {
@extend .btn-primary;
font-size: 1.2rem;
width: 50%;
}

View File

@@ -149,7 +149,7 @@ const Calculator = () => {
/>
</li>
</ul>
<table className="table small">
<table className="pgn__data-table small">
<thead>
<tr>
<th scope="col">

View File

@@ -4,4 +4,19 @@
background-color: #f1f1f1;
box-shadow: 0 -1px 0 0 #ddd;
}
table {
tr {
border-bottom: var(--pgn-size-border-width) solid var(--pgn-color-border);
}
thead tr {
border-bottom: calc(2 * var(--pgn-size-border-width)) solid var(--pgn-color-border);
border-top: var(--pgn-size-border-width) solid var(--pgn-color-border);
}
tbody tr {
vertical-align: top;
}
}
}

View File

@@ -8,8 +8,8 @@
display: inline-block;
position: relative;
z-index: 2;
background-color: #f1f1f1;
border: solid 1px #ddd;
background-color: #f1f1f1 !important;
border: solid 1px #ddd !important;
border-bottom: none;
border-top-left-radius: .3rem;
border-top-right-radius: .3rem;

View File

@@ -3,7 +3,7 @@ import React from 'react';
import { ErrorPage } from '@edx/frontend-platform/react';
import { StrictDict } from '@edx/react-unit-test-utils';
import { ModalDialog, Modal } from '@openedx/paragon';
import { ModalDialog } from '@openedx/paragon';
import { ContentIFrameLoaderSlot } from '../../../../plugin-slots/ContentIFrameLoaderSlot';
import * as hooks from './hooks';
@@ -65,21 +65,6 @@ const ContentIFrame = ({
onLoad: handleIFrameLoad,
};
let modalContent;
if (modalOptions.isOpen) {
modalContent = modalOptions.body
? <div className="unit-modal">{ modalOptions.body }</div>
: (
<iframe
title={modalOptions.title}
allow={IFRAME_FEATURE_POLICY}
frameBorder="0"
src={modalOptions.url}
style={{ width: '100%', height: modalOptions.height }}
/>
);
}
return (
<>
{(shouldShowContent && !hasLoaded) && (
@@ -90,29 +75,30 @@ const ContentIFrame = ({
<iframe title={title} {...contentIFrameProps} data-testid={testIDs.contentIFrame} />
</div>
)}
{modalOptions.isOpen && (modalOptions.isFullscreen
? (
{modalOptions.isOpen
&& (
<ModalDialog
dialogClassName="modal-lti"
onClose={handleModalClose}
size="fullscreen"
size={modalOptions.isFullscreen ? 'fullscreen' : 'md'}
isOpen
hasCloseButton={false}
>
<ModalDialog.Body className={modalOptions.modalBodyClassName}>
{modalContent}
{modalOptions.body
? <div className="unit-modal">{ modalOptions.body }</div>
: (
<iframe
title={modalOptions.title}
allow={IFRAME_FEATURE_POLICY}
frameBorder="0"
src={modalOptions.url}
style={{ width: '100%', height: modalOptions.height }}
/>
)}
</ModalDialog.Body>
</ModalDialog>
) : (
<Modal
body={modalContent}
dialogClassName="modal-lti"
onClose={handleModalClose}
open
/>
)
)}
)}
</>
);
};

View File

@@ -1,7 +1,7 @@
import React from 'react';
import { ErrorPage } from '@edx/frontend-platform/react';
import { ModalDialog, Modal } from '@openedx/paragon';
import { ModalDialog } from '@openedx/paragon';
import { shallow } from '@edx/react-unit-test-utils';
import PageLoading from '@src/generic/PageLoading';
@@ -14,7 +14,6 @@ jest.mock('@edx/frontend-platform/react', () => ({ ErrorPage: 'ErrorPage' }));
jest.mock('@openedx/paragon', () => jest.requireActual('@edx/react-unit-test-utils')
.mockComponents({
Modal: 'Modal',
ModalDialog: {
Body: 'ModalDialog.Body',
},
@@ -139,7 +138,7 @@ describe('ContentIFrame Component', () => {
});
it('does not display modal if modalOptions returns isOpen: false', () => {
el = shallow(<ContentIFrame {...props} />);
expect(el.instance.findByType(Modal).length).toEqual(0);
expect(el.instance.findByType(ModalDialog).length).toEqual(0);
});
describe('if modalOptions.isOpen', () => {
const testModalOpenAndHandleClose = () => {
@@ -194,10 +193,11 @@ describe('ContentIFrame Component', () => {
beforeEach(() => {
hooks.useModalIFrameData.mockReturnValueOnce({ ...modalIFrameData, modalOptions: modalOptions.withBody });
el = shallow(<ContentIFrame {...props} />);
[component] = el.instance.findByType(Modal);
[component] = el.instance.findByType(ModalDialog);
});
it('displays Modal with div wrapping provided body content if modal.body is provided', () => {
expect(component.props.body).toEqual(<div className="unit-modal">{modalOptions.withBody.body}</div>);
const content = component.findByType(ModalDialog.Body)[0].children[0];
expect(content.matches(shallow(<div className="unit-modal">{modalOptions.withBody.body}</div>))).toEqual(true);
});
testModalOpenAndHandleClose();
});
@@ -205,11 +205,12 @@ describe('ContentIFrame Component', () => {
beforeEach(() => {
hooks.useModalIFrameData.mockReturnValueOnce({ ...modalIFrameData, modalOptions: modalOptions.withUrl });
el = shallow(<ContentIFrame {...props} />);
[component] = el.instance.findByType(Modal);
[component] = el.instance.findByType(ModalDialog);
});
testModalOpenAndHandleClose();
it('displays Modal with iframe to provided url if modal.body is not provided', () => {
expect(component.props.body).toEqual(
const content = component.findByType(ModalDialog.Body)[0].children[0];
expect(content.matches(shallow(
<iframe
title={modalOptions.withUrl.title}
allow={IFRAME_FEATURE_POLICY}
@@ -217,7 +218,7 @@ describe('ContentIFrame Component', () => {
src={modalOptions.withUrl.url}
style={{ width: '100%', height: modalOptions.withUrl.height }}
/>,
);
))).toEqual(true);
});
});
});

View File

@@ -4,7 +4,7 @@
}
.lock-paywall-container svg {
color: $primary-700;
color: var(--pgn-color-primary-700);
}
@media only screen and (min-width: 992px) and (max-width: 1100px) {

View File

@@ -1,5 +1,5 @@
#course-sidebar {
@media (max-width: map-get($grid-breakpoints, "lg")) {
@media (--pgn-size-breakpoint-max-width-lg) {
overflow-y: scroll;
padding: 0 .625rem !important;
}

View File

@@ -6,7 +6,7 @@
}
.outline-sidebar {
@media (min-width: map-get($grid-breakpoints, "xl")) {
@media (--pgn-size-breakpoint-min-width-xl) {
left: 0;
top: 0;
}
@@ -23,12 +23,12 @@
}
.outline-sidebar-heading {
font-weight: $font-weight-bold;
font-weight: var(--pgn-typography-font-weight-bold);
}
}
.course-sidebar-section {
background: $white;
background: var(--pgn-color-white);
border: 1px solid #d7d3d1;
button {
@@ -52,7 +52,7 @@
#outline-sidebar-outline {
margin-top: -1px;
@media (min-width: map-get($grid-breakpoints, "xl")) {
@media (--pgn-size-breakpoint-min-width-xl) {
margin-bottom: 0;
}
@@ -62,14 +62,14 @@
.collapsible-trigger {
border-radius: 0;
padding: map-get($spacers, 3\.5) map-get($spacers, 4) map-get($spacers, 3\.5) map-get($spacers, 5);
padding: var(--pgn-spacing-spacer-3-5) var(--pgn-spacing-spacer-4) var(--pgn-spacing-spacer-3-5) var(--pgn-spacing-spacer-5);
@media (max-width: map-get($grid-breakpoints, "sm")) {
padding-left: map-get($spacers, 4);
@media (--pgn-size-breakpoint-max-width-sm) {
padding-left: var(--pgn-spacing-spacer-4);
}
&:hover {
background-color: $light-500;
background-color: var(--pgn-color-light-500);
}
.collapsible-icon {
@@ -78,7 +78,7 @@
}
&:last-child .pgn_collapsible {
@extend .mb-0;
margin-bottom: 0px !important;
}
}
@@ -86,15 +86,15 @@
padding: 0;
ol li > a {
padding: map-get($spacers, 3\.5) map-get($spacers, 4) map-get($spacers, 3\.5) map-get($spacers, 5\.5);
padding: var(--pgn-spacing-spacer-3-5) var(--pgn-spacing-spacer-4) var(--pgn-spacing-spacer-3-5) var(--pgn-spacing-spacer-5-5);
@media (max-width: map-get($grid-breakpoints, "sm")) {
padding-left: map-get($spacers, 4\.5);
@media (--pgn-size-breakpoint-max-width-sm) {
padding-left: var(--pgn-spacing-spacer-4-5);
}
&:hover {
text-decoration: none;
background-color: $light-500;
background-color: var(--pgn-color-light-500);
}
}
}

View File

@@ -1,5 +1,5 @@
.discussions-sidebar-frame {
@media (max-width: map-get($grid-breakpoints, "xl")) {
@media (--pgn-size-breakpoint-max-width-xl) {
max-height: calc(100vh - 65px);
}
}