Skip to content

Commit 9d1883e

Browse files
committed
Adding I18N feature on controls
1 parent 18b05b3 commit 9d1883e

File tree

13 files changed

+86
-26
lines changed

13 files changed

+86
-26
lines changed

project/packages/core/src/components/controls/FullScreenControl.tsx

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import { ReactComponent as EnterIcon } from "../../assets/icons/expand-solid.svg
44
import { ReactComponent as ExitIcon } from "../../assets/icons/compress-solid.svg";
55
import { useFullScreen } from "../../hooks/useFullScreen";
66

7+
type FullScreenLabelKeys = "enter" | "exit";
8+
79
/**
810
* Properties for `FullScreenControl` component.
911
*/
@@ -35,6 +37,12 @@ export interface FullScreenControlProps {
3537
* ```
3638
*/
3739
children?: [JSX.Element, JSX.Element];
40+
41+
/**
42+
* Map of the labels we use in the component.
43+
* This is usefull for I18N
44+
*/
45+
labels?: { [Key in FullScreenLabelKeys]?: string };
3846
}
3947

4048
/**
@@ -56,6 +64,7 @@ export const FullScreenControl: React.FC<FullScreenControlProps> = ({
5664
className,
5765
style,
5866
children,
67+
labels = {},
5968
}: FullScreenControlProps) => {
6069
// Get Sigma
6170
const { isFullScreen, toggle } = useFullScreen();
@@ -71,7 +80,10 @@ export const FullScreenControl: React.FC<FullScreenControlProps> = ({
7180

7281
return (
7382
<div {...htmlProps}>
74-
<button onClick={toggle} title={isFullScreen ? "Exit fullscreen" : "Enter fullscreen"}>
83+
<button
84+
onClick={toggle}
85+
title={isFullScreen ? labels["exit"] || "Exit fullscreen" : labels["enter"] || "Enter fullscreen"}
86+
>
7587
{children && !isFullScreen && children[0]}
7688
{children && isFullScreen && children[1]}
7789
{!children && !isFullScreen && <EnterIcon style={{ width: "1em" }} />}

project/packages/core/src/components/controls/SearchControl.tsx

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import { useSigma } from "../../hooks/useSigma";
66
import { useCamera } from "../../hooks/useCamera";
77
import { useRegisterEvents } from "../../hooks/useRegisterEvents";
88

9+
type SearchLabelKeys = "text" | "placeholder";
10+
911
/**
1012
* Properties for `SearchControl` component
1113
*/
@@ -24,6 +26,12 @@ export interface SearchControlProps {
2426
* HTML CSS style
2527
*/
2628
style?: CSSProperties;
29+
30+
/**
31+
* Map of the labels we use in the component.
32+
* This is usefull for I18N
33+
*/
34+
labels?: { [Key in SearchLabelKeys]?: string };
2735
}
2836

2937
/**
@@ -42,7 +50,12 @@ export interface SearchControlProps {
4250
*
4351
* @category Component
4452
*/
45-
export const SearchControl: React.FC<SearchControlProps> = ({ id, className, style }: SearchControlProps) => {
53+
export const SearchControl: React.FC<SearchControlProps> = ({
54+
id,
55+
className,
56+
style,
57+
labels = {},
58+
}: SearchControlProps) => {
4659
// Get sigma
4760
const sigma = useSigma();
4861
// Get event hook
@@ -134,12 +147,12 @@ export const SearchControl: React.FC<SearchControlProps> = ({ id, className, sty
134147
return (
135148
<div {...htmlProps}>
136149
<label htmlFor={inputId} style={{ display: "none" }}>
137-
Search a node
150+
{labels["text"] || "Search a node"}
138151
</label>
139152
<input
140153
id={inputId}
141154
type="text"
142-
placeholder="Search..."
155+
placeholder={labels["placeholder"] || "Search..."}
143156
list={`${inputId}-datalist`}
144157
value={search}
145158
onChange={onInputChange}

project/packages/core/src/components/controls/ZoomControl.tsx

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import { ReactComponent as ZoomOutIcon } from "../../assets/icons/minus-solid.sv
55
import { ReactComponent as ZoomResetIcon } from "../../assets/icons/dot-circle-regular.svg";
66
import { useCamera } from "../../hooks/useCamera";
77

8+
type ZoomLabelKeys = "zoomIn" | "zoomOut" | "reset";
9+
810
/**
911
* Properties for `ZoomControl` component
1012
*/
@@ -23,6 +25,7 @@ export interface ZoomControlProps {
2325
* Number of ms for the zoom animation (default is 200ms)
2426
*/
2527
animationDuration?: number;
28+
2629
/**
2730
* It's possible to customize the button, by passing to JSX Element.
2831
* First one is for the "zoom in", second for "zoom out" and third for "view whole graph".
@@ -36,6 +39,12 @@ export interface ZoomControlProps {
3639
* ```
3740
*/
3841
children?: [JSX.Element, JSX.Element, JSX.Element];
42+
43+
/**
44+
* Map of the labels we use in the component.
45+
* This is usefull for I18N
46+
*/
47+
labels?: { [Key in ZoomLabelKeys]?: string };
3948
}
4049

