diff --git a/packages/react-components/src/index.mjs b/packages/react-components/src/index.mjs
index 04c7d646d50..a5d18224b06 100644
--- a/packages/react-components/src/index.mjs
+++ b/packages/react-components/src/index.mjs
@@ -1,4 +1,5 @@
// Components
+// Pattern
import { Pattern as PatternComponent } from './pattern/index.mjs'
import { Svg as SvgComponent } from './pattern/svg.mjs'
import { Defs as DefsComponent } from './pattern/defs.mjs'
@@ -12,6 +13,8 @@ import { Grid as GridComponent } from './pattern/grid.mjs'
import { Text as TextComponent, TextOnPath as TextOnPathComponent } from './pattern/text.mjs'
// Pattern Utils
import { getProps, withinPartBounds, getId, translateStrings } from './pattern/utils.mjs'
+// PatternXray
+import { PatternXray as PatternXrayComponent } from './pattern-xray/index.mjs'
/*
* Export all components as named exports
@@ -28,6 +31,7 @@ export const Snippet = SnippetComponent
export const Grid = GridComponent
export const Text = TextComponent
export const TextOnPath = TextOnPathComponent
+export const PatternXray = PatternXrayComponent
/*
* Export pattern utils
diff --git a/packages/react-components/src/pattern-xray/index.mjs b/packages/react-components/src/pattern-xray/index.mjs
new file mode 100644
index 00000000000..1754b025b86
--- /dev/null
+++ b/packages/react-components/src/pattern-xray/index.mjs
@@ -0,0 +1,71 @@
+// eslint-disable-next-line no-unused-vars
+import React, { forwardRef } from 'react'
+import { defaultPatternComponents } from '../pattern/index.mjs'
+// Components that can be swizzled
+import { PointXray } from './point.mjs'
+import { PathXray } from './path.mjs'
+/*
+ * Allow people to swizzle these components
+ */
+export const defaultPatternXrayComponents = {
+ ...defaultPatternComponents,
+ Point: PointXray,
+ Path: PathXray,
+}
+
+export const PatternXray = forwardRef(
+ (
+ {
+ renderProps = false,
+ t = (string) => string,
+ components = {},
+ children = false,
+ className = 'freesewing pattern',
+ },
+ ref
+ ) => {
+ if (!renderProps) return null
+
+ // Merge default and swizzled components
+ components = {
+ ...defaultPatternXrayComponents,
+ ...components,
+ }
+
+ const { Svg, Defs, Stack, Group } = components
+
+ const optionalProps = {}
+ if (className) optionalProps.className = className
+
+ return (
+
+ )
+ }
+)
+
+PatternXray.displayName = 'PatternXray'
diff --git a/packages/react-components/src/pattern-xray/path.mjs b/packages/react-components/src/pattern-xray/path.mjs
new file mode 100644
index 00000000000..d276bc9c361
--- /dev/null
+++ b/packages/react-components/src/pattern-xray/path.mjs
@@ -0,0 +1,53 @@
+// Components
+import { Path } from '../pattern/path.mjs'
+import { getProps, getId } from '../pattern/utils.mjs'
+
+const coords = (point) => `${point.x},${point.y}`
+
+const Cp = ({ at }) => (
+
+)
+
+const Xray = ({ stackName, pathName, path, t, inspector }) => {
+ const output = []
+ let prev
+ let i = 0
+ for (const op of path.ops) {
+ if (op.type === 'curve') {
+ output.push(
+ ,
+ ,
+
+ )
+ }
+ prev = op
+ i++
+ }
+ output.push(
+
+ )
+
+ return output
+}
+
+export const PathXray = ({
+ stackName,
+ pathName,
+ part,
+ path,
+ settings,
+ components,
+ t,
+ inspector,
+}) => (
+ <>
+
+
+ >
+)
diff --git a/packages/react-components/src/pattern-xray/point.mjs b/packages/react-components/src/pattern-xray/point.mjs
new file mode 100644
index 00000000000..040b036b2a3
--- /dev/null
+++ b/packages/react-components/src/pattern-xray/point.mjs
@@ -0,0 +1,19 @@
+// Components
+import { Point } from '../pattern/point.mjs'
+import { withinPartBounds } from '../pattern/utils.mjs'
+
+export const PointXray = ({ stackName, pointName, part, point, settings, components, t }) => {
+ // Don't include parts outside the part bounding box
+ if (!withinPartBounds(point, part)) return null
+ return (
+ <>
+
+
+ >
+ )
+}
diff --git a/packages/react-components/src/pattern/index.mjs b/packages/react-components/src/pattern/index.mjs
index 54fdc41b0ea..652a59637cd 100644
--- a/packages/react-components/src/pattern/index.mjs
+++ b/packages/react-components/src/pattern/index.mjs
@@ -16,7 +16,7 @@ import { Circle as DefaultCircle } from './circle.mjs'
/*
* Allow people to swizzle these components
*/
-const defaultComponents = {
+export const defaultPatternComponents = {
Svg: DefaultSvg,
Defs: DefaultDefs,
Group: DefaultGroup,
@@ -46,7 +46,7 @@ export const Pattern = forwardRef(
// Merge default and swizzled components
components = {
- ...defaultComponents,
+ ...defaultPatternComponents,
...components,
}