[WebApp][MM-51266]: Add compass (MUI wrapper components) in common components package (#22942)
* wrap all the components using compass-components with compass-components theme provider Co-authored-by: @michelengelen Co-authored-by: Mattermost Build <build@mattermost.com>
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
a496c14cc2
Коммит
389062193b
@@ -13,9 +13,10 @@
|
||||
"@mattermost/compass-components": "^0.2.12",
|
||||
"@mattermost/compass-icons": "0.1.34",
|
||||
"@mattermost/types": "*",
|
||||
"@mui/base": "5.0.0-alpha.116",
|
||||
"@mui/material": "5.11.7",
|
||||
"@mui/styled-engine-sc": "5.11.0",
|
||||
"@mui/base": "5.0.0-alpha.127",
|
||||
"@mui/material": "5.11.16",
|
||||
"@mui/system": "5.11.16",
|
||||
"@mui/styled-engine-sc": "5.11.11",
|
||||
"@stripe/react-stripe-js": "1.13.0",
|
||||
"@stripe/stripe-js": "1.41.0",
|
||||
"@tippyjs/react": "4.2.6",
|
||||
|
||||
@@ -7,7 +7,7 @@ import {FormattedMessage} from 'react-intl';
|
||||
|
||||
import {useDispatch, useSelector} from 'react-redux';
|
||||
|
||||
import {GenericModal} from '@mattermost/components';
|
||||
import {LegacyGenericModal} from '@mattermost/components';
|
||||
|
||||
import LaptopAlertSVG from 'components/common/svg_images_components/laptop_alert_svg';
|
||||
import {closeModal, openModal} from 'actions/views/modals';
|
||||
@@ -180,7 +180,7 @@ export default function DeleteWorkspaceModal(props: Props) {
|
||||
}
|
||||
|
||||
return (
|
||||
<GenericModal
|
||||
<LegacyGenericModal
|
||||
className='DeleteWorkspaceModal'
|
||||
onExited={handleClickCancel}
|
||||
>
|
||||
@@ -249,6 +249,6 @@ export default function DeleteWorkspaceModal(props: Props) {
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</GenericModal>
|
||||
</LegacyGenericModal>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import React from 'react';
|
||||
import {FormattedMessage} from 'react-intl';
|
||||
|
||||
import {GenericModal} from '@mattermost/components';
|
||||
import {LegacyGenericModal} from '@mattermost/components';
|
||||
import {CloudLinks} from 'utils/constants';
|
||||
import CreditCardSvg from 'components/common/svg_images_components/credit_card_svg';
|
||||
import {useControlAirGappedSelfHostedPurchaseModal} from 'components/common/hooks/useControlModal';
|
||||
@@ -15,7 +15,7 @@ export default function AirGappedSelfHostedPurhcaseModal() {
|
||||
const {close} = useControlAirGappedSelfHostedPurchaseModal();
|
||||
|
||||
return (
|
||||
<GenericModal
|
||||
<LegacyGenericModal
|
||||
onExited={close}
|
||||
show={true}
|
||||
className='air-gapped-purchase-modal'
|
||||
@@ -39,6 +39,6 @@ export default function AirGappedSelfHostedPurhcaseModal() {
|
||||
</span>
|
||||
<a href={CloudLinks.SELF_HOSTED_PRICING}>{CloudLinks.SELF_HOSTED_PRICING}</a>
|
||||
</div>
|
||||
</GenericModal>
|
||||
</LegacyGenericModal>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`components/drafts/draft_actions/delete_draft_modal should have called onConfirm 1`] = `
|
||||
<GenericModal
|
||||
<LegacyGenericModal
|
||||
autoCloseOnCancelButton={true}
|
||||
autoCloseOnConfirmButton={true}
|
||||
bodyPadding={true}
|
||||
@@ -39,11 +39,11 @@ exports[`components/drafts/draft_actions/delete_draft_modal should have called o
|
||||
}
|
||||
}
|
||||
/>
|
||||
</GenericModal>
|
||||
</LegacyGenericModal>
|
||||
`;
|
||||
|
||||
exports[`components/drafts/draft_actions/delete_draft_modal should have called onExited 1`] = `
|
||||
<GenericModal
|
||||
<LegacyGenericModal
|
||||
autoCloseOnCancelButton={true}
|
||||
autoCloseOnConfirmButton={true}
|
||||
bodyPadding={true}
|
||||
@@ -81,7 +81,7 @@ exports[`components/drafts/draft_actions/delete_draft_modal should have called o
|
||||
}
|
||||
}
|
||||
/>
|
||||
</GenericModal>
|
||||
</LegacyGenericModal>
|
||||
`;
|
||||
|
||||
exports[`components/drafts/draft_actions/delete_draft_modal should match snapshot 1`] = `
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`components/drafts/draft_actions/send_draft_modal should have called onConfirm 1`] = `
|
||||
<GenericModal
|
||||
<LegacyGenericModal
|
||||
autoCloseOnCancelButton={true}
|
||||
autoCloseOnConfirmButton={true}
|
||||
bodyPadding={true}
|
||||
@@ -38,11 +38,11 @@ exports[`components/drafts/draft_actions/send_draft_modal should have called onC
|
||||
}
|
||||
}
|
||||
/>
|
||||
</GenericModal>
|
||||
</LegacyGenericModal>
|
||||
`;
|
||||
|
||||
exports[`components/drafts/draft_actions/send_draft_modal should have called onExited 1`] = `
|
||||
<GenericModal
|
||||
<LegacyGenericModal
|
||||
autoCloseOnCancelButton={true}
|
||||
autoCloseOnConfirmButton={true}
|
||||
bodyPadding={true}
|
||||
@@ -79,7 +79,7 @@ exports[`components/drafts/draft_actions/send_draft_modal should have called onE
|
||||
}
|
||||
}
|
||||
/>
|
||||
</GenericModal>
|
||||
</LegacyGenericModal>
|
||||
`;
|
||||
|
||||
exports[`components/drafts/draft_actions/send_draft_modal should match snapshot 1`] = `
|
||||
|
||||
@@ -6,7 +6,7 @@ import React, {useState} from 'react';
|
||||
import {injectIntl, WrappedComponentProps} from 'react-intl';
|
||||
import {useDispatch} from 'react-redux';
|
||||
|
||||
import {GenericModal} from '@mattermost/components';
|
||||
import {LegacyGenericModal} from '@mattermost/components';
|
||||
import {Feedback} from '@mattermost/types/cloud';
|
||||
import {closeModal} from 'actions/views/modals';
|
||||
import RadioButtonGroup from 'components/common/radio_group';
|
||||
@@ -59,7 +59,7 @@ function FeedbackModal(props: Props) {
|
||||
};
|
||||
|
||||
return (
|
||||
<GenericModal
|
||||
<LegacyGenericModal
|
||||
compassDesign={true}
|
||||
onExited={handleCancel}
|
||||
className='FeedbackModal__Container'
|
||||
@@ -102,7 +102,7 @@ function FeedbackModal(props: Props) {
|
||||
</span>
|
||||
</>
|
||||
}
|
||||
</GenericModal>
|
||||
</LegacyGenericModal>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {GenericModal} from '@mattermost/components';
|
||||
import {LegacyGenericModal} from '@mattermost/components';
|
||||
|
||||
import {t} from 'utils/i18n';
|
||||
|
||||
@@ -15,4 +15,4 @@ t('footer_pagination.count');
|
||||
t('footer_pagination.prev');
|
||||
t('footer_pagination.next');
|
||||
|
||||
export default GenericModal;
|
||||
export default LegacyGenericModal;
|
||||
|
||||
@@ -1,96 +0,0 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`components/new_channel_modal should match snapshot 1`] = `
|
||||
<GenericModal
|
||||
autoCloseOnCancelButton={true}
|
||||
autoCloseOnConfirmButton={false}
|
||||
bodyPadding={true}
|
||||
cancelButtonText="Cancel"
|
||||
className="new-channel-modal"
|
||||
compassDesign={true}
|
||||
confirmButtonText="Create channel"
|
||||
enforceFocus={true}
|
||||
errorText=""
|
||||
handleCancel={[Function]}
|
||||
handleConfirm={[Function]}
|
||||
handleEnterKeyPress={[Function]}
|
||||
id="new-channel-modal"
|
||||
isConfirmDisabled={true}
|
||||
keyboardEscape={true}
|
||||
modalHeaderText="Create a new channel"
|
||||
onExited={[Function]}
|
||||
show={true}
|
||||
>
|
||||
<div
|
||||
className="new-channel-modal-body"
|
||||
>
|
||||
<ForwardRef
|
||||
autoComplete="off"
|
||||
autoFocus={true}
|
||||
containerClassName="new-channel-modal-name-container"
|
||||
customMessage={null}
|
||||
inputClassName="new-channel-modal-name-input"
|
||||
label="Channel name"
|
||||
limit={64}
|
||||
name="new-channel-modal-name"
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
placeholder="Enter a name for your new channel"
|
||||
required={true}
|
||||
type="text"
|
||||
value=""
|
||||
/>
|
||||
<UrlInput
|
||||
base="http://localhost:8065"
|
||||
className="new-channel-modal__url"
|
||||
error=""
|
||||
limit={64}
|
||||
onChange={[Function]}
|
||||
path="current-team/channels"
|
||||
pathInfo=""
|
||||
shortenLength={52}
|
||||
/>
|
||||
<PublicPrivateSelector
|
||||
className="new-channel-modal-type-selector"
|
||||
onChange={[Function]}
|
||||
privateButtonProps={
|
||||
Object {
|
||||
"description": "Only invited members",
|
||||
"disabled": false,
|
||||
"title": "Private Channel",
|
||||
}
|
||||
}
|
||||
publicButtonProps={
|
||||
Object {
|
||||
"description": "Anyone can join",
|
||||
"disabled": false,
|
||||
"title": "Public Channel",
|
||||
}
|
||||
}
|
||||
selected="O"
|
||||
/>
|
||||
<div
|
||||
className="new-channel-modal-purpose-container"
|
||||
>
|
||||
<textarea
|
||||
autoComplete="off"
|
||||
className="new-channel-modal-purpose-textarea"
|
||||
id="new-channel-modal-purpose"
|
||||
maxLength={250}
|
||||
onChange={[Function]}
|
||||
onKeyDown={[Function]}
|
||||
placeholder="Enter a purpose for this channel (optional)"
|
||||
rows={4}
|
||||
value=""
|
||||
/>
|
||||
<div
|
||||
className="new-channel-modal-purpose-info"
|
||||
>
|
||||
<span>
|
||||
This will be displayed when browsing for channels.
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</GenericModal>
|
||||
`;
|
||||
@@ -3,26 +3,19 @@
|
||||
|
||||
import React from 'react';
|
||||
import {act} from 'react-dom/test-utils';
|
||||
import {shallow} from 'enzyme';
|
||||
|
||||
import {mountWithIntl} from 'tests/helpers/intl-test-helper';
|
||||
|
||||
import GenericModal from 'components/generic_modal';
|
||||
import Input from 'components/widgets/inputs/input/input';
|
||||
import URLInput from 'components/widgets/inputs/url_input/url_input';
|
||||
import PublicPrivateSelector from 'components/widgets/public-private-selector/public-private-selector';
|
||||
|
||||
import Constants, {suitePluginIds} from 'utils/constants';
|
||||
import {suitePluginIds} from 'utils/constants';
|
||||
import {cleanUpUrlable} from 'utils/url';
|
||||
import {GlobalState} from 'types/store';
|
||||
import Permissions from 'mattermost-redux/constants/permissions';
|
||||
import {createChannel} from 'mattermost-redux/actions/channels';
|
||||
|
||||
import {ChannelType} from '@mattermost/types/channels';
|
||||
|
||||
jest.mock('mattermost-redux/actions/channels');
|
||||
|
||||
import NewChannelModal from './new_channel_modal';
|
||||
import {render, screen, waitFor} from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import {renderWithIntl} from 'tests/react_testing_utils';
|
||||
|
||||
const mockDispatch = jest.fn();
|
||||
let mockState: GlobalState;
|
||||
@@ -113,313 +106,324 @@ describe('components/new_channel_modal', () => {
|
||||
} as unknown as GlobalState;
|
||||
});
|
||||
|
||||
test('should match snapshot', () => {
|
||||
expect(
|
||||
shallow(
|
||||
<NewChannelModal/>,
|
||||
),
|
||||
).toMatchSnapshot();
|
||||
test('should match component state with given props', () => {
|
||||
render(<NewChannelModal/>);
|
||||
|
||||
const heading = screen.getByRole('heading');
|
||||
expect(heading).toBeInTheDocument();
|
||||
expect(heading).toHaveAttribute('id', 'genericModalLabel');
|
||||
expect(heading.parentElement).toHaveClass('GenericModal__header');
|
||||
expect(heading).toHaveTextContent('Create a new channel');
|
||||
|
||||
const channelNameHeading = screen.getByText('Channel name');
|
||||
expect(channelNameHeading).toBeInTheDocument();
|
||||
expect(channelNameHeading).toHaveClass('Input_legend Input_legend___focus');
|
||||
|
||||
const channelNameInput = screen.getByPlaceholderText('Enter a name for your new channel');
|
||||
expect(channelNameInput).toBeInTheDocument();
|
||||
expect(channelNameInput).toHaveAttribute('value', '');
|
||||
expect(channelNameInput).toHaveAttribute('type', 'text');
|
||||
expect(channelNameInput).toHaveAttribute('name', 'new-channel-modal-name');
|
||||
expect(channelNameInput).toHaveAttribute('id', 'input_new-channel-modal-name');
|
||||
expect(channelNameInput).toHaveClass('Input form-control medium new-channel-modal-name-input Input__focus');
|
||||
|
||||
const editUrl = screen.getByText('Edit');
|
||||
expect(editUrl).toBeInTheDocument();
|
||||
expect(editUrl).toHaveClass('url-input-button-label');
|
||||
expect(editUrl.parentElement).toHaveClass('url-input-button');
|
||||
|
||||
const publicChannelSvg = screen.getByLabelText('Globe Circle Solid Icon');
|
||||
expect(publicChannelSvg).toBeInTheDocument();
|
||||
|
||||
const publicChannelHeading = screen.getByText('Public Channel');
|
||||
expect(publicChannelHeading).toBeInTheDocument();
|
||||
expect(publicChannelHeading.nextSibling).toHaveTextContent('Anyone can join');
|
||||
|
||||
const privateChannelSvg = screen.getByLabelText('Lock Circle Solid Icon');
|
||||
expect(privateChannelSvg).toBeInTheDocument();
|
||||
|
||||
const privateChannelHeading = screen.getByText('Private Channel');
|
||||
expect(privateChannelHeading).toBeInTheDocument();
|
||||
expect(privateChannelHeading.nextSibling).toHaveTextContent('Only invited members');
|
||||
|
||||
const purposeTextArea = screen.getByPlaceholderText('Enter a purpose for this channel (optional)');
|
||||
expect(purposeTextArea).toBeInTheDocument();
|
||||
expect(purposeTextArea).toHaveClass('new-channel-modal-purpose-textarea');
|
||||
|
||||
const purposeDesc = screen.getByText('This will be displayed when browsing for channels.');
|
||||
expect(purposeDesc).toBeInTheDocument();
|
||||
|
||||
const cancelButton = screen.getByText('Cancel');
|
||||
expect(cancelButton).toBeInTheDocument();
|
||||
expect(cancelButton).toHaveClass('GenericModal__button cancel');
|
||||
|
||||
const createChannelButton = screen.getByText('Create channel');
|
||||
expect(createChannelButton).toBeInTheDocument();
|
||||
expect(createChannelButton).toHaveClass('GenericModal__button confirm');
|
||||
expect(createChannelButton).toBeDisabled();
|
||||
});
|
||||
|
||||
test('should handle display name change', () => {
|
||||
const value = 'Channel name';
|
||||
const mockChangeEvent = {
|
||||
preventDefault: jest.fn(),
|
||||
target: {
|
||||
value,
|
||||
},
|
||||
} as unknown as React.ChangeEvent<HTMLInputElement>;
|
||||
|
||||
const wrapper = shallow(
|
||||
render(
|
||||
<NewChannelModal/>,
|
||||
);
|
||||
|
||||
// Change display name
|
||||
let input = wrapper.find(Input).first();
|
||||
input.props().onChange!(mockChangeEvent);
|
||||
const channelNameInput = screen.getByPlaceholderText('Enter a name for your new channel');
|
||||
expect(channelNameInput).toBeInTheDocument();
|
||||
expect(channelNameInput).toHaveAttribute('value', '');
|
||||
|
||||
userEvent.type(channelNameInput, value);
|
||||
|
||||
// Display name should have been updated
|
||||
input = wrapper.find(Input).first();
|
||||
expect(input.props().value).toEqual(value);
|
||||
expect(channelNameInput).toHaveAttribute('value', value);
|
||||
|
||||
// URL should have been changed according to display name
|
||||
const urlInput = wrapper.find(URLInput);
|
||||
expect(urlInput.props().pathInfo).toEqual(cleanUpUrlable(value));
|
||||
const urlInputLabel = screen.getByTestId('urlInputLabel');
|
||||
expect(urlInputLabel).toHaveTextContent(cleanUpUrlable(value));
|
||||
});
|
||||
|
||||
test('should handle url change', () => {
|
||||
test('should handle url change', async () => {
|
||||
const value = 'Channel name';
|
||||
const mockInputChangeEvent = {
|
||||
preventDefault: jest.fn(),
|
||||
target: {
|
||||
value,
|
||||
},
|
||||
} as unknown as React.ChangeEvent<HTMLInputElement>;
|
||||
const mockInputChangeUpdatedEvent = {
|
||||
preventDefault: jest.fn(),
|
||||
target: {
|
||||
value: `${value} updated`,
|
||||
},
|
||||
} as unknown as React.ChangeEvent<HTMLInputElement>;
|
||||
|
||||
const url = 'channel-name-new';
|
||||
const mockURLInputChangeEvent = {
|
||||
preventDefault: jest.fn(),
|
||||
target: {
|
||||
value: url,
|
||||
},
|
||||
} as unknown as React.ChangeEvent<HTMLInputElement>;
|
||||
|
||||
const wrapper = shallow(
|
||||
render(
|
||||
<NewChannelModal/>,
|
||||
);
|
||||
|
||||
// Change display name
|
||||
let input = wrapper.find(Input).first();
|
||||
input.props().onChange!(mockInputChangeEvent);
|
||||
const channelNameInput = screen.getByPlaceholderText('Enter a name for your new channel');
|
||||
expect(channelNameInput).toBeInTheDocument();
|
||||
expect(channelNameInput).toHaveAttribute('value', '');
|
||||
|
||||
// URL should have been changed according to display name
|
||||
let urlInput = wrapper.find(URLInput);
|
||||
expect(urlInput.props().pathInfo).toEqual(cleanUpUrlable(value));
|
||||
userEvent.type(channelNameInput, value);
|
||||
const urlInputLabel = screen.getByTestId('urlInputLabel');
|
||||
expect(urlInputLabel).toHaveTextContent(cleanUpUrlable(value));
|
||||
|
||||
// Change URL
|
||||
urlInput.props().onChange!(mockURLInputChangeEvent);
|
||||
const editUrl = screen.getByText('Edit');
|
||||
expect(editUrl).toBeInTheDocument();
|
||||
|
||||
userEvent.click(editUrl);
|
||||
|
||||
const editUrlInput = screen.getByTestId('channelURLInput');
|
||||
userEvent.clear(editUrlInput);
|
||||
userEvent.type(editUrlInput, url);
|
||||
|
||||
const doneButton = screen.getByText('Done');
|
||||
await waitFor(() =>
|
||||
userEvent.click(doneButton),
|
||||
);
|
||||
|
||||
// URL should have been updated
|
||||
urlInput = wrapper.find(URLInput);
|
||||
expect(urlInput.props().pathInfo).toEqual(url);
|
||||
expect(screen.getByText(url, {exact: false})).toBeInTheDocument();
|
||||
|
||||
// Change display name again
|
||||
input = wrapper.find(Input).first();
|
||||
input.props().onChange!(mockInputChangeUpdatedEvent);
|
||||
userEvent.type(channelNameInput, `${value} updated`);
|
||||
|
||||
// URL should NOT be updated
|
||||
urlInput = wrapper.find(URLInput);
|
||||
expect(urlInput.props().pathInfo).toEqual(url);
|
||||
expect(screen.getByText(url, {exact: false})).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('should handle type changes', () => {
|
||||
const typePublic = Constants.OPEN_CHANNEL as ChannelType;
|
||||
const typePrivate = Constants.PRIVATE_CHANNEL as ChannelType;
|
||||
|
||||
const wrapper = shallow(
|
||||
render(
|
||||
<NewChannelModal/>,
|
||||
);
|
||||
|
||||
// Change type to private
|
||||
let selector = wrapper.find(PublicPrivateSelector);
|
||||
selector.props().onChange!(typePrivate);
|
||||
const privateChannel = screen.getByText('Private Channel');
|
||||
expect(privateChannel).toBeInTheDocument();
|
||||
|
||||
userEvent.click(privateChannel);
|
||||
|
||||
// Type should have been updated to private
|
||||
selector = wrapper.find(PublicPrivateSelector);
|
||||
expect(selector.props().selected).toEqual(typePrivate);
|
||||
expect(privateChannel.parentElement?.nextSibling?.firstChild).toHaveAttribute('aria-label', 'Check Circle Icon');
|
||||
|
||||
// Change type to private
|
||||
selector = wrapper.find(PublicPrivateSelector);
|
||||
selector.props().onChange!(typePublic);
|
||||
// Change type to public
|
||||
const publicChannel = screen.getByText('Public Channel');
|
||||
expect(publicChannel).toBeInTheDocument();
|
||||
|
||||
userEvent.click(publicChannel);
|
||||
|
||||
// Type should have been updated to public
|
||||
selector = wrapper.find(PublicPrivateSelector);
|
||||
expect(selector.props().selected).toEqual(typePublic);
|
||||
expect(publicChannel.parentElement?.nextSibling?.firstChild).toHaveAttribute('aria-label', 'Check Circle Icon');
|
||||
});
|
||||
|
||||
test('should handle purpose changes', () => {
|
||||
const value = 'Purpose';
|
||||
const mockChangeEvent = {
|
||||
preventDefault: jest.fn(),
|
||||
target: {
|
||||
value,
|
||||
},
|
||||
} as unknown as React.ChangeEvent<HTMLTextAreaElement>;
|
||||
|
||||
const wrapper = shallow(
|
||||
render(
|
||||
<NewChannelModal/>,
|
||||
);
|
||||
|
||||
// Change purpose
|
||||
let textarea = wrapper.find('textarea');
|
||||
textarea.props().onChange!(mockChangeEvent);
|
||||
const ChannelPurposeTextArea = screen.getByPlaceholderText('Enter a purpose for this channel (optional)');
|
||||
expect(ChannelPurposeTextArea).toBeInTheDocument();
|
||||
|
||||
userEvent.click(ChannelPurposeTextArea);
|
||||
userEvent.type(ChannelPurposeTextArea, value);
|
||||
|
||||
// Purpose should have been updated
|
||||
textarea = wrapper.find('textarea');
|
||||
expect(textarea.props().value).toEqual(value);
|
||||
expect(ChannelPurposeTextArea).toHaveValue(value);
|
||||
});
|
||||
|
||||
test('should enable confirm button when having valid display name, url and type', () => {
|
||||
const mockChangeEvent = {
|
||||
preventDefault: jest.fn(),
|
||||
target: {
|
||||
value: 'Channel name',
|
||||
},
|
||||
} as unknown as React.ChangeEvent<HTMLInputElement>;
|
||||
|
||||
const wrapper = shallow(
|
||||
render(
|
||||
<NewChannelModal/>,
|
||||
);
|
||||
|
||||
// Confirm button should be disabled
|
||||
let genericModal = wrapper.find(GenericModal);
|
||||
expect(genericModal.props().isConfirmDisabled).toEqual(true);
|
||||
const createChannelButton = screen.getByText('Create channel');
|
||||
expect(createChannelButton).toBeInTheDocument();
|
||||
expect(createChannelButton).toBeDisabled();
|
||||
|
||||
// Change display name
|
||||
const input = wrapper.find(Input).first();
|
||||
input.props().onChange!(mockChangeEvent);
|
||||
const channelNameInput = screen.getByPlaceholderText('Enter a name for your new channel');
|
||||
expect(channelNameInput).toBeInTheDocument();
|
||||
expect(channelNameInput).toHaveAttribute('value', '');
|
||||
|
||||
userEvent.type(channelNameInput, 'Channel name');
|
||||
|
||||
// Change type to private
|
||||
const selector = wrapper.find(PublicPrivateSelector);
|
||||
selector.props().onChange!(Constants.PRIVATE_CHANNEL as ChannelType);
|
||||
const privateChannel = screen.getByText('Private Channel');
|
||||
expect(privateChannel).toBeInTheDocument();
|
||||
|
||||
userEvent.click(privateChannel);
|
||||
|
||||
// Confirm button should be enabled
|
||||
genericModal = wrapper.find(GenericModal);
|
||||
expect(genericModal.props().isConfirmDisabled).toEqual(false);
|
||||
expect(createChannelButton).toBeEnabled();
|
||||
});
|
||||
|
||||
test('should disable confirm button when display name in error', () => {
|
||||
const mockChangeEvent = {
|
||||
preventDefault: jest.fn(),
|
||||
target: {
|
||||
value: 'Channel name',
|
||||
},
|
||||
} as unknown as React.ChangeEvent<HTMLInputElement>;
|
||||
const mockChangeInvalidEvent = {
|
||||
preventDefault: jest.fn(),
|
||||
target: {
|
||||
value: '',
|
||||
},
|
||||
} as unknown as React.ChangeEvent<HTMLInputElement>;
|
||||
|
||||
const wrapper = shallow(
|
||||
render(
|
||||
<NewChannelModal/>,
|
||||
);
|
||||
|
||||
// Change display name
|
||||
let input = wrapper.find(Input).first();
|
||||
input.props().onChange!(mockChangeEvent);
|
||||
const channelNameInput = screen.getByPlaceholderText('Enter a name for your new channel');
|
||||
expect(channelNameInput).toBeInTheDocument();
|
||||
expect(channelNameInput).toHaveAttribute('value', '');
|
||||
|
||||
userEvent.type(channelNameInput, 'Channel name');
|
||||
|
||||
// Change type to private
|
||||
const selector = wrapper.find(PublicPrivateSelector);
|
||||
selector.props().onChange!(Constants.PRIVATE_CHANNEL as ChannelType);
|
||||
const privateChannel = screen.getByText('Private Channel');
|
||||
expect(privateChannel).toBeInTheDocument();
|
||||
|
||||
userEvent.click(privateChannel);
|
||||
|
||||
// Confirm button should be enabled
|
||||
let genericModal = wrapper.find(GenericModal);
|
||||
expect(genericModal.props().isConfirmDisabled).toEqual(false);
|
||||
const createChannelButton = screen.getByText('Create channel');
|
||||
expect(createChannelButton).toBeEnabled();
|
||||
|
||||
// Change display name to invalid
|
||||
input = wrapper.find(Input).first();
|
||||
input.props().onChange!(mockChangeInvalidEvent);
|
||||
userEvent.clear(channelNameInput);
|
||||
userEvent.type(channelNameInput, '');
|
||||
|
||||
// Confirm button should be disabled
|
||||
genericModal = wrapper.find(GenericModal);
|
||||
expect(genericModal.props().isConfirmDisabled).toEqual(true);
|
||||
expect(createChannelButton).toBeDisabled();
|
||||
});
|
||||
|
||||
test('should disable confirm button when url in error', () => {
|
||||
const mockChangeEvent = {
|
||||
preventDefault: jest.fn(),
|
||||
target: {
|
||||
value: 'Channel name',
|
||||
},
|
||||
} as unknown as React.ChangeEvent<HTMLInputElement>;
|
||||
const mockChangeURLInvalidEvent = {
|
||||
preventDefault: jest.fn(),
|
||||
target: {
|
||||
value: 'c-',
|
||||
},
|
||||
} as unknown as React.ChangeEvent<HTMLInputElement>;
|
||||
|
||||
const wrapper = shallow(
|
||||
render(
|
||||
<NewChannelModal/>,
|
||||
);
|
||||
|
||||
// Change display name
|
||||
const input = wrapper.find(Input).first();
|
||||
input.props().onChange!(mockChangeEvent);
|
||||
const channelNameInput = screen.getByPlaceholderText('Enter a name for your new channel');
|
||||
expect(channelNameInput).toBeInTheDocument();
|
||||
expect(channelNameInput).toHaveAttribute('value', '');
|
||||
|
||||
userEvent.type(channelNameInput, 'Channel name');
|
||||
|
||||
// Change type to private
|
||||
const selector = wrapper.find(PublicPrivateSelector);
|
||||
selector.props().onChange!(Constants.PRIVATE_CHANNEL as ChannelType);
|
||||
const privateChannel = screen.getByText('Private Channel');
|
||||
expect(privateChannel).toBeInTheDocument();
|
||||
|
||||
userEvent.click(privateChannel);
|
||||
|
||||
// Confirm button should be enabled
|
||||
let genericModal = wrapper.find(GenericModal);
|
||||
expect(genericModal.props().isConfirmDisabled).toEqual(false);
|
||||
const createChannelButton = screen.getByText('Create channel');
|
||||
expect(createChannelButton).toBeEnabled();
|
||||
|
||||
// Change url to invalid
|
||||
const urlInput = wrapper.find(URLInput);
|
||||
urlInput.props().onChange!(mockChangeURLInvalidEvent);
|
||||
const editUrl = screen.getByText('Edit');
|
||||
expect(editUrl).toBeInTheDocument();
|
||||
|
||||
userEvent.click(editUrl);
|
||||
|
||||
const editUrlInput = screen.getByTestId('channelURLInput');
|
||||
userEvent.clear(editUrlInput);
|
||||
userEvent.type(editUrlInput, 'c-');
|
||||
|
||||
// Confirm button should be disabled
|
||||
genericModal = wrapper.find(GenericModal);
|
||||
expect(genericModal.props().isConfirmDisabled).toEqual(true);
|
||||
expect(createChannelButton).toBeDisabled();
|
||||
});
|
||||
|
||||
test('should disable confirm button when server error', async () => {
|
||||
const mockChangeEvent = {
|
||||
preventDefault: jest.fn(),
|
||||
target: {
|
||||
value: 'Channel name',
|
||||
},
|
||||
} as unknown as React.ChangeEvent<HTMLInputElement>;
|
||||
|
||||
const wrapper = shallow(
|
||||
render(
|
||||
<NewChannelModal/>,
|
||||
);
|
||||
|
||||
// Confirm button should be disabled
|
||||
let genericModal = wrapper.find(GenericModal);
|
||||
expect(genericModal.props().isConfirmDisabled).toEqual(true);
|
||||
const createChannelButton = screen.getByText('Create channel');
|
||||
expect(createChannelButton).toBeDisabled();
|
||||
|
||||
// Change display name
|
||||
const input = wrapper.find(Input).first();
|
||||
input.props().onChange!(mockChangeEvent);
|
||||
const channelNameInput = screen.getByPlaceholderText('Enter a name for your new channel');
|
||||
expect(channelNameInput).toBeInTheDocument();
|
||||
expect(channelNameInput).toHaveAttribute('value', '');
|
||||
|
||||
userEvent.type(channelNameInput, 'Channel name');
|
||||
|
||||
// Change type to private
|
||||
const selector = wrapper.find(PublicPrivateSelector);
|
||||
selector.props().onChange!(Constants.PRIVATE_CHANNEL as ChannelType);
|
||||
const privateChannel = screen.getByText('Private Channel');
|
||||
expect(privateChannel).toBeInTheDocument();
|
||||
|
||||
userEvent.click(privateChannel);
|
||||
|
||||
// Confirm button should be enabled
|
||||
genericModal = wrapper.find(GenericModal);
|
||||
expect(genericModal.props().isConfirmDisabled).toEqual(false);
|
||||
expect(createChannelButton).toBeEnabled();
|
||||
|
||||
// Submit
|
||||
await genericModal.props().handleConfirm!();
|
||||
await act(async () => userEvent.click(createChannelButton));
|
||||
|
||||
genericModal = wrapper.find(GenericModal);
|
||||
expect(genericModal.props().errorText).toEqual('Something went wrong. Please try again.');
|
||||
expect(genericModal.props().isConfirmDisabled).toEqual(true);
|
||||
const serverError = screen.getByText('Something went wrong. Please try again.');
|
||||
expect(serverError).toBeInTheDocument();
|
||||
expect(createChannelButton).toBeDisabled();
|
||||
});
|
||||
|
||||
test('should request team creation on submit', async () => {
|
||||
const name = 'Channel name';
|
||||
const mockChangeEvent = {
|
||||
preventDefault: jest.fn(),
|
||||
target: {
|
||||
value: name,
|
||||
},
|
||||
} as unknown as React.ChangeEvent<HTMLInputElement>;
|
||||
|
||||
const wrapper = mountWithIntl(
|
||||
renderWithIntl(
|
||||
<NewChannelModal/>,
|
||||
);
|
||||
|
||||
const genericModal = wrapper.find('GenericModal');
|
||||
const displayName = genericModal.find('.new-channel-modal-name-input');
|
||||
const confirmButton = genericModal.find('button[type=\'submit\']');
|
||||
|
||||
// Confirm button should be disabled
|
||||
expect((confirmButton.instance() as unknown as HTMLButtonElement).disabled).toEqual(true);
|
||||
const createChannelButton = screen.getByText('Create channel');
|
||||
expect(createChannelButton).toBeDisabled();
|
||||
|
||||
// Enter data
|
||||
displayName.simulate('change', mockChangeEvent);
|
||||
|
||||
const channelNameInput = screen.getByPlaceholderText('Enter a name for your new channel');
|
||||
expect(channelNameInput).toBeInTheDocument();
|
||||
expect(channelNameInput).toHaveAttribute('value', '');
|
||||
|
||||
userEvent.type(channelNameInput, name);
|
||||
|
||||
// Display name should be updated
|
||||
expect((displayName.instance() as unknown as HTMLInputElement).value).toEqual(name);
|
||||
expect(channelNameInput).toHaveValue(name);
|
||||
|
||||
// Confirm button should be enabled
|
||||
expect((confirmButton.instance() as unknown as HTMLButtonElement).disabled).toEqual(false);
|
||||
expect(createChannelButton).toBeEnabled();
|
||||
|
||||
// Submit
|
||||
await act(async () => {
|
||||
confirmButton.simulate('click');
|
||||
userEvent.click(createChannelButton);
|
||||
});
|
||||
|
||||
// Request should be sent
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`ProductNoticesModal Match snapshot for single notice 1`] = `
|
||||
<GenericModal
|
||||
<LegacyGenericModal
|
||||
autoCloseOnCancelButton={false}
|
||||
autoCloseOnConfirmButton={true}
|
||||
bodyPadding={true}
|
||||
@@ -38,11 +38,11 @@ exports[`ProductNoticesModal Match snapshot for single notice 1`] = `
|
||||
<div
|
||||
className="productNotices__info"
|
||||
/>
|
||||
</GenericModal>
|
||||
</LegacyGenericModal>
|
||||
`;
|
||||
|
||||
exports[`ProductNoticesModal Match snapshot for user notice 1`] = `
|
||||
<GenericModal
|
||||
<LegacyGenericModal
|
||||
autoCloseOnCancelButton={false}
|
||||
autoCloseOnConfirmButton={true}
|
||||
bodyPadding={true}
|
||||
@@ -117,11 +117,11 @@ exports[`ProductNoticesModal Match snapshot for user notice 1`] = `
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
</GenericModal>
|
||||
</LegacyGenericModal>
|
||||
`;
|
||||
|
||||
exports[`ProductNoticesModal Should match snapshot for system admin notice 1`] = `
|
||||
<GenericModal
|
||||
<LegacyGenericModal
|
||||
autoCloseOnCancelButton={false}
|
||||
autoCloseOnConfirmButton={false}
|
||||
bodyPadding={true}
|
||||
@@ -200,7 +200,7 @@ exports[`ProductNoticesModal Should match snapshot for system admin notice 1`] =
|
||||
id="inProduct_notices.adminOnlyMessage"
|
||||
/>
|
||||
</div>
|
||||
</GenericModal>
|
||||
</LegacyGenericModal>
|
||||
`;
|
||||
|
||||
exports[`ProductNoticesModal Should match snapshot when there are no notices 1`] = `""`;
|
||||
|
||||
@@ -5,7 +5,7 @@ import React from 'react';
|
||||
import {useSelector} from 'react-redux';
|
||||
import {FormattedMessage} from 'react-intl';
|
||||
|
||||
import {GenericModal, GenericModalProps} from '@mattermost/components';
|
||||
import {LegacyGenericModal, LegacyGenericModalProps} from '@mattermost/components';
|
||||
|
||||
import {getCurrentUser} from 'mattermost-redux/selectors/entities/common';
|
||||
import {getUserByEmail} from 'mattermost-redux/selectors/entities/users';
|
||||
@@ -48,7 +48,7 @@ export default function PurchaseInProgressModal(props: Props) {
|
||||
/>
|
||||
);
|
||||
let actionToTake;
|
||||
const genericModalProps: Partial<GenericModalProps> = {};
|
||||
const genericModalProps: Partial<LegacyGenericModalProps> = {};
|
||||
if (sameUserAlreadyPurchasing) {
|
||||
description = (
|
||||
<FormattedMessage
|
||||
@@ -76,7 +76,7 @@ export default function PurchaseInProgressModal(props: Props) {
|
||||
);
|
||||
}
|
||||
return (
|
||||
<GenericModal
|
||||
<LegacyGenericModal
|
||||
onExited={close}
|
||||
show={true}
|
||||
modalHeaderText={header}
|
||||
@@ -98,6 +98,6 @@ export default function PurchaseInProgressModal(props: Props) {
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</GenericModal>
|
||||
</LegacyGenericModal>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import React from 'react';
|
||||
import {FormattedMessage} from 'react-intl';
|
||||
|
||||
import {GenericModal} from '@mattermost/components';
|
||||
import {LegacyGenericModal} from '@mattermost/components';
|
||||
import AccessDeniedHappySvg from 'components/common/svg_images_components/access_denied_happy_svg';
|
||||
import {useControlScreeningInProgressModal} from 'components/common/hooks/useControlModal';
|
||||
|
||||
@@ -14,7 +14,7 @@ export default function ScreeningInProgressModal() {
|
||||
const {close} = useControlScreeningInProgressModal();
|
||||
|
||||
return (
|
||||
<GenericModal
|
||||
<LegacyGenericModal
|
||||
onExited={close}
|
||||
show={true}
|
||||
className='ScreeningInProgressModal'
|
||||
@@ -49,6 +49,6 @@ export default function ScreeningInProgressModal() {
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</GenericModal>
|
||||
</LegacyGenericModal>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import * as React from 'react';
|
||||
import {useIntl} from 'react-intl';
|
||||
|
||||
import {GenericModal} from '@mattermost/components';
|
||||
import {LegacyGenericModal} from '@mattermost/components';
|
||||
|
||||
import './mark_all_threads_as_read_modal.scss';
|
||||
|
||||
@@ -20,7 +20,7 @@ function MarkAllThreadsAsReadModal({
|
||||
const {formatMessage} = useIntl();
|
||||
|
||||
return (
|
||||
<GenericModal
|
||||
<LegacyGenericModal
|
||||
className='mark-all-threads-as-read'
|
||||
id='mark-all-threads-as-read-modal'
|
||||
compassDesign={true}
|
||||
@@ -48,7 +48,7 @@ function MarkAllThreadsAsReadModal({
|
||||
})}
|
||||
</span>
|
||||
</div>
|
||||
</GenericModal>
|
||||
</LegacyGenericModal>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -79,7 +79,10 @@ function UrlInput({
|
||||
};
|
||||
|
||||
const urlInputLabel = (
|
||||
<span className='url-input-label'>
|
||||
<span
|
||||
className='url-input-label'
|
||||
data-testid='urlInputLabel'
|
||||
>
|
||||
{formatMessage({id: 'url_input.label.url', defaultMessage: 'URL: '})}
|
||||
{isShortenedURL ? getShortenedURL(fullURL, shortenLength) : fullURL}
|
||||
</span>
|
||||
@@ -105,6 +108,7 @@ function UrlInput({
|
||||
)}
|
||||
{(editing || hasError) && (
|
||||
<Input
|
||||
data-testid='channelURLInput'
|
||||
name='url-input'
|
||||
type='text'
|
||||
containerClassName='url-input-editable-container'
|
||||
|
||||
366
webapp/package-lock.json
сгенерированный
366
webapp/package-lock.json
сгенерированный
@@ -3574,9 +3574,10 @@
|
||||
"@mattermost/compass-components": "^0.2.12",
|
||||
"@mattermost/compass-icons": "0.1.34",
|
||||
"@mattermost/types": "*",
|
||||
"@mui/base": "5.0.0-alpha.116",
|
||||
"@mui/material": "5.11.7",
|
||||
"@mui/styled-engine-sc": "5.11.0",
|
||||
"@mui/base": "5.0.0-alpha.127",
|
||||
"@mui/material": "5.11.16",
|
||||
"@mui/styled-engine-sc": "5.11.11",
|
||||
"@mui/system": "5.11.16",
|
||||
"@stripe/react-stripe-js": "1.13.0",
|
||||
"@stripe/stripe-js": "1.41.0",
|
||||
"@tippyjs/react": "4.2.6",
|
||||
@@ -3770,6 +3771,14 @@
|
||||
"yup": "0.32.11"
|
||||
}
|
||||
},
|
||||
"channels/node_modules/@emotion/is-prop-valid": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.0.tgz",
|
||||
"integrity": "sha512-3aDpDprjM0AwaxGE09bOPkNxHpBd+kA6jty3RnaEXdweX1DF1U3VQpPYb0g1IStAuK7SVQ1cy+bNBBKp4W3Fjg==",
|
||||
"dependencies": {
|
||||
"@emotion/memoize": "^0.8.0"
|
||||
}
|
||||
},
|
||||
"channels/node_modules/@eslint-community/eslint-utils": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
|
||||
@@ -3794,6 +3803,43 @@
|
||||
"node": "^12.0.0 || ^14.0.0 || >=16.0.0"
|
||||
}
|
||||
},
|
||||
"channels/node_modules/@mui/base": {
|
||||
"version": "5.0.0-alpha.127",
|
||||
"resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.127.tgz",
|
||||
"integrity": "sha512-FoRQd0IOH9MnfyL5yXssyQRnC4vXI+1bwkU1idr+wNkP1ZfxE+JsThHcfl1dy5azLssVUGTtQFD9edQLdbyJog==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.21.0",
|
||||
"@emotion/is-prop-valid": "^1.2.0",
|
||||
"@mui/types": "^7.2.4",
|
||||
"@mui/utils": "^5.12.0",
|
||||
"@popperjs/core": "^2.11.7",
|
||||
"clsx": "^1.2.1",
|
||||
"prop-types": "^15.8.1",
|
||||
"react-is": "^18.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/mui"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "^17.0.0 || ^18.0.0",
|
||||
"react": "^17.0.0 || ^18.0.0",
|
||||
"react-dom": "^17.0.0 || ^18.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"channels/node_modules/@mui/base/node_modules/react-is": {
|
||||
"version": "18.2.0",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
|
||||
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
|
||||
},
|
||||
"channels/node_modules/@testing-library/user-event": {
|
||||
"version": "12.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-12.1.4.tgz",
|
||||
@@ -6510,9 +6556,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/runtime": {
|
||||
"version": "7.20.13",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.13.tgz",
|
||||
"integrity": "sha512-gt3PKXs0DBoL9xCvOIIZ2NEqAGZqHjAnmVbfQtB620V0uReIQutpel14KcneZuer7UioY8ALKZ7iocavvzTNFA==",
|
||||
"version": "7.21.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.5.tgz",
|
||||
"integrity": "sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q==",
|
||||
"dependencies": {
|
||||
"regenerator-runtime": "^0.13.11"
|
||||
},
|
||||
@@ -9809,15 +9855,15 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@mui/base": {
|
||||
"version": "5.0.0-alpha.116",
|
||||
"resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.116.tgz",
|
||||
"integrity": "sha512-VwhifWdrfHc4/ZdqRZ4Gf+7P39sovNN24By1YVZdvJ9fvp0Sr8sNftGUCjYXXz+xCXVBQDXvhfxMwZrj2MvJvA==",
|
||||
"version": "5.0.0-alpha.124",
|
||||
"resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.124.tgz",
|
||||
"integrity": "sha512-I6M+FrjRCybQCr8I8JTu6L2MkUobSQFgNIpOJyDNKL5zq/73LvZIQXvsKumAzthVGvI1PYaarM9vGDrDYbumKA==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.20.7",
|
||||
"@babel/runtime": "^7.21.0",
|
||||
"@emotion/is-prop-valid": "^1.2.0",
|
||||
"@mui/types": "^7.2.3",
|
||||
"@mui/utils": "^5.11.7",
|
||||
"@popperjs/core": "^2.11.6",
|
||||
"@mui/utils": "^5.11.13",
|
||||
"@popperjs/core": "^2.11.7",
|
||||
"clsx": "^1.2.1",
|
||||
"prop-types": "^15.8.1",
|
||||
"react-is": "^18.2.0"
|
||||
@@ -9854,28 +9900,28 @@
|
||||
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
|
||||
},
|
||||
"node_modules/@mui/core-downloads-tracker": {
|
||||
"version": "5.11.7",
|
||||
"resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.11.7.tgz",
|
||||
"integrity": "sha512-lZgX7XQTk0zVcpwEa80r+T4y09dosnUxWvFPSikU/2Hh5wnyNOek8WfJwGCNsaRiXJHMi5eHY+z8oku4u5lgNw==",
|
||||
"version": "5.12.3",
|
||||
"resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.12.3.tgz",
|
||||
"integrity": "sha512-yiJZ+knaknPHuRKhRk4L6XiwppwkAahVal3LuYpvBH7GkA2g+D9WLEXOEnNYtVFUggyKf6fWGLGnx0iqzkU5YA==",
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/mui"
|
||||
}
|
||||
},
|
||||
"node_modules/@mui/material": {
|
||||
"version": "5.11.7",
|
||||
"resolved": "https://registry.npmjs.org/@mui/material/-/material-5.11.7.tgz",
|
||||
"integrity": "sha512-wDv7Pc6kMe9jeWkmCLt4JChd1lPc2u23JQHpB35L2VwQowpNFoDfIwqi0sYCnZTMKlRc7lza8LqwSwHl2G52Rw==",
|
||||
"version": "5.11.16",
|
||||
"resolved": "https://registry.npmjs.org/@mui/material/-/material-5.11.16.tgz",
|
||||
"integrity": "sha512-++glQqbZ3rMzOWB77yOvqRG+k8+scYTUKVWZpWff+GWsf6L10g9L2wgRhhAS8bDLuxCbXZlPNbSZowXDDw6z6Q==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.20.7",
|
||||
"@mui/base": "5.0.0-alpha.116",
|
||||
"@mui/core-downloads-tracker": "^5.11.7",
|
||||
"@mui/system": "^5.11.7",
|
||||
"@babel/runtime": "^7.21.0",
|
||||
"@mui/base": "5.0.0-alpha.124",
|
||||
"@mui/core-downloads-tracker": "^5.11.16",
|
||||
"@mui/system": "^5.11.16",
|
||||
"@mui/types": "^7.2.3",
|
||||
"@mui/utils": "^5.11.7",
|
||||
"@mui/utils": "^5.11.13",
|
||||
"@types/react-transition-group": "^4.4.5",
|
||||
"clsx": "^1.2.1",
|
||||
"csstype": "^3.1.1",
|
||||
"csstype": "^3.1.2",
|
||||
"prop-types": "^15.8.1",
|
||||
"react-is": "^18.2.0",
|
||||
"react-transition-group": "^4.4.5"
|
||||
@@ -9912,12 +9958,12 @@
|
||||
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
|
||||
},
|
||||
"node_modules/@mui/private-theming": {
|
||||
"version": "5.11.7",
|
||||
"resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.11.7.tgz",
|
||||
"integrity": "sha512-XzRTSZdc8bhuUdjablTNv3kFkZ/XIMlKkOqqJCU0G8W3tWGXpau2DXkafPd1ddjPhF9zF3qLKNGgKCChYItjgA==",
|
||||
"version": "5.12.3",
|
||||
"resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.12.3.tgz",
|
||||
"integrity": "sha512-o1e7Z1Bp27n4x2iUHhegV4/Jp6H3T6iBKHJdLivS5GbwsuAE/5l4SnZ+7+K+e5u9TuhwcAKZLkjvqzkDe8zqfA==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.20.7",
|
||||
"@mui/utils": "^5.11.7",
|
||||
"@babel/runtime": "^7.21.0",
|
||||
"@mui/utils": "^5.12.3",
|
||||
"prop-types": "^15.8.1"
|
||||
},
|
||||
"engines": {
|
||||
@@ -9938,13 +9984,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@mui/styled-engine": {
|
||||
"version": "5.11.0",
|
||||
"resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.11.0.tgz",
|
||||
"integrity": "sha512-AF06K60Zc58qf0f7X+Y/QjaHaZq16znliLnGc9iVrV/+s8Ln/FCoeNuFvhlCbZZQ5WQcJvcy59zp0nXrklGGPQ==",
|
||||
"version": "5.12.3",
|
||||
"resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.12.3.tgz",
|
||||
"integrity": "sha512-AhZtiRyT8Bjr7fufxE/mLS+QJ3LxwX1kghIcM2B2dvJzSSg9rnIuXDXM959QfUVIM3C8U4x3mgVoPFMQJvc4/g==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.20.6",
|
||||
"@emotion/cache": "^11.10.5",
|
||||
"csstype": "^3.1.1",
|
||||
"@babel/runtime": "^7.21.0",
|
||||
"@emotion/cache": "^11.10.8",
|
||||
"csstype": "^3.1.2",
|
||||
"prop-types": "^15.8.1"
|
||||
},
|
||||
"engines": {
|
||||
@@ -9969,11 +10015,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@mui/styled-engine-sc": {
|
||||
"version": "5.11.0",
|
||||
"resolved": "https://registry.npmjs.org/@mui/styled-engine-sc/-/styled-engine-sc-5.11.0.tgz",
|
||||
"integrity": "sha512-U8cA7DHB3fnLpDVM5qd/9FGnw5y+LrmwIXQ9Lzk3HYkF903tSMx9jXIbiz1vltpOfZTKX/Rn02m/nkH4OF6Pcg==",
|
||||
"version": "5.11.11",
|
||||
"resolved": "https://registry.npmjs.org/@mui/styled-engine-sc/-/styled-engine-sc-5.11.11.tgz",
|
||||
"integrity": "sha512-6+HsfcKHlhjQklDoEup7Itl+Xgn+BCsqEpIdIIhlxED4YlOZ38xghxIKrx78XFZznTorbhAspUgDDKIaB5vDMg==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.20.6",
|
||||
"@babel/runtime": "^7.21.0",
|
||||
"prop-types": "^15.8.1"
|
||||
},
|
||||
"engines": {
|
||||
@@ -9994,15 +10040,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@mui/styled-engine/node_modules/@emotion/cache": {
|
||||
"version": "11.10.5",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.10.5.tgz",
|
||||
"integrity": "sha512-dGYHWyzTdmK+f2+EnIGBpkz1lKc4Zbj2KHd4cX3Wi8/OWr5pKslNjc3yABKH4adRGCvSX4VDC0i04mrrq0aiRA==",
|
||||
"version": "11.10.8",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.10.8.tgz",
|
||||
"integrity": "sha512-5fyqGHi51LU95o7qQ/vD1jyvC4uCY5GcBT+UgP4LHdpO9jPDlXqhrRr9/wCKmfoAvh5G/F7aOh4MwQa+8uEqhA==",
|
||||
"dependencies": {
|
||||
"@emotion/memoize": "^0.8.0",
|
||||
"@emotion/sheet": "^1.2.1",
|
||||
"@emotion/utils": "^1.2.0",
|
||||
"@emotion/weak-memoize": "^0.3.0",
|
||||
"stylis": "4.1.3"
|
||||
"stylis": "4.1.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@mui/styled-engine/node_modules/@emotion/sheet": {
|
||||
@@ -10015,18 +10061,23 @@
|
||||
"resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.0.tgz",
|
||||
"integrity": "sha512-AHPmaAx+RYfZz0eYu6Gviiagpmiyw98ySSlQvCUhVGDRtDFe4DBS0x1bSjdF3gqUDYOczB+yYvBTtEylYSdRhg=="
|
||||
},
|
||||
"node_modules/@mui/styled-engine/node_modules/stylis": {
|
||||
"version": "4.1.4",
|
||||
"resolved": "https://registry.npmjs.org/stylis/-/stylis-4.1.4.tgz",
|
||||
"integrity": "sha512-USf5pszRYwuE6hg9by0OkKChkQYEXfkeTtm0xKw+jqQhwyjCVLdYyMBK7R+n7dhzsblAWJnGxju4vxq5eH20GQ=="
|
||||
},
|
||||
"node_modules/@mui/system": {
|
||||
"version": "5.11.7",
|
||||
"resolved": "https://registry.npmjs.org/@mui/system/-/system-5.11.7.tgz",
|
||||
"integrity": "sha512-uGB6hBxGlAdlmbLdTtUZYNPXkgQGGnKxHdkRATqsu7UlCxNsc/yS5NCEWy/3c4pnelD1LDLD39WrntP9mwhfkQ==",
|
||||
"version": "5.11.16",
|
||||
"resolved": "https://registry.npmjs.org/@mui/system/-/system-5.11.16.tgz",
|
||||
"integrity": "sha512-JY7CNm7ik2Gr4kQpz1+C9N/f4ET3QjVBo/iaHcmlSOgjdxnOzFbv+vCdb1DMzBGew+UbqckppZpZwbgbrBE2Rw==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.20.7",
|
||||
"@mui/private-theming": "^5.11.7",
|
||||
"@mui/styled-engine": "^5.11.0",
|
||||
"@babel/runtime": "^7.21.0",
|
||||
"@mui/private-theming": "^5.11.13",
|
||||
"@mui/styled-engine": "^5.11.16",
|
||||
"@mui/types": "^7.2.3",
|
||||
"@mui/utils": "^5.11.7",
|
||||
"@mui/utils": "^5.11.13",
|
||||
"clsx": "^1.2.1",
|
||||
"csstype": "^3.1.1",
|
||||
"csstype": "^3.1.2",
|
||||
"prop-types": "^15.8.1"
|
||||
},
|
||||
"engines": {
|
||||
@@ -10055,9 +10106,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@mui/types": {
|
||||
"version": "7.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.3.tgz",
|
||||
"integrity": "sha512-tZ+CQggbe9Ol7e/Fs5RcKwg/woU+o8DCtOnccX6KmbBc7YrfqMYEYuaIcXHuhpT880QwNkZZ3wQwvtlDFA2yOw==",
|
||||
"version": "7.2.4",
|
||||
"resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.4.tgz",
|
||||
"integrity": "sha512-LBcwa8rN84bKF+f5sDyku42w1NTxaPgPyYKODsh01U1fVstTClbUoSA96oyRBnSNyEiAVjKm6Gwx9vjR+xyqHA==",
|
||||
"peerDependencies": {
|
||||
"@types/react": "*"
|
||||
},
|
||||
@@ -10068,11 +10119,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@mui/utils": {
|
||||
"version": "5.11.7",
|
||||
"resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.11.7.tgz",
|
||||
"integrity": "sha512-8uyNDeVHZA804Ego20Erv8TpxlbqTe/EbhTI2H1UYr4/RiIbBprat8W4Qqr2UQIsC/b3DLz+0RQ6R/E5BxEcLA==",
|
||||
"version": "5.12.3",
|
||||
"resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.12.3.tgz",
|
||||
"integrity": "sha512-D/Z4Ub3MRl7HiUccid7sQYclTr24TqUAQFFlxHQF8FR177BrCTQ0JJZom7EqYjZCdXhwnSkOj2ph685MSKNtIA==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.20.7",
|
||||
"@babel/runtime": "^7.21.0",
|
||||
"@types/prop-types": "^15.7.5",
|
||||
"@types/react-is": "^16.7.1 || ^17.0.0",
|
||||
"prop-types": "^15.8.1",
|
||||
@@ -10352,9 +10403,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@popperjs/core": {
|
||||
"version": "2.11.6",
|
||||
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.6.tgz",
|
||||
"integrity": "sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==",
|
||||
"version": "2.11.7",
|
||||
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.7.tgz",
|
||||
"integrity": "sha512-Cr4OjIkipTtcXKjAsm8agyleBuDHvxzeBoa1v543lbv1YaIwQjESsVcmjiWiPEbC1FIeHOG/Op9kdCmAmiS3Kw==",
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/popperjs"
|
||||
@@ -16093,9 +16144,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/csstype": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz",
|
||||
"integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw=="
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz",
|
||||
"integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ=="
|
||||
},
|
||||
"node_modules/currently-unhandled": {
|
||||
"version": "0.4.1",
|
||||
@@ -33485,6 +33536,9 @@
|
||||
"platform/components": {
|
||||
"name": "@mattermost/components",
|
||||
"version": "7.11.0",
|
||||
"dependencies": {
|
||||
"color-blend": "4.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/cli": "^7.17.6",
|
||||
"@babel/core": "^7.17.7",
|
||||
@@ -33521,8 +33575,10 @@
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@babel/runtime-corejs3": "^7.17.8",
|
||||
"@mui/base": "5.0.0-alpha.116",
|
||||
"@mui/material": "5.11.7",
|
||||
"@mui/base": "5.0.0-alpha.127",
|
||||
"@mui/material": "5.11.16",
|
||||
"@mui/styled-engine-sc": "5.11.11",
|
||||
"@mui/system": "5.11.16",
|
||||
"@tippyjs/react": "^4.2.6",
|
||||
"classnames": "^2.3.1",
|
||||
"lodash": "^4.17.21",
|
||||
@@ -33826,6 +33882,14 @@
|
||||
"styled-components": ">= 2"
|
||||
}
|
||||
},
|
||||
"platform/components/node_modules/color-blend": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/color-blend/-/color-blend-4.0.0.tgz",
|
||||
"integrity": "sha512-fYODTHhI/NG+B5GnzvuL3kiFrK/UnkUezWFTgEPBTY5V+kpyfAn95Vn9sJeeCX6omrCOdxnqCL3CvH+6sXtIbw==",
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
}
|
||||
},
|
||||
"platform/components/node_modules/css-loader": {
|
||||
"version": "6.7.3",
|
||||
"resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.7.3.tgz",
|
||||
@@ -37206,9 +37270,9 @@
|
||||
}
|
||||
},
|
||||
"@babel/runtime": {
|
||||
"version": "7.20.13",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.13.tgz",
|
||||
"integrity": "sha512-gt3PKXs0DBoL9xCvOIIZ2NEqAGZqHjAnmVbfQtB620V0uReIQutpel14KcneZuer7UioY8ALKZ7iocavvzTNFA==",
|
||||
"version": "7.21.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.5.tgz",
|
||||
"integrity": "sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q==",
|
||||
"requires": {
|
||||
"regenerator-runtime": "^0.13.11"
|
||||
},
|
||||
@@ -39921,6 +39985,7 @@
|
||||
"babel-loader": "^8.2.3",
|
||||
"babel-plugin-formatjs": "10.3.14",
|
||||
"babel-plugin-styled-components": "^2.0.6",
|
||||
"color-blend": "4.0.0",
|
||||
"css-loader": "^6.7.1",
|
||||
"rollup": "^2.75.7",
|
||||
"rollup-plugin-auto-external": "^2.0.0",
|
||||
@@ -40166,6 +40231,11 @@
|
||||
"picomatch": "^2.3.0"
|
||||
}
|
||||
},
|
||||
"color-blend": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/color-blend/-/color-blend-4.0.0.tgz",
|
||||
"integrity": "sha512-fYODTHhI/NG+B5GnzvuL3kiFrK/UnkUezWFTgEPBTY5V+kpyfAn95Vn9sJeeCX6omrCOdxnqCL3CvH+6sXtIbw=="
|
||||
},
|
||||
"css-loader": {
|
||||
"version": "6.7.3",
|
||||
"resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.7.3.tgz",
|
||||
@@ -40220,15 +40290,15 @@
|
||||
"dev": true
|
||||
},
|
||||
"@mui/base": {
|
||||
"version": "5.0.0-alpha.116",
|
||||
"resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.116.tgz",
|
||||
"integrity": "sha512-VwhifWdrfHc4/ZdqRZ4Gf+7P39sovNN24By1YVZdvJ9fvp0Sr8sNftGUCjYXXz+xCXVBQDXvhfxMwZrj2MvJvA==",
|
||||
"version": "5.0.0-alpha.124",
|
||||
"resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.124.tgz",
|
||||
"integrity": "sha512-I6M+FrjRCybQCr8I8JTu6L2MkUobSQFgNIpOJyDNKL5zq/73LvZIQXvsKumAzthVGvI1PYaarM9vGDrDYbumKA==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.20.7",
|
||||
"@babel/runtime": "^7.21.0",
|
||||
"@emotion/is-prop-valid": "^1.2.0",
|
||||
"@mui/types": "^7.2.3",
|
||||
"@mui/utils": "^5.11.7",
|
||||
"@popperjs/core": "^2.11.6",
|
||||
"@mui/utils": "^5.11.13",
|
||||
"@popperjs/core": "^2.11.7",
|
||||
"clsx": "^1.2.1",
|
||||
"prop-types": "^15.8.1",
|
||||
"react-is": "^18.2.0"
|
||||
@@ -40250,24 +40320,24 @@
|
||||
}
|
||||
},
|
||||
"@mui/core-downloads-tracker": {
|
||||
"version": "5.11.7",
|
||||
"resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.11.7.tgz",
|
||||
"integrity": "sha512-lZgX7XQTk0zVcpwEa80r+T4y09dosnUxWvFPSikU/2Hh5wnyNOek8WfJwGCNsaRiXJHMi5eHY+z8oku4u5lgNw=="
|
||||
"version": "5.12.3",
|
||||
"resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.12.3.tgz",
|
||||
"integrity": "sha512-yiJZ+knaknPHuRKhRk4L6XiwppwkAahVal3LuYpvBH7GkA2g+D9WLEXOEnNYtVFUggyKf6fWGLGnx0iqzkU5YA=="
|
||||
},
|
||||
"@mui/material": {
|
||||
"version": "5.11.7",
|
||||
"resolved": "https://registry.npmjs.org/@mui/material/-/material-5.11.7.tgz",
|
||||
"integrity": "sha512-wDv7Pc6kMe9jeWkmCLt4JChd1lPc2u23JQHpB35L2VwQowpNFoDfIwqi0sYCnZTMKlRc7lza8LqwSwHl2G52Rw==",
|
||||
"version": "5.11.16",
|
||||
"resolved": "https://registry.npmjs.org/@mui/material/-/material-5.11.16.tgz",
|
||||
"integrity": "sha512-++glQqbZ3rMzOWB77yOvqRG+k8+scYTUKVWZpWff+GWsf6L10g9L2wgRhhAS8bDLuxCbXZlPNbSZowXDDw6z6Q==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.20.7",
|
||||
"@mui/base": "5.0.0-alpha.116",
|
||||
"@mui/core-downloads-tracker": "^5.11.7",
|
||||
"@mui/system": "^5.11.7",
|
||||
"@babel/runtime": "^7.21.0",
|
||||
"@mui/base": "5.0.0-alpha.124",
|
||||
"@mui/core-downloads-tracker": "^5.11.16",
|
||||
"@mui/system": "^5.11.16",
|
||||
"@mui/types": "^7.2.3",
|
||||
"@mui/utils": "^5.11.7",
|
||||
"@mui/utils": "^5.11.13",
|
||||
"@types/react-transition-group": "^4.4.5",
|
||||
"clsx": "^1.2.1",
|
||||
"csstype": "^3.1.1",
|
||||
"csstype": "^3.1.2",
|
||||
"prop-types": "^15.8.1",
|
||||
"react-is": "^18.2.0",
|
||||
"react-transition-group": "^4.4.5"
|
||||
@@ -40281,36 +40351,36 @@
|
||||
}
|
||||
},
|
||||
"@mui/private-theming": {
|
||||
"version": "5.11.7",
|
||||
"resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.11.7.tgz",
|
||||
"integrity": "sha512-XzRTSZdc8bhuUdjablTNv3kFkZ/XIMlKkOqqJCU0G8W3tWGXpau2DXkafPd1ddjPhF9zF3qLKNGgKCChYItjgA==",
|
||||
"version": "5.12.3",
|
||||
"resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.12.3.tgz",
|
||||
"integrity": "sha512-o1e7Z1Bp27n4x2iUHhegV4/Jp6H3T6iBKHJdLivS5GbwsuAE/5l4SnZ+7+K+e5u9TuhwcAKZLkjvqzkDe8zqfA==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.20.7",
|
||||
"@mui/utils": "^5.11.7",
|
||||
"@babel/runtime": "^7.21.0",
|
||||
"@mui/utils": "^5.12.3",
|
||||
"prop-types": "^15.8.1"
|
||||
}
|
||||
},
|
||||
"@mui/styled-engine": {
|
||||
"version": "5.11.0",
|
||||
"resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.11.0.tgz",
|
||||
"integrity": "sha512-AF06K60Zc58qf0f7X+Y/QjaHaZq16znliLnGc9iVrV/+s8Ln/FCoeNuFvhlCbZZQ5WQcJvcy59zp0nXrklGGPQ==",
|
||||
"version": "5.12.3",
|
||||
"resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.12.3.tgz",
|
||||
"integrity": "sha512-AhZtiRyT8Bjr7fufxE/mLS+QJ3LxwX1kghIcM2B2dvJzSSg9rnIuXDXM959QfUVIM3C8U4x3mgVoPFMQJvc4/g==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.20.6",
|
||||
"@emotion/cache": "^11.10.5",
|
||||
"csstype": "^3.1.1",
|
||||
"@babel/runtime": "^7.21.0",
|
||||
"@emotion/cache": "^11.10.8",
|
||||
"csstype": "^3.1.2",
|
||||
"prop-types": "^15.8.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@emotion/cache": {
|
||||
"version": "11.10.5",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.10.5.tgz",
|
||||
"integrity": "sha512-dGYHWyzTdmK+f2+EnIGBpkz1lKc4Zbj2KHd4cX3Wi8/OWr5pKslNjc3yABKH4adRGCvSX4VDC0i04mrrq0aiRA==",
|
||||
"version": "11.10.8",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.10.8.tgz",
|
||||
"integrity": "sha512-5fyqGHi51LU95o7qQ/vD1jyvC4uCY5GcBT+UgP4LHdpO9jPDlXqhrRr9/wCKmfoAvh5G/F7aOh4MwQa+8uEqhA==",
|
||||
"requires": {
|
||||
"@emotion/memoize": "^0.8.0",
|
||||
"@emotion/sheet": "^1.2.1",
|
||||
"@emotion/utils": "^1.2.0",
|
||||
"@emotion/weak-memoize": "^0.3.0",
|
||||
"stylis": "4.1.3"
|
||||
"stylis": "4.1.4"
|
||||
}
|
||||
},
|
||||
"@emotion/sheet": {
|
||||
@@ -40322,44 +40392,49 @@
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.0.tgz",
|
||||
"integrity": "sha512-AHPmaAx+RYfZz0eYu6Gviiagpmiyw98ySSlQvCUhVGDRtDFe4DBS0x1bSjdF3gqUDYOczB+yYvBTtEylYSdRhg=="
|
||||
},
|
||||
"stylis": {
|
||||
"version": "4.1.4",
|
||||
"resolved": "https://registry.npmjs.org/stylis/-/stylis-4.1.4.tgz",
|
||||
"integrity": "sha512-USf5pszRYwuE6hg9by0OkKChkQYEXfkeTtm0xKw+jqQhwyjCVLdYyMBK7R+n7dhzsblAWJnGxju4vxq5eH20GQ=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"@mui/styled-engine-sc": {
|
||||
"version": "5.11.0",
|
||||
"resolved": "https://registry.npmjs.org/@mui/styled-engine-sc/-/styled-engine-sc-5.11.0.tgz",
|
||||
"integrity": "sha512-U8cA7DHB3fnLpDVM5qd/9FGnw5y+LrmwIXQ9Lzk3HYkF903tSMx9jXIbiz1vltpOfZTKX/Rn02m/nkH4OF6Pcg==",
|
||||
"version": "5.11.11",
|
||||
"resolved": "https://registry.npmjs.org/@mui/styled-engine-sc/-/styled-engine-sc-5.11.11.tgz",
|
||||
"integrity": "sha512-6+HsfcKHlhjQklDoEup7Itl+Xgn+BCsqEpIdIIhlxED4YlOZ38xghxIKrx78XFZznTorbhAspUgDDKIaB5vDMg==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.20.6",
|
||||
"@babel/runtime": "^7.21.0",
|
||||
"prop-types": "^15.8.1"
|
||||
}
|
||||
},
|
||||
"@mui/system": {
|
||||
"version": "5.11.7",
|
||||
"resolved": "https://registry.npmjs.org/@mui/system/-/system-5.11.7.tgz",
|
||||
"integrity": "sha512-uGB6hBxGlAdlmbLdTtUZYNPXkgQGGnKxHdkRATqsu7UlCxNsc/yS5NCEWy/3c4pnelD1LDLD39WrntP9mwhfkQ==",
|
||||
"version": "5.11.16",
|
||||
"resolved": "https://registry.npmjs.org/@mui/system/-/system-5.11.16.tgz",
|
||||
"integrity": "sha512-JY7CNm7ik2Gr4kQpz1+C9N/f4ET3QjVBo/iaHcmlSOgjdxnOzFbv+vCdb1DMzBGew+UbqckppZpZwbgbrBE2Rw==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.20.7",
|
||||
"@mui/private-theming": "^5.11.7",
|
||||
"@mui/styled-engine": "^5.11.0",
|
||||
"@babel/runtime": "^7.21.0",
|
||||
"@mui/private-theming": "^5.11.13",
|
||||
"@mui/styled-engine": "^5.11.16",
|
||||
"@mui/types": "^7.2.3",
|
||||
"@mui/utils": "^5.11.7",
|
||||
"@mui/utils": "^5.11.13",
|
||||
"clsx": "^1.2.1",
|
||||
"csstype": "^3.1.1",
|
||||
"csstype": "^3.1.2",
|
||||
"prop-types": "^15.8.1"
|
||||
}
|
||||
},
|
||||
"@mui/types": {
|
||||
"version": "7.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.3.tgz",
|
||||
"integrity": "sha512-tZ+CQggbe9Ol7e/Fs5RcKwg/woU+o8DCtOnccX6KmbBc7YrfqMYEYuaIcXHuhpT880QwNkZZ3wQwvtlDFA2yOw=="
|
||||
"version": "7.2.4",
|
||||
"resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.4.tgz",
|
||||
"integrity": "sha512-LBcwa8rN84bKF+f5sDyku42w1NTxaPgPyYKODsh01U1fVstTClbUoSA96oyRBnSNyEiAVjKm6Gwx9vjR+xyqHA=="
|
||||
},
|
||||
"@mui/utils": {
|
||||
"version": "5.11.7",
|
||||
"resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.11.7.tgz",
|
||||
"integrity": "sha512-8uyNDeVHZA804Ego20Erv8TpxlbqTe/EbhTI2H1UYr4/RiIbBprat8W4Qqr2UQIsC/b3DLz+0RQ6R/E5BxEcLA==",
|
||||
"version": "5.12.3",
|
||||
"resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.12.3.tgz",
|
||||
"integrity": "sha512-D/Z4Ub3MRl7HiUccid7sQYclTr24TqUAQFFlxHQF8FR177BrCTQ0JJZom7EqYjZCdXhwnSkOj2ph685MSKNtIA==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.20.7",
|
||||
"@babel/runtime": "^7.21.0",
|
||||
"@types/prop-types": "^15.7.5",
|
||||
"@types/react-is": "^16.7.1 || ^17.0.0",
|
||||
"prop-types": "^15.8.1",
|
||||
@@ -40545,9 +40620,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"@popperjs/core": {
|
||||
"version": "2.11.6",
|
||||
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.6.tgz",
|
||||
"integrity": "sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw=="
|
||||
"version": "2.11.7",
|
||||
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.7.tgz",
|
||||
"integrity": "sha512-Cr4OjIkipTtcXKjAsm8agyleBuDHvxzeBoa1v543lbv1YaIwQjESsVcmjiWiPEbC1FIeHOG/Op9kdCmAmiS3Kw=="
|
||||
},
|
||||
"@react-dnd/asap": {
|
||||
"version": "4.0.1",
|
||||
@@ -47840,9 +47915,9 @@
|
||||
}
|
||||
},
|
||||
"csstype": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz",
|
||||
"integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw=="
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz",
|
||||
"integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ=="
|
||||
},
|
||||
"currently-unhandled": {
|
||||
"version": "0.4.1",
|
||||
@@ -54105,9 +54180,10 @@
|
||||
"@mattermost/compass-components": "^0.2.12",
|
||||
"@mattermost/compass-icons": "0.1.34",
|
||||
"@mattermost/types": "*",
|
||||
"@mui/base": "5.0.0-alpha.116",
|
||||
"@mui/material": "5.11.7",
|
||||
"@mui/styled-engine-sc": "5.11.0",
|
||||
"@mui/base": "5.0.0-alpha.127",
|
||||
"@mui/material": "5.11.16",
|
||||
"@mui/styled-engine-sc": "5.11.11",
|
||||
"@mui/system": "5.11.16",
|
||||
"@redux-devtools/extension": "3.2.3",
|
||||
"@stripe/react-stripe-js": "1.13.0",
|
||||
"@stripe/stripe-js": "1.41.0",
|
||||
@@ -54288,6 +54364,14 @@
|
||||
"zen-observable": "0.9.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@emotion/is-prop-valid": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.0.tgz",
|
||||
"integrity": "sha512-3aDpDprjM0AwaxGE09bOPkNxHpBd+kA6jty3RnaEXdweX1DF1U3VQpPYb0g1IStAuK7SVQ1cy+bNBBKp4W3Fjg==",
|
||||
"requires": {
|
||||
"@emotion/memoize": "^0.8.0"
|
||||
}
|
||||
},
|
||||
"@eslint-community/eslint-utils": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
|
||||
@@ -54303,6 +54387,28 @@
|
||||
"integrity": "sha512-vITaYzIcNmjn5tF5uxcZ/ft7/RXGrMUIS9HalWckEOF6ESiwXKoMzAQf2UW0aVd6rnOeExTJVd5hmWXucBKGXQ==",
|
||||
"dev": true
|
||||
},
|
||||
"@mui/base": {
|
||||
"version": "5.0.0-alpha.127",
|
||||
"resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.127.tgz",
|
||||
"integrity": "sha512-FoRQd0IOH9MnfyL5yXssyQRnC4vXI+1bwkU1idr+wNkP1ZfxE+JsThHcfl1dy5azLssVUGTtQFD9edQLdbyJog==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.21.0",
|
||||
"@emotion/is-prop-valid": "^1.2.0",
|
||||
"@mui/types": "^7.2.4",
|
||||
"@mui/utils": "^5.12.0",
|
||||
"@popperjs/core": "^2.11.7",
|
||||
"clsx": "^1.2.1",
|
||||
"prop-types": "^15.8.1",
|
||||
"react-is": "^18.2.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"react-is": {
|
||||
"version": "18.2.0",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
|
||||
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"@testing-library/user-event": {
|
||||
"version": "12.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-12.1.4.tgz",
|
||||
|
||||
@@ -45,8 +45,10 @@
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@babel/runtime-corejs3": "^7.17.8",
|
||||
"@mui/base": "5.0.0-alpha.116",
|
||||
"@mui/material": "5.11.7",
|
||||
"@mui/base": "5.0.0-alpha.127",
|
||||
"@mui/material": "5.11.16",
|
||||
"@mui/styled-engine-sc": "5.11.11",
|
||||
"@mui/system": "5.11.16",
|
||||
"@tippyjs/react": "^4.2.6",
|
||||
"classnames": "^2.3.1",
|
||||
"lodash": "^4.17.21",
|
||||
@@ -57,5 +59,8 @@
|
||||
"shallow-equals": "^1.0.0",
|
||||
"styled-components": "^5.3.5",
|
||||
"tippy.js": "^6.3.7"
|
||||
},
|
||||
"dependencies": {
|
||||
"color-blend": "4.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
139
webapp/platform/components/src/common/constants/theme.ts
Обычный файл
139
webapp/platform/components/src/common/constants/theme.ts
Обычный файл
@@ -0,0 +1,139 @@
|
||||
import {Theme, ThemeKey} from '@mattermost/types/theme';
|
||||
|
||||
export const THEMES: Record<ThemeKey, Theme> = {
|
||||
denim: {
|
||||
type: 'Denim',
|
||||
sidebarBg: '#1e325c',
|
||||
sidebarText: '#ffffff',
|
||||
sidebarUnreadText: '#ffffff',
|
||||
sidebarTextHoverBg: '#28427b',
|
||||
sidebarTextActiveBorder: '#5d89ea',
|
||||
sidebarTextActiveColor: '#ffffff',
|
||||
sidebarHeaderBg: '#192a4d',
|
||||
sidebarHeaderTextColor: '#ffffff',
|
||||
sidebarTeamBarBg: '#14213e',
|
||||
onlineIndicator: '#3db887',
|
||||
awayIndicator: '#ffbc1f',
|
||||
dndIndicator: '#d24b4e',
|
||||
mentionBg: '#ffffff',
|
||||
mentionColor: '#1e325c',
|
||||
centerChannelBg: '#ffffff',
|
||||
centerChannelColor: '#3f4350',
|
||||
newMessageSeparator: '#cc8f00',
|
||||
linkColor: '#386fe5',
|
||||
buttonBg: '#1c58d9',
|
||||
buttonColor: '#ffffff',
|
||||
errorTextColor: '#d24b4e',
|
||||
mentionHighlightBg: '#ffd470',
|
||||
mentionHighlightLink: '#1b1d22',
|
||||
codeTheme: 'github',
|
||||
},
|
||||
sapphire: {
|
||||
type: 'Sapphire',
|
||||
sidebarBg: '#174ab5',
|
||||
sidebarText: '#ffffff',
|
||||
sidebarUnreadText: '#ffffff',
|
||||
sidebarTextHoverBg: '#2a58ba',
|
||||
sidebarTextActiveBorder: '#57b5f0',
|
||||
sidebarTextActiveColor: '#ffffff',
|
||||
sidebarHeaderBg: '#1542a2',
|
||||
sidebarHeaderTextColor: '#ffffff',
|
||||
sidebarTeamBarBg: '#133a91',
|
||||
onlineIndicator: '#3db887',
|
||||
awayIndicator: '#ffbc1f',
|
||||
dndIndicator: '#d24b4e',
|
||||
mentionBg: '#ffffff',
|
||||
mentionColor: '#174ab5',
|
||||
centerChannelBg: '#ffffff',
|
||||
centerChannelColor: '#3f4350',
|
||||
newMessageSeparator: '#15b7b7',
|
||||
linkColor: '#1c58d9',
|
||||
buttonBg: '#1c58d9',
|
||||
buttonColor: '#ffffff',
|
||||
errorTextColor: '#d24b4e',
|
||||
mentionHighlightBg: '#7ff0f0',
|
||||
mentionHighlightLink: '#0d6e6e',
|
||||
codeTheme: 'github',
|
||||
},
|
||||
quartz: {
|
||||
type: 'Quartz',
|
||||
sidebarBg: '#f4f4f6',
|
||||
sidebarText: '#090a0b',
|
||||
sidebarUnreadText: '#2d3039',
|
||||
sidebarTextHoverBg: '#ebebed',
|
||||
sidebarTextActiveBorder: '#32a4ec',
|
||||
sidebarTextActiveColor: '#2d3039',
|
||||
sidebarHeaderBg: '#e8e9ed',
|
||||
sidebarHeaderTextColor: '#2d3039',
|
||||
sidebarTeamBarBg: '#dddfe4',
|
||||
onlineIndicator: '#3db887',
|
||||
awayIndicator: '#f5ab07',
|
||||
dndIndicator: '#d24b4e',
|
||||
mentionBg: '#1c58d9',
|
||||
mentionColor: '#ffffff',
|
||||
centerChannelBg: '#ffffff',
|
||||
centerChannelColor: '#3f4350',
|
||||
newMessageSeparator: '#15b7b7',
|
||||
linkColor: '#1c58d9',
|
||||
buttonBg: '#1c58d9',
|
||||
buttonColor: '#ffffff',
|
||||
errorTextColor: '#d24b4e',
|
||||
mentionHighlightBg: '#7ff0f0',
|
||||
mentionHighlightLink: '#0d6e6e',
|
||||
codeTheme: 'github',
|
||||
},
|
||||
indigo: {
|
||||
type: 'Indigo',
|
||||
sidebarBg: '#0f1a2e',
|
||||
sidebarText: '#ffffff',
|
||||
sidebarUnreadText: '#ffffff',
|
||||
sidebarTextHoverBg: '#222c3f',
|
||||
sidebarTextActiveBorder: '#1279ba',
|
||||
sidebarTextActiveColor: '#ffffff',
|
||||
sidebarHeaderBg: '#152231',
|
||||
sidebarHeaderTextColor: '#dddfe4',
|
||||
sidebarTeamBarBg: '#05080f',
|
||||
onlineIndicator: '#3db887',
|
||||
awayIndicator: '#f5ab00',
|
||||
dndIndicator: '#d24b4e',
|
||||
mentionBg: '#1c58d9',
|
||||
mentionColor: '#ffffff',
|
||||
centerChannelBg: '#0a111f',
|
||||
centerChannelColor: '#dddfe4',
|
||||
newMessageSeparator: '#81a3ef',
|
||||
linkColor: '#5d89ea',
|
||||
buttonBg: '#386fe5',
|
||||
buttonColor: '#ffffff',
|
||||
errorTextColor: '#d24b4e',
|
||||
mentionHighlightBg: '#133a91',
|
||||
mentionHighlightLink: '#a4f4f4',
|
||||
codeTheme: 'solarized-dark',
|
||||
},
|
||||
onyx: {
|
||||
type: 'Onyx',
|
||||
sidebarBg: '#121317',
|
||||
sidebarText: '#ffffff',
|
||||
sidebarUnreadText: '#ffffff',
|
||||
sidebarTextHoverBg: '#25262a',
|
||||
sidebarTextActiveBorder: '#1592e0',
|
||||
sidebarTextActiveColor: '#ffffff',
|
||||
sidebarHeaderBg: '#1b1d22',
|
||||
sidebarHeaderTextColor: '#dddfe4',
|
||||
sidebarTeamBarBg: '#000000',
|
||||
onlineIndicator: '#3db887',
|
||||
awayIndicator: '#f5ab00',
|
||||
dndIndicator: '#d24b4e',
|
||||
mentionBg: '#1c58d9',
|
||||
mentionColor: '#ffffff',
|
||||
centerChannelBg: '#090a0b',
|
||||
centerChannelColor: '#dddfe4',
|
||||
newMessageSeparator: '#1adbdb',
|
||||
linkColor: '#5d89ea',
|
||||
buttonBg: '#386fe5',
|
||||
buttonColor: '#ffffff',
|
||||
errorTextColor: '#da6c6e',
|
||||
mentionHighlightBg: '#0d6e6e',
|
||||
mentionHighlightLink: '#a4f4f4',
|
||||
codeTheme: 'monokai',
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,59 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React, {memo} from 'react';
|
||||
import {styled} from '@mui/material/styles';
|
||||
import Dialog from '@mui/material/Dialog';
|
||||
import MUIPaper, {PaperProps} from '@mui/material/Paper';
|
||||
import Slide from '@mui/material/Slide';
|
||||
import {TransitionProps} from '@mui/material/transitions';
|
||||
|
||||
const Transition = React.forwardRef((
|
||||
{children, ...props}: TransitionProps & {
|
||||
children: React.ReactElement<any, any>;
|
||||
},
|
||||
ref: React.Ref<unknown>,
|
||||
) => {
|
||||
return (
|
||||
<Slide
|
||||
direction='up'
|
||||
ref={ref}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</Slide>
|
||||
);
|
||||
});
|
||||
|
||||
const Paper = styled(MUIPaper)<PaperProps>(() => ({
|
||||
border: '1px solid rgba(var(--center-channel-color-rgb), 0.16)',
|
||||
borderRadius: 12,
|
||||
backgroundColor: 'var(--center-channel-bg)',
|
||||
boxShadow: '0 20px 32px 0 rgba(0, 0, 0, 0.12)',
|
||||
minWidth: 600,
|
||||
}));
|
||||
|
||||
type ModalProps = {
|
||||
children: React.ReactNode | React.ReactNodeArray;
|
||||
isOpen: boolean;
|
||||
dialogClassName?: string;
|
||||
dialogId?: string;
|
||||
onClose?: () => void;
|
||||
}
|
||||
|
||||
const BaseModal = ({children, isOpen, onClose, dialogClassName = '', dialogId = ''}: ModalProps) => (
|
||||
<Dialog
|
||||
open={isOpen}
|
||||
TransitionComponent={Transition}
|
||||
PaperComponent={Paper}
|
||||
keepMounted={true}
|
||||
onClose={onClose}
|
||||
aria-describedby='alert-dialog-slide-description'
|
||||
role='dialog'
|
||||
className={dialogClassName}
|
||||
id={dialogId}
|
||||
>{children}
|
||||
</Dialog>
|
||||
);
|
||||
|
||||
export default BaseModal;
|
||||
@@ -0,0 +1,71 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React from 'react';
|
||||
import {styled} from '@mui/material/styles';
|
||||
import MUIDialogTitle, {DialogTitleProps as MUIDialogTitleProps} from '@mui/material/DialogTitle';
|
||||
|
||||
import {CloseIcon} from '@mattermost/compass-icons/components';
|
||||
|
||||
import Icon_button from '../icon_button/icon_button';
|
||||
|
||||
type DialogTitleProps = MUIDialogTitleProps & { hasCloseButton: boolean };
|
||||
|
||||
const StyledModalTitle = styled(MUIDialogTitle, {
|
||||
shouldForwardProp: (prop) => prop !== 'hasCloseButton',
|
||||
})<DialogTitleProps>(({hasCloseButton}) => ({
|
||||
display: 'grid',
|
||||
gridTemplateColumns: '1fr max-content max-content',
|
||||
gap: 12,
|
||||
fontFamily: 'Metropolis',
|
||||
fontStyle: 'normal',
|
||||
fontWeight: 600,
|
||||
fontSize: 22,
|
||||
lineHeight: '28px',
|
||||
color: 'var(--center-channel-color)',
|
||||
alignItems: 'center',
|
||||
padding: hasCloseButton ? '22px 26px 24px 32px' : '28px 32px 24px',
|
||||
}));
|
||||
|
||||
const StyledModalTitleSection = styled('div')(() => ({
|
||||
padding: '0 32px 24px 32px',
|
||||
borderBottom: '1px solid rgba(var(--center-channel-text-rgb), 0.12)',
|
||||
}));
|
||||
|
||||
type ModalTitleProps = {
|
||||
title: string;
|
||||
rightSection?: React.ReactNode | React.ReactNode[];
|
||||
children?: React.ReactNode | React.ReactNode[];
|
||||
onClose?: React.MouseEventHandler;
|
||||
}
|
||||
|
||||
const ModalTitle = ({title, onClose, children, rightSection = null}: ModalTitleProps) => {
|
||||
const hasCloseButton = Boolean(onClose);
|
||||
|
||||
return (
|
||||
<>
|
||||
<StyledModalTitle
|
||||
hasCloseButton={hasCloseButton}
|
||||
component={'div'}
|
||||
>
|
||||
{title}
|
||||
{rightSection}
|
||||
{hasCloseButton && (
|
||||
<Icon_button
|
||||
compact={true}
|
||||
type='button'
|
||||
onClick={onClose}
|
||||
IconComponent={CloseIcon}
|
||||
/>
|
||||
)}
|
||||
</StyledModalTitle>
|
||||
{children && (
|
||||
<StyledModalTitleSection>
|
||||
{children}
|
||||
</StyledModalTitleSection>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default ModalTitle;
|
||||
@@ -0,0 +1,173 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {alpha, ComponentsProps, ComponentsVariants, emphasize, Theme} from '@mui/material';
|
||||
import {ComponentsOverrides} from '@mui/material/styles/overrides';
|
||||
|
||||
import {blend} from '../../utils/color';
|
||||
|
||||
const componentName = 'MuiButton';
|
||||
|
||||
declare module '@mui/material/Button' {
|
||||
interface ButtonPropsSizeOverrides {
|
||||
'x-small': true;
|
||||
}
|
||||
|
||||
interface ButtonPropsVariantOverrides {
|
||||
quaternary: true;
|
||||
}
|
||||
}
|
||||
|
||||
const defaultProps: ComponentsProps[typeof componentName] = {
|
||||
disableElevation: true,
|
||||
disableRipple: true,
|
||||
disableTouchRipple: true,
|
||||
disableFocusRipple: true,
|
||||
};
|
||||
|
||||
const getFocusStyles = (color: string) => ({
|
||||
'&:not(.Mui-disabled)': {
|
||||
'&:focus': {
|
||||
boxShadow: `inset 0 0 0 2px ${emphasize(color, 0.05)}`,
|
||||
},
|
||||
|
||||
'&:focus:not(:focus-visible)': {
|
||||
boxShadow: 'none',
|
||||
},
|
||||
|
||||
'&:focus:focus-visible': {
|
||||
boxShadow: `inset 0 0 0 2px ${emphasize(color, 0.05)}`,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const styleOverrides: ComponentsOverrides<Theme>[typeof componentName] = {
|
||||
containedPrimary: ({theme, ownerState}) => ({
|
||||
backgroundColor: ownerState.inverted ? theme.palette.text.primary : theme.palette.primary.main,
|
||||
color: ownerState.inverted ? theme.palette.primary.main : theme.palette.primary.contrastText,
|
||||
|
||||
'&:hover': {
|
||||
backgroundColor: ownerState.inverted ? blend(theme.palette.text.primary, alpha(theme.palette.primary.main, 0.08)) : emphasize(theme.palette.primary.main, 0.1),
|
||||
},
|
||||
'&:active': {
|
||||
backgroundColor: ownerState.inverted ? blend(theme.palette.text.primary, alpha(theme.palette.primary.main, 0.16)) : emphasize(theme.palette.primary.main, 0.2),
|
||||
},
|
||||
|
||||
...getFocusStyles(theme.palette.primary.main),
|
||||
}),
|
||||
containedError: ({theme}) => ({
|
||||
'&:hover': {
|
||||
backgroundColor: emphasize(theme.palette.error.dark, 0.1),
|
||||
},
|
||||
'&:active': {
|
||||
backgroundColor: emphasize(theme.palette.error.dark, 0.2),
|
||||
},
|
||||
|
||||
...getFocusStyles(theme.palette.error.main),
|
||||
}),
|
||||
outlinedPrimary: ({theme}) => ({
|
||||
backgroundColor: alpha(theme.palette.primary.main, 0),
|
||||
|
||||
'&:hover': {
|
||||
backgroundColor: alpha(theme.palette.primary.main, 0.08),
|
||||
},
|
||||
|
||||
'&:active': {
|
||||
backgroundColor: alpha(theme.palette.primary.main, 0.16),
|
||||
},
|
||||
|
||||
...getFocusStyles(theme.palette.primary.main),
|
||||
}),
|
||||
outlinedError: ({theme}) => ({
|
||||
backgroundColor: alpha(theme.palette.error.main, 0),
|
||||
|
||||
'&:hover': {
|
||||
backgroundColor: alpha(theme.palette.error.main, 0.08),
|
||||
},
|
||||
|
||||
'&:active': {
|
||||
backgroundColor: alpha(theme.palette.error.main, 0.16),
|
||||
},
|
||||
|
||||
...getFocusStyles(theme.palette.error.main),
|
||||
}),
|
||||
textPrimary: ({theme}) => ({
|
||||
backgroundColor: alpha(theme.palette.primary.main, 0.08),
|
||||
|
||||
'&:hover': {
|
||||
backgroundColor: alpha(theme.palette.primary.main, 0.12),
|
||||
},
|
||||
|
||||
'&:active': {
|
||||
backgroundColor: alpha(theme.palette.primary.main, 0.16),
|
||||
},
|
||||
|
||||
...getFocusStyles(theme.palette.primary.main),
|
||||
}),
|
||||
textError: ({theme, ownerState}) => ({
|
||||
backgroundColor: ownerState.disabled ? theme.palette.action.disabledBackground : alpha(theme.palette.error.main, 0.12),
|
||||
|
||||
'&:hover': {
|
||||
backgroundColor: alpha(theme.palette.error.main, 0.12),
|
||||
},
|
||||
|
||||
'&:active': {
|
||||
backgroundColor: alpha(theme.palette.error.main, 0.16),
|
||||
},
|
||||
|
||||
...getFocusStyles(theme.palette.error.main),
|
||||
}),
|
||||
};
|
||||
|
||||
const variants: ComponentsVariants[typeof componentName] = [
|
||||
{
|
||||
props: {size: 'x-small'},
|
||||
style: ({theme}) => ({
|
||||
padding: '0.4rem 1rem',
|
||||
...theme.typography.b50,
|
||||
margin: 0,
|
||||
textTransform: 'none',
|
||||
}),
|
||||
},
|
||||
{
|
||||
props: {size: 'small'},
|
||||
style: ({theme}) => ({
|
||||
padding: '0.8rem 1.6rem',
|
||||
...theme.typography.b75,
|
||||
margin: 0,
|
||||
textTransform: 'none',
|
||||
}),
|
||||
},
|
||||
{
|
||||
props: {size: 'medium'},
|
||||
style: ({theme}) => ({
|
||||
padding: '1rem 2rem',
|
||||
...theme.typography.b100,
|
||||
margin: 0,
|
||||
textTransform: 'none',
|
||||
}),
|
||||
},
|
||||
{
|
||||
props: {size: 'large'},
|
||||
style: ({theme}) => ({
|
||||
padding: '1.2rem 2.4rem',
|
||||
...theme.typography.b200,
|
||||
margin: 0,
|
||||
textTransform: 'none',
|
||||
}),
|
||||
},
|
||||
{
|
||||
props: {variant: 'quaternary'},
|
||||
style: () => ({
|
||||
backgroundColor: 'red',
|
||||
}),
|
||||
},
|
||||
];
|
||||
|
||||
const buttonOverrides = {
|
||||
variants,
|
||||
defaultProps,
|
||||
styleOverrides,
|
||||
};
|
||||
|
||||
export default buttonOverrides;
|
||||
@@ -0,0 +1,39 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React from 'react';
|
||||
import MuiButton, {ButtonProps as MuiButtonProps} from '@mui/material/Button';
|
||||
|
||||
type ButtonVariant = 'primary' | 'secondary' | 'tertiary';
|
||||
|
||||
const variantMap: Record<ButtonVariant, Exclude<MuiButtonProps['variant'], undefined>> = {
|
||||
primary: 'contained',
|
||||
secondary: 'outlined',
|
||||
tertiary: 'text',
|
||||
};
|
||||
|
||||
type ExcludedMuiProps =
|
||||
| 'sx'
|
||||
| 'classes'
|
||||
| 'variant'
|
||||
| 'disableElevation'
|
||||
| 'disableRipple'
|
||||
| 'disableFocusRipple';
|
||||
|
||||
export type ButtonProps = Omit<MuiButtonProps, ExcludedMuiProps> & {
|
||||
destructive?: boolean;
|
||||
disabled?: boolean;
|
||||
inverted?: boolean;
|
||||
variant?: ButtonVariant;
|
||||
children: React.ReactNode | React.ReactNode[];
|
||||
}
|
||||
|
||||
export const Button = ({variant = 'primary', destructive, ...rest}: ButtonProps) => (
|
||||
<MuiButton
|
||||
{...rest}
|
||||
color={destructive ? 'error' : 'primary'}
|
||||
variant={variantMap[variant]}
|
||||
/>
|
||||
);
|
||||
|
||||
export default Button;
|
||||
@@ -0,0 +1,80 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React, {memo} from 'react';
|
||||
import {styled} from '@mui/material/styles';
|
||||
import Button from '@mui/material/Button';
|
||||
import MUIPaper, {PaperProps} from '@mui/material/Paper';
|
||||
import DialogActions from '@mui/material/DialogActions';
|
||||
import Slide from '@mui/material/Slide';
|
||||
import {TransitionProps} from '@mui/material/transitions';
|
||||
import BaseModal from "../base_modal/base_modal";
|
||||
|
||||
const Transition = React.forwardRef((
|
||||
{children, ...props}: TransitionProps & {
|
||||
children: React.ReactElement<any, any>;
|
||||
},
|
||||
ref: React.Ref<unknown>,
|
||||
) => {
|
||||
return (
|
||||
<Slide
|
||||
direction='up'
|
||||
ref={ref}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</Slide>
|
||||
);
|
||||
});
|
||||
|
||||
const Paper = styled(MUIPaper)<PaperProps>(() => ({
|
||||
border: '1px solid rgba(var(--center-channel-color-rgb), 0.16)',
|
||||
borderRadius: 12,
|
||||
backgroundColor: 'var(--center-channel-bg)',
|
||||
boxShadow: '0 20px 32px 0 rgba(0, 0, 0, 0.12)',
|
||||
minWidth: 600,
|
||||
}));
|
||||
|
||||
type ModalProps = {
|
||||
children: React.ReactNode | React.ReactNodeArray;
|
||||
isOpen: boolean;
|
||||
dialogClassName?: string;
|
||||
dialogId?: string;
|
||||
onClose?: () => void;
|
||||
onConfirm?: () => void;
|
||||
onCancel?: () => void;
|
||||
}
|
||||
|
||||
const GenericModal = ({children, isOpen, onClose, onConfirm, onCancel, dialogClassName = '', dialogId = ''}: ModalProps) => {
|
||||
const hasActions = Boolean(onConfirm || onCancel);
|
||||
|
||||
const handleConfirmAction = () => {
|
||||
onConfirm?.();
|
||||
onClose?.();
|
||||
};
|
||||
|
||||
const handleCancelAction = () => {
|
||||
onCancel?.();
|
||||
onClose?.();
|
||||
};
|
||||
|
||||
return (
|
||||
<BaseModal
|
||||
isOpen={isOpen}
|
||||
onClose={onClose}
|
||||
aria-describedby='alert-dialog-slide-description'
|
||||
dialogClassName={dialogClassName}
|
||||
dialogId={dialogId}
|
||||
>
|
||||
{children}
|
||||
{hasActions && (
|
||||
<DialogActions>
|
||||
{onCancel && <Button onClick={handleCancelAction}>{'Cancel'}</Button>}
|
||||
{onConfirm && <Button onClick={handleConfirmAction}>{'Confirm'}</Button>}
|
||||
</DialogActions>
|
||||
)}
|
||||
</BaseModal>
|
||||
);
|
||||
};
|
||||
|
||||
export default memo(GenericModal);
|
||||
@@ -0,0 +1,206 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {alpha, ComponentsProps, emphasize, Theme} from '@mui/material';
|
||||
import type {ComponentsVariants} from '@mui/material';
|
||||
import type {ComponentsOverrides} from '@mui/material/styles/overrides';
|
||||
|
||||
const componentName = 'MuiIconButton';
|
||||
|
||||
declare module '@mui/material/IconButton' {
|
||||
interface IconButtonPropsSizeOverrides {
|
||||
'x-small': true;
|
||||
}
|
||||
interface IconButtonPropsOverrides {
|
||||
destructive: boolean;
|
||||
compact: boolean;
|
||||
}
|
||||
}
|
||||
|
||||
const defaultProps: ComponentsProps[typeof componentName] = {
|
||||
disableRipple: true,
|
||||
disableTouchRipple: true,
|
||||
disableFocusRipple: true,
|
||||
};
|
||||
|
||||
export const getFocusStyles = (color: string) => ({
|
||||
'&:not(.Mui-disabled)': {
|
||||
'&:focus': {
|
||||
boxShadow: `inset 0 0 0 2px ${emphasize(color, 0.05)}`,
|
||||
},
|
||||
|
||||
'&:focus:not(:focus-visible)': {
|
||||
boxShadow: 'none',
|
||||
},
|
||||
|
||||
'&:focus:focus-visible': {
|
||||
boxShadow: `inset 0 0 0 2px ${emphasize(color, 0.05)}`,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const styleOverrides: ComponentsOverrides<Theme>[typeof componentName] = {
|
||||
root: ({theme, ownerState}) => ({
|
||||
backgroundColor: 'transparent',
|
||||
color: ownerState.color === 'error' ? theme.palette.error.main : alpha(theme.palette.text.primary, 0.56),
|
||||
borderRadius: 4,
|
||||
margin: 0,
|
||||
|
||||
'&:hover': {
|
||||
backgroundColor: alpha(ownerState.color === 'error' ? theme.palette.error.main : theme.palette.text.primary, 0.08),
|
||||
color: ownerState.color === 'error' ? theme.palette.error.main : alpha(theme.palette.text.primary, 0.72),
|
||||
},
|
||||
|
||||
'&:active': {
|
||||
backgroundColor: alpha(ownerState.color === 'error' ? theme.palette.error.main : theme.palette.primary.main, 0.16),
|
||||
color: ownerState.color === 'error' ? theme.palette.error.main : theme.palette.primary.main,
|
||||
},
|
||||
|
||||
svg: {
|
||||
margin: 0,
|
||||
fill: 'currentColor',
|
||||
},
|
||||
|
||||
...getFocusStyles(ownerState.color === 'error' ? theme.palette.error.main : theme.palette.primary.main),
|
||||
|
||||
...(ownerState.color !== 'error' && {
|
||||
'&.toggled:not(.inverted):not(.Mui-disabled)': {
|
||||
backgroundColor: theme.palette.primary.main,
|
||||
color: theme.palette.primary.contrastText,
|
||||
|
||||
'&:hover': {
|
||||
backgroundColor: alpha(theme.palette.primary.main, 0.92),
|
||||
color: theme.palette.primary.contrastText,
|
||||
},
|
||||
|
||||
'&:active': {
|
||||
backgroundColor: alpha(theme.palette.primary.main, 0.16),
|
||||
color: theme.palette.primary.main,
|
||||
},
|
||||
},
|
||||
|
||||
'&.inverted:not(.Mui-disabled)': {
|
||||
backgroundColor: 'transparent',
|
||||
color: alpha(theme.palette.text.primary, 0.56),
|
||||
|
||||
'&:hover': {
|
||||
backgroundColor: alpha(theme.palette.text.primary, 0.08),
|
||||
color: theme.palette.text.primary,
|
||||
},
|
||||
|
||||
'&:active': {
|
||||
backgroundColor: alpha(theme.palette.text.primary, 0.16),
|
||||
color: theme.palette.text.primary,
|
||||
},
|
||||
|
||||
'&.toggled': {
|
||||
backgroundColor: theme.palette.text.primary,
|
||||
color: alpha(theme.palette.background.default, 0.56),
|
||||
|
||||
'&:hover': {
|
||||
backgroundColor: alpha(theme.palette.text.primary, 0.92),
|
||||
color: alpha(theme.palette.background.default, 0.56),
|
||||
},
|
||||
|
||||
'&:active': {
|
||||
backgroundColor: alpha(theme.palette.text.primary, 0.16),
|
||||
color: theme.palette.text.primary,
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
|
||||
transition: theme.transitions.create(['background-color', 'color'], {duration: theme.transitions.duration.shorter}),
|
||||
}),
|
||||
};
|
||||
|
||||
const variants: ComponentsVariants[typeof componentName] = [
|
||||
{
|
||||
props: {size: 'x-small'},
|
||||
style: ({theme}) => ({
|
||||
padding: theme.spacing(0.5),
|
||||
|
||||
svg: {
|
||||
width: '12px',
|
||||
height: '12px',
|
||||
},
|
||||
|
||||
...theme.typography.b75,
|
||||
lineHeight: 0,
|
||||
fontWeight: 600,
|
||||
|
||||
'.MuiGrid-container': {
|
||||
gap: theme.spacing(0.25),
|
||||
maxHeight: theme.spacing(1.5),
|
||||
},
|
||||
}),
|
||||
},
|
||||
{
|
||||
props: {size: 'small'},
|
||||
style: ({theme}) => ({
|
||||
padding: theme.spacing(0.75),
|
||||
|
||||
svg: {
|
||||
width: '16px',
|
||||
height: '16px',
|
||||
},
|
||||
|
||||
...theme.typography.b100,
|
||||
lineHeight: 0,
|
||||
fontWeight: 600,
|
||||
|
||||
'.MuiGrid-container': {
|
||||
gap: theme.spacing(0.5),
|
||||
maxHeight: theme.spacing(2),
|
||||
},
|
||||
}),
|
||||
},
|
||||
{
|
||||
props: {size: 'medium'},
|
||||
style: ({theme}) => ({
|
||||
padding: theme.spacing(1),
|
||||
|
||||
svg: {
|
||||
width: '20px',
|
||||
height: '20px',
|
||||
},
|
||||
|
||||
...theme.typography.b200,
|
||||
lineHeight: 0,
|
||||
fontWeight: 600,
|
||||
|
||||
'.MuiGrid-container': {
|
||||
gap: theme.spacing(0.75),
|
||||
maxHeight: theme.spacing(2.5),
|
||||
},
|
||||
}),
|
||||
},
|
||||
{
|
||||
props: {size: 'large'},
|
||||
style: ({theme}) => ({
|
||||
padding: theme.spacing(1),
|
||||
|
||||
svg: {
|
||||
width: '28px',
|
||||
height: '28px',
|
||||
},
|
||||
|
||||
...theme.typography.b300,
|
||||
lineHeight: 0,
|
||||
fontWeight: 600,
|
||||
|
||||
'.MuiGrid-container': {
|
||||
gap: theme.spacing(0.75),
|
||||
maxHeight: theme.spacing(3.5),
|
||||
},
|
||||
}),
|
||||
},
|
||||
];
|
||||
|
||||
const overrides = {
|
||||
variants,
|
||||
defaultProps,
|
||||
styleOverrides,
|
||||
};
|
||||
|
||||
export default overrides;
|
||||
@@ -0,0 +1,51 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {Grid} from '@mui/material';
|
||||
import classNames from 'classnames';
|
||||
import React from 'react';
|
||||
import MuiIconButton, {IconButtonProps as MuiIconButtonProps} from '@mui/material/IconButton';
|
||||
|
||||
type ExcludedMuiProps = 'sx' | 'disableFocusRipple' | 'disableRipple' | 'color' | 'classes';
|
||||
|
||||
type CustomProps = {
|
||||
IconComponent: React.FC;
|
||||
compact?: boolean;
|
||||
toggled?: boolean;
|
||||
inverted?: boolean;
|
||||
destructive?: boolean;
|
||||
label?: string;
|
||||
}
|
||||
|
||||
type IconButtonProps = Omit<MuiIconButtonProps, ExcludedMuiProps> & CustomProps;
|
||||
|
||||
const IconButton = ({IconComponent, label, destructive = false, compact = false, toggled = false, inverted = false, ...props}: IconButtonProps) => {
|
||||
return (
|
||||
<MuiIconButton
|
||||
{...props}
|
||||
className={classNames({compact, toggled, inverted})}
|
||||
color={destructive ? 'error' : 'primary'}
|
||||
>
|
||||
<Grid
|
||||
container={true}
|
||||
m={compact ? 0 : 0.25}
|
||||
alignItems='center'
|
||||
alignContent='center'
|
||||
>
|
||||
<Grid item={true}>
|
||||
<IconComponent/>
|
||||
</Grid>
|
||||
{label && (
|
||||
<Grid
|
||||
item={true}
|
||||
pt={0.25}
|
||||
>
|
||||
{label}
|
||||
</Grid>
|
||||
)}
|
||||
</Grid>
|
||||
</MuiIconButton>
|
||||
);
|
||||
};
|
||||
|
||||
export default IconButton;
|
||||
16
webapp/platform/components/src/compass/components/index.ts
Обычный файл
16
webapp/platform/components/src/compass/components/index.ts
Обычный файл
@@ -0,0 +1,16 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import Typography from './typography/typography';
|
||||
import Button, {ButtonProps} from './button/button';
|
||||
import IconButton from './icon_button/icon_button';
|
||||
|
||||
export {
|
||||
IconButton,
|
||||
Button,
|
||||
Typography,
|
||||
};
|
||||
|
||||
export type {
|
||||
ButtonProps,
|
||||
};
|
||||
@@ -0,0 +1,285 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {TypographyOptions} from '@mui/material/styles/createTypography';
|
||||
|
||||
import {getFontMargin} from '../../utils/font';
|
||||
|
||||
declare module '@mui/material/styles' {
|
||||
interface TypographyVariants {
|
||||
|
||||
// body text variants
|
||||
b25: React.CSSProperties;
|
||||
b50: React.CSSProperties;
|
||||
b75: React.CSSProperties;
|
||||
b100: React.CSSProperties;
|
||||
b200: React.CSSProperties;
|
||||
b300: React.CSSProperties;
|
||||
|
||||
// heading variants
|
||||
h25: React.CSSProperties;
|
||||
h50: React.CSSProperties;
|
||||
h75: React.CSSProperties;
|
||||
h100: React.CSSProperties;
|
||||
h200: React.CSSProperties;
|
||||
h300: React.CSSProperties;
|
||||
h400: React.CSSProperties;
|
||||
h500: React.CSSProperties;
|
||||
h600: React.CSSProperties;
|
||||
h700: React.CSSProperties;
|
||||
h800: React.CSSProperties;
|
||||
h900: React.CSSProperties;
|
||||
h1000: React.CSSProperties;
|
||||
}
|
||||
|
||||
// allow configuration using `createTheme`
|
||||
interface TypographyVariantsOptions {
|
||||
|
||||
// body text style properties
|
||||
b25?: React.CSSProperties;
|
||||
b50?: React.CSSProperties;
|
||||
b75?: React.CSSProperties;
|
||||
b100?: React.CSSProperties;
|
||||
b200?: React.CSSProperties;
|
||||
b300?: React.CSSProperties;
|
||||
|
||||
// heading style properties
|
||||
h25?: React.CSSProperties;
|
||||
h50?: React.CSSProperties;
|
||||
h75?: React.CSSProperties;
|
||||
h100?: React.CSSProperties;
|
||||
h200?: React.CSSProperties;
|
||||
h300?: React.CSSProperties;
|
||||
h400?: React.CSSProperties;
|
||||
h500?: React.CSSProperties;
|
||||
h600?: React.CSSProperties;
|
||||
h700?: React.CSSProperties;
|
||||
h800?: React.CSSProperties;
|
||||
h900?: React.CSSProperties;
|
||||
h1000?: React.CSSProperties;
|
||||
}
|
||||
}
|
||||
|
||||
// Update the Typography's variant prop options
|
||||
declare module '@mui/material/Typography' {
|
||||
interface TypographyPropsVariantOverrides {
|
||||
|
||||
// enable our custom body text variants
|
||||
b25: true;
|
||||
b50: true;
|
||||
b75: true;
|
||||
b100: true;
|
||||
b200: true;
|
||||
b300: true;
|
||||
|
||||
// enable our custom heading variants
|
||||
h25: true;
|
||||
h50: true;
|
||||
h75: true;
|
||||
h100: true;
|
||||
h200: true;
|
||||
h300: true;
|
||||
h400: true;
|
||||
h500: true;
|
||||
h600: true;
|
||||
h700: true;
|
||||
h800: true;
|
||||
h900: true;
|
||||
h1000: true;
|
||||
|
||||
// disable the MUI variants
|
||||
h1: false;
|
||||
h2: false;
|
||||
h3: false;
|
||||
h4: false;
|
||||
h5: false;
|
||||
h6: false;
|
||||
body1: false;
|
||||
body2: false;
|
||||
button: false;
|
||||
caption: false;
|
||||
inherit: false;
|
||||
overline: false;
|
||||
subtitle1: false;
|
||||
subtitle2: false;
|
||||
}
|
||||
}
|
||||
|
||||
const baseBodyStyles = {
|
||||
fontFamily: 'Open Sans, sans-serif',
|
||||
fontStyle: 'normal',
|
||||
fontWeight: 400,
|
||||
};
|
||||
|
||||
const b25 = {
|
||||
fontSize: '1rem',
|
||||
lineHeight: '1.6rem',
|
||||
marginTop: getFontMargin(10, 0.75),
|
||||
marginBottom: getFontMargin(10, 0.75),
|
||||
...baseBodyStyles,
|
||||
};
|
||||
const b50 = {
|
||||
fontSize: '1.1rem',
|
||||
lineHeight: '1.6rem',
|
||||
marginTop: getFontMargin(11, 0.75),
|
||||
marginBottom: getFontMargin(11, 0.75),
|
||||
...baseBodyStyles,
|
||||
};
|
||||
const b75 = {
|
||||
fontSize: '1.2rem',
|
||||
lineHeight: '1.6rem',
|
||||
marginTop: getFontMargin(12, 0.75),
|
||||
marginBottom: getFontMargin(12, 0.75),
|
||||
...baseBodyStyles,
|
||||
};
|
||||
const b100 = {
|
||||
fontSize: '1.4rem',
|
||||
lineHeight: '2rem',
|
||||
marginTop: getFontMargin(14, 0.75),
|
||||
marginBottom: getFontMargin(14, 0.75),
|
||||
...baseBodyStyles,
|
||||
};
|
||||
const b200 = {
|
||||
fontSize: '1.6rem',
|
||||
lineHeight: '2.4rem',
|
||||
marginTop: getFontMargin(16, 0.75),
|
||||
marginBottom: getFontMargin(16, 0.75),
|
||||
...baseBodyStyles,
|
||||
};
|
||||
const b300 = {
|
||||
fontSize: '1.8rem',
|
||||
lineHeight: '2.8rem',
|
||||
marginTop: getFontMargin(18, 0.75),
|
||||
marginBottom: getFontMargin(18, 0.75),
|
||||
...baseBodyStyles,
|
||||
};
|
||||
|
||||
const baseHeadingStyles = {
|
||||
fontFamily: 'Metropolis, sans-serif',
|
||||
fontStyle: 'normal',
|
||||
fontWeight: 600,
|
||||
|
||||
'&:first-of-type': {
|
||||
marginTop: 0,
|
||||
},
|
||||
};
|
||||
|
||||
const h25 = {
|
||||
fontSize: '1rem',
|
||||
lineHeight: '1.6rem',
|
||||
marginTop: getFontMargin(10, 8 / 9),
|
||||
marginBottom: getFontMargin(10, 0.5),
|
||||
...baseHeadingStyles,
|
||||
fontFamily: 'Open Sans, sans-serif',
|
||||
};
|
||||
const h50 = {
|
||||
fontSize: '1.1rem',
|
||||
lineHeight: '1.6rem',
|
||||
marginTop: getFontMargin(11, 8 / 9),
|
||||
marginBottom: getFontMargin(11, 0.5),
|
||||
...baseHeadingStyles,
|
||||
fontFamily: 'Open Sans, sans-serif',
|
||||
};
|
||||
const h75 = {
|
||||
fontSize: '1.2rem',
|
||||
lineHeight: '1.6rem',
|
||||
marginTop: getFontMargin(12, 8 / 9),
|
||||
marginBottom: getFontMargin(12, 0.5),
|
||||
...baseHeadingStyles,
|
||||
fontFamily: 'Open Sans, sans-serif',
|
||||
};
|
||||
const h100 = {
|
||||
fontSize: '1.4rem',
|
||||
lineHeight: '2rem',
|
||||
marginTop: getFontMargin(14, 8 / 9),
|
||||
marginBottom: getFontMargin(14, 0.5),
|
||||
...baseHeadingStyles,
|
||||
fontFamily: 'Open Sans, sans-serif',
|
||||
};
|
||||
const h200 = {
|
||||
fontSize: '1.6rem',
|
||||
lineHeight: '2.4rem',
|
||||
marginTop: getFontMargin(16, 8 / 9),
|
||||
marginBottom: getFontMargin(16, 0.5),
|
||||
...baseHeadingStyles,
|
||||
};
|
||||
const h300 = {
|
||||
fontSize: '1.8rem',
|
||||
lineHeight: '2.4rem',
|
||||
marginTop: getFontMargin(18, 8 / 9),
|
||||
marginBottom: getFontMargin(18, 0.5),
|
||||
...baseHeadingStyles,
|
||||
};
|
||||
const h400 = {
|
||||
fontSize: '2rem',
|
||||
lineHeight: '2.8rem',
|
||||
marginTop: getFontMargin(18, 8 / 9),
|
||||
marginBottom: getFontMargin(18, 0.5),
|
||||
...baseHeadingStyles,
|
||||
};
|
||||
const h500 = {
|
||||
fontSize: '2.2rem',
|
||||
lineHeight: '2.8rem',
|
||||
marginTop: getFontMargin(22, 8 / 9),
|
||||
marginBottom: getFontMargin(22, 0.5),
|
||||
...baseHeadingStyles,
|
||||
};
|
||||
const h600 = {
|
||||
fontSize: '2.5rem',
|
||||
lineHeight: '3rem',
|
||||
marginTop: getFontMargin(25, 8 / 9),
|
||||
marginBottom: getFontMargin(25, 0.5),
|
||||
...baseHeadingStyles,
|
||||
};
|
||||
const h700 = {
|
||||
fontSize: '2.8rem',
|
||||
lineHeight: '3.6rem',
|
||||
marginTop: getFontMargin(28, 8 / 9),
|
||||
marginBottom: getFontMargin(28, 0.5),
|
||||
...baseHeadingStyles,
|
||||
};
|
||||
const h800 = {
|
||||
fontSize: '3.2rem',
|
||||
lineHeight: '4rem',
|
||||
marginTop: getFontMargin(32, 8 / 9),
|
||||
marginBottom: getFontMargin(32, 0.5),
|
||||
...baseHeadingStyles,
|
||||
};
|
||||
const h900 = {
|
||||
fontSize: '3.6rem',
|
||||
lineHeight: '4.4rem',
|
||||
marginTop: getFontMargin(36, 8 / 9),
|
||||
marginBottom: getFontMargin(36, 0.5),
|
||||
...baseHeadingStyles,
|
||||
};
|
||||
const h1000 = {
|
||||
fontSize: '4rem',
|
||||
lineHeight: '4.8rem',
|
||||
marginTop: getFontMargin(40, 8 / 9),
|
||||
marginBottom: getFontMargin(40, 0.5),
|
||||
...baseHeadingStyles,
|
||||
};
|
||||
|
||||
const typographyOverrides: TypographyOptions = {
|
||||
b25,
|
||||
b50,
|
||||
b75,
|
||||
b100,
|
||||
b200,
|
||||
b300,
|
||||
h25,
|
||||
h50,
|
||||
h75,
|
||||
h100,
|
||||
h200,
|
||||
h300,
|
||||
h400,
|
||||
h500,
|
||||
h600,
|
||||
h700,
|
||||
h800,
|
||||
h900,
|
||||
h1000,
|
||||
};
|
||||
|
||||
export default typographyOverrides;
|
||||
@@ -0,0 +1,44 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React from 'react';
|
||||
import {Typography as MuiTypography, TypographyProps as MuiTypographyProps} from '@mui/material';
|
||||
|
||||
type Props = Omit<MuiTypographyProps, 'variantMapping' | 'paragraph'> & {
|
||||
gutterTop?: boolean;
|
||||
}
|
||||
|
||||
const Typography = ({variant = 'b100', ...props}: Props) => {
|
||||
const variantMap = {
|
||||
b25: 'p',
|
||||
b50: 'p',
|
||||
b75: 'p',
|
||||
b100: 'p',
|
||||
b200: 'p',
|
||||
b300: 'p',
|
||||
|
||||
h25: 'h6',
|
||||
h50: 'h6',
|
||||
h75: 'h6',
|
||||
h100: 'h5',
|
||||
h200: 'h5',
|
||||
h300: 'h4',
|
||||
h400: 'h4',
|
||||
h500: 'h3',
|
||||
h600: 'h3',
|
||||
h700: 'h2',
|
||||
h800: 'h2',
|
||||
h900: 'h1',
|
||||
h1000: 'h1',
|
||||
};
|
||||
|
||||
return (
|
||||
<MuiTypography
|
||||
{...props}
|
||||
variant={variant}
|
||||
variantMapping={variantMap}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default Typography;
|
||||
10
webapp/platform/components/src/compass/index.ts
Обычный файл
10
webapp/platform/components/src/compass/index.ts
Обычный файл
@@ -0,0 +1,10 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
export * from './components';
|
||||
|
||||
import ThemeProvider from './theme_provider/theme_provider';
|
||||
|
||||
export {
|
||||
ThemeProvider,
|
||||
};
|
||||
@@ -0,0 +1,23 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {ThemeOptions} from '@mui/material/styles/createTheme';
|
||||
|
||||
import MuiButton from '../components/button/button.overrides';
|
||||
import MuiIconButton from '../components/icon_button/icon_button.overrides';
|
||||
import typographyOverrides from '../components/typography/typography.overrides';
|
||||
|
||||
const components: ThemeOptions['components'] = {
|
||||
MuiButton,
|
||||
MuiIconButton,
|
||||
};
|
||||
|
||||
const overrides: ThemeOptions = {
|
||||
components,
|
||||
typography: {
|
||||
...typographyOverrides,
|
||||
htmlFontSize: 10,
|
||||
},
|
||||
};
|
||||
|
||||
export default overrides;
|
||||
@@ -0,0 +1,31 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React from 'react';
|
||||
import {createTheme, ThemeProvider as MUIThemeProvider} from '@mui/material/styles';
|
||||
import {Theme} from "@mattermost/types/theme";
|
||||
|
||||
import {createMUIThemeFromMMTheme} from './themes';
|
||||
|
||||
import {THEMES} from '../../common/constants/theme';
|
||||
import overrides from './overrides';
|
||||
|
||||
type Props = {
|
||||
theme: Theme;
|
||||
}
|
||||
|
||||
const ThemeProvider = ({theme = THEMES.onyx}: Props) => {
|
||||
const MUITheme = createMUIThemeFromMMTheme(theme);
|
||||
const combinedTheme = createTheme({
|
||||
...MUITheme,
|
||||
...overrides,
|
||||
});
|
||||
|
||||
return (
|
||||
<MUIThemeProvider
|
||||
theme={combinedTheme}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default ThemeProvider;
|
||||
47
webapp/platform/components/src/compass/theme_provider/themes.ts
Обычный файл
47
webapp/platform/components/src/compass/theme_provider/themes.ts
Обычный файл
@@ -0,0 +1,47 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {alpha} from '@mui/material';
|
||||
import {createTheme} from '@mui/material/styles';
|
||||
import {Theme} from '@mattermost/types/theme';
|
||||
|
||||
import {THEMES} from '../../common/constants/theme';
|
||||
|
||||
declare module '@mui/material/styles' {
|
||||
interface Palette {
|
||||
mention?: Palette['primary'];
|
||||
}
|
||||
interface PaletteOptions {
|
||||
mention?: PaletteOptions['primary'];
|
||||
}
|
||||
|
||||
interface PaletteColor {
|
||||
darker?: string;
|
||||
}
|
||||
interface SimplePaletteColorOptions {
|
||||
darker?: string;
|
||||
}
|
||||
}
|
||||
|
||||
export const createMUIThemeFromMMTheme = (theme: Theme) => createTheme({
|
||||
palette: {
|
||||
primary: {main: theme.buttonBg},
|
||||
secondary: {main: theme.linkColor},
|
||||
error: {main: theme.dndIndicator},
|
||||
warning: {main: theme.awayIndicator},
|
||||
info: {main: theme.mentionHighlightBg},
|
||||
success: {main: theme.onlineIndicator},
|
||||
text: {
|
||||
primary: theme.centerChannelColor,
|
||||
},
|
||||
background: {
|
||||
default: theme.centerChannelBg,
|
||||
},
|
||||
action: {
|
||||
disabled: alpha(theme.centerChannelColor, 0.32),
|
||||
disabledBackground: alpha(theme.centerChannelColor, 0.08),
|
||||
},
|
||||
tonalOffset: 0.05,
|
||||
},
|
||||
});
|
||||
|
||||
32
webapp/platform/components/src/compass/utils/color.ts
Обычный файл
32
webapp/platform/components/src/compass/utils/color.ts
Обычный файл
@@ -0,0 +1,32 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {decomposeColor, hslToRgb} from '@mui/material';
|
||||
import {normal} from 'color-blend';
|
||||
|
||||
export const decomposeColorToRgb = (color: string) => {
|
||||
if (color.startsWith('hsl')) {
|
||||
return decomposeColor(hslToRgb(color));
|
||||
}
|
||||
|
||||
return decomposeColor(color);
|
||||
};
|
||||
|
||||
export const blend = (background: string, foreground: string) => {
|
||||
const bg = decomposeColorToRgb(background);
|
||||
const fg = decomposeColorToRgb(foreground);
|
||||
|
||||
const blended = normal({
|
||||
r: bg.values[0],
|
||||
g: bg.values[1],
|
||||
b: bg.values[2],
|
||||
a: bg.values[3] || 1,
|
||||
}, {
|
||||
r: fg.values[0],
|
||||
g: fg.values[1],
|
||||
b: fg.values[2],
|
||||
a: fg.values[3] || 1,
|
||||
});
|
||||
|
||||
return `rgba(${blended.r}, ${blended.g}, ${blended.b}, ${blended.a})`;
|
||||
};
|
||||
5
webapp/platform/components/src/compass/utils/font.ts
Обычный файл
5
webapp/platform/components/src/compass/utils/font.ts
Обычный файл
@@ -0,0 +1,5 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
export const getFontMargin = (fontSize: number, multiplier: number): number =>
|
||||
Math.max(Math.round((fontSize * multiplier) / 4) * 4, 8);
|
||||
@@ -2,13 +2,14 @@
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
// type
|
||||
export type {Props as GenericModalProps} from './generic_modal/generic_modal';
|
||||
export type {Props as LegacyGenericModalProps} from './legacy_generic_modal/legacy_generic_modal';
|
||||
export type {CircleSkeletonLoaderProps, RectangleSkeletonLoaderProps} from './skeleton_loader';
|
||||
export type {Props as FocusTrapProps} from './focus_trap';
|
||||
|
||||
// components
|
||||
export * from './generic_modal/footer_content';
|
||||
export {GenericModal} from './generic_modal/generic_modal';
|
||||
export * from './compass';
|
||||
export * from './legacy_generic_modal/footer_content';
|
||||
export {LegacyGenericModal} from './legacy_generic_modal/legacy_generic_modal';
|
||||
export {CircleSkeletonLoader, RectangleSkeletonLoader} from './skeleton_loader';
|
||||
export * from './tour_tip';
|
||||
export * from './pulsating_dot';
|
||||
|
||||
@@ -52,7 +52,7 @@ type State = {
|
||||
isFocalTrapActive: boolean;
|
||||
}
|
||||
|
||||
export class GenericModal extends React.PureComponent<Props, State> {
|
||||
export class LegacyGenericModal extends React.PureComponent<Props, State> {
|
||||
static defaultProps: Partial<Props> = {
|
||||
show: true,
|
||||
id: 'genericModal',
|
||||
33
webapp/platform/types/src/theme.ts
Обычный файл
33
webapp/platform/types/src/theme.ts
Обычный файл
@@ -0,0 +1,33 @@
|
||||
export type ThemeKey = 'denim' | 'sapphire' | 'quartz' | 'indigo' | 'onyx';
|
||||
|
||||
export type LegacyThemeType = 'Mattermost' | 'Organization' | 'Mattermost Dark' | 'Windows Dark';
|
||||
|
||||
export type ThemeType = 'Denim' | 'Sapphire' | 'Quartz' | 'Indigo' | 'Onyx';
|
||||
|
||||
export type Theme = {
|
||||
type?: ThemeType | 'custom';
|
||||
sidebarBg: string;
|
||||
sidebarText: string;
|
||||
sidebarUnreadText: string;
|
||||
sidebarTextHoverBg: string;
|
||||
sidebarTextActiveBorder: string;
|
||||
sidebarTextActiveColor: string;
|
||||
sidebarHeaderBg: string;
|
||||
sidebarTeamBarBg: string;
|
||||
sidebarHeaderTextColor: string;
|
||||
onlineIndicator: string;
|
||||
awayIndicator: string;
|
||||
dndIndicator: string;
|
||||
mentionBg: string;
|
||||
mentionColor: string;
|
||||
centerChannelBg: string;
|
||||
centerChannelColor: string;
|
||||
newMessageSeparator: string;
|
||||
linkColor: string;
|
||||
buttonBg: string;
|
||||
buttonColor: string;
|
||||
errorTextColor: string;
|
||||
mentionHighlightBg: string;
|
||||
mentionHighlightLink: string;
|
||||
codeTheme: string;
|
||||
};
|
||||
Ссылка в новой задаче
Block a user