4150
/**
@@ -60,6 +69,7 @@ export const ZoomControl: React.FC<ZoomControlProps> = ({
6069
style,
6170
animationDuration = 200,
6271
children,
72+
labels = {},
6373
}: ZoomControlProps) => {
6474
const { zoomIn, zoomOut, reset } = useCamera({ duration: animationDuration, factor: 1.5 });
6575

@@ -72,17 +82,17 @@ export const ZoomControl: React.FC<ZoomControlProps> = ({
7282
return (
7383
<>
7484
<div {...htmlProps}>
75-
<button onClick={() => zoomIn()} title="Zoom In">
85+
<button onClick={() => zoomIn()} title={labels["zoomIn"] || "Zoom In"}>
7686
{children ? children[0] : <ZoomInIcon style={{ width: "1em" }} />}
7787
</button>
7888
</div>
7989
<div {...htmlProps}>
80-
<button onClick={() => zoomOut()} title="Zoom Out">
90+
<button onClick={() => zoomOut()} title={labels["zoomOut"] || "Zoom Out"}>
8191
{children ? children[1] : <ZoomOutIcon style={{ width: "1em" }} />}
8292
</button>
8393
</div>
8494
<div {...htmlProps}>
85-
<button onClick={() => reset()} title="See whole graph">
95+
<button onClick={() => reset()} title={labels["reset"] || "See whole graph"}>
8696
{children ? children[2] : <ZoomResetIcon style={{ width: "1em" }} />}
8797
</button>
8898
</div>

project/packages/examples/src/routing.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { HomeView } from "./views/home";
55
import { CompleteView } from "./views/complete";
66
import { EventsView } from "./views/events";
77
import { MultipleView } from "./views/multiple";
8-
import { CustomButtonsView } from "./views/custom-buttons";
8+
import { CustomRenderView } from "./views/custom-render";
99
import { MultiDirectedGraphView } from "./views/multidirectedgraph";
1010
import { ExternalView } from "./views/external";
1111

@@ -16,7 +16,7 @@ export const Routing: FC = () => {
1616
<Route path="/complete" element={<CompleteView />} />
1717
<Route path="/events" element={<EventsView />} />
1818
<Route path="/multiple" element={<MultipleView />} />
19-
<Route path="/custom-buttons" element={<CustomButtonsView />} />
19+
<Route path="/custom-render" element={<CustomRenderView />} />
2020
<Route path="/multidirectedgraph" element={<MultiDirectedGraphView />} />
2121
<Route path="/external" element={<ExternalView />} />
2222
</Routes>

project/packages/examples/src/views/custom-buttons.tsx renamed to project/packages/examples/src/views/custom-render.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,23 +14,23 @@ import { SigmaContainer, ControlsContainer, ZoomControl, FullScreenControl } fro
1414
import { LayoutForceAtlas2Control } from "@react-sigma/layout-forceatlas2";
1515
import { SampleGraph } from "../common/SampleGraph";
1616

17-
export const CustomButtonsView: FC = () => {
17+
export const CustomRenderView: FC = () => {
1818
const [searchParams] = useSearchParams();
1919
const faTime = Number.parseInt(searchParams.get("faTime") || "2000");
2020
return (
2121
<SigmaContainer settings={{ renderLabels: false }}>
2222
<SampleGraph />
2323
<ControlsContainer position={"bottom-right"}>
24-
<ZoomControl>
24+
<ZoomControl labels={{ zoomIn: "PLUS", zoomOut: "MINUS", reset: "RESET" }}>
2525
<AiOutlineZoomIn />
2626
<AiOutlineZoomOut />
2727
<MdFilterCenterFocus />
2828
</ZoomControl>
29-
<FullScreenControl>
29+
<FullScreenControl labels={{ enter: "ENTER", exit: "EXIT" }}>
3030
<AiOutlineFullscreen />
3131
<AiOutlineFullscreenExit />
3232
</FullScreenControl>
33-
<LayoutForceAtlas2Control autoRunFor={faTime}>
33+
<LayoutForceAtlas2Control labels={{ stop: "STOP", start: "START" }} autoRunFor={faTime}>
3434
<AiFillPlayCircle />
3535
<AiFillPauseCircle />
3636
</LayoutForceAtlas2Control>

project/packages/examples/src/views/home.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@ export const HomeView: FC = () => {
2525
Display multiple independant graph on the same page
2626
</li>
2727
<li>
28-
<Link to="/custom-buttons" title="Custom Buttons">
29-
Custom Buttons
28+
<Link to="/custom-render" title="Custom render">
29+
Custom Render
3030
</Link>{" "}
31-
Make your own style by overring the native display of controllers
31+
Make your own style by overring the native display and labels of controllers
3232
</li>
3333
<li>
3434
<Link to="/multidirectedgraph" title="MultiDirectedGraph">

project/packages/examples/test/e2e/config.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ export const tests: Tests = [
1515
{ name: "complete", url: "http://localhost:3000/complete?seed=foo&faTime=-1", waitFor: 200, failureThreshold: 0.001 },
1616
{ name: "multiple", url: "http://localhost:3000/multiple?seed=foo&faTime=-1", waitFor: 200, failureThreshold: 0.001 },
1717
{
18-
name: "custom-buttons",
19-
url: "http://localhost:3000/custom-buttons?seed=foo&faTime=-1",
18+
name: "custom-render",
19+
url: "http://localhost:3000/custom-render?seed=foo&faTime=-1",
2020
waitFor: 200,
2121
failureThreshold: 0.001,
2222
},
253 KB
Loading

project/packages/layout-core/src/WorkerLayoutControl.tsx

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import { ReactComponent as StartLayoutIcon } from "./assets/icons/play-solid.svg
55
import { ReactComponent as StopLayoutIcon } from "./assets/icons/stop-solid.svg";
66
import { LayoutWorkerHook } from "./useWorkerLayoutFactory";
77

8+
type WorkerLayoutLabelKeys = "start" | "stop";
9+
810
/**
911
* Properties for `WorkerLayoutControl` component
1012
*/
@@ -47,15 +49,21 @@ export interface WorkerLayoutControlProps<T> {
4749
* First one is for the "start layout", and the second to "stop layout".
4850
* Example :
4951
* ```jsx
50-
* <FullScreenControl>
52+
* <WorkerLayoutControl>
5153
* <>
52-
* <BiFullscreen />
53-
* <BiExitFullscreen />
54+
* <span>Start</span>
55+
* <span>Stop</span>
5456
* </>
55-
* </FullScreenControl>
57+
* </WorkerLayoutControl>
5658
* ```
5759
*/
5860
children?: [JSX.Element, JSX.Element];
61+
62+
/**
63+
* Map of the labels we use in the component.
64+
* This is usefull for I18N
65+
*/
66+
labels?: { [Key in WorkerLayoutLabelKeys]?: string };
5967
}
6068

