mirror of
https://github.com/notion-enhancer/notion-enhancer.git
synced 2025-04-10 15:39:01 +00:00
feat(menu): clone notion select/dropdown
This commit is contained in:
parent
5db238024a
commit
b1e1405409
@ -162,8 +162,8 @@ const svgElements = [
|
|||||||
"use",
|
"use",
|
||||||
"view",
|
"view",
|
||||||
],
|
],
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes
|
|
||||||
htmlAttributes = [
|
htmlAttributes = [
|
||||||
|
// https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes
|
||||||
"accept",
|
"accept",
|
||||||
"accept-charset",
|
"accept-charset",
|
||||||
"accesskey",
|
"accesskey",
|
||||||
@ -292,7 +292,246 @@ const svgElements = [
|
|||||||
"value",
|
"value",
|
||||||
"width",
|
"width",
|
||||||
"wrap",
|
"wrap",
|
||||||
|
// https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute[
|
||||||
|
"accent-height",
|
||||||
|
"accumulate",
|
||||||
|
"additive",
|
||||||
|
"alignment-baseline",
|
||||||
|
"alphabetic",
|
||||||
|
"amplitude",
|
||||||
|
"arabic-form",
|
||||||
|
"ascent",
|
||||||
|
"attributeName",
|
||||||
|
"attributeType",
|
||||||
|
"azimuth",
|
||||||
|
"baseFrequency",
|
||||||
|
"baseline-shift",
|
||||||
|
"baseProfile",
|
||||||
|
"bbox",
|
||||||
|
"begin",
|
||||||
|
"bias",
|
||||||
|
"by",
|
||||||
|
"calcMode",
|
||||||
|
"cap-height",
|
||||||
|
"clip",
|
||||||
|
"clipPathUnits",
|
||||||
|
"clip-path",
|
||||||
|
"clip-rule",
|
||||||
|
"color-interpolation",
|
||||||
|
"color-interpolation-filters",
|
||||||
|
"color-profile",
|
||||||
|
"color-rendering",
|
||||||
|
"contentScriptType",
|
||||||
|
"contentStyleType",
|
||||||
|
"cursor",
|
||||||
|
"cx",
|
||||||
|
"cy",
|
||||||
|
"d",
|
||||||
|
"decelerate",
|
||||||
|
"descent",
|
||||||
|
"diffuseConstant",
|
||||||
|
"direction",
|
||||||
|
"display",
|
||||||
|
"divisor",
|
||||||
|
"dominant-baseline",
|
||||||
|
"dur",
|
||||||
|
"dx",
|
||||||
|
"dy",
|
||||||
|
"edgeMode",
|
||||||
|
"elevation",
|
||||||
|
"enable-background",
|
||||||
|
"end",
|
||||||
|
"exponent",
|
||||||
|
"fill",
|
||||||
|
"fill-opacity",
|
||||||
|
"fill-rule",
|
||||||
|
"filter",
|
||||||
|
"filterRes",
|
||||||
|
"filterUnits",
|
||||||
|
"flood-color",
|
||||||
|
"flood-opacity",
|
||||||
|
"font-family",
|
||||||
|
"font-size",
|
||||||
|
"font-size-adjust",
|
||||||
|
"font-stretch",
|
||||||
|
"font-style",
|
||||||
|
"font-variant",
|
||||||
|
"font-weight",
|
||||||
|
"format",
|
||||||
|
"from",
|
||||||
|
"fr",
|
||||||
|
"fx",
|
||||||
|
"fy",
|
||||||
|
"g1",
|
||||||
|
"g2",
|
||||||
|
"glyph-name",
|
||||||
|
"glyph-orientation-horizontal",
|
||||||
|
"glyph-orientation-vertical",
|
||||||
|
"glyphRef",
|
||||||
|
"gradientTransform",
|
||||||
|
"gradientUnits",
|
||||||
|
"hanging",
|
||||||
|
"horiz-adv-x",
|
||||||
|
"horiz-origin-x",
|
||||||
|
"ideographic",
|
||||||
|
"image-rendering",
|
||||||
|
"in",
|
||||||
|
"in2",
|
||||||
|
"intercept",
|
||||||
|
"k",
|
||||||
|
"k1",
|
||||||
|
"k2",
|
||||||
|
"k3",
|
||||||
|
"k4",
|
||||||
|
"kernelMatrix",
|
||||||
|
"kernelUnitLength",
|
||||||
|
"kerning",
|
||||||
|
"keyPoints",
|
||||||
|
"keySplines",
|
||||||
|
"keyTimes",
|
||||||
|
"lengthAdjust",
|
||||||
|
"letter-spacing",
|
||||||
|
"lighting-color",
|
||||||
|
"limitingConeAngle",
|
||||||
|
"local",
|
||||||
|
"marker-end",
|
||||||
|
"marker-mid",
|
||||||
|
"marker-start",
|
||||||
|
"markerHeight",
|
||||||
|
"markerUnits",
|
||||||
|
"markerWidth",
|
||||||
|
"mask",
|
||||||
|
"maskContentUnits",
|
||||||
|
"maskUnits",
|
||||||
|
"mathematical",
|
||||||
|
"mode",
|
||||||
|
"numOctaves",
|
||||||
|
"offset",
|
||||||
|
"opacity",
|
||||||
|
"operator",
|
||||||
|
"order",
|
||||||
|
"orient",
|
||||||
|
"orientation",
|
||||||
|
"origin",
|
||||||
|
"overflow",
|
||||||
|
"overline-position",
|
||||||
|
"overline-thickness",
|
||||||
|
"panose-1",
|
||||||
|
"paint-order",
|
||||||
|
"path",
|
||||||
|
"pathLength",
|
||||||
|
"patternContentUnits",
|
||||||
|
"patternTransform",
|
||||||
|
"patternUnits",
|
||||||
|
"pointer-events",
|
||||||
|
"points",
|
||||||
|
"pointsAtX",
|
||||||
|
"pointsAtY",
|
||||||
|
"pointsAtZ",
|
||||||
|
"preserveAlpha",
|
||||||
|
"preserveAspectRatio",
|
||||||
|
"primitiveUnits",
|
||||||
|
"r",
|
||||||
|
"radius",
|
||||||
|
"referrerPolicy",
|
||||||
|
"refX",
|
||||||
|
"refY",
|
||||||
|
"rendering-intent",
|
||||||
|
"repeatCount",
|
||||||
|
"repeatDur",
|
||||||
|
"requiredExtensions",
|
||||||
|
"requiredFeatures",
|
||||||
|
"restart",
|
||||||
|
"result",
|
||||||
|
"rotate",
|
||||||
|
"rx",
|
||||||
|
"ry",
|
||||||
|
"scale",
|
||||||
|
"seed",
|
||||||
|
"shape-rendering",
|
||||||
|
"slope",
|
||||||
|
"spacing",
|
||||||
|
"specularConstant",
|
||||||
|
"specularExponent",
|
||||||
|
"speed",
|
||||||
|
"spreadMethod",
|
||||||
|
"startOffset",
|
||||||
|
"stdDeviation",
|
||||||
|
"stemh",
|
||||||
|
"stemv",
|
||||||
|
"stitchTiles",
|
||||||
|
"stop-color",
|
||||||
|
"stop-opacity",
|
||||||
|
"strikethrough-position",
|
||||||
|
"strikethrough-thickness",
|
||||||
|
"string",
|
||||||
|
"stroke",
|
||||||
|
"stroke-dasharray",
|
||||||
|
"stroke-dashoffset",
|
||||||
|
"stroke-linecap",
|
||||||
|
"stroke-linejoin",
|
||||||
|
"stroke-miterlimit",
|
||||||
|
"stroke-opacity",
|
||||||
|
"stroke-width",
|
||||||
|
"surfaceScale",
|
||||||
|
"systemLanguage",
|
||||||
|
"tableValues",
|
||||||
|
"targetX",
|
||||||
|
"targetY",
|
||||||
|
"text-anchor",
|
||||||
|
"text-decoration",
|
||||||
|
"text-rendering",
|
||||||
|
"textLength",
|
||||||
|
"to",
|
||||||
|
"transform",
|
||||||
|
"transform-origin",
|
||||||
|
"u1",
|
||||||
|
"u2",
|
||||||
|
"underline-position",
|
||||||
|
"underline-thickness",
|
||||||
|
"unicode",
|
||||||
|
"unicode-bidi",
|
||||||
|
"unicode-range",
|
||||||
|
"units-per-em",
|
||||||
|
"v-alphabetic",
|
||||||
|
"v-hanging",
|
||||||
|
"v-ideographic",
|
||||||
|
"v-mathematical",
|
||||||
|
"values",
|
||||||
|
"vector-effect",
|
||||||
|
"version",
|
||||||
|
"vert-adv-y",
|
||||||
|
"vert-origin-x",
|
||||||
|
"vert-origin-y",
|
||||||
|
"viewBox",
|
||||||
|
"viewTarget",
|
||||||
|
"visibility",
|
||||||
|
"widths",
|
||||||
|
"word-spacing",
|
||||||
|
"writing-mode",
|
||||||
|
"x",
|
||||||
|
"x-height",
|
||||||
|
"x1",
|
||||||
|
"x2",
|
||||||
|
"xChannelSelector",
|
||||||
|
"xlink:actuate",
|
||||||
|
"xlink:arcrole",
|
||||||
|
"xlink:href",
|
||||||
|
"xlink:role",
|
||||||
|
"xlink:show",
|
||||||
|
"xlink:title",
|
||||||
|
"xlink:type",
|
||||||
|
"xml:base",
|
||||||
|
"xml:lang",
|
||||||
|
"xml:space",
|
||||||
|
"y",
|
||||||
|
"y1",
|
||||||
|
"y2",
|
||||||
|
"yChannelSelector",
|
||||||
|
"z",
|
||||||
|
"zoomAndPan",
|
||||||
];
|
];
|
||||||
|
|
||||||
// html`<div class=${className}></div>`
|
// html`<div class=${className}></div>`
|
||||||
const h = (type, props, ...children) => {
|
const h = (type, props, ...children) => {
|
||||||
children = children.flat(Infinity);
|
children = children.flat(Infinity);
|
||||||
|
@ -33,7 +33,7 @@ const SidebarButton = ({ icon, ...props }, ...children) => {
|
|||||||
icon === "notion-enhancer"
|
icon === "notion-enhancer"
|
||||||
? "w-[16px] h-[16px] ml-[2px] mr-[10px]"
|
? "w-[16px] h-[16px] ml-[2px] mr-[10px]"
|
||||||
: "w-[18px] h-[18px] ml-px mr-[9px]",
|
: "w-[18px] h-[18px] ml-px mr-[9px]",
|
||||||
el = html`<${props.href ? "a" : "button"}
|
$el = html`<${props.href ? "a" : "button"}
|
||||||
class="flex select-none cursor-pointer w-full
|
class="flex select-none cursor-pointer w-full
|
||||||
items-center py-[5px] px-[15px] text-[14px] last:mb-[12px]
|
items-center py-[5px] px-[15px] text-[14px] last:mb-[12px]
|
||||||
transition hover:bg-[color:var(--theme--bg-hover)]"
|
transition hover:bg-[color:var(--theme--bg-hover)]"
|
||||||
@ -43,20 +43,20 @@ const SidebarButton = ({ icon, ...props }, ...children) => {
|
|||||||
<span class="leading-[20px]">${children}</span>
|
<span class="leading-[20px]">${children}</span>
|
||||||
<//>`;
|
<//>`;
|
||||||
if (!props.href) {
|
if (!props.href) {
|
||||||
const id = el.innerText;
|
const id = $el.innerText;
|
||||||
el.onclick ??= () => setState({ view: id });
|
$el.onclick ??= () => setState({ view: id });
|
||||||
useState(["view"], ([view = "welcome"]) => {
|
useState(["view"], ([view = "welcome"]) => {
|
||||||
const active = view.toLowerCase() === id.toLowerCase();
|
const active = view.toLowerCase() === id.toLowerCase();
|
||||||
el.style.background = active ? "var(--theme--bg-hover)" : "";
|
$el.style.background = active ? "var(--theme--bg-hover)" : "";
|
||||||
el.style.fontWeight = active ? "600" : "";
|
$el.style.fontWeight = active ? "600" : "";
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return el;
|
return $el;
|
||||||
};
|
};
|
||||||
|
|
||||||
const View = ({ id }, ...children) => {
|
const View = ({ id }, ...children) => {
|
||||||
const { html } = globalThis.__enhancerApi,
|
const { html } = globalThis.__enhancerApi,
|
||||||
el = html`<article
|
$el = html`<article
|
||||||
id=${id}
|
id=${id}
|
||||||
class="notion-enhancer--menu-view h-full
|
class="notion-enhancer--menu-view h-full
|
||||||
overflow-y-auto px-[60px] py-[36px] grow"
|
overflow-y-auto px-[60px] py-[36px] grow"
|
||||||
@ -65,9 +65,9 @@ const View = ({ id }, ...children) => {
|
|||||||
</article>`;
|
</article>`;
|
||||||
useState(["view"], ([view = "welcome"]) => {
|
useState(["view"], ([view = "welcome"]) => {
|
||||||
const active = view.toLowerCase() === id.toLowerCase();
|
const active = view.toLowerCase() === id.toLowerCase();
|
||||||
el.style.display = active ? "" : "none";
|
$el.style.display = active ? "" : "none";
|
||||||
});
|
});
|
||||||
return el;
|
return $el;
|
||||||
};
|
};
|
||||||
|
|
||||||
const TextInput = ({}, ...children) => {};
|
const TextInput = ({}, ...children) => {};
|
||||||
@ -80,7 +80,52 @@ const ColorInput = ({}, ...children) => {};
|
|||||||
|
|
||||||
const FileInput = ({}, ...children) => {};
|
const FileInput = ({}, ...children) => {};
|
||||||
|
|
||||||
const Select = ({}, ...children) => {};
|
const Select = ({ values, onchange, ...props }, ...children) => {
|
||||||
|
const { html } = globalThis.__enhancerApi,
|
||||||
|
updateWidth = ($select) => {
|
||||||
|
const $tmp = html`<span
|
||||||
|
class="text-[14px] pl-[8px] pr-[32px]
|
||||||
|
absolute top-[-9999px] left-[-9999px]"
|
||||||
|
>${$select.value}</span
|
||||||
|
>`;
|
||||||
|
document.body.append($tmp);
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
$select.style.width = `${Math.min($tmp.offsetWidth, 256)}px`;
|
||||||
|
$tmp.remove();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
props.onchange = (event) => {
|
||||||
|
onchange?.(event);
|
||||||
|
updateWidth(event.target);
|
||||||
|
};
|
||||||
|
|
||||||
|
const $select = html`<select
|
||||||
|
class="appearance-none bg-transparent rounded-[4px] max-w-[256px]
|
||||||
|
text-[14px] leading-[1.2] h-[28px] pl-[8px] pr-[32px] cursor-pointer
|
||||||
|
transition duration-[20ms] hover:bg-[color:var(--theme--bg-hover)]"
|
||||||
|
...${props}
|
||||||
|
>
|
||||||
|
${values.map((value) => {
|
||||||
|
return html`<option
|
||||||
|
value=${value}
|
||||||
|
class="bg-[color:var(--theme--bg-secondary)]
|
||||||
|
text-[color:var(--theme--fg-primary)]"
|
||||||
|
>
|
||||||
|
${value}
|
||||||
|
</option>`;
|
||||||
|
})}
|
||||||
|
</select>`;
|
||||||
|
updateWidth($select);
|
||||||
|
|
||||||
|
return html`<div class="notion-enhancer--menu-select relative">
|
||||||
|
${$select}
|
||||||
|
<i
|
||||||
|
class="i-chevron-down pointer-events-none
|
||||||
|
absolute right-[8px] top-[6px] w-[16px] h-[16px]
|
||||||
|
text-[color:var(--theme--fg-secondary)]"
|
||||||
|
></i>
|
||||||
|
</div>`;
|
||||||
|
};
|
||||||
|
|
||||||
const Toggle = (props, ..._children) => {
|
const Toggle = (props, ..._children) => {
|
||||||
const { html } = globalThis.__enhancerApi;
|
const { html } = globalThis.__enhancerApi;
|
||||||
@ -128,7 +173,7 @@ const Option = ({ mod, type, ...props }, ..._children) => {
|
|||||||
</h2>`;
|
</h2>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const id = `${mod}-${props.key}`;
|
let $input;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
// case "text":
|
// case "text":
|
||||||
// break;
|
// break;
|
||||||
@ -140,28 +185,40 @@ const Option = ({ mod, type, ...props }, ..._children) => {
|
|||||||
// break;
|
// break;
|
||||||
// case "file":
|
// case "file":
|
||||||
// break;
|
// break;
|
||||||
// case "select":
|
// <div
|
||||||
// break;
|
// class="notion-focusable"
|
||||||
// case "toggle":
|
// role="button"
|
||||||
default:
|
// tabindex="0"
|
||||||
|
// style="display: inline-flex; align-items: center; flex-shrink: 0; white-space: nowrap; height: 28px; border-radius: 4px; font-size: 14px; line-height: 1.2; min-width: 0px; padding-left: 8px; padding-right: 8px; color: rgba(255, 255, 255, 0.81); margin-top: 12px; margin-bottom: 4px;"
|
||||||
|
// >
|
||||||
|
// ${props.values[0]}
|
||||||
|
// <svg
|
||||||
|
// viewBox="0 0 30 30"
|
||||||
|
// class="chevronDown"
|
||||||
|
// style="width: 10px; height: 100%; display: block; fill: rgba(255, 255, 255, 0.282); flex-shrink: 0; backface-visibility: hidden; margin-left: 4px;"
|
||||||
|
// >
|
||||||
|
// <polygon points="15,17.4 4.8,7 2,9.8 15,23 28,9.8 25.2,7"></polygon>
|
||||||
|
// </svg>
|
||||||
|
// </div>
|
||||||
|
case "select":
|
||||||
|
$input = html`<${Select} values=${props.values} />`;
|
||||||
break;
|
break;
|
||||||
|
case "toggle":
|
||||||
|
$input = html`<${Toggle} />`;
|
||||||
}
|
}
|
||||||
return html`
|
return html`<${type === "toggle" ? "label" : "div"}
|
||||||
<label
|
class="notion-enhancer--menu-option flex items-center justify-between
|
||||||
class="notion-enhancer--menu-option mb-[18px]
|
mb-[18px] ${type === "toggle" ? "cursor-pointer" : ""}"
|
||||||
flex items-center justify-between cursor-pointer"
|
><div class="flex flex-col mr-[10%]">
|
||||||
>
|
<h3 class="text-[14px] mb-[2px] mt-0">${label}</h3>
|
||||||
<div class="flex flex-col mr-[10%]" for=${id}>
|
<p
|
||||||
<h3 class="text-[14px] mb-[2px] mt-0">${label}</h3>
|
class="text-[12px] leading-[16px]
|
||||||
<p
|
text-[color:var(--theme--fg-secondary)]"
|
||||||
class="text-[12px] leading-[16px]
|
innerHTML=${description}
|
||||||
text-[color:var(--theme--fg-secondary)]"
|
></p>
|
||||||
innerHTML=${description}
|
</div>
|
||||||
></p>
|
${$input}
|
||||||
</div>
|
<//>`;
|
||||||
<${Toggle} id=${id} />
|
|
||||||
</label>
|
|
||||||
`;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export { Sidebar, SidebarSection, SidebarButton, View, Toggle, Option };
|
export { Sidebar, SidebarSection, SidebarButton, View, Select, Toggle, Option };
|
||||||
|
Loading…
Reference in New Issue
Block a user