mirror of https://github.com/laurent22/joplin.git
Chore: Desktop: Use SCSS instead of styled-components for plugin dialogs and toolbar buttons (#11189)
parent
e63d545ed8
commit
e3d5f0c9cf
|
@ -442,7 +442,6 @@ packages/app-desktop/gui/ToggleEditorsButton/ToggleEditorsButton.js
|
||||||
packages/app-desktop/gui/ToggleEditorsButton/styles/index.js
|
packages/app-desktop/gui/ToggleEditorsButton/styles/index.js
|
||||||
packages/app-desktop/gui/ToolbarBase.js
|
packages/app-desktop/gui/ToolbarBase.js
|
||||||
packages/app-desktop/gui/ToolbarButton/ToolbarButton.js
|
packages/app-desktop/gui/ToolbarButton/ToolbarButton.js
|
||||||
packages/app-desktop/gui/ToolbarButton/styles/index.js
|
|
||||||
packages/app-desktop/gui/ToolbarSpace.js
|
packages/app-desktop/gui/ToolbarSpace.js
|
||||||
packages/app-desktop/gui/TrashNotification/TrashNotification.js
|
packages/app-desktop/gui/TrashNotification/TrashNotification.js
|
||||||
packages/app-desktop/gui/UpdateNotification/UpdateNotification.js
|
packages/app-desktop/gui/UpdateNotification/UpdateNotification.js
|
||||||
|
|
|
@ -419,7 +419,6 @@ packages/app-desktop/gui/ToggleEditorsButton/ToggleEditorsButton.js
|
||||||
packages/app-desktop/gui/ToggleEditorsButton/styles/index.js
|
packages/app-desktop/gui/ToggleEditorsButton/styles/index.js
|
||||||
packages/app-desktop/gui/ToolbarBase.js
|
packages/app-desktop/gui/ToolbarBase.js
|
||||||
packages/app-desktop/gui/ToolbarButton/ToolbarButton.js
|
packages/app-desktop/gui/ToolbarButton/ToolbarButton.js
|
||||||
packages/app-desktop/gui/ToolbarButton/styles/index.js
|
|
||||||
packages/app-desktop/gui/ToolbarSpace.js
|
packages/app-desktop/gui/ToolbarSpace.js
|
||||||
packages/app-desktop/gui/TrashNotification/TrashNotification.js
|
packages/app-desktop/gui/TrashNotification/TrashNotification.js
|
||||||
packages/app-desktop/gui/UpdateNotification/UpdateNotification.js
|
packages/app-desktop/gui/UpdateNotification/UpdateNotification.js
|
||||||
|
|
|
@ -5,30 +5,6 @@ import { ChangeEvent, useCallback, useRef } from 'react';
|
||||||
import NoteToolbar from '../../NoteToolbar/NoteToolbar';
|
import NoteToolbar from '../../NoteToolbar/NoteToolbar';
|
||||||
import { buildStyle } from '@joplin/lib/theme';
|
import { buildStyle } from '@joplin/lib/theme';
|
||||||
import time from '@joplin/lib/time';
|
import time from '@joplin/lib/time';
|
||||||
import styled from 'styled-components';
|
|
||||||
|
|
||||||
const StyledRoot = styled.div`
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
|
||||||
padding-left: ${props => props.theme.editorPaddingLeft}px;
|
|
||||||
|
|
||||||
@media (max-width: 800px) {
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: flex-start;
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
const InfoGroup = styled.div`
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
@media (max-width: 800px) {
|
|
||||||
border-top: 1px solid ${props => props.theme.dividerColor};
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
themeId: number;
|
themeId: number;
|
||||||
|
@ -130,7 +106,7 @@ export default function NoteTitleBar(props: Props) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledRoot>
|
<div className='note-title-wrapper'>
|
||||||
<input
|
<input
|
||||||
className="title-input"
|
className="title-input"
|
||||||
type="text"
|
type="text"
|
||||||
|
@ -144,10 +120,10 @@ export default function NoteTitleBar(props: Props) {
|
||||||
onBlur={onTitleBlur}
|
onBlur={onTitleBlur}
|
||||||
value={props.noteTitle}
|
value={props.noteTitle}
|
||||||
/>
|
/>
|
||||||
<InfoGroup>
|
<div className='note-title-info-group'>
|
||||||
{renderTitleBarDate()}
|
{renderTitleBarDate()}
|
||||||
{renderNoteToolbar()}
|
{renderNoteToolbar()}
|
||||||
</InfoGroup>
|
</div>
|
||||||
</StyledRoot>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
|
||||||
@use "./styles/warning-banner.scss";
|
@use "./styles/warning-banner.scss";
|
||||||
@use "./styles/warning-banner-link.scss";
|
@use "./styles/warning-banner-link.scss";
|
||||||
|
@use "./styles/note-title-info-group.scss";
|
||||||
|
@use "./styles/note-title-wrapper.scss";
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
|
||||||
|
.note-title-info-group {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
@media (max-width: 800px) {
|
||||||
|
border-top: 1px solid var(--joplin-divider-color);
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
|
||||||
|
.note-title-wrapper {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
padding-left: var(--joplin-editor-padding-left);
|
||||||
|
|
||||||
|
@media (max-width: 800px) {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,5 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { ToolbarButtonInfo } from '@joplin/lib/services/commands/ToolbarButtonUtils';
|
import { ToolbarButtonInfo } from '@joplin/lib/services/commands/ToolbarButtonUtils';
|
||||||
import { StyledIconSpan, StyledIconI } from './styles';
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
readonly themeId: number;
|
readonly themeId: number;
|
||||||
|
@ -36,8 +35,12 @@ export default function ToolbarButton(props: Props) {
|
||||||
let icon = null;
|
let icon = null;
|
||||||
const iconName = getProp(props, 'iconName');
|
const iconName = getProp(props, 'iconName');
|
||||||
if (iconName) {
|
if (iconName) {
|
||||||
const IconClass = isFontAwesomeIcon(iconName) ? StyledIconI : StyledIconSpan;
|
const iconProps: React.HTMLProps<HTMLDivElement> = {
|
||||||
icon = <IconClass className={iconName} aria-label='' hasTitle={!!title} role='img'/>;
|
'aria-label': '',
|
||||||
|
role: 'img',
|
||||||
|
className: `toolbar-icon ${title ? '-has-title' : ''} ${iconName}`,
|
||||||
|
};
|
||||||
|
icon = isFontAwesomeIcon(iconName) ? <i {...iconProps} /> : <span {...iconProps} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keep this for legacy compatibility but for consistency we should use "disabled" prop
|
// Keep this for legacy compatibility but for consistency we should use "disabled" prop
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
import { ThemeStyle } from '@joplin/lib/theme';
|
|
||||||
|
|
||||||
const styled = require('styled-components').default;
|
|
||||||
const { css } = require('styled-components');
|
|
||||||
|
|
||||||
interface IconProps {
|
|
||||||
readonly theme: ThemeStyle;
|
|
||||||
readonly hasTitle: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
const iconStyle = css<IconProps>`
|
|
||||||
font-size: ${(props: IconProps) => props.theme.toolbarIconSize}px;
|
|
||||||
color: ${(props: IconProps) => props.theme.color3};
|
|
||||||
margin-right: ${(props: IconProps) => props.hasTitle ? 5 : 0}px;
|
|
||||||
pointer-events: none; /* Need this to get button tooltip to work */
|
|
||||||
`;
|
|
||||||
|
|
||||||
export const StyledIconI = styled.i`${iconStyle}`;
|
|
||||||
export const StyledIconSpan = styled.span`${iconStyle}`;
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
|
||||||
|
.dialog-anchor-node {
|
||||||
|
display: none;
|
||||||
|
}
|
|
@ -5,4 +5,7 @@
|
||||||
@use './flat-button.scss';
|
@use './flat-button.scss';
|
||||||
@use './help-text.scss';
|
@use './help-text.scss';
|
||||||
@use './toolbar-button.scss';
|
@use './toolbar-button.scss';
|
||||||
|
@use './toolbar-icon.scss';
|
||||||
@use './editor-toolbar.scss';
|
@use './editor-toolbar.scss';
|
||||||
|
@use './user-webview-dialog-container.scss';
|
||||||
|
@use './dialog-anchor-node.scss';
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
|
||||||
|
.toolbar-icon {
|
||||||
|
font-size: var(--joplin-toolbar-icon-size);
|
||||||
|
color: var(--joplin-color3);
|
||||||
|
margin-right: 0px;
|
||||||
|
pointer-events: none; /* Need this to get button tooltip to work */
|
||||||
|
|
||||||
|
&.-has-title {
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
|
||||||
|
.user-webview-dialog-container {
|
||||||
|
display: flex;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
z-index: 1000;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { useRef, useImperativeHandle, forwardRef, useEffect } from 'react';
|
import { useRef, useImperativeHandle, forwardRef, useEffect, useMemo } from 'react';
|
||||||
import useViewIsReady from './hooks/useViewIsReady';
|
import useViewIsReady from './hooks/useViewIsReady';
|
||||||
import useThemeCss from './hooks/useThemeCss';
|
import useThemeCss from './hooks/useThemeCss';
|
||||||
import useContentSize from './hooks/useContentSize';
|
import useContentSize from './hooks/useContentSize';
|
||||||
|
@ -8,14 +8,10 @@ import useHtmlLoader from './hooks/useHtmlLoader';
|
||||||
import useWebviewToPluginMessages from './hooks/useWebviewToPluginMessages';
|
import useWebviewToPluginMessages from './hooks/useWebviewToPluginMessages';
|
||||||
import useScriptLoader from './hooks/useScriptLoader';
|
import useScriptLoader from './hooks/useScriptLoader';
|
||||||
import Logger from '@joplin/utils/Logger';
|
import Logger from '@joplin/utils/Logger';
|
||||||
import styled from 'styled-components';
|
|
||||||
import { focus } from '@joplin/lib/utils/focusHandler';
|
import { focus } from '@joplin/lib/utils/focusHandler';
|
||||||
|
|
||||||
const logger = Logger.create('UserWebview');
|
const logger = Logger.create('UserWebview');
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
|
|
||||||
type StyleProps = any;
|
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
html: string;
|
html: string;
|
||||||
scripts: string[];
|
scripts: string[];
|
||||||
|
@ -36,15 +32,6 @@ export interface Props {
|
||||||
onReady?: Function;
|
onReady?: Function;
|
||||||
}
|
}
|
||||||
|
|
||||||
const StyledFrame = styled.iframe<{ fitToContent: boolean; borderBottom: boolean }>`
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
width: ${(props: StyleProps) => props.fitToContent ? `${props.width}px` : '100%'};
|
|
||||||
height: ${(props: StyleProps) => props.fitToContent ? `${props.height}px` : '100%'};
|
|
||||||
border: none;
|
|
||||||
border-bottom: ${(props: StyleProps) => props.borderBottom ? `1px solid ${props.theme.dividerColor}` : 'none'};
|
|
||||||
`;
|
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
|
||||||
function serializeForm(form: any) {
|
function serializeForm(form: any) {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
|
||||||
|
@ -153,15 +140,18 @@ function UserWebview(props: Props, ref: any) {
|
||||||
cssFilePath,
|
cssFilePath,
|
||||||
);
|
);
|
||||||
|
|
||||||
return <StyledFrame
|
const style = useMemo(() => ({
|
||||||
|
'--content-width': `${contentSize.width}px`,
|
||||||
|
'--content-height': `${contentSize.height}px`,
|
||||||
|
} as React.CSSProperties), [contentSize.width, contentSize.height]);
|
||||||
|
|
||||||
|
return <iframe
|
||||||
id={props.viewId}
|
id={props.viewId}
|
||||||
width={contentSize.width}
|
style={style}
|
||||||
height={contentSize.height}
|
className={`plugin-user-webview ${props.fitToContent ? '-fit-to-content' : ''} ${props.borderBottom ? '-border-bottom' : ''}`}
|
||||||
fitToContent={props.fitToContent}
|
|
||||||
ref={viewRef}
|
ref={viewRef}
|
||||||
src="services/plugins/UserWebviewIndex.html"
|
src="services/plugins/UserWebviewIndex.html"
|
||||||
borderBottom={props.borderBottom}
|
></iframe>;
|
||||||
></StyledFrame>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default forwardRef(UserWebview);
|
export default forwardRef(UserWebview);
|
||||||
|
|
|
@ -7,18 +7,12 @@ import UserWebview, { Props as UserWebviewProps } from './UserWebview';
|
||||||
import UserWebviewDialogButtonBar from './UserWebviewDialogButtonBar';
|
import UserWebviewDialogButtonBar from './UserWebviewDialogButtonBar';
|
||||||
import { focus } from '@joplin/lib/utils/focusHandler';
|
import { focus } from '@joplin/lib/utils/focusHandler';
|
||||||
import Dialog from '../../gui/Dialog';
|
import Dialog from '../../gui/Dialog';
|
||||||
const styled = require('styled-components').default;
|
|
||||||
|
|
||||||
interface Props extends UserWebviewProps {
|
interface Props extends UserWebviewProps {
|
||||||
buttons: ButtonSpec[];
|
buttons: ButtonSpec[];
|
||||||
fitToContent: boolean;
|
fitToContent: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const UserWebViewWrapper = styled.div`
|
|
||||||
display: flex;
|
|
||||||
flex: 1;
|
|
||||||
`;
|
|
||||||
|
|
||||||
function defaultButtons(): ButtonSpec[] {
|
function defaultButtons(): ButtonSpec[] {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
|
@ -84,7 +78,7 @@ export default function UserWebviewDialog(props: Props) {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog className={`user-webview-dialog ${props.fitToContent ? '-fit' : ''}`}>
|
<Dialog className={`user-webview-dialog ${props.fitToContent ? '-fit' : ''}`}>
|
||||||
<UserWebViewWrapper>
|
<div className='user-dialog-wrapper'>
|
||||||
<UserWebview
|
<UserWebview
|
||||||
ref={webviewRef}
|
ref={webviewRef}
|
||||||
html={props.html}
|
html={props.html}
|
||||||
|
@ -98,7 +92,7 @@ export default function UserWebviewDialog(props: Props) {
|
||||||
onDismiss={onDismiss}
|
onDismiss={onDismiss}
|
||||||
onReady={onReady}
|
onReady={onReady}
|
||||||
/>
|
/>
|
||||||
</UserWebViewWrapper>
|
</div>
|
||||||
<UserWebviewDialogButtonBar buttons={buttons}/>
|
<UserWebviewDialogButtonBar buttons={buttons}/>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
);
|
);
|
||||||
|
|
|
@ -5,20 +5,10 @@ import { ButtonSpec } from '@joplin/lib/services/plugins/api/types';
|
||||||
const styled = require('styled-components').default;
|
const styled = require('styled-components').default;
|
||||||
const { space } = require('styled-system');
|
const { space } = require('styled-system');
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
|
|
||||||
type StyleProps = any;
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
buttons: ButtonSpec[];
|
buttons: ButtonSpec[];
|
||||||
}
|
}
|
||||||
|
|
||||||
const StyledRoot = styled.div`
|
|
||||||
display: flex;
|
|
||||||
width: 100%;
|
|
||||||
box-sizing: border-box;
|
|
||||||
justify-content: flex-end;
|
|
||||||
padding-top: ${(props: StyleProps) => props.theme.mainPadding}px;
|
|
||||||
`;
|
|
||||||
|
|
||||||
const StyledButton = styled(Button)`${space}`;
|
const StyledButton = styled(Button)`${space}`;
|
||||||
|
|
||||||
|
@ -48,8 +38,8 @@ export default function UserWebviewDialogButtonBar(props: Props) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledRoot>
|
<div className='user-dialog-button-bar'>
|
||||||
{renderButtons()}
|
{renderButtons()}
|
||||||
</StyledRoot>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
@use './plugin-user-webview.scss';
|
||||||
|
@use './user-dialog-wrapper.scss';
|
||||||
|
@use './user-dialog-button-bar.scss';
|
|
@ -0,0 +1,17 @@
|
||||||
|
|
||||||
|
.plugin-user-webview {
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
border: none;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
&.-border-bottom {
|
||||||
|
border-bottom: 1px solid var(--joplin-divider-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.-fit-to-content {
|
||||||
|
width: var(--content-width);
|
||||||
|
height: var(--content-height);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
|
||||||
|
.user-dialog-button-bar {
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
justify-content: flex-end;
|
||||||
|
padding-top: var(--joplin-main-padding);
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
|
||||||
|
.user-dialog-wrapper {
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
}
|
|
@ -11,6 +11,7 @@
|
||||||
@use 'gui/UpdateNotification/style.scss' as update-notification;
|
@use 'gui/UpdateNotification/style.scss' as update-notification;
|
||||||
@use 'gui/TrashNotification/style.scss' as trash-notification;
|
@use 'gui/TrashNotification/style.scss' as trash-notification;
|
||||||
@use 'gui/Sidebar/style.scss' as sidebar-styles;
|
@use 'gui/Sidebar/style.scss' as sidebar-styles;
|
||||||
@use 'gui/styles/index.scss';
|
@use 'gui/NoteEditor/style.scss' as note-editor-styles;
|
||||||
@use 'gui/NoteEditor/style.scss';
|
@use 'services/plugins/styles/index.scss' as plugins-styles;
|
||||||
|
@use 'gui/styles/index.scss' as gui-styles;
|
||||||
@use 'main.scss' as main;
|
@use 'main.scss' as main;
|
||||||
|
|
Loading…
Reference in New Issue