mirror of
https://github.com/logseq/logseq.git
synced 2026-05-28 06:34:34 +00:00
chore: color system enhancements
This commit is contained in:
@@ -330,21 +330,17 @@ const SwatchAction = observer(() => {
|
||||
const shapes = filterShapeByAction<
|
||||
BoxShape | PolygonShape | EllipseShape | LineShape | PencilShape | TextShape
|
||||
>(app.selectedShapesArray, 'Swatch')
|
||||
const handleChange = React.useMemo(() => {
|
||||
let latestValue = ''
|
||||
const handler: React.ChangeEventHandler<HTMLInputElement> = e => {
|
||||
shapes.forEach(s => {
|
||||
s.update({ fill: latestValue, stroke: latestValue })
|
||||
})
|
||||
app.persist()
|
||||
}
|
||||
return debounce(handler, 100, e => {
|
||||
latestValue = e.target.value
|
||||
|
||||
const handleClick = React.useCallback((e: React.MouseEvent<HTMLButtonElement>) => {
|
||||
const color = e.target.getAttribute("data-color")
|
||||
shapes.forEach(s => {
|
||||
s.update({ fill: color, stroke: color })
|
||||
})
|
||||
app.persist()
|
||||
}, [])
|
||||
|
||||
const value = shapes[0].props.noFill ? shapes[0].props.stroke : shapes[0].props.fill
|
||||
return <ColorInput title="Color Picker" value={value} onChange={handleChange} />
|
||||
return <ColorInput title="Color Picker" value={value} onClick={handleClick} />
|
||||
})
|
||||
|
||||
const StrokeTypeAction = observer(() => {
|
||||
|
||||
@@ -2,7 +2,7 @@ import * as React from 'react'
|
||||
import * as Popover from '@radix-ui/react-popover';
|
||||
import { TablerIcon } from '../icons'
|
||||
|
||||
interface ColorInputProps extends React.InputHTMLAttributes<HTMLInputElement> {}
|
||||
interface ColorInputProps extends React.InputHTMLAttributes<HTMLButtonElement> {}
|
||||
|
||||
enum HighlightColor {
|
||||
Gray = 'gray',
|
||||
@@ -12,9 +12,10 @@ enum HighlightColor {
|
||||
Blue = 'blue',
|
||||
Purple = 'purple',
|
||||
Pink = 'pink',
|
||||
None = 'transparent',
|
||||
}
|
||||
|
||||
export function ColorInput({ value, onChange, ...rest }: ColorInputProps) {
|
||||
export function ColorInput({ value, onClick, ...rest }: ColorInputProps) {
|
||||
const ref = React.useRef<HTMLDivElement>(null)
|
||||
const [computedValue, setComputedValue] = React.useState(value)
|
||||
|
||||
@@ -31,12 +32,10 @@ export function ColorInput({ value, onChange, ...rest }: ColorInputProps) {
|
||||
|
||||
return (
|
||||
<Popover.Root>
|
||||
<Popover.Trigger asChild>
|
||||
<Popover.Trigger>
|
||||
<div className="input" ref={ref}>
|
||||
<div className="color-input-wrapper">
|
||||
<button
|
||||
className={`bg-${computedValue}-500)`}
|
||||
/>
|
||||
<button className={`bg-${value}-500`} />
|
||||
</div>
|
||||
</div>
|
||||
</Popover.Trigger>
|
||||
@@ -48,19 +47,18 @@ export function ColorInput({ value, onChange, ...rest }: ColorInputProps) {
|
||||
arrowPadding={10}
|
||||
>
|
||||
<div className={"tl-color-palette"}>
|
||||
{Object.values(HighlightColor).map(value =>
|
||||
{Object.values(HighlightColor).map(color =>
|
||||
<button
|
||||
className={`tl-color-drip bg-${value}-500`}
|
||||
onClick={()=>{
|
||||
setComputedValue(value)
|
||||
className={`tl-color-drip bg-${color}-500`}
|
||||
data-color={color}
|
||||
onClick={(e)=>{
|
||||
// setComputedValue(value)
|
||||
onClick?.(e)
|
||||
}}
|
||||
/>
|
||||
>
|
||||
{(color === "transparent") && <TablerIcon name="droplet-off" />}
|
||||
</button>
|
||||
)}
|
||||
<button
|
||||
className="tl-color-drip"
|
||||
>
|
||||
<TablerIcon name="text" />
|
||||
</button>
|
||||
</div>
|
||||
<Popover.Arrow className="tl-popover-arrow" />
|
||||
</Popover.Content>
|
||||
|
||||
@@ -65,7 +65,7 @@ export class BoxShape extends TLBoxShape<BoxShapeProps> {
|
||||
strokeWidth={strokeWidth}
|
||||
stroke={noFill ? fill : stroke}
|
||||
strokeDasharray={strokeType === 'dashed' ? '8 2' : undefined}
|
||||
fill={noFill ? 'none' : fill}
|
||||
fill={noFill ? 'none' : `var(--color-${fill}-500)`}
|
||||
/>
|
||||
</SVGContainer>
|
||||
)
|
||||
|
||||
@@ -152,7 +152,7 @@ const CircleButton = ({
|
||||
}, [active])
|
||||
|
||||
return (
|
||||
<div
|
||||
<button
|
||||
data-active={active}
|
||||
data-recently-changed={recentlyChanged}
|
||||
style={style}
|
||||
@@ -163,7 +163,7 @@ const CircleButton = ({
|
||||
{otherIcon && <TablerIcon name={otherIcon} />}
|
||||
<TablerIcon name={icon} />
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -181,7 +181,7 @@ export class LogseqPortalShape extends TLBoxShape<LogseqPortalShapeProps> {
|
||||
// collapsedHeight is the height before collapsing
|
||||
collapsedHeight: 0,
|
||||
stroke: 'var(--ls-primary-text-color)',
|
||||
fill: 'var(--ls-secondary-background-color)',
|
||||
fill: 'transparent',
|
||||
noFill: false,
|
||||
borderRadius: 8,
|
||||
strokeWidth: 2,
|
||||
@@ -661,7 +661,7 @@ export class LogseqPortalShape extends TLBoxShape<LogseqPortalShapeProps> {
|
||||
|
||||
PortalComponent = observer(({}: TLComponentProps) => {
|
||||
const {
|
||||
props: { pageId },
|
||||
props: { pageId, fill },
|
||||
} = this
|
||||
const { renderers } = React.useContext(LogseqContext)
|
||||
const app = useApp<Shape>()
|
||||
@@ -707,6 +707,7 @@ export class LogseqPortalShape extends TLBoxShape<LogseqPortalShapeProps> {
|
||||
ref={cpRefContainer}
|
||||
className="tl-logseq-cp-container"
|
||||
style={{
|
||||
background: `var(--ls-highlight-color-${fill})`,
|
||||
overflow: this.props.isAutoResizing ? 'visible' : 'auto',
|
||||
}}
|
||||
>
|
||||
@@ -838,8 +839,6 @@ export class LogseqPortalShape extends TLBoxShape<LogseqPortalShapeProps> {
|
||||
data-portal-selected={portalSelected}
|
||||
data-editing={isEditing}
|
||||
style={{
|
||||
background: this.props.compact ? 'transparent' : fill,
|
||||
color: stroke,
|
||||
width: `calc(100% / ${scaleRatio})`,
|
||||
height: `calc(100% / ${scaleRatio})`,
|
||||
transform: `scale(${scaleRatio})`,
|
||||
|
||||
@@ -647,6 +647,7 @@ button.tl-select-input-trigger {
|
||||
opacity: 1;
|
||||
user-select: text;
|
||||
transform-origin: top left;
|
||||
background: var(--ls-secondary-background-color);
|
||||
|
||||
&[data-collapsed='true'][data-editing='false'] {
|
||||
@apply overflow-hidden;
|
||||
@@ -850,8 +851,10 @@ html[data-theme='dark'] {
|
||||
}
|
||||
|
||||
.tl-popover-content {
|
||||
border-radius: 4px;
|
||||
padding: 20px;
|
||||
@apply rounded-sm;
|
||||
|
||||
padding: 4px;
|
||||
width: 160px;
|
||||
background-color: var(--ls-secondary-background-color);
|
||||
z-index: 100000;
|
||||
}
|
||||
@@ -861,12 +864,15 @@ html[data-theme='dark'] {
|
||||
}
|
||||
|
||||
.tl-color-palette {
|
||||
@apply flex;
|
||||
@apply flex flex-wrap;
|
||||
}
|
||||
|
||||
.tl-color-drip {
|
||||
@apply rounded-sm;
|
||||
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
margin: 2px;
|
||||
margin: 4px;
|
||||
border: 1px solid var(--ls-secondary-border-color);
|
||||
color: var(--ls-secondary-text-color);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user