diff --git a/package.json b/package.json index 9d799cfaf..ae8e127c9 100644 --- a/package.json +++ b/package.json @@ -97,6 +97,7 @@ "@microsoft/api-extractor@^7.35.4": "patch:@microsoft/api-extractor@npm%3A7.35.4#./.yarn/patches/@microsoft-api-extractor-npm-7.35.4-5f4f0357b4.patch" }, "dependencies": { + "purgecss": "^5.0.0", "svgo": "^3.0.2" } } diff --git a/packages/editor/editor.css b/packages/editor/editor.css index c7e02a380..d41f4db7b 100644 --- a/packages/editor/editor.css +++ b/packages/editor/editor.css @@ -20,7 +20,7 @@ --radius-1: 4px; --radius-2: 6px; --radius-3: 9px; - --radius-4: 13px; + --radius-4: 11px; /* Z Index */ --layer-background: 100; --layer-grid: 150; @@ -112,7 +112,7 @@ --color-muted-1: hsl(0, 0%, 0%, 10%); --color-muted-2: hsl(0, 0%, 0%, 4.3%); --color-hint: hsl(0, 0%, 0%, 5.5%); - --color-overlay: hsl(0, 0%, 0% 20%); + --color-overlay: hsl(0, 0%, 0%, 20%); --color-divider: hsl(0, 0%, 91%); --color-panel-contrast: hsl(0, 0%, 100%); --color-panel-overlay: hsl(0, 0%, 100%, 82%); @@ -120,7 +120,7 @@ --color-focus: hsl(214, 100%, 29%); --color-selected: hsl(214, 84%, 56%); --color-selected-contrast: hsl(0, 0%, 100%); - --color-selection-fill: hsl(210, 100%, 56% 2.4%); + --color-selection-fill: hsl(210, 100%, 56%, 24%); --color-selection-stroke: hsl(214, 84%, 56%); --color-text-0: hsl(0, 0%, 11%); --color-text-1: hsl(0, 0%, 18%); @@ -153,16 +153,16 @@ --color-muted-0: hsl(0, 0%, 100%, 2%); --color-muted-1: hsl(0, 0%, 100%, 10%); --color-muted-2: hsl(0, 0%, 100%, 5%); - --color-hint: hsl(0, 0%, 100%, 10%); - --color-overlay: hsl(0, 0%, 0%, 35%); + --color-hint: hsl(0, 0%, 100%, 7%); + --color-overlay: hsl(0, 0%, 0%, 50%); --color-divider: hsl(240, 9%, 25%); - --color-panel-contrast: hsl(240, 13%, 19%); + --color-panel-contrast: hsl(240, 13%, 22%); --color-panel: hsl(220, 8%, 15%); --color-panel-overlay: hsl(210, 11%, 24%, 82%); --color-focus: hsl(217, 76%, 80%); --color-selected: hsl(217, 89%, 61%); --color-selected-contrast: hsl(0, 0%, 100%); - --color-selection-fill: hsl(209, 100%, 57%, 5%); + --color-selection-fill: hsl(209, 100%, 57%, 20%); --color-selection-stroke: hsl(214, 84%, 56%); --color-text-0: hsl(0, 9%, 94%); --color-text-1: hsl(0, 0%, 85%); @@ -175,9 +175,9 @@ /* Shadows */ --shadow-1: 0px 1px 2px hsl(0, 0%, 0%, 16.1%), 0px 1px 3px hsl(0, 0%, 0%, 22%), inset 0px 0px 0px 1px var(--color-panel-contrast); - --shadow-2: 0px 1px 3px hsl(0, 0%, 0%, 46.7%), 0px 2px 6px hsl(0, 0%, 0%, 33.3%), + --shadow-2: 0px 1px 3px hsl(0, 0%, 0%, 66.6%), 0px 2px 6px hsl(0, 0%, 0%, 33%), inset 0px 0px 0px 1px var(--color-panel-contrast); - --shadow-3: 0px 1px 3px hsl(0, 0%, 0%, 46.7%), 0px 2px 12px hsl(0, 0%, 0%, 22%), + --shadow-3: 0px 1px 3px hsl(0, 0%, 0%, 50%), 0px 2px 12px hsl(0, 0%, 0%, 50%), inset 0px 0px 0px 1px var(--color-panel-contrast); } @@ -329,11 +329,6 @@ input, fill: var(--color-brush-fill); } -.tl-screenshot-brush { - stroke: var(--color-text-0); - fill: none; -} - /* -------------------- Scribble -------------------- */ .tl-scribble { @@ -500,13 +495,6 @@ input, stroke: var(--color-selection-stroke); } -.tl-rotate-handle { - stroke: var(--color-selection-stroke); - fill: var(--color-background); - stroke-width: calc(1.5px * var(--tl-scale)); - pointer-events: all; -} - .tl-mobile-rotate__bg { pointer-events: all; cursor: var(--tl-cursor-grab); @@ -538,7 +526,7 @@ input, } .tl-handle__fg { - fill: var(--color-background); + fill: var(--color-selected-contrast); stroke: var(--color-selection-stroke); stroke-width: calc(1.5px * var(--tl-scale)); pointer-events: none; @@ -581,7 +569,6 @@ input, } .tl-image-container, -.tl-video-container, .tl-embed-container { width: 100%; height: 100%; @@ -712,36 +699,6 @@ input, } } -.tl-spinner::after { - content: ''; - box-sizing: border-box; - position: absolute; - top: 50%; - left: 50%; - width: 20px; - height: 20px; - margin-top: -10px; - margin-left: -10px; - border-radius: 50%; - border: 2px solid #ccc; - border-top-color: #000; - animation: spinner 0.6s linear infinite; - pointer-events: none; -} - -/* -------------------- IconShape ------------------- */ - -.tl-iconshape__icon { - pointer-events: all; - width: 100%; - height: 100%; -} - -.tl-icon-preview { - width: 14px; - height: 14px; -} - /* ------------------- Text Shape ------------------- */ .tl-text-shape__wrapper { @@ -845,12 +802,6 @@ input, -webkit-user-select: none; } -.tl-text-edit-container { - position: relative; - width: 100%; - height: 100%; -} - .tl-text-input, .tl-text-content { position: absolute; @@ -1323,21 +1274,6 @@ input, fill: none; } -.tl-frame__hitarea { - border-style: solid; - border-width: calc(8px * var(--tl-scale)); - border-color: transparent; - background: none; - pointer-events: stroke; - box-sizing: border-box; - top: calc(-8px * var(--tl-scale)); - left: calc(-8px * var(--tl-scale)); - width: calc(100% + calc(16px * var(--tl-scale))); - height: calc(100% + calc(16px * var(--tl-scale))); - z-index: 1; - position: absolute; -} - .tl-frame-heading { display: flex; align-items: center; @@ -1422,39 +1358,6 @@ input, border-radius: var(--radius-2); } -/* ------------------- Code Editor ------------------ */ - -.tl-image__button { - padding: 4px 8px; - color: var(--color-text); - background-color: var(--color-panel); - border-radius: var(--radius-2); - box-shadow: var(--shadow-1); - pointer-events: all; - cursor: var(--tl-cursor-pointer); - outline: none; - display: flex; -} - -.tl-image__button:disabled { - opacity: 0.5; - pointer-events: none; -} - -.tl-image__toolbox { - position: absolute; - top: 0px; - left: 0px; - display: flex; - justify-content: flex-end; - align-items: flex-end; - padding: 10px; -} - -.tl-image__toolbox__hidden { - display: none; -} - /* -------------- Shape Error Boundary -------------- */ .tl-shape-error-boundary { @@ -1636,13 +1539,6 @@ it from receiving any pointer events or affecting the cursor. */ /* --------------------- Coarse --------------------- */ -@media screen and (pointer: coarse) { - /* If mobile always show handle-hint as there is no hover state */ - .tl-canvas__mobile .tl-handle__hint { - opacity: 1; - } -} - .tl-hidden { opacity: 0; pointer-events: none; diff --git a/packages/tldraw/src/lib/shapes/arrow/ArrowShapeUtil.tsx b/packages/tldraw/src/lib/shapes/arrow/ArrowShapeUtil.tsx index 99a54ef61..186b2c55c 100644 --- a/packages/tldraw/src/lib/shapes/arrow/ArrowShapeUtil.tsx +++ b/packages/tldraw/src/lib/shapes/arrow/ArrowShapeUtil.tsx @@ -567,6 +567,7 @@ export class ArrowShapeUtil extends ShapeUtil { // eslint-disable-next-line react-hooks/rules-of-hooks const theme = useDefaultColorTheme() const onlySelectedShape = this.editor.getOnlySelectedShape() + const shouldDisplayHandles = this.editor.isInAny( 'select.idle', diff --git a/packages/tldraw/src/lib/ui.css b/packages/tldraw/src/lib/ui.css index 757765358..676dca1f7 100644 --- a/packages/tldraw/src/lib/ui.css +++ b/packages/tldraw/src/lib/ui.css @@ -595,8 +595,8 @@ position: relative; z-index: var(--layer-panels); width: fit-content; - border-right: 4px solid var(--color-background); - border-bottom: 4px solid var(--color-background); + border-right: 2px solid var(--color-background); + border-bottom: 2px solid var(--color-background); border-bottom-right-radius: var(--radius-4); background-color: var(--color-low); } @@ -614,7 +614,7 @@ background-color: var(--color-panel); height: fit-content; max-height: 100%; - margin: 4px 8px; + margin: 8px; touch-action: auto; overscroll-behavior: none; overflow-y: auto; @@ -665,11 +665,6 @@ margin-left: -2px; } -.tlui-style-panel__double-select-picker__wrapper { - width: 100%; - max-width: 100%; -} - .tlui-style-panel__double-select-picker { display: flex; grid-template-columns: 1fr auto; @@ -743,56 +738,6 @@ } } -/* ---------------- Prompt ---------------- */ - -.tlui-prompt__overlay { - background: var(--color-overlay); - position: fixed; - top: 0px; - left: 0px; - right: 0px; - bottom: 0px; - display: grid; - place-items: center; - overflow-y: auto; - z-index: var(--layer-overlays); -} - -.tlui-prompt__content { - cursor: default; - background-color: var(--color-panel); - box-shadow: var(--shadow-3); - border-radius: var(--radius-4); - padding: var(--space-5); - font-size: 12px; - overflow-y: auto; - min-width: 300px; - max-width: 80vw; - max-height: 80vh; -} - -.tlui-prompt__actions { - border: none; - padding: 0px; - margin: 0px; - display: flex; - justify-content: flex-end; - margin-right: calc(-1 * var(--space-3)); - margin-bottom: calc(-1 * var(--space-3)); -} - -.tlui-prompt__title { - margin: 0px; - font-size: 12px; -} - -.tlui-prompt__error { - color: #d10b0b; - display: flex; - gap: var(--space-2); - align-items: center; -} - /* ---------------- Dialog ---------------- */ .tlui-dialog__overlay { @@ -905,7 +850,7 @@ z-index: 1; width: 100%; pointer-events: none; - top: 4px; + top: 6px; height: 48px; } @@ -917,7 +862,7 @@ background-color: var(--color-low); border-top-left-radius: var(--radius-4); border-top-right-radius: var(--radius-4); - border: 4px solid var(--color-background); + border: 2px solid var(--color-background); margin-left: 8px; margin-right: 0px; pointer-events: all; @@ -928,7 +873,7 @@ display: flex; flex-direction: row; background-color: var(--color-low); - border-radius: 11px; + border-radius: var(--radius-4); z-index: var(--layer-panels); pointer-events: all; position: relative; @@ -960,7 +905,7 @@ bottom: var(--space-2); right: var(--space-2); z-index: var(--layer-panels); - border: 4px solid var(--color-background); + border: 2px solid var(--color-background); border-radius: 100%; } @@ -1172,10 +1117,10 @@ display: block; position: absolute; z-index: -1; - inset: -4px -4px 0px 0px; + inset: -2px -2px 0px 0px; border-radius: 0; - border-top: 4px solid var(--color-background); - border-right: 4px solid var(--color-background); + border-top: 2px solid var(--color-background); + border-right: 2px solid var(--color-background); border-top-right-radius: var(--radius-4); background-color: var(--color-low); } @@ -1450,34 +1395,6 @@ padding-bottom: var(--space-5); } -.tlui-embed-dialog__item { - position: relative; - border: none; - background: none; - font-family: inherit; - display: flex; - text-align: left; - gap: var(--space-3); - margin: 0px -8px; - cursor: pointer; - padding: 0px 4px; - align-items: center; - color: var(--color-text); - font-size: var(--font-size-1); - height: 44px; -} - -@media (hover: hover) { - .tlui-embed-dialog__item:not(:disabled, :focus-visible):hover::after { - display: block; - content: ''; - position: absolute; - inset: 4px; - background-color: var(--color-muted-2); - border-radius: var(--radius-1); - } -} - .tlui-embed-dialog__item__image { width: 24px; height: 24px; diff --git a/public-yarn.lock b/public-yarn.lock index 521856c12..4cff69d73 100644 --- a/public-yarn.lock +++ b/public-yarn.lock @@ -4481,6 +4481,7 @@ __metadata: lint-staged: ">=10" prettier: ^2.8.6 prettier-plugin-organize-imports: ^3.2.2 + purgecss: ^5.0.0 rimraf: ^4.4.0 svgo: ^3.0.2 tsx: ^3.12.7 @@ -7277,7 +7278,7 @@ __metadata: languageName: node linkType: hard -"commander@npm:^9.4.1": +"commander@npm:^9.0.0, commander@npm:^9.4.1": version: 9.5.0 resolution: "commander@npm:9.5.0" checksum: c7a3e27aa59e913b54a1bafd366b88650bc41d6651f0cbe258d4ff09d43d6a7394232a4dadd0bf518b3e696fdf595db1028a0d82c785b88bd61f8a440cecfade @@ -13923,6 +13924,15 @@ __metadata: languageName: node linkType: hard +"nanoid@npm:^3.3.7": + version: 3.3.7 + resolution: "nanoid@npm:3.3.7" + bin: + nanoid: bin/nanoid.cjs + checksum: d36c427e530713e4ac6567d488b489a36582ef89da1d6d4e3b87eded11eb10d7042a877958c6f104929809b2ab0bafa17652b076cdf84324aa75b30b722204f2 + languageName: node + linkType: hard + "napi-build-utils@npm:^1.0.1": version: 1.0.2 resolution: "napi-build-utils@npm:1.0.2" @@ -14932,6 +14942,16 @@ __metadata: languageName: node linkType: hard +"postcss-selector-parser@npm:^6.0.7": + version: 6.0.15 + resolution: "postcss-selector-parser@npm:6.0.15" + dependencies: + cssesc: ^3.0.0 + util-deprecate: ^1.0.2 + checksum: 57decb94152111004f15e27b9c61131eb50ee10a3288e7fcf424cebbb4aba82c2817517ae718f8b5d704ee9e02a638d4a2acff8f47685c295a33ecee4fd31055 + languageName: node + linkType: hard + "postcss-value-parser@npm:^4.1.0": version: 4.2.0 resolution: "postcss-value-parser@npm:4.2.0" @@ -14950,6 +14970,17 @@ __metadata: languageName: node linkType: hard +"postcss@npm:^8.4.4": + version: 8.4.33 + resolution: "postcss@npm:8.4.33" + dependencies: + nanoid: ^3.3.7 + picocolors: ^1.0.0 + source-map-js: ^1.0.2 + checksum: 6f98b2af4b76632a3de20c4f47bf0e984a1ce1a531cf11adcb0b1d63a6cbda0aae4165e578b66c32ca4879038e3eaad386a6be725a8fb4429c78e3c1ab858fe9 + languageName: node + linkType: hard + "prebuild-install@npm:^7.0.1": version: 7.1.1 resolution: "prebuild-install@npm:7.1.1" @@ -15208,6 +15239,20 @@ __metadata: languageName: node linkType: hard +"purgecss@npm:^5.0.0": + version: 5.0.0 + resolution: "purgecss@npm:5.0.0" + dependencies: + commander: ^9.0.0 + glob: ^8.0.3 + postcss: ^8.4.4 + postcss-selector-parser: ^6.0.7 + bin: + purgecss: bin/purgecss.js + checksum: ea1e1d0d33b8a887ad324b0562b6ae73ef69304422f88f95ea2c4a2a73b975c344e6b65dba77e9502c8bc6f1b0ae0512a7a395365724a85c4686415b5f08a580 + languageName: node + linkType: hard + "pvtsutils@npm:^1.3.2": version: 1.3.2 resolution: "pvtsutils@npm:1.3.2" diff --git a/scripts/purge-css.ts b/scripts/purge-css.ts new file mode 100644 index 000000000..f6fbe5931 --- /dev/null +++ b/scripts/purge-css.ts @@ -0,0 +1,14 @@ +import { PurgeCSS } from 'purgecss' +import { nicelog } from './lib/nicelog' + +async function main() { + const purgeCSSResults = await new PurgeCSS().purge({ + content: ['packages/tldraw/**/*.tsx', 'packages/editor/**/*.tsx'], + css: ['packages/tldraw/src/lib/ui.css'], + rejected: true, + }) + + nicelog(purgeCSSResults) +} + +main()