Skip to content

Commit fabc840

Browse files
authored
Merge pull request #13 from yWorks/dev
2.0.0
2 parents f305101 + ecf6147 commit fabc840

File tree

8 files changed

+88
-20
lines changed

8 files changed

+88
-20
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@yworks/react-yfiles-core",
3-
"version": "2.0.0-beta.1",
3+
"version": "2.0.0",
44
"author": {
55
"name": "yFiles for HTML team @ yWorks GmbH",
66
"email": "[email protected]"

src/controls/Controls.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,13 +87,13 @@ export interface ControlsProps {
8787
* This component must be used inside a parent component that displays the graph, or its corresponding provider.
8888
*
8989
* ```tsx
90-
* function OrganizationChart() {
90+
* function App() {
9191
* const button1 = { action: () => alert('Button 1 clicked!'), icon: <div>Button 1</div> }
9292
* const button2 = { action: () => alert('Button 2 clicked!'), icon: <div>Button 2</div> }
9393
* return (
94-
* <OrgChart data={data}>
94+
* <MyReactYFilesComponent data={data}>
9595
* <Controls buttons={() => [button1, button2]}></Controls>
96-
* </OrgChart>
96+
* </MyReactYFilesComponent>
9797
* )
9898
* }
9999
* ```

src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,4 @@ export {
2525
type ExportSettings
2626
} from './utils/ExportSupport.ts'
2727
export { registerWebWorker } from './utils/WebworkerSupport.ts'
28+
export * from './utils/CheckStylesheetLoaded.ts'

src/license/registerLicense.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { DefaultGraph, License } from 'yfiles'
22
import { setWebWorkerLicense } from '../utils/WebworkerSupport.ts'
3+
import { isProd } from '../utils/DevMode.ts'
34

45
/**
56
* Registers the [yFiles license]{@link http://docs.yworks.com/yfileshtml/#/dguide/licensing} which is needed to
@@ -10,7 +11,7 @@ import { setWebWorkerLicense } from '../utils/WebworkerSupport.ts'
1011
* registerLicense(yFilesLicense)
1112
*
1213
* return (
13-
* <OrgChart data={data}></OrgChart>
14+
* <MyReactYFilesComponent data={data}></MyReactYFilesComponent>
1415
* )
1516
* }
1617
* ```
@@ -26,7 +27,11 @@ export function registerLicense(licenseKey: Record<string, unknown>) {
2627
* Checks whether there is a valid yfiles license registered.
2728
*/
2829
export function checkLicense(): boolean {
29-
const g = new DefaultGraph()
30-
g.createNode()
31-
return g.nodes.size === 1
30+
if (!isProd) {
31+
const g = new DefaultGraph()
32+
g.createNode()
33+
return g.nodes.size === 1
34+
}
35+
36+
return true
3237
}

src/overview-component/Overview.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,11 @@ export interface OverviewProps {
3030
* This component has to be used inside a parent component that displays the graph, or its corresponding provider.
3131
*
3232
* ```tsx
33-
* function OrganizationChart() {
33+
* function App() {
3434
* return (
35-
* <OrgChart data={data}>
35+
* <MyReactYFilesComponent data={data}>
3636
* <Overview></Overview>
37-
* </OrgChart>
37+
* </MyReactYFilesComponent>
3838
* )
3939
* }
4040
* ```

src/popup/Popup.tsx

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -92,18 +92,13 @@ export function Popup<TDataItem>({
9292
const graphComponent = useGraphComponent()!
9393
const [location, setLocation] = useState<{ x: number; y: number }>({ x: 0, y: 0 })
9494
const [currentItem, setCurrentItem] = useState<IModelItem | null>(null)
95+
const [visibility, setVisibility] = useState(false)
9596
const popupContainerRef = useRef<HTMLDivElement>(null)
96-
const [mounted, setMounted] = useState(false)
97-
98-
useEffect(() => {
99-
// needed to run the updateLocation twice the first time that the popup appears to make sure
100-
// that the content is already in the dom, and it has the correct width and height
101-
setMounted(!!currentItem)
102-
}, [currentItem])
10397

10498
useEffect(() => {
99+
setVisibility(false)
105100
updateLocation(graphComponent, currentItem, popupContainerRef, position)
106-
}, [currentItem, graphComponent, mounted, position])
101+
}, [currentItem, graphComponent, position])
107102

108103
/**
109104
* Registers the popup listeners.
@@ -117,6 +112,11 @@ export function Popup<TDataItem>({
117112
}
118113
inputMode.addCanvasClickedListener(canvasClickedListener)
119114

115+
const viewportChangedListener = () => {
116+
updateLocation(graphComponent, graphComponent.currentItem, popupContainerRef, position)
117+
}
118+
graphComponent.addViewportChangedListener(viewportChangedListener)
119+
120120
const itemClickedListener = (_: GraphInputMode, evt: ItemClickedEventArgs<IModelItem>) => {
121121
setCurrentItem(evt.item instanceof INode || evt.item instanceof IEdge ? evt.item : null)
122122
}
@@ -139,6 +139,7 @@ export function Popup<TDataItem>({
139139
return () => {
140140
// clean up
141141
inputMode.removeCanvasClickedListener(canvasClickedListener)
142+
graphComponent.removeViewportChangedListener(viewportChangedListener)
142143

143144
switch (clickMode) {
144145
case 'double':
@@ -171,7 +172,8 @@ export function Popup<TDataItem>({
171172
style={{
172173
position: 'absolute',
173174
left: location.x,
174-
top: location.y
175+
top: location.y,
176+
visibility: visibility ? 'visible' : 'hidden'
175177
}}
176178
ref={popupContainerRef}
177179
>
@@ -218,6 +220,7 @@ export function Popup<TDataItem>({
218220
new Point(newLayout.anchorX, newLayout.anchorY - (height + 10) / zoom)
219221
)
220222
setLocation(location)
223+
setVisibility(true)
221224
}
222225
}
223226
}

src/utils/CheckStylesheetLoaded.ts

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import { isProd } from './DevMode.ts'
2+
3+
export function checkStylesheetLoaded(root: HTMLElement, name: string) {
4+
//@ts-ignore
5+
if (!isProd && !window['skip-react-yfiles-css-check']) {
6+
const dummy = document.createElement('div')
7+
dummy.id = `${name}-stylesheet-detection`
8+
const rootNode = root?.getRootNode() ?? document
9+
const parent = rootNode === document ? document.body : rootNode
10+
parent.appendChild(dummy)
11+
const computedStyle = getComputedStyle(dummy)
12+
const hasStyle =
13+
computedStyle.getPropertyValue('--yfiles-react-stylesheet-detection') ===
14+
`${name}-stylesheet-detection`
15+
16+
if (!hasStyle) {
17+
console.warn(
18+
`Stylesheet not loaded! Please import 'dist/index.css' from the @yworks/${name} package:`
19+
)
20+
displayCssWarning(root!, name)
21+
}
22+
dummy.remove()
23+
}
24+
}
25+
26+
function displayCssWarning(root: HTMLElement, componentName: string) {
27+
if (root.getAttribute('cssWarningAdded')) {
28+
return
29+
}
30+
const warning = document.createElement('div')
31+
warning.innerHTML = `<div
32+
style="user-select: text; position:absolute; inset: 0; display: flex; align-items: center; justify-content: center; font-family: Roboto, sans-serif;">
33+
<div
34+
style="max-width: 700px; padding: 20px; border: 1px solid #ccc; border-radius: 8px; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); background-color: #f1f5f9; color: #334155; overflow-y: auto; text-align: left;">
35+
<div style="font-size: 20px; font-weight: bold; margin-bottom: 10px; display: flex">Missing CSS
36+
<button class="cssWarningClose" style="margin-left: auto">X</button>
37+
</div>
38+
<div style="margin: 2ex 0;"> The required CSS stylesheet could not be detected.<br>
39+
Please import <code>'dist/index.css'</code> from the
40+
<code style="white-space: nowrap">@yworks/${componentName}</code>
41+
package.
42+
</div>
43+
<div style="background-color: #ffffff; padding: 0 10px; border-radius: 4px; overflow-x: auto;">
44+
<pre>import '@yworks/${componentName}/dist/index.css'</pre>
45+
</div>
46+
</div>
47+
</div>
48+
`
49+
50+
warning.addEventListener('mousedown', e => e.stopPropagation(), true)
51+
warning.querySelector('.cssWarningClose')!.addEventListener('click', e => warning.remove())
52+
root.appendChild(warning)
53+
root.setAttribute(`cssWarningAdded`, 'true')
54+
}

src/utils/DevMode.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export let isProd = false
2+
try {
3+
// @ts-ignore
4+
isProd = process.env.NODE_ENV === 'production'
5+
} catch (e: any) {}

0 commit comments

Comments
 (0)