From d290f340ef73519236ec2118418ceb31f70dada2 Mon Sep 17 00:00:00 2001 From: celine Date: Wed, 7 Jan 2026 09:51:22 -1000 Subject: [PATCH] Fix/accent contrast on page (#251) * inital tweaking of the page and leaflet background logic * Added some helptext to page color picker when it's defining containers * moved menu into its own file * Create Menu.tsx * unifed block layout * little fix * minor adjustments to unify hover and focus states * adjusting buttons to match better with blocks --- .../home/Actions/CreateNewButton.tsx | 2 +- .../home/LeafletList/LeafletOptions.tsx | 2 +- app/[leaflet_id]/actions/HelpButton.tsx | 2 +- app/[leaflet_id]/actions/PublishButton.tsx | 2 +- .../actions/ShareOptions/index.tsx | 2 +- app/globals.css | 5 + .../[did]/[publication]/[rkey]/PostPages.tsx | 2 +- .../[did]/[publication]/dashboard/Actions.tsx | 3 +- .../dashboard/PublicationSubscribers.tsx | 3 +- .../dashboard/PublishedPostsLists.tsx | 2 +- components/Blocks/Block.tsx | 26 ++ .../Blocks/BlueskyPostBlock/BlueskyEmbed.tsx | 12 +- components/Blocks/BlueskyPostBlock/index.tsx | 19 +- components/Blocks/ButtonBlock.tsx | 206 +++++----- components/Blocks/CodeBlock.tsx | 23 +- components/Blocks/DateTimeBlock.tsx | 10 +- components/Blocks/EmbedBlock.tsx | 29 +- components/Blocks/ExternalLinkBlock.tsx | 85 ++-- components/Blocks/ImageBlock.tsx | 59 +-- components/Blocks/MailboxBlock.tsx | 174 ++++----- components/Blocks/MathBlock.tsx | 56 +-- components/Blocks/PageLinkBlock.tsx | 48 +-- components/Blocks/PollBlock/index.tsx | 17 +- components/Blocks/PublicationPollBlock.tsx | 15 +- components/Blocks/RSVPBlock/index.tsx | 14 +- components/Buttons.tsx | 16 +- components/Layout.tsx | 94 ----- components/Menu.tsx | 97 +++++ components/Pages/PageOptions.tsx | 4 +- components/ThemeManager/PageThemeSetter.tsx | 9 +- .../ThemeManager/Pickers/ColorPicker.tsx | 6 + .../ThemeManager/Pickers/LeafletBGPicker.tsx | 162 -------- .../ThemeManager/Pickers/PageThemePickers.tsx | 362 ++++++++++++++++-- .../PubPickers/PubBackgroundPickers.tsx | 29 +- components/ThemeManager/PubThemeSetter.tsx | 2 +- .../ThemeManager/PublicationThemeProvider.tsx | 7 +- components/ThemeManager/ThemeProvider.tsx | 11 +- components/ThemeManager/ThemeSetter.tsx | 22 +- 38 files changed, 926 insertions(+), 713 deletions(-) create mode 100644 components/Menu.tsx delete mode 100644 components/ThemeManager/Pickers/LeafletBGPicker.tsx diff --git a/app/(home-pages)/home/Actions/CreateNewButton.tsx b/app/(home-pages)/home/Actions/CreateNewButton.tsx index bfd7dfe7..417c5dcd 100644 --- a/app/(home-pages)/home/Actions/CreateNewButton.tsx +++ b/app/(home-pages)/home/Actions/CreateNewButton.tsx @@ -5,7 +5,7 @@ import { ActionButton } from "components/ActionBar/ActionButton"; import { AddTiny } from "components/Icons/AddTiny"; import { BlockCanvasPageSmall } from "components/Icons/BlockCanvasPageSmall"; import { BlockDocPageSmall } from "components/Icons/BlockDocPageSmall"; -import { Menu, MenuItem } from "components/Layout"; +import { Menu, MenuItem } from "components/Menu"; import { useIsMobile } from "src/hooks/isMobile"; export const CreateNewLeafletButton = (props: {}) => { diff --git a/app/(home-pages)/home/LeafletList/LeafletOptions.tsx b/app/(home-pages)/home/LeafletList/LeafletOptions.tsx index 99930da9..b87c4715 100644 --- a/app/(home-pages)/home/LeafletList/LeafletOptions.tsx +++ b/app/(home-pages)/home/LeafletList/LeafletOptions.tsx @@ -1,6 +1,6 @@ "use client"; -import { Menu, MenuItem } from "components/Layout"; +import { Menu, MenuItem } from "components/Menu"; import { useState } from "react"; import { ButtonPrimary, ButtonTertiary } from "components/Buttons"; import { useToaster } from "components/Toast"; diff --git a/app/[leaflet_id]/actions/HelpButton.tsx b/app/[leaflet_id]/actions/HelpButton.tsx index 651a4b54..d20d2f04 100644 --- a/app/[leaflet_id]/actions/HelpButton.tsx +++ b/app/[leaflet_id]/actions/HelpButton.tsx @@ -161,7 +161,7 @@ const HelpLink = (props: { url: string; text: string }) => { className="py-2 px-2 rounded-md flex flex-col gap-1 bg-border-light hover:bg-border hover:no-underline" style={{ backgroundColor: isHovered - ? "color-mix(in oklab, rgb(var(--accent-contrast)), rgb(var(--bg-page)) 85%)" + ? "rgb(var(--accent-light))" : "color-mix(in oklab, rgb(var(--accent-contrast)), rgb(var(--bg-page)) 75%)", }} onMouseEnter={handleMouseEnter} diff --git a/app/[leaflet_id]/actions/PublishButton.tsx b/app/[leaflet_id]/actions/PublishButton.tsx index 0991bffa..4c2e8a29 100644 --- a/app/[leaflet_id]/actions/PublishButton.tsx +++ b/app/[leaflet_id]/actions/PublishButton.tsx @@ -13,7 +13,7 @@ import { LooseLeafSmall } from "components/Icons/LooseleafSmall"; import { PublishSmall } from "components/Icons/PublishSmall"; import { useIdentityData } from "components/IdentityProvider"; import { InputWithLabel } from "components/Input"; -import { Menu, MenuItem } from "components/Layout"; +import { Menu, MenuItem } from "components/Menu"; import { useLeafletDomains, useLeafletPublicationData, diff --git a/app/[leaflet_id]/actions/ShareOptions/index.tsx b/app/[leaflet_id]/actions/ShareOptions/index.tsx index 7739150b..7ad067f8 100644 --- a/app/[leaflet_id]/actions/ShareOptions/index.tsx +++ b/app/[leaflet_id]/actions/ShareOptions/index.tsx @@ -3,7 +3,7 @@ import React, { useEffect, useState } from "react"; import { getShareLink } from "./getShareLink"; import { useEntitySetContext } from "components/EntitySetProvider"; import { useSmoker } from "components/Toast"; -import { Menu, MenuItem } from "components/Layout"; +import { Menu, MenuItem } from "components/Menu"; import { ActionButton } from "components/ActionBar/ActionButton"; import useSWR from "swr"; import LoginForm from "app/login/LoginForm"; diff --git a/app/globals.css b/app/globals.css index ae584c7a..8d5888ab 100644 --- a/app/globals.css +++ b/app/globals.css @@ -270,9 +270,14 @@ pre.shiki code { } pre.shiki { + @apply sm:p-3; @apply p-2; @apply rounded-md; @apply overflow-auto; + + @media (min-width: 640px) { + @apply p-3; + } } .highlight:has(+ .highlight) { diff --git a/app/lish/[did]/[publication]/[rkey]/PostPages.tsx b/app/lish/[did]/[publication]/[rkey]/PostPages.tsx index 307628f2..76e689c4 100644 --- a/app/lish/[did]/[publication]/[rkey]/PostPages.tsx +++ b/app/lish/[did]/[publication]/[rkey]/PostPages.tsx @@ -374,7 +374,7 @@ const PageOptions = (props: { return (
diff --git a/app/lish/[did]/[publication]/dashboard/Actions.tsx b/app/lish/[did]/[publication]/dashboard/Actions.tsx index fbd807a0..fc1ae126 100644 --- a/app/lish/[did]/[publication]/dashboard/Actions.tsx +++ b/app/lish/[did]/[publication]/dashboard/Actions.tsx @@ -4,8 +4,7 @@ import { NewDraftActionButton } from "./NewDraftButton"; import { PublicationSettingsButton } from "./PublicationSettings"; import { ActionButton } from "components/ActionBar/ActionButton"; import { ShareSmall } from "components/Icons/ShareSmall"; -import { Menu } from "components/Layout"; -import { MenuItem } from "components/Layout"; +import { Menu, MenuItem } from "components/Menu"; import { getPublicationURL } from "app/lish/createPub/getPublicationURL"; import { usePublicationData } from "./PublicationSWRProvider"; import { useSmoker } from "components/Toast"; diff --git a/app/lish/[did]/[publication]/dashboard/PublicationSubscribers.tsx b/app/lish/[did]/[publication]/dashboard/PublicationSubscribers.tsx index b3053fa6..ac1b27b2 100644 --- a/app/lish/[did]/[publication]/dashboard/PublicationSubscribers.tsx +++ b/app/lish/[did]/[publication]/dashboard/PublicationSubscribers.tsx @@ -4,7 +4,8 @@ import { usePublicationData } from "./PublicationSWRProvider"; import { ButtonPrimary } from "components/Buttons"; import { getPublicationURL } from "app/lish/createPub/getPublicationURL"; import { useSmoker } from "components/Toast"; -import { Menu, MenuItem, Separator } from "components/Layout"; +import { Menu, MenuItem } from "components/Menu"; +import { Separator } from "components/Layout"; import { MoreOptionsVerticalTiny } from "components/Icons/MoreOptionsVerticalTiny"; import { Checkbox } from "components/Checkbox"; import { useEffect, useState } from "react"; diff --git a/app/lish/[did]/[publication]/dashboard/PublishedPostsLists.tsx b/app/lish/[did]/[publication]/dashboard/PublishedPostsLists.tsx index 83a5b00a..dba8f845 100644 --- a/app/lish/[did]/[publication]/dashboard/PublishedPostsLists.tsx +++ b/app/lish/[did]/[publication]/dashboard/PublishedPostsLists.tsx @@ -7,7 +7,7 @@ import { usePublicationData } from "./PublicationSWRProvider"; import { Fragment, useState } from "react"; import { useParams } from "next/navigation"; import { getPublicationURL } from "app/lish/createPub/getPublicationURL"; -import { Menu, MenuItem } from "components/Layout"; +import { Menu, MenuItem } from "components/Menu"; import { deletePost } from "./deletePost"; import { ButtonPrimary } from "components/Buttons"; import { MoreOptionsVerticalTiny } from "components/Icons/MoreOptionsVerticalTiny"; diff --git a/components/Blocks/Block.tsx b/components/Blocks/Block.tsx index ac60f901..f38b6482 100644 --- a/components/Blocks/Block.tsx +++ b/components/Blocks/Block.tsx @@ -383,6 +383,32 @@ export const BlockMultiselectIndicator = (props: BlockProps) => { ); }; +export const BlockLayout = (props: { + isSelected?: boolean; + children: React.ReactNode; + className?: string; + hasBackground?: "accent" | "page"; + borderOnHover?: boolean; +}) => { + return ( +
+ {props.children} +
+ ); +}; + export const ListMarker = ( props: Block & { previousBlock?: Block | null; diff --git a/components/Blocks/BlueskyPostBlock/BlueskyEmbed.tsx b/components/Blocks/BlueskyPostBlock/BlueskyEmbed.tsx index 4f961b43..96b70eb0 100644 --- a/components/Blocks/BlueskyPostBlock/BlueskyEmbed.tsx +++ b/components/Blocks/BlueskyPostBlock/BlueskyEmbed.tsx @@ -148,17 +148,17 @@ export const BlueskyEmbed = (props: { } return (
-
+
{record.author.avatar && ( {`${record.author?.displayName}'s )} -
+
{record.author?.displayName}
- {text &&
{text}
} + {text && ( +
{text}
+ )} {record.embeds !== undefined ? record.embeds.map((embed, index) => ( diff --git a/components/Blocks/BlueskyPostBlock/index.tsx b/components/Blocks/BlueskyPostBlock/index.tsx index a19a0775..01cdbd86 100644 --- a/components/Blocks/BlueskyPostBlock/index.tsx +++ b/components/Blocks/BlueskyPostBlock/index.tsx @@ -2,7 +2,7 @@ import { useEntitySetContext } from "components/EntitySetProvider"; import { useEffect, useState } from "react"; import { useEntity } from "src/replicache"; import { useUIState } from "src/useUIState"; -import { BlockProps } from "../Block"; +import { BlockProps, BlockLayout } from "../Block"; import { elementId } from "src/utils/elementId"; import { focusBlock } from "src/utils/focusBlock"; import { AppBskyFeedDefs, AppBskyFeedPost, RichText } from "@atproto/api"; @@ -56,11 +56,9 @@ export const BlueskyPostBlock = (props: BlockProps & { preview?: boolean }) => { AppBskyFeedDefs.isBlockedAuthor(post) || AppBskyFeedDefs.isNotFoundPost(post): return ( -
+ -
+ ); case AppBskyFeedDefs.isThreadViewPost(post): @@ -81,11 +79,10 @@ export const BlueskyPostBlock = (props: BlockProps & { preview?: boolean }) => { let url = `https://bsky.app/profile/${post.post.author.handle}/post/${postId}`; return ( -
-
+ ); } }; diff --git a/components/Blocks/ButtonBlock.tsx b/components/Blocks/ButtonBlock.tsx index 1dacde90..2c9fbc87 100644 --- a/components/Blocks/ButtonBlock.tsx +++ b/components/Blocks/ButtonBlock.tsx @@ -3,7 +3,7 @@ import { generateKeyBetween } from "fractional-indexing"; import { useCallback, useEffect, useState } from "react"; import { useEntity, useReplicache } from "src/replicache"; import { useUIState } from "src/useUIState"; -import { BlockProps } from "./Block"; +import { BlockProps, BlockLayout } from "./Block"; import { v7 } from "uuid"; import { useSmoker } from "components/Toast"; @@ -106,113 +106,113 @@ const ButtonBlockSettings = (props: BlockProps) => { }; return ( -
+
{text !== "" ? text : "Button"} - -
{ - e.preventDefault(); - let rect = document - .getElementById("button-block-settings") - ?.getBoundingClientRect(); - if (!textValue) { - smoker({ - error: true, - text: "missing button text!", - position: { - y: rect ? rect.top : 0, - x: rect ? rect.left + 12 : 0, - }, - }); - return; - } - if (!urlValue) { - smoker({ - error: true, - text: "missing url!", - position: { - y: rect ? rect.top : 0, - x: rect ? rect.left + 12 : 0, - }, - }); - return; - } - if (!isUrl(urlValue)) { - smoker({ - error: true, - text: "invalid url!", - position: { - y: rect ? rect.top : 0, - x: rect ? rect.left + 12 : 0, - }, - }); - return; - } - submit(); - }} + -
-
- - - setTextValue(e.target.value)} - onKeyDown={(e) => { - if ( - e.key === "Backspace" && - !e.currentTarget.value && - urlValue !== "" - ) - e.preventDefault(); - }} - /> -
-
- - - setUrlValue(e.target.value)} - onKeyDown={(e) => { - if (e.key === "Backspace" && !e.currentTarget.value) - e.preventDefault(); - }} - /> + { + e.preventDefault(); + let rect = document + .getElementById("button-block-settings") + ?.getBoundingClientRect(); + if (!textValue) { + smoker({ + error: true, + text: "missing button text!", + position: { + y: rect ? rect.top : 0, + x: rect ? rect.left + 12 : 0, + }, + }); + return; + } + if (!urlValue) { + smoker({ + error: true, + text: "missing url!", + position: { + y: rect ? rect.top : 0, + x: rect ? rect.left + 12 : 0, + }, + }); + return; + } + if (!isUrl(urlValue)) { + smoker({ + error: true, + text: "invalid url!", + position: { + y: rect ? rect.top : 0, + x: rect ? rect.left + 12 : 0, + }, + }); + return; + } + submit(); + }} + > +
+
+ + + setTextValue(e.target.value)} + onKeyDown={(e) => { + if ( + e.key === "Backspace" && + !e.currentTarget.value && + urlValue !== "" + ) + e.preventDefault(); + }} + /> +
+
+ + + setUrlValue(e.target.value)} + onKeyDown={(e) => { + if (e.key === "Backspace" && !e.currentTarget.value) + e.preventDefault(); + }} + /> +
+
- -
- + +
); }; diff --git a/components/Blocks/CodeBlock.tsx b/components/Blocks/CodeBlock.tsx index 7a358b56..83f98ed5 100644 --- a/components/Blocks/CodeBlock.tsx +++ b/components/Blocks/CodeBlock.tsx @@ -6,7 +6,7 @@ import { } from "shiki"; import { useEntity, useReplicache } from "src/replicache"; import "katex/dist/katex.min.css"; -import { BlockProps } from "./Block"; +import { BlockLayout, BlockProps } from "./Block"; import { useCallback, useLayoutEffect, useMemo, useState } from "react"; import { useUIState } from "src/useUIState"; import { BaseTextareaBlock } from "./BaseTextareaBlock"; @@ -119,9 +119,16 @@ export function CodeBlock(props: BlockProps) {
)} -
+ + {focusedBlock && permissions.write ? ( { // Update the entity with the new value @@ -146,9 +153,13 @@ export function CodeBlock(props: BlockProps) {
 e.stopPropagation()}
-            className="codeBlockRendered overflow-auto! font-mono p-2 w-full h-full"
+            className="codeBlockRendered overflow-auto! font-mono p-2 sm:p-3 w-full h-full"
           >
-            {content?.data.value}
+            {content?.data.value === "" || content?.data.value === undefined ? (
+              
write some code…
+ ) : ( + content?.data.value + )}
) : (
)} -
+
); } diff --git a/components/Blocks/DateTimeBlock.tsx b/components/Blocks/DateTimeBlock.tsx index 29430a33..437b0442 100644 --- a/components/Blocks/DateTimeBlock.tsx +++ b/components/Blocks/DateTimeBlock.tsx @@ -1,5 +1,5 @@ import { useEntity, useReplicache } from "src/replicache"; -import { BlockProps } from "./Block"; +import { BlockProps, BlockLayout } from "./Block"; import { ChevronProps, DayPicker } from "react-day-picker"; import { Popover } from "components/Popover"; import { useEffect, useMemo, useState } from "react"; @@ -121,9 +121,9 @@ export function BaseDateTimeBlock( disabled={isLocked || !permissions.write} className="w-64 z-10 px-2!" trigger={ -
@@ -163,7 +163,7 @@ export function BaseDateTimeBlock(
)} -
+ } >
diff --git a/components/Blocks/EmbedBlock.tsx b/components/Blocks/EmbedBlock.tsx index 919479b0..c53c1fe5 100644 --- a/components/Blocks/EmbedBlock.tsx +++ b/components/Blocks/EmbedBlock.tsx @@ -3,7 +3,7 @@ import { generateKeyBetween } from "fractional-indexing"; import { useCallback, useEffect, useState } from "react"; import { useEntity, useReplicache } from "src/replicache"; import { useUIState } from "src/useUIState"; -import { BlockProps } from "./Block"; +import { BlockProps, BlockLayout } from "./Block"; import { v7 } from "uuid"; import { useSmoker } from "components/Toast"; import { Separator } from "components/Layout"; @@ -84,21 +84,18 @@ export const EmbedBlock = (props: BlockProps & { preview?: boolean }) => {
- {/* - the iframe! - can also add 'allow' and 'referrerpolicy' attributes later if needed - */} - + + + {/*
-
-
-
- {title?.data.value} -
+
+
+
+
+ {title?.data.value} +
-
- {description?.data.value} -
-
- {url?.data.value} +
+ {description?.data.value} +
+
+ {url?.data.value} +
-
-
- +
+ + ); }; diff --git a/components/Blocks/ImageBlock.tsx b/components/Blocks/ImageBlock.tsx index 1d913838..ab225d03 100644 --- a/components/Blocks/ImageBlock.tsx +++ b/components/Blocks/ImageBlock.tsx @@ -1,7 +1,7 @@ "use client"; import { useEntity, useReplicache } from "src/replicache"; -import { BlockProps } from "./Block"; +import { BlockProps, BlockLayout } from "./Block"; import { useUIState } from "src/useUIState"; import Image from "next/image"; import { v7 } from "uuid"; @@ -64,10 +64,7 @@ export function ImageBlock(props: BlockProps & { preview?: boolean }) { factID: v7(), permission_set: entity_set.set, type: "text", - position: generateKeyBetween( - props.position, - props.nextPosition, - ), + position: generateKeyBetween(props.position, props.nextPosition), newEntityID: entity, }); } @@ -85,15 +82,17 @@ export function ImageBlock(props: BlockProps & { preview?: boolean }) { if (!image) { if (!entity_set.permissions.write) return null; return ( -
+ -
+ ); } - let className = isFullBleed + let imageClassName = isFullBleed ? "" : isSelected ? "block-border-selected border-transparent! " @@ -143,15 +142,15 @@ export function ImageBlock(props: BlockProps & { preview?: boolean }) { let isLocalUpload = localImages.get(image.data.src); + let blockClassName = ` + relative group/image border-transparent! p-0! w-fit! + ${isFullBleed && "-mx-3 sm:-mx-4"} + ${isFullBleed ? (isFirst ? "-mt-3 sm:-mt-4" : prevIsFullBleed ? "-mt-1" : "") : ""} + ${isFullBleed ? (isLast ? "-mb-4" : nextIsFullBleed ? "-mb-2" : "") : ""} + `; + return ( -
- {isFullBleed && isSelected ? : null} + {isLocalUpload || image.data.local ? ( )} {altText !== undefined && !props.preview ? ( ) : null} {!props.preview ? : null} -
+ ); } @@ -200,10 +199,18 @@ const CoverImageButton = (props: { entityID: string }) => { let coverImage = useSubscribe(rep, (tx) => tx.get("publication_cover_image"), ); - let isFocused = useUIState((s) => s.focusedEntity?.entityID === props.entityID); + let isFocused = useUIState( + (s) => s.focusedEntity?.entityID === props.entityID, + ); // Only show if focused, in a publication, has write permissions, and no cover image is set - if (!isFocused || !pubData?.publications || !entity_set.permissions.write || coverImage) return null; + if ( + !isFocused || + !pubData?.publications || + !entity_set.permissions.write || + coverImage + ) + return null; return (
diff --git a/components/Blocks/MailboxBlock.tsx b/components/Blocks/MailboxBlock.tsx index 17236337..1bc591cd 100644 --- a/components/Blocks/MailboxBlock.tsx +++ b/components/Blocks/MailboxBlock.tsx @@ -1,10 +1,11 @@ import { ButtonPrimary } from "components/Buttons"; import { Popover } from "components/Popover"; -import { Menu, MenuItem, Separator } from "components/Layout"; +import { MenuItem } from "components/Menu"; +import { Separator } from "components/Layout"; import { useUIState } from "src/useUIState"; import { useState } from "react"; import { useSmoker, useToaster } from "components/Toast"; -import { BlockProps } from "./Block"; +import { BlockProps, BlockLayout } from "./Block"; import { useEntity, useReplicache } from "src/replicache"; import { useEntitySetContext } from "components/EntitySetProvider"; import { subscribeToMailboxWithEmail } from "actions/subscriptions/subscribeToMailboxWithEmail"; @@ -45,40 +46,35 @@ export const MailboxBlock = (props: BlockProps) => { return (
-
-
- { - let entity; - if (draft) { - entity = draft.data.value; - } else { - entity = v7(); - await rep?.mutate.createDraft({ - mailboxEntity: props.entityID, - permission_set: entity_set.set, - newEntity: entity, - firstBlockEntity: v7(), - firstBlockFactID: v7(), - }); - } - useUIState.getState().openPage(props.parent, entity); - if (rep) focusPage(entity, rep, "focusFirstBlock"); - return; - }} - > - {draft ? "Edit Draft" : "Write a Post"} - - -
-
+ { + let entity; + if (draft) { + entity = draft.data.value; + } else { + entity = v7(); + await rep?.mutate.createDraft({ + mailboxEntity: props.entityID, + permission_set: entity_set.set, + newEntity: entity, + firstBlockEntity: v7(), + firstBlockFactID: v7(), + }); + } + useUIState.getState().openPage(props.parent, entity); + if (rep) focusPage(entity, rep, "focusFirstBlock"); + return; + }} + > + {draft ? "Edit Draft" : "Write a Post"} + + +
{ <> @@ -134,69 +130,59 @@ const MailboxReaderView = (props: { entityID: string; parent: string }) => { let { rep } = useReplicache(); return (
-
-
- {!isSubscribed?.confirmed ? ( - <> - - - ) : ( -
-
- You're Subscribed! -
-
- {archive ? ( - { - e.preventDefault(); - if (rep) { - useUIState - .getState() - .openPage(props.parent, archive.data.value); - focusPage(archive.data.value, rep); - } - }} - > - See All Posts - - ) : ( -
- Nothing has been posted yet -
- )} - -
+ See All Posts + + ) : ( +
Nothing has been posted yet
+ )} +
- )} -
-
+
+ )} +
); }; diff --git a/components/Blocks/MathBlock.tsx b/components/Blocks/MathBlock.tsx index ecd60e6d..286912e7 100644 --- a/components/Blocks/MathBlock.tsx +++ b/components/Blocks/MathBlock.tsx @@ -1,6 +1,6 @@ import { useEntity, useReplicache } from "src/replicache"; import "katex/dist/katex.min.css"; -import { BlockProps } from "./Block"; +import { BlockLayout, BlockProps } from "./Block"; import Katex from "katex"; import { useMemo } from "react"; import { useUIState } from "src/useUIState"; @@ -32,32 +32,42 @@ export function MathBlock(props: BlockProps) { } }, [content?.data.value]); return focusedBlock ? ( - { - // Update the entity with the new value - await rep?.mutate.assertFact({ - attribute: "block/math", - entity: props.entityID, - data: { type: "string", value: e.target.value }, - }); - }} - /> + + { + // Update the entity with the new value + await rep?.mutate.assertFact({ + attribute: "block/math", + entity: props.entityID, + data: { type: "string", value: e.target.value }, + }); + }} + /> + ) : html && content?.data.value ? (
) : ( -
- write some Tex here... -
+ +
write some Tex here...
+
); } diff --git a/components/Blocks/PageLinkBlock.tsx b/components/Blocks/PageLinkBlock.tsx index b3b8d64b..df27bd24 100644 --- a/components/Blocks/PageLinkBlock.tsx +++ b/components/Blocks/PageLinkBlock.tsx @@ -1,5 +1,5 @@ "use client"; -import { BlockProps, BaseBlock, ListMarker, Block } from "./Block"; +import { BlockProps, ListMarker, Block, BlockLayout } from "./Block"; import { focusBlock } from "src/utils/focusBlock"; import { focusPage } from "src/utils/focusPage"; @@ -29,30 +29,34 @@ export function PageLinkBlock(props: BlockProps & { preview?: boolean }) { return ( -
{ - if (!page) return; - if (e.isDefaultPrevented()) return; - if (e.shiftKey) return; - e.preventDefault(); - e.stopPropagation(); - useUIState.getState().openPage(props.parent, page.data.value); - if (rep) focusPage(page.data.value, rep); - }} > - {type === "canvas" && page ? ( - - ) : ( - - )} -
+
{ + if (!page) return; + if (e.isDefaultPrevented()) return; + if (e.shiftKey) return; + e.preventDefault(); + e.stopPropagation(); + useUIState.getState().openPage(props.parent, page.data.value); + if (rep) focusPage(page.data.value, rep); + }} + > + {type === "canvas" && page ? ( + + ) : ( + + )} +
+
); } diff --git a/components/Blocks/PollBlock/index.tsx b/components/Blocks/PollBlock/index.tsx index 35a780ad..0438841b 100644 --- a/components/Blocks/PollBlock/index.tsx +++ b/components/Blocks/PollBlock/index.tsx @@ -1,5 +1,5 @@ import { useUIState } from "src/useUIState"; -import { BlockProps } from "../Block"; +import { BlockProps, BlockLayout } from "../Block"; import { ButtonPrimary, ButtonSecondary } from "components/Buttons"; import { useCallback, useEffect, useState } from "react"; import { Input } from "components/Input"; @@ -61,13 +61,10 @@ export const LeafletPollBlock = (props: BlockProps) => { let totalVotes = votes.length; return ( -
{pollState === "editing" ? ( { hasVoted={!!hasVoted} /> )} -
+ ); }; @@ -486,7 +483,7 @@ const PollStateToggle = (props: { }) => { return ( - -
- {bgImage ? ( -
Image
- ) : ( - <> - - { - e.currentTarget.setSelectionRange( - 1, - e.currentTarget.value.length, - ); - }} - onPaste={(e) => { - console.log(e); - }} - onKeyDown={(e) => { - if (e.key === "Enter") { - e.currentTarget.blur(); - } else return; - }} - onBlur={(e) => { - props.setValue(parseColor(e.currentTarget.value)); - }} - className={`w-[72px] bg-transparent outline-nonetext-[#595959]`} - /> - - - )} -
-
-
- {bgImage && ( - - )} - -
-
- {open && ( -
- - {bgImage ? ( - - ) : ( - <> - - - - - - - - - - )} - -
- )} - - ); -}; diff --git a/components/ThemeManager/Pickers/PageThemePickers.tsx b/components/ThemeManager/Pickers/PageThemePickers.tsx index 8aaf4a61..5066067e 100644 --- a/components/ThemeManager/Pickers/PageThemePickers.tsx +++ b/components/ThemeManager/Pickers/PageThemePickers.tsx @@ -61,49 +61,71 @@ export const PageThemePickers = (props: { ); }; -export const PageBackgroundPicker = (props: { +// Page background picker for subpages - shows Page/Containers color with optional background image +export const SubpageBackgroundPicker = (props: { entityID: string; - setValue: (c: Color) => void; openPicker: pickers; setOpenPicker: (p: pickers) => void; - home?: boolean; }) => { + let { rep, rootEntity } = useReplicache(); + let set = useMemo(() => { + return setColorAttribute(rep, props.entityID); + }, [rep, props.entityID]); + let pageValue = useColorAttribute(props.entityID, "theme/card-background"); let pageBGImage = useEntity(props.entityID, "theme/card-background-image"); - let pageBorderHidden = useEntity(props.entityID, "theme/card-border-hidden"); + let rootPageBorderHidden = useEntity(rootEntity, "theme/card-border-hidden"); + let entityPageBorderHidden = useEntity( + props.entityID, + "theme/card-border-hidden", + ); + let pageBorderHidden = + (entityPageBorderHidden || rootPageBorderHidden)?.data.value || false; + let hasPageBackground = !pageBorderHidden; + + // Label is "Page" when page background is visible, "Containers" when hidden + let label = hasPageBackground ? "Page" : "Containers"; + + // If root page border is hidden, only show color picker (no image support) + if (!hasPageBackground) { + return ( + props.setOpenPicker("null")} + alpha + /> + ); + } return ( <> - {pageBGImage && pageBGImage !== null && ( - props.setOpenPicker("null")} - setValue={props.setValue} - home={props.home} + setValue={set("theme/card-background")} /> )}
- props.setOpenPicker("null")} alpha /> - {(pageBGImage === null || - (!pageBGImage && !pageBorderHidden?.data.value && !props.home)) && ( -