0
0
mirror of https://github.com/naturalcrit/homebrewery.git synced 2026-01-05 18:52:38 +00:00

Add View Mode Options

Adds a new AnchoredBox component that is functionally a clone of the "saving error" notifications, but drops a lot of the JS in favor of the new (chrome-only!) CSS Anchor Positioning API.  In subsequent commits, either alternate styling or a polyfill will be added non-supported browsers.

The box contains a few inputs that modify the CSS applied to `.pages`, most critically a "start on right" toggle for the Facing Pages mode.
This commit is contained in:
Gazook89
2024-10-06 21:51:44 -05:00
parent 9fce94af63
commit d6d6cc1e29
5 changed files with 148 additions and 5 deletions

View File

@@ -67,7 +67,8 @@ const BrewRenderer = (props)=>{
height : PAGE_HEIGHT,
isMounted : false,
visibility : 'hidden',
zoom : 100
zoom : 100,
pagesStyle : null
});
const mainRef = useRef(null);
@@ -187,6 +188,13 @@ const BrewRenderer = (props)=>{
}));
};
const handleStyle = (newStyle)=>{
setState((prevState)=>({
...prevState,
pagesStyle : { ...prevState.pagesStyle, ...newStyle },
}));
};
return (
<>
{/*render dummy page while iFrame is mounting.*/}
@@ -204,7 +212,7 @@ const BrewRenderer = (props)=>{
<NotificationPopup />
</div>
<ToolBar onZoomChange={handleZoom} currentPage={props.currentBrewRendererPageNum} totalPages={rawPages.length}/>
<ToolBar onZoomChange={handleZoom} currentPage={props.currentBrewRendererPageNum} totalPages={rawPages.length} onStyleChange={handleStyle} />
{/*render in iFrame so broken code doesn't crash the site.*/}
<Frame id='BrewRenderer' initialContent={INITIAL_CONTENT}
@@ -223,7 +231,7 @@ const BrewRenderer = (props)=>{
&&
<>
{renderStyle()}
<div className='pages' lang={`${props.lang || 'en'}`} style={{ zoom: `${state.zoom}%` }}>
<div className='pages' lang={`${props.lang || 'en'}`} style={{ zoom: `${state.zoom}%`, ...state.pagesStyle }}>
{renderPages()}
</div>
</>

View File

@@ -3,16 +3,19 @@ const React = require('react');
const { useState, useEffect } = React;
const _ = require('lodash');
import AnchoredBox from '../../../components/anchoredBox.jsx';
// import * as ZoomIcons from '../../../icons/icon-components/zoomIcons.jsx';
const MAX_ZOOM = 300;
const MIN_ZOOM = 10;
const ToolBar = ({ onZoomChange, currentPage, onPageChange, totalPages })=>{
const ToolBar = ({ onZoomChange, currentPage, onPageChange, totalPages, onStyleChange })=>{
const [zoomLevel, setZoomLevel] = useState(100);
const [pageNum, setPageNum] = useState(currentPage);
const [arrangement, setArrangement] = useState('single');
const [startOnRight, setStartOnRight] = useState(true);
const [pagesStyle, setPagesStyle] = useState({});
const [toolsVisible, setToolsVisible] = useState(true);
const modes = ['single', 'facing', 'flow'];
@@ -25,6 +28,7 @@ const ToolBar = ({ onZoomChange, currentPage, onPageChange, totalPages })=>{
}, [currentPage]);;
// update display arrangement when arrangement state is changed.
// todo: do this the 'react' way, without querying the dom.
useEffect(()=>{
const iframe = document.getElementById('BrewRenderer');
const pagesContainer = iframe?.contentWindow?.document.querySelector('.pages');
@@ -35,7 +39,6 @@ const ToolBar = ({ onZoomChange, currentPage, onPageChange, totalPages })=>{
['recto', 'verso'].forEach((leaf)=>pagesContainer.classList.remove(leaf));
pagesContainer.classList.add(startOnRight ? 'recto' : 'verso');
}
}, [arrangement]);
}, [arrangement, startOnRight]);
@@ -152,6 +155,19 @@ const ToolBar = ({ onZoomChange, currentPage, onPageChange, totalPages })=>{
>
{arrangement}
</button>
<AnchoredBox id='view-mode-options' className='tool' title='Options'>
<label title='Modify the horizontal space between pages.'>Column gap<input type='range' min={0} max={200} className='range-input' onChange={(evt)=>onStyleChange({ columnGap: `${evt.target.value}px` })} /></label>
<label title='Modify the vertical space between rows of pages.'>Row gap<input type='range' min={0} max={200} className='range-input' onChange={(evt)=>onStyleChange({ rowGap: `${evt.target.value}px` })} /></label>
<h2>Facing</h2>
<label title='Start 1st page on the right side, such as if you have cover page.'>Start on right
<input type='checkbox'
onChange={()=>setStartOnRight(!startOnRight)}
checked={startOnRight}
disabled={arrangement !== 'facing' ? true : false}
title={arrangement !== 'facing' ? 'Switch to Facing to enable toggle.' : null} />
</label>
</AnchoredBox>
</div>
<div className='group'>

View File

@@ -34,6 +34,13 @@
align-items : center;
}
.anchored-box {
color: #CCCCCC;
input[type='number']{
width: 4ch;
}
}
input {
position : relative;
height : 1.5em;