6169
export function WorkerLayoutControl<T>({
@@ -66,6 +74,7 @@ export function WorkerLayoutControl<T>({
6674
settings,
6775
autoRunFor,
6876
children,
77+
labels = {},
6978
}: WorkerLayoutControlProps<T>) {
7079
// Get Sigma
7180
const sigma = useSigma();
@@ -111,7 +120,9 @@ export function WorkerLayoutControl<T>({
111120
<div {...props}>
112121
<button
113122
onClick={() => (isRunning ? stop() : start())}
114-
title={isRunning ? "Stop the layout animation" : "Start the layout animation"}
123+
title={
124+
isRunning ? labels["stop"] || "Stop the layout animation" : labels["start"] || "Start the layout animation"
125+
}
115126
>
116127
{children && !isRunning && children[0]}
117128
{children && isRunning && children[1]}

project/packages/layout-force/src/LayoutForceControl.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ export const LayoutForceControl: React.FC<LayoutForceControlProps> = ({
2626
settings = {},
2727
autoRunFor,
2828
children,
29+
labels,
2930
}) => {
30-
const workerLayoutProps = { id, className, style, settings, autoRunFor, layout: useWorkerLayoutForce };
31+
const workerLayoutProps = { id, className, style, settings, autoRunFor, labels, layout: useWorkerLayoutForce };
3132
return <WorkerLayoutControl {...workerLayoutProps}>{children}</WorkerLayoutControl>;
3233
};

0 commit comments

Comments
 (0)