tycho-components 0.37.0 → 0.37.2

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.
@@ -1,2 +1,3 @@
1
+ import './style.scss';
1
2
  import { PageRenderViewProps } from './types';
2
- export default function PageRenderView({ elements, selectedTier, corpus, document, displayTags, showLineNumbers, highlightSentenceUid, getDisplayValue, getTokenStyle, isTokenEdited, getParticipantName, getParticipantColor, onTokenClick, }: PageRenderViewProps): import("react/jsx-runtime").JSX.Element;
3
+ export default function PageRenderView({ elements, selectedTier, corpus, displayTags, showLineNumbers, highlightSentenceUid, activeTokenKey, selectedTokenKeys, tokenSelectionKey, getDisplayValue, getTokenStyle, getTokenClassName, isTokenEdited, getParticipantName, getParticipantColor, onTokenClick, onTokenHover, onParticipantHover, wrapToken, renderTokenSuffix, }: PageRenderViewProps): import("react/jsx-runtime").JSX.Element;
@@ -1,12 +1,13 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import cx from 'classnames';
3
+ import './style.scss';
3
4
  import collapseElementsForTier from './collapseElementsForTier';
4
5
  import isTokenRefVisible, { tokenRefToToken } from './tokenUtils';
5
6
  import { PageRenderElementType, } from './types';
6
- export default function PageRenderView({ elements, selectedTier, corpus, document, displayTags = false, showLineNumbers = true, highlightSentenceUid, getDisplayValue, getTokenStyle, isTokenEdited, getParticipantName, getParticipantColor, onTokenClick, }) {
7
+ export default function PageRenderView({ elements, selectedTier, corpus, displayTags = false, showLineNumbers = true, highlightSentenceUid, activeTokenKey, selectedTokenKeys, tokenSelectionKey, getDisplayValue, getTokenStyle, getTokenClassName, isTokenEdited, getParticipantName, getParticipantColor, onTokenClick, onTokenHover, onParticipantHover, wrapToken, renderTokenSuffix, }) {
7
8
  const collapsed = collapseElementsForTier(elements, selectedTier, corpus);
8
9
  return (_jsx("div", { className: "page-render-elements", children: collapsed.map((item) => (_jsx(PageRenderElementItem, { item: item, highlight: highlightSentenceUid != null &&
9
- sentenceUidForItem(item) === highlightSentenceUid, showLineNumbers: showLineNumbers, displayTags: displayTags, getDisplayValue: getDisplayValue, getTokenStyle: getTokenStyle, isTokenEdited: isTokenEdited, getParticipantName: getParticipantName, getParticipantColor: getParticipantColor, onTokenClick: onTokenClick, document: document }, item.key))) }));
10
+ sentenceUidForItem(item) === highlightSentenceUid, showLineNumbers: showLineNumbers, displayTags: displayTags, activeTokenKey: activeTokenKey, selectedTokenKeys: selectedTokenKeys, tokenSelectionKey: tokenSelectionKey, getDisplayValue: getDisplayValue, getTokenStyle: getTokenStyle, getTokenClassName: getTokenClassName, isTokenEdited: isTokenEdited, getParticipantName: getParticipantName, getParticipantColor: getParticipantColor, onTokenClick: onTokenClick, onTokenHover: onTokenHover, onParticipantHover: onParticipantHover, wrapToken: wrapToken, renderTokenSuffix: renderTokenSuffix }, item.key))) }));
10
11
  }
