From a3d6fae1482c61ca725d0a103f13b621aa32b3e3 Mon Sep 17 00:00:00 2001 From: bobzel Date: Sat, 5 Apr 2025 14:29:03 -0400 Subject: fixed multitoggle behavior to only toggle submenu closed. switched to hard-light for masking ink. fixed to make menu toggle take effect immediately. --- packages/components/src/components/Group/Group.tsx | 68 +++++------ .../components/MultiToggle/MultiToggle.stories.tsx | 125 ++++++++++----------- .../src/components/MultiToggle/MultiToggle.tsx | 36 +++--- packages/components/src/components/Popup/Popup.tsx | 22 ++-- src/client/documents/Documents.ts | 37 +++--- src/client/views/collections/CollectionSubView.tsx | 7 +- .../views/collections/FlashcardPracticeUI.tsx | 5 +- .../collectionFreeForm/CollectionFreeFormView.scss | 2 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 5 +- src/client/views/nodes/FontIconBox/FontIconBox.tsx | 1 - 10 files changed, 139 insertions(+), 169 deletions(-) diff --git a/packages/components/src/components/Group/Group.tsx b/packages/components/src/components/Group/Group.tsx index 7abe4a1c7..6275a09dd 100644 --- a/packages/components/src/components/Group/Group.tsx +++ b/packages/components/src/components/Group/Group.tsx @@ -1,49 +1,33 @@ -import React from 'react' -import './Group.scss' -import { Colors, IGlobalProps, getFontSize, isDark , getFormLabelSize } from '../../global'; +import React from 'react'; +import './Group.scss'; +import { Colors, IGlobalProps, getFontSize, isDark, getFormLabelSize } from '../../global'; export interface IGroupProps extends IGlobalProps { - children: any - rowGap?: number; - columnGap?: number; - padding?: number | string; + children: any; + rowGap?: number; + columnGap?: number; + padding?: number | string; } export const Group = (props: IGroupProps) => { - const { - children, - width = '100%', - rowGap = 5, - columnGap = 5, - padding = 0, - formLabel, - formLabelPlacement, - size, - style, - color, - fillWidth - } = props + const { children, width = '100%', rowGap = 5, columnGap = 5, padding = 0, formLabel, formLabelPlacement, size, style, fillWidth } = props; - const group: JSX.Element = - ( -
-
{children}
-
- ) + const group: JSX.Element = ( +
+
+ {children} +
+
+ ); - return ( - formLabel ? -
-
{formLabel}
- {group} -
- : - group - ) -} + return formLabel ? ( +
+
+ {formLabel} +
+ {group} +
+ ) : ( + group + ); +}; diff --git a/packages/components/src/components/MultiToggle/MultiToggle.stories.tsx b/packages/components/src/components/MultiToggle/MultiToggle.stories.tsx index e71423d7a..b9ba45f72 100644 --- a/packages/components/src/components/MultiToggle/MultiToggle.stories.tsx +++ b/packages/components/src/components/MultiToggle/MultiToggle.stories.tsx @@ -1,69 +1,68 @@ -import { Meta, Story } from '@storybook/react' -import React from 'react' -import { IMultiToggleProps, MultiToggle } from './MultiToggle' -import { FaAlignLeft, FaAlignCenter, FaAlignJustify, FaAlignRight } from 'react-icons/fa' +import { Meta, Story } from '@storybook/react'; +import React from 'react'; +import { IMultiToggleProps, MultiToggle } from './MultiToggle'; +import { FaAlignLeft, FaAlignCenter, FaAlignJustify, FaAlignRight } from 'react-icons/fa'; export default { - title: 'Dash/MultiToggle', - component: MultiToggle, - argTypes: {}, -} as Meta + title: 'Dash/MultiToggle', + component: MultiToggle, + argTypes: {}, +} as Meta; -const MultiToggleStory: Story = (args) => -export const MultiToggleOne = MultiToggleStory.bind({}) +const MultiToggleStory: Story = args => ; +export const MultiToggleOne = MultiToggleStory.bind({}); MultiToggleOne.args = { - tooltip: "Text alignment", - label: "Alignment", - defaultSelectedItems: "center", - toggleStatus: true, - isToggle: false, - items: [ - { - icon: , - tooltip: 'Align left', - val: "left" - }, - { - icon: , - tooltip: 'Align center', - val: "center" - }, - { - icon: , - tooltip: 'Align right', - val: "right" - }, - { - icon: , - tooltip: 'Justify', - val: "justify" - }, - ] -} + tooltip: 'Text alignment', + label: 'Alignment', + defaultSelectedItems: 'center', + toggleStatus: true, + items: [ + { + icon: , + tooltip: 'Align left', + val: 'left', + }, + { + icon: , + tooltip: 'Align center', + val: 'center', + }, + { + icon: , + tooltip: 'Align right', + val: 'right', + }, + { + icon: , + tooltip: 'Justify', + val: 'justify', + }, + ], +}; -export const MultiToggleTwo = MultiToggleStory.bind({}) +export const MultiToggleTwo = MultiToggleStory.bind({}); MultiToggleTwo.args = { - tooltip: "Text Tags", - label: "Tags", - defaultSelectedItems : ["left"], - background: "green", - color: 'white', - multiSelect: true, - items: [ - { - icon: , - tooltip: 'Like', - val: "left" - }, - { - icon: , - tooltip: 'Todo', - val: "center" - }, - { - icon: , - tooltip: 'Idea', - val: "right" - }, - ] -} + tooltip: 'Text Tags', + label: 'Tags', + defaultSelectedItems: ['left'], + background: 'green', + color: 'white', + multiSelect: true, + items: [ + { + icon: , + tooltip: 'Like', + val: 'left', + }, + { + icon: , + tooltip: 'Todo', + val: 'center', + }, + { + icon: , + tooltip: 'Idea', + val: 'right', + }, + ], +}; diff --git a/packages/components/src/components/MultiToggle/MultiToggle.tsx b/packages/components/src/components/MultiToggle/MultiToggle.tsx index 0f659c5ca..0a6fb81c9 100644 --- a/packages/components/src/components/MultiToggle/MultiToggle.tsx +++ b/packages/components/src/components/MultiToggle/MultiToggle.tsx @@ -16,7 +16,6 @@ export interface IMultiToggleProps extends IGlobalProps { defaultSelectedItems?: (string | number) | (string | number)[]; selectedItems?: (string | number) | (string | number)[]; onSelectionChange?: (val: (string | number) | (string | number)[], added: boolean) => unknown; - isToggle?: boolean; toggleStatus?: boolean; } @@ -37,33 +36,30 @@ export const MultiToggle = (props: IMultiToggleProps) => { const itemsMap = new Map(); items.forEach(item => itemsMap.set(item.val, item)); return ( -
+
- - {promoteToArray(selectedItems).length < 2 ? null :
+
} -
- ) +
+ + {promoteToArray(selectedItems).length < 2 ? null :
+
} +
} - isToggle={props.isToggle} + isToggle={true} toggleFunc={() => { const selItem = items.find(item => promoteToArray(selectedItems).includes(item.val)); selItem && setSelectedItemsLocal([selItem.val]); }} type={props.type} - label={props.isToggle ? props.label : undefined} - toggleStatus={props.isToggle ? props.toggleStatus : undefined} + label={undefined} color={color} background={background} popup={ diff --git a/packages/components/src/components/Popup/Popup.tsx b/packages/components/src/components/Popup/Popup.tsx index 82e60f343..9e72ece87 100644 --- a/packages/components/src/components/Popup/Popup.tsx +++ b/packages/components/src/components/Popup/Popup.tsx @@ -20,11 +20,10 @@ export interface IPopupProps extends IGlobalProps { toggle?: JSX.Element; popup: JSX.Element | string | (() => JSX.Element); trigger?: PopupTrigger; - toggleStatus?: boolean; isOpen?: boolean; setOpen?: (b: boolean) => void; background?: string; - isToggle?: boolean; + isToggle?: boolean; // whether popup stays open when background is clicked. muyst click toggle button tp close it. toggleFunc?: () => void; popupContainsPt?: (x: number, y: number) => boolean; } @@ -71,6 +70,7 @@ export const Popup = (props: IPopupProps) => { const rect = popperRef.current?.getBoundingClientRect(); const rect2 = toggleRef.current?.getBoundingClientRect(); if ( + !props.isToggle && (!rect2 || !(rect2.left < e.clientX && rect2.top < e.clientY && rect2.right > e.clientX && rect2.bottom > e.clientY)) && rect && !(rect.left < e.clientX && rect.top < e.clientY && rect.right > e.clientX && rect.bottom > e.clientY) && @@ -109,8 +109,8 @@ export const Popup = (props: IPopupProps) => { timeout = setTimeout(() => setOpen(false), 1000); } }}> - {toggle ?? ( -
+
+ {toggle ?? ( { iconPlacement={iconPlacement} text={text} label={props.label} - toggleStatus={isOpen || props.toggleStatus} + toggleStatus={isOpen} onClick={() => { if (trigger === PopupTrigger.CLICK) { - if (!props.isToggle || props.toggleStatus) { - setOpen(!isOpen); - } + setOpen(!isOpen); props.toggleFunc?.(); } }} fillWidth={fillWidth} /> -
- )} + )} +
{ ref={popperRef} style={{ width, height, background }} tabIndex={-1} - onPointerDown={e => { - e.stopPropagation(); - }} + onPointerDown={e => e.stopPropagation()} onPointerEnter={() => { if (trigger === PopupTrigger.HOVER || trigger === PopupTrigger.HOVER_DELAY) { clearTimeout(timeout); diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 8458699fa..f1655e3cf 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -4,7 +4,6 @@ import { basename } from 'path'; import { ClientUtils, OmitKeys } from '../../ClientUtils'; import { DateField } from '../../fields/DateField'; import { CreateLinkToActiveAudio, Doc, FieldType, Opt, updateCachedAcls } from '../../fields/Doc'; -import { Initializing } from '../../fields/DocSymbols'; import { Id } from '../../fields/FieldSymbols'; import { HtmlField } from '../../fields/HtmlField'; import { InkField } from '../../fields/InkField'; @@ -983,26 +982,22 @@ export namespace Docs { export function InkDocument(points: PointData[], options: DocumentOptions = {}, strokeWidth: number, color: string, strokeBezier: string, fillColor: string, arrowStart: string, arrowEnd: string, dash: string, isInkMask: boolean) { const ink = InstanceFromProto(Prototypes.get(DocumentType.INK), '', { title: 'ink', ...options }); - const I = Doc.GetProto(ink); - // I.layout_hideOpenButton = true; // don't show open full screen button when selected - I.color = color; - I.fillColor = fillColor && fillColor !== 'transparent' ? fillColor : undefined; - I.stroke = new InkField(points); - I.stroke_width = strokeWidth; - I.stroke_bezier = strokeBezier; - I.stroke_startMarker = arrowStart; - I.stroke_endMarker = arrowEnd; - I.stroke_dash = dash; - I.stroke_isInkMask = isInkMask; - I.text_align = 'center'; - I.rotation = 0; - I.width_min = 1; - I.height_min = 1; - I.defaultDoubleClick = 'ignore'; - I.author_date = new DateField(); - I.acl_Guest = Doc.defaultAclPrivate ? SharingPermissions.None : SharingPermissions.View; - // I.acl_Override = SharingPermissions.Unset; - I[Initializing] = false; + ink.$color = color; + ink.$fillColor = fillColor && fillColor !== 'transparent' ? fillColor : undefined; + ink.$stroke = new InkField(points); + ink.$stroke_width = strokeWidth; + ink.$stroke_bezier = strokeBezier; + ink.$stroke_startMarker = arrowStart; + ink.$stroke_endMarker = arrowEnd; + ink.$stroke_dash = dash; + ink.$stroke_isInkMask = isInkMask; + ink.$text_align = 'center'; + ink.$rotation = 0; + ink.$width_min = 1; + ink.$height_min = 1; + ink.$defaultDoubleClick = 'ignore'; + ink.$author_date = new DateField(); + ink.$acl_Guest = Doc.defaultAclPrivate ? SharingPermissions.None : SharingPermissions.View; return ink; } diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index cfd52f9ee..a88707c6f 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -13,6 +13,7 @@ import { BoolCast, Cast, DateCast, NumCast, ScriptCast, StrCast, toList } from ' import { WebField } from '../../../fields/URLField'; import { GetEffectiveAcl, TraceMobx } from '../../../fields/util'; import { GestureUtils } from '../../../pen-gestures/GestureUtils'; +import { Upload } from '../../../server/SharedMediaTypes'; import { DocServer } from '../../DocServer'; import { Networking } from '../../Network'; import { DocUtils } from '../../documents/DocUtils'; @@ -24,11 +25,11 @@ import { ImageUtils } from '../../util/Import & Export/ImageUtils'; import { SnappingManager } from '../../util/SnappingManager'; import { UndoManager } from '../../util/UndoManager'; import { ViewBoxBaseComponent } from '../DocComponent'; +import { DocumentViewProps } from '../nodes/DocumentContentsView'; +import { DocumentView } from '../nodes/DocumentView'; import { FieldViewProps } from '../nodes/FieldView'; -import { DocumentView, DocumentViewProps } from '../nodes/DocumentView'; -import { FlashcardPracticeUI } from './FlashcardPracticeUI'; import { OpenWhere, OpenWhereMod } from '../nodes/OpenWhere'; -import { Upload } from '../../../server/SharedMediaTypes'; +import { FlashcardPracticeUI } from './FlashcardPracticeUI'; export enum docSortings { Time = 'time', diff --git a/src/client/views/collections/FlashcardPracticeUI.tsx b/src/client/views/collections/FlashcardPracticeUI.tsx index 3bcdd843e..8cd9c5452 100644 --- a/src/client/views/collections/FlashcardPracticeUI.tsx +++ b/src/client/views/collections/FlashcardPracticeUI.tsx @@ -12,10 +12,11 @@ import { BoolCast, NumCast, StrCast } from '../../../fields/Types'; import { SnappingManager } from '../../util/SnappingManager'; import { Transform } from '../../util/Transform'; import { ObservableReactComponent } from '../ObservableReactComponent'; -import { DocumentView, DocumentViewProps } from '../nodes/DocumentView'; +import { DocumentView } from '../nodes/DocumentView'; import './FlashcardPracticeUI.scss'; import { StyleProp } from '../StyleProp'; import { FieldViewProps } from '../nodes/FieldView'; +import { DocumentViewProps } from '../nodes/DocumentContentsView'; export enum practiceMode { PRACTICE = 'practice', @@ -142,7 +143,6 @@ export class FlashcardPracticeUI extends ObservableReactComponent() { background={background} multiSelect={true} onPointerDown={e => script && !toggleStatus && setupMoveUpEvents(this, e, returnFalse, emptyFunction, () => script.run({ this: this.Document, value: undefined, _readOnly_: false }))} - isToggle={false} toggleStatus={toggleStatus} label={selectedItems.length === 1 ? selectedItems[0] : this.label} items={items.map(item => ({ -- cgit v1.2.3-70-g09d2