diff --git a/src/core/islands/Panel.mjs b/src/core/islands/Panel.mjs
index 7217e19..1149b98 100644
--- a/src/core/islands/Panel.mjs
+++ b/src/core/islands/Panel.mjs
@@ -50,27 +50,27 @@ function View({ _get }) {
function Switcher({ _get, _set, minWidth, maxWidth }) {
const { html, useState } = globalThis.__enhancerApi,
- $switcher = html`
`,
- setView = (view) => _set?.(view);
+ $select = html`<${Select}
+ popupMode="dropdown"
+ class="w-full text-left"
+ maxWidth=${maxWidth - 56}
+ minWidth=${minWidth - 56}
+ ...${{ _get, _set }}
+ />`;
useState(["panelViews"], ([panelViews = []]) => {
const values = panelViews.map(([{ title, $icon }]) => {
// panel switcher internally uses the select island,
// which expects an option value rather than a title
return { value: title, $icon };
});
- $switcher.innerHTML = "";
- $switcher.append(html`<${Select}
- popupMode="dropdown"
- class="w-full text-left"
- maxWidth=${maxWidth - 56}
- minWidth=${minWidth - 56}
- ...${{ _get, _set: setView, values }}
- />`);
+ $select.setValues(values);
});
- return $switcher;
+ return html`
+ ${$select}
+
`;
}
function Panel({
diff --git a/src/core/menu/islands/Select.mjs b/src/core/menu/islands/Select.mjs
index 1d753dd..93b6b54 100644
--- a/src/core/menu/islands/Select.mjs
+++ b/src/core/menu/islands/Select.mjs
@@ -7,46 +7,40 @@
import { Popup } from "./Popup.mjs";
function Option({ $icon = "", value = "", _get, _set }) {
- const { html, useState } = globalThis.__enhancerApi,
- $selected = html``,
- $option = html` event.target.focus()}
- onclick=${() => _set?.(value)}
- onkeydown=${(event) => {
- // if (["Enter", " "].includes(event.key)) _set?.(value);
- }}
+ const { html, useState } = globalThis.__enhancerApi;
+ return html`
event.target.focus()}
+ onclick=${() => _set?.(value)}
+ onkeydown=${(event) => {
+ if (["Enter", " "].includes(event.key)) _set?.(value);
+ }}
+ >
+
`;
- useState(["rerender"], async () => {
- if ((await _get?.()) === value) {
- $option.append($selected);
- } else $selected.remove();
- });
- return $option;
+ ${$icon}
${value}
+
+
`;
}
function Select({
- values,
_get,
_set,
_requireReload = true,
+ values = [],
popupMode = "left",
maxWidth = 256,
minWidth = 48,
...props
}) {
const { html, extendProps, setState, useState } = globalThis.__enhancerApi,
+ $selected = html``,
// dir="rtl" overflows to the left during transition
$select = html``;
-
- let xyz;
- const options = values.map((opt) => {
- if (["string", "number"].includes(typeof opt)) opt = { value: opt };
- if (!(opt?.$icon instanceof Element)) {
- if (typeof opt?.$icon === "string") {
- opt.$icon = html``;
- } else delete opt.$icon;
- }
- return {
- ...opt,
- $option: html`<${Option} ...${{ ...opt, _get, _set }} />`,
- $value: html`
-
- ${opt.value}${opt.$icon?.cloneNode(true) ?? ""}
-
`,
- };
- }),
- getSelected = async () => {
- const value = (await _get?.()) ?? $select.innerText,
- option = options.find((opt) => opt.value === value);
- if (!option) {
- console.log(1, options, options.length, options === xyz);
- _set?.(options[0].value);
- }
- return option || options[0];
- },
+ >`,
+ $popup = html``,
onKeydown = (event) => {
- // const intercept = () => {
- // event.preventDefault();
- // event.stopPropagation();
- // };
- // if (event.key === "Escape") {
- // intercept(setState({ rerender: true }));
- // } else if (!options.length) return;
- // // prettier-ignore
- // const $next = options.find(({ $option }) => $option === event.target)
- // ?.$option.nextElementSibling ?? options.at(0).$option,
- // $prev = options.find(({ $option }) => $option === event.target)
- // ?.$option.previousElementSibling ?? options.at(-1).$option;
- // // overflow to opposite end of list from dir of travel
- // if (event.key === "ArrowUp") intercept($prev.focus());
- // if (event.key === "ArrowDown") intercept($next.focus());
- // // re-enable natural tab behaviour in notion interface
- // if (event.key === "Tab") event.stopPropagation();
+ const intercept = () => {
+ event.preventDefault();
+ event.stopPropagation();
+ };
+ if (event.key === "Escape") {
+ intercept(setState({ rerender: true }));
+ } else if (!options.length) return;
+ // prettier-ignore
+ const $next = options.find(({ $option }) => $option === event.target)
+ ?.$option.nextElementSibling ?? options.at(0).$option,
+ $prev = options.find(({ $option }) => $option === event.target)
+ ?.$option.previousElementSibling ?? options.at(-1).$option;
+ // overflow to opposite end of list from dir of travel
+ if (event.key === "ArrowUp") intercept($prev.focus());
+ if (event.key === "ArrowDown") intercept($next.focus());
+ // re-enable natural tab behaviour in notion interface
+ if (event.key === "Tab") event.stopPropagation();
};
- xyz = options;
- console.log(2, options, options.length, options === xyz);
+
+ let options = [];
+ const valueToOption = (opt) => {
+ if (["string", "number"].includes(typeof opt)) opt = { value: opt };
+ if (!(opt?.$icon instanceof Element)) {
+ if (typeof opt?.$icon === "string") {
+ opt.$icon = html``;
+ } else delete opt.$icon;
+ }
+ const $icon = opt.$icon?.cloneNode(true);
+ return {
+ ...opt,
+ $option: html`<${Option} ...${{ ...opt, _get, _set }} />`,
+ $value: html`
+
+ ${opt.label || opt.value}${$icon ?? ""}
+
`,
+ };
+ };
+ $select.setValues = (values) => {
+ options = values.map(valueToOption);
+ $popup.innerHTML = "";
+ $popup.append(...options.map(({ $option }) => $option));
+ };
+ $select.setValues(values);
let _initialValue;
+ const getSelected = async () => {
+ const value = (await _get?.()) ?? $select.innerText,
+ option = options.find((opt) => opt.value === value);
+ if (!option) _set?.(options[0].value);
+ return option || options[0];
+ };
useState(["rerender"], async () => {
if (!options.length) return;
- const { value, $value } = await getSelected();
+ const { value, $value, $option } = await getSelected();
$select.innerHTML = "";
$select.append($value);
+ $option.append($selected);
if (_requireReload) {
_initialValue ??= value;
if (value !== _initialValue) setState({ databaseUpdated: true });
@@ -122,7 +118,7 @@ function Select({
});
extendProps(props, { class: "notion-enhancer--menu-select relative" });
- return html`
+ return html`
${$select}<${Popup}
tabindex="0"
trigger=${$select}
@@ -137,7 +133,7 @@ function Select({
$select.style.width = "";
$select.style.background = "";
}}
- >${options.map(({ $option }) => $option)}
+ >${$popup}
/>
{