mirror of
https://github.com/notion-enhancer/notion-enhancer.git
synced 2025-04-09 15:09:02 +00:00
extension: simpler databases
This commit is contained in:
parent
38484b7e42
commit
047b4cce7d
@ -26,7 +26,7 @@ export default async function ({ web }, db) {
|
|||||||
lineNumbers += `${i}\n`;
|
lineNumbers += `${i}\n`;
|
||||||
if (wordWrap && lines[i - 1]) {
|
if (wordWrap && lines[i - 1]) {
|
||||||
$temp.innerText = lines[i - 1];
|
$temp.innerText = lines[i - 1];
|
||||||
$codeBlock.lastElementChild.append($temp);
|
web.render($codeBlock.lastElementChild, $temp);
|
||||||
const height = parseFloat($temp.getBoundingClientRect().height);
|
const height = parseFloat($temp.getBoundingClientRect().height);
|
||||||
$temp.remove();
|
$temp.remove();
|
||||||
for (let j = 1; j < height / 20.4; j++) lineNumbers += '\n';
|
for (let j = 1; j < height / 20.4; j++) lineNumbers += '\n';
|
||||||
|
@ -1,86 +0,0 @@
|
|||||||
/*
|
|
||||||
* collapsible headers
|
|
||||||
* (c) 2020 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
|
|
||||||
* (c) 2020 CloudHill
|
|
||||||
* under the MIT license
|
|
||||||
*/
|
|
||||||
|
|
||||||
.notion-page-content .notion-selectable[collapsed] {
|
|
||||||
max-height: 0px;
|
|
||||||
overflow: hidden;
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.notion-page-content .notion-selectable[collapsed] .notion-selectable {
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.collapse-header {
|
|
||||||
flex-grow: 0;
|
|
||||||
flex-shrink: 0;
|
|
||||||
align-self: center;
|
|
||||||
width: 24px;
|
|
||||||
height: 24px;
|
|
||||||
padding: 6px;
|
|
||||||
margin: 0 6px;
|
|
||||||
border-radius: 3px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
z-index: 1;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: 200ms ease-in;
|
|
||||||
}
|
|
||||||
.collapse-header:hover {
|
|
||||||
background: var(--theme--interactive_hover);
|
|
||||||
}
|
|
||||||
/* position: left */
|
|
||||||
.collapse-header:first-child {
|
|
||||||
margin-left: 2px;
|
|
||||||
}
|
|
||||||
/* position: right / inline */
|
|
||||||
.collapse-header:last-child {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* show toggle on: collapsed, hover, focus */
|
|
||||||
[data-collapsed="true"] .collapse-header:last-child,
|
|
||||||
[data-collapsed]:hover .collapse-header:last-child,
|
|
||||||
[data-collapsed] :focus + .collapse-header:last-child {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.collapse-header svg {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
transition: transform 200ms ease-out 0s;
|
|
||||||
}
|
|
||||||
/* position: left */
|
|
||||||
.collapse-header:first-child svg {
|
|
||||||
transform: rotateZ(90deg);
|
|
||||||
}
|
|
||||||
/* position: right / inline */
|
|
||||||
.collapse-header:last-child svg {
|
|
||||||
transform: rotateZ(270deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
[data-collapsed="false"] .collapse-header svg {
|
|
||||||
transform: rotateZ(180deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* position: inline */
|
|
||||||
[inline-toggle] {
|
|
||||||
position: relative;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
[inline-toggle] [placeholder] {
|
|
||||||
width: auto !important;
|
|
||||||
}
|
|
||||||
[inline-toggle] [placeholder]::after {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
cursor: text;
|
|
||||||
}
|
|
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
export default async function ({ web }, db) {
|
export default async function ({ web }, db) {
|
||||||
const headerSelector = '.notion-page-content [class*="header-block"]',
|
const headerSelector = '.notion-page-content [class*="header-block"]',
|
||||||
|
pageScroller = '.notion-frame > .notion-scroller.vertical.horizontal',
|
||||||
haloClass = 'notion-selectable-halo',
|
haloClass = 'notion-selectable-halo',
|
||||||
blockSelector = '.notion-selectable[data-block-id]',
|
blockSelector = '.notion-selectable[data-block-id]',
|
||||||
dividerClass = 'notion-divider-block',
|
dividerClass = 'notion-divider-block',
|
||||||
@ -30,7 +31,7 @@ export default async function ({ web }, db) {
|
|||||||
overflow: 'hidden',
|
overflow: 'hidden',
|
||||||
};
|
};
|
||||||
|
|
||||||
const collapseParentsCache = new Map(),
|
let collapseParentsCache = new Map(),
|
||||||
collapsedBlocksCache = new Map();
|
collapsedBlocksCache = new Map();
|
||||||
|
|
||||||
const getHeaderLevel = ($block) => {
|
const getHeaderLevel = ($block) => {
|
||||||
@ -81,7 +82,7 @@ export default async function ({ web }, db) {
|
|||||||
[
|
[
|
||||||
animationCollapsed,
|
animationCollapsed,
|
||||||
{
|
{
|
||||||
height: $block.scrollHeight + 'px',
|
maxHeight: '100%',
|
||||||
opacity: 1,
|
opacity: 1,
|
||||||
marginTop: $block.style.marginTop,
|
marginTop: $block.style.marginTop,
|
||||||
marginBottom: $block.style.marginBottom,
|
marginBottom: $block.style.marginBottom,
|
||||||
@ -181,6 +182,12 @@ export default async function ({ web }, db) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const insertToggles = async (event) => {
|
const insertToggles = async (event) => {
|
||||||
|
if ([...event.addedNodes].some(($node) => $node?.matches(pageScroller))) {
|
||||||
|
collapseParentsCache = new Map();
|
||||||
|
collapsedBlocksCache = new Map();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const childNodeEvent =
|
const childNodeEvent =
|
||||||
event.target.matches(blockSelector) && !event.target.matches(headerSelector);
|
event.target.matches(blockSelector) && !event.target.matches(headerSelector);
|
||||||
if (childNodeEvent) return;
|
if (childNodeEvent) return;
|
||||||
@ -241,7 +248,7 @@ export default async function ({ web }, db) {
|
|||||||
`;
|
`;
|
||||||
if (togglePosition === 'left') {
|
if (togglePosition === 'left') {
|
||||||
$header.firstChild.prepend($toggle);
|
$header.firstChild.prepend($toggle);
|
||||||
} else $header.firstChild.append($toggle);
|
} else web.render($header.firstChild, $toggle);
|
||||||
if (togglePosition === 'inline') $header.firstChild.classList.add(inlineToggleClass);
|
if (togglePosition === 'inline') $header.firstChild.classList.add(inlineToggleClass);
|
||||||
|
|
||||||
$toggle.header = $header;
|
$toggle.header = $header;
|
||||||
@ -266,7 +273,7 @@ export default async function ({ web }, db) {
|
|||||||
expandHeaderSection($header, animateToggle);
|
expandHeaderSection($header, animateToggle);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
web.addDocumentObserver(insertToggles, [headerSelector]);
|
web.addDocumentObserver(insertToggles, ['.notion-page-content', headerSelector]);
|
||||||
|
|
||||||
web.addHotkeyListener(toggleHotkey, (event) => {
|
web.addHotkeyListener(toggleHotkey, (event) => {
|
||||||
const $header = document.activeElement.closest(headerSelector);
|
const $header = document.activeElement.closest(headerSelector);
|
||||||
|
@ -87,5 +87,5 @@ export default async function ({ web }, db) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
document.head.append(web.html`<style>${css}</style>`);
|
web.render(document.head, web.html`<style>${css}</style>`);
|
||||||
}
|
}
|
||||||
|
@ -61,7 +61,7 @@ export default async function ({ web, components }, db) {
|
|||||||
$outlineHeader.addEventListener('click', (event) => {
|
$outlineHeader.addEventListener('click', (event) => {
|
||||||
location.hash = '';
|
location.hash = '';
|
||||||
});
|
});
|
||||||
$fragment.append($outlineHeader);
|
web.render($fragment, $outlineHeader);
|
||||||
}
|
}
|
||||||
if ($fragment.innerHTML !== $headingList.innerHTML) {
|
if ($fragment.innerHTML !== $headingList.innerHTML) {
|
||||||
web.render(web.empty($headingList), ...$fragment.children);
|
web.render(web.empty($headingList), ...$fragment.children);
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
"scroll-to-top",
|
"scroll-to-top",
|
||||||
"indentation-lines",
|
"indentation-lines",
|
||||||
"right-to-left",
|
"right-to-left",
|
||||||
|
"simpler-databases",
|
||||||
"emoji-sets",
|
"emoji-sets",
|
||||||
"bypass-preview",
|
"bypass-preview",
|
||||||
"topbar-icons",
|
"topbar-icons",
|
||||||
|
429
repo/simpler-databases/client.css
Normal file
429
repo/simpler-databases/client.css
Normal file
@ -0,0 +1,429 @@
|
|||||||
|
/*
|
||||||
|
* notion-enhancer: simpler databases
|
||||||
|
* (c) 2020 CloudHill <rl.cloudhill@gmail.com> (https://github.com/CloudHill)
|
||||||
|
* (c) 2021 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
|
||||||
|
* (https://notion-enhancer.github.io/) under the MIT license
|
||||||
|
*/
|
||||||
|
|
||||||
|
.simpler_databases--config_button:hover {
|
||||||
|
background: linear-gradient(
|
||||||
|
var(--theme--ui_interactive-hover),
|
||||||
|
var(--theme--ui_interactive-hover)
|
||||||
|
),
|
||||||
|
linear-gradient(var(--theme--bg), var(--theme--bg));
|
||||||
|
}
|
||||||
|
.simpler_databases--config_button svg {
|
||||||
|
width: 12px;
|
||||||
|
height: 12px;
|
||||||
|
fill: var(--theme--icon_secondary);
|
||||||
|
}
|
||||||
|
.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[icon]']):not([data-simpler-db-tweaks*='[title]']):not([data-simpler-db-tweaks*='[toggle]']):not([data-simpler-db-tweaks*='[views']):not([data-simpler-db-tweaks*='[toolbar]'])
|
||||||
|
[style*=' height: 42px;']
|
||||||
|
> :last-child {
|
||||||
|
position: absolute;
|
||||||
|
top: 4px;
|
||||||
|
right: 0;
|
||||||
|
z-index: 99;
|
||||||
|
pointer-events: auto;
|
||||||
|
}
|
||||||
|
.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[icon]']):not([data-simpler-db-tweaks*='[title]']):not([data-simpler-db-tweaks*='[toggle]']):not([data-simpler-db-tweaks*='[views']):not([data-simpler-db-tweaks*='[toolbar]'])
|
||||||
|
.simpler_databases--config_button {
|
||||||
|
box-shadow: var(--theme--ui_shadow, rgba(15, 15, 15, 0.05)) 0px 0px 0px 1px,
|
||||||
|
var(--theme--ui_shadow, rgba(15, 15, 15, 0.1)) 0px 3px 6px,
|
||||||
|
var(--theme--ui_shadow, rgba(15, 15, 15, 0.2)) 0px 9px 24px !important;
|
||||||
|
}
|
||||||
|
.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[icon]']):not([data-simpler-db-tweaks*='[title]']):not([data-simpler-db-tweaks*='[toggle]']):not([data-simpler-db-tweaks*='[views']):not([data-simpler-db-tweaks*='[toolbar]'])
|
||||||
|
.simpler_databases--config_button:not(:hover) {
|
||||||
|
background: var(--theme--bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.simpler_databases--overlay_container {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: 999;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.simpler_databases--config_menu {
|
||||||
|
position: relative;
|
||||||
|
width: 220px;
|
||||||
|
max-height: 70vh;
|
||||||
|
padding: 8px 0;
|
||||||
|
border-radius: 3px;
|
||||||
|
box-shadow: var(--theme--ui_shadow, rgba(15, 15, 15, 0.05)) 0px 0px 0px 1px,
|
||||||
|
var(--theme--ui_shadow, rgba(15, 15, 15, 0.1)) 0px 3px 6px,
|
||||||
|
var(--theme--ui_shadow, rgba(15, 15, 15, 0.2)) 0px 9px 24px;
|
||||||
|
background: var(--theme--bg_card);
|
||||||
|
overflow: hidden auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.simpler_databases--config_item-toggle,
|
||||||
|
.simpler_databases--config_item-input {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
min-height: 28px;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1.2;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
.simpler_databases--config_item-toggle {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.simpler_databases--config_item-toggle:hover,
|
||||||
|
.simpler_databases--config_item-toggle:focus {
|
||||||
|
background: var(--theme--ui_interactive-hover);
|
||||||
|
}
|
||||||
|
.simpler_databases--config_item-input {
|
||||||
|
padding: 6px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.simpler_databases--config_title {
|
||||||
|
margin: 0 14px;
|
||||||
|
min-width: 0;
|
||||||
|
flex: 1 1 auto;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
.simpler_databases--config_toggle {
|
||||||
|
flex-shrink: 0;
|
||||||
|
position: relative;
|
||||||
|
height: 14px;
|
||||||
|
width: 26px;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: 14px;
|
||||||
|
padding: 2px;
|
||||||
|
border-radius: 44px;
|
||||||
|
cursor: pointer;
|
||||||
|
user-select: none;
|
||||||
|
box-sizing: content-box;
|
||||||
|
background: var(--theme--ui_toggle-off);
|
||||||
|
transition: background 200ms ease 0s, box-shadow 200ms ease 0s;
|
||||||
|
}
|
||||||
|
.simpler_databases--config_toggle[data-toggled='true'] {
|
||||||
|
background: var(--theme--ui_toggle-on);
|
||||||
|
}
|
||||||
|
.simpler_databases--config_toggle::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
width: 14px;
|
||||||
|
height: 14px;
|
||||||
|
border-radius: 44px;
|
||||||
|
background: var(--theme--ui_toggle-feature);
|
||||||
|
transition: transform 200ms ease-out 0s, background 200ms ease-out 0s;
|
||||||
|
}
|
||||||
|
.simpler_databases--config_toggle[data-toggled='true']::before {
|
||||||
|
transform: translateX(12px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.simpler_databases--config_input {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
height: 28px;
|
||||||
|
margin: 0 14px;
|
||||||
|
padding: 3px 6px;
|
||||||
|
background: var(--theme--ui_input);
|
||||||
|
box-shadow: var(--theme--ui_shadow) 0px 0px 0px 1px inset;
|
||||||
|
border-radius: 3px;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 20px;
|
||||||
|
cursor: text;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.simpler_databases--config_input input {
|
||||||
|
font-size: inherit;
|
||||||
|
line-height: inherit;
|
||||||
|
border: none;
|
||||||
|
background: none;
|
||||||
|
width: 100%;
|
||||||
|
display: block;
|
||||||
|
resize: none;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.simpler_databases--config_divider {
|
||||||
|
border-bottom: 1px solid var(--theme--ui_divider);
|
||||||
|
width: 100%;
|
||||||
|
margin: 6px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notion-collection_view-block[data-simpler-db-tweaks*='[config-open]']
|
||||||
|
[style*=' height: 42px;']
|
||||||
|
> :not(:first-child) {
|
||||||
|
opacity: 1 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TWEAKS */
|
||||||
|
|
||||||
|
/* Toggle */
|
||||||
|
.simpler_databases--toggle {
|
||||||
|
flex-shrink: 0;
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
border-radius: 3px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background 20ms ease-in 0s;
|
||||||
|
}
|
||||||
|
.simpler_databases--toggle svg {
|
||||||
|
width: 12px;
|
||||||
|
height: 12px;
|
||||||
|
transform: rotateZ(180deg);
|
||||||
|
transition: transform 200ms ease-out 0s;
|
||||||
|
}
|
||||||
|
.simpler_databases--toggle:hover {
|
||||||
|
background: var(--theme--ui_interactive-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
.notion-collection_view-block[data-simpler-db-tweaks*='[toggle]'][data-simpler-db-toggle-hidden='true']
|
||||||
|
.simpler_databases--toggle
|
||||||
|
svg {
|
||||||
|
transform: rotateZ(90deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.notion-collection_view-block[data-simpler-db-tweaks*='[toggle]'] > div > .notion-scroller {
|
||||||
|
transition: height 200ms ease-in, opacity 200ms ease-in;
|
||||||
|
}
|
||||||
|
.notion-collection_view-block[data-simpler-db-tweaks*='[toggle]'][data-simpler-db-toggle-hidden='true']
|
||||||
|
> div
|
||||||
|
> .notion-scroller {
|
||||||
|
opacity: 0;
|
||||||
|
height: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notion-collection_view-block[data-simpler-db-tweaks*='[toggle]'][data-simpler-db-toggle-hidden='true']
|
||||||
|
[data-simpler-db-hide-items]
|
||||||
|
[class$='view']
|
||||||
|
> .notion-collection_view-block,
|
||||||
|
.notion-collection_view-block[data-simpler-db-tweaks*='[toggle]'][data-simpler-db-toggle-hidden='true']
|
||||||
|
[data-simpler-db-hide-items]
|
||||||
|
.notion-collection-item {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Title */
|
||||||
|
|
||||||
|
.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[title]'])
|
||||||
|
[style*=' height: 42px;']
|
||||||
|
> [style*='white-space: nowrap; overflow: hidden;']
|
||||||
|
[placeholder] {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Icons + Link Arrows */
|
||||||
|
|
||||||
|
.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[icon]'])
|
||||||
|
[style*=' height: 42px;']
|
||||||
|
a
|
||||||
|
:first-child[style*='margin-right: 6px'] {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Views */
|
||||||
|
|
||||||
|
.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[views]'])
|
||||||
|
[style*=' height: 42px;']
|
||||||
|
> [role='button'] {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Toolbar */
|
||||||
|
|
||||||
|
.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[toolbar]'])
|
||||||
|
.simpler_databases--config_button
|
||||||
|
~ * {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Header - table, calendar */
|
||||||
|
|
||||||
|
.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[header_row]'])
|
||||||
|
.notion-table-view
|
||||||
|
> .notion-collection_view-block
|
||||||
|
> :first-child,
|
||||||
|
.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[header_row]'])
|
||||||
|
.notion-table-view
|
||||||
|
> .notion-collection_view-block
|
||||||
|
> :first-child
|
||||||
|
+ div {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[header_row]'])
|
||||||
|
.notion-table-view
|
||||||
|
.notion-collection_view-block
|
||||||
|
> [style*='height: 34px']
|
||||||
|
+ div {
|
||||||
|
border-top: 1px solid var(--theme--ui_divider);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* New Item - table, board, timeline, list, gallery */
|
||||||
|
|
||||||
|
.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[new_item]'])
|
||||||
|
.notion-table-view-add-row,
|
||||||
|
.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[new_item]'])
|
||||||
|
.notion-board-view
|
||||||
|
.notion-board-group
|
||||||
|
> [role='button']:not(.notion-collection-item),
|
||||||
|
.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[new_item]'])
|
||||||
|
.notion-timeline-item-row:last-child,
|
||||||
|
.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[new_item]'])
|
||||||
|
.notion-list-view
|
||||||
|
> .notion-collection_view-block
|
||||||
|
> [role='button']:not(.notion-collection-item),
|
||||||
|
.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[new_item]'])
|
||||||
|
.notion-gallery-view
|
||||||
|
> .notion-collection_view-block
|
||||||
|
[style*='grid']
|
||||||
|
> [role='button'] {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[new_item]'])
|
||||||
|
.notion-timeline-view
|
||||||
|
> [style*='padding-bottom: 34px;'] {
|
||||||
|
padding-bottom: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Calc Row - table, timeline */
|
||||||
|
|
||||||
|
.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[calc_row]'])
|
||||||
|
.notion-table-view-add-row
|
||||||
|
~ div:not(.notion-selectable-halo):not([role='button']),
|
||||||
|
.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[calc_row]'])
|
||||||
|
.notion-timeline-view
|
||||||
|
> [style*='z-index: 4;']:last-child {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hidden Columns - board */
|
||||||
|
|
||||||
|
.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[hidden_column]'])
|
||||||
|
.notion-board-view
|
||||||
|
> .notion-collection_view-block
|
||||||
|
[style*='width: 220px;'] {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add Group - board */
|
||||||
|
|
||||||
|
.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[add_group]'])
|
||||||
|
.notion-board-view
|
||||||
|
> .notion-collection_view-block
|
||||||
|
[style*='width: 180px;'] {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* New Column - table */
|
||||||
|
|
||||||
|
.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[new_column]'])
|
||||||
|
.notion-table-view-add-column,
|
||||||
|
.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[new_column]'])
|
||||||
|
.notion-table-view
|
||||||
|
.notion-collection-item
|
||||||
|
> [style*='width: 32px;'] {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[new_column]'])
|
||||||
|
.notion-table-view-add-row
|
||||||
|
+ [style*='padding-right: 32px;'] {
|
||||||
|
padding-right: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Full Width - table */
|
||||||
|
|
||||||
|
.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[full_width]'])
|
||||||
|
.notion-table-view
|
||||||
|
> .notion-collection_view-block {
|
||||||
|
max-width: fit-content;
|
||||||
|
}
|
||||||
|
.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[full_width]'])
|
||||||
|
.notion-table-view
|
||||||
|
.notion-collection_view-block
|
||||||
|
> [style*='min-width'] {
|
||||||
|
min-width: 0 !important;
|
||||||
|
}
|
||||||
|
.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[full_width]'])
|
||||||
|
.notion-table-view
|
||||||
|
.notion-collection-item {
|
||||||
|
width: fit-content;
|
||||||
|
}
|
||||||
|
.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[full_width]'])
|
||||||
|
.notion-table-view
|
||||||
|
.notion-collection_view-block
|
||||||
|
> [style*='height: 34px']
|
||||||
|
+ div,
|
||||||
|
.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[full_width]'])
|
||||||
|
.notion-table-view
|
||||||
|
.notion-collection_view-block
|
||||||
|
> :first-child {
|
||||||
|
border-left: 1px solid var(--theme--ui_divider);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* COMPOUND TWEAKS */
|
||||||
|
|
||||||
|
/* Title and Link disabled > Hide title container */
|
||||||
|
.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[icon]']):not([data-simpler-db-tweaks*='[title]'])
|
||||||
|
[style*=' height: 42px;']
|
||||||
|
> [style*='white-space: nowrap; overflow: hidden;'] {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* New Row and Calc Row disabled > Add bottom border - table */
|
||||||
|
.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[calc_row]']):not([data-simpler-db-tweaks*='[new_item]'])
|
||||||
|
.notion-table-view
|
||||||
|
.notion-collection_view-block
|
||||||
|
> [style*='height: 34px']
|
||||||
|
+ div {
|
||||||
|
border-bottom: 1px solid var(--theme--ui_divider);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* New Column enabled with Full Width disabled > Add right border - table */
|
||||||
|
.notion-collection_view-block[data-simpler-db-tweaks][data-simpler-db-tweaks*='[new_column]']:not([data-simpler-db-tweaks*='[full_width]'])
|
||||||
|
.notion-table-view
|
||||||
|
.notion-collection_view-block
|
||||||
|
> [style*='height: 34px']
|
||||||
|
+ div,
|
||||||
|
.notion-collection_view-block[data-simpler-db-tweaks][data-simpler-db-tweaks*='[new_column]']:not([data-simpler-db-tweaks*='[full_width]'])
|
||||||
|
.notion-table-view
|
||||||
|
.notion-collection_view-block
|
||||||
|
> :first-child {
|
||||||
|
border-right: 1px solid var(--theme--ui_divider);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* REMOVE DATABASE HEADER < Title, Link, Toggle, Views, and Toolbar disabled */
|
||||||
|
|
||||||
|
/* Hide Header */
|
||||||
|
.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[icon]']):not([data-simpler-db-tweaks*='[title]']):not([data-simpler-db-tweaks*='[toggle]']):not([data-simpler-db-tweaks*='[views']):not([data-simpler-db-tweaks*='[toolbar]'])
|
||||||
|
[style*='min-height: 42px'] {
|
||||||
|
min-height: 0 !important;
|
||||||
|
max-height: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[icon]']):not([data-simpler-db-tweaks*='[title]']):not([data-simpler-db-tweaks*='[toggle]']):not([data-simpler-db-tweaks*='[views']):not([data-simpler-db-tweaks*='[toolbar]'])
|
||||||
|
[style*='height: 42px'] {
|
||||||
|
overflow: visible !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hide Top Border */
|
||||||
|
.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[icon]']):not([data-simpler-db-tweaks*='[title]']):not([data-simpler-db-tweaks*='[toggle]']):not([data-simpler-db-tweaks*='[views']):not([data-simpler-db-tweaks*='[toolbar]'])
|
||||||
|
:not(.notion-table-view)
|
||||||
|
> .notion-collection_view-block
|
||||||
|
> [style*='box-shadow'] {
|
||||||
|
box-shadow: none !important;
|
||||||
|
}
|
||||||
|
.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[icon]']):not([data-simpler-db-tweaks*='[title]']):not([data-simpler-db-tweaks*='[toggle]']):not([data-simpler-db-tweaks*='[views']):not([data-simpler-db-tweaks*='[toolbar]'])
|
||||||
|
:not(.notion-table-view)
|
||||||
|
> .notion-collection_view-block[style*='border-top'],
|
||||||
|
.notion-collection_view-block[data-simpler-db-tweaks]:not([data-simpler-db-tweaks*='[icon]']):not([data-simpler-db-tweaks*='[title]']):not([data-simpler-db-tweaks*='[toggle]']):not([data-simpler-db-tweaks*='[views']):not([data-simpler-db-tweaks*='[toolbar]'])
|
||||||
|
:not(.notion-table-view)
|
||||||
|
> .notion-collection_view-block
|
||||||
|
> [style*='border-top'] {
|
||||||
|
border-top: none !important;
|
||||||
|
}
|
452
repo/simpler-databases/client.mjs
Normal file
452
repo/simpler-databases/client.mjs
Normal file
@ -0,0 +1,452 @@
|
|||||||
|
/*
|
||||||
|
* notion-enhancer: simpler databases
|
||||||
|
* (c) 2020 CloudHill <rl.cloudhill@gmail.com> (https://github.com/CloudHill)
|
||||||
|
* (c) 2021 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
|
||||||
|
* (https://notion-enhancer.github.io/) under the MIT license
|
||||||
|
*/
|
||||||
|
|
||||||
|
export default async function ({ web, components }, db) {
|
||||||
|
const collectionViewSelector =
|
||||||
|
'.notion-collection_view-block[style*="width"][style*="max-width"]',
|
||||||
|
collectionAddNewSelector = '.notion-collection-view-item-add',
|
||||||
|
collectionToolbarSelector = '[style*=" height: 42px"]',
|
||||||
|
linkedCollectionTitleSelector = `${collectionToolbarSelector} > a [placeholder]`,
|
||||||
|
viewContainerSelector = '.notion-scroller [class$="view"]',
|
||||||
|
configButtonClass = 'simpler_databases--config_button',
|
||||||
|
configButtonSvg = web.raw`<svg viewBox="0 0 14 14">
|
||||||
|
<path d="M14,7.77 L14,6.17 L12.06,5.53 L11.61,4.44 L12.49,2.6 L11.36,1.47
|
||||||
|
L9.55,2.38 L8.46,1.93 L7.77,0.01 L6.17,0.01 L5.54,1.95 L4.43,2.4 L2.59,1.52
|
||||||
|
L1.46,2.65 L2.37,4.46 L1.92,5.55 L0,6.23 L0,7.82 L1.94,8.46 L2.39,9.55
|
||||||
|
L1.51,11.39 L2.64,12.52 L4.45,11.61 L5.54,12.06 L6.23,13.98 L7.82,13.98
|
||||||
|
L8.45,12.04 L9.56,11.59 L11.4,12.47 L12.53,11.34 L11.61,9.53 L12.08,8.44
|
||||||
|
L14,7.75 L14,7.77 Z M7,10 C5.34,10 4,8.66 4,7 C4,5.34 5.34,4 7,4 C8.66,4
|
||||||
|
10,5.34 10,7 C10,8.66 8.66,10 7,10 Z" />
|
||||||
|
</svg>`,
|
||||||
|
overlayContainerClass = 'simpler_databases--overlay_container',
|
||||||
|
configMenuClass = 'simpler_databases--config_menu',
|
||||||
|
configDividerClass = 'simpler_databases--config_divider',
|
||||||
|
configItemClass = 'simpler_databases--config_item',
|
||||||
|
configTitleClass = 'simpler_databases--config_title',
|
||||||
|
configToggleClass = 'simpler_databases--config_toggle',
|
||||||
|
configInputClassName = 'simpler_databases--config_input notion-focusable',
|
||||||
|
configOpenCollectionSelector =
|
||||||
|
'.notion-collection_view-block[data-simpler-db-tweaks*="[config-open]"]',
|
||||||
|
collectionToggleClass = 'simpler_databases--toggle',
|
||||||
|
notionAppSelector = '.notion-app-inner';
|
||||||
|
|
||||||
|
const replaceTitle = ($collection, state) => {
|
||||||
|
const $title = $collection.querySelector(linkedCollectionTitleSelector),
|
||||||
|
blockId = $collection.dataset.blockId;
|
||||||
|
if (!$title) return;
|
||||||
|
if (!$title.dataset.originalTitle && state) {
|
||||||
|
$title.dataset.originalTitle = $title.innerText;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$title.titleObserver) {
|
||||||
|
if (!state) return;
|
||||||
|
$title.titleObserver = new MutationObserver(async () => {
|
||||||
|
const customTitle = await db.get(['collections', blockId, 'replace_title'], false);
|
||||||
|
if (customTitle && $title.innerText !== customTitle) $title.innerText = customTitle;
|
||||||
|
});
|
||||||
|
} else $title.titleObserver.disconnect();
|
||||||
|
|
||||||
|
if (state) {
|
||||||
|
// observe
|
||||||
|
$title.innerText = state;
|
||||||
|
$title.titleObserver.observe($title, { characterData: true, childList: true });
|
||||||
|
} else {
|
||||||
|
// reset
|
||||||
|
$title.titleObserver.disconnect();
|
||||||
|
$title.innerText = $title.dataset.originalTitle;
|
||||||
|
delete $title.dataset.originalTitle;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
insertToggle = async ($collection, state) => {
|
||||||
|
const datasetKey = 'simplerDbToggleHidden',
|
||||||
|
blockId = $collection.dataset.blockId,
|
||||||
|
$toolbar = $collection.querySelector(collectionToolbarSelector);
|
||||||
|
if (!$toolbar) return;
|
||||||
|
|
||||||
|
const $collectionView = $collection.querySelector('.notion-scroller'),
|
||||||
|
hideCollection = () => {
|
||||||
|
$collectionView.style.height = $collectionView.offsetHeight + 'px';
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
$collection.dataset[datasetKey] = true;
|
||||||
|
setTimeout(() => ($collectionView.dataset.simplerDbHideItems = 'true'), 200); // hide drag handles
|
||||||
|
});
|
||||||
|
},
|
||||||
|
showCollection = () => {
|
||||||
|
$collection.dataset[datasetKey] = false;
|
||||||
|
$collectionView.style.height = '';
|
||||||
|
$collectionView.style.height = $collectionView.offsetHeight + 'px';
|
||||||
|
$collection.dataset[datasetKey] = true;
|
||||||
|
|
||||||
|
delete $collectionView.dataset.simplerDbHideItems;
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
$collection.dataset[datasetKey] = false;
|
||||||
|
setTimeout(() => ($collectionView.style.height = ''), 200);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!$collection.dataset[datasetKey]) {
|
||||||
|
const storedState = await db.get(['collections', blockId, 'toggle_hidden'], false);
|
||||||
|
if (storedState) {
|
||||||
|
hideCollection();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let $toggle = $toolbar.querySelector(`.${collectionToggleClass}`);
|
||||||
|
if ($toggle) {
|
||||||
|
if (!state) $toggle.remove();
|
||||||
|
return;
|
||||||
|
} else if (state) {
|
||||||
|
$toggle = web.html`
|
||||||
|
<div class="${collectionToggleClass}">
|
||||||
|
<svg viewBox="0 0 100 100"><polygon points="5.9,88.2 50,11.8 94.1,88.2" /></svg>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
$toggle.addEventListener('click', async () => {
|
||||||
|
const hide = !($collection.dataset[datasetKey] === 'true');
|
||||||
|
await db.set(['collections', blockId, 'toggle_hidden'], hide);
|
||||||
|
if (hide) {
|
||||||
|
hideCollection();
|
||||||
|
} else showCollection();
|
||||||
|
});
|
||||||
|
$toolbar.prepend($toggle);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const menuItems = [
|
||||||
|
{
|
||||||
|
key: 'replace_title',
|
||||||
|
name: 'Replace title...',
|
||||||
|
type: 'input',
|
||||||
|
linkedOnly: true,
|
||||||
|
default: '',
|
||||||
|
action: replaceTitle,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'icon',
|
||||||
|
name: 'Icon',
|
||||||
|
type: 'toggle',
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'title',
|
||||||
|
name: 'Title',
|
||||||
|
type: 'toggle',
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'toggle',
|
||||||
|
name: 'Toggle',
|
||||||
|
type: 'toggle',
|
||||||
|
default: false,
|
||||||
|
action: insertToggle,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'views',
|
||||||
|
name: 'Views',
|
||||||
|
type: 'toggle',
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'toolbar',
|
||||||
|
name: 'Toolbar',
|
||||||
|
type: 'toggle',
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'divider',
|
||||||
|
views: ['table', 'board', 'timeline', 'list', 'gallery'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'header_row',
|
||||||
|
name: 'Header row',
|
||||||
|
type: 'toggle',
|
||||||
|
default: true,
|
||||||
|
views: ['table'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'new_item',
|
||||||
|
name: 'New row',
|
||||||
|
type: 'toggle',
|
||||||
|
default: true,
|
||||||
|
views: ['table', 'timeline'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'new_item',
|
||||||
|
name: 'New item',
|
||||||
|
type: 'toggle',
|
||||||
|
default: true,
|
||||||
|
views: ['board', 'list', 'gallery'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'calc_row',
|
||||||
|
name: 'Calculation row',
|
||||||
|
type: 'toggle',
|
||||||
|
default: true,
|
||||||
|
views: ['table', 'timeline'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'divider',
|
||||||
|
views: ['table', 'board'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'hidden_column',
|
||||||
|
name: 'Hidden columns',
|
||||||
|
type: 'toggle',
|
||||||
|
default: true,
|
||||||
|
views: ['board'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'add_group',
|
||||||
|
name: 'Add group',
|
||||||
|
type: 'toggle',
|
||||||
|
default: true,
|
||||||
|
views: ['board'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'new_column',
|
||||||
|
name: 'New column',
|
||||||
|
type: 'toggle',
|
||||||
|
default: true,
|
||||||
|
views: ['table'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'full_width',
|
||||||
|
name: 'Full width',
|
||||||
|
type: 'toggle',
|
||||||
|
default: true,
|
||||||
|
views: ['table'],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const isLinked = ($collection) => !!$collection.querySelector(linkedCollectionTitleSelector),
|
||||||
|
getViewType = ($collection) =>
|
||||||
|
$collection.querySelector(viewContainerSelector)?.className.split('-')[1],
|
||||||
|
setTweakState = ($collection, key, state) => {
|
||||||
|
const datasetKey = 'simplerDbTweaks';
|
||||||
|
if (!$collection.dataset[datasetKey]) $collection.dataset[datasetKey] = '';
|
||||||
|
|
||||||
|
key = web.escape(key);
|
||||||
|
const isActive = $collection.dataset[datasetKey].includes(`[${key}]`);
|
||||||
|
|
||||||
|
if (state && !isActive) {
|
||||||
|
$collection.dataset[datasetKey] += `[${key}]`;
|
||||||
|
} else if (!state && isActive) {
|
||||||
|
const prev = $collection.dataset[datasetKey];
|
||||||
|
$collection.dataset[datasetKey] = prev.replace(`[${key}]`, '');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const clickItem = (event) => {
|
||||||
|
event.stopPropagation();
|
||||||
|
const focusedItem = event.target.closest(`[class^="${configItemClass}"]`);
|
||||||
|
if (focusedItem) focusedItem.click();
|
||||||
|
},
|
||||||
|
focusNextItem = (event) => {
|
||||||
|
event.stopPropagation();
|
||||||
|
event.preventDefault();
|
||||||
|
const $focusedItem = event.target.closest(`[class^="${configItemClass}"]`);
|
||||||
|
if (!$focusedItem) return;
|
||||||
|
let $targetItem = $focusedItem.nextElementSibling;
|
||||||
|
if (!$targetItem) $targetItem = $focusedItem.parentElement.firstElementChild;
|
||||||
|
if ($targetItem.classList.contains(configDividerClass)) {
|
||||||
|
$targetItem = $targetItem.nextElementSibling;
|
||||||
|
}
|
||||||
|
const $input = $targetItem.querySelector('input');
|
||||||
|
if ($input) {
|
||||||
|
$input.focus();
|
||||||
|
} else $targetItem.focus();
|
||||||
|
},
|
||||||
|
focusPrevItem = (event) => {
|
||||||
|
event.stopPropagation();
|
||||||
|
event.preventDefault();
|
||||||
|
const $focusedItem = event.target.closest(`[class^="${configItemClass}"]`);
|
||||||
|
if (!$focusedItem) return;
|
||||||
|
let $targetItem = $focusedItem.previousElementSibling;
|
||||||
|
if (!$targetItem) $targetItem = $focusedItem.parentElement.lastElementChild;
|
||||||
|
if ($targetItem.classList.contains(configDividerClass)) {
|
||||||
|
$targetItem = $targetItem.previousElementSibling;
|
||||||
|
}
|
||||||
|
const $input = $targetItem.querySelector('input');
|
||||||
|
if ($input) {
|
||||||
|
$input.focus();
|
||||||
|
} else $targetItem.focus();
|
||||||
|
},
|
||||||
|
keyListeners = [
|
||||||
|
{
|
||||||
|
keys: ['Escape'],
|
||||||
|
listener: (event) => {
|
||||||
|
event.stopPropagation();
|
||||||
|
hideConfig();
|
||||||
|
},
|
||||||
|
opts: { listenInInput: true, keydown: true },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
keys: [' '],
|
||||||
|
listener: (event) => clickItem(event),
|
||||||
|
opts: { keydown: true },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
keys: ['Enter'],
|
||||||
|
listener: (event) => clickItem(event),
|
||||||
|
opts: { keydown: true },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
keys: ['ArrowDown'],
|
||||||
|
listener: focusNextItem,
|
||||||
|
opts: { listenInInput: true, keydown: true },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
keys: ['ArrowUp'],
|
||||||
|
listener: focusPrevItem,
|
||||||
|
opts: { listenInInput: true, keydown: true },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
keys: ['Tab'],
|
||||||
|
listener: focusNextItem,
|
||||||
|
opts: { listenInInput: true, keydown: true },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
keys: ['Shift', 'Tab'],
|
||||||
|
listener: focusPrevItem,
|
||||||
|
opts: { listenInInput: true, keydown: true },
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const renderConfigItem = async ($collection, menuItem) => {
|
||||||
|
if (menuItem.key === 'divider')
|
||||||
|
return web.html`<div class="${configDividerClass}"></div>`;
|
||||||
|
|
||||||
|
const blockId = $collection.dataset.blockId,
|
||||||
|
storedState = await db.get(['collections', blockId, menuItem.key], menuItem.default),
|
||||||
|
$item = web.html`<div class="${configItemClass}-${menuItem.type}"></div>`;
|
||||||
|
|
||||||
|
switch (menuItem.type) {
|
||||||
|
case 'toggle':
|
||||||
|
const $label = web.html`<div class="${configTitleClass}">${menuItem.name}</div>`,
|
||||||
|
$toggle = web.html`<div class="${configToggleClass}"
|
||||||
|
data-toggled="${storedState || false}"></div>`;
|
||||||
|
web.render($item, $label, $toggle);
|
||||||
|
$item.setAttribute('tabindex', 0);
|
||||||
|
$item.addEventListener('click', async (e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
const newState = !($toggle.dataset.toggled === 'true');
|
||||||
|
$toggle.dataset.toggled = newState;
|
||||||
|
await db.set(['collections', blockId, menuItem.key], newState);
|
||||||
|
setTweakState($collection, menuItem.key, newState);
|
||||||
|
if (menuItem.action) menuItem.action($collection, newState);
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'input':
|
||||||
|
const $input = web.html`<div class="${configInputClassName}">
|
||||||
|
<input placeholder="${menuItem.name}" type="text"
|
||||||
|
value="${web.escape(storedState) || ''}">
|
||||||
|
</div>`;
|
||||||
|
web.render($item, $input);
|
||||||
|
$item.addEventListener('click', (e) => e.stopPropagation());
|
||||||
|
if (menuItem.action) {
|
||||||
|
$input.firstElementChild.addEventListener('input', async (e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
const newState = e.target.value;
|
||||||
|
await db.set(['collections', blockId, menuItem.key], newState);
|
||||||
|
menuItem.action($collection, newState);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return $item;
|
||||||
|
},
|
||||||
|
renderConfig = async ($collection, $button) => {
|
||||||
|
if (document.querySelector(`.${overlayContainerClass}`)) return;
|
||||||
|
|
||||||
|
const collectionViewType = getViewType($collection);
|
||||||
|
if (!collectionViewType) return;
|
||||||
|
|
||||||
|
const $overlay = web.html`<div class="${overlayContainerClass}"></div>`;
|
||||||
|
$overlay.addEventListener('click', hideConfig);
|
||||||
|
web.render(document.querySelector(notionAppSelector), $overlay);
|
||||||
|
|
||||||
|
const $config = web.html`<div class="${configMenuClass}"></div>`,
|
||||||
|
viewMenuItems = menuItems.filter(
|
||||||
|
(item) =>
|
||||||
|
(!item.views || item.views.includes(collectionViewType)) &&
|
||||||
|
(!item.linkedOnly || isLinked($collection))
|
||||||
|
),
|
||||||
|
$menuItemElements = await Promise.all(
|
||||||
|
viewMenuItems.map((item) => renderConfigItem($collection, item))
|
||||||
|
);
|
||||||
|
web.render($config, ...$menuItemElements);
|
||||||
|
const $firstMenuItem =
|
||||||
|
$config.firstElementChild.getElementsByTagName('input')[0] ||
|
||||||
|
$config.firstElementChild;
|
||||||
|
|
||||||
|
const $position = web.html`
|
||||||
|
<div style="position: fixed;">
|
||||||
|
<div style="position: relative; pointer-events: auto;"></div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
$position.firstElementChild.appendChild($config);
|
||||||
|
web.render($overlay, $position);
|
||||||
|
|
||||||
|
const rect = $button.getBoundingClientRect();
|
||||||
|
$position.style.left =
|
||||||
|
Math.min(rect.left + rect.width / 2, window.innerWidth - ($config.offsetWidth + 14)) +
|
||||||
|
'px';
|
||||||
|
$position.style.top =
|
||||||
|
Math.min(
|
||||||
|
rect.top + rect.height / 2,
|
||||||
|
window.innerHeight - ($config.offsetHeight + 14)
|
||||||
|
) + 'px';
|
||||||
|
|
||||||
|
setTweakState($collection, 'config-open', true);
|
||||||
|
for (const { keys, listener, opts } of keyListeners) {
|
||||||
|
web.addHotkeyListener(keys, listener, opts);
|
||||||
|
}
|
||||||
|
await $config.animate([{ opacity: 0 }, { opacity: 1 }], { duration: 200 }).finished;
|
||||||
|
$firstMenuItem.focus();
|
||||||
|
};
|
||||||
|
async function hideConfig() {
|
||||||
|
const $overlay = document.querySelector(`.${overlayContainerClass}`),
|
||||||
|
$collection = document.querySelector(configOpenCollectionSelector);
|
||||||
|
if (!$overlay) return;
|
||||||
|
|
||||||
|
$overlay.removeEventListener('click', hideConfig);
|
||||||
|
for (const { listener } of keyListeners) web.removeHotkeyListener(listener);
|
||||||
|
|
||||||
|
await document
|
||||||
|
.querySelector(`.${configMenuClass}`)
|
||||||
|
.animate([{ opacity: 1 }, { opacity: 0 }], { duration: 200 }).finished;
|
||||||
|
setTweakState($collection, 'config-open', false);
|
||||||
|
$overlay.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
const simplifyCollection = async () => {
|
||||||
|
for (const $collection of document.querySelectorAll(collectionViewSelector)) {
|
||||||
|
const blockId = $collection.dataset.blockId,
|
||||||
|
$addNew = $collection.querySelector(collectionAddNewSelector);
|
||||||
|
if ($collection.querySelector(`.${configButtonClass}`) || !$addNew) continue;
|
||||||
|
|
||||||
|
const $configButton = $addNew.previousElementSibling.cloneNode();
|
||||||
|
$configButton.className = configButtonClass;
|
||||||
|
$configButton.innerHTML = configButtonSvg;
|
||||||
|
$configButton.addEventListener('click', () => {
|
||||||
|
renderConfig($collection, $configButton);
|
||||||
|
});
|
||||||
|
$addNew.parentElement.prepend($configButton);
|
||||||
|
|
||||||
|
for (const item of menuItems) {
|
||||||
|
if (item.key === 'divider') continue;
|
||||||
|
const state = await db.get(['collections', blockId, item.key], item.default);
|
||||||
|
if ((item.type !== 'input' && !item.linkedOnly) || isLinked($collection)) {
|
||||||
|
setTweakState($collection, item.key, state);
|
||||||
|
}
|
||||||
|
if (state && item.action) item.action($collection, state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
web.addDocumentObserver(simplifyCollection, [collectionViewSelector]);
|
||||||
|
}
|
22
repo/simpler-databases/mod.json
Normal file
22
repo/simpler-databases/mod.json
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"name": "simpler databases",
|
||||||
|
"id": "752933b5-1258-44e3-b49a-61b4885f8bda",
|
||||||
|
"version": "0.2.0",
|
||||||
|
"description": "adds a menu to inline databases to toggle ui elements.",
|
||||||
|
"tags": ["extension", "layout"],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "CloudHill",
|
||||||
|
"email": "rh.cloudhill@gmail.com",
|
||||||
|
"homepage": "https://github.com/CloudHill",
|
||||||
|
"avatar": "https://avatars.githubusercontent.com/u/54142180"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"js": {
|
||||||
|
"client": ["client.mjs"]
|
||||||
|
},
|
||||||
|
"css": {
|
||||||
|
"client": ["client.css"]
|
||||||
|
},
|
||||||
|
"options": []
|
||||||
|
}
|
@ -28,9 +28,9 @@
|
|||||||
.enhancer--tweak-normalise_table_scroll
|
.enhancer--tweak-normalise_table_scroll
|
||||||
.notion-page-template-modal
|
.notion-page-template-modal
|
||||||
.notion-collection_view-block {
|
.notion-collection_view-block {
|
||||||
width: calc(100% + 8px) !important;
|
width: 100% !important;
|
||||||
padding-left: 4px;
|
padding-left: 0;
|
||||||
padding-right: 4px;
|
padding-right: 0;
|
||||||
}
|
}
|
||||||
.enhancer--tweak-normalise_table_scroll
|
.enhancer--tweak-normalise_table_scroll
|
||||||
.notion-collection_view-block
|
.notion-collection_view-block
|
||||||
|
Loading…
Reference in New Issue
Block a user