Align and standardize settings data source list layout
Aligns the "Data source" list items in the side panel by resolving a browser-specific layout discrepancy where icons with different intrinsic widths (e.g., "edit" vs "calendar") caused uneven text indentation and vertical misalignment. - Refactored `SourceHead` in `head.tsx` to wrap all list icons in a `list-icon-wrapper` container instead of using `<List.Icon>` directly. - Added CSS rules in `index.css` to format `.list-icon-wrapper` and its sibling `.content` as table cells aligned at the top, with a fixed width of `20px` for the icon column. - Converted relative sizing (`em`) to absolute pixels (`px`) for pixel-perfect cross-browser precision. - Updated Playwright visual regression snapshots to match the newly aligned and corrected UI layout.
@@ -154,6 +154,28 @@ div.zoom {
|
||||
padding: 0 15px 0 25px;
|
||||
}
|
||||
|
||||
.details .ui.list .item > .list-icon-wrapper {
|
||||
display: table-cell;
|
||||
width: 20px;
|
||||
text-align: center;
|
||||
vertical-align: top;
|
||||
padding-right: 4px;
|
||||
}
|
||||
|
||||
.details .ui.list .item > .list-icon-wrapper > i.icon {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
|
||||
.details .ui.list .item > .list-icon-wrapper + .content {
|
||||
display: table-cell;
|
||||
vertical-align: top;
|
||||
padding-left: 8px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
.details .item-header {
|
||||
justify-content: space-between;
|
||||
display: flex;
|
||||
|
||||
@@ -118,10 +118,9 @@ export function ConfigPanel(props: {
|
||||
onChange: (config: Config) => void;
|
||||
}) {
|
||||
return (
|
||||
<>
|
||||
{SourceHead(props.gedcom)}
|
||||
<Form className="details">
|
||||
<Item.Group>
|
||||
{SourceHead(props.gedcom)}
|
||||
<Item>
|
||||
<Item.Content>
|
||||
<Header sub>
|
||||
@@ -359,6 +358,5 @@ export function ConfigPanel(props: {
|
||||
</Item>
|
||||
</Item.Group>
|
||||
</Form>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import {FormattedMessage, useIntl} from 'react-intl';
|
||||
import {Divider, Header, List} from 'semantic-ui-react';
|
||||
import {Divider, Header, Icon, Item, List} from 'semantic-ui-react';
|
||||
import {getDate} from 'topola';
|
||||
import {formatDateOrRange} from '../../util/date_util';
|
||||
import {dereference, GedcomData} from '../../util/gedcom_util';
|
||||
@@ -66,63 +66,81 @@ export function SourceHead(gedcom: GedcomData) {
|
||||
|
||||
// Icons: https://react.semantic-ui.com/elements/icon/
|
||||
return (
|
||||
<>
|
||||
<Item>
|
||||
<Item.Content>
|
||||
<Header sub>
|
||||
<FormattedMessage id="head.source" defaultMessage="Data source" />
|
||||
</Header>
|
||||
<List>
|
||||
{sour_name && (
|
||||
<List.Item>
|
||||
<List.Icon name="edit" />
|
||||
<div className="list-icon-wrapper">
|
||||
<Icon name="edit" />
|
||||
</div>
|
||||
<List.Content>{sour_name}</List.Content>
|
||||
</List.Item>
|
||||
)}
|
||||
|
||||
{date && (
|
||||
<List.Item>
|
||||
<List.Icon name="calendar" />
|
||||
<div className="list-icon-wrapper">
|
||||
<Icon name="calendar" />
|
||||
</div>
|
||||
<List.Content>{dateFormatted}</List.Content>
|
||||
</List.Item>
|
||||
)}
|
||||
{file && (
|
||||
<List.Item>
|
||||
<List.Icon name="file" />
|
||||
<div className="list-icon-wrapper">
|
||||
<Icon name="file" />
|
||||
</div>
|
||||
<List.Content>{filename}</List.Content>
|
||||
</List.Item>
|
||||
)}
|
||||
{name && (
|
||||
<List.Item>
|
||||
<List.Icon name="user" />
|
||||
<div className="list-icon-wrapper">
|
||||
<Icon name="user" />
|
||||
</div>
|
||||
<List.Content>{name}</List.Content>
|
||||
</List.Item>
|
||||
)}
|
||||
{adr1 && (
|
||||
<List.Item>
|
||||
<List.Icon name="marker" />
|
||||
<div className="list-icon-wrapper">
|
||||
<Icon name="marker" />
|
||||
</div>
|
||||
<List.Content>{location}</List.Content>
|
||||
</List.Item>
|
||||
)}
|
||||
{phon && (
|
||||
<List.Item>
|
||||
<List.Icon name="phone" />
|
||||
<div className="list-icon-wrapper">
|
||||
<Icon name="phone" />
|
||||
</div>
|
||||
<List.Content>{phon}</List.Content>
|
||||
</List.Item>
|
||||
)}
|
||||
{email && (
|
||||
<List.Item>
|
||||
<List.Icon name="mail" />
|
||||
<div className="list-icon-wrapper">
|
||||
<Icon name="mail" />
|
||||
</div>
|
||||
<List.Content>{email}</List.Content>
|
||||
</List.Item>
|
||||
)}
|
||||
{copr && (
|
||||
<List.Item>
|
||||
<List.Icon name="copyright" />
|
||||
<div className="list-icon-wrapper">
|
||||
<Icon name="copyright" />
|
||||
</div>
|
||||
<List.Content>{copr}</List.Content>
|
||||
</List.Item>
|
||||
)}
|
||||
</List>
|
||||
|
||||
<Divider />
|
||||
</>
|
||||
</Item.Content>
|
||||
</Item>
|
||||
);
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 75 KiB After Width: | Height: | Size: 75 KiB |
|
Before Width: | Height: | Size: 76 KiB After Width: | Height: | Size: 76 KiB |
|
Before Width: | Height: | Size: 69 KiB After Width: | Height: | Size: 69 KiB |
|
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 70 KiB |
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 72 KiB |
|
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 74 KiB |