a tool for shared writing and social publishing
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

reorganized block padding so that clicking in between and on the margins of blocks still selects into nearest block - moved padding into text and header blocks - redesigned selected state to still look nice with new architecture - fixed off padding on block options in new block button - adjusted a value in arrow up key map so that up arrow still traverses between blocks despite new increased padding - made adjustments to blocks in the little card preview image to use no padding

celine 09020db6 ebd67843

+52 -23
+1 -1
components/BlockOptions.tsx
··· 31 31 : focusedElement?.parent; 32 32 33 33 return ( 34 - <div className="blockOptionsWrapper absolute top-0 right-0 hidden group-hover/text:block group-focus-within/text:block"> 34 + <div className="blockOptionsWrapper absolute top-0 right-2 sm:right-3 hidden group-hover/text:block group-focus-within/text:block"> 35 35 <div className="blockOptionsContent flex gap-1 items-center"> 36 36 <label className="blockOptionsImage hover:cursor-pointer flex place-items-center"> 37 37 <div className="text-tertiary hover:text-accent ">
+11 -6
components/Blocks.tsx
··· 224 224 } 225 225 useUIState.getState().removeBlockFromSelection(props); 226 226 }} 227 - className={`rounded-md p-1 first:mt-0 mx-1 sm:mx-2 ${ 228 - !selected ? "" : "bg-border-light" 229 - } ${props.type === "heading" ? "mt-1 mb-0" : "mb-2"}`} 227 + // text and heading blocks handle thier own padding so that 228 + // clicking anywhere on them (even the padding between blocks) will focus the textarea 229 + className={`${ 230 + props.type !== "heading" && 231 + props.type !== "text" && 232 + `border-l-4 first:pt-0 pl-1 sm:pl-2 pr-2 sm:pr-3 pt-1 pb-2 ${selected ? "border-tertiary" : "border-transparent"}` 233 + }`} 230 234 id={elementId.block(props.entityID).container} 231 235 > 232 236 {props.type === "card" ? ( ··· 270 274 } 271 275 let nextBlockID = block.value; 272 276 let nextBlock = useEditorStates.getState().editorStates[nextBlockID]; 277 + console.log("yo?"); 273 278 if (!nextBlock || !nextBlock.view) return; 274 279 nextBlock.view.focus(); 275 280 let nextBlockViewClientRect = nextBlock.view.dom.getBoundingClientRect(); ··· 282 287 : nextBlock.view.posAtCoords({ 283 288 top: 284 289 top === "top" 285 - ? nextBlockViewClientRect.top + 2 286 - : nextBlockViewClientRect.bottom - 2, 290 + ? nextBlockViewClientRect.top + 12 291 + : nextBlockViewClientRect.bottom - 12, 287 292 left, 288 293 }); 289 - 294 + console.log(pos); 290 295 let newState = nextBlock.editor.apply( 291 296 tr.setSelection(TextSelection.create(tr.doc, pos?.pos || 0)), 292 297 );
+7 -7
components/CardBlock.tsx
··· 73 73 let blocks = useEntity(props.entityID, "card/block"); 74 74 return ( 75 75 <div 76 - className={`cardBlockPreview w-[120px] p-1 m-2 -mb-2 bg-bg-card border shrink-0 border-border-light flex flex-col gap-1 rotate-6 origin-center`} 76 + className={`cardBlockPreview w-[120px] p-1 mx-3 mt-3 -mb-2 bg-bg-card border rounded-md shrink-0 border-border-light flex flex-col gap-1 rotate-[4deg] origin-center`} 77 77 > 78 78 {blocks 79 79 .sort((a, b) => (a.data.position > b.data.position ? 1 : -1)) ··· 89 89 switch (type?.data.value) { 90 90 case "text": { 91 91 return ( 92 - <div style={{ fontSize: "3px" }}> 93 - <RenderedTextBlock entityID={props.entityID} /> 92 + <div style={{ fontSize: "4px" }}> 93 + <RenderedTextBlock entityID={props.entityID} preview /> 94 94 </div> 95 95 ); 96 96 } ··· 111 111 let headingLevel = useEntity(props.entityID, "block/heading-level"); 112 112 return ( 113 113 <div className={HeadingStyle[headingLevel?.data.value || 1]}> 114 - <RenderedTextBlock entityID={props.entityID} /> 114 + <RenderedTextBlock entityID={props.entityID} preview /> 115 115 </div> 116 116 ); 117 117 } 118 118 119 119 const HeadingStyle = { 120 - 1: "text-[5px] font-bold", 121 - 2: "text-[4px] font-bold ", 122 - 3: "text-[3px] font-bold italic text-secondary ", 120 + 1: "text-[6px] font-bold", 121 + 2: "text-[5px] font-bold ", 122 + 3: "text-[4px] font-bold italic text-secondary ", 123 123 } as { [level: number]: string }; 124 124 125 125 function ImagePreviewBlock(props: { entityID: string }) {
+31 -8
components/TextBlock/index.tsx
··· 65 65 66 66 export function TextBlock(props: BlockProps & { className: string }) { 67 67 let initialized = useInitialPageLoad(); 68 + let first = props.previousBlock === null; 68 69 return ( 69 70 <> 70 71 {!initialized && ( 71 72 <RenderedTextBlock 72 73 entityID={props.entityID} 73 74 className={props.className} 75 + type={props.type} 76 + first={first} 74 77 /> 75 78 )} 76 79 <div className={`relative group/text ${!initialized ? "hidden" : ""}`}> ··· 84 87 entityID: string; 85 88 className?: string; 86 89 placeholder?: string; 90 + type?: string; 91 + first?: boolean; 92 + preview?: boolean; 87 93 }) { 88 94 let initialFact = useEntity(props.entityID, "block/text"); 89 - if (!initialFact) return <pre className="min-h-6" />; 95 + if (!initialFact) return <pre className="min-h-9 " />; 90 96 let doc = new Y.Doc(); 91 97 const update = base64.toByteArray(initialFact.data.value); 92 98 Y.applyUpdate(doc, update); ··· 94 100 95 101 return ( 96 102 <pre 97 - className={`w-full whitespace-pre-wrap outline-none ${props.className}`} 103 + className={` 104 + w-full whitespace-pre-wrap outline-none ${props.className} ${ 105 + props.preview 106 + ? "p-0" 107 + : `px-2 sm:px-3 ${ 108 + props.type === "heading" ? "pt-1 pb-0 " : "pt-1 pb-2" 109 + } ${props.first ? "pt-0" : "pt-1"}` 110 + }`} 98 111 > 99 112 {nodes.map((node, index) => ( 100 113 <RenderYJSFragment key={index} node={node} /> ··· 107 120 let selected = useUIState((s) => 108 121 s.selectedBlock.find((b) => b.value === props.entityID), 109 122 ); 123 + let first = props.previousBlock === null; 124 + 110 125 let [value, factID] = useYJSValue(props.entityID); 111 126 let repRef = useRef<null | Replicache<ReplicacheMutators>>(null); 112 127 let propsRef = useRef(props); ··· 370 385 })); 371 386 }} 372 387 id={elementId.block(props.entityID).text} 373 - className={`textBlock w-full p-0 border-none outline-none resize-none align-top bg-transparent whitespace-pre-wrap ${props.className}`} 388 + className={` 389 + textBlock 390 + w-full pl-1 pr-2 sm:pl-2 sm:pr-3 pt-1 391 + border-l-4 outline-none 392 + resize-none align-top whitespace-pre-wrap bg-transparent ${ 393 + selected ? " border-border" : "border-transparent" 394 + } ${first ? "pt-0" : "pt-1"} ${props.type === "heading" ? "pb-0" : "pb-2"} ${props.className}`} 374 395 ref={setMount} 375 396 /> 376 397 377 - {editorState.doc.textContent.length === 0 && props.position === "a0" && ( 378 - <div className="pointer-events-none absolute top-0 left-0 italic text-tertiary"> 379 - write something... 380 - </div> 381 - )} 398 + {editorState.doc.textContent.length === 0 && 399 + props.position === "a0" && 400 + props.nextBlock === null && ( 401 + <div className="pointer-events-none absolute top-0 left-0 px-2 sm:px-3 pt-1 pb-2 italic text-tertiary"> 402 + write something... 403 + </div> 404 + )} 382 405 {editorState.doc.textContent.length === 0 && selected && ( 383 406 <BlockOptions 384 407 factID={factID}
+2 -1
components/TextBlock/keymap.ts
··· 91 91 if (view.state.selection.from !== view.state.selection.to) return false; 92 92 const viewClientRect = view.dom.getBoundingClientRect(); 93 93 const coords = view.coordsAtPos(view.state.selection.anchor); 94 - if (coords.top - viewClientRect.top < 5) { 94 + console.log(coords.top - viewClientRect.top); 95 + if (coords.top - viewClientRect.top < 12) { 95 96 let block = propsRef.current.previousBlock; 96 97 if (block) { 97 98 view.dom.blur();