Skip to content

Commit

Permalink
Add banner header
Browse files Browse the repository at this point in the history
  • Loading branch information
noatpad committed Sep 11, 2023
1 parent 91409bf commit 99f4979
Show file tree
Hide file tree
Showing 9 changed files with 73 additions and 39 deletions.
8 changes: 5 additions & 3 deletions src/banner/Banner.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
export let x = 0.5;
export let y = 0.5;
export let icon: IconString | undefined = undefined;
export let header: string | undefined = undefined;
export let viewType: 'editing' | 'reading';
export let file: TFile;
Expand All @@ -34,15 +35,15 @@
mobileHeight,
popoverHeight,
internalEmbedHeight,
iconSize,
headerSize,
iconVerticalAlignment
} = $settings);
$: heights = getHeights(embed, [
desktopHeight,
mobileHeight,
popoverHeight,
internalEmbedHeight,
iconSize
headerSize
]);
onDestroy(() => {
Expand Down Expand Up @@ -82,9 +83,10 @@
<Error {error} />
{/await}
{/if}
{#if icon}
{#if icon || header}
<Header
{icon}
{header}
on:open-icon-modal={openIconModal}
/>
{/if}
Expand Down
32 changes: 24 additions & 8 deletions src/banner/Header.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
import Icon from './Icon.svelte';
import { getIconTransform } from './utils';
export let icon: IconString;
export let icon: IconString | undefined;
export let header: string | undefined;
$: ({
headerSize,
iconHorizontalAlignment,
iconHorizontalTransform,
iconVerticalAlignment,
Expand All @@ -17,34 +19,48 @@
$: vertical = getSetting('iconVerticalAlignment', iconVerticalAlignment);
$: vTransform = getSetting('iconVerticalTransform', iconVerticalTransform);
$: transform = getIconTransform(horizontal, hTransform, vertical, vTransform);
$: fontSize = getSetting('headerSize', headerSize);
</script>

<div
class="header"
class="banner-header"
class:align-left={horizontal === 'left'}
class:align-center={horizontal === 'center'}
class:align-right={horizontal === 'right'}
class:center-of-banner={vertical === 'center'}
style:transform
style:font-size={fontSize}
>
<Icon {icon} on:open-icon-modal />
{#if icon}
<Icon {icon} on:open-icon-modal />
{/if}
{#if header}
<h1 class="banner-header-title">{header}</h1>
{/if}
</div>

<style lang="scss">
// TODO: Adjust for when 'Readable line length' core setting is off
.header {
.banner-header {
display: flex;
align-items: center;
gap: 0.2em;
position: absolute;
left: 0;
right: 0;
bottom: 0;
max-width: calc(var(--file-line-width) + (var(--file-margins) * 2));
padding: 4px var(--file-margins);
margin: 0 auto;
&.align-left { justify-content: start; }
&.align-center { justify-content: center; }
&.align-right { justify-content: end; }
&.center-of-banner { bottom: 50%; }
}
.align-left { justify-content: start; }
.align-center { justify-content: center; }
.align-right { justify-content: end; }
.center-of-banner { bottom: 50%; }
.banner-header-title {
font-size: 1em;
margin: 0;
}
</style>
22 changes: 12 additions & 10 deletions src/banner/Icon.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,31 @@
const dispatch = createEventDispatcher();
export let icon: IconString;
let div: HTMLElement;
$: ({ iconSize, useTwemoji } = $settings);
$: ({ type, value } = icon);
$: fontSize = getSetting('iconSize', iconSize);
$: html = (type === 'emoji' && useTwemoji)
? twemoji.parse(value, { className: 'banner-emoji' })
: value;
$: if (div && html) {
div.querySelector<HTMLElement>('img.banner-emoji')?.setCssStyles({
height: '1em',
width: '1em'
});
}
</script>

<div
class="banner-icon"
class:text-icon={type === 'text'}
class:emoji-icon={type === 'emoji'}
style:font-size={fontSize}
on:click={() => dispatch('open-icon-modal')}
on:keydown={(e) => e.code === 'Enter' && dispatch('open-icon-modal')}
role="button"
tabindex="-1"
on:click={() => dispatch('open-icon-modal')}
on:keydown={(e) => e.code === 'Enter' && dispatch('open-icon-modal')}
bind:this={div}
>
<!-- eslint-disable-next-line svelte/no-at-html-tags -->
{@html html}
Expand All @@ -37,18 +45,12 @@
display: inline-flex;
align-items: center;
justify-content: center;
height: calc(1em + 12px);
width: calc(1em + 12px);
height: calc(1em + 8px);
width: calc(1em + 8px);
border-radius: 6px;
cursor: pointer;
transition: ease 0.2s background;
:global(&.emoji-icon img.banner-emoji) {
height: 1em;
width: 1em;
vertical-align: 0.15em;
}
&:hover {
background: #aaa4;
}
Expand Down
2 changes: 1 addition & 1 deletion src/banner/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export const getHeights = (embedded: Embedded, _deps?: any[]): Heights => {
else if (embedded === 'popover') bannerHeight = getSetting('popoverHeight');

const banner = `${bannerHeight}px`;
const icon = getSetting('iconSize');
const icon = getSetting('headerSize');
return { banner, icon };
};

Expand Down
25 changes: 11 additions & 14 deletions src/bannerData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,23 @@ import { plug } from './main';
import { getSetting } from './settings';
import { extractIconFromYaml } from './transformers';

interface ReadWriteProperty { transform?: CallableFunction }
interface ReadProperty extends ReadWriteProperty { key: keyof BannerMetadata }
interface WriteProperty extends ReadWriteProperty { suffix: string }
interface ReadProperty { key: keyof BannerMetadata; transform?: CallableFunction }
interface WriteProperty { suffix: string }

export interface IconString {
type: 'text' | 'emoji';
value: string;
}

// NOTE: This must have every key in `BannerMetadata` and its corresponding type
export interface BannerMetadataWrite {
source: string;
x: number;
y: number;
icon: string;
header: string;
}

export const BANNER_DATA_KEYS: Array<keyof BannerMetadata> = [
'source',
'x',
'y',
'icon'
];

/* NOTE: These are bi-directional maps between YAML banner keys and `BannerMetadata` keys,
to help read, write, & transform banner data between them */
// Read: YAML -> BannerMetadata
Expand All @@ -38,17 +32,20 @@ const READ_MAP: Record<string, ReadProperty> = {
icon: {
key: 'icon',
transform: extractIconFromYaml
}
},
header: { key: 'header' }
} as const;

// Write: BannerMetadata -> YAML
const WRITE_MAP: Record<keyof BannerMetadata, WriteProperty> = {
source: { suffix: '' },
x: { suffix: 'x' },
y: { suffix: 'y' },
icon: { suffix: 'icon' }
icon: { suffix: 'icon' },
header: { suffix: 'header' }
} as const;

export const BANNER_WRITE_KEYS = Object.keys(WRITE_MAP) as Array<keyof BannerMetadata>;
const YAML_REGEX = /^---(?<yaml>.*)---/s;

const getYamlKey = (suffix: string) => {
Expand Down Expand Up @@ -91,9 +88,9 @@ export const extractBannerDataFromState = (state: EditorState): Partial<BannerMe
export const updateBannerData = async (file: TFile, bannerData: Partial<BannerMetadataWrite>) => {
await plug.app.fileManager.processFrontMatter(file, async (frontmatter) => {
for (const [dataKey, val] of Object.entries(bannerData) as [keyof BannerMetadata, any][]) {
const { suffix, transform } = WRITE_MAP[dataKey];
const { suffix } = WRITE_MAP[dataKey];
const yamlKey = getYamlKey(suffix);
frontmatter[yamlKey] = transform ? transform(val) : val;
frontmatter[yamlKey] = val;
}
});
};
4 changes: 2 additions & 2 deletions src/editing/extensions/bannerField.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { EditorState, StateField } from '@codemirror/state';
import { editorEditorField, editorInfoField } from 'obsidian';
import Banner from 'src/banner/Banner.svelte';
import { WRAPPER_CLASS } from 'src/banner/utils';
import { BANNER_DATA_KEYS } from 'src/bannerData';
import { BANNER_WRITE_KEYS } from 'src/bannerData';
import {
assignBannerEffect,
removeBannerEffect,
Expand Down Expand Up @@ -34,7 +34,7 @@ const addBanner = (state: EditorState, bannerData: Partial<BannerMetadata>): Ban

const updateBanner = (banner: Banner, bannerData: Partial<BannerMetadata>): Banner => {
console.log('update!');
const data = BANNER_DATA_KEYS.reduce((accum, key) => {
const data = BANNER_WRITE_KEYS.reduce((accum, key) => {
accum[key] = bannerData[key];
return accum;
}, {} as Record<string, unknown>);
Expand Down
13 changes: 13 additions & 0 deletions src/settings/components/Settings.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,17 @@
</ToggleSetting>
</Depends>

<!-- Banner Headers -->
<Header title="Banner Headers" description="Kinda like inline titles, but with a bit of pizazz" />
<InputSetting key="headerSize">
<span slot="name">Header font size</span>
<span slot="description">
Set the font size of the banner header. This can be any valid
<a href="https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Values_and_units#lengths" target="_blank" rel="noopener noreferrer">CSS length value</a>,
such as <code>10px</code>, <code>-30%</code>, <code>calc(1em + 10px)</code>, and so on...
</span>
</InputSetting>

<!-- Banner Icons -->
<Header title="Banner Icons" description="Give a lil' notion of what your note is about" />
<InputSetting key="iconSize">
Expand All @@ -106,6 +117,8 @@
Set the size of the banner icon. This can be any valid
<a href="https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Values_and_units#lengths" target="_blank" rel="noopener noreferrer">CSS length value</a>,
such as <code>10px</code>, <code>-30%</code>, <code>calc(1em + 10px)</code>, and so on...
<br />
<span><em>Note:</em> this setting stacks with the <b>Header font size</b> setting above</span>
</span>
</InputSetting>
<SelectSetting key="iconHorizontalAlignment">
Expand Down
5 changes: 4 additions & 1 deletion src/settings/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export interface BannerSettings {
frontmatterField: string;
enableDragInInternalEmbed: boolean;
enableDragInPopover: boolean;
headerSize: string;
iconSize: string;
iconHorizontalAlignment: IconHorizontalAlignmentOption;
iconHorizontalTransform: string;
Expand All @@ -39,7 +40,8 @@ export const DEFAULT_SETTINGS: BannerSettings = {
frontmatterField: 'banner',
enableDragInInternalEmbed: false,
enableDragInPopover: false,
iconSize: '4.5em',
headerSize: '3em',
iconSize: '1.2em',
iconHorizontalAlignment: 'left',
iconHorizontalTransform: '0px',
iconVerticalAlignment: 'edge',
Expand All @@ -49,6 +51,7 @@ export const DEFAULT_SETTINGS: BannerSettings = {

const TEXT_SETTINGS: Array<keyof BannerSettings> = [
'frontmatterField',
'headerSize',
'iconSize',
'iconHorizontalTransform',
'iconVerticalTransform'
Expand Down
1 change: 1 addition & 0 deletions src/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,5 +80,6 @@ declare global {
x: number;
y: number;
icon: IconString;
header: string;
}
}

0 comments on commit 99f4979

Please sign in to comment.