@dxos/plugin-navtree 0.8.1-staging.391c573 → 0.8.1-staging.9eaf14f
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/browser/{app-graph-builder-BL7LRXCM.mjs → app-graph-builder-26D3MUCA.mjs} +2 -2
- package/dist/lib/browser/{chunk-AOAGODQB.mjs → chunk-4RQJXI4D.mjs} +2 -2
- package/dist/lib/browser/{chunk-GXNOX2XZ.mjs → chunk-DN43QXSX.mjs} +147 -187
- package/dist/lib/browser/chunk-DN43QXSX.mjs.map +7 -0
- package/dist/lib/browser/{chunk-KOXMEAOS.mjs → chunk-IEW3JD5C.mjs} +3 -2
- package/dist/lib/browser/{chunk-KOXMEAOS.mjs.map → chunk-IEW3JD5C.mjs.map} +3 -3
- package/dist/lib/browser/index.mjs +3 -5
- package/dist/lib/browser/index.mjs.map +2 -2
- package/dist/lib/browser/{intent-resolver-U25VBFH3.mjs → intent-resolver-BZMUS24C.mjs} +3 -3
- package/dist/lib/browser/{keyboard-MUBRTPI5.mjs → keyboard-IQXHKUWM.mjs} +2 -2
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/{react-surface-SG4QBA2U.mjs → react-surface-3HCM3SHJ.mjs} +5 -11
- package/dist/lib/browser/react-surface-3HCM3SHJ.mjs.map +7 -0
- package/dist/lib/browser/{state-IEFQTUPG.mjs → state-M5UJ3MHL.mjs} +3 -3
- package/dist/types/src/NavTreePlugin.d.ts.map +1 -1
- package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
- package/dist/types/src/components/L0Menu.d.ts +2 -1
- package/dist/types/src/components/L0Menu.d.ts.map +1 -1
- package/dist/types/src/components/L1Panels.d.ts.map +1 -1
- package/dist/types/src/components/NavTree.d.ts.map +1 -1
- package/dist/types/src/components/NavTreeContainer.d.ts.map +1 -1
- package/dist/types/src/components/UserAccountAvatar.d.ts +11 -0
- package/dist/types/src/components/UserAccountAvatar.d.ts.map +1 -0
- package/dist/types/src/components/{HaloButton.stories.d.ts → UserAccountAvatar.stories.d.ts} +3 -3
- package/dist/types/src/components/UserAccountAvatar.stories.d.ts.map +1 -0
- package/dist/types/src/components/index.d.ts +0 -1
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/meta.d.ts +2 -3
- package/dist/types/src/meta.d.ts.map +1 -1
- package/dist/types/src/testing/generator.d.ts +3 -3
- package/dist/types/src/testing/generator.d.ts.map +1 -1
- package/dist/types/src/util.d.ts +0 -8
- package/dist/types/src/util.d.ts.map +1 -1
- package/package.json +31 -30
- package/src/NavTreePlugin.tsx +0 -1
- package/src/capabilities/react-surface.tsx +1 -12
- package/src/components/L0Menu.tsx +46 -32
- package/src/components/L1Panels.tsx +15 -19
- package/src/components/NavTree.tsx +12 -2
- package/src/components/NavTreeContainer.tsx +11 -5
- package/src/components/NavTreeItemColumns.tsx +3 -3
- package/src/components/UserAccountAvatar.stories.tsx +21 -0
- package/src/components/UserAccountAvatar.tsx +35 -0
- package/src/components/index.ts +0 -1
- package/src/meta.ts +3 -2
- package/src/testing/generator.ts +3 -3
- package/src/util.ts +1 -42
- package/dist/lib/browser/chunk-GXNOX2XZ.mjs.map +0 -7
- package/dist/lib/browser/react-surface-SG4QBA2U.mjs.map +0 -7
- package/dist/types/src/components/HaloButton.d.ts +0 -12
- package/dist/types/src/components/HaloButton.d.ts.map +0 -1
- package/dist/types/src/components/HaloButton.stories.d.ts.map +0 -1
- package/dist/types/src/components/NotchStart.d.ts +0 -3
- package/dist/types/src/components/NotchStart.d.ts.map +0 -1
- package/src/components/HaloButton.stories.tsx +0 -21
- package/src/components/HaloButton.tsx +0 -41
- package/src/components/NotchStart.tsx +0 -30
- /package/dist/lib/browser/{app-graph-builder-BL7LRXCM.mjs.map → app-graph-builder-26D3MUCA.mjs.map} +0 -0
- /package/dist/lib/browser/{chunk-AOAGODQB.mjs.map → chunk-4RQJXI4D.mjs.map} +0 -0
- /package/dist/lib/browser/{intent-resolver-U25VBFH3.mjs.map → intent-resolver-BZMUS24C.mjs.map} +0 -0
- /package/dist/lib/browser/{keyboard-MUBRTPI5.mjs.map → keyboard-IQXHKUWM.mjs.map} +0 -0
- /package/dist/lib/browser/{state-IEFQTUPG.mjs.map → state-M5UJ3MHL.mjs.map} +0 -0
|
@@ -30,13 +30,13 @@ import {
|
|
|
30
30
|
import type { StackItemRearrangeHandler } from '@dxos/react-ui-stack';
|
|
31
31
|
import { Tabs } from '@dxos/react-ui-tabs';
|
|
32
32
|
import { mx } from '@dxos/react-ui-theme';
|
|
33
|
-
import { arrayMove } from '@dxos/util';
|
|
33
|
+
import { arrayMove, getFirstTwoRenderableChars } from '@dxos/util';
|
|
34
34
|
|
|
35
35
|
import { useNavTreeContext } from './NavTreeContext';
|
|
36
|
-
import {
|
|
36
|
+
import { UserAccountAvatar } from './UserAccountAvatar';
|
|
37
37
|
import { useLoadDescendents } from '../hooks';
|
|
38
38
|
import { NAVTREE_PLUGIN } from '../meta';
|
|
39
|
-
import {
|
|
39
|
+
import { l0ItemType } from '../util';
|
|
40
40
|
|
|
41
41
|
type L0ItemData = { id: L0ItemProps['item']['id']; type: 'l0Item' };
|
|
42
42
|
|
|
@@ -45,6 +45,7 @@ type L0ItemProps = {
|
|
|
45
45
|
parent?: Node<any>;
|
|
46
46
|
path: string[];
|
|
47
47
|
pinned?: boolean;
|
|
48
|
+
userAccount?: boolean;
|
|
48
49
|
onRearrange?: StackItemRearrangeHandler<L0ItemData>;
|
|
49
50
|
};
|
|
50
51
|
|
|
@@ -95,7 +96,7 @@ const l0Breakpoints: Record<string, string> = {
|
|
|
95
96
|
lg: 'hidden lg:grid',
|
|
96
97
|
};
|
|
97
98
|
|
|
98
|
-
const L0Item = ({ item, parent, path, pinned, onRearrange }: L0ItemProps) => {
|
|
99
|
+
const L0Item = ({ item, parent, path, pinned, userAccount, onRearrange }: L0ItemProps) => {
|
|
99
100
|
const { t } = useTranslation(NAVTREE_PLUGIN);
|
|
100
101
|
const itemElement = useRef<HTMLElement | null>(null);
|
|
101
102
|
const [closestEdge, setEdge] = useState<Edge | null>(null);
|
|
@@ -184,31 +185,40 @@ const L0Item = ({ item, parent, path, pinned, onRearrange }: L0ItemProps) => {
|
|
|
184
185
|
)}
|
|
185
186
|
ref={itemElement}
|
|
186
187
|
>
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
188
|
+
{userAccount ? (
|
|
189
|
+
<UserAccountAvatar
|
|
190
|
+
userId={item.properties.userId}
|
|
191
|
+
hue={item.properties.hue}
|
|
192
|
+
emoji={item.properties.emoji}
|
|
193
|
+
status={item.properties.status}
|
|
194
|
+
/>
|
|
195
|
+
) : (
|
|
196
|
+
<div
|
|
197
|
+
role='none'
|
|
198
|
+
data-frame={true}
|
|
199
|
+
className={mx(
|
|
200
|
+
'absolute grid dx-focus-ring-group-indicator transition-colors',
|
|
201
|
+
type === 'tab' || pinned ? 'rounded' : 'rounded-full',
|
|
202
|
+
pinned
|
|
203
|
+
? 'bg-transparent group-hover/l0i:bg-groupSurface inset-inline-3 inset-block-0.5'
|
|
204
|
+
: 'bg-groupSurface inset-inline-3 inset-block-2',
|
|
205
|
+
)}
|
|
206
|
+
{...(hue && { style: { background: `var(--dx-${hue}Surface)` } })}
|
|
207
|
+
>
|
|
208
|
+
{(item.properties.icon && (
|
|
209
|
+
<Icon icon={item.properties.icon} size={pinned ? 5 : 7} classNames='place-self-center' {...hueFgStyle} />
|
|
210
|
+
)) ||
|
|
211
|
+
(type === 'tab' && item.properties.disposition !== 'pin-end' ? (
|
|
212
|
+
<span role='img' className='place-self-center text-3xl font-light' {...hueFgStyle}>
|
|
213
|
+
{avatarValue}
|
|
214
|
+
</span>
|
|
215
|
+
) : (
|
|
216
|
+
item.properties.icon && (
|
|
217
|
+
<Icon icon='ph--planet--regular' size={pinned ? 5 : 7} classNames='place-self-center' {...hueFgStyle} />
|
|
218
|
+
)
|
|
219
|
+
))}
|
|
220
|
+
</div>
|
|
221
|
+
)}
|
|
212
222
|
<div
|
|
213
223
|
role='none'
|
|
214
224
|
className='hidden group-aria-selected/l0i:block absolute inline-start-0 inset-block-4 is-1 bg-accentSurface rounded-ie'
|
|
@@ -280,11 +290,13 @@ const L0Collection = ({ item, path, parent }: L0ItemProps) => {
|
|
|
280
290
|
export const L0Menu = ({
|
|
281
291
|
topLevelItems,
|
|
282
292
|
pinnedItems,
|
|
293
|
+
userAccountItem,
|
|
283
294
|
parent,
|
|
284
295
|
path,
|
|
285
296
|
}: {
|
|
286
297
|
topLevelItems: Node<any>[];
|
|
287
298
|
pinnedItems: Node<any>[];
|
|
299
|
+
userAccountItem: Node<any>;
|
|
288
300
|
parent?: Node<any>;
|
|
289
301
|
path: string[];
|
|
290
302
|
}) => {
|
|
@@ -316,9 +328,11 @@ export const L0Menu = ({
|
|
|
316
328
|
<L0Item key={item.id} item={item} parent={parent} path={path} pinned />
|
|
317
329
|
))}
|
|
318
330
|
</div>
|
|
319
|
-
|
|
320
|
-
<
|
|
321
|
-
|
|
331
|
+
{userAccountItem && (
|
|
332
|
+
<div role='none' className='grid py-2 app-no-drag'>
|
|
333
|
+
<L0Item key={userAccountItem.id} item={userAccountItem} parent={parent} path={path} userAccount />
|
|
334
|
+
</div>
|
|
335
|
+
)}
|
|
322
336
|
<div
|
|
323
337
|
role='none'
|
|
324
338
|
className='hidden [body[data-platform="darwin"]_&]:block absolute block-start-0 is-[calc(var(--l0-size)-1px)] bs-[calc(40px+0.25rem)]'
|
|
@@ -6,7 +6,7 @@ import React, { useMemo } from 'react';
|
|
|
6
6
|
|
|
7
7
|
import { useLayout } from '@dxos/app-framework';
|
|
8
8
|
import { type Node } from '@dxos/app-graph';
|
|
9
|
-
import {
|
|
9
|
+
import { Button, Icon, toLocalizedString, useTranslation } from '@dxos/react-ui';
|
|
10
10
|
import { Tree } from '@dxos/react-ui-list';
|
|
11
11
|
import { Tabs } from '@dxos/react-ui-tabs';
|
|
12
12
|
import { hoverableControlItem, hoverableOpenControlItem, mx } from '@dxos/react-ui-theme';
|
|
@@ -36,24 +36,20 @@ const L1Panel = ({ item, path, currentItemId, onBack }: L1PanelProps) => {
|
|
|
36
36
|
>
|
|
37
37
|
{item.id === currentItemId && (
|
|
38
38
|
<>
|
|
39
|
-
<h2 className='flex items-center border-be border-separator
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
)}
|
|
54
|
-
onClick={onBack}
|
|
55
|
-
/>
|
|
56
|
-
)}
|
|
39
|
+
<h2 className='flex items-center border-be border-separator app-drag'>
|
|
40
|
+
<Button
|
|
41
|
+
variant='ghost'
|
|
42
|
+
density='fine'
|
|
43
|
+
classNames={mx(
|
|
44
|
+
'is-6 pli-0 dx-focus-ring-inset',
|
|
45
|
+
!item.id.startsWith('!') && 'invisible',
|
|
46
|
+
hoverableControlItem,
|
|
47
|
+
hoverableOpenControlItem,
|
|
48
|
+
)}
|
|
49
|
+
onClick={onBack}
|
|
50
|
+
>
|
|
51
|
+
<Icon icon='ph--caret-left--regular' size={3} />
|
|
52
|
+
</Button>
|
|
57
53
|
<span className='flex-1 truncate cursor-default'>{toLocalizedString(item.properties.label, t)}</span>
|
|
58
54
|
<NavTreeItemColumns path={path} item={item} open />
|
|
59
55
|
</h2>
|
|
@@ -26,7 +26,11 @@ export const NavTree = ({ id, root }: NavTreeProps) => {
|
|
|
26
26
|
[topLevelActions, topLevelCollections, topLevelWorkspaces, topLevelNavigation],
|
|
27
27
|
);
|
|
28
28
|
const pinnedItems = getItems(root, 'pin-end').toSorted((a, b) => byPosition(a.properties, b.properties));
|
|
29
|
-
const
|
|
29
|
+
const userAccountItem = getItems(root, 'user-account')[0];
|
|
30
|
+
const topLevelItems = useMemo(
|
|
31
|
+
() => [...l0Items, ...pinnedItems, userAccountItem],
|
|
32
|
+
[l0Items, pinnedItems, userAccountItem],
|
|
33
|
+
);
|
|
30
34
|
|
|
31
35
|
useLoadDescendents(root);
|
|
32
36
|
const path = useMemo(() => [id], [id]);
|
|
@@ -34,7 +38,13 @@ export const NavTree = ({ id, root }: NavTreeProps) => {
|
|
|
34
38
|
return (
|
|
35
39
|
// NOTE(thure): 74px (rather than rem) is intentional in order to match the size of macOS windowing controls
|
|
36
40
|
<Tabs.Root value={tab} orientation='vertical' verticalVariant='stateless' classNames='relative'>
|
|
37
|
-
<L0Menu
|
|
41
|
+
<L0Menu
|
|
42
|
+
topLevelItems={l0Items}
|
|
43
|
+
pinnedItems={pinnedItems}
|
|
44
|
+
userAccountItem={userAccountItem}
|
|
45
|
+
path={path}
|
|
46
|
+
parent={root}
|
|
47
|
+
/>
|
|
38
48
|
<L1Panels topLevelItems={topLevelItems} path={path} currentItemId={tab} onBack={onBack} />
|
|
39
49
|
</Tabs.Root>
|
|
40
50
|
);
|
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
useLayout,
|
|
18
18
|
} from '@dxos/app-framework';
|
|
19
19
|
import { isAction, isActionLike, type Node } from '@dxos/app-graph';
|
|
20
|
+
import { PLANK_COMPANION_TYPE } from '@dxos/plugin-deck/types';
|
|
20
21
|
import { isEchoObject, isSpace } from '@dxos/react-client/echo';
|
|
21
22
|
import { useMediaQuery } from '@dxos/react-ui';
|
|
22
23
|
import { isTreeData, type TreeData, type PropsFromTreeItem } from '@dxos/react-ui-list';
|
|
@@ -45,6 +46,9 @@ const renderItemEnd = ({ node, open }: { node: Node; open: boolean }) => (
|
|
|
45
46
|
<Surface role='navtree-item-end' data={{ id: node.id, subject: node.data, open }} limit={1} />
|
|
46
47
|
);
|
|
47
48
|
|
|
49
|
+
const getChildrenFilter = (node: Node): node is Node =>
|
|
50
|
+
untracked(() => !isActionLike(node) && node.type !== PLANK_COMPANION_TYPE);
|
|
51
|
+
|
|
48
52
|
export type NavTreeContainerProps = {
|
|
49
53
|
popoverAnchorId?: string;
|
|
50
54
|
topbar?: boolean;
|
|
@@ -64,12 +68,14 @@ export const NavTreeContainer = memo(({ tab, popoverAnchorId, topbar }: NavTreeC
|
|
|
64
68
|
return graph.nodes(node ?? graph.root, {
|
|
65
69
|
filter: (node): node is Node => {
|
|
66
70
|
return untracked(() => {
|
|
67
|
-
|
|
68
|
-
|
|
71
|
+
if (node.properties.disposition === 'hidden') {
|
|
72
|
+
return false;
|
|
73
|
+
} else if (!disposition) {
|
|
74
|
+
const action = isAction(node);
|
|
69
75
|
return !action || node.properties.disposition === 'item';
|
|
76
|
+
} else {
|
|
77
|
+
return node.properties.disposition === disposition;
|
|
70
78
|
}
|
|
71
|
-
|
|
72
|
-
return node.properties.disposition === disposition;
|
|
73
79
|
});
|
|
74
80
|
},
|
|
75
81
|
});
|
|
@@ -79,7 +85,7 @@ export const NavTreeContainer = memo(({ tab, popoverAnchorId, topbar }: NavTreeC
|
|
|
79
85
|
|
|
80
86
|
const getProps = useCallback(
|
|
81
87
|
(node: Node, path: string[]): PropsFromTreeItem => {
|
|
82
|
-
const children = getChildren(graph, node,
|
|
88
|
+
const children = getChildren(graph, node, getChildrenFilter, path);
|
|
83
89
|
const parentOf =
|
|
84
90
|
children.length > 0 ? children.map(({ id }) => id) : node.properties.role === 'branch' ? [] : undefined;
|
|
85
91
|
return {
|
|
@@ -22,10 +22,10 @@ export const NavTreeItemColumns = memo(({ path, item, open }: NavTreeItemColumns
|
|
|
22
22
|
|
|
23
23
|
const { actions: _actions, groupedActions } = getActions(item);
|
|
24
24
|
const [primaryAction, ...secondaryActions] = _actions.toSorted((a, b) =>
|
|
25
|
-
a.properties?.disposition === '
|
|
25
|
+
a.properties?.disposition === 'list-item-primary' ? -1 : 1,
|
|
26
26
|
);
|
|
27
27
|
|
|
28
|
-
const actions = (primaryAction?.properties?.disposition === '
|
|
28
|
+
const actions = (primaryAction?.properties?.disposition === 'list-item-primary' ? secondaryActions : _actions)
|
|
29
29
|
.flatMap((action) => (isAction(action) ? [action] : []))
|
|
30
30
|
.filter((action) => !action.properties?.hidden);
|
|
31
31
|
|
|
@@ -36,7 +36,7 @@ export const NavTreeItemColumns = memo(({ path, item, open }: NavTreeItemColumns
|
|
|
36
36
|
|
|
37
37
|
return (
|
|
38
38
|
<div role='none' className='contents app-no-drag'>
|
|
39
|
-
{primaryAction?.properties?.disposition === '
|
|
39
|
+
{primaryAction?.properties?.disposition === 'list-item-primary' && !primaryAction?.properties?.disabled ? (
|
|
40
40
|
<NavTreeItemAction
|
|
41
41
|
testId={primaryAction.properties?.testId}
|
|
42
42
|
label={toLocalizedString(primaryAction.properties?.label, t)}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2023 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import '@dxos-theme';
|
|
6
|
+
|
|
7
|
+
import { type Meta } from '@storybook/react';
|
|
8
|
+
import React from 'react';
|
|
9
|
+
|
|
10
|
+
import { UserAccountAvatar } from './UserAccountAvatar';
|
|
11
|
+
|
|
12
|
+
export const Default = (props: any) => {
|
|
13
|
+
return <UserAccountAvatar {...props} />;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const meta: Meta<typeof UserAccountAvatar> = {
|
|
17
|
+
title: 'plugins/plugin-navtree/UserAccountAvatar',
|
|
18
|
+
component: UserAccountAvatar,
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export default meta;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2023 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import React from 'react';
|
|
6
|
+
|
|
7
|
+
import { Avatar, type AvatarStatus, type Size } from '@dxos/react-ui';
|
|
8
|
+
import { hexToFallback } from '@dxos/util';
|
|
9
|
+
|
|
10
|
+
export type UserAccountAvatarProps = {
|
|
11
|
+
size?: Size;
|
|
12
|
+
userId?: string;
|
|
13
|
+
hue?: string;
|
|
14
|
+
emoji?: string;
|
|
15
|
+
status?: AvatarStatus;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export const UserAccountAvatar = (props: UserAccountAvatarProps) => {
|
|
19
|
+
const fallbackValue = hexToFallback(props.userId ?? '0');
|
|
20
|
+
|
|
21
|
+
return (
|
|
22
|
+
<div className='grid place-items-center' data-joyride='welcome/account'>
|
|
23
|
+
<Avatar.Root>
|
|
24
|
+
<Avatar.Content
|
|
25
|
+
variant='circle'
|
|
26
|
+
size={props.size ?? 12}
|
|
27
|
+
status={props.status ?? 'active'}
|
|
28
|
+
hue={props.hue || fallbackValue.hue}
|
|
29
|
+
fallback={props.emoji || fallbackValue.emoji}
|
|
30
|
+
data-testid='treeview.userAccount'
|
|
31
|
+
/>
|
|
32
|
+
</Avatar.Root>
|
|
33
|
+
</div>
|
|
34
|
+
);
|
|
35
|
+
};
|
package/src/components/index.ts
CHANGED
package/src/meta.ts
CHANGED
|
@@ -11,6 +11,7 @@ export const KEY_BINDING = 'KeyBinding';
|
|
|
11
11
|
// TODO(wittjosiah): Factor out.
|
|
12
12
|
export const COMMANDS_DIALOG = `${NAVTREE_PLUGIN}/CommandsDialog`;
|
|
13
13
|
|
|
14
|
-
export const meta = {
|
|
14
|
+
export const meta: PluginMeta = {
|
|
15
15
|
id: NAVTREE_PLUGIN,
|
|
16
|
-
|
|
16
|
+
name: 'Navtree',
|
|
17
|
+
};
|
package/src/testing/generator.ts
CHANGED
|
@@ -15,12 +15,12 @@ import { range } from '@dxos/util';
|
|
|
15
15
|
export type TestItem = { id: string; type: string } & Record<string, any>;
|
|
16
16
|
|
|
17
17
|
type ObjectDataGenerator = {
|
|
18
|
-
createSchema?: () => S.Schema
|
|
18
|
+
createSchema?: () => S.Schema.AnyNoContext;
|
|
19
19
|
createData: () => any;
|
|
20
20
|
};
|
|
21
21
|
|
|
22
22
|
type ObjectFactory<T extends ReactiveObject<any>> = {
|
|
23
|
-
schema?: S.Schema
|
|
23
|
+
schema?: S.Schema.AnyNoContext; // TODO(burdon): Support both typed and expando schema.
|
|
24
24
|
createObject: () => T;
|
|
25
25
|
};
|
|
26
26
|
|
|
@@ -87,7 +87,7 @@ export class TestObjectGenerator {
|
|
|
87
87
|
}, {});
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
-
get schema(): S.Schema
|
|
90
|
+
get schema(): S.Schema.AnyNoContext[] {
|
|
91
91
|
return Object.values(this.factories).map((f) => f.schema!);
|
|
92
92
|
}
|
|
93
93
|
|
package/src/util.ts
CHANGED
|
@@ -75,7 +75,7 @@ export const sortActions = (actions: Action[]): Action[] =>
|
|
|
75
75
|
return 0;
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
-
if (a.properties.disposition === '
|
|
78
|
+
if (a.properties.disposition === 'list-item-primary') {
|
|
79
79
|
return -1;
|
|
80
80
|
}
|
|
81
81
|
|
|
@@ -139,44 +139,3 @@ export const l0ItemType = (item: Node<any>) => {
|
|
|
139
139
|
return 'tab';
|
|
140
140
|
}
|
|
141
141
|
};
|
|
142
|
-
|
|
143
|
-
// Regular expression to match renderable characters
|
|
144
|
-
// Excludes control characters, combining marks, and other non-renderable characters
|
|
145
|
-
const renderableCharRegex =
|
|
146
|
-
/^(?![\p{Control}\p{Mark}\p{Separator}\p{Surrogate}\p{Unassigned}])[\p{L}\p{N}\p{P}\p{S}\p{Emoji}]$/u;
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* Returns the first two renderable characters from a string that are separated by non-word characters.
|
|
150
|
-
* Handles Unicode characters correctly.
|
|
151
|
-
*
|
|
152
|
-
* @param {string} label - The input string to process
|
|
153
|
-
* @returns {[string, string]} Array containing the two characters, or empty strings if not found
|
|
154
|
-
*/
|
|
155
|
-
export const getFirstTwoRenderableChars = (label: string) => {
|
|
156
|
-
// Convert string to array of Unicode characters
|
|
157
|
-
const characters = Array.from(label);
|
|
158
|
-
|
|
159
|
-
// Keep track of found renderable characters
|
|
160
|
-
const result = ['', ''];
|
|
161
|
-
let foundFirst = false;
|
|
162
|
-
|
|
163
|
-
for (let i = 0; i < characters.length; i++) {
|
|
164
|
-
const char = characters[i];
|
|
165
|
-
|
|
166
|
-
if (renderableCharRegex.test(char)) {
|
|
167
|
-
if (!foundFirst) {
|
|
168
|
-
result[0] = char;
|
|
169
|
-
foundFirst = true;
|
|
170
|
-
} else {
|
|
171
|
-
// Check if there's at least one non-word character between the first and current char
|
|
172
|
-
const textBetween = characters.slice(result[0].length, i).join('');
|
|
173
|
-
if (/[^\p{L}\p{N}_]/u.test(textBetween)) {
|
|
174
|
-
result[1] = char;
|
|
175
|
-
break;
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
return result;
|
|
182
|
-
};
|