|
| 1 | +import React from 'react'; |
| 2 | + |
| 3 | +type IconProps = React.SVGProps<SVGSVGElement> & { title?: string; titleId?: string }; |
| 4 | + |
| 5 | +/** |
| 6 | + * Toolbar icons drawn on the Heroicons outline grid (24px, 1.5 stroke, round caps) |
| 7 | + * so they can sit next to the Heroicons that the toolbar still uses. |
| 8 | + * A 22% fill of the current color (`tint`) marks the "data" part of a glyph. |
| 9 | + */ |
| 10 | +function createIcon(children: React.ReactNode) { |
| 11 | + return function ToolbarIcon({ title, titleId, ...props }: IconProps) { |
| 12 | + return ( |
| 13 | + <svg |
| 14 | + xmlns="http://www.w3.org/2000/svg" |
| 15 | + viewBox="0 0 24 24" |
| 16 | + fill="none" |
| 17 | + stroke="currentColor" |
| 18 | + strokeWidth={1.5} |
| 19 | + strokeLinecap="round" |
| 20 | + strokeLinejoin="round" |
| 21 | + aria-hidden |
| 22 | + aria-labelledby={titleId} |
| 23 | + {...props} |
| 24 | + > |
| 25 | + {title ? <title id={titleId}>{title}</title> : null} |
| 26 | + {children} |
| 27 | + </svg> |
| 28 | + ); |
| 29 | + }; |
| 30 | +} |
| 31 | + |
| 32 | +const tint = { fill: 'currentColor', fillOpacity: 0.22 } as const; |
| 33 | + |
| 34 | +/** One stacked column whose lower segment (from `split` down to the baseline) is tinted. */ |
| 35 | +const stackedColumn = (x: number, top: number, split: number) => ( |
| 36 | + <> |
| 37 | + <rect x={x} y={top} width="4.5" height={20.5 - top} rx=".75" /> |
| 38 | + <path {...tint} d={`M${x} ${split}h4.5v${20.5 - split}h-4.5z`} /> |
| 39 | + </> |
| 40 | +); |
| 41 | + |
| 42 | +// ---------- toolbar actions ---------- |
| 43 | + |
| 44 | +/** The familiar cube, with a small sigma badge that spells out "aggregate". */ |
| 45 | +export const AggregationIcon = createIcon( |
| 46 | + <> |
| 47 | + <path d="M2.5 6.5l7-4 7 4-7 4z" /> |
| 48 | + <path d="M2.5 6.5v8l7 4v-8M16.5 6.5v4.25M9.5 18.5l2.25-1.29" /> |
| 49 | + <path d="M20.75 15.25V13.5h-6.5l3.5 4-3.5 4h6.5v-1.75" /> |
| 50 | + </> |
| 51 | +); |
| 52 | + |
| 53 | +export const MarkTypeIcon = createIcon( |
| 54 | + <> |
| 55 | + <rect x="3.5" y="10" width="5" height="10.5" rx="1" /> |
| 56 | + <circle cx="16.5" cy="7" r="3.5" /> |
| 57 | + <path d="M12.5 20.5l8-6.5" /> |
| 58 | + </> |
| 59 | +); |
| 60 | + |
| 61 | +export const TransposeIcon = createIcon( |
| 62 | + <> |
| 63 | + <rect x="3" y="3.5" width="12" height="5" rx="1" /> |
| 64 | + <rect x="15.5" y="9" width="5" height="12" rx="1" /> |
| 65 | + <path d="M5.5 12v3.5a4 4 0 0 0 4 4H12" /> |
| 66 | + <path d="M3.5 14l2-2 2 2M10 17.5l2 2-2 2" /> |
| 67 | + </> |
| 68 | +); |
| 69 | + |
| 70 | +export const SortAscendingIcon = createIcon( |
| 71 | + <> |
| 72 | + <path d="M3.5 20.5v-4M8 20.5v-8M12.5 20.5v-12" /> |
| 73 | + <path d="M18.5 20.5v-16m-2.75 2.75 2.75-2.75 2.75 2.75" /> |
| 74 | + </> |
| 75 | +); |
| 76 | + |
| 77 | +export const SortDescendingIcon = createIcon( |
| 78 | + <> |
| 79 | + <path d="M3.5 20.5v-12M8 20.5v-8M12.5 20.5v-4" /> |
| 80 | + <path d="M18.5 4.5v16m-2.75-2.75 2.75 2.75 2.75-2.75" /> |
| 81 | + </> |
| 82 | +); |
| 83 | + |
| 84 | +export const TableSummaryIcon = createIcon( |
| 85 | + <> |
| 86 | + <rect x="3" y="4.5" width="18" height="15" rx="1.5" /> |
| 87 | + <path d="M3 9.5h18M9.5 4.5v10" /> |
| 88 | + <path {...tint} d="M3 14.5h18V18a1.5 1.5 0 0 1-1.5 1.5h-15A1.5 1.5 0 0 1 3 18z" /> |
| 89 | + </> |
| 90 | +); |
| 91 | + |
| 92 | +export const ComputedFieldIcon = createIcon( |
| 93 | + <> |
| 94 | + <path d="M11 5c-2.2-.9-3.7.1-4 2.2L5.6 17c-.3 2-1.6 2.9-3.4 2.3M4 10.5h6" /> |
| 95 | + <path d="M12.5 13l5 6.5M17.5 13l-5 6.5" /> |
| 96 | + <path d="M19 3.5v5M16.5 6h5" /> |
| 97 | + </> |
| 98 | +); |
| 99 | + |
| 100 | +export const AxesZoomIcon = createIcon( |
| 101 | + <> |
| 102 | + <path d="M3.5 3.5v17h17" /> |
| 103 | + <circle cx="12.5" cy="10" r="4.25" /> |
| 104 | + <path d="M15.6 13.1l3.9 3.9" /> |
| 105 | + </> |
| 106 | +); |
| 107 | + |
| 108 | +export const LayoutSizeIcon = createIcon( |
| 109 | + <> |
| 110 | + <rect x="3.5" y="8.5" width="12" height="12" rx="1.5" /> |
| 111 | + <path d="M3.5 4.5h12m-10-2-2 2 2 2m8-4 2 2-2 2" /> |
| 112 | + <path d="M19.5 8.5v12m-2-10 2-2 2 2m-4 8 2 2 2-2" /> |
| 113 | + </> |
| 114 | +); |
| 115 | + |
| 116 | +export const CoordSystemIcon = createIcon(<path d="M5 3v16h16M3 5l2-2 2 2M19 17l2 2-2 2" />); |
| 117 | + |
| 118 | +export const DebugIcon = createIcon( |
| 119 | + <> |
| 120 | + <path d="M8 11a4 4 0 0 1 8 0v4.5a4 4 0 0 1-8 0z" /> |
| 121 | + <path d="M12 11v8.5M9.3 7.9 7.5 5.5M14.7 7.9l1.8-2.4M8 12H4.5M8 16l-3 1.5M16 12h3.5M16 16l3 1.5" /> |
| 122 | + </> |
| 123 | +); |
| 124 | + |
| 125 | +export const ExportChartIcon = createIcon( |
| 126 | + <> |
| 127 | + <path d="M12 19.5H5.5A1.5 1.5 0 0 1 4 18V6a1.5 1.5 0 0 1 1.5-1.5h13A1.5 1.5 0 0 1 20 6v5" /> |
| 128 | + <path d="M4 15.5l4-4 4 4" /> |
| 129 | + <circle cx="14.5" cy="8.5" r="1.25" /> |
| 130 | + <path d="M18 14v7m-3-3 3 3 3-3" /> |
| 131 | + </> |
| 132 | +); |
| 133 | + |
| 134 | +export const ExportCsvIcon = createIcon( |
| 135 | + <> |
| 136 | + <path d="M12 19.5H5.5A1.5 1.5 0 0 1 4 18V6a1.5 1.5 0 0 1 1.5-1.5h13A1.5 1.5 0 0 1 20 6v5" /> |
| 137 | + <path d="M4 9.5h16M4 14.5h8M10 4.5v15" /> |
| 138 | + <path d="M18 14v7m-3-3 3 3 3-3" /> |
| 139 | + </> |
| 140 | +); |
| 141 | + |
| 142 | +export const RowLimitIcon = createIcon( |
| 143 | + <> |
| 144 | + <path d="M4 5h16M4 9.5h16" /> |
| 145 | + <path strokeDasharray="2 2.5" d="M2.5 14h19" /> |
| 146 | + <path opacity={0.35} d="M4 18.5h16" /> |
| 147 | + </> |
| 148 | +); |
| 149 | + |
| 150 | +// ---------- mark types ---------- |
| 151 | + |
| 152 | +export const MarkAutoIcon = createIcon( |
| 153 | + <> |
| 154 | + <rect x="3.5" y="3.5" width="17" height="17" rx="3" strokeDasharray="2.5 2.5" /> |
| 155 | + <path d="M8.5 16.5 12 7.5l3.5 9M9.8 13.5h4.4" /> |
| 156 | + </> |
| 157 | +); |
| 158 | + |
| 159 | +export const MarkBarIcon = createIcon( |
| 160 | + <> |
| 161 | + <rect x="4" y="12" width="4" height="8.5" rx=".75" /> |
| 162 | + <rect x="10" y="4" width="4" height="16.5" rx=".75" /> |
| 163 | + <rect x="16" y="8.5" width="4" height="12" rx=".75" /> |
| 164 | + </> |
| 165 | +); |
| 166 | + |
| 167 | +export const MarkLineIcon = createIcon(<path d="M3 17.5l5.5-7 4.5 3.5L20.5 5" />); |
| 168 | + |
| 169 | +export const MarkAreaIcon = createIcon(<path {...tint} d="M3 20.5v-6l5.5-5 4.5 3.5L21 5v15.5z" />); |
| 170 | + |
| 171 | +export const MarkTrailIcon = createIcon(<path {...tint} d="M3 16.5 9 10.5l5 2.5 7-9v6l-7 7.5-5-4.5z" />); |
| 172 | + |
| 173 | +export const MarkPointIcon = createIcon( |
| 174 | + <> |
| 175 | + <path d="M3.5 3.5v17h17" /> |
| 176 | + <circle cx="8" cy="15.5" r="1.5" /> |
| 177 | + <circle cx="11.5" cy="10" r="1.5" /> |
| 178 | + <circle cx="15.5" cy="13" r="1.5" /> |
| 179 | + <circle cx="18.5" cy="6.5" r="1.5" /> |
| 180 | + </> |
| 181 | +); |
| 182 | + |
| 183 | +export const MarkCircleIcon = createIcon( |
| 184 | + <> |
| 185 | + <circle {...tint} cx="8.5" cy="14.5" r="4.5" /> |
| 186 | + <circle {...tint} cx="17" cy="7.5" r="3" /> |
| 187 | + <circle {...tint} cx="18" cy="17.5" r="1.75" /> |
| 188 | + </> |
| 189 | +); |
| 190 | + |
| 191 | +export const MarkTickIcon = createIcon(<path d="M4 7v10M7.5 7v10M10 7v10M15 7v10M20 7v10" />); |
| 192 | + |
| 193 | +export const MarkRectIcon = createIcon( |
| 194 | + <> |
| 195 | + <rect x="3.5" y="3.5" width="17" height="17" rx="1.5" /> |
| 196 | + <path d="M3.5 9.17h17M3.5 14.83h17M9.17 3.5v17M14.83 3.5v17" /> |
| 197 | + <path fill="currentColor" stroke="none" opacity={0.3} d="M9.17 3.5h5.66v5.67H9.17zM14.83 9.17H20.5v5.66h-5.67zM3.5 14.83h5.67V20.5H3.5z" /> |
| 198 | + </> |
| 199 | +); |
| 200 | + |
| 201 | +export const MarkArcIcon = createIcon( |
| 202 | + <> |
| 203 | + <path d="M10.5 6a7.5 7.5 0 1 0 7.5 7.5h-7.5V6Z" /> |
| 204 | + <path d="M13.5 10.5H21A7.5 7.5 0 0 0 13.5 3v7.5Z" /> |
| 205 | + </> |
| 206 | +); |
| 207 | + |
| 208 | +export const MarkTextIcon = createIcon(<path d="M5 7V4.5h14V7M12 4.5v15M9 19.5h6" />); |
| 209 | + |
| 210 | +export const MarkBoxplotIcon = createIcon( |
| 211 | + <> |
| 212 | + <path d="M12 3v4M12 17v4M9 3h6M9 21h6M7 12.5h10" /> |
| 213 | + <rect x="7" y="7" width="10" height="10" rx="1" /> |
| 214 | + </> |
| 215 | +); |
| 216 | + |
| 217 | +export const MarkTableIcon = createIcon( |
| 218 | + <> |
| 219 | + <rect x="3" y="4.5" width="18" height="15" rx="1.5" /> |
| 220 | + <path d="M3 9.5h18M3 14.5h18M9.5 4.5v15" /> |
| 221 | + </> |
| 222 | +); |
| 223 | + |
| 224 | +export const MarkChoroplethIcon = createIcon( |
| 225 | + <> |
| 226 | + <path d="M3.5 6.5 9 4l6 2.5L20.5 4v13.5L15 20l-6-2.5L3.5 20z" /> |
| 227 | + <path {...tint} d="M9 4l6 2.5V20l-6-2.5z" /> |
| 228 | + </> |
| 229 | +); |
| 230 | + |
| 231 | +// ---------- stack modes ---------- |
| 232 | + |
| 233 | +export const StackNoneIcon = createIcon( |
| 234 | + <> |
| 235 | + <rect {...tint} x="4" y="7" width="9" height="13.5" rx="1" /> |
| 236 | + <rect x="11" y="12" width="9" height="8.5" rx="1" /> |
| 237 | + </> |
| 238 | +); |
| 239 | + |
| 240 | +export const StackIcon = createIcon( |
| 241 | + <> |
| 242 | + {stackedColumn(3.25, 11, 16)} |
| 243 | + {stackedColumn(9.75, 4, 13)} |
| 244 | + {stackedColumn(16.25, 8, 15)} |
| 245 | + </> |
| 246 | +); |
| 247 | + |
| 248 | +export const StackNormalizeIcon = createIcon( |
| 249 | + <> |
| 250 | + {stackedColumn(3.25, 3.5, 14)} |
| 251 | + {stackedColumn(9.75, 3.5, 9)} |
| 252 | + {stackedColumn(16.25, 3.5, 12)} |
| 253 | + </> |
| 254 | +); |
| 255 | + |
| 256 | +export const StackCenterIcon = createIcon( |
| 257 | + <> |
| 258 | + <rect x="3.25" y="7" width="4.5" height="10" rx=".75" /> |
| 259 | + <path {...tint} d="M3.25 12h4.5v5h-4.5z" /> |
| 260 | + <rect x="9.75" y="3.5" width="4.5" height="17" rx=".75" /> |
| 261 | + <path {...tint} d="M9.75 12h4.5v8.5h-4.5z" /> |
| 262 | + <rect x="16.25" y="6" width="4.5" height="12" rx=".75" /> |
| 263 | + <path {...tint} d="M16.25 12h4.5v6h-4.5z" /> |
| 264 | + </> |
| 265 | +); |
| 266 | + |
| 267 | +// ---------- layout modes ---------- |
| 268 | + |
| 269 | +export const LayoutFixedIcon = createIcon( |
| 270 | + <> |
| 271 | + <rect x="7.5" y="7.5" width="13" height="13" rx="1.5" /> |
| 272 | + <path d="M3.5 7.5v13M3.5 10.75H5M3.5 14H5M3.5 17.25H5M7.5 3.5h13M10.75 3.5V5M14 3.5V5M17.25 3.5V5" /> |
| 273 | + </> |
| 274 | +); |
| 275 | + |
| 276 | +export const LayoutAutoIcon = createIcon( |
| 277 | + <> |
| 278 | + <rect x="8" y="7" width="8" height="10" rx="1.5" /> |
| 279 | + <path d="M2 12h3.5m-2-2 2 2-2 2M22 12h-3.5m2-2-2 2 2 2" /> |
| 280 | + </> |
| 281 | +); |
| 282 | + |
| 283 | +export const LayoutFullIcon = createIcon( |
| 284 | + <> |
| 285 | + <rect x="3" y="3" width="18" height="18" rx="2" /> |
| 286 | + <path d="M13.5 10.5l4-4m-3 0h3v3M10.5 13.5l-4 4m0-3v3h3" /> |
| 287 | + </> |
| 288 | +); |
| 289 | + |
| 290 | +// ---------- coordinate systems ---------- |
| 291 | + |
| 292 | +export const CoordGenericIcon = createIcon( |
| 293 | + <> |
| 294 | + <path d="M5 3v16h16M3 5l2-2 2 2M19 17l2 2-2 2" /> |
| 295 | + <circle cx="14" cy="9.5" r="1.5" /> |
| 296 | + <path strokeDasharray="1.5 2" d="M14 12.5V19M5 9.5h6" /> |
| 297 | + </> |
| 298 | +); |
0 commit comments