Skip to content

Commit

Permalink
Extend embed configurator with some more options (#502)
Browse files Browse the repository at this point in the history
Closes #494 and #467

Signed-off-by: Cintia Sanchez Garcia <cynthiasg@icloud.com>
  • Loading branch information
cynthia-sg authored Feb 16, 2024
1 parent 1d742f0 commit e813698
Show file tree
Hide file tree
Showing 8 changed files with 818 additions and 239 deletions.
222 changes: 182 additions & 40 deletions embed/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,64 @@ import Loading from './common/Loading';
import NoData from './common/NoData';
import StyleView from './common/StyleView';
import {
Alignment,
BaseItem,
BGCOLOR_PARAM,
Data,
DEFAULT_BG_COLOR,
DEFAULT_DISPLAY_CATEGORY_HEADER,
DEFAULT_DISPLAY_CATEGORY_IN_SUBCATEGORY,
DEFAULT_DISPLAY_HEADER,
DEFAULT_FG_COLOR,
DEFAULT_SIZE,
DEFAULT_STYLE_VIEW,
DEFAULT_DISPLAY_ITEM_NAME,
DEFAULT_ITEM_NAME_SIZE,
DEFAULT_ITEMS_ALIGNMENT,
DEFAULT_ITEMS_SIZE,
DEFAULT_ITEMS_STYLE_VIEW,
DEFAULT_TITLE_ALIGNMENT,
DEFAULT_TITLE_BG_COLOR,
DEFAULT_TITLE_FG_COLOR,
DEFAULT_TITLE_FONT_FAMILY,
DEFAULT_TITLE_SIZE,
DEFAULT_UPPERCASE_TITLE,
DISPLAY_CATEGORY_IN_SUBCATEGORY_PARAM,
DISPLAY_HEADER_CATEGORY_PARAM,
DISPLAY_HEADER_PARAM,
FGCOLOR_PARAM,
DISPLAY_ITEM_NAME_PARAM,
FontFamily,
ITEM_NAME_SIZE_PARAM,
ITEMS_ALIGNMENT_PARAM,
ITEMS_SIZE_PARAM,
ITEMS_SPACING_PARAM,
ITEMS_STYLE_PARAM,
KEY_PARAM,
Size,
SIZE_PARAM,
Style,
STYLE_PARAM,
Subcategory,
TITLE_ALIGNMENT_PARAM,
TITLE_BGCOLOR_PARAM,
TITLE_FGCOLOR_PARAM,
TITLE_FONT_FAMILY_PARAM,
TITLE_SIZE_PARAM,
UPPERCASE_TITLE_PARAM,
} from './types';
import getUrl from './utils/getUrl';

interface TitleProps {
isBgTransparent: boolean;
size: number;
alignment: Alignment;
uppercase: boolean;
firstTitle?: boolean;
spacing?: number;
}

interface ContentProps {
fontFamily: FontFamily;
}

const FONT_FAMILY_OPTIONS = {
[FontFamily.Serif]: `Times, "Times New Roman", Georgia, Palatino, serif`,
[FontFamily.SansSerif]: `"Clarity City", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, Roboto, Ubuntu, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"`,
[FontFamily.Monospace]: `Courier, Consolas, "Andale Mono", monospace`,
};

const Content = styled('div')`
margin: 0;
padding: 0;
Expand All @@ -40,8 +75,7 @@ const Content = styled('div')`
*,
*::before,
*::after {
font-family: Clarity City, -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif, Roboto, Ubuntu,
Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol;
font-family: ${(props: ContentProps) => FONT_FAMILY_OPTIONS[props.fontFamily]};
box-sizing: border-box;
}
`;
Expand All @@ -50,11 +84,13 @@ const CategoryTitle = styled('div')`
background-color: var(--bg-color);
color: var(--fg-color);
padding: ${(props: TitleProps) => (props.isBgTransparent ? '0.5rem 0' : '0.5rem 0.75rem')};
font-size: 0.8rem;
font-weight: 600;
font-size: ${(props: TitleProps) => (props.size ? `${props.size}px` : '0.8rem')};
text-align: ${(props: TitleProps) => props.alignment};
text-transform: ${(props: TitleProps) => (props.uppercase ? 'uppercase' : 'normal')};
font-weight: 500;
line-height: 1.5;
text-transform: uppercase;
overflow: hidden;
margin-bottom: 16px;
text-overflow: ellipsis;
white-space: nowrap;
`;
Expand All @@ -63,11 +99,17 @@ const SubcategoryTitle = styled('div')`
background-color: var(--bg-color);
color: var(--fg-color);
padding: ${(props: TitleProps) => (props.isBgTransparent ? '0.5rem 0' : '0.5rem 0.75rem')};
font-size: 0.8rem;
font-weight: 600;
font-size: ${(props: TitleProps) => (props.size ? `${props.size}px` : '0.8rem')};
text-align: ${(props: TitleProps) => props.alignment};
text-transform: ${(props: TitleProps) => (props.uppercase ? 'uppercase' : 'normal')};
font-weight: 500;
line-height: 1.5;
margin: 1rem 0;
margin-top: 1rem;
margin: ${(props: TitleProps) => {
const marginValue = typeof props.spacing !== 'undefined' && props.spacing > 16 ? `${props.spacing}px` : '16px';
return typeof props.firstTitle !== 'undefined' && props.firstTitle
? `0 0 ${marginValue} 0`
: `${marginValue} 0 ${marginValue} 0`;
}};
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
Expand All @@ -77,46 +119,107 @@ const App = () => {
const [key, setKey] = createSignal<string>();
const [data, setData] = createSignal<Data | null>();
const [displayHeader, setDisplayHeader] = createSignal<boolean>(DEFAULT_DISPLAY_HEADER);
const [styleView, setStyleView] = createSignal<Style>(DEFAULT_STYLE_VIEW);
const [itemsStyleView, setItemsStyleView] = createSignal<Style>(DEFAULT_ITEMS_STYLE_VIEW);
const [isBgTransparent, setIsBgTransparent] = createSignal<boolean>(false);
const [bgColor, setBgColor] = createSignal<string>(DEFAULT_BG_COLOR);
const [fgColor, setFgColor] = createSignal<string>(DEFAULT_FG_COLOR);
const [size, setSize] = createSignal<Size>(DEFAULT_SIZE);
const [titleBgColor, setTitleBgColor] = createSignal<string>(DEFAULT_TITLE_BG_COLOR);
const [tilteFgColor, setTitleFgColor] = createSignal<string>(DEFAULT_TITLE_FG_COLOR);
const [itemsSize, setItemsSize] = createSignal<Size>(DEFAULT_ITEMS_SIZE);
const [displayCategoryTitle, setDisplayCategoryTitle] = createSignal<boolean>(DEFAULT_DISPLAY_CATEGORY_HEADER);
const [displayCategoryInSubcategory, setDisplayCategoryInSubcategory] = createSignal<boolean>(
DEFAULT_DISPLAY_CATEGORY_IN_SUBCATEGORY
);
const [uppercaseTitle, setUppercaseTitle] = createSignal<boolean>(DEFAULT_UPPERCASE_TITLE);
const [titleAlignment, setTitleAlignment] = createSignal<Alignment>(DEFAULT_TITLE_ALIGNMENT);
const [titleFontFamily, setTitleFontFamily] = createSignal<FontFamily>(DEFAULT_TITLE_FONT_FAMILY);
const [titleSize, setTitleSize] = createSignal<number>(DEFAULT_TITLE_SIZE);
const [displayItemName, setDisplayItemName] = createSignal<boolean>(DEFAULT_DISPLAY_ITEM_NAME);
const [itemNameSize, setItemNameSize] = createSignal<number>(DEFAULT_ITEM_NAME_SIZE);
const [itemsAlignment, setItemsAlignment] = createSignal<Alignment>(DEFAULT_ITEMS_ALIGNMENT);
const [itemsSpacing, setItemsSpacing] = createSignal<number | undefined>();

onMount(() => {
const urlParams = new URLSearchParams(window.location.search);
const keyParam = urlParams.get(KEY_PARAM);
const displayHeader = urlParams.get(DISPLAY_HEADER_PARAM);
const styleParam = urlParams.get(STYLE_PARAM);
const sizeParam = urlParams.get(SIZE_PARAM);
const bgParam = urlParams.get(BGCOLOR_PARAM);
const fgParam = urlParams.get(FGCOLOR_PARAM);
const displayHeaderParam = urlParams.get(DISPLAY_HEADER_PARAM);
const styleParam = urlParams.get(ITEMS_STYLE_PARAM);
const sizeParam = urlParams.get(ITEMS_SIZE_PARAM);
const bgParam = urlParams.get(TITLE_BGCOLOR_PARAM);
const fgParam = urlParams.get(TITLE_FGCOLOR_PARAM);
const displayCategoryParam = urlParams.get(DISPLAY_HEADER_CATEGORY_PARAM);
const displayCategoryInSubcategoryParam = urlParams.get(DISPLAY_CATEGORY_IN_SUBCATEGORY_PARAM);
const titleAligmentParam = urlParams.get(TITLE_ALIGNMENT_PARAM);
const titleFontFamilyParam = urlParams.get(TITLE_FONT_FAMILY_PARAM);
const titleSizeParam = urlParams.get(TITLE_SIZE_PARAM);
const displayItemNameParam = urlParams.get(DISPLAY_ITEM_NAME_PARAM);
const itemNameSizeParam = urlParams.get(ITEM_NAME_SIZE_PARAM);
const alignmentParam = urlParams.get(ITEMS_ALIGNMENT_PARAM);
const spacingParam = urlParams.get(ITEMS_SPACING_PARAM);
const uppercaseParam = urlParams.get(UPPERCASE_TITLE_PARAM);

batch(() => {
if (keyParam !== null) {
let isValidSize = true;
let isValidStyle = true;
setDisplayHeader(displayHeader === 'true');
setDisplayHeader(displayHeaderParam === 'true');
if (displayCategoryParam !== null) {
setDisplayCategoryTitle(displayCategoryParam === 'true');
}
if (displayCategoryInSubcategoryParam !== null) {
setDisplayCategoryInSubcategory(displayCategoryInSubcategoryParam === 'true');
}
if (uppercaseParam !== null) {
setUppercaseTitle(uppercaseParam === 'true');
}
if (displayItemNameParam !== null) {
setDisplayItemName(displayItemNameParam === 'true');
if (itemNameSizeParam !== null) {
const itemNameS = parseInt(itemNameSizeParam);
if (itemNameS >= 10 && itemNameS <= 40) {
setItemNameSize(itemNameS);
}
}
}
if (styleParam !== null) {
if (Object.values(Style).includes(styleParam as Style)) {
setStyleView(styleParam as Style);
setItemsStyleView(styleParam as Style);
} else {
isValidStyle = false;
}
}
if (sizeParam !== null) {
if (Object.values(Size).includes(sizeParam as Size)) {
setSize(sizeParam as Size);
setItemsSize(sizeParam as Size);
} else {
isValidSize = false;
}
}
if (bgParam !== null) {
setBgColor(bgParam);
setTitleBgColor(bgParam);
setIsBgTransparent(bgParam === 'transparent');
}
if (fgParam !== null) {
setFgColor(fgParam);
setTitleFgColor(fgParam);
}
if (titleFontFamilyParam !== null) {
setTitleFontFamily(titleFontFamilyParam as FontFamily);
}
if (titleAligmentParam !== null) {
setTitleAlignment(titleAligmentParam as Alignment);
}
if (titleSizeParam !== null) {
const titleS = parseInt(titleSizeParam);
if (titleS >= 10 && titleS <= 60) {
setTitleSize(titleS);
}
}
if (alignmentParam !== null) {
setItemsAlignment(alignmentParam as Alignment);
}
if (spacingParam !== null) {
const spacing = parseInt(spacingParam);
if (spacing >= 0) {
setItemsSpacing(spacing);
}
}
// When size and style are not valid, we don´t save the key
if (isValidSize && isValidStyle) {
Expand Down Expand Up @@ -163,12 +266,13 @@ const App = () => {

return (
<Content
fontFamily={titleFontFamily()}
style={{
all: 'initial',
isolation: 'isolate',
overflow: 'hidden',
'--bg-color': bgColor(),
'--fg-color': fgColor(),
'--bg-color': titleBgColor(),
'--fg-color': tilteFgColor(),
}}
>
<Show
Expand All @@ -184,21 +288,59 @@ const App = () => {
</NoData>
}
>
<Show when={typeof data() !== 'undefined'} fallback={<Loading bgColor={bgColor()} />}>
<Show when={displayHeader()} fallback={<StyleView items={data()!.items} style={styleView()} size={size()} />}>
<CategoryTitle isBgTransparent={isBgTransparent()}>{data()!.category.name}</CategoryTitle>
<Show when={typeof data() !== 'undefined'} fallback={<Loading bgColor={titleBgColor()} />}>
<Show
when={displayHeader()}
fallback={
<StyleView
items={data()!.items}
style={itemsStyleView()}
size={itemsSize()}
alignment={itemsAlignment()}
spacing={itemsSpacing()}
displayName={displayItemName()}
itemNameSize={itemNameSize()}
/>
}
>
<Show when={displayCategoryTitle()}>
<CategoryTitle
isBgTransparent={isBgTransparent()}
size={titleSize()}
alignment={titleAlignment()}
uppercase={uppercaseTitle()}
>
{data()!.category.name}
</CategoryTitle>
</Show>
<For each={data()!.category.subcategories}>
{(subcategory: Subcategory) => {
{(subcategory, index) => {
const items = data()!.items.filter((item: BaseItem) => {
return item.category === data()!.category.name && item.subcategory === subcategory.name;
});

return (
<>
<SubcategoryTitle isBgTransparent={isBgTransparent()}>
<SubcategoryTitle
isBgTransparent={isBgTransparent()}
size={titleSize()}
alignment={titleAlignment()}
uppercase={uppercaseTitle()}
firstTitle={index() === 0}
spacing={itemsSpacing()}
>
<Show when={displayCategoryInSubcategory()}>{data()!.category.name} - </Show>
{subcategory.name} ({items.length})
</SubcategoryTitle>
<StyleView items={items} style={styleView()} size={size()} />
<StyleView
items={items}
style={itemsStyleView()}
size={itemsSize()}
alignment={itemsAlignment()}
spacing={itemsSpacing()}
displayName={displayItemName()}
itemNameSize={itemNameSize()}
/>
</>
);
}}
Expand Down
17 changes: 14 additions & 3 deletions embed/src/common/ExternalLink.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,24 @@
import { JSXElement } from 'solid-js';
import { css } from 'solid-styled-components';
import { css, styled } from 'solid-styled-components';

interface Props {
children: JSXElement | JSXElement[] | string;
href: string;
paddingBottom?: number;
class?: string;
label?: string;
title?: string;
}

interface LinkProps {
paddingBottom?: number;
}

const Link = styled('a')`
padding-bottom: ${(props: LinkProps) =>
typeof props.paddingBottom !== 'undefined' ? `${props.paddingBottom}px` : '0'};
`;

const LinkClass = css`
color: inherit;
text-decoration: underline;
Expand All @@ -20,17 +30,18 @@ const LinkClass = css`

const ExternalLink = (props: Props) => {
return (
<a
<Link
title={props.title}
class={`${LinkClass} ${props.class}`}
href={props.href}
target="_blank"
rel="noopener noreferrer"
aria-label={props.label || 'Open external link'}
tabIndex={-1}
paddingBottom={props.paddingBottom}
>
{props.children}
</a>
</Link>
);
};

Expand Down
Loading

0 comments on commit e813698

Please sign in to comment.