feat(note_bars/collection): support comboboxes

This commit is contained in:
Elian Doran 2025-12-11 20:09:25 +02:00
parent 00df3c3d1f
commit 53b7d93efb
No known key found for this signature in database
3 changed files with 47 additions and 4 deletions

View File

@ -2031,7 +2031,7 @@
"book_properties_config": { "book_properties_config": {
"hide-weekends": "Hide weekends", "hide-weekends": "Hide weekends",
"display-week-numbers": "Display week numbers", "display-week-numbers": "Display week numbers",
"map-style": "Map style:", "map-style": "Map style",
"max-nesting-depth": "Max nesting depth:", "max-nesting-depth": "Max nesting depth:",
"raster": "Raster", "raster": "Raster",
"vector_light": "Vector (Light)", "vector_light": "Vector (Light)",

View File

@ -5,11 +5,12 @@ import Dropdown from "../react/Dropdown";
import { FormDropdownDivider, FormDropdownSubmenu, FormListItem, FormListToggleableItem } from "../react/FormList"; import { FormDropdownDivider, FormDropdownSubmenu, FormListItem, FormListToggleableItem } from "../react/FormList";
import Icon from "../react/Icon"; import Icon from "../react/Icon";
import { useViewType, VIEW_TYPE_MAPPINGS } from "../ribbon/CollectionPropertiesTab"; import { useViewType, VIEW_TYPE_MAPPINGS } from "../ribbon/CollectionPropertiesTab";
import { bookPropertiesConfig, BookProperty, ButtonProperty, CheckBoxProperty, NumberProperty, SplitButtonProperty } from "../ribbon/collection-properties-config"; import { bookPropertiesConfig, BookProperty, ButtonProperty, CheckBoxProperty, ComboBoxItem, ComboBoxProperty, NumberProperty, SplitButtonProperty } from "../ribbon/collection-properties-config";
import { useNoteLabel, useNoteLabelBoolean } from "../react/hooks"; import { useNoteLabel, useNoteLabelBoolean, useNoteLabelWithDefault } from "../react/hooks";
import { useContext } from "preact/hooks"; import { useContext } from "preact/hooks";
import { ParentComponent } from "../react/react_utils"; import { ParentComponent } from "../react/react_utils";
import FormTextBox from "../react/FormTextBox"; import FormTextBox from "../react/FormTextBox";
import { Fragment } from "preact/jsx-runtime";
const ICON_MAPPINGS: Record<ViewTypeOptions, string> = { const ICON_MAPPINGS: Record<ViewTypeOptions, string> = {
grid: "bx bxs-grid", grid: "bx bxs-grid",
@ -86,6 +87,8 @@ function ViewProperty({ note, property }: { note: FNote, property: BookProperty
return <CheckBoxPropertyView note={note} property={property} />; return <CheckBoxPropertyView note={note} property={property} />;
case "number": case "number":
return <NumberPropertyView note={note} property={property} />; return <NumberPropertyView note={note} property={property} />;
case "combobox":
return <ComboBoxPropertyView note={note} property={property} />;
} }
} }
@ -149,6 +152,43 @@ function NumberPropertyView({ note, property }: { note: FNote, property: NumberP
); );
} }
function ComboBoxPropertyView({ note, property }: { note: FNote, property: ComboBoxProperty }) {
const [ value, setValue ] = useNoteLabelWithDefault(note, property.bindToLabel, property.defaultValue ?? "");
function renderItem(option: ComboBoxItem) {
return (
<FormListItem
key={option.value}
checked={value === option.value}
onClick={() => setValue(option.value)}
>
{option.label}
</FormListItem>
);
}
return (
<FormDropdownSubmenu
title={property.label}
icon={property.icon ?? "bx bx-empty"}
>
{(property.options).map((option, index) => {
if ("items" in option) {
return (
<Fragment key={option.title}>
<FormListItem key={option.title} disabled>{option.title}</FormListItem>
{option.items.map(renderItem)}
{index < property.options.length - 1 && <FormDropdownDivider />}
</Fragment>
);
} else {
return renderItem(option);
}
})}
</FormDropdownSubmenu>
)
}
function CheckBoxPropertyView({ note, property }: { note: FNote, property: CheckBoxProperty }) { function CheckBoxPropertyView({ note, property }: { note: FNote, property: CheckBoxProperty }) {
const [ value, setValue ] = useNoteLabelBoolean(note, property.bindToLabel); const [ value, setValue ] = useNoteLabelBoolean(note, property.bindToLabel);
return ( return (

View File

@ -45,7 +45,7 @@ export interface NumberProperty {
disabled?: (note: FNote) => boolean; disabled?: (note: FNote) => boolean;
} }
interface ComboBoxItem { export interface ComboBoxItem {
value: string; value: string;
label: string; label: string;
} }
@ -58,6 +58,7 @@ interface ComboBoxGroup {
export interface ComboBoxProperty { export interface ComboBoxProperty {
type: "combobox", type: "combobox",
label: string; label: string;
icon?: string;
bindToLabel: FilterLabelsByType<string>; bindToLabel: FilterLabelsByType<string>;
/** /**
* The default value is used when the label is not set. * The default value is used when the label is not set.
@ -125,6 +126,7 @@ export const bookPropertiesConfig: Record<ViewTypeOptions, BookConfig> = {
properties: [ properties: [
{ {
label: t("book_properties_config.map-style"), label: t("book_properties_config.map-style"),
icon: "bx bx-palette",
type: "combobox", type: "combobox",
bindToLabel: "map:style", bindToLabel: "map:style",
defaultValue: DEFAULT_MAP_LAYER_NAME, defaultValue: DEFAULT_MAP_LAYER_NAME,
@ -177,6 +179,7 @@ export const bookPropertiesConfig: Record<ViewTypeOptions, BookConfig> = {
{ {
label: "Theme", label: "Theme",
type: "combobox", type: "combobox",
icon: "bx bx-palette",
bindToLabel: "presentation:theme", bindToLabel: "presentation:theme",
defaultValue: DEFAULT_THEME, defaultValue: DEFAULT_THEME,
options: getPresentationThemes().map(theme => ({ options: getPresentationThemes().map(theme => ({