Loading packages/client/src/components/Header/HeaderRight.tsx +2 −2 Original line number Diff line number Diff line Loading @@ -118,9 +118,9 @@ export const HeaderRight = () => { className="header-right box flex flex-col gap-2" transition={reduceMotion ? { duration: 0 } : SIDEBAR_SPRING} > <User /> {!isMobile && <User />} <div className="header-right-actions flex gap-2"> <div ref={captureMenuRef} className="relative"> <div ref={captureMenuRef} className="header-share-menu relative"> <Button aria-label="Share" aria-expanded={captureMenuOpen} Loading packages/client/src/components/Settings/MiscSettings.tsx +22 −13 Original line number Diff line number Diff line import { usePanel } from "@/contexts/PanelContext"; import { useAppContext } from "../../contexts/AppContext"; import { useDialog } from "../../contexts/DialogContext"; import { useIsCompactPaletteDefault } from "../../hooks/useCompactPalette"; import { useIsMobile } from "../../hooks/useIsMobile"; import { Button } from "../core/Button"; import { Switch } from "../core/Switch"; Loading @@ -10,6 +11,10 @@ export const MiscSettings = () => { const Dialog = useDialog(); const Panel = usePanel(); const isMobile = useIsMobile(); const compactPaletteDefault = useIsCompactPaletteDefault(); const compactPaletteSetting = settings.get["palette.compact"]; const compactPaletteSelected = compactPaletteSetting ?? compactPaletteDefault; const showCompactPaletteSettings = !isMobile; return ( <div className="flex flex-col gap-4 p-2"> Loading Loading @@ -80,15 +85,19 @@ export const MiscSettings = () => { > Compact Buttons </Switch> {showCompactPaletteSettings && ( <Switch isSelected={settings.get["palette.compact"]} isSelected={compactPaletteSelected} onValueChange={(value) => { settings.set({ key: "palette.compact", value }); }} > Compact Palette </Switch> {!settings.get["palette.compact"] && ( )} {showCompactPaletteSettings && compactPaletteSetting === undefined && !compactPaletteDefault && ( <Switch className="sidebar-adaptation-setting" isSelected={settings.get["ui.compactPaletteForSidebar"]} Loading packages/client/src/components/Templating/MobileTemplateButtons.tsx +1 −1 Original line number Diff line number Diff line Loading @@ -8,7 +8,7 @@ export const MobileTemplateButtons = () => { if (!url) return null; return ( <div className="md:hidden toolbar-box top-[-10px] right-[10px]"> <div className="mobile-template-toggle-wrapper md:hidden"> <Card className="mobile-template-toggle canvas-overlay-card"> <Switch size="sm" Loading packages/client/src/components/Toolbar/CanvasMeta.tsx +2 −1 Original line number Diff line number Diff line Loading @@ -101,6 +101,7 @@ export const CanvasMeta = () => { const reduceMotion = useReducedMotion() ?? false; const sidebarWidth = useSidebarWidth("Left"); const compactPalette = useCompactPalette(); const canvasMetaBottom = !isMobile && compactPalette ? 84 : 76; const offsetForSidebar = Boolean( !isMobile && Panel.state.info && Loading Loading @@ -132,7 +133,7 @@ export const CanvasMeta = () => { <motion.div animate={{ x: offsetForSidebar ? sidebarWidth : 0, bottom: compactPalette ? 84 : 76, bottom: canvasMetaBottom, }} id="canvas-meta" className={`toolbar-box canvas-overlay-card${isCollapsed ? " canvas-meta--collapsed" : ""}`} Loading packages/client/src/components/Toolbar/Palette.scss +373 −2 Original line number Diff line number Diff line Loading @@ -281,13 +281,14 @@ flex-grow: 0; display: flex; align-items: center; justify-content: center; justify-content: safe center; gap: 10px; width: 100%; height: 68px; margin-inline: auto; padding: 4px 0; overflow: hidden; overflow-x: auto; overflow-y: hidden; white-space: normal; } Loading Loading @@ -352,6 +353,376 @@ } } #pallete.pallete--mobile { padding: 8px 10px calc(8px + env(safe-area-inset-bottom)); .mobile-palette-bar { display: grid; grid-template-columns: minmax(0, 1fr) 44px 44px; align-items: center; gap: 8px; width: 100%; } .mobile-palette-current, .mobile-palette-icon-button { min-width: 0; height: 44px; border: 1px solid var(--pallete-outline-color); border-radius: 8px; background: transparent; color: inherit; cursor: pointer; } .mobile-palette-current { display: grid; grid-template-columns: 34px minmax(0, 1fr) 20px; align-items: center; gap: 10px; padding: 4px 10px 4px 4px; text-align: left; } .mobile-palette-current-swatch { position: relative; display: inline-flex; align-items: center; justify-content: center; width: 34px; height: 34px; overflow: hidden; border: 1px solid var(--pallete-outline-color); border-radius: 6px; } .mobile-palette-current-swatch--empty { background: conic-gradient( #ef4444, #f97316, #facc15, #22c55e, #06b6d4, #3b82f6, #a855f7, #ef4444 ); } .mobile-palette-current-text { min-width: 0; overflow: hidden; font-size: 0.875rem; font-weight: 700; line-height: 1; text-overflow: ellipsis; white-space: nowrap; } .mobile-palette-icon-button { display: inline-flex; align-items: center; justify-content: center; padding: 0; } .mobile-palette-current-swatch .pallete-color-surface { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; } } .mobile-palette-avatar { display: inline-flex; align-items: center; justify-content: center; width: 34px; height: 34px; overflow: hidden; border-radius: 50%; background: #e5e7eb; color: #111827; font-size: 0.875rem; font-weight: 800; line-height: 1; } .mobile-palette-avatar img { display: block; width: 100%; height: 100%; object-fit: cover; } .mobile-palette-avatar-button { overflow: visible; border: 0 !important; border-radius: 50% !important; background: transparent !important; } .mobile-palette-avatar-button:focus-visible { outline: 2px solid var(--pallete-outline-color); outline-offset: 2px; } .mobile-action-sheet-header { align-items: center; } .mobile-action-sheet-header > button:last-child { flex: 0 0 auto; } .mobile-action-sheet-account-heading { display: grid; grid-template-columns: 40px minmax(0, 1fr); align-items: center; gap: 12px; min-width: 0; } .mobile-action-sheet-account-heading .mobile-palette-avatar { width: 40px; height: 40px; } .mobile-action-sheet-account-copy { display: flex; min-width: 0; flex-direction: column; gap: 3px; } .mobile-action-sheet-account-copy strong, .mobile-action-sheet-account-copy span { min-width: 0; overflow: hidden; line-height: 1.15; text-overflow: ellipsis; white-space: nowrap; } .mobile-action-sheet-account-copy strong { font-size: 0.95rem; font-weight: 800; } .mobile-action-sheet-account-copy span { color: #6b7280; font-size: 0.75rem; font-weight: 600; } .dark .mobile-action-sheet-account-copy span { color: #a1a1aa; } .mobile-palette-sheet-backdrop { position: fixed; inset: 0; z-index: 9999; display: flex; align-items: flex-end; justify-content: center; padding: 0 8px env(safe-area-inset-bottom); background: rgba(0, 0, 0, 0.34); } .mobile-palette-sheet, .mobile-action-sheet { --pallete-outline-color: #e5e7eb; --pallete-active-gap-color: #fff; --pallete-selected-outline-color: #c1c5cd; box-sizing: border-box; width: min(100%, 480px); max-height: calc(100dvh - 72px); overflow: hidden; border-radius: 8px 8px 0 0; background: #fff; color: #111827; } .mobile-palette-sheet-header { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 10px 12px; border-bottom: 1px solid var(--pallete-outline-color); font-size: 0.95rem; font-weight: 800; line-height: 1; } .mobile-palette-sheet-deselect-icon { display: inline-flex; align-items: center; justify-content: center; place-self: center; width: 44px; height: 44px; padding: 0; border: 0; border-radius: 0; appearance: none; background: transparent; box-shadow: none; color: inherit; cursor: pointer; font-size: 2.25rem; line-height: 1; transition: scale 0.25s; } .mobile-palette-sheet-deselect-icon:hover { scale: 1.075; } .mobile-palette-sheet .mobile-palette-icon-button, .mobile-action-sheet .mobile-palette-icon-button { display: inline-flex; align-items: center; justify-content: center; width: 36px; height: 36px; border: 1px solid var(--pallete-outline-color); border-radius: 8px; background: transparent; color: inherit; cursor: pointer; } .mobile-action-sheet-items { display: flex; flex-direction: column; gap: 8px; max-height: min(58dvh, 420px); overflow-y: auto; padding: 12px; } .mobile-action-sheet-item { justify-content: flex-start !important; min-height: 42px; } .mobile-action-sheet-item .header-button-label { max-width: none; opacity: 1; transform: none; } .mobile-palette-sheet-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(44px, 1fr)); gap: 8px; max-height: min(58dvh, 420px); overflow-y: auto; padding: 12px; } .mobile-palette-sheet-color { position: relative; min-width: 0; min-height: 44px; aspect-ratio: 1; overflow: visible; border: 1px solid var(--pallete-outline-color); border-radius: 6px; background: transparent; cursor: pointer; isolation: isolate; transition: box-shadow 0.16s ease, scale 0.16s ease, border-color 0.16s ease; } .mobile-palette-sheet-color.active { z-index: 3; scale: 1.08; border-color: var(--pallete-selected-outline-color); box-shadow: 0 0 0 1px var(--pallete-active-gap-color), 0 0 0 3px var(--pallete-selected-outline-color); } .mobile-palette-sheet-color .pallete-color-surface { position: absolute; z-index: 0; inset: 0; width: 100%; height: 100%; border-radius: 5px; pointer-events: none; } .mobile-palette-sheet-color .pallete-color-number, .mobile-palette-sheet-color .pallete-color-needed { position: absolute; z-index: 2; left: 50%; min-width: 18px; height: 16px; padding: 0 4px; transform: translateX(-50%); display: inline-flex; align-items: center; justify-content: center; background-color: white; color: black; border: 1px solid var(--pallete-outline-color); border-radius: 3px; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.24); font-size: 9px; font-weight: 700; font-variant-numeric: tabular-nums; line-height: 1; letter-spacing: 0; pointer-events: none; } .mobile-palette-sheet-color .pallete-color-number { top: -5px; } .mobile-palette-sheet-color .pallete-color-needed { bottom: -5px; min-width: 22px; } .mobile-palette-sheet-color .pallete-color-symbol { position: absolute; z-index: 1; inset: 5px; pointer-events: none; mask-repeat: no-repeat; -webkit-mask-repeat: no-repeat; image-rendering: pixelated; } .dark .mobile-palette-sheet, .dark .mobile-action-sheet { --pallete-outline-color: #27272a; --pallete-active-gap-color: #000; --pallete-selected-outline-color: #3d3d43; background: #000; color: #f5f5f5; } .dark .mobile-palette-sheet-color .pallete-color-number, .dark .mobile-palette-sheet-color .pallete-color-needed { background-color: #000; color: #f5f5f5; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.5); } .dark #pallete .pallete-color .pallete-color-number, .dark #pallete .pallete-color .pallete-color-needed { background-color: #000; Loading Loading
packages/client/src/components/Header/HeaderRight.tsx +2 −2 Original line number Diff line number Diff line Loading @@ -118,9 +118,9 @@ export const HeaderRight = () => { className="header-right box flex flex-col gap-2" transition={reduceMotion ? { duration: 0 } : SIDEBAR_SPRING} > <User /> {!isMobile && <User />} <div className="header-right-actions flex gap-2"> <div ref={captureMenuRef} className="relative"> <div ref={captureMenuRef} className="header-share-menu relative"> <Button aria-label="Share" aria-expanded={captureMenuOpen} Loading
packages/client/src/components/Settings/MiscSettings.tsx +22 −13 Original line number Diff line number Diff line import { usePanel } from "@/contexts/PanelContext"; import { useAppContext } from "../../contexts/AppContext"; import { useDialog } from "../../contexts/DialogContext"; import { useIsCompactPaletteDefault } from "../../hooks/useCompactPalette"; import { useIsMobile } from "../../hooks/useIsMobile"; import { Button } from "../core/Button"; import { Switch } from "../core/Switch"; Loading @@ -10,6 +11,10 @@ export const MiscSettings = () => { const Dialog = useDialog(); const Panel = usePanel(); const isMobile = useIsMobile(); const compactPaletteDefault = useIsCompactPaletteDefault(); const compactPaletteSetting = settings.get["palette.compact"]; const compactPaletteSelected = compactPaletteSetting ?? compactPaletteDefault; const showCompactPaletteSettings = !isMobile; return ( <div className="flex flex-col gap-4 p-2"> Loading Loading @@ -80,15 +85,19 @@ export const MiscSettings = () => { > Compact Buttons </Switch> {showCompactPaletteSettings && ( <Switch isSelected={settings.get["palette.compact"]} isSelected={compactPaletteSelected} onValueChange={(value) => { settings.set({ key: "palette.compact", value }); }} > Compact Palette </Switch> {!settings.get["palette.compact"] && ( )} {showCompactPaletteSettings && compactPaletteSetting === undefined && !compactPaletteDefault && ( <Switch className="sidebar-adaptation-setting" isSelected={settings.get["ui.compactPaletteForSidebar"]} Loading
packages/client/src/components/Templating/MobileTemplateButtons.tsx +1 −1 Original line number Diff line number Diff line Loading @@ -8,7 +8,7 @@ export const MobileTemplateButtons = () => { if (!url) return null; return ( <div className="md:hidden toolbar-box top-[-10px] right-[10px]"> <div className="mobile-template-toggle-wrapper md:hidden"> <Card className="mobile-template-toggle canvas-overlay-card"> <Switch size="sm" Loading
packages/client/src/components/Toolbar/CanvasMeta.tsx +2 −1 Original line number Diff line number Diff line Loading @@ -101,6 +101,7 @@ export const CanvasMeta = () => { const reduceMotion = useReducedMotion() ?? false; const sidebarWidth = useSidebarWidth("Left"); const compactPalette = useCompactPalette(); const canvasMetaBottom = !isMobile && compactPalette ? 84 : 76; const offsetForSidebar = Boolean( !isMobile && Panel.state.info && Loading Loading @@ -132,7 +133,7 @@ export const CanvasMeta = () => { <motion.div animate={{ x: offsetForSidebar ? sidebarWidth : 0, bottom: compactPalette ? 84 : 76, bottom: canvasMetaBottom, }} id="canvas-meta" className={`toolbar-box canvas-overlay-card${isCollapsed ? " canvas-meta--collapsed" : ""}`} Loading
packages/client/src/components/Toolbar/Palette.scss +373 −2 Original line number Diff line number Diff line Loading @@ -281,13 +281,14 @@ flex-grow: 0; display: flex; align-items: center; justify-content: center; justify-content: safe center; gap: 10px; width: 100%; height: 68px; margin-inline: auto; padding: 4px 0; overflow: hidden; overflow-x: auto; overflow-y: hidden; white-space: normal; } Loading Loading @@ -352,6 +353,376 @@ } } #pallete.pallete--mobile { padding: 8px 10px calc(8px + env(safe-area-inset-bottom)); .mobile-palette-bar { display: grid; grid-template-columns: minmax(0, 1fr) 44px 44px; align-items: center; gap: 8px; width: 100%; } .mobile-palette-current, .mobile-palette-icon-button { min-width: 0; height: 44px; border: 1px solid var(--pallete-outline-color); border-radius: 8px; background: transparent; color: inherit; cursor: pointer; } .mobile-palette-current { display: grid; grid-template-columns: 34px minmax(0, 1fr) 20px; align-items: center; gap: 10px; padding: 4px 10px 4px 4px; text-align: left; } .mobile-palette-current-swatch { position: relative; display: inline-flex; align-items: center; justify-content: center; width: 34px; height: 34px; overflow: hidden; border: 1px solid var(--pallete-outline-color); border-radius: 6px; } .mobile-palette-current-swatch--empty { background: conic-gradient( #ef4444, #f97316, #facc15, #22c55e, #06b6d4, #3b82f6, #a855f7, #ef4444 ); } .mobile-palette-current-text { min-width: 0; overflow: hidden; font-size: 0.875rem; font-weight: 700; line-height: 1; text-overflow: ellipsis; white-space: nowrap; } .mobile-palette-icon-button { display: inline-flex; align-items: center; justify-content: center; padding: 0; } .mobile-palette-current-swatch .pallete-color-surface { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; } } .mobile-palette-avatar { display: inline-flex; align-items: center; justify-content: center; width: 34px; height: 34px; overflow: hidden; border-radius: 50%; background: #e5e7eb; color: #111827; font-size: 0.875rem; font-weight: 800; line-height: 1; } .mobile-palette-avatar img { display: block; width: 100%; height: 100%; object-fit: cover; } .mobile-palette-avatar-button { overflow: visible; border: 0 !important; border-radius: 50% !important; background: transparent !important; } .mobile-palette-avatar-button:focus-visible { outline: 2px solid var(--pallete-outline-color); outline-offset: 2px; } .mobile-action-sheet-header { align-items: center; } .mobile-action-sheet-header > button:last-child { flex: 0 0 auto; } .mobile-action-sheet-account-heading { display: grid; grid-template-columns: 40px minmax(0, 1fr); align-items: center; gap: 12px; min-width: 0; } .mobile-action-sheet-account-heading .mobile-palette-avatar { width: 40px; height: 40px; } .mobile-action-sheet-account-copy { display: flex; min-width: 0; flex-direction: column; gap: 3px; } .mobile-action-sheet-account-copy strong, .mobile-action-sheet-account-copy span { min-width: 0; overflow: hidden; line-height: 1.15; text-overflow: ellipsis; white-space: nowrap; } .mobile-action-sheet-account-copy strong { font-size: 0.95rem; font-weight: 800; } .mobile-action-sheet-account-copy span { color: #6b7280; font-size: 0.75rem; font-weight: 600; } .dark .mobile-action-sheet-account-copy span { color: #a1a1aa; } .mobile-palette-sheet-backdrop { position: fixed; inset: 0; z-index: 9999; display: flex; align-items: flex-end; justify-content: center; padding: 0 8px env(safe-area-inset-bottom); background: rgba(0, 0, 0, 0.34); } .mobile-palette-sheet, .mobile-action-sheet { --pallete-outline-color: #e5e7eb; --pallete-active-gap-color: #fff; --pallete-selected-outline-color: #c1c5cd; box-sizing: border-box; width: min(100%, 480px); max-height: calc(100dvh - 72px); overflow: hidden; border-radius: 8px 8px 0 0; background: #fff; color: #111827; } .mobile-palette-sheet-header { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 10px 12px; border-bottom: 1px solid var(--pallete-outline-color); font-size: 0.95rem; font-weight: 800; line-height: 1; } .mobile-palette-sheet-deselect-icon { display: inline-flex; align-items: center; justify-content: center; place-self: center; width: 44px; height: 44px; padding: 0; border: 0; border-radius: 0; appearance: none; background: transparent; box-shadow: none; color: inherit; cursor: pointer; font-size: 2.25rem; line-height: 1; transition: scale 0.25s; } .mobile-palette-sheet-deselect-icon:hover { scale: 1.075; } .mobile-palette-sheet .mobile-palette-icon-button, .mobile-action-sheet .mobile-palette-icon-button { display: inline-flex; align-items: center; justify-content: center; width: 36px; height: 36px; border: 1px solid var(--pallete-outline-color); border-radius: 8px; background: transparent; color: inherit; cursor: pointer; } .mobile-action-sheet-items { display: flex; flex-direction: column; gap: 8px; max-height: min(58dvh, 420px); overflow-y: auto; padding: 12px; } .mobile-action-sheet-item { justify-content: flex-start !important; min-height: 42px; } .mobile-action-sheet-item .header-button-label { max-width: none; opacity: 1; transform: none; } .mobile-palette-sheet-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(44px, 1fr)); gap: 8px; max-height: min(58dvh, 420px); overflow-y: auto; padding: 12px; } .mobile-palette-sheet-color { position: relative; min-width: 0; min-height: 44px; aspect-ratio: 1; overflow: visible; border: 1px solid var(--pallete-outline-color); border-radius: 6px; background: transparent; cursor: pointer; isolation: isolate; transition: box-shadow 0.16s ease, scale 0.16s ease, border-color 0.16s ease; } .mobile-palette-sheet-color.active { z-index: 3; scale: 1.08; border-color: var(--pallete-selected-outline-color); box-shadow: 0 0 0 1px var(--pallete-active-gap-color), 0 0 0 3px var(--pallete-selected-outline-color); } .mobile-palette-sheet-color .pallete-color-surface { position: absolute; z-index: 0; inset: 0; width: 100%; height: 100%; border-radius: 5px; pointer-events: none; } .mobile-palette-sheet-color .pallete-color-number, .mobile-palette-sheet-color .pallete-color-needed { position: absolute; z-index: 2; left: 50%; min-width: 18px; height: 16px; padding: 0 4px; transform: translateX(-50%); display: inline-flex; align-items: center; justify-content: center; background-color: white; color: black; border: 1px solid var(--pallete-outline-color); border-radius: 3px; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.24); font-size: 9px; font-weight: 700; font-variant-numeric: tabular-nums; line-height: 1; letter-spacing: 0; pointer-events: none; } .mobile-palette-sheet-color .pallete-color-number { top: -5px; } .mobile-palette-sheet-color .pallete-color-needed { bottom: -5px; min-width: 22px; } .mobile-palette-sheet-color .pallete-color-symbol { position: absolute; z-index: 1; inset: 5px; pointer-events: none; mask-repeat: no-repeat; -webkit-mask-repeat: no-repeat; image-rendering: pixelated; } .dark .mobile-palette-sheet, .dark .mobile-action-sheet { --pallete-outline-color: #27272a; --pallete-active-gap-color: #000; --pallete-selected-outline-color: #3d3d43; background: #000; color: #f5f5f5; } .dark .mobile-palette-sheet-color .pallete-color-number, .dark .mobile-palette-sheet-color .pallete-color-needed { background-color: #000; color: #f5f5f5; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.5); } .dark #pallete .pallete-color .pallete-color-number, .dark #pallete .pallete-color .pallete-color-needed { background-color: #000; Loading