diff --git a/apps/client/src/widgets/react/FormSelect.tsx b/apps/client/src/widgets/react/FormSelect.tsx index 90ace2100..ce42c4815 100644 --- a/apps/client/src/widgets/react/FormSelect.tsx +++ b/apps/client/src/widgets/react/FormSelect.tsx @@ -1,27 +1,74 @@ -interface FormSelectProps { - currentValue?: string; - onChange(newValue: string): void; - values: T[]; - keyProperty: keyof T; - titleProperty: keyof T; +import type { ComponentChildren } from "preact"; + +type OnChangeListener = (newValue: string) => void; + +interface FormSelectGroup { + title: string; + items: T[]; } -export default function FormSelect({ currentValue, values, onChange, keyProperty, titleProperty }: FormSelectProps) { +interface ValueConfig { + values: Q[]; + /** The property of an item of {@link values} to be used as the key, uniquely identifying it. The key will be passed to the change listener. */ + keyProperty: keyof T; + /** The property of an item of {@link values} to be used as the label, representing a human-readable version of the key. If missing, {@link keyProperty} will be used instead. */ + titleProperty?: keyof T; + /** The current value of the combobox. The value will be looked up by going through {@link values} and looking an item whose {@link #keyProperty} value matches this one */ + currentValue?: string; +} + +interface FormSelectProps extends ValueConfig { + onChange: OnChangeListener; +} + +/** + * Combobox component that takes in any object array as data. Each item of the array is rendered as an item, and the key and values are obtained by looking into the object by a specified key. + */ +export default function FormSelect(props: FormSelectProps) { + return ( + + + + ); +} + +/** + * Similar to {@link FormSelect}, but the top-level elements are actually groups. + */ +export function FormSelectWithGroups({ values, keyProperty, titleProperty, currentValue, onChange }: FormSelectProps>) { + return ( + + {values.map(({ title, items }) => { + return ( + + + + ); + })} + + ) +} + +function FormSelectBody({ children, onChange }: { children: ComponentChildren, onChange: OnChangeListener }) { return ( ) +} + +function FormSelectGroup({ values, keyProperty, titleProperty, currentValue }: ValueConfig) { + return values.map(item => { + return ( + + ); + }); } \ No newline at end of file diff --git a/apps/client/src/widgets/type_widgets/options/appearance.tsx b/apps/client/src/widgets/type_widgets/options/appearance.tsx index 9ea95f9f3..43e839968 100644 --- a/apps/client/src/widgets/type_widgets/options/appearance.tsx +++ b/apps/client/src/widgets/type_widgets/options/appearance.tsx @@ -3,11 +3,13 @@ import { t } from "../../../services/i18n"; import { isMobile, reloadFrontendApp } from "../../../services/utils"; import Column from "../../react/Column"; import FormRadioGroup from "../../react/FormRadioGroup"; -import FormSelect from "../../react/FormSelect"; +import FormSelect, { FormSelectWithGroups } from "../../react/FormSelect"; import { useTriliumOption, useTriliumOptionBool } from "../../react/hooks"; import OptionsSection from "./components/OptionsSection"; import server from "../../../services/server"; import FormCheckbox from "../../react/FormCheckbox"; +import FormGroup from "../../react/FormGroup"; +import { FontFamily, OptionNames } from "@triliumnext/commons"; interface Theme { val: string; @@ -24,11 +26,59 @@ const BUILTIN_THEMES: Theme[] = [ { val: "dark", title: t("theme.dark_theme") } ] +interface FontFamilyEntry { + value: FontFamily; + label?: string; +} + +interface FontGroup { + title: string; + items: FontFamilyEntry[]; +} + +const FONT_FAMILIES: FontGroup[] = [ + { + title: t("fonts.generic-fonts"), + items: [ + { value: "theme", label: t("fonts.theme_defined") }, + { value: "system", label: t("fonts.system-default") }, + { value: "serif", label: t("fonts.serif") }, + { value: "sans-serif", label: t("fonts.sans-serif") }, + { value: "monospace", label: t("fonts.monospace") } + ] + }, + { + title: t("fonts.sans-serif-system-fonts"), + items: [{ value: "Arial" }, { value: "Verdana" }, { value: "Helvetica" }, { value: "Tahoma" }, { value: "Trebuchet MS" }, { value: "Microsoft YaHei" }] + }, + { + title: t("fonts.serif-system-fonts"), + items: [{ value: "Times New Roman" }, { value: "Georgia" }, { value: "Garamond" }] + }, + { + title: t("fonts.monospace-system-fonts"), + items: [ + { value: "Courier New" }, + { value: "Brush Script MT" }, + { value: "Impact" }, + { value: "American Typewriter" }, + { value: "Andalé Mono" }, + { value: "Lucida Console" }, + { value: "Monaco" } + ] + }, + { + title: t("fonts.handwriting-system-fonts"), + items: [{ value: "Bradley Hand" }, { value: "Luminari" }, { value: "Comic Sans MS" }] + } +]; + export default function AppearanceSettings() { return ( <> + ) } @@ -75,7 +125,10 @@ function ApplicationTheme() { - + @@ -86,4 +139,35 @@ function ApplicationTheme() { ) +} + +function Fonts() { + return ( + + + + + + + ); +} + +function Font({ title, fontFamilyOption }: { title: string, fontFamilyOption: OptionNames }) { + const [ fontFamily, setFontFamily ] = useTriliumOption(fontFamilyOption); + + return ( + <> +
{title}
+ + + + + + + + ); } \ No newline at end of file diff --git a/apps/client/src/widgets/type_widgets/options/appearance/fonts.ts b/apps/client/src/widgets/type_widgets/options/appearance/fonts.ts index 7d4fa3ce0..527834716 100644 --- a/apps/client/src/widgets/type_widgets/options/appearance/fonts.ts +++ b/apps/client/src/widgets/type_widgets/options/appearance/fonts.ts @@ -1,64 +1,14 @@ import OptionsWidget from "../options_widget.js"; import utils from "../../../../services/utils.js"; import { t } from "../../../../services/i18n.js"; -import type { FontFamily, OptionMap, OptionNames } from "@triliumnext/commons"; +import type { OptionMap, OptionNames } from "@triliumnext/commons"; -interface FontFamilyEntry { - value: FontFamily; - label?: string; -} -interface FontGroup { - title: string; - items: FontFamilyEntry[]; -} - -const FONT_FAMILIES: FontGroup[] = [ - { - title: t("fonts.generic-fonts"), - items: [ - { value: "theme", label: t("fonts.theme_defined") }, - { value: "system", label: t("fonts.system-default") }, - { value: "serif", label: t("fonts.serif") }, - { value: "sans-serif", label: t("fonts.sans-serif") }, - { value: "monospace", label: t("fonts.monospace") } - ] - }, - { - title: t("fonts.sans-serif-system-fonts"), - items: [{ value: "Arial" }, { value: "Verdana" }, { value: "Helvetica" }, { value: "Tahoma" }, { value: "Trebuchet MS" }, { value: "Microsoft YaHei" }] - }, - { - title: t("fonts.serif-system-fonts"), - items: [{ value: "Times New Roman" }, { value: "Georgia" }, { value: "Garamond" }] - }, - { - title: t("fonts.monospace-system-fonts"), - items: [ - { value: "Courier New" }, - { value: "Brush Script MT" }, - { value: "Impact" }, - { value: "American Typewriter" }, - { value: "Andalé Mono" }, - { value: "Lucida Console" }, - { value: "Monaco" } - ] - }, - { - title: t("fonts.handwriting-system-fonts"), - items: [{ value: "Bradley Hand" }, { value: "Luminari" }, { value: "Comic Sans MS" }] - } -]; const TPL = /*html*/`
-

${t("fonts.fonts")}

- -
${t("fonts.main_font")}
-
-
@@ -72,8 +22,6 @@ const TPL = /*html*/`
-
${t("fonts.note_tree_font")}
-
@@ -90,8 +38,6 @@ const TPL = /*html*/`
-
${t("fonts.note_detail_font")}
-
@@ -108,8 +54,6 @@ const TPL = /*html*/`
-
${t("fonts.monospace_font")}
-
@@ -189,7 +133,7 @@ export default class FontsOptions extends OptionsWidget { this.$monospaceFontSize.val(options.monospaceFontSize); this.fillFontFamilyOptions(this.$monospaceFontFamily, options.monospaceFontFamily); - const optionsToSave: OptionNames[] = ["mainFontFamily", "mainFontSize", "treeFontFamily", "treeFontSize", "detailFontFamily", "detailFontSize", "monospaceFontFamily", "monospaceFontSize"]; + const optionsToSave: OptionNames[] = ["mainFontSize", "treeFontSize", "monospaceFontSize"]; for (const optionName of optionsToSave) { const $el = (this as any)[`$${optionName}`]; @@ -197,22 +141,4 @@ export default class FontsOptions extends OptionsWidget { } } - fillFontFamilyOptions($select: JQuery, currentValue: string) { - $select.empty(); - - for (const { title, items } of Object.values(FONT_FAMILIES)) { - const $group = $("").attr("label", title); - - for (const { value, label } of items) { - $group.append( - $("