1
0
Peng Xiao 3 жил өмнө
parent
commit
3e5ee7c541

+ 3 - 2
tldraw/apps/tldraw-logseq/package.json

@@ -30,9 +30,10 @@
     "tsup": "^6.1.2",
     "typescript": "^4.7.3",
     "zx": "^6.2.4",
-    "@radix-ui/react-switch": "^1.0.0",
     "@radix-ui/react-dropdown-menu": "^1.0.0",
-    "@radix-ui/react-select": "^1.0.0"
+    "@radix-ui/react-select": "^1.0.0",
+    "@radix-ui/react-switch": "^1.0.0",
+    "@radix-ui/react-toggle-group": "^1.0.0"
   },
   "peerDependencies": {
     "react": "^16.8.0 || ^17.0.0 || ^18.0.0",

+ 55 - 5
tldraw/apps/tldraw-logseq/src/components/ContextBar/contextBarActionFactory.tsx

@@ -3,6 +3,7 @@ import { useApp } from '@tldraw/react'
 import { observer } from 'mobx-react-lite'
 import { TablerIcon } from '~components/icons'
 import { SelectInput, SelectOption } from '~components/inputs/SelectInput'
+import { ToggleGroupInput, ToggleGroupInputOption } from '~components/inputs/ToggleGroupInput'
 import { LogseqPortalShape, Shape } from '~lib'
 
 export const contextBarActionTypes = [
@@ -27,18 +28,18 @@ const LogseqPortalViewModeAction = observer(() => {
   ) as LogseqPortalShape[]
 
   const collapsed = shapes.every(s => s.collapsed)
-  const ViewModeOptions: SelectOption[] = [
+  const ViewModeOptions: ToggleGroupInputOption[] = [
     {
       value: '0',
-      label: <TablerIcon name="layout-navbar-expand" />,
+      icon: 'layout-navbar-expand',
     },
     {
       value: '1',
-      label: <TablerIcon name="layout-navbar-collapse" />,
+      icon: 'layout-navbar-collapse',
     },
   ]
   return (
-    <SelectInput
+    <ToggleGroupInput
       options={ViewModeOptions}
       value={collapsed ? '1' : '0'}
       onValueChange={v => {
@@ -50,12 +51,61 @@ const LogseqPortalViewModeAction = observer(() => {
   )
 })
 
+const ScaleLevelAction = observer(() => {
+  const app = useApp<Shape>()
+  const shapes = app.selectedShapesArray.filter(
+    s => s.props.type === LogseqPortalShape.defaultProps.type
+  ) as LogseqPortalShape[]
+
+  const scaleLevel = new Set(shapes.map(s => s.scaleLevel)).size > 1 ? '' : shapes[0].scaleLevel
+  const sizeOptions: SelectOption[] = [
+    {
+      label: 'Extra Small',
+      value: 'xs',
+    },
+    {
+      label: 'Small',
+      value: 'sm',
+    },
+    {
+      label: 'Medium',
+      value: 'md',
+    },
+    {
+      label: 'Large',
+      value: 'lg',
+    },
+    {
+      label: 'Extra Large',
+      value: 'xl',
+    },
+    {
+      label: '2 Extra Large',
+      value: 'xxl',
+    },
+  ]
+  return (
+    <SelectInput
+      options={sizeOptions}
+      value={scaleLevel}
+      onValueChange={v => {
+        if (v) {
+          shapes.forEach(shape => {
+            shape.setScaleLevel(v as LogseqPortalShape['props']['scaleLevel'])
+          })
+        }
+      }}
+    />
+  )
+})
+
 contextBarActionMapping.set('LogseqPortalViewMode', LogseqPortalViewModeAction)
+contextBarActionMapping.set('ScaleLevel', ScaleLevelAction)
 
 type ShapeType = Shape['props']['type']
 
 const shapeMapping: Partial<Record<ShapeType, ContextBarActionType[]>> = {
-  'logseq-portal': ['LogseqPortalViewMode'],
+  'logseq-portal': ['LogseqPortalViewMode', 'ScaleLevel'],
 }
 
 export const getContextBarActionsForType = (type: ShapeType) => {

+ 2 - 2
tldraw/apps/tldraw-logseq/src/components/inputs/SelectInput.tsx

@@ -7,7 +7,7 @@ export interface SelectOption {
   label: React.ReactNode
 }
 
-interface SelectInputProps extends React.InputHTMLAttributes<HTMLInputElement> {
+interface SelectInputProps extends React.HTMLAttributes<HTMLElement> {
   options: SelectOption[]
   value: string
   onValueChange: (value: string) => void
@@ -27,7 +27,7 @@ export function SelectInput({ options, value, onValueChange, ...rest }: SelectIn
           <div className="tl-select-input-trigger-value">
             <Select.Value />
           </div>
-          <Select.Icon>
+          <Select.Icon style={{ lineHeight: 1 }}>
             <TablerIcon name={isOpen ? 'chevron-up' : 'chevron-down'} />
           </Select.Icon>
         </Select.Trigger>

+ 38 - 0
tldraw/apps/tldraw-logseq/src/components/inputs/ToggleGroupInput.tsx

@@ -0,0 +1,38 @@
+import * as ToggleGroup from '@radix-ui/react-toggle-group'
+import { TablerIcon } from '~components/icons'
+
+export interface ToggleGroupInputOption {
+  value: string
+  icon: string
+}
+
+interface SelectInputProps extends React.HTMLAttributes<HTMLElement> {
+  options: ToggleGroupInputOption[]
+  value: string
+  onValueChange: (value: string) => void
+}
+
+export function ToggleGroupInput({ options, value, onValueChange, ...rest }: SelectInputProps) {
+  return (
+    <div {...rest}>
+      <ToggleGroup.Root
+        className="tl-toggle-group-input"
+        type="single"
+        value={value}
+        onValueChange={onValueChange}
+      >
+        {options.map(option => {
+          return (
+            <ToggleGroup.Item
+              className="tl-toggle-group-input-button"
+              key={option.value}
+              value={option.value}
+            >
+              <TablerIcon name={option.icon} />
+            </ToggleGroup.Item>
+          )
+        })}
+      </ToggleGroup.Root>
+    </div>
+  )
+}

+ 20 - 69
tldraw/apps/tldraw-logseq/src/lib/shapes/LogseqPortalShape.tsx

@@ -30,33 +30,6 @@ interface LogseqQuickSearchProps {
   onChange: (id: string) => void
 }
 
-const sizeOptions: SelectOption[] = [
-  {
-    label: 'Extra Small',
-    value: 'xs',
-  },
-  {
-    label: 'Small',
-    value: 'sm',
-  },
-  {
-    label: 'Medium',
-    value: 'md',
-  },
-  {
-    label: 'Large',
-    value: 'lg',
-  },
-  {
-    label: 'Extra Large',
-    value: 'xl',
-  },
-  {
-    label: '2 Extra Large',
-    value: 'xxl',
-  },
-]
-
 const levelToScale = {
   xs: 0.5,
   sm: 0.8,
@@ -222,6 +195,26 @@ export class LogseqPortalShape extends TLBoxShape<LogseqPortalShapeProps> {
     }
   }
 
+  @computed get scaleLevel() {
+    return this.props.scaleLevel ?? 'md'
+  }
+
+  @action setScaleLevel = (v?: SizeLevel) => {
+    const newSize = Vec.mul(
+      this.props.size,
+      levelToScale[(v as SizeLevel) ?? 'md'] / levelToScale[this.props.scaleLevel ?? 'md']
+    )
+    this.update({
+      scaleLevel: v,
+    })
+    setTimeout(() => {
+      this.update({
+        size: newSize,
+      })
+      this.persist?.()
+    })
+  }
+
   useComponentSize<T extends HTMLElement>(ref: React.RefObject<T> | null, selector = '') {
     const [size, setSize] = React.useState<[number, number]>([0, 0])
     const app = useApp<Shape>()
@@ -252,48 +245,6 @@ export class LogseqPortalShape extends TLBoxShape<LogseqPortalShapeProps> {
     return size
   }
 
-  ReactContextBar = observer(() => {
-    const app = useApp<Shape>()
-    return (
-      <>
-        <SelectInput
-          options={sizeOptions}
-          value={this.props.scaleLevel ?? 'md'}
-          onValueChange={v => {
-            const newSize = Vec.mul(
-              this.props.size,
-              levelToScale[(v as SizeLevel) ?? 'md'] / levelToScale[this.props.scaleLevel ?? 'md']
-            )
-            this.update({
-              scaleLevel: v,
-            })
-            setTimeout(() => {
-              this.update({
-                size: newSize,
-              })
-              app.persist()
-            })
-          }}
-        />
-        {this.props.blockType !== 'B' && (
-          <SwitchInput
-            label="Collapsed"
-            checked={this.props.collapsed}
-            onCheckedChange={this.setCollapsed}
-          />
-        )}
-
-        {this.props.blockType === 'B' && (
-          <SwitchInput
-            label="Compact"
-            checked={this.props.compact}
-            onCheckedChange={this.setCollapsed}
-          />
-        )}
-      </>
-    )
-  })
-
   shouldAutoResizeHeight() {
     return this.props.blockType === 'B' && this.props.compact
   }

+ 32 - 5
tldraw/apps/tldraw-logseq/src/styles.css

@@ -28,7 +28,7 @@
   z-index: 100000;
   user-select: none;
   background: white;
-  border-bottom: 1px solid black;
+  border-bottom: 1px solid var(--ls-secondary-border-color);
   font-size: inherit;
 }
 
@@ -107,7 +107,7 @@
 
   pointer-events: all;
   position: relative;
-  background-color: #fff;
+  background-color: var(--ls-secondary-background-color);
   color: #a4b5b6;
   padding: 8px 12px;
   border-radius: 8px;
@@ -198,7 +198,7 @@
   z-index: 100000;
   user-select: none;
   background: white;
-  border-top: 1px solid black;
+  border-top: 1px solid var(--ls-secondary-border-color);
   flex-shrink: 0;
   height: 32px;
 }
@@ -249,12 +249,13 @@
 
 button.tl-select-input-trigger {
   @apply flex items-center py-1 px-3;
-  border: 1px solid var(--ls-secondary-background-color);
-  background-color: var(--ls-tertiary-background-color);
+  border: 1px solid var(--ls-secondary-border-color);
+  background-color: var(--ls-quaternary-background-color);
   min-width: 160px;
   border-radius: 8px;
   font-size: 16px;
   height: 100%;
+  color: var(--ls-secondary-text-color);
 }
 
 .tl-select-input-trigger-value {
@@ -271,6 +272,8 @@ button.tl-select-input-trigger {
   cursor: default;
   padding: 4px 12px;
 
+  color: var(--ls-secondary-text-color);
+
   &[data-state='unchecked']:hover {
     background-color: var(--ls-tertiary-background-color);
     color: var(--ls-primary-text-color);
@@ -692,3 +695,27 @@ html[data-theme='dark'] {
     backdrop-filter: brightness(1.2);
   }
 }
+
+.tl-toggle-group-input {
+  @apply rounded overflow-hidden;
+  border: 1px solid var(--ls-secondary-border-color);
+}
+
+.tl-toggle-group-input-button {
+  @apply inline-flex items-center justify-center;
+  border-right: 1px solid var(--ls-secondary-border-color);
+  height: 32px;
+  width: 32px;
+  color: var(--ls-secondary-text-color);
+  opacity: 0.3;
+
+  &:last-of-type {
+    border-right: none;
+  }
+
+  &[data-state='on'] {
+    background-color: var(--ls-tertiary-background-color);
+    color: var(--ls-primary-text-color);
+    opacity: 1;
+  }
+}

+ 24 - 0
tldraw/yarn.lock

@@ -2031,6 +2031,30 @@
     "@radix-ui/react-use-previous" "1.0.0"
     "@radix-ui/react-use-size" "1.0.0"
 
+"@radix-ui/react-toggle-group@^1.0.0":
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/@radix-ui/react-toggle-group/-/react-toggle-group-1.0.0.tgz#6e78ffb13e0b4c1f789828930330638f4ba9c06d"
+  integrity sha512-R/5sK4/BPgOYWAsheFaFpNFh0sLPHdqsBcqO5KW2+Foy36B2KBYrGd6Hu4HnzgivawVX+mSmVNhAwHA8Yb1hLA==
+  dependencies:
+    "@babel/runtime" "^7.13.10"
+    "@radix-ui/primitive" "1.0.0"
+    "@radix-ui/react-context" "1.0.0"
+    "@radix-ui/react-direction" "1.0.0"
+    "@radix-ui/react-primitive" "1.0.0"
+    "@radix-ui/react-roving-focus" "1.0.0"
+    "@radix-ui/react-toggle" "1.0.0"
+    "@radix-ui/react-use-controllable-state" "1.0.0"
+
+"@radix-ui/[email protected]":
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/@radix-ui/react-toggle/-/react-toggle-1.0.0.tgz#9c8f655497b26410766b9c01aa2954159c0cb60b"
+  integrity sha512-RvY06eyDlZMC4rZdWK8jNovEDKf2jBvYFOB4rkQ/ypMOjFQuoh2QodlxlGakrZDrLnfxzyNnn/pg88CWVtAAdw==
+  dependencies:
+    "@babel/runtime" "^7.13.10"
+    "@radix-ui/primitive" "1.0.0"
+    "@radix-ui/react-primitive" "1.0.0"
+    "@radix-ui/react-use-controllable-state" "1.0.0"
+
 "@radix-ui/[email protected]":
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.0.0.tgz#9e7b8b6b4946fe3cbe8f748c82a2cce54e7b6a90"