Skip to content

Commit 11d201d

Browse files
committed
Feat: added section color binding
1 parent c69a59e commit 11d201d

File tree

7 files changed

+56
-23
lines changed

7 files changed

+56
-23
lines changed

src/components/controls/select/polyline/index.tsx

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import { useSelector } from "react-redux";
2+
import { selectPolylineById } from "@/store/reducers/editor";
23
import { d3Extended, rgbToHex } from "@/utils";
34
import { default as ControlInput } from "../../control-input";
45
import { default as SectionSelector } from "./section-selector";
56

67
const PolylineSelectControls = () => {
78
const selectedElementIds = useSelector((state: any) => state.editor.selectedElementIds);
9+
const firstPolyline = useSelector(selectPolylineById(selectedElementIds[0]));
810
const firstElement = document.getElementById(selectedElementIds[0]);
911
return (
1012
<div className="flex flex-col gap-4 py-1">
@@ -13,21 +15,23 @@ const PolylineSelectControls = () => {
1315
<ControlInput
1416
id="polyline-stroke-input"
1517
label="Stroke"
16-
defaultValue={rgbToHex(d3Extended.select(firstElement).style("stroke"))}
18+
defaultValue={rgbToHex(d3Extended.select(firstElement)?.style("stroke"))}
1719
type="color"
20+
disabled={!!firstPolyline.section}
1821
onChange={(e) => {
19-
selectedElementIds.forEach((id) => {
22+
selectedElementIds.forEach((id: string) => {
2023
d3Extended.selectById(id).style("stroke", e.target.value);
2124
});
2225
}}
2326
/>
2427
<ControlInput
2528
id="polyline-fill-input"
2629
label="Fill"
27-
defaultValue={rgbToHex(d3Extended.select(firstElement).style("color"))}
30+
defaultValue={rgbToHex(d3Extended.select(firstElement)?.style("color"))}
2831
type="color"
32+
disabled={!!firstPolyline.section}
2933
onChange={(e) => {
30-
selectedElementIds.forEach((id) => {
34+
selectedElementIds.forEach((id: string) => {
3135
d3Extended.selectById(id).style("color", e.target.value);
3236
});
3337
}}

src/components/controls/select/polyline/section-selector.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@ const SectionSelector = ({ firstElement, selectedElementIds }) => {
4848
className="flex-shrink-0 w-6 h-6 p-0 bg-white rounded-color-input"
4949
onChange={(e) => onUpdateSection({ ...section, color: e.target.value })}
5050
/>
51+
<input
52+
defaultValue={section.stroke}
53+
type="color"
54+
className="flex-shrink-0 w-6 h-6 p-0 bg-white rounded-color-input"
55+
onChange={(e) => onUpdateSection({ ...section, stroke: e.target.value })}
56+
/>
5157
<Input
5258
defaultValue={section.name}
5359
className="h-8"
@@ -71,7 +77,7 @@ const SectionSelector = ({ firstElement, selectedElementIds }) => {
7177
<Select
7278
onValueChange={(value) => {
7379
selectedElementIds.forEach((id: string) =>
74-
store.dispatch(updatePolyline({ id, section: value === "0" ? null : value }))
80+
store.dispatch(updatePolyline({ id, section: +value === 0 ? null : value }))
7581
);
7682
}}
7783
defaultValue={firstElement?.getAttribute?.(dataAttributes.section) || undefined}

src/components/footer.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ const Footer: React.FC<ISTKProps> = ({ options: { showFooter = true } = {}, ...p
1717
style={styles?.root?.properties}
1818
>
1919
<span className={twMerge("text-sm", styles?.title?.className)} style={styles?.title?.properties}>
20-
React Seat Toolkit{" "}
20+
React Seat Toolkit
2121
</span>
2222
<AnimatedSwitcher
2323
show={!!selectedTool}

src/components/workspace/elements/polyline.tsx

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,29 @@
1-
import { forwardRef } from "react";
1+
import { forwardRef, useMemo } from "react";
22
import { twMerge } from "tailwind-merge";
33
import { dataAttributes } from "@/constants";
4-
import { IPolyline } from "@/types";
4+
import { IPolyline, ISection } from "@/types";
55

66
export interface IPolylineProps extends IPolyline {
77
className?: string;
8+
sections?: ISection[];
89
}
910

10-
const Polyline: React.FC<IPolylineProps> = forwardRef(({ id, points, color, stroke, section, ...props }, ref: any) => {
11-
return (
12-
<polyline
13-
ref={ref}
14-
id={id}
15-
points={points.map((p) => `${p.x},${p.y}`).join(" ")}
16-
{...props}
17-
style={{ color: color ?? "transparent", stroke }}
18-
{...{ [dataAttributes.section]: section }}
19-
className={twMerge(props.className)}
20-
/>
21-
);
22-
});
11+
const Polyline: React.FC<IPolylineProps> = forwardRef(
12+
({ id, points, color, stroke, sections, section, ...props }, ref: any) => {
13+
const sectionObject = useMemo(() => sections?.find?.((s) => s.id === section), [sections, section]);
14+
return (
15+
<polyline
16+
ref={ref}
17+
id={id}
18+
points={points.map((p) => `${p.x},${p.y}`).join(" ")}
19+
{...props}
20+
style={{ color: sectionObject?.color ?? color ?? "transparent", stroke: sectionObject?.stroke ?? stroke }}
21+
{...{ [dataAttributes.section]: section }}
22+
className={twMerge(props.className)}
23+
/>
24+
);
25+
}
26+
);
2327

2428
Polyline.displayName = "Polyline";
2529

src/components/workspace/index.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export const Workspace: React.FC<ISTKProps> = (props) => {
2121
const polylines = useSelector((state: any) => state.editor.polylines);
2222
const images = useSelector((state: any) => state.editor.images);
2323
const categories = useSelector((state: any) => state.editor.categories);
24+
const sections = useSelector((state: any) => state.editor.sections);
2425
const selectedElementIds = useSelector((state: any) => state.editor.selectedElementIds);
2526
const selectedPolylineId = useSelector((state: any) => state.editor.selectedPolylineId);
2627
const selectedTool = useSelector((state: any) => state.toolbar.selectedTool);
@@ -99,7 +100,14 @@ export const Workspace: React.FC<ISTKProps> = (props) => {
99100
/>
100101
))}
101102
{polylines.map((e) => (
102-
<Element key={e.id} type={ElementType.Polyline} points={e.points} {...elementProps(e)} />
103+
<Element
104+
key={e.id}
105+
type={ElementType.Polyline}
106+
points={e.points}
107+
sections={sections}
108+
section={e.section}
109+
{...elementProps(e)}
110+
/>
103111
))}
104112
{images.map((e) => (
105113
<Element

src/store/reducers/editor/index.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Reducer, createSlice } from "@reduxjs/toolkit";
1+
import { Reducer, createSelector, createSlice } from "@reduxjs/toolkit";
22
import { v4 as uuidv4 } from "uuid";
33
import type { ISTKData } from "@/types";
44
import booths from "./booths";
@@ -48,19 +48,22 @@ const initialState = {
4848
id: uuidv4(),
4949
name: "Section 1",
5050
color: "#000000",
51+
stroke: "#000000",
5152
freeSeating: true,
5253
capacity: 100
5354
},
5455
{
5556
id: uuidv4(),
5657
name: "Section 2",
5758
color: "#FF0000",
59+
stroke: "#FF0000",
5860
freeSeating: false
5961
},
6062
{
6163
id: uuidv4(),
6264
name: "Section 3",
6365
color: "#0000FF",
66+
stroke: "#0000FF",
6467
freeSeating: false
6568
}
6669
],
@@ -192,6 +195,7 @@ export const slice = createSlice({
192195
id: uuidv4(),
193196
name: `Section ${state.sections.length + 1}`,
194197
color: "#000000",
198+
stroke: "#000000",
195199
freeSeating: false
196200
});
197201
},
@@ -253,4 +257,10 @@ export const {
253257
sync
254258
} = slice.actions;
255259

260+
export const selectPolylineById = (id: string) =>
261+
createSelector(
262+
(state: any) => state.editor.polylines,
263+
(polylines) => polylines.find((polyline) => polyline.id === id)
264+
);
265+
256266
export default slice.reducer as Reducer<typeof initialState>;

src/types/elements/polyline.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ export interface ISection {
22
id: string;
33
name: string;
44
color: string;
5+
stroke: string;
56
freeSeating: boolean;
67
capacity?: number;
78
}

0 commit comments

Comments
 (0)