|
1 | 1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. |
2 | 2 | // SPDX-License-Identifier: Apache-2.0 |
3 | 3 |
|
| 4 | +import { useId } from "react"; |
| 5 | + |
4 | 6 | import { BaseComponentProps } from "@cloudscape-design/components/internal/base-component"; |
5 | | -import { colorTextInteractiveDisabled } from "@cloudscape-design/design-tokens"; |
| 7 | +import { colorBorderStatusWarning, colorTextInteractiveDisabled } from "@cloudscape-design/design-tokens"; |
6 | 8 |
|
7 | 9 | import styles from "./styles.css.js"; |
8 | 10 |
|
@@ -43,104 +45,113 @@ export function ChartSeriesMarker({ |
43 | 45 | i18nStrings, |
44 | 46 | }: ChartSeriesMarkerProps) { |
45 | 47 | color = visible ? color : colorTextInteractiveDisabled; |
| 48 | + |
| 49 | + // As React re-renders the components, a new ID should be created for masks. |
| 50 | + // Not doing so will not evaluate the mask. |
| 51 | + const maskId = useId(); |
| 52 | + |
46 | 53 | return ( |
47 | 54 | <div className={styles.marker}> |
48 | | - <svg focusable={false} aria-hidden={true} viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> |
49 | | - {type === "line" && <SVGLine color={color} />} |
| 55 | + <svg focusable={false} aria-hidden={true} viewBox="0 0 32 16" xmlns="http://www.w3.org/2000/svg"> |
| 56 | + <defs> |
| 57 | + <mask id={maskId}> |
| 58 | + <rect width="100%" height="100%" fill="white" /> |
| 59 | + |
| 60 | + {status === "warning" && <SVGWarningMask></SVGWarningMask>} |
| 61 | + </mask> |
| 62 | + </defs> |
| 63 | + |
| 64 | + {status === "warning" && <SVGWarning ariaLabel={i18nStrings.seriesStatusWarningAriaLabel ?? ""}></SVGWarning>} |
| 65 | + |
| 66 | + {type === "line" && <SVGLine maskId={maskId} color={color} />} |
50 | 67 |
|
51 | | - {type === "dashed" && <SVGLineDashed color={color} />} |
| 68 | + {type === "dashed" && <SVGLineDashed maskId={maskId} color={color} />} |
52 | 69 |
|
53 | | - {type === "large-square" && <SVGLargeSquare color={color} />} |
| 70 | + {type === "large-square" && <SVGLargeSquare maskId={maskId} color={color} />} |
54 | 71 |
|
55 | | - {type === "hollow-square" && <SVGHollowSquare color={color} />} |
| 72 | + {type === "hollow-square" && <SVGHollowSquare maskId={maskId} color={color} />} |
56 | 73 |
|
57 | | - {type === "square" && <SVGSquare color={color} />} |
| 74 | + {type === "square" && <SVGSquare maskId={maskId} color={color} />} |
58 | 75 |
|
59 | | - {type === "diamond" && <SVGDiamond color={color} />} |
| 76 | + {type === "diamond" && <SVGDiamond maskId={maskId} color={color} />} |
60 | 77 |
|
61 | | - {type === "triangle" && <SVGTriangle color={color} />} |
| 78 | + {type === "triangle" && <SVGTriangle maskId={maskId} color={color} />} |
62 | 79 |
|
63 | | - {type === "triangle-down" && <SVGTriangleDown color={color} />} |
| 80 | + {type === "triangle-down" && <SVGTriangleDown maskId={maskId} color={color} />} |
64 | 81 |
|
65 | | - {type === "circle" && <SVGCircle color={color} />} |
| 82 | + {type === "circle" && <SVGCircle maskId={maskId} color={color} />} |
66 | 83 | </svg> |
67 | | - {status === "warning" && ( |
68 | | - <div className={styles["marker-status"]}> |
69 | | - <SVGWarning ariaLabel={i18nStrings.seriesStatusWarningAriaLabel ?? ""} /> |
70 | | - </div> |
71 | | - )} |
72 | 84 | </div> |
73 | 85 | ); |
74 | 86 | } |
75 | 87 |
|
76 | | -function SVGLine({ color }: { color: string }) { |
77 | | - return <rect x={1} y={7} height={4} width={14} strokeWidth={0} rx={2} fill={color} />; |
| 88 | +function SVGLine({ color, maskId }: { color: string; maskId: string }) { |
| 89 | + return <rect mask={`url(#${maskId})`} x={1} y={7} height={4} width={14} strokeWidth={0} rx={2} fill={color} />; |
78 | 90 | } |
79 | 91 |
|
80 | | -function SVGLineDashed({ color }: { color: string }) { |
| 92 | +function SVGLineDashed({ color, maskId }: { color: string; maskId: string }) { |
81 | 93 | return ( |
82 | 94 | <> |
83 | | - <rect x={1} y={7} height={4} width={6} strokeWidth={0} rx={2} fill={color} /> |
84 | | - <rect x={9} y={7} height={4} width={6} strokeWidth={0} rx={2} fill={color} /> |
| 95 | + <rect mask={`url(#${maskId})`} x={1} y={7} height={4} width={6} strokeWidth={0} rx={2} fill={color} /> |
| 96 | + <rect mask={`url(#${maskId})`} x={9} y={7} height={4} width={6} strokeWidth={0} rx={2} fill={color} /> |
85 | 97 | </> |
86 | 98 | ); |
87 | 99 | } |
88 | 100 |
|
89 | | -function SVGLargeSquare({ color }: { color: string }) { |
| 101 | +function SVGLargeSquare({ color, maskId }: { color: string; maskId: string }) { |
90 | 102 | const shape = { x: 0, y: 0, width: 16, height: 16, rx: 2, transform: scale(16, 0.85) }; |
91 | | - return <rect {...shape} strokeWidth={0} fill={color} />; |
| 103 | + return <rect mask={`url(#${maskId})`} {...shape} strokeWidth={0} fill={color} />; |
92 | 104 | } |
93 | 105 |
|
94 | | -function SVGHollowSquare({ color }: { color: string }) { |
| 106 | +function SVGHollowSquare({ color, maskId }: { color: string; maskId: string }) { |
95 | 107 | const size = { x: 0, y: 0, width: 16, height: 16, rx: 2, transform: scale(16, 0.75) }; |
96 | | - return <rect {...size} strokeWidth={2} stroke={color} fill={color} fillOpacity="0.40" />; |
| 108 | + return <rect mask={`url(#${maskId})`} {...size} strokeWidth={2} stroke={color} fill={color} fillOpacity="0.40" />; |
97 | 109 | } |
98 | 110 |
|
99 | | -function SVGSquare({ color }: { color: string }) { |
| 111 | +function SVGSquare({ color, maskId }: { color: string; maskId: string }) { |
100 | 112 | const size = { x: 3, y: 3, width: 10, height: 10, rx: 2 }; |
101 | | - return <rect {...size} strokeWidth={0} fill={color} />; |
| 113 | + return <rect mask={`url(#${maskId})`} {...size} strokeWidth={0} fill={color} />; |
102 | 114 | } |
103 | 115 |
|
104 | | -function SVGDiamond({ color }: { color: string }) { |
| 116 | +function SVGDiamond({ color, maskId }: { color: string; maskId: string }) { |
105 | 117 | const shape = { points: "8,0 16,8 8,16 0,8", transform: scale(16, 0.65) }; |
106 | | - return <polygon {...shape} strokeWidth={0} fill={color} />; |
| 118 | + return <polygon mask={`url(#${maskId})`} {...shape} strokeWidth={0} fill={color} />; |
107 | 119 | } |
108 | 120 |
|
109 | | -function SVGTriangle({ color }: { color: string }) { |
| 121 | +function SVGTriangle({ color, maskId }: { color: string; maskId: string }) { |
110 | 122 | const shape = { points: "8,0 16,16 0,16", transform: scale(16, 0.65) }; |
111 | | - return <polygon {...shape} strokeWidth={0} fill={color} />; |
| 123 | + return <polygon mask={`url(#${maskId})`} {...shape} strokeWidth={0} fill={color} />; |
112 | 124 | } |
113 | 125 |
|
114 | | -function SVGTriangleDown({ color }: { color: string }) { |
| 126 | +function SVGTriangleDown({ color, maskId }: { color: string; maskId: string }) { |
115 | 127 | const shape = { points: "8,16 0,0 16,0", transform: scale(16, 0.65) }; |
116 | | - return <polygon {...shape} strokeWidth={0} fill={color} />; |
| 128 | + return <polygon mask={`url(#${maskId})`} {...shape} strokeWidth={0} fill={color} />; |
117 | 129 | } |
118 | 130 |
|
119 | | -function SVGCircle({ color }: { color: string }) { |
| 131 | +function SVGCircle({ color, maskId }: { color: string; maskId: string }) { |
120 | 132 | const shape = { cx: 8, cy: 8, r: 5 }; |
121 | | - return <circle {...shape} strokeWidth={0} fill={color} />; |
| 133 | + return <circle mask={`url(#${maskId})`} {...shape} strokeWidth={0} fill={color} />; |
122 | 134 | } |
123 | 135 |
|
| 136 | +const SVGWarningTranslate = `translate(12, 1)`; |
| 137 | + |
124 | 138 | function SVGWarning({ ariaLabel }: { ariaLabel: string }) { |
125 | 139 | return ( |
126 | | - <svg |
| 140 | + <path |
127 | 141 | aria-label={ariaLabel} |
128 | | - width="2048" |
129 | | - height="2048" |
130 | | - viewBox="0 0 2048 2048" |
131 | | - fill="none" |
132 | | - xmlns="http://www.w3.org/2000/svg" |
133 | | - > |
134 | | - <path |
135 | | - d="M1026.13 189.272C1070.05 189.638 1112.23 201.32 1150.09 223.616L1151.92 224.703L1153.73 225.798C1190.95 248.557 1220.82 279.873 1241.92 317.63L1242.93 319.462L1243.02 319.61L1243.1 319.76L1842.42 1418.91C1886.25 1498.63 1883.99 1587.56 1838.52 1665.03L1838.52 1665.02C1816.34 1702.83 1785.36 1733.29 1747.79 1754.95C1709.7 1776.91 1667.35 1788.26 1623.32 1788.26H424.678C380.651 1788.26 338.304 1776.91 300.21 1754.95C262.607 1733.27 231.602 1702.77 209.421 1664.92L209.422 1664.92C163.991 1587.46 161.763 1498.54 205.625 1418.83L804.904 319.759L805.066 319.462C826.549 280.274 857.415 247.911 896.081 224.703L897.91 223.616C936.377 200.961 979.316 189.264 1024 189.264L1026.13 189.272Z" |
136 | | - fill="white" |
137 | | - stroke="white" |
138 | | - strokeWidth="300" |
139 | | - /> |
140 | | - <path |
141 | | - d="M1123.89 1412.66V1264.33C1123.89 1257.05 1121.42 1250.93 1116.47 1245.99C1111.53 1241.04 1105.68 1238.57 1098.92 1238.57H949.085C942.322 1238.57 936.469 1241.04 931.526 1245.99C926.584 1250.93 924.113 1257.05 924.113 1264.33V1412.66C924.113 1419.94 926.584 1426.06 931.526 1431C936.469 1435.95 942.322 1438.42 949.085 1438.42H1098.92C1105.68 1438.42 1111.53 1435.95 1116.47 1431C1121.42 1426.06 1123.89 1419.94 1123.89 1412.66ZM1122.33 1120.69L1136.37 762.375C1136.37 756.13 1133.77 751.186 1128.57 747.543C1121.81 741.818 1115.56 738.956 1109.84 738.956H938.16C932.437 738.956 926.194 741.818 919.431 747.543C914.228 751.186 911.627 756.651 911.627 763.937L924.893 1120.69C924.893 1125.9 927.495 1130.19 932.697 1133.57C937.899 1136.96 944.142 1138.65 951.426 1138.65H1095.79C1103.08 1138.65 1109.19 1136.96 1114.13 1133.57C1119.07 1130.19 1121.81 1125.9 1122.33 1120.69ZM1111.4 391.567L1710.72 1490.72C1728.93 1523.51 1728.41 1556.3 1709.16 1589.08C1700.32 1604.18 1688.22 1616.15 1672.88 1624.99C1657.53 1633.84 1641.01 1638.26 1623.32 1638.26H424.678C406.99 1638.26 390.472 1633.84 375.125 1624.99C359.778 1616.15 347.682 1604.18 338.838 1589.08C319.589 1556.3 319.068 1523.51 337.277 1490.72L936.599 391.567C945.443 375.434 957.669 362.683 973.276 353.315C988.883 343.948 1005.79 339.264 1024 339.264C1042.21 339.264 1059.12 343.948 1074.72 353.315C1090.33 362.683 1102.56 375.434 1111.4 391.567Z" |
142 | | - fill="#E07700" |
143 | | - /> |
144 | | - </svg> |
| 142 | + transform={`${SVGWarningTranslate} ${scale(16, 0.8)}`} |
| 143 | + d="M9.14157,12.3948v-1.713c0,-0.084,-0.028,-0.154,-0.085,-0.211c-0.056,-0.058,-0.123,-0.086,-0.2,-0.086h-1.713c-0.077,0,-0.144,0.028,-0.2,0.086c-0.057,0.057,-0.085,0.127,-0.085,0.211v1.713c0,0.084,0.028,0.155,0.085,0.212c0.056,0.057,0.123,0.085,0.2,0.085h1.713c0.077,0,0.144,-0.028,0.2,-0.085c0.057,-0.057,0.085,-0.128,0.085,-0.212zm-0.018,-3.371l0.161,-4.138c0,-0.072,-0.03,-0.129,-0.089,-0.171c-0.078,-0.066,-0.149,-0.099,-0.215,-0.099h-1.962c-0.065,0,-0.136,0.033,-0.214,0.099c-0.059,0.042,-0.089,0.105,-0.089,0.189l0.152,4.12c0,0.06,0.03,0.109,0.089,0.148c0.059,0.039,0.131,0.059,0.214,0.059h1.65c0.083,0,0.153,-0.02,0.21,-0.059c0.056,-0.039,0.087,-0.088,0.093,-0.148zm-0.125,-8.419l6.85,12.692c0.208,0.378,0.202,0.757,-0.018,1.136c-0.101,0.174,-0.24,0.312,-0.415,0.414c-0.175,0.102,-0.364,0.154,-0.566,0.154h-13.699c-0.202,0,-0.391,-0.052,-0.566,-0.154c-0.176,-0.102,-0.314,-0.24,-0.415,-0.414c-0.22,-0.379,-0.226,-0.758,-0.018,-1.136l6.849,-12.692c0.101,-0.187,0.241,-0.334,0.42,-0.442c0.178,-0.108,0.371,-0.162,0.579,-0.162c0.208,0,0.402,0.054,0.58,0.162c0.178,0.108,0.318,0.255,0.419,0.442z" |
| 144 | + fill={colorBorderStatusWarning} |
| 145 | + /> |
| 146 | + ); |
| 147 | +} |
| 148 | + |
| 149 | +function SVGWarningMask() { |
| 150 | + return ( |
| 151 | + <path |
| 152 | + transform={`${SVGWarningTranslate} ${scale(16, 1.4)}`} |
| 153 | + d="M8 0C8.2081 2.01716e-08 8.40171 0.0539363 8.58008 0.162109C8.75826 0.270216 8.898 0.417425 8.99902 0.603516L15.8486 13.2959C16.0567 13.6744 16.05 14.0531 15.8301 14.4316C15.7291 14.6058 15.5913 14.7445 15.416 14.8467C15.2407 14.9488 15.0517 15 14.8496 15H1.15039C0.94832 15 0.759318 14.9488 0.583984 14.8467C0.408709 14.7445 0.270949 14.6058 0.169922 14.4316C-0.0499612 14.0531 -0.0566966 13.6744 0.151367 13.2959L7.00098 0.603516C7.102 0.417424 7.24174 0.270216 7.41992 0.162109C7.59829 0.0539363 7.7919 0 8 0Z" |
| 154 | + fill="black" |
| 155 | + /> |
145 | 156 | ); |
146 | 157 | } |
0 commit comments