11
12
  function sentenceUidForItem(item) {
12
13
  if (item.kind === 'collapsedJunction')
@@ -15,9 +16,9 @@ function sentenceUidForItem(item) {
15
16
  return item.element.token.uid;
16
17
  return undefined;
17
18
  }
18
- function PageRenderElementItem({ item, highlight, showLineNumbers, displayTags, document, getDisplayValue, getTokenStyle, isTokenEdited, getParticipantName, getParticipantColor, onTokenClick, }) {
19
+ function PageRenderElementItem({ item, highlight, showLineNumbers, displayTags, activeTokenKey, selectedTokenKeys, tokenSelectionKey, getDisplayValue, getTokenStyle, getTokenClassName, isTokenEdited, getParticipantName, getParticipantColor, onTokenClick, onTokenHover, onParticipantHover, wrapToken, renderTokenSuffix, }) {
19
20
  if (item.kind === 'collapsedJunction') {
20
- return renderToken(item.token, item.splitIdx ?? 0, true, highlight, displayTags, getDisplayValue, getTokenStyle, isTokenEdited, onTokenClick);
21
+ return (_jsx(TokenNode, { refToken: item.token, splitIdx: item.splitIdx ?? 0, isSplit: true, isCollapsedJunction: true, highlight: highlight, displayTags: displayTags, activeTokenKey: activeTokenKey, selectedTokenKeys: selectedTokenKeys, tokenSelectionKey: tokenSelectionKey, getDisplayValue: getDisplayValue, getTokenStyle: getTokenStyle, getTokenClassName: getTokenClassName, isTokenEdited: isTokenEdited, onTokenClick: onTokenClick, onTokenHover: onTokenHover, wrapToken: wrapToken, renderTokenSuffix: renderTokenSuffix }));
21
22
  }
22
23
  const { element } = item;
23
24
  switch (element.type) {
@@ -26,7 +27,7 @@ function PageRenderElementItem({ item, highlight, showLineNumbers, displayTags,
26
27
  return null;
27
28
  return (_jsx("span", { className: "participant", style: getParticipantColor
28
29
  ? { backgroundColor: getParticipantColor(element.participant) }
29
- : undefined, children: getParticipantName
30
+ : undefined, onMouseEnter: () => onParticipantHover?.(element.participant), onMouseLeave: () => onParticipantHover?.(undefined), children: getParticipantName
30
31
  ? getParticipantName(element.participant)
31
32
  : element.participant }));
32
33
  case PageRenderElementType.LINE_BREAK:
@@ -38,30 +39,54 @@ function PageRenderElementItem({ item, highlight, showLineNumbers, displayTags,
38
39
  case PageRenderElementType.MARK:
39
40
  if (!element.token)
40
41
  return null;
41
- return renderToken(element.token, 0, false, highlight, displayTags, getDisplayValue, getTokenStyle, isTokenEdited, onTokenClick, true);
42
+ return (_jsx(TokenNode, { refToken: element.token, splitIdx: 0, isMark: true, highlight: highlight, displayTags: displayTags, activeTokenKey: activeTokenKey, selectedTokenKeys: selectedTokenKeys, tokenSelectionKey: tokenSelectionKey, getDisplayValue: getDisplayValue, getTokenStyle: getTokenStyle, getTokenClassName: getTokenClassName, isTokenEdited: isTokenEdited, onTokenClick: onTokenClick, onTokenHover: onTokenHover, wrapToken: wrapToken, renderTokenSuffix: renderTokenSuffix }));
42
43
  case PageRenderElementType.JUNCTION_SPLIT:
43
44
  if (!element.token)
44
45
  return null;
45
- return renderToken(element.token, element.idx ?? 0, true, highlight, displayTags, getDisplayValue, getTokenStyle, isTokenEdited, onTokenClick);
46
+ return (_jsx(TokenNode, { refToken: element.token, splitIdx: element.idx ?? 0, isSplit: true, highlight: highlight, displayTags: displayTags, activeTokenKey: activeTokenKey, selectedTokenKeys: selectedTokenKeys, tokenSelectionKey: tokenSelectionKey, getDisplayValue: getDisplayValue, getTokenStyle: getTokenStyle, getTokenClassName: getTokenClassName, isTokenEdited: isTokenEdited, onTokenClick: onTokenClick, onTokenHover: onTokenHover, wrapToken: wrapToken, renderTokenSuffix: renderTokenSuffix }));
46
47
  case PageRenderElementType.TOKEN:
47
48
  if (!element.token)
48
49
  return null;
49
- return renderToken(element.token, 0, false, highlight, displayTags, getDisplayValue, getTokenStyle, isTokenEdited, onTokenClick);
50
+ return (_jsx(TokenNode, { refToken: element.token, splitIdx: 0, highlight: highlight, displayTags: displayTags, activeTokenKey: activeTokenKey, selectedTokenKeys: selectedTokenKeys, tokenSelectionKey: tokenSelectionKey, getDisplayValue: getDisplayValue, getTokenStyle: getTokenStyle, getTokenClassName: getTokenClassName, isTokenEdited: isTokenEdited, onTokenClick: onTokenClick, onTokenHover: onTokenHover, wrapToken: wrapToken, renderTokenSuffix: renderTokenSuffix }));
50
51
  default:
51
52
  return null;
52
53
  }
53
54
  }
54
- function renderToken(ref, splitIdx, isSplit, highlight, displayTags, getDisplayValue, getTokenStyle, isTokenEdited, onTokenClick, isMark = false) {
55
- const token = tokenRefToToken(ref);
56
- const displaySplits = token.ec && token.split && !displayTags;
57
- const visible = isMark || isTokenRefVisible(ref);
58
- const tokenClass = cx('token', {
55
+ function TokenNode({ refToken, splitIdx, isSplit = false, isMark = false, isCollapsedJunction = false, highlight, displayTags, activeTokenKey, selectedTokenKeys, tokenSelectionKey, getDisplayValue, getTokenStyle, getTokenClassName, isTokenEdited, onTokenClick, onTokenHover, wrapToken, renderTokenSuffix, }) {
56
+ const token = tokenRefToToken(refToken);
57
+ const displaySplits = Boolean(token.ec && token.split && !displayTags);
58
+ const visible = isMark || isTokenRefVisible(refToken);
59
+ const key = tokenSelectionKey?.(refToken);
60
+ const selected = (key != null && activeTokenKey === key) ||
61
+ (key != null && selectedTokenKeys?.has(key));
62
+ const ctx = {
63
+ isSplit,
64
+ isMark,
65
+ isCollapsedJunction,
66
+ splitIdx,
67
+ highlight,
68
+ selected: Boolean(selected),
69
+ };
70
+ const tokenClass = cx(isMark ? 'mark' : 'token', {
59
71
  split: isSplit,
60
- 'd-none': !visible || !!displaySplits,
61
- edited: isTokenEdited ? isTokenEdited(token) : !!ref.edited,
72
+ 'd-none': !visible || displaySplits,
73
+ edited: isTokenEdited ? isTokenEdited(token) : !!refToken.edited,
62
74
  highlight,
63
- mark: isMark,
75
+ selected: ctx.selected,
76
+ }, getTokenClassName?.(refToken, token, ctx));
77
+ const source = isMark ? 'mark' : 'word';
78
+ const clickModifiers = (event) => ({
79
+ ctrlKey: event.ctrlKey,
80
+ altKey: event.altKey,
81
+ metaKey: event.metaKey,
64
82
  });
65
- const anchorId = highlight && ref.p === 1 ? 'selected' : undefined;
66
- return (_jsxs("div", { id: anchorId, className: tokenClass, style: getTokenStyle?.(token), onClick: onTokenClick ? () => onTokenClick(ref, splitIdx) : undefined, children: [getDisplayValue(token, splitIdx), displayTags && (_jsxs("b", { className: "tag", children: ["/", token.split ? token.split.t : token.t] }))] }));
83
+ const content = (_jsxs("div", { id: highlight && refToken.p === 1 ? 'selected' : undefined, className: tokenClass, style: getTokenStyle?.(refToken, token, ctx), onClick: onTokenClick
84
+ ? (event) => onTokenClick(refToken, splitIdx, source, clickModifiers(event))
85
+ : undefined, onContextMenu: onTokenClick
86
+ ? (event) => {
87
+ event.preventDefault();
88
+ onTokenClick(refToken, splitIdx, 'sentence', clickModifiers(event));
89
+ }
90
+ : undefined, onMouseEnter: () => onTokenHover?.(refToken.uid), onMouseLeave: () => onTokenHover?.(undefined), children: [getDisplayValue(token, splitIdx), displayTags && (_jsxs("b", { className: "tag", children: ["/", token.split ? token.split.t : token.t] })), renderTokenSuffix?.(refToken, token, ctx)] }));
91
+ return (_jsx(_Fragment, { children: wrapToken ? wrapToken(refToken, token, content, ctx) : content }));
67
92
  }
@@ -1,4 +1,4 @@
1
1
  export { default as PageRenderView } from './PageRenderView';
2
- export { default as collapseElementsForTier } from './collapseElementsForTier';
2
+ export { default as collapseElementsForTier, shouldSkipJunctionContinuationElement, shouldSkipSegmentationElement, shouldSkipSegmentationToken, findSegmentationGroupBounds, isTokenBearingCollapsed, } from './collapseElementsForTier';
3
3
  export { tokenRefToToken, default as isTokenRefVisible } from './tokenUtils';
4
4
  export * from './types';
@@ -1,4 +1,4 @@
1
1
  export { default as PageRenderView } from './PageRenderView';
2
- export { default as collapseElementsForTier } from './collapseElementsForTier';
2
+ export { default as collapseElementsForTier, shouldSkipJunctionContinuationElement, shouldSkipSegmentationElement, shouldSkipSegmentationToken, findSegmentationGroupBounds, isTokenBearingCollapsed, } from './collapseElementsForTier';
3
3
  export { tokenRefToToken, default as isTokenRefVisible } from './tokenUtils';
4
4
  export * from './types';
@@ -0,0 +1,109 @@
1
+ .page-render-elements {
2
+ display: flex;
3
+ flex-flow: wrap;
4
+
5
+ .line-break {
6
+ width: 100%;
7
+ margin: 2px 0;
8
+ background-color: transparent;
9
+ border: none;
10
+
11
+ + .line-break {
12
+ margin: var(--spacing-100) 0;
13
+ }
14
+ }
15
+
16
+ .line-break-number {
17
+ position: relative;
18
+ left: calc(-1 * var(--spacing-150));
19
+ top: var(--spacing-075);
20
+ font-size: 0.7em;
21
+ }
22
+
23
+ .mark {
24
+ font-family: 'Georgia', serif;
25
+ cursor: pointer;
26
+ @include body-xmedium-1;
27
+ display: inline-flex;
28
+ height: var(--spacing-300);
29
+ padding: 0 var(--spacing-050);
30
+ margin-bottom: var(--spacing-050);
31
+ width: auto;
32
+ background-color: var(--layer-semantic-warning);
33
+ line-height: var(--spacing-300);
34
+
35
+ &.selected {
36
+ background-color: var(--layer-semantic-danger);
37
+ color: var(--text-primary);
38
+ }
39
+ }
40
+
41
+ .token {
42
+ font-family: 'Georgia', serif;
43
+ cursor: pointer;
44
+ @include body-xmedium-1;
45
+ display: inline-flex;
46
+ align-items: center;
47
+ height: var(--spacing-300);
48
+ line-height: var(--spacing-300);
49
+ min-height: 0;
50
+ padding: 0 var(--spacing-050);
51
+ margin-bottom: var(--spacing-050);
52
+ width: auto;
53
+
54
+ sup {
55
+ font-size: var(--spacing-150);
56
+ line-height: 0;
57
+ vertical-align: super;
58
+ margin-bottom: var(--spacing-100);
59
+ }
60
+
61
+ &.highlight {
62
+ background-color: var(--layer-semantic-warning);
63
+ }
64
+
65
+ &.edited {
66
+ border-bottom: 1px dashed var(--text-on-color-accent);
67
+ }
68
+
69
+ &.review {
70
+ background-color: color-mix(
71
+ in srgb,
72
+ var(--semantic-danger-70) 50%,
73
+ transparent
74
+ );
75
+ }
76
+
77
+ &.inconsistency {
78
+ border-bottom: 2px dashed var(--semantic-danger-70);
79
+ }
80
+
81
+ &.ignore {
82
+ opacity: 0.6;
83
+ }
84
+
85
+ &.comment {
86
+ border-bottom: 2px dashed var(--semantic-success-60);
87
+ }
88
+
89
+ &.selected {
90
+ background-color: var(--layer-semantic-danger);
91
+ color: var(--text-primary);
92
+ }
93
+
94
+ &.participant {
95
+ border-bottom-width: 1px;
96
+ border-bottom-style: solid;
97
+ }
98
+ }
99
+
100
+ .participant {
101
+ margin-right: var(--spacing-100);
102
+ border-radius: var(--radius-200);
103
+ padding: 0 var(--spacing-100);
104
+ background-color: var(--layer-hover-2);
105
+ border: 1px dashed var(--text-placeholder);
106
+ cursor: pointer;
107
+ height: var(--spacing-300);
108
+ }
109
+ }
@@ -1,4 +1,4 @@
1
- import type { ReactNode } from 'react';
1
+ import type { CSSProperties, ReactNode } from 'react';
2
2
  import type { Corpus } from '../../configs/types/Corpus';
3
3
  import type Document from '../../configs/types/Document';
4
4
  import type { Edition, Format, Split, Token } from '../../configs/types/Struct';
@@ -45,6 +45,20 @@ export type CollapsedPageRenderElement = {
45
45
  splitIdx?: number;
46
46
  key: string;
47
47
  };
48
+ export type TokenClickSource = 'word' | 'sentence' | 'mark';
49
+ export type TokenClickModifiers = {
50
+ ctrlKey: boolean;
51
+ altKey: boolean;
52
+ metaKey: boolean;
53
+ };
54
+ export type PageRenderTokenContext = {
55
+ isSplit: boolean;
56
+ isMark: boolean;
57
+ isCollapsedJunction: boolean;
58
+ splitIdx: number;
59
+ highlight: boolean;
60
+ selected: boolean;
61
+ };
48
62
  export type PageRenderViewProps = {
49
63
  elements: PageRenderElement[];
50
64
  selectedTier: string;
@@ -53,10 +67,18 @@ export type PageRenderViewProps = {
53
67
  displayTags?: boolean;
54
68
  showLineNumbers?: boolean;
55
69
  highlightSentenceUid?: string;
70
+ activeTokenKey?: string;
71
+ selectedTokenKeys?: Set<string>;
72
+ tokenSelectionKey?: (ref: TokenRef) => string;
56
73
  getDisplayValue: (token: Token, splitIdx?: number) => ReactNode;
57
- getTokenStyle?: (token: Token) => React.CSSProperties;
74
+ getTokenStyle?: (ref: TokenRef, token: Token, ctx: PageRenderTokenContext) => CSSProperties | undefined;
75
+ getTokenClassName?: (ref: TokenRef, token: Token, ctx: PageRenderTokenContext) => string | undefined;
58
76
  isTokenEdited?: (token: Token) => boolean;
59
77
  getParticipantName?: (code: string) => string;
60
- getParticipantColor?: (code: string) => string;
61
- onTokenClick?: (ref: TokenRef, splitIdx?: number) => void;
78
+ getParticipantColor?: (code: string) => string | undefined;
79
+ onTokenClick?: (ref: TokenRef, splitIdx: number | undefined, source: TokenClickSource, modifiers: TokenClickModifiers) => void;
80
+ onTokenHover?: (sentenceUid: string | undefined) => void;
81
+ onParticipantHover?: (code: string | undefined) => void;
82
+ wrapToken?: (ref: TokenRef, token: Token, content: ReactNode, ctx: PageRenderTokenContext) => ReactNode;
83
+ renderTokenSuffix?: (ref: TokenRef, token: Token, ctx: PageRenderTokenContext) => ReactNode;
62
84
  };
@@ -13,5 +13,5 @@ export type { SearchCriteria } from "./TreeView/TreeViewSearch/TreeViewSearch";
13
13
  export { default as CytoscapeMenuCanvas } from "./CytoscapeMenu/CytoscapeMenuCanvas";
14
14
  export { registerCytoscapeContextMenus, contextMenus } from "./CytoscapeMenu";
15
15
  export type { CytoscapeContextMenuOptions, MenuItemOption, ContextMenusInstance, } from "./CytoscapeMenu";
16
- export { PageRenderView, collapseElementsForTier, tokenRefToToken, isTokenRefVisible, } from "./PageRender";
17
- export type { PageRenderElement, PageRenderElementType, PageRenderViewProps, TokenRef, CollapsedPageRenderElement, } from "./PageRender";
16
+ export { PageRenderView, collapseElementsForTier, shouldSkipJunctionContinuationElement, shouldSkipSegmentationElement, shouldSkipSegmentationToken, findSegmentationGroupBounds, isTokenBearingCollapsed, tokenRefToToken, isTokenRefVisible, } from "./PageRender";
17
+ export type { PageRenderElement, PageRenderElementType, PageRenderViewProps, PageRenderTokenContext, TokenRef, CollapsedPageRenderElement, TokenClickSource, TokenClickModifiers, } from "./PageRender";
@@ -9,4 +9,4 @@ export { default as SyntreesCytoscape } from "./TreeView/cytoscape/SyntreesCytos
9
9
  export { default as TreeViewSearch } from "./TreeView/TreeViewSearch/TreeViewSearch";
10
10
  export { default as CytoscapeMenuCanvas } from "./CytoscapeMenu/CytoscapeMenuCanvas";
11
11
  export { registerCytoscapeContextMenus, contextMenus } from "./CytoscapeMenu";
12
- export { PageRenderView, collapseElementsForTier, tokenRefToToken, isTokenRefVisible, } from "./PageRender";
12
+ export { PageRenderView, collapseElementsForTier, shouldSkipJunctionContinuationElement, shouldSkipSegmentationElement, shouldSkipSegmentationToken, findSegmentationGroupBounds, isTokenBearingCollapsed, tokenRefToToken, isTokenRefVisible, } from "./PageRender";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "tycho-components",
3
3
  "private": false,
4
- "version": "0.37.0",
4
+ "version": "0.37.2",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "exports": {