chore(react/ribbon): add note types

This commit is contained in:
Elian Doran 2025-08-21 20:30:12 +03:00
parent e2e9721d5f
commit cabeb13adb
No known key found for this signature in database
5 changed files with 44 additions and 26 deletions

View File

@ -13,18 +13,10 @@ const NOT_SELECTABLE_NOTE_TYPES = NOTE_TYPES.filter((nt) => nt.reserved || nt.st
const TPL = /*html*/`
<div class="dropdown note-type-widget">
<style>
.note-type-dropdown {
max-height: 500px;
overflow-y: auto;
overflow-x: hidden;
}
</style>
<button type="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" class="btn btn-sm dropdown-toggle select-button note-type-button">
<span class="note-type-desc"></span>
<span class="caret"></span>
</button>
<div class="note-type-dropdown dropdown-menu dropdown-menu-left tn-dropdown-list"></div>
</div>
`;
@ -83,7 +75,7 @@ export default class NoteTypeWidget extends NoteContextAwareWidget {
});
} else {
this.$noteTypeDropdown.append('<div class="dropdown-divider"></div>');
$typeLink = $('<a class="dropdown-item disabled">').attr("data-note-type", noteType.type).append('<span class="check">&check;</span> ').append($("<strong>").text(noteType.title));
$typeLink = $('<a class="dropdown-item disabled">').attr("data-note-type", noteType.type).append('<span class="check">&check;</span> ').append($("<strong>").text());
}
if (this.note.type === noteType.type) {
@ -93,15 +85,10 @@ export default class NoteTypeWidget extends NoteContextAwareWidget {
this.$noteTypeDropdown.append($typeLink);
}
for (const mimeType of mimeTypesService.getMimeTypes()) {
if (!mimeType.enabled) {
continue;
}
for (const mimeType of ) {
const $mimeLink = $('<a class="dropdown-item">')
.attr("data-mime-type", mimeType.mime)
.append('<span class="check">&check;</span> ')
.append($("<span>").text(mimeType.title))
.on("click", (e) => {
const $link = $(e.target).closest(".dropdown-item");

View File

@ -11,11 +11,12 @@ interface DropdownProps {
children: ComponentChildren;
title?: string;
dropdownContainerStyle?: CSSProperties;
dropdownContainerClassName?: string;
hideToggleArrow?: boolean;
disabled?: boolean;
}
export default function Dropdown({ className, buttonClassName, isStatic, children, title, dropdownContainerStyle, hideToggleArrow, disabled }: DropdownProps) {
export default function Dropdown({ className, buttonClassName, isStatic, children, title, dropdownContainerStyle, dropdownContainerClassName, hideToggleArrow, disabled }: DropdownProps) {
const dropdownRef = useRef<HTMLDivElement | null>(null);
const triggerRef = useRef<HTMLButtonElement | null>(null);
@ -68,7 +69,7 @@ export default function Dropdown({ className, buttonClassName, isStatic, childre
/>
<div
class={`dropdown-menu ${isStatic ? "static" : undefined}`}
class={`dropdown-menu ${isStatic ? "static" : ""} ${dropdownContainerClassName ?? ""} tn-dropdown-list`}
style={dropdownContainerStyle}
aria-labelledby={ariaId}
>

View File

@ -75,12 +75,13 @@ interface FormListItemOpts {
title?: string;
active?: boolean;
badges?: FormListBadge[];
disabled?: boolean;
}
export function FormListItem({ children, icon, value, title, active, badges }: FormListItemOpts) {
export function FormListItem({ children, icon, value, title, active, badges, disabled }: FormListItemOpts) {
return (
<a
class={`dropdown-item ${active ? "active" : ""}`}
class={`dropdown-item ${active ? "active" : ""} ${disabled ? "disabled" : ""}`}
data-value={value} title={title}
tabIndex={0}
>
@ -104,3 +105,7 @@ export function FormListHeader({ text }: FormListHeaderOpts) {
</li>
)
}
export function FormDivider() {
return <div className="dropdown-divider" />;
}

View File

@ -1,8 +1,10 @@
import { useCallback, useMemo } from "preact/hooks";
import Dropdown from "../react/Dropdown";
import { NOTE_TYPES } from "../../services/note_types";
import { FormListBadge, FormListItem } from "../react/FormList";
import { FormDivider, FormListBadge, FormListItem } from "../react/FormList";
import { t } from "../../services/i18n";
import { useTriliumOption } from "../react/hooks";
import mime_types from "../../services/mime_types";
export default function BasicPropertiesTab() {
return (
@ -14,9 +16,11 @@ export default function BasicPropertiesTab() {
function NoteTypeWidget() {
const noteTypes = useMemo(() => NOTE_TYPES.filter((nt) => !nt.reserved && !nt.static), []);
const [ codeNotesMimeTypes ] = useTriliumOption("codeNotesMimeTypes");
const mimeTypes = useMemo(() => mime_types.getMimeTypes().filter(mimeType => mimeType.enabled), [ codeNotesMimeTypes ]);
return (
<Dropdown>
<Dropdown dropdownContainerClassName="note-type-dropdown">
{noteTypes.map(noteType => {
const badges: FormListBadge[] = [];
if (noteType.isNew) {
@ -31,12 +35,27 @@ function NoteTypeWidget() {
});
}
return (
<FormListItem
badges={badges}
>{noteType.title}</FormListItem>
);
if (noteType.type !== "code") {
return (
<FormListItem
badges={badges}
>{noteType.title}</FormListItem>
);
} else {
return (
<>
<FormDivider />
<FormListItem disabled>
<strong>{noteType.title}</strong>
</FormListItem>
</>
)
}
})}
{mimeTypes.map(mimeType => (
<FormListItem>{mimeType.title}</FormListItem>
))}
</Dropdown>
)
}

View File

@ -115,3 +115,9 @@
display: flex;
align-items: center;
}
.note-type-dropdown {
max-height: 500px;
overflow-y: auto;
overflow-x: hidden;
}