diff --git a/src/components/Editor/components/Editor.module.scss b/src/components/Editor/components/Editor.module.scss index 894a9dea..cb285d23 100644 --- a/src/components/Editor/components/Editor.module.scss +++ b/src/components/Editor/components/Editor.module.scss @@ -1,3 +1,61 @@ +.editor { + flex: 1; + padding-top: 1em; + + a { + color: rgb(0 100 200); + text-decoration: none; + } + + a:hover { + text-decoration: underline; + } + + a:visited { + color: rgb(0 80 160); + } + + label { + display: block; + } + + input, + button, + select, + textarea { + font-family: inherit; + font-size: inherit; + -webkit-padding: 0.4em 0; + padding: 0.4em; + margin: 0 0 0.5em; + box-sizing: border-box; + border: 1px solid #ccc; + border-radius: 2px; + } + + input:disabled { + color: #ccc; + } + + button { + color: #333; + background-color: #f4f4f4; + outline: none; + } + + button:disabled { + color: #999; + } + + button:not(:disabled):active { + background-color: #ddd; + } + + button:focus { + border-color: #666; + } +} + .error { display: none; } @@ -5,3 +63,11 @@ .markdown { white-space: pre-wrap; } + +.tooltip { + background: #fff; + box-shadow: 0 4px 10px rgb(0 0 0 / 25%); + color: #000; + display: flex; + position: absolute; +} diff --git a/src/components/Editor/components/Editor.tsx b/src/components/Editor/components/Editor.tsx index 3bdcbf3d..0aa84b66 100644 --- a/src/components/Editor/components/Editor.tsx +++ b/src/components/Editor/components/Editor.tsx @@ -2,7 +2,6 @@ import type { EditorView } from 'prosemirror-view' import type { EditorState } from 'prosemirror-state' import { useState } from '../store/context' import { ProseMirror } from './ProseMirror' -import '../styles/Editor.scss' import styles from './Editor.module.scss' import { clsx } from 'clsx' @@ -14,7 +13,7 @@ export const Editor = () => { return ( { const [store] = useState() @@ -24,8 +24,8 @@ const InvalidState = (props: { title: string }) => { const onClick = () => ctrl.clean() return ( -
-
+
+

{props.title}

There is an error with the editor state. This is probably due to an old version in which the data @@ -35,7 +35,7 @@ const InvalidState = (props: { title: string }) => {

           {JSON.stringify(store.error.props)}
         
-
@@ -53,13 +53,13 @@ const Other = () => { } return ( -
-
+
+

An error occurred.

           {getMessage()}
         
-
diff --git a/src/components/Editor/styles/Layout.scss b/src/components/Editor/components/Layout.module.scss similarity index 96% rename from src/components/Editor/styles/Layout.scss rename to src/components/Editor/components/Layout.module.scss index 4bb4bd13..35935670 100644 --- a/src/components/Editor/styles/Layout.scss +++ b/src/components/Editor/components/Layout.module.scss @@ -6,7 +6,7 @@ border-color: var(--background); min-height: 100vh; - &.dark { + .dark & { background: var(--foreground); color: var(--background); border-color: var(--foreground); diff --git a/src/components/Editor/components/Layout.tsx b/src/components/Editor/components/Layout.tsx index eeea10a8..5bb1bcb8 100644 --- a/src/components/Editor/components/Layout.tsx +++ b/src/components/Editor/components/Layout.tsx @@ -1,6 +1,7 @@ import type { JSX } from 'solid-js/jsx-runtime' import type { Config } from '../store/context' -import '../styles/Layout.scss' +import { clsx } from 'clsx' +import styles from './Layout.module.scss' export type Styled = { children: JSX.Element @@ -12,7 +13,11 @@ export type Styled = { export const Layout = (props: Styled) => { return ( -
+
{props.children}
) diff --git a/src/components/Editor/components/ProseMirror.tsx b/src/components/Editor/components/ProseMirror.tsx index 1f1c9a86..231036b7 100644 --- a/src/components/Editor/components/ProseMirror.tsx +++ b/src/components/Editor/components/ProseMirror.tsx @@ -4,6 +4,7 @@ import { EditorState, EditorStateConfig, Transaction } from 'prosemirror-state' import { EditorView } from 'prosemirror-view' import { Schema } from 'prosemirror-model' import type { NodeViewFn, ProseMirrorExtension, ProseMirrorState } from '../prosemirror/helpers' +import '../styles/ProseMirror.scss' interface ProseMirrorProps { cssClass?: string diff --git a/src/components/Editor/components/Sidebar.module.scss b/src/components/Editor/components/Sidebar.module.scss index a626b942..187cd08b 100644 --- a/src/components/Editor/components/Sidebar.module.scss +++ b/src/components/Editor/components/Sidebar.module.scss @@ -1,3 +1,221 @@ -.withMargin { - margin-bottom: 10px; +.sidebarContainer { + color: rgb(255 255 255 / 50%); + @include font-size(1.6rem); + + overflow: hidden; + position: relative; + top: 0; + + p { + color: var(--foreground); + } + + h4 { + @include font-size(120%); + + margin-left: 1rem; + } + + button { + height: auto; + min-height: 50px; + padding: 0 1rem; + width: 100%; + } +} + +.sidebarOff { + background: #1f1f1f; + height: 100%; + min-height: 100vh; + padding: 40px 20px 20px; + top: 0; + transform: translateX(0); + transition: transform 0.3s; + overflow-y: auto; + scrollbar-width: none; + width: 350px; + + .sidebarContainerHidden & { + transform: translateX(100%); + } + + ::-webkit-scrollbar { + display: none; + } +} + +.sidebarOpener { + color: #000; + cursor: pointer; + opacity: 1; + position: absolute; + top: 1em; + transition: opacity 0.3s; + + &:hover { + opacity: 0.5; + } + + &::after { + background-image: url("data:image/svg+xml,%3Csvg width='18' height='18' viewBox='0 0 18 18' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cmask id='mask0_1090_23825' style='mask-type:alpha' maskUnits='userSpaceOnUse' x='0' y='14' width='4' height='4'%3E%3Crect y='14.8237' width='3.17647' height='3.17647' fill='%23fff'/%3E%3C/mask%3E%3Cg mask='url(%23mask0_1090_23825)'%3E%3Cpath d='M16.0941 1.05908H0.847027C0.379194 1.05908 0 1.43828 0 1.90611V18.0003L3.38824 14.612H16.0942C16.562 14.612 16.9412 14.2328 16.9412 13.765V1.90614C16.9412 1.43831 16.562 1.05912 16.0942 1.05912L16.0941 1.05908ZM15.2471 12.9179H1.69412V2.7532H15.2471V12.9179Z' fill='black'/%3E%3C/g%3E%3Crect x='1' y='1' width='16' height='12.8235' stroke='black' stroke-width='2'/%3E%3Crect x='4.23535' y='3.17627' width='9.52941' height='2.11765' fill='black'/%3E%3Crect x='4.23535' y='9.5293' width='7.41176' height='2.11765' fill='black'/%3E%3Crect x='4.23535' y='6.35303' width='5.29412' height='2.11765' fill='black'/%3E%3C/svg%3E"); + content: ''; + height: 18px; + left: 100%; + margin-left: 0.3em; + position: absolute; + top: 50%; + transform: translateY(-50%); + width: 18px; + } +} + +.sidebarCloser { + background-image: url("data:image/svg+xml,%3Csvg width='16' height='16' viewBox='0 0 16 16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M13.1517 0.423857L0.42375 13.1518L2.84812 15.5761L15.576 2.84822L13.1517 0.423857Z M15.576 13.1518L2.84812 0.423855L0.423751 2.84822L13.1517 15.5761L15.576 13.1518Z' fill='white'/%3E%3C/svg%3E%0A"); + cursor: pointer; + height: 16px; + opacity: 1; + position: absolute; + transition: opacity 0.3s; + top: 20px; + width: 16px; + + &:hover { + opacity: 0.5; + } +} + +.sidebarLabel { + color: var(--foreground); + + > i { + text-transform: none; + } +} + +.sidebarContainer button, +.sidebarContainer a, +.sidebarItem { + margin: 0; + outline: none; + display: flex; + align-items: center; + line-height: 24px; + text-align: left; +} + +.sidebarContainer a, +.sidebarItem { + font-size: 18px; + padding: 2px 0; + width: 100%; +} + +.sidebarLink { + background: none; + border: 0; + color: inherit; + cursor: pointer; + font-size: inherit; + justify-content: flex-start; + + &:hover { + color: #fff !important; + } + + &:active { + > span i { + position: relative; + box-shadow: none; + top: 1px; + } + } + + &[disabled] { + color: var(--foreground); + cursor: not-allowed; + } + + &.draft { + color: rgb(255 255 255 / 50%); + line-height: 1.4; + margin: 0 0 1em 1.5em; + width: calc(100% - 2rem); + + &:hover { + background: none; + } + } + + > span { + justify-self: flex-end; + margin-left: auto; + + > i { + border: 1px solid; + border-bottom-width: 2px; + border-radius: 0.2rem; + display: inline-block; + color: inherit; + font-size: 13px; + line-height: 1.4; + margin: 0 0.5em 0 0; + padding: 1px 4px; + + &:last-child { + text-transform: uppercase; + } + } + } +} + +.themeSwitcher { + border-bottom: 1px solid rgb(255 255 255 / 30%); + border-top: 1px solid rgb(255 255 255 / 30%); + display: flex; + justify-content: space-between; + margin: 1rem; + padding: 1em 0; + + input[type='checkbox'] { + opacity: 0; + position: absolute; + + + label { + background: url("data:image/svg+xml,%3Csvg width='10' height='10' viewBox='0 0 10 10' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M6.20869 7.73227C5.22953 7.36499 4.38795 6.70402 3.79906 5.83976C3.2103 4.97565 2.90318 3.95064 2.91979 2.90512C2.93639 1.8597 3.27597 0.844915 3.8919 0C2.82862 0.254038 1.87585 0.844877 1.17594 1.68438C0.475894 2.52388 0.0660276 3.5671 0.00731938 4.6585C-0.0513888 5.74989 0.244296 6.83095 0.850296 7.74073C1.45631 8.65037 2.34006 9.33992 3.36994 9.70637C4.39987 10.073 5.52063 10.0969 6.56523 9.77466C7.60985 9.45247 8.52223 8.80134 9.16667 7.91837C8.1842 8.15404 7.15363 8.08912 6.20869 7.73205V7.73227Z' fill='white'/%3E%3C/svg%3E%0A") + no-repeat 30px 9px, + url("data:image/svg+xml,%3Csvg width='12' height='12' viewBox='0 0 12 12' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M6.41196 0H5.58811V2.43024H6.41196V0ZM5.99988 8.96576C4.36601 8.96576 3.03419 7.63397 3.03419 6.00007C3.04792 4.3662 4.36598 3.04818 5.99988 3.03439C7.63375 3.03439 8.96557 4.3662 8.96557 6.00007C8.96557 7.63395 7.63375 8.96576 5.99988 8.96576ZM5.58811 9.56977H6.41196V12H5.58811V9.56977ZM12.0002 5.58811H9.56996V6.41196H12.0002V5.58811ZM0 5.58811H2.43024V6.41196H0V5.58811ZM8.81339 3.76727L10.5318 2.04891L9.94925 1.46641L8.23089 3.18477L8.81339 3.76727ZM3.7745 8.8129L2.05614 10.5313L1.47364 9.94877L3.192 8.2304L3.7745 8.8129ZM9.95043 10.5269L10.5329 9.94437L8.81456 8.22601L8.23207 8.80851L9.95043 10.5269ZM3.76864 3.18731L3.18614 3.76981L1.46778 2.05145L2.05028 1.46895L3.76864 3.18731Z' fill='%231F1F1F'/%3E%3C/svg%3E%0A") + #000 no-repeat 8px 8px; + border-radius: 14px; + cursor: pointer; + display: block; + height: 28px; + line-height: 10em; + overflow: hidden; + position: relative; + transition: background-color 0.3s; + width: 46px; + + &::before { + background-color: #fff; + border-radius: 100%; + content: ''; + height: 16px; + left: 6px; + position: absolute; + top: 6px; + transition: left 0.3s, color 0.3s; + width: 16px; + } + } + + &:checked + label { + background-color: #fff; + + &::before { + background-color: #1f1f1f; + left: 24px; + } + } + } } diff --git a/src/components/Editor/components/Sidebar.tsx b/src/components/Editor/components/Sidebar.tsx index 03141f07..043f5660 100644 --- a/src/components/Editor/components/Sidebar.tsx +++ b/src/components/Editor/components/Sidebar.tsx @@ -5,20 +5,21 @@ import { Draft, useState } from '../store/context' import * as remote from '../remote' import { isEmpty } from '../prosemirror/helpers' import type { Styled } from './Layout' -import '../styles/Sidebar.scss' import { clsx } from 'clsx' import styles from './Sidebar.module.scss' -import { isServer } from 'solid-js/web' +import { useOutsideClickHandler } from '../../../utils/useOutsideClickHandler' +import { useEscKeyDownHandler } from '../../../utils/useEscKeyDownHandler' +import { hideModal } from '../../../stores/ui' -const Off = (props) => +const Off = (props) =>
{props.children}
-const Label = (props: Styled) => +const Label = (props: Styled) =>

{props.children}

const Link = ( props: Styled & { withMargin?: boolean; disabled?: boolean; title?: string; className?: string } ) => (