a tool for shared writing and social publishing

add text align justified

+48 -5
+4 -1
app/lish/[did]/[publication]/[rkey]/PostContent.tsx
··· 97 97 ? "text-right justify-end" 98 98 : b.alignment === "lex:pub.leaflet.pages.linearDocument#textAlignCenter" 99 99 ? "text-center justify-center" 100 - : ""; 100 + : b.alignment === 101 + "lex:pub.leaflet.pages.linearDocument#textAlignJustify" 102 + ? "text-justify justify-start" 103 + : ""; 101 104 if (!alignment && PubLeafletBlocksImage.isMain(b.block)) 102 105 alignment = "text-center justify-center"; 103 106
+1
components/Blocks/Block.tsx
··· 247 247 left: "justify-start", 248 248 right: "justify-end", 249 249 center: "justify-center", 250 + justify: "justify-start", 250 251 }[alignment]; 251 252 252 253 if (!BlockTypeComponent) return <div>unknown block</div>;
+2
components/Blocks/TextBlock/index.tsx
··· 133 133 left: "text-left", 134 134 right: "text-right", 135 135 center: "text-center", 136 + justify: "text-justify", 136 137 }[alignment]; 137 138 let { permissions } = useEntitySetContext(); 138 139 ··· 198 199 left: "text-left", 199 200 right: "text-right", 200 201 center: "text-center", 202 + justify: "text-justify", 201 203 }[alignment]; 202 204 203 205 let value = useYJSValue(props.entityID);
+31 -2
components/Toolbar/TextAlignmentToolbar.tsx
··· 1 1 import { useUIState } from "src/useUIState"; 2 2 import { ToolbarButton } from "."; 3 3 import { useCallback } from "react"; 4 - import { useEntity, useReplicache } from "src/replicache"; 4 + import { Fact, useEntity, useReplicache } from "src/replicache"; 5 5 import { Props } from "components/Icons/Props"; 6 6 7 7 export function TextAlignmentToolbar() { 8 8 let focusedBlock = useUIState((s) => s.focusedEntity); 9 9 let { rep } = useReplicache(); 10 10 let setAlignment = useCallback( 11 - (alignment: "right" | "center" | "left") => { 11 + (alignment: Fact<"block/text-alignment">["data"]["value"]) => { 12 12 let blocks = useUIState.getState().selectedBlocks; 13 13 if (focusedBlock?.entityType === "page" || !focusedBlock) return null; 14 14 rep?.mutate.assertFact( ··· 41 41 > 42 42 <AlignRightSmall /> 43 43 </ToolbarButton> 44 + 45 + <ToolbarButton 46 + onClick={() => setAlignment("justify")} 47 + tooltipContent="Align Justified" 48 + > 49 + <AlignJustifiedSmall /> 50 + </ToolbarButton> 44 51 </> 45 52 ); 46 53 } ··· 66 73 <AlignLeftSmall /> 67 74 ) : alignment === "center" ? ( 68 75 <AlignCenterSmall /> 76 + ) : alignment === "justify" ? ( 77 + <AlignJustifiedSmall /> 69 78 ) : ( 70 79 <AlignRightSmall /> 71 80 )} ··· 130 139 </svg> 131 140 ); 132 141 }; 142 + 143 + export const AlignJustifiedSmall = (props: Props) => { 144 + return ( 145 + <svg 146 + width="24" 147 + height="24" 148 + viewBox="0 0 24 24" 149 + fill="none" 150 + xmlns="http://www.w3.org/2000/svg" 151 + {...props} 152 + > 153 + <path 154 + fillRule="evenodd" 155 + clipRule="evenodd" 156 + d="M3.5 6.19983C3.5 5.64754 3.94772 5.19983 4.5 5.19983H19.6547C20.2069 5.19983 20.6547 5.64754 20.6547 6.19983C20.6547 6.75211 20.2069 7.19983 19.6547 7.19983H4.5C3.94772 7.19983 3.5 6.75211 3.5 6.19983ZM3.5 12C3.5 11.4477 3.94772 11 4.5 11H19.6547C20.2069 11 20.6547 11.4477 20.6547 12C20.6547 12.5523 20.2069 13 19.6547 13H4.5C3.94772 13 3.5 12.5523 3.5 12ZM4.5 16.7999C3.94772 16.7999 3.5 17.2476 3.5 17.7999C3.5 18.3522 3.94772 18.7999 4.5 18.7999H19.6547C20.2069 18.7999 20.6547 18.3522 20.6547 17.7999C20.6547 17.2476 20.2069 16.7999 19.6547 16.7999H4.5Z" 157 + fill="currentColor" 158 + /> 159 + </svg> 160 + ); 161 + };
+1
lexicons/api/lexicons.ts
··· 557 557 'lex:pub.leaflet.pages.linearDocument#textAlignLeft', 558 558 'lex:pub.leaflet.pages.linearDocument#textAlignCenter', 559 559 'lex:pub.leaflet.pages.linearDocument#textAlignRight', 560 + 'lex:pub.leaflet.pages.linearDocument#textAlignJustify', 560 561 ], 561 562 }, 562 563 },
+1
lexicons/api/types/pub/leaflet/pages/linearDocument.ts
··· 55 55 | 'lex:pub.leaflet.pages.linearDocument#textAlignLeft' 56 56 | 'lex:pub.leaflet.pages.linearDocument#textAlignCenter' 57 57 | 'lex:pub.leaflet.pages.linearDocument#textAlignRight' 58 + | 'lex:pub.leaflet.pages.linearDocument#textAlignJustify' 58 59 | (string & {}) 59 60 } 60 61
+2 -1
lexicons/pub/leaflet/pages/linearDocument.json
··· 41 41 "knownValues": [ 42 42 "#textAlignLeft", 43 43 "#textAlignCenter", 44 - "#textAlignRight" 44 + "#textAlignRight", 45 + "#textAlignJustify" 45 46 ] 46 47 } 47 48 }
+1
lexicons/src/pages/LinearDocument.ts
··· 22 22 "#textAlignLeft", 23 23 "#textAlignCenter", 24 24 "#textAlignRight", 25 + "#textAlignJustify", 25 26 ], 26 27 }, 27 28 },
+5 -1
src/replicache/attributes.ts
··· 183 183 } as const; 184 184 185 185 export const ThemeAttributes = { 186 + "theme/font": { 187 + type: "string", 188 + cardinality: "one", 189 + }, 186 190 "theme/page-leaflet-watermark": { 187 191 type: "boolean", 188 192 cardinality: "one", ··· 312 316 reference: { type: "reference"; value: string }; 313 317 "text-alignment-type-union": { 314 318 type: "text-alignment-type-union"; 315 - value: "right" | "left" | "center"; 319 + value: "right" | "left" | "center" | "justify"; 316 320 }; 317 321 "page-type-union": { type: "page-type-union"; value: "doc" | "canvas" }; 318 322 "block-type-union": {