@tatamicks/core 0.2.2 → 0.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../node_modules/react/cjs/react-jsx-runtime.production.min.js","../../../node_modules/react/cjs/react-jsx-runtime.development.js","../../../node_modules/react/jsx-runtime.js","../src/plugin/Alignment/schemas.ts","../src/properties/components/Select/Select.tsx","../src/plugin/Alignment/definition.ts","../src/properties/components/Checkbox/Checkbox.tsx","../src/utils/color/func.ts","../src/utils/color/types.ts","../src/properties/components/ColorPicker/ColorPalette.tsx","../src/properties/components/NumberInput/NumberInput.tsx","../src/properties/components/ColorPicker/RGBAInputs.tsx","../src/utils/zIndex/constants.ts","../src/properties/components/ColorPicker/ColorPickerPopover.tsx","../src/properties/components/ColorPicker/ColorPicker.tsx","../src/properties/components/DimensionInput/DimensionInput.tsx","../src/properties/components/TabPanel/TabPanel.tsx","../src/properties/components/Tabs/Tabs.tsx","../src/properties/components/TextInput/TextInput.tsx","../src/types/unit/index.ts","../src/plugin/Padding/definition.ts","../src/plugin/common/universalProperties.ts","../src/plugin/FontStyle/definition.ts","../src/plugin/func.ts","../src/plugin/Image/schemas.ts","../src/plugin/Image/definition.ts","../src/plugin/Multiline/schemas.ts","../src/plugin/Multiline/definition.ts","../src/plugin/Placeholder/definition.ts","../src/plugin/Size/definition.ts","../src/plugin/utils/func.ts","../src/plugin/utils/block.ts","../src/plugin/Validation/definition.ts","../src/types/block/events.ts","../src/types/grid/types.ts","../src/types/line/types.ts","../src/constants/index.ts","../src/utils/assert/number.ts","../src/utils/convert/toPx.ts","../src/types/line/func.ts","../src/types/mode/index.ts","../src/types/paper/types.ts","../src/types/schema/index.ts","../src/types/validation/index.ts","../src/canvas/components/BorderRenderer/BorderRenderer.tsx","../src/utils/zIndex/helpers.ts","../src/canvas/BlockLayer/BlockBorder/BlockBorder.tsx","../src/canvas/BlockLayer/BlockCanvas/BlockCanvas.tsx","../src/canvas/BlockLayer/BlockGuideBorder/constants.ts","../src/canvas/BlockLayer/BlockGuideBorder/BlockGuideBorder.tsx","../src/canvas/BlockLayer/BlockRenderer/BlockRenderer.tsx","../src/utils/blockLayout/getBlockContainerStyle.ts","../src/canvas/BlockLayer/BlockContainer/BlockContainer.tsx","../src/canvas/BlockLayer/BlockLayer.tsx","../src/canvas/GridLayer/BorderOverlay/BorderOverlay.tsx","../src/canvas/GridLayer/GridCanvas/GridCanvas.tsx","../src/utils/convert/toDimension.ts","../src/utils/convert/toMm.ts","../src/utils/convert/toString.ts","../src/canvas/GridLayer/GridDimensionLabel/GridUnitEditor.tsx","../src/canvas/GridLayer/GridDimensionLabel/GridDimensionLabel.tsx","../src/canvas/GridLayer/GridOverlay/getGridPathD.ts","../src/canvas/GridLayer/GridOverlay/GridOverlay.tsx","../src/canvas/GridLayer/GridResizeHandle/GridResizeHandle.tsx","../src/canvas/GridLayer/MarginOverlay/MarginOverlay.tsx","../src/canvas/GridLayer/GridLayer.tsx","../src/utils/GlobalDragStore/GlobalDragStore.ts","../src/utils/grid/calculateGridResize.ts","../src/utils/grid/distributeRemainder.ts","../src/utils/grid/findGridIndex.ts","../src/utils/grid/gridToMms.ts","../src/utils/grid/mmsToPxs.ts","../src/utils/grid/gridToPxs.ts","../src/utils/objectUtils.ts","../src/utils/print/index.ts","../src/utils/schema/validate.ts","../src/utils/schema/deserialize.ts","../src/utils/schema/serialize.ts","../src/utils/values/validate.ts","../src/utils/values/deserialize.ts","../src/utils/values/serialize.ts","../src/canvas/InteractionLayer/InteractionBlock/constants.ts","../src/canvas/InteractionLayer/types.ts","../src/canvas/InteractionLayer/InteractionBlock/ResizeHandles.tsx","../src/canvas/InteractionLayer/InteractionBlock/SelectionBorder.tsx","../src/canvas/InteractionLayer/InteractionBlock/InteractionBlock.tsx","../src/canvas/InteractionLayer/DragLayer/InsertGhost.tsx","../src/canvas/InteractionLayer/utils/clampMultipleBlocks.ts","../src/canvas/InteractionLayer/DragLayer/MovingGhost.tsx","../src/canvas/InteractionLayer/utils/calcResize.ts","../src/canvas/InteractionLayer/DragLayer/ResizeGhost.tsx","../src/canvas/InteractionLayer/DragLayer/DragLayer.tsx","../src/canvas/InteractionLayer/EditingBlock/EditingBlock.tsx","../src/canvas/InteractionLayer/hooks/useInteractionState.ts","../src/canvas/InteractionLayer/SelectionLayer/SelectionLayer.tsx","../src/canvas/InteractionLayer/utils/clampBlock.ts","../src/canvas/InteractionLayer/utils/hitTest.ts","../src/canvas/InteractionLayer/InteractionLayer.tsx","../src/hooks/useGridCalc/index.ts","../src/canvas/NoteEdit.tsx","../src/canvas/NoteForm.tsx","../src/canvas/NoteView.tsx","../src/canvas/NoteEditor.tsx","../src/canvas/NotePrint.tsx","../src/properties/utils/getCommonValue.ts","../src/properties/BlockPropertyPanel/BasePanels/BackgroundPanel/BackgroundPanel.tsx","../src/properties/BlockPropertyPanel/BasePanels/BorderPanel/BorderPanel.tsx","../src/properties/BlockPropertyPanel/BasePanels/LayoutPanel/LayoutPanel.tsx","../src/properties/BlockPropertyPanel/BasePanels/MetaPanel/MetaPanel.tsx","../src/properties/BlockPropertyPanel/PluginPanels/PropertyField.tsx","../src/properties/BlockPropertyPanel/BlockPropertyPanel.tsx","../src/properties/BlockPropertyPanel/PluginPanels/PluginPanels.tsx","../src/properties/CanvasPanel/BlockOrderPanel/BlockOrderPanel.tsx","../src/properties/CanvasPanel/CanvasPanel.tsx","../src/properties/CanvasPanel/GridSizePanel/GridSizePanel.tsx","../src/properties/CanvasPanel/MarginPanel/MarginPanel.tsx","../src/properties/CanvasPanel/PaperSizePanel/PaperSizePanel.tsx","../src/properties/OtherPanel/ImportExportPanel/ImportExportPanel.tsx","../src/properties/OtherPanel/OtherPanel.tsx","../src/properties/PalettePanel/PalettePanel.tsx","../src/properties/Sidebar/Sidebar.tsx"],"sourcesContent":["/**\n * @license React\n * react-jsx-runtime.production.min.js\n *\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n'use strict';var f=require(\"react\"),k=Symbol.for(\"react.element\"),l=Symbol.for(\"react.fragment\"),m=Object.prototype.hasOwnProperty,n=f.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,p={key:!0,ref:!0,__self:!0,__source:!0};\nfunction q(c,a,g){var b,d={},e=null,h=null;void 0!==g&&(e=\"\"+g);void 0!==a.key&&(e=\"\"+a.key);void 0!==a.ref&&(h=a.ref);for(b in a)m.call(a,b)&&!p.hasOwnProperty(b)&&(d[b]=a[b]);if(c&&c.defaultProps)for(b in a=c.defaultProps,a)void 0===d[b]&&(d[b]=a[b]);return{$$typeof:k,type:c,key:e,ref:h,props:d,_owner:n.current}}exports.Fragment=l;exports.jsx=q;exports.jsxs=q;\n","/**\n * @license React\n * react-jsx-runtime.development.js\n *\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n'use strict';\n\nif (process.env.NODE_ENV !== \"production\") {\n (function() {\n'use strict';\n\nvar React = require('react');\n\n// ATTENTION\n// When adding new symbols to this file,\n// Please consider also adding to 'react-devtools-shared/src/backend/ReactSymbols'\n// The Symbol used to tag the ReactElement-like types.\nvar REACT_ELEMENT_TYPE = Symbol.for('react.element');\nvar REACT_PORTAL_TYPE = Symbol.for('react.portal');\nvar REACT_FRAGMENT_TYPE = Symbol.for('react.fragment');\nvar REACT_STRICT_MODE_TYPE = Symbol.for('react.strict_mode');\nvar REACT_PROFILER_TYPE = Symbol.for('react.profiler');\nvar REACT_PROVIDER_TYPE = Symbol.for('react.provider');\nvar REACT_CONTEXT_TYPE = Symbol.for('react.context');\nvar REACT_FORWARD_REF_TYPE = Symbol.for('react.forward_ref');\nvar REACT_SUSPENSE_TYPE = Symbol.for('react.suspense');\nvar REACT_SUSPENSE_LIST_TYPE = Symbol.for('react.suspense_list');\nvar REACT_MEMO_TYPE = Symbol.for('react.memo');\nvar REACT_LAZY_TYPE = Symbol.for('react.lazy');\nvar REACT_OFFSCREEN_TYPE = Symbol.for('react.offscreen');\nvar MAYBE_ITERATOR_SYMBOL = Symbol.iterator;\nvar FAUX_ITERATOR_SYMBOL = '@@iterator';\nfunction getIteratorFn(maybeIterable) {\n if (maybeIterable === null || typeof maybeIterable !== 'object') {\n return null;\n }\n\n var maybeIterator = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL];\n\n if (typeof maybeIterator === 'function') {\n return maybeIterator;\n }\n\n return null;\n}\n\nvar ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;\n\nfunction error(format) {\n {\n {\n for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {\n args[_key2 - 1] = arguments[_key2];\n }\n\n printWarning('error', format, args);\n }\n }\n}\n\nfunction printWarning(level, format, args) {\n // When changing this logic, you might want to also\n // update consoleWithStackDev.www.js as well.\n {\n var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;\n var stack = ReactDebugCurrentFrame.getStackAddendum();\n\n if (stack !== '') {\n format += '%s';\n args = args.concat([stack]);\n } // eslint-disable-next-line react-internal/safe-string-coercion\n\n\n var argsWithFormat = args.map(function (item) {\n return String(item);\n }); // Careful: RN currently depends on this prefix\n\n argsWithFormat.unshift('Warning: ' + format); // We intentionally don't use spread (or .apply) directly because it\n // breaks IE9: https://github.com/facebook/react/issues/13610\n // eslint-disable-next-line react-internal/no-production-logging\n\n Function.prototype.apply.call(console[level], console, argsWithFormat);\n }\n}\n\n// -----------------------------------------------------------------------------\n\nvar enableScopeAPI = false; // Experimental Create Event Handle API.\nvar enableCacheElement = false;\nvar enableTransitionTracing = false; // No known bugs, but needs performance testing\n\nvar enableLegacyHidden = false; // Enables unstable_avoidThisFallback feature in Fiber\n// stuff. Intended to enable React core members to more easily debug scheduling\n// issues in DEV builds.\n\nvar enableDebugTracing = false; // Track which Fiber(s) schedule render work.\n\nvar REACT_MODULE_REFERENCE;\n\n{\n REACT_MODULE_REFERENCE = Symbol.for('react.module.reference');\n}\n\nfunction isValidElementType(type) {\n if (typeof type === 'string' || typeof type === 'function') {\n return true;\n } // Note: typeof might be other than 'symbol' or 'number' (e.g. if it's a polyfill).\n\n\n if (type === REACT_FRAGMENT_TYPE || type === REACT_PROFILER_TYPE || enableDebugTracing || type === REACT_STRICT_MODE_TYPE || type === REACT_SUSPENSE_TYPE || type === REACT_SUSPENSE_LIST_TYPE || enableLegacyHidden || type === REACT_OFFSCREEN_TYPE || enableScopeAPI || enableCacheElement || enableTransitionTracing ) {\n return true;\n }\n\n if (typeof type === 'object' && type !== null) {\n if (type.$$typeof === REACT_LAZY_TYPE || type.$$typeof === REACT_MEMO_TYPE || type.$$typeof === REACT_PROVIDER_TYPE || type.$$typeof === REACT_CONTEXT_TYPE || type.$$typeof === REACT_FORWARD_REF_TYPE || // This needs to include all possible module reference object\n // types supported by any Flight configuration anywhere since\n // we don't know which Flight build this will end up being used\n // with.\n type.$$typeof === REACT_MODULE_REFERENCE || type.getModuleId !== undefined) {\n return true;\n }\n }\n\n return false;\n}\n\nfunction getWrappedName(outerType, innerType, wrapperName) {\n var displayName = outerType.displayName;\n\n if (displayName) {\n return displayName;\n }\n\n var functionName = innerType.displayName || innerType.name || '';\n return functionName !== '' ? wrapperName + \"(\" + functionName + \")\" : wrapperName;\n} // Keep in sync with react-reconciler/getComponentNameFromFiber\n\n\nfunction getContextName(type) {\n return type.displayName || 'Context';\n} // Note that the reconciler package should generally prefer to use getComponentNameFromFiber() instead.\n\n\nfunction getComponentNameFromType(type) {\n if (type == null) {\n // Host root, text node or just invalid type.\n return null;\n }\n\n {\n if (typeof type.tag === 'number') {\n error('Received an unexpected object in getComponentNameFromType(). ' + 'This is likely a bug in React. Please file an issue.');\n }\n }\n\n if (typeof type === 'function') {\n return type.displayName || type.name || null;\n }\n\n if (typeof type === 'string') {\n return type;\n }\n\n switch (type) {\n case REACT_FRAGMENT_TYPE:\n return 'Fragment';\n\n case REACT_PORTAL_TYPE:\n return 'Portal';\n\n case REACT_PROFILER_TYPE:\n return 'Profiler';\n\n case REACT_STRICT_MODE_TYPE:\n return 'StrictMode';\n\n case REACT_SUSPENSE_TYPE:\n return 'Suspense';\n\n case REACT_SUSPENSE_LIST_TYPE:\n return 'SuspenseList';\n\n }\n\n if (typeof type === 'object') {\n switch (type.$$typeof) {\n case REACT_CONTEXT_TYPE:\n var context = type;\n return getContextName(context) + '.Consumer';\n\n case REACT_PROVIDER_TYPE:\n var provider = type;\n return getContextName(provider._context) + '.Provider';\n\n case REACT_FORWARD_REF_TYPE:\n return getWrappedName(type, type.render, 'ForwardRef');\n\n case REACT_MEMO_TYPE:\n var outerName = type.displayName || null;\n\n if (outerName !== null) {\n return outerName;\n }\n\n return getComponentNameFromType(type.type) || 'Memo';\n\n case REACT_LAZY_TYPE:\n {\n var lazyComponent = type;\n var payload = lazyComponent._payload;\n var init = lazyComponent._init;\n\n try {\n return getComponentNameFromType(init(payload));\n } catch (x) {\n return null;\n }\n }\n\n // eslint-disable-next-line no-fallthrough\n }\n }\n\n return null;\n}\n\nvar assign = Object.assign;\n\n// Helpers to patch console.logs to avoid logging during side-effect free\n// replaying on render function. This currently only patches the object\n// lazily which won't cover if the log function was extracted eagerly.\n// We could also eagerly patch the method.\nvar disabledDepth = 0;\nvar prevLog;\nvar prevInfo;\nvar prevWarn;\nvar prevError;\nvar prevGroup;\nvar prevGroupCollapsed;\nvar prevGroupEnd;\n\nfunction disabledLog() {}\n\ndisabledLog.__reactDisabledLog = true;\nfunction disableLogs() {\n {\n if (disabledDepth === 0) {\n /* eslint-disable react-internal/no-production-logging */\n prevLog = console.log;\n prevInfo = console.info;\n prevWarn = console.warn;\n prevError = console.error;\n prevGroup = console.group;\n prevGroupCollapsed = console.groupCollapsed;\n prevGroupEnd = console.groupEnd; // https://github.com/facebook/react/issues/19099\n\n var props = {\n configurable: true,\n enumerable: true,\n value: disabledLog,\n writable: true\n }; // $FlowFixMe Flow thinks console is immutable.\n\n Object.defineProperties(console, {\n info: props,\n log: props,\n warn: props,\n error: props,\n group: props,\n groupCollapsed: props,\n groupEnd: props\n });\n /* eslint-enable react-internal/no-production-logging */\n }\n\n disabledDepth++;\n }\n}\nfunction reenableLogs() {\n {\n disabledDepth--;\n\n if (disabledDepth === 0) {\n /* eslint-disable react-internal/no-production-logging */\n var props = {\n configurable: true,\n enumerable: true,\n writable: true\n }; // $FlowFixMe Flow thinks console is immutable.\n\n Object.defineProperties(console, {\n log: assign({}, props, {\n value: prevLog\n }),\n info: assign({}, props, {\n value: prevInfo\n }),\n warn: assign({}, props, {\n value: prevWarn\n }),\n error: assign({}, props, {\n value: prevError\n }),\n group: assign({}, props, {\n value: prevGroup\n }),\n groupCollapsed: assign({}, props, {\n value: prevGroupCollapsed\n }),\n groupEnd: assign({}, props, {\n value: prevGroupEnd\n })\n });\n /* eslint-enable react-internal/no-production-logging */\n }\n\n if (disabledDepth < 0) {\n error('disabledDepth fell below zero. ' + 'This is a bug in React. Please file an issue.');\n }\n }\n}\n\nvar ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;\nvar prefix;\nfunction describeBuiltInComponentFrame(name, source, ownerFn) {\n {\n if (prefix === undefined) {\n // Extract the VM specific prefix used by each line.\n try {\n throw Error();\n } catch (x) {\n var match = x.stack.trim().match(/\\n( *(at )?)/);\n prefix = match && match[1] || '';\n }\n } // We use the prefix to ensure our stacks line up with native stack frames.\n\n\n return '\\n' + prefix + name;\n }\n}\nvar reentry = false;\nvar componentFrameCache;\n\n{\n var PossiblyWeakMap = typeof WeakMap === 'function' ? WeakMap : Map;\n componentFrameCache = new PossiblyWeakMap();\n}\n\nfunction describeNativeComponentFrame(fn, construct) {\n // If something asked for a stack inside a fake render, it should get ignored.\n if ( !fn || reentry) {\n return '';\n }\n\n {\n var frame = componentFrameCache.get(fn);\n\n if (frame !== undefined) {\n return frame;\n }\n }\n\n var control;\n reentry = true;\n var previousPrepareStackTrace = Error.prepareStackTrace; // $FlowFixMe It does accept undefined.\n\n Error.prepareStackTrace = undefined;\n var previousDispatcher;\n\n {\n previousDispatcher = ReactCurrentDispatcher.current; // Set the dispatcher in DEV because this might be call in the render function\n // for warnings.\n\n ReactCurrentDispatcher.current = null;\n disableLogs();\n }\n\n try {\n // This should throw.\n if (construct) {\n // Something should be setting the props in the constructor.\n var Fake = function () {\n throw Error();\n }; // $FlowFixMe\n\n\n Object.defineProperty(Fake.prototype, 'props', {\n set: function () {\n // We use a throwing setter instead of frozen or non-writable props\n // because that won't throw in a non-strict mode function.\n throw Error();\n }\n });\n\n if (typeof Reflect === 'object' && Reflect.construct) {\n // We construct a different control for this case to include any extra\n // frames added by the construct call.\n try {\n Reflect.construct(Fake, []);\n } catch (x) {\n control = x;\n }\n\n Reflect.construct(fn, [], Fake);\n } else {\n try {\n Fake.call();\n } catch (x) {\n control = x;\n }\n\n fn.call(Fake.prototype);\n }\n } else {\n try {\n throw Error();\n } catch (x) {\n control = x;\n }\n\n fn();\n }\n } catch (sample) {\n // This is inlined manually because closure doesn't do it for us.\n if (sample && control && typeof sample.stack === 'string') {\n // This extracts the first frame from the sample that isn't also in the control.\n // Skipping one frame that we assume is the frame that calls the two.\n var sampleLines = sample.stack.split('\\n');\n var controlLines = control.stack.split('\\n');\n var s = sampleLines.length - 1;\n var c = controlLines.length - 1;\n\n while (s >= 1 && c >= 0 && sampleLines[s] !== controlLines[c]) {\n // We expect at least one stack frame to be shared.\n // Typically this will be the root most one. However, stack frames may be\n // cut off due to maximum stack limits. In this case, one maybe cut off\n // earlier than the other. We assume that the sample is longer or the same\n // and there for cut off earlier. So we should find the root most frame in\n // the sample somewhere in the control.\n c--;\n }\n\n for (; s >= 1 && c >= 0; s--, c--) {\n // Next we find the first one that isn't the same which should be the\n // frame that called our sample function and the control.\n if (sampleLines[s] !== controlLines[c]) {\n // In V8, the first line is describing the message but other VMs don't.\n // If we're about to return the first line, and the control is also on the same\n // line, that's a pretty good indicator that our sample threw at same line as\n // the control. I.e. before we entered the sample frame. So we ignore this result.\n // This can happen if you passed a class to function component, or non-function.\n if (s !== 1 || c !== 1) {\n do {\n s--;\n c--; // We may still have similar intermediate frames from the construct call.\n // The next one that isn't the same should be our match though.\n\n if (c < 0 || sampleLines[s] !== controlLines[c]) {\n // V8 adds a \"new\" prefix for native classes. Let's remove it to make it prettier.\n var _frame = '\\n' + sampleLines[s].replace(' at new ', ' at '); // If our component frame is labeled \"<anonymous>\"\n // but we have a user-provided \"displayName\"\n // splice it in to make the stack more readable.\n\n\n if (fn.displayName && _frame.includes('<anonymous>')) {\n _frame = _frame.replace('<anonymous>', fn.displayName);\n }\n\n {\n if (typeof fn === 'function') {\n componentFrameCache.set(fn, _frame);\n }\n } // Return the line we found.\n\n\n return _frame;\n }\n } while (s >= 1 && c >= 0);\n }\n\n break;\n }\n }\n }\n } finally {\n reentry = false;\n\n {\n ReactCurrentDispatcher.current = previousDispatcher;\n reenableLogs();\n }\n\n Error.prepareStackTrace = previousPrepareStackTrace;\n } // Fallback to just using the name if we couldn't make it throw.\n\n\n var name = fn ? fn.displayName || fn.name : '';\n var syntheticFrame = name ? describeBuiltInComponentFrame(name) : '';\n\n {\n if (typeof fn === 'function') {\n componentFrameCache.set(fn, syntheticFrame);\n }\n }\n\n return syntheticFrame;\n}\nfunction describeFunctionComponentFrame(fn, source, ownerFn) {\n {\n return describeNativeComponentFrame(fn, false);\n }\n}\n\nfunction shouldConstruct(Component) {\n var prototype = Component.prototype;\n return !!(prototype && prototype.isReactComponent);\n}\n\nfunction describeUnknownElementTypeFrameInDEV(type, source, ownerFn) {\n\n if (type == null) {\n return '';\n }\n\n if (typeof type === 'function') {\n {\n return describeNativeComponentFrame(type, shouldConstruct(type));\n }\n }\n\n if (typeof type === 'string') {\n return describeBuiltInComponentFrame(type);\n }\n\n switch (type) {\n case REACT_SUSPENSE_TYPE:\n return describeBuiltInComponentFrame('Suspense');\n\n case REACT_SUSPENSE_LIST_TYPE:\n return describeBuiltInComponentFrame('SuspenseList');\n }\n\n if (typeof type === 'object') {\n switch (type.$$typeof) {\n case REACT_FORWARD_REF_TYPE:\n return describeFunctionComponentFrame(type.render);\n\n case REACT_MEMO_TYPE:\n // Memo may contain any component type so we recursively resolve it.\n return describeUnknownElementTypeFrameInDEV(type.type, source, ownerFn);\n\n case REACT_LAZY_TYPE:\n {\n var lazyComponent = type;\n var payload = lazyComponent._payload;\n var init = lazyComponent._init;\n\n try {\n // Lazy may contain any component type so we recursively resolve it.\n return describeUnknownElementTypeFrameInDEV(init(payload), source, ownerFn);\n } catch (x) {}\n }\n }\n }\n\n return '';\n}\n\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\n\nvar loggedTypeFailures = {};\nvar ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;\n\nfunction setCurrentlyValidatingElement(element) {\n {\n if (element) {\n var owner = element._owner;\n var stack = describeUnknownElementTypeFrameInDEV(element.type, element._source, owner ? owner.type : null);\n ReactDebugCurrentFrame.setExtraStackFrame(stack);\n } else {\n ReactDebugCurrentFrame.setExtraStackFrame(null);\n }\n }\n}\n\nfunction checkPropTypes(typeSpecs, values, location, componentName, element) {\n {\n // $FlowFixMe This is okay but Flow doesn't know it.\n var has = Function.call.bind(hasOwnProperty);\n\n for (var typeSpecName in typeSpecs) {\n if (has(typeSpecs, typeSpecName)) {\n var error$1 = void 0; // Prop type validation may throw. In case they do, we don't want to\n // fail the render phase where it didn't fail before. So we log it.\n // After these have been cleaned up, we'll let them throw.\n\n try {\n // This is intentionally an invariant that gets caught. It's the same\n // behavior as without this statement except with a better message.\n if (typeof typeSpecs[typeSpecName] !== 'function') {\n // eslint-disable-next-line react-internal/prod-error-codes\n var err = Error((componentName || 'React class') + ': ' + location + ' type `' + typeSpecName + '` is invalid; ' + 'it must be a function, usually from the `prop-types` package, but received `' + typeof typeSpecs[typeSpecName] + '`.' + 'This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`.');\n err.name = 'Invariant Violation';\n throw err;\n }\n\n error$1 = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED');\n } catch (ex) {\n error$1 = ex;\n }\n\n if (error$1 && !(error$1 instanceof Error)) {\n setCurrentlyValidatingElement(element);\n\n error('%s: type specification of %s' + ' `%s` is invalid; the type checker ' + 'function must return `null` or an `Error` but returned a %s. ' + 'You may have forgotten to pass an argument to the type checker ' + 'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' + 'shape all require an argument).', componentName || 'React class', location, typeSpecName, typeof error$1);\n\n setCurrentlyValidatingElement(null);\n }\n\n if (error$1 instanceof Error && !(error$1.message in loggedTypeFailures)) {\n // Only monitor this failure once because there tends to be a lot of the\n // same error.\n loggedTypeFailures[error$1.message] = true;\n setCurrentlyValidatingElement(element);\n\n error('Failed %s type: %s', location, error$1.message);\n\n setCurrentlyValidatingElement(null);\n }\n }\n }\n }\n}\n\nvar isArrayImpl = Array.isArray; // eslint-disable-next-line no-redeclare\n\nfunction isArray(a) {\n return isArrayImpl(a);\n}\n\n/*\n * The `'' + value` pattern (used in in perf-sensitive code) throws for Symbol\n * and Temporal.* types. See https://github.com/facebook/react/pull/22064.\n *\n * The functions in this module will throw an easier-to-understand,\n * easier-to-debug exception with a clear errors message message explaining the\n * problem. (Instead of a confusing exception thrown inside the implementation\n * of the `value` object).\n */\n// $FlowFixMe only called in DEV, so void return is not possible.\nfunction typeName(value) {\n {\n // toStringTag is needed for namespaced types like Temporal.Instant\n var hasToStringTag = typeof Symbol === 'function' && Symbol.toStringTag;\n var type = hasToStringTag && value[Symbol.toStringTag] || value.constructor.name || 'Object';\n return type;\n }\n} // $FlowFixMe only called in DEV, so void return is not possible.\n\n\nfunction willCoercionThrow(value) {\n {\n try {\n testStringCoercion(value);\n return false;\n } catch (e) {\n return true;\n }\n }\n}\n\nfunction testStringCoercion(value) {\n // If you ended up here by following an exception call stack, here's what's\n // happened: you supplied an object or symbol value to React (as a prop, key,\n // DOM attribute, CSS property, string ref, etc.) and when React tried to\n // coerce it to a string using `'' + value`, an exception was thrown.\n //\n // The most common types that will cause this exception are `Symbol` instances\n // and Temporal objects like `Temporal.Instant`. But any object that has a\n // `valueOf` or `[Symbol.toPrimitive]` method that throws will also cause this\n // exception. (Library authors do this to prevent users from using built-in\n // numeric operators like `+` or comparison operators like `>=` because custom\n // methods are needed to perform accurate arithmetic or comparison.)\n //\n // To fix the problem, coerce this object or symbol value to a string before\n // passing it to React. The most reliable way is usually `String(value)`.\n //\n // To find which value is throwing, check the browser or debugger console.\n // Before this exception was thrown, there should be `console.error` output\n // that shows the type (Symbol, Temporal.PlainDate, etc.) that caused the\n // problem and how that type was used: key, atrribute, input value prop, etc.\n // In most cases, this console output also shows the component and its\n // ancestor components where the exception happened.\n //\n // eslint-disable-next-line react-internal/safe-string-coercion\n return '' + value;\n}\nfunction checkKeyStringCoercion(value) {\n {\n if (willCoercionThrow(value)) {\n error('The provided key is an unsupported type %s.' + ' This value must be coerced to a string before before using it here.', typeName(value));\n\n return testStringCoercion(value); // throw (to help callers find troubleshooting comments)\n }\n }\n}\n\nvar ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;\nvar RESERVED_PROPS = {\n key: true,\n ref: true,\n __self: true,\n __source: true\n};\nvar specialPropKeyWarningShown;\nvar specialPropRefWarningShown;\nvar didWarnAboutStringRefs;\n\n{\n didWarnAboutStringRefs = {};\n}\n\nfunction hasValidRef(config) {\n {\n if (hasOwnProperty.call(config, 'ref')) {\n var getter = Object.getOwnPropertyDescriptor(config, 'ref').get;\n\n if (getter && getter.isReactWarning) {\n return false;\n }\n }\n }\n\n return config.ref !== undefined;\n}\n\nfunction hasValidKey(config) {\n {\n if (hasOwnProperty.call(config, 'key')) {\n var getter = Object.getOwnPropertyDescriptor(config, 'key').get;\n\n if (getter && getter.isReactWarning) {\n return false;\n }\n }\n }\n\n return config.key !== undefined;\n}\n\nfunction warnIfStringRefCannotBeAutoConverted(config, self) {\n {\n if (typeof config.ref === 'string' && ReactCurrentOwner.current && self && ReactCurrentOwner.current.stateNode !== self) {\n var componentName = getComponentNameFromType(ReactCurrentOwner.current.type);\n\n if (!didWarnAboutStringRefs[componentName]) {\n error('Component \"%s\" contains the string ref \"%s\". ' + 'Support for string refs will be removed in a future major release. ' + 'This case cannot be automatically converted to an arrow function. ' + 'We ask you to manually fix this case by using useRef() or createRef() instead. ' + 'Learn more about using refs safely here: ' + 'https://reactjs.org/link/strict-mode-string-ref', getComponentNameFromType(ReactCurrentOwner.current.type), config.ref);\n\n didWarnAboutStringRefs[componentName] = true;\n }\n }\n }\n}\n\nfunction defineKeyPropWarningGetter(props, displayName) {\n {\n var warnAboutAccessingKey = function () {\n if (!specialPropKeyWarningShown) {\n specialPropKeyWarningShown = true;\n\n error('%s: `key` is not a prop. Trying to access it will result ' + 'in `undefined` being returned. If you need to access the same ' + 'value within the child component, you should pass it as a different ' + 'prop. (https://reactjs.org/link/special-props)', displayName);\n }\n };\n\n warnAboutAccessingKey.isReactWarning = true;\n Object.defineProperty(props, 'key', {\n get: warnAboutAccessingKey,\n configurable: true\n });\n }\n}\n\nfunction defineRefPropWarningGetter(props, displayName) {\n {\n var warnAboutAccessingRef = function () {\n if (!specialPropRefWarningShown) {\n specialPropRefWarningShown = true;\n\n error('%s: `ref` is not a prop. Trying to access it will result ' + 'in `undefined` being returned. If you need to access the same ' + 'value within the child component, you should pass it as a different ' + 'prop. (https://reactjs.org/link/special-props)', displayName);\n }\n };\n\n warnAboutAccessingRef.isReactWarning = true;\n Object.defineProperty(props, 'ref', {\n get: warnAboutAccessingRef,\n configurable: true\n });\n }\n}\n/**\n * Factory method to create a new React element. This no longer adheres to\n * the class pattern, so do not use new to call it. Also, instanceof check\n * will not work. Instead test $$typeof field against Symbol.for('react.element') to check\n * if something is a React Element.\n *\n * @param {*} type\n * @param {*} props\n * @param {*} key\n * @param {string|object} ref\n * @param {*} owner\n * @param {*} self A *temporary* helper to detect places where `this` is\n * different from the `owner` when React.createElement is called, so that we\n * can warn. We want to get rid of owner and replace string `ref`s with arrow\n * functions, and as long as `this` and owner are the same, there will be no\n * change in behavior.\n * @param {*} source An annotation object (added by a transpiler or otherwise)\n * indicating filename, line number, and/or other information.\n * @internal\n */\n\n\nvar ReactElement = function (type, key, ref, self, source, owner, props) {\n var element = {\n // This tag allows us to uniquely identify this as a React Element\n $$typeof: REACT_ELEMENT_TYPE,\n // Built-in properties that belong on the element\n type: type,\n key: key,\n ref: ref,\n props: props,\n // Record the component responsible for creating this element.\n _owner: owner\n };\n\n {\n // The validation flag is currently mutative. We put it on\n // an external backing store so that we can freeze the whole object.\n // This can be replaced with a WeakMap once they are implemented in\n // commonly used development environments.\n element._store = {}; // To make comparing ReactElements easier for testing purposes, we make\n // the validation flag non-enumerable (where possible, which should\n // include every environment we run tests in), so the test framework\n // ignores it.\n\n Object.defineProperty(element._store, 'validated', {\n configurable: false,\n enumerable: false,\n writable: true,\n value: false\n }); // self and source are DEV only properties.\n\n Object.defineProperty(element, '_self', {\n configurable: false,\n enumerable: false,\n writable: false,\n value: self\n }); // Two elements created in two different places should be considered\n // equal for testing purposes and therefore we hide it from enumeration.\n\n Object.defineProperty(element, '_source', {\n configurable: false,\n enumerable: false,\n writable: false,\n value: source\n });\n\n if (Object.freeze) {\n Object.freeze(element.props);\n Object.freeze(element);\n }\n }\n\n return element;\n};\n/**\n * https://github.com/reactjs/rfcs/pull/107\n * @param {*} type\n * @param {object} props\n * @param {string} key\n */\n\nfunction jsxDEV(type, config, maybeKey, source, self) {\n {\n var propName; // Reserved names are extracted\n\n var props = {};\n var key = null;\n var ref = null; // Currently, key can be spread in as a prop. This causes a potential\n // issue if key is also explicitly declared (ie. <div {...props} key=\"Hi\" />\n // or <div key=\"Hi\" {...props} /> ). We want to deprecate key spread,\n // but as an intermediary step, we will use jsxDEV for everything except\n // <div {...props} key=\"Hi\" />, because we aren't currently able to tell if\n // key is explicitly declared to be undefined or not.\n\n if (maybeKey !== undefined) {\n {\n checkKeyStringCoercion(maybeKey);\n }\n\n key = '' + maybeKey;\n }\n\n if (hasValidKey(config)) {\n {\n checkKeyStringCoercion(config.key);\n }\n\n key = '' + config.key;\n }\n\n if (hasValidRef(config)) {\n ref = config.ref;\n warnIfStringRefCannotBeAutoConverted(config, self);\n } // Remaining properties are added to a new props object\n\n\n for (propName in config) {\n if (hasOwnProperty.call(config, propName) && !RESERVED_PROPS.hasOwnProperty(propName)) {\n props[propName] = config[propName];\n }\n } // Resolve default props\n\n\n if (type && type.defaultProps) {\n var defaultProps = type.defaultProps;\n\n for (propName in defaultProps) {\n if (props[propName] === undefined) {\n props[propName] = defaultProps[propName];\n }\n }\n }\n\n if (key || ref) {\n var displayName = typeof type === 'function' ? type.displayName || type.name || 'Unknown' : type;\n\n if (key) {\n defineKeyPropWarningGetter(props, displayName);\n }\n\n if (ref) {\n defineRefPropWarningGetter(props, displayName);\n }\n }\n\n return ReactElement(type, key, ref, self, source, ReactCurrentOwner.current, props);\n }\n}\n\nvar ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner;\nvar ReactDebugCurrentFrame$1 = ReactSharedInternals.ReactDebugCurrentFrame;\n\nfunction setCurrentlyValidatingElement$1(element) {\n {\n if (element) {\n var owner = element._owner;\n var stack = describeUnknownElementTypeFrameInDEV(element.type, element._source, owner ? owner.type : null);\n ReactDebugCurrentFrame$1.setExtraStackFrame(stack);\n } else {\n ReactDebugCurrentFrame$1.setExtraStackFrame(null);\n }\n }\n}\n\nvar propTypesMisspellWarningShown;\n\n{\n propTypesMisspellWarningShown = false;\n}\n/**\n * Verifies the object is a ReactElement.\n * See https://reactjs.org/docs/react-api.html#isvalidelement\n * @param {?object} object\n * @return {boolean} True if `object` is a ReactElement.\n * @final\n */\n\n\nfunction isValidElement(object) {\n {\n return typeof object === 'object' && object !== null && object.$$typeof === REACT_ELEMENT_TYPE;\n }\n}\n\nfunction getDeclarationErrorAddendum() {\n {\n if (ReactCurrentOwner$1.current) {\n var name = getComponentNameFromType(ReactCurrentOwner$1.current.type);\n\n if (name) {\n return '\\n\\nCheck the render method of `' + name + '`.';\n }\n }\n\n return '';\n }\n}\n\nfunction getSourceInfoErrorAddendum(source) {\n {\n if (source !== undefined) {\n var fileName = source.fileName.replace(/^.*[\\\\\\/]/, '');\n var lineNumber = source.lineNumber;\n return '\\n\\nCheck your code at ' + fileName + ':' + lineNumber + '.';\n }\n\n return '';\n }\n}\n/**\n * Warn if there's no key explicitly set on dynamic arrays of children or\n * object keys are not valid. This allows us to keep track of children between\n * updates.\n */\n\n\nvar ownerHasKeyUseWarning = {};\n\nfunction getCurrentComponentErrorInfo(parentType) {\n {\n var info = getDeclarationErrorAddendum();\n\n if (!info) {\n var parentName = typeof parentType === 'string' ? parentType : parentType.displayName || parentType.name;\n\n if (parentName) {\n info = \"\\n\\nCheck the top-level render call using <\" + parentName + \">.\";\n }\n }\n\n return info;\n }\n}\n/**\n * Warn if the element doesn't have an explicit key assigned to it.\n * This element is in an array. The array could grow and shrink or be\n * reordered. All children that haven't already been validated are required to\n * have a \"key\" property assigned to it. Error statuses are cached so a warning\n * will only be shown once.\n *\n * @internal\n * @param {ReactElement} element Element that requires a key.\n * @param {*} parentType element's parent's type.\n */\n\n\nfunction validateExplicitKey(element, parentType) {\n {\n if (!element._store || element._store.validated || element.key != null) {\n return;\n }\n\n element._store.validated = true;\n var currentComponentErrorInfo = getCurrentComponentErrorInfo(parentType);\n\n if (ownerHasKeyUseWarning[currentComponentErrorInfo]) {\n return;\n }\n\n ownerHasKeyUseWarning[currentComponentErrorInfo] = true; // Usually the current owner is the offender, but if it accepts children as a\n // property, it may be the creator of the child that's responsible for\n // assigning it a key.\n\n var childOwner = '';\n\n if (element && element._owner && element._owner !== ReactCurrentOwner$1.current) {\n // Give the component that originally created this child.\n childOwner = \" It was passed a child from \" + getComponentNameFromType(element._owner.type) + \".\";\n }\n\n setCurrentlyValidatingElement$1(element);\n\n error('Each child in a list should have a unique \"key\" prop.' + '%s%s See https://reactjs.org/link/warning-keys for more information.', currentComponentErrorInfo, childOwner);\n\n setCurrentlyValidatingElement$1(null);\n }\n}\n/**\n * Ensure that every element either is passed in a static location, in an\n * array with an explicit keys property defined, or in an object literal\n * with valid key property.\n *\n * @internal\n * @param {ReactNode} node Statically passed child of any type.\n * @param {*} parentType node's parent's type.\n */\n\n\nfunction validateChildKeys(node, parentType) {\n {\n if (typeof node !== 'object') {\n return;\n }\n\n if (isArray(node)) {\n for (var i = 0; i < node.length; i++) {\n var child = node[i];\n\n if (isValidElement(child)) {\n validateExplicitKey(child, parentType);\n }\n }\n } else if (isValidElement(node)) {\n // This element was passed in a valid location.\n if (node._store) {\n node._store.validated = true;\n }\n } else if (node) {\n var iteratorFn = getIteratorFn(node);\n\n if (typeof iteratorFn === 'function') {\n // Entry iterators used to provide implicit keys,\n // but now we print a separate warning for them later.\n if (iteratorFn !== node.entries) {\n var iterator = iteratorFn.call(node);\n var step;\n\n while (!(step = iterator.next()).done) {\n if (isValidElement(step.value)) {\n validateExplicitKey(step.value, parentType);\n }\n }\n }\n }\n }\n }\n}\n/**\n * Given an element, validate that its props follow the propTypes definition,\n * provided by the type.\n *\n * @param {ReactElement} element\n */\n\n\nfunction validatePropTypes(element) {\n {\n var type = element.type;\n\n if (type === null || type === undefined || typeof type === 'string') {\n return;\n }\n\n var propTypes;\n\n if (typeof type === 'function') {\n propTypes = type.propTypes;\n } else if (typeof type === 'object' && (type.$$typeof === REACT_FORWARD_REF_TYPE || // Note: Memo only checks outer props here.\n // Inner props are checked in the reconciler.\n type.$$typeof === REACT_MEMO_TYPE)) {\n propTypes = type.propTypes;\n } else {\n return;\n }\n\n if (propTypes) {\n // Intentionally inside to avoid triggering lazy initializers:\n var name = getComponentNameFromType(type);\n checkPropTypes(propTypes, element.props, 'prop', name, element);\n } else if (type.PropTypes !== undefined && !propTypesMisspellWarningShown) {\n propTypesMisspellWarningShown = true; // Intentionally inside to avoid triggering lazy initializers:\n\n var _name = getComponentNameFromType(type);\n\n error('Component %s declared `PropTypes` instead of `propTypes`. Did you misspell the property assignment?', _name || 'Unknown');\n }\n\n if (typeof type.getDefaultProps === 'function' && !type.getDefaultProps.isReactClassApproved) {\n error('getDefaultProps is only used on classic React.createClass ' + 'definitions. Use a static property named `defaultProps` instead.');\n }\n }\n}\n/**\n * Given a fragment, validate that it can only be provided with fragment props\n * @param {ReactElement} fragment\n */\n\n\nfunction validateFragmentProps(fragment) {\n {\n var keys = Object.keys(fragment.props);\n\n for (var i = 0; i < keys.length; i++) {\n var key = keys[i];\n\n if (key !== 'children' && key !== 'key') {\n setCurrentlyValidatingElement$1(fragment);\n\n error('Invalid prop `%s` supplied to `React.Fragment`. ' + 'React.Fragment can only have `key` and `children` props.', key);\n\n setCurrentlyValidatingElement$1(null);\n break;\n }\n }\n\n if (fragment.ref !== null) {\n setCurrentlyValidatingElement$1(fragment);\n\n error('Invalid attribute `ref` supplied to `React.Fragment`.');\n\n setCurrentlyValidatingElement$1(null);\n }\n }\n}\n\nvar didWarnAboutKeySpread = {};\nfunction jsxWithValidation(type, props, key, isStaticChildren, source, self) {\n {\n var validType = isValidElementType(type); // We warn in this case but don't throw. We expect the element creation to\n // succeed and there will likely be errors in render.\n\n if (!validType) {\n var info = '';\n\n if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) {\n info += ' You likely forgot to export your component from the file ' + \"it's defined in, or you might have mixed up default and named imports.\";\n }\n\n var sourceInfo = getSourceInfoErrorAddendum(source);\n\n if (sourceInfo) {\n info += sourceInfo;\n } else {\n info += getDeclarationErrorAddendum();\n }\n\n var typeString;\n\n if (type === null) {\n typeString = 'null';\n } else if (isArray(type)) {\n typeString = 'array';\n } else if (type !== undefined && type.$$typeof === REACT_ELEMENT_TYPE) {\n typeString = \"<\" + (getComponentNameFromType(type.type) || 'Unknown') + \" />\";\n info = ' Did you accidentally export a JSX literal instead of a component?';\n } else {\n typeString = typeof type;\n }\n\n error('React.jsx: type is invalid -- expected a string (for ' + 'built-in components) or a class/function (for composite ' + 'components) but got: %s.%s', typeString, info);\n }\n\n var element = jsxDEV(type, props, key, source, self); // The result can be nullish if a mock or a custom function is used.\n // TODO: Drop this when these are no longer allowed as the type argument.\n\n if (element == null) {\n return element;\n } // Skip key warning if the type isn't valid since our key validation logic\n // doesn't expect a non-string/function type and can throw confusing errors.\n // We don't want exception behavior to differ between dev and prod.\n // (Rendering will throw with a helpful message and as soon as the type is\n // fixed, the key warnings will appear.)\n\n\n if (validType) {\n var children = props.children;\n\n if (children !== undefined) {\n if (isStaticChildren) {\n if (isArray(children)) {\n for (var i = 0; i < children.length; i++) {\n validateChildKeys(children[i], type);\n }\n\n if (Object.freeze) {\n Object.freeze(children);\n }\n } else {\n error('React.jsx: Static children should always be an array. ' + 'You are likely explicitly calling React.jsxs or React.jsxDEV. ' + 'Use the Babel transform instead.');\n }\n } else {\n validateChildKeys(children, type);\n }\n }\n }\n\n {\n if (hasOwnProperty.call(props, 'key')) {\n var componentName = getComponentNameFromType(type);\n var keys = Object.keys(props).filter(function (k) {\n return k !== 'key';\n });\n var beforeExample = keys.length > 0 ? '{key: someKey, ' + keys.join(': ..., ') + ': ...}' : '{key: someKey}';\n\n if (!didWarnAboutKeySpread[componentName + beforeExample]) {\n var afterExample = keys.length > 0 ? '{' + keys.join(': ..., ') + ': ...}' : '{}';\n\n error('A props object containing a \"key\" prop is being spread into JSX:\\n' + ' let props = %s;\\n' + ' <%s {...props} />\\n' + 'React keys must be passed directly to JSX without using spread:\\n' + ' let props = %s;\\n' + ' <%s key={someKey} {...props} />', beforeExample, componentName, afterExample, componentName);\n\n didWarnAboutKeySpread[componentName + beforeExample] = true;\n }\n }\n }\n\n if (type === REACT_FRAGMENT_TYPE) {\n validateFragmentProps(element);\n } else {\n validatePropTypes(element);\n }\n\n return element;\n }\n} // These two functions exist to still get child warnings in dev\n// even with the prod transform. This means that jsxDEV is purely\n// opt-in behavior for better messages but that we won't stop\n// giving you warnings if you use production apis.\n\nfunction jsxWithValidationStatic(type, props, key) {\n {\n return jsxWithValidation(type, props, key, true);\n }\n}\nfunction jsxWithValidationDynamic(type, props, key) {\n {\n return jsxWithValidation(type, props, key, false);\n }\n}\n\nvar jsx = jsxWithValidationDynamic ; // we may want to special case jsxs internally to take advantage of static children.\n// for now we can ship identical prod functions\n\nvar jsxs = jsxWithValidationStatic ;\n\nexports.Fragment = REACT_FRAGMENT_TYPE;\nexports.jsx = jsx;\nexports.jsxs = jsxs;\n })();\n}\n","'use strict';\n\nif (process.env.NODE_ENV === 'production') {\n module.exports = require('./cjs/react-jsx-runtime.production.min.js');\n} else {\n module.exports = require('./cjs/react-jsx-runtime.development.js');\n}\n","export enum HorizontalAlign {\r\n\tleft = \"flex-start\",\r\n\tcenter = \"center\",\r\n\tright = \"flex-end\",\r\n}\r\n\r\nexport enum VerticalAlign {\r\n\ttop = \"flex-start\",\r\n\tcenter = \"center\",\r\n\tbottom = \"flex-end\",\r\n}\r\n\r\nexport interface AlignmentSchema {\r\n\tjustifyContent?: HorizontalAlign;\r\n\talignItems?: VerticalAlign;\r\n}\r\n","/**\r\n * @file Select.tsx\r\n * @description ドロップダウン選択コンポーネント\r\n */\r\n\r\nimport { useCallback } from \"react\";\r\n\r\nimport styles from \"./Select.module.css\";\r\n\r\nimport type React from \"react\";\r\nimport type { PropertyComponentProps } from \"@/plugin\";\r\nimport type { Value } from \"@/types/value\";\r\n\r\n/**\r\n * 選択肢の型\r\n */\r\nexport interface SelectOption {\r\n\tvalue: Value;\r\n\tlabel: string;\r\n\t[key: string]: Value;\r\n}\r\n\r\n/**\r\n * Config型定義\r\n */\r\nexport interface SelectConfig {\r\n\toptions?: readonly SelectOption[];\r\n\tplaceholder?: string;\r\n\twidth?: number;\r\n\theight?: number;\r\n\r\n\t[key: string]: Value;\r\n}\r\n\r\n/**\r\n * Select固有のProps\r\n */\r\nexport interface SelectProps<T extends string = string>\r\n\textends PropertyComponentProps<T | undefined> {\r\n\toptions?: readonly SelectOption[];\r\n\tplaceholder?: string;\r\n\t/** 幅(px) */\r\n\twidth?: number;\r\n\t/** 高さ(px) */\r\n\theight?: number;\r\n\r\n\tconfig?: SelectConfig;\r\n}\r\n\r\n/**\r\n * ドロップダウン選択コンポーネント\r\n */\r\nexport const Select = <T extends string = string>(\r\n\tprops: SelectProps<T>,\r\n): React.ReactElement => {\r\n\tconst { value, onChange, readOnly = false, config } = props;\r\n\r\n\t// 設定のマージ\r\n\tconst options = props.options ?? config?.options ?? [];\r\n\tconst placeholder =\r\n\t\tprops.placeholder ?? config?.placeholder ?? \"選択してください\";\r\n\tconst width = props.width ?? config?.width;\r\n\tconst height = props.height ?? config?.height;\r\n\r\n\tconst handleChange = useCallback(\r\n\t\t(e: React.ChangeEvent<HTMLSelectElement>) => {\r\n\t\t\tconst selectedValue = e.target.value;\r\n\t\t\tif (selectedValue === \"\") {\r\n\t\t\t\tonChange(undefined as unknown as T);\r\n\t\t\t} else {\r\n\t\t\t\t// optionsから実際のvalueを取得(文字列変換されたものではなく元の値)\r\n\t\t\t\tconst option = options.find(\r\n\t\t\t\t\t(opt) => String(opt.value) === selectedValue,\r\n\t\t\t\t);\r\n\t\t\t\tif (option) {\r\n\t\t\t\t\tonChange(option.value as T);\r\n\t\t\t\t} else {\r\n\t\t\t\t\tonChange(selectedValue as T);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t},\r\n\t\t[onChange, options],\r\n\t);\r\n\r\n\tconst displayValue = value ?? \"\";\r\n\tconst hasValue = value !== undefined && value !== \"\";\r\n\r\n\t// インラインスタイル(containerには幅のみ適用)\r\n\tconst containerStyle: React.CSSProperties = {};\r\n\tif (width !== undefined) {\r\n\t\tcontainerStyle.width = `${width}px`;\r\n\t} else {\r\n\t\tcontainerStyle.width = \"100%\"; // デフォルトは親要素の幅\r\n\t}\r\n\r\n\t// selectとoverlayには高さを適用\r\n\tconst elementStyle: React.CSSProperties = {\r\n\t\twidth: \"100%\",\r\n\t\theight: height ? `${height}px` : undefined,\r\n\t};\r\n\r\n\treturn (\r\n\t\t<div className={styles.container} style={containerStyle}>\r\n\t\t\t{!hasValue && (\r\n\t\t\t\t<input\r\n\t\t\t\t\tclassName={styles.placeholderOverlay}\r\n\t\t\t\t\tstyle={elementStyle}\r\n\t\t\t\t\treadOnly\r\n\t\t\t\t\tplaceholder={placeholder}\r\n\t\t\t\t/>\r\n\t\t\t)}\r\n\t\t\t<select\r\n\t\t\t\tclassName={styles.select}\r\n\t\t\t\tstyle={elementStyle}\r\n\t\t\t\tvalue={displayValue}\r\n\t\t\t\tonChange={handleChange}\r\n\t\t\t\tdisabled={readOnly}\r\n\t\t\t>\r\n\t\t\t\t{options.map((option) => (\r\n\t\t\t\t\t<option key={String(option.value)} value={String(option.value)}>\r\n\t\t\t\t\t\t{option.label}\r\n\t\t\t\t\t</option>\r\n\t\t\t\t))}\r\n\t\t\t</select>\r\n\t\t</div>\r\n\t);\r\n};\r\n\r\nSelect.displayName = \"Select\";\r\n","import {\r\n\ttype AlignmentSchema,\r\n\tHorizontalAlign,\r\n\tVerticalAlign,\r\n} from \"./schemas\";\r\n\r\nimport { Select } from \"@/properties/components/Select\";\r\n\r\nimport type { PluginProperties } from \"@/plugin\";\r\n\r\nexport const alignmentDefinition: PluginProperties<AlignmentSchema> = {\r\n\tjustifyContent: {\r\n\t\tdefaultValue: HorizontalAlign.left,\r\n\t\tlabel: \"水平方向の配置\",\r\n\t\tgroup: \"配置\",\r\n\t\tdescription: \"ブロック内のコンテンツの水平方向の配置を設定します。\",\r\n\t\tComponent: Select,\r\n\t\tconfig: {\r\n\t\t\toptions: [\r\n\t\t\t\t{ label: \"左揃え\", value: HorizontalAlign.left },\r\n\t\t\t\t{ label: \"中央揃え\", value: HorizontalAlign.center },\r\n\t\t\t\t{ label: \"右揃え\", value: HorizontalAlign.right },\r\n\t\t\t],\r\n\t\t},\r\n\t},\r\n\r\n\talignItems: {\r\n\t\tdefaultValue: VerticalAlign.center,\r\n\t\tlabel: \"垂直方向の配置\",\r\n\t\tgroup: \"配置\",\r\n\t\tdescription: \"ブロック内のコンテンツの垂直方向の配置を設定します。\",\r\n\t\tComponent: Select,\r\n\t\tconfig: {\r\n\t\t\toptions: [\r\n\t\t\t\t{ label: \"上揃え\", value: VerticalAlign.top },\r\n\t\t\t\t{ label: \"中央揃え\", value: VerticalAlign.center },\r\n\t\t\t\t{ label: \"下揃え\", value: VerticalAlign.bottom },\r\n\t\t\t],\r\n\t\t},\r\n\t},\r\n};\r\n","/**\r\n * @file Checkbox.tsx\r\n * @description チェックボックス入力コンポーネント\r\n */\r\n\r\nimport { useCallback } from \"react\";\r\n\r\nimport styles from \"./Checkbox.module.css\";\r\n\r\nimport type React from \"react\";\r\nimport type { PropertyComponentProps } from \"@/plugin\";\r\nimport type { Value } from \"@/types/value\";\r\n\r\nexport interface CheckboxConfig {\r\n\tlabel?: string;\r\n\t[key: string]: Value;\r\n}\r\n\r\n/**\r\n * Checkbox固有のProps\r\n * ★修正: boolean | undefined にして未設定を許容する\r\n */\r\nexport interface CheckboxProps\r\n\textends PropertyComponentProps<boolean | undefined> {\r\n\tlabel?: string;\r\n\tconfig?: CheckboxConfig;\r\n}\r\n\r\n/**\r\n * チェックボックスコンポーネント\r\n */\r\nexport const Checkbox = ({\r\n\tvalue,\r\n\tonChange,\r\n\treadOnly = false,\r\n\tlabel: propLabel,\r\n\tconfig,\r\n}: CheckboxProps): React.ReactElement => {\r\n\tconst label = propLabel ?? config?.label;\r\n\r\n\tconst handleChange = useCallback(\r\n\t\t(e: React.ChangeEvent<HTMLInputElement>) => {\r\n\t\t\tonChange(e.target.checked);\r\n\t\t},\r\n\t\t[onChange],\r\n\t);\r\n\r\n\treturn (\r\n\t\t<label className={styles.container}>\r\n\t\t\t<input\r\n\t\t\t\ttype=\"checkbox\"\r\n\t\t\t\tclassName={styles.input}\r\n\t\t\t\tchecked={!!value} // undefined の場合は false として扱う\r\n\t\t\t\tonChange={handleChange}\r\n\t\t\t\tdisabled={readOnly}\r\n\t\t\t/>\r\n\t\t\t{label && <span className={styles.label}>{label}</span>}\r\n\t\t</label>\r\n\t);\r\n};\r\n\r\nCheckbox.displayName = \"Checkbox\";\r\n","import type { RGBA } from \"./types\";\r\n\r\n/**\r\n * カラー文字列を RGBA オブジェクトに変換\r\n * @param value カラー文字列 (#RRGGBB, #RRGGBBAA, rgba(r,g,b,a), undefined)\r\n * @returns RGBA オブジェクト、または null(変換失敗時)\r\n */\r\nexport function parseColor(value: string | undefined): RGBA | null {\r\n\tif (!value) {\r\n\t\treturn null;\r\n\t}\r\n\r\n\t// Hex形式 (#RRGGBB または #RRGGBBAA)\r\n\tconst hexMatch = value.match(/^#([0-9a-f]{6}|[0-9a-f]{8})$/i);\r\n\tif (hexMatch && typeof hexMatch[1] === \"string\") {\r\n\t\tconst hex = hexMatch[1];\r\n\t\tconst r = Number.parseInt(hex.slice(0, 2), 16);\r\n\t\tconst g = Number.parseInt(hex.slice(2, 4), 16);\r\n\t\tconst b = Number.parseInt(hex.slice(4, 6), 16);\r\n\t\tconst a = hex.length === 8 ? Number.parseInt(hex.slice(6, 8), 16) / 255 : 1;\r\n\t\treturn { r, g, b, a };\r\n\t}\r\n\r\n\t// rgba形式 (rgba(r, g, b, a))\r\n\tconst rgbaMatch = value.match(\r\n\t\t/^rgba?\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*(?:,\\s*([\\d.]+)\\s*)?\\)$/,\r\n\t);\r\n\tif (rgbaMatch) {\r\n\t\tconst r = Number.parseInt(rgbaMatch[1] ?? \"\", 10);\r\n\t\tconst g = Number.parseInt(rgbaMatch[2] ?? \"\", 10);\r\n\t\tconst b = Number.parseInt(rgbaMatch[3] ?? \"\", 10);\r\n\t\tconst a = rgbaMatch[4] ? Number.parseFloat(rgbaMatch[4]) : 1;\r\n\t\treturn { r, g, b, a };\r\n\t}\r\n\r\n\treturn null;\r\n}\r\n\r\n/**\r\n * RGBA オブジェクトを Hex 文字列に変換\r\n * @param rgba RGBA オブジェクト\r\n * @returns #RRGGBB または #RRGGBBAA 形式の文字列、透明の場合は undefined\r\n */\r\nexport function toHex(rgba: RGBA): string | undefined {\r\n\tconst { r, g, b, a } = rgba;\r\n\r\n\t// 透明の場合\r\n\tif (a === 0) {\r\n\t\treturn undefined;\r\n\t}\r\n\r\n\tconst rHex = r.toString(16).padStart(2, \"0\");\r\n\tconst gHex = g.toString(16).padStart(2, \"0\");\r\n\tconst bHex = b.toString(16).padStart(2, \"0\");\r\n\r\n\t// アルファが1未満の場合は8桁形式\r\n\tif (a < 1) {\r\n\t\tconst aHex = Math.round(a * 255)\r\n\t\t\t.toString(16)\r\n\t\t\t.padStart(2, \"0\");\r\n\t\treturn `#${rHex}${gHex}${bHex}${aHex}`;\r\n\t}\r\n\r\n\t// アルファが1の場合は6桁形式\r\n\treturn `#${rHex}${gHex}${bHex}`;\r\n}\r\n\r\n/**\r\n * RGBA オブジェクトを rgba() 文字列に変換\r\n * @param rgba RGBA オブジェクト\r\n * @returns rgba(r, g, b, a) 形式の文字列、透明の場合は undefined\r\n */\r\nexport function toRgbaString(rgba: RGBA): string | undefined {\r\n\tconst { r, g, b, a } = rgba;\r\n\r\n\t// 透明の場合\r\n\tif (a === 0) {\r\n\t\treturn undefined;\r\n\t}\r\n\r\n\treturn `rgba(${r}, ${g}, ${b}, ${a})`;\r\n}\r\n\r\n/**\r\n * Hex カラー文字列の妥当性をチェック\r\n * @param hex チェックする文字列\r\n * @returns 妥当な Hex カラー文字列かどうか\r\n */\r\nexport function isValidHex(hex: string): boolean {\r\n\treturn /^#([0-9a-f]{6}|[0-9a-f]{8})$/i.test(hex);\r\n}\r\n","/**\r\n * RGBA カラー型定義\r\n */\r\nexport interface RGBA {\r\n\tr: number; // 0-255\r\n\tg: number; // 0-255\r\n\tb: number; // 0-255\r\n\ta: number; // 0-1\r\n}\r\n\r\n/**\r\n * カラーパレット定義(30色)\r\n */\r\nexport const COLOR_PALETTE = [\r\n\t{ label: \"無色\", value: undefined as string | undefined },\r\n\t{ label: \"白\", value: \"#ffffff\" },\r\n\t{ label: \"グレー1\", value: \"#efefef\" },\r\n\t{ label: \"グレー2\", value: \"#d9d9d9\" },\r\n\t{ label: \"グレー3\", value: \"#cccccc\" },\r\n\t{ label: \"グレー4\", value: \"#b7b7b7\" },\r\n\t{ label: \"グレー5\", value: \"#999999\" },\r\n\t{ label: \"グレー6\", value: \"#666666\" },\r\n\t{ label: \"グレー7\", value: \"#434343\" },\r\n\t{ label: \"黒\", value: \"#000000\" },\r\n\t{ label: \"薄茶\", value: \"#E6B8AF\" },\r\n\t{ label: \"薄赤\", value: \"#F4CCCC\" },\r\n\t{ label: \"薄橙\", value: \"#FCE5CD\" },\r\n\t{ label: \"薄黄\", value: \"#FFF2CC\" },\r\n\t{ label: \"薄緑\", value: \"#D9EAD3\" },\r\n\t{ label: \"薄青緑\", value: \"#D0E0E3\" },\r\n\t{ label: \"薄青\", value: \"#C9DAF8\" },\r\n\t{ label: \"薄青紫\", value: \"#CFE2F3\" },\r\n\t{ label: \"薄紫\", value: \"#D9D2E9\" },\r\n\t{ label: \"薄赤紫\", value: \"#EAD1DC\" },\r\n\t{ label: \"茶\", value: \"#DD7E6B\" },\r\n\t{ label: \"赤\", value: \"#EA9999\" },\r\n\t{ label: \"橙\", value: \"#F9CB9C\" },\r\n\t{ label: \"黄\", value: \"#FFE599\" },\r\n\t{ label: \"緑\", value: \"#B6D7A8\" },\r\n\t{ label: \"青緑\", value: \"#A2C4C9\" },\r\n\t{ label: \"青\", value: \"#A4C2F4\" },\r\n\t{ label: \"青紫\", value: \"#9FC5E8\" },\r\n\t{ label: \"紫\", value: \"#B4A7D6\" },\r\n\t{ label: \"赤紫\", value: \"#D5A6BD\" },\r\n] as const;\r\n","/**\r\n * @file ColorPalette.tsx\r\n * @description カラーパレットコンポーネント\r\n */\r\n\r\nimport styles from \"./ColorPicker.module.css\";\r\n\r\nimport { COLOR_PALETTE } from \"@/utils/color\";\r\n\r\nimport type React from \"react\";\r\n\r\nexport interface ColorPaletteProps {\r\n\tonColorSelect: (color: string | undefined) => void;\r\n\tselectedColor?: string;\r\n\treadOnly?: boolean;\r\n}\r\n\r\n/**\r\n * カラーパレットコンポーネント\r\n */\r\nexport const ColorPalette = ({\r\n\tonColorSelect,\r\n\tselectedColor,\r\n\treadOnly = false,\r\n}: ColorPaletteProps): React.ReactElement => {\r\n\treturn (\r\n\t\t<div className={styles.palette}>\r\n\t\t\t{COLOR_PALETTE.map((color, index) => {\r\n\t\t\t\tconst isUndefined = color.value === undefined;\r\n\t\t\t\tconst isSelected = color.value === selectedColor;\r\n\t\t\t\tconst buttonStyle: React.CSSProperties = isUndefined\r\n\t\t\t\t\t? {}\r\n\t\t\t\t\t: { backgroundColor: color.value };\r\n\r\n\t\t\t\treturn (\r\n\t\t\t\t\t<button\r\n\t\t\t\t\t\tkey={color.value ?? `undefined-${index}`}\r\n\t\t\t\t\t\ttype=\"button\"\r\n\t\t\t\t\t\tclassName={`${styles.paletteButton} ${isUndefined ? styles.transparentPaletteButton : \"\"} ${isSelected ? styles.selected : \"\"}`}\r\n\t\t\t\t\t\tonClick={() => onColorSelect(color.value)}\r\n\t\t\t\t\t\tdisabled={readOnly}\r\n\t\t\t\t\t\ttitle={color.label}\r\n\t\t\t\t\t\taria-label={color.label}\r\n\t\t\t\t\t\tstyle={buttonStyle}\r\n\t\t\t\t\t/>\r\n\t\t\t\t);\r\n\t\t\t})}\r\n\t\t</div>\r\n\t);\r\n};\r\n\r\nColorPalette.displayName = \"ColorPalette\";\r\n","import { useCallback } from \"react\";\r\n\r\nimport styles from \"./NumberInput.module.css\";\r\n\r\nimport type React from \"react\";\r\nimport type { PropertyComponentProps } from \"@/plugin\";\r\nimport type { Value } from \"@/types/value\";\r\n\r\nexport interface NumberInputConfig {\r\n\tmin?: number;\r\n\tmax?: number;\r\n\tstep?: number;\r\n\tinteger?: boolean;\r\n\tplaceholder?: string;\r\n\twidth?: number;\r\n\theight?: number;\r\n\t[key: string]: Value;\r\n}\r\n\r\nexport interface NumberInputProps\r\n\textends PropertyComponentProps<number | undefined> {\r\n\tmin?: number;\r\n\tmax?: number;\r\n\tstep?: number;\r\n\tinteger?: boolean;\r\n\tplaceholder?: string;\r\n\t/** 幅(px) */\r\n\twidth?: number;\r\n\t/** 高さ(px) */\r\n\theight?: number;\r\n\tconfig?: NumberInputConfig;\r\n\tonBlur?: () => void;\r\n}\r\n\r\nexport const NumberInput = ({\r\n\tvalue,\r\n\tonChange,\r\n\treadOnly = false,\r\n\tmin: propMin,\r\n\tmax: propMax,\r\n\tstep: propStep,\r\n\tinteger: propInteger,\r\n\tplaceholder: propPlaceholder,\r\n\twidth: propWidth,\r\n\theight: propHeight,\r\n\tconfig,\r\n\tonBlur,\r\n}: NumberInputProps): React.ReactElement => {\r\n\tconst min = propMin ?? config?.min ?? 1;\r\n\tconst max = propMax ?? config?.max;\r\n\tconst step = propStep ?? config?.step ?? 1;\r\n\tconst integer = propInteger ?? config?.integer ?? false;\r\n\tconst placeholder = propPlaceholder ?? config?.placeholder;\r\n\tconst width = propWidth ?? config?.width;\r\n\tconst height = propHeight ?? config?.height;\r\n\r\n\tconst handleChange = useCallback(\r\n\t\t(e: React.ChangeEvent<HTMLInputElement>) => {\r\n\t\t\tconst text = e.target.value;\r\n\t\t\tif (text === \"\") {\r\n\t\t\t\tonChange(undefined);\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tlet num = Number.parseFloat(text);\r\n\t\t\tif (Number.isNaN(num)) return;\r\n\r\n\t\t\tif (integer) num = Math.round(num);\r\n\t\t\tif (min !== undefined && num < min) num = min;\r\n\t\t\tif (max !== undefined && num > max) num = max;\r\n\r\n\t\t\tonChange(num);\r\n\t\t},\r\n\t\t[onChange, min, max, integer],\r\n\t);\r\n\r\n\t// スタイルの構築\r\n\tconst style: React.CSSProperties = {};\r\n\tif (width !== undefined) style.width = `${width}px`;\r\n\r\n\tif (height !== undefined) {\r\n\t\tstyle.height = `${height}px`;\r\n\t\t// 高さが小さい場合、パディングがあると文字が見切れるため調整\r\n\t\tstyle.paddingTop = 0;\r\n\t\tstyle.paddingBottom = 0;\r\n\t}\r\n\r\n\treturn (\r\n\t\t<input\r\n\t\t\ttype=\"number\"\r\n\t\t\tclassName={styles.input}\r\n\t\t\tstyle={style}\r\n\t\t\tvalue={value ?? \"\"}\r\n\t\t\tonChange={handleChange}\r\n\t\t\tonBlur={onBlur}\r\n\t\t\tdisabled={readOnly}\r\n\t\t\tmin={min}\r\n\t\t\tmax={max}\r\n\t\t\tstep={step}\r\n\t\t\tplaceholder={placeholder}\r\n\t\t/>\r\n\t);\r\n};\r\n\r\nNumberInput.displayName = \"NumberInput\";\r\n","/**\r\n * @file RGBAInputs.tsx\r\n * @description RGBA入力コンポーネント\r\n */\r\n\r\nimport { NumberInput } from \"../NumberInput/NumberInput\";\r\nimport styles from \"./ColorPicker.module.css\";\r\n\r\nimport type React from \"react\";\r\nimport type { RGBA } from \"@/utils/color\";\r\n\r\nexport interface RGBAInputsProps {\r\n\trgba: RGBA;\r\n\tonChange: (channel: keyof RGBA, value: number | undefined) => void;\r\n\treadOnly?: boolean;\r\n}\r\n\r\n/**\r\n * RGBA入力コンポーネント\r\n */\r\nexport const RGBAInputs = ({\r\n\trgba,\r\n\tonChange,\r\n\treadOnly = false,\r\n}: RGBAInputsProps): React.ReactElement => {\r\n\treturn (\r\n\t\t<div className={styles.rgbaInputs}>\r\n\t\t\t<div className={styles.rgbaInputGroup}>\r\n\t\t\t\t<span className={styles.rgbaLabel}>R</span>\r\n\t\t\t\t<NumberInput\r\n\t\t\t\t\tvalue={rgba.r}\r\n\t\t\t\t\tonChange={(v) => onChange(\"r\", v)}\r\n\t\t\t\t\tmin={0}\r\n\t\t\t\t\tmax={255}\r\n\t\t\t\t\tstep={1}\r\n\t\t\t\t\tinteger={true}\r\n\t\t\t\t\twidth={48}\r\n\t\t\t\t\treadOnly={readOnly}\r\n\t\t\t\t/>\r\n\t\t\t</div>\r\n\t\t\t<div className={styles.rgbaInputGroup}>\r\n\t\t\t\t<span className={styles.rgbaLabel}>G</span>\r\n\t\t\t\t<NumberInput\r\n\t\t\t\t\tvalue={rgba.g}\r\n\t\t\t\t\tonChange={(v) => onChange(\"g\", v)}\r\n\t\t\t\t\tmin={0}\r\n\t\t\t\t\tmax={255}\r\n\t\t\t\t\tstep={1}\r\n\t\t\t\t\tinteger={true}\r\n\t\t\t\t\twidth={48}\r\n\t\t\t\t\treadOnly={readOnly}\r\n\t\t\t\t/>\r\n\t\t\t</div>\r\n\t\t\t<div className={styles.rgbaInputGroup}>\r\n\t\t\t\t<span className={styles.rgbaLabel}>B</span>\r\n\t\t\t\t<NumberInput\r\n\t\t\t\t\tvalue={rgba.b}\r\n\t\t\t\t\tonChange={(v) => onChange(\"b\", v)}\r\n\t\t\t\t\tmin={0}\r\n\t\t\t\t\tmax={255}\r\n\t\t\t\t\tstep={1}\r\n\t\t\t\t\tinteger={true}\r\n\t\t\t\t\twidth={48}\r\n\t\t\t\t\treadOnly={readOnly}\r\n\t\t\t\t/>\r\n\t\t\t</div>\r\n\t\t\t<div className={styles.rgbaInputGroup}>\r\n\t\t\t\t<span className={styles.rgbaLabel}>A</span>\r\n\t\t\t\t<NumberInput\r\n\t\t\t\t\tvalue={Math.round(rgba.a * 100)}\r\n\t\t\t\t\tonChange={(v) => onChange(\"a\", v !== undefined ? v / 100 : undefined)}\r\n\t\t\t\t\tmin={0}\r\n\t\t\t\t\tmax={100}\r\n\t\t\t\t\tstep={1}\r\n\t\t\t\t\tinteger={true}\r\n\t\t\t\t\twidth={48}\r\n\t\t\t\t\treadOnly={readOnly}\r\n\t\t\t\t/>\r\n\t\t\t</div>\r\n\t\t</div>\r\n\t);\r\n};\r\n\r\nRGBAInputs.displayName = \"RGBAInputs\";\r\n","/**\r\n * @file constants.ts\r\n * @description z-index定数定義\r\n *\r\n * 4層アーキテクチャに基づくz-index管理:\r\n * - GridLayer: 0-9 (静的背景)\r\n * - BlockLayer: 10-99,999 (ブロックコンテンツ)\r\n * - ErrorLayer: 150,000-199,999 (バリデーションエラー表示)\r\n * - InteractionLayer: 200,000+ (インタラクション要素)\r\n */\r\n\r\n/**\r\n * Z-INDEX定数\r\n *\r\n * 各レイヤーのz-index範囲を定義\r\n */\r\nexport const Z_INDEX = {\r\n\t// ==================== GridLayer (10-90) ====================\r\n\t/** グリッド背景(用紙背景) */\r\n\tGRID_CANVAS: 10,\r\n\t/** 用紙マージン表示(印刷可能範囲) */\r\n\tMARGIN_OVERLAY: 20,\r\n\t/** グリッド線 */\r\n\tGRID_OVERLAY: 30,\r\n\t/** 印刷可能領域の境界線 */\r\n\tBORDER_OVERLAY: 40,\r\n\r\n\t// ==================== BlockLayer (100-999,999) ====================\r\n\t/** BlockLayerの最小z-index */\r\n\tBLOCK_LAYER_MIN: 100,\r\n\t/** BlockLayerの最大z-index */\r\n\tBLOCK_LAYER_MAX: 999999,\r\n\t/** ブロック間のz-indexステップ(各ブロックは100段階のサブレイヤーを持っている) */\r\n\tBLOCK_LAYER_STEP: 100,\r\n\r\n\t// ==================== ErrorLayer (1,000,000-1,999,999) ====================\r\n\t/** エラー枠線 */\r\n\tERROR_BORDER: 1100000,\r\n\t/** エラーツールチップ */\r\n\tERROR_TOOLTIP: 1200000,\r\n\t/** エラー背景ハイライト */\r\n\tERROR_HIGHLIGHT: 1300000,\r\n\r\n\t// ==================== InteractionLayer (2,000,000+) ====================\r\n\t/** 選択中ブロック */\r\n\tSELECT_BLOCK: 2000000,\r\n\t// interactionLayerのベース\r\n\tINTERACTION_LAYER_BASE: 2100000,\r\n\t/** ドラッグ中ゴースト */\r\n\tBLOCK_GHOST: 2200000,\r\n\t/** ホバー枠線 */\r\n\tHOVER_OUTLINE: 2300000,\r\n\t/** ブロック編集中 */\r\n\tEDIT_BLOCK: 2400000,\r\n\t/** 選択中ブロック枠線 */\r\n\tBLOCK_SELECT_BORDER: 2500000,\r\n\t/** ブロックリサイズハンドル */\r\n\tBLOCK_HANDLES: 2600000,\r\n\t/** グリッドリサイズ中のゴースト線 */\r\n\tGRID_GHOST: 2700000,\r\n\t/** グリッドリサイズハンドル */\r\n\tGRID_HANDLES: 2800000,\r\n\t/** 範囲選択矩形 */\r\n\tRUBBER_BAND: 2900000,\r\n\r\n\t// ==================== Application UI (3,000,000+) ====================\r\n\t/** プロパティパネル(サイドバー) */\r\n\tPROPERTY_PANEL: 3100000,\r\n\t/** ブロック追加パレット */\r\n\tPALETTE: 3200000,\r\n\t/** ツールチップ */\r\n\tTOOLTIP: 3300000,\r\n\t/** ドロップダウン */\r\n\tDROPDOWN: 3400000,\r\n\t/** コンテキストメニュー */\r\n\tCONTEXT_MENU: 3500000,\r\n\t/** モーダル */\r\n\tMODAL: 3600000,\r\n\r\n\t// ==================== Debug (10,000,000) ====================\r\n\t/** デバッグ表示 */\r\n\tDEBUG: 10000000,\r\n} as const;\r\n\r\nexport const BLOCK_SUB_INDEX = {\r\n\tBG: 10, // 本体側でのデフォルト背景\r\n\tCONTENT: 50, // コンテンツ本体\r\n\tGUIDE: 70, // ガイド線など\r\n\tBORDER: 80, // 枠線\r\n} as const;\r\n\r\n/**\r\n * Z_INDEX型(型安全性のため)\r\n */\r\nexport type ZIndexValue = (typeof Z_INDEX)[keyof typeof Z_INDEX];\r\n\r\nexport type BlockSubIndexValue =\r\n\t(typeof BLOCK_SUB_INDEX)[keyof typeof BLOCK_SUB_INDEX];\r\n","/**\r\n * @file ColorPickerPopover.tsx\r\n * @description カラーピッカーポップオーバーコンポーネント\r\n */\r\n\r\nimport { useEffect, useRef } from \"react\";\r\n\r\nimport { ColorPalette } from \"./ColorPalette\";\r\nimport styles from \"./ColorPicker.module.css\";\r\nimport { RGBAInputs } from \"./RGBAInputs\";\r\n\r\nimport { Z_INDEX } from \"@/utils/zIndex/constants\";\r\n\r\nimport type React from \"react\";\r\nimport type { RGBA } from \"@/utils/color\";\r\n\r\nexport interface ColorPickerPopoverProps {\r\n\tisOpen: boolean;\r\n\tonClose: () => void;\r\n\trgba: RGBA;\r\n\tonRgbaChange: (channel: keyof RGBA, value: number | undefined) => void;\r\n\tonColorSelect: (color: string | undefined) => void;\r\n\tselectedColor?: string;\r\n\treadOnly?: boolean;\r\n}\r\n\r\n/**\r\n * カラーピッカーポップオーバーコンポーネント\r\n */\r\nexport const ColorPickerPopover = ({\r\n\tisOpen,\r\n\tonClose,\r\n\trgba,\r\n\tonRgbaChange,\r\n\tonColorSelect,\r\n\tselectedColor,\r\n\treadOnly = false,\r\n}: ColorPickerPopoverProps): React.ReactElement | null => {\r\n\tconst popoverRef = useRef<HTMLDivElement>(null);\r\n\r\n\t// 外側クリックでクローズ\r\n\tuseEffect(() => {\r\n\t\tif (!isOpen) return;\r\n\r\n\t\tconst handleClickOutside = (e: MouseEvent) => {\r\n\t\t\tif (\r\n\t\t\t\tpopoverRef.current &&\r\n\t\t\t\t!popoverRef.current.contains(e.target as Node)\r\n\t\t\t) {\r\n\t\t\t\tonClose();\r\n\t\t\t}\r\n\t\t};\r\n\r\n\t\tdocument.addEventListener(\"mousedown\", handleClickOutside);\r\n\t\treturn () => {\r\n\t\t\tdocument.removeEventListener(\"mousedown\", handleClickOutside);\r\n\t\t};\r\n\t}, [isOpen, onClose]);\r\n\r\n\tif (!isOpen) return null;\r\n\r\n\treturn (\r\n\t\t<div\r\n\t\t\tclassName={styles.popover}\r\n\t\t\tref={popoverRef}\r\n\t\t\tstyle={{ zIndex: Z_INDEX.DROPDOWN }}\r\n\t\t>\r\n\t\t\t{/* カラーパレット */}\r\n\t\t\t<ColorPalette\r\n\t\t\t\tonColorSelect={onColorSelect}\r\n\t\t\t\tselectedColor={selectedColor}\r\n\t\t\t\treadOnly={readOnly}\r\n\t\t\t/>\r\n\r\n\t\t\t{/* RGBA入力 */}\r\n\t\t\t<RGBAInputs rgba={rgba} onChange={onRgbaChange} readOnly={readOnly} />\r\n\t\t</div>\r\n\t);\r\n};\r\n\r\nColorPickerPopover.displayName = \"ColorPickerPopover\";\r\n","/**\r\n * @file ColorPicker.tsx\r\n * @description カラーピッカーコンポーネント\r\n */\r\n\r\nimport { useCallback, useEffect, useRef, useState } from \"react\";\r\n\r\nimport styles from \"./ColorPicker.module.css\";\r\nimport { ColorPickerPopover } from \"./ColorPickerPopover\";\r\n\r\nimport { parseColor, toHex } from \"@/utils/color\";\r\n\r\nimport type React from \"react\";\r\nimport type { PropertyComponentProps } from \"@/plugin\";\r\nimport type { Value } from \"@/types/value\";\r\nimport type { RGBA } from \"@/utils/color\";\r\n\r\n/**\r\n * Config型定義\r\n * Record<string, Value> との互換性を持たせる\r\n */\r\nexport interface ColorPickerConfig {\r\n\tallowUndefined?: boolean;\r\n\twidth?: number;\r\n\theight?: number;\r\n\t[key: string]: Value;\r\n}\r\n\r\n/**\r\n * ColorPicker固有のProps\r\n * T は string | undefined\r\n */\r\nexport interface ColorPickerProps\r\n\textends PropertyComponentProps<string | undefined> {\r\n\t/** カラーテキスト入力を表示するか */\r\n\tshowTextInput?: boolean;\r\n\t/** undefined(未設定)を許容するか */\r\n\tallowUndefined?: boolean;\r\n\t/** プレースホルダーテキスト */\r\n\tplaceholder?: string;\r\n\t/** 幅(px) */\r\n\twidth?: number;\r\n\t/** 高さ(px) */\r\n\theight?: number;\r\n\t/** 設定オブジェクト */\r\n\tconfig?: ColorPickerConfig;\r\n}\r\n\r\n/**\r\n * カラーピッカーコンポーネント\r\n */\r\nexport const ColorPicker = ({\r\n\tvalue,\r\n\tonChange,\r\n\treadOnly = false,\r\n\tshowTextInput = true,\r\n\tallowUndefined: propAllowUndefined,\r\n\tplaceholder: propPlaceholder,\r\n\twidth: propWidth,\r\n\theight: propHeight,\r\n\tconfig,\r\n}: ColorPickerProps): React.ReactElement => {\r\n\t// 設定のマージ\r\n\tconst allowUndefined = propAllowUndefined ?? config?.allowUndefined ?? true;\r\n\tconst placeholder =\r\n\t\tpropPlaceholder ?? (allowUndefined ? \"未設定\" : \"#000000\");\r\n\tconst width = propWidth ?? config?.width;\r\n\tconst height = propHeight ?? config?.height;\r\n\r\n\t// ポップオーバーの開閉状態\r\n\tconst [isOpen, setIsOpen] = useState(false);\r\n\tconst containerRef = useRef<HTMLDivElement>(null);\r\n\r\n\t// RGBA値の状態(ポップオーバー内での編集用)\r\n\tconst [rgbaValues, setRgbaValues] = useState<RGBA>(() => {\r\n\t\tconst parsed = parseColor(value);\r\n\t\treturn parsed ?? { r: 0, g: 0, b: 0, a: 1 };\r\n\t});\r\n\r\n\t// valueが外部から変更された時にRGBA値を更新\r\n\tuseEffect(() => {\r\n\t\tconst parsed = parseColor(value);\r\n\t\tif (parsed) {\r\n\t\t\tsetRgbaValues(parsed);\r\n\t\t}\r\n\t}, [value]);\r\n\r\n\t// カラーボタンクリック\r\n\tconst handleColorButtonClick = useCallback(() => {\r\n\t\tif (!readOnly) {\r\n\t\t\tsetIsOpen((prev) => !prev);\r\n\t\t}\r\n\t}, [readOnly]);\r\n\r\n\t// テキスト入力変更(入力中の制限)\r\n\tconst [textInputValue, setTextInputValue] = useState(\r\n\t\tvalue ? value.replace(/^#/, \"\") : \"\",\r\n\t);\r\n\r\n\t// valueが外部から変更された時にテキスト入力も更新\r\n\tuseEffect(() => {\r\n\t\tsetTextInputValue(value ? value.replace(/^#/, \"\") : \"\");\r\n\t}, [value]);\r\n\r\n\tconst handleTextChange = useCallback(\r\n\t\t(e: React.ChangeEvent<HTMLInputElement>) => {\r\n\t\t\tconst text = e.target.value;\r\n\r\n\t\t\t// 16進数文字のみ許可(0-9, a-f, A-F)\r\n\t\t\tif (/^[0-9A-Fa-f]*$/.test(text)) {\r\n\t\t\t\tsetTextInputValue(text);\r\n\t\t\t}\r\n\t\t},\r\n\t\t[],\r\n\t);\r\n\r\n\t// テキスト入力確定処理(共通ロジック)\r\n\tconst confirmTextInput = useCallback(\r\n\t\t(text: string) => {\r\n\t\t\t// 空文字の場合、allowUndefinedなら undefined を返す\r\n\t\t\tif (text === \"\" && allowUndefined) {\r\n\t\t\t\tonChange(undefined);\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\t// #RRGGBB または #RRGGBBAA の検証(#は自動付与されるので除外)\r\n\t\t\tif (/^[0-9A-Fa-f]{6}([0-9A-Fa-f]{2})?$/.test(text)) {\r\n\t\t\t\tonChange(`#${text}`);\r\n\t\t\t} else {\r\n\t\t\t\t// 不正な入力の場合、元の値に戻す\r\n\t\t\t\tsetTextInputValue(value ? value.replace(/^#/, \"\") : \"\");\r\n\t\t\t}\r\n\t\t},\r\n\t\t[onChange, allowUndefined, value],\r\n\t);\r\n\r\n\t// テキスト入力確定(onBlur)\r\n\tconst handleTextBlur = useCallback(\r\n\t\t(e: React.FocusEvent<HTMLInputElement>) => {\r\n\t\t\tconfirmTextInput(e.target.value);\r\n\t\t},\r\n\t\t[confirmTextInput],\r\n\t);\r\n\r\n\t// Enterキーで確定\r\n\tconst handleTextKeyDown = useCallback(\r\n\t\t(e: React.KeyboardEvent<HTMLInputElement>) => {\r\n\t\t\tif (e.key === \"Enter\") {\r\n\t\t\t\te.preventDefault();\r\n\t\t\t\tconfirmTextInput(e.currentTarget.value);\r\n\t\t\t\te.currentTarget.blur(); // フォーカスを外す\r\n\t\t\t}\r\n\t\t},\r\n\t\t[confirmTextInput],\r\n\t);\r\n\r\n\t// カラーパレットクリック\r\n\tconst handlePaletteClick = useCallback(\r\n\t\t(colorValue: string | undefined) => {\r\n\t\t\tonChange(colorValue);\r\n\t\t\t// ポップアップは閉じない(外クリックで閉じる)\r\n\t\t},\r\n\t\t[onChange],\r\n\t);\r\n\r\n\t// RGBA値変更ハンドラー\r\n\tconst handleRgbaChange = useCallback(\r\n\t\t(channel: keyof RGBA, newValue: number | undefined) => {\r\n\t\t\tif (newValue === undefined) return;\r\n\r\n\t\t\tconst newRgba = { ...rgbaValues, [channel]: newValue };\r\n\t\t\tsetRgbaValues(newRgba);\r\n\t\t\tonChange(toHex(newRgba));\r\n\t\t},\r\n\t\t[rgbaValues, onChange],\r\n\t);\r\n\r\n\t// 現在の値を表示用に変換\r\n\tconst displayColor = value ?? \"未設定\";\r\n\r\n\t// カラーボタンのスタイル\r\n\tconst colorStyle: React.CSSProperties = {};\r\n\tif (value) {\r\n\t\t// backgroundプロパティ全体を上書き\r\n\t\tcolorStyle.background = value;\r\n\t}\r\n\r\n\t// インラインスタイル\r\n\tconst containerStyle: React.CSSProperties = {};\r\n\tif (width !== undefined) {\r\n\t\tcontainerStyle.width = `${width}px`;\r\n\t} else {\r\n\t\tcontainerStyle.width = \"100%\";\r\n\t}\r\n\tif (height !== undefined) containerStyle.height = `${height}px`;\r\n\r\n\treturn (\r\n\t\t<div className={styles.container} style={containerStyle} ref={containerRef}>\r\n\t\t\t{/* カラーボタン */}\r\n\t\t\t<button\r\n\t\t\t\ttype=\"button\"\r\n\t\t\t\tclassName={styles.colorButton}\r\n\t\t\t\tonClick={handleColorButtonClick}\r\n\t\t\t\tdisabled={readOnly}\r\n\t\t\t\ttitle={displayColor}\r\n\t\t\t\taria-label=\"カラーピッカーを開く\"\r\n\t\t\t\tstyle={colorStyle}\r\n\t\t\t/>\r\n\t\t\t{/* テキスト入力 */}\r\n\t\t\t{showTextInput && (\r\n\t\t\t\t<div className={styles.textInputWrapper}>\r\n\t\t\t\t\t<span className={styles.textInputPrefix}>#</span>\r\n\t\t\t\t\t<input\r\n\t\t\t\t\t\ttype=\"text\"\r\n\t\t\t\t\t\tclassName={styles.textInput}\r\n\t\t\t\t\t\tvalue={textInputValue}\r\n\t\t\t\t\t\tonChange={handleTextChange}\r\n\t\t\t\t\t\tonKeyDown={handleTextKeyDown}\r\n\t\t\t\t\t\tonBlur={handleTextBlur}\r\n\t\t\t\t\t\tdisabled={readOnly}\r\n\t\t\t\t\t\tplaceholder={placeholder}\r\n\t\t\t\t\t\tmaxLength={8} // RRGGBBAA = 8文字(#は固定)\r\n\t\t\t\t\t/>\r\n\t\t\t\t</div>\r\n\t\t\t)}\r\n\t\t\t{/* ポップオーバー */}\r\n\t\t\t<ColorPickerPopover\r\n\t\t\t\tisOpen={isOpen}\r\n\t\t\t\tonClose={() => setIsOpen(false)}\r\n\t\t\t\trgba={rgbaValues}\r\n\t\t\t\tonRgbaChange={handleRgbaChange}\r\n\t\t\t\tonColorSelect={handlePaletteClick}\r\n\t\t\t\tselectedColor={value}\r\n\t\t\t\treadOnly={readOnly}\r\n\t\t\t/>\r\n\t\t</div>\r\n\t);\r\n};\r\n\r\nColorPicker.displayName = \"ColorPicker\";\r\n","/**\r\n * @file DimensionInput.tsx\r\n * @description Dimension型(値+単位)の入力コンポーネント\r\n */\r\n\r\nimport { useCallback } from \"react\";\r\n\r\n// CSSモジュールのパスは環境に合わせてください\r\nimport styles from \"./DimensionInput.module.css\";\r\n\r\nimport type React from \"react\";\r\nimport type { PropertyComponentProps } from \"@/plugin\";\r\n// Value型が必要な場合はインポート\r\nimport type { Value } from \"@/types/index\";\r\nimport type { Dimension, Unit } from \"@/types/unit\";\r\n\r\nexport interface DimensionInputConfig<U extends Unit> {\r\n\tallowedUnits?: readonly U[];\r\n\tmin?: number;\r\n\tmax?: number;\r\n\tstep?: number;\r\n\tplaceholder?: string;\r\n\twidth?: number;\r\n\theight?: number;\r\n\t// 必要に応じてインデックスシグネチャを追加\r\n\t[key: string]: Value;\r\n}\r\n\r\n/**\r\n * DimensionInput固有のProps\r\n * ★重要: ジェネリクスに `| undefined` を追加して、未設定状態を受け入れられるようにする\r\n */\r\nexport interface DimensionInputProps<U extends Unit>\r\n\textends PropertyComponentProps<Dimension<U> | undefined> {\r\n\tallowedUnits?: readonly U[];\r\n\tmin?: number;\r\n\tmax?: number;\r\n\tstep?: number;\r\n\tplaceholder?: string;\r\n\t/** 幅(px) */\r\n\twidth?: number;\r\n\t/** 高さ(px) */\r\n\theight?: number;\r\n\r\n\tconfig?: DimensionInputConfig<U>;\r\n}\r\n\r\nexport const DimensionInput = <U extends Unit>(\r\n\tprops: DimensionInputProps<U>,\r\n): React.ReactElement => {\r\n\tconst { value, onChange, readOnly = false, config } = props;\r\n\r\n\t// 設定のマージ\r\n\tconst allowedUnits = props.allowedUnits ?? config?.allowedUnits;\r\n\tconst min = props.min ?? config?.min;\r\n\tconst max = props.max ?? config?.max;\r\n\tconst step = props.step ?? config?.step ?? 1;\r\n\tconst placeholder = props.placeholder ?? config?.placeholder;\r\n\tconst width = props.width ?? config?.width;\r\n\tconst height = props.height ?? config?.height;\r\n\r\n\t// デフォルト単位の決定(現在の値の単位 -> 許可リストの先頭 -> undefined)\r\n\tconst currentUnit = value?.unit ?? allowedUnits?.[0];\r\n\r\n\t// --- ハンドラ ---\r\n\r\n\tconst handleValueChange = useCallback(\r\n\t\t(e: React.ChangeEvent<HTMLInputElement>) => {\r\n\t\t\tconst inputValue = e.target.value;\r\n\r\n\t\t\tlet newValue = Number.parseFloat(inputValue);\r\n\t\t\tif (Number.isNaN(newValue)) return;\r\n\r\n\t\t\t// minが指定されていない場合はデフォルトで1以上に制限\r\n\t\t\tconst effectiveMin = min ?? 1;\r\n\t\t\tif (newValue < effectiveMin) {\r\n\t\t\t\tnewValue = effectiveMin;\r\n\t\t\t}\r\n\t\t\tif (max !== undefined && newValue > max) {\r\n\t\t\t\tnewValue = max;\r\n\t\t\t}\r\n\r\n\t\t\tonChange({\r\n\t\t\t\tvalue: newValue,\r\n\t\t\t\t// 単位が未定ならデフォルト単位(または最初の許可単位)を強制\r\n\t\t\t\tunit: (value?.unit ?? currentUnit) as U,\r\n\t\t\t});\r\n\t\t},\r\n\t\t[value, onChange, currentUnit, min, max],\r\n\t);\r\n\r\n\t// フォーカスを失った時のバリデーション\r\n\tconst handleBlur = useCallback(\r\n\t\t(e: React.FocusEvent<HTMLInputElement>) => {\r\n\t\t\tconst inputValue = e.target.value;\r\n\r\n\t\t\tif (inputValue === \"\") return;\r\n\r\n\t\t\tlet newValue = Number.parseFloat(inputValue);\r\n\t\t\tif (Number.isNaN(newValue)) return;\r\n\r\n\t\t\t// minが指定されていない場合はデフォルトで1以上に制限\r\n\t\t\tconst effectiveMin = min ?? 1;\r\n\t\t\tif (newValue < effectiveMin) {\r\n\t\t\t\tnewValue = effectiveMin;\r\n\t\t\t\t// 最小値未満の場合は強制的に補正\r\n\t\t\t\tonChange({\r\n\t\t\t\t\tvalue: newValue,\r\n\t\t\t\t\tunit: (value?.unit ?? currentUnit) as U,\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t\tif (max !== undefined && newValue > max) {\r\n\t\t\t\tnewValue = max;\r\n\t\t\t\t// 最大値超過の場合は強制的に補正\r\n\t\t\t\tonChange({\r\n\t\t\t\t\tvalue: newValue,\r\n\t\t\t\t\tunit: (value?.unit ?? currentUnit) as U,\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t},\r\n\t\t[value, onChange, currentUnit, min, max],\r\n\t);\r\n\r\n\tconst handleUnitChange = useCallback(\r\n\t\t(e: React.ChangeEvent<HTMLSelectElement>) => {\r\n\t\t\tconst newUnit = e.target.value as U;\r\n\t\t\tonChange({\r\n\t\t\t\t// 値が未設定ならデフォルト値(例: 1)を入れてオブジェクトを作成\r\n\t\t\t\tvalue: value?.value ?? 1,\r\n\t\t\t\tunit: newUnit,\r\n\t\t\t});\r\n\t\t},\r\n\t\t[value, onChange],\r\n\t);\r\n\r\n\t// --- 表示用データ ---\r\n\r\n\t// valueがundefinedなら空文字を表示\r\n\tconst displayValue = value?.value ?? \"\";\r\n\r\n\t// 単位もundefinedなら空文字(ただしSelectの選択肢に空文字がないと警告が出るため注意)\r\n\tconst displayUnit = value?.unit ?? currentUnit ?? \"\";\r\n\r\n\t// インラインスタイル\r\n\tconst containerStyle: React.CSSProperties = {};\r\n\tif (width !== undefined) {\r\n\t\tcontainerStyle.width = `${width}px`;\r\n\t} else {\r\n\t\tcontainerStyle.width = \"100%\"; // デフォルトは親要素の幅\r\n\t}\r\n\tif (height !== undefined) containerStyle.height = `${height}px`;\r\n\r\n\treturn (\r\n\t\t<div className={styles.container} style={containerStyle}>\r\n\t\t\t<input\r\n\t\t\t\ttype=\"number\"\r\n\t\t\t\tclassName={styles.valueInput}\r\n\t\t\t\tvalue={displayValue}\r\n\t\t\t\tonChange={handleValueChange}\r\n\t\t\t\tonBlur={handleBlur}\r\n\t\t\t\tplaceholder={placeholder}\r\n\t\t\t\tmin={min ?? 1}\r\n\t\t\t\tmax={max}\r\n\t\t\t\tstep={step}\r\n\t\t\t\treadOnly={readOnly}\r\n\t\t\t\tdisabled={readOnly}\r\n\t\t\t/>\r\n\t\t\t<select\r\n\t\t\t\tclassName={styles.unitSelect}\r\n\t\t\t\tvalue={displayUnit}\r\n\t\t\t\tonChange={handleUnitChange}\r\n\t\t\t\tdisabled={readOnly || !allowedUnits || allowedUnits.length <= 1}\r\n\t\t\t>\r\n\t\t\t\t{allowedUnits ? (\r\n\t\t\t\t\tallowedUnits.map((u) => (\r\n\t\t\t\t\t\t<option key={u} value={u}>\r\n\t\t\t\t\t\t\t{u}\r\n\t\t\t\t\t\t</option>\r\n\t\t\t\t\t))\r\n\t\t\t\t) : (\r\n\t\t\t\t\t// 単位リストがない場合は現在の値を表示\r\n\t\t\t\t\t<option value={displayUnit as string}>{displayUnit}</option>\r\n\t\t\t\t)}\r\n\t\t\t</select>\r\n\t\t</div>\r\n\t);\r\n};\r\n","/**\r\n * @file TabPanel.tsx\r\n * @description タブパネル共通コンポーネント\r\n */\r\n\r\nimport styles from \"./TabPanel.module.css\";\r\n\r\nimport type { ReactNode } from \"react\";\r\n\r\nexport interface TabPanelProps {\r\n\t/** パネルの内容 */\r\n\tchildren: ReactNode;\r\n\t/** 空状態のメッセージ(childrenがない場合に表示) */\r\n\temptyMessage?: string;\r\n\t/** カスタムクラス名 */\r\n\tclassName?: string;\r\n}\r\n\r\n/**\r\n * TabPanel\r\n * タブコンテンツの共通ラッパー\r\n */\r\nexport const TabPanel = ({\r\n\tchildren,\r\n\temptyMessage,\r\n\tclassName,\r\n}: TabPanelProps) => {\r\n\treturn (\r\n\t\t<div className={`${styles.container} ${className || \"\"}`}>\r\n\t\t\t{children ? (\r\n\t\t\t\t<div className={styles.scrollArea}>{children}</div>\r\n\t\t\t) : (\r\n\t\t\t\temptyMessage && <div className={styles.emptyState}>{emptyMessage}</div>\r\n\t\t\t)}\r\n\t\t</div>\r\n\t);\r\n};\r\n","import { createContext, useContext, useState } from \"react\";\r\n\r\nimport styles from \"./Tabs.module.css\";\r\n\r\nimport type React from \"react\";\r\n\r\n// --- Context ---\r\ninterface TabsContextType {\r\n\tvalue: string;\r\n\tonChange: (value: string) => void;\r\n\tvariant: \"default\" | \"segmented\";\r\n}\r\n\r\nconst TabsContext = createContext<TabsContextType | undefined>(undefined);\r\n\r\n// --- Components ---\r\n\r\nexport interface TabsProps {\r\n\tdefaultValue: string;\r\n\tvalue?: string; // 制御コンポーネントとして使う場合\r\n\tonValueChange?: (value: string) => void;\r\n\tchildren: React.ReactNode;\r\n\tvariant?: \"default\" | \"segmented\";\r\n\tclassName?: string;\r\n}\r\n\r\nexport const Tabs: React.FC<TabsProps> = ({\r\n\tdefaultValue,\r\n\tvalue: propValue,\r\n\tonValueChange,\r\n\tchildren,\r\n\tvariant = \"default\",\r\n\tclassName = \"\",\r\n}) => {\r\n\tconst [localValue, setLocalValue] = useState(defaultValue);\r\n\tconst value = propValue ?? localValue;\r\n\r\n\tconst handleChange = (newValue: string) => {\r\n\t\tsetLocalValue(newValue);\r\n\t\tonValueChange?.(newValue);\r\n\t};\r\n\r\n\treturn (\r\n\t\t<TabsContext.Provider value={{ value, onChange: handleChange, variant }}>\r\n\t\t\t<div className={`${styles.root} ${className}`} data-variant={variant}>\r\n\t\t\t\t{children}\r\n\t\t\t</div>\r\n\t\t</TabsContext.Provider>\r\n\t);\r\n};\r\n\r\nexport interface TabsListProps {\r\n\tchildren: React.ReactNode;\r\n\tclassName?: string;\r\n\twidth?: number;\r\n\theight?: number;\r\n\tstyle?: React.CSSProperties;\r\n}\r\n\r\nexport const TabsList: React.FC<TabsListProps> = ({\r\n\tchildren,\r\n\tclassName = \"\",\r\n\twidth,\r\n\theight,\r\n\tstyle: propStyle,\r\n}) => {\r\n\tconst context = useContext(TabsContext);\r\n\tif (!context) {\r\n\t\tthrow new Error(\"TabsList must be used within a Tabs component\");\r\n\t}\r\n\tconst { variant } = context;\r\n\r\n\t// プロパティで渡されたstyleとwidth/heightをマージ\r\n\tconst computedStyle: React.CSSProperties = { ...propStyle };\r\n\tif (width !== undefined) computedStyle.width = `${width}px`;\r\n\tif (height !== undefined) computedStyle.height = `${height}px`;\r\n\r\n\treturn (\r\n\t\t<div\r\n\t\t\tclassName={`${styles.list} ${className}`}\r\n\t\t\tdata-variant={variant}\r\n\t\t\tstyle={computedStyle}\r\n\t\t>\r\n\t\t\t{children}\r\n\t\t</div>\r\n\t);\r\n};\r\n\r\nexport interface TabsTriggerProps {\r\n\tvalue: string;\r\n\tchildren: React.ReactNode;\r\n\tclassName?: string;\r\n\tdisabled?: boolean;\r\n\twidth?: number;\r\n\theight?: number;\r\n\tstyle?: React.CSSProperties;\r\n}\r\n\r\nexport const TabsTrigger: React.FC<TabsTriggerProps> = ({\r\n\tvalue,\r\n\tchildren,\r\n\tclassName = \"\",\r\n\tdisabled = false,\r\n\twidth,\r\n\theight,\r\n\tstyle: propStyle,\r\n}) => {\r\n\tconst context = useContext(TabsContext);\r\n\tif (!context) {\r\n\t\tthrow new Error(\"TabsTrigger must be used within a Tabs component\");\r\n\t}\r\n\tconst { value: selectedValue, onChange, variant } = context;\r\n\tconst isSelected = selectedValue === value;\r\n\r\n\tconst computedStyle: React.CSSProperties = { ...propStyle };\r\n\tif (width !== undefined) computedStyle.width = `${width}px`;\r\n\tif (height !== undefined) computedStyle.height = `${height}px`;\r\n\r\n\treturn (\r\n\t\t<button\r\n\t\t\tclassName={`${styles.trigger} ${className}`}\r\n\t\t\tdata-state={isSelected ? \"active\" : \"inactive\"}\r\n\t\t\tdata-variant={variant}\r\n\t\t\tonClick={() => onChange(value)}\r\n\t\t\tdisabled={disabled}\r\n\t\t\ttype=\"button\"\r\n\t\t\tstyle={computedStyle}\r\n\t\t>\r\n\t\t\t{children}\r\n\t\t</button>\r\n\t);\r\n};\r\n\r\nexport interface TabsContentProps {\r\n\tvalue: string;\r\n\tchildren: React.ReactNode;\r\n\tclassName?: string;\r\n}\r\n\r\nexport const TabsContent: React.FC<TabsContentProps> = ({\r\n\tvalue,\r\n\tchildren,\r\n\tclassName = \"\",\r\n}) => {\r\n\tconst context = useContext(TabsContext);\r\n\tif (!context) {\r\n\t\tthrow new Error(\"TabsContent must be used within a Tabs component\");\r\n\t}\r\n\tconst { value: selectedValue } = context;\r\n\r\n\tif (selectedValue !== value) return null;\r\n\r\n\treturn <div className={`${styles.content} ${className}`}>{children}</div>;\r\n};\r\n","/**\r\n * @file TextInput.tsx\r\n * @description テキスト入力コンポーネント\r\n */\r\n\r\nimport { useCallback } from \"react\";\r\n\r\nimport styles from \"./TextInput.module.css\";\r\n\r\nimport type React from \"react\";\r\nimport type { PropertyComponentProps } from \"@/plugin\";\r\nimport type { Value } from \"@/types/value\";\r\n\r\n/**\r\n * Config型定義\r\n * Record<string, Value> との互換性を持たせる\r\n */\r\nexport interface TextInputConfig {\r\n\tplaceholder?: string;\r\n\tmaxLength?: number;\r\n\tmultiline?: boolean;\r\n\trows?: number;\r\n\twidth?: number;\r\n\theight?: number;\r\n\t[key: string]: Value;\r\n}\r\n\r\n/**\r\n * TextInput固有のProps\r\n * T は string | undefined\r\n */\r\nexport interface TextInputProps\r\n\textends PropertyComponentProps<string | undefined> {\r\n\tplaceholder?: string;\r\n\tmaxLength?: number;\r\n\tmultiline?: boolean;\r\n\trows?: number;\r\n\twidth?: number;\r\n\theight?: number;\r\n\tconfig?: TextInputConfig;\r\n\tonBlur?: () => void;\r\n}\r\n\r\n/**\r\n * テキスト入力コンポーネント\r\n */\r\nexport const TextInput = ({\r\n\tvalue,\r\n\tonChange,\r\n\treadOnly = false, // readonly -> readOnly に統一\r\n\tplaceholder: propPlaceholder,\r\n\tmaxLength: propMaxLength,\r\n\tmultiline: propMultiline,\r\n\trows: propRows,\r\n\twidth,\r\n\theight,\r\n\tconfig,\r\n\tonBlur,\r\n}: TextInputProps): React.ReactElement => {\r\n\t// 設定のマージ\r\n\tconst placeholder = propPlaceholder ?? config?.placeholder;\r\n\tconst maxLength = propMaxLength ?? config?.maxLength;\r\n\tconst multiline = propMultiline ?? config?.multiline ?? false;\r\n\tconst rows = propRows ?? config?.rows ?? 3;\r\n\r\n\tconst handleChange = useCallback(\r\n\t\t(e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {\r\n\t\t\tconst newValue = e.target.value;\r\n\t\t\t// 空文字の場合は undefined (未設定) として扱うか、そのまま空文字とするかは要件次第だが、\r\n\t\t\t// ここでは空文字として渡す(テキストは空文字が有効な値であることが多いため)\r\n\t\t\t// 必要であればここを undefined に変えてください\r\n\t\t\tonChange(newValue);\r\n\t\t},\r\n\t\t[onChange],\r\n\t);\r\n\r\n\t// インラインスタイルの構築\r\n\tconst style: React.CSSProperties = {};\r\n\tif (width !== undefined) {\r\n\t\tstyle.width = `${width}px`;\r\n\t} else {\r\n\t\tstyle.width = \"100%\";\r\n\t}\r\n\tif (height !== undefined) {\r\n\t\tstyle.height = `${height}px`;\r\n\t}\r\n\r\n\tconst commonProps = {\r\n\t\tclassName: styles.input,\r\n\t\tstyle,\r\n\t\tvalue: value ?? \"\", // undefined なら空文字を表示\r\n\t\tonChange: handleChange,\r\n\t\tdisabled: readOnly,\r\n\t\tplaceholder,\r\n\t\tmaxLength,\r\n\t};\r\n\r\n\tif (multiline) {\r\n\t\treturn <textarea {...commonProps} rows={rows} />;\r\n\t}\r\n\r\n\treturn <input {...commonProps} type=\"text\" onBlur={onBlur} />;\r\n};\r\n\r\nTextInput.displayName = \"TextInput\";\r\n","export const ALL_UNITS = [\"mm\", \"cm\", \"fr\", \"inch\", \"pt\", \"px\", \"%\"] as const;\r\nexport const ACTUAL_UNITS = [\"mm\", \"cm\", \"pt\", \"inch\", \"px\"] as const;\r\nexport const PAPER_UNITS = [\"mm\", \"cm\", \"inch\"] as const;\r\nexport const GRID_UNITS = [\"mm\", \"cm\", \"fr\", \"inch\", \"pt\", \"px\"] as const;\r\nexport const BORDER_UNITS = [\"px\", \"pt\", \"mm\"] as const;\r\nexport const FONT_UNITS = [\"px\", \"pt\", \"mm\"] as const;\r\nexport const PADDING_UNITS = [\"mm\", \"pt\", \"px\", \"%\"] as const;\r\nexport const SIZE_UNITS = [\"mm\", \"cm\", \"inch\", \"pt\", \"px\", \"%\"] as const;\r\n\r\nexport type Unit = (typeof ALL_UNITS)[number];\r\nexport type ActualUnit = (typeof ACTUAL_UNITS)[number];\r\nexport type PaperUnit = (typeof PAPER_UNITS)[number];\r\nexport type GridUnit = (typeof GRID_UNITS)[number];\r\nexport type BorderUnit = (typeof BORDER_UNITS)[number];\r\nexport type FontUnit = (typeof FONT_UNITS)[number];\r\nexport type PaddingUnit = (typeof PADDING_UNITS)[number];\r\nexport type SizeUnit = (typeof SIZE_UNITS)[number];\r\n\r\nexport interface Dimension<U extends Unit = Unit> {\r\n\tvalue: number; // 値\r\n\tunit: U; // 単位\r\n}\r\n","// 必要なコンポーネントと定数をインポート\r\nimport { Checkbox, DimensionInput } from \"@/properties/components\";\r\nimport { PADDING_UNITS } from \"@/types/unit\";\r\n\r\nimport type { PluginProperties } from \"../definition\";\r\nimport type { PaddingSchema } from \"./schemas\";\r\n\r\n/**\r\n * PaddingSchema の実体定義\r\n */\r\nexport const paddingDefinition: PluginProperties<PaddingSchema> = {\r\n\t// 1. 切り替えスイッチ\r\n\tisIndividual: {\r\n\t\tdefaultValue: false,\r\n\t\tlabel: \"個別に設定\",\r\n\t\tgroup: \"余白\",\r\n\t\tComponent: Checkbox,\r\n\t\tdescription: \"上下左右の余白を個別に設定します\",\r\n\t},\r\n\r\n\t// 2. 一括設定 (isIndividual が false のとき表示)\r\n\tall: {\r\n\t\tdefaultValue: { value: 10, unit: \"px\" },\r\n\t\tlabel: \"全方向\",\r\n\t\tgroup: \"余白\",\r\n\t\tComponent: DimensionInput,\r\n\t\tconfig: {\r\n\t\t\tallowedUnits: PADDING_UNITS,\r\n\t\t\tmin: 0,\r\n\t\t},\r\n\t\t// ★ condition: 個別設定OFFのときだけ表示\r\n\t\tcondition: (data) => !data.isIndividual,\r\n\t},\r\n\r\n\t// 3. 個別設定 (isIndividual が true のとき表示)\r\n\ttop: {\r\n\t\tdefaultValue: { value: 10, unit: \"px\" },\r\n\t\tlabel: \"上\",\r\n\t\tgroup: \"余白\",\r\n\t\tComponent: DimensionInput,\r\n\t\tconfig: {\r\n\t\t\tallowedUnits: PADDING_UNITS,\r\n\t\t\tmin: 0,\r\n\t\t},\r\n\t\t// ★ condition: 個別設定ONのときだけ表示\r\n\t\tcondition: (data) => data.isIndividual === true,\r\n\t},\r\n\r\n\tright: {\r\n\t\tdefaultValue: { value: 10, unit: \"px\" },\r\n\t\tlabel: \"右\",\r\n\t\tgroup: \"余白\",\r\n\t\tComponent: DimensionInput,\r\n\t\tconfig: {\r\n\t\t\tallowedUnits: PADDING_UNITS,\r\n\t\t\tmin: 0,\r\n\t\t},\r\n\t\tcondition: (data) => data.isIndividual === true,\r\n\t},\r\n\r\n\tbottom: {\r\n\t\tdefaultValue: { value: 10, unit: \"px\" },\r\n\t\tlabel: \"下\",\r\n\t\tgroup: \"余白\",\r\n\t\tComponent: DimensionInput,\r\n\t\tconfig: {\r\n\t\t\tallowedUnits: PADDING_UNITS,\r\n\t\t\tmin: 0,\r\n\t\t},\r\n\t\tcondition: (data) => data.isIndividual === true,\r\n\t},\r\n\r\n\tleft: {\r\n\t\tdefaultValue: { value: 10, unit: \"px\" },\r\n\t\tlabel: \"左\",\r\n\t\tgroup: \"余白\",\r\n\t\tComponent: DimensionInput,\r\n\t\tconfig: {\r\n\t\t\tallowedUnits: PADDING_UNITS,\r\n\t\t\tmin: 0,\r\n\t\t},\r\n\t\tcondition: (data) => data.isIndividual === true,\r\n\t},\r\n};\r\n","import { alignmentDefinition } from \"../Alignment\";\r\nimport { paddingDefinition } from \"../Padding\";\r\n\r\n/**\r\n * ほぼすべてのブロックで使用される共通プロパティ定義\r\n *\r\n * ## 使用方法\r\n * ```typescript\r\n * export const MyPlugin: BlockPlugin = {\r\n * properties: {\r\n * ...universalProperties, // フラットに展開\r\n * // プラグイン固有のプロパティ\r\n * customProp: { ... },\r\n * },\r\n * };\r\n * ```\r\n *\r\n * ## 上書き\r\n * 個別のプロパティを上書きする場合は、後から定義します:\r\n * ```typescript\r\n * properties: {\r\n * ...universalProperties,\r\n * justifyContent: {\r\n * ...universalProperties.justifyContent,\r\n * defaultValue: HorizontalAlign.center, // デフォルト値を変更\r\n * },\r\n * }\r\n * ```\r\n *\r\n * ## 含まれるプロパティ\r\n * - **alignment** (justifyContent, alignItems): コンテンツの配置\r\n * - **padding** (isIndividual, all, top, right, bottom, left): 余白\r\n */\r\nexport const universalProperties = {\r\n\t...alignmentDefinition,\r\n\t...paddingDefinition,\r\n} as const;\r\n","import {\r\n\tCheckbox,\r\n\tColorPicker,\r\n\tDimensionInput,\r\n\tNumberInput,\r\n\tSelect,\r\n\ttype SelectOption,\r\n} from \"@/properties/components\";\r\nimport { FONT_UNITS } from \"@/types/unit\";\r\n\r\nimport type { PluginProperties } from \"../definition\";\r\nimport type { FontStyleSchema } from \"./schemas\";\r\n\r\nexport const DEFAULT_FONT_FAMILY: readonly SelectOption[] = [\r\n\t{ label: \"ゴシック体\", value: \"sans-serif\" },\r\n\t{ label: \"明朝体\", value: \"serif\" },\r\n\t{ label: \"等幅\", value: \"monospace\" },\r\n\t{ label: \"Arial\", value: \"Arial, sans-serif\" },\r\n\t{ label: \"Times New Roman\", value: \"'Times New Roman', serif\" },\r\n];\r\n\r\n/**\r\n * FontStyleSchema の実体定義\r\n */\r\nexport const fontStyleDefinition: PluginProperties<FontStyleSchema> = {\r\n\tfontSize: {\r\n\t\tdefaultValue: { value: 14, unit: \"pt\" },\r\n\t\tlabel: \"フォントサイズ\",\r\n\t\tgroup: \"フォント\",\r\n\t\tdescription: \"テキストのフォントサイズを設定します\",\r\n\t\tComponent: DimensionInput,\r\n\t\tconfig: {\r\n\t\t\tallowedUnits: FONT_UNITS,\r\n\t\t\tmin: 1,\r\n\t\t\tstep: 1,\r\n\t\t},\r\n\t},\r\n\r\n\tfontFamily: {\r\n\t\tdefaultValue: \"sans-serif\",\r\n\t\tlabel: \"フォント\",\r\n\t\tgroup: \"フォント\",\r\n\t\tComponent: Select,\r\n\t\tconfig: {\r\n\t\t\tplaceholder: \"フォントを選択\",\r\n\t\t\toptions: DEFAULT_FONT_FAMILY,\r\n\t\t},\r\n\t},\r\n\r\n\tcolor: {\r\n\t\tdefaultValue: undefined, // CSS変数を使用するため未設定\r\n\t\tlabel: \"文字色\",\r\n\t\tgroup: \"フォント\",\r\n\t\tComponent: ColorPicker,\r\n\t\tconfig: {\r\n\t\t\tallowUndefined: true, // 明示的に許可(デフォルトtrueなので省略可)\r\n\t\t},\r\n\t},\r\n\r\n\tfontWeight: {\r\n\t\tdefaultValue: false,\r\n\t\tlabel: \"太字\",\r\n\t\tgroup: \"フォント\",\r\n\t\tdescription: \"テキストを太字にします\",\r\n\t\tComponent: Checkbox,\r\n\t},\r\n\r\n\titalic: {\r\n\t\tdefaultValue: false,\r\n\t\tlabel: \"斜体\",\r\n\t\tgroup: \"フォント\",\r\n\t\tdescription: \"テキストを斜体にします\",\r\n\t\tComponent: Checkbox,\r\n\t},\r\n\r\n\tunderline: {\r\n\t\tdefaultValue: false,\r\n\t\tlabel: \"下線\",\r\n\t\tgroup: \"フォント\",\r\n\t\tdescription: \"テキストに下線を引きます\",\r\n\t\tComponent: Checkbox,\r\n\t},\r\n\r\n\tlineThrough: {\r\n\t\tdefaultValue: false,\r\n\t\tlabel: \"取り消し線\",\r\n\t\tgroup: \"フォント\",\r\n\t\tdescription: \"テキストに取り消し線を引きます\",\r\n\t\tComponent: Checkbox,\r\n\t},\r\n\r\n\tlineHeight: {\r\n\t\tdefaultValue: 1.2,\r\n\t\tlabel: \"行の高さ\",\r\n\t\tgroup: \"フォント\",\r\n\t\tdescription: \"行の高さを設定します(1.0〜3.0)\",\r\n\t\tComponent: NumberInput,\r\n\t\tconfig: {\r\n\t\t\tmin: 1,\r\n\t\t\tmax: 3,\r\n\t\t\tstep: 0.1,\r\n\t\t},\r\n\t},\r\n};\r\n","import type { Value } from \"@/types/value\";\r\nimport type { BlockPlugin } from \"../types\";\r\n\r\nexport type AnyBlockPlugin = BlockPlugin<Record<string, Value>, Value>;\r\n\r\n/**\r\n * プラグイン配列からプラグインレジストリを作成\r\n *\r\n * @remarks\r\n * - プラグインの kind をキーとしたオブジェクトを生成します\r\n * - 型推論により、配列内の具体的なプラグイン型が保持されます\r\n *\r\n * @template T - BlockPlugin の配列型\r\n * @param plugins プラグインの配列 (as const推奨)\r\n * @returns kind をキーとしたプラグインレジストリ\r\n *\r\n * @example\r\n * ```typescript\r\n * const registry = createPluginRegistry([\r\n * TextPlugin,\r\n * SelectPlugin,\r\n * CheckboxPlugin,\r\n * ] as const);\r\n * // registry.text, registry.select, registry.checkbox が型推論される\r\n * ```\r\n */\r\nexport function createPluginRegistry<T extends readonly BlockPlugin[]>(\r\n\tplugins: T,\r\n): Record<string, T[number]> {\r\n\treturn plugins.reduce(\r\n\t\t(acc, plugin) => {\r\n\t\t\tacc[plugin.kind] = plugin;\r\n\t\t\treturn acc;\r\n\t\t},\r\n\t\t{} as Record<string, T[number]>,\r\n\t);\r\n}\r\n","/**\r\n * 画像プロパティのスキーマ(フラット)\r\n */\r\n\r\nexport enum ImageObjectFit {\r\n\tContain = \"contain\",\r\n\tCover = \"cover\",\r\n\tFill = \"fill\",\r\n\tNone = \"none\",\r\n\tScaleDown = \"scale-down\",\r\n}\r\n\r\nexport interface ImageSchema {\r\n\tobjectFit?: ImageObjectFit;\r\n\talt?: string;\r\n}\r\n","// UIコンポーネントをインポート\r\n\r\nimport { ImageObjectFit, type ImageSchema } from \"./schemas\";\r\n\r\nimport { Select } from \"@/properties/components/Select\";\r\nimport { TextInput } from \"@/properties/components/TextInput\";\r\n\r\n// ★ 型安全な定義型をインポート\r\nimport type { PluginProperties } from \"@/plugin\";\r\n\r\n/**\r\n * ImageSchema の実体定義\r\n */\r\nexport const imageDefinition: PluginProperties<ImageSchema> = {\r\n\tobjectFit: {\r\n\t\tdefaultValue: ImageObjectFit.Contain,\r\n\t\tlabel: \"表示方法\",\r\n\t\tgroup: \"画像\",\r\n\t\tdescription: \"画像のサイズが枠と合わない場合の表示方法を設定します\",\r\n\t\tComponent: Select,\r\n\t\tconfig: {\r\n\t\t\toptions: [\r\n\t\t\t\t{\r\n\t\t\t\t\tlabel: \"全体を表示\",\r\n\t\t\t\t\tvalue: ImageObjectFit.Contain,\r\n\t\t\t\t},\r\n\t\t\t\t{\r\n\t\t\t\t\tlabel: \"枠を埋める/切り抜き\",\r\n\t\t\t\t\tvalue: ImageObjectFit.Cover,\r\n\t\t\t\t},\r\n\t\t\t\t{\r\n\t\t\t\t\tlabel: \"引き伸ばす/縮小する\",\r\n\t\t\t\t\tvalue: ImageObjectFit.Fill,\r\n\t\t\t\t},\r\n\t\t\t\t{\r\n\t\t\t\t\tlabel: \"元のサイズ\",\r\n\t\t\t\t\tvalue: ImageObjectFit.None,\r\n\t\t\t\t},\r\n\t\t\t\t{\r\n\t\t\t\t\tlabel: \"縮小のみ\",\r\n\t\t\t\t\tvalue: ImageObjectFit.ScaleDown,\r\n\t\t\t\t},\r\n\t\t\t],\r\n\t\t},\r\n\t},\r\n\r\n\talt: {\r\n\t\tdefaultValue: \"\",\r\n\t\tlabel: \"代替テキスト\",\r\n\t\tgroup: \"画像\",\r\n\t\tdescription: \"画像が表示できない場合に表示されるテキスト\",\r\n\t\tComponent: TextInput,\r\n\t\tconfig: {\r\n\t\t\tplaceholder: \"画像の説明\",\r\n\t\t},\r\n\t},\r\n};\r\n","// 複数行プロパティ\r\nexport enum MultilineWordWrap {\r\n\tNormal = \"normal\",\r\n\tBreakWord = \"break-word\",\r\n\tBreakAll = \"break-all\",\r\n}\r\n\r\nexport enum MultilineWhiteSpace {\r\n\tNormal = \"normal\",\r\n\tNoWrap = \"nowrap\",\r\n\tPre = \"pre\",\r\n\tPreWrap = \"pre-wrap\",\r\n\tPreLine = \"pre-line\",\r\n}\r\n\r\nexport interface MultilineSchema {\r\n\tmultiline?: boolean;\r\n\twordWrap?: MultilineWordWrap;\r\n\twhiteSpace?: MultilineWhiteSpace;\r\n}\r\n","import {\r\n\ttype MultilineSchema,\r\n\tMultilineWhiteSpace,\r\n\tMultilineWordWrap,\r\n} from \"./schemas\";\r\n\r\nimport { Checkbox, Select } from \"@/properties/components\";\r\n\r\nimport type { PluginProperties } from \"../definition\";\r\n\r\nexport const multilineDefinition: PluginProperties<MultilineSchema> = {\r\n\tmultiline: {\r\n\t\tdefaultValue: false,\r\n\t\tlabel: \"複数行モード\",\r\n\t\tgroup: \"設定\",\r\n\t\tComponent: Checkbox,\r\n\t\tconfig: { label: \"有効にする\" },\r\n\t},\r\n\r\n\twordWrap: {\r\n\t\tdefaultValue: MultilineWordWrap.Normal,\r\n\t\tlabel: \"単語の折り返し\",\r\n\t\tgroup: \"設定\",\r\n\t\tComponent: Select,\r\n\t\tconfig: {\r\n\t\t\toptions: [\r\n\t\t\t\t{ label: \"通常\", value: MultilineWordWrap.Normal },\r\n\t\t\t\t{ label: \"単語で改行\", value: MultilineWordWrap.BreakWord },\r\n\t\t\t\t{ label: \"強制改行\", value: MultilineWordWrap.BreakAll },\r\n\t\t\t],\r\n\t\t},\r\n\t\tcondition: (data) => data.multiline === true,\r\n\t},\r\n\r\n\twhiteSpace: {\r\n\t\tdefaultValue: MultilineWhiteSpace.Normal,\r\n\t\tlabel: \"空白文字の扱い\",\r\n\t\tgroup: \"設定\",\r\n\t\tComponent: Select,\r\n\t\tconfig: {\r\n\t\t\toptions: [\r\n\t\t\t\t{ label: \"通常\", value: MultilineWhiteSpace.Normal },\r\n\t\t\t\t{ label: \"折り返しなし\", value: MultilineWhiteSpace.NoWrap },\r\n\t\t\t\t{ label: \"そのまま表示\", value: MultilineWhiteSpace.Pre },\r\n\t\t\t],\r\n\t\t},\r\n\t\tcondition: (data) => data.multiline === true,\r\n\t},\r\n};\r\n","// 型定義とコンポーネントをインポート\r\n\r\nimport { TextInput } from \"@/properties/components/TextInput\";\r\n\r\nimport type { PluginProperties } from \"../definition\";\r\nimport type { PlaceholderSchema } from \"./schemas\";\r\n\r\n/**\r\n * PlaceholderSchema の実体定義\r\n */\r\nexport const placeholderDefinition: PluginProperties<PlaceholderSchema> = {\r\n\tplaceholder: {\r\n\t\tdefaultValue: undefined,\r\n\t\tlabel: \"プレースホルダー\",\r\n\t\tgroup: \"設定\",\r\n\t\tdescription: \"入力欄に表示するプレースホルダーテキストを設定します\",\r\n\r\n\t\tComponent: TextInput,\r\n\r\n\t\tconfig: {\r\n\t\t\tplaceholder: \"例: テキストを入力してください\",\r\n\t\t},\r\n\t},\r\n};\r\n","// UIコンポーネントと定数\r\nimport { DimensionInput } from \"@/properties/components/DimensionInput\";\r\nimport { SIZE_UNITS } from \"@/types/unit\";\r\n\r\nimport type { PluginProperties } from \"../definition\"; // パスは環境に合わせてください\r\nimport type { SizeSchema } from \"./schemas\";\r\n\r\n/**\r\n * SizeSchema の実体定義\r\n */\r\nexport const sizeDefinition: PluginProperties<SizeSchema> = {\r\n\twidth: {\r\n\t\tdefaultValue: undefined, // undefinedなら auto として扱う想定\r\n\t\tlabel: \"幅\",\r\n\t\tgroup: \"サイズ\",\r\n\t\tdescription: \"要素の幅を設定します\",\r\n\r\n\t\tComponent: DimensionInput,\r\n\t\tconfig: {\r\n\t\t\tmin: 0,\r\n\t\t\tallowedUnits: SIZE_UNITS, // px, %, mm など\r\n\t\t\tplaceholder: \"auto\", // 未設定時は \"auto\" と表示されると親切\r\n\t\t},\r\n\t},\r\n\r\n\theight: {\r\n\t\tdefaultValue: undefined,\r\n\t\tlabel: \"高さ\",\r\n\t\tgroup: \"サイズ\",\r\n\t\tdescription: \"要素の高さを設定します\",\r\n\r\n\t\tComponent: DimensionInput,\r\n\t\tconfig: {\r\n\t\t\tmin: 0,\r\n\t\t\tallowedUnits: SIZE_UNITS,\r\n\t\t\tplaceholder: \"auto\",\r\n\t\t},\r\n\t},\r\n};\r\n","// packages/core/src/utils/plugin.ts\r\n\r\nimport type { BlockPlugin } from \"../types\";\r\n\r\n/**\r\n * プラグインの properties 定義から初期Propsを生成\r\n *\r\n * @remarks\r\n * - フラットなプロパティ定義から defaultValue を抽出してオブジェクトを生成します\r\n * - false で無効化されたプロパティはスキップします\r\n * - defaultValue が undefined のプロパティも含めます(CSS変数対応のため)\r\n *\r\n * @param plugin BlockPlugin オブジェクト\r\n * @returns 初期化されたプロパティオブジェクト\r\n */\r\nexport const createInitialProps = <P>(plugin: BlockPlugin<P>): P => {\r\n\tconst initialProps: Record<string, unknown> = {};\r\n\r\n\tObject.entries(plugin.properties).forEach(([key, config]) => {\r\n\t\t// false (無効) の場合はスキップ\r\n\t\tif (config === false) return;\r\n\r\n\t\t// プロパティ定義オブジェクトの場合、defaultValue を取得\r\n\t\t// (今の設計ではすべての定義がフラットなので再帰処理は不要)\r\n\t\tif (\r\n\t\t\ttypeof config === \"object\" &&\r\n\t\t\tconfig !== null &&\r\n\t\t\t\"defaultValue\" in config\r\n\t\t) {\r\n\t\t\tinitialProps[key] = config.defaultValue;\r\n\t\t}\r\n\t});\r\n\r\n\treturn initialProps as P;\r\n};\r\n","// packages/core/src/utils/block.ts\r\n\r\nimport { createInitialProps } from \"./func\";\r\n\r\nimport type { Block } from \"@/types/block\";\r\nimport type { BlockPlugin } from \"../types\";\r\n\r\n/**\r\n * ブロック ID を生成\r\n *\r\n * @remarks\r\n * UUID/nanoid は使わず、カスタム ID 方式\r\n * タイムスタンプ + ランダム文字列で一意性を保証\r\n */\r\nexport function createBlockId(kind: string): string {\r\n\tconst timestamp = Date.now();\r\n\tconst random = Math.random().toString(36).slice(2);\r\n\treturn `${kind}_${timestamp}_${random}`;\r\n}\r\n\r\n/**\r\n * 新規ブロックを作成\r\n *\r\n * @remarks\r\n * Interaction層(D&Dでの配置)や初期化時に使用されます。\r\n *\r\n * @param plugin ブロックプラグイン\r\n * @param position グリッド上の配置情報\r\n * @param overrideProps プロパティの上書き(オプション)\r\n * @returns 新しい Block オブジェクト\r\n */\r\nexport function createBlock<P = Record<string, unknown>>(\r\n\tplugin: BlockPlugin<P>,\r\n\tposition: { x: number; y: number; w: number; h: number },\r\n\toverrideProps?: Partial<P>,\r\n): Block<P> {\r\n\t// プラグインの properties 定義から初期Propsを生成\r\n\tconst initialProps = createInitialProps(plugin);\r\n\r\n\treturn {\r\n\t\tid: createBlockId(plugin.kind),\r\n\t\tkind: plugin.kind,\r\n\t\tlayout: {\r\n\t\t\tx: position.x,\r\n\t\t\ty: position.y,\r\n\t\t\tw: position.w,\r\n\t\t\th: position.h,\r\n\t\t},\r\n\t\tstyle: {},\r\n\t\tbehavior: {},\r\n\t\tprops: {\r\n\t\t\t...initialProps,\r\n\t\t\t...overrideProps, // 上書き可能\r\n\t\t},\r\n\t};\r\n}\r\n","// UIコンポーネント\r\nimport { Checkbox, NumberInput, TextInput } from \"@/properties/components\";\r\n\r\nimport type { PluginProperties } from \"../definition\";\r\nimport type { ValidationSchema } from \"./schemas\";\r\n\r\n/**\r\n * ValidationSchema の実体定義\r\n */\r\nexport const validationDefinition: PluginProperties<ValidationSchema> = {\r\n\trequired: {\r\n\t\tdefaultValue: false,\r\n\t\tlabel: \"必須項目\",\r\n\t\tgroup: \"バリデーション\",\r\n\t\tdescription: \"この項目を必須入力にします\",\r\n\t\tComponent: Checkbox,\r\n\t\tconfig: {\r\n\t\t\tlabel: \"必須にする\",\r\n\t\t},\r\n\t},\r\n\r\n\tminLength: {\r\n\t\tdefaultValue: undefined,\r\n\t\tlabel: \"最小文字数\",\r\n\t\tgroup: \"バリデーション\",\r\n\t\tdescription: \"入力可能な最小文字数を設定します\",\r\n\t\tComponent: NumberInput,\r\n\t\tconfig: {\r\n\t\t\tmin: 0,\r\n\t\t\tinteger: true, // 文字数は整数のみ\r\n\t\t\tplaceholder: \"制限なし\",\r\n\t\t},\r\n\t},\r\n\r\n\tmaxLength: {\r\n\t\tdefaultValue: undefined,\r\n\t\tlabel: \"最大文字数\",\r\n\t\tgroup: \"バリデーション\",\r\n\t\tdescription: \"入力可能な最大文字数を設定します\",\r\n\t\tComponent: NumberInput,\r\n\t\tconfig: {\r\n\t\t\tmin: 0,\r\n\t\t\tinteger: true,\r\n\t\t\tplaceholder: \"制限なし\",\r\n\t\t},\r\n\t},\r\n\r\n\tpattern: {\r\n\t\tdefaultValue: undefined,\r\n\t\tlabel: \"入力パターン (正規表現)\",\r\n\t\tgroup: \"バリデーション\",\r\n\t\tdescription: \"入力値を検証する正規表現パターンを設定します\",\r\n\t\tComponent: TextInput,\r\n\t\tconfig: {\r\n\t\t\tplaceholder: \"例: ^[0-9]+$\", // 正規表現の例を表示\r\n\t\t},\r\n\t\tdisableInMultiSelection: true, // 複雑な設定なので複数選択時は無効化が無難\r\n\t},\r\n};\r\n","// ブロック変更イベント関連型定義\r\n\r\nimport type { Block } from \"./types\";\r\n\r\n// ブロック変更操作種別\r\nexport enum BlockChangeType {\r\n\t/** ブロック追加 */\r\n\tADD = \"add\",\r\n\t/** ブロック更新 */\r\n\tUPDATE = \"update\",\r\n\t/** ブロック削除 */\r\n\tDELETE = \"delete\",\r\n\t/** ブロック移動 */\r\n\tMOVE = \"move\",\r\n\t/** ブロックリサイズ */\r\n\tRESIZE = \"resize\",\r\n\t/** ブロック複製 */\r\n\tDUPLICATE = \"duplicate\",\r\n\t/** ブロック貼り付け */\r\n\tPASTE = \"paste\",\r\n}\r\n\r\n// ブロック変更イベント\r\nexport interface BlockChangeEvent {\r\n\ttype: BlockChangeType;\r\n\tblockIds: string[];\r\n\tblocks?: Block[];\r\n\tupdates?: Record<string, Partial<Block>>;\r\n}\r\n","// グリッド関連型定義\r\n\r\nimport type { Dimension, GridUnit } from \"../unit\";\r\n\r\n// グリッドオブジェクト(物理単位)\r\nexport interface Grid {\r\n\tcols: Dimension<GridUnit>[]; // 列幅配列\r\n\trows: Dimension<GridUnit>[]; // 行高配列\r\n}\r\n\r\n// デフォルトグリッド設定 (12列x16行、均等配分)\r\nexport const DEFAULT_GRID: Grid = {\r\n\tcols: Array.from({ length: 12 }).map(() => ({ value: 1, unit: \"fr\" })),\r\n\trows: Array.from({ length: 16 }).map(() => ({ value: 1, unit: \"fr\" })),\r\n};\r\n\r\n// グリッド位置(ピクセル単位)\r\nexport interface GridPosPx {\r\n\tcols: number[]; // 列インデックス配列 (px単位)\r\n\trows: number[]; // 行インデックス配列 (px単位)\r\n}\r\n","// 線関連型定義\r\n\r\nimport type { BorderUnit, Dimension } from \"../unit\";\r\n\r\n// 線スタイル列挙型\r\nexport enum LineType {\r\n\tSOLID = \"solid\", // 実線\r\n\tDASHED = \"dashed\", // 破線\r\n\tDOTTED = \"dotted\", // 点線\r\n}\r\n\r\n// 線スタイル定義\r\nexport interface LineStyle {\r\n\tcolor: string; // 線の色 (CSS color値)\r\n\twidth: Dimension<BorderUnit>; // 線の幅\r\n\ttype: LineType; // 線のスタイル\r\n}\r\n\r\n// 枠線スタイル定義\r\nexport interface BorderStyle {\r\n\tall?: LineStyle; // 全辺共通スタイル\r\n\ttop?: LineStyle; // 上辺スタイル\r\n\tright?: LineStyle; // 右辺スタイル\r\n\tbottom?: LineStyle; // 下辺スタイル\r\n\tleft?: LineStyle; // 左辺スタイル\r\n}\r\n","export const DEFAULT_DPI = 96;\r\n","// 数値のアサーション\r\n\r\n/**\r\n * 値が正 (> 0) であることを検証し、失敗時は例外を投げる\r\n * @param value 検証する値\r\n * @param name 値の名前(エラーメッセージに含まれる)\r\n * @throws {Error} 値が0以下の場合\r\n */\r\nexport function assertPositive(value: number, name?: string): void {\r\n\tif (value <= 0) {\r\n\t\tconst label = name ?? \"Value\";\r\n\t\tthrow new Error(`${label} must be positive (> 0): got ${value}`);\r\n\t}\r\n}\r\n\r\n/**\r\n * 値が非負(>= 0)であることを検証し、失敗時は例外を投げる\r\n * @param value 検証する値\r\n * @param name 値の名前(エラーメッセージに含まれる)\r\n * @throws {Error} 値が負の場合\r\n */\r\nexport function assertNonNegative(value: number, name?: string): void {\r\n\tif (value < 0) {\r\n\t\tconst label = name ?? \"Value\";\r\n\t\tthrow new Error(`${label} must be non-negative (>= 0): got ${value}`);\r\n\t}\r\n}\r\n\r\n/**\r\n * 値が指定範囲内であることを検証し、失敗時は例外を投げる\r\n * @param value 検証する値\r\n * @param min 最小値(含む)\r\n * @param max 最大値(含む)\r\n * @param name 値の名前(エラーメッセージに含まれる)\r\n * @throws {Error} 値が範囲外の場合\r\n */\r\nexport function assertRange(\r\n\tvalue: number,\r\n\tmin: number,\r\n\tmax: number,\r\n\tname?: string,\r\n): void {\r\n\tif (value < min || value > max) {\r\n\t\tconst label = name ?? \"Value\";\r\n\t\tthrow new Error(`${label} must be between ${min} and ${max}: got ${value}`);\r\n\t}\r\n}\r\n\r\n/**\r\n * 値が整数であることを検証し、失敗時は例外を投げる\r\n * @param value 検証する値\r\n * @param name 値の名前(エラーメッセージに含まれる)\r\n * @throws {Error} 値が整数でない場合\r\n */\r\nexport function assertInteger(value: number, name?: string): void {\r\n\tif (!Number.isInteger(value)) {\r\n\t\tconst label = name ?? \"Value\";\r\n\t\tthrow new Error(`${label} must be an integer: got ${value}`);\r\n\t}\r\n}\r\n\r\n/**\r\n * 値が有限数であることを検証し、失敗時は例外を投げる\r\n * @param value 検証する値\r\n * @param name 値の名前(エラーメッセージに含まれる)\r\n * @throws {Error} 値がInfinityまたはNaNの場合\r\n */\r\nexport function assertFinite(value: number, name?: string): void {\r\n\tif (!Number.isFinite(value)) {\r\n\t\tconst label = name ?? \"Value\";\r\n\t\tthrow new Error(`${label} must be a finite number: got ${value}`);\r\n\t}\r\n}\r\n","import {\r\n\tassertInteger,\r\n\tassertNonNegative,\r\n\tassertPositive,\r\n} from \"../assert/number\";\r\n\r\nimport { DEFAULT_DPI } from \"@/constants\";\r\n\r\nimport type { Dimension, Unit } from \"@/types\";\r\n\r\nconst MM_PER_INCH = 25.4;\r\nconst CM_PER_INCH = 2.54;\r\nconst PT_PER_INCH = 72;\r\n\r\nexport const toPx = {\r\n\t_assertDpi(dpi: number) {\r\n\t\tassertPositive(dpi, \"DPI\");\r\n\t\tassertInteger(dpi, \"DPI\");\r\n\t},\r\n\r\n\tfromMm(mm: number, dpi: number = DEFAULT_DPI): number {\r\n\t\ttoPx._assertDpi(dpi);\r\n\t\tassertNonNegative(mm, `Millimeter value`);\r\n\t\treturn (mm * dpi) / MM_PER_INCH;\r\n\t},\r\n\r\n\tfromCm(cm: number, dpi: number = DEFAULT_DPI): number {\r\n\t\ttoPx._assertDpi(dpi);\r\n\t\tassertNonNegative(cm, `Centimeter value`);\r\n\t\treturn (cm * dpi) / CM_PER_INCH;\r\n\t},\r\n\r\n\tfromInch(inch: number, dpi: number = DEFAULT_DPI): number {\r\n\t\ttoPx._assertDpi(dpi);\r\n\t\tassertNonNegative(inch, `Inch value`);\r\n\t\treturn inch * dpi;\r\n\t},\r\n\r\n\tfromPt(pt: number, dpi: number = DEFAULT_DPI): number {\r\n\t\ttoPx._assertDpi(dpi);\r\n\t\tassertNonNegative(pt, `Point value`);\r\n\t\treturn (pt * dpi) / PT_PER_INCH;\r\n\t},\r\n\r\n\t// データ上のpxはDPI=96として扱う\r\n\tfromPx(px: number, dpi: number = DEFAULT_DPI): number {\r\n\t\ttoPx._assertDpi(dpi);\r\n\t\tassertNonNegative(px, `Pixel value`);\r\n\t\treturn (px * dpi) / DEFAULT_DPI;\r\n\t},\r\n\r\n\tfromDim<U extends Unit>(\r\n\t\tdim: Dimension<U>,\r\n\t\tdpi: number = DEFAULT_DPI,\r\n\t\tbaseSizePx?: number,\r\n\t): number {\r\n\t\ttoPx._assertDpi(dpi);\r\n\t\tassertNonNegative(dim.value, `Dimension value`);\r\n\t\tswitch (dim.unit) {\r\n\t\t\tcase \"mm\":\r\n\t\t\t\treturn toPx.fromMm(dim.value, dpi);\r\n\t\t\tcase \"cm\":\r\n\t\t\t\treturn toPx.fromCm(dim.value, dpi);\r\n\t\t\tcase \"inch\":\r\n\t\t\t\treturn toPx.fromInch(dim.value, dpi);\r\n\t\t\tcase \"pt\":\r\n\t\t\t\treturn toPx.fromPt(dim.value, dpi);\r\n\t\t\tcase \"px\":\r\n\t\t\t\treturn toPx.fromPx(dim.value, dpi);\r\n\t\t\tcase \"%\":\r\n\t\t\t\tif (baseSizePx === undefined) {\r\n\t\t\t\t\tthrow new Error(`Base size must be defined for percentage values.`);\r\n\t\t\t\t}\r\n\t\t\t\treturn (dim.value / 100) * baseSizePx;\r\n\t\t\tcase \"fr\":\r\n\t\t\t\tthrow new Error(\r\n\t\t\t\t\t`Cannot convert ${dim.unit} to px. Use physical units only.`,\r\n\t\t\t\t);\r\n\t\t\tdefault: {\r\n\t\t\t\tconst _exhaustive: never = dim.unit;\r\n\t\t\t\tthrow new Error(`Unsupported unit: ${_exhaustive}`);\r\n\t\t\t}\r\n\t\t}\r\n\t},\r\n};\r\n","import { type BorderStyle, type LineStyle, LineType } from \"./types\";\r\n\r\nimport { DEFAULT_DPI } from \"@/constants\";\r\nimport { toPx } from \"@/utils/convert/toPx\";\r\n\r\nexport const getStrokeDasharray = (\r\n\tlineStyle?: LineStyle,\r\n): string | undefined => {\r\n\tif (!lineStyle?.width || !lineStyle?.type) return undefined;\r\n\tconst actualLineWidth = lineStyle.width.value;\r\n\t// widthが0の場合はundefinedを返す\r\n\tif (actualLineWidth === 0) return undefined;\r\n\tif (lineStyle.type === LineType.DASHED) {\r\n\t\treturn `${actualLineWidth * 4} ${actualLineWidth * 2}`;\r\n\t}\r\n\tif (lineStyle.type === LineType.DOTTED) {\r\n\t\treturn `${actualLineWidth * 1} ${actualLineWidth * 2}`;\r\n\t}\r\n\treturn undefined;\r\n};\r\n\r\nexport class Border {\r\n\tconstructor(private readonly style: BorderStyle) {}\r\n\r\n\tget top(): LineStyle | undefined {\r\n\t\tif (!this.style.top) return this.style.all;\r\n\t\treturn {\r\n\t\t\t...this.style.all,\r\n\t\t\t...this.style.top,\r\n\t\t} as LineStyle;\r\n\t}\r\n\r\n\tget right(): LineStyle | undefined {\r\n\t\tif (!this.style.right) return this.style.all;\r\n\t\treturn {\r\n\t\t\t...this.style.all,\r\n\t\t\t...this.style.right,\r\n\t\t} as LineStyle;\r\n\t}\r\n\r\n\tget bottom(): LineStyle | undefined {\r\n\t\tif (!this.style.bottom) return this.style.all;\r\n\t\treturn {\r\n\t\t\t...this.style.all,\r\n\t\t\t...this.style.bottom,\r\n\t\t} as LineStyle;\r\n\t}\r\n\r\n\tget left(): LineStyle | undefined {\r\n\t\tif (!this.style.left) return this.style.all;\r\n\t\treturn {\r\n\t\t\t...this.style.all,\r\n\t\t\t...this.style.left,\r\n\t\t} as LineStyle;\r\n\t}\r\n\r\n\tget hasAnyBorder(): boolean {\r\n\t\treturn !!(this.top || this.right || this.bottom || this.left);\r\n\t}\r\n\r\n\tgetTopSVGProps(widthPx: number, dpi: number = DEFAULT_DPI) {\r\n\t\tconst style = this.top;\r\n\t\tif (!style) return null;\r\n\t\treturn {\r\n\t\t\tx1: 0,\r\n\t\t\ty1: 0,\r\n\t\t\tx2: widthPx,\r\n\t\t\ty2: 0,\r\n\t\t\tstroke: style.color,\r\n\t\t\tstrokeWidth: toPx.fromDim(style.width, dpi),\r\n\t\t\tstrokeDasharray: getStrokeDasharray(style),\r\n\t\t\tvectorEffect: \"non-scaling-stroke\",\r\n\t\t\t\"data-edge\": \"top\",\r\n\t\t};\r\n\t}\r\n\r\n\tgetRightSVGProps(\r\n\t\twidthPx: number,\r\n\t\theightPx: number,\r\n\t\tdpi: number = DEFAULT_DPI,\r\n\t) {\r\n\t\tconst style = this.right;\r\n\t\tif (!style) return null;\r\n\t\treturn {\r\n\t\t\tx1: widthPx,\r\n\t\t\ty1: 0,\r\n\t\t\tx2: widthPx,\r\n\t\t\ty2: heightPx,\r\n\t\t\tstroke: style.color,\r\n\t\t\tstrokeWidth: toPx.fromDim(style.width, dpi),\r\n\t\t\tstrokeDasharray: getStrokeDasharray(style),\r\n\t\t\tvectorEffect: \"non-scaling-stroke\",\r\n\t\t\t\"data-edge\": \"right\",\r\n\t\t};\r\n\t}\r\n\r\n\tgetBottomSVGProps(\r\n\t\twidthPx: number,\r\n\t\theightPx: number,\r\n\t\tdpi: number = DEFAULT_DPI,\r\n\t) {\r\n\t\tconst style = this.bottom;\r\n\t\tif (!style) return null;\r\n\t\treturn {\r\n\t\t\tx1: 0,\r\n\t\t\ty1: heightPx,\r\n\t\t\tx2: widthPx,\r\n\t\t\ty2: heightPx,\r\n\t\t\tstroke: style.color,\r\n\t\t\tstrokeWidth: toPx.fromDim(style.width, dpi),\r\n\t\t\tstrokeDasharray: getStrokeDasharray(style),\r\n\t\t\tvectorEffect: \"non-scaling-stroke\",\r\n\t\t\t\"data-edge\": \"bottom\",\r\n\t\t};\r\n\t}\r\n\r\n\tgetLeftSVGProps(heightPx: number, dpi: number = DEFAULT_DPI) {\r\n\t\tconst style = this.left;\r\n\t\tif (!style) return null;\r\n\t\treturn {\r\n\t\t\tx1: 0,\r\n\t\t\ty1: 0,\r\n\t\t\tx2: 0,\r\n\t\t\ty2: heightPx,\r\n\t\t\tstroke: style.color,\r\n\t\t\tstrokeWidth: toPx.fromDim(style.width, dpi),\r\n\t\t\tstrokeDasharray: getStrokeDasharray(style),\r\n\t\t\tvectorEffect: \"non-scaling-stroke\",\r\n\t\t\t\"data-edge\": \"left\",\r\n\t\t};\r\n\t}\r\n}\r\n","// モード列挙型\r\n\r\nexport enum NoteMode {\r\n\tFORM = \"Form\", // テンプレート作成モード\r\n\tEDIT = \"Edit\", // 値入力モード\r\n\tVIEW = \"View\", // 閲覧モード\r\n}\r\n","// 用紙関連型定義\r\n\r\nimport type { Dimension, PaperUnit } from \"../unit\";\r\n\r\n// 用紙サイズプリセット名\r\nexport enum PaperSizePreset {\r\n\tA4 = \"A4\",\r\n\tB5 = \"B5\",\r\n\tA3 = \"A3\",\r\n\tLETTER = \"Letter\",\r\n\tLEGAL = \"Legal\",\r\n\tCUSTOM = \"Custom\",\r\n}\r\n\r\n// 用紙サイズ設定\r\nexport interface PaperSize {\r\n\tpreset: PaperSizePreset; // プリセット名\r\n\twidth: Dimension<PaperUnit>; // 幅 (物理単位)\r\n\theight: Dimension<PaperUnit>; // 高さ (物理単位)\r\n}\r\n\r\n// デフォルト用紙サイズ設定\r\nexport const DEFAULT_PAPER_SIZES: Record<PaperSizePreset, PaperSize> = {\r\n\t[PaperSizePreset.A4]: {\r\n\t\tpreset: PaperSizePreset.A4,\r\n\t\twidth: { value: 210, unit: \"mm\" },\r\n\t\theight: { value: 297, unit: \"mm\" },\r\n\t},\r\n\t[PaperSizePreset.A3]: {\r\n\t\tpreset: PaperSizePreset.A3,\r\n\t\twidth: { value: 297, unit: \"mm\" },\r\n\t\theight: { value: 420, unit: \"mm\" },\r\n\t},\r\n\t[PaperSizePreset.B5]: {\r\n\t\tpreset: PaperSizePreset.B5,\r\n\t\twidth: { value: 182, unit: \"mm\" },\r\n\t\theight: { value: 257, unit: \"mm\" },\r\n\t},\r\n\t[PaperSizePreset.LETTER]: {\r\n\t\tpreset: PaperSizePreset.LETTER,\r\n\t\twidth: { value: 8.5, unit: \"inch\" },\r\n\t\theight: { value: 11, unit: \"inch\" },\r\n\t},\r\n\t[PaperSizePreset.LEGAL]: {\r\n\t\tpreset: PaperSizePreset.LEGAL,\r\n\t\twidth: { value: 8.5, unit: \"inch\" },\r\n\t\theight: { value: 14, unit: \"inch\" },\r\n\t},\r\n\t[PaperSizePreset.CUSTOM]: {\r\n\t\tpreset: PaperSizePreset.CUSTOM,\r\n\t\twidth: { value: 210, unit: \"mm\" },\r\n\t\theight: { value: 297, unit: \"mm\" },\r\n\t},\r\n};\r\n\r\n// 用紙マージン設定\r\nexport interface PaperMargin {\r\n\ttop: Dimension<PaperUnit>; // 上マージン\r\n\tright: Dimension<PaperUnit>; // 右マージン\r\n\tbottom: Dimension<PaperUnit>; // 下マージン\r\n\tleft: Dimension<PaperUnit>; // 左マージン\r\n}\r\n\r\n// デフォルト用紙マージン設定\r\nexport const DEFAULT_PAPER_MARGIN: PaperMargin = {\r\n\ttop: { value: 10, unit: \"mm\" },\r\n\tright: { value: 10, unit: \"mm\" },\r\n\tbottom: { value: 10, unit: \"mm\" },\r\n\tleft: { value: 10, unit: \"mm\" },\r\n};\r\n\r\n// 用紙設定\r\nexport interface Paper {\r\n\tsize: PaperSize;\r\n\tmargin: PaperMargin;\r\n}\r\n\r\n// デフォルト用紙設定\r\nexport const DEFAULT_PAPER: Paper = {\r\n\tsize: DEFAULT_PAPER_SIZES[PaperSizePreset.A4],\r\n\tmargin: DEFAULT_PAPER_MARGIN,\r\n};\r\n\r\n// 用紙サイズ設定(ピクセル単位)\r\nexport interface PaperCanvasPx {\r\n\twidth: number; // 幅 (px)\r\n\theight: number; // 高さ (px)\r\n}\r\n\r\n// 用紙マージン設定(ピクセル単位)\r\nexport interface PaperMarginPx {\r\n\ttop: number; // 上マージン (px)\r\n\tright: number; // 右マージン (px)\r\n\tbottom: number; // 下マージン (px)\r\n\tleft: number; // 左マージン (px)\r\n}\r\n\r\nexport interface PaperContentPx {\r\n\twidth: number; // コンテンツ幅 (px)\r\n\theight: number; // コンテンツ高さ (px)\r\n}\r\n\r\n// 用紙設定(ピクセル単位)\r\nexport interface PaperPx {\r\n\tcanvas: PaperCanvasPx;\r\n\tmargin: PaperMarginPx;\r\n\tcontent: PaperContentPx;\r\n}\r\n","// 用紙・スキーマ関連タイプ定義\r\n\r\nimport { DEFAULT_GRID, type Grid } from \"../grid\";\r\nimport { DEFAULT_PAPER, type Paper } from \"../paper\";\r\n\r\nimport type { Block } from \"../block\";\r\nimport type { Value } from \"../value\";\r\n\r\n// フォームスキーマ定義\r\nexport interface FormSchema {\r\n\tpaper: Paper; // 用紙設定\r\n\tgrid: Grid; // グリッド設定\r\n\tblocks: Block[]; // 配置されているブロック一覧\r\n\r\n\t// 追加のメタデータ(オプション)\r\n\t// バージョン管理などが必要になった場合に備えておく\r\n\tmetaData?: Record<string, Value>;\r\n}\r\n\r\n// デフォルトフォームスキーマ\r\nexport const DEFAULT_SCHEMA: FormSchema = {\r\n\tpaper: DEFAULT_PAPER,\r\n\tgrid: DEFAULT_GRID,\r\n\tblocks: [],\r\n};\r\n","// バリデーション関連型定義\r\n\r\nimport type { Value } from \"../value\";\r\n\r\n/**\r\n * エラーの重大度レベル\r\n */\r\nexport enum ValidationSeverity {\r\n\tERROR = \"error\",\r\n\tWARNING = \"warning\",\r\n\tINFO = \"info\",\r\n}\r\n\r\n/**\r\n * バリデーションエラー情報\r\n */\r\nexport interface ValidationError {\r\n\tmessage: string; // エラーメッセージ\r\n\tcode: string; // エラーコード\r\n\tfield?: string; // 関連するフィールド名(オプション)\r\n\tseverity: ValidationSeverity; // 重大度レベル\r\n\tmetadata?: Record<string, Value>; // 追加のメタデータ(オプション)\r\n}\r\n\r\n/**\r\n * バリデーション結果\r\n */\r\nexport interface ValidationResult {\r\n\tvalid: boolean; // バリデーション結果(有効/無効)\r\n\terrors: ValidationError[]; // 発生したエラーの配列\r\n}\r\n\r\n/**\r\n * Block単位のバリデーター関数型\r\n */\r\nexport type BlockValidator<P = unknown, V = unknown> = (\r\n\tprops: P,\r\n\tvalue: V,\r\n) => ValidationError | null;\r\n\r\n/**\r\n * 複数のBlockバリデーター関数型\r\n */\r\nexport type BlockValidators<P = unknown, V = unknown> = (\r\n\tprops: P,\r\n\tvalue: V,\r\n) => ValidationError[];\r\n","/**\r\n * @file BorderRenderer.tsx\r\n * @description 枠線SVG描画の共通コンポーネント\r\n */\r\nimport { memo } from \"react\";\r\n\r\nimport { DEFAULT_DPI } from \"@/constants\";\r\n\r\nimport type { Border } from \"@/types/line\";\r\n\r\nexport interface BorderRendererProps {\r\n\twidth: number;\r\n\theight: number;\r\n\tborder: Border;\r\n\tdpi?: number;\r\n\tclassName?: string;\r\n}\r\n\r\nexport const BorderRenderer = memo(\r\n\t({\r\n\t\twidth,\r\n\t\theight,\r\n\t\tborder,\r\n\t\tdpi = DEFAULT_DPI,\r\n\t\tclassName = \"\",\r\n\t}: BorderRendererProps) => {\r\n\t\t// 枠線が一つもない場合は描画しない\r\n\t\tif (!border.hasAnyBorder) return null;\r\n\r\n\t\treturn (\r\n\t\t\t<svg\r\n\t\t\t\twidth={width}\r\n\t\t\t\theight={height}\r\n\t\t\t\txmlns=\"http://www.w3.org/2000/svg\"\r\n\t\t\t\tclassName={className}\r\n\t\t\t\tstyle={{ overflow: \"visible\" }} // 線幅によってはみ出るのを許容\r\n\t\t\t>\r\n\t\t\t\t<title>border SVG</title>\r\n\t\t\t\t{/* 上辺 */}\r\n\t\t\t\t{border.top && <line {...border.getTopSVGProps(width, dpi)} />}\r\n\r\n\t\t\t\t{/* 右辺 */}\r\n\t\t\t\t{border.right && (\r\n\t\t\t\t\t<line {...border.getRightSVGProps(width, height, dpi)} />\r\n\t\t\t\t)}\r\n\r\n\t\t\t\t{/* 下辺 */}\r\n\t\t\t\t{border.bottom && (\r\n\t\t\t\t\t<line {...border.getBottomSVGProps(width, height, dpi)} />\r\n\t\t\t\t)}\r\n\r\n\t\t\t\t{/* 左辺 */}\r\n\t\t\t\t{border.left && <line {...border.getLeftSVGProps(height, dpi)} />}\r\n\t\t\t</svg>\r\n\t\t);\r\n\t},\r\n);\r\n\r\nBorderRenderer.displayName = \"BorderRenderer\";\r\n","/**\r\n * @file helpers.ts\r\n * @description z-index計算ヘルパー関数\r\n */\r\n\r\nimport { Z_INDEX } from \"./constants\";\r\n\r\n/**\r\n * ブロックの基底z-indexを計算\r\n *\r\n * @param index - ブロックの配列インデックス (0-based)\r\n * @returns 基底z-index(ブロックはbase ~ base+9を使用可能)\r\n *\r\n * @example\r\n * ```ts\r\n * getBlockZIndex(0); // 100\r\n * getBlockZIndex(1); // 200\r\n * getBlockZIndex(10); // 1100\r\n * ```\r\n */\r\nexport function getBlockZIndex(index: number): number {\r\n\tconst zIndex = Z_INDEX.BLOCK_LAYER_MIN + index * Z_INDEX.BLOCK_LAYER_STEP;\r\n\r\n\t// 最大値を超えないようにクランプ\r\n\tif (zIndex >= Z_INDEX.BLOCK_LAYER_MAX) {\r\n\t\treturn Z_INDEX.BLOCK_LAYER_MAX;\r\n\t}\r\n\r\n\treturn zIndex;\r\n}\r\n\r\n/**\r\n * ブロック内のサブレイヤーz-indexを計算\r\n *\r\n * @param baseZIndex - ブロックの基底z-index\r\n * @param subIndex - サブレイヤーのオフセット (0-99)\r\n * @returns サブレイヤーのz-index\r\n *\r\n * @example\r\n * ```ts\r\n * const baseZ = getBlockZIndex(0); // 100\r\n * getSubLayerZIndex(baseZ, BLOCK_SUB_INDEX.BG); // 110 (Blockの背景色)\r\n * getSubLayerZIndex(baseZ, BLOCK_SUB_INDEX.CONTENT); // 150 (Blockのコンテンツ)\r\n * ```\r\n */\r\nexport function getSubZIndex(baseZIndex: number, subIndex: number): number {\r\n\t// subIndexを範囲内にクランプ\r\n\tconst clampedOffset = Math.min(\r\n\t\tMath.max(0, subIndex),\r\n\t\tZ_INDEX.BLOCK_LAYER_STEP - 1,\r\n\t);\r\n\treturn baseZIndex + clampedOffset;\r\n}\r\n\r\n/**\r\n * サポートされる最大ブロック数を取得\r\n *\r\n * @returns 最大ブロック数\r\n *\r\n * @example\r\n * ```ts\r\n * getMaxBlockCount(); // 9999 (99,999 - 10) / 10\r\n * ```\r\n */\r\nexport function getMaxBlockCount(): number {\r\n\treturn Math.floor(\r\n\t\t(Z_INDEX.BLOCK_LAYER_MAX - Z_INDEX.BLOCK_LAYER_MIN) /\r\n\t\t\tZ_INDEX.BLOCK_LAYER_STEP,\r\n\t);\r\n}\r\n","/**\r\n * @file BlockBorder.tsx\r\n * @description ブロック境界線描画コンポーネント\r\n * @z-index BlockLayer内の上層(BlockCanvasとBlockRendererより上)\r\n */\r\n\r\nimport { memo, useMemo } from \"react\";\r\nimport { Border } from \"@types\";\r\n\r\nimport { BorderRenderer } from \"@/canvas/components/BorderRenderer\";\r\nimport { DEFAULT_DPI } from \"@/constants\";\r\nimport { BLOCK_SUB_INDEX } from \"@/utils/zIndex\";\r\nimport { getSubZIndex } from \"@/utils/zIndex/helpers\";\r\n\r\nimport type React from \"react\";\r\nimport type { BlockSizePx } from \"@/types/block\";\r\nimport type { BorderStyle } from \"@/types/line\";\r\n\r\n/**\r\n * BlockBorderコンポーネントのProps\r\n */\r\nexport interface BlockBorderProps {\r\n\tblockSizePx: BlockSizePx; // ブロックのサイズ(px)\r\n\tborderStyle?: BorderStyle; // 境界線スタイル\r\n\tblockZIndex: number; // ブロックのベースz-index\r\n\tsubZIndex?: number; // ブロック内でのレイヤーz-index(デフォルト:BLOCK_SUB_INDEX.BORDER)\r\n\tvisible?: boolean; // 表示/非表示(デフォルト: true)\r\n\tdpi?: number; // DPI(デフォルト: DEFAULT_DPI)\r\n\tclassName?: string; // 追加のクラス名\r\n}\r\n\r\n/**\r\n * BlockBorder\r\n *\r\n * ブロックの境界線を描画するコンポーネント\r\n * - block.style?.borderで設定された枠線を描画\r\n * - pointer-events: none (クリックイベント透過)\r\n *\r\n * @remarks\r\n * - ユーザー設定の枠線を描画\r\n * - BlockBaseBorderと構造は同じだが、用途とz-indexが異なる\r\n * - BlockBaseBorder: ガイド線(GUIDE層)\r\n * - BlockBorder: 実際の枠線(BORDER層)\r\n */\r\nexport const BlockBorder: React.FC<BlockBorderProps> = memo(\r\n\t({\r\n\t\tblockSizePx,\r\n\t\tborderStyle,\r\n\t\tblockZIndex,\r\n\t\tsubZIndex = BLOCK_SUB_INDEX.BORDER,\r\n\t\tvisible = true,\r\n\t\tdpi = DEFAULT_DPI,\r\n\t\tclassName = \"\",\r\n\t}) => {\r\n\t\tconst border: Border | undefined = useMemo(() => {\r\n\t\t\tif (!borderStyle) return undefined;\r\n\t\t\treturn new Border(borderStyle);\r\n\t\t}, [borderStyle]);\r\n\r\n\t\tif (!visible || !border || !border.hasAnyBorder) return null;\r\n\r\n\t\tconst zIndex = getSubZIndex(blockZIndex, subZIndex);\r\n\r\n\t\tconst overlayStyle: React.CSSProperties = {\r\n\t\t\tposition: \"absolute\",\r\n\t\t\tleft: 0,\r\n\t\t\ttop: 0,\r\n\t\t\twidth: `${blockSizePx.width}px`,\r\n\t\t\theight: `${blockSizePx.height}px`,\r\n\t\t\tpointerEvents: \"none\",\r\n\t\t\toverflow: \"visible\",\r\n\t\t\tzIndex,\r\n\t\t};\r\n\r\n\t\treturn (\r\n\t\t\t<div\r\n\t\t\t\tclassName={className}\r\n\t\t\t\tstyle={overlayStyle}\r\n\t\t\t\tdata-testid=\"block-border\"\r\n\t\t\t>\r\n\t\t\t\t<BorderRenderer\r\n\t\t\t\t\twidth={blockSizePx.width}\r\n\t\t\t\t\theight={blockSizePx.height}\r\n\t\t\t\t\tborder={border}\r\n\t\t\t\t\tdpi={dpi}\r\n\t\t\t\t/>\r\n\t\t\t</div>\r\n\t\t);\r\n\t},\r\n);\r\n","/**\r\n * @file BlockCanvas.tsx\r\n * @description ブロック背景描画コンポーネント\r\n * @z-index BLOCK_LAYER_MIN + blockIndex * BLOCK_LAYER_STEP + 0 (各ブロックの最下層)\r\n */\r\n\r\nimport { memo } from \"react\";\r\n\r\nimport { BLOCK_SUB_INDEX, getSubZIndex } from \"@/utils/zIndex\";\r\n\r\nimport type React from \"react\";\r\nimport type { BlockSizePx } from \"@/types/block\";\r\n\r\n/**\r\n * BlockCanvasコンポーネントのProps\r\n */\r\nexport interface BlockCanvasProps {\r\n\tblockSizePx: BlockSizePx; // ブロックのサイズ(px)\r\n\tblockZIndex: number; // z-index(ブロック基底値)\r\n\tsubZIndex?: number; // ブロック内でのレイヤーz-index(デフォルト:BLOCK_SUB_INDEX.BG)\r\n\tbackgroundColor?: string; // ブロックの背景色\r\n\tclassName?: string; // 追加のクラス名\r\n}\r\n\r\n/**\r\n * BlockCanvas\r\n *\r\n * ブロック背景を描画するコンポーネント\r\n * - z-index: ブロック基底値 + 0 (各ブロックの最下層)\r\n * - pointer-events: none (クリックイベント透過)\r\n * - 背景色のみを描画(境界線はBlockBaseBorderが担当)\r\n */\r\nexport const BlockCanvas: React.FC<BlockCanvasProps> = memo(\r\n\t({\r\n\t\tblockSizePx,\r\n\t\tblockZIndex,\r\n\t\tsubZIndex = BLOCK_SUB_INDEX.BG,\r\n\t\tbackgroundColor = \"transparent\",\r\n\t\tclassName = \"\",\r\n\t}) => {\r\n\t\tconst zIndex = getSubZIndex(blockZIndex, subZIndex);\r\n\r\n\t\tconst canvasStyle: React.CSSProperties = {\r\n\t\t\tposition: \"absolute\",\r\n\t\t\tinset: 0,\r\n\t\t\twidth: `${blockSizePx.width}px`,\r\n\t\t\theight: `${blockSizePx.height}px`,\r\n\t\t\tbackgroundColor,\r\n\t\t\tpointerEvents: \"none\",\r\n\t\t\tzIndex: zIndex,\r\n\t\t};\r\n\r\n\t\treturn (\r\n\t\t\t<div\r\n\t\t\t\tclassName={className}\r\n\t\t\t\tstyle={canvasStyle}\r\n\t\t\t\trole=\"presentation\"\r\n\t\t\t\taria-label=\"Block background\"\r\n\t\t\t\tdata-testid=\"block-canvas\"\r\n\t\t\t/>\r\n\t\t);\r\n\t},\r\n);\r\n","import { type BorderStyle, type LineStyle, LineType } from \"@/types/line\";\r\n\r\nexport const DEFAULT_GUIDE_LINE: LineStyle = {\r\n\tcolor: \"#cccccc\",\r\n\twidth: { value: 1, unit: \"pt\" },\r\n\ttype: LineType.SOLID,\r\n};\r\n\r\nexport const DEFAULT_GUIDE_BORDER: BorderStyle = {\r\n\tall: DEFAULT_GUIDE_LINE,\r\n};\r\n","/**\r\n * @file BlockBaseBorder.tsx\r\n * @description レイアウト編集時のブロック境界ガイド線コンポーネント\r\n * @z-index BlockLayer内の中層(BlockCanvasより上、BlockRendererより下)\r\n */\r\n\r\nimport { memo, useMemo } from \"react\";\r\nimport { Border } from \"@types\";\r\n\r\nimport { DEFAULT_GUIDE_BORDER } from \"./constants\";\r\n\r\nimport { BorderRenderer } from \"@/canvas/components/BorderRenderer\";\r\nimport { DEFAULT_DPI } from \"@/constants\";\r\nimport { BLOCK_SUB_INDEX } from \"@/utils/zIndex\";\r\nimport { getSubZIndex } from \"@/utils/zIndex/helpers\";\r\n\r\nimport type React from \"react\";\r\nimport type { BlockSizePx } from \"@/types/block\";\r\nimport type { BorderStyle } from \"@/types/line\";\r\n\r\n/**\r\n * BlockBaseBorderコンポーネントのProps\r\n */\r\nexport interface BlockGuideBorderProps {\r\n\tblockSizePx: BlockSizePx; // ブロックのサイズ(px)\r\n\tblockZIndex: number; // ブロックのベースz-index\r\n\tsubZIndex?: number; // ブロック内でのレイヤーz-index(デフォルト:BLOCK_SUB_INDEX.GUIDE)\r\n\tborderStyle?: BorderStyle; // 境界線スタイル\r\n\tvisible?: boolean; // 表示/非表示(デフォルト: true)\r\n\tdpi?: number; // DPI(デフォルト: DEFAULT_DPI)\r\n\tclassName?: string; // 追加のクラス名\r\n}\r\n\r\n/**\r\n * BlockBaseBorder\r\n *\r\n * レイアウト編集時にブロックの境界を可視化するガイド線コンポーネント\r\n * - formモードでのみ使用される\r\n * - block.style?.borderが未設定のブロックに表示\r\n * - pointer-events: none (クリックイベント透過)\r\n *\r\n * @remarks\r\n * - 固定スタイル(薄いグレーの実線)でブロック境界を描画\r\n * - ユーザー設定の枠線とは別の、編集補助用のガイド\r\n * - BorderOverlayと構造は同じだが、用途と表示条件が異なる\r\n */\r\nexport const BlockGuideBorder: React.FC<BlockGuideBorderProps> = memo(\r\n\t({\r\n\t\tblockSizePx,\r\n\t\tblockZIndex,\r\n\t\tsubZIndex = BLOCK_SUB_INDEX.GUIDE,\r\n\t\tborderStyle = DEFAULT_GUIDE_BORDER,\r\n\t\tvisible = true,\r\n\t\tdpi = DEFAULT_DPI,\r\n\t\tclassName = \"\",\r\n\t}) => {\r\n\t\tconst border: Border | undefined = useMemo(() => {\r\n\t\t\tif (!borderStyle) return undefined;\r\n\t\t\treturn new Border(borderStyle);\r\n\t\t}, [borderStyle]);\r\n\r\n\t\tif (!visible || !border || !border.hasAnyBorder) return null;\r\n\r\n\t\tconst zIndex = getSubZIndex(blockZIndex, subZIndex);\r\n\r\n\t\tconst overlayStyle: React.CSSProperties = {\r\n\t\t\tposition: \"absolute\",\r\n\t\t\tleft: 0,\r\n\t\t\ttop: 0,\r\n\t\t\twidth: `${blockSizePx.width}px`,\r\n\t\t\theight: `${blockSizePx.height}px`,\r\n\t\t\tpointerEvents: \"none\",\r\n\t\t\toverflow: \"visible\",\r\n\t\t\tzIndex,\r\n\t\t};\r\n\r\n\t\treturn (\r\n\t\t\t<div\r\n\t\t\t\tclassName={className}\r\n\t\t\t\tstyle={overlayStyle}\r\n\t\t\t\tdata-testid=\"block-base-border\"\r\n\t\t\t>\r\n\t\t\t\t<BorderRenderer\r\n\t\t\t\t\twidth={blockSizePx.width}\r\n\t\t\t\t\theight={blockSizePx.height}\r\n\t\t\t\t\tborder={border}\r\n\t\t\t\t\tdpi={dpi}\r\n\t\t\t\t/>\r\n\t\t\t</div>\r\n\t\t);\r\n\t},\r\n);\r\n","/**\r\n * @file BlockRenderer.tsx\r\n * @description ブロックコンテンツ描画コンポーネント\r\n * @z-index BLOCK_LAYER_MIN + blockIndex * BLOCK_LAYER_STEP + 100 (ブロック中層)\r\n */\r\n\r\nimport { forwardRef, memo, useImperativeHandle, useRef } from \"react\";\r\n\r\nimport { BLOCK_SUB_INDEX, getSubZIndex } from \"@/utils/zIndex\";\r\n\r\nimport type React from \"react\";\r\nimport type { BlockPlugin, BlockRef, RendererProps } from \"@/plugin\";\r\nimport type { BlockSizePx } from \"@/types/block\";\r\nimport type { NoteMode } from \"@/types/mode\";\r\nimport type { Value } from \"@/types/value\";\r\n\r\n/**\r\n * BlockRendererコンポーネントのProps\r\n *\r\n * @template P - プラグイン固有プロパティ型\r\n * @template V - プラグインが扱う値の型\r\n */\r\nexport interface BlockRendererProps<P = Record<string, Value>, V = Value> {\r\n\t/** ブロックID */\r\n\tid: string;\r\n\r\n\t/** プラグイン定義 */\r\n\tplugin: BlockPlugin<P, V>;\r\n\r\n\t/** プラグイン固有プロパティ */\r\n\tprops: P;\r\n\r\n\t/** ブロックの現在値 */\r\n\tvalue: V;\r\n\r\n\t/** 値変更コールバック (オプション) */\r\n\tonChange?: (value: V) => void;\r\n\r\n\t/** 値確定コールバック (オプション) */\r\n\tonBlur?: (value: V) => void;\r\n\r\n\t/** 読み取り専用フラグ */\r\n\treadOnly: boolean;\r\n\r\n\t/** 現在のモード */\r\n\tmode: NoteMode;\r\n\r\n\t/** ブロックの位置とサイズ(ピクセル単位) */\r\n\tblockSizePx: BlockSizePx;\r\n\r\n\t/** ブロック基底z-index */\r\n\tblockZIndex: number;\r\n\r\n\t/** ブロック内でのレイヤーz-index (オプション) */\r\n\tsubZIndex?: number;\r\n\r\n\t/** バリデーション状態 (オプション) */\r\n\tvalidationState?: \"valid\" | \"invalid\" | \"warning\";\r\n\r\n\t/** 追加のクラス名 */\r\n\tclassName?: string;\r\n}\r\n\r\n/**\r\n * BlockRenderer\r\n *\r\n * プラグインのRendererコンポーネントをラップし、適切な位置・z-indexで配置します\r\n *\r\n * @template P - プラグイン固有プロパティ型\r\n * @template V - プラグインが扱う値の型\r\n *\r\n * @remarks\r\n * - プラグインのRendererを動的に描画\r\n * - 位置とz-indexを管理\r\n * - BlockRef経由でfocusメソッドを公開\r\n */\r\nconst BlockRendererInner = <P extends Record<string, Value>, V extends Value>(\r\n\t{\r\n\t\tid,\r\n\t\tplugin,\r\n\t\tprops,\r\n\t\tvalue,\r\n\t\tonChange,\r\n\t\tonBlur,\r\n\t\treadOnly,\r\n\t\tmode,\r\n\t\tblockSizePx,\r\n\t\tblockZIndex,\r\n\t\tsubZIndex = BLOCK_SUB_INDEX.CONTENT,\r\n\t\tvalidationState,\r\n\t\tclassName = \"\",\r\n\t}: BlockRendererProps<P, V>,\r\n\tref: React.ForwardedRef<BlockRef>,\r\n) => {\r\n\t// プラグインのRendererコンポーネントへの参照\r\n\tconst pluginRendererRef = useRef<BlockRef>(null);\r\n\r\n\t// 親コンポーネントにfocusメソッドを公開\r\n\tuseImperativeHandle(\r\n\t\tref,\r\n\t\t() => ({\r\n\t\t\tfocus: () => pluginRendererRef.current?.focus(),\r\n\t\t}),\r\n\t\t[],\r\n\t);\r\n\r\n\t// z-index計算\r\n\tconst zIndex = getSubZIndex(blockZIndex, subZIndex);\r\n\r\n\t// コンテナスタイル\r\n\tconst containerStyle: React.CSSProperties = {\r\n\t\tposition: \"absolute\",\r\n\t\tinset: 0,\r\n\t\twidth: `${blockSizePx.width}px`,\r\n\t\theight: `${blockSizePx.height}px`,\r\n\t\tzIndex,\r\n\t\tpointerEvents: \"auto\", // クリックイベントを受け取る\r\n\t};\r\n\r\n\t// プラグインRendererに渡すprops\r\n\tconst pluginProps: RendererProps<P, V> = {\r\n\t\tid,\r\n\t\tprops,\r\n\t\tvalue,\r\n\t\tonChange: onChange ?? (() => {}),\r\n\t\tonBlur,\r\n\t\treadOnly,\r\n\t\tmode,\r\n\t\tdimensions: {\r\n\t\t\twidthPx: blockSizePx.width,\r\n\t\t\theightPx: blockSizePx.height,\r\n\t\t},\r\n\t\tvalidationState,\r\n\t};\r\n\r\n\t// プラグインのRendererコンポーネントを取得\r\n\tconst PluginRendererComponent = plugin.Renderer;\r\n\r\n\treturn (\r\n\t\t<div\r\n\t\t\tclassName={className}\r\n\t\t\tstyle={containerStyle}\r\n\t\t\tdata-testid=\"block-renderer\"\r\n\t\t\tdata-block-id={id}\r\n\t\t\tdata-plugin-kind={plugin.kind}\r\n\t\t>\r\n\t\t\t<PluginRendererComponent ref={pluginRendererRef} {...pluginProps} />\r\n\t\t</div>\r\n\t);\r\n};\r\n\r\nconst ForwardedBlockRenderer = forwardRef(BlockRendererInner) as <\r\n\tP extends Record<string, Value> = Record<string, Value>,\r\n\tV extends Value = Value,\r\n>(\r\n\tprops: BlockRendererProps<P, V> & { ref?: React.Ref<BlockRef> },\r\n) => React.ReactElement;\r\n\r\nexport const BlockRenderer = memo(\r\n\tForwardedBlockRenderer,\r\n) as typeof ForwardedBlockRenderer;\r\n","/**\r\n * @file getBlockContainerStyle.ts\r\n * @description ブロックコンテナの共通スタイル生成関数\r\n *\r\n * @remarks\r\n * BlockContainer と EditingBlock で共通のレイアウト計算ロジックを提供します。\r\n * 位置とサイズは BlockRectPx から計算され、z-index と pointerEvents はオプションで指定可能です。\r\n */\r\n\r\nimport type React from \"react\";\r\nimport type { BlockRectPx } from \"@/types/block\";\r\n\r\n/**\r\n * ブロックコンテナスタイルのオプション\r\n */\r\nexport interface BlockContainerStyleOptions {\r\n\t/** z-index値 (オプション) */\r\n\tzIndex?: number;\r\n\t/** ポインターイベントの制御 (デフォルト: \"auto\") */\r\n\tpointerEvents?: \"auto\" | \"none\";\r\n}\r\n\r\n/**\r\n * ブロックコンテナの共通スタイルを生成\r\n *\r\n * @param blockRectPx - ブロックの位置とサイズ (ピクセル単位)\r\n * @param options - オプション設定\r\n * @returns React CSSProperties オブジェクト\r\n *\r\n * @example\r\n * ```tsx\r\n * const style = getBlockContainerStyle(blockRectPx, {\r\n * zIndex: 2400000,\r\n * pointerEvents: \"auto\"\r\n * });\r\n * ```\r\n */\r\nexport function getBlockContainerStyle(\r\n\tblockRectPx: BlockRectPx,\r\n\toptions?: BlockContainerStyleOptions,\r\n): React.CSSProperties {\r\n\treturn {\r\n\t\tposition: \"absolute\",\r\n\t\tleft: `${blockRectPx.left}px`,\r\n\t\ttop: `${blockRectPx.top}px`,\r\n\t\twidth: `${blockRectPx.width}px`,\r\n\t\theight: `${blockRectPx.height}px`,\r\n\t\tzIndex: options?.zIndex,\r\n\t\tpointerEvents: options?.pointerEvents ?? \"auto\",\r\n\t};\r\n}\r\n","/**\r\n * @file BlockContainer.tsx\r\n * @description 1つのブロックを構成するコンテナコンポーネント\r\n */\r\nimport { forwardRef, memo, useMemo } from \"react\";\r\n\r\nimport { BlockBorder } from \"../BlockBorder\";\r\nimport { BlockCanvas } from \"../BlockCanvas\";\r\nimport { BlockGuideBorder, DEFAULT_GUIDE_BORDER } from \"../BlockGuideBorder\";\r\nimport { BlockRenderer } from \"../BlockRenderer\";\r\n\r\nimport { DEFAULT_DPI } from \"@/constants\";\r\nimport { NoteMode } from \"@/types/mode\";\r\nimport { getBlockContainerStyle } from \"@/utils/blockLayout\";\r\nimport { BLOCK_SUB_INDEX } from \"@/utils/zIndex\";\r\n\r\nimport type { BlockPlugin, BlockRef } from \"@/plugin\";\r\nimport type { Block, BlockRectPx, BlockSizePx } from \"@/types/block\";\r\nimport type { BorderStyle } from \"@/types/line\";\r\nimport type { Value } from \"@/types/value\";\r\n\r\nexport interface BlockContainerProps {\r\n\tblock: Block;\r\n\tplugin: BlockPlugin;\r\n\tblockRectPx: BlockRectPx;\r\n\tblockZIndex: number;\r\n\tmode: NoteMode;\r\n\tvalue: Value;\r\n\tonValueChange?: (val: Value) => void;\r\n\tonValueBlur?: (val: Value) => void;\r\n\tshowGuides?: boolean;\r\n\tshowBorder?: boolean;\r\n\tblockSubZIndex?: Record<string, number>;\r\n\tdefaultGuideBorder?: BorderStyle;\r\n\tdpi?: number;\r\n\tclassName?: string;\r\n\tpointerEvents?: \"auto\" | \"none\";\r\n}\r\n\r\nexport const BlockContainer = memo(\r\n\tforwardRef<BlockRef, BlockContainerProps>(\r\n\t\t(\r\n\t\t\t{\r\n\t\t\t\tblock,\r\n\t\t\t\tplugin,\r\n\t\t\t\tblockRectPx,\r\n\t\t\t\tblockZIndex,\r\n\t\t\t\tmode,\r\n\t\t\t\tvalue,\r\n\t\t\t\tonValueChange,\r\n\t\t\t\tonValueBlur,\r\n\t\t\t\tshowGuides = true,\r\n\t\t\t\tshowBorder = true,\r\n\t\t\t\tblockSubZIndex = {\r\n\t\t\t\t\tbg: BLOCK_SUB_INDEX.BG,\r\n\t\t\t\t\tguide: BLOCK_SUB_INDEX.GUIDE,\r\n\t\t\t\t\tcontent: BLOCK_SUB_INDEX.CONTENT,\r\n\t\t\t\t\tborder: BLOCK_SUB_INDEX.BORDER,\r\n\t\t\t\t},\r\n\t\t\t\tdefaultGuideBorder = DEFAULT_GUIDE_BORDER,\r\n\t\t\t\tdpi = DEFAULT_DPI,\r\n\t\t\t\tclassName = \"\",\r\n\t\t\t\tpointerEvents = \"none\",\r\n\t\t\t}: BlockContainerProps,\r\n\t\t\tref,\r\n\t\t) => {\r\n\t\t\t// コンテナスタイル (共通関数を使用)\r\n\t\t\tconst containerStyle = getBlockContainerStyle(blockRectPx, {\r\n\t\t\t\tzIndex: blockZIndex,\r\n\t\t\t\tpointerEvents,\r\n\t\t\t});\r\n\r\n\t\t\tconst blockSizePx: BlockSizePx = useMemo(() => {\r\n\t\t\t\treturn {\r\n\t\t\t\t\twidth: blockRectPx.width,\r\n\t\t\t\t\theight: blockRectPx.height,\r\n\t\t\t\t};\r\n\t\t\t}, [blockRectPx.width, blockRectPx.height]);\r\n\r\n\t\t\treturn (\r\n\t\t\t\t<div\r\n\t\t\t\t\tstyle={containerStyle}\r\n\t\t\t\t\tdata-block-id={block.id}\r\n\t\t\t\t\tclassName={className}\r\n\t\t\t\t>\r\n\t\t\t\t\t{/* 1. 背景 (最下層) */}\r\n\t\t\t\t\t<BlockCanvas\r\n\t\t\t\t\t\tblockSizePx={blockSizePx}\r\n\t\t\t\t\t\tblockZIndex={blockZIndex}\r\n\t\t\t\t\t\tbackgroundColor={block.style?.backgroundColor}\r\n\t\t\t\t\t\tsubZIndex={blockSubZIndex.bg}\r\n\t\t\t\t\t/>\r\n\t\t\t\t\t{/* 2. ガイド線 (編集モードかつ枠線なしの場合) */}\r\n\t\t\t\t\t{showGuides && !block.style?.border && (\r\n\t\t\t\t\t\t<BlockGuideBorder\r\n\t\t\t\t\t\t\tblockSizePx={blockSizePx}\r\n\t\t\t\t\t\t\tblockZIndex={blockZIndex}\r\n\t\t\t\t\t\t\tsubZIndex={blockSubZIndex.guide}\r\n\t\t\t\t\t\t\tborderStyle={defaultGuideBorder}\r\n\t\t\t\t\t\t\tdpi={dpi}\r\n\t\t\t\t\t\t/>\r\n\t\t\t\t\t)}\r\n\t\t\t\t\t{/* 3. コンテンツ (Renderer) */}\r\n\t\t\t\t\t<BlockRenderer\r\n\t\t\t\t\t\tid={block.id}\r\n\t\t\t\t\t\tref={ref}\r\n\t\t\t\t\t\tplugin={plugin}\r\n\t\t\t\t\t\tprops={block.props}\r\n\t\t\t\t\t\tvalue={value}\r\n\t\t\t\t\t\tonChange={onValueChange}\r\n\t\t\t\t\t\tonBlur={onValueBlur}\r\n\t\t\t\t\t\treadOnly={\r\n\t\t\t\t\t\t\tmode === NoteMode.EDIT\r\n\t\t\t\t\t\t\t\t? (block.behavior?.readOnly ?? false)\r\n\t\t\t\t\t\t\t\t: true\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tmode={mode}\r\n\t\t\t\t\t\tblockSizePx={blockSizePx}\r\n\t\t\t\t\t\tblockZIndex={blockZIndex}\r\n\t\t\t\t\t\tsubZIndex={blockSubZIndex.content}\r\n\t\t\t\t\t/>\r\n\t\t\t\t\t{/* 4. 枠線 (最上層) */}\r\n\t\t\t\t\t<BlockBorder\r\n\t\t\t\t\t\tblockSizePx={blockSizePx}\r\n\t\t\t\t\t\tblockZIndex={blockZIndex}\r\n\t\t\t\t\t\tborderStyle={block.style?.border}\r\n\t\t\t\t\t\tsubZIndex={blockSubZIndex.border}\r\n\t\t\t\t\t\tvisible={showBorder}\r\n\t\t\t\t\t\tdpi={dpi}\r\n\t\t\t\t\t/>\r\n\t\t\t\t</div>\r\n\t\t\t);\r\n\t\t},\r\n\t),\r\n);\r\n\r\nBlockContainer.displayName = \"BlockContainer\";\r\n","import { memo, useRef } from \"react\";\r\n\r\nimport { BlockContainer } from \"./BlockContainer\";\r\nimport { DEFAULT_GUIDE_BORDER } from \"./BlockGuideBorder\";\r\n\r\nimport { DEFAULT_DPI } from \"@/constants\";\r\nimport { BLOCK_SUB_INDEX, getBlockZIndex, Z_INDEX } from \"@/utils/zIndex\";\r\n\r\nimport type { BlockPlugin, BlockRef } from \"@/plugin\";\r\nimport type { Block, BlockRectPx } from \"@/types/block\";\r\nimport type { OnBlur, OnChange } from \"@/types/callbacks\";\r\nimport type { BorderStyle } from \"@/types/line\";\r\nimport type { NoteMode } from \"@/types/mode\";\r\nimport type { Value } from \"@/types/value\";\r\n\r\nexport interface BlockLayerProps {\r\n\tblocks: Block[];\r\n\tpluginRegistry: Record<string, BlockPlugin>;\r\n\tmode: NoteMode;\r\n\tvalues: Record<string, Value>;\r\n\tselectedBlockIds?: string[];\r\n\tgetBlockRectPx: (block: Block) => BlockRectPx;\r\n\tonValueChange?: OnChange;\r\n\tonValueBlur?: OnBlur;\r\n\tshowGuides?: boolean;\r\n\tshowBorder?: boolean;\r\n\tblockSubZIndex?: Record<string, number>;\r\n\tdefaultGuideBorder?: BorderStyle;\r\n\tdpi?: number;\r\n\tclassName?: string;\r\n}\r\n\r\nexport const BlockLayer = memo(\r\n\t({\r\n\t\tblocks,\r\n\t\tpluginRegistry,\r\n\t\tmode,\r\n\t\tvalues,\r\n\t\tselectedBlockIds = [],\r\n\t\tgetBlockRectPx,\r\n\t\tonValueChange,\r\n\t\tonValueBlur,\r\n\t\tshowGuides = true,\r\n\t\tshowBorder = true,\r\n\t\tblockSubZIndex = {\r\n\t\t\tbg: BLOCK_SUB_INDEX.BG,\r\n\t\t\tguide: BLOCK_SUB_INDEX.GUIDE,\r\n\t\t\tcontent: BLOCK_SUB_INDEX.CONTENT,\r\n\t\t\tborder: BLOCK_SUB_INDEX.BORDER,\r\n\t\t},\r\n\t\tdefaultGuideBorder = DEFAULT_GUIDE_BORDER,\r\n\t\tdpi = DEFAULT_DPI,\r\n\t\tclassName = \"\",\r\n\t}: BlockLayerProps) => {\r\n\t\tconst blockRefs = useRef<Map<string, BlockRef>>(new Map());\r\n\r\n\t\tconst layerStyle: React.CSSProperties = {\r\n\t\t\tposition: \"absolute\",\r\n\t\t\tinset: 0,\r\n\t\t\tpointerEvents: \"none\",\r\n\t\t};\r\n\r\n\t\treturn (\r\n\t\t\t<div className={className} style={layerStyle} data-testid=\"block-layer\">\r\n\t\t\t\t{blocks.map((block, index) => {\r\n\t\t\t\t\tconst plugin = pluginRegistry[block.kind];\r\n\t\t\t\t\tif (!plugin) return null;\r\n\r\n\t\t\t\t\tconst blockRectPx = getBlockRectPx(block);\r\n\t\t\t\t\tconst isSelected = selectedBlockIds.includes(block.id);\r\n\r\n\t\t\t\t\tlet blockZIndex = getBlockZIndex(index);\r\n\t\t\t\t\tif (isSelected) {\r\n\t\t\t\t\t\tblockZIndex = Z_INDEX.SELECT_BLOCK;\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tconst value = values[block.id] ?? block.initValue;\r\n\t\t\t\t\treturn (\r\n\t\t\t\t\t\t<BlockContainer\r\n\t\t\t\t\t\t\tkey={block.id}\r\n\t\t\t\t\t\t\tref={(ref) => {\r\n\t\t\t\t\t\t\t\tif (ref) blockRefs.current.set(block.id, ref);\r\n\t\t\t\t\t\t\t\telse blockRefs.current.delete(block.id);\r\n\t\t\t\t\t\t\t}}\r\n\t\t\t\t\t\t\tblock={block}\r\n\t\t\t\t\t\t\tplugin={plugin}\r\n\t\t\t\t\t\t\tblockRectPx={blockRectPx}\r\n\t\t\t\t\t\t\tblockZIndex={blockZIndex}\r\n\t\t\t\t\t\t\tmode={mode}\r\n\t\t\t\t\t\t\tvalue={value}\r\n\t\t\t\t\t\t\tonValueChange={\r\n\t\t\t\t\t\t\t\tonValueChange\r\n\t\t\t\t\t\t\t\t\t? (val) => onValueChange(block.id, val)\r\n\t\t\t\t\t\t\t\t\t: undefined\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\tonValueBlur={(val) => onValueBlur?.(block.id, val)}\r\n\t\t\t\t\t\t\tshowGuides={showGuides}\r\n\t\t\t\t\t\t\tshowBorder={showBorder}\r\n\t\t\t\t\t\t\tblockSubZIndex={blockSubZIndex}\r\n\t\t\t\t\t\t\tdefaultGuideBorder={defaultGuideBorder}\r\n\t\t\t\t\t\t\tdpi={dpi}\r\n\t\t\t\t\t\t\tpointerEvents=\"none\"\r\n\t\t\t\t\t\t/>\r\n\t\t\t\t\t);\r\n\t\t\t\t})}\r\n\t\t\t</div>\r\n\t\t);\r\n\t},\r\n);\r\n\r\nBlockLayer.displayName = \"BlockLayer\";\r\n","/**\r\n * @file BorderOverlay.tsx\r\n * @description 印刷可能領域の境界線オーバーレイコンポーネント\r\n * @z-index 3 (GridLayerの最上層)\r\n */\r\n\r\nimport { memo, useMemo } from \"react\";\r\nimport { Border } from \"@types\";\r\n\r\nimport { BorderRenderer } from \"@/canvas/components/BorderRenderer\";\r\nimport { DEFAULT_DPI } from \"@/constants\";\r\nimport { Z_INDEX } from \"@/utils/zIndex\";\r\n\r\nimport type { PaperContentPx } from \"@types\";\r\nimport type React from \"react\";\r\nimport type { BorderStyle } from \"@/types/line/types\";\r\n\r\n/**\r\n * BorderOverlayコンポーネントのProps\r\n */\r\nexport interface BorderOverlayProps {\r\n\tcontentPx: PaperContentPx; // コンテンツエリア(印刷可能領域)のサイズ(px)\r\n\tmarginLeftPx: number; // 左マージン(px) - SVGの配置位置調整用\r\n\tmarginTopPx: number; // 上マージン(px) - SVGの配置位置調整用\r\n\tborderStyle?: BorderStyle; // 境界線スタイル\r\n\tvisible?: boolean; // 表示/非表示\r\n\tdpi?: number; // DPI(デフォルト: DEFAULT_DPI)\r\n\tzIndex?: number; // z-index(デフォルト: Z_INDEX.BORDER_OVERLAY)\r\n\tclassName?: string; // 追加のクラス名\r\n}\r\n\r\n/**\r\n * BorderOverlay\r\n *\r\n * 印刷可能領域の境界線をSVGで描画するオーバーレイコンポーネント\r\n * - z-index: 3 (GridLayerの最上層)\r\n * - pointer-events: none (クリックイベント透過)\r\n * - 印刷可能領域の4辺に境界線を描画\r\n *\r\n * @remarks\r\n * - 境界線は印刷可能領域(contentArea)の外枠に描画される\r\n * - 個別設定(topBorderStyle等)が優先され、なければborderStyleを使用\r\n * - すべてのスタイルが未指定の場合、その辺は描画されない\r\n */\r\nexport const BorderOverlay: React.FC<BorderOverlayProps> = memo(\r\n\t({\r\n\t\tcontentPx,\r\n\t\tmarginLeftPx,\r\n\t\tmarginTopPx,\r\n\t\tborderStyle,\r\n\t\tvisible = true,\r\n\t\tdpi = DEFAULT_DPI,\r\n\t\tzIndex = Z_INDEX.BORDER_OVERLAY,\r\n\t\tclassName = \"\",\r\n\t}) => {\r\n\t\tconst border: Border | undefined = useMemo(() => {\r\n\t\t\tif (!borderStyle) return undefined;\r\n\t\t\treturn new Border(borderStyle);\r\n\t\t}, [borderStyle]);\r\n\r\n\t\tif (!visible || !border || !border.hasAnyBorder) return null;\r\n\r\n\t\tconst overlayStyle: React.CSSProperties = {\r\n\t\t\tposition: \"absolute\",\r\n\t\t\tleft: `${marginLeftPx}px`,\r\n\t\t\ttop: `${marginTopPx}px`,\r\n\t\t\twidth: `${contentPx.width}px`,\r\n\t\t\theight: `${contentPx.height}px`,\r\n\t\t\tpointerEvents: \"none\",\r\n\t\t\toverflow: \"visible\",\r\n\t\t\tzIndex,\r\n\t\t};\r\n\r\n\t\treturn (\r\n\t\t\t<div\r\n\t\t\t\tclassName={className}\r\n\t\t\t\tstyle={overlayStyle}\r\n\t\t\t\tdata-testid=\"border-overlay\"\r\n\t\t\t>\r\n\t\t\t\t<BorderRenderer\r\n\t\t\t\t\twidth={contentPx.width}\r\n\t\t\t\t\theight={contentPx.height}\r\n\t\t\t\t\tborder={border}\r\n\t\t\t\t\tdpi={dpi}\r\n\t\t\t\t/>\r\n\t\t\t</div>\r\n\t\t);\r\n\t},\r\n);\r\n","/**\r\n * @file GridCanvas.tsx\r\n * @description 用紙背景描画コンポーネント\r\n * @z-index 0 (GridLayerの最下層)\r\n */\r\n\r\nimport { memo } from \"react\";\r\n\r\nimport { Z_INDEX } from \"@/utils/zIndex\";\r\n\r\nimport type { PaperCanvasPx } from \"@/types\";\r\n\r\n/**\r\n * GridCanvasコンポーネントのProps\r\n */\r\nexport interface GridCanvasProps {\r\n\tcanvasPx: PaperCanvasPx; // 用紙キャンバスのサイズ(px)\r\n\tbackgroundColor?: string; // 用紙の背景色\r\n\tboxShadow?: string; // 用紙のボックスシャドウ\r\n\tzIndex?: number; // z-index(デフォルト: Z_INDEX.GRID_CANVAS)\r\n\tclassName?: string; // 追加のクラス名\r\n}\r\n\r\n/**\r\n * GridCanvas\r\n *\r\n * 用紙背景を描画するコンポーネント\r\n * - z-index: 0 (GridLayerの最下層)\r\n * - pointer-events: none (クリックイベント透過)\r\n * - 白い用紙背景を表示\r\n */\r\nexport const GridCanvas: React.FC<GridCanvasProps> = memo(\r\n\t({\r\n\t\tcanvasPx,\r\n\t\tbackgroundColor = \"#ffffff\",\r\n\t\tboxShadow = \"0 2px 8px rgba(0, 0, 0, 0.1)\",\r\n\t\tzIndex = Z_INDEX.GRID_CANVAS,\r\n\t\tclassName,\r\n\t}) => {\r\n\t\tconst canvasStyle: React.CSSProperties = {\r\n\t\t\tposition: \"absolute\",\r\n\t\t\tinset: 0,\r\n\t\t\twidth: `${canvasPx.width}px`,\r\n\t\t\theight: `${canvasPx.height}px`,\r\n\t\t\tbackgroundColor,\r\n\t\t\tboxShadow,\r\n\t\t\tpointerEvents: \"none\",\r\n\t\t\tzIndex: zIndex,\r\n\t\t};\r\n\r\n\t\treturn (\r\n\t\t\t<div\r\n\t\t\t\tclassName={className}\r\n\t\t\t\tstyle={canvasStyle}\r\n\t\t\t\trole=\"presentation\"\r\n\t\t\t\taria-label=\"Paper background\"\r\n\t\t\t\tdata-testid=\"grid-canvas\"\r\n\t\t\t/>\r\n\t\t);\r\n\t},\r\n);\r\n","// 文字列を寸法オブジェクトに変換\r\n\r\nimport { assertNonNegative } from \"../assert\";\r\n\r\nimport type { Dimension, Unit } from \"@/types/unit\";\r\n\r\n// 文字列を寸法オブジェクトに変換\r\nexport function stringToDimension<U extends Unit>(\r\n\tstr: string,\r\n\tallowedUnits: readonly U[],\r\n): Dimension<U> {\r\n\tconst match = str.match(/^(\\d+(?:\\.\\d+)?)([a-zA-Z%]+)$/);\r\n\tif (!match) {\r\n\t\tthrow new Error(`Invalid dimension string: ${str}`);\r\n\t}\r\n\r\n\tconst value = Number(match[1]);\r\n\tconst unit = match[2] as U;\r\n\r\n\tassertNonNegative(value, `Dimension value`);\r\n\tif (!allowedUnits.includes(unit)) {\r\n\t\tthrow new Error(`Unit not allowed: ${unit}`);\r\n\t}\r\n\r\n\treturn { value, unit };\r\n}\r\n\r\n// 文字列の配列を寸法オブジェクトの配列に変換\r\nexport function stringsToDimensions<U extends Unit>(\r\n\tstrs: string[],\r\n\tallowedUnits: readonly U[],\r\n): Dimension<U>[] {\r\n\treturn strs.map((str) => stringToDimension(str, allowedUnits));\r\n}\r\n","import { assertNonNegative } from \"../assert/number\";\r\n\r\nimport type { Dimension, Unit } from \"@/types\";\r\n\r\nconst CM_TO_MM = 10;\r\nconst INCH_TO_MM = 25.4;\r\nconst PT_TO_MM = 0.352778;\r\nconst PX_TO_MM = 0.264583;\r\n\r\nexport const toMm = {\r\n\tfromCm(cm: number): number {\r\n\t\tassertNonNegative(cm, `Centimeter value`);\r\n\t\treturn cm * CM_TO_MM;\r\n\t},\r\n\r\n\tfromInch(inch: number): number {\r\n\t\tassertNonNegative(inch, `Inch value`);\r\n\t\treturn inch * INCH_TO_MM;\r\n\t},\r\n\r\n\tfromPt(pt: number): number {\r\n\t\tassertNonNegative(pt, `Point value`);\r\n\t\treturn pt * PT_TO_MM;\r\n\t},\r\n\r\n\t// データ上のpxはDPI=96として扱う\r\n\tfromPx(px: number): number {\r\n\t\tassertNonNegative(px, `Pixel value`);\r\n\t\treturn px * PX_TO_MM;\r\n\t},\r\n\r\n\tfromDim<U extends Unit>(dim: Dimension<U>): number {\r\n\t\tassertNonNegative(dim.value, `Dimension value`);\r\n\t\tswitch (dim.unit) {\r\n\t\t\tcase \"mm\":\r\n\t\t\t\treturn dim.value;\r\n\t\t\tcase \"cm\":\r\n\t\t\t\treturn toMm.fromCm(dim.value);\r\n\t\t\tcase \"inch\":\r\n\t\t\t\treturn toMm.fromInch(dim.value);\r\n\t\t\tcase \"pt\":\r\n\t\t\t\treturn toMm.fromPt(dim.value);\r\n\t\t\tcase \"px\":\r\n\t\t\t\treturn toMm.fromPx(dim.value);\r\n\t\t\tcase \"fr\":\r\n\t\t\tcase \"%\":\r\n\t\t\t\tthrow new Error(\r\n\t\t\t\t\t`Cannot convert ${dim.unit} to mm. Use physical units only.`,\r\n\t\t\t\t);\r\n\t\t\tdefault: {\r\n\t\t\t\tconst _exhaustive: never = dim.unit;\r\n\t\t\t\tthrow new Error(`Unsupported unit: ${_exhaustive}`);\r\n\t\t\t}\r\n\t\t}\r\n\t},\r\n};\r\n","// 寸法オブジェクトを文字列に変換\r\n\r\nimport { assertNonNegative } from \"@/utils/assert/number\";\r\n\r\nimport type { Dimension, Unit } from \"@/types/unit\";\r\n\r\n// 寸法オブジェクトを文字列に変換\r\nexport function dimensionToString<U extends Unit>(dim: Dimension<U>): string {\r\n\tassertNonNegative(dim.value, \"Dimension\");\r\n\treturn `${dim.value}${dim.unit}`;\r\n}\r\n\r\n// 寸法オブジェクトの配列を文字列の配列に変換\r\nexport function dimensionsToStrings<U extends Unit>(\r\n\tdims: Dimension<U>[],\r\n): string[] {\r\n\treturn dims.map(dimensionToString);\r\n}\r\n","/**\r\n * @file GridUnitEditor.tsx\r\n * @description グリッド寸法の単位を編集するポップアップUIコンポーネント\r\n */\r\n\r\nimport { memo, useEffect, useRef, useState } from \"react\";\r\n\r\nimport styles from \"./GridUnitEditor.module.css\";\r\n\r\nimport { toMm } from \"@/utils/convert\";\r\n\r\nimport type { Dimension, GridUnit } from \"@types\";\r\n\r\nexport interface GridUnitEditorProps {\r\n\t/** エディタの方向 */\r\n\tdirection: \"column\" | \"row\";\r\n\t/** 現在の寸法 */\r\n\tdimension: Dimension<GridUnit>;\r\n\t/** 現在のpxサイズ(単位変換用) */\r\n\tcurrentPxSize: number;\r\n\t/** エディタの位置 (px) */\r\n\tposition: number;\r\n\t/** 印刷可能領域の左マージン (px) */\r\n\tmarginLeftPx: number;\r\n\t/** 印刷可能領域の上マージン (px) */\r\n\tmarginTopPx: number;\r\n\t/** 寸法変更時のコールバック */\r\n\tonChange: (dimension: Dimension<GridUnit>) => void;\r\n\t/** キャンセル時のコールバック */\r\n\tonCancel: () => void;\r\n}\r\n\r\nconst SUPPORTED_UNITS: GridUnit[] = [\"fr\", \"px\", \"mm\", \"cm\", \"pt\", \"inch\"];\r\n\r\n/**\r\n * 単位変換: 現在のpxサイズから新しい単位の値を計算\r\n */\r\nfunction convertPxToUnit(pxSize: number, targetUnit: GridUnit): number {\r\n\tif (targetUnit === \"fr\") {\r\n\t\t// frは比率なので、元の値を保持\r\n\t\treturn 1;\r\n\t}\r\n\r\n\tswitch (targetUnit) {\r\n\t\tcase \"px\":\r\n\t\t\t// pxはそのまま(DPI=96基準)\r\n\t\t\treturn pxSize;\r\n\t\tcase \"mm\": {\r\n\t\t\tconst mm = toMm.fromPx(pxSize);\r\n\t\t\treturn Math.round(mm * 10) / 10; // 小数第1位まで\r\n\t\t}\r\n\t\tcase \"cm\": {\r\n\t\t\tconst mm = toMm.fromPx(pxSize);\r\n\t\t\tconst cm = mm / 10;\r\n\t\t\treturn Math.round(cm * 100) / 100; // 小数第2位まで\r\n\t\t}\r\n\t\tcase \"inch\": {\r\n\t\t\tconst mm = toMm.fromPx(pxSize);\r\n\t\t\tconst inch = mm / 25.4;\r\n\t\t\treturn Math.round(inch * 100) / 100; // 小数第2位まで\r\n\t\t}\r\n\t\tcase \"pt\": {\r\n\t\t\tconst mm = toMm.fromPx(pxSize);\r\n\t\t\tconst inch = mm / 25.4;\r\n\t\t\tconst pt = inch * 72;\r\n\t\t\treturn Math.round(pt * 10) / 10; // 小数第1位まで\r\n\t\t}\r\n\t\tdefault: {\r\n\t\t\tconst _exhaustive: never = targetUnit;\r\n\t\t\tthrow new Error(`Unsupported unit: ${_exhaustive}`);\r\n\t\t}\r\n\t}\r\n}\r\n\r\n/**\r\n * GridUnitEditor - グリッド寸法編集UI\r\n *\r\n * グリッド線間の寸法を編集するためのポップアップUIです。\r\n */\r\nexport const GridUnitEditor = memo(\r\n\t({\r\n\t\tdirection,\r\n\t\tdimension,\r\n\t\tcurrentPxSize,\r\n\t\tposition,\r\n\t\tmarginLeftPx,\r\n\t\tmarginTopPx,\r\n\t\tonChange,\r\n\t\tonCancel,\r\n\t}: GridUnitEditorProps) => {\r\n\t\tconst [value, setValue] = useState(dimension.value.toString());\r\n\t\tconst [unit, setUnit] = useState<GridUnit>(dimension.unit as GridUnit);\r\n\t\tconst inputRef = useRef<HTMLInputElement>(null);\r\n\t\tconst containerRef = useRef<HTMLDivElement>(null);\r\n\r\n\t\t// エディタの表示位置\r\n\t\tconst editorStyle: React.CSSProperties =\r\n\t\t\tdirection === \"column\"\r\n\t\t\t\t? {\r\n\t\t\t\t\t\tleft: `${marginLeftPx + position}px`,\r\n\t\t\t\t\t\ttop: `${marginTopPx + 24}px`,\r\n\t\t\t\t\t\ttransform: \"translateX(-50%)\",\r\n\t\t\t\t\t}\r\n\t\t\t\t: {\r\n\t\t\t\t\t\tleft: `${marginLeftPx + 24}px`,\r\n\t\t\t\t\t\ttop: `${marginTopPx + position}px`,\r\n\t\t\t\t\t\ttransform: \"translateY(-50%)\",\r\n\t\t\t\t\t};\r\n\r\n\t\t// マウント時にinputにフォーカス\r\n\t\tuseEffect(() => {\r\n\t\t\tinputRef.current?.focus();\r\n\t\t\tinputRef.current?.select();\r\n\t\t}, []);\r\n\r\n\t\t// 外部クリックでキャンセル\r\n\t\tuseEffect(() => {\r\n\t\t\tconst handleClickOutside = (event: MouseEvent) => {\r\n\t\t\t\tif (\r\n\t\t\t\t\tcontainerRef.current &&\r\n\t\t\t\t\t!containerRef.current.contains(event.target as Node)\r\n\t\t\t\t) {\r\n\t\t\t\t\tonCancel();\r\n\t\t\t\t}\r\n\t\t\t};\r\n\r\n\t\t\tdocument.addEventListener(\"mousedown\", handleClickOutside);\r\n\t\t\treturn () => {\r\n\t\t\t\tdocument.removeEventListener(\"mousedown\", handleClickOutside);\r\n\t\t\t};\r\n\t\t}, [onCancel]);\r\n\r\n\t\tconst handleSubmit = () => {\r\n\t\t\tconst numValue = Number.parseFloat(value);\r\n\t\t\tif (!Number.isNaN(numValue) && numValue >= 0.1) {\r\n\t\t\t\tonChange({ unit, value: numValue });\r\n\t\t\t} else {\r\n\t\t\t\tonCancel();\r\n\t\t\t}\r\n\t\t};\r\n\r\n\t\tconst handleKeyDown = (e: React.KeyboardEvent) => {\r\n\t\t\tif (e.key === \"Enter\") {\r\n\t\t\t\te.preventDefault();\r\n\t\t\t\thandleSubmit();\r\n\t\t\t} else if (e.key === \"Escape\") {\r\n\t\t\t\te.preventDefault();\r\n\t\t\t\tonCancel();\r\n\t\t\t}\r\n\t\t};\r\n\r\n\t\tconst handleUnitChange = (e: React.ChangeEvent<HTMLSelectElement>) => {\r\n\t\t\tconst newUnit = e.target.value as GridUnit;\r\n\t\t\tsetUnit(newUnit);\r\n\r\n\t\t\t// 単位変更時: 現在のpxサイズから新しい単位に変換\r\n\t\t\tconst convertedValue = convertPxToUnit(currentPxSize, newUnit);\r\n\t\t\tsetValue(convertedValue.toString());\r\n\t\t};\r\n\t\treturn (\r\n\t\t\t<div\r\n\t\t\t\tref={containerRef}\r\n\t\t\t\tclassName={styles.editor}\r\n\t\t\t\tstyle={editorStyle}\r\n\t\t\t\tdata-testid={`grid-unit-editor-${direction}`}\r\n\t\t\t>\r\n\t\t\t\t<input\r\n\t\t\t\t\tref={inputRef}\r\n\t\t\t\t\ttype=\"number\"\r\n\t\t\t\t\tclassName={styles.input}\r\n\t\t\t\t\tvalue={value}\r\n\t\t\t\t\tonChange={(e) => setValue(e.target.value)}\r\n\t\t\t\t\tonKeyDown={handleKeyDown}\r\n\t\t\t\t\tmin=\"0.1\"\r\n\t\t\t\t\tstep={unit === \"fr\" ? \"0.1\" : \"1\"}\r\n\t\t\t\t/>\r\n\t\t\t\t<select\r\n\t\t\t\t\tclassName={styles.select}\r\n\t\t\t\t\tvalue={unit}\r\n\t\t\t\t\tonChange={handleUnitChange}\r\n\t\t\t\t>\r\n\t\t\t\t\t{SUPPORTED_UNITS.map((u) => (\r\n\t\t\t\t\t\t<option key={u} value={u}>\r\n\t\t\t\t\t\t\t{u}\r\n\t\t\t\t\t\t</option>\r\n\t\t\t\t\t))}\r\n\t\t\t\t</select>\r\n\t\t\t\t<button\r\n\t\t\t\t\ttype=\"button\"\r\n\t\t\t\t\tclassName={styles.button}\r\n\t\t\t\t\tonClick={handleSubmit}\r\n\t\t\t\t\ttitle=\"確定\"\r\n\t\t\t\t>\r\n\t\t\t\t\t✓\r\n\t\t\t\t</button>\r\n\t\t\t</div>\r\n\t\t);\r\n\t},\r\n);\r\n\r\nGridUnitEditor.displayName = \"GridUnitEditor\";\r\n","/**\r\n * @file GridDimensionLabel.tsx\r\n * @description グリッド線間の寸法を表示するラベルコンポーネント\r\n */\r\n\r\nimport { memo, useState } from \"react\";\r\n\r\nimport styles from \"./GridDimensionLabel.module.css\";\r\nimport { GridUnitEditor } from \"./GridUnitEditor\";\r\n\r\nimport { toMm } from \"@/utils/convert\";\r\n\r\nimport type { Dimension, GridUnit } from \"@types\";\r\n\r\nexport interface GridDimensionLabelProps {\r\n\t/** ラベルの方向 ('column' or 'row') */\r\n\tdirection: \"column\" | \"row\";\r\n\t/** 次元のインデックス(配列のインデックス) */\r\n\tindex: number;\r\n\t/** 寸法の値(Dimensionオブジェクト) */\r\n\tdimension: Dimension<GridUnit>;\r\n\t/** ラベルの位置 (px) - 中央座標 */\r\n\tposition: number;\r\n\t/** 現在のpxサイズ(単位変換用) */\r\n\tcurrentPxSize: number;\r\n\t/** 印刷可能領域の左マージン (px) */\r\n\tmarginLeftPx: number;\r\n\t/** 印刷可能領域の上マージン (px) */\r\n\tmarginTopPx: number;\r\n\t/** カーソルが近い場合にのみ表示 */\r\n\tisNearCursor: boolean;\r\n\t/** リサイズ中のプレビューサイズ(px) - 指定時は単位変換して表示 */\r\n\tresizingPxSize?: number;\r\n\t/** 寸法更新時のコールバック */\r\n\tonDimensionChange?: (\r\n\t\tdirection: \"column\" | \"row\",\r\n\t\tindex: number,\r\n\t\tdimension: Dimension<GridUnit>,\r\n\t) => void;\r\n}\r\n\r\n/**\r\n * px値を指定単位に変換\r\n * @param pxSize - 変換するpxサイズ\r\n * @param targetUnit - 変換先の単位\r\n * @param originalValue - 元の値(fr計算用)\r\n * @param originalPxSize - 元のpxサイズ(fr計算用)\r\n */\r\nfunction convertPxToUnit(\r\n\tpxSize: number,\r\n\ttargetUnit: GridUnit,\r\n\toriginalValue?: number,\r\n\toriginalPxSize?: number,\r\n): number {\r\n\tif (targetUnit === \"fr\") {\r\n\t\t// frは比率なので、元のサイズとの比率から計算\r\n\t\tif (\r\n\t\t\toriginalValue !== undefined &&\r\n\t\t\toriginalPxSize !== undefined &&\r\n\t\t\toriginalPxSize > 0\r\n\t\t) {\r\n\t\t\tconst ratio = pxSize / originalPxSize;\r\n\t\t\treturn Math.round(originalValue * ratio * 100) / 100;\r\n\t\t}\r\n\t\treturn 1;\r\n\t}\r\n\r\n\tswitch (targetUnit) {\r\n\t\tcase \"px\":\r\n\t\t\treturn Math.round(pxSize);\r\n\t\tcase \"mm\": {\r\n\t\t\tconst mm = toMm.fromPx(pxSize);\r\n\t\t\treturn Math.round(mm * 10) / 10;\r\n\t\t}\r\n\t\tcase \"cm\": {\r\n\t\t\tconst mm = toMm.fromPx(pxSize);\r\n\t\t\treturn Math.round((mm / 10) * 100) / 100;\r\n\t\t}\r\n\t\tcase \"inch\": {\r\n\t\t\tconst mm = toMm.fromPx(pxSize);\r\n\t\t\treturn Math.round((mm / 25.4) * 100) / 100;\r\n\t\t}\r\n\t\tcase \"pt\": {\r\n\t\t\tconst mm = toMm.fromPx(pxSize);\r\n\t\t\treturn Math.round((mm / 25.4) * 72 * 10) / 10;\r\n\t\t}\r\n\t\tdefault: {\r\n\t\t\tconst _exhaustive: never = targetUnit;\r\n\t\t\tthrow new Error(`Unsupported unit: ${_exhaustive}`);\r\n\t\t}\r\n\t}\r\n}\r\n\r\n/**\r\n * GridDimensionLabel - グリッド線間の寸法表示\r\n *\r\n * グリッド線と線の間に寸法(値と単位)を表示します。\r\n * ダブルクリックで単位編集UIを表示します。\r\n */\r\nexport const GridDimensionLabel = memo(\r\n\t({\r\n\t\tdirection,\r\n\t\tindex,\r\n\t\tdimension,\r\n\t\tposition,\r\n\t\tcurrentPxSize,\r\n\t\tmarginLeftPx,\r\n\t\tmarginTopPx,\r\n\t\tisNearCursor,\r\n\t\tresizingPxSize,\r\n\t\tonDimensionChange,\r\n\t}: GridDimensionLabelProps) => {\r\n\t\tconst [isEditing, setIsEditing] = useState(false);\r\n\r\n\t\t// カーソルが近くないか編集中でなければ非表示\r\n\t\tif (!isNearCursor && !isEditing) {\r\n\t\t\treturn null;\r\n\t\t}\r\n\r\n\t\t// ラベルの表示スタイル(キャンバス外に配置)\r\n\t\tconst labelStyle: React.CSSProperties =\r\n\t\t\tdirection === \"column\"\r\n\t\t\t\t? {\r\n\t\t\t\t\t\t// 列のラベル: 上端外側に水平表示\r\n\t\t\t\t\t\tleft: `${marginLeftPx + position}px`,\r\n\t\t\t\t\t\ttop: `${marginTopPx - 20}px`, // キャンバス外(上)\r\n\t\t\t\t\t\ttransform: \"translateX(-50%)\",\r\n\t\t\t\t\t}\r\n\t\t\t\t: {\r\n\t\t\t\t\t\t// 行のラベル: 左端外側に垂直表示\r\n\t\t\t\t\t\tleft: `${marginLeftPx - 20}px`, // キャンバス外(左)\r\n\t\t\t\t\t\ttop: `${marginTopPx + position}px`,\r\n\t\t\t\t\t\ttransform: \"translateY(-50%)\",\r\n\t\t\t\t\t\twritingMode: \"vertical-rl\",\r\n\t\t\t\t\t};\r\n\r\n\t\tconst handleDoubleClick = () => {\r\n\t\t\tsetIsEditing(true);\r\n\t\t};\r\n\r\n\t\tconst handleDimensionChange = (newDimension: Dimension<GridUnit>) => {\r\n\t\t\tonDimensionChange?.(direction, index, newDimension);\r\n\t\t\tsetIsEditing(false);\r\n\t\t};\r\n\r\n\t\tconst handleCancel = () => {\r\n\t\t\tsetIsEditing(false);\r\n\t\t};\r\n\r\n\t\t// 寸法のフォーマット表示\r\n\t\tconst formatDimension = (dim: Dimension<GridUnit>): string => {\r\n\t\t\tif (dim.unit === \"fr\") {\r\n\t\t\t\treturn `${dim.value}fr`;\r\n\t\t\t}\r\n\t\t\treturn `${dim.value}${dim.unit}`;\r\n\t\t};\r\n\r\n\t\t// リサイズ中はプレビュー表示(元の単位に変換)\r\n\t\tconst displayText = resizingPxSize\r\n\t\t\t? (() => {\r\n\t\t\t\t\tconst convertedValue = convertPxToUnit(\r\n\t\t\t\t\t\tresizingPxSize,\r\n\t\t\t\t\t\tdimension.unit,\r\n\t\t\t\t\t\tdimension.value,\r\n\t\t\t\t\t\tcurrentPxSize,\r\n\t\t\t\t\t);\r\n\t\t\t\t\tif (dimension.unit === \"fr\") {\r\n\t\t\t\t\t\treturn `${convertedValue}fr`;\r\n\t\t\t\t\t}\r\n\t\t\t\t\treturn `${convertedValue}${dimension.unit}`;\r\n\t\t\t\t})()\r\n\t\t\t: formatDimension(dimension);\r\n\r\n\t\treturn (\r\n\t\t\t<>\r\n\t\t\t\t<button\r\n\t\t\t\t\ttype=\"button\"\r\n\t\t\t\t\tclassName={styles.label}\r\n\t\t\t\t\tstyle={labelStyle}\r\n\t\t\t\t\tonDoubleClick={handleDoubleClick}\r\n\t\t\t\t\tdata-testid={`grid-dimension-${direction}-${index}`}\r\n\t\t\t\t\taria-label={`グリッド寸法: ${displayText}`}\r\n\t\t\t\t>\r\n\t\t\t\t\t{displayText}\r\n\t\t\t\t</button>{\" \"}\r\n\t\t\t\t{isEditing && (\r\n\t\t\t\t\t<GridUnitEditor\r\n\t\t\t\t\t\tdirection={direction}\r\n\t\t\t\t\t\tdimension={dimension}\r\n\t\t\t\t\t\tcurrentPxSize={currentPxSize}\r\n\t\t\t\t\t\tposition={position}\r\n\t\t\t\t\t\tmarginLeftPx={marginLeftPx}\r\n\t\t\t\t\t\tmarginTopPx={marginTopPx}\r\n\t\t\t\t\t\tonChange={handleDimensionChange}\r\n\t\t\t\t\t\tonCancel={handleCancel}\r\n\t\t\t\t\t/>\r\n\t\t\t\t)}\r\n\t\t\t</>\r\n\t\t);\r\n\t},\r\n);\r\n\r\nGridDimensionLabel.displayName = \"GridDimensionLabel\";\r\n","// グリッド線用のPathデータ(d属性)を生成する関数\r\n\r\nexport function getGridPathD(\r\n\tcolPxs: number[],\r\n\trowPxs: number[],\r\n\twidth: number,\r\n\theight: number,\r\n): string {\r\n\tlet d = \"\";\r\n\r\n\t// 縦線のコマンド生成 (Move to -> Line to)\r\n\tfor (const x of colPxs) {\r\n\t\t// 小数点以下のズレによる滲みを防ぐため Math.round や toFixed を使う場合もあります\r\n\t\td += `M ${x} 0 L ${x} ${height} `;\r\n\t}\r\n\r\n\t// 横線のコマンド生成\r\n\tfor (const y of rowPxs) {\r\n\t\td += `M 0 ${y} L ${width} ${y} `;\r\n\t}\r\n\r\n\treturn d;\r\n}\r\n","/**\r\n * @file GridOverlay.tsx\r\n * @description グリッド線オーバーレイコンポーネント\r\n * @z-index 2 (GridLayerの最上層)\r\n */\r\n\r\nimport { memo, useMemo } from \"react\";\r\nimport { getStrokeDasharray } from \"@types\";\r\n\r\nimport { getGridPathD } from \"./getGridPathD\";\r\n\r\nimport { DEFAULT_DPI } from \"@/constants\";\r\nimport { toPx } from \"@/utils/convert/toPx\";\r\nimport { Z_INDEX } from \"@/utils/zIndex\";\r\n\r\nimport type { GridPosPx, LineStyle, PaperContentPx } from \"@types\";\r\nimport type React from \"react\";\r\n\r\n/**\r\n * GridOverlayコンポーネントのProps\r\n */\r\nexport interface GridOverlayProps {\r\n\tgridPosPx: GridPosPx; // グリッド線の位置(px配列)\r\n\tcontentPx: PaperContentPx; // コンテンツエリア(印刷可能領域)のサイズ(px)\r\n\tmarginLeftPx: number; // 左マージン(px) - SVGの配置位置調整用\r\n\tmarginTopPx: number; // 上マージン(px) - SVGの配置位置調整用\r\n\tlineStyle?: LineStyle; // グリッド線のスタイル\r\n\tvisible?: boolean; // 表示/非表示\r\n\tzIndex?: number; // z-index(デフォルト: Z_INDEX.GRID_OVERLAY)\r\n\tdpi?: number; // DPI(デフォルト: DEFAULT_DPI)\r\n\tclassName?: string; // 追加のクラス名\r\n}\r\n\r\n/**\r\n * GridOverlay\r\n *\r\n * グリッド線をSVGで描画するオーバーレイコンポーネント\r\n * - z-index: 2 (GridLayerの最上層)\r\n * - pointer-events: none (クリックイベント透過)\r\n * - コンテンツエリア(印刷可能領域)内にグリッド線を描画\r\n */\r\nexport const GridOverlay: React.FC<GridOverlayProps> = memo(\r\n\t({\r\n\t\tgridPosPx,\r\n\t\tcontentPx,\r\n\t\tmarginLeftPx,\r\n\t\tmarginTopPx,\r\n\t\tlineStyle,\r\n\t\tvisible = true,\r\n\t\tzIndex = Z_INDEX.GRID_OVERLAY,\r\n\t\tdpi = DEFAULT_DPI,\r\n\t\tclassName = \"\",\r\n\t}) => {\r\n\t\tconst pathData = useMemo(() => {\r\n\t\t\treturn getGridPathD(\r\n\t\t\t\tgridPosPx.cols.slice(1, -1),\r\n\t\t\t\tgridPosPx.rows.slice(1, -1),\r\n\t\t\t\tcontentPx.width,\r\n\t\t\t\tcontentPx.height,\r\n\t\t\t);\r\n\t\t}, [gridPosPx, contentPx]);\r\n\r\n\t\tif (!visible || !lineStyle) return null;\r\n\r\n\t\tconst strokeDasharray = getStrokeDasharray(lineStyle);\r\n\t\tconst borderWidth = toPx.fromDim(lineStyle.width, dpi);\r\n\r\n\t\t// SVGコンテナのスタイル\r\n\t\tconst svgStyle: React.CSSProperties = {\r\n\t\t\tposition: \"absolute\",\r\n\t\t\tleft: `${marginLeftPx}px`,\r\n\t\t\ttop: `${marginTopPx}px`,\r\n\t\t\tpointerEvents: \"none\",\r\n\t\t\tzIndex: zIndex,\r\n\t\t};\r\n\r\n\t\treturn (\r\n\t\t\t<svg\r\n\t\t\t\tclassName={className}\r\n\t\t\t\tstyle={svgStyle}\r\n\t\t\t\twidth={contentPx.width}\r\n\t\t\t\theight={contentPx.height}\r\n\t\t\t\txmlns=\"http://www.w3.org/2000/svg\"\r\n\t\t\t\trole=\"img\"\r\n\t\t\t\taria-label=\"Grid overlay lines\"\r\n\t\t\t>\r\n\t\t\t\t<path\r\n\t\t\t\t\td={pathData}\r\n\t\t\t\t\tstroke={lineStyle.color}\r\n\t\t\t\t\tstrokeWidth={borderWidth}\r\n\t\t\t\t\tstrokeDasharray={strokeDasharray}\r\n\t\t\t\t\tfill=\"none\"\r\n\t\t\t\t/>\r\n\t\t\t</svg>\r\n\t\t);\r\n\t},\r\n);\r\n","/**\r\n * @file GridResizeHandle.tsx\r\n * @description グリッドリサイズ用のハンドルコンポーネント\r\n */\r\n\r\nimport { memo, useCallback, useState } from \"react\";\r\n\r\nimport styles from \"./GridResizeHandle.module.css\";\r\n\r\nexport interface GridResizeHandleProps {\r\n\t/** ハンドルの方向 ('column' or 'row') */\r\n\tdirection: \"column\" | \"row\";\r\n\t/** グリッドのインデックス (列なら列番号、行なら行番号) */\r\n\tindex: number;\r\n\t/** ハンドルの位置 (px) - グリッド線の位置 */\r\n\tposition: number;\r\n\t/** 印刷可能領域の左マージン (px) */\r\n\tmarginLeftPx: number;\r\n\t/** 印刷可能領域の上マージン (px) */\r\n\tmarginTopPx: number;\r\n\t/** リサイズ開始時のコールバック */\r\n\tonResizeStart?: (direction: \"column\" | \"row\", index: number) => void;\r\n\t/** リサイズ中のコールバック */\r\n\tonResize?: (\r\n\t\tdirection: \"column\" | \"row\",\r\n\t\tindex: number,\r\n\t\tdelta: number,\r\n\t) => void;\r\n\t/** リサイズ終了時のコールバック */\r\n\tonResizeEnd?: (\r\n\t\tdirection: \"column\" | \"row\",\r\n\t\tindex: number,\r\n\t\tdelta: number,\r\n\t) => void;\r\n}\r\n\r\n/**\r\n * GridResizeHandle - グリッドリサイズ用のハンドル\r\n *\r\n * グリッド線の両端にハンドルを配置し、ドラッグでリサイズ可能にします。\r\n * 設計文書に従い、「グリッド線そのもののドラッグは禁止」し、\r\n * 「グリッド線の両端ハンドル」のみをドラッグ可能とします。\r\n */\r\nexport const GridResizeHandle = memo(\r\n\t({\r\n\t\tdirection,\r\n\t\tindex,\r\n\t\tposition,\r\n\t\tmarginLeftPx,\r\n\t\tmarginTopPx,\r\n\t\tonResizeStart,\r\n\t\tonResize,\r\n\t\tonResizeEnd,\r\n\t}: GridResizeHandleProps) => {\r\n\t\tconst [isDragging, setIsDragging] = useState(false);\r\n\r\n\t\t// ハンドルの配置スタイル(端点の外側に配置、ブロックリサイズハンドルと同じデザイン)\r\n\t\tconst HANDLE_SIZE = 12; // ブロックハンドルと同じサイズ\r\n\t\tconst HANDLE_OFFSET = HANDLE_SIZE / 2; // 中央揃え用オフセット\r\n\r\n\t\tconst handleStyle: React.CSSProperties =\r\n\t\t\tdirection === \"column\"\r\n\t\t\t\t? {\r\n\t\t\t\t\t\t// 列のハンドル: 上端の外側に配置\r\n\t\t\t\t\t\tleft: `${marginLeftPx + position - HANDLE_OFFSET}px`,\r\n\t\t\t\t\t\ttop: `${marginTopPx - HANDLE_OFFSET}px`, // キャンバス外(上)\r\n\t\t\t\t\t\twidth: `${HANDLE_SIZE}px`,\r\n\t\t\t\t\t\theight: `${HANDLE_SIZE}px`,\r\n\t\t\t\t\t\tcursor: \"col-resize\",\r\n\t\t\t\t\t}\r\n\t\t\t\t: {\r\n\t\t\t\t\t\t// 行のハンドル: 左端の外側に配置\r\n\t\t\t\t\t\tleft: `${marginLeftPx - HANDLE_OFFSET}px`, // キャンバス外(左)\r\n\t\t\t\t\t\ttop: `${marginTopPx + position - HANDLE_OFFSET}px`,\r\n\t\t\t\t\t\twidth: `${HANDLE_SIZE}px`,\r\n\t\t\t\t\t\theight: `${HANDLE_SIZE}px`,\r\n\t\t\t\t\t\tcursor: \"row-resize\",\r\n\t\t\t\t\t};\r\n\r\n\t\tconst handlePointerDown = useCallback(\r\n\t\t\t(e: React.PointerEvent) => {\r\n\t\t\t\te.stopPropagation();\r\n\t\t\t\te.preventDefault();\r\n\r\n\t\t\t\tconst initialPos = direction === \"column\" ? e.clientX : e.clientY;\r\n\t\t\t\tsetIsDragging(true);\r\n\r\n\t\t\t\tonResizeStart?.(direction, index);\r\n\r\n\t\t\t\t// グローバルなポインターイベントをリスン\r\n\t\t\t\tconst handlePointerMove = (moveEvent: PointerEvent) => {\r\n\t\t\t\t\tconst currentPos =\r\n\t\t\t\t\t\tdirection === \"column\" ? moveEvent.clientX : moveEvent.clientY;\r\n\t\t\t\t\tconst delta = currentPos - initialPos;\r\n\r\n\t\t\t\t\tonResize?.(direction, index, delta);\r\n\t\t\t\t};\r\n\r\n\t\t\t\tconst handlePointerUp = (upEvent: PointerEvent) => {\r\n\t\t\t\t\tconst currentPos =\r\n\t\t\t\t\t\tdirection === \"column\" ? upEvent.clientX : upEvent.clientY;\r\n\t\t\t\t\tconst delta = currentPos - initialPos;\r\n\r\n\t\t\t\t\tsetIsDragging(false);\r\n\t\t\t\t\tonResizeEnd?.(direction, index, delta);\r\n\r\n\t\t\t\t\twindow.removeEventListener(\"pointermove\", handlePointerMove);\r\n\t\t\t\t\twindow.removeEventListener(\"pointerup\", handlePointerUp);\r\n\t\t\t\t};\r\n\r\n\t\t\t\twindow.addEventListener(\"pointermove\", handlePointerMove);\r\n\t\t\t\twindow.addEventListener(\"pointerup\", handlePointerUp);\r\n\t\t\t},\r\n\t\t\t[direction, index, onResizeStart, onResize, onResizeEnd],\r\n\t\t);\r\n\r\n\t\treturn (\r\n\t\t\t<div\r\n\t\t\t\tclassName={`${styles.handle} ${styles[direction]} ${isDragging ? styles.dragging : \"\"}`}\r\n\t\t\t\tstyle={handleStyle}\r\n\t\t\t\tonPointerDown={handlePointerDown}\r\n\t\t\t\tdata-testid={`grid-resize-handle-${direction}-${index}`}\r\n\t\t\t/>\r\n\t\t);\r\n\t},\r\n);\r\n\r\nGridResizeHandle.displayName = \"GridResizeHandle\";\r\n","/**\r\n * @file MarginOverlay.tsx\r\n * @description 用紙マージン表示コンポーネント\r\n * @z-index 1 (GridLayerの中間層)\r\n */\r\n\r\nimport { memo } from \"react\";\r\n\r\nimport { Z_INDEX } from \"@/utils/zIndex\";\r\n\r\nimport type React from \"react\";\r\nimport type { PaperPx } from \"@/types\";\r\n\r\n/**\r\n * MarginOverlayコンポーネントのProps\r\n */\r\nexport interface MarginOverlayProps {\r\n\tpaperPx: PaperPx; // 用紙設定(ピクセル単位)\r\n\tvisible?: boolean; // 表示/非表示\r\n\tmarginColor?: string; // マージン領域の塗りつぶし色\r\n\tzIndex?: number; // z-index(デフォルト: Z_INDEX.MARGIN_OVERLAY)\r\n\tclassName?: string; // 追加のクラス名\r\n}\r\n\r\n/**\r\n * MarginOverlay\r\n *\r\n * 用紙のマージン(印刷不可領域)を視覚的に表示するコンポーネント\r\n * - z-index: 1 (GridCanvasの上、GridOverlayの下)\r\n * - pointer-events: none (クリックイベント透過)\r\n * - 半透明の影でマージン領域を表現\r\n */\r\nexport const MarginOverlay: React.FC<MarginOverlayProps> = memo(\r\n\t({\r\n\t\tpaperPx,\r\n\t\tvisible = true,\r\n\t\tmarginColor,\r\n\t\tzIndex = Z_INDEX.MARGIN_OVERLAY,\r\n\t\tclassName = \"\",\r\n\t}) => {\r\n\t\tif (!visible) return null;\r\n\r\n\t\tconst overlayStyle: React.CSSProperties = {\r\n\t\t\tposition: \"absolute\",\r\n\t\t\tinset: 0,\r\n\t\t\tpointerEvents: \"none\",\r\n\t\t\twidth: `${paperPx.canvas.width}px`,\r\n\t\t\theight: `${paperPx.canvas.height}px`,\r\n\t\t\tzIndex: zIndex,\r\n\t\t};\r\n\r\n\t\tconst marginBoxStyle: React.CSSProperties = {\r\n\t\t\tposition: \"absolute\",\r\n\t\t\tbackgroundColor: marginColor || \"rgba(0, 0, 0, 0.05)\",\r\n\t\t\tpointerEvents: \"none\",\r\n\t\t};\r\n\r\n\t\treturn (\r\n\t\t\t<div\r\n\t\t\t\tclassName={className}\r\n\t\t\t\tstyle={overlayStyle}\r\n\t\t\t\trole=\"presentation\"\r\n\t\t\t\taria-label=\"Printable area margin\"\r\n\t\t\t\tdata-testid=\"margin-overlay\"\r\n\t\t\t>\r\n\t\t\t\t{/* 上マージン */}\r\n\t\t\t\t{paperPx.margin.top > 0 && (\r\n\t\t\t\t\t<div\r\n\t\t\t\t\t\tdata-testid=\"margin-top\"\r\n\t\t\t\t\t\tstyle={{\r\n\t\t\t\t\t\t\t...marginBoxStyle,\r\n\t\t\t\t\t\t\ttop: 0,\r\n\t\t\t\t\t\t\tleft: 0,\r\n\t\t\t\t\t\t\twidth: \"100%\",\r\n\t\t\t\t\t\t\theight: `${paperPx.margin.top}px`,\r\n\t\t\t\t\t\t}}\r\n\t\t\t\t\t/>\r\n\t\t\t\t)}\r\n\r\n\t\t\t\t{/* 下マージン */}\r\n\t\t\t\t{paperPx.margin.bottom > 0 && (\r\n\t\t\t\t\t<div\r\n\t\t\t\t\t\tdata-testid=\"margin-bottom\"\r\n\t\t\t\t\t\tstyle={{\r\n\t\t\t\t\t\t\t...marginBoxStyle,\r\n\t\t\t\t\t\t\tbottom: 0,\r\n\t\t\t\t\t\t\tleft: 0,\r\n\t\t\t\t\t\t\twidth: \"100%\",\r\n\t\t\t\t\t\t\theight: `${paperPx.margin.bottom}px`,\r\n\t\t\t\t\t\t}}\r\n\t\t\t\t\t/>\r\n\t\t\t\t)}\r\n\r\n\t\t\t\t{/* 左マージン */}\r\n\t\t\t\t{paperPx.margin.left > 0 && (\r\n\t\t\t\t\t<div\r\n\t\t\t\t\t\tdata-testid=\"margin-left\"\r\n\t\t\t\t\t\tstyle={{\r\n\t\t\t\t\t\t\t...marginBoxStyle,\r\n\t\t\t\t\t\t\tleft: 0,\r\n\t\t\t\t\t\t\ttop: `${paperPx.margin.top}px`,\r\n\t\t\t\t\t\t\theight: `${paperPx.content.height}px`,\r\n\t\t\t\t\t\t\twidth: `${paperPx.margin.left}px`,\r\n\t\t\t\t\t\t}}\r\n\t\t\t\t\t/>\r\n\t\t\t\t)}\r\n\r\n\t\t\t\t{/* 右マージン */}\r\n\t\t\t\t{paperPx.margin.right > 0 && (\r\n\t\t\t\t\t<div\r\n\t\t\t\t\t\tdata-testid=\"margin-right\"\r\n\t\t\t\t\t\tstyle={{\r\n\t\t\t\t\t\t\t...marginBoxStyle,\r\n\t\t\t\t\t\t\tright: 0,\r\n\t\t\t\t\t\t\ttop: `${paperPx.margin.top}px`,\r\n\t\t\t\t\t\t\theight: `${paperPx.content.height}px`,\r\n\t\t\t\t\t\t\twidth: `${paperPx.margin.right}px`,\r\n\t\t\t\t\t\t}}\r\n\t\t\t\t\t/>\r\n\t\t\t\t)}\r\n\t\t\t</div>\r\n\t\t);\r\n\t},\r\n);\r\n","import { memo, useCallback, useEffect, useMemo, useRef, useState } from \"react\";\r\n\r\nimport { Z_INDEX } from \"../../utils/zIndex\";\r\nimport { BorderOverlay } from \"./BorderOverlay/BorderOverlay\";\r\nimport { GridCanvas } from \"./GridCanvas/GridCanvas\";\r\nimport { GridDimensionLabel } from \"./GridDimensionLabel\";\r\nimport { GridOverlay } from \"./GridOverlay/GridOverlay\";\r\nimport { GridResizeHandle } from \"./GridResizeHandle\";\r\nimport { MarginOverlay } from \"./MarginOverlay/MarginOverlay\";\r\n\r\nimport { DEFAULT_DPI } from \"@/constants\";\r\n\r\nimport type {\r\n\tBorderStyle,\r\n\tDimension,\r\n\tGridPosPx,\r\n\tGridUnit,\r\n\tLineStyle,\r\n\tPaperPx,\r\n} from \"@types\";\r\n\r\n/**\r\n * GridLayerのプロパティ\r\n */\r\nexport interface GridLayerProps {\r\n\tpaperPx: PaperPx; // 用紙設定(ピクセル単位)\r\n\tgridPosPxs: GridPosPx; // グリッド線の位置(px配列)\r\n\tgridDimensions?: {\r\n\t\tcols: Array<Dimension<GridUnit>>;\r\n\t\trows: Array<Dimension<GridUnit>>;\r\n\t}; // グリッド寸法(単位付き)\r\n\tgridLineStyle?: LineStyle; // グリッド線のスタイル\r\n\tborderStyle?: BorderStyle; // 印刷可能領域枠のスタイル\r\n\tbackgroundColor?: string; // 用紙背景色\r\n\tboxShadow?: string; // 用紙のボックスシャドウ\r\n\tmarginFillColor?: string; // マージン領域の塗りつぶし色\r\n\tshowGridLines?: boolean; // グリッド線を表示するか\r\n\tshowMargins?: boolean; // マージン領域を表示するか\r\n\tshowBorder?: boolean; // 印刷可能領域枠を表示するか\r\n\tshowResizeHandles?: boolean; // リサイズハンドルを表示するか\r\n\tshowDimensionLabels?: boolean; // 寸法ラベルを表示するか\r\n\tonGridResize?: (\r\n\t\tdirection: \"column\" | \"row\",\r\n\t\tindex: number,\r\n\t\tdelta: number,\r\n\t) => void; // リサイズコールバック\r\n\tonDimensionChange?: (\r\n\t\tdirection: \"column\" | \"row\",\r\n\t\tindex: number,\r\n\t\tdimension: Dimension<GridUnit>,\r\n\t) => void; // 寸法変更コールバック\r\n\tclassName?: string; // 追加のクラス名\r\n\tzIndex?: {\r\n\t\t// 各レイヤーのz-indexオーバーライド\r\n\t\tcanvas?: number;\r\n\t\tmargin?: number;\r\n\t\tgrid?: number;\r\n\t\tborder?: number;\r\n\t};\r\n}\r\n\r\n/**\r\n * GridLayer - グリッドシステムの統合コンポーネント\r\n *\r\n * 4つのレイヤーを統合して提供します:\r\n * 1. GridCanvas (z-index: 0) - 用紙背景\r\n * 2. MarginOverlay (z-index: 1) - 印刷不可領域の視覚化\r\n * 3. GridOverlay (z-index: 2) - グリッド線\r\n * 4. BorderOverlay (z-index: 3) - 印刷可能領域の境界線\r\n *\r\n * @example\r\n * ```tsx\r\n * <GridLayer\r\n * paper={schema.paper}\r\n * grid={schema.grid}\r\n * paperWidthPx={794}\r\n * paperHeightPx={1123}\r\n * contentAreaWidthPx={718}\r\n * contentAreaHeightPx={1047}\r\n * marginLeftPx={38}\r\n * marginRightPx={38}\r\n * marginTopPx={38}\r\n * marginBottomPx={38}\r\n * colWidthPxs={[100, 150, 200, 268]}\r\n * rowHeightPxs={[50, 75, 100, 125, 697]}\r\n * />\r\n * ```\r\n */\r\nexport const GridLayer: React.FC<GridLayerProps> = memo(\r\n\t({\r\n\t\tpaperPx,\r\n\t\tgridPosPxs,\r\n\t\tgridDimensions,\r\n\t\tgridLineStyle,\r\n\t\tborderStyle,\r\n\t\tbackgroundColor = \"#ffffff\",\r\n\t\tboxShadow = \"0 2px 8px rgba(0, 0, 0, 0.1)\",\r\n\t\tmarginFillColor = \"rgba(0, 0, 0, 0.05)\",\r\n\t\tshowGridLines = true,\r\n\t\tshowMargins = true,\r\n\t\tshowBorder = true,\r\n\t\tshowResizeHandles = false,\r\n\t\tshowDimensionLabels = false,\r\n\t\tonGridResize,\r\n\t\tonDimensionChange,\r\n\t\tclassName = \"\",\r\n\t\tzIndex = {},\r\n\t}) => {\r\n\t\t// グリッドリサイズ中のゴースト線の状態\r\n\t\tconst [ghostLine, setGhostLine] = useState<{\r\n\t\t\tdirection: \"column\" | \"row\";\r\n\t\t\tposition: number;\r\n\t\t} | null>(null);\r\n\r\n\t\t// ドラッグ中の状態(隣接するラベルを表示するため)\r\n\t\tconst [draggingHandle, setDraggingHandle] = useState<{\r\n\t\t\tdirection: \"column\" | \"row\";\r\n\t\t\tindex: number;\r\n\t\t} | null>(null);\r\n\r\n\t\t// マウス位置の状態(寸法ラベルの表示判定用)\r\n\t\t// windowレベルでマウス位置を監視(z-indexの高い要素に邪魔されない)\r\n\t\tconst [mousePos, setMousePos] = useState<{ x: number; y: number } | null>(\r\n\t\t\tnull,\r\n\t\t);\r\n\t\tconst containerRef = useRef<HTMLDivElement>(null);\r\n\t\tuseEffect(() => {\r\n\t\t\tconst handleMouseMove = (e: MouseEvent) => {\r\n\t\t\t\tif (!containerRef.current) return;\r\n\t\t\t\tconst rect = containerRef.current.getBoundingClientRect();\r\n\t\t\t\tsetMousePos({\r\n\t\t\t\t\tx: e.clientX - rect.left,\r\n\t\t\t\t\ty: e.clientY - rect.top,\r\n\t\t\t\t});\r\n\t\t\t};\r\n\r\n\t\t\tconst handleMouseLeave = (e: MouseEvent) => {\r\n\t\t\t\tif (!containerRef.current) return;\r\n\t\t\t\tconst rect = containerRef.current.getBoundingClientRect();\r\n\t\t\t\t// コンテナの外に出たかチェック\r\n\t\t\t\tconst isOutside =\r\n\t\t\t\t\te.clientX < rect.left ||\r\n\t\t\t\t\te.clientX > rect.right ||\r\n\t\t\t\t\te.clientY < rect.top ||\r\n\t\t\t\t\te.clientY > rect.bottom;\r\n\t\t\t\tif (isOutside) {\r\n\t\t\t\t\tsetMousePos(null);\r\n\t\t\t\t}\r\n\t\t\t};\r\n\r\n\t\t\twindow.addEventListener(\"mousemove\", handleMouseMove);\r\n\t\t\twindow.addEventListener(\"mouseleave\", handleMouseLeave);\r\n\r\n\t\t\treturn () => {\r\n\t\t\t\twindow.removeEventListener(\"mousemove\", handleMouseMove);\r\n\t\t\t\twindow.removeEventListener(\"mouseleave\", handleMouseLeave);\r\n\t\t\t};\r\n\t\t}, []); // 寸法ラベル表示判定: カーソルがキャンバス外にあるかどうか\r\n\t\tconst shouldShowDimensionLabels = useMemo(() => {\r\n\t\t\tif (!mousePos) return false;\r\n\r\n\t\t\t// カーソルがキャンバス内にあるかどうか\r\n\t\t\tconst contentWidth = paperPx.content.width;\r\n\t\t\tconst contentHeight = paperPx.content.height;\r\n\t\t\tconst marginLeftPx = paperPx.margin.left;\r\n\t\t\tconst marginTopPx = paperPx.margin.top;\r\n\r\n\t\t\tconst isInsideCanvas =\r\n\t\t\t\tmousePos.x >= marginLeftPx &&\r\n\t\t\t\tmousePos.x <= marginLeftPx + contentWidth &&\r\n\t\t\t\tmousePos.y >= marginTopPx &&\r\n\t\t\t\tmousePos.y <= marginTopPx + contentHeight;\r\n\r\n\t\t\t// キャンバス外なら表示\r\n\t\t\treturn !isInsideCanvas;\r\n\t\t}, [mousePos, paperPx]); // リサイズ開始時\r\n\t\tconst handleResizeStart = useCallback(\r\n\t\t\t(direction: \"column\" | \"row\", index: number) => {\r\n\t\t\t\tsetDraggingHandle({ direction, index });\r\n\t\t\t},\r\n\t\t\t[],\r\n\t\t);\r\n\r\n\t\t// リサイズ中のプレビューサイズを計算\r\n\t\tconst resizingPreviewSizes = useMemo(() => {\r\n\t\t\tif (!ghostLine || !draggingHandle) return null;\r\n\r\n\t\t\tconst gridLines =\r\n\t\t\t\tdraggingHandle.direction === \"column\"\r\n\t\t\t\t\t? gridPosPxs.cols\r\n\t\t\t\t\t: gridPosPxs.rows;\r\n\t\t\tconst index = draggingHandle.index;\r\n\r\n\t\t\t// 左/上のグリッド(index-1からindexまで)\r\n\t\t\tconst prevStart = gridLines[index - 1];\r\n\t\t\tconst prevEnd = ghostLine.position;\r\n\t\t\tconst prevSize = prevStart !== undefined ? prevEnd - prevStart : 0;\r\n\r\n\t\t\t// 右/下のグリッド(indexからindex+1まで)\r\n\t\t\tconst nextStart = ghostLine.position;\r\n\t\t\tconst nextEnd = gridLines[index + 1];\r\n\t\t\tconst nextSize = nextEnd !== undefined ? nextEnd - nextStart : 0;\r\n\r\n\t\t\treturn {\r\n\t\t\t\tdirection: draggingHandle.direction,\r\n\t\t\t\tprevIndex: index - 1,\r\n\t\t\t\tprevSize,\r\n\t\t\t\tnextIndex: index,\r\n\t\t\t\tnextSize,\r\n\t\t\t};\r\n\t\t}, [ghostLine, draggingHandle, gridPosPxs]);\r\n\r\n\t\t// リサイズ中(ゴースト線を表示)\r\n\t\tconst handleResize = useCallback(\r\n\t\t\t(direction: \"column\" | \"row\", index: number, delta: number) => {\r\n\t\t\t\t// 元の位置を取得\r\n\t\t\t\tconst gridLines =\r\n\t\t\t\t\tdirection === \"column\" ? gridPosPxs.cols : gridPosPxs.rows;\r\n\t\t\t\tconst originalPos = gridLines[index];\r\n\r\n\t\t\t\tif (originalPos === undefined) return;\r\n\r\n\t\t\t\t// 隣のグリッド線の位置を取得\r\n\t\t\t\tconst prevLinePos = gridLines[index - 1];\r\n\t\t\t\tconst nextLinePos = gridLines[index + 1];\r\n\r\n\t\t\t\t// 最小間隔(10px)\r\n\t\t\t\tconst MIN_GAP = 10;\r\n\r\n\t\t\t\t// deltaを制限(隣のグリッド線を超えないように)\r\n\t\t\t\tlet clampedDelta = delta;\r\n\t\t\t\tif (prevLinePos !== undefined) {\r\n\t\t\t\t\tconst minDelta = prevLinePos + MIN_GAP - originalPos;\r\n\t\t\t\t\tclampedDelta = Math.max(clampedDelta, minDelta);\r\n\t\t\t\t}\r\n\t\t\t\tif (nextLinePos !== undefined) {\r\n\t\t\t\t\tconst maxDelta = nextLinePos - MIN_GAP - originalPos;\r\n\t\t\t\t\tclampedDelta = Math.min(clampedDelta, maxDelta);\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// ゴースト線の位置を更新(制限付き)\r\n\t\t\t\tsetGhostLine({\r\n\t\t\t\t\tdirection,\r\n\t\t\t\t\tposition: originalPos + clampedDelta,\r\n\t\t\t\t});\r\n\t\t\t},\r\n\t\t\t[gridPosPxs],\r\n\t\t); // リサイズ終了時(ゴースト線を非表示)\r\n\t\tconst handleResizeEnd = useCallback(\r\n\t\t\t(direction: \"column\" | \"row\", index: number, delta: number) => {\r\n\t\t\t\t// 元の位置を取得\r\n\t\t\t\tconst gridLines =\r\n\t\t\t\t\tdirection === \"column\" ? gridPosPxs.cols : gridPosPxs.rows;\r\n\t\t\t\tconst originalPos = gridLines[index];\r\n\r\n\t\t\t\tif (originalPos === undefined) {\r\n\t\t\t\t\tsetGhostLine(null);\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// 隣のグリッド線の位置を取得\r\n\t\t\t\tconst prevLinePos = gridLines[index - 1];\r\n\t\t\t\tconst nextLinePos = gridLines[index + 1];\r\n\r\n\t\t\t\t// 最小間隔(10px)\r\n\t\t\t\tconst MIN_GAP = 10;\r\n\r\n\t\t\t\t// deltaを制限(隣のグリッド線を超えないように)\r\n\t\t\t\tlet clampedDelta = delta;\r\n\t\t\t\tif (prevLinePos !== undefined) {\r\n\t\t\t\t\tconst minDelta = prevLinePos + MIN_GAP - originalPos;\r\n\t\t\t\t\tclampedDelta = Math.max(clampedDelta, minDelta);\r\n\t\t\t\t}\r\n\t\t\t\tif (nextLinePos !== undefined) {\r\n\t\t\t\t\tconst maxDelta = nextLinePos - MIN_GAP - originalPos;\r\n\t\t\t\t\tclampedDelta = Math.min(clampedDelta, maxDelta);\r\n\t\t\t\t}\r\n\r\n\t\t\t\tsetGhostLine(null);\r\n\t\t\t\tsetDraggingHandle(null);\r\n\t\t\t\t// 制限されたdeltaで実際のリサイズを実行\r\n\t\t\t\tonGridResize?.(direction, index, clampedDelta);\r\n\t\t\t},\r\n\t\t\t[gridPosPxs, onGridResize],\r\n\t\t);\r\n\t\tconst containerStyle: React.CSSProperties = {\r\n\t\t\tposition: \"relative\",\r\n\t\t\twidth: \"100%\",\r\n\t\t\theight: \"100%\",\r\n\t\t};\r\n\r\n\t\treturn (\r\n\t\t\t<div ref={containerRef} className={className} style={containerStyle}>\r\n\t\t\t\t{/* レイヤー1: 用紙背景 (z-index: 0) */}\r\n\t\t\t\t<GridCanvas\r\n\t\t\t\t\tcanvasPx={paperPx.canvas}\r\n\t\t\t\t\tbackgroundColor={backgroundColor}\r\n\t\t\t\t\tboxShadow={boxShadow}\r\n\t\t\t\t\tzIndex={zIndex?.canvas ?? Z_INDEX.GRID_CANVAS}\r\n\t\t\t\t\tclassName={className}\r\n\t\t\t\t/>\r\n\r\n\t\t\t\t{/* レイヤー2: マージン領域 (z-index: 1) */}\r\n\t\t\t\t{showMargins && (\r\n\t\t\t\t\t<MarginOverlay\r\n\t\t\t\t\t\tpaperPx={paperPx}\r\n\t\t\t\t\t\tvisible={showMargins}\r\n\t\t\t\t\t\tmarginColor={marginFillColor}\r\n\t\t\t\t\t\tzIndex={zIndex?.margin ?? Z_INDEX.MARGIN_OVERLAY}\r\n\t\t\t\t\t\tclassName={className}\r\n\t\t\t\t\t/>\r\n\t\t\t\t)}\r\n\r\n\t\t\t\t{/* レイヤー3: グリッド線 (z-index: 2) */}\r\n\t\t\t\t{showGridLines && (\r\n\t\t\t\t\t<GridOverlay\r\n\t\t\t\t\t\tgridPosPx={gridPosPxs}\r\n\t\t\t\t\t\tcontentPx={paperPx.content}\r\n\t\t\t\t\t\tmarginLeftPx={paperPx.margin.left}\r\n\t\t\t\t\t\tmarginTopPx={paperPx.margin.top}\r\n\t\t\t\t\t\tlineStyle={gridLineStyle}\r\n\t\t\t\t\t\tvisible={showGridLines}\r\n\t\t\t\t\t\tzIndex={zIndex?.grid ?? Z_INDEX.GRID_OVERLAY}\r\n\t\t\t\t\t\tdpi={DEFAULT_DPI}\r\n\t\t\t\t\t\tclassName={className}\r\n\t\t\t\t\t/>\r\n\t\t\t\t)}\r\n\r\n\t\t\t\t{/* レイヤー4: 境界線 (z-index: 3) */}\r\n\t\t\t\t{showBorder && (\r\n\t\t\t\t\t<BorderOverlay\r\n\t\t\t\t\t\tcontentPx={paperPx.content}\r\n\t\t\t\t\t\tmarginLeftPx={paperPx.margin.left}\r\n\t\t\t\t\t\tmarginTopPx={paperPx.margin.top}\r\n\t\t\t\t\t\tborderStyle={borderStyle}\r\n\t\t\t\t\t\tvisible={showBorder}\r\n\t\t\t\t\t\tdpi={DEFAULT_DPI}\r\n\t\t\t\t\t\tzIndex={zIndex?.border ?? Z_INDEX.BORDER_OVERLAY}\r\n\t\t\t\t\t\tclassName={className}\r\n\t\t\t\t\t/>\r\n\t\t\t\t)}\r\n\r\n\t\t\t\t{/* レイヤー5: リサイズハンドル */}\r\n\t\t\t\t{showResizeHandles && onGridResize && (\r\n\t\t\t\t\t<>\r\n\t\t\t\t\t\t{/* 列のリサイズハンドル */}\r\n\t\t\t\t\t\t{gridPosPxs.cols.map((colPos, index) => {\r\n\t\t\t\t\t\t\t// 最初と最後の列は除外(端は動かせない)\r\n\t\t\t\t\t\t\tif (index === 0 || index === gridPosPxs.cols.length - 1) {\r\n\t\t\t\t\t\t\t\treturn null;\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\tconst key = `col-${index}`;\r\n\r\n\t\t\t\t\t\t\treturn (\r\n\t\t\t\t\t\t\t\t<GridResizeHandle\r\n\t\t\t\t\t\t\t\t\tkey={key}\r\n\t\t\t\t\t\t\t\t\tdirection=\"column\"\r\n\t\t\t\t\t\t\t\t\tindex={index}\r\n\t\t\t\t\t\t\t\t\tposition={colPos}\r\n\t\t\t\t\t\t\t\t\tmarginLeftPx={paperPx.margin.left}\r\n\t\t\t\t\t\t\t\t\tmarginTopPx={paperPx.margin.top}\r\n\t\t\t\t\t\t\t\t\tonResizeStart={handleResizeStart}\r\n\t\t\t\t\t\t\t\t\tonResize={handleResize}\r\n\t\t\t\t\t\t\t\t\tonResizeEnd={handleResizeEnd}\r\n\t\t\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t\t);\r\n\t\t\t\t\t\t})}\r\n\r\n\t\t\t\t\t\t{/* 行のリサイズハンドル */}\r\n\t\t\t\t\t\t{gridPosPxs.rows.map((rowPos, index) => {\r\n\t\t\t\t\t\t\t// 最初と最後の行は除外(端は動かせない)\r\n\t\t\t\t\t\t\tif (index === 0 || index === gridPosPxs.rows.length - 1) {\r\n\t\t\t\t\t\t\t\treturn null;\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\tconst key = `row-${index}`;\r\n\r\n\t\t\t\t\t\t\treturn (\r\n\t\t\t\t\t\t\t\t<GridResizeHandle\r\n\t\t\t\t\t\t\t\t\tkey={key}\r\n\t\t\t\t\t\t\t\t\tdirection=\"row\"\r\n\t\t\t\t\t\t\t\t\tindex={index}\r\n\t\t\t\t\t\t\t\t\tposition={rowPos}\r\n\t\t\t\t\t\t\t\t\tmarginLeftPx={paperPx.margin.left}\r\n\t\t\t\t\t\t\t\t\tmarginTopPx={paperPx.margin.top}\r\n\t\t\t\t\t\t\t\t\tonResizeStart={handleResizeStart}\r\n\t\t\t\t\t\t\t\t\tonResize={handleResize}\r\n\t\t\t\t\t\t\t\t\tonResizeEnd={handleResizeEnd}\r\n\t\t\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t\t);\r\n\t\t\t\t\t\t})}\r\n\t\t\t\t\t</>\r\n\t\t\t\t)}\r\n\r\n\t\t\t\t{/* レイヤー6: 寸法ラベル */}\r\n\t\t\t\t{showDimensionLabels && gridDimensions && (\r\n\t\t\t\t\t<>\r\n\t\t\t\t\t\t{/* 列の寸法ラベル */}\r\n\t\t\t\t\t\t{gridDimensions.cols.map((dimension, index) => {\r\n\t\t\t\t\t\t\t// 隣接する2つのグリッド線の中央位置を計算\r\n\t\t\t\t\t\t\tconst startPos = gridPosPxs.cols[index];\r\n\t\t\t\t\t\t\tconst endPos = gridPosPxs.cols[index + 1];\r\n\t\t\t\t\t\t\tif (startPos === undefined || endPos === undefined) return null;\r\n\r\n\t\t\t\t\t\t\t// ドラッグ中の隣接ラベルかどうか判定\r\n\t\t\t\t\t\t\tconst isDraggingAdjacentColumn =\r\n\t\t\t\t\t\t\t\tdraggingHandle?.direction === \"column\" &&\r\n\t\t\t\t\t\t\t\t(draggingHandle.index === index ||\r\n\t\t\t\t\t\t\t\t\tdraggingHandle.index === index + 1);\r\n\r\n\t\t\t\t\t\t\t// リサイズ中のプレビューサイズを取得\r\n\t\t\t\t\t\t\tlet resizingPxSize: number | undefined;\r\n\t\t\t\t\t\t\tif (\r\n\t\t\t\t\t\t\t\tresizingPreviewSizes &&\r\n\t\t\t\t\t\t\t\tresizingPreviewSizes.direction === \"column\"\r\n\t\t\t\t\t\t\t) {\r\n\t\t\t\t\t\t\t\tif (resizingPreviewSizes.prevIndex === index) {\r\n\t\t\t\t\t\t\t\t\tresizingPxSize = resizingPreviewSizes.prevSize;\r\n\t\t\t\t\t\t\t\t} else if (resizingPreviewSizes.nextIndex === index) {\r\n\t\t\t\t\t\t\t\t\tresizingPxSize = resizingPreviewSizes.nextSize;\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t\tconst centerPos = (startPos + endPos) / 2;\r\n\t\t\t\t\t\t\tconst currentPxSize = endPos - startPos;\r\n\t\t\t\t\t\t\tconst key = `col-dim-${index}`;\r\n\r\n\t\t\t\t\t\t\treturn (\r\n\t\t\t\t\t\t\t\t<GridDimensionLabel\r\n\t\t\t\t\t\t\t\t\tkey={key}\r\n\t\t\t\t\t\t\t\t\tdirection=\"column\"\r\n\t\t\t\t\t\t\t\t\tindex={index}\r\n\t\t\t\t\t\t\t\t\tdimension={dimension}\r\n\t\t\t\t\t\t\t\t\tposition={centerPos}\r\n\t\t\t\t\t\t\t\t\tcurrentPxSize={currentPxSize}\r\n\t\t\t\t\t\t\t\t\tmarginLeftPx={paperPx.margin.left}\r\n\t\t\t\t\t\t\t\t\tmarginTopPx={paperPx.margin.top}\r\n\t\t\t\t\t\t\t\t\tisNearCursor={\r\n\t\t\t\t\t\t\t\t\t\tshouldShowDimensionLabels || isDraggingAdjacentColumn\r\n\t\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t\tresizingPxSize={resizingPxSize}\r\n\t\t\t\t\t\t\t\t\tonDimensionChange={onDimensionChange}\r\n\t\t\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t\t);\r\n\t\t\t\t\t\t})}{\" \"}\r\n\t\t\t\t\t\t{/* 行の寸法ラベル */}\r\n\t\t\t\t\t\t{gridDimensions.rows.map((dimension, index) => {\r\n\t\t\t\t\t\t\t// 隣接する2つのグリッド線の中央位置を計算\r\n\t\t\t\t\t\t\tconst startPos = gridPosPxs.rows[index];\r\n\t\t\t\t\t\t\tconst endPos = gridPosPxs.rows[index + 1];\r\n\t\t\t\t\t\t\tif (startPos === undefined || endPos === undefined) return null;\r\n\r\n\t\t\t\t\t\t\t// ドラッグ中の隣接ラベルかどうか判定\r\n\t\t\t\t\t\t\tconst isDraggingAdjacentRow =\r\n\t\t\t\t\t\t\t\tdraggingHandle?.direction === \"row\" &&\r\n\t\t\t\t\t\t\t\t(draggingHandle.index === index ||\r\n\t\t\t\t\t\t\t\t\tdraggingHandle.index === index + 1);\r\n\r\n\t\t\t\t\t\t\tconst centerPos = (startPos + endPos) / 2;\r\n\t\t\t\t\t\t\tconst currentPxSize = endPos - startPos;\r\n\t\t\t\t\t\t\tconst key = `row-dim-${index}`;\r\n\r\n\t\t\t\t\t\t\treturn (\r\n\t\t\t\t\t\t\t\t<GridDimensionLabel\r\n\t\t\t\t\t\t\t\t\tkey={key}\r\n\t\t\t\t\t\t\t\t\tdirection=\"row\"\r\n\t\t\t\t\t\t\t\t\tindex={index}\r\n\t\t\t\t\t\t\t\t\tdimension={dimension}\r\n\t\t\t\t\t\t\t\t\tposition={centerPos}\r\n\t\t\t\t\t\t\t\t\tcurrentPxSize={currentPxSize}\r\n\t\t\t\t\t\t\t\t\tmarginLeftPx={paperPx.margin.left}\r\n\t\t\t\t\t\t\t\t\tmarginTopPx={paperPx.margin.top}\r\n\t\t\t\t\t\t\t\t\tisNearCursor={\r\n\t\t\t\t\t\t\t\t\t\tshouldShowDimensionLabels || isDraggingAdjacentRow\r\n\t\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t\tonDimensionChange={onDimensionChange}\r\n\t\t\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t\t);\r\n\t\t\t\t\t\t})}\r\n\t\t\t\t\t</>\r\n\t\t\t\t)}\r\n\r\n\t\t\t\t{/* レイヤー7: ゴースト線 (ドラッグ中の予覧) */}\r\n\t\t\t\t{ghostLine && (\r\n\t\t\t\t\t<div\r\n\t\t\t\t\t\tstyle={{\r\n\t\t\t\t\t\t\tposition: \"absolute\",\r\n\t\t\t\t\t\t\tleft:\r\n\t\t\t\t\t\t\t\tghostLine.direction === \"column\"\r\n\t\t\t\t\t\t\t\t\t? paperPx.margin.left + ghostLine.position\r\n\t\t\t\t\t\t\t\t\t: paperPx.margin.left,\r\n\t\t\t\t\t\t\ttop:\r\n\t\t\t\t\t\t\t\tghostLine.direction === \"row\"\r\n\t\t\t\t\t\t\t\t\t? paperPx.margin.top + ghostLine.position\r\n\t\t\t\t\t\t\t\t\t: paperPx.margin.top,\r\n\t\t\t\t\t\t\twidth:\r\n\t\t\t\t\t\t\t\tghostLine.direction === \"column\"\r\n\t\t\t\t\t\t\t\t\t? \"2px\"\r\n\t\t\t\t\t\t\t\t\t: paperPx.content.width,\r\n\t\t\t\t\t\t\theight:\r\n\t\t\t\t\t\t\t\tghostLine.direction === \"row\" ? \"2px\" : paperPx.content.height,\r\n\t\t\t\t\t\t\tbackgroundColor: \"#3b82f6\",\r\n\t\t\t\t\t\t\topacity: 0.5,\r\n\t\t\t\t\t\t\tpointerEvents: \"none\",\r\n\t\t\t\t\t\t\tzIndex: Z_INDEX.GRID_GHOST,\r\n\t\t\t\t\t\t}}\r\n\t\t\t\t\t/>\r\n\t\t\t\t)}\r\n\t\t\t</div>\r\n\t\t);\r\n\t},\r\n);\r\n","/**\r\n * GlobalDragStore\r\n *\r\n * Palette → Canvas 間のドラッグ&ドロップで使用するグローバル状態管理\r\n * 「現在ドラッグ中のアイテム」を保持し、NoteFormが必要に応じて参照する\r\n *\r\n * ## 使用方法\r\n *\r\n * ### Palette側 (ホストアプリ)\r\n * ```tsx\r\n * const handlePointerDown = (e: React.PointerEvent) => {\r\n * globalDragStore.start('text', { w: 200, h: 100 });\r\n *\r\n * const handleWindowUp = () => {\r\n * globalDragStore.end();\r\n * window.removeEventListener('pointerup', handleWindowUp);\r\n * };\r\n * window.addEventListener('pointerup', handleWindowUp);\r\n * };\r\n * ```\r\n *\r\n * ### NoteForm側 (core)\r\n * ```tsx\r\n * const handlePointerEnter = () => {\r\n * const item = globalDragStore.get();\r\n * if (item) {\r\n * handleInteractionChange({\r\n * type: InteractionEventType.START_INSERT,\r\n * pluginKind: item.kind,\r\n * defaultSize: item.defaultSize,\r\n * });\r\n * }\r\n * };\r\n * ```\r\n */\r\n\r\n/**\r\n * ドラッグ中のアイテム情報\r\n */\r\nexport type DragState = {\r\n\t/** プラグインの種類 (例: 'text', 'image') */\r\n\tkind: string;\r\n\t/** デフォルトサイズ (グリッド単位) */\r\n\tdefaultSize: { w: number; h: number };\r\n} | null;\r\n\r\n/**\r\n * 状態変化を監視するリスナー関数\r\n */\r\ntype Listener = (state: DragState) => void;\r\n\r\n/**\r\n * グローバルドラッグストア\r\n * シングルトンパターンで実装\r\n */\r\nclass GlobalDragStore {\r\n\tprivate state: DragState = null;\r\n\tprivate listeners: Listener[] = [];\r\n\r\n\t/**\r\n\t * ドラッグ開始\r\n\t * Paletteから呼ばれる\r\n\t *\r\n\t * @param kind プラグインの種類\r\n\t * @param defaultSize デフォルトサイズ (グリッド単位)\r\n\t */\r\n\tstart(kind: string, defaultSize: { w: number; h: number }): void {\r\n\t\tthis.state = { kind, defaultSize };\r\n\t\tthis.notify();\r\n\t}\r\n\r\n\t/**\r\n\t * ドラッグ終了\r\n\t * window.pointerup で呼ばれる\r\n\t */\r\n\tend(): void {\r\n\t\tthis.state = null;\r\n\t\tthis.notify();\r\n\t}\r\n\r\n\t/**\r\n\t * 現在の状態を取得\r\n\t * NoteFormのonPointerEnterから呼ばれる\r\n\t *\r\n\t * @returns 現在ドラッグ中のアイテム (なければ null)\r\n\t */\r\n\tget(): DragState {\r\n\t\treturn this.state;\r\n\t}\r\n\r\n\t/**\r\n\t * 状態変化を監視\r\n\t * (現在は使用していないが、将来的なデバッグ用に実装)\r\n\t *\r\n\t * @param listener 状態変化時に呼ばれる関数\r\n\t * @returns アンサブスクライブ関数\r\n\t */\r\n\tsubscribe(listener: Listener): () => void {\r\n\t\tthis.listeners.push(listener);\r\n\t\treturn () => {\r\n\t\t\tthis.listeners = this.listeners.filter((l) => l !== listener);\r\n\t\t};\r\n\t}\r\n\r\n\t/**\r\n\t * 全リスナーに状態変化を通知\r\n\t */\r\n\tprivate notify(): void {\r\n\t\tfor (const listener of this.listeners) {\r\n\t\t\tlistener(this.state);\r\n\t\t}\r\n\t}\r\n}\r\n\r\n/**\r\n * グローバルドラッグストアのシングルトンインスタンス\r\n */\r\nexport const globalDragStore = new GlobalDragStore();\r\n","/**\r\n * @file calculateGridResize.ts\r\n * @description グリッドリサイズ時のDimension計算ロジック\r\n */\r\n\r\nimport { toMm, toPx } from \"@/utils/convert\";\r\n\r\nimport type { Dimension, GridUnit } from \"@/types/unit\";\r\n\r\n/**\r\n * px単位でのデルタ値をGridDimensionに反映\r\n *\r\n * @param dimensions - 現在のDimension配列\r\n * @param index - リサイズするグリッドのインデックス\r\n * @param deltaPx - ピクセル単位での変更量\r\n * @param totalContentPx - コンテンツ全体のサイズ(px)\r\n * @returns 更新されたDimension配列\r\n */\r\nexport function calculateGridResize(\r\n\tdimensions: Dimension<GridUnit>[],\r\n\tindex: number,\r\n\tdeltaPx: number,\r\n\ttotalContentPx: number,\r\n): Dimension<GridUnit>[] {\r\n\t// インデックスの範囲チェック\r\n\tif (index < 0 || index >= dimensions.length) {\r\n\t\treturn dimensions;\r\n\t}\r\n\r\n\tconst newDimensions = [...dimensions];\r\n\tconst current = newDimensions[index];\r\n\tconst next = newDimensions[index + 1];\r\n\r\n\tif (!current || !next) {\r\n\t\treturn dimensions;\r\n\t}\r\n\r\n\t// ケース1: 両方がfr単位\r\n\tif (current.unit === \"fr\" && next.unit === \"fr\") {\r\n\t\treturn resizeFrPair(newDimensions, index, deltaPx, totalContentPx);\r\n\t}\r\n\r\n\t// ケース2: 両方が固定単位\r\n\tif (current.unit !== \"fr\" && next.unit !== \"fr\") {\r\n\t\treturn resizeFixedPair(newDimensions, index, deltaPx);\r\n\t}\r\n\r\n\t// ケース3: frと固定単位の混在\r\n\t// frは変えず、固定単位だけ調整\r\n\tif (current.unit === \"fr\" && next.unit !== \"fr\") {\r\n\t\t// currentはfr、nextは固定値\r\n\t\treturn resizeFrAndFixed(\r\n\t\t\tnewDimensions,\r\n\t\t\tindex,\r\n\t\t\tdeltaPx,\r\n\t\t\t\"next\",\r\n\t\t\ttotalContentPx,\r\n\t\t);\r\n\t} else {\r\n\t\t// currentは固定値、nextはfr\r\n\t\treturn resizeFrAndFixed(\r\n\t\t\tnewDimensions,\r\n\t\t\tindex,\r\n\t\t\tdeltaPx,\r\n\t\t\t\"current\",\r\n\t\t\ttotalContentPx,\r\n\t\t);\r\n\t}\r\n}\r\n\r\n/**\r\n * 両方がfr単位の場合のリサイズ\r\n */\r\nfunction resizeFrPair(\r\n\tdimensions: Dimension<GridUnit>[],\r\n\tindex: number,\r\n\tdeltaPx: number,\r\n\ttotalContentPx: number,\r\n): Dimension<GridUnit>[] {\r\n\tconst current = dimensions[index];\r\n\tconst next = dimensions[index + 1];\r\n\tif (!current || !next) return dimensions;\r\n\r\n\t// 現在のfr値の合計を計算\r\n\tconst totalFr = dimensions.reduce(\r\n\t\t(sum, dim) => (dim.unit === \"fr\" ? sum + dim.value : sum),\r\n\t\t0,\r\n\t);\r\n\r\n\t// px単位での現在のサイズを計算\r\n\tconst frToPx = totalContentPx / totalFr;\r\n\tconst currentPx = current.value * frToPx;\r\n\tconst nextPx = next.value * frToPx;\r\n\r\n\t// 新しいサイズを計算\r\n\tconst newCurrentPx = Math.max(10, currentPx + deltaPx);\r\n\tconst newNextPx = Math.max(10, nextPx - deltaPx);\r\n\r\n\t// frに変換\r\n\tconst newCurrentFr = newCurrentPx / frToPx;\r\n\tconst newNextFr = newNextPx / frToPx;\r\n\r\n\t// 小数第2位まで丸める\r\n\tdimensions[index] = {\r\n\t\t...current,\r\n\t\tvalue: Math.round(newCurrentFr * 100) / 100,\r\n\t};\r\n\tdimensions[index + 1] = {\r\n\t\t...next,\r\n\t\tvalue: Math.round(newNextFr * 100) / 100,\r\n\t};\r\n\r\n\treturn dimensions;\r\n}\r\n\r\n/**\r\n * 両方が固定単位の場合のリサイズ\r\n */\r\nfunction resizeFixedPair(\r\n\tdimensions: Dimension<GridUnit>[],\r\n\tindex: number,\r\n\tdeltaPx: number,\r\n): Dimension<GridUnit>[] {\r\n\tconst current = dimensions[index];\r\n\tconst next = dimensions[index + 1];\r\n\tif (!current || !next) return dimensions;\r\n\r\n\t// px値を取得\r\n\tconst currentPx = toPx.fromDim(current);\r\n\tconst nextPx = toPx.fromDim(next);\r\n\r\n\t// 新しいサイズを計算\r\n\tconst newCurrentPx = Math.max(10, currentPx + deltaPx);\r\n\tconst newNextPx = Math.max(10, nextPx - deltaPx);\r\n\r\n\t// 単位に応じて変換\r\n\tdimensions[index] = {\r\n\t\t...current,\r\n\t\tvalue: convertPxToUnit(newCurrentPx, current.unit),\r\n\t};\r\n\tdimensions[index + 1] = {\r\n\t\t...next,\r\n\t\tvalue: convertPxToUnit(newNextPx, next.unit),\r\n\t};\r\n\r\n\treturn dimensions;\r\n}\r\n\r\n/**\r\n * frと実寸値が混在する場合のリサイズ\r\n * 実寸値を変更し、frは現在のpx/fr比率から逆算して再計算\r\n */\r\nfunction resizeFrAndFixed(\r\n\tdimensions: Dimension<GridUnit>[],\r\n\tindex: number,\r\n\tdeltaPx: number,\r\n\tfixedSide: \"current\" | \"next\",\r\n\ttotalContentPx: number,\r\n): Dimension<GridUnit>[] {\r\n\tconst current = dimensions[index];\r\n\tconst next = dimensions[index + 1];\r\n\tif (!current || !next) return dimensions;\r\n\r\n\t// 全体のfr合計と固定値合計を計算\r\n\tlet totalFr = 0;\r\n\tlet totalFixedPx = 0;\r\n\r\n\tfor (const dim of dimensions) {\r\n\t\tif (dim.unit === \"fr\") {\r\n\t\t\ttotalFr += dim.value;\r\n\t\t} else {\r\n\t\t\ttotalFixedPx += toPx.fromDim(dim);\r\n\t\t}\r\n\t}\r\n\r\n\t// 現在のfr利用可能スペース\r\n\tconst availableForFrPx = totalContentPx - totalFixedPx;\r\n\tconst currentFrToPx = totalFr > 0 ? availableForFrPx / totalFr : 0;\r\n\r\n\tif (fixedSide === \"next\") {\r\n\t\t// nextが実寸値、currentはfr\r\n\t\tconst nextPx = toPx.fromDim(next);\r\n\t\tconst newNextPx = Math.max(10, nextPx - deltaPx);\r\n\r\n\t\t// nextの実寸値を更新\r\n\t\tdimensions[index + 1] = {\r\n\t\t\t...next,\r\n\t\t\tvalue: convertPxToUnit(newNextPx, next.unit),\r\n\t\t};\r\n\r\n\t\t// 固定値の変化量\r\n\t\tconst fixedDelta = newNextPx - nextPx;\r\n\r\n\t\t// frの利用可能スペースが変わる\r\n\t\tconst newAvailableForFrPx = availableForFrPx - fixedDelta;\r\n\r\n\t\t// currentのfrを、新しいpx値から逆算\r\n\t\tconst currentPx = current.value * currentFrToPx;\r\n\t\tconst newCurrentPx = Math.max(10, currentPx + deltaPx);\r\n\t\tconst newCurrentFr =\r\n\t\t\ttotalFr > 0 ? (newCurrentPx / newAvailableForFrPx) * totalFr : 1;\r\n\r\n\t\tdimensions[index] = {\r\n\t\t\t...current,\r\n\t\t\tvalue: Math.round(newCurrentFr * 100) / 100,\r\n\t\t};\r\n\t} else {\r\n\t\t// currentが実寸値、nextはfr\r\n\t\tconst currentPx = toPx.fromDim(current);\r\n\t\tconst newCurrentPx = Math.max(10, currentPx + deltaPx);\r\n\r\n\t\t// currentの実寸値を更新\r\n\t\tdimensions[index] = {\r\n\t\t\t...current,\r\n\t\t\tvalue: convertPxToUnit(newCurrentPx, current.unit),\r\n\t\t};\r\n\r\n\t\t// 固定値の変化量\r\n\t\tconst fixedDelta = newCurrentPx - currentPx;\r\n\r\n\t\t// frの利用可能スペースが変わる\r\n\t\tconst newAvailableForFrPx = availableForFrPx - fixedDelta;\r\n\r\n\t\t// nextのfrを、新しいpx値から逆算\r\n\t\tconst nextPx = next.value * currentFrToPx;\r\n\t\tconst newNextPx = Math.max(10, nextPx - deltaPx);\r\n\t\tconst newNextFr =\r\n\t\t\ttotalFr > 0 ? (newNextPx / newAvailableForFrPx) * totalFr : 1;\r\n\r\n\t\tdimensions[index + 1] = {\r\n\t\t\t...next,\r\n\t\t\tvalue: Math.round(newNextFr * 100) / 100,\r\n\t\t};\r\n\t}\r\n\r\n\treturn dimensions;\r\n}\r\n\r\n/**\r\n * px値を指定単位に変換\r\n */\r\nfunction convertPxToUnit(pxValue: number, unit: GridUnit): number {\r\n\tswitch (unit) {\r\n\t\tcase \"px\":\r\n\t\t\treturn Math.round(pxValue);\r\n\t\tcase \"mm\": {\r\n\t\t\tconst mm = toMm.fromPx(pxValue);\r\n\t\t\treturn Math.round(mm * 10) / 10;\r\n\t\t}\r\n\t\tcase \"cm\": {\r\n\t\t\tconst mm = toMm.fromPx(pxValue);\r\n\t\t\treturn Math.round((mm / 10) * 100) / 100;\r\n\t\t}\r\n\t\tcase \"inch\": {\r\n\t\t\tconst mm = toMm.fromPx(pxValue);\r\n\t\t\treturn Math.round((mm / 25.4) * 100) / 100;\r\n\t\t}\r\n\t\tcase \"pt\": {\r\n\t\t\tconst mm = toMm.fromPx(pxValue);\r\n\t\t\treturn Math.round((mm / 25.4) * 72 * 10) / 10;\r\n\t\t}\r\n\t\tcase \"fr\":\r\n\t\t\t// frの場合は変換しない\r\n\t\t\treturn 1;\r\n\t\tdefault: {\r\n\t\t\tconst _exhaustive: never = unit;\r\n\t\t\tthrow new Error(`Unsupported unit: ${_exhaustive}`);\r\n\t\t}\r\n\t}\r\n}\r\n","// 浮動小数点ピクセル配列を整数ピクセル配列に変換(累積誤差補正アルゴリズム)\r\n\r\nimport { assertNonNegative } from \"../assert\";\r\n\r\n/**\r\n * 浮動小数点のピクセル配列を整数ピクセル配列に変換します。\r\n *\r\n * Bresenhamアルゴリズムに基づく累積誤差補正により、\r\n * 境界位置(prefix sum)のズレを最小化します。\r\n * これにより視覚的なバランスが保たれ、ピクセルギャップを防ぎます。\r\n *\r\n * @example\r\n * // 767px ÷ 3 = 255.666...\r\n * distributeRemainder([255.666, 255.666, 255.666])\r\n * // → [256, 255, 256] (合計767px、累積誤差を均等に分散)\r\n *\r\n * @example\r\n * // 100px ÷ 3 = 33.333...\r\n * distributeRemainder([33.333, 33.333, 33.333])\r\n * // → [33, 34, 33] (合計100px、累積誤差を補正)\r\n *\r\n * @param floatPixels - 浮動小数点のピクセル値配列\r\n * @returns 整数のピクセル値配列(合計値は元の合計を四捨五入した値と一致)\r\n *\r\n * @see https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm\r\n * @see Zen Grids - Responsive Design's Dirty Little Secret\r\n */\r\nexport function distributeRemainder(floatPixels: number[]): number[] {\r\n\tif (floatPixels.length === 0) {\r\n\t\treturn [];\r\n\t}\r\n\r\n\tconst result: number[] = [];\r\n\tlet accumulatedError = 0;\r\n\r\n\tfor (const px of floatPixels) {\r\n\t\tassertNonNegative(px, \"Pixel value\");\r\n\r\n\t\t// 1. 誤差を含めた目標値を計算\r\n\t\tconst target = px + accumulatedError;\r\n\r\n\t\t// 2. 四捨五入で整数化\r\n\t\tconst rounded = Math.round(target);\r\n\r\n\t\t// 3. 結果に追加\r\n\t\tresult.push(rounded);\r\n\r\n\t\t// 4. 新たな誤差を計算(目標値 - 実際の値)\r\n\t\taccumulatedError = target - rounded;\r\n\t}\r\n\r\n\treturn result;\r\n}\r\n","// 現在のpx値からグリッドインデックスを取得するユーティリティ関数\r\n// 正直過剰実装気味かも\r\n\r\n// ここらへんは経験的な値、調整の余地あり\r\n// 一般的にステップ数は8〜32の間、らしい(多いのは16)\r\nconst MIN_STEP = 8;\r\nconst MAX_STEP = 32;\r\n\r\n// 大きく動いたとみなすpx値\r\nconst MIN_WINDOW_PX = 64;\r\nconst MAX_WINDOW_PX = 512;\r\n\r\nconst _clamp = (x: number, lo: number, hi: number): number => {\r\n\treturn Math.min(Math.max(x, lo), hi);\r\n};\r\n\r\n// fingerSearchから二分探索に切り替える歩数と領域を取得する関数\r\n// useMemoでキャッシュして使うことを想定\r\nexport function getMaxStep(starts: number[]): {\r\n\treadonly step: number;\r\n\treadonly windowPx: number;\r\n} {\r\n\tconst count = starts.length - 1;\r\n\tconst total = count >= 1 ? (starts[count] ?? 0) : 0;\r\n\tconst avg = starts.length >= 1 ? total / count : 0;\r\n\r\n\t// 現在位置からたどる最大ステップ\r\n\tconst step = _clamp(Math.ceil(Math.log2(count + 1)), MIN_STEP, MAX_STEP);\r\n\r\n\t// 小さい幅のグリッドがたくさん並ぶほど窓を小さくし、二分探索に早く切り替える\r\n\tconst windowPx = _clamp(avg * 2, MIN_WINDOW_PX, MAX_WINDOW_PX);\r\n\r\n\treturn { step, windowPx };\r\n}\r\n\r\n// 整列済み配列に対する二分探索\r\nexport function binarySearch(num: number, arr: readonly number[]): number {\r\n\tconst cnt = arr.length - 1;\r\n\tif (cnt <= 0) return -1;\r\n\tif (arr[0] === undefined || num < arr[0]) return -1;\r\n\tif (arr[cnt] === undefined) return -1;\r\n\tif (num >= arr[cnt]) return cnt - 1;\r\n\r\n\tlet lo = 1;\r\n\tlet hi = cnt;\r\n\twhile (lo <= hi) {\r\n\t\tconst mid = (lo + hi) >>> 1;\r\n\t\tconst midValue = arr[mid];\r\n\t\tif (midValue === undefined) {\r\n\t\t\thi = mid - 1;\r\n\t\t\tcontinue;\r\n\t\t}\r\n\t\tif (midValue <= num) {\r\n\t\t\tlo = mid + 1;\r\n\t\t} else {\r\n\t\t\thi = mid - 1;\r\n\t\t}\r\n\t}\r\n\treturn lo - 1;\r\n}\r\n\r\n// finger search + 二分探索によるグリッドインデックス探索\r\nexport function findGridIndex(\r\n\tstarts: readonly number[],\r\n\tmaxStep: number,\r\n\twindowPx: number,\r\n): (px: number) => number {\r\n\tconst cnt = starts.length - 1;\r\n\tlet last = 0;\r\n\r\n\treturn (px: number) => {\r\n\t\t// 前提\r\n\t\tif (cnt <= 0) return -1;\r\n\t\tif (starts[0] === undefined || px < starts[0]) return -1;\r\n\t\tif (starts[cnt] === undefined) return -1;\r\n\t\tif (px >= starts[cnt]) return cnt - 1;\r\n\r\n\t\t// 同じ位置ならキャッシュを使う\r\n\t\tconst startValue = starts[last];\r\n\t\tconst nextValue = starts[last + 1];\r\n\t\tif (startValue === undefined || nextValue === undefined) {\r\n\t\t\treturn -1;\r\n\t\t}\r\n\t\tif (startValue <= px && px < nextValue) return last;\r\n\r\n\t\t// 大ジャンプ判定(windowPx超え)\r\n\t\tconst leftPx = startValue - windowPx;\r\n\t\tconst rightPx = nextValue + windowPx;\r\n\t\tif (px < leftPx || px >= rightPx) {\r\n\t\t\t// 二分探索に切り替え\r\n\t\t\tlast = binarySearch(px, starts);\r\n\t\t\treturn last;\r\n\t\t}\r\n\r\n\t\t// finger search(近い所から順にたどる)\r\n\t\tlet steps = 0;\r\n\t\tconst nextStart = starts[last + 1];\r\n\t\tif (nextStart !== undefined && px >= nextStart) {\r\n\t\t\t// 右方向\r\n\t\t\twhile (last + 1 < cnt) {\r\n\t\t\t\tconst next = starts[last + 1];\r\n\t\t\t\tif (next === undefined || px < next) break;\r\n\t\t\t\tlast++;\r\n\t\t\t\tif (++steps > maxStep) {\r\n\t\t\t\t\tlast = binarySearch(px, starts);\r\n\t\t\t\t\treturn last;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\t// 左方向\r\n\t\t\twhile (last > 0) {\r\n\t\t\t\tconst current = starts[last];\r\n\t\t\t\tif (current === undefined || px >= current) break;\r\n\t\t\t\tlast--;\r\n\t\t\t\tif (++steps > maxStep) {\r\n\t\t\t\t\tlast = binarySearch(px, starts);\r\n\t\t\t\t\treturn last;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn last;\r\n\t};\r\n}\r\n","// 複数の単位が混在するグリッド寸法配列をmm配列に変換するユーティリティ関数\r\n\r\nimport { assertNonNegative, assertRange } from \"../assert\";\r\nimport { toMm } from \"../convert\";\r\n\r\nimport type { Dimension, GridUnit } from \"@/types/unit\";\r\n\r\n// グリッド寸法配列をmm配列に変換する関数\r\nexport function gridToMms(\r\n\tdims: Dimension<GridUnit>[],\r\n\tcontentSizeMm: number,\r\n): number[] {\r\n\t// 入力値チェック\r\n\tif (dims.length === 0) return [];\r\n\tassertNonNegative(contentSizeMm, \"Content size\");\r\n\r\n\t// 各要素をmmに変換、frはnullに置き換え\r\n\tlet totalFr = 0;\r\n\tlet fixedTotalMm = 0;\r\n\r\n\tconst mmsWithoutFr: (number | null)[] = dims.map((dim) => {\r\n\t\tassertNonNegative(dim.value, `Grid dimension value`);\r\n\t\tif (dim.unit === \"fr\") {\r\n\t\t\ttotalFr += dim.value;\r\n\t\t\treturn null;\r\n\t\t} else {\r\n\t\t\tconst mm = toMm.fromDim(dim);\r\n\t\t\tfixedTotalMm += mm;\r\n\t\t\treturn mm;\r\n\t\t}\r\n\t});\r\n\r\n\t// frがない場合はそのまま返す\r\n\tif (totalFr === 0) {\r\n\t\tassertRange(fixedTotalMm, 0, contentSizeMm, \"Total fixed size\");\r\n\t\treturn mmsWithoutFr as number[];\r\n\t}\r\n\r\n\t// 残りのサイズを計算\r\n\tconst remainingMm = contentSizeMm - fixedTotalMm;\r\n\tassertNonNegative(remainingMm, \"Content size - fixed sizes\");\r\n\r\n\t// 1frあたりのサイズを計算\r\n\tconst mmPerFr = remainingMm / totalFr;\r\n\r\n\t// frをmmに変換して最終結果を作成\r\n\treturn mmsWithoutFr.map((val, i) => {\r\n\t\tconst dim = dims[i];\r\n\t\tif (val !== null && val !== undefined) return val;\r\n\t\tif (!dim) throw new Error(`dims[${i}] is undefined`);\r\n\t\treturn dim.value * mmPerFr;\r\n\t});\r\n}\r\n","// mm単位をpx単位に変換(剰余配布あり)\r\n\r\nimport { assertInteger, assertPositive } from \"../assert/number\";\r\nimport { toPx } from \"../convert\";\r\nimport { distributeRemainder } from \"./distributeRemainder\";\r\n\r\n// mm単位の数字配列をpx単位の数字配列に変換\r\nexport function mmsToPxs(mms: number[], dpi: number = 96): number[] {\r\n\t// 入力値チェック\r\n\tassertPositive(dpi, \"DPI\");\r\n\tassertInteger(dpi, \"DPI\");\r\n\r\n\t// mm配列をpx配列に変換(一旦float許容)\r\n\tconst gridPxsFloat = mms.map((mm) => toPx.fromMm(mm, dpi));\r\n\r\n\t// float配列を整数配列に変換(剰余配布あり)\r\n\tconst gridPxs = distributeRemainder(gridPxsFloat);\r\n\r\n\treturn gridPxs;\r\n}\r\n","// 複数の単位が混在するグリッド寸法配列をピクセル単位の整数配列に変換するユーティリティ関数\r\n\r\nimport {\r\n\tassertInteger,\r\n\tassertNonNegative,\r\n\tassertPositive,\r\n} from \"../assert/number\";\r\nimport { gridToMms } from \"./gridToMms\";\r\nimport { mmsToPxs } from \"./mmsToPxs\";\r\n\r\nimport type { Dimension, GridUnit } from \"@/types\";\r\n\r\nexport function gridToPxs(\r\n\tdims: Dimension<GridUnit>[],\r\n\tcontentSizeMm: number,\r\n\tdpi: number,\r\n): number[] {\r\n\t// 入力値チェック\r\n\tif (dims.length === 0) return [];\r\n\tassertPositive(dpi, \"DPI\");\r\n\tassertInteger(dpi, \"DPI\");\r\n\tassertNonNegative(contentSizeMm, \"Content size\");\r\n\r\n\t// グリッド寸法配列をmm配列に変換\r\n\tconst mms = gridToMms(dims, contentSizeMm);\r\n\r\n\t// mm配列をpx配列に変換\r\n\treturn mmsToPxs(mms, dpi);\r\n}\r\n","/**\r\n * @file objectUtils.ts\r\n * @description オブジェクト操作のユーティリティ関数\r\n */\r\n\r\n/**\r\n * オブジェクトからundefined/nullプロパティを再帰的に削除する\r\n * 空オブジェクト{}は保持される(削除指示として重要)\r\n */\r\nexport function removeUndefinedProps<T extends Record<string, unknown>>(\r\n\tobj: T,\r\n): T {\r\n\tconst result: Record<string, unknown> = {};\r\n\r\n\tfor (const [key, value] of Object.entries(obj)) {\r\n\t\tif (value === undefined || value === null) {\r\n\t\t\t// undefined/null は削除(resultに含めない)\r\n\t\t\tcontinue;\r\n\t\t}\r\n\r\n\t\tif (typeof value === \"object\" && !Array.isArray(value) && value !== null) {\r\n\t\t\t// ネストしたオブジェクトを再帰的に処理\r\n\t\t\tconst cleaned = removeUndefinedProps(value as Record<string, unknown>);\r\n\t\t\t// 空オブジェクトも保持する(削除指示として重要)\r\n\t\t\tresult[key] = cleaned;\r\n\t\t} else {\r\n\t\t\t// プリミティブ値や配列はそのまま保持\r\n\t\t\tresult[key] = value;\r\n\t\t}\r\n\t}\r\n\r\n\treturn result as T;\r\n}\r\n","/**\r\n * @file utils/print/index.ts\r\n * @description 印刷機能のユーティリティ\r\n */\r\n\r\nimport type { Orientation, PrintPaperSize } from \"@/types/print\";\r\n\r\n/**\r\n * 用紙サイズの寸法を取得(mm単位)\r\n */\r\nexport function getPaperSize(\r\n\tpaperSize: PrintPaperSize,\r\n\torientation: Orientation,\r\n): { width: number; height: number } {\r\n\tconst sizes: Record<PrintPaperSize, { width: number; height: number }> = {\r\n\t\tA4: { width: 210, height: 297 },\r\n\t\tA3: { width: 297, height: 420 },\r\n\t\tB4: { width: 257, height: 364 },\r\n\t\tB5: { width: 182, height: 257 },\r\n\t\tLetter: { width: 215.9, height: 279.4 },\r\n\t\tLegal: { width: 215.9, height: 355.6 },\r\n\t};\r\n\r\n\tconst size = sizes[paperSize];\r\n\r\n\tif (orientation === \"landscape\") {\r\n\t\treturn { width: size.height, height: size.width };\r\n\t}\r\n\r\n\treturn size;\r\n}\r\n\r\n/**\r\n * 印刷前の準備処理\r\n */\r\nexport function preparePrint(options?: {\r\n\ttitle?: string;\r\n\tremoveScrollbars?: boolean;\r\n}): void {\r\n\tif (options?.title) {\r\n\t\tdocument.title = options.title;\r\n\t}\r\n\r\n\tif (options?.removeScrollbars) {\r\n\t\tdocument.body.style.overflow = \"hidden\";\r\n\t}\r\n}\r\n\r\n/**\r\n * 印刷後のクリーンアップ処理\r\n */\r\nexport function cleanupPrint(options?: { restoreScrollbars?: boolean }): void {\r\n\tif (options?.restoreScrollbars) {\r\n\t\tdocument.body.style.overflow = \"\";\r\n\t}\r\n}\r\n\r\n/**\r\n * 特定の要素だけを印刷\r\n * 非破壊的な方法: 一時的なクラスを使用して、CSSで他の要素を非表示化\r\n */\r\nexport function printElement(\r\n\telement: HTMLElement,\r\n\toptions?: {\r\n\t\ttitle?: string;\r\n\t\tonBeforePrint?: () => void;\r\n\t\tonAfterPrint?: () => void;\r\n\t},\r\n): void {\r\n\tconst originalTitle = document.title;\r\n\r\n\t// 印刷用の一時的なスタイル要素を作成\r\n\tconst printStyle = document.createElement(\"style\");\r\n\tprintStyle.id = \"tatamicks-print-style\";\r\n\tprintStyle.textContent = `\r\n\t\t@media print {\r\n\t\t\t/* bodyとhtmlのマージン・パディングをリセット */\r\n\t\t\thtml, body {\r\n\t\t\t\tmargin: 0 !important;\r\n\t\t\t\tpadding: 0 !important;\r\n\t\t\t\twidth: 100% !important;\r\n\t\t\t\theight: 100% !important;\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\t/* すべての要素を非表示 */\r\n\t\t\tbody * {\r\n\t\t\t\tvisibility: hidden !important;\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\t/* 印刷対象の要素とその子孫を表示 */\r\n\t\t\t.tatamicks-print-target,\r\n\t\t\t.tatamicks-print-target * {\r\n\t\t\t\tvisibility: visible !important;\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\t/* 印刷対象の要素を左上に固定 */\r\n\t\t\t.tatamicks-print-target {\r\n\t\t\t\tposition: fixed !important;\r\n\t\t\t\tleft: 0 !important;\r\n\t\t\t\ttop: 0 !important;\r\n\t\t\t\tmargin: 0 !important;\r\n\t\t\t\tpadding: 0 !important;\r\n\t\t\t\ttransform: none !important;\r\n\t\t\t\t/* 親要素のスタイルを完全にオーバーライド */\r\n\t\t\t\tinset: 0 auto auto 0 !important;\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\t/* 背景色を印刷に含める */\r\n\t\t\t* {\r\n\t\t\t\t-webkit-print-color-adjust: exact !important;\r\n\t\t\t\tprint-color-adjust: exact !important;\r\n\t\t\t\tcolor-adjust: exact !important;\r\n\t\t\t}\r\n\t\t}\r\n\t`;\r\n\r\n\ttry {\r\n\t\t// スタイルを追加\r\n\t\tdocument.head.appendChild(printStyle);\r\n\r\n\t\t// 印刷対象の要素にクラスを追加\r\n\t\telement.classList.add(\"tatamicks-print-target\");\r\n\r\n\t\t// タイトル設定\r\n\t\tif (options?.title) {\r\n\t\t\tdocument.title = options.title;\r\n\t\t}\r\n\r\n\t\t// beforeprint コールバック\r\n\t\toptions?.onBeforePrint?.();\r\n\r\n\t\t// 印刷実行\r\n\t\twindow.print();\r\n\r\n\t\t// afterprint コールバック\r\n\t\toptions?.onAfterPrint?.();\r\n\t} finally {\r\n\t\t// クリーンアップ: クラスを削除\r\n\t\telement.classList.remove(\"tatamicks-print-target\");\r\n\r\n\t\t// スタイル要素を削除\r\n\t\tconst styleElement = document.getElementById(\"tatamicks-print-style\");\r\n\t\tif (styleElement) {\r\n\t\t\tstyleElement.remove();\r\n\t\t}\r\n\r\n\t\t// タイトルを復元\r\n\t\tdocument.title = originalTitle;\r\n\t}\r\n}\r\n\r\n/**\r\n * 印刷を実行(準備 + 印刷 + クリーンアップ)\r\n */\r\nexport function executePrint(options?: {\r\n\ttitle?: string;\r\n\tonBeforePrint?: () => void;\r\n\tonAfterPrint?: () => void;\r\n}): void {\r\n\t// 準備\r\n\tpreparePrint({ title: options?.title, removeScrollbars: true });\r\n\r\n\t// beforeprint イベント\r\n\tconst handleBeforePrint = () => {\r\n\t\toptions?.onBeforePrint?.();\r\n\t};\r\n\r\n\t// afterprint イベント\r\n\tconst handleAfterPrint = () => {\r\n\t\toptions?.onAfterPrint?.();\r\n\t\tcleanupPrint({ restoreScrollbars: true });\r\n\r\n\t\t// イベントリスナーを削除\r\n\t\twindow.removeEventListener(\"beforeprint\", handleBeforePrint);\r\n\t\twindow.removeEventListener(\"afterprint\", handleAfterPrint);\r\n\t};\r\n\r\n\t// イベントリスナーを登録\r\n\twindow.addEventListener(\"beforeprint\", handleBeforePrint);\r\n\twindow.addEventListener(\"afterprint\", handleAfterPrint);\r\n\r\n\t// 印刷実行\r\n\twindow.print();\r\n}\r\n","/**\r\n * @file validate.ts\r\n * @description スキーマのバリデーション機能\r\n */\r\n\r\nimport type { Block } from \"@/types/block\";\r\nimport type { Grid } from \"@/types/grid\";\r\nimport type { Paper } from \"@/types/paper\";\r\nimport type { FormSchema } from \"@/types/schema\";\r\nimport type { GridUnit } from \"@/types/unit\";\r\nimport type { Value } from \"@/types/value\";\r\n\r\n/**\r\n * 未知の値がBlockかどうかを型ガード\r\n */\r\nfunction isBlock(value: unknown): value is Block {\r\n\tif (typeof value !== \"object\" || value === null) return false;\r\n\r\n\tconst obj = value as Record<string, unknown>;\r\n\r\n\t// 必須プロパティのチェック\r\n\tif (typeof obj.id !== \"string\") return false;\r\n\tif (typeof obj.kind !== \"string\") return false;\r\n\r\n\t// layoutのチェック\r\n\tif (typeof obj.layout !== \"object\" || obj.layout === null) return false;\r\n\tconst layout = obj.layout as Record<string, unknown>;\r\n\tif (\r\n\t\ttypeof layout.x !== \"number\" ||\r\n\t\ttypeof layout.y !== \"number\" ||\r\n\t\ttypeof layout.w !== \"number\" ||\r\n\t\ttypeof layout.h !== \"number\"\r\n\t) {\r\n\t\treturn false;\r\n\t}\r\n\r\n\t// propsのチェック(存在する場合)\r\n\tif (obj.props !== undefined && typeof obj.props !== \"object\") {\r\n\t\treturn false;\r\n\t}\r\n\r\n\treturn true;\r\n}\r\n\r\n/**\r\n * 未知の値がGridUnitかどうかを型ガード\r\n */\r\nfunction isGridUnit(value: unknown): value is GridUnit {\r\n\treturn value === \"fr\" || value === \"px\" || value === \"%\";\r\n}\r\n\r\n/**\r\n * 未知の値がDimension配列かどうかを型ガード\r\n */\r\nfunction isDimensionArray(\r\n\tvalue: unknown,\r\n): value is Array<{ value: number; unit: GridUnit }> {\r\n\tif (!Array.isArray(value)) return false;\r\n\r\n\treturn value.every((item) => {\r\n\t\tif (typeof item !== \"object\" || item === null) return false;\r\n\t\tconst dim = item as Record<string, unknown>;\r\n\t\treturn typeof dim.value === \"number\" && isGridUnit(dim.unit);\r\n\t});\r\n}\r\n\r\n/**\r\n * 未知の値がGridかどうかを型ガード\r\n */\r\nfunction isGrid(value: unknown): value is Grid {\r\n\tif (typeof value !== \"object\" || value === null) return false;\r\n\r\n\tconst obj = value as Record<string, unknown>;\r\n\r\n\treturn isDimensionArray(obj.cols) && isDimensionArray(obj.rows);\r\n}\r\n\r\n/**\r\n * 未知の値がPaperかどうかを型ガード\r\n */\r\nfunction isPaper(value: unknown): value is Paper {\r\n\tif (typeof value !== \"object\" || value === null) return false;\r\n\r\n\tconst obj = value as Record<string, unknown>;\r\n\r\n\t// sizeのチェック\r\n\tif (typeof obj.size !== \"object\" || obj.size === null) return false;\r\n\tconst size = obj.size as Record<string, unknown>;\r\n\tif (typeof size.preset !== \"string\") return false;\r\n\r\n\t// size.widthのチェック (Dimension<PaperUnit>)\r\n\tif (typeof size.width !== \"object\" || size.width === null) return false;\r\n\tconst width = size.width as Record<string, unknown>;\r\n\tif (typeof width.value !== \"number\" || typeof width.unit !== \"string\") {\r\n\t\treturn false;\r\n\t}\r\n\r\n\t// size.heightのチェック (Dimension<PaperUnit>)\r\n\tif (typeof size.height !== \"object\" || size.height === null) return false;\r\n\tconst height = size.height as Record<string, unknown>;\r\n\tif (typeof height.value !== \"number\" || typeof height.unit !== \"string\") {\r\n\t\treturn false;\r\n\t}\r\n\r\n\t// marginのチェック\r\n\tif (typeof obj.margin !== \"object\" || obj.margin === null) return false;\r\n\tconst margin = obj.margin as Record<string, unknown>;\r\n\r\n\t// 各マージンがDimension<PaperUnit>かチェック\r\n\tfor (const key of [\"top\", \"right\", \"bottom\", \"left\"]) {\r\n\t\tconst marginSide = margin[key];\r\n\t\tif (typeof marginSide !== \"object\" || marginSide === null) return false;\r\n\t\tconst dim = marginSide as Record<string, unknown>;\r\n\t\tif (typeof dim.value !== \"number\" || typeof dim.unit !== \"string\") {\r\n\t\t\treturn false;\r\n\t\t}\r\n\t}\r\n\r\n\treturn true;\r\n}\r\n\r\n/**\r\n * 未知の値がValueかどうかを型ガード\r\n */\r\nfunction isValue(value: unknown): value is Value {\r\n\t// Valueは string | number | boolean | null | undefined | Record<string, unknown>\r\n\tif (value === null || value === undefined) return true;\r\n\tif (typeof value === \"string\") return true;\r\n\tif (typeof value === \"number\") return true;\r\n\tif (typeof value === \"boolean\") return true;\r\n\tif (typeof value === \"object\" && !Array.isArray(value)) return true;\r\n\r\n\treturn false;\r\n}\r\n\r\n/**\r\n * 未知の値がFormSchemaかどうかをバリデーションし、型安全に変換\r\n *\r\n * @param value - バリデーションする値\r\n * @returns FormSchema (バリデーション済み)\r\n * @throws バリデーションエラー時にエラーをスロー\r\n *\r\n * @example\r\n * ```ts\r\n * const unknownData = JSON.parse(jsonString);\r\n * const schema = validateSchema(unknownData);\r\n * ```\r\n */\r\nexport function validateSchema(value: unknown): FormSchema {\r\n\tif (typeof value !== \"object\" || value === null) {\r\n\t\tthrow new Error(\"Schema must be an object\");\r\n\t}\r\n\r\n\tconst obj = value as Record<string, unknown>;\r\n\r\n\t// paperのバリデーション\r\n\tif (!isPaper(obj.paper)) {\r\n\t\tthrow new Error(\"Invalid paper definition\");\r\n\t}\r\n\r\n\t// gridのバリデーション\r\n\tif (!isGrid(obj.grid)) {\r\n\t\tthrow new Error(\"Invalid grid definition\");\r\n\t}\r\n\r\n\t// blocksのバリデーション\r\n\tif (!Array.isArray(obj.blocks)) {\r\n\t\tthrow new Error(\"blocks must be an array\");\r\n\t}\r\n\r\n\tif (!obj.blocks.every(isBlock)) {\r\n\t\tthrow new Error(\"Invalid block definition in blocks array\");\r\n\t}\r\n\r\n\t// metaDataのバリデーション(オプション)\r\n\tif (obj.metaData !== undefined) {\r\n\t\tif (typeof obj.metaData !== \"object\" || obj.metaData === null) {\r\n\t\t\tthrow new Error(\"metaData must be an object if provided\");\r\n\t\t}\r\n\r\n\t\tconst metaData = obj.metaData as Record<string, unknown>;\r\n\t\tfor (const key in metaData) {\r\n\t\t\tif (!isValue(metaData[key])) {\r\n\t\t\t\tthrow new Error(`Invalid value in metaData.${key}`);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\treturn obj as unknown as FormSchema;\r\n}\r\n","/**\r\n * @file deserialize.ts\r\n * @description スキーマのデシリアライズ機能\r\n */\r\n\r\nimport { validateSchema } from \"./validate\";\r\n\r\nimport type { FormSchema } from \"@/types/schema\";\r\n\r\n/**\r\n * JSON文字列をFormSchemaにデシリアライズ\r\n *\r\n * @param json - デシリアライズするJSON文字列\r\n * @returns FormSchema (バリデーション済み)\r\n * @throws バリデーションエラー時にエラーをスロー\r\n *\r\n * @example\r\n * ```ts\r\n * const json = '{\"paper\": {...}, \"grid\": {...}, \"blocks\": [...]}';\r\n * const schema = deserializeSchema(json);\r\n * ```\r\n */\r\nexport function deserializeSchema(json: string): FormSchema {\r\n\ttry {\r\n\t\tconst parsed = JSON.parse(json);\r\n\t\treturn validateSchema(parsed);\r\n\t} catch (error) {\r\n\t\tif (error instanceof SyntaxError) {\r\n\t\t\tthrow new Error(`Invalid JSON format: ${error.message}`);\r\n\t\t}\r\n\t\tthrow error;\r\n\t}\r\n}\r\n","/**\r\n * @file serialize.ts\r\n * @description スキーマのシリアライズ機能\r\n */\r\n\r\nimport type { FormSchema } from \"@/types/schema\";\r\n\r\n/**\r\n * FormSchemaをJSON文字列にシリアライズ\r\n *\r\n * @param schema - シリアライズするスキーマ\r\n * @param pretty - 整形して出力するか (デフォルト: false)\r\n * @returns JSON文字列\r\n *\r\n * @example\r\n * ```ts\r\n * const schema: FormSchema = { ... };\r\n * const json = serializeSchema(schema);\r\n * // または整形版\r\n * const prettyJson = serializeSchema(schema, true);\r\n * ```\r\n */\r\nexport function serializeSchema(schema: FormSchema, pretty = false): string {\r\n\ttry {\r\n\t\treturn pretty ? JSON.stringify(schema, null, 2) : JSON.stringify(schema);\r\n\t} catch (error) {\r\n\t\tthrow new Error(\r\n\t\t\t`Failed to serialize schema: ${error instanceof Error ? error.message : \"Unknown error\"}`,\r\n\t\t);\r\n\t}\r\n}\r\n","/**\r\n * @file validate.ts\r\n * @description 入力値のバリデーション機能\r\n */\r\n\r\nimport type { Value } from \"@/types/value\";\r\n\r\n/**\r\n * 未知の値がValueかどうかを型ガード\r\n */\r\nfunction isValue(value: unknown): value is Value {\r\n\t// Valueは string | number | boolean | null | undefined | Record<string, unknown>\r\n\tif (value === null || value === undefined) return true;\r\n\tif (typeof value === \"string\") return true;\r\n\tif (typeof value === \"number\") return true;\r\n\tif (typeof value === \"boolean\") return true;\r\n\tif (typeof value === \"object\" && !Array.isArray(value)) {\r\n\t\t// オブジェクトの場合、再帰的にチェック\r\n\t\tconst obj = value as Record<string, unknown>;\r\n\t\treturn Object.values(obj).every(isValue);\r\n\t}\r\n\r\n\treturn false;\r\n}\r\n\r\n/**\r\n * 未知の値がRecord<string, Value>かどうかをバリデーションし、型安全に変換\r\n *\r\n * @param value - バリデーションする値\r\n * @returns Record<string, Value> (バリデーション済み)\r\n * @throws バリデーションエラー時にエラーをスロー\r\n *\r\n * @example\r\n * ```ts\r\n * const unknownData = JSON.parse(jsonString);\r\n * const values = validateValues(unknownData);\r\n * ```\r\n */\r\nexport function validateValues(value: unknown): Record<string, Value> {\r\n\tif (typeof value !== \"object\" || value === null) {\r\n\t\tthrow new Error(\"Values must be an object\");\r\n\t}\r\n\r\n\tif (Array.isArray(value)) {\r\n\t\tthrow new Error(\"Values must be an object, not an array\");\r\n\t}\r\n\r\n\tconst obj = value as Record<string, unknown>;\r\n\r\n\t// すべてのプロパティがValidなValueかチェック\r\n\tfor (const key in obj) {\r\n\t\tif (!isValue(obj[key])) {\r\n\t\t\tthrow new Error(`Invalid value at key \"${key}\"`);\r\n\t\t}\r\n\t}\r\n\r\n\treturn obj as Record<string, Value>;\r\n}\r\n","/**\r\n * @file deserialize.ts\r\n * @description 入力値のデシリアライズ機能\r\n */\r\n\r\nimport { validateValues } from \"./validate\";\r\n\r\nimport type { Value } from \"@/types/value\";\r\n\r\n/**\r\n * JSON文字列を入力値(values)にデシリアライズ\r\n *\r\n * @param json - デシリアライズするJSON文字列\r\n * @returns Record<string, Value> (バリデーション済み)\r\n * @throws バリデーションエラー時にエラーをスロー\r\n *\r\n * @example\r\n * ```ts\r\n * const json = '{\"block-1\": \"Hello\", \"block-2\": 42}';\r\n * const values = deserializeValues(json);\r\n * ```\r\n */\r\nexport function deserializeValues(json: string): Record<string, Value> {\r\n\ttry {\r\n\t\tconst parsed = JSON.parse(json);\r\n\t\treturn validateValues(parsed);\r\n\t} catch (error) {\r\n\t\tif (error instanceof SyntaxError) {\r\n\t\t\tthrow new Error(`Invalid JSON format: ${error.message}`);\r\n\t\t}\r\n\t\tthrow error;\r\n\t}\r\n}\r\n","/**\r\n * @file serialize.ts\r\n * @description 入力値のシリアライズ機能\r\n */\r\n\r\nimport type { Value } from \"@/types/value\";\r\n\r\n/**\r\n * 入力値(values)をJSON文字列にシリアライズ\r\n *\r\n * @param values - シリアライズする入力値\r\n * @param pretty - 整形して出力するか (デフォルト: false)\r\n * @returns JSON文字列\r\n *\r\n * @example\r\n * ```ts\r\n * const values: Record<string, Value> = {\r\n * 'block-1': 'Hello',\r\n * 'block-2': 42,\r\n * };\r\n * const json = serializeValues(values);\r\n * // または整形版\r\n * const prettyJson = serializeValues(values, true);\r\n * ```\r\n */\r\nexport function serializeValues(\r\n\tvalues: Record<string, Value>,\r\n\tpretty = false,\r\n): string {\r\n\ttry {\r\n\t\treturn pretty ? JSON.stringify(values, null, 2) : JSON.stringify(values);\r\n\t} catch (error) {\r\n\t\tthrow new Error(\r\n\t\t\t`Failed to serialize values: ${error instanceof Error ? error.message : \"Unknown error\"}`,\r\n\t\t);\r\n\t}\r\n}\r\n","import { type BorderStyle, LineType } from \"@/types/line\";\r\nimport { Z_INDEX } from \"@/utils\";\r\n\r\nimport type { ResizeHandleStyle } from \"./ResizeHandles\";\r\n\r\nexport const SELECTION_STYLE: BorderStyle = {\r\n\tall: {\r\n\t\tcolor: \"#3b82f688\",\r\n\t\twidth: { value: 4, unit: \"px\" },\r\n\t\ttype: LineType.SOLID,\r\n\t},\r\n};\r\n\r\nexport const RESIZE_HANDLE_STYLE: ResizeHandleStyle = {\r\n\tsize: 12,\r\n\tbackgroundColor: \"#ffffff\",\r\n\tborderColor: \"#3b82f6\",\r\n\tborderWidth: 1,\r\n\tborderRadius: \"50%\",\r\n};\r\n\r\nexport const interactionZIndexs = {\r\n\tbase: Z_INDEX.INTERACTION_LAYER_BASE,\r\n\tselect_block: Z_INDEX.SELECT_BLOCK,\r\n\tblock_ghost: Z_INDEX.BLOCK_GHOST,\r\n\thover_outline: Z_INDEX.HOVER_OUTLINE,\r\n\tedit_block: Z_INDEX.EDIT_BLOCK,\r\n\tgrid_ghost: Z_INDEX.GRID_GHOST,\r\n\tgrid_handles: Z_INDEX.GRID_HANDLES,\r\n\tselect_border: Z_INDEX.BLOCK_SELECT_BORDER,\r\n\tblock_handles: Z_INDEX.BLOCK_HANDLES,\r\n\trubber_band: Z_INDEX.RUBBER_BAND,\r\n} as const;\r\n","/**\r\n * インタラクションモード\r\n *\r\n * @remarks\r\n * インタラクション操作の状態を型安全に扱うための列挙型\r\n */\r\nexport enum InteractionMode {\r\n\t/** 待機状態 */\r\n\tIDLE = \"idle\",\r\n\t/** マウスダウン中(クリックかドラッグか判定前) */\r\n\tPRESSING = \"pressing\",\r\n\t/** ドラッグ確定 */\r\n\tDRAGGING = \"dragging\",\r\n\t/** 編集中 */\r\n\tEDITING = \"editing\",\r\n}\r\n\r\n/**\r\n * リサイズハンドル方向\r\n *\r\n * @remarks\r\n * 8方向のリサイズハンドルを型安全に扱うための列挙型\r\n */\r\nexport enum ResizeHandle {\r\n\t/** 北(上) */\r\n\tN = \"n\",\r\n\t/** 北東(右上) */\r\n\tNE = \"ne\",\r\n\t/** 東(右) */\r\n\tE = \"e\",\r\n\t/** 南東(右下) */\r\n\tSE = \"se\",\r\n\t/** 南(下) */\r\n\tS = \"s\",\r\n\t/** 南西(左下) */\r\n\tSW = \"sw\",\r\n\t/** 西(左) */\r\n\tW = \"w\",\r\n\t/** 北西(左上) */\r\n\tNW = \"nw\",\r\n}\r\n\r\n/**\r\n * ドラッグ種別\r\n *\r\n * @remarks\r\n * ドラッグ操作の種類を型安全に扱うための列挙型\r\n */\r\nexport enum DragType {\r\n\t/** ブロックの移動 */\r\n\tMOVE = \"move\",\r\n\t/** ブロックのリサイズ */\r\n\tRESIZE = \"resize\",\r\n\t/** 新規ブロックの挿入 */\r\n\tINSERT = \"insert\",\r\n}\r\n\r\n/**\r\n * インタラクション変更イベント種別\r\n *\r\n * @remarks\r\n * インタラクション変更イベントの種類を型安全に扱うための列挙型\r\n */\r\nexport enum InteractionEventType {\r\n\t/** ブロックを選択 */\r\n\tSELECT = \"select\",\r\n\t/** 選択を解除 */\r\n\tDESELECT = \"deselect\",\r\n\t/** プレス開始(ドラッグ判定前) */\r\n\tSTART_PRESS = \"startPress\",\r\n\t/** ドラッグ更新 */\r\n\tUPDATE_DRAG = \"updateDrag\",\r\n\t/** ドラッグ終了 */\r\n\tEND_DRAG = \"endDrag\",\r\n\t/** ドラッグキャンセル */\r\n\tCANCEL_DRAG = \"cancelDrag\",\r\n\t/** 編集開始 */\r\n\tEDIT = \"edit\",\r\n\t/** 編集終了 */\r\n\tEND_EDIT = \"endEdit\",\r\n\t/** 挿入開始 */\r\n\tSTART_INSERT = \"startInsert\",\r\n\t/** 挿入キャンセル */\r\n\tCANCEL_INSERT = \"cancelInsert\",\r\n\t/** リサイズ開始 */\r\n\tSTART_RESIZE = \"startResize\",\r\n}\r\n\r\n/**\r\n * ドラッグ状態の詳細情報\r\n */\r\nexport interface DraggingState {\r\n\t/** ドラッグ種別 */\r\n\ttype: DragType;\r\n\r\n\t/** ドラッグ対象のブロックID群 */\r\n\tblockIds: string[];\r\n\r\n\t/** 開始グリッド座標 */\r\n\tstartGrid: { col: number; row: number };\r\n\r\n\t/** 現在のグリッド座標 */\r\n\tcurrentGrid: { col: number; row: number };\r\n\r\n\t/** 現在のマウス座標 (px, キャンバス相対) - キャンバス外でのゴースト表示用 */\r\n\tcurrentMousePx?: { x: number; y: number };\r\n\r\n\t/** リサイズ用: ハンドル位置 */\r\n\thandle?: ResizeHandle;\r\n\r\n\t/** 挿入用: プラグイン種別 */\r\n\tpluginKind?: string;\r\n\r\n\t/** 挿入用: デフォルトサイズ */\r\n\tdefaultSize?: { w: number; h: number };\r\n\r\n\t/** キャンバス外フラグ (true: 範囲外でドロップすると削除) */\r\n\tisOutside?: boolean;\r\n}\r\n\r\n/**\r\n * インタラクション状態 (単一オブジェクト)\r\n *\r\n * @remarks\r\n * Pluginの `value` に相当する統合状態\r\n * 全ての操作状態をこのオブジェクト1つで管理する\r\n */\r\nexport interface InteractionState {\r\n\t/** 現在のモード */\r\n\tmode: InteractionMode;\r\n\r\n\t/** 選択中のブロックID群 */\r\n\tselectedBlockIds: string[];\r\n\r\n\t/** 編集中のブロックID (nullの場合は編集モードではない) */\r\n\teditingBlockId: string | null;\r\n\r\n\t/** ドラッグ中の状態 (ドラッグ中のみ有効) */\r\n\tdragging?: DraggingState;\r\n}\r\n\r\n/**\r\n * インタラクション変更イベント\r\n *\r\n * @remarks\r\n * OnBlockChangeと同じパターン (type付きUnion型)\r\n * 全ての操作をこのイベントで表現する\r\n */\r\nexport type InteractionChangeEvent =\r\n\t| {\r\n\t\t\ttype: InteractionEventType.SELECT;\r\n\t\t\tblockIds: string[];\r\n\t\t\tshiftKey?: boolean;\r\n\t }\r\n\t| { type: InteractionEventType.DESELECT }\r\n\t| {\r\n\t\t\ttype: InteractionEventType.START_PRESS;\r\n\t\t\tblockId: string;\r\n\t\t\tstartGrid: { col: number; row: number };\r\n\t\t\tselectedBlockIds?: string[]; // 複数選択時のドラッグ対象\r\n\t }\r\n\t| {\r\n\t\t\ttype: InteractionEventType.UPDATE_DRAG;\r\n\t\t\tcurrentGrid: { col: number; row: number };\r\n\t\t\tcurrentMousePx: { x: number; y: number };\r\n\t\t\tisOutside?: boolean;\r\n\t }\r\n\t| { type: InteractionEventType.END_DRAG }\r\n\t| { type: InteractionEventType.CANCEL_DRAG }\r\n\t| { type: InteractionEventType.EDIT; blockId: string }\r\n\t| { type: InteractionEventType.END_EDIT }\r\n\t| {\r\n\t\t\ttype: InteractionEventType.START_INSERT;\r\n\t\t\tpluginKind: string;\r\n\t\t\tdefaultSize: { w: number; h: number };\r\n\t }\r\n\t| { type: InteractionEventType.CANCEL_INSERT }\r\n\t| {\r\n\t\t\ttype: InteractionEventType.START_RESIZE;\r\n\t\t\tblockId: string;\r\n\t\t\thandle: ResizeHandle;\r\n\t\t\tstartGrid: { col: number; row: number };\r\n\t };\r\n\r\n/**\r\n * インタラクション変更コールバック\r\n *\r\n * @remarks\r\n * Pluginの `onChange` に相当\r\n * 全ての操作変更をこの1つのコールバックで処理する\r\n */\r\nexport type OnInteractionChange = (event: InteractionChangeEvent) => void;\r\n","/**\r\n * @file ResizeHandles.tsx\r\n * @description リサイズ用ハンドル(8方向)を描画するコンポーネント\r\n */\r\nimport { memo } from \"react\";\r\n\r\nimport { ResizeHandle } from \"../types\";\r\nimport { RESIZE_HANDLE_STYLE } from \"./constants\";\r\nimport styles from \"./InteractionBlock.module.css\";\r\n\r\nimport { Z_INDEX } from \"@/utils/zIndex\";\r\n\r\nimport type React from \"react\";\r\n\r\nexport interface ResizeHandleStyle {\r\n\tsize: number;\r\n\tbackgroundColor: string;\r\n\tborderColor: string;\r\n\tborderWidth: number;\r\n\tborderRadius: string;\r\n}\r\n\r\nexport interface ResizeHandlesProps {\r\n\tonResizeStart: (e: React.PointerEvent, handle: ResizeHandle) => void;\r\n\tactiveHandle?: ResizeHandle | null;\r\n\thandleStyle?: ResizeHandleStyle;\r\n\tzIndex?: number;\r\n}\r\n\r\n// ハンドル定義(位置とカーソル)\r\nconst HANDLES = [\r\n\t{ id: ResizeHandle.NW, cursor: \"nwse-resize\", x: 0, y: 0 },\r\n\t{ id: ResizeHandle.N, cursor: \"ns-resize\", x: 50, y: 0 },\r\n\t{ id: ResizeHandle.NE, cursor: \"nesw-resize\", x: 100, y: 0 },\r\n\t{ id: ResizeHandle.W, cursor: \"ew-resize\", x: 0, y: 50 },\r\n\t{ id: ResizeHandle.E, cursor: \"ew-resize\", x: 100, y: 50 },\r\n\t{ id: ResizeHandle.SW, cursor: \"nesw-resize\", x: 0, y: 100 },\r\n\t{ id: ResizeHandle.S, cursor: \"ns-resize\", x: 50, y: 100 },\r\n\t{ id: ResizeHandle.SE, cursor: \"nwse-resize\", x: 100, y: 100 },\r\n] as const;\r\n\r\nexport const ResizeHandles = memo(\r\n\t({\r\n\t\tonResizeStart,\r\n\t\tactiveHandle,\r\n\t\thandleStyle = RESIZE_HANDLE_STYLE,\r\n\t\tzIndex = Z_INDEX.BLOCK_HANDLES,\r\n\t}: ResizeHandlesProps) => {\r\n\t\t// ハンドルのサイズ\r\n\t\tconst handleSize = handleStyle.size;\r\n\t\tconst offset = handleSize / 2;\r\n\r\n\t\treturn (\r\n\t\t\t<>\r\n\t\t\t\t{HANDLES.map(({ id, cursor, x, y }) => {\r\n\t\t\t\t\t// 位置計算: 0, 50(center), 100(end) からCSSを生成\r\n\t\t\t\t\tconst left =\r\n\t\t\t\t\t\tx === 50\r\n\t\t\t\t\t\t\t? `calc(50% - ${offset}px)`\r\n\t\t\t\t\t\t\t: x === 100\r\n\t\t\t\t\t\t\t\t? `calc(100% - ${offset}px)`\r\n\t\t\t\t\t\t\t\t: `-${offset}px`;\r\n\t\t\t\t\tconst top =\r\n\t\t\t\t\t\ty === 50\r\n\t\t\t\t\t\t\t? `calc(50% - ${offset}px)`\r\n\t\t\t\t\t\t\t: y === 100\r\n\t\t\t\t\t\t\t\t? `calc(100% - ${offset}px)`\r\n\t\t\t\t\t\t\t\t: `-${offset}px`;\r\n\r\n\t\t\t\t\tconst isActive = activeHandle === id;\r\n\r\n\t\t\t\t\treturn (\r\n\t\t\t\t\t\t<div\r\n\t\t\t\t\t\t\tkey={id}\r\n\t\t\t\t\t\t\tclassName={styles.resizeHandle}\r\n\t\t\t\t\t\t\tonPointerDown={(e) => {\r\n\t\t\t\t\t\t\t\te.stopPropagation(); // 親の移動開始イベントを止める\r\n\t\t\t\t\t\t\t\tonResizeStart(e, id);\r\n\t\t\t\t\t\t\t}}\r\n\t\t\t\t\t\t\tstyle={{\r\n\t\t\t\t\t\t\t\tposition: \"absolute\",\r\n\t\t\t\t\t\t\t\tleft,\r\n\t\t\t\t\t\t\t\ttop,\r\n\t\t\t\t\t\t\t\twidth: `${handleSize}px`,\r\n\t\t\t\t\t\t\t\theight: `${handleSize}px`,\r\n\t\t\t\t\t\t\t\tbackgroundColor: isActive\r\n\t\t\t\t\t\t\t\t\t? handleStyle.borderColor\r\n\t\t\t\t\t\t\t\t\t: handleStyle.backgroundColor, // アクティブ時は青で塗りつぶし\r\n\t\t\t\t\t\t\t\tborder: `${handleStyle.borderWidth}px solid ${handleStyle.borderColor}`,\r\n\t\t\t\t\t\t\t\tborderRadius: handleStyle.borderRadius,\r\n\t\t\t\t\t\t\t\tcursor,\r\n\t\t\t\t\t\t\t\tzIndex: zIndex,\r\n\t\t\t\t\t\t\t\tpointerEvents: \"auto\", // ハンドルはクリック可能\r\n\t\t\t\t\t\t\t\tboxSizing: \"border-box\",\r\n\t\t\t\t\t\t\t\topacity: isActive ? 1 : undefined, // アクティブなら常に表示、それ以外はCSSホバーで制御\r\n\t\t\t\t\t\t\t\ttransition:\r\n\t\t\t\t\t\t\t\t\t\"opacity 0.2s, background-color 0.2s, transform 0.2s\",\r\n\t\t\t\t\t\t\t\ttransform: isActive ? \"scale(1.2)\" : undefined, // アクティブ時に拡大\r\n\t\t\t\t\t\t\t}}\r\n\t\t\t\t\t\t\tdata-testid={`resize-handle-${id}`}\r\n\t\t\t\t\t\t/>\r\n\t\t\t\t\t);\r\n\t\t\t\t})}\r\n\t\t\t</>\r\n\t\t);\r\n\t},\r\n);\r\n\r\nResizeHandles.displayName = \"ResizeHandles\";\r\n","import { memo, useMemo } from \"react\";\r\n\r\nimport { SELECTION_STYLE } from \"./constants\";\r\n\r\nimport { BorderRenderer } from \"@/canvas/components/BorderRenderer/BorderRenderer\";\r\nimport { Border, type BorderStyle } from \"@/types/line\";\r\nimport { Z_INDEX } from \"@/utils/zIndex\";\r\n\r\ninterface SelectionBorderProps {\r\n\twidth: number;\r\n\theight: number;\r\n\tzIndex?: number;\r\n\tborderStyle?: BorderStyle;\r\n}\r\n\r\nexport const SelectionBorder = memo(\r\n\t({\r\n\t\twidth,\r\n\t\theight,\r\n\t\tzIndex = Z_INDEX.BLOCK_SELECT_BORDER,\r\n\t\tborderStyle = SELECTION_STYLE,\r\n\t}: SelectionBorderProps) => {\r\n\t\tconst border = useMemo(() => new Border(borderStyle), [borderStyle]);\r\n\r\n\t\tconst style: React.CSSProperties = {\r\n\t\t\tposition: \"absolute\",\r\n\t\t\tinset: 0,\r\n\t\t\tpointerEvents: \"none\",\r\n\t\t\tzIndex: zIndex,\r\n\t\t};\r\n\r\n\t\treturn (\r\n\t\t\t<div style={style}>\r\n\t\t\t\t<BorderRenderer width={width} height={height} border={border} />\r\n\t\t\t</div>\r\n\t\t);\r\n\t},\r\n);\r\n","/**\r\n * @file InteractionBlock.tsx\r\n */\r\nimport { memo } from \"react\";\r\n\r\nimport {\r\n\tinteractionZIndexs,\r\n\tRESIZE_HANDLE_STYLE,\r\n\tSELECTION_STYLE,\r\n} from \"./constants\";\r\nimport styles from \"./InteractionBlock.module.css\";\r\nimport { ResizeHandles } from \"./ResizeHandles\";\r\nimport { SelectionBorder } from \"./SelectionBorder\";\r\n\r\nimport type React from \"react\";\r\nimport type { Block, BlockRectPx } from \"@/types/block\";\r\nimport type { BorderStyle } from \"@/types/line\";\r\nimport type { ResizeHandle } from \"../types\";\r\n\r\nexport interface InteractionBlockProps {\r\n\tblock: Block;\r\n\trect: BlockRectPx;\r\n\t// リサイズ関連\r\n\tshowHandles?: boolean;\r\n\tonResizeStart?: (e: React.PointerEvent, handle: ResizeHandle) => void;\r\n\tactiveHandle?: ResizeHandle | null;\r\n\t// スタイル関連\r\n\tselectionStyle?: BorderStyle;\r\n\thandleStyle?: typeof RESIZE_HANDLE_STYLE;\r\n\t/** 選択枠のz-index (デフォルト: interactionZIndexs.select_border) */\r\n\tselectBorderZIndex?: number;\r\n\t/** リサイズハンドルのz-index (デフォルト: interactionZIndexs.block_handles) */\r\n\tblockHandlesZIndex?: number;\r\n}\r\n\r\nexport const InteractionBlock = memo(\r\n\t({\r\n\t\tblock,\r\n\t\trect,\r\n\t\tshowHandles = false,\r\n\t\tonResizeStart,\r\n\t\tactiveHandle,\r\n\t\tselectionStyle = SELECTION_STYLE,\r\n\t\thandleStyle = RESIZE_HANDLE_STYLE,\r\n\t\tselectBorderZIndex = interactionZIndexs.select_border,\r\n\t\tblockHandlesZIndex = interactionZIndexs.block_handles,\r\n\t}: InteractionBlockProps) => {\r\n\t\tconst style: React.CSSProperties = {\r\n\t\t\tposition: \"absolute\",\r\n\t\t\tleft: `${rect.left}px`,\r\n\t\t\ttop: `${rect.top}px`,\r\n\t\t\twidth: `${rect.width}px`,\r\n\t\t\theight: `${rect.height}px`,\r\n\t\t\tpointerEvents: \"none\",\r\n\t\t\t// zIndexを削除: 親にz-indexを設定すると子要素のz-indexが親に制約される\r\n\t\t};\r\n\r\n\t\treturn (\r\n\t\t\t<div\r\n\t\t\t\tclassName={styles.interactionBlock}\r\n\t\t\t\tstyle={style}\r\n\t\t\t\tdata-testid=\"interaction-block\"\r\n\t\t\t\tdata-block-id={block.id}\r\n\t\t\t>\r\n\t\t\t\t{/* 1. 選択枠 */}\r\n\t\t\t\t<SelectionBorder\r\n\t\t\t\t\twidth={rect.width}\r\n\t\t\t\t\theight={rect.height}\r\n\t\t\t\t\tzIndex={selectBorderZIndex}\r\n\t\t\t\t\tborderStyle={selectionStyle}\r\n\t\t\t\t/>\r\n\r\n\t\t\t\t{/* 2. リサイズハンドル */}\r\n\t\t\t\t{showHandles && onResizeStart && (\r\n\t\t\t\t\t<ResizeHandles\r\n\t\t\t\t\t\tonResizeStart={onResizeStart}\r\n\t\t\t\t\t\tactiveHandle={activeHandle}\r\n\t\t\t\t\t\thandleStyle={handleStyle}\r\n\t\t\t\t\t\tzIndex={blockHandlesZIndex}\r\n\t\t\t\t\t/>\r\n\t\t\t\t)}\r\n\t\t\t</div>\r\n\t\t);\r\n\t},\r\n);\r\n\r\nInteractionBlock.displayName = \"InteractionBlock\";\r\n","import { memo } from \"react\";\r\n\r\nimport { BlockRenderer } from \"../../BlockLayer/BlockRenderer\";\r\nimport { InteractionBlock } from \"../InteractionBlock\";\r\nimport { interactionZIndexs } from \"../InteractionBlock/constants\";\r\n\r\nimport { createBlock } from \"@/plugin/utils/block\";\r\nimport { NoteMode } from \"@/types/mode\";\r\n\r\nimport type { BlockPlugin } from \"@/plugin\";\r\nimport type { Block, BlockRectPx } from \"@/types/block\";\r\nimport type { BorderStyle } from \"@/types/line\";\r\n\r\nexport interface InsertGhostProps {\r\n\tpluginRegistry: Record<string, BlockPlugin>;\r\n\tgridLength: { cols: number; rows: number };\r\n\tgetBlockRectPx: (block: Block) => BlockRectPx;\r\n\tcurrentGrid: { col: number; row: number };\r\n\tcurrentMousePx?: { x: number; y: number }; // マウス座標を追加\r\n\tpluginKind: string;\r\n\tdefaultSize: { w: number; h: number };\r\n\tisOutside: boolean;\r\n\tselectionStyle: BorderStyle;\r\n\tghostZIndex?: number;\r\n\tselectBorderZIndex?: number;\r\n\tblockHandlesZIndex?: number;\r\n}\r\n\r\nexport const InsertGhost = memo(\r\n\t({\r\n\t\tpluginRegistry,\r\n\t\tgridLength,\r\n\t\tgetBlockRectPx,\r\n\t\tcurrentGrid,\r\n\t\tcurrentMousePx, // TODO: キャンバス外でマウス追従ゴースト表示用(将来実装)\r\n\t\tpluginKind,\r\n\t\tdefaultSize,\r\n\t\tisOutside,\r\n\t\tselectionStyle,\r\n\t\tghostZIndex = interactionZIndexs.block_ghost,\r\n\t\tselectBorderZIndex = interactionZIndexs.select_border,\r\n\t\tblockHandlesZIndex = interactionZIndexs.block_handles,\r\n\t}: InsertGhostProps) => {\r\n\t\tconst plugin = pluginRegistry[pluginKind];\r\n\r\n\t\tif (!plugin) return null;\r\n\r\n\t\tlet ghostRect: BlockRectPx;\r\n\r\n\t\t// キャンバス外ではマウス座標に追従するゴーストを表示\r\n\t\tif (isOutside && currentMousePx) {\r\n\t\t\t// 仮のブロックデータを生成(サイズ計算用)\r\n\t\t\tconst tempBlock = createBlock(plugin, {\r\n\t\t\t\tx: 0,\r\n\t\t\t\ty: 0,\r\n\t\t\t\tw: defaultSize.w,\r\n\t\t\t\th: defaultSize.h,\r\n\t\t\t});\r\n\t\t\tconst tempRect = getBlockRectPx(tempBlock);\r\n\r\n\t\t\t// マウス位置を中心にゴーストを配置\r\n\t\t\tghostRect = {\r\n\t\t\t\tleft: currentMousePx.x - tempRect.width / 2,\r\n\t\t\t\ttop: currentMousePx.y - tempRect.height / 2,\r\n\t\t\t\twidth: tempRect.width,\r\n\t\t\t\theight: tempRect.height,\r\n\t\t\t};\r\n\t\t} else {\r\n\t\t\t// キャンバス内ではグリッドに吸着\r\n\t\t\t// 1. グリッド範囲内にクランプ(はみ出し防止)\r\n\t\t\tconst maxX = gridLength.cols - defaultSize.w;\r\n\t\t\tconst maxY = gridLength.rows - defaultSize.h;\r\n\r\n\t\t\tconst x = Math.max(0, Math.min(currentGrid.col, maxX));\r\n\t\t\tconst y = Math.max(0, Math.min(currentGrid.row, maxY));\r\n\r\n\t\t\t// 2. 仮のブロックデータを生成(表示用)\r\n\t\t\tconst ghostBlock = createBlock(plugin, {\r\n\t\t\t\tx,\r\n\t\t\t\ty,\r\n\t\t\t\tw: defaultSize.w,\r\n\t\t\t\th: defaultSize.h,\r\n\t\t\t});\r\n\r\n\t\t\t// 3. ピクセル座標を取得 (getBlockRectPxを使用)\r\n\t\t\tghostRect = getBlockRectPx(ghostBlock);\r\n\t\t}\r\n\r\n\t\t// 4. 実際に表示するブロックデータ(レンダリング用)\r\n\t\tconst ghostBlock = createBlock(plugin, {\r\n\t\t\tx: 0,\r\n\t\t\ty: 0,\r\n\t\t\tw: defaultSize.w,\r\n\t\t\th: defaultSize.h,\r\n\t\t});\r\n\r\n\t\treturn (\r\n\t\t\t<div\r\n\t\t\t\tdata-testid=\"insert-ghost\"\r\n\t\t\t\tstyle={{\r\n\t\t\t\t\tposition: \"absolute\",\r\n\t\t\t\t\tinset: 0,\r\n\t\t\t\t\tpointerEvents: \"none\",\r\n\t\t\t\t}}\r\n\t\t\t>\r\n\t\t\t\t<div\r\n\t\t\t\t\tstyle={{\r\n\t\t\t\t\t\tposition: \"absolute\",\r\n\t\t\t\t\t\tleft: `${ghostRect.left}px`,\r\n\t\t\t\t\t\ttop: `${ghostRect.top}px`,\r\n\t\t\t\t\t\twidth: `${ghostRect.width}px`,\r\n\t\t\t\t\t\theight: `${ghostRect.height}px`,\r\n\t\t\t\t\t\topacity: isOutside ? 0.3 : 0.6,\r\n\t\t\t\t\t\tfilter: isOutside ? \"grayscale(100%)\" : \"none\",\r\n\t\t\t\t\t\tzIndex: ghostZIndex,\r\n\t\t\t\t\t}}\r\n\t\t\t\t>\r\n\t\t\t\t\t<BlockRenderer\r\n\t\t\t\t\t\tid={ghostBlock.id}\r\n\t\t\t\t\t\tplugin={plugin}\r\n\t\t\t\t\t\tprops={ghostBlock.props}\r\n\t\t\t\t\t\tvalue={ghostBlock.initValue}\r\n\t\t\t\t\t\tonChange={() => {}}\r\n\t\t\t\t\t\treadOnly={true}\r\n\t\t\t\t\t\tmode={NoteMode.EDIT}\r\n\t\t\t\t\t\tblockSizePx={ghostRect}\r\n\t\t\t\t\t\tblockZIndex={ghostZIndex}\r\n\t\t\t\t\t/>\r\n\t\t\t\t</div>\r\n\t\t\t\t<InteractionBlock\r\n\t\t\t\t\tblock={ghostBlock}\r\n\t\t\t\t\trect={ghostRect}\r\n\t\t\t\t\tselectionStyle={selectionStyle}\r\n\t\t\t\t\tselectBorderZIndex={selectBorderZIndex}\r\n\t\t\t\t\tblockHandlesZIndex={blockHandlesZIndex}\r\n\t\t\t\t/>\r\n\t\t\t</div>\r\n\t\t);\r\n\t},\r\n);\r\n\r\nInsertGhost.displayName = \"InsertGhost\";\r\n","/**\r\n * @file clampMultipleBlocks.ts\r\n * @description 複数ブロックの移動時に全体をまとめてクランプする処理\r\n */\r\n\r\nimport type { Block } from \"@/types/block\";\r\n\r\nexport interface ClampedBlockPosition {\r\n\tblockId: string;\r\n\tx: number;\r\n\ty: number;\r\n}\r\n\r\n/**\r\n * 複数ブロックの移動をクランプ\r\n * 全体のバウンディングボックスを計算し、グリッド範囲内に収めた上で\r\n * 相対位置を保持したまま各ブロックの新しい座標を返す\r\n *\r\n * @param blocks - 移動対象のブロック配列\r\n * @param deltaCol - 列方向の移動量\r\n * @param deltaRow - 行方向の移動量\r\n * @param gridCols - グリッドの列数\r\n * @param gridRows - グリッドの行数\r\n * @returns クランプ後の各ブロックの座標配列\r\n */\r\nexport function clampMultipleBlocks(\r\n\tblocks: Block[],\r\n\tdeltaCol: number,\r\n\tdeltaRow: number,\r\n\tgridCols: number,\r\n\tgridRows: number,\r\n): ClampedBlockPosition[] {\r\n\tif (blocks.length === 0) {\r\n\t\treturn [];\r\n\t}\r\n\r\n\t// 単一ブロックの場合\r\n\tif (blocks.length === 1) {\r\n\t\tconst block = blocks[0];\r\n\t\tif (!block) return [];\r\n\r\n\t\tconst maxX = gridCols - block.layout.w;\r\n\t\tconst maxY = gridRows - block.layout.h;\r\n\t\tconst newX = Math.max(0, Math.min(block.layout.x + deltaCol, maxX));\r\n\t\tconst newY = Math.max(0, Math.min(block.layout.y + deltaRow, maxY));\r\n\r\n\t\treturn [{ blockId: block.id, x: newX, y: newY }];\r\n\t}\r\n\r\n\t// 複数ブロックの場合: バウンディングボックス計算\r\n\tconst minX = Math.min(...blocks.map((b) => b.layout.x));\r\n\tconst minY = Math.min(...blocks.map((b) => b.layout.y));\r\n\tconst maxX = Math.max(...blocks.map((b) => b.layout.x + b.layout.w));\r\n\tconst maxY = Math.max(...blocks.map((b) => b.layout.y + b.layout.h));\r\n\r\n\tconst boundingW = maxX - minX;\r\n\tconst boundingH = maxY - minY;\r\n\r\n\t// バウンディングボックス全体の新しい最小座標を計算\r\n\tconst newMinX = minX + deltaCol;\r\n\tconst newMinY = minY + deltaRow;\r\n\r\n\t// グリッド範囲内にクランプ\r\n\tconst clampedMinX = Math.max(0, Math.min(newMinX, gridCols - boundingW));\r\n\tconst clampedMinY = Math.max(0, Math.min(newMinY, gridRows - boundingH));\r\n\r\n\t// 実際に適用する移動量 (クランプによって制限される可能性がある)\r\n\tconst actualDeltaCol = clampedMinX - minX;\r\n\tconst actualDeltaRow = clampedMinY - minY;\r\n\r\n\t// 各ブロックに同じオフセットを適用\r\n\treturn blocks.map((block) => ({\r\n\t\tblockId: block.id,\r\n\t\tx: block.layout.x + actualDeltaCol,\r\n\t\ty: block.layout.y + actualDeltaRow,\r\n\t}));\r\n}\r\n","/**\r\n * @file MovingGhost.tsx\r\n * @description ブロック移動中のゴースト表示コンポーネント\r\n */\r\n\r\nimport { memo } from \"react\";\r\n\r\nimport { BlockRenderer } from \"../../BlockLayer/BlockRenderer\";\r\nimport { InteractionBlock } from \"../InteractionBlock\";\r\nimport { interactionZIndexs } from \"../InteractionBlock/constants\";\r\nimport { clampMultipleBlocks } from \"../utils/clampMultipleBlocks\";\r\n\r\nimport { NoteMode } from \"@/types/mode\";\r\n\r\nimport type { BlockPlugin } from \"@/plugin\";\r\nimport type { Block, BlockRectPx } from \"@/types/block\";\r\nimport type { BorderStyle } from \"@/types/line\";\r\n\r\nexport interface MovingGhostProps {\r\n\tblocks: Block[];\r\n\tpluginRegistry: Record<string, BlockPlugin>;\r\n\tgridLength: { cols: number; rows: number };\r\n\tgetBlockRectPx: (block: Block) => BlockRectPx;\r\n\tselectedBlockIds: string[];\r\n\tdeltaCol: number;\r\n\tdeltaRow: number;\r\n\tisOutside: boolean;\r\n\tcurrentMousePx?: { x: number; y: number }; // マウス座標を追加\r\n\tselectionStyle: BorderStyle;\r\n\tghostZIndex?: number;\r\n\tselectBorderZIndex?: number;\r\n\tblockHandlesZIndex?: number;\r\n}\r\n\r\nexport const MovingGhost = memo(\r\n\t({\r\n\t\tblocks,\r\n\t\tpluginRegistry,\r\n\t\tgridLength,\r\n\t\tgetBlockRectPx,\r\n\t\tselectedBlockIds,\r\n\t\tdeltaCol,\r\n\t\tdeltaRow,\r\n\t\tisOutside,\r\n\t\tcurrentMousePx,\r\n\t\tselectionStyle,\r\n\t\tghostZIndex = interactionZIndexs.block_ghost,\r\n\t\tselectBorderZIndex = interactionZIndexs.select_border,\r\n\t\tblockHandlesZIndex = interactionZIndexs.block_handles,\r\n\t}: MovingGhostProps) => {\r\n\t\t// 共通のクランプ処理を使用して各ブロックの新しい座標を計算\r\n\t\tconst dragTargets = selectedBlockIds\r\n\t\t\t.map((id) => blocks.find((b) => b.id === id))\r\n\t\t\t.filter(Boolean) as Block[];\r\n\r\n\t\tconst clampedPositions = clampMultipleBlocks(\r\n\t\t\tdragTargets,\r\n\t\t\tdeltaCol,\r\n\t\t\tdeltaRow,\r\n\t\t\tgridLength.cols,\r\n\t\t\tgridLength.rows,\r\n\t\t);\r\n\r\n\t\treturn (\r\n\t\t\t<div\r\n\t\t\t\tdata-testid=\"moving-ghost\"\r\n\t\t\t\tstyle={{\r\n\t\t\t\t\tposition: \"absolute\",\r\n\t\t\t\t\tinset: 0,\r\n\t\t\t\t\tpointerEvents: \"none\",\r\n\t\t\t\t}}\r\n\t\t\t>\r\n\t\t\t\t{selectedBlockIds.map((id) => {\r\n\t\t\t\t\tconst block = blocks.find((b) => b.id === id);\r\n\t\t\t\t\tif (!block) return null;\r\n\r\n\t\t\t\t\tconst plugin = pluginRegistry[block.kind];\r\n\t\t\t\t\tif (!plugin) return null;\r\n\r\n\t\t\t\t\tlet ghostRect: BlockRectPx;\r\n\r\n\t\t\t\t\t// キャンバス外ではマウス座標に追従するゴーストを表示\r\n\t\t\t\t\tif (isOutside && currentMousePx) {\r\n\t\t\t\t\t\t// 元のブロックのサイズを取得\r\n\t\t\t\t\t\tconst originalRect = getBlockRectPx(block);\r\n\r\n\t\t\t\t\t\t// マウス位置を中心にゴーストを配置\r\n\t\t\t\t\t\tghostRect = {\r\n\t\t\t\t\t\t\tleft: currentMousePx.x - originalRect.width / 2,\r\n\t\t\t\t\t\t\ttop: currentMousePx.y - originalRect.height / 2,\r\n\t\t\t\t\t\t\twidth: originalRect.width,\r\n\t\t\t\t\t\t\theight: originalRect.height,\r\n\t\t\t\t\t\t};\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\t// キャンバス内ではクランプ済みの座標を使用\r\n\t\t\t\t\t\tconst clampedPos = clampedPositions.find(\r\n\t\t\t\t\t\t\t(p) => p.blockId === block.id,\r\n\t\t\t\t\t\t);\r\n\r\n\t\t\t\t\t\tif (!clampedPos) return null;\r\n\r\n\t\t\t\t\t\tconst ghostBlock: Block = {\r\n\t\t\t\t\t\t\t...block,\r\n\t\t\t\t\t\t\tlayout: {\r\n\t\t\t\t\t\t\t\t...block.layout,\r\n\t\t\t\t\t\t\t\tx: clampedPos.x,\r\n\t\t\t\t\t\t\t\ty: clampedPos.y,\r\n\t\t\t\t\t\t\t},\r\n\t\t\t\t\t\t};\r\n\r\n\t\t\t\t\t\tghostRect = getBlockRectPx(ghostBlock);\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// 表示用のブロックデータ\r\n\t\t\t\t\tconst ghostBlock: Block = {\r\n\t\t\t\t\t\t...block,\r\n\t\t\t\t\t\tlayout: {\r\n\t\t\t\t\t\t\t...block.layout,\r\n\t\t\t\t\t\t\tx: 0,\r\n\t\t\t\t\t\t\ty: 0,\r\n\t\t\t\t\t\t},\r\n\t\t\t\t\t};\r\n\r\n\t\t\t\t\treturn (\r\n\t\t\t\t\t\t<div key={id}>\r\n\t\t\t\t\t\t\t<div\r\n\t\t\t\t\t\t\t\tstyle={{\r\n\t\t\t\t\t\t\t\t\tposition: \"absolute\",\r\n\t\t\t\t\t\t\t\t\tleft: `${ghostRect.left}px`,\r\n\t\t\t\t\t\t\t\t\ttop: `${ghostRect.top}px`,\r\n\t\t\t\t\t\t\t\t\twidth: `${ghostRect.width}px`,\r\n\t\t\t\t\t\t\t\t\theight: `${ghostRect.height}px`,\r\n\t\t\t\t\t\t\t\t\topacity: isOutside ? 0.3 : 0.5,\r\n\t\t\t\t\t\t\t\t\tfilter: isOutside ? \"grayscale(100%)\" : \"none\",\r\n\t\t\t\t\t\t\t\t\tzIndex: ghostZIndex,\r\n\t\t\t\t\t\t\t\t}}\r\n\t\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t\t<BlockRenderer\r\n\t\t\t\t\t\t\t\t\tid={ghostBlock.id}\r\n\t\t\t\t\t\t\t\t\tplugin={plugin}\r\n\t\t\t\t\t\t\t\t\tprops={ghostBlock.props}\r\n\t\t\t\t\t\t\t\t\tvalue={ghostBlock.initValue}\r\n\t\t\t\t\t\t\t\t\tonChange={() => {}}\r\n\t\t\t\t\t\t\t\t\treadOnly={true}\r\n\t\t\t\t\t\t\t\t\tmode={NoteMode.EDIT}\r\n\t\t\t\t\t\t\t\t\tblockSizePx={ghostRect}\r\n\t\t\t\t\t\t\t\t\tblockZIndex={ghostZIndex}\r\n\t\t\t\t\t\t\t\t\tclassName=\"ghost-content\"\r\n\t\t\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t\t</div>\r\n\t\t\t\t\t\t\t<InteractionBlock\r\n\t\t\t\t\t\t\t\tblock={ghostBlock}\r\n\t\t\t\t\t\t\t\trect={ghostRect}\r\n\t\t\t\t\t\t\t\tselectionStyle={selectionStyle}\r\n\t\t\t\t\t\t\t\tselectBorderZIndex={selectBorderZIndex}\r\n\t\t\t\t\t\t\t\tblockHandlesZIndex={blockHandlesZIndex}\r\n\t\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t</div>\r\n\t\t\t\t\t);\r\n\t\t\t\t})}\r\n\t\t\t</div>\r\n\t\t);\r\n\t},\r\n);\r\n\r\nMovingGhost.displayName = \"MovingGhost\";\r\n","/**\r\n * @file calcResize.ts\r\n * @description リサイズ計算ロジックの共通関数\r\n *\r\n * @remarks\r\n * InteractionLayerとResizeGhostで共通使用される計算ロジック。\r\n * DRY原則に従い、1箇所に集約することで保守性を向上。\r\n */\r\n\r\nimport { ResizeHandle } from \"../types\";\r\n\r\n/**\r\n * ブロックレイアウト(グリッド座標系)\r\n */\r\nexport interface BlockLayout {\r\n\tx: number;\r\n\ty: number;\r\n\tw: number;\r\n\th: number;\r\n}\r\n\r\n/**\r\n * リサイズ計算パラメータ\r\n */\r\nexport interface ResizeParams {\r\n\t/** 現在のレイアウト */\r\n\tlayout: BlockLayout;\r\n\t/** リサイズハンドル */\r\n\thandle: ResizeHandle;\r\n\t/** 列方向の移動量 */\r\n\tdeltaCol: number;\r\n\t/** 行方向の移動量 */\r\n\tdeltaRow: number;\r\n\t/** グリッドの列数 */\r\n\tgridCols: number;\r\n\t/** グリッドの行数 */\r\n\tgridRows: number;\r\n}\r\n\r\n/**\r\n * リサイズ後のレイアウトを計算\r\n *\r\n * @param params - リサイズパラメータ\r\n * @returns 新しいレイアウト\r\n *\r\n * @remarks\r\n * - 最小サイズは1x1\r\n * - グリッド範囲外にははみ出さない\r\n * - 左端・上端を超える場合は自動的にクランプ\r\n *\r\n * @example\r\n * ```typescript\r\n * const newLayout = calculateResizedLayout({\r\n * layout: { x: 2, y: 2, w: 3, h: 3 },\r\n * handle: ResizeHandle.SE,\r\n * deltaCol: 2,\r\n * deltaRow: 1,\r\n * gridCols: 10,\r\n * gridRows: 10,\r\n * });\r\n * // => { x: 2, y: 2, w: 5, h: 4 }\r\n * ```\r\n */\r\nexport function calculateResizedLayout({\r\n\tlayout,\r\n\thandle,\r\n\tdeltaCol,\r\n\tdeltaRow,\r\n\tgridCols,\r\n\tgridRows,\r\n}: ResizeParams): BlockLayout {\r\n\tconst newLayout = { ...layout };\r\n\r\n\t// --- 横方向のリサイズ ---\r\n\tif (\r\n\t\thandle === ResizeHandle.E ||\r\n\t\thandle === ResizeHandle.NE ||\r\n\t\thandle === ResizeHandle.SE\r\n\t) {\r\n\t\t// 右へ拡大・縮小\r\n\t\tconst maxW = gridCols - layout.x;\r\n\t\tnewLayout.w = Math.max(1, Math.min(layout.w + deltaCol, maxW));\r\n\t} else if (\r\n\t\thandle === ResizeHandle.W ||\r\n\t\thandle === ResizeHandle.NW ||\r\n\t\thandle === ResizeHandle.SW\r\n\t) {\r\n\t\t// 左へ拡大・縮小\r\n\t\t// 幅が1未満にならないようにdeltaを制限\r\n\t\tconst maxShrink = layout.w - 1;\r\n\t\tconst validDCol = deltaCol > 0 ? Math.min(deltaCol, maxShrink) : deltaCol;\r\n\r\n\t\t// 左端(x=0)を超えないように制限\r\n\t\tif (layout.x + validDCol >= 0) {\r\n\t\t\tnewLayout.x = layout.x + validDCol;\r\n\t\t\tnewLayout.w = layout.w - validDCol;\r\n\t\t} else {\r\n\t\t\t// 左端に張り付く場合\r\n\t\t\tnewLayout.x = 0;\r\n\t\t\tnewLayout.w = layout.w + layout.x;\r\n\t\t}\r\n\t}\r\n\r\n\t// --- 縦方向のリサイズ ---\r\n\tif (\r\n\t\thandle === ResizeHandle.S ||\r\n\t\thandle === ResizeHandle.SE ||\r\n\t\thandle === ResizeHandle.SW\r\n\t) {\r\n\t\t// 下へ拡大・縮小\r\n\t\tconst maxH = gridRows - layout.y;\r\n\t\tnewLayout.h = Math.max(1, Math.min(layout.h + deltaRow, maxH));\r\n\t} else if (\r\n\t\thandle === ResizeHandle.N ||\r\n\t\thandle === ResizeHandle.NE ||\r\n\t\thandle === ResizeHandle.NW\r\n\t) {\r\n\t\t// 上へ拡大・縮小\r\n\t\tconst maxShrink = layout.h - 1;\r\n\t\tconst validDRow = deltaRow > 0 ? Math.min(deltaRow, maxShrink) : deltaRow;\r\n\r\n\t\t// 上端(y=0)を超えないように制限\r\n\t\tif (layout.y + validDRow >= 0) {\r\n\t\t\tnewLayout.y = layout.y + validDRow;\r\n\t\t\tnewLayout.h = layout.h - validDRow;\r\n\t\t} else {\r\n\t\t\t// 上端に張り付く場合\r\n\t\t\tnewLayout.y = 0;\r\n\t\t\tnewLayout.h = layout.h + layout.y;\r\n\t\t}\r\n\t}\r\n\r\n\treturn newLayout;\r\n}\r\n","/**\r\n * @file ResizeGhost.tsx\r\n * @description ブロックリサイズ中のゴースト表示コンポーネント\r\n */\r\n\r\nimport { memo } from \"react\";\r\n\r\nimport { BlockRenderer } from \"../../BlockLayer/BlockRenderer\";\r\nimport { InteractionBlock } from \"../InteractionBlock\";\r\nimport { interactionZIndexs } from \"../InteractionBlock/constants\";\r\nimport { calculateResizedLayout } from \"../utils/calcResize\";\r\n\r\nimport { NoteMode } from \"@/types/mode\";\r\n\r\nimport type { BlockPlugin } from \"@/plugin\";\r\nimport type { Block, BlockRectPx } from \"@/types/block\";\r\nimport type { BorderStyle } from \"@/types/line\";\r\nimport type { ResizeHandle } from \"../types\";\r\n\r\nexport interface ResizeGhostProps {\r\n\tblocks: Block[];\r\n\tpluginRegistry: Record<string, BlockPlugin>;\r\n\tgridLength: { cols: number; rows: number };\r\n\tgetBlockRectPx: (block: Block) => BlockRectPx;\r\n\tblockId: string;\r\n\thandle: ResizeHandle;\r\n\tdeltaCol: number;\r\n\tdeltaRow: number;\r\n\tisOutside: boolean;\r\n\tselectionStyle: BorderStyle;\r\n\tghostZIndex?: number;\r\n\tselectBorderZIndex?: number;\r\n\tblockHandlesZIndex?: number;\r\n}\r\n\r\nexport const ResizeGhost = memo(\r\n\t({\r\n\t\tblocks,\r\n\t\tpluginRegistry,\r\n\t\tgridLength,\r\n\t\tgetBlockRectPx,\r\n\t\tblockId,\r\n\t\thandle,\r\n\t\tdeltaCol,\r\n\t\tdeltaRow,\r\n\t\tisOutside,\r\n\t\tselectionStyle,\r\n\t\tghostZIndex = interactionZIndexs.block_ghost,\r\n\t\tselectBorderZIndex = interactionZIndexs.select_border,\r\n\t\tblockHandlesZIndex = interactionZIndexs.block_handles,\r\n\t}: ResizeGhostProps) => {\r\n\t\tconst block = blocks.find((b) => b.id === blockId);\r\n\t\tconst plugin = pluginRegistry[block?.kind ?? \"\"];\r\n\t\tif (!block || !plugin) return null;\r\n\r\n\t\tconst newLayout = calculateResizedLayout({\r\n\t\t\tlayout: block.layout,\r\n\t\t\thandle,\r\n\t\t\tdeltaCol,\r\n\t\t\tdeltaRow,\r\n\t\t\tgridCols: gridLength.cols,\r\n\t\t\tgridRows: gridLength.rows,\r\n\t\t});\r\n\r\n\t\tconst ghostBlock: Block = {\r\n\t\t\t...block,\r\n\t\t\tlayout: newLayout,\r\n\t\t};\r\n\r\n\t\tconst ghostRect = getBlockRectPx(ghostBlock);\r\n\r\n\t\treturn (\r\n\t\t\t<div\r\n\t\t\t\tdata-testid=\"resize-ghost\"\r\n\t\t\t\tstyle={{\r\n\t\t\t\t\tposition: \"absolute\",\r\n\t\t\t\t\tinset: 0,\r\n\t\t\t\t\tpointerEvents: \"none\",\r\n\t\t\t\t}}\r\n\t\t\t>\r\n\t\t\t\t<div key={block.id}>\r\n\t\t\t\t\t<div\r\n\t\t\t\t\t\tstyle={{\r\n\t\t\t\t\t\t\tposition: \"absolute\",\r\n\t\t\t\t\t\t\tleft: `${ghostRect.left}px`,\r\n\t\t\t\t\t\t\ttop: `${ghostRect.top}px`,\r\n\t\t\t\t\t\t\twidth: `${ghostRect.width}px`,\r\n\t\t\t\t\t\t\theight: `${ghostRect.height}px`,\r\n\t\t\t\t\t\t\topacity: isOutside ? 0.3 : 0.5,\r\n\t\t\t\t\t\t\tfilter: isOutside ? \"grayscale(100%)\" : \"none\",\r\n\t\t\t\t\t\t\tzIndex: ghostZIndex,\r\n\t\t\t\t\t\t}}\r\n\t\t\t\t\t>\r\n\t\t\t\t\t\t<BlockRenderer\r\n\t\t\t\t\t\t\tid={ghostBlock.id}\r\n\t\t\t\t\t\t\tplugin={plugin}\r\n\t\t\t\t\t\t\tprops={ghostBlock.props}\r\n\t\t\t\t\t\t\tvalue={ghostBlock.initValue}\r\n\t\t\t\t\t\t\tonChange={() => {}}\r\n\t\t\t\t\t\t\treadOnly={true}\r\n\t\t\t\t\t\t\tmode={NoteMode.EDIT}\r\n\t\t\t\t\t\t\tblockSizePx={ghostRect}\r\n\t\t\t\t\t\t\tblockZIndex={ghostZIndex}\r\n\t\t\t\t\t\t\tclassName=\"resize-ghost-content\"\r\n\t\t\t\t\t\t/>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t\t<InteractionBlock\r\n\t\t\t\t\t\tblock={ghostBlock}\r\n\t\t\t\t\t\trect={ghostRect}\r\n\t\t\t\t\t\tselectionStyle={selectionStyle}\r\n\t\t\t\t\t\tselectBorderZIndex={selectBorderZIndex}\r\n\t\t\t\t\t\tblockHandlesZIndex={blockHandlesZIndex}\r\n\t\t\t\t\t/>\r\n\t\t\t\t</div>\r\n\t\t\t</div>\r\n\t\t);\r\n\t},\r\n);\r\n\r\nResizeGhost.displayName = \"ResizeGhost\";\r\n","/**\r\n * @file DragLayer.tsx\r\n * @description ドラッグ移動・リサイズ中のゴーストを表示するレイヤー\r\n */\r\n\r\nimport { memo } from \"react\";\r\n\r\nimport {\r\n\tinteractionZIndexs,\r\n\tSELECTION_STYLE,\r\n} from \"../InteractionBlock/constants\";\r\nimport { type DraggingState, DragType } from \"../types\";\r\nimport { InsertGhost } from \"./InsertGhost\";\r\nimport { MovingGhost } from \"./MovingGhost\";\r\nimport { ResizeGhost } from \"./ResizeGhost\";\r\n\r\nimport type { BlockPlugin } from \"@/plugin\";\r\nimport type { Block, BlockRectPx } from \"@/types/block\";\r\nimport type { BorderStyle } from \"@/types/line\";\r\n\r\nexport interface DragLayerProps {\r\n\tblocks: Block[];\r\n\tpluginRegistry: Record<string, BlockPlugin>;\r\n\tgridLength: { cols: number; rows: number };\r\n\tdraggingState: DraggingState | undefined;\r\n\tgetBlockRectPx: (block: Block) => BlockRectPx;\r\n\tselectionStyle?: BorderStyle;\r\n\tghostZIndex?: number;\r\n\tselectBorderZIndex?: number;\r\n\tblockHandlesZIndex?: number;\r\n}\r\n\r\nexport const DragLayer = memo(\r\n\t({\r\n\t\tblocks,\r\n\t\tpluginRegistry,\r\n\t\tgridLength,\r\n\t\tdraggingState,\r\n\t\tgetBlockRectPx,\r\n\t\tselectionStyle = SELECTION_STYLE,\r\n\t\tghostZIndex = interactionZIndexs.block_ghost,\r\n\t\tselectBorderZIndex = interactionZIndexs.select_border,\r\n\t\tblockHandlesZIndex = interactionZIndexs.block_handles,\r\n\t}: DragLayerProps) => {\r\n\t\t// ドラッグ中でなければ何も表示しない\r\n\t\tif (!draggingState) return null;\r\n\r\n\t\tconst deltaCol =\r\n\t\t\tdraggingState.currentGrid.col - draggingState.startGrid.col;\r\n\t\tconst deltaRow =\r\n\t\t\tdraggingState.currentGrid.row - draggingState.startGrid.row;\r\n\r\n\t\tswitch (draggingState.type) {\r\n\t\t\t// 移動モード\r\n\t\t\tcase DragType.MOVE:\r\n\t\t\t\treturn (\r\n\t\t\t\t\t<MovingGhost\r\n\t\t\t\t\t\tblocks={blocks}\r\n\t\t\t\t\t\tpluginRegistry={pluginRegistry}\r\n\t\t\t\t\t\tgridLength={gridLength}\r\n\t\t\t\t\t\tgetBlockRectPx={getBlockRectPx}\r\n\t\t\t\t\t\tselectedBlockIds={draggingState.blockIds}\r\n\t\t\t\t\t\tdeltaCol={deltaCol}\r\n\t\t\t\t\t\tdeltaRow={deltaRow}\r\n\t\t\t\t\t\tisOutside={draggingState.isOutside ?? false}\r\n\t\t\t\t\t\tcurrentMousePx={draggingState.currentMousePx}\r\n\t\t\t\t\t\tselectionStyle={selectionStyle}\r\n\t\t\t\t\t\tghostZIndex={ghostZIndex}\r\n\t\t\t\t\t\tselectBorderZIndex={selectBorderZIndex}\r\n\t\t\t\t\t\tblockHandlesZIndex={blockHandlesZIndex}\r\n\t\t\t\t\t/>\r\n\t\t\t\t);\r\n\r\n\t\t\t// リサイズモード\r\n\t\t\tcase DragType.RESIZE: {\r\n\t\t\t\tconst resizeBlockId = draggingState.blockIds[0];\r\n\t\t\t\tif (!resizeBlockId || !draggingState.handle) return null;\r\n\r\n\t\t\t\treturn (\r\n\t\t\t\t\t<ResizeGhost\r\n\t\t\t\t\t\tblocks={blocks}\r\n\t\t\t\t\t\tpluginRegistry={pluginRegistry}\r\n\t\t\t\t\t\tgridLength={gridLength}\r\n\t\t\t\t\t\tgetBlockRectPx={getBlockRectPx}\r\n\t\t\t\t\t\tblockId={resizeBlockId}\r\n\t\t\t\t\t\thandle={draggingState.handle}\r\n\t\t\t\t\t\tdeltaCol={deltaCol}\r\n\t\t\t\t\t\tdeltaRow={deltaRow}\r\n\t\t\t\t\t\tisOutside={draggingState.isOutside ?? false}\r\n\t\t\t\t\t\tselectionStyle={selectionStyle}\r\n\t\t\t\t\t\tghostZIndex={ghostZIndex}\r\n\t\t\t\t\t\tselectBorderZIndex={selectBorderZIndex}\r\n\t\t\t\t\t\tblockHandlesZIndex={blockHandlesZIndex}\r\n\t\t\t\t\t/>\r\n\t\t\t\t);\r\n\t\t\t}\r\n\r\n\t\t\t// 挿入モード\r\n\t\t\tcase DragType.INSERT: {\r\n\t\t\t\t// defaultSizeが未定義の場合は何も表示しない\r\n\t\t\t\tif (!draggingState.defaultSize) return null;\r\n\r\n\t\t\t\treturn (\r\n\t\t\t\t\t<InsertGhost\r\n\t\t\t\t\t\tpluginRegistry={pluginRegistry}\r\n\t\t\t\t\t\tgridLength={gridLength}\r\n\t\t\t\t\t\tgetBlockRectPx={getBlockRectPx}\r\n\t\t\t\t\t\tcurrentGrid={draggingState.currentGrid}\r\n\t\t\t\t\t\tcurrentMousePx={draggingState.currentMousePx}\r\n\t\t\t\t\t\tpluginKind={draggingState.pluginKind || \"\"}\r\n\t\t\t\t\t\tdefaultSize={draggingState.defaultSize}\r\n\t\t\t\t\t\tisOutside={draggingState.isOutside ?? false}\r\n\t\t\t\t\t\tselectionStyle={selectionStyle}\r\n\t\t\t\t\t\tghostZIndex={ghostZIndex}\r\n\t\t\t\t\t\tselectBorderZIndex={selectBorderZIndex}\r\n\t\t\t\t\t\tblockHandlesZIndex={blockHandlesZIndex}\r\n\t\t\t\t\t/>\r\n\t\t\t\t);\r\n\t\t\t}\r\n\r\n\t\t\t// その他のモードは何も表示しない\r\n\t\t\tdefault:\r\n\t\t\t\treturn null;\r\n\t\t}\r\n\t},\r\n);\r\n\r\nDragLayer.displayName = \"DragLayer\";\r\n","/**\r\n * @file EditingBlock.tsx\r\n * @description 編集中ブロックのRendererをInteractionLayer上に表示するコンポーネント\r\n *\r\n * @remarks\r\n * - BlockLayerとは独立して、InteractionLayer内でブロックの編集UIを表示\r\n * - z-indexはInteractionLayer内の順序(EDIT_BLOCK: 2,400,000)で管理\r\n * - SelectionBorderやResizeHandlesと同じStacking Context内にあるため、正しく重なり順を制御可能\r\n */\r\n\r\nimport { forwardRef, memo, useImperativeHandle, useRef } from \"react\";\r\n\r\nimport { NoteMode } from \"@/types/mode\";\r\nimport { getBlockContainerStyle } from \"@/utils/blockLayout\";\r\nimport { Z_INDEX } from \"@/utils/zIndex\";\r\n\r\nimport type React from \"react\";\r\nimport type { BlockPlugin, BlockRef, RendererProps } from \"@/plugin\";\r\nimport type { BlockRectPx, BlockSizePx } from \"@/types/block\";\r\nimport type { Value } from \"@/types/value\";\r\n\r\nexport interface EditingBlockProps<P = Record<string, Value>, V = Value> {\r\n\t/** ブロックID */\r\n\tid: string;\r\n\r\n\t/** プラグイン定義 */\r\n\tplugin: BlockPlugin<P, V>;\r\n\r\n\t/** プラグイン固有プロパティ */\r\n\tprops: P;\r\n\r\n\t/** ブロックの現在値 */\r\n\tvalue: V;\r\n\r\n\t/** 値変更コールバック */\r\n\tonChange: (value: V) => void;\r\n\r\n\t/** 値確定コールバック (オプション) */\r\n\tonBlur?: (value: V) => void;\r\n\r\n\t/** ブロックの位置とサイズ(ピクセル単位) */\r\n\tblockRectPx: BlockRectPx;\r\n\r\n\t/** z-index (オプション、デフォルト: Z_INDEX.EDIT_BLOCK) */\r\n\tzIndex?: number;\r\n\r\n\t/** バリデーション状態 (オプション) */\r\n\tvalidationState?: \"valid\" | \"invalid\" | \"warning\";\r\n\r\n\t/** 追加のクラス名 */\r\n\tclassName?: string;\r\n}\r\n\r\n/**\r\n * EditingBlock\r\n *\r\n * 編集中ブロックのRendererをInteractionLayer上に表示\r\n * - BlockLayerのブロックと同じ位置・サイズで表示\r\n * - プラグインのRendererコンポーネントを動的にレンダリング\r\n * - BlockRef経由でfocusメソッドを公開\r\n */\r\nconst EditingBlockInner = <P extends Record<string, Value>, V extends Value>(\r\n\t{\r\n\t\tid,\r\n\t\tplugin,\r\n\t\tprops,\r\n\t\tvalue,\r\n\t\tonChange,\r\n\t\tonBlur,\r\n\t\tblockRectPx,\r\n\t\tzIndex = Z_INDEX.EDIT_BLOCK,\r\n\t\tvalidationState,\r\n\t\tclassName = \"\",\r\n\t}: EditingBlockProps<P, V>,\r\n\tref: React.ForwardedRef<BlockRef>,\r\n) => {\r\n\t// プラグインのRendererコンポーネントへの参照\r\n\tconst pluginRendererRef = useRef<BlockRef>(null);\r\n\r\n\t// 外部から呼び出し可能なfocusメソッドを公開\r\n\tuseImperativeHandle(\r\n\t\tref,\r\n\t\t() => ({\r\n\t\t\tfocus: () => {\r\n\t\t\t\tpluginRendererRef.current?.focus();\r\n\t\t\t},\r\n\t\t}),\r\n\t\t[],\r\n\t);\r\n\r\n\t// コンテナスタイル (共通関数を使用)\r\n\tconst containerStyle = getBlockContainerStyle(blockRectPx, {\r\n\t\tzIndex,\r\n\t\tpointerEvents: \"auto\", // クリックイベントを受け取る\r\n\t});\r\n\r\n\t// ブロックサイズ\r\n\tconst blockSizePx: BlockSizePx = {\r\n\t\twidth: blockRectPx.width,\r\n\t\theight: blockRectPx.height,\r\n\t};\r\n\r\n\t// プラグインRendererに渡すprops\r\n\tconst pluginProps: RendererProps<P, V> = {\r\n\t\tid,\r\n\t\tprops,\r\n\t\tvalue,\r\n\t\tonChange,\r\n\t\tonBlur,\r\n\t\treadOnly: false, // 編集中は常に編集可能\r\n\t\tmode: NoteMode.FORM, // EditingBlockはFormモード専用\r\n\t\tdimensions: {\r\n\t\t\twidthPx: blockSizePx.width,\r\n\t\t\theightPx: blockSizePx.height,\r\n\t\t},\r\n\t\tvalidationState,\r\n\t};\r\n\r\n\t// プラグインのRendererコンポーネントを取得\r\n\tconst PluginRendererComponent = plugin.Renderer;\r\n\r\n\treturn (\r\n\t\t<div\r\n\t\t\tclassName={className}\r\n\t\t\tstyle={containerStyle}\r\n\t\t\tdata-testid=\"editing-block\"\r\n\t\t\tdata-block-id={id}\r\n\t\t\tdata-plugin-kind={plugin.kind}\r\n\t\t>\r\n\t\t\t<PluginRendererComponent ref={pluginRendererRef} {...pluginProps} />\r\n\t\t</div>\r\n\t);\r\n};\r\n\r\nconst ForwardedEditingBlock = forwardRef(EditingBlockInner) as <\r\n\tP extends Record<string, Value>,\r\n\tV extends Value,\r\n>(\r\n\tprops: EditingBlockProps<P, V> & { ref?: React.ForwardedRef<BlockRef> },\r\n) => React.ReactElement;\r\n\r\nexport const EditingBlock = memo(\r\n\tForwardedEditingBlock,\r\n) as typeof ForwardedEditingBlock;\r\n","import { useCallback, useState } from \"react\";\r\n\r\nimport {\r\n\tDragType,\r\n\ttype InteractionChangeEvent,\r\n\tInteractionEventType,\r\n\tInteractionMode,\r\n\ttype InteractionState,\r\n} from \"../types\";\r\n\r\n/**\r\n * インタラクション状態管理Hook\r\n *\r\n * @remarks\r\n * Reducer的なロジックを内包、外部からはシンプルなAPIのみ公開\r\n *\r\n * **核心機能**: グリッド変化判定によるドラッグ確定\r\n * - `mode: 'pressing'` でグリッドをまたいだら → `mode: 'dragging'` に遷移\r\n * - ピクセル閾値 (5px) は使わない\r\n *\r\n * @param initialState - 初期状態 (オプション)\r\n * @returns [state, handleChange] - 状態とコールバック\r\n *\r\n * @example\r\n * ```tsx\r\n * const [state, onChange] = useInteractionState();\r\n *\r\n * // ブロックをクリック\r\n * onChange({ type: InteractionEventType.SELECT, blockIds: ['block-1'] });\r\n *\r\n * // ドラッグ開始 (まだpressing)\r\n * onChange({ type: InteractionEventType.START_PRESS, blockId: 'block-1', startGrid: { col: 0, row: 0 } });\r\n *\r\n * // グリッドをまたぐ (自動的にdraggingへ遷移)\r\n * onChange({ type: InteractionEventType.UPDATE_DRAG, currentGrid: { col: 1, row: 0 } });\r\n * ```\r\n */\r\nexport function useInteractionState(initialState?: Partial<InteractionState>) {\r\n\tconst [state, setState] = useState<InteractionState>({\r\n\t\tmode: InteractionMode.IDLE,\r\n\t\tselectedBlockIds: [],\r\n\t\teditingBlockId: null,\r\n\t\t...initialState,\r\n\t});\r\n\r\n\tconst handleChange = useCallback((event: InteractionChangeEvent) => {\r\n\t\tsetState((prev) => {\r\n\t\t\tswitch (event.type) {\r\n\t\t\t\tcase InteractionEventType.SELECT: {\r\n\t\t\t\t\t// 選択\r\n\t\t\t\t\t// InteractionLayer側で既にShift+クリックのトグル処理が完了しているため、\r\n\t\t\t\t\t// 渡された配列をそのまま使用する\r\n\t\t\t\t\tconst newBlockIds = event.blockIds;\r\n\r\n\t\t\t\t\treturn {\r\n\t\t\t\t\t\t...prev,\r\n\t\t\t\t\t\tmode: InteractionMode.IDLE,\r\n\t\t\t\t\t\tselectedBlockIds: newBlockIds,\r\n\t\t\t\t\t};\r\n\t\t\t\t}\r\n\t\t\t\tcase InteractionEventType.DESELECT:\r\n\t\t\t\t\t// 選択解除\r\n\t\t\t\t\treturn {\r\n\t\t\t\t\t\t...prev,\r\n\t\t\t\t\t\tmode: InteractionMode.IDLE,\r\n\t\t\t\t\t\tselectedBlockIds: [],\r\n\t\t\t\t\t};\r\n\r\n\t\t\t\tcase InteractionEventType.START_PRESS: {\r\n\t\t\t\t\t// プレス開始 (まだドラッグではない、監視状態に入る)\r\n\t\t\t\t\t// selectedBlockIdsが指定されていれば複数選択のドラッグ、なければ単一ドラッグ\r\n\t\t\t\t\tconst dragTargetIds = event.selectedBlockIds || [event.blockId];\r\n\t\t\t\t\treturn {\r\n\t\t\t\t\t\t...prev,\r\n\t\t\t\t\t\tmode: InteractionMode.PRESSING,\r\n\t\t\t\t\t\tdragging: {\r\n\t\t\t\t\t\t\ttype: DragType.MOVE,\r\n\t\t\t\t\t\t\tblockIds: dragTargetIds,\r\n\t\t\t\t\t\t\tstartGrid: event.startGrid,\r\n\t\t\t\t\t\t\tcurrentGrid: event.startGrid,\r\n\t\t\t\t\t\t\tisOutside: false,\r\n\t\t\t\t\t\t},\r\n\t\t\t\t\t};\r\n\t\t\t\t}\r\n\r\n\t\t\t\tcase InteractionEventType.UPDATE_DRAG: {\r\n\t\t\t\t\tif (!prev.dragging) return prev;\r\n\r\n\t\t\t\t\t// ★ グリッド変化判定 ★\r\n\t\t\t\t\tconst gridChanged =\r\n\t\t\t\t\t\tevent.currentGrid.col !== prev.dragging.startGrid.col ||\r\n\t\t\t\t\t\tevent.currentGrid.row !== prev.dragging.startGrid.row;\r\n\r\n\t\t\t\t\tif (prev.mode === InteractionMode.PRESSING) {\r\n\t\t\t\t\t\tif (gridChanged) {\r\n\t\t\t\t\t\t\t// ✅ グリッドをまたいだ瞬間にドラッグ確定\r\n\t\t\t\t\t\t\treturn {\r\n\t\t\t\t\t\t\t\t...prev,\r\n\t\t\t\t\t\t\t\tmode: InteractionMode.DRAGGING,\r\n\t\t\t\t\t\t\t\tdragging: {\r\n\t\t\t\t\t\t\t\t\t...prev.dragging,\r\n\t\t\t\t\t\t\t\t\tcurrentGrid: event.currentGrid,\r\n\t\t\t\t\t\t\t\t\tcurrentMousePx: event.currentMousePx, // マウス座標を追加\r\n\t\t\t\t\t\t\t\t\tisOutside: event.isOutside ?? false,\r\n\t\t\t\t\t\t\t\t},\r\n\t\t\t\t\t\t\t};\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\t// グリッド変化なしでもisOutsideは更新(範囲外判定用)\r\n\t\t\t\t\t\treturn {\r\n\t\t\t\t\t\t\t...prev,\r\n\t\t\t\t\t\t\tdragging: {\r\n\t\t\t\t\t\t\t\t...prev.dragging,\r\n\t\t\t\t\t\t\t\tcurrentGrid: event.currentGrid,\r\n\t\t\t\t\t\t\t\tcurrentMousePx: event.currentMousePx, // マウス座標を追加\r\n\t\t\t\t\t\t\t\tisOutside: event.isOutside ?? false,\r\n\t\t\t\t\t\t\t},\r\n\t\t\t\t\t\t};\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tif (prev.mode === InteractionMode.DRAGGING) {\r\n\t\t\t\t\t\t// ドラッグ中は座標とisOutsideを更新\r\n\t\t\t\t\t\treturn {\r\n\t\t\t\t\t\t\t...prev,\r\n\t\t\t\t\t\t\tdragging: {\r\n\t\t\t\t\t\t\t\t...prev.dragging,\r\n\t\t\t\t\t\t\t\tcurrentGrid: event.currentGrid,\r\n\t\t\t\t\t\t\t\tcurrentMousePx: event.currentMousePx, // マウス座標を追加\r\n\t\t\t\t\t\t\t\tisOutside: event.isOutside ?? false,\r\n\t\t\t\t\t\t\t},\r\n\t\t\t\t\t\t};\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\treturn prev;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tcase InteractionEventType.END_DRAG:\r\n\t\t\t\t\t// ドラッグ確定\r\n\t\t\t\t\treturn {\r\n\t\t\t\t\t\t...prev,\r\n\t\t\t\t\t\tmode: InteractionMode.IDLE,\r\n\t\t\t\t\t\tdragging: undefined,\r\n\t\t\t\t\t};\r\n\r\n\t\t\t\tcase InteractionEventType.CANCEL_DRAG:\r\n\t\t\t\t\t// ドラッグキャンセル (クリック扱い)\r\n\t\t\t\t\treturn {\r\n\t\t\t\t\t\t...prev,\r\n\t\t\t\t\t\tmode: InteractionMode.IDLE,\r\n\t\t\t\t\t\tdragging: undefined,\r\n\t\t\t\t\t};\r\n\r\n\t\t\t\tcase InteractionEventType.EDIT:\r\n\t\t\t\t\treturn {\r\n\t\t\t\t\t\t...prev,\r\n\t\t\t\t\t\tmode: InteractionMode.EDITING,\r\n\t\t\t\t\t\teditingBlockId: event.blockId,\r\n\t\t\t\t\t};\r\n\r\n\t\t\t\tcase InteractionEventType.END_EDIT:\r\n\t\t\t\t\treturn {\r\n\t\t\t\t\t\t...prev,\r\n\t\t\t\t\t\tmode: InteractionMode.IDLE,\r\n\t\t\t\t\t\teditingBlockId: null,\r\n\t\t\t\t\t};\r\n\r\n\t\t\t\tcase InteractionEventType.START_INSERT:\r\n\t\t\t\t\t// 挿入開始\r\n\t\t\t\t\treturn {\r\n\t\t\t\t\t\t...prev,\r\n\t\t\t\t\t\tmode: InteractionMode.DRAGGING,\r\n\t\t\t\t\t\tdragging: {\r\n\t\t\t\t\t\t\ttype: DragType.INSERT,\r\n\t\t\t\t\t\t\tblockIds: [],\r\n\t\t\t\t\t\t\tstartGrid: { col: 0, row: 0 },\r\n\t\t\t\t\t\t\tcurrentGrid: { col: 0, row: 0 },\r\n\t\t\t\t\t\t\tpluginKind: event.pluginKind,\r\n\t\t\t\t\t\t\tdefaultSize: event.defaultSize,\r\n\t\t\t\t\t\t\tisOutside: false,\r\n\t\t\t\t\t\t},\r\n\t\t\t\t\t};\r\n\r\n\t\t\t\tcase InteractionEventType.CANCEL_INSERT:\r\n\t\t\t\t\t// 挿入キャンセル\r\n\t\t\t\t\treturn {\r\n\t\t\t\t\t\t...prev,\r\n\t\t\t\t\t\tmode: InteractionMode.IDLE,\r\n\t\t\t\t\t\tdragging: undefined,\r\n\t\t\t\t\t};\r\n\r\n\t\t\t\tcase InteractionEventType.START_RESIZE: {\r\n\t\t\t\t\t// リサイズ開始\r\n\t\t\t\t\treturn {\r\n\t\t\t\t\t\t...prev,\r\n\t\t\t\t\t\tmode: InteractionMode.DRAGGING,\r\n\t\t\t\t\t\tdragging: {\r\n\t\t\t\t\t\t\ttype: DragType.RESIZE,\r\n\t\t\t\t\t\t\tblockIds: [event.blockId],\r\n\t\t\t\t\t\t\tstartGrid: event.startGrid,\r\n\t\t\t\t\t\t\tcurrentGrid: event.startGrid,\r\n\t\t\t\t\t\t\thandle: event.handle,\r\n\t\t\t\t\t\t\tisOutside: false,\r\n\t\t\t\t\t\t},\r\n\t\t\t\t\t};\r\n\t\t\t\t}\r\n\r\n\t\t\t\tdefault:\r\n\t\t\t\t\treturn prev;\r\n\t\t\t}\r\n\t\t});\r\n\t}, []);\r\n\r\n\treturn [state, handleChange] as const;\r\n}\r\n","/**\r\n * @file SelectionLayer.tsx\r\n */\r\nimport { memo } from \"react\";\r\n\r\nimport { InteractionBlock } from \"../InteractionBlock\";\r\nimport {\r\n\tinteractionZIndexs,\r\n\tRESIZE_HANDLE_STYLE,\r\n\tSELECTION_STYLE,\r\n} from \"../InteractionBlock/constants\";\r\nimport { type DraggingState, DragType, type ResizeHandle } from \"../types\";\r\n\r\nimport type React from \"react\";\r\nimport type { Block, BlockRectPx } from \"@/types/block\";\r\nimport type { BorderStyle } from \"@/types/line\";\r\n\r\nexport interface SelectionLayerProps {\r\n\tblocks: Block[];\r\n\tselectedBlockIds: string[];\r\n\tisDragging: boolean;\r\n\tdraggingState?: DraggingState;\r\n\tgetBlockRectPx: (block: Block) => BlockRectPx;\r\n\tonResizeStart: (\r\n\t\te: React.PointerEvent,\r\n\t\thandle: ResizeHandle,\r\n\t\tblockId: string,\r\n\t) => void;\r\n\tselectionStyle?: BorderStyle;\r\n\thandleStyle?: typeof RESIZE_HANDLE_STYLE;\r\n\t/** 選択枠のz-index (デフォルト: interactionZIndexs.select_border) */\r\n\tselectBorderZIndex?: number;\r\n\t/** リサイズハンドルのz-index (デフォルト: interactionZIndexs.block_handles) */\r\n\tblockHandlesZIndex?: number;\r\n}\r\n\r\nexport const SelectionLayer = memo(\r\n\t({\r\n\t\tblocks,\r\n\t\tselectedBlockIds,\r\n\t\tisDragging,\r\n\t\tdraggingState,\r\n\t\tgetBlockRectPx,\r\n\t\tonResizeStart,\r\n\t\tselectionStyle = SELECTION_STYLE,\r\n\t\thandleStyle = RESIZE_HANDLE_STYLE,\r\n\t\tselectBorderZIndex = interactionZIndexs.select_border,\r\n\t\tblockHandlesZIndex = interactionZIndexs.block_handles,\r\n\t}: SelectionLayerProps) => {\r\n\t\t// 移動中(move/insert)は枠を消す。ただしリサイズ中は枠が必要なので除外\r\n\t\tconst isMoving = isDragging && draggingState?.type !== DragType.RESIZE;\r\n\r\n\t\tif (isMoving) {\r\n\t\t\treturn null;\r\n\t\t}\r\n\r\n\t\t// 重複を除去(念のため)\r\n\t\tconst uniqueSelectedIds = Array.from(new Set(selectedBlockIds));\r\n\r\n\t\treturn (\r\n\t\t\t<div\r\n\t\t\t\tstyle={{\r\n\t\t\t\t\tposition: \"absolute\",\r\n\t\t\t\t\tinset: 0,\r\n\t\t\t\t\tpointerEvents: \"none\",\r\n\t\t\t\t}}\r\n\t\t\t>\r\n\t\t\t\t{uniqueSelectedIds.map((id) => {\r\n\t\t\t\t\tconst block = blocks.find((b) => b.id === id);\r\n\t\t\t\t\tif (!block) return null;\r\n\r\n\t\t\t\t\t// リサイズ中のハンドル特定\r\n\t\t\t\t\tconst isResizing =\r\n\t\t\t\t\t\tdraggingState?.type === DragType.RESIZE &&\r\n\t\t\t\t\t\tdraggingState.blockIds.includes(id);\r\n\t\t\t\t\tconst activeHandle = isResizing ? draggingState?.handle : null;\r\n\r\n\t\t\t\t\treturn (\r\n\t\t\t\t\t\t<InteractionBlock\r\n\t\t\t\t\t\t\tkey={block.id}\r\n\t\t\t\t\t\t\tblock={block}\r\n\t\t\t\t\t\t\trect={getBlockRectPx(block)}\r\n\t\t\t\t\t\t\tshowHandles={true}\r\n\t\t\t\t\t\t\tonResizeStart={(e, handle) => onResizeStart(e, handle, id)}\r\n\t\t\t\t\t\t\tactiveHandle={activeHandle}\r\n\t\t\t\t\t\t\tselectionStyle={selectionStyle}\r\n\t\t\t\t\t\t\thandleStyle={handleStyle}\r\n\t\t\t\t\t\t\tselectBorderZIndex={selectBorderZIndex}\r\n\t\t\t\t\t\t\tblockHandlesZIndex={blockHandlesZIndex}\r\n\t\t\t\t\t\t/>\r\n\t\t\t\t\t);\r\n\t\t\t\t})}\r\n\t\t\t</div>\r\n\t\t);\r\n\t},\r\n);\r\n\r\nSelectionLayer.displayName = \"SelectionLayer\";\r\n","/**\r\n * @file clampBlock.ts\r\n * @description ブロックをグリッド範囲内にクランプする共通ロジック\r\n *\r\n * @remarks\r\n * 移動・挿入・リサイズ時のはみ出し防止処理を集約。\r\n * DRY原則に従い、InteractionLayer内の重複コードを排除。\r\n */\r\n\r\n/**\r\n * ブロックの位置をグリッド範囲内にクランプ\r\n *\r\n * @param position - ブロックの位置 (x, y)\r\n * @param size - ブロックのサイズ (w, h)\r\n * @param gridCols - グリッドの列数\r\n * @param gridRows - グリッドの行数\r\n * @returns クランプされた位置 { x, y }\r\n *\r\n * @remarks\r\n * - x は 0 ~ (gridCols - w) の範囲にクランプ\r\n * - y は 0 ~ (gridRows - h) の範囲にクランプ\r\n * - ブロックがグリッドからはみ出さないことを保証\r\n *\r\n * @example\r\n * ```typescript\r\n * const clamped = clampBlockToGrid(\r\n * { x: -1, y: 5 },\r\n * { w: 2, h: 3 },\r\n * 10, // gridCols\r\n * 10 // gridRows\r\n * );\r\n * // => { x: 0, y: 5 }\r\n * ```\r\n */\r\nexport function clampBlockToGrid(\r\n\tposition: { x: number; y: number },\r\n\tsize: { w: number; h: number },\r\n\tgridCols: number,\r\n\tgridRows: number,\r\n): { x: number; y: number } {\r\n\tconst maxX = gridCols - size.w;\r\n\tconst maxY = gridRows - size.h;\r\n\r\n\treturn {\r\n\t\tx: Math.max(0, Math.min(position.x, maxX)),\r\n\t\ty: Math.max(0, Math.min(position.y, maxY)),\r\n\t};\r\n}\r\n","/**\r\n * @file hitTest.ts\r\n * @description 座標に基づく当たり判定ユーティリティ\r\n */\r\n\r\nimport type { Block, BlockRectPx } from \"@/types/block\";\r\n\r\n/**\r\n * 指定された座標にあるブロックを検索します\r\n *\r\n * @param point - 検索対象の座標 (Client/Offset座標ではなく、InteractionLayer内の相対座標)\r\n * @param blocks - ブロックのリスト\r\n * @param getBlockRectPx - ブロックからピクセル矩形を計算する関数 (useGridCalc由来)\r\n * @returns 見つかったブロックのID。見つからない場合は null\r\n */\r\nexport function findBlockAtPoint(\r\n\tpoint: { x: number; y: number },\r\n\tblocks: Block[],\r\n\tgetBlockRectPx: (block: Block) => BlockRectPx,\r\n): string | null {\r\n\tconst { x, y } = point;\r\n\r\n\t// Z-indexを考慮して、配列の「後ろ(描画順で手前)」から走査する\r\n\tfor (let i = blocks.length - 1; i >= 0; i--) {\r\n\t\tconst block = blocks[i];\r\n\t\tif (!block) continue;\r\n\t\tconst rect = getBlockRectPx(block);\r\n\r\n\t\tconst isInBounds =\r\n\t\t\tx >= rect.left &&\r\n\t\t\tx <= rect.left + rect.width &&\r\n\t\t\ty >= rect.top &&\r\n\t\t\ty <= rect.top + rect.height;\r\n\r\n\t\t// 矩形範囲内判定\r\n\t\tif (isInBounds) {\r\n\t\t\treturn block.id;\r\n\t\t}\r\n\t}\r\n\r\n\treturn null;\r\n}\r\n","import { memo, useCallback, useEffect, useRef } from \"react\";\r\n\r\nimport { DragLayer } from \"./DragLayer\";\r\nimport { EditingBlock } from \"./EditingBlock\";\r\nimport {\r\n\tinteractionZIndexs,\r\n\ttype RESIZE_HANDLE_STYLE,\r\n} from \"./InteractionBlock/constants\";\r\nimport { SelectionLayer } from \"./SelectionLayer\";\r\nimport { DragType, InteractionEventType, InteractionMode } from \"./types\";\r\nimport { calculateResizedLayout } from \"./utils/calcResize\";\r\nimport { clampBlockToGrid } from \"./utils/clampBlock\";\r\nimport { clampMultipleBlocks } from \"./utils/clampMultipleBlocks\";\r\nimport { findBlockAtPoint } from \"./utils/hitTest\";\r\n\r\nimport { createBlock } from \"@/plugin/utils/block\";\r\nimport { type Block, BlockChangeType, type BlockRectPx } from \"@/types/block\";\r\nimport { Z_INDEX } from \"@/utils/zIndex\";\r\n\r\nimport type { BlockPlugin, BlockRef } from \"@/plugin\";\r\nimport type { OnBlockChange } from \"@/types/callbacks\";\r\nimport type { BorderStyle } from \"@/types/line\";\r\nimport type { InteractionState, OnInteractionChange } from \"./types\";\r\n\r\n/**\r\n * InteractionLayerProps\r\n */\r\nexport interface InteractionLayerProps {\r\n\t// --- データ ---\r\n\tblocks: Block[];\r\n\tpluginRegistry: Record<string, BlockPlugin>;\r\n\tgridLength: { cols: number; rows: number };\r\n\r\n\t// --- 座標変換 ---\r\n\tgetBlockRectPx: (block: Block) => BlockRectPx;\r\n\tgetColIndex: (px: number) => number;\r\n\tgetRowIndex: (px: number) => number;\r\n\r\n\t// --- Controlled State ---\r\n\tstate: InteractionState;\r\n\tonChange: OnInteractionChange;\r\n\r\n\t// --- ブロック変更 ---\r\n\tonBlockChange?: OnBlockChange;\r\n\r\n\t// --- スケール ---\r\n\tscale?: number;\r\n\r\n\t// --- スタイル ---\r\n\tclassName?: string;\r\n\tselectionStyle?: BorderStyle;\r\n\thandleStyle?: typeof RESIZE_HANDLE_STYLE;\r\n\r\n\t// --- Z-Index (個別指定、全てオプション) ---\r\n\teditBlockZIndex?: number;\r\n\tselectBorderZIndex?: number;\r\n\tblockHandlesZIndex?: number;\r\n\tdragGhostZIndex?: number;\r\n}\r\n\r\nexport const InteractionLayer = memo(\r\n\t({\r\n\t\tblocks,\r\n\t\tpluginRegistry,\r\n\t\tgridLength,\r\n\t\tgetBlockRectPx,\r\n\t\tgetColIndex,\r\n\t\tgetRowIndex,\r\n\t\tstate,\r\n\t\tonChange,\r\n\t\tonBlockChange,\r\n\t\tscale = 1.0,\r\n\t\tclassName = \"\",\r\n\t\tselectionStyle,\r\n\t\thandleStyle,\r\n\t\teditBlockZIndex = Z_INDEX.EDIT_BLOCK,\r\n\t\tselectBorderZIndex = interactionZIndexs.select_border,\r\n\t\tblockHandlesZIndex = interactionZIndexs.block_handles,\r\n\t\tdragGhostZIndex = interactionZIndexs.block_ghost,\r\n\t}: InteractionLayerProps) => {\r\n\t\tconst layerRef = useRef<HTMLDivElement>(null);\r\n\t\tconst editingBlockRef = useRef<BlockRef>(null);\r\n\r\n\t\t// 編集モード時のフォーカス処理\r\n\t\tuseEffect(() => {\r\n\t\t\tif (state.mode === InteractionMode.EDITING && state.editingBlockId) {\r\n\t\t\t\tsetTimeout(() => {\r\n\t\t\t\t\teditingBlockRef.current?.focus();\r\n\t\t\t\t}, 0);\r\n\t\t\t}\r\n\t\t}, [state.mode, state.editingBlockId]);\r\n\r\n\t\t// ブロックが削除された時、存在しないブロックIDを選択から除外\r\n\t\tuseEffect(() => {\r\n\t\t\tconst blockIds = new Set(blocks.map((b) => b.id));\r\n\t\t\tconst validSelectedIds = state.selectedBlockIds.filter((id) =>\r\n\t\t\t\tblockIds.has(id),\r\n\t\t\t);\r\n\r\n\t\t\t// 選択中のブロックが存在しなくなった場合\r\n\t\t\tif (validSelectedIds.length !== state.selectedBlockIds.length) {\r\n\t\t\t\tonChange({\r\n\t\t\t\t\ttype: InteractionEventType.SELECT,\r\n\t\t\t\t\tblockIds: validSelectedIds,\r\n\t\t\t\t\tshiftKey: false,\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t}, [blocks, state.selectedBlockIds, onChange]);\r\n\r\n\t\t// --- PointerDown ---\r\n\t\tconst handlePointerDown = useCallback(\r\n\t\t\t(e: React.PointerEvent) => {\r\n\t\t\t\tif (e.button !== 0) return;\r\n\r\n\t\t\t\tconst rect = layerRef.current?.getBoundingClientRect();\r\n\t\t\t\tif (!rect) return;\r\n\t\t\t\tconst scaleFactor = scale ?? 1.0;\r\n\t\t\t\tconst px = {\r\n\t\t\t\t\tx: (e.clientX - rect.left) / scaleFactor,\r\n\t\t\t\t\ty: (e.clientY - rect.top) / scaleFactor,\r\n\t\t\t\t};\r\n\r\n\t\t\t\tconst targetId = findBlockAtPoint(px, blocks, getBlockRectPx);\r\n\r\n\t\t\t\t// 編集モード中の処理\r\n\t\t\t\tif (state.mode === InteractionMode.EDITING) {\r\n\t\t\t\t\t// 編集中ブロック以外をクリックした場合のみ編集終了\r\n\t\t\t\t\tif (targetId !== state.editingBlockId) {\r\n\t\t\t\t\t\tonChange({ type: InteractionEventType.END_EDIT });\r\n\t\t\t\t\t\t// 空白クリックの場合は選択も解除\r\n\t\t\t\t\t\tif (!targetId) {\r\n\t\t\t\t\t\t\tonChange({ type: InteractionEventType.DESELECT });\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tconst gridCol = getColIndex(px.x);\r\n\t\t\t\tconst gridRow = getRowIndex(px.y);\r\n\r\n\t\t\t\tif (targetId) {\r\n\t\t\t\t\te.stopPropagation();\r\n\r\n\t\t\t\t\tconst isAlreadySelected = state.selectedBlockIds.includes(targetId);\r\n\r\n\t\t\t\t\tif (isAlreadySelected && e.shiftKey) {\r\n\t\t\t\t\t\tconst newSelectedIds = state.selectedBlockIds.filter(\r\n\t\t\t\t\t\t\t(id) => id !== targetId,\r\n\t\t\t\t\t\t);\r\n\t\t\t\t\t\tonChange({\r\n\t\t\t\t\t\t\ttype: InteractionEventType.SELECT,\r\n\t\t\t\t\t\t\tblockIds: newSelectedIds,\r\n\t\t\t\t\t\t\tshiftKey: true,\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t\treturn;\r\n\t\t\t\t\t} else if (isAlreadySelected) {\r\n\t\t\t\t\t\t// 既に選択済み(Shiftなし): 複数選択状態を維持してドラッグ開始\r\n\t\t\t\t\t\t(e.currentTarget as Element).setPointerCapture(e.pointerId);\r\n\t\t\t\t\t\tonChange({\r\n\t\t\t\t\t\t\ttype: InteractionEventType.START_PRESS,\r\n\t\t\t\t\t\t\tblockId: targetId,\r\n\t\t\t\t\t\t\tstartGrid: { col: gridCol, row: gridRow },\r\n\t\t\t\t\t\t\t// 複数選択時は全選択ブロックを移動対象にする\r\n\t\t\t\t\t\t\tselectedBlockIds: state.selectedBlockIds,\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\t// 未選択: 選択してから即座にドラッグ開始\r\n\t\t\t\t\t\t(e.currentTarget as Element).setPointerCapture(e.pointerId);\r\n\t\t\t\t\t\tif (e.shiftKey) {\r\n\t\t\t\t\t\t\t// Shiftキー: 複数選択に追加\r\n\t\t\t\t\t\t\tonChange({\r\n\t\t\t\t\t\t\t\ttype: InteractionEventType.SELECT,\r\n\t\t\t\t\t\t\t\tblockIds: [...state.selectedBlockIds, targetId],\r\n\t\t\t\t\t\t\t\tshiftKey: true,\r\n\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\t// 通常クリック: 単一選択してから即座にドラッグ開始\r\n\t\t\t\t\t\t\tonChange({\r\n\t\t\t\t\t\t\t\ttype: InteractionEventType.SELECT,\r\n\t\t\t\t\t\t\t\tblockIds: [targetId],\r\n\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t\t// 選択後、即座にドラッグ可能状態に遷移\r\n\t\t\t\t\t\t\tonChange({\r\n\t\t\t\t\t\t\t\ttype: InteractionEventType.START_PRESS,\r\n\t\t\t\t\t\t\t\tblockId: targetId,\r\n\t\t\t\t\t\t\t\tstartGrid: { col: gridCol, row: gridRow },\r\n\t\t\t\t\t\t\t\tselectedBlockIds: [targetId],\r\n\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t} else {\r\n\t\t\t\t\t// 空白クリック: 選択解除\r\n\t\t\t\t\te.stopPropagation();\r\n\t\t\t\t\tonChange({ type: InteractionEventType.DESELECT });\r\n\t\t\t\t}\r\n\t\t\t},\r\n\t\t\t[\r\n\t\t\t\tblocks,\r\n\t\t\t\tgetBlockRectPx,\r\n\t\t\t\tgetColIndex,\r\n\t\t\t\tgetRowIndex,\r\n\t\t\t\tstate.mode,\r\n\t\t\t\tstate.selectedBlockIds,\r\n\t\t\t\tonChange,\r\n\t\t\t\tscale,\r\n\t\t\t\tstate.editingBlockId,\r\n\t\t\t],\r\n\t\t);\r\n\r\n\t\t// --- PointerMove ---\r\n\t\tconst handlePointerMove = useCallback(\r\n\t\t\t(e: React.PointerEvent) => {\r\n\t\t\t\tif (\r\n\t\t\t\t\tstate.mode !== InteractionMode.PRESSING &&\r\n\t\t\t\t\tstate.mode !== InteractionMode.DRAGGING\r\n\t\t\t\t)\r\n\t\t\t\t\treturn;\r\n\t\t\t\tif (!state.dragging) return;\r\n\r\n\t\t\t\tconst rect = layerRef.current?.getBoundingClientRect();\r\n\t\t\t\tif (!rect) return;\r\n\r\n\t\t\t\tconst scaleFactor = scale ?? 1.0;\r\n\t\t\t\tconst canvasWidth = rect.width / scaleFactor;\r\n\t\t\t\tconst canvasHeight = rect.height / scaleFactor;\r\n\r\n\t\t\t\t// クランプなしの生座標(範囲外判定用)\r\n\t\t\t\tconst rawX = (e.clientX - rect.left) / scaleFactor;\r\n\t\t\t\tconst rawY = (e.clientY - rect.top) / scaleFactor;\r\n\r\n\t\t\t\t// 1. 範囲外判定(リサイズ中は無視)\r\n\t\t\t\tconst isOutside =\r\n\t\t\t\t\tstate.dragging.type !== DragType.RESIZE &&\r\n\t\t\t\t\t(rawX < 0 || rawX > canvasWidth || rawY < 0 || rawY > canvasHeight);\r\n\r\n\t\t\t\t// 2. グリッド計算用にクランプ\r\n\t\t\t\tconst clampedX = Math.max(0, Math.min(rawX, canvasWidth));\r\n\t\t\t\tconst clampedY = Math.max(0, Math.min(rawY, canvasHeight));\r\n\r\n\t\t\t\tconst currentCol = getColIndex(clampedX);\r\n\t\t\t\tconst currentRow = getRowIndex(clampedY);\r\n\r\n\t\t\t\tonChange({\r\n\t\t\t\t\ttype: InteractionEventType.UPDATE_DRAG,\r\n\t\t\t\t\tcurrentGrid: { col: currentCol, row: currentRow },\r\n\t\t\t\t\tcurrentMousePx: { x: rawX, y: rawY },\r\n\t\t\t\t\tisOutside: isOutside,\r\n\t\t\t\t});\r\n\t\t\t},\r\n\t\t\t[state.mode, state.dragging, getColIndex, getRowIndex, onChange, scale],\r\n\t\t);\r\n\r\n\t\t// --- PointerUp ---\r\n\t\tconst handlePointerUp = useCallback(\r\n\t\t\t(e: React.PointerEvent) => {\r\n\t\t\t\tif (state.mode === InteractionMode.DRAGGING && state.dragging) {\r\n\t\t\t\t\t// 1. 範囲外なら処理\r\n\t\t\t\t\tif (state.dragging.isOutside) {\r\n\t\t\t\t\t\tif (state.dragging.type === DragType.MOVE) {\r\n\t\t\t\t\t\t\tonBlockChange?.({\r\n\t\t\t\t\t\t\t\ttype: BlockChangeType.DELETE,\r\n\t\t\t\t\t\t\t\tblockIds: state.dragging.blockIds,\r\n\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t\t// 削除したブロックの選択を解除\r\n\t\t\t\t\t\t\tonChange({ type: InteractionEventType.DESELECT });\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\t// INSERT/RESIZEの場合は何もしない(キャンセル)\r\n\t\t\t\t\t\tonChange({ type: InteractionEventType.END_DRAG });\r\n\t\t\t\t\t\t(e.currentTarget as Element).releasePointerCapture(e.pointerId);\r\n\t\t\t\t\t\treturn;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tconst deltaCol =\r\n\t\t\t\t\t\tstate.dragging.currentGrid.col - state.dragging.startGrid.col;\r\n\t\t\t\t\tconst deltaRow =\r\n\t\t\t\t\t\tstate.dragging.currentGrid.row - state.dragging.startGrid.row;\r\n\r\n\t\t\t\t\t// 2. 移動 (Move) の確定\r\n\t\t\t\t\tif (state.dragging.type === DragType.MOVE) {\r\n\t\t\t\t\t\tif (deltaCol !== 0 || deltaRow !== 0) {\r\n\t\t\t\t\t\t\tconst dragTargets = state.dragging.blockIds\r\n\t\t\t\t\t\t\t\t.map((id) => blocks.find((b) => b.id === id))\r\n\t\t\t\t\t\t\t\t.filter(Boolean) as Block[];\r\n\r\n\t\t\t\t\t\t\tif (dragTargets.length === 0) {\r\n\t\t\t\t\t\t\t\tonChange({ type: InteractionEventType.END_DRAG });\r\n\t\t\t\t\t\t\t\t(e.currentTarget as Element).releasePointerCapture(e.pointerId);\r\n\t\t\t\t\t\t\t\treturn;\r\n\t\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t\t// 共通のクランプ処理を使用\r\n\t\t\t\t\t\t\tconst clampedPositions = clampMultipleBlocks(\r\n\t\t\t\t\t\t\t\tdragTargets,\r\n\t\t\t\t\t\t\t\tdeltaCol,\r\n\t\t\t\t\t\t\t\tdeltaRow,\r\n\t\t\t\t\t\t\t\tgridLength.cols,\r\n\t\t\t\t\t\t\t\tgridLength.rows,\r\n\t\t\t\t\t\t\t);\r\n\r\n\t\t\t\t\t\t\t// クランプ後の座標で各ブロックを更新\r\n\t\t\t\t\t\t\tconst movedBlocks = dragTargets.map((block) => {\r\n\t\t\t\t\t\t\t\tconst clampedPos = clampedPositions.find(\r\n\t\t\t\t\t\t\t\t\t(p) => p.blockId === block.id,\r\n\t\t\t\t\t\t\t\t);\r\n\t\t\t\t\t\t\t\tif (!clampedPos) return block;\r\n\r\n\t\t\t\t\t\t\t\treturn {\r\n\t\t\t\t\t\t\t\t\t...block,\r\n\t\t\t\t\t\t\t\t\tlayout: {\r\n\t\t\t\t\t\t\t\t\t\t...block.layout,\r\n\t\t\t\t\t\t\t\t\t\tx: clampedPos.x,\r\n\t\t\t\t\t\t\t\t\t\ty: clampedPos.y,\r\n\t\t\t\t\t\t\t\t\t},\r\n\t\t\t\t\t\t\t\t};\r\n\t\t\t\t\t\t\t});\r\n\r\n\t\t\t\t\t\t\tonBlockChange?.({\r\n\t\t\t\t\t\t\t\ttype: BlockChangeType.MOVE,\r\n\t\t\t\t\t\t\t\tblockIds: state.dragging.blockIds,\r\n\t\t\t\t\t\t\t\tblocks: movedBlocks,\r\n\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t\t// 3. 挿入 (Insert) の確定\r\n\t\t\t\t\telse if (state.dragging.type === DragType.INSERT) {\r\n\t\t\t\t\t\tconst { pluginKind, currentGrid, defaultSize } = state.dragging;\r\n\t\t\t\t\t\tif (pluginKind && defaultSize) {\r\n\t\t\t\t\t\t\tconst plugin = pluginRegistry[pluginKind];\r\n\t\t\t\t\t\t\tif (plugin) {\r\n\t\t\t\t\t\t\t\t// はみ出し防止クランプ\r\n\t\t\t\t\t\t\t\tconst { x, y } = clampBlockToGrid(\r\n\t\t\t\t\t\t\t\t\t{ x: currentGrid.col, y: currentGrid.row },\r\n\t\t\t\t\t\t\t\t\t{ w: defaultSize.w, h: defaultSize.h },\r\n\t\t\t\t\t\t\t\t\tgridLength.cols,\r\n\t\t\t\t\t\t\t\t\tgridLength.rows,\r\n\t\t\t\t\t\t\t\t);\r\n\r\n\t\t\t\t\t\t\t\t// 新規ブロック作成\r\n\t\t\t\t\t\t\t\tconst newBlock = createBlock(plugin, {\r\n\t\t\t\t\t\t\t\t\tx,\r\n\t\t\t\t\t\t\t\t\ty,\r\n\t\t\t\t\t\t\t\t\tw: defaultSize.w,\r\n\t\t\t\t\t\t\t\t\th: defaultSize.h,\r\n\t\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t\t\tonBlockChange?.({\r\n\t\t\t\t\t\t\t\t\ttype: BlockChangeType.ADD,\r\n\t\t\t\t\t\t\t\t\tblockIds: [newBlock.id],\r\n\t\t\t\t\t\t\t\t\tblocks: [newBlock],\r\n\t\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t\t// 4. リサイズ (Resize) の確定\r\n\t\t\t\t\telse if (state.dragging.type === DragType.RESIZE) {\r\n\t\t\t\t\t\tconst targetId = state.dragging.blockIds[0];\r\n\t\t\t\t\t\tconst block = blocks.find((b) => b.id === targetId);\r\n\t\t\t\t\t\tconst handle = state.dragging.handle;\r\n\r\n\t\t\t\t\t\tif (block && handle && (deltaCol !== 0 || deltaRow !== 0)) {\r\n\t\t\t\t\t\t\tconst newLayout = calculateResizedLayout({\r\n\t\t\t\t\t\t\t\tlayout: block.layout,\r\n\t\t\t\t\t\t\t\thandle,\r\n\t\t\t\t\t\t\t\tdeltaCol,\r\n\t\t\t\t\t\t\t\tdeltaRow,\r\n\t\t\t\t\t\t\t\tgridCols: gridLength.cols,\r\n\t\t\t\t\t\t\t\tgridRows: gridLength.rows,\r\n\t\t\t\t\t\t\t});\r\n\r\n\t\t\t\t\t\t\t// 変更があった場合のみ通知\r\n\t\t\t\t\t\t\tif (\r\n\t\t\t\t\t\t\t\tnewLayout.x !== block.layout.x ||\r\n\t\t\t\t\t\t\t\tnewLayout.y !== block.layout.y ||\r\n\t\t\t\t\t\t\t\tnewLayout.w !== block.layout.w ||\r\n\t\t\t\t\t\t\t\tnewLayout.h !== block.layout.h\r\n\t\t\t\t\t\t\t) {\r\n\t\t\t\t\t\t\t\tonBlockChange?.({\r\n\t\t\t\t\t\t\t\t\ttype: BlockChangeType.RESIZE,\r\n\t\t\t\t\t\t\t\t\tblockIds: [block.id],\r\n\t\t\t\t\t\t\t\t\tblocks: [{ ...block, layout: newLayout }],\r\n\t\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tonChange({ type: InteractionEventType.END_DRAG });\r\n\t\t\t\t} else if (state.mode === InteractionMode.PRESSING && state.dragging) {\r\n\t\t\t\t\t// PRESSING状態でもisOutsideなら削除\r\n\t\t\t\t\tif (\r\n\t\t\t\t\t\tstate.dragging.isOutside &&\r\n\t\t\t\t\t\tstate.dragging.type === DragType.MOVE\r\n\t\t\t\t\t) {\r\n\t\t\t\t\t\tonBlockChange?.({\r\n\t\t\t\t\t\t\ttype: BlockChangeType.DELETE,\r\n\t\t\t\t\t\t\tblockIds: state.dragging.blockIds,\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t\t// 削除したブロックの選択を解除\r\n\t\t\t\t\t\tonChange({ type: InteractionEventType.DESELECT });\r\n\t\t\t\t\t}\r\n\t\t\t\t\tonChange({ type: InteractionEventType.CANCEL_DRAG });\r\n\t\t\t\t}\r\n\r\n\t\t\t\t(e.currentTarget as Element).releasePointerCapture(e.pointerId);\r\n\t\t\t},\r\n\t\t\t[\r\n\t\t\t\tstate.mode,\r\n\t\t\t\tstate.dragging,\r\n\t\t\t\tblocks,\r\n\t\t\t\tgridLength,\r\n\t\t\t\tpluginRegistry,\r\n\t\t\t\tonBlockChange,\r\n\t\t\t\tonChange,\r\n\t\t\t],\r\n\t\t);\r\n\r\n\t\t// --- DoubleClick ---\r\n\t\tconst handleDoubleClick = useCallback(\r\n\t\t\t(e: React.MouseEvent) => {\r\n\t\t\t\tconst rect = layerRef.current?.getBoundingClientRect();\r\n\t\t\t\tif (!rect) return;\r\n\r\n\t\t\t\tconst scaleFactor = scale ?? 1.0;\r\n\t\t\t\tconst px = {\r\n\t\t\t\t\tx: (e.clientX - rect.left) / scaleFactor,\r\n\t\t\t\t\ty: (e.clientY - rect.top) / scaleFactor,\r\n\t\t\t\t};\r\n\r\n\t\t\t\tconst targetId = findBlockAtPoint(px, blocks, getBlockRectPx);\r\n\r\n\t\t\t\tif (targetId) {\r\n\t\t\t\t\t// ブロックが選択されていない場合は先に選択\r\n\t\t\t\t\tif (!state.selectedBlockIds.includes(targetId)) {\r\n\t\t\t\t\t\tonChange({\r\n\t\t\t\t\t\t\ttype: InteractionEventType.SELECT,\r\n\t\t\t\t\t\t\tblockIds: [targetId],\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t}\r\n\t\t\t\t\tonChange({ type: InteractionEventType.EDIT, blockId: targetId });\r\n\t\t\t\t}\r\n\t\t\t},\r\n\t\t\t[blocks, getBlockRectPx, onChange, scale, state.selectedBlockIds],\r\n\t\t);\r\n\r\n\t\t// キャンバス外処理\r\n\t\tconst handlePointerLeave = useCallback(\r\n\t\t\t(e: React.PointerEvent) => {\r\n\t\t\t\t// キャンバスを出た場合の処理\r\n\t\t\t\tif (\r\n\t\t\t\t\t(state.mode === InteractionMode.PRESSING ||\r\n\t\t\t\t\t\tstate.mode === InteractionMode.DRAGGING) &&\r\n\t\t\t\t\tstate.dragging\r\n\t\t\t\t) {\r\n\t\t\t\t\tconst rect = layerRef.current?.getBoundingClientRect();\r\n\t\t\t\t\tif (rect) {\r\n\t\t\t\t\t\tconst scaleFactor = scale ?? 1.0;\r\n\t\t\t\t\t\tconst rawX = (e.clientX - rect.left) / scaleFactor;\r\n\t\t\t\t\t\tconst rawY = (e.clientY - rect.top) / scaleFactor;\r\n\t\t\t\t\t\tconst canvasWidth = rect.width / scaleFactor;\r\n\t\t\t\t\t\tconst canvasHeight = rect.height / scaleFactor;\r\n\t\t\t\t\t\tconst clampedX = Math.max(0, Math.min(rawX, canvasWidth));\r\n\t\t\t\t\t\tconst clampedY = Math.max(0, Math.min(rawY, canvasHeight));\r\n\r\n\t\t\t\t\t\t// isOutside=trueを設定してゴーストをマウス追従モードに\r\n\t\t\t\t\t\tonChange({\r\n\t\t\t\t\t\t\ttype: InteractionEventType.UPDATE_DRAG,\r\n\t\t\t\t\t\t\tcurrentGrid: {\r\n\t\t\t\t\t\t\t\tcol: getColIndex(clampedX),\r\n\t\t\t\t\t\t\t\trow: getRowIndex(clampedY),\r\n\t\t\t\t\t\t\t},\r\n\t\t\t\t\t\t\tcurrentMousePx: { x: rawX, y: rawY },\r\n\t\t\t\t\t\t\tisOutside: true,\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t},\r\n\t\t\t[state.mode, state.dragging, scale, getColIndex, getRowIndex, onChange],\r\n\t\t);\r\n\t\treturn (\r\n\t\t\t<div\r\n\t\t\t\tref={layerRef}\r\n\t\t\t\tclassName={className}\r\n\t\t\t\tstyle={{\r\n\t\t\t\t\tposition: \"absolute\",\r\n\t\t\t\t\tinset: 0,\r\n\t\t\t\t\tzIndex: Z_INDEX.INTERACTION_LAYER_BASE,\r\n\t\t\t\t\tpointerEvents: \"auto\",\r\n\t\t\t\t\ttouchAction: \"none\",\r\n\t\t\t\t}}\r\n\t\t\t\trole=\"application\"\r\n\t\t\t\taria-label=\"Interactive canvas layer\"\r\n\t\t\t\ttabIndex={-1}\r\n\t\t\t\tonPointerDown={handlePointerDown}\r\n\t\t\t\tonPointerMove={handlePointerMove}\r\n\t\t\t\tonPointerUp={handlePointerUp}\r\n\t\t\t\tonPointerLeave={handlePointerLeave}\r\n\t\t\t\tonDoubleClick={handleDoubleClick}\r\n\t\t\t\tdata-testid=\"interaction-layer\"\r\n\t\t\t>\r\n\t\t\t\t{/* 編集中ブロックのRenderer (InteractionLayer上で表示) */}\r\n\t\t\t\t{state.editingBlockId &&\r\n\t\t\t\t\t(() => {\r\n\t\t\t\t\t\tconst editingBlock = blocks.find(\r\n\t\t\t\t\t\t\t(b) => b.id === state.editingBlockId,\r\n\t\t\t\t\t\t);\r\n\t\t\t\t\t\tconst plugin = editingBlock\r\n\t\t\t\t\t\t\t? pluginRegistry[editingBlock.kind]\r\n\t\t\t\t\t\t\t: null;\r\n\r\n\t\t\t\t\t\tif (!editingBlock || !plugin) return null;\r\n\r\n\t\t\t\t\t\treturn (\r\n\t\t\t\t\t\t\t<EditingBlock\r\n\t\t\t\t\t\t\t\tref={editingBlockRef}\r\n\t\t\t\t\t\t\t\tid={editingBlock.id}\r\n\t\t\t\t\t\t\t\tplugin={plugin}\r\n\t\t\t\t\t\t\t\tprops={editingBlock.props}\r\n\t\t\t\t\t\t\t\tvalue={editingBlock.initValue}\r\n\t\t\t\t\t\t\t\tonChange={(val) => {\r\n\t\t\t\t\t\t\t\t\tonBlockChange?.({\r\n\t\t\t\t\t\t\t\t\t\ttype: BlockChangeType.UPDATE,\r\n\t\t\t\t\t\t\t\t\t\tblockIds: [editingBlock.id],\r\n\t\t\t\t\t\t\t\t\t\tblocks: [{ ...editingBlock, initValue: val }],\r\n\t\t\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t\t\t}}\r\n\t\t\t\t\t\t\t\tonBlur={(val) => {\r\n\t\t\t\t\t\t\t\t\tonBlockChange?.({\r\n\t\t\t\t\t\t\t\t\t\ttype: BlockChangeType.UPDATE,\r\n\t\t\t\t\t\t\t\t\t\tblockIds: [editingBlock.id],\r\n\t\t\t\t\t\t\t\t\t\tblocks: [{ ...editingBlock, initValue: val }],\r\n\t\t\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t\t\t}}\r\n\t\t\t\t\t\t\t\tblockRectPx={getBlockRectPx(editingBlock)}\r\n\t\t\t\t\t\t\t\tzIndex={editBlockZIndex}\r\n\t\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t);\r\n\t\t\t\t\t})()}\r\n\r\n\t\t\t\t{/* 選択枠 */}\r\n\t\t\t\t<SelectionLayer\r\n\t\t\t\t\tblocks={blocks}\r\n\t\t\t\t\tselectedBlockIds={state.selectedBlockIds}\r\n\t\t\t\t\tisDragging={state.mode === InteractionMode.DRAGGING}\r\n\t\t\t\t\tdraggingState={state.dragging}\r\n\t\t\t\t\tgetBlockRectPx={getBlockRectPx}\r\n\t\t\t\t\tonResizeStart={(e, handle, blockId) => {\r\n\t\t\t\t\t\tconst rect = layerRef.current?.getBoundingClientRect();\r\n\t\t\t\t\t\tif (!rect) return;\r\n\r\n\t\t\t\t\t\t// リサイズ開始時に編集モードを終了\r\n\t\t\t\t\t\tif (state.mode === InteractionMode.EDITING) {\r\n\t\t\t\t\t\t\tonChange({ type: InteractionEventType.END_EDIT });\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t// Pointer Captureを設定(ハンドルから外れても追従)\r\n\t\t\t\t\t\t(e.currentTarget as Element).setPointerCapture(e.pointerId);\r\n\r\n\t\t\t\t\t\tconst scaleFactor = scale ?? 1.0;\r\n\t\t\t\t\t\tconst px = {\r\n\t\t\t\t\t\t\tx: (e.clientX - rect.left) / scaleFactor,\r\n\t\t\t\t\t\t\ty: (e.clientY - rect.top) / scaleFactor,\r\n\t\t\t\t\t\t};\r\n\r\n\t\t\t\t\t\tonChange({\r\n\t\t\t\t\t\t\ttype: InteractionEventType.START_RESIZE,\r\n\t\t\t\t\t\t\tblockId,\r\n\t\t\t\t\t\t\thandle,\r\n\t\t\t\t\t\t\tstartGrid: { col: getColIndex(px.x), row: getRowIndex(px.y) },\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t}}\r\n\t\t\t\t\tselectionStyle={selectionStyle}\r\n\t\t\t\t\thandleStyle={handleStyle}\r\n\t\t\t\t\tselectBorderZIndex={selectBorderZIndex}\r\n\t\t\t\t\tblockHandlesZIndex={blockHandlesZIndex}\r\n\t\t\t\t/>\r\n\r\n\t\t\t\t{/* ドラッグ時のゴースト */}\r\n\t\t\t\t<DragLayer\r\n\t\t\t\t\tblocks={blocks}\r\n\t\t\t\t\tpluginRegistry={pluginRegistry}\r\n\t\t\t\t\tgridLength={gridLength}\r\n\t\t\t\t\tdraggingState={state.dragging}\r\n\t\t\t\t\tgetBlockRectPx={getBlockRectPx}\r\n\t\t\t\t\tselectionStyle={selectionStyle}\r\n\t\t\t\t\tghostZIndex={dragGhostZIndex}\r\n\t\t\t\t\tselectBorderZIndex={selectBorderZIndex}\r\n\t\t\t\t\tblockHandlesZIndex={blockHandlesZIndex}\r\n\t\t\t\t/>\r\n\t\t\t</div>\r\n\t\t);\r\n\t},\r\n);\r\n\r\nInteractionLayer.displayName = \"InteractionLayer\";\r\n","import { useCallback, useMemo } from \"react\";\r\n\r\nimport { DEFAULT_DPI } from \"@/constants\";\r\nimport { toMm, toPx } from \"@/utils\";\r\nimport { findGridIndex, getMaxStep, gridToMms, mmsToPxs } from \"@/utils/grid\";\r\n\r\nimport type {\r\n\tBlock,\r\n\tBlockRectPx,\r\n\tGrid,\r\n\tGridPosPx,\r\n\tPaper,\r\n\tPaperCanvasPx,\r\n\tPaperMarginPx,\r\n\tPaperPx,\r\n} from \"@/types\";\r\n\r\nexport function useGridCalc(\r\n\tpaper: Paper,\r\n\tgrid: Grid,\r\n\tdpi: number = DEFAULT_DPI,\r\n) {\r\n\t// Paperをmm単位で保持\r\n\tconst canvasWidthMm = useMemo(\r\n\t\t() => toMm.fromDim(paper.size.width),\r\n\t\t[paper.size.width],\r\n\t);\r\n\tconst canvasHeightMm = useMemo(\r\n\t\t() => toMm.fromDim(paper.size.height),\r\n\t\t[paper.size.height],\r\n\t);\r\n\tconst marginTopMm = useMemo(\r\n\t\t() => toMm.fromDim(paper.margin.top),\r\n\t\t[paper.margin.top],\r\n\t);\r\n\tconst marginBottomMm = useMemo(\r\n\t\t() => toMm.fromDim(paper.margin.bottom),\r\n\t\t[paper.margin.bottom],\r\n\t);\r\n\tconst marginLeftMm = useMemo(\r\n\t\t() => toMm.fromDim(paper.margin.left),\r\n\t\t[paper.margin.left],\r\n\t);\r\n\tconst marginRightMm = useMemo(\r\n\t\t() => toMm.fromDim(paper.margin.right),\r\n\t\t[paper.margin.right],\r\n\t);\r\n\r\n\t// 描画領域の寸法をmm単位で計算\r\n\tconst contentWidthMm = useMemo(\r\n\t\t() => canvasWidthMm - marginLeftMm - marginRightMm,\r\n\t\t[canvasWidthMm, marginLeftMm, marginRightMm],\r\n\t);\r\n\tconst contentHeightMm = useMemo(\r\n\t\t() => canvasHeightMm - marginTopMm - marginBottomMm,\r\n\t\t[canvasHeightMm, marginTopMm, marginBottomMm],\r\n\t);\r\n\r\n\t// Gridをmm単位で保持\r\n\tconst colMms = useMemo(\r\n\t\t() => gridToMms(grid.cols, contentWidthMm),\r\n\t\t[grid.cols, contentWidthMm],\r\n\t);\r\n\tconst rowMms = useMemo(\r\n\t\t() => gridToMms(grid.rows, contentHeightMm),\r\n\t\t[grid.rows, contentHeightMm],\r\n\t);\r\n\r\n\t// Paperをpx単位で保持\r\n\tconst canvasWidthPx = useMemo(\r\n\t\t() => toPx.fromMm(canvasWidthMm, dpi),\r\n\t\t[canvasWidthMm, dpi],\r\n\t);\r\n\tconst canvasHeightPx = useMemo(\r\n\t\t() => toPx.fromMm(canvasHeightMm, dpi),\r\n\t\t[canvasHeightMm, dpi],\r\n\t);\r\n\tconst marginTopPx = useMemo(\r\n\t\t() => toPx.fromMm(marginTopMm, dpi),\r\n\t\t[marginTopMm, dpi],\r\n\t);\r\n\tconst marginBottomPx = useMemo(\r\n\t\t() => toPx.fromMm(marginBottomMm, dpi),\r\n\t\t[marginBottomMm, dpi],\r\n\t);\r\n\tconst marginLeftPx = useMemo(\r\n\t\t() => toPx.fromMm(marginLeftMm, dpi),\r\n\t\t[marginLeftMm, dpi],\r\n\t);\r\n\tconst marginRightPx = useMemo(\r\n\t\t() => toPx.fromMm(marginRightMm, dpi),\r\n\t\t[marginRightMm, dpi],\r\n\t);\r\n\r\n\t// 描画領域の寸法をpx単位で計算\r\n\tconst contentWidthPx = useMemo(\r\n\t\t() => toPx.fromMm(contentWidthMm, dpi),\r\n\t\t[contentWidthMm, dpi],\r\n\t);\r\n\tconst contentHeightPx = useMemo(\r\n\t\t() => toPx.fromMm(contentHeightMm, dpi),\r\n\t\t[contentHeightMm, dpi],\r\n\t);\r\n\r\n\t// Gridをpx単位で保持\r\n\tconst colPxs = useMemo(() => mmsToPxs(colMms, dpi), [colMms, dpi]);\r\n\tconst rowPxs = useMemo(() => mmsToPxs(rowMms, dpi), [rowMms, dpi]);\r\n\r\n\t// Gridのスタート位置を累積和配列で保持\r\n\tconst colPosPxs = useMemo(() => {\r\n\t\tconst starts = [0];\r\n\t\tfor (const width of colPxs) {\r\n\t\t\tconst last = starts[starts.length - 1] ?? 0;\r\n\t\t\tstarts.push(last + width);\r\n\t\t}\r\n\t\treturn starts;\r\n\t}, [colPxs]);\r\n\tconst rowPosPxs = useMemo(() => {\r\n\t\tconst starts = [0];\r\n\t\tfor (const height of rowPxs) {\r\n\t\t\tconst last = starts[starts.length - 1] ?? 0;\r\n\t\t\tstarts.push(last + height);\r\n\t\t}\r\n\t\treturn starts;\r\n\t}, [rowPxs]);\r\n\r\n\t// pxからグリッドの列・行番号を取得する関数\r\n\tconst { step: colMaxStep, windowPx: colWindowPx } = useMemo(\r\n\t\t() => getMaxStep(colPosPxs),\r\n\t\t[colPosPxs],\r\n\t);\r\n\tconst { step: rowMaxStep, windowPx: rowWindowPx } = useMemo(\r\n\t\t() => getMaxStep(rowPosPxs),\r\n\t\t[rowPosPxs],\r\n\t);\r\n\tconst colIndexer = useMemo(\r\n\t\t() => findGridIndex(colPosPxs, colMaxStep, colWindowPx),\r\n\t\t[colPosPxs, colMaxStep, colWindowPx],\r\n\t);\r\n\tconst rowIndexer = useMemo(\r\n\t\t() => findGridIndex(rowPosPxs, rowMaxStep, rowWindowPx),\r\n\t\t[rowPosPxs, rowMaxStep, rowWindowPx],\r\n\t);\r\n\tconst getColIndex = useCallback(\r\n\t\t(px: number) => colIndexer(px - marginLeftPx),\r\n\t\t[colIndexer, marginLeftPx],\r\n\t);\r\n\tconst getRowIndex = useCallback(\r\n\t\t(px: number) => rowIndexer(px - marginTopPx),\r\n\t\t[rowIndexer, marginTopPx],\r\n\t);\r\n\r\n\t// 変数まとめ\r\n\tconst gridPosPx = useMemo(() => {\r\n\t\treturn {\r\n\t\t\tcols: colPosPxs,\r\n\t\t\trows: rowPosPxs,\r\n\t\t} as GridPosPx;\r\n\t}, [colPosPxs, rowPosPxs]);\r\n\r\n\tconst paperCanvasPx = useMemo(() => {\r\n\t\treturn {\r\n\t\t\twidth: canvasWidthPx,\r\n\t\t\theight: canvasHeightPx,\r\n\t\t} as PaperCanvasPx;\r\n\t}, [canvasWidthPx, canvasHeightPx]);\r\n\r\n\tconst paperMarginPx = useMemo(() => {\r\n\t\treturn {\r\n\t\t\ttop: marginTopPx,\r\n\t\t\tbottom: marginBottomPx,\r\n\t\t\tleft: marginLeftPx,\r\n\t\t\tright: marginRightPx,\r\n\t\t} as PaperMarginPx;\r\n\t}, [marginTopPx, marginBottomPx, marginLeftPx, marginRightPx]);\r\n\r\n\tconst paperContentPx = useMemo(() => {\r\n\t\treturn {\r\n\t\t\twidth: contentWidthPx,\r\n\t\t\theight: contentHeightPx,\r\n\t\t};\r\n\t}, [contentWidthPx, contentHeightPx]);\r\n\r\n\tconst paperPx = useMemo(() => {\r\n\t\treturn {\r\n\t\t\tcanvas: paperCanvasPx,\r\n\t\t\tmargin: paperMarginPx,\r\n\t\t\tcontent: paperContentPx,\r\n\t\t} as PaperPx;\r\n\t}, [paperCanvasPx, paperMarginPx, paperContentPx]);\r\n\r\n\tconst getBlockRectPx = useCallback(\r\n\t\t(block: Block): BlockRectPx => {\r\n\t\t\tconst { x, y, w, h } = block.layout;\r\n\t\t\tconst colLines = gridPosPx.cols;\r\n\t\t\tconst rowLines = gridPosPx.rows;\r\n\r\n\t\t\t// 安全策: グリッド定義がない場合は0を返す\r\n\t\t\tif (!colLines.length || !rowLines.length) {\r\n\t\t\t\treturn { left: 0, top: 0, width: 0, height: 0 };\r\n\t\t\t}\r\n\r\n\t\t\t// インデックス範囲制限 (clamp)\r\n\t\t\tconst x1 = Math.min(Math.max(0, x), colLines.length - 1);\r\n\t\t\tconst x2 = Math.min(Math.max(0, x + w), colLines.length - 1);\r\n\t\t\tconst y1 = Math.min(Math.max(0, y), rowLines.length - 1);\r\n\t\t\tconst y2 = Math.min(Math.max(0, y + h), rowLines.length - 1);\r\n\r\n\t\t\tconst left = (colLines[x1] ?? 0) + marginLeftPx;\r\n\t\t\tconst top = (rowLines[y1] ?? 0) + marginTopPx;\r\n\t\t\tconst width = (colLines[x2] ?? 0) - (colLines[x1] ?? 0);\r\n\t\t\tconst height = (rowLines[y2] ?? 0) - (rowLines[y1] ?? 0);\r\n\r\n\t\t\treturn { left, top, width, height };\r\n\t\t},\r\n\t\t[gridPosPx, marginLeftPx, marginTopPx],\r\n\t);\r\n\r\n\treturn {\r\n\t\tpaperPx,\r\n\t\tgridPosPx,\r\n\t\tgetColIndex,\r\n\t\tgetRowIndex,\r\n\t\tgetBlockRectPx,\r\n\t};\r\n}\r\n","/**\r\n * @file NoteEdit.tsx\r\n * @description 値入力モード(Editモード)専用コンポーネント\r\n * - ブロックの配置・サイズ変更は不可\r\n * - 直接valueを編集可能\r\n * - InteractionLayerなし(pointerEvents常に\"auto\")\r\n */\r\n\r\nimport { memo, useCallback } from \"react\";\r\n\r\nimport { BlockLayer } from \"./BlockLayer\";\r\nimport { GridLayer } from \"./GridLayer\";\r\n\r\nimport { DEFAULT_DPI } from \"@/constants\";\r\nimport { useGridCalc } from \"@/hooks/useGridCalc\";\r\nimport { NoteMode } from \"@/types/mode\";\r\n\r\nimport type { BlockPlugin } from \"@/plugin\";\r\nimport type { OnChange } from \"@/types/callbacks\";\r\nimport type { FormSchema } from \"@/types/schema\";\r\nimport type { Value } from \"@/types/value\";\r\n\r\nexport interface NoteEditProps {\r\n\tschema: FormSchema;\r\n\tvalues: Record<string, Value>;\r\n\tpluginRegistry: Record<string, BlockPlugin>;\r\n\tonValueChange?: OnChange;\r\n\tscale?: number;\r\n\tclassName?: string;\r\n}\r\n\r\nconst NoteEditBase = ({\r\n\tschema,\r\n\tvalues,\r\n\tpluginRegistry,\r\n\tonValueChange,\r\n\tscale = 1.0,\r\n\tclassName,\r\n}: NoteEditProps) => {\r\n\tconst { paperPx, gridPosPx, getBlockRectPx } = useGridCalc(\r\n\t\tschema.paper,\r\n\t\tschema.grid,\r\n\t\tDEFAULT_DPI,\r\n\t);\r\n\r\n\t// 値変更ハンドラ\r\n\tconst handleValueChange = useCallback(\r\n\t\t(id: string, val: Value) => {\r\n\t\t\tif (!onValueChange) return;\r\n\t\t\tonValueChange(id, val);\r\n\t\t},\r\n\t\t[onValueChange],\r\n\t);\r\n\r\n\treturn (\r\n\t\t<div\r\n\t\t\tclassName={className}\r\n\t\t\tstyle={{\r\n\t\t\t\tposition: \"relative\",\r\n\t\t\t\twidth: `${paperPx.canvas.width}px`,\r\n\t\t\t\theight: `${paperPx.canvas.height}px`,\r\n\t\t\t\tmargin: \"0 auto\",\r\n\t\t\t\tboxShadow: \"0 2px 8px rgba(0,0,0,0.1)\",\r\n\t\t\t\tbackgroundColor: \"#fff\",\r\n\t\t\t\ttransform: scale !== 1 ? `scale(${scale})` : undefined,\r\n\t\t\t\ttransformOrigin: \"top center\",\r\n\t\t\t}}\r\n\t\t>\r\n\t\t\t<GridLayer\r\n\t\t\t\tpaperPx={paperPx}\r\n\t\t\t\tgridPosPxs={gridPosPx}\r\n\t\t\t\tshowGridLines={false}\r\n\t\t\t\tshowMargins={false}\r\n\t\t\t\tshowBorder={false}\r\n\t\t\t/>\r\n\r\n\t\t\t<BlockLayer\r\n\t\t\t\tblocks={schema.blocks}\r\n\t\t\t\tpluginRegistry={pluginRegistry}\r\n\t\t\t\tmode={NoteMode.EDIT}\r\n\t\t\t\tvalues={values}\r\n\t\t\t\tgetBlockRectPx={getBlockRectPx}\r\n\t\t\t\tonValueChange={handleValueChange}\r\n\t\t\t\tshowGuides={true}\r\n\t\t\t\tshowBorder={true}\r\n\t\t\t/>\r\n\t\t</div>\r\n\t);\r\n};\r\n\r\nNoteEditBase.displayName = \"NoteEdit\";\r\n\r\nexport const NoteEdit = memo(NoteEditBase);\r\n","/**\r\n * @file NoteForm.tsx\r\n * @description テンプレート作成モード(Formモード)専用コンポーネント\r\n * - ブロックの配置・サイズ変更が可能\r\n * - ダブルクリックでinitValueを編集\r\n * - InteractionLayerが有効\r\n */\r\n\r\nimport { memo, useCallback, useEffect, useMemo, useRef } from \"react\";\r\n\r\nimport { BlockLayer } from \"./BlockLayer\";\r\nimport { GridLayer } from \"./GridLayer\";\r\nimport {\r\n\tDragType,\r\n\tInteractionEventType,\r\n\tInteractionLayer,\r\n\tInteractionMode,\r\n\tuseInteractionState,\r\n} from \"./InteractionLayer\";\r\n\r\nimport { DEFAULT_DPI } from \"@/constants\";\r\nimport { useGridCalc } from \"@/hooks/useGridCalc\";\r\nimport { BlockChangeType } from \"@/types\";\r\nimport { LineType } from \"@/types/line\";\r\nimport { NoteMode } from \"@/types/mode\";\r\nimport { globalDragStore } from \"@/utils/GlobalDragStore\";\r\nimport { calculateGridResize } from \"@/utils/grid\";\r\nimport { removeUndefinedProps } from \"@/utils/objectUtils\";\r\n\r\nimport type { BlockPlugin } from \"@/plugin\";\r\nimport type { OnBlockChange, OnSchemaChange } from \"@/types/callbacks\";\r\nimport type { FormSchema } from \"@/types/schema\";\r\nimport type { Value } from \"@/types/value\";\r\n\r\nexport interface NoteFormProps {\r\n\tschema: FormSchema;\r\n\tpluginRegistry: Record<string, BlockPlugin>;\r\n\tonSchemaChange?: OnSchemaChange;\r\n\tonSelectionChange?: (selectedBlockIds: string[]) => void;\r\n\tscale?: number;\r\n\tclassName?: string;\r\n}\r\n\r\nconst NoteFormBase = ({\r\n\tschema,\r\n\tpluginRegistry,\r\n\tonSchemaChange,\r\n\tonSelectionChange,\r\n\tscale = 1.0,\r\n\tclassName,\r\n}: NoteFormProps) => {\r\n\t// ✅ 新しいHookで状態管理\r\n\tconst [interactionState, handleInteractionChange] = useInteractionState();\r\n\r\n\t// 用紙要素への参照\r\n\tconst paperRef = useRef<HTMLDivElement>(null);\r\n\r\n\tconst { paperPx, gridPosPx, getBlockRectPx, getColIndex, getRowIndex } =\r\n\t\tuseGridCalc(schema.paper, schema.grid, DEFAULT_DPI);\r\n\r\n\t// ブロック配置変更ハンドラ\r\n\tconst handleBlockChange: OnBlockChange = useCallback(\r\n\t\t(event) => {\r\n\t\t\tif (!onSchemaChange) return;\r\n\r\n\t\t\tswitch (event.type) {\r\n\t\t\t\tcase BlockChangeType.MOVE:\r\n\t\t\t\tcase BlockChangeType.RESIZE: {\r\n\t\t\t\t\tif (!event.blocks) return;\r\n\t\t\t\t\tconst nextBlocks = schema.blocks.map((block) => {\r\n\t\t\t\t\t\tconst updated = event.blocks?.find((b) => b.id === block.id);\r\n\t\t\t\t\t\treturn updated || block;\r\n\t\t\t\t\t});\r\n\t\t\t\t\tonSchemaChange({ ...schema, blocks: nextBlocks });\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tcase BlockChangeType.ADD: {\r\n\t\t\t\t\tif (!event.blocks) return;\r\n\t\t\t\t\tonSchemaChange({\r\n\t\t\t\t\t\t...schema,\r\n\t\t\t\t\t\tblocks: [...schema.blocks, ...event.blocks],\r\n\t\t\t\t\t});\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tcase BlockChangeType.DELETE: {\r\n\t\t\t\t\tconst deletedIds = new Set(event.blockIds);\r\n\t\t\t\t\tconst nextBlocks = schema.blocks.filter(\r\n\t\t\t\t\t\t(block) => !deletedIds.has(block.id),\r\n\t\t\t\t\t);\r\n\t\t\t\t\tonSchemaChange({ ...schema, blocks: nextBlocks });\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tcase BlockChangeType.UPDATE: {\r\n\t\t\t\t\tif (!event.blocks) return;\r\n\t\t\t\t\tconst nextBlocks = schema.blocks.map((block) => {\r\n\t\t\t\t\t\tconst updated = event.blocks?.find((b) => b.id === block.id);\r\n\t\t\t\t\t\tif (!updated) return block;\r\n\r\n\t\t\t\t\t\t// styleやpropsからundefined/nullプロパティを削除\r\n\t\t\t\t\t\tconst cleanedStyle = updated.style\r\n\t\t\t\t\t\t\t? (removeUndefinedProps(\r\n\t\t\t\t\t\t\t\t\tupdated.style as Record<string, unknown>,\r\n\t\t\t\t\t\t\t\t) as typeof updated.style)\r\n\t\t\t\t\t\t\t: updated.style;\r\n\r\n\t\t\t\t\t\tconst cleanedProps = updated.props\r\n\t\t\t\t\t\t\t? (removeUndefinedProps(\r\n\t\t\t\t\t\t\t\t\tupdated.props as Record<string, unknown>,\r\n\t\t\t\t\t\t\t\t) as typeof updated.props)\r\n\t\t\t\t\t\t\t: updated.props;\r\n\r\n\t\t\t\t\t\treturn {\r\n\t\t\t\t\t\t\t...block,\r\n\t\t\t\t\t\t\t...updated,\r\n\t\t\t\t\t\t\tstyle: cleanedStyle,\r\n\t\t\t\t\t\t\tprops: cleanedProps,\r\n\t\t\t\t\t\t};\r\n\t\t\t\t\t});\r\n\t\t\t\t\tonSchemaChange({ ...schema, blocks: nextBlocks });\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tdefault:\r\n\t\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t},\r\n\t\t[schema, onSchemaChange],\r\n\t);\r\n\r\n\t// initValue変更ハンドラ(ダブルクリックで編集時)\r\n\tconst handleInitValueChange = useCallback(\r\n\t\t(id: string, val: Value) => {\r\n\t\t\tif (!onSchemaChange) return;\r\n\t\t\tconst nextBlocks = schema.blocks.map((block) => {\r\n\t\t\t\tif (block.id === id) {\r\n\t\t\t\t\treturn { ...block, initValue: val };\r\n\t\t\t\t}\r\n\t\t\t\treturn block;\r\n\t\t\t});\r\n\t\t\tonSchemaChange({ ...schema, blocks: nextBlocks });\r\n\t\t},\r\n\t\t[schema, onSchemaChange],\r\n\t);\r\n\r\n\t// 選択状態の変更を通知\r\n\tuseEffect(() => {\r\n\t\tif (onSelectionChange) {\r\n\t\t\tonSelectionChange(interactionState.selectedBlockIds);\r\n\t\t}\r\n\t}, [interactionState.selectedBlockIds, onSelectionChange]);\r\n\r\n\t// globalDragStoreの状態を監視し、ドラッグ終了時にINSERT操作をキャンセル\r\n\tuseEffect(() => {\r\n\t\tconst unsubscribe = globalDragStore.subscribe((dragState) => {\r\n\t\t\t// グローバルドラッグが終了し、かつINSERT操作中の場合はキャンセル\r\n\t\t\tif (\r\n\t\t\t\t!dragState &&\r\n\t\t\t\tinteractionState.mode === InteractionMode.DRAGGING &&\r\n\t\t\t\tinteractionState.dragging?.type === DragType.INSERT\r\n\t\t\t) {\r\n\t\t\t\thandleInteractionChange({ type: InteractionEventType.CANCEL_INSERT });\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\treturn () => unsubscribe();\r\n\t}, [\r\n\t\tinteractionState.mode,\r\n\t\tinteractionState.dragging,\r\n\t\thandleInteractionChange,\r\n\t]);\r\n\r\n\t// 用紙外のクリックを検知して選択を解除\r\n\tuseEffect(() => {\r\n\t\tconst handleClickOutside = (event: MouseEvent) => {\r\n\t\t\t// ブロックが選択されていない場合は何もしない\r\n\t\t\tif (interactionState.selectedBlockIds.length === 0) return;\r\n\r\n\t\t\t// クリックされた要素を取得\r\n\t\t\tconst target = event.target as Node;\r\n\r\n\t\t\t// 1. まずSidebar内のクリックかチェック(最優先で除外)\r\n\t\t\tif (target instanceof HTMLElement) {\r\n\t\t\t\tconst isSidebar = target.closest('[data-sidebar=\"true\"]');\r\n\t\t\t\tif (isSidebar) return;\r\n\t\t\t}\r\n\r\n\t\t\t// 2. 用紙要素が存在し、クリックが用紙の外側の場合のみ選択解除\r\n\t\t\tif (paperRef.current && !paperRef.current.contains(target)) {\r\n\t\t\t\thandleInteractionChange({ type: InteractionEventType.DESELECT });\r\n\t\t\t}\r\n\t\t};\r\n\r\n\t\t// documentにイベントリスナーを追加\r\n\t\tdocument.addEventListener(\"mousedown\", handleClickOutside);\r\n\r\n\t\treturn () => {\r\n\t\t\t// クリーンアップ\r\n\t\t\tdocument.removeEventListener(\"mousedown\", handleClickOutside);\r\n\t\t};\r\n\t}, [interactionState.selectedBlockIds, handleInteractionChange]);\r\n\r\n\t// グリッドリサイズハンドラ\r\n\tconst handleGridResize = useCallback(\r\n\t\t(direction: \"column\" | \"row\", index: number, deltaPx: number) => {\r\n\t\t\tif (!onSchemaChange) return;\r\n\r\n\t\t\t// グリッド線のindexをdimension配列のindexに変換\r\n\t\t\t// グリッド線index=1 → dimension[0]とdimension[1]の境界\r\n\t\t\tconst dimensionIndex = index - 1;\r\n\r\n\t\t\tif (direction === \"column\") {\r\n\t\t\t\t// 列幅を変更\r\n\t\t\t\tconst newCols = calculateGridResize(\r\n\t\t\t\t\tschema.grid.cols,\r\n\t\t\t\t\tdimensionIndex,\r\n\t\t\t\t\tdeltaPx,\r\n\t\t\t\t\tpaperPx.content.width,\r\n\t\t\t\t);\r\n\t\t\t\tonSchemaChange({\r\n\t\t\t\t\t...schema,\r\n\t\t\t\t\tgrid: { ...schema.grid, cols: newCols },\r\n\t\t\t\t});\r\n\t\t\t} else {\r\n\t\t\t\t// 行高を変更\r\n\t\t\t\tconst newRows = calculateGridResize(\r\n\t\t\t\t\tschema.grid.rows,\r\n\t\t\t\t\tdimensionIndex,\r\n\t\t\t\t\tdeltaPx,\r\n\t\t\t\t\tpaperPx.content.height,\r\n\t\t\t\t);\r\n\t\t\t\tonSchemaChange({\r\n\t\t\t\t\t...schema,\r\n\t\t\t\t\tgrid: { ...schema.grid, rows: newRows },\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t},\r\n\t\t[schema, paperPx, onSchemaChange],\r\n\t);\r\n\r\n\t/**\r\n\t * グリッド寸法の単位/値を変更した際のハンドラ\r\n\t */\r\n\tconst handleDimensionChange = useCallback(\r\n\t\t(\r\n\t\t\tdirection: \"column\" | \"row\",\r\n\t\t\tindex: number,\r\n\t\t\tdimension: import(\"@types\").Dimension<import(\"@types\").GridUnit>,\r\n\t\t) => {\r\n\t\t\tif (!onSchemaChange) return;\r\n\r\n\t\t\tif (direction === \"column\") {\r\n\t\t\t\tconst newCols = [...schema.grid.cols];\r\n\t\t\t\tnewCols[index] = dimension;\r\n\t\t\t\tonSchemaChange({\r\n\t\t\t\t\t...schema,\r\n\t\t\t\t\tgrid: { ...schema.grid, cols: newCols },\r\n\t\t\t\t});\r\n\t\t\t} else {\r\n\t\t\t\tconst newRows = [...schema.grid.rows];\r\n\t\t\t\tnewRows[index] = dimension;\r\n\t\t\t\tonSchemaChange({\r\n\t\t\t\t\t...schema,\r\n\t\t\t\t\tgrid: { ...schema.grid, rows: newRows },\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t},\r\n\t\t[onSchemaChange, schema],\r\n\t); // initValueをvaluesとして使用\r\n\tconst values = useMemo(\r\n\t\t() =>\r\n\t\t\tschema.blocks.reduce(\r\n\t\t\t\t(acc, block) => {\r\n\t\t\t\t\tacc[block.id] = block.initValue;\r\n\t\t\t\t\treturn acc;\r\n\t\t\t\t},\r\n\t\t\t\t{} as Record<string, Value>,\r\n\t\t\t),\r\n\t\t[schema.blocks],\r\n\t); /**\r\n\t * マウスがCanvas上に入ってきた時の処理\r\n\t * Paletteからドラッグ中のアイテムがあれば、INSERT操作を開始\r\n\t */\r\n\tconst handlePointerEnter = useCallback(() => {\r\n\t\t// 1. グローバルストアから「今ドラッグ中のもの」を取得\r\n\t\tconst draggingItem = globalDragStore.get();\r\n\r\n\t\t// 2. 何も持ってなければ無視\r\n\t\tif (!draggingItem) return;\r\n\r\n\t\t// 3. すでにドラッグ中またはドラッグ状態が存在する場合は無視 (二重起動防止)\r\n\t\tif (\r\n\t\t\tinteractionState.mode === InteractionMode.DRAGGING ||\r\n\t\t\tinteractionState.dragging\r\n\t\t) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// 4. ここで初めて INSERT モードを開始\r\n\t\thandleInteractionChange({\r\n\t\t\ttype: InteractionEventType.START_INSERT,\r\n\t\t\tpluginKind: draggingItem.kind,\r\n\t\t\tdefaultSize: draggingItem.defaultSize,\r\n\t\t});\r\n\t}, [\r\n\t\tinteractionState.mode,\r\n\t\tinteractionState.dragging,\r\n\t\thandleInteractionChange,\r\n\t]);\r\n\r\n\t/**\r\n\t * マウスがCanvasから出た時の処理\r\n\t * INSERT操作中なら、範囲外フラグを立てる\r\n\t */\r\n\tconst handlePointerLeave = useCallback(() => {\r\n\t\t// INSERT操作中なら何もしない(InteractionLayerで処理)\r\n\t\t// ここでキャンセルすると、マウスが一瞬外に出ただけでキャンセルされてしまう\r\n\t}, []);\r\n\r\n\treturn (\r\n\t\t<div\r\n\t\t\tref={paperRef}\r\n\t\t\tclassName={className}\r\n\t\t\tonPointerEnter={handlePointerEnter}\r\n\t\t\tonPointerLeave={handlePointerLeave}\r\n\t\t\tstyle={{\r\n\t\t\t\tposition: \"relative\",\r\n\t\t\t\twidth: `${paperPx.canvas.width}px`,\r\n\t\t\t\theight: `${paperPx.canvas.height}px`,\r\n\t\t\t\tmargin: \"0 auto\",\r\n\t\t\t\tboxShadow: \"0 2px 8px rgba(0,0,0,0.1)\",\r\n\t\t\t\tbackgroundColor: \"#fff\",\r\n\t\t\t\ttransform: scale !== 1 ? `scale(${scale})` : undefined,\r\n\t\t\t\ttransformOrigin: \"top center\",\r\n\t\t\t}}\r\n\t\t>\r\n\t\t\t<GridLayer\r\n\t\t\t\tpaperPx={paperPx}\r\n\t\t\t\tgridPosPxs={gridPosPx}\r\n\t\t\t\tgridDimensions={{\r\n\t\t\t\t\tcols: schema.grid.cols,\r\n\t\t\t\t\trows: schema.grid.rows,\r\n\t\t\t\t}}\r\n\t\t\t\tshowGridLines={true}\r\n\t\t\t\tshowMargins={true}\r\n\t\t\t\tshowBorder={true}\r\n\t\t\t\tshowResizeHandles={true}\r\n\t\t\t\tshowDimensionLabels={true}\r\n\t\t\t\tonGridResize={handleGridResize}\r\n\t\t\t\tonDimensionChange={handleDimensionChange}\r\n\t\t\t\tgridLineStyle={{\r\n\t\t\t\t\tcolor: \"#e5e7eb\",\r\n\t\t\t\t\twidth: { value: 1, unit: \"px\" },\r\n\t\t\t\t\ttype: LineType.SOLID,\r\n\t\t\t\t}}\r\n\t\t\t\tborderStyle={{\r\n\t\t\t\t\tall: {\r\n\t\t\t\t\t\tcolor: \"#000000\",\r\n\t\t\t\t\t\twidth: { value: 1, unit: \"px\" },\r\n\t\t\t\t\t\ttype: LineType.SOLID,\r\n\t\t\t\t\t},\r\n\t\t\t\t}}\r\n\t\t\t/>\r\n\t\t\t<BlockLayer\r\n\t\t\t\tblocks={schema.blocks}\r\n\t\t\t\tpluginRegistry={pluginRegistry}\r\n\t\t\t\tmode={NoteMode.FORM}\r\n\t\t\t\tvalues={values}\r\n\t\t\t\tselectedBlockIds={interactionState.selectedBlockIds}\r\n\t\t\t\tgetBlockRectPx={getBlockRectPx}\r\n\t\t\t\tonValueChange={handleInitValueChange}\r\n\t\t\t\tshowGuides={true}\r\n\t\t\t\tshowBorder={true}\r\n\t\t\t/>\r\n\t\t\t<InteractionLayer\r\n\t\t\t\tblocks={schema.blocks}\r\n\t\t\t\tgridLength={{\r\n\t\t\t\t\tcols: schema.grid.cols.length,\r\n\t\t\t\t\trows: schema.grid.rows.length,\r\n\t\t\t\t}}\r\n\t\t\t\tpluginRegistry={pluginRegistry}\r\n\t\t\t\tgetBlockRectPx={getBlockRectPx}\r\n\t\t\t\tgetColIndex={getColIndex}\r\n\t\t\t\tgetRowIndex={getRowIndex}\r\n\t\t\t\tstate={interactionState}\r\n\t\t\t\tonChange={handleInteractionChange}\r\n\t\t\t\tonBlockChange={handleBlockChange}\r\n\t\t\t\tscale={scale}\r\n\t\t\t/>\r\n\t\t</div>\r\n\t);\r\n};\r\n\r\nNoteFormBase.displayName = \"NoteForm\";\r\n\r\nexport const NoteForm = memo(NoteFormBase);\r\n","/**\r\n * @file NoteView.tsx\r\n * @description 閲覧モード(Viewモード)専用コンポーネント\r\n * - すべて読み取り専用\r\n * - ブロックの配置・サイズ変更不可\r\n * - 値の編集不可\r\n * - InteractionLayerなし\r\n */\r\n\r\nimport { memo } from \"react\";\r\n\r\nimport { BlockLayer } from \"./BlockLayer\";\r\nimport { GridLayer } from \"./GridLayer\";\r\n\r\nimport { DEFAULT_DPI } from \"@/constants\";\r\nimport { useGridCalc } from \"@/hooks/useGridCalc\";\r\nimport { NoteMode } from \"@/types/mode\";\r\n\r\nimport type { BlockPlugin } from \"@/plugin\";\r\nimport type { FormSchema } from \"@/types/schema\";\r\nimport type { Value } from \"@/types/value\";\r\n\r\nexport interface NoteViewProps {\r\n\tschema: FormSchema;\r\n\tvalues: Record<string, Value>;\r\n\tpluginRegistry: Record<string, BlockPlugin>;\r\n\tscale?: number;\r\n\tclassName?: string;\r\n}\r\n\r\nconst NoteViewBase = ({\r\n\tschema,\r\n\tvalues,\r\n\tpluginRegistry,\r\n\tscale = 1.0,\r\n\tclassName,\r\n}: NoteViewProps) => {\r\n\tconst { paperPx, gridPosPx, getBlockRectPx } = useGridCalc(\r\n\t\tschema.paper,\r\n\t\tschema.grid,\r\n\t\tDEFAULT_DPI,\r\n\t);\r\n\r\n\treturn (\r\n\t\t<div\r\n\t\t\tclassName={className}\r\n\t\t\tstyle={{\r\n\t\t\t\tposition: \"relative\",\r\n\t\t\t\twidth: `${paperPx.canvas.width}px`,\r\n\t\t\t\theight: `${paperPx.canvas.height}px`,\r\n\t\t\t\tmargin: \"0 auto\",\r\n\t\t\t\tboxShadow: \"0 2px 8px rgba(0,0,0,0.1)\",\r\n\t\t\t\tbackgroundColor: \"#fff\",\r\n\t\t\t\ttransform: scale !== 1 ? `scale(${scale})` : undefined,\r\n\t\t\t\ttransformOrigin: \"top center\",\r\n\t\t\t}}\r\n\t\t>\r\n\t\t\t<GridLayer\r\n\t\t\t\tpaperPx={paperPx}\r\n\t\t\t\tgridPosPxs={gridPosPx}\r\n\t\t\t\tshowGridLines={false}\r\n\t\t\t\tshowMargins={false}\r\n\t\t\t\tshowBorder={false}\r\n\t\t\t/>\r\n\r\n\t\t\t<BlockLayer\r\n\t\t\t\tblocks={schema.blocks}\r\n\t\t\t\tpluginRegistry={pluginRegistry}\r\n\t\t\t\tmode={NoteMode.VIEW}\r\n\t\t\t\tvalues={values}\r\n\t\t\t\tgetBlockRectPx={getBlockRectPx}\r\n\t\t\t\tshowGuides={false}\r\n\t\t\t\tshowBorder={true}\r\n\t\t\t/>\r\n\t\t</div>\r\n\t);\r\n};\r\n\r\nNoteViewBase.displayName = \"NoteView\";\r\n\r\nexport const NoteView = memo(NoteViewBase);\r\n","/**\r\n * @file NoteEditor.tsx\r\n * @description 帳票エディタのメインコンポーネント(モード振り分け専用)\r\n * - modeに応じてNoteForm/NoteEdit/NoteViewを振り分ける\r\n */\r\n\r\nimport { memo, useCallback } from \"react\";\r\n\r\nimport { NoteEdit } from \"./NoteEdit\";\r\nimport { NoteForm } from \"./NoteForm\";\r\nimport { NoteView } from \"./NoteView\";\r\n\r\nimport { NoteMode } from \"@/types/mode\";\r\n\r\nimport type { BlockPlugin } from \"@/plugin\";\r\nimport type { OnSchemaChange, OnValuesChange } from \"@/types/callbacks\";\r\nimport type { FormSchema } from \"@/types/schema\";\r\nimport type { Value } from \"@/types/value\";\r\n\r\nexport interface NoteEditorProps {\r\n\tschema: FormSchema;\r\n\tvalues: Record<string, Value>;\r\n\tmode: NoteMode;\r\n\tpluginRegistry: Record<string, BlockPlugin>;\r\n\tonSchemaChange?: OnSchemaChange;\r\n\tonValuesChange?: OnValuesChange;\r\n\tonSelectionChange?: (selectedBlockIds: string[]) => void;\r\n\tscale?: number;\r\n\tclassName?: string;\r\n}\r\n\r\nconst NoteEditorBase = ({\r\n\tschema,\r\n\tvalues,\r\n\tmode,\r\n\tpluginRegistry,\r\n\tonSchemaChange,\r\n\tonValuesChange,\r\n\tonSelectionChange,\r\n\tscale = 1.0,\r\n\tclassName,\r\n}: NoteEditorProps) => {\r\n\t// 値変更ハンドラ(Edit/Formモード用)\r\n\tconst handleValueChange = useCallback(\r\n\t\t(id: string, val: Value) => {\r\n\t\t\tif (!onValuesChange) return;\r\n\t\t\tif (val === undefined || val === null) {\r\n\t\t\t\tconst { [id]: _, ...rest } = values;\r\n\t\t\t\tonValuesChange(rest);\r\n\t\t\t} else {\r\n\t\t\t\tonValuesChange({ ...values, [id]: val });\r\n\t\t\t}\r\n\t\t},\r\n\t\t[values, onValuesChange],\r\n\t);\r\n\r\n\t// モード別にコンポーネントを振り分け\r\n\tif (mode === NoteMode.FORM) {\r\n\t\treturn (\r\n\t\t\t<NoteForm\r\n\t\t\t\tschema={schema}\r\n\t\t\t\tpluginRegistry={pluginRegistry}\r\n\t\t\t\tonSchemaChange={onSchemaChange}\r\n\t\t\t\tonSelectionChange={onSelectionChange}\r\n\t\t\t\tscale={scale}\r\n\t\t\t\tclassName={className}\r\n\t\t\t/>\r\n\t\t);\r\n\t}\r\n\r\n\tif (mode === NoteMode.EDIT) {\r\n\t\treturn (\r\n\t\t\t<NoteEdit\r\n\t\t\t\tschema={schema}\r\n\t\t\t\tvalues={values}\r\n\t\t\t\tpluginRegistry={pluginRegistry}\r\n\t\t\t\tonValueChange={handleValueChange}\r\n\t\t\t\tscale={scale}\r\n\t\t\t\tclassName={className}\r\n\t\t\t/>\r\n\t\t);\r\n\t}\r\n\r\n\t// mode === NoteMode.VIEW\r\n\treturn (\r\n\t\t<NoteView\r\n\t\t\tschema={schema}\r\n\t\t\tvalues={values}\r\n\t\t\tpluginRegistry={pluginRegistry}\r\n\t\t\tscale={scale}\r\n\t\t\tclassName={className}\r\n\t\t/>\r\n\t);\r\n};\r\n\r\nNoteEditorBase.displayName = \"NoteEditor\";\r\n\r\nexport const NoteEditor = memo(NoteEditorBase);\r\n","/**\r\n * @file PrintableNote.tsx\r\n * @description 印刷専用コンポーネント\r\n * - FormSchemaとvaluesを受け取り、BlockLayerのみをレンダリング\r\n * - 余計な装飾(box-shadow, transformなど)なし\r\n * - FormSchema.paperから直接サイズとマージンを取得\r\n * - refを通じてprint()メソッドを提供\r\n */\r\n\r\nimport {\r\n\ttype ForwardedRef,\r\n\tforwardRef,\r\n\tmemo,\r\n\tuseEffect,\r\n\tuseImperativeHandle,\r\n\tuseRef,\r\n} from \"react\";\r\n\r\nimport { BlockLayer } from \"./BlockLayer\";\r\n\r\nimport { DEFAULT_DPI } from \"@/constants\";\r\nimport { useGridCalc } from \"@/hooks/useGridCalc\";\r\nimport { NoteMode } from \"@/types/mode\";\r\nimport { toMm } from \"@/utils/convert\";\r\nimport { printElement } from \"@/utils/print\";\r\n\r\nimport type { BlockPlugin } from \"@/plugin\";\r\nimport type { NoteViewPrintRef } from \"@/types/print\";\r\nimport type { FormSchema } from \"@/types/schema\";\r\nimport type { Value } from \"@/types/value\";\r\n\r\nexport interface NotePrintProps {\r\n\tschema: FormSchema;\r\n\tvalues?: Record<string, Value>;\r\n\tpluginRegistry: Record<string, BlockPlugin>;\r\n\tclassName?: string;\r\n}\r\n\r\nconst NotePrintBase = (\r\n\t{ schema, values, pluginRegistry, className }: NotePrintProps,\r\n\tref: ForwardedRef<NoteViewPrintRef>,\r\n) => {\r\n\tconst containerRef = useRef<HTMLDivElement>(null);\r\n\tconst { paperPx, getBlockRectPx } = useGridCalc(\r\n\t\tschema.paper,\r\n\t\tschema.grid,\r\n\t\tDEFAULT_DPI,\r\n\t);\r\n\r\n\t// FormSchema.paperから用紙サイズを取得し、@pageルールを設定\r\n\t// 注意: @pageのmarginは0に設定し、要素側でマージンを表現する\r\n\t// 理由: @pageのmarginを設定すると、position:absoluteの座標原点がマージン後の領域になるため\r\n\tuseEffect(() => {\r\n\t\tconst { size } = schema.paper;\r\n\r\n\t\t// 用紙サイズをmm単位に変換\r\n\t\tconst widthMm = toMm.fromDim(size.width);\r\n\t\tconst heightMm = toMm.fromDim(size.height);\r\n\r\n\t\t// 既存のstyle要素を削除\r\n\t\tconst existingStyle = document.getElementById(\"printable-note-page-style\");\r\n\t\tif (existingStyle) {\r\n\t\t\texistingStyle.remove();\r\n\t\t}\r\n\r\n\t\t// 新しいstyle要素を作成\r\n\t\tconst style = document.createElement(\"style\");\r\n\t\tstyle.id = \"printable-note-page-style\";\r\n\t\tstyle.textContent = `\r\n\t\t\t@media print {\r\n\t\t\t\t@page {\r\n\t\t\t\t\tsize: ${widthMm}mm ${heightMm}mm;\r\n\t\t\t\t\tmargin: 0;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t`;\r\n\r\n\t\tdocument.head.appendChild(style);\r\n\r\n\t\treturn () => {\r\n\t\t\t// クリーンアップ\r\n\t\t\tconst styleElement = document.getElementById(\"printable-note-page-style\");\r\n\t\t\tif (styleElement) {\r\n\t\t\t\tstyleElement.remove();\r\n\t\t\t}\r\n\t\t};\r\n\t}, [schema.paper]);\r\n\r\n\t// 印刷メソッドをrefに公開\r\n\tuseImperativeHandle(\r\n\t\tref,\r\n\t\t() => ({\r\n\t\t\tprint: () => {\r\n\t\t\t\tif (!containerRef.current) return;\r\n\t\t\t\tprintElement(containerRef.current, {\r\n\t\t\t\t\ttitle: \"Document\",\r\n\t\t\t\t});\r\n\t\t\t},\r\n\t\t\topenPrintPreview: () => {\r\n\t\t\t\tif (!containerRef.current) return;\r\n\t\t\t\tprintElement(containerRef.current, {\r\n\t\t\t\t\ttitle: \"Document\",\r\n\t\t\t\t});\r\n\t\t\t},\r\n\t\t}),\r\n\t\t[],\r\n\t);\r\n\r\n\treturn (\r\n\t\t<div\r\n\t\t\tref={containerRef}\r\n\t\t\tclassName={className}\r\n\t\t\tstyle={{\r\n\t\t\t\twidth: `${paperPx.canvas.width}px`,\r\n\t\t\t\theight: `${paperPx.canvas.height}px`,\r\n\t\t\t\tbackgroundColor: \"#fff\",\r\n\t\t\t\tpaddingTop: `${paperPx.margin.top}px`,\r\n\t\t\t\tpaddingLeft: `${paperPx.margin.left}px`,\r\n\t\t\t\tpaddingRight: `${paperPx.margin.right}px`,\r\n\t\t\t\tpaddingBottom: `${paperPx.margin.bottom}px`,\r\n\t\t\t\tboxSizing: \"border-box\",\r\n\t\t\t}}\r\n\t\t>\r\n\t\t\t{/* コンテンツ領域 */}\r\n\t\t\t<div\r\n\t\t\t\tstyle={{\r\n\t\t\t\t\tposition: \"relative\",\r\n\t\t\t\t\twidth: `${paperPx.content.width}px`,\r\n\t\t\t\t\theight: `${paperPx.content.height}px`,\r\n\t\t\t\t}}\r\n\t\t\t>\r\n\t\t\t\t<BlockLayer\r\n\t\t\t\t\tblocks={schema.blocks}\r\n\t\t\t\t\tpluginRegistry={pluginRegistry}\r\n\t\t\t\t\tmode={NoteMode.VIEW}\r\n\t\t\t\t\tvalues={values ?? {}}\r\n\t\t\t\t\tgetBlockRectPx={getBlockRectPx}\r\n\t\t\t\t\tshowGuides={false}\r\n\t\t\t\t\tshowBorder={true}\r\n\t\t\t\t/>\r\n\t\t\t</div>\r\n\t\t</div>\r\n\t);\r\n};\r\n\r\nNotePrintBase.displayName = \"NotePrint\";\r\n\r\nexport const NotePrint = memo(forwardRef(NotePrintBase));\r\n","// src/properties/utils/getCommonValue.ts\r\nimport type { Block, Value } from \"@/types\";\r\n\r\n/**\r\n * 選択中のブロックから共通の値を取得する\r\n * 値がバラバラの場合は undefined を返す\r\n *\r\n * @param blocks 選択中のブロック配列\r\n * @param path プロパティへのパス (例: \"props.text\", \"layout.x\", \"style.backgroundColor\")\r\n * @returns 全ブロックで共通の値、または値が異なる場合は undefined\r\n *\r\n * @example\r\n * ```ts\r\n * // propsの値を取得\r\n * const textValue = getCommonValue(blocks, \"props.text\");\r\n *\r\n * // layoutの値を取得\r\n * const xPos = getCommonValue<number>(blocks, \"layout.x\");\r\n *\r\n * // styleの値を取得\r\n * const bgColor = getCommonValue(blocks, \"style.backgroundColor\");\r\n * ```\r\n */\r\nexport function getCommonValue<T = Value>(\r\n\tblocks: Block[],\r\n\tpath: string,\r\n): T | undefined {\r\n\tif (blocks.length === 0) return undefined;\r\n\r\n\t// パスから値を取得するヘルパー関数\r\n\tconst getValueByPath = (obj: unknown, keys: string[]): unknown => {\r\n\t\tlet current: unknown = obj;\r\n\r\n\t\tfor (const key of keys) {\r\n\t\t\tif (current == null) return undefined;\r\n\t\t\tif (typeof current !== \"object\" || Array.isArray(current))\r\n\t\t\t\treturn undefined;\r\n\r\n\t\t\tcurrent = (current as Record<string, unknown>)[key];\r\n\t\t}\r\n\r\n\t\treturn current;\r\n\t};\r\n\r\n\tconst keys = path.split(\".\");\r\n\r\n\t// 最初のブロックの値を取得\r\n\tconst firstValue = getValueByPath(blocks[0], keys);\r\n\r\n\t// 全てのブロックが同じ値を持つか確認\r\n\tconst allSame = blocks.every((block) => {\r\n\t\tconst value = getValueByPath(block, keys);\r\n\t\t// 厳密等価性でチェック(オブジェクトや配列は参照比較)\r\n\t\treturn value === firstValue;\r\n\t});\r\n\r\n\treturn allSame ? (firstValue as T) : undefined;\r\n}\r\n","import { ColorPicker } from \"../../../components\";\r\nimport { getCommonValue } from \"../../../utils/getCommonValue\";\r\nimport styles from \"./BackgroundPanel.module.css\";\r\n\r\nimport type React from \"react\";\r\nimport type { Block } from \"@/types\";\r\n\r\nexport interface BackgroundPanelProps {\r\n\tselectedBlocks: Block[];\r\n\tonUpdateBlocks: (updates: Record<string, Partial<Block>>) => void;\r\n}\r\n\r\nexport const BackgroundPanel: React.FC<BackgroundPanelProps> = ({\r\n\tselectedBlocks,\r\n\tonUpdateBlocks,\r\n}) => {\r\n\tif (selectedBlocks.length === 0) return null;\r\n\r\n\tconst handleChange = (color: string | undefined) => {\r\n\t\tconst updates: Record<string, Partial<Block>> = {};\r\n\t\tselectedBlocks.forEach((b) => {\r\n\t\t\tupdates[b.id] = {\r\n\t\t\t\tstyle: {\r\n\t\t\t\t\t...b.style,\r\n\t\t\t\t\tbackgroundColor: color,\r\n\t\t\t\t},\r\n\t\t\t};\r\n\t\t});\r\n\t\tonUpdateBlocks(updates);\r\n\t};\r\n\r\n\treturn (\r\n\t\t<div className={styles.container}>\r\n\t\t\t<div className={styles.row}>\r\n\t\t\t\t<div className={styles.inputWrapper}>\r\n\t\t\t\t\t<ColorPicker\r\n\t\t\t\t\t\tvalue={getCommonValue(selectedBlocks, \"style.backgroundColor\")}\r\n\t\t\t\t\t\tonChange={handleChange}\r\n\t\t\t\t\t\tallowUndefined\r\n\t\t\t\t\t\tplaceholder=\"無色\"\r\n\t\t\t\t\t\theight={24}\r\n\t\t\t\t\t/>\r\n\t\t\t\t</div>\r\n\t\t\t</div>\r\n\t\t</div>\r\n\t);\r\n};\r\n","import { useMemo } from \"react\";\r\n\r\nimport { ColorPicker, DimensionInput, Select } from \"../../../components\";\r\nimport {\r\n\tTabs,\r\n\tTabsContent,\r\n\tTabsList,\r\n\tTabsTrigger,\r\n} from \"../../../components/Tabs\";\r\nimport { getCommonValue } from \"../../../utils/getCommonValue\";\r\n\r\nimport { BorderRenderer } from \"@/canvas/components/BorderRenderer\";\r\nimport { Border, LineType } from \"@/types/line\";\r\nimport { BORDER_UNITS } from \"@/types/unit\";\r\n\r\nimport type React from \"react\";\r\nimport type { Block, Value } from \"@/types\";\r\n\r\n/**\r\n * オブジェクトの特定パスの値を更新した新しいオブジェクトを返す (Immutable)\r\n * valueがundefinedまたはnullの場合、そのプロパティを削除する\r\n */\r\nfunction setNestedValue<T>(obj: T, path: string, value: Value): T {\r\n\tconst keys = path.split(\".\");\r\n\r\n\tconst update = (\r\n\t\tcurrent: Record<string, unknown>,\r\n\t\tdepth: number,\r\n\t): Record<string, unknown> => {\r\n\t\tconst key = keys[depth] as string;\r\n\t\tif (depth === keys.length - 1) {\r\n\t\t\t// 最後のキー: valueがundefined/nullの場合はプロパティを削除\r\n\t\t\tif (value === undefined || value === null) {\r\n\t\t\t\tconst { [key]: _, ...rest } = current;\r\n\t\t\t\treturn rest;\r\n\t\t\t}\r\n\t\t\treturn { ...current, [key]: value };\r\n\t\t}\r\n\t\tconst nextValue =\r\n\t\t\t(current?.[key] as Record<string, unknown> | undefined) || {};\r\n\t\tconst updated = update(nextValue, depth + 1);\r\n\r\n\t\t// 更新後のオブジェクトが空なら、このキーも削除\r\n\t\tif (Object.keys(updated).length === 0) {\r\n\t\t\tconst { [key]: _, ...rest } = current;\r\n\t\t\treturn rest;\r\n\t\t}\r\n\r\n\t\treturn {\r\n\t\t\t...current,\r\n\t\t\t[key]: updated,\r\n\t\t};\r\n\t};\r\n\r\n\treturn update(obj as Record<string, unknown>, 0) as T;\r\n}\r\n\r\nexport interface BorderPanelProps {\r\n\tselectedBlocks: Block[];\r\n\tonUpdateBlocks: (updates: Record<string, Partial<Block>>) => void;\r\n}\r\n\r\ntype BorderEdge = \"all\" | \"top\" | \"right\" | \"bottom\" | \"left\";\r\n\r\nexport const BorderPanel: React.FC<BorderPanelProps> = ({\r\n\tselectedBlocks,\r\n\tonUpdateBlocks,\r\n}) => {\r\n\t// --- ハンドラ ---\r\n\tconst handleChange = (\r\n\t\tedge: BorderEdge,\r\n\t\tprop: \"type\" | \"width\" | \"color\",\r\n\t\tval: Value,\r\n\t) => {\r\n\t\tconst updates: Record<string, Partial<Block>> = {};\r\n\r\n\t\tselectedBlocks.forEach((b) => {\r\n\t\t\tlet newStyle = setNestedValue(\r\n\t\t\t\tb.style || {},\r\n\t\t\t\t`border.${edge}.${prop}`,\r\n\t\t\t\tval,\r\n\t\t\t);\r\n\r\n\t\t\t// typeが「なし」(undefined)に設定された場合、widthとcolorも削除\r\n\t\t\tif (prop === \"type\" && (val === undefined || val === null)) {\r\n\t\t\t\tnewStyle = setNestedValue(newStyle, `border.${edge}.width`, undefined);\r\n\t\t\t\tnewStyle = setNestedValue(newStyle, `border.${edge}.color`, undefined);\r\n\t\t\t}\r\n\r\n\t\t\t// typeやcolorが設定された場合(なし以外)、widthとcolorが未設定ならデフォルト値を設定\r\n\t\t\tif (prop === \"type\" && val !== undefined && val !== null) {\r\n\t\t\t\tconst currentBorder = (b.style as { border?: Record<string, unknown> })\r\n\t\t\t\t\t?.border as\r\n\t\t\t\t\t| Record<string, { width?: unknown; color?: unknown }>\r\n\t\t\t\t\t| undefined;\r\n\t\t\t\tconst edgeStyle = currentBorder?.[edge];\r\n\r\n\t\t\t\t// widthが未設定なら1pxをデフォルト設定\r\n\t\t\t\tif (!edgeStyle?.width) {\r\n\t\t\t\t\tnewStyle = setNestedValue(newStyle, `border.${edge}.width`, {\r\n\t\t\t\t\t\tvalue: 1,\r\n\t\t\t\t\t\tunit: \"px\",\r\n\t\t\t\t\t});\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// colorが未設定なら#000000をデフォルト設定\r\n\t\t\t\tif (!edgeStyle?.color) {\r\n\t\t\t\t\tnewStyle = setNestedValue(\r\n\t\t\t\t\t\tnewStyle,\r\n\t\t\t\t\t\t`border.${edge}.color`,\r\n\t\t\t\t\t\t\"#000000\",\r\n\t\t\t\t\t);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t// colorが設定された場合、typeとwidthが未設定ならデフォルト値を設定\r\n\t\t\tif (prop === \"color\" && val !== undefined && val !== null) {\r\n\t\t\t\tconst currentBorder = (b.style as { border?: Record<string, unknown> })\r\n\t\t\t\t\t?.border as\r\n\t\t\t\t\t| Record<string, { type?: unknown; width?: unknown }>\r\n\t\t\t\t\t| undefined;\r\n\t\t\t\tconst edgeStyle = currentBorder?.[edge];\r\n\r\n\t\t\t\t// typeが未設定ならsolidをデフォルト設定\r\n\t\t\t\tif (!edgeStyle?.type) {\r\n\t\t\t\t\tnewStyle = setNestedValue(\r\n\t\t\t\t\t\tnewStyle,\r\n\t\t\t\t\t\t`border.${edge}.type`,\r\n\t\t\t\t\t\tLineType.SOLID,\r\n\t\t\t\t\t);\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// widthが未設定なら1pxをデフォルト設定\r\n\t\t\t\tif (!edgeStyle?.width) {\r\n\t\t\t\t\tnewStyle = setNestedValue(newStyle, `border.${edge}.width`, {\r\n\t\t\t\t\t\tvalue: 1,\r\n\t\t\t\t\t\tunit: \"px\",\r\n\t\t\t\t\t});\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t// widthが設定された場合、typeとcolorが未設定ならデフォルト値を設定\r\n\t\t\tif (prop === \"width\" && val !== undefined && val !== null) {\r\n\t\t\t\tconst currentBorder = (b.style as { border?: Record<string, unknown> })\r\n\t\t\t\t\t?.border as\r\n\t\t\t\t\t| Record<string, { type?: unknown; color?: unknown }>\r\n\t\t\t\t\t| undefined;\r\n\t\t\t\tconst edgeStyle = currentBorder?.[edge];\r\n\r\n\t\t\t\t// typeが未設定ならsolidをデフォルト設定\r\n\t\t\t\tif (!edgeStyle?.type) {\r\n\t\t\t\t\tnewStyle = setNestedValue(\r\n\t\t\t\t\t\tnewStyle,\r\n\t\t\t\t\t\t`border.${edge}.type`,\r\n\t\t\t\t\t\tLineType.SOLID,\r\n\t\t\t\t\t);\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// colorが未設定なら#000000をデフォルト設定\r\n\t\t\t\tif (!edgeStyle?.color) {\r\n\t\t\t\t\tnewStyle = setNestedValue(\r\n\t\t\t\t\t\tnewStyle,\r\n\t\t\t\t\t\t`border.${edge}.color`,\r\n\t\t\t\t\t\t\"#000000\",\r\n\t\t\t\t\t);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tupdates[b.id] = { style: newStyle };\r\n\t\t});\r\n\r\n\t\tonUpdateBlocks(updates);\r\n\t};\r\n\r\n\t// --- プレビュー用 ---\r\n\tconst previewBorder = useMemo(() => {\r\n\t\tif (selectedBlocks.length !== 1) return null;\r\n\t\tconst firstBlock = selectedBlocks[0];\r\n\t\tif (!firstBlock?.style?.border) return null;\r\n\r\n\t\tconst borderStyle = firstBlock.style.border;\r\n\t\tif (!borderStyle) return null;\r\n\r\n\t\tconst validateEdge = (edge?: { type?: unknown; width?: unknown }) => {\r\n\t\t\tif (!edge) return true;\r\n\t\t\tif (edge.type && !edge.width) return false;\r\n\t\t\treturn true;\r\n\t\t};\r\n\r\n\t\tconst edges = [\"all\", \"top\", \"right\", \"bottom\", \"left\"] as const;\r\n\t\tif (\r\n\t\t\t!edges.every((e) =>\r\n\t\t\t\tvalidateEdge(\r\n\t\t\t\t\tborderStyle[e] as { type?: unknown; width?: unknown } | undefined,\r\n\t\t\t\t),\r\n\t\t\t)\r\n\t\t) {\r\n\t\t\treturn null;\r\n\t\t}\r\n\r\n\t\treturn new Border(borderStyle);\r\n\t}, [selectedBlocks]);\r\n\r\n\t// --- 入力フォーム ---\r\n\tconst renderInputs = (edge: BorderEdge) => (\r\n\t\t<div\r\n\t\t\tstyle={{\r\n\t\t\t\tdisplay: \"flex\",\r\n\t\t\t\tflexDirection: \"column\",\r\n\t\t\t\tgap: \"4px\",\r\n\t\t\t}}\r\n\t\t>\r\n\t\t\t<Select\r\n\t\t\t\tvalue={getCommonValue(selectedBlocks, `style.border.${edge}.type`)}\r\n\t\t\t\tonChange={(val) => handleChange(edge, \"type\", val)}\r\n\t\t\t\tplaceholder=\"スタイル\"\r\n\t\t\t\theight={24}\r\n\t\t\t\toptions={[\r\n\t\t\t\t\t{ label: \"\", value: undefined },\r\n\t\t\t\t\t{ label: \"実線\", value: LineType.SOLID },\r\n\t\t\t\t\t{ label: \"破線\", value: LineType.DASHED },\r\n\t\t\t\t\t{ label: \"点線\", value: LineType.DOTTED },\r\n\t\t\t\t]}\r\n\t\t\t/>\r\n\r\n\t\t\t<DimensionInput\r\n\t\t\t\tvalue={\r\n\t\t\t\t\tgetCommonValue(\r\n\t\t\t\t\t\tselectedBlocks,\r\n\t\t\t\t\t\t`style.border.${edge}.width`,\r\n\t\t\t\t\t) as (typeof BORDER_UNITS)[number] extends infer U extends string\r\n\t\t\t\t\t\t? { value: number; unit: U } | undefined\r\n\t\t\t\t\t\t: never\r\n\t\t\t\t}\r\n\t\t\t\tonChange={(val) => handleChange(edge, \"width\", val as Value)}\r\n\t\t\t\tplaceholder=\"太さ\"\r\n\t\t\t\theight={24}\r\n\t\t\t\tallowedUnits={BORDER_UNITS}\r\n\t\t\t\tmin={1}\r\n\t\t\t/>\r\n\r\n\t\t\t<ColorPicker\r\n\t\t\t\tvalue={getCommonValue(selectedBlocks, `style.border.${edge}.color`)}\r\n\t\t\t\tonChange={(val) => handleChange(edge, \"color\", val)}\r\n\t\t\t\tplaceholder=\"色\"\r\n\t\t\t\theight={24}\r\n\t\t\t\tallowUndefined\r\n\t\t\t/>\r\n\t\t</div>\r\n\t);\r\n\r\n\t// タブの共通スタイル\r\n\tconst triggerStyle: React.CSSProperties = {\r\n\t\tflex: 1, // 均等割付\r\n\t\tpadding: \"0 2px\", // 左右パディングを詰める\r\n\t\tfontSize: \"12px\",\r\n\t\tminWidth: 0, // Flexアイテムの縮小許可\r\n\t\twhiteSpace: \"nowrap\", // 折り返し禁止\r\n\t\toverflow: \"hidden\", // はみ出し非表示\r\n\t\ttextOverflow: \"ellipsis\", // 省略記号\r\n\t};\r\n\r\n\treturn (\r\n\t\t<div\r\n\t\t\tstyle={{\r\n\t\t\t\tdisplay: \"flex\",\r\n\t\t\t\tflexDirection: \"row\",\r\n\t\t\t\tpadding: \"4px\",\r\n\t\t\t\talignItems: \"stretch\",\r\n\t\t\t}}\r\n\t\t>\r\n\t\t\t{/* --- 左側: プレビュー (30%) --- */}\r\n\t\t\t<div\r\n\t\t\t\tstyle={{\r\n\t\t\t\t\tflex: \"0 0 30%\",\r\n\t\t\t\t\tdisplay: \"flex\",\r\n\t\t\t\t\tflexDirection: \"column\",\r\n\t\t\t\t\talignItems: \"center\",\r\n\t\t\t\t\tjustifyContent: \"center\",\r\n\t\t\t\t}}\r\n\t\t\t>\r\n\t\t\t\t<div\r\n\t\t\t\t\tstyle={{\r\n\t\t\t\t\t\twidth: \"80px\",\r\n\t\t\t\t\t\theight: \"80px\",\r\n\t\t\t\t\t\tbackgroundColor: \"transparent\",\r\n\t\t\t\t\t\tborder: \"transparent\",\r\n\t\t\t\t\t\tborderRadius: \"0.25rem\",\r\n\t\t\t\t\t\tdisplay: \"flex\",\r\n\t\t\t\t\t\talignItems: \"center\",\r\n\t\t\t\t\t\tjustifyContent: \"center\",\r\n\t\t\t\t\t\tposition: \"relative\",\r\n\t\t\t\t\t}}\r\n\t\t\t\t>\r\n\t\t\t\t\t{/* 十字線(常に表示) */}\r\n\t\t\t\t\t<svg\r\n\t\t\t\t\t\twidth=\"80\"\r\n\t\t\t\t\t\theight=\"80\"\r\n\t\t\t\t\t\tviewBox=\"0 0 80 80\"\r\n\t\t\t\t\t\tstyle={{\r\n\t\t\t\t\t\t\tposition: \"absolute\",\r\n\t\t\t\t\t\t\ttop: 0,\r\n\t\t\t\t\t\t\tleft: 0,\r\n\t\t\t\t\t\t\topacity: 0.3,\r\n\t\t\t\t\t\t\tpointerEvents: \"none\",\r\n\t\t\t\t\t\t}}\r\n\t\t\t\t\t>\r\n\t\t\t\t\t\t<title>枠線ガイド</title>\r\n\t\t\t\t\t\t{/* 十字の縦線 */}\r\n\t\t\t\t\t\t<line\r\n\t\t\t\t\t\t\tx1=\"40\"\r\n\t\t\t\t\t\t\ty1=\"0\"\r\n\t\t\t\t\t\t\tx2=\"40\"\r\n\t\t\t\t\t\t\ty2=\"80\"\r\n\t\t\t\t\t\t\tstroke=\"#9ca3af\"\r\n\t\t\t\t\t\t\tstrokeWidth=\"1\"\r\n\t\t\t\t\t\t\tstrokeDasharray=\"4 2\"\r\n\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t{/* 十字の横線 */}\r\n\t\t\t\t\t\t<line\r\n\t\t\t\t\t\t\tx1=\"0\"\r\n\t\t\t\t\t\t\ty1=\"40\"\r\n\t\t\t\t\t\t\tx2=\"80\"\r\n\t\t\t\t\t\t\ty2=\"40\"\r\n\t\t\t\t\t\t\tstroke=\"#9ca3af\"\r\n\t\t\t\t\t\t\tstrokeWidth=\"1\"\r\n\t\t\t\t\t\t\tstrokeDasharray=\"4 2\"\r\n\t\t\t\t\t\t/>\r\n\t\t\t\t\t</svg>\r\n\r\n\t\t\t\t\t{/* 枠線プレビューまたは未設定の四角 */}\r\n\t\t\t\t\t{previewBorder ? (\r\n\t\t\t\t\t\t<div\r\n\t\t\t\t\t\t\tstyle={{\r\n\t\t\t\t\t\t\t\tposition: \"absolute\",\r\n\t\t\t\t\t\t\t\ttop: 0,\r\n\t\t\t\t\t\t\t\tleft: 0,\r\n\t\t\t\t\t\t\t\twidth: \"80px\",\r\n\t\t\t\t\t\t\t\theight: \"80px\",\r\n\t\t\t\t\t\t\t\tpointerEvents: \"none\",\r\n\t\t\t\t\t\t\t}}\r\n\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t<BorderRenderer width={80} height={80} border={previewBorder} />\r\n\t\t\t\t\t\t</div>\r\n\t\t\t\t\t) : (\r\n\t\t\t\t\t\t<svg\r\n\t\t\t\t\t\t\twidth=\"80\"\r\n\t\t\t\t\t\t\theight=\"80\"\r\n\t\t\t\t\t\t\tviewBox=\"0 0 80 80\"\r\n\t\t\t\t\t\t\tstyle={{\r\n\t\t\t\t\t\t\t\tposition: \"absolute\",\r\n\t\t\t\t\t\t\t\ttop: 0,\r\n\t\t\t\t\t\t\t\tleft: 0,\r\n\t\t\t\t\t\t\t\topacity: 0.3,\r\n\t\t\t\t\t\t\t}}\r\n\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t<title>枠線未設定</title>\r\n\t\t\t\t\t\t\t{/* 点線の四角 */}\r\n\t\t\t\t\t\t\t<rect\r\n\t\t\t\t\t\t\t\tx=\"0\"\r\n\t\t\t\t\t\t\t\ty=\"0\"\r\n\t\t\t\t\t\t\t\twidth=\"80\"\r\n\t\t\t\t\t\t\t\theight=\"80\"\r\n\t\t\t\t\t\t\t\tfill=\"none\"\r\n\t\t\t\t\t\t\t\tstroke=\"#9ca3af\"\r\n\t\t\t\t\t\t\t\tstrokeWidth=\"1\"\r\n\t\t\t\t\t\t\t\tstrokeDasharray=\"4 2\"\r\n\t\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t</svg>\r\n\t\t\t\t\t)}\r\n\t\t\t\t</div>\r\n\t\t\t</div>\r\n\r\n\t\t\t{/* --- 右側: 設定項目 (70%) --- */}\r\n\t\t\t<div\r\n\t\t\t\tstyle={{\r\n\t\t\t\t\tflex: \"0 0 70%\",\r\n\t\t\t\t\tminWidth: 0,\r\n\t\t\t\t\tpadding: \"0 0 2px 0\",\r\n\t\t\t\t}}\r\n\t\t\t>\r\n\t\t\t\t<Tabs defaultValue=\"all\" variant=\"segmented\">\r\n\t\t\t\t\t{/* TabsList に width: 100% と display: flex を直接指定して強制的に横並びにする */}\r\n\t\t\t\t\t<div style={{ width: \"100%\" }}>\r\n\t\t\t\t\t\t<TabsList style={{ width: \"100%\", display: \"flex\" }}>\r\n\t\t\t\t\t\t\t<TabsTrigger value=\"all\" height={24} style={triggerStyle}>\r\n\t\t\t\t\t\t\t\t共通\r\n\t\t\t\t\t\t\t</TabsTrigger>\r\n\t\t\t\t\t\t\t<TabsTrigger value=\"top\" height={24} style={triggerStyle}>\r\n\t\t\t\t\t\t\t\t上\r\n\t\t\t\t\t\t\t</TabsTrigger>\r\n\t\t\t\t\t\t\t<TabsTrigger value=\"bottom\" height={24} style={triggerStyle}>\r\n\t\t\t\t\t\t\t\t下\r\n\t\t\t\t\t\t\t</TabsTrigger>\r\n\t\t\t\t\t\t\t<TabsTrigger value=\"left\" height={24} style={triggerStyle}>\r\n\t\t\t\t\t\t\t\t左\r\n\t\t\t\t\t\t\t</TabsTrigger>\r\n\t\t\t\t\t\t\t<TabsTrigger value=\"right\" height={24} style={triggerStyle}>\r\n\t\t\t\t\t\t\t\t右\r\n\t\t\t\t\t\t\t</TabsTrigger>\r\n\t\t\t\t\t\t</TabsList>\r\n\t\t\t\t\t</div>\r\n\r\n\t\t\t\t\t<div style={{ marginTop: \"4px\" }}>\r\n\t\t\t\t\t\t<TabsContent value=\"all\">{renderInputs(\"all\")}</TabsContent>\r\n\t\t\t\t\t\t<TabsContent value=\"top\">{renderInputs(\"top\")}</TabsContent>\r\n\t\t\t\t\t\t<TabsContent value=\"bottom\">{renderInputs(\"bottom\")}</TabsContent>\r\n\t\t\t\t\t\t<TabsContent value=\"left\">{renderInputs(\"left\")}</TabsContent>\r\n\t\t\t\t\t\t<TabsContent value=\"right\">{renderInputs(\"right\")}</TabsContent>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t</Tabs>\r\n\t\t\t</div>\r\n\t\t</div>\r\n\t);\r\n};\r\n","import { NumberInput } from \"../../../components\";\r\nimport { getCommonValue } from \"../../../utils/getCommonValue\";\r\nimport styles from \"./LayoutPanel.module.css\";\r\n\r\nimport type React from \"react\";\r\nimport type { Block } from \"@/types\";\r\n\r\nexport interface LayoutPanelProps {\r\n\tselectedBlocks: Block[];\r\n\tonUpdateBlocks: (updates: Record<string, Partial<Block>>) => void;\r\n\tgridSize?: { cols: number; rows: number };\r\n}\r\n\r\nexport const LayoutPanel: React.FC<LayoutPanelProps> = ({\r\n\tselectedBlocks,\r\n\tonUpdateBlocks,\r\n\tgridSize,\r\n}) => {\r\n\tif (selectedBlocks.length === 0) return null;\r\n\r\n\tconst isMultipleSelection = selectedBlocks.length > 1;\r\n\r\n\t// 複数選択時: 最も左上の座標を取得\r\n\tconst minX = isMultipleSelection\r\n\t\t? Math.min(...selectedBlocks.map((b) => b.layout.x))\r\n\t\t: undefined;\r\n\tconst minY = isMultipleSelection\r\n\t\t? Math.min(...selectedBlocks.map((b) => b.layout.y))\r\n\t\t: undefined;\r\n\r\n\tconst handleChange = (\r\n\t\tkey: \"x\" | \"y\" | \"w\" | \"h\",\r\n\t\tval: number | undefined,\r\n\t) => {\r\n\t\tif (val === undefined) return;\r\n\r\n\t\tconst updates: Record<string, Partial<Block>> = {};\r\n\r\n\t\tif (isMultipleSelection && (key === \"x\" || key === \"y\")) {\r\n\t\t\t// 複数選択時のX, Y変更: 相対位置を保持して全ブロックを移動\r\n\t\t\tconst currentMin = key === \"x\" ? minX : minY;\r\n\t\t\tif (currentMin === undefined) return;\r\n\r\n\t\t\t// バウンディングボックスを計算\r\n\t\t\tconst maxX = Math.max(\r\n\t\t\t\t...selectedBlocks.map((b) => b.layout.x + b.layout.w),\r\n\t\t\t);\r\n\t\t\tconst maxY = Math.max(\r\n\t\t\t\t...selectedBlocks.map((b) => b.layout.y + b.layout.h),\r\n\t\t\t);\r\n\t\t\tconst boundingW = maxX - (minX ?? 0);\r\n\t\t\tconst boundingH = maxY - (minY ?? 0);\r\n\r\n\t\t\t// 入力値をバウンディングボックスを考慮してクランプ\r\n\t\t\tlet clampedVal = val;\r\n\t\t\tif (key === \"x\" && gridSize) {\r\n\t\t\t\t// 最小値は0、最大値はcols - boundingW\r\n\t\t\t\tclampedVal = Math.max(0, Math.min(val, gridSize.cols - boundingW));\r\n\t\t\t} else if (key === \"y\" && gridSize) {\r\n\t\t\t\t// 最小値は0、最大値はrows - boundingH\r\n\t\t\t\tclampedVal = Math.max(0, Math.min(val, gridSize.rows - boundingH));\r\n\t\t\t} else {\r\n\t\t\t\tclampedVal = Math.max(0, val);\r\n\t\t\t}\r\n\r\n\t\t\t// クランプ後のオフセットを計算\r\n\t\t\tconst offset = clampedVal - currentMin;\r\n\r\n\t\t\t// 全ブロックに同じオフセットを適用(相対位置を保持)\r\n\t\t\tselectedBlocks.forEach((b) => {\r\n\t\t\t\tconst newValue = b.layout[key] + offset;\r\n\t\t\t\tupdates[b.id] = {\r\n\t\t\t\t\tlayout: { ...b.layout, [key]: newValue },\r\n\t\t\t\t};\r\n\t\t\t});\r\n\t\t} else {\r\n\t\t\t// 単一選択時 または W, H変更時\r\n\t\t\tselectedBlocks.forEach((b) => {\r\n\t\t\t\tlet clampedVal = val;\r\n\r\n\t\t\t\t// クランプ処理(ブロックサイズを考慮)\r\n\t\t\t\tif (key === \"x\" && gridSize) {\r\n\t\t\t\t\t// X座標: 0 ~ (cols - w)\r\n\t\t\t\t\tclampedVal = Math.max(0, Math.min(val, gridSize.cols - b.layout.w));\r\n\t\t\t\t} else if (key === \"y\" && gridSize) {\r\n\t\t\t\t\t// Y座標: 0 ~ (rows - h)\r\n\t\t\t\t\tclampedVal = Math.max(0, Math.min(val, gridSize.rows - b.layout.h));\r\n\t\t\t\t} else if (key === \"w\" && gridSize) {\r\n\t\t\t\t\t// 幅: 1 ~ (cols - x)\r\n\t\t\t\t\tconst maxW = gridSize.cols - b.layout.x;\r\n\t\t\t\t\tclampedVal = Math.max(1, Math.min(val, maxW));\r\n\t\t\t\t} else if (key === \"h\" && gridSize) {\r\n\t\t\t\t\t// 高さ: 1 ~ (rows - y)\r\n\t\t\t\t\tconst maxH = gridSize.rows - b.layout.y;\r\n\t\t\t\t\tclampedVal = Math.max(1, Math.min(val, maxH));\r\n\t\t\t\t} else if (key === \"w\" || key === \"h\") {\r\n\t\t\t\t\t// gridSizeがない場合は最小値1のみ\r\n\t\t\t\t\tclampedVal = Math.max(1, val);\r\n\t\t\t\t} else {\r\n\t\t\t\t\t// x, yでgridSizeがない場合は0以上\r\n\t\t\t\t\tclampedVal = Math.max(0, val);\r\n\t\t\t\t}\r\n\r\n\t\t\t\tupdates[b.id] = {\r\n\t\t\t\t\tlayout: { ...b.layout, [key]: clampedVal },\r\n\t\t\t\t};\r\n\t\t\t});\r\n\t\t}\r\n\t\tonUpdateBlocks(updates);\r\n\t};\r\n\r\n\treturn (\r\n\t\t<div className={styles.container}>\r\n\t\t\t<div className={styles.grid}>\r\n\t\t\t\t{/* X (列) */}\r\n\t\t\t\t<div className={styles.field}>\r\n\t\t\t\t\t<span className={styles.label}>X</span>\r\n\t\t\t\t\t<div className={styles.inputWrapper}>\r\n\t\t\t\t\t\t<NumberInput\r\n\t\t\t\t\t\t\tvalue={\r\n\t\t\t\t\t\t\t\tisMultipleSelection\r\n\t\t\t\t\t\t\t\t\t? minX\r\n\t\t\t\t\t\t\t\t\t: getCommonValue(selectedBlocks, \"layout.x\")\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\tonChange={(v) => handleChange(\"x\", v)}\r\n\t\t\t\t\t\t\tmin={0}\r\n\t\t\t\t\t\t\tmax={gridSize ? gridSize.cols - 1 : undefined}\r\n\t\t\t\t\t\t\tinteger\r\n\t\t\t\t\t\t\theight={22}\r\n\t\t\t\t\t\t\tplaceholder=\"-\"\r\n\t\t\t\t\t\t/>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t</div>\r\n\r\n\t\t\t\t{/* Y (行) */}\r\n\t\t\t\t<div className={styles.field}>\r\n\t\t\t\t\t<span className={styles.label}>Y</span>\r\n\t\t\t\t\t<div className={styles.inputWrapper}>\r\n\t\t\t\t\t\t<NumberInput\r\n\t\t\t\t\t\t\tvalue={\r\n\t\t\t\t\t\t\t\tisMultipleSelection\r\n\t\t\t\t\t\t\t\t\t? minY\r\n\t\t\t\t\t\t\t\t\t: getCommonValue(selectedBlocks, \"layout.y\")\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\tonChange={(v) => handleChange(\"y\", v)}\r\n\t\t\t\t\t\t\tmin={0}\r\n\t\t\t\t\t\t\tmax={gridSize ? gridSize.rows - 1 : undefined}\r\n\t\t\t\t\t\t\tinteger\r\n\t\t\t\t\t\t\theight={22}\r\n\t\t\t\t\t\t\tplaceholder=\"-\"\r\n\t\t\t\t\t\t/>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t</div>\r\n\r\n\t\t\t\t{/* W (幅) - 複数選択時は非表示 */}\r\n\t\t\t\t{!isMultipleSelection && (\r\n\t\t\t\t\t<div className={styles.field}>\r\n\t\t\t\t\t\t<span className={styles.label}>W</span>\r\n\t\t\t\t\t\t<div className={styles.inputWrapper}>\r\n\t\t\t\t\t\t\t<NumberInput\r\n\t\t\t\t\t\t\t\tvalue={getCommonValue(selectedBlocks, \"layout.w\")}\r\n\t\t\t\t\t\t\t\tonChange={(v) => handleChange(\"w\", v)}\r\n\t\t\t\t\t\t\t\tmin={1}\r\n\t\t\t\t\t\t\t\tmax={gridSize?.cols}\r\n\t\t\t\t\t\t\t\tinteger\r\n\t\t\t\t\t\t\t\theight={22}\r\n\t\t\t\t\t\t\t\tplaceholder=\"-\"\r\n\t\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t</div>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t)}\r\n\r\n\t\t\t\t{/* H (高さ) - 複数選択時は非表示 */}\r\n\t\t\t\t{!isMultipleSelection && (\r\n\t\t\t\t\t<div className={styles.field}>\r\n\t\t\t\t\t\t<span className={styles.label}>H</span>\r\n\t\t\t\t\t\t<div className={styles.inputWrapper}>\r\n\t\t\t\t\t\t\t<NumberInput\r\n\t\t\t\t\t\t\t\tvalue={getCommonValue(selectedBlocks, \"layout.h\")}\r\n\t\t\t\t\t\t\t\tonChange={(v) => handleChange(\"h\", v)}\r\n\t\t\t\t\t\t\t\tmin={1}\r\n\t\t\t\t\t\t\t\tmax={gridSize?.rows}\r\n\t\t\t\t\t\t\t\tinteger\r\n\t\t\t\t\t\t\t\theight={22}\r\n\t\t\t\t\t\t\t\tplaceholder=\"-\"\r\n\t\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t</div>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t)}\r\n\t\t\t</div>\r\n\t\t</div>\r\n\t);\r\n};\r\n","import { useEffect, useState } from \"react\";\r\n\r\nimport { Checkbox, TextInput } from \"../../../components\";\r\nimport { getCommonValue } from \"../../../utils/getCommonValue\";\r\nimport styles from \"./MetaPanel.module.css\";\r\n\r\nimport type React from \"react\";\r\nimport type { Block } from \"@/types\";\r\n\r\nexport interface MetaPanelProps {\r\n\tselectedBlocks: Block[];\r\n\tonUpdateBlocks: (updates: Record<string, Partial<Block>>) => void;\r\n}\r\n\r\nexport const MetaPanel: React.FC<MetaPanelProps> = ({\r\n\tselectedBlocks,\r\n\tonUpdateBlocks,\r\n}) => {\r\n\tconst [localId, setLocalId] = useState(\"\");\r\n\r\n\tconst primaryBlock = selectedBlocks[0];\r\n\r\n\tuseEffect(() => {\r\n\t\tif (selectedBlocks.length === 1 && primaryBlock) {\r\n\t\t\tsetLocalId(primaryBlock.id);\r\n\t\t}\r\n\t}, [selectedBlocks, primaryBlock]);\r\n\r\n\t// ID確定時の処理 (onBlur)\r\n\tconst handleIdBlur = () => {\r\n\t\tif (!primaryBlock) return;\r\n\r\n\t\tconst currentId = primaryBlock.id;\r\n\t\tconst newId = localId.trim();\r\n\r\n\t\t// 変更がない、または空の場合は元に戻す\r\n\t\tif (newId === currentId || !newId) {\r\n\t\t\tsetLocalId(currentId);\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// TODO: ここでIDの重複チェックを行うのが望ましい\r\n\t\t// 重複していなければ更新\r\n\t\tonUpdateBlocks({\r\n\t\t\t[currentId]: { id: newId },\r\n\t\t});\r\n\t};\r\n\r\n\t// --- ID onChange ---\r\n\tconst handleIdChange = (val: string | undefined) => {\r\n\t\tsetLocalId(val ?? \"\");\r\n\t};\r\n\r\n\t// --- ReadOnly ---\r\n\tconst handleReadOnlyChange = (val: boolean | undefined) => {\r\n\t\tconst updates: Record<string, Partial<Block>> = {};\r\n\t\tselectedBlocks.forEach((b) => {\r\n\t\t\tupdates[b.id] = {\r\n\t\t\t\tbehavior: { ...b.behavior, readOnly: !!val },\r\n\t\t\t};\r\n\t\t});\r\n\t\tonUpdateBlocks(updates);\r\n\t};\r\n\r\n\treturn (\r\n\t\t<div className={styles.container}>\r\n\t\t\t{/* ID */}\r\n\t\t\t{selectedBlocks.length === 1 && (\r\n\t\t\t\t<div className={styles.row}>\r\n\t\t\t\t\t<span className={styles.label}>ID</span>\r\n\t\t\t\t\t<div className={styles.inputWrapper}>\r\n\t\t\t\t\t\t<TextInput\r\n\t\t\t\t\t\t\tvalue={localId}\r\n\t\t\t\t\t\t\tonChange={handleIdChange}\r\n\t\t\t\t\t\t\tonBlur={handleIdBlur}\r\n\t\t\t\t\t\t\tplaceholder=\"IDを入力\"\r\n\t\t\t\t\t\t\theight={16} // 他のパネルと高さを統一\r\n\t\t\t\t\t\t/>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t</div>\r\n\t\t\t)}\r\n\r\n\t\t\t{/* 振る舞い (Behavior) */}\r\n\t\t\t{selectedBlocks.length > 0 && (\r\n\t\t\t\t<div className={styles.row}>\r\n\t\t\t\t\t<div className={styles.inputWrapper}>\r\n\t\t\t\t\t\t<Checkbox\r\n\t\t\t\t\t\t\tlabel=\"読み取り専用\"\r\n\t\t\t\t\t\t\tvalue={!!getCommonValue(selectedBlocks, \"behavior.readOnly\")}\r\n\t\t\t\t\t\t\tonChange={handleReadOnlyChange}\r\n\t\t\t\t\t\t/>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t</div>\r\n\t\t\t)}\r\n\t\t</div>\r\n\t);\r\n};\r\n","import { memo } from \"react\";\r\n\r\nimport { getCommonValue } from \"../../utils/getCommonValue\";\r\nimport styles from \"./PropertyField.module.css\";\r\n\r\nimport type { PropertyDefinition } from \"@/plugin\";\r\nimport type { Block, Value } from \"@/types\";\r\n\r\nexport interface PropertyFieldProps {\r\n\tpropertyKey: string;\r\n\tdefinition: PropertyDefinition<Value, Record<string, Value>>;\r\n\tselectedBlocks: Block[];\r\n\tonChange: (key: string, val: Value) => void;\r\n}\r\n\r\nexport const PropertyField = memo(\r\n\t({\r\n\t\tpropertyKey,\r\n\t\tdefinition,\r\n\t\tselectedBlocks,\r\n\t\tonChange,\r\n\t}: PropertyFieldProps) => {\r\n\t\tconst Component = definition.Component;\r\n\r\n\t\t// コンポーネントがない場合は何も描画しない\r\n\t\tif (!Component) return null;\r\n\r\n\t\t// 値の計算ロジック\r\n\t\tconst displayValue = getCommonValue(selectedBlocks, `props.${propertyKey}`);\r\n\t\tconst vals = selectedBlocks.map((b) => b.props[propertyKey]);\r\n\t\tconst allUndefined = vals.every((v) => v === undefined);\r\n\r\n\t\t// 混在判定: 全てがundefinedではなく、かつ共通値がundefinedの場合\r\n\t\tconst isMixed =\r\n\t\t\t!allUndefined && displayValue === undefined && selectedBlocks.length > 1;\r\n\r\n\t\t// コンポーネントに渡すPropsの構築\r\n\t\tconst componentProps = {\r\n\t\t\tvalue: isMixed\r\n\t\t\t\t? undefined\r\n\t\t\t\t: displayValue !== undefined\r\n\t\t\t\t\t? displayValue\r\n\t\t\t\t\t: definition.defaultValue,\r\n\t\t\tonChange: (val: Value) => onChange(propertyKey, val),\r\n\t\t\treadOnly: false,\r\n\t\t\tconfig: {\r\n\t\t\t\t...definition.config,\r\n\t\t\t\t// 混在時はプレースホルダーを上書きしてユーザーに知らせる\r\n\t\t\t\tplaceholder: isMixed\r\n\t\t\t\t\t? \"複数選択中 (値が異なります)\"\r\n\t\t\t\t\t: definition.config?.placeholder,\r\n\t\t\t},\r\n\t\t};\r\n\r\n\t\treturn (\r\n\t\t\t<div className={styles.field}>\r\n\t\t\t\t{definition.label && (\r\n\t\t\t\t\t<div className={styles.label} title={definition.description}>\r\n\t\t\t\t\t\t{definition.label}\r\n\t\t\t\t\t</div>\r\n\t\t\t\t)}\r\n\r\n\t\t\t\t{/* 入力コンポーネントの描画 */}\r\n\t\t\t\t<Component {...componentProps} />\r\n\r\n\t\t\t\t{isMixed && <span className={styles.mixed}>(混在)</span>}\r\n\r\n\t\t\t\t{definition.description && (\r\n\t\t\t\t\t<p className={styles.description}>{definition.description}</p>\r\n\t\t\t\t)}\r\n\t\t\t</div>\r\n\t\t);\r\n\t},\r\n);\r\n\r\nPropertyField.displayName = \"PropertyField\";\r\n","import { memo, useMemo } from \"react\";\r\n\r\nimport {\r\n\tBackgroundPanel,\r\n\tBorderPanel,\r\n\tLayoutPanel,\r\n\tMetaPanel,\r\n} from \"./BasePanels\";\r\nimport styles from \"./BlockPropertyPanel.module.css\";\r\nimport { PropertyField } from \"./PluginPanels/PropertyField\";\r\n\r\nimport type { BlockPlugin, PropertyConfig, PropertyDefinition } from \"@/plugin\";\r\nimport type { Block, Value } from \"@/types\";\r\n\r\nfunction isPropertyDefinition(\r\n\tconfig: PropertyConfig<Value, Record<string, Value>>,\r\n): config is PropertyDefinition<Value, Record<string, Value>> {\r\n\treturn config !== false;\r\n}\r\n\r\nexport interface BlockPropertyPanelProps {\r\n\tselectedBlocks: Block[];\r\n\tpluginRegistry: Record<string, BlockPlugin>;\r\n\tonUpdateBlocks: (updates: Record<string, Partial<Block>>) => void;\r\n\tgridSize?: { cols: number; rows: number };\r\n\tclassName?: string;\r\n}\r\n\r\n/**\r\n * PropertyPanel\r\n *\r\n * 選択されたブロックのプロパティを編集するための統合サイドバーコンポーネント。\r\n * BasePanels(共通設定)と PluginPanels(固有設定)を組み合わせて表示します。\r\n */\r\nexport const BlockPropertyPanel = memo(\r\n\t({\r\n\t\tselectedBlocks,\r\n\t\tpluginRegistry,\r\n\t\tonUpdateBlocks,\r\n\t\tgridSize,\r\n\t\tclassName = \"\",\r\n\t}: BlockPropertyPanelProps) => {\r\n\t\tconst primaryBlock = selectedBlocks[0];\r\n\t\tconst plugin = primaryBlock ? pluginRegistry[primaryBlock.kind] : undefined;\r\n\r\n\t\t// 選択されたブロックがすべて同じ種類(kind)かチェック\r\n\t\tconst allSameKind = useMemo(() => {\r\n\t\t\tif (selectedBlocks.length === 0) return false;\r\n\t\t\tconst firstKind = selectedBlocks[0]?.kind;\r\n\t\t\treturn selectedBlocks.every((block) => block.kind === firstKind);\r\n\t\t}, [selectedBlocks]);\r\n\r\n\t\t// プロパティ定義のグルーピング\r\n\t\tconst groupedProps = useMemo(() => {\r\n\t\t\tif (!primaryBlock || !plugin) return {};\r\n\r\n\t\t\tconst groups: Record<\r\n\t\t\t\tstring,\r\n\t\t\t\tArray<{\r\n\t\t\t\t\tkey: string;\r\n\t\t\t\t\tdefinition: PropertyDefinition<Value, Record<string, Value>> & {\r\n\t\t\t\t\t\tComponent: React.ComponentType<{\r\n\t\t\t\t\t\t\tvalue: Value;\r\n\t\t\t\t\t\t\tonChange: (value: Value) => void;\r\n\t\t\t\t\t\t}>;\r\n\t\t\t\t\t};\r\n\t\t\t\t}>\r\n\t\t\t> = {};\r\n\r\n\t\t\t// 異なる種類のブロックが混在している場合は、共通プロパティのみを表示\r\n\t\t\tlet propertiesToShow: [\r\n\t\t\t\tstring,\r\n\t\t\t\tPropertyConfig<Value, Record<string, Value>>,\r\n\t\t\t][];\r\n\r\n\t\t\tif (allSameKind) {\r\n\t\t\t\t// 同じ種類のブロックのみ: すべてのプロパティを表示\r\n\t\t\t\tpropertiesToShow = Object.entries(plugin.properties);\r\n\t\t\t} else {\r\n\t\t\t\t// 異なる種類のブロックが混在: 共通プロパティのみを表示\r\n\t\t\t\tconst allPlugins = selectedBlocks\r\n\t\t\t\t\t.map((block) => pluginRegistry[block.kind])\r\n\t\t\t\t\t.filter((p): p is BlockPlugin => p !== undefined);\r\n\r\n\t\t\t\tif (allPlugins.length === 0) return {};\r\n\r\n\t\t\t\t// すべてのプラグインで共通しているプロパティキーを抽出\r\n\t\t\t\tconst firstPlugin = allPlugins[0];\r\n\t\t\t\tif (!firstPlugin) return {};\r\n\r\n\t\t\t\tconst firstPluginKeys = new Set(Object.keys(firstPlugin.properties));\r\n\t\t\t\tconst commonKeys = Array.from(firstPluginKeys).filter((key) =>\r\n\t\t\t\t\tallPlugins.every((p) => key in p.properties),\r\n\t\t\t\t);\r\n\r\n\t\t\t\t// primaryBlockのプラグインから共通プロパティを取得\r\n\t\t\t\tpropertiesToShow = commonKeys\r\n\t\t\t\t\t.map(\r\n\t\t\t\t\t\t(\r\n\t\t\t\t\t\t\tkey,\r\n\t\t\t\t\t\t):\r\n\t\t\t\t\t\t\t| [string, PropertyConfig<Value, Record<string, Value>>]\r\n\t\t\t\t\t\t\t| null => {\r\n\t\t\t\t\t\t\tconst prop = plugin.properties[key];\r\n\t\t\t\t\t\t\treturn prop ? [key, prop] : null;\r\n\t\t\t\t\t\t},\r\n\t\t\t\t\t)\r\n\t\t\t\t\t.filter(\r\n\t\t\t\t\t\t(\r\n\t\t\t\t\t\t\tentry,\r\n\t\t\t\t\t\t): entry is [\r\n\t\t\t\t\t\t\tstring,\r\n\t\t\t\t\t\t\tPropertyConfig<Value, Record<string, Value>>,\r\n\t\t\t\t\t\t] => entry !== null,\r\n\t\t\t\t\t);\r\n\t\t\t}\r\n\r\n\t\t\tpropertiesToShow.forEach(([key, propertyConfig]) => {\r\n\t\t\t\t// 無効な定義を除外\r\n\t\t\t\tif (!isPropertyDefinition(propertyConfig)) return;\r\n\r\n\t\t\t\t// 複数選択時の制限チェック\r\n\t\t\t\tif (selectedBlocks.length > 1 && propertyConfig.disableInMultiSelection)\r\n\t\t\t\t\treturn;\r\n\r\n\t\t\t\t// 表示条件(condition)のチェック\r\n\t\t\t\tif (\r\n\t\t\t\t\tpropertyConfig.condition &&\r\n\t\t\t\t\t!propertyConfig.condition(primaryBlock.props)\r\n\t\t\t\t)\r\n\t\t\t\t\treturn;\r\n\r\n\t\t\t\t// グループ分け\r\n\t\t\t\tconst groupName = propertyConfig.group || \"基本\";\r\n\t\t\t\tif (!groups[groupName]) groups[groupName] = [];\r\n\t\t\t\t// Componentが存在しない場合はスキップ\r\n\t\t\t\tif (!propertyConfig.Component) return;\r\n\t\t\t\tgroups[groupName].push({\r\n\t\t\t\t\tkey,\r\n\t\t\t\t\tdefinition: propertyConfig as PropertyDefinition<\r\n\t\t\t\t\t\tValue,\r\n\t\t\t\t\t\tRecord<string, Value>\r\n\t\t\t\t\t> & {\r\n\t\t\t\t\t\tComponent: React.ComponentType<{\r\n\t\t\t\t\t\t\tvalue: Value;\r\n\t\t\t\t\t\t\tonChange: (value: Value) => void;\r\n\t\t\t\t\t\t}>;\r\n\t\t\t\t\t},\r\n\t\t\t\t});\r\n\t\t\t});\r\n\r\n\t\t\treturn groups;\r\n\t\t}, [plugin, pluginRegistry, selectedBlocks, primaryBlock, allSameKind]); // プラグインプロパティ変更ハンドラ\r\n\t\tconst handlePluginPropertyChange = (key: string, newValue: Value) => {\r\n\t\t\tconst updates: Record<string, Partial<Block>> = {};\r\n\t\t\tselectedBlocks.forEach((block) => {\r\n\t\t\t\tupdates[block.id] = {\r\n\t\t\t\t\tprops: {\r\n\t\t\t\t\t\t...block.props,\r\n\t\t\t\t\t\t[key]: newValue,\r\n\t\t\t\t\t},\r\n\t\t\t\t};\r\n\t\t\t});\r\n\t\t\tonUpdateBlocks(updates);\r\n\t\t};\r\n\r\n\t\t// ブロックが選択されていない場合\r\n\t\tif (selectedBlocks.length === 0) {\r\n\t\t\treturn (\r\n\t\t\t\t<div className={`${styles.container} ${className}`}>\r\n\t\t\t\t\t<div className={styles.emptyState}>\r\n\t\t\t\t\t\tブロックを選択すると\r\n\t\t\t\t\t\t<br />\r\n\t\t\t\t\t\tプロパティが表示されます\r\n\t\t\t\t\t</div>\r\n\t\t\t\t</div>\r\n\t\t\t);\r\n\t\t}\r\n\r\n\t\treturn (\r\n\t\t\t<div className={`${styles.container} ${className}`}>\r\n\t\t\t\t<div className={styles.scrollArea}>\r\n\t\t\t\t\t{/* 2. レイアウト (X, Y, W, H) */}\r\n\t\t\t\t\t<div className={styles.section}>\r\n\t\t\t\t\t\t<div className={styles.sectionTitle}>配置・サイズ</div>\r\n\t\t\t\t\t\t<LayoutPanel\r\n\t\t\t\t\t\t\tselectedBlocks={selectedBlocks}\r\n\t\t\t\t\t\t\tonUpdateBlocks={onUpdateBlocks}\r\n\t\t\t\t\t\t\tgridSize={gridSize}\r\n\t\t\t\t\t\t/>\r\n\t\t\t\t\t</div>\r\n\r\n\t\t\t\t\t{/* 4. スタイル (背景色) */}\r\n\t\t\t\t\t<div className={styles.section}>\r\n\t\t\t\t\t\t<div className={styles.sectionTitle}>背景</div>\r\n\t\t\t\t\t\t<BackgroundPanel\r\n\t\t\t\t\t\t\tselectedBlocks={selectedBlocks}\r\n\t\t\t\t\t\t\tonUpdateBlocks={onUpdateBlocks}\r\n\t\t\t\t\t\t/>\r\n\t\t\t\t\t</div>\r\n\r\n\t\t\t\t\t{/* 5. スタイル (枠線) */}\r\n\t\t\t\t\t<div className={styles.section}>\r\n\t\t\t\t\t\t<div className={styles.sectionTitle}>枠線</div>\r\n\t\t\t\t\t\t<BorderPanel\r\n\t\t\t\t\t\t\tselectedBlocks={selectedBlocks}\r\n\t\t\t\t\t\t\tonUpdateBlocks={onUpdateBlocks}\r\n\t\t\t\t\t\t/>\r\n\t\t\t\t\t</div>\r\n\r\n\t\t\t\t\t{/* 3. プラグイン固有プロパティ (TextPlugin等) */}\r\n\t\t\t\t\t{plugin && Object.keys(groupedProps).length > 0 && (\r\n\t\t\t\t\t\t<div className={styles.section}>\r\n\t\t\t\t\t\t\t{Object.entries(groupedProps).map(([groupName, items]) => (\r\n\t\t\t\t\t\t\t\t<div key={groupName} className={styles.subsection}>\r\n\t\t\t\t\t\t\t\t\t<div className={styles.subsectionTitle}>{groupName}</div>\r\n\t\t\t\t\t\t\t\t\t<div className={styles.fields}>\r\n\t\t\t\t\t\t\t\t\t\t{items.map(({ key, definition }) => (\r\n\t\t\t\t\t\t\t\t\t\t\t<PropertyField\r\n\t\t\t\t\t\t\t\t\t\t\t\tkey={key}\r\n\t\t\t\t\t\t\t\t\t\t\t\tpropertyKey={key}\r\n\t\t\t\t\t\t\t\t\t\t\t\tdefinition={definition}\r\n\t\t\t\t\t\t\t\t\t\t\t\tselectedBlocks={selectedBlocks}\r\n\t\t\t\t\t\t\t\t\t\t\t\tonChange={handlePluginPropertyChange}\r\n\t\t\t\t\t\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t\t\t\t\t))}\r\n\t\t\t\t\t\t\t\t\t</div>\r\n\t\t\t\t\t\t\t\t</div>\r\n\t\t\t\t\t\t\t))}\r\n\t\t\t\t\t\t</div>\r\n\t\t\t\t\t)}\r\n\r\n\t\t\t\t\t{/* 1. メタ情報 (ID, ReadOnly) */}\r\n\t\t\t\t\t<div className={styles.section}>\r\n\t\t\t\t\t\t<div className={styles.sectionTitle}>基本設定</div>\r\n\t\t\t\t\t\t<MetaPanel\r\n\t\t\t\t\t\t\tselectedBlocks={selectedBlocks}\r\n\t\t\t\t\t\t\tonUpdateBlocks={onUpdateBlocks}\r\n\t\t\t\t\t\t/>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t</div>\r\n\t\t\t</div>\r\n\t\t);\r\n\t},\r\n);\r\n\r\nBlockPropertyPanel.displayName = \"BlockPropertyPanel\";\r\n","import { useMemo } from \"react\";\r\n\r\nimport styles from \"./PluginPanels.module.css\";\r\nimport { PropertyField } from \"./PropertyField\";\r\n\r\nimport type { BlockPlugin, PropertyConfig, PropertyDefinition } from \"@/plugin\";\r\nimport type { Block, Value } from \"@/types\";\r\n\r\nexport interface PluginPanelsProps {\r\n\tselectedBlocks: Block[];\r\n\tpluginRegistry: Record<string, BlockPlugin>;\r\n\tonUpdateBlocks: (updates: Record<string, Partial<Block>>) => void;\r\n}\r\n\r\nfunction isPropertyDefinition(\r\n\tconfig: PropertyConfig<Value, Record<string, Value>>,\r\n): config is PropertyDefinition<Value, Record<string, Value>> {\r\n\treturn config !== false;\r\n}\r\n\r\nexport const PluginPanels: React.FC<PluginPanelsProps> = ({\r\n\tselectedBlocks,\r\n\tpluginRegistry,\r\n\tonUpdateBlocks,\r\n}) => {\r\n\tconst primaryBlock = selectedBlocks[0];\r\n\tconst plugin = primaryBlock ? pluginRegistry[primaryBlock.kind] : undefined;\r\n\r\n\t// プロパティ定義のグルーピング\r\n\tconst groupedProps = useMemo(() => {\r\n\t\tif (!primaryBlock || !plugin) return {};\r\n\t\tconst groups: Record<\r\n\t\t\tstring,\r\n\t\t\tArray<{\r\n\t\t\t\tkey: string;\r\n\t\t\t\tdefinition: PropertyDefinition<Value, Record<string, Value>> & {\r\n\t\t\t\t\tComponent: React.ComponentType<{\r\n\t\t\t\t\t\tvalue: Value;\r\n\t\t\t\t\t\tonChange: (value: Value) => void;\r\n\t\t\t\t\t}>;\r\n\t\t\t\t};\r\n\t\t\t}>\r\n\t\t> = {};\r\n\r\n\t\tObject.entries(plugin.properties).forEach(([key, propertyConfig]) => {\r\n\t\t\t// 無効な定義を除外\r\n\t\t\tif (!isPropertyDefinition(propertyConfig)) return;\r\n\r\n\t\t\t// 複数選択時の制限チェック\r\n\t\t\tif (selectedBlocks.length > 1 && propertyConfig.disableInMultiSelection)\r\n\t\t\t\treturn;\r\n\r\n\t\t\t// 表示条件(condition)のチェック\r\n\t\t\tif (\r\n\t\t\t\tpropertyConfig.condition &&\r\n\t\t\t\t!propertyConfig.condition(primaryBlock.props)\r\n\t\t\t)\r\n\t\t\t\treturn;\r\n\r\n\t\t\t// グループ分け\r\n\t\t\tconst groupName = propertyConfig.group || \"基本\";\r\n\t\t\tif (!groups[groupName]) groups[groupName] = [];\r\n\t\t\t// Componentが存在しない場合はスキップ\r\n\t\t\tif (!propertyConfig.Component) return;\r\n\t\t\tgroups[groupName].push({\r\n\t\t\t\tkey,\r\n\t\t\t\tdefinition: propertyConfig as PropertyDefinition<\r\n\t\t\t\t\tValue,\r\n\t\t\t\t\tRecord<string, Value>\r\n\t\t\t\t> & {\r\n\t\t\t\t\tComponent: React.ComponentType<{\r\n\t\t\t\t\t\tvalue: Value;\r\n\t\t\t\t\t\tonChange: (value: Value) => void;\r\n\t\t\t\t\t}>;\r\n\t\t\t\t},\r\n\t\t\t});\r\n\t\t});\r\n\r\n\t\treturn groups;\r\n\t}, [plugin, selectedBlocks.length, primaryBlock]);\r\n\r\n\t// ハンドラ\r\n\tconst handleChange = (key: string, newValue: Value) => {\r\n\t\tconst updates: Record<string, Partial<Block>> = {};\r\n\t\tselectedBlocks.forEach((block) => {\r\n\t\t\tupdates[block.id] = {\r\n\t\t\t\tprops: {\r\n\t\t\t\t\t...block.props,\r\n\t\t\t\t\t[key]: newValue,\r\n\t\t\t\t},\r\n\t\t\t};\r\n\t\t});\r\n\t\tonUpdateBlocks(updates);\r\n\t};\r\n\r\n\tif (!primaryBlock) return null;\r\n\tif (!plugin) return null;\r\n\tif (selectedBlocks.length === 0) return null;\r\n\r\n\treturn (\r\n\t\t<div className={styles.panel}>\r\n\t\t\t<div className={styles.header}>\r\n\t\t\t\t{selectedBlocks.length > 1\r\n\t\t\t\t\t? `${selectedBlocks.length}個のブロック`\r\n\t\t\t\t\t: plugin.meta.displayName}\r\n\t\t\t</div>\r\n\r\n\t\t\t{Object.entries(groupedProps).map(([groupName, items]) => (\r\n\t\t\t\t<div key={groupName} className={styles.group}>\r\n\t\t\t\t\t<div className={styles.groupTitle}>{groupName}</div>\r\n\t\t\t\t\t<div className={styles.groupContent}>\r\n\t\t\t\t\t\t{items.map(({ key, definition }) => (\r\n\t\t\t\t\t\t\t<PropertyField\r\n\t\t\t\t\t\t\t\tkey={key}\r\n\t\t\t\t\t\t\t\tpropertyKey={key}\r\n\t\t\t\t\t\t\t\tdefinition={definition}\r\n\t\t\t\t\t\t\t\tselectedBlocks={selectedBlocks}\r\n\t\t\t\t\t\t\t\tonChange={handleChange}\r\n\t\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t))}\r\n\t\t\t\t\t</div>\r\n\t\t\t\t</div>\r\n\t\t\t))}\r\n\t\t</div>\r\n\t);\r\n};\r\n","/**\r\n * @file BlockOrderPanel.tsx\r\n * @description ブロック配列順番変更パネル\r\n */\r\n\r\nimport { useCallback, useState } from \"react\";\r\n\r\nimport styles from \"./BlockOrderPanel.module.css\";\r\n\r\nimport type { Block } from \"@/types/block\";\r\n\r\nexport interface BlockOrderPanelProps {\r\n\t/** ブロック一覧 */\r\n\tblocks: Block[];\r\n\t/** ブロック更新時のコールバック (blocks配列全体を更新) */\r\n\tonBlocksChange: (blocks: Block[]) => void;\r\n}\r\n\r\n/**\r\n * BlockOrderPanel\r\n * ブロックの配列順序を変更するパネル\r\n * UIでは上が最前面、下が最背面(一般的なデザインソフトと同じ)\r\n * 内部配列では最後が最前面\r\n */\r\nexport const BlockOrderPanel = ({\r\n\tblocks,\r\n\tonBlocksChange,\r\n}: BlockOrderPanelProps) => {\r\n\t// ドラッグ中のブロックインデックス\r\n\tconst [draggedIndex, setDraggedIndex] = useState<number | null>(null);\r\n\tconst [dragOverIndex, setDragOverIndex] = useState<number | null>(null);\r\n\r\n\t// UIでは逆順で表示(上が最前面)\r\n\tconst displayBlocks = [...blocks].reverse();\r\n\r\n\t// 最前面へ移動(配列の最後に移動)\r\n\tconst handleBringToFront = useCallback(\r\n\t\t(blockId: string) => {\r\n\t\t\tconst index = blocks.findIndex((b) => b.id === blockId);\r\n\t\t\tif (index === -1 || index === blocks.length - 1) return;\r\n\r\n\t\t\tconst newBlocks = [...blocks];\r\n\t\t\tconst [block] = newBlocks.splice(index, 1);\r\n\t\t\tif (!block) return;\r\n\t\t\tnewBlocks.push(block);\r\n\t\t\tonBlocksChange(newBlocks);\r\n\t\t},\r\n\t\t[blocks, onBlocksChange],\r\n\t);\r\n\r\n\t// 最背面へ移動(配列の先頭に移動)\r\n\tconst handleSendToBack = useCallback(\r\n\t\t(blockId: string) => {\r\n\t\t\tconst index = blocks.findIndex((b) => b.id === blockId);\r\n\t\t\tif (index === -1 || index === 0) return;\r\n\r\n\t\t\tconst newBlocks = [...blocks];\r\n\t\t\tconst [block] = newBlocks.splice(index, 1);\r\n\t\t\tif (!block) return;\r\n\t\t\tnewBlocks.unshift(block);\r\n\t\t\tonBlocksChange(newBlocks);\r\n\t\t},\r\n\t\t[blocks, onBlocksChange],\r\n\t);\r\n\r\n\t// 前面へ移動(1つ後ろに移動)\r\n\tconst handleBringForward = useCallback(\r\n\t\t(blockId: string) => {\r\n\t\t\tconst index = blocks.findIndex((b) => b.id === blockId);\r\n\t\t\tif (index === -1 || index === blocks.length - 1) return;\r\n\r\n\t\t\tconst newBlocks = [...blocks];\r\n\t\t\tconst temp = newBlocks[index];\r\n\t\t\tconst next = newBlocks[index + 1];\r\n\t\t\tif (!temp || !next) return;\r\n\t\t\tnewBlocks[index] = next;\r\n\t\t\tnewBlocks[index + 1] = temp;\r\n\t\t\tonBlocksChange(newBlocks);\r\n\t\t},\r\n\t\t[blocks, onBlocksChange],\r\n\t);\r\n\r\n\t// 背面へ移動(1つ前に移動)\r\n\tconst handleSendBackward = useCallback(\r\n\t\t(blockId: string) => {\r\n\t\t\tconst index = blocks.findIndex((b) => b.id === blockId);\r\n\t\t\tif (index === -1 || index === 0) return;\r\n\r\n\t\t\tconst newBlocks = [...blocks];\r\n\t\t\tconst temp = newBlocks[index];\r\n\t\t\tconst prev = newBlocks[index - 1];\r\n\t\t\tif (!temp || !prev) return;\r\n\t\t\tnewBlocks[index] = prev;\r\n\t\t\tnewBlocks[index - 1] = temp;\r\n\t\t\tonBlocksChange(newBlocks);\r\n\t\t},\r\n\t\t[blocks, onBlocksChange],\r\n\t);\r\n\r\n\t// ドラッグ開始\r\n\tconst handleDragStart = useCallback(\r\n\t\t(e: React.DragEvent<HTMLElement>, displayIndex: number) => {\r\n\t\t\tsetDraggedIndex(displayIndex);\r\n\t\t\te.dataTransfer.effectAllowed = \"move\";\r\n\t\t\t// 実際のブロックインデックスを取得(逆順)\r\n\t\t\tconst actualIndex = blocks.length - 1 - displayIndex;\r\n\t\t\tif (e.currentTarget) {\r\n\t\t\t\te.dataTransfer.setData(\"text/plain\", blocks[actualIndex]?.id || \"\");\r\n\t\t\t}\r\n\t\t},\r\n\t\t[blocks],\r\n\t);\r\n\r\n\t// ドラッグ終了\r\n\tconst handleDragEnd = useCallback(() => {\r\n\t\tsetDraggedIndex(null);\r\n\t\tsetDragOverIndex(null);\r\n\t}, []);\r\n\r\n\t// ドラッグオーバー\r\n\tconst handleDragOver = useCallback(\r\n\t\t(e: React.DragEvent<HTMLElement>, displayIndex: number) => {\r\n\t\t\te.preventDefault();\r\n\t\t\te.dataTransfer.dropEffect = \"move\";\r\n\r\n\t\t\tif (draggedIndex === null || draggedIndex === displayIndex) return;\r\n\t\t\tsetDragOverIndex(displayIndex);\r\n\t\t},\r\n\t\t[draggedIndex],\r\n\t);\r\n\r\n\t// ドラッグリーブ\r\n\tconst handleDragLeave = useCallback(() => {\r\n\t\tsetDragOverIndex(null);\r\n\t}, []);\r\n\r\n\t// ドロップ\r\n\tconst handleDrop = useCallback(\r\n\t\t(e: React.DragEvent<HTMLElement>, displayDropIndex: number) => {\r\n\t\t\te.preventDefault();\r\n\r\n\t\t\tif (draggedIndex === null || draggedIndex === displayDropIndex) {\r\n\t\t\t\tsetDraggedIndex(null);\r\n\t\t\t\tsetDragOverIndex(null);\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\t// 表示インデックスを実際の配列インデックスに変換\r\n\t\t\tconst actualDraggedIndex = blocks.length - 1 - draggedIndex;\r\n\t\t\tconst actualDropIndex = blocks.length - 1 - displayDropIndex;\r\n\r\n\t\t\tconst newBlocks = [...blocks];\r\n\t\t\tconst [draggedBlock] = newBlocks.splice(actualDraggedIndex, 1);\r\n\t\t\tif (!draggedBlock) return;\r\n\r\n\t\t\tnewBlocks.splice(actualDropIndex, 0, draggedBlock);\r\n\r\n\t\t\tonBlocksChange(newBlocks);\r\n\t\t\tsetDraggedIndex(null);\r\n\t\t\tsetDragOverIndex(null);\r\n\t\t},\r\n\t\t[blocks, draggedIndex, onBlocksChange],\r\n\t);\r\n\r\n\treturn (\r\n\t\t<div className={styles.panel}>\r\n\t\t\t<h3 className={styles.title}>ブロック順序</h3>\r\n\r\n\t\t\t<div className={styles.content}>\r\n\t\t\t\t<p className={styles.description}>上が最前面、下が最背面</p>\r\n\r\n\t\t\t\t<ul className={styles.list}>\r\n\t\t\t\t\t{displayBlocks.map((block, displayIndex) => {\r\n\t\t\t\t\t\t// 実際の配列インデックス\r\n\t\t\t\t\t\tconst actualIndex = blocks.length - 1 - displayIndex;\r\n\t\t\t\t\t\treturn (\r\n\t\t\t\t\t\t\t<li\r\n\t\t\t\t\t\t\t\tkey={block.id}\r\n\t\t\t\t\t\t\t\tclassName={`${styles.item} ${\r\n\t\t\t\t\t\t\t\t\tdraggedIndex === displayIndex ? styles.dragging : \"\"\r\n\t\t\t\t\t\t\t\t} ${dragOverIndex === displayIndex ? styles.dragOver : \"\"}`}\r\n\t\t\t\t\t\t\t\tonDragOver={(e) => handleDragOver(e, displayIndex)}\r\n\t\t\t\t\t\t\t\tonDragLeave={handleDragLeave}\r\n\t\t\t\t\t\t\t\tonDrop={(e) => handleDrop(e, displayIndex)}\r\n\t\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t\t<button\r\n\t\t\t\t\t\t\t\t\ttype=\"button\"\r\n\t\t\t\t\t\t\t\t\tclassName={styles.dragHandle}\r\n\t\t\t\t\t\t\t\t\ttitle=\"ドラッグして並び替え\"\r\n\t\t\t\t\t\t\t\t\tdraggable\r\n\t\t\t\t\t\t\t\t\tonDragStart={(e) => handleDragStart(e, displayIndex)}\r\n\t\t\t\t\t\t\t\t\tonDragEnd={handleDragEnd}\r\n\t\t\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t\t\t<svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\r\n\t\t\t\t\t\t\t\t\t\t<title>ドラッグハンドル</title>\r\n\t\t\t\t\t\t\t\t\t\t<circle cx=\"6\" cy=\"4\" r=\"1\" fill=\"currentColor\" />\r\n\t\t\t\t\t\t\t\t\t\t<circle cx=\"10\" cy=\"4\" r=\"1\" fill=\"currentColor\" />\r\n\t\t\t\t\t\t\t\t\t\t<circle cx=\"6\" cy=\"8\" r=\"1\" fill=\"currentColor\" />\r\n\t\t\t\t\t\t\t\t\t\t<circle cx=\"10\" cy=\"8\" r=\"1\" fill=\"currentColor\" />\r\n\t\t\t\t\t\t\t\t\t\t<circle cx=\"6\" cy=\"12\" r=\"1\" fill=\"currentColor\" />\r\n\t\t\t\t\t\t\t\t\t\t<circle cx=\"10\" cy=\"12\" r=\"1\" fill=\"currentColor\" />\r\n\t\t\t\t\t\t\t\t\t</svg>\r\n\t\t\t\t\t\t\t\t</button>\r\n\t\t\t\t\t\t\t\t<div className={styles.itemInfo}>\r\n\t\t\t\t\t\t\t\t\t<div className={styles.itemId}>{block.id}</div>\r\n\t\t\t\t\t\t\t\t\t<div className={styles.itemMeta}>\r\n\t\t\t\t\t\t\t\t\t\t<span className={styles.itemKind}>{block.kind}</span>\r\n\t\t\t\t\t\t\t\t\t</div>\r\n\t\t\t\t\t\t\t\t</div>\r\n\r\n\t\t\t\t\t\t\t\t<div className={styles.itemActions}>\r\n\t\t\t\t\t\t\t\t\t<button\r\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\r\n\t\t\t\t\t\t\t\t\t\tclassName={styles.actionButton}\r\n\t\t\t\t\t\t\t\t\t\tonClick={() => handleBringToFront(block.id)}\r\n\t\t\t\t\t\t\t\t\t\ttitle=\"最前面へ\"\r\n\t\t\t\t\t\t\t\t\t\taria-label=\"最前面へ移動\"\r\n\t\t\t\t\t\t\t\t\t\tdisabled={actualIndex === blocks.length - 1}\r\n\t\t\t\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t\t\t\t<svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\r\n\t\t\t\t\t\t\t\t\t\t\t<title>最前面へ</title>\r\n\t\t\t\t\t\t\t\t\t\t\t<path\r\n\t\t\t\t\t\t\t\t\t\t\t\td=\"M4 12v-8M8 12v-8M12 12v-8\"\r\n\t\t\t\t\t\t\t\t\t\t\t\tstroke=\"currentColor\"\r\n\t\t\t\t\t\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t\t\t\t\t\t<path\r\n\t\t\t\t\t\t\t\t\t\t\t\td=\"M12 4h-8\"\r\n\t\t\t\t\t\t\t\t\t\t\t\tstroke=\"currentColor\"\r\n\t\t\t\t\t\t\t\t\t\t\t\tstrokeWidth=\"2\"\r\n\t\t\t\t\t\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t\t\t\t\t</svg>\r\n\t\t\t\t\t\t\t\t\t</button>\r\n\t\t\t\t\t\t\t\t\t<button\r\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\r\n\t\t\t\t\t\t\t\t\t\tclassName={styles.actionButton}\r\n\t\t\t\t\t\t\t\t\t\tonClick={() => handleBringForward(block.id)}\r\n\t\t\t\t\t\t\t\t\t\ttitle=\"前面へ\"\r\n\t\t\t\t\t\t\t\t\t\taria-label=\"前面へ移動\"\r\n\t\t\t\t\t\t\t\t\t\tdisabled={actualIndex === blocks.length - 1}\r\n\t\t\t\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t\t\t\t<svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\r\n\t\t\t\t\t\t\t\t\t\t\t<title>前面へ</title>\r\n\t\t\t\t\t\t\t\t\t\t\t<path d=\"M8 4v8\" stroke=\"currentColor\" />\r\n\t\t\t\t\t\t\t\t\t\t\t<path d=\"M5 7l3-3 3 3\" stroke=\"currentColor\" />\r\n\t\t\t\t\t\t\t\t\t\t</svg>\r\n\t\t\t\t\t\t\t\t\t</button>\r\n\t\t\t\t\t\t\t\t\t<button\r\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\r\n\t\t\t\t\t\t\t\t\t\tclassName={styles.actionButton}\r\n\t\t\t\t\t\t\t\t\t\tonClick={() => handleSendBackward(block.id)}\r\n\t\t\t\t\t\t\t\t\t\ttitle=\"背面へ\"\r\n\t\t\t\t\t\t\t\t\t\taria-label=\"背面へ移動\"\r\n\t\t\t\t\t\t\t\t\t\tdisabled={actualIndex === 0}\r\n\t\t\t\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t\t\t\t<svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\r\n\t\t\t\t\t\t\t\t\t\t\t<title>背面へ</title>\r\n\t\t\t\t\t\t\t\t\t\t\t<path d=\"M8 12v-8\" stroke=\"currentColor\" />\r\n\t\t\t\t\t\t\t\t\t\t\t<path d=\"M5 9l3 3 3-3\" stroke=\"currentColor\" />\r\n\t\t\t\t\t\t\t\t\t\t</svg>\r\n\t\t\t\t\t\t\t\t\t</button>\r\n\t\t\t\t\t\t\t\t\t<button\r\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\r\n\t\t\t\t\t\t\t\t\t\tclassName={styles.actionButton}\r\n\t\t\t\t\t\t\t\t\t\tonClick={() => handleSendToBack(block.id)}\r\n\t\t\t\t\t\t\t\t\t\ttitle=\"最背面へ\"\r\n\t\t\t\t\t\t\t\t\t\taria-label=\"最背面へ移動\"\r\n\t\t\t\t\t\t\t\t\t\tdisabled={actualIndex === 0}\r\n\t\t\t\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t\t\t\t<svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\r\n\t\t\t\t\t\t\t\t\t\t\t<title>最背面へ</title>\r\n\t\t\t\t\t\t\t\t\t\t\t<path\r\n\t\t\t\t\t\t\t\t\t\t\t\td=\"M4 12v-8M8 12v-8M12 12v-8\"\r\n\t\t\t\t\t\t\t\t\t\t\t\tstroke=\"currentColor\"\r\n\t\t\t\t\t\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t\t\t\t\t\t<path\r\n\t\t\t\t\t\t\t\t\t\t\t\td=\"M12 12h-8\"\r\n\t\t\t\t\t\t\t\t\t\t\t\tstroke=\"currentColor\"\r\n\t\t\t\t\t\t\t\t\t\t\t\tstrokeWidth=\"2\"\r\n\t\t\t\t\t\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t\t\t\t\t</svg>\r\n\t\t\t\t\t\t\t\t\t</button>\r\n\t\t\t\t\t\t\t\t</div>\r\n\t\t\t\t\t\t\t</li>\r\n\t\t\t\t\t\t);\r\n\t\t\t\t\t})}\r\n\t\t\t\t</ul>\r\n\r\n\t\t\t\t{blocks.length === 0 && (\r\n\t\t\t\t\t<div className={styles.empty}>ブロックがありません</div>\r\n\t\t\t\t)}\r\n\t\t\t</div>\r\n\t\t</div>\r\n\t);\r\n};\r\n\r\nBlockOrderPanel.displayName = \"BlockOrderPanel\";\r\n","/**\r\n * @file CanvasPanel.tsx\r\n * @description キャンバス設定統合パネル\r\n */\r\n\r\nimport { useCallback } from \"react\";\r\n\r\nimport { TabPanel } from \"../components/TabPanel\";\r\nimport { BlockOrderPanel, GridSizePanel, MarginPanel, PaperSizePanel } from \".\";\r\n\r\nimport type { Block } from \"@/types/block\";\r\nimport type { Grid } from \"@/types/grid\";\r\nimport type { Paper } from \"@/types/paper\";\r\nimport type { FormSchema } from \"@/types/schema\";\r\n\r\nexport interface CanvasPanelProps {\r\n\t/** フォームスキーマ */\r\n\tschema: FormSchema;\r\n\t/** スキーマ変更時のコールバック */\r\n\tonSchemaChange: (newSchema: FormSchema) => void;\r\n}\r\n\r\n/**\r\n * CanvasPanel\r\n * キャンバス設定の統合パネル\r\n * - PaperSizePanel: 用紙サイズ設定\r\n * - MarginPanel: マージン設定\r\n * - GridSizePanel: グリッドサイズ設定\r\n * - BlockOrderPanel: ブロック順序設定\r\n */\r\nexport const CanvasPanel = ({ schema, onSchemaChange }: CanvasPanelProps) => {\r\n\t// 用紙設定変更\r\n\tconst handlePaperChange = useCallback(\r\n\t\t(newPaper: Paper) => {\r\n\t\t\tonSchemaChange({\r\n\t\t\t\t...schema,\r\n\t\t\t\tpaper: newPaper,\r\n\t\t\t});\r\n\t\t},\r\n\t\t[schema, onSchemaChange],\r\n\t);\r\n\r\n\t// グリッド設定変更\r\n\tconst handleGridChange = useCallback(\r\n\t\t(newGrid: Grid) => {\r\n\t\t\tonSchemaChange({\r\n\t\t\t\t...schema,\r\n\t\t\t\tgrid: newGrid,\r\n\t\t\t});\r\n\t\t},\r\n\t\t[schema, onSchemaChange],\r\n\t);\r\n\r\n\t// ブロック順序変更\r\n\tconst handleBlocksChange = useCallback(\r\n\t\t(newBlocks: Block[]) => {\r\n\t\t\tonSchemaChange({\r\n\t\t\t\t...schema,\r\n\t\t\t\tblocks: newBlocks,\r\n\t\t\t});\r\n\t\t},\r\n\t\t[schema, onSchemaChange],\r\n\t);\r\n\r\n\treturn (\r\n\t\t<TabPanel>\r\n\t\t\t<PaperSizePanel paper={schema.paper} onPaperChange={handlePaperChange} />\r\n\t\t\t<MarginPanel paper={schema.paper} onPaperChange={handlePaperChange} />\r\n\t\t\t<GridSizePanel grid={schema.grid} onGridChange={handleGridChange} />\r\n\t\t\t<BlockOrderPanel\r\n\t\t\t\tblocks={schema.blocks}\r\n\t\t\t\tonBlocksChange={handleBlocksChange}\r\n\t\t\t/>\r\n\t\t</TabPanel>\r\n\t);\r\n};\r\n\r\nCanvasPanel.displayName = \"CanvasPanel\";\r\n","/**\r\n * @file GridSizePanel.tsx\r\n * @description 行・列数変更パネル\r\n */\r\n\r\nimport { useCallback } from \"react\";\r\n\r\nimport { NumberInput } from \"../../components/NumberInput\";\r\nimport styles from \"./GridSizePanel.module.css\";\r\n\r\nimport type { Grid } from \"@/types/grid\";\r\nimport type { Dimension, GridUnit } from \"@/types/unit\";\r\n\r\nexport interface GridSizePanelProps {\r\n\t/** グリッド設定 */\r\n\tgrid: Grid;\r\n\t/** グリッド変更時のコールバック */\r\n\tonGridChange: (grid: Grid) => void;\r\n}\r\n\r\n/**\r\n * GridSizePanel\r\n * 行・列数を変更するパネル\r\n */\r\nexport const GridSizePanel = ({ grid, onGridChange }: GridSizePanelProps) => {\r\n\t// 列数変更ハンドラ\r\n\tconst handleColsChange = useCallback(\r\n\t\t(newColCount: number | undefined) => {\r\n\t\t\tif (!newColCount || newColCount < 1 || newColCount > 100) return;\r\n\r\n\t\t\tconst currentColCount = grid.cols.length;\r\n\t\t\tconst newCols: Dimension<GridUnit>[] = [];\r\n\r\n\t\t\tif (newColCount > currentColCount) {\r\n\t\t\t\t// 列を追加\r\n\t\t\t\tnewCols.push(...grid.cols);\r\n\t\t\t\tfor (let i = currentColCount; i < newColCount; i++) {\r\n\t\t\t\t\tnewCols.push({ value: 1, unit: \"fr\" });\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\t// 列を削除\r\n\t\t\t\tnewCols.push(...grid.cols.slice(0, newColCount));\r\n\t\t\t}\r\n\r\n\t\t\tonGridChange({\r\n\t\t\t\t...grid,\r\n\t\t\t\tcols: newCols,\r\n\t\t\t});\r\n\t\t},\r\n\t\t[grid, onGridChange],\r\n\t);\r\n\r\n\t// 行数変更ハンドラ\r\n\tconst handleRowsChange = useCallback(\r\n\t\t(newRowCount: number | undefined) => {\r\n\t\t\tif (!newRowCount || newRowCount < 1 || newRowCount > 100) return;\r\n\r\n\t\t\tconst currentRowCount = grid.rows.length;\r\n\t\t\tconst newRows: Dimension<GridUnit>[] = [];\r\n\r\n\t\t\tif (newRowCount > currentRowCount) {\r\n\t\t\t\t// 行を追加\r\n\t\t\t\tnewRows.push(...grid.rows);\r\n\t\t\t\tfor (let i = currentRowCount; i < newRowCount; i++) {\r\n\t\t\t\t\tnewRows.push({ value: 1, unit: \"fr\" });\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\t// 行を削除\r\n\t\t\t\tnewRows.push(...grid.rows.slice(0, newRowCount));\r\n\t\t\t}\r\n\r\n\t\t\tonGridChange({\r\n\t\t\t\t...grid,\r\n\t\t\t\trows: newRows,\r\n\t\t\t});\r\n\t\t},\r\n\t\t[grid, onGridChange],\r\n\t);\r\n\r\n\treturn (\r\n\t\t<div className={styles.panel}>\r\n\t\t\t<h3 className={styles.title}>グリッドサイズ</h3>\r\n\r\n\t\t\t<div className={styles.content}>\r\n\t\t\t\t<div className={styles.gridSizeRow}>\r\n\t\t\t\t\t<div className={`${styles.field} ${styles.horizontal}`}>\r\n\t\t\t\t\t\t<span className={styles.label}>列数</span>\r\n\t\t\t\t\t\t<NumberInput\r\n\t\t\t\t\t\t\tvalue={grid.cols.length}\r\n\t\t\t\t\t\t\tonChange={handleColsChange}\r\n\t\t\t\t\t\t\tmin={1}\r\n\t\t\t\t\t\t\tmax={100}\r\n\t\t\t\t\t\t\tstep={1}\r\n\t\t\t\t\t\t/>\r\n\t\t\t\t\t</div>\r\n\r\n\t\t\t\t\t<div className={`${styles.field} ${styles.horizontal}`}>\r\n\t\t\t\t\t\t<span className={styles.label}>行数</span>\r\n\t\t\t\t\t\t<NumberInput\r\n\t\t\t\t\t\t\tvalue={grid.rows.length}\r\n\t\t\t\t\t\t\tonChange={handleRowsChange}\r\n\t\t\t\t\t\t\tmin={1}\r\n\t\t\t\t\t\t\tmax={100}\r\n\t\t\t\t\t\t\tstep={1}\r\n\t\t\t\t\t\t/>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t</div>\r\n\t\t\t</div>\r\n\t\t</div>\r\n\t);\r\n};\r\n\r\nGridSizePanel.displayName = \"GridSizePanel\";\r\n","/**\r\n * @file MarginPanel.tsx\r\n * @description マージン変更パネル\r\n */\r\n\r\nimport { useCallback, useState } from \"react\";\r\n\r\nimport { Checkbox } from \"../../components/Checkbox\";\r\nimport { DimensionInput } from \"../../components/DimensionInput\";\r\nimport styles from \"./MarginPanel.module.css\";\r\n\r\nimport type { Paper, PaperMargin } from \"@/types/paper\";\r\nimport type { Dimension, PaperUnit } from \"@/types/unit\";\r\n\r\nexport interface MarginPanelProps {\r\n\t/** 用紙設定 */\r\n\tpaper: Paper;\r\n\t/** 用紙変更時のコールバック */\r\n\tonPaperChange: (paper: Paper) => void;\r\n}\r\n\r\n/**\r\n * MarginPanel\r\n * マージンを変更するパネル\r\n */\r\nexport const MarginPanel = ({ paper, onPaperChange }: MarginPanelProps) => {\r\n\t// 全辺一括設定モード\r\n\tconst [linkMargins, setLinkMargins] = useState(false);\r\n\r\n\t// リンク変更ハンドラ\r\n\tconst handleLinkChange = useCallback((checked: boolean | undefined) => {\r\n\t\tif (checked !== undefined) {\r\n\t\t\tsetLinkMargins(checked);\r\n\t\t}\r\n\t}, []);\r\n\r\n\t// 上マージン変更ハンドラ\r\n\tconst handleTopChange = useCallback(\r\n\t\t(top: Dimension<PaperUnit> | undefined) => {\r\n\t\t\tif (!top) return;\r\n\r\n\t\t\tconst newMargin: PaperMargin = linkMargins\r\n\t\t\t\t? {\r\n\t\t\t\t\t\ttop,\r\n\t\t\t\t\t\tright: top,\r\n\t\t\t\t\t\tbottom: top,\r\n\t\t\t\t\t\tleft: top,\r\n\t\t\t\t\t}\r\n\t\t\t\t: {\r\n\t\t\t\t\t\t...paper.margin,\r\n\t\t\t\t\t\ttop,\r\n\t\t\t\t\t};\r\n\r\n\t\t\tonPaperChange({\r\n\t\t\t\t...paper,\r\n\t\t\t\tmargin: newMargin,\r\n\t\t\t});\r\n\t\t},\r\n\t\t[paper, onPaperChange, linkMargins],\r\n\t);\r\n\r\n\t// 右マージン変更ハンドラ\r\n\tconst handleRightChange = useCallback(\r\n\t\t(right: Dimension<PaperUnit> | undefined) => {\r\n\t\t\tif (!right) return;\r\n\r\n\t\t\tonPaperChange({\r\n\t\t\t\t...paper,\r\n\t\t\t\tmargin: {\r\n\t\t\t\t\t...paper.margin,\r\n\t\t\t\t\tright,\r\n\t\t\t\t},\r\n\t\t\t});\r\n\t\t},\r\n\t\t[paper, onPaperChange],\r\n\t);\r\n\r\n\t// 下マージン変更ハンドラ\r\n\tconst handleBottomChange = useCallback(\r\n\t\t(bottom: Dimension<PaperUnit> | undefined) => {\r\n\t\t\tif (!bottom) return;\r\n\r\n\t\t\tonPaperChange({\r\n\t\t\t\t...paper,\r\n\t\t\t\tmargin: {\r\n\t\t\t\t\t...paper.margin,\r\n\t\t\t\t\tbottom,\r\n\t\t\t\t},\r\n\t\t\t});\r\n\t\t},\r\n\t\t[paper, onPaperChange],\r\n\t);\r\n\r\n\t// 左マージン変更ハンドラ\r\n\tconst handleLeftChange = useCallback(\r\n\t\t(left: Dimension<PaperUnit> | undefined) => {\r\n\t\t\tif (!left) return;\r\n\r\n\t\t\tonPaperChange({\r\n\t\t\t\t...paper,\r\n\t\t\t\tmargin: {\r\n\t\t\t\t\t...paper.margin,\r\n\t\t\t\t\tleft,\r\n\t\t\t\t},\r\n\t\t\t});\r\n\t\t},\r\n\t\t[paper, onPaperChange],\r\n\t);\r\n\r\n\treturn (\r\n\t\t<div className={styles.panel}>\r\n\t\t\t<div className={styles.header}>\r\n\t\t\t\t<h3 className={styles.title}>マージン</h3>\r\n\t\t\t\t<div className={styles.headerActions}>\r\n\t\t\t\t\t<Checkbox\r\n\t\t\t\t\t\tvalue={linkMargins}\r\n\t\t\t\t\t\tonChange={handleLinkChange}\r\n\t\t\t\t\t\tlabel=\"全辺を一括設定\"\r\n\t\t\t\t\t/>\r\n\t\t\t\t</div>\r\n\t\t\t</div>\r\n\r\n\t\t\t<div className={styles.content}>\r\n\t\t\t\t{linkMargins ? (\r\n\t\t\t\t\t<div className={`${styles.field} ${styles.horizontal}`}>\r\n\t\t\t\t\t\t<span className={styles.label}>全辺</span>\r\n\t\t\t\t\t\t<DimensionInput\r\n\t\t\t\t\t\t\tvalue={paper.margin.top}\r\n\t\t\t\t\t\t\tonChange={handleTopChange}\r\n\t\t\t\t\t\t\tallowedUnits={[\"mm\", \"cm\", \"inch\"]}\r\n\t\t\t\t\t\t\tmin={0}\r\n\t\t\t\t\t\t\tmax={1000}\r\n\t\t\t\t\t\t/>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t) : (\r\n\t\t\t\t\t<div className={styles.marginsGrid}>\r\n\t\t\t\t\t\t<div\r\n\t\t\t\t\t\t\tclassName={`${styles.field} ${styles.horizontal} ${styles.topMargin}`}\r\n\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t<DimensionInput\r\n\t\t\t\t\t\t\t\tvalue={paper.margin.top}\r\n\t\t\t\t\t\t\t\tonChange={handleTopChange}\r\n\t\t\t\t\t\t\t\tallowedUnits={[\"mm\", \"cm\", \"inch\"]}\r\n\t\t\t\t\t\t\t\tmin={0}\r\n\t\t\t\t\t\t\t\tmax={1000}\r\n\t\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t</div>\r\n\r\n\t\t\t\t\t\t<div className={styles.sideMargins}>\r\n\t\t\t\t\t\t\t<div className={`${styles.field} ${styles.horizontal}`}>\r\n\t\t\t\t\t\t\t\t<DimensionInput\r\n\t\t\t\t\t\t\t\t\tvalue={paper.margin.left}\r\n\t\t\t\t\t\t\t\t\tonChange={handleLeftChange}\r\n\t\t\t\t\t\t\t\t\tallowedUnits={[\"mm\", \"cm\", \"inch\"]}\r\n\t\t\t\t\t\t\t\t\tmin={0}\r\n\t\t\t\t\t\t\t\t\tmax={1000}\r\n\t\t\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t\t</div>\r\n\r\n\t\t\t\t\t\t\t<div className={`${styles.field} ${styles.horizontal}`}>\r\n\t\t\t\t\t\t\t\t<DimensionInput\r\n\t\t\t\t\t\t\t\t\tvalue={paper.margin.right}\r\n\t\t\t\t\t\t\t\t\tonChange={handleRightChange}\r\n\t\t\t\t\t\t\t\t\tallowedUnits={[\"mm\", \"cm\", \"inch\"]}\r\n\t\t\t\t\t\t\t\t\tmin={0}\r\n\t\t\t\t\t\t\t\t\tmax={1000}\r\n\t\t\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t\t</div>\r\n\t\t\t\t\t\t</div>\r\n\r\n\t\t\t\t\t\t<div\r\n\t\t\t\t\t\t\tclassName={`${styles.field} ${styles.horizontal} ${styles.bottomMargin}`}\r\n\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t<DimensionInput\r\n\t\t\t\t\t\t\t\tvalue={paper.margin.bottom}\r\n\t\t\t\t\t\t\t\tonChange={handleBottomChange}\r\n\t\t\t\t\t\t\t\tallowedUnits={[\"mm\", \"cm\", \"inch\"]}\r\n\t\t\t\t\t\t\t\tmin={0}\r\n\t\t\t\t\t\t\t\tmax={1000}\r\n\t\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t</div>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t)}\r\n\t\t\t</div>\r\n\t\t</div>\r\n\t);\r\n};\r\n\r\nMarginPanel.displayName = \"MarginPanel\";\r\n","/**\r\n * @file PaperSizePanel.tsx\r\n * @description 用紙サイズ変更パネル\r\n */\r\n\r\nimport { useCallback, useMemo } from \"react\";\r\n\r\nimport { DimensionInput } from \"../../components/DimensionInput\";\r\nimport { Select } from \"../../components/Select\";\r\nimport styles from \"./PaperSizePanel.module.css\";\r\n\r\nimport {\r\n\tDEFAULT_PAPER_SIZES,\r\n\ttype Paper,\r\n\ttype PaperSize,\r\n\tPaperSizePreset,\r\n} from \"@/types/paper\";\r\n\r\nimport type { Dimension, PaperUnit } from \"@/types/unit\";\r\n\r\nexport interface PaperSizePanelProps {\r\n\t/** 用紙設定 */\r\n\tpaper: Paper;\r\n\t/** 用紙変更時のコールバック */\r\n\tonPaperChange: (paper: Paper) => void;\r\n}\r\n\r\n/**\r\n * PaperSizePanel\r\n * 用紙サイズを変更するパネル\r\n */\r\nexport const PaperSizePanel = ({\r\n\tpaper,\r\n\tonPaperChange,\r\n}: PaperSizePanelProps) => {\r\n\t// プリセット選択肢\r\n\tconst presetOptions = useMemo(\r\n\t\t() => [\r\n\t\t\t{ value: PaperSizePreset.A4, label: \"A4 (210 × 297 mm)\" },\r\n\t\t\t{ value: PaperSizePreset.A3, label: \"A3 (297 × 420 mm)\" },\r\n\t\t\t{ value: PaperSizePreset.B5, label: \"B5 (182 × 257 mm)\" },\r\n\t\t\t{ value: PaperSizePreset.LETTER, label: \"Letter (8.5 × 11 inch)\" },\r\n\t\t\t{ value: PaperSizePreset.LEGAL, label: \"Legal (8.5 × 14 inch)\" },\r\n\t\t\t{ value: PaperSizePreset.CUSTOM, label: \"カスタム\" },\r\n\t\t],\r\n\t\t[],\r\n\t);\r\n\r\n\t// プリセット変更ハンドラ\r\n\tconst handlePresetChange = useCallback(\r\n\t\t(preset: PaperSizePreset | undefined) => {\r\n\t\t\tif (!preset) return;\r\n\t\t\tconst newSize = DEFAULT_PAPER_SIZES[preset];\r\n\r\n\t\t\tonPaperChange({\r\n\t\t\t\t...paper,\r\n\t\t\t\tsize: newSize,\r\n\t\t\t});\r\n\t\t},\r\n\t\t[paper, onPaperChange],\r\n\t);\r\n\r\n\t// 幅変更ハンドラ\r\n\tconst handleWidthChange = useCallback(\r\n\t\t(width: Dimension<PaperUnit> | undefined) => {\r\n\t\t\tif (!width) return;\r\n\t\t\tconst newSize: PaperSize = {\r\n\t\t\t\t...paper.size,\r\n\t\t\t\tpreset: PaperSizePreset.CUSTOM,\r\n\t\t\t\twidth,\r\n\t\t\t};\r\n\r\n\t\t\tonPaperChange({\r\n\t\t\t\t...paper,\r\n\t\t\t\tsize: newSize,\r\n\t\t\t});\r\n\t\t},\r\n\t\t[paper, onPaperChange],\r\n\t);\r\n\r\n\t// 高さ変更ハンドラ\r\n\tconst handleHeightChange = useCallback(\r\n\t\t(height: Dimension<PaperUnit> | undefined) => {\r\n\t\t\tif (!height) return;\r\n\t\t\tconst newSize: PaperSize = {\r\n\t\t\t\t...paper.size,\r\n\t\t\t\tpreset: PaperSizePreset.CUSTOM,\r\n\t\t\t\theight,\r\n\t\t\t};\r\n\r\n\t\t\tonPaperChange({\r\n\t\t\t\t...paper,\r\n\t\t\t\tsize: newSize,\r\n\t\t\t});\r\n\t\t},\r\n\t\t[paper, onPaperChange],\r\n\t);\r\n\r\n\t// カスタムサイズかどうか\r\n\tconst isCustom = paper.size.preset === PaperSizePreset.CUSTOM;\r\n\r\n\treturn (\r\n\t\t<div className={styles.panel}>\r\n\t\t\t<h3 className={styles.title}>用紙サイズ</h3>\r\n\r\n\t\t\t<div className={styles.content}>\r\n\t\t\t\t<div className={styles.field}>\r\n\t\t\t\t\t<Select\r\n\t\t\t\t\t\tvalue={paper.size.preset}\r\n\t\t\t\t\t\toptions={presetOptions}\r\n\t\t\t\t\t\tonChange={handlePresetChange}\r\n\t\t\t\t\t/>\r\n\t\t\t\t</div>\r\n\r\n\t\t\t\t{isCustom && (\r\n\t\t\t\t\t<div className={styles.dimensionsRow}>\r\n\t\t\t\t\t\t<div className={`${styles.field} ${styles.horizontal}`}>\r\n\t\t\t\t\t\t\t<span className={styles.label}>幅</span>\r\n\t\t\t\t\t\t\t<DimensionInput\r\n\t\t\t\t\t\t\t\tvalue={paper.size.width}\r\n\t\t\t\t\t\t\t\tonChange={handleWidthChange}\r\n\t\t\t\t\t\t\t\tallowedUnits={[\"mm\", \"cm\", \"inch\"]}\r\n\t\t\t\t\t\t\t\tmin={paper.margin.left.value + paper.margin.right.value + 1}\r\n\t\t\t\t\t\t\t\tmax={500}\r\n\t\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t</div>\r\n\r\n\t\t\t\t\t\t<div className={`${styles.field} ${styles.horizontal}`}>\r\n\t\t\t\t\t\t\t<span className={styles.label}>高さ</span>\r\n\t\t\t\t\t\t\t<DimensionInput\r\n\t\t\t\t\t\t\t\tvalue={paper.size.height}\r\n\t\t\t\t\t\t\t\tonChange={handleHeightChange}\r\n\t\t\t\t\t\t\t\tallowedUnits={[\"mm\", \"cm\", \"inch\"]}\r\n\t\t\t\t\t\t\t\tmin={paper.margin.top.value + paper.margin.bottom.value + 1}\r\n\t\t\t\t\t\t\t\tmax={500}\r\n\t\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t</div>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t)}\r\n\t\t\t</div>\r\n\t\t</div>\r\n\t);\r\n};\r\n\r\nPaperSizePanel.displayName = \"PaperSizePanel\";\r\n","/**\r\n * @file ImportExportPanel.tsx\r\n * @description スキーマ・値のImport/Exportパネル\r\n */\r\n\r\nimport { useCallback, useRef, useState } from \"react\";\r\n\r\nimport styles from \"./ImportExportPanel.module.css\";\r\n\r\nimport {\r\n\tdeserializeSchema,\r\n\tdeserializeValues,\r\n\tserializeSchema,\r\n\tserializeValues,\r\n} from \"@/utils\";\r\n\r\nimport type { FormSchema } from \"@/types/schema\";\r\nimport type { Value } from \"@/types/value\";\r\n\r\nexport interface ImportExportPanelProps {\r\n\t/** スキーマ */\r\n\tschema: FormSchema;\r\n\t/** 値 */\r\n\tvalues: Record<string, Value>;\r\n\t/** スキーマ変更時のコールバック */\r\n\tonSchemaChange: (schema: FormSchema) => void;\r\n\t/** 値変更時のコールバック */\r\n\tonValuesChange: (values: Record<string, Value>) => void;\r\n}\r\n\r\n/**\r\n * ImportExportPanel\r\n * スキーマと値のインポート/エクスポート機能を提供\r\n */\r\nexport const ImportExportPanel = ({\r\n\tschema,\r\n\tvalues,\r\n\tonSchemaChange,\r\n\tonValuesChange,\r\n}: ImportExportPanelProps) => {\r\n\tconst [error, setError] = useState<string>(\"\");\r\n\tconst schemaFileInputRef = useRef<HTMLInputElement>(null);\r\n\tconst valuesFileInputRef = useRef<HTMLInputElement>(null);\r\n\r\n\t// スキーマをファイルにエクスポート\r\n\tconst handleExportSchemaFile = useCallback(() => {\r\n\t\ttry {\r\n\t\t\tconst json = serializeSchema(schema, true);\r\n\t\t\tconst blob = new Blob([json], { type: \"application/json\" });\r\n\t\t\tconst url = URL.createObjectURL(blob);\r\n\t\t\tconst a = document.createElement(\"a\");\r\n\t\t\ta.href = url;\r\n\t\t\ta.download = \"schema.json\";\r\n\t\t\ta.click();\r\n\t\t\tURL.revokeObjectURL(url);\r\n\t\t\tsetError(\"\");\r\n\t\t} catch (err) {\r\n\t\t\tsetError(\r\n\t\t\t\t`エクスポートエラー: ${err instanceof Error ? err.message : String(err)}`,\r\n\t\t\t);\r\n\t\t}\r\n\t}, [schema]);\r\n\r\n\t// スキーマをクリップボードにコピー\r\n\tconst handleExportSchemaClipboard = useCallback(async () => {\r\n\t\ttry {\r\n\t\t\tconst json = serializeSchema(schema, true);\r\n\t\t\tawait navigator.clipboard.writeText(json);\r\n\t\t\tsetError(\"\");\r\n\t\t\talert(\"スキーマをクリップボードにコピーしました\");\r\n\t\t} catch (err) {\r\n\t\t\tsetError(\r\n\t\t\t\t`クリップボードエラー: ${err instanceof Error ? err.message : String(err)}`,\r\n\t\t\t);\r\n\t\t}\r\n\t}, [schema]);\r\n\r\n\t// スキーマをファイルからインポート\r\n\tconst handleImportSchemaFile = useCallback(() => {\r\n\t\tschemaFileInputRef.current?.click();\r\n\t}, []);\r\n\r\n\t// ファイル選択時の処理\r\n\tconst handleSchemaFileChange = useCallback(\r\n\t\t(event: React.ChangeEvent<HTMLInputElement>) => {\r\n\t\t\tconst file = event.target.files?.[0];\r\n\t\t\tif (!file) return;\r\n\r\n\t\t\tconst reader = new FileReader();\r\n\t\t\treader.onload = (e) => {\r\n\t\t\t\ttry {\r\n\t\t\t\t\tconst json = e.target?.result as string;\r\n\t\t\t\t\tconst newSchema = deserializeSchema(json);\r\n\t\t\t\t\tonSchemaChange(newSchema);\r\n\t\t\t\t\tsetError(\"\");\r\n\t\t\t\t\talert(\"スキーマをインポートしました\");\r\n\t\t\t\t} catch (err) {\r\n\t\t\t\t\tsetError(\r\n\t\t\t\t\t\t`インポートエラー: ${err instanceof Error ? err.message : String(err)}`,\r\n\t\t\t\t\t);\r\n\t\t\t\t}\r\n\t\t\t};\r\n\t\t\treader.readAsText(file);\r\n\r\n\t\t\t// リセット(同じファイルを再度選択できるように)\r\n\t\t\tevent.target.value = \"\";\r\n\t\t},\r\n\t\t[onSchemaChange],\r\n\t);\r\n\r\n\t// スキーマをクリップボードからインポート\r\n\tconst handleImportSchemaClipboard = useCallback(async () => {\r\n\t\ttry {\r\n\t\t\tconst json = await navigator.clipboard.readText();\r\n\t\t\tconst newSchema = deserializeSchema(json);\r\n\t\t\tonSchemaChange(newSchema);\r\n\t\t\tsetError(\"\");\r\n\t\t\talert(\"スキーマをインポートしました\");\r\n\t\t} catch (err) {\r\n\t\t\tsetError(\r\n\t\t\t\t`インポートエラー: ${err instanceof Error ? err.message : String(err)}`,\r\n\t\t\t);\r\n\t\t}\r\n\t}, [onSchemaChange]);\r\n\r\n\t// 値をファイルにエクスポート\r\n\tconst handleExportValuesFile = useCallback(() => {\r\n\t\ttry {\r\n\t\t\tconst json = serializeValues(values, true);\r\n\t\t\tconst blob = new Blob([json], { type: \"application/json\" });\r\n\t\t\tconst url = URL.createObjectURL(blob);\r\n\t\t\tconst a = document.createElement(\"a\");\r\n\t\t\ta.href = url;\r\n\t\t\ta.download = \"values.json\";\r\n\t\t\ta.click();\r\n\t\t\tURL.revokeObjectURL(url);\r\n\t\t\tsetError(\"\");\r\n\t\t} catch (err) {\r\n\t\t\tsetError(\r\n\t\t\t\t`エクスポートエラー: ${err instanceof Error ? err.message : String(err)}`,\r\n\t\t\t);\r\n\t\t}\r\n\t}, [values]);\r\n\r\n\t// 値をクリップボードにコピー\r\n\tconst handleExportValuesClipboard = useCallback(async () => {\r\n\t\ttry {\r\n\t\t\tconst json = serializeValues(values, true);\r\n\t\t\tawait navigator.clipboard.writeText(json);\r\n\t\t\tsetError(\"\");\r\n\t\t\talert(\"値をクリップボードにコピーしました\");\r\n\t\t} catch (err) {\r\n\t\t\tsetError(\r\n\t\t\t\t`クリップボードエラー: ${err instanceof Error ? err.message : String(err)}`,\r\n\t\t\t);\r\n\t\t}\r\n\t}, [values]);\r\n\r\n\t// 値をファイルからインポート\r\n\tconst handleImportValuesFile = useCallback(() => {\r\n\t\tvaluesFileInputRef.current?.click();\r\n\t}, []);\r\n\r\n\t// ファイル選択時の処理\r\n\tconst handleValuesFileChange = useCallback(\r\n\t\t(event: React.ChangeEvent<HTMLInputElement>) => {\r\n\t\t\tconst file = event.target.files?.[0];\r\n\t\t\tif (!file) return;\r\n\r\n\t\t\tconst reader = new FileReader();\r\n\t\t\treader.onload = (e) => {\r\n\t\t\t\ttry {\r\n\t\t\t\t\tconst json = e.target?.result as string;\r\n\t\t\t\t\tconst newValues = deserializeValues(json);\r\n\t\t\t\t\tonValuesChange(newValues);\r\n\t\t\t\t\tsetError(\"\");\r\n\t\t\t\t\talert(\"値をインポートしました\");\r\n\t\t\t\t} catch (err) {\r\n\t\t\t\t\tsetError(\r\n\t\t\t\t\t\t`インポートエラー: ${err instanceof Error ? err.message : String(err)}`,\r\n\t\t\t\t\t);\r\n\t\t\t\t}\r\n\t\t\t};\r\n\t\t\treader.readAsText(file);\r\n\r\n\t\t\t// リセット\r\n\t\t\tevent.target.value = \"\";\r\n\t\t},\r\n\t\t[onValuesChange],\r\n\t);\r\n\r\n\t// 値をクリップボードからインポート\r\n\tconst handleImportValuesClipboard = useCallback(async () => {\r\n\t\ttry {\r\n\t\t\tconst json = await navigator.clipboard.readText();\r\n\t\t\tconst newValues = deserializeValues(json);\r\n\t\t\tonValuesChange(newValues);\r\n\t\t\tsetError(\"\");\r\n\t\t\talert(\"値をインポートしました\");\r\n\t\t} catch (err) {\r\n\t\t\tsetError(\r\n\t\t\t\t`インポートエラー: ${err instanceof Error ? err.message : String(err)}`,\r\n\t\t\t);\r\n\t\t}\r\n\t}, [onValuesChange]);\r\n\r\n\treturn (\r\n\t\t<>\r\n\t\t\t<div className={styles.section}>\r\n\t\t\t\t<h3 className={styles.title}>スキーマ</h3>\r\n\r\n\t\t\t\t<div className={styles.content}>\r\n\t\t\t\t\t<div className={styles.buttonGroup}>\r\n\t\t\t\t\t\t<button\r\n\t\t\t\t\t\t\ttype=\"button\"\r\n\t\t\t\t\t\t\tclassName={styles.button}\r\n\t\t\t\t\t\t\tonClick={handleExportSchemaFile}\r\n\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t📥 ファイルにエクスポート\r\n\t\t\t\t\t\t</button>\r\n\t\t\t\t\t\t<button\r\n\t\t\t\t\t\t\ttype=\"button\"\r\n\t\t\t\t\t\t\tclassName={styles.button}\r\n\t\t\t\t\t\t\tonClick={handleExportSchemaClipboard}\r\n\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t📋 クリップボードにコピー\r\n\t\t\t\t\t\t</button>\r\n\t\t\t\t\t</div>\r\n\r\n\t\t\t\t\t<div className={styles.buttonGroup}>\r\n\t\t\t\t\t\t<button\r\n\t\t\t\t\t\t\ttype=\"button\"\r\n\t\t\t\t\t\t\tclassName={styles.button}\r\n\t\t\t\t\t\t\tonClick={handleImportSchemaFile}\r\n\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t📤 ファイルからインポート\r\n\t\t\t\t\t\t</button>\r\n\t\t\t\t\t\t<button\r\n\t\t\t\t\t\t\ttype=\"button\"\r\n\t\t\t\t\t\t\tclassName={styles.button}\r\n\t\t\t\t\t\t\tonClick={handleImportSchemaClipboard}\r\n\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t📋 クリップボードからペースト\r\n\t\t\t\t\t\t</button>\r\n\t\t\t\t\t</div>\r\n\r\n\t\t\t\t\t<input\r\n\t\t\t\t\t\tref={schemaFileInputRef}\r\n\t\t\t\t\t\ttype=\"file\"\r\n\t\t\t\t\t\taccept=\".json\"\r\n\t\t\t\t\t\tstyle={{ display: \"none\" }}\r\n\t\t\t\t\t\tonChange={handleSchemaFileChange}\r\n\t\t\t\t\t/>\r\n\t\t\t\t</div>\r\n\t\t\t</div>\r\n\r\n\t\t\t<div className={styles.section}>\r\n\t\t\t\t<h3 className={styles.title}>値</h3>\r\n\r\n\t\t\t\t<div className={styles.content}>\r\n\t\t\t\t\t<div className={styles.buttonGroup}>\r\n\t\t\t\t\t\t<button\r\n\t\t\t\t\t\t\ttype=\"button\"\r\n\t\t\t\t\t\t\tclassName={styles.button}\r\n\t\t\t\t\t\t\tonClick={handleExportValuesFile}\r\n\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t📥 ファイルにエクスポート\r\n\t\t\t\t\t\t</button>\r\n\t\t\t\t\t\t<button\r\n\t\t\t\t\t\t\ttype=\"button\"\r\n\t\t\t\t\t\t\tclassName={styles.button}\r\n\t\t\t\t\t\t\tonClick={handleExportValuesClipboard}\r\n\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t📋 クリップボードにコピー\r\n\t\t\t\t\t\t</button>\r\n\t\t\t\t\t</div>\r\n\r\n\t\t\t\t\t<div className={styles.buttonGroup}>\r\n\t\t\t\t\t\t<button\r\n\t\t\t\t\t\t\ttype=\"button\"\r\n\t\t\t\t\t\t\tclassName={styles.button}\r\n\t\t\t\t\t\t\tonClick={handleImportValuesFile}\r\n\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t📤 ファイルからインポート\r\n\t\t\t\t\t\t</button>\r\n\t\t\t\t\t\t<button\r\n\t\t\t\t\t\t\ttype=\"button\"\r\n\t\t\t\t\t\t\tclassName={styles.button}\r\n\t\t\t\t\t\t\tonClick={handleImportValuesClipboard}\r\n\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t📋 クリップボードからペースト\r\n\t\t\t\t\t\t</button>\r\n\t\t\t\t\t</div>\r\n\r\n\t\t\t\t\t<input\r\n\t\t\t\t\t\tref={valuesFileInputRef}\r\n\t\t\t\t\t\ttype=\"file\"\r\n\t\t\t\t\t\taccept=\".json\"\r\n\t\t\t\t\t\tstyle={{ display: \"none\" }}\r\n\t\t\t\t\t\tonChange={handleValuesFileChange}\r\n\t\t\t\t\t/>\r\n\t\t\t\t</div>\r\n\t\t\t</div>\r\n\r\n\t\t\t{error && (\r\n\t\t\t\t<div className={styles.error} role=\"alert\">\r\n\t\t\t\t\t{error}\r\n\t\t\t\t</div>\r\n\t\t\t)}\r\n\t\t</>\r\n\t);\r\n};\r\n\r\nImportExportPanel.displayName = \"ImportExportPanel\";\r\n","/**\r\n * @file OtherPanel.tsx\r\n * @description その他の設定統合パネル\r\n */\r\n\r\nimport { TabPanel } from \"../components/TabPanel\";\r\nimport { ImportExportPanel } from \".\";\r\n\r\nimport type { FormSchema } from \"@/types/schema\";\r\nimport type { Value } from \"@/types/value\";\r\n\r\nexport interface OtherPanelProps {\r\n\t/** フォームスキーマ */\r\n\tschema: FormSchema;\r\n\t/** 入力データ */\r\n\tvalues: Record<string, Value>;\r\n\t/** スキーマ変更時のコールバック */\r\n\tonSchemaChange: (newSchema: FormSchema) => void;\r\n\t/** 入力データ変更時のコールバック */\r\n\tonValuesChange: (newValues: Record<string, Value>) => void;\r\n}\r\n\r\n/**\r\n * OtherPanel\r\n * その他の設定の統合パネル\r\n * - ImportExportPanel: スキーマ・値のインポート/エクスポート\r\n */\r\nexport const OtherPanel = ({\r\n\tschema,\r\n\tvalues,\r\n\tonSchemaChange,\r\n\tonValuesChange,\r\n}: OtherPanelProps) => {\r\n\treturn (\r\n\t\t<TabPanel>\r\n\t\t\t<ImportExportPanel\r\n\t\t\t\tschema={schema}\r\n\t\t\t\tvalues={values}\r\n\t\t\t\tonSchemaChange={onSchemaChange}\r\n\t\t\t\tonValuesChange={onValuesChange}\r\n\t\t\t/>\r\n\t\t</TabPanel>\r\n\t);\r\n};\r\n\r\nOtherPanel.displayName = \"OtherPanel\";\r\n","/**\r\n * @file PalettePanel.tsx\r\n * @description ブロック挿入用パレットパネル\r\n * ブロック未選択時にサイドバーに表示される\r\n */\r\n\r\nimport { useCallback, useMemo, useState } from \"react\";\r\n\r\nimport styles from \"./PalettePanel.module.css\";\r\n\r\nimport { createBlock } from \"@/plugin/utils/block\";\r\nimport { NoteMode } from \"@/types/mode\";\r\nimport { globalDragStore } from \"@/utils/GlobalDragStore\";\r\n\r\nimport type { BlockPlugin } from \"@/plugin\";\r\n\r\nexport interface PalettePanelProps {\r\n\t/** 利用可能なプラグイン一覧 */\r\n\tplugins: BlockPlugin[];\r\n\t/** カスタムクラス名 */\r\n\tclassName?: string;\r\n}\r\n\r\n/**\r\n * PalettePanel\r\n * ブロックをドラッグ&ドロップで挿入するためのパレット\r\n */\r\nexport const PalettePanel = ({ plugins, className }: PalettePanelProps) => {\r\n\t// ドラッグ中のゴースト表示用の状態\r\n\tconst [dragState, setDragState] = useState<{\r\n\t\tplugin: BlockPlugin;\r\n\t\tmousePos: { x: number; y: number };\r\n\t\tisOverCanvas: boolean;\r\n\t} | null>(null);\r\n\r\n\tconst handleDragStart = useCallback(\r\n\t\t(plugin: BlockPlugin, initialPos: { x: number; y: number }) => {\r\n\t\t\tsetDragState({ plugin, mousePos: initialPos, isOverCanvas: false });\r\n\r\n\t\t\t// マウス移動を追跡\r\n\t\t\tconst handleMove = (e: PointerEvent) => {\r\n\t\t\t\t// マウス位置の要素を取得してキャンバス上かチェック\r\n\t\t\t\tconst elementUnderMouse = document.elementFromPoint(\r\n\t\t\t\t\te.clientX,\r\n\t\t\t\t\te.clientY,\r\n\t\t\t\t);\r\n\t\t\t\tconst isOverCanvas = !!elementUnderMouse?.closest(\r\n\t\t\t\t\t'[data-testid=\"interaction-layer\"]',\r\n\t\t\t\t);\r\n\r\n\t\t\t\tsetDragState((prev) =>\r\n\t\t\t\t\tprev\r\n\t\t\t\t\t\t? {\r\n\t\t\t\t\t\t\t\t...prev,\r\n\t\t\t\t\t\t\t\tmousePos: { x: e.clientX, y: e.clientY },\r\n\t\t\t\t\t\t\t\tisOverCanvas,\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t: null,\r\n\t\t\t\t);\r\n\t\t\t};\r\n\r\n\t\t\t// ドラッグ終了\r\n\t\t\tconst handleUp = () => {\r\n\t\t\t\tsetDragState(null);\r\n\t\t\t\twindow.removeEventListener(\"pointermove\", handleMove);\r\n\t\t\t\twindow.removeEventListener(\"pointerup\", handleUp);\r\n\t\t\t};\r\n\r\n\t\t\twindow.addEventListener(\"pointermove\", handleMove);\r\n\t\t\twindow.addEventListener(\"pointerup\", handleUp);\r\n\t\t},\r\n\t\t[],\r\n\t);\r\n\r\n\treturn (\r\n\t\t<>\r\n\t\t\t<div className={`${styles.container} ${className || \"\"}`}>\r\n\t\t\t\t<div className={styles.paletteItems}>\r\n\t\t\t\t\t{plugins.map((plugin) => (\r\n\t\t\t\t\t\t<PaletteItem\r\n\t\t\t\t\t\t\tkey={plugin.kind}\r\n\t\t\t\t\t\t\tplugin={plugin}\r\n\t\t\t\t\t\t\tonDragStart={handleDragStart}\r\n\t\t\t\t\t\t/>\r\n\t\t\t\t\t))}\r\n\t\t\t\t</div>\r\n\t\t\t</div>\r\n\r\n\t\t\t{/* \r\n\t\t\t\tドラッグ中のゴースト表示(キャンバス外のみ)\r\n\t\t\t\tNOTE: キャンバス内に入ったらInteractionLayerのInsertGhostが表示されるため、\r\n\t\t\t\tここではキャンバス外(isOverCanvas=false)の時だけ表示する。\r\n\t\t\t*/}\r\n\t\t\t{dragState && !dragState.isOverCanvas && (\r\n\t\t\t\t<DragGhost plugin={dragState.plugin} mousePos={dragState.mousePos} />\r\n\t\t\t)}\r\n\t\t</>\r\n\t);\r\n};\r\n\r\nPalettePanel.displayName = \"PalettePanel\";\r\n\r\n/**\r\n * PaletteItem\r\n * 個々のブロックアイテム\r\n */\r\ninterface PaletteItemProps {\r\n\tplugin: BlockPlugin;\r\n\tonDragStart: (\r\n\t\tplugin: BlockPlugin,\r\n\t\tinitialPos: { x: number; y: number },\r\n\t) => void;\r\n}\r\n\r\nconst PaletteItem = ({ plugin, onDragStart }: PaletteItemProps) => {\r\n\t// プレビュー用のブロックオブジェクトを作成\r\n\tconst previewBlock = useMemo(() => {\r\n\t\treturn createBlock(\r\n\t\t\tplugin,\r\n\t\t\t{\r\n\t\t\t\tx: 0,\r\n\t\t\t\ty: 0,\r\n\t\t\t\tw: plugin.meta.defaultSize.w,\r\n\t\t\t\th: plugin.meta.defaultSize.h,\r\n\t\t\t},\r\n\t\t\t{}, // overrideProps\r\n\t\t);\r\n\t}, [plugin]);\r\n\r\n\t// プレビュー表示用のデフォルト値\r\n\tconst previewValue = useMemo(() => {\r\n\t\t// validateValue が存在する場合のみ使用\r\n\t\tif (plugin.validateValue) {\r\n\t\t\treturn plugin.validateValue(undefined, previewBlock.props);\r\n\t\t}\r\n\t\treturn undefined;\r\n\t}, [plugin, previewBlock.props]);\r\n\r\n\tconst handlePointerDown = useCallback(\r\n\t\t(e: React.PointerEvent) => {\r\n\t\t\te.preventDefault();\r\n\r\n\t\t\t// 1. グローバルストアにセット\r\n\t\t\tglobalDragStore.start(plugin.kind, plugin.meta.defaultSize);\r\n\r\n\t\t\t// 2. ドラッグゴースト表示開始\r\n\t\t\tonDragStart(plugin, { x: e.clientX, y: e.clientY });\r\n\r\n\t\t\t// 3. どこで離してもドラッグ終了するように監視\r\n\t\t\tconst handleWindowUp = () => {\r\n\t\t\t\tglobalDragStore.end();\r\n\t\t\t\twindow.removeEventListener(\"pointerup\", handleWindowUp);\r\n\t\t\t};\r\n\t\t\twindow.addEventListener(\"pointerup\", handleWindowUp);\r\n\t\t},\r\n\t\t[plugin, onDragStart],\r\n\t);\r\n\r\n\treturn (\r\n\t\t<div className={styles.item}>\r\n\t\t\t{/* ドラッグ可能なヘッダー部分 */}\r\n\t\t\t<button\r\n\t\t\t\ttype=\"button\"\r\n\t\t\t\tonPointerDown={handlePointerDown}\r\n\t\t\t\tclassName={styles.itemName}\r\n\t\t\t\taria-label={`${plugin.meta.displayName}ブロックを追加`}\r\n\t\t\t>\r\n\t\t\t\t{plugin.meta.displayName}\r\n\t\t\t</button>\r\n\t\t\t{/* プレビュー部分(非インタラクティブ) */}\r\n\t\t\t<div\r\n\t\t\t\tclassName={styles.itemPreview}\r\n\t\t\t\tonPointerDown={handlePointerDown}\r\n\t\t\t\taria-hidden=\"true\"\r\n\t\t\t>\r\n\t\t\t\t<plugin.Renderer\r\n\t\t\t\t\tid={previewBlock.id}\r\n\t\t\t\t\tprops={previewBlock.props}\r\n\t\t\t\t\tvalue={previewValue}\r\n\t\t\t\t\tonChange={() => {\r\n\t\t\t\t\t\t/* プレビューなので変更不可 */\r\n\t\t\t\t\t}}\r\n\t\t\t\t\treadOnly={true}\r\n\t\t\t\t\tmode={NoteMode.FORM}\r\n\t\t\t\t/>\r\n\t\t\t</div>\r\n\t\t</div>\r\n\t);\r\n};\r\n\r\nPaletteItem.displayName = \"PaletteItem\";\r\n\r\n/**\r\n * DragGhost\r\n * ドラッグ中のゴースト表示(position: fixed)\r\n * キャンバス外でのみ表示される\r\n */\r\ninterface DragGhostProps {\r\n\tplugin: BlockPlugin;\r\n\tmousePos: { x: number; y: number };\r\n}\r\n\r\nconst DragGhost = ({ plugin, mousePos }: DragGhostProps) => {\r\n\t// ゴースト用のブロックオブジェクトを作成\r\n\tconst ghostBlock = useMemo(() => {\r\n\t\treturn createBlock(\r\n\t\t\tplugin,\r\n\t\t\t{\r\n\t\t\t\tx: 0,\r\n\t\t\t\ty: 0,\r\n\t\t\t\tw: plugin.meta.defaultSize.w,\r\n\t\t\t\th: plugin.meta.defaultSize.h,\r\n\t\t\t},\r\n\t\t\t{},\r\n\t\t);\r\n\t}, [plugin]);\r\n\r\n\t// ゴースト表示用のデフォルト値\r\n\tconst ghostValue = useMemo(() => {\r\n\t\tif (plugin.validateValue) {\r\n\t\t\treturn plugin.validateValue(undefined, ghostBlock.props);\r\n\t\t}\r\n\t\treturn undefined;\r\n\t}, [plugin, ghostBlock.props]);\r\n\r\n\t// ゴーストのサイズ(仮の固定サイズ、実際はgetBlockRectPxで計算すべき)\r\n\tconst ghostSize = {\r\n\t\twidth: plugin.meta.defaultSize.w * 50, // 仮の計算(グリッド1単位=50px想定)\r\n\t\theight: plugin.meta.defaultSize.h * 50,\r\n\t};\r\n\r\n\treturn (\r\n\t\t<div\r\n\t\t\tdata-testid=\"palette-drag-ghost\"\r\n\t\t\tstyle={{\r\n\t\t\t\tposition: \"fixed\",\r\n\t\t\t\tleft: `${mousePos.x - ghostSize.width / 2}px`,\r\n\t\t\t\ttop: `${mousePos.y - ghostSize.height / 2}px`,\r\n\t\t\t\twidth: `${ghostSize.width}px`,\r\n\t\t\t\theight: `${ghostSize.height}px`,\r\n\t\t\t\tpointerEvents: \"none\",\r\n\t\t\t\topacity: 0.5,\r\n\t\t\t\tfilter: \"grayscale(50%)\",\r\n\t\t\t\tzIndex: 9999,\r\n\t\t\t\tborder: \"2px dashed #3b82f6\",\r\n\t\t\t\tbackgroundColor: \"#fff\",\r\n\t\t\t}}\r\n\t\t>\r\n\t\t\t<plugin.Renderer\r\n\t\t\t\tid={ghostBlock.id}\r\n\t\t\t\tprops={ghostBlock.props}\r\n\t\t\t\tvalue={ghostValue}\r\n\t\t\t\tonChange={() => {}}\r\n\t\t\t\treadOnly={true}\r\n\t\t\t\tmode={NoteMode.FORM}\r\n\t\t\t/>\r\n\t\t</div>\r\n\t);\r\n};\r\n\r\nDragGhost.displayName = \"DragGhost\";\r\n","/**\r\n * @file Sidebar.tsx\r\n * @description プロパティパネルとパレットを切り替えるサイドバー\r\n */\r\n\r\nimport { useMemo } from \"react\";\r\n\r\nimport { BlockPropertyPanel } from \"../BlockPropertyPanel\";\r\nimport { CanvasPanel } from \"../CanvasPanel\";\r\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from \"../components/Tabs\";\r\nimport { OtherPanel } from \"../OtherPanel\";\r\nimport { PalettePanel } from \"../PalettePanel\";\r\nimport styles from \"./Sidebar.module.css\";\r\n\r\nimport type { BlockPlugin } from \"@/plugin\";\r\nimport type { Block } from \"@/types/block\";\r\nimport type { FormSchema } from \"@/types/schema\";\r\nimport type { Value } from \"@/types/value\";\r\n\r\nexport interface SidebarProps {\r\n\t/** 全ブロック */\r\n\tblocks: Block[];\r\n\t/** 選択中のブロックID一覧 */\r\n\tselectedBlockIds: string[];\r\n\t/** プラグインレジストリ */\r\n\tpluginRegistry: Record<string, BlockPlugin>;\r\n\t/** ブロック更新時のコールバック */\r\n\tonUpdateBlocks: (updates: Record<string, Partial<Block>>) => void;\r\n\t/** フォームスキーマ (CanvasPanel/OtherPanelで使用) */\r\n\tschema: FormSchema;\r\n\t/** 入力データ (OtherPanelで使用) */\r\n\tvalues: Record<string, Value>;\r\n\t/** スキーマ変更時のコールバック */\r\n\tonSchemaChange: (newSchema: FormSchema) => void;\r\n\t/** 入力データ変更時のコールバック */\r\n\tonValuesChange: (newValues: Record<string, Value>) => void;\r\n\t/** グリッドサイズ (LayoutPanelで使用) */\r\n\tgridSize?: { cols: number; rows: number };\r\n\t/** カスタムクラス名 */\r\n\tclassName?: string;\r\n}\r\n\r\n/**\r\n * Sidebar\r\n * タブ切り替え機能を持つサイドバー\r\n * - ブロックタブ: BlockPropertyPanel / PalettePanel\r\n * - キャンバスタブ: CanvasPanel (用紙設定、マージン設定、グリッド設定、ブロック順序)\r\n * - その他タブ: OtherPanel (スキーマ/値のインポート/エクスポート)\r\n */\r\nexport const Sidebar = ({\r\n\tblocks,\r\n\tselectedBlockIds,\r\n\tpluginRegistry,\r\n\tonUpdateBlocks,\r\n\tschema,\r\n\tvalues,\r\n\tonSchemaChange,\r\n\tonValuesChange,\r\n\tgridSize,\r\n\tclassName,\r\n}: SidebarProps) => {\r\n\t// 利用可能なプラグイン一覧\r\n\tconst availablePlugins = useMemo(\r\n\t\t() => Object.values(pluginRegistry),\r\n\t\t[pluginRegistry],\r\n\t);\r\n\r\n\t// 選択中のブロック一覧\r\n\tconst selectedBlocks = useMemo(\r\n\t\t() => blocks.filter((block) => selectedBlockIds.includes(block.id)),\r\n\t\t[blocks, selectedBlockIds],\r\n\t);\r\n\r\n\t// ブロックが選択されているかどうか\r\n\tconst hasSelection = selectedBlockIds.length > 0;\r\n\r\n\treturn (\r\n\t\t<div\r\n\t\t\tclassName={`${styles.container} ${className || \"\"}`}\r\n\t\t\tdata-sidebar=\"true\"\r\n\t\t>\r\n\t\t\t<Tabs defaultValue=\"block\" variant=\"default\">\r\n\t\t\t\t<TabsList className={styles.tabHeader}>\r\n\t\t\t\t\t<TabsTrigger value=\"block\">ブロック</TabsTrigger>\r\n\t\t\t\t\t<TabsTrigger value=\"canvas\">キャンバス</TabsTrigger>\r\n\t\t\t\t\t<TabsTrigger value=\"other\">その他</TabsTrigger>\r\n\t\t\t\t</TabsList>\r\n\r\n\t\t\t\t<TabsContent value=\"block\" className={styles.tabContent}>\r\n\t\t\t\t\t{hasSelection ? (\r\n\t\t\t\t\t\t<BlockPropertyPanel\r\n\t\t\t\t\t\t\tselectedBlocks={selectedBlocks}\r\n\t\t\t\t\t\t\tpluginRegistry={pluginRegistry}\r\n\t\t\t\t\t\t\tonUpdateBlocks={onUpdateBlocks}\r\n\t\t\t\t\t\t\tgridSize={gridSize}\r\n\t\t\t\t\t\t/>\r\n\t\t\t\t\t) : (\r\n\t\t\t\t\t\t<PalettePanel plugins={availablePlugins} />\r\n\t\t\t\t\t)}\r\n\t\t\t\t</TabsContent>\r\n\r\n\t\t\t\t<TabsContent value=\"canvas\" className={styles.tabContent}>\r\n\t\t\t\t\t<CanvasPanel schema={schema} onSchemaChange={onSchemaChange} />\r\n\t\t\t\t</TabsContent>\r\n\r\n\t\t\t\t<TabsContent value=\"other\" className={styles.tabContent}>\r\n\t\t\t\t\t<OtherPanel\r\n\t\t\t\t\t\tschema={schema}\r\n\t\t\t\t\t\tvalues={values}\r\n\t\t\t\t\t\tonSchemaChange={onSchemaChange}\r\n\t\t\t\t\t\tonValuesChange={onValuesChange}\r\n\t\t\t\t\t/>\r\n\t\t\t\t</TabsContent>\r\n\t\t\t</Tabs>\r\n\t\t</div>\r\n\t);\r\n};\r\n\r\nSidebar.displayName = \"Sidebar\";\r\n"],"names":["f","require$$0","k","l","m","n","p","q","c","a","g","b","d","e","h","reactJsxRuntime_production_min","React","REACT_ELEMENT_TYPE","REACT_PORTAL_TYPE","REACT_FRAGMENT_TYPE","REACT_STRICT_MODE_TYPE","REACT_PROFILER_TYPE","REACT_PROVIDER_TYPE","REACT_CONTEXT_TYPE","REACT_FORWARD_REF_TYPE","REACT_SUSPENSE_TYPE","REACT_SUSPENSE_LIST_TYPE","REACT_MEMO_TYPE","REACT_LAZY_TYPE","REACT_OFFSCREEN_TYPE","MAYBE_ITERATOR_SYMBOL","FAUX_ITERATOR_SYMBOL","getIteratorFn","maybeIterable","maybeIterator","ReactSharedInternals","error","format","_len2","args","_key2","printWarning","level","ReactDebugCurrentFrame","stack","argsWithFormat","item","enableScopeAPI","enableCacheElement","enableTransitionTracing","enableLegacyHidden","enableDebugTracing","REACT_MODULE_REFERENCE","isValidElementType","type","getWrappedName","outerType","innerType","wrapperName","displayName","functionName","getContextName","getComponentNameFromType","context","provider","outerName","lazyComponent","payload","init","assign","disabledDepth","prevLog","prevInfo","prevWarn","prevError","prevGroup","prevGroupCollapsed","prevGroupEnd","disabledLog","disableLogs","props","reenableLogs","ReactCurrentDispatcher","prefix","describeBuiltInComponentFrame","name","source","ownerFn","x","match","reentry","componentFrameCache","PossiblyWeakMap","describeNativeComponentFrame","fn","construct","frame","control","previousPrepareStackTrace","previousDispatcher","Fake","sample","sampleLines","controlLines","s","_frame","syntheticFrame","describeFunctionComponentFrame","shouldConstruct","Component","prototype","describeUnknownElementTypeFrameInDEV","hasOwnProperty","loggedTypeFailures","setCurrentlyValidatingElement","element","owner","checkPropTypes","typeSpecs","values","location","componentName","has","typeSpecName","error$1","err","ex","isArrayImpl","isArray","typeName","value","hasToStringTag","willCoercionThrow","testStringCoercion","checkKeyStringCoercion","ReactCurrentOwner","RESERVED_PROPS","specialPropKeyWarningShown","specialPropRefWarningShown","hasValidRef","config","getter","hasValidKey","warnIfStringRefCannotBeAutoConverted","self","defineKeyPropWarningGetter","warnAboutAccessingKey","defineRefPropWarningGetter","warnAboutAccessingRef","ReactElement","key","ref","jsxDEV","maybeKey","propName","defaultProps","ReactCurrentOwner$1","ReactDebugCurrentFrame$1","setCurrentlyValidatingElement$1","propTypesMisspellWarningShown","isValidElement","object","getDeclarationErrorAddendum","getSourceInfoErrorAddendum","ownerHasKeyUseWarning","getCurrentComponentErrorInfo","parentType","info","parentName","validateExplicitKey","currentComponentErrorInfo","childOwner","validateChildKeys","node","i","child","iteratorFn","iterator","step","validatePropTypes","propTypes","_name","validateFragmentProps","fragment","keys","didWarnAboutKeySpread","jsxWithValidation","isStaticChildren","validType","sourceInfo","typeString","children","beforeExample","afterExample","jsxWithValidationStatic","jsxWithValidationDynamic","jsx","jsxs","reactJsxRuntime_development","jsxRuntimeModule","require$$1","HorizontalAlign","VerticalAlign","Select","onChange","readOnly","options","placeholder","width","height","handleChange","useCallback","selectedValue","option","opt","displayValue","hasValue","containerStyle","elementStyle","styles","alignmentDefinition","Checkbox","propLabel","label","parseColor","hexMatch","hex","r","rgbaMatch","toHex","rgba","rHex","gHex","bHex","aHex","toRgbaString","isValidHex","COLOR_PALETTE","ColorPalette","onColorSelect","selectedColor","color","index","isUndefined","isSelected","buttonStyle","NumberInput","propMin","propMax","propStep","propInteger","propPlaceholder","propWidth","propHeight","onBlur","min","max","integer","text","num","style","RGBAInputs","v","Z_INDEX","BLOCK_SUB_INDEX","ColorPickerPopover","isOpen","onClose","onRgbaChange","popoverRef","useRef","useEffect","handleClickOutside","ColorPicker","showTextInput","propAllowUndefined","allowUndefined","setIsOpen","useState","containerRef","rgbaValues","setRgbaValues","parsed","handleColorButtonClick","prev","textInputValue","setTextInputValue","handleTextChange","confirmTextInput","handleTextBlur","handleTextKeyDown","handlePaletteClick","colorValue","handleRgbaChange","channel","newValue","newRgba","displayColor","colorStyle","DimensionInput","allowedUnits","currentUnit","handleValueChange","inputValue","effectiveMin","handleBlur","handleUnitChange","newUnit","displayUnit","u","TabPanel","emptyMessage","className","TabsContext","createContext","Tabs","defaultValue","propValue","onValueChange","variant","localValue","setLocalValue","TabsList","propStyle","useContext","computedStyle","TabsTrigger","disabled","TabsContent","TextInput","propMaxLength","propMultiline","propRows","maxLength","multiline","rows","commonProps","ALL_UNITS","ACTUAL_UNITS","PAPER_UNITS","GRID_UNITS","BORDER_UNITS","FONT_UNITS","PADDING_UNITS","SIZE_UNITS","paddingDefinition","data","universalProperties","DEFAULT_FONT_FAMILY","fontStyleDefinition","createPluginRegistry","plugins","acc","plugin","ImageObjectFit","imageDefinition","MultilineWordWrap","MultilineWhiteSpace","multilineDefinition","placeholderDefinition","sizeDefinition","createInitialProps","initialProps","createBlockId","kind","timestamp","random","createBlock","position","overrideProps","validationDefinition","BlockChangeType","DEFAULT_GRID","LineType","DEFAULT_DPI","assertPositive","assertNonNegative","assertRange","assertInteger","assertFinite","MM_PER_INCH","CM_PER_INCH","PT_PER_INCH","toPx","dpi","mm","cm","inch","pt","px","dim","baseSizePx","_exhaustive","getStrokeDasharray","lineStyle","actualLineWidth","Border","widthPx","heightPx","NoteMode","PaperSizePreset","DEFAULT_PAPER_SIZES","DEFAULT_PAPER_MARGIN","DEFAULT_PAPER","DEFAULT_SCHEMA","ValidationSeverity","BorderRenderer","memo","border","getBlockZIndex","zIndex","getSubZIndex","baseZIndex","subIndex","clampedOffset","getMaxBlockCount","BlockBorder","blockSizePx","borderStyle","blockZIndex","subZIndex","visible","useMemo","overlayStyle","BlockCanvas","backgroundColor","canvasStyle","DEFAULT_GUIDE_LINE","DEFAULT_GUIDE_BORDER","BlockGuideBorder","BlockRendererInner","id","mode","validationState","pluginRendererRef","useImperativeHandle","_a","pluginProps","PluginRendererComponent","ForwardedBlockRenderer","forwardRef","BlockRenderer","getBlockContainerStyle","blockRectPx","BlockContainer","block","onValueBlur","showGuides","showBorder","blockSubZIndex","defaultGuideBorder","pointerEvents","_b","_c","_d","BlockLayer","blocks","pluginRegistry","selectedBlockIds","getBlockRectPx","blockRefs","layerStyle","val","BorderOverlay","contentPx","marginLeftPx","marginTopPx","GridCanvas","canvasPx","boxShadow","stringToDimension","str","unit","stringsToDimensions","strs","CM_TO_MM","INCH_TO_MM","PT_TO_MM","PX_TO_MM","toMm","dimensionToString","dimensionsToStrings","dims","SUPPORTED_UNITS","convertPxToUnit","pxSize","targetUnit","GridUnitEditor","direction","dimension","currentPxSize","onCancel","setValue","setUnit","inputRef","editorStyle","event","handleSubmit","numValue","handleKeyDown","convertedValue","originalValue","originalPxSize","ratio","GridDimensionLabel","isNearCursor","resizingPxSize","onDimensionChange","isEditing","setIsEditing","labelStyle","handleDoubleClick","handleDimensionChange","newDimension","handleCancel","displayText","Fragment","getGridPathD","colPxs","rowPxs","y","GridOverlay","gridPosPx","pathData","strokeDasharray","borderWidth","svgStyle","GridResizeHandle","onResizeStart","onResize","onResizeEnd","isDragging","setIsDragging","HANDLE_SIZE","HANDLE_OFFSET","handleStyle","handlePointerDown","initialPos","handlePointerMove","moveEvent","delta","handlePointerUp","upEvent","MarginOverlay","paperPx","marginColor","marginBoxStyle","GridLayer","gridPosPxs","gridDimensions","gridLineStyle","marginFillColor","showGridLines","showMargins","showResizeHandles","showDimensionLabels","onGridResize","ghostLine","setGhostLine","draggingHandle","setDraggingHandle","mousePos","setMousePos","handleMouseMove","rect","handleMouseLeave","shouldShowDimensionLabels","contentWidth","contentHeight","handleResizeStart","resizingPreviewSizes","gridLines","prevStart","prevEnd","prevSize","nextStart","nextEnd","nextSize","handleResize","originalPos","prevLinePos","nextLinePos","MIN_GAP","clampedDelta","minDelta","maxDelta","handleResizeEnd","colPos","rowPos","startPos","endPos","isDraggingAdjacentColumn","centerPos","isDraggingAdjacentRow","GlobalDragStore","__publicField","defaultSize","listener","globalDragStore","calculateGridResize","dimensions","deltaPx","totalContentPx","newDimensions","current","next","resizeFrPair","resizeFixedPair","resizeFrAndFixed","totalFr","sum","frToPx","currentPx","nextPx","newCurrentPx","newNextPx","newCurrentFr","newNextFr","fixedSide","totalFixedPx","availableForFrPx","currentFrToPx","fixedDelta","newAvailableForFrPx","pxValue","distributeRemainder","floatPixels","result","accumulatedError","target","rounded","MIN_STEP","MAX_STEP","MIN_WINDOW_PX","MAX_WINDOW_PX","_clamp","lo","hi","getMaxStep","starts","count","total","avg","windowPx","binarySearch","arr","cnt","mid","midValue","findGridIndex","maxStep","last","startValue","nextValue","leftPx","rightPx","steps","gridToMms","contentSizeMm","fixedTotalMm","mmsWithoutFr","remainingMm","mmPerFr","mmsToPxs","mms","gridPxsFloat","gridToPxs","removeUndefinedProps","obj","cleaned","getPaperSize","paperSize","orientation","size","preparePrint","cleanupPrint","printElement","originalTitle","printStyle","styleElement","executePrint","handleBeforePrint","handleAfterPrint","isBlock","layout","isGridUnit","isDimensionArray","isGrid","isPaper","margin","marginSide","isValue","validateSchema","metaData","deserializeSchema","json","serializeSchema","schema","pretty","validateValues","deserializeValues","serializeValues","SELECTION_STYLE","RESIZE_HANDLE_STYLE","interactionZIndexs","InteractionMode","ResizeHandle","DragType","InteractionEventType","HANDLES","ResizeHandles","activeHandle","handleSize","offset","cursor","left","top","isActive","SelectionBorder","InteractionBlock","showHandles","selectionStyle","selectBorderZIndex","blockHandlesZIndex","InsertGhost","gridLength","currentGrid","currentMousePx","pluginKind","isOutside","ghostZIndex","ghostRect","tempBlock","tempRect","maxX","maxY","ghostBlock","clampMultipleBlocks","deltaCol","deltaRow","gridCols","gridRows","newX","newY","minX","minY","boundingW","boundingH","newMinX","newMinY","clampedMinX","clampedMinY","actualDeltaCol","actualDeltaRow","MovingGhost","dragTargets","clampedPositions","originalRect","clampedPos","calculateResizedLayout","handle","newLayout","maxW","maxShrink","validDCol","maxH","validDRow","ResizeGhost","blockId","DragLayer","draggingState","resizeBlockId","EditingBlockInner","ForwardedEditingBlock","EditingBlock","useInteractionState","initialState","state","setState","newBlockIds","dragTargetIds","gridChanged","SelectionLayer","uniqueSelectedIds","clampBlockToGrid","findBlockAtPoint","point","InteractionLayer","getColIndex","getRowIndex","onBlockChange","scale","editBlockZIndex","dragGhostZIndex","layerRef","editingBlockRef","blockIds","validSelectedIds","scaleFactor","targetId","gridCol","gridRow","isAlreadySelected","newSelectedIds","canvasWidth","canvasHeight","rawX","rawY","clampedX","clampedY","currentCol","currentRow","movedBlocks","newBlock","handlePointerLeave","editingBlock","useGridCalc","paper","grid","canvasWidthMm","canvasHeightMm","marginTopMm","marginBottomMm","marginLeftMm","marginRightMm","contentWidthMm","contentHeightMm","colMms","rowMms","canvasWidthPx","canvasHeightPx","marginBottomPx","marginRightPx","contentWidthPx","contentHeightPx","colPosPxs","rowPosPxs","colMaxStep","colWindowPx","rowMaxStep","rowWindowPx","colIndexer","rowIndexer","paperCanvasPx","paperMarginPx","paperContentPx","w","colLines","rowLines","x1","x2","y1","y2","NoteEditBase","NoteEdit","NoteFormBase","onSchemaChange","onSelectionChange","interactionState","handleInteractionChange","paperRef","handleBlockChange","nextBlocks","deletedIds","updated","cleanedStyle","cleanedProps","handleInitValueChange","unsubscribe","dragState","handleGridResize","dimensionIndex","newCols","newRows","handlePointerEnter","draggingItem","NoteForm","NoteViewBase","NoteView","NoteEditorBase","onValuesChange","_","rest","NoteEditor","NotePrintBase","widthMm","heightMm","existingStyle","NotePrint","getCommonValue","path","getValueByPath","firstValue","BackgroundPanel","selectedBlocks","onUpdateBlocks","updates","setNestedValue","update","depth","BorderPanel","edge","prop","newStyle","currentBorder","edgeStyle","previewBorder","firstBlock","validateEdge","renderInputs","triggerStyle","LayoutPanel","gridSize","isMultipleSelection","currentMin","clampedVal","MetaPanel","localId","setLocalId","primaryBlock","handleIdBlur","currentId","newId","handleIdChange","handleReadOnlyChange","PropertyField","propertyKey","definition","isMixed","componentProps","isPropertyDefinition","BlockPropertyPanel","allSameKind","firstKind","groupedProps","groups","propertiesToShow","allPlugins","firstPlugin","firstPluginKeys","entry","propertyConfig","groupName","handlePluginPropertyChange","items","PluginPanels","BlockOrderPanel","onBlocksChange","draggedIndex","setDraggedIndex","dragOverIndex","setDragOverIndex","displayBlocks","handleBringToFront","newBlocks","handleSendToBack","handleBringForward","temp","handleSendBackward","handleDragStart","displayIndex","actualIndex","handleDragEnd","handleDragOver","handleDragLeave","handleDrop","displayDropIndex","actualDraggedIndex","actualDropIndex","draggedBlock","CanvasPanel","handlePaperChange","newPaper","handleGridChange","newGrid","handleBlocksChange","PaperSizePanel","MarginPanel","GridSizePanel","onGridChange","handleColsChange","newColCount","currentColCount","handleRowsChange","newRowCount","currentRowCount","onPaperChange","linkMargins","setLinkMargins","handleLinkChange","checked","handleTopChange","newMargin","handleRightChange","right","handleBottomChange","bottom","handleLeftChange","presetOptions","handlePresetChange","preset","newSize","handleWidthChange","handleHeightChange","isCustom","ImportExportPanel","setError","schemaFileInputRef","valuesFileInputRef","handleExportSchemaFile","blob","url","handleExportSchemaClipboard","handleImportSchemaFile","handleSchemaFileChange","file","reader","newSchema","handleImportSchemaClipboard","handleExportValuesFile","handleExportValuesClipboard","handleImportValuesFile","handleValuesFileChange","newValues","handleImportValuesClipboard","OtherPanel","PalettePanel","setDragState","handleMove","elementUnderMouse","isOverCanvas","handleUp","PaletteItem","DragGhost","onDragStart","previewBlock","previewValue","handleWindowUp","ghostValue","ghostSize","Sidebar","availablePlugins","hasSelection"],"mappings":"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","x_google_ignoreList":[0,1,2]}
1
+ {"version":3,"file":"index.js","sources":["../../../node_modules/react/cjs/react-jsx-runtime.production.js","../../../node_modules/react/cjs/react-jsx-runtime.development.js","../../../node_modules/react/jsx-runtime.js","../src/plugin/Alignment/schemas.ts","../src/properties/components/Select/Select.tsx","../src/plugin/Alignment/definition.ts","../src/properties/components/Checkbox/Checkbox.tsx","../src/utils/color/func.ts","../src/utils/color/types.ts","../src/properties/components/ColorPicker/ColorPalette.tsx","../src/properties/components/NumberInput/NumberInput.tsx","../src/properties/components/ColorPicker/RGBAInputs.tsx","../src/utils/zIndex/constants.ts","../src/properties/components/ColorPicker/ColorPickerPopover.tsx","../src/properties/components/ColorPicker/ColorPicker.tsx","../src/properties/components/DimensionInput/DimensionInput.tsx","../src/properties/components/TabPanel/TabPanel.tsx","../src/properties/components/Tabs/Tabs.tsx","../src/properties/components/TextInput/TextInput.tsx","../src/types/unit/index.ts","../src/plugin/Padding/definition.ts","../src/plugin/common/universalProperties.ts","../src/plugin/FontStyle/definition.ts","../src/plugin/func.ts","../src/plugin/Image/schemas.ts","../src/plugin/Image/definition.ts","../src/plugin/Multiline/schemas.ts","../src/plugin/Multiline/definition.ts","../src/plugin/Placeholder/definition.ts","../src/plugin/Size/definition.ts","../src/plugin/utils/func.ts","../src/plugin/utils/block.ts","../src/plugin/Validation/definition.ts","../src/types/block/events.ts","../src/types/grid/types.ts","../src/types/line/types.ts","../src/constants/index.ts","../src/utils/assert/number.ts","../src/utils/convert/toPx.ts","../src/types/line/func.ts","../src/types/mode/index.ts","../src/types/paper/types.ts","../src/types/schema/index.ts","../src/types/validation/index.ts","../src/canvas/components/BorderRenderer/BorderRenderer.tsx","../src/utils/zIndex/helpers.ts","../src/canvas/BlockLayer/BlockBorder/BlockBorder.tsx","../src/canvas/BlockLayer/BlockCanvas/BlockCanvas.tsx","../src/canvas/BlockLayer/BlockGuideBorder/constants.ts","../src/canvas/BlockLayer/BlockGuideBorder/BlockGuideBorder.tsx","../src/canvas/BlockLayer/BlockRenderer/BlockRenderer.tsx","../src/utils/blockLayout/getBlockContainerStyle.ts","../src/canvas/BlockLayer/BlockContainer/BlockContainer.tsx","../src/canvas/BlockLayer/BlockLayer.tsx","../src/canvas/GridLayer/BorderOverlay/BorderOverlay.tsx","../src/canvas/GridLayer/GridCanvas/GridCanvas.tsx","../src/utils/convert/toDimension.ts","../src/utils/convert/toMm.ts","../src/utils/convert/toString.ts","../src/canvas/GridLayer/GridDimensionLabel/GridUnitEditor.tsx","../src/canvas/GridLayer/GridDimensionLabel/GridDimensionLabel.tsx","../src/canvas/GridLayer/GridOverlay/getGridPathD.ts","../src/canvas/GridLayer/GridOverlay/GridOverlay.tsx","../src/canvas/GridLayer/GridResizeHandle/GridResizeHandle.tsx","../src/canvas/GridLayer/MarginOverlay/MarginOverlay.tsx","../src/canvas/GridLayer/GridLayer.tsx","../src/utils/GlobalDragStore/GlobalDragStore.ts","../src/utils/grid/calculateGridResize.ts","../src/utils/grid/distributeRemainder.ts","../src/utils/grid/findGridIndex.ts","../src/utils/grid/gridToMms.ts","../src/utils/grid/mmsToPxs.ts","../src/utils/grid/gridToPxs.ts","../src/utils/objectUtils.ts","../src/utils/print/index.ts","../src/utils/schema/validate.ts","../src/utils/schema/deserialize.ts","../src/utils/schema/serialize.ts","../src/utils/values/validate.ts","../src/utils/values/deserialize.ts","../src/utils/values/serialize.ts","../src/canvas/InteractionLayer/InteractionBlock/constants.ts","../src/canvas/InteractionLayer/types.ts","../src/canvas/InteractionLayer/InteractionBlock/ResizeHandles.tsx","../src/canvas/InteractionLayer/InteractionBlock/SelectionBorder.tsx","../src/canvas/InteractionLayer/InteractionBlock/InteractionBlock.tsx","../src/canvas/InteractionLayer/DragLayer/InsertGhost.tsx","../src/canvas/InteractionLayer/utils/clampMultipleBlocks.ts","../src/canvas/InteractionLayer/DragLayer/MovingGhost.tsx","../src/canvas/InteractionLayer/utils/calcResize.ts","../src/canvas/InteractionLayer/DragLayer/ResizeGhost.tsx","../src/canvas/InteractionLayer/DragLayer/DragLayer.tsx","../src/canvas/InteractionLayer/EditingBlock/EditingBlock.tsx","../src/canvas/InteractionLayer/hooks/useInteractionState.ts","../src/canvas/InteractionLayer/SelectionLayer/SelectionLayer.tsx","../src/canvas/InteractionLayer/utils/clampBlock.ts","../src/canvas/InteractionLayer/utils/hitTest.ts","../src/canvas/InteractionLayer/InteractionLayer.tsx","../src/hooks/useGridCalc/index.ts","../src/canvas/NoteEdit.tsx","../src/canvas/NoteForm.tsx","../src/canvas/NoteView.tsx","../src/canvas/NoteEditor.tsx","../src/canvas/NotePrint.tsx","../src/properties/utils/getCommonValue.ts","../src/properties/BlockPropertyPanel/BasePanels/BackgroundPanel/BackgroundPanel.tsx","../src/properties/BlockPropertyPanel/BasePanels/BorderPanel/BorderPanel.tsx","../src/properties/BlockPropertyPanel/BasePanels/LayoutPanel/LayoutPanel.tsx","../src/properties/BlockPropertyPanel/BasePanels/MetaPanel/MetaPanel.tsx","../src/properties/BlockPropertyPanel/PluginPanels/PropertyField.tsx","../src/properties/BlockPropertyPanel/BlockPropertyPanel.tsx","../src/properties/BlockPropertyPanel/PluginPanels/PluginPanels.tsx","../src/properties/CanvasPanel/BlockOrderPanel/BlockOrderPanel.tsx","../src/properties/CanvasPanel/CanvasPanel.tsx","../src/properties/CanvasPanel/GridSizePanel/GridSizePanel.tsx","../src/properties/CanvasPanel/MarginPanel/MarginPanel.tsx","../src/properties/CanvasPanel/PaperSizePanel/PaperSizePanel.tsx","../src/properties/OtherPanel/ImportExportPanel/ImportExportPanel.tsx","../src/properties/OtherPanel/OtherPanel.tsx","../src/properties/PalettePanel/PalettePanel.tsx","../src/properties/Sidebar/Sidebar.tsx"],"sourcesContent":["/**\n * @license React\n * react-jsx-runtime.production.js\n *\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n\"use strict\";\nvar REACT_ELEMENT_TYPE = Symbol.for(\"react.transitional.element\"),\n REACT_FRAGMENT_TYPE = Symbol.for(\"react.fragment\");\nfunction jsxProd(type, config, maybeKey) {\n var key = null;\n void 0 !== maybeKey && (key = \"\" + maybeKey);\n void 0 !== config.key && (key = \"\" + config.key);\n if (\"key\" in config) {\n maybeKey = {};\n for (var propName in config)\n \"key\" !== propName && (maybeKey[propName] = config[propName]);\n } else maybeKey = config;\n config = maybeKey.ref;\n return {\n $$typeof: REACT_ELEMENT_TYPE,\n type: type,\n key: key,\n ref: void 0 !== config ? config : null,\n props: maybeKey\n };\n}\nexports.Fragment = REACT_FRAGMENT_TYPE;\nexports.jsx = jsxProd;\nexports.jsxs = jsxProd;\n","/**\n * @license React\n * react-jsx-runtime.development.js\n *\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n\"use strict\";\n\"production\" !== process.env.NODE_ENV &&\n (function () {\n function getComponentNameFromType(type) {\n if (null == type) return null;\n if (\"function\" === typeof type)\n return type.$$typeof === REACT_CLIENT_REFERENCE\n ? null\n : type.displayName || type.name || null;\n if (\"string\" === typeof type) return type;\n switch (type) {\n case REACT_FRAGMENT_TYPE:\n return \"Fragment\";\n case REACT_PROFILER_TYPE:\n return \"Profiler\";\n case REACT_STRICT_MODE_TYPE:\n return \"StrictMode\";\n case REACT_SUSPENSE_TYPE:\n return \"Suspense\";\n case REACT_SUSPENSE_LIST_TYPE:\n return \"SuspenseList\";\n case REACT_ACTIVITY_TYPE:\n return \"Activity\";\n }\n if (\"object\" === typeof type)\n switch (\n (\"number\" === typeof type.tag &&\n console.error(\n \"Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue.\"\n ),\n type.$$typeof)\n ) {\n case REACT_PORTAL_TYPE:\n return \"Portal\";\n case REACT_CONTEXT_TYPE:\n return type.displayName || \"Context\";\n case REACT_CONSUMER_TYPE:\n return (type._context.displayName || \"Context\") + \".Consumer\";\n case REACT_FORWARD_REF_TYPE:\n var innerType = type.render;\n type = type.displayName;\n type ||\n ((type = innerType.displayName || innerType.name || \"\"),\n (type = \"\" !== type ? \"ForwardRef(\" + type + \")\" : \"ForwardRef\"));\n return type;\n case REACT_MEMO_TYPE:\n return (\n (innerType = type.displayName || null),\n null !== innerType\n ? innerType\n : getComponentNameFromType(type.type) || \"Memo\"\n );\n case REACT_LAZY_TYPE:\n innerType = type._payload;\n type = type._init;\n try {\n return getComponentNameFromType(type(innerType));\n } catch (x) {}\n }\n return null;\n }\n function testStringCoercion(value) {\n return \"\" + value;\n }\n function checkKeyStringCoercion(value) {\n try {\n testStringCoercion(value);\n var JSCompiler_inline_result = !1;\n } catch (e) {\n JSCompiler_inline_result = !0;\n }\n if (JSCompiler_inline_result) {\n JSCompiler_inline_result = console;\n var JSCompiler_temp_const = JSCompiler_inline_result.error;\n var JSCompiler_inline_result$jscomp$0 =\n (\"function\" === typeof Symbol &&\n Symbol.toStringTag &&\n value[Symbol.toStringTag]) ||\n value.constructor.name ||\n \"Object\";\n JSCompiler_temp_const.call(\n JSCompiler_inline_result,\n \"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.\",\n JSCompiler_inline_result$jscomp$0\n );\n return testStringCoercion(value);\n }\n }\n function getTaskName(type) {\n if (type === REACT_FRAGMENT_TYPE) return \"<>\";\n if (\n \"object\" === typeof type &&\n null !== type &&\n type.$$typeof === REACT_LAZY_TYPE\n )\n return \"<...>\";\n try {\n var name = getComponentNameFromType(type);\n return name ? \"<\" + name + \">\" : \"<...>\";\n } catch (x) {\n return \"<...>\";\n }\n }\n function getOwner() {\n var dispatcher = ReactSharedInternals.A;\n return null === dispatcher ? null : dispatcher.getOwner();\n }\n function UnknownOwner() {\n return Error(\"react-stack-top-frame\");\n }\n function hasValidKey(config) {\n if (hasOwnProperty.call(config, \"key\")) {\n var getter = Object.getOwnPropertyDescriptor(config, \"key\").get;\n if (getter && getter.isReactWarning) return !1;\n }\n return void 0 !== config.key;\n }\n function defineKeyPropWarningGetter(props, displayName) {\n function warnAboutAccessingKey() {\n specialPropKeyWarningShown ||\n ((specialPropKeyWarningShown = !0),\n console.error(\n \"%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)\",\n displayName\n ));\n }\n warnAboutAccessingKey.isReactWarning = !0;\n Object.defineProperty(props, \"key\", {\n get: warnAboutAccessingKey,\n configurable: !0\n });\n }\n function elementRefGetterWithDeprecationWarning() {\n var componentName = getComponentNameFromType(this.type);\n didWarnAboutElementRef[componentName] ||\n ((didWarnAboutElementRef[componentName] = !0),\n console.error(\n \"Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release.\"\n ));\n componentName = this.props.ref;\n return void 0 !== componentName ? componentName : null;\n }\n function ReactElement(type, key, props, owner, debugStack, debugTask) {\n var refProp = props.ref;\n type = {\n $$typeof: REACT_ELEMENT_TYPE,\n type: type,\n key: key,\n props: props,\n _owner: owner\n };\n null !== (void 0 !== refProp ? refProp : null)\n ? Object.defineProperty(type, \"ref\", {\n enumerable: !1,\n get: elementRefGetterWithDeprecationWarning\n })\n : Object.defineProperty(type, \"ref\", { enumerable: !1, value: null });\n type._store = {};\n Object.defineProperty(type._store, \"validated\", {\n configurable: !1,\n enumerable: !1,\n writable: !0,\n value: 0\n });\n Object.defineProperty(type, \"_debugInfo\", {\n configurable: !1,\n enumerable: !1,\n writable: !0,\n value: null\n });\n Object.defineProperty(type, \"_debugStack\", {\n configurable: !1,\n enumerable: !1,\n writable: !0,\n value: debugStack\n });\n Object.defineProperty(type, \"_debugTask\", {\n configurable: !1,\n enumerable: !1,\n writable: !0,\n value: debugTask\n });\n Object.freeze && (Object.freeze(type.props), Object.freeze(type));\n return type;\n }\n function jsxDEVImpl(\n type,\n config,\n maybeKey,\n isStaticChildren,\n debugStack,\n debugTask\n ) {\n var children = config.children;\n if (void 0 !== children)\n if (isStaticChildren)\n if (isArrayImpl(children)) {\n for (\n isStaticChildren = 0;\n isStaticChildren < children.length;\n isStaticChildren++\n )\n validateChildKeys(children[isStaticChildren]);\n Object.freeze && Object.freeze(children);\n } else\n console.error(\n \"React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.\"\n );\n else validateChildKeys(children);\n if (hasOwnProperty.call(config, \"key\")) {\n children = getComponentNameFromType(type);\n var keys = Object.keys(config).filter(function (k) {\n return \"key\" !== k;\n });\n isStaticChildren =\n 0 < keys.length\n ? \"{key: someKey, \" + keys.join(\": ..., \") + \": ...}\"\n : \"{key: someKey}\";\n didWarnAboutKeySpread[children + isStaticChildren] ||\n ((keys =\n 0 < keys.length ? \"{\" + keys.join(\": ..., \") + \": ...}\" : \"{}\"),\n console.error(\n 'A props object containing a \"key\" prop is being spread into JSX:\\n let props = %s;\\n <%s {...props} />\\nReact keys must be passed directly to JSX without using spread:\\n let props = %s;\\n <%s key={someKey} {...props} />',\n isStaticChildren,\n children,\n keys,\n children\n ),\n (didWarnAboutKeySpread[children + isStaticChildren] = !0));\n }\n children = null;\n void 0 !== maybeKey &&\n (checkKeyStringCoercion(maybeKey), (children = \"\" + maybeKey));\n hasValidKey(config) &&\n (checkKeyStringCoercion(config.key), (children = \"\" + config.key));\n if (\"key\" in config) {\n maybeKey = {};\n for (var propName in config)\n \"key\" !== propName && (maybeKey[propName] = config[propName]);\n } else maybeKey = config;\n children &&\n defineKeyPropWarningGetter(\n maybeKey,\n \"function\" === typeof type\n ? type.displayName || type.name || \"Unknown\"\n : type\n );\n return ReactElement(\n type,\n children,\n maybeKey,\n getOwner(),\n debugStack,\n debugTask\n );\n }\n function validateChildKeys(node) {\n isValidElement(node)\n ? node._store && (node._store.validated = 1)\n : \"object\" === typeof node &&\n null !== node &&\n node.$$typeof === REACT_LAZY_TYPE &&\n (\"fulfilled\" === node._payload.status\n ? isValidElement(node._payload.value) &&\n node._payload.value._store &&\n (node._payload.value._store.validated = 1)\n : node._store && (node._store.validated = 1));\n }\n function isValidElement(object) {\n return (\n \"object\" === typeof object &&\n null !== object &&\n object.$$typeof === REACT_ELEMENT_TYPE\n );\n }\n var React = require(\"react\"),\n REACT_ELEMENT_TYPE = Symbol.for(\"react.transitional.element\"),\n REACT_PORTAL_TYPE = Symbol.for(\"react.portal\"),\n REACT_FRAGMENT_TYPE = Symbol.for(\"react.fragment\"),\n REACT_STRICT_MODE_TYPE = Symbol.for(\"react.strict_mode\"),\n REACT_PROFILER_TYPE = Symbol.for(\"react.profiler\"),\n REACT_CONSUMER_TYPE = Symbol.for(\"react.consumer\"),\n REACT_CONTEXT_TYPE = Symbol.for(\"react.context\"),\n REACT_FORWARD_REF_TYPE = Symbol.for(\"react.forward_ref\"),\n REACT_SUSPENSE_TYPE = Symbol.for(\"react.suspense\"),\n REACT_SUSPENSE_LIST_TYPE = Symbol.for(\"react.suspense_list\"),\n REACT_MEMO_TYPE = Symbol.for(\"react.memo\"),\n REACT_LAZY_TYPE = Symbol.for(\"react.lazy\"),\n REACT_ACTIVITY_TYPE = Symbol.for(\"react.activity\"),\n REACT_CLIENT_REFERENCE = Symbol.for(\"react.client.reference\"),\n ReactSharedInternals =\n React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,\n hasOwnProperty = Object.prototype.hasOwnProperty,\n isArrayImpl = Array.isArray,\n createTask = console.createTask\n ? console.createTask\n : function () {\n return null;\n };\n React = {\n react_stack_bottom_frame: function (callStackForError) {\n return callStackForError();\n }\n };\n var specialPropKeyWarningShown;\n var didWarnAboutElementRef = {};\n var unknownOwnerDebugStack = React.react_stack_bottom_frame.bind(\n React,\n UnknownOwner\n )();\n var unknownOwnerDebugTask = createTask(getTaskName(UnknownOwner));\n var didWarnAboutKeySpread = {};\n exports.Fragment = REACT_FRAGMENT_TYPE;\n exports.jsx = function (type, config, maybeKey) {\n var trackActualOwner =\n 1e4 > ReactSharedInternals.recentlyCreatedOwnerStacks++;\n return jsxDEVImpl(\n type,\n config,\n maybeKey,\n !1,\n trackActualOwner\n ? Error(\"react-stack-top-frame\")\n : unknownOwnerDebugStack,\n trackActualOwner ? createTask(getTaskName(type)) : unknownOwnerDebugTask\n );\n };\n exports.jsxs = function (type, config, maybeKey) {\n var trackActualOwner =\n 1e4 > ReactSharedInternals.recentlyCreatedOwnerStacks++;\n return jsxDEVImpl(\n type,\n config,\n maybeKey,\n !0,\n trackActualOwner\n ? Error(\"react-stack-top-frame\")\n : unknownOwnerDebugStack,\n trackActualOwner ? createTask(getTaskName(type)) : unknownOwnerDebugTask\n );\n };\n })();\n","'use strict';\n\nif (process.env.NODE_ENV === 'production') {\n module.exports = require('./cjs/react-jsx-runtime.production.js');\n} else {\n module.exports = require('./cjs/react-jsx-runtime.development.js');\n}\n","export enum HorizontalAlign {\r\n\tleft = \"flex-start\",\r\n\tcenter = \"center\",\r\n\tright = \"flex-end\",\r\n}\r\n\r\nexport enum VerticalAlign {\r\n\ttop = \"flex-start\",\r\n\tcenter = \"center\",\r\n\tbottom = \"flex-end\",\r\n}\r\n\r\nexport interface AlignmentSchema {\r\n\tjustifyContent?: HorizontalAlign;\r\n\talignItems?: VerticalAlign;\r\n}\r\n","/**\r\n * @file Select.tsx\r\n * @description ドロップダウン選択コンポーネント\r\n */\r\n\r\nimport { useCallback } from \"react\";\r\n\r\nimport styles from \"./Select.module.css\";\r\n\r\nimport type React from \"react\";\r\nimport type { PropertyComponentProps } from \"@/plugin\";\r\nimport type { Value } from \"@/types/value\";\r\n\r\n/**\r\n * 選択肢の型\r\n */\r\nexport interface SelectOption {\r\n\tvalue: Value;\r\n\tlabel: string;\r\n\t[key: string]: Value;\r\n}\r\n\r\n/**\r\n * Config型定義\r\n */\r\nexport interface SelectConfig {\r\n\toptions?: readonly SelectOption[];\r\n\tplaceholder?: string;\r\n\twidth?: number;\r\n\theight?: number;\r\n\r\n\t[key: string]: Value;\r\n}\r\n\r\n/**\r\n * Select固有のProps\r\n */\r\nexport interface SelectProps<T extends string = string>\r\n\textends PropertyComponentProps<T | undefined> {\r\n\toptions?: readonly SelectOption[];\r\n\tplaceholder?: string;\r\n\t/** 幅(px) */\r\n\twidth?: number;\r\n\t/** 高さ(px) */\r\n\theight?: number;\r\n\r\n\tconfig?: SelectConfig;\r\n}\r\n\r\n/**\r\n * ドロップダウン選択コンポーネント\r\n */\r\nexport const Select = <T extends string = string>(\r\n\tprops: SelectProps<T>,\r\n): React.ReactElement => {\r\n\tconst { value, onChange, readOnly = false, config } = props;\r\n\r\n\t// 設定のマージ\r\n\tconst options = props.options ?? config?.options ?? [];\r\n\tconst placeholder =\r\n\t\tprops.placeholder ?? config?.placeholder ?? \"選択してください\";\r\n\tconst width = props.width ?? config?.width;\r\n\tconst height = props.height ?? config?.height;\r\n\r\n\tconst handleChange = useCallback(\r\n\t\t(e: React.ChangeEvent<HTMLSelectElement>) => {\r\n\t\t\tconst selectedValue = e.target.value;\r\n\t\t\tif (selectedValue === \"\") {\r\n\t\t\t\tonChange(undefined as unknown as T);\r\n\t\t\t} else {\r\n\t\t\t\t// optionsから実際のvalueを取得(文字列変換されたものではなく元の値)\r\n\t\t\t\tconst option = options.find(\r\n\t\t\t\t\t(opt) => String(opt.value) === selectedValue,\r\n\t\t\t\t);\r\n\t\t\t\tif (option) {\r\n\t\t\t\t\tonChange(option.value as T);\r\n\t\t\t\t} else {\r\n\t\t\t\t\tonChange(selectedValue as T);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t},\r\n\t\t[onChange, options],\r\n\t);\r\n\r\n\tconst displayValue = value ?? \"\";\r\n\tconst hasValue = value !== undefined && value !== \"\";\r\n\r\n\t// インラインスタイル(containerには幅のみ適用)\r\n\tconst containerStyle: React.CSSProperties = {};\r\n\tif (width !== undefined) {\r\n\t\tcontainerStyle.width = `${width}px`;\r\n\t} else {\r\n\t\tcontainerStyle.width = \"100%\"; // デフォルトは親要素の幅\r\n\t}\r\n\r\n\t// selectとoverlayには高さを適用\r\n\tconst elementStyle: React.CSSProperties = {\r\n\t\twidth: \"100%\",\r\n\t\theight: height ? `${height}px` : undefined,\r\n\t};\r\n\r\n\treturn (\r\n\t\t<div className={styles.container} style={containerStyle}>\r\n\t\t\t{!hasValue && (\r\n\t\t\t\t<input\r\n\t\t\t\t\tclassName={styles.placeholderOverlay}\r\n\t\t\t\t\tstyle={elementStyle}\r\n\t\t\t\t\treadOnly\r\n\t\t\t\t\tplaceholder={placeholder}\r\n\t\t\t\t/>\r\n\t\t\t)}\r\n\t\t\t<select\r\n\t\t\t\tclassName={styles.select}\r\n\t\t\t\tstyle={elementStyle}\r\n\t\t\t\tvalue={displayValue}\r\n\t\t\t\tonChange={handleChange}\r\n\t\t\t\tdisabled={readOnly}\r\n\t\t\t>\r\n\t\t\t\t{options.map((option) => (\r\n\t\t\t\t\t<option key={String(option.value)} value={String(option.value)}>\r\n\t\t\t\t\t\t{option.label}\r\n\t\t\t\t\t</option>\r\n\t\t\t\t))}\r\n\t\t\t</select>\r\n\t\t</div>\r\n\t);\r\n};\r\n\r\nSelect.displayName = \"Select\";\r\n","import {\r\n\ttype AlignmentSchema,\r\n\tHorizontalAlign,\r\n\tVerticalAlign,\r\n} from \"./schemas\";\r\n\r\nimport { Select } from \"@/properties/components/Select\";\r\n\r\nimport type { PluginProperties } from \"@/plugin\";\r\n\r\nexport const alignmentDefinition: PluginProperties<AlignmentSchema> = {\r\n\tjustifyContent: {\r\n\t\tdefaultValue: HorizontalAlign.left,\r\n\t\tlabel: \"水平方向の配置\",\r\n\t\tgroup: \"配置\",\r\n\t\tdescription: \"ブロック内のコンテンツの水平方向の配置を設定します。\",\r\n\t\tComponent: Select,\r\n\t\tconfig: {\r\n\t\t\toptions: [\r\n\t\t\t\t{ label: \"左揃え\", value: HorizontalAlign.left },\r\n\t\t\t\t{ label: \"中央揃え\", value: HorizontalAlign.center },\r\n\t\t\t\t{ label: \"右揃え\", value: HorizontalAlign.right },\r\n\t\t\t],\r\n\t\t},\r\n\t},\r\n\r\n\talignItems: {\r\n\t\tdefaultValue: VerticalAlign.center,\r\n\t\tlabel: \"垂直方向の配置\",\r\n\t\tgroup: \"配置\",\r\n\t\tdescription: \"ブロック内のコンテンツの垂直方向の配置を設定します。\",\r\n\t\tComponent: Select,\r\n\t\tconfig: {\r\n\t\t\toptions: [\r\n\t\t\t\t{ label: \"上揃え\", value: VerticalAlign.top },\r\n\t\t\t\t{ label: \"中央揃え\", value: VerticalAlign.center },\r\n\t\t\t\t{ label: \"下揃え\", value: VerticalAlign.bottom },\r\n\t\t\t],\r\n\t\t},\r\n\t},\r\n};\r\n","/**\r\n * @file Checkbox.tsx\r\n * @description チェックボックス入力コンポーネント\r\n */\r\n\r\nimport { useCallback } from \"react\";\r\n\r\nimport styles from \"./Checkbox.module.css\";\r\n\r\nimport type React from \"react\";\r\nimport type { PropertyComponentProps } from \"@/plugin\";\r\nimport type { Value } from \"@/types/value\";\r\n\r\nexport interface CheckboxConfig {\r\n\tlabel?: string;\r\n\t[key: string]: Value;\r\n}\r\n\r\n/**\r\n * Checkbox固有のProps\r\n * ★修正: boolean | undefined にして未設定を許容する\r\n */\r\nexport interface CheckboxProps\r\n\textends PropertyComponentProps<boolean | undefined> {\r\n\tlabel?: string;\r\n\tconfig?: CheckboxConfig;\r\n}\r\n\r\n/**\r\n * チェックボックスコンポーネント\r\n */\r\nexport const Checkbox = ({\r\n\tvalue,\r\n\tonChange,\r\n\treadOnly = false,\r\n\tlabel: propLabel,\r\n\tconfig,\r\n}: CheckboxProps): React.ReactElement => {\r\n\tconst label = propLabel ?? config?.label;\r\n\r\n\tconst handleChange = useCallback(\r\n\t\t(e: React.ChangeEvent<HTMLInputElement>) => {\r\n\t\t\tonChange(e.target.checked);\r\n\t\t},\r\n\t\t[onChange],\r\n\t);\r\n\r\n\treturn (\r\n\t\t<label className={styles.container}>\r\n\t\t\t<input\r\n\t\t\t\ttype=\"checkbox\"\r\n\t\t\t\tclassName={styles.input}\r\n\t\t\t\tchecked={!!value} // undefined の場合は false として扱う\r\n\t\t\t\tonChange={handleChange}\r\n\t\t\t\tdisabled={readOnly}\r\n\t\t\t/>\r\n\t\t\t{label && <span className={styles.label}>{label}</span>}\r\n\t\t</label>\r\n\t);\r\n};\r\n\r\nCheckbox.displayName = \"Checkbox\";\r\n","import type { RGBA } from \"./types\";\r\n\r\n/**\r\n * カラー文字列を RGBA オブジェクトに変換\r\n * @param value カラー文字列 (#RRGGBB, #RRGGBBAA, rgba(r,g,b,a), undefined)\r\n * @returns RGBA オブジェクト、または null(変換失敗時)\r\n */\r\nexport function parseColor(value: string | undefined): RGBA | null {\r\n\tif (!value) {\r\n\t\treturn null;\r\n\t}\r\n\r\n\t// Hex形式 (#RRGGBB または #RRGGBBAA)\r\n\tconst hexMatch = value.match(/^#([0-9a-f]{6}|[0-9a-f]{8})$/i);\r\n\tif (hexMatch && typeof hexMatch[1] === \"string\") {\r\n\t\tconst hex = hexMatch[1];\r\n\t\tconst r = Number.parseInt(hex.slice(0, 2), 16);\r\n\t\tconst g = Number.parseInt(hex.slice(2, 4), 16);\r\n\t\tconst b = Number.parseInt(hex.slice(4, 6), 16);\r\n\t\tconst a = hex.length === 8 ? Number.parseInt(hex.slice(6, 8), 16) / 255 : 1;\r\n\t\treturn { r, g, b, a };\r\n\t}\r\n\r\n\t// rgba形式 (rgba(r, g, b, a))\r\n\tconst rgbaMatch = value.match(\r\n\t\t/^rgba?\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*(?:,\\s*([\\d.]+)\\s*)?\\)$/,\r\n\t);\r\n\tif (rgbaMatch) {\r\n\t\tconst r = Number.parseInt(rgbaMatch[1] ?? \"\", 10);\r\n\t\tconst g = Number.parseInt(rgbaMatch[2] ?? \"\", 10);\r\n\t\tconst b = Number.parseInt(rgbaMatch[3] ?? \"\", 10);\r\n\t\tconst a = rgbaMatch[4] ? Number.parseFloat(rgbaMatch[4]) : 1;\r\n\t\treturn { r, g, b, a };\r\n\t}\r\n\r\n\treturn null;\r\n}\r\n\r\n/**\r\n * RGBA オブジェクトを Hex 文字列に変換\r\n * @param rgba RGBA オブジェクト\r\n * @returns #RRGGBB または #RRGGBBAA 形式の文字列、透明の場合は undefined\r\n */\r\nexport function toHex(rgba: RGBA): string | undefined {\r\n\tconst { r, g, b, a } = rgba;\r\n\r\n\t// 透明の場合\r\n\tif (a === 0) {\r\n\t\treturn undefined;\r\n\t}\r\n\r\n\tconst rHex = r.toString(16).padStart(2, \"0\");\r\n\tconst gHex = g.toString(16).padStart(2, \"0\");\r\n\tconst bHex = b.toString(16).padStart(2, \"0\");\r\n\r\n\t// アルファが1未満の場合は8桁形式\r\n\tif (a < 1) {\r\n\t\tconst aHex = Math.round(a * 255)\r\n\t\t\t.toString(16)\r\n\t\t\t.padStart(2, \"0\");\r\n\t\treturn `#${rHex}${gHex}${bHex}${aHex}`;\r\n\t}\r\n\r\n\t// アルファが1の場合は6桁形式\r\n\treturn `#${rHex}${gHex}${bHex}`;\r\n}\r\n\r\n/**\r\n * RGBA オブジェクトを rgba() 文字列に変換\r\n * @param rgba RGBA オブジェクト\r\n * @returns rgba(r, g, b, a) 形式の文字列、透明の場合は undefined\r\n */\r\nexport function toRgbaString(rgba: RGBA): string | undefined {\r\n\tconst { r, g, b, a } = rgba;\r\n\r\n\t// 透明の場合\r\n\tif (a === 0) {\r\n\t\treturn undefined;\r\n\t}\r\n\r\n\treturn `rgba(${r}, ${g}, ${b}, ${a})`;\r\n}\r\n\r\n/**\r\n * Hex カラー文字列の妥当性をチェック\r\n * @param hex チェックする文字列\r\n * @returns 妥当な Hex カラー文字列かどうか\r\n */\r\nexport function isValidHex(hex: string): boolean {\r\n\treturn /^#([0-9a-f]{6}|[0-9a-f]{8})$/i.test(hex);\r\n}\r\n","/**\r\n * RGBA カラー型定義\r\n */\r\nexport interface RGBA {\r\n\tr: number; // 0-255\r\n\tg: number; // 0-255\r\n\tb: number; // 0-255\r\n\ta: number; // 0-1\r\n}\r\n\r\n/**\r\n * カラーパレット定義(30色)\r\n */\r\nexport const COLOR_PALETTE = [\r\n\t{ label: \"無色\", value: undefined as string | undefined },\r\n\t{ label: \"白\", value: \"#ffffff\" },\r\n\t{ label: \"グレー1\", value: \"#efefef\" },\r\n\t{ label: \"グレー2\", value: \"#d9d9d9\" },\r\n\t{ label: \"グレー3\", value: \"#cccccc\" },\r\n\t{ label: \"グレー4\", value: \"#b7b7b7\" },\r\n\t{ label: \"グレー5\", value: \"#999999\" },\r\n\t{ label: \"グレー6\", value: \"#666666\" },\r\n\t{ label: \"グレー7\", value: \"#434343\" },\r\n\t{ label: \"黒\", value: \"#000000\" },\r\n\t{ label: \"薄茶\", value: \"#E6B8AF\" },\r\n\t{ label: \"薄赤\", value: \"#F4CCCC\" },\r\n\t{ label: \"薄橙\", value: \"#FCE5CD\" },\r\n\t{ label: \"薄黄\", value: \"#FFF2CC\" },\r\n\t{ label: \"薄緑\", value: \"#D9EAD3\" },\r\n\t{ label: \"薄青緑\", value: \"#D0E0E3\" },\r\n\t{ label: \"薄青\", value: \"#C9DAF8\" },\r\n\t{ label: \"薄青紫\", value: \"#CFE2F3\" },\r\n\t{ label: \"薄紫\", value: \"#D9D2E9\" },\r\n\t{ label: \"薄赤紫\", value: \"#EAD1DC\" },\r\n\t{ label: \"茶\", value: \"#DD7E6B\" },\r\n\t{ label: \"赤\", value: \"#EA9999\" },\r\n\t{ label: \"橙\", value: \"#F9CB9C\" },\r\n\t{ label: \"黄\", value: \"#FFE599\" },\r\n\t{ label: \"緑\", value: \"#B6D7A8\" },\r\n\t{ label: \"青緑\", value: \"#A2C4C9\" },\r\n\t{ label: \"青\", value: \"#A4C2F4\" },\r\n\t{ label: \"青紫\", value: \"#9FC5E8\" },\r\n\t{ label: \"紫\", value: \"#B4A7D6\" },\r\n\t{ label: \"赤紫\", value: \"#D5A6BD\" },\r\n] as const;\r\n","/**\r\n * @file ColorPalette.tsx\r\n * @description カラーパレットコンポーネント\r\n */\r\n\r\nimport styles from \"./ColorPicker.module.css\";\r\n\r\nimport { COLOR_PALETTE } from \"@/utils/color\";\r\n\r\nimport type React from \"react\";\r\n\r\nexport interface ColorPaletteProps {\r\n\tonColorSelect: (color: string | undefined) => void;\r\n\tselectedColor?: string;\r\n\treadOnly?: boolean;\r\n}\r\n\r\n/**\r\n * カラーパレットコンポーネント\r\n */\r\nexport const ColorPalette = ({\r\n\tonColorSelect,\r\n\tselectedColor,\r\n\treadOnly = false,\r\n}: ColorPaletteProps): React.ReactElement => {\r\n\treturn (\r\n\t\t<div className={styles.palette}>\r\n\t\t\t{COLOR_PALETTE.map((color, index) => {\r\n\t\t\t\tconst isUndefined = color.value === undefined;\r\n\t\t\t\tconst isSelected = color.value === selectedColor;\r\n\t\t\t\tconst buttonStyle: React.CSSProperties = isUndefined\r\n\t\t\t\t\t? {}\r\n\t\t\t\t\t: { backgroundColor: color.value };\r\n\r\n\t\t\t\treturn (\r\n\t\t\t\t\t<button\r\n\t\t\t\t\t\tkey={color.value ?? `undefined-${index}`}\r\n\t\t\t\t\t\ttype=\"button\"\r\n\t\t\t\t\t\tclassName={`${styles.paletteButton} ${isUndefined ? styles.transparentPaletteButton : \"\"} ${isSelected ? styles.selected : \"\"}`}\r\n\t\t\t\t\t\tonClick={() => onColorSelect(color.value)}\r\n\t\t\t\t\t\tdisabled={readOnly}\r\n\t\t\t\t\t\ttitle={color.label}\r\n\t\t\t\t\t\taria-label={color.label}\r\n\t\t\t\t\t\tstyle={buttonStyle}\r\n\t\t\t\t\t/>\r\n\t\t\t\t);\r\n\t\t\t})}\r\n\t\t</div>\r\n\t);\r\n};\r\n\r\nColorPalette.displayName = \"ColorPalette\";\r\n","import { useCallback } from \"react\";\r\n\r\nimport styles from \"./NumberInput.module.css\";\r\n\r\nimport type React from \"react\";\r\nimport type { PropertyComponentProps } from \"@/plugin\";\r\nimport type { Value } from \"@/types/value\";\r\n\r\nexport interface NumberInputConfig {\r\n\tmin?: number;\r\n\tmax?: number;\r\n\tstep?: number;\r\n\tinteger?: boolean;\r\n\tplaceholder?: string;\r\n\twidth?: number;\r\n\theight?: number;\r\n\t[key: string]: Value;\r\n}\r\n\r\nexport interface NumberInputProps\r\n\textends PropertyComponentProps<number | undefined> {\r\n\tmin?: number;\r\n\tmax?: number;\r\n\tstep?: number;\r\n\tinteger?: boolean;\r\n\tplaceholder?: string;\r\n\t/** 幅(px) */\r\n\twidth?: number;\r\n\t/** 高さ(px) */\r\n\theight?: number;\r\n\tconfig?: NumberInputConfig;\r\n\tonBlur?: () => void;\r\n}\r\n\r\nexport const NumberInput = ({\r\n\tvalue,\r\n\tonChange,\r\n\treadOnly = false,\r\n\tmin: propMin,\r\n\tmax: propMax,\r\n\tstep: propStep,\r\n\tinteger: propInteger,\r\n\tplaceholder: propPlaceholder,\r\n\twidth: propWidth,\r\n\theight: propHeight,\r\n\tconfig,\r\n\tonBlur,\r\n}: NumberInputProps): React.ReactElement => {\r\n\tconst min = propMin ?? config?.min ?? 1;\r\n\tconst max = propMax ?? config?.max;\r\n\tconst step = propStep ?? config?.step ?? 1;\r\n\tconst integer = propInteger ?? config?.integer ?? false;\r\n\tconst placeholder = propPlaceholder ?? config?.placeholder;\r\n\tconst width = propWidth ?? config?.width;\r\n\tconst height = propHeight ?? config?.height;\r\n\r\n\tconst handleChange = useCallback(\r\n\t\t(e: React.ChangeEvent<HTMLInputElement>) => {\r\n\t\t\tconst text = e.target.value;\r\n\t\t\tif (text === \"\") {\r\n\t\t\t\tonChange(undefined);\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tlet num = Number.parseFloat(text);\r\n\t\t\tif (Number.isNaN(num)) return;\r\n\r\n\t\t\tif (integer) num = Math.round(num);\r\n\t\t\tif (min !== undefined && num < min) num = min;\r\n\t\t\tif (max !== undefined && num > max) num = max;\r\n\r\n\t\t\tonChange(num);\r\n\t\t},\r\n\t\t[onChange, min, max, integer],\r\n\t);\r\n\r\n\t// スタイルの構築\r\n\tconst style: React.CSSProperties = {};\r\n\tif (width !== undefined) style.width = `${width}px`;\r\n\r\n\tif (height !== undefined) {\r\n\t\tstyle.height = `${height}px`;\r\n\t\t// 高さが小さい場合、パディングがあると文字が見切れるため調整\r\n\t\tstyle.paddingTop = 0;\r\n\t\tstyle.paddingBottom = 0;\r\n\t}\r\n\r\n\treturn (\r\n\t\t<input\r\n\t\t\ttype=\"number\"\r\n\t\t\tclassName={styles.input}\r\n\t\t\tstyle={style}\r\n\t\t\tvalue={value ?? \"\"}\r\n\t\t\tonChange={handleChange}\r\n\t\t\tonBlur={onBlur}\r\n\t\t\tdisabled={readOnly}\r\n\t\t\tmin={min}\r\n\t\t\tmax={max}\r\n\t\t\tstep={step}\r\n\t\t\tplaceholder={placeholder}\r\n\t\t/>\r\n\t);\r\n};\r\n\r\nNumberInput.displayName = \"NumberInput\";\r\n","/**\r\n * @file RGBAInputs.tsx\r\n * @description RGBA入力コンポーネント\r\n */\r\n\r\nimport { NumberInput } from \"../NumberInput/NumberInput\";\r\nimport styles from \"./ColorPicker.module.css\";\r\n\r\nimport type React from \"react\";\r\nimport type { RGBA } from \"@/utils/color\";\r\n\r\nexport interface RGBAInputsProps {\r\n\trgba: RGBA;\r\n\tonChange: (channel: keyof RGBA, value: number | undefined) => void;\r\n\treadOnly?: boolean;\r\n}\r\n\r\n/**\r\n * RGBA入力コンポーネント\r\n */\r\nexport const RGBAInputs = ({\r\n\trgba,\r\n\tonChange,\r\n\treadOnly = false,\r\n}: RGBAInputsProps): React.ReactElement => {\r\n\treturn (\r\n\t\t<div className={styles.rgbaInputs}>\r\n\t\t\t<div className={styles.rgbaInputGroup}>\r\n\t\t\t\t<span className={styles.rgbaLabel}>R</span>\r\n\t\t\t\t<NumberInput\r\n\t\t\t\t\tvalue={rgba.r}\r\n\t\t\t\t\tonChange={(v) => onChange(\"r\", v)}\r\n\t\t\t\t\tmin={0}\r\n\t\t\t\t\tmax={255}\r\n\t\t\t\t\tstep={1}\r\n\t\t\t\t\tinteger={true}\r\n\t\t\t\t\twidth={48}\r\n\t\t\t\t\treadOnly={readOnly}\r\n\t\t\t\t/>\r\n\t\t\t</div>\r\n\t\t\t<div className={styles.rgbaInputGroup}>\r\n\t\t\t\t<span className={styles.rgbaLabel}>G</span>\r\n\t\t\t\t<NumberInput\r\n\t\t\t\t\tvalue={rgba.g}\r\n\t\t\t\t\tonChange={(v) => onChange(\"g\", v)}\r\n\t\t\t\t\tmin={0}\r\n\t\t\t\t\tmax={255}\r\n\t\t\t\t\tstep={1}\r\n\t\t\t\t\tinteger={true}\r\n\t\t\t\t\twidth={48}\r\n\t\t\t\t\treadOnly={readOnly}\r\n\t\t\t\t/>\r\n\t\t\t</div>\r\n\t\t\t<div className={styles.rgbaInputGroup}>\r\n\t\t\t\t<span className={styles.rgbaLabel}>B</span>\r\n\t\t\t\t<NumberInput\r\n\t\t\t\t\tvalue={rgba.b}\r\n\t\t\t\t\tonChange={(v) => onChange(\"b\", v)}\r\n\t\t\t\t\tmin={0}\r\n\t\t\t\t\tmax={255}\r\n\t\t\t\t\tstep={1}\r\n\t\t\t\t\tinteger={true}\r\n\t\t\t\t\twidth={48}\r\n\t\t\t\t\treadOnly={readOnly}\r\n\t\t\t\t/>\r\n\t\t\t</div>\r\n\t\t\t<div className={styles.rgbaInputGroup}>\r\n\t\t\t\t<span className={styles.rgbaLabel}>A</span>\r\n\t\t\t\t<NumberInput\r\n\t\t\t\t\tvalue={Math.round(rgba.a * 100)}\r\n\t\t\t\t\tonChange={(v) => onChange(\"a\", v !== undefined ? v / 100 : undefined)}\r\n\t\t\t\t\tmin={0}\r\n\t\t\t\t\tmax={100}\r\n\t\t\t\t\tstep={1}\r\n\t\t\t\t\tinteger={true}\r\n\t\t\t\t\twidth={48}\r\n\t\t\t\t\treadOnly={readOnly}\r\n\t\t\t\t/>\r\n\t\t\t</div>\r\n\t\t</div>\r\n\t);\r\n};\r\n\r\nRGBAInputs.displayName = \"RGBAInputs\";\r\n","/**\r\n * @file constants.ts\r\n * @description z-index定数定義\r\n *\r\n * 4層アーキテクチャに基づくz-index管理:\r\n * - GridLayer: 0-9 (静的背景)\r\n * - BlockLayer: 10-99,999 (ブロックコンテンツ)\r\n * - ErrorLayer: 150,000-199,999 (バリデーションエラー表示)\r\n * - InteractionLayer: 200,000+ (インタラクション要素)\r\n */\r\n\r\n/**\r\n * Z-INDEX定数\r\n *\r\n * 各レイヤーのz-index範囲を定義\r\n */\r\nexport const Z_INDEX = {\r\n\t// ==================== GridLayer (10-90) ====================\r\n\t/** グリッド背景(用紙背景) */\r\n\tGRID_CANVAS: 10,\r\n\t/** 用紙マージン表示(印刷可能範囲) */\r\n\tMARGIN_OVERLAY: 20,\r\n\t/** グリッド線 */\r\n\tGRID_OVERLAY: 30,\r\n\t/** 印刷可能領域の境界線 */\r\n\tBORDER_OVERLAY: 40,\r\n\r\n\t// ==================== BlockLayer (100-999,999) ====================\r\n\t/** BlockLayerの最小z-index */\r\n\tBLOCK_LAYER_MIN: 100,\r\n\t/** BlockLayerの最大z-index */\r\n\tBLOCK_LAYER_MAX: 999999,\r\n\t/** ブロック間のz-indexステップ(各ブロックは100段階のサブレイヤーを持っている) */\r\n\tBLOCK_LAYER_STEP: 100,\r\n\r\n\t// ==================== ErrorLayer (1,000,000-1,999,999) ====================\r\n\t/** エラー枠線 */\r\n\tERROR_BORDER: 1100000,\r\n\t/** エラーツールチップ */\r\n\tERROR_TOOLTIP: 1200000,\r\n\t/** エラー背景ハイライト */\r\n\tERROR_HIGHLIGHT: 1300000,\r\n\r\n\t// ==================== InteractionLayer (2,000,000+) ====================\r\n\t/** 選択中ブロック */\r\n\tSELECT_BLOCK: 2000000,\r\n\t// interactionLayerのベース\r\n\tINTERACTION_LAYER_BASE: 2100000,\r\n\t/** ドラッグ中ゴースト */\r\n\tBLOCK_GHOST: 2200000,\r\n\t/** ホバー枠線 */\r\n\tHOVER_OUTLINE: 2300000,\r\n\t/** ブロック編集中 */\r\n\tEDIT_BLOCK: 2400000,\r\n\t/** 選択中ブロック枠線 */\r\n\tBLOCK_SELECT_BORDER: 2500000,\r\n\t/** ブロックリサイズハンドル */\r\n\tBLOCK_HANDLES: 2600000,\r\n\t/** グリッドリサイズ中のゴースト線 */\r\n\tGRID_GHOST: 2700000,\r\n\t/** グリッドリサイズハンドル */\r\n\tGRID_HANDLES: 2800000,\r\n\t/** 範囲選択矩形 */\r\n\tRUBBER_BAND: 2900000,\r\n\r\n\t// ==================== Application UI (3,000,000+) ====================\r\n\t/** プロパティパネル(サイドバー) */\r\n\tPROPERTY_PANEL: 3100000,\r\n\t/** ブロック追加パレット */\r\n\tPALETTE: 3200000,\r\n\t/** ツールチップ */\r\n\tTOOLTIP: 3300000,\r\n\t/** ドロップダウン */\r\n\tDROPDOWN: 3400000,\r\n\t/** コンテキストメニュー */\r\n\tCONTEXT_MENU: 3500000,\r\n\t/** モーダル */\r\n\tMODAL: 3600000,\r\n\r\n\t// ==================== Debug (10,000,000) ====================\r\n\t/** デバッグ表示 */\r\n\tDEBUG: 10000000,\r\n} as const;\r\n\r\nexport const BLOCK_SUB_INDEX = {\r\n\tBG: 10, // 本体側でのデフォルト背景\r\n\tCONTENT: 50, // コンテンツ本体\r\n\tGUIDE: 70, // ガイド線など\r\n\tBORDER: 80, // 枠線\r\n} as const;\r\n\r\n/**\r\n * Z_INDEX型(型安全性のため)\r\n */\r\nexport type ZIndexValue = (typeof Z_INDEX)[keyof typeof Z_INDEX];\r\n\r\nexport type BlockSubIndexValue =\r\n\t(typeof BLOCK_SUB_INDEX)[keyof typeof BLOCK_SUB_INDEX];\r\n","/**\r\n * @file ColorPickerPopover.tsx\r\n * @description カラーピッカーポップオーバーコンポーネント\r\n */\r\n\r\nimport { useEffect, useRef } from \"react\";\r\n\r\nimport { ColorPalette } from \"./ColorPalette\";\r\nimport styles from \"./ColorPicker.module.css\";\r\nimport { RGBAInputs } from \"./RGBAInputs\";\r\n\r\nimport { Z_INDEX } from \"@/utils/zIndex/constants\";\r\n\r\nimport type React from \"react\";\r\nimport type { RGBA } from \"@/utils/color\";\r\n\r\nexport interface ColorPickerPopoverProps {\r\n\tisOpen: boolean;\r\n\tonClose: () => void;\r\n\trgba: RGBA;\r\n\tonRgbaChange: (channel: keyof RGBA, value: number | undefined) => void;\r\n\tonColorSelect: (color: string | undefined) => void;\r\n\tselectedColor?: string;\r\n\treadOnly?: boolean;\r\n}\r\n\r\n/**\r\n * カラーピッカーポップオーバーコンポーネント\r\n */\r\nexport const ColorPickerPopover = ({\r\n\tisOpen,\r\n\tonClose,\r\n\trgba,\r\n\tonRgbaChange,\r\n\tonColorSelect,\r\n\tselectedColor,\r\n\treadOnly = false,\r\n}: ColorPickerPopoverProps): React.ReactElement | null => {\r\n\tconst popoverRef = useRef<HTMLDivElement>(null);\r\n\r\n\t// 外側クリックでクローズ\r\n\tuseEffect(() => {\r\n\t\tif (!isOpen) return;\r\n\r\n\t\tconst handleClickOutside = (e: MouseEvent) => {\r\n\t\t\tif (\r\n\t\t\t\tpopoverRef.current &&\r\n\t\t\t\t!popoverRef.current.contains(e.target as Node)\r\n\t\t\t) {\r\n\t\t\t\tonClose();\r\n\t\t\t}\r\n\t\t};\r\n\r\n\t\tdocument.addEventListener(\"mousedown\", handleClickOutside);\r\n\t\treturn () => {\r\n\t\t\tdocument.removeEventListener(\"mousedown\", handleClickOutside);\r\n\t\t};\r\n\t}, [isOpen, onClose]);\r\n\r\n\tif (!isOpen) return null;\r\n\r\n\treturn (\r\n\t\t<div\r\n\t\t\tclassName={styles.popover}\r\n\t\t\tref={popoverRef}\r\n\t\t\tstyle={{ zIndex: Z_INDEX.DROPDOWN }}\r\n\t\t>\r\n\t\t\t{/* カラーパレット */}\r\n\t\t\t<ColorPalette\r\n\t\t\t\tonColorSelect={onColorSelect}\r\n\t\t\t\tselectedColor={selectedColor}\r\n\t\t\t\treadOnly={readOnly}\r\n\t\t\t/>\r\n\r\n\t\t\t{/* RGBA入力 */}\r\n\t\t\t<RGBAInputs rgba={rgba} onChange={onRgbaChange} readOnly={readOnly} />\r\n\t\t</div>\r\n\t);\r\n};\r\n\r\nColorPickerPopover.displayName = \"ColorPickerPopover\";\r\n","/**\r\n * @file ColorPicker.tsx\r\n * @description カラーピッカーコンポーネント\r\n */\r\n\r\nimport { useCallback, useEffect, useRef, useState } from \"react\";\r\n\r\nimport styles from \"./ColorPicker.module.css\";\r\nimport { ColorPickerPopover } from \"./ColorPickerPopover\";\r\n\r\nimport { parseColor, toHex } from \"@/utils/color\";\r\n\r\nimport type React from \"react\";\r\nimport type { PropertyComponentProps } from \"@/plugin\";\r\nimport type { Value } from \"@/types/value\";\r\nimport type { RGBA } from \"@/utils/color\";\r\n\r\n/**\r\n * Config型定義\r\n * Record<string, Value> との互換性を持たせる\r\n */\r\nexport interface ColorPickerConfig {\r\n\tallowUndefined?: boolean;\r\n\twidth?: number;\r\n\theight?: number;\r\n\t[key: string]: Value;\r\n}\r\n\r\n/**\r\n * ColorPicker固有のProps\r\n * T は string | undefined\r\n */\r\nexport interface ColorPickerProps\r\n\textends PropertyComponentProps<string | undefined> {\r\n\t/** カラーテキスト入力を表示するか */\r\n\tshowTextInput?: boolean;\r\n\t/** undefined(未設定)を許容するか */\r\n\tallowUndefined?: boolean;\r\n\t/** プレースホルダーテキスト */\r\n\tplaceholder?: string;\r\n\t/** 幅(px) */\r\n\twidth?: number;\r\n\t/** 高さ(px) */\r\n\theight?: number;\r\n\t/** 設定オブジェクト */\r\n\tconfig?: ColorPickerConfig;\r\n}\r\n\r\n/**\r\n * カラーピッカーコンポーネント\r\n */\r\nexport const ColorPicker = ({\r\n\tvalue,\r\n\tonChange,\r\n\treadOnly = false,\r\n\tshowTextInput = true,\r\n\tallowUndefined: propAllowUndefined,\r\n\tplaceholder: propPlaceholder,\r\n\twidth: propWidth,\r\n\theight: propHeight,\r\n\tconfig,\r\n}: ColorPickerProps): React.ReactElement => {\r\n\t// 設定のマージ\r\n\tconst allowUndefined = propAllowUndefined ?? config?.allowUndefined ?? true;\r\n\tconst placeholder =\r\n\t\tpropPlaceholder ?? (allowUndefined ? \"未設定\" : \"#000000\");\r\n\tconst width = propWidth ?? config?.width;\r\n\tconst height = propHeight ?? config?.height;\r\n\r\n\t// ポップオーバーの開閉状態\r\n\tconst [isOpen, setIsOpen] = useState(false);\r\n\tconst containerRef = useRef<HTMLDivElement>(null);\r\n\r\n\t// RGBA値の状態(ポップオーバー内での編集用)\r\n\tconst [rgbaValues, setRgbaValues] = useState<RGBA>(() => {\r\n\t\tconst parsed = parseColor(value);\r\n\t\treturn parsed ?? { r: 0, g: 0, b: 0, a: 1 };\r\n\t});\r\n\r\n\t// valueが外部から変更された時にRGBA値を更新\r\n\tuseEffect(() => {\r\n\t\tconst parsed = parseColor(value);\r\n\t\tif (parsed) {\r\n\t\t\tsetRgbaValues(parsed);\r\n\t\t}\r\n\t}, [value]);\r\n\r\n\t// カラーボタンクリック\r\n\tconst handleColorButtonClick = useCallback(() => {\r\n\t\tif (!readOnly) {\r\n\t\t\tsetIsOpen((prev) => !prev);\r\n\t\t}\r\n\t}, [readOnly]);\r\n\r\n\t// テキスト入力変更(入力中の制限)\r\n\tconst [textInputValue, setTextInputValue] = useState(\r\n\t\tvalue ? value.replace(/^#/, \"\") : \"\",\r\n\t);\r\n\r\n\t// valueが外部から変更された時にテキスト入力も更新\r\n\tuseEffect(() => {\r\n\t\tsetTextInputValue(value ? value.replace(/^#/, \"\") : \"\");\r\n\t}, [value]);\r\n\r\n\tconst handleTextChange = useCallback(\r\n\t\t(e: React.ChangeEvent<HTMLInputElement>) => {\r\n\t\t\tconst text = e.target.value;\r\n\r\n\t\t\t// 16進数文字のみ許可(0-9, a-f, A-F)\r\n\t\t\tif (/^[0-9A-Fa-f]*$/.test(text)) {\r\n\t\t\t\tsetTextInputValue(text);\r\n\t\t\t}\r\n\t\t},\r\n\t\t[],\r\n\t);\r\n\r\n\t// テキスト入力確定処理(共通ロジック)\r\n\tconst confirmTextInput = useCallback(\r\n\t\t(text: string) => {\r\n\t\t\t// 空文字の場合、allowUndefinedなら undefined を返す\r\n\t\t\tif (text === \"\" && allowUndefined) {\r\n\t\t\t\tonChange(undefined);\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\t// #RRGGBB または #RRGGBBAA の検証(#は自動付与されるので除外)\r\n\t\t\tif (/^[0-9A-Fa-f]{6}([0-9A-Fa-f]{2})?$/.test(text)) {\r\n\t\t\t\tonChange(`#${text}`);\r\n\t\t\t} else {\r\n\t\t\t\t// 不正な入力の場合、元の値に戻す\r\n\t\t\t\tsetTextInputValue(value ? value.replace(/^#/, \"\") : \"\");\r\n\t\t\t}\r\n\t\t},\r\n\t\t[onChange, allowUndefined, value],\r\n\t);\r\n\r\n\t// テキスト入力確定(onBlur)\r\n\tconst handleTextBlur = useCallback(\r\n\t\t(e: React.FocusEvent<HTMLInputElement>) => {\r\n\t\t\tconfirmTextInput(e.target.value);\r\n\t\t},\r\n\t\t[confirmTextInput],\r\n\t);\r\n\r\n\t// Enterキーで確定\r\n\tconst handleTextKeyDown = useCallback(\r\n\t\t(e: React.KeyboardEvent<HTMLInputElement>) => {\r\n\t\t\tif (e.key === \"Enter\") {\r\n\t\t\t\te.preventDefault();\r\n\t\t\t\tconfirmTextInput(e.currentTarget.value);\r\n\t\t\t\te.currentTarget.blur(); // フォーカスを外す\r\n\t\t\t}\r\n\t\t},\r\n\t\t[confirmTextInput],\r\n\t);\r\n\r\n\t// カラーパレットクリック\r\n\tconst handlePaletteClick = useCallback(\r\n\t\t(colorValue: string | undefined) => {\r\n\t\t\tonChange(colorValue);\r\n\t\t\t// ポップアップは閉じない(外クリックで閉じる)\r\n\t\t},\r\n\t\t[onChange],\r\n\t);\r\n\r\n\t// RGBA値変更ハンドラー\r\n\tconst handleRgbaChange = useCallback(\r\n\t\t(channel: keyof RGBA, newValue: number | undefined) => {\r\n\t\t\tif (newValue === undefined) return;\r\n\r\n\t\t\tconst newRgba = { ...rgbaValues, [channel]: newValue };\r\n\t\t\tsetRgbaValues(newRgba);\r\n\t\t\tonChange(toHex(newRgba));\r\n\t\t},\r\n\t\t[rgbaValues, onChange],\r\n\t);\r\n\r\n\t// 現在の値を表示用に変換\r\n\tconst displayColor = value ?? \"未設定\";\r\n\r\n\t// カラーボタンのスタイル\r\n\tconst colorStyle: React.CSSProperties = {};\r\n\tif (value) {\r\n\t\t// backgroundプロパティ全体を上書き\r\n\t\tcolorStyle.background = value;\r\n\t}\r\n\r\n\t// インラインスタイル\r\n\tconst containerStyle: React.CSSProperties = {};\r\n\tif (width !== undefined) {\r\n\t\tcontainerStyle.width = `${width}px`;\r\n\t} else {\r\n\t\tcontainerStyle.width = \"100%\";\r\n\t}\r\n\tif (height !== undefined) containerStyle.height = `${height}px`;\r\n\r\n\treturn (\r\n\t\t<div className={styles.container} style={containerStyle} ref={containerRef}>\r\n\t\t\t{/* カラーボタン */}\r\n\t\t\t<button\r\n\t\t\t\ttype=\"button\"\r\n\t\t\t\tclassName={styles.colorButton}\r\n\t\t\t\tonClick={handleColorButtonClick}\r\n\t\t\t\tdisabled={readOnly}\r\n\t\t\t\ttitle={displayColor}\r\n\t\t\t\taria-label=\"カラーピッカーを開く\"\r\n\t\t\t\tstyle={colorStyle}\r\n\t\t\t/>\r\n\t\t\t{/* テキスト入力 */}\r\n\t\t\t{showTextInput && (\r\n\t\t\t\t<div className={styles.textInputWrapper}>\r\n\t\t\t\t\t<span className={styles.textInputPrefix}>#</span>\r\n\t\t\t\t\t<input\r\n\t\t\t\t\t\ttype=\"text\"\r\n\t\t\t\t\t\tclassName={styles.textInput}\r\n\t\t\t\t\t\tvalue={textInputValue}\r\n\t\t\t\t\t\tonChange={handleTextChange}\r\n\t\t\t\t\t\tonKeyDown={handleTextKeyDown}\r\n\t\t\t\t\t\tonBlur={handleTextBlur}\r\n\t\t\t\t\t\tdisabled={readOnly}\r\n\t\t\t\t\t\tplaceholder={placeholder}\r\n\t\t\t\t\t\tmaxLength={8} // RRGGBBAA = 8文字(#は固定)\r\n\t\t\t\t\t/>\r\n\t\t\t\t</div>\r\n\t\t\t)}\r\n\t\t\t{/* ポップオーバー */}\r\n\t\t\t<ColorPickerPopover\r\n\t\t\t\tisOpen={isOpen}\r\n\t\t\t\tonClose={() => setIsOpen(false)}\r\n\t\t\t\trgba={rgbaValues}\r\n\t\t\t\tonRgbaChange={handleRgbaChange}\r\n\t\t\t\tonColorSelect={handlePaletteClick}\r\n\t\t\t\tselectedColor={value}\r\n\t\t\t\treadOnly={readOnly}\r\n\t\t\t/>\r\n\t\t</div>\r\n\t);\r\n};\r\n\r\nColorPicker.displayName = \"ColorPicker\";\r\n","/**\r\n * @file DimensionInput.tsx\r\n * @description Dimension型(値+単位)の入力コンポーネント\r\n */\r\n\r\nimport { useCallback } from \"react\";\r\n\r\n// CSSモジュールのパスは環境に合わせてください\r\nimport styles from \"./DimensionInput.module.css\";\r\n\r\nimport type React from \"react\";\r\nimport type { PropertyComponentProps } from \"@/plugin\";\r\n// Value型が必要な場合はインポート\r\nimport type { Value } from \"@/types/index\";\r\nimport type { Dimension, Unit } from \"@/types/unit\";\r\n\r\nexport interface DimensionInputConfig<U extends Unit> {\r\n\tallowedUnits?: readonly U[];\r\n\tmin?: number;\r\n\tmax?: number;\r\n\tstep?: number;\r\n\tplaceholder?: string;\r\n\twidth?: number;\r\n\theight?: number;\r\n\t// 必要に応じてインデックスシグネチャを追加\r\n\t[key: string]: Value;\r\n}\r\n\r\n/**\r\n * DimensionInput固有のProps\r\n * ★重要: ジェネリクスに `| undefined` を追加して、未設定状態を受け入れられるようにする\r\n */\r\nexport interface DimensionInputProps<U extends Unit>\r\n\textends PropertyComponentProps<Dimension<U> | undefined> {\r\n\tallowedUnits?: readonly U[];\r\n\tmin?: number;\r\n\tmax?: number;\r\n\tstep?: number;\r\n\tplaceholder?: string;\r\n\t/** 幅(px) */\r\n\twidth?: number;\r\n\t/** 高さ(px) */\r\n\theight?: number;\r\n\r\n\tconfig?: DimensionInputConfig<U>;\r\n}\r\n\r\nexport const DimensionInput = <U extends Unit>(\r\n\tprops: DimensionInputProps<U>,\r\n): React.ReactElement => {\r\n\tconst { value, onChange, readOnly = false, config } = props;\r\n\r\n\t// 設定のマージ\r\n\tconst allowedUnits = props.allowedUnits ?? config?.allowedUnits;\r\n\tconst min = props.min ?? config?.min;\r\n\tconst max = props.max ?? config?.max;\r\n\tconst step = props.step ?? config?.step ?? 1;\r\n\tconst placeholder = props.placeholder ?? config?.placeholder;\r\n\tconst width = props.width ?? config?.width;\r\n\tconst height = props.height ?? config?.height;\r\n\r\n\t// デフォルト単位の決定(現在の値の単位 -> 許可リストの先頭 -> undefined)\r\n\tconst currentUnit = value?.unit ?? allowedUnits?.[0];\r\n\r\n\t// --- ハンドラ ---\r\n\r\n\tconst handleValueChange = useCallback(\r\n\t\t(e: React.ChangeEvent<HTMLInputElement>) => {\r\n\t\t\tconst inputValue = e.target.value;\r\n\r\n\t\t\tlet newValue = Number.parseFloat(inputValue);\r\n\t\t\tif (Number.isNaN(newValue)) return;\r\n\r\n\t\t\t// minが指定されていない場合はデフォルトで1以上に制限\r\n\t\t\tconst effectiveMin = min ?? 1;\r\n\t\t\tif (newValue < effectiveMin) {\r\n\t\t\t\tnewValue = effectiveMin;\r\n\t\t\t}\r\n\t\t\tif (max !== undefined && newValue > max) {\r\n\t\t\t\tnewValue = max;\r\n\t\t\t}\r\n\r\n\t\t\tonChange({\r\n\t\t\t\tvalue: newValue,\r\n\t\t\t\t// 単位が未定ならデフォルト単位(または最初の許可単位)を強制\r\n\t\t\t\tunit: (value?.unit ?? currentUnit) as U,\r\n\t\t\t});\r\n\t\t},\r\n\t\t[value, onChange, currentUnit, min, max],\r\n\t);\r\n\r\n\t// フォーカスを失った時のバリデーション\r\n\tconst handleBlur = useCallback(\r\n\t\t(e: React.FocusEvent<HTMLInputElement>) => {\r\n\t\t\tconst inputValue = e.target.value;\r\n\r\n\t\t\tif (inputValue === \"\") return;\r\n\r\n\t\t\tlet newValue = Number.parseFloat(inputValue);\r\n\t\t\tif (Number.isNaN(newValue)) return;\r\n\r\n\t\t\t// minが指定されていない場合はデフォルトで1以上に制限\r\n\t\t\tconst effectiveMin = min ?? 1;\r\n\t\t\tif (newValue < effectiveMin) {\r\n\t\t\t\tnewValue = effectiveMin;\r\n\t\t\t\t// 最小値未満の場合は強制的に補正\r\n\t\t\t\tonChange({\r\n\t\t\t\t\tvalue: newValue,\r\n\t\t\t\t\tunit: (value?.unit ?? currentUnit) as U,\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t\tif (max !== undefined && newValue > max) {\r\n\t\t\t\tnewValue = max;\r\n\t\t\t\t// 最大値超過の場合は強制的に補正\r\n\t\t\t\tonChange({\r\n\t\t\t\t\tvalue: newValue,\r\n\t\t\t\t\tunit: (value?.unit ?? currentUnit) as U,\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t},\r\n\t\t[value, onChange, currentUnit, min, max],\r\n\t);\r\n\r\n\tconst handleUnitChange = useCallback(\r\n\t\t(e: React.ChangeEvent<HTMLSelectElement>) => {\r\n\t\t\tconst newUnit = e.target.value as U;\r\n\t\t\tonChange({\r\n\t\t\t\t// 値が未設定ならデフォルト値(例: 1)を入れてオブジェクトを作成\r\n\t\t\t\tvalue: value?.value ?? 1,\r\n\t\t\t\tunit: newUnit,\r\n\t\t\t});\r\n\t\t},\r\n\t\t[value, onChange],\r\n\t);\r\n\r\n\t// --- 表示用データ ---\r\n\r\n\t// valueがundefinedなら空文字を表示\r\n\tconst displayValue = value?.value ?? \"\";\r\n\r\n\t// 単位もundefinedなら空文字(ただしSelectの選択肢に空文字がないと警告が出るため注意)\r\n\tconst displayUnit = value?.unit ?? currentUnit ?? \"\";\r\n\r\n\t// インラインスタイル\r\n\tconst containerStyle: React.CSSProperties = {};\r\n\tif (width !== undefined) {\r\n\t\tcontainerStyle.width = `${width}px`;\r\n\t} else {\r\n\t\tcontainerStyle.width = \"100%\"; // デフォルトは親要素の幅\r\n\t}\r\n\tif (height !== undefined) containerStyle.height = `${height}px`;\r\n\r\n\treturn (\r\n\t\t<div className={styles.container} style={containerStyle}>\r\n\t\t\t<input\r\n\t\t\t\ttype=\"number\"\r\n\t\t\t\tclassName={styles.valueInput}\r\n\t\t\t\tvalue={displayValue}\r\n\t\t\t\tonChange={handleValueChange}\r\n\t\t\t\tonBlur={handleBlur}\r\n\t\t\t\tplaceholder={placeholder}\r\n\t\t\t\tmin={min ?? 1}\r\n\t\t\t\tmax={max}\r\n\t\t\t\tstep={step}\r\n\t\t\t\treadOnly={readOnly}\r\n\t\t\t\tdisabled={readOnly}\r\n\t\t\t/>\r\n\t\t\t<select\r\n\t\t\t\tclassName={styles.unitSelect}\r\n\t\t\t\tvalue={displayUnit}\r\n\t\t\t\tonChange={handleUnitChange}\r\n\t\t\t\tdisabled={readOnly || !allowedUnits || allowedUnits.length <= 1}\r\n\t\t\t>\r\n\t\t\t\t{allowedUnits ? (\r\n\t\t\t\t\tallowedUnits.map((u) => (\r\n\t\t\t\t\t\t<option key={u} value={u}>\r\n\t\t\t\t\t\t\t{u}\r\n\t\t\t\t\t\t</option>\r\n\t\t\t\t\t))\r\n\t\t\t\t) : (\r\n\t\t\t\t\t// 単位リストがない場合は現在の値を表示\r\n\t\t\t\t\t<option value={displayUnit as string}>{displayUnit}</option>\r\n\t\t\t\t)}\r\n\t\t\t</select>\r\n\t\t</div>\r\n\t);\r\n};\r\n","/**\r\n * @file TabPanel.tsx\r\n * @description タブパネル共通コンポーネント\r\n */\r\n\r\nimport styles from \"./TabPanel.module.css\";\r\n\r\nimport type { ReactNode } from \"react\";\r\n\r\nexport interface TabPanelProps {\r\n\t/** パネルの内容 */\r\n\tchildren: ReactNode;\r\n\t/** 空状態のメッセージ(childrenがない場合に表示) */\r\n\temptyMessage?: string;\r\n\t/** カスタムクラス名 */\r\n\tclassName?: string;\r\n}\r\n\r\n/**\r\n * TabPanel\r\n * タブコンテンツの共通ラッパー\r\n */\r\nexport const TabPanel = ({\r\n\tchildren,\r\n\temptyMessage,\r\n\tclassName,\r\n}: TabPanelProps) => {\r\n\treturn (\r\n\t\t<div className={`${styles.container} ${className || \"\"}`}>\r\n\t\t\t{children ? (\r\n\t\t\t\t<div className={styles.scrollArea}>{children}</div>\r\n\t\t\t) : (\r\n\t\t\t\temptyMessage && <div className={styles.emptyState}>{emptyMessage}</div>\r\n\t\t\t)}\r\n\t\t</div>\r\n\t);\r\n};\r\n","import { createContext, useContext, useState } from \"react\";\r\n\r\nimport styles from \"./Tabs.module.css\";\r\n\r\nimport type React from \"react\";\r\n\r\n// --- Context ---\r\ninterface TabsContextType {\r\n\tvalue: string;\r\n\tonChange: (value: string) => void;\r\n\tvariant: \"default\" | \"segmented\";\r\n}\r\n\r\nconst TabsContext = createContext<TabsContextType | undefined>(undefined);\r\n\r\n// --- Components ---\r\n\r\nexport interface TabsProps {\r\n\tdefaultValue: string;\r\n\tvalue?: string; // 制御コンポーネントとして使う場合\r\n\tonValueChange?: (value: string) => void;\r\n\tchildren: React.ReactNode;\r\n\tvariant?: \"default\" | \"segmented\";\r\n\tclassName?: string;\r\n}\r\n\r\nexport const Tabs: React.FC<TabsProps> = ({\r\n\tdefaultValue,\r\n\tvalue: propValue,\r\n\tonValueChange,\r\n\tchildren,\r\n\tvariant = \"default\",\r\n\tclassName = \"\",\r\n}) => {\r\n\tconst [localValue, setLocalValue] = useState(defaultValue);\r\n\tconst value = propValue ?? localValue;\r\n\r\n\tconst handleChange = (newValue: string) => {\r\n\t\tsetLocalValue(newValue);\r\n\t\tonValueChange?.(newValue);\r\n\t};\r\n\r\n\treturn (\r\n\t\t<TabsContext.Provider value={{ value, onChange: handleChange, variant }}>\r\n\t\t\t<div className={`${styles.root} ${className}`} data-variant={variant}>\r\n\t\t\t\t{children}\r\n\t\t\t</div>\r\n\t\t</TabsContext.Provider>\r\n\t);\r\n};\r\n\r\nexport interface TabsListProps {\r\n\tchildren: React.ReactNode;\r\n\tclassName?: string;\r\n\twidth?: number;\r\n\theight?: number;\r\n\tstyle?: React.CSSProperties;\r\n}\r\n\r\nexport const TabsList: React.FC<TabsListProps> = ({\r\n\tchildren,\r\n\tclassName = \"\",\r\n\twidth,\r\n\theight,\r\n\tstyle: propStyle,\r\n}) => {\r\n\tconst context = useContext(TabsContext);\r\n\tif (!context) {\r\n\t\tthrow new Error(\"TabsList must be used within a Tabs component\");\r\n\t}\r\n\tconst { variant } = context;\r\n\r\n\t// プロパティで渡されたstyleとwidth/heightをマージ\r\n\tconst computedStyle: React.CSSProperties = { ...propStyle };\r\n\tif (width !== undefined) computedStyle.width = `${width}px`;\r\n\tif (height !== undefined) computedStyle.height = `${height}px`;\r\n\r\n\treturn (\r\n\t\t<div\r\n\t\t\tclassName={`${styles.list} ${className}`}\r\n\t\t\tdata-variant={variant}\r\n\t\t\tstyle={computedStyle}\r\n\t\t>\r\n\t\t\t{children}\r\n\t\t</div>\r\n\t);\r\n};\r\n\r\nexport interface TabsTriggerProps {\r\n\tvalue: string;\r\n\tchildren: React.ReactNode;\r\n\tclassName?: string;\r\n\tdisabled?: boolean;\r\n\twidth?: number;\r\n\theight?: number;\r\n\tstyle?: React.CSSProperties;\r\n}\r\n\r\nexport const TabsTrigger: React.FC<TabsTriggerProps> = ({\r\n\tvalue,\r\n\tchildren,\r\n\tclassName = \"\",\r\n\tdisabled = false,\r\n\twidth,\r\n\theight,\r\n\tstyle: propStyle,\r\n}) => {\r\n\tconst context = useContext(TabsContext);\r\n\tif (!context) {\r\n\t\tthrow new Error(\"TabsTrigger must be used within a Tabs component\");\r\n\t}\r\n\tconst { value: selectedValue, onChange, variant } = context;\r\n\tconst isSelected = selectedValue === value;\r\n\r\n\tconst computedStyle: React.CSSProperties = { ...propStyle };\r\n\tif (width !== undefined) computedStyle.width = `${width}px`;\r\n\tif (height !== undefined) computedStyle.height = `${height}px`;\r\n\r\n\treturn (\r\n\t\t<button\r\n\t\t\tclassName={`${styles.trigger} ${className}`}\r\n\t\t\tdata-state={isSelected ? \"active\" : \"inactive\"}\r\n\t\t\tdata-variant={variant}\r\n\t\t\tonClick={() => onChange(value)}\r\n\t\t\tdisabled={disabled}\r\n\t\t\ttype=\"button\"\r\n\t\t\tstyle={computedStyle}\r\n\t\t>\r\n\t\t\t{children}\r\n\t\t</button>\r\n\t);\r\n};\r\n\r\nexport interface TabsContentProps {\r\n\tvalue: string;\r\n\tchildren: React.ReactNode;\r\n\tclassName?: string;\r\n}\r\n\r\nexport const TabsContent: React.FC<TabsContentProps> = ({\r\n\tvalue,\r\n\tchildren,\r\n\tclassName = \"\",\r\n}) => {\r\n\tconst context = useContext(TabsContext);\r\n\tif (!context) {\r\n\t\tthrow new Error(\"TabsContent must be used within a Tabs component\");\r\n\t}\r\n\tconst { value: selectedValue } = context;\r\n\r\n\tif (selectedValue !== value) return null;\r\n\r\n\treturn <div className={`${styles.content} ${className}`}>{children}</div>;\r\n};\r\n","/**\r\n * @file TextInput.tsx\r\n * @description テキスト入力コンポーネント\r\n */\r\n\r\nimport { useCallback } from \"react\";\r\n\r\nimport styles from \"./TextInput.module.css\";\r\n\r\nimport type React from \"react\";\r\nimport type { PropertyComponentProps } from \"@/plugin\";\r\nimport type { Value } from \"@/types/value\";\r\n\r\n/**\r\n * Config型定義\r\n * Record<string, Value> との互換性を持たせる\r\n */\r\nexport interface TextInputConfig {\r\n\tplaceholder?: string;\r\n\tmaxLength?: number;\r\n\tmultiline?: boolean;\r\n\trows?: number;\r\n\twidth?: number;\r\n\theight?: number;\r\n\t[key: string]: Value;\r\n}\r\n\r\n/**\r\n * TextInput固有のProps\r\n * T は string | undefined\r\n */\r\nexport interface TextInputProps\r\n\textends PropertyComponentProps<string | undefined> {\r\n\tplaceholder?: string;\r\n\tmaxLength?: number;\r\n\tmultiline?: boolean;\r\n\trows?: number;\r\n\twidth?: number;\r\n\theight?: number;\r\n\tconfig?: TextInputConfig;\r\n\tonBlur?: () => void;\r\n}\r\n\r\n/**\r\n * テキスト入力コンポーネント\r\n */\r\nexport const TextInput = ({\r\n\tvalue,\r\n\tonChange,\r\n\treadOnly = false, // readonly -> readOnly に統一\r\n\tplaceholder: propPlaceholder,\r\n\tmaxLength: propMaxLength,\r\n\tmultiline: propMultiline,\r\n\trows: propRows,\r\n\twidth,\r\n\theight,\r\n\tconfig,\r\n\tonBlur,\r\n}: TextInputProps): React.ReactElement => {\r\n\t// 設定のマージ\r\n\tconst placeholder = propPlaceholder ?? config?.placeholder;\r\n\tconst maxLength = propMaxLength ?? config?.maxLength;\r\n\tconst multiline = propMultiline ?? config?.multiline ?? false;\r\n\tconst rows = propRows ?? config?.rows ?? 3;\r\n\r\n\tconst handleChange = useCallback(\r\n\t\t(e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {\r\n\t\t\tconst newValue = e.target.value;\r\n\t\t\t// 空文字の場合は undefined (未設定) として扱うか、そのまま空文字とするかは要件次第だが、\r\n\t\t\t// ここでは空文字として渡す(テキストは空文字が有効な値であることが多いため)\r\n\t\t\t// 必要であればここを undefined に変えてください\r\n\t\t\tonChange(newValue);\r\n\t\t},\r\n\t\t[onChange],\r\n\t);\r\n\r\n\t// インラインスタイルの構築\r\n\tconst style: React.CSSProperties = {};\r\n\tif (width !== undefined) {\r\n\t\tstyle.width = `${width}px`;\r\n\t} else {\r\n\t\tstyle.width = \"100%\";\r\n\t}\r\n\tif (height !== undefined) {\r\n\t\tstyle.height = `${height}px`;\r\n\t}\r\n\r\n\tconst commonProps = {\r\n\t\tclassName: styles.input,\r\n\t\tstyle,\r\n\t\tvalue: value ?? \"\", // undefined なら空文字を表示\r\n\t\tonChange: handleChange,\r\n\t\tdisabled: readOnly,\r\n\t\tplaceholder,\r\n\t\tmaxLength,\r\n\t};\r\n\r\n\tif (multiline) {\r\n\t\treturn <textarea {...commonProps} rows={rows} />;\r\n\t}\r\n\r\n\treturn <input {...commonProps} type=\"text\" onBlur={onBlur} />;\r\n};\r\n\r\nTextInput.displayName = \"TextInput\";\r\n","export const ALL_UNITS = [\"mm\", \"cm\", \"fr\", \"inch\", \"pt\", \"px\", \"%\"] as const;\r\nexport const ACTUAL_UNITS = [\"mm\", \"cm\", \"pt\", \"inch\", \"px\"] as const;\r\nexport const PAPER_UNITS = [\"mm\", \"cm\", \"inch\"] as const;\r\nexport const GRID_UNITS = [\"mm\", \"cm\", \"fr\", \"inch\", \"pt\", \"px\"] as const;\r\nexport const BORDER_UNITS = [\"px\", \"pt\", \"mm\"] as const;\r\nexport const FONT_UNITS = [\"px\", \"pt\", \"mm\"] as const;\r\nexport const PADDING_UNITS = [\"mm\", \"pt\", \"px\", \"%\"] as const;\r\nexport const SIZE_UNITS = [\"mm\", \"cm\", \"inch\", \"pt\", \"px\", \"%\"] as const;\r\n\r\nexport type Unit = (typeof ALL_UNITS)[number];\r\nexport type ActualUnit = (typeof ACTUAL_UNITS)[number];\r\nexport type PaperUnit = (typeof PAPER_UNITS)[number];\r\nexport type GridUnit = (typeof GRID_UNITS)[number];\r\nexport type BorderUnit = (typeof BORDER_UNITS)[number];\r\nexport type FontUnit = (typeof FONT_UNITS)[number];\r\nexport type PaddingUnit = (typeof PADDING_UNITS)[number];\r\nexport type SizeUnit = (typeof SIZE_UNITS)[number];\r\n\r\nexport interface Dimension<U extends Unit = Unit> {\r\n\tvalue: number; // 値\r\n\tunit: U; // 単位\r\n}\r\n","// 必要なコンポーネントと定数をインポート\r\nimport { Checkbox, DimensionInput } from \"@/properties/components\";\r\nimport { PADDING_UNITS } from \"@/types/unit\";\r\n\r\nimport type { PluginProperties } from \"../definition\";\r\nimport type { PaddingSchema } from \"./schemas\";\r\n\r\n/**\r\n * PaddingSchema の実体定義\r\n */\r\nexport const paddingDefinition: PluginProperties<PaddingSchema> = {\r\n\t// 1. 切り替えスイッチ\r\n\tisIndividual: {\r\n\t\tdefaultValue: false,\r\n\t\tlabel: \"個別に設定\",\r\n\t\tgroup: \"余白\",\r\n\t\tComponent: Checkbox,\r\n\t\tdescription: \"上下左右の余白を個別に設定します\",\r\n\t},\r\n\r\n\t// 2. 一括設定 (isIndividual が false のとき表示)\r\n\tall: {\r\n\t\tdefaultValue: { value: 10, unit: \"px\" },\r\n\t\tlabel: \"全方向\",\r\n\t\tgroup: \"余白\",\r\n\t\tComponent: DimensionInput,\r\n\t\tconfig: {\r\n\t\t\tallowedUnits: PADDING_UNITS,\r\n\t\t\tmin: 0,\r\n\t\t},\r\n\t\t// ★ condition: 個別設定OFFのときだけ表示\r\n\t\tcondition: (data) => !data.isIndividual,\r\n\t},\r\n\r\n\t// 3. 個別設定 (isIndividual が true のとき表示)\r\n\ttop: {\r\n\t\tdefaultValue: { value: 10, unit: \"px\" },\r\n\t\tlabel: \"上\",\r\n\t\tgroup: \"余白\",\r\n\t\tComponent: DimensionInput,\r\n\t\tconfig: {\r\n\t\t\tallowedUnits: PADDING_UNITS,\r\n\t\t\tmin: 0,\r\n\t\t},\r\n\t\t// ★ condition: 個別設定ONのときだけ表示\r\n\t\tcondition: (data) => data.isIndividual === true,\r\n\t},\r\n\r\n\tright: {\r\n\t\tdefaultValue: { value: 10, unit: \"px\" },\r\n\t\tlabel: \"右\",\r\n\t\tgroup: \"余白\",\r\n\t\tComponent: DimensionInput,\r\n\t\tconfig: {\r\n\t\t\tallowedUnits: PADDING_UNITS,\r\n\t\t\tmin: 0,\r\n\t\t},\r\n\t\tcondition: (data) => data.isIndividual === true,\r\n\t},\r\n\r\n\tbottom: {\r\n\t\tdefaultValue: { value: 10, unit: \"px\" },\r\n\t\tlabel: \"下\",\r\n\t\tgroup: \"余白\",\r\n\t\tComponent: DimensionInput,\r\n\t\tconfig: {\r\n\t\t\tallowedUnits: PADDING_UNITS,\r\n\t\t\tmin: 0,\r\n\t\t},\r\n\t\tcondition: (data) => data.isIndividual === true,\r\n\t},\r\n\r\n\tleft: {\r\n\t\tdefaultValue: { value: 10, unit: \"px\" },\r\n\t\tlabel: \"左\",\r\n\t\tgroup: \"余白\",\r\n\t\tComponent: DimensionInput,\r\n\t\tconfig: {\r\n\t\t\tallowedUnits: PADDING_UNITS,\r\n\t\t\tmin: 0,\r\n\t\t},\r\n\t\tcondition: (data) => data.isIndividual === true,\r\n\t},\r\n};\r\n","import { alignmentDefinition } from \"../Alignment\";\r\nimport { paddingDefinition } from \"../Padding\";\r\n\r\n/**\r\n * ほぼすべてのブロックで使用される共通プロパティ定義\r\n *\r\n * ## 使用方法\r\n * ```typescript\r\n * export const MyPlugin: BlockPlugin = {\r\n * properties: {\r\n * ...universalProperties, // フラットに展開\r\n * // プラグイン固有のプロパティ\r\n * customProp: { ... },\r\n * },\r\n * };\r\n * ```\r\n *\r\n * ## 上書き\r\n * 個別のプロパティを上書きする場合は、後から定義します:\r\n * ```typescript\r\n * properties: {\r\n * ...universalProperties,\r\n * justifyContent: {\r\n * ...universalProperties.justifyContent,\r\n * defaultValue: HorizontalAlign.center, // デフォルト値を変更\r\n * },\r\n * }\r\n * ```\r\n *\r\n * ## 含まれるプロパティ\r\n * - **alignment** (justifyContent, alignItems): コンテンツの配置\r\n * - **padding** (isIndividual, all, top, right, bottom, left): 余白\r\n */\r\nexport const universalProperties = {\r\n\t...alignmentDefinition,\r\n\t...paddingDefinition,\r\n} as const;\r\n","import {\r\n\tCheckbox,\r\n\tColorPicker,\r\n\tDimensionInput,\r\n\tNumberInput,\r\n\tSelect,\r\n\ttype SelectOption,\r\n} from \"@/properties/components\";\r\nimport { FONT_UNITS } from \"@/types/unit\";\r\n\r\nimport type { PluginProperties } from \"../definition\";\r\nimport type { FontStyleSchema } from \"./schemas\";\r\n\r\nexport const DEFAULT_FONT_FAMILY: readonly SelectOption[] = [\r\n\t{ label: \"ゴシック体\", value: \"sans-serif\" },\r\n\t{ label: \"明朝体\", value: \"serif\" },\r\n\t{ label: \"等幅\", value: \"monospace\" },\r\n\t{ label: \"Arial\", value: \"Arial, sans-serif\" },\r\n\t{ label: \"Times New Roman\", value: \"'Times New Roman', serif\" },\r\n];\r\n\r\n/**\r\n * FontStyleSchema の実体定義\r\n */\r\nexport const fontStyleDefinition: PluginProperties<FontStyleSchema> = {\r\n\tfontSize: {\r\n\t\tdefaultValue: { value: 14, unit: \"pt\" },\r\n\t\tlabel: \"フォントサイズ\",\r\n\t\tgroup: \"フォント\",\r\n\t\tdescription: \"テキストのフォントサイズを設定します\",\r\n\t\tComponent: DimensionInput,\r\n\t\tconfig: {\r\n\t\t\tallowedUnits: FONT_UNITS,\r\n\t\t\tmin: 1,\r\n\t\t\tstep: 1,\r\n\t\t},\r\n\t},\r\n\r\n\tfontFamily: {\r\n\t\tdefaultValue: \"sans-serif\",\r\n\t\tlabel: \"フォント\",\r\n\t\tgroup: \"フォント\",\r\n\t\tComponent: Select,\r\n\t\tconfig: {\r\n\t\t\tplaceholder: \"フォントを選択\",\r\n\t\t\toptions: DEFAULT_FONT_FAMILY,\r\n\t\t},\r\n\t},\r\n\r\n\tcolor: {\r\n\t\tdefaultValue: undefined, // CSS変数を使用するため未設定\r\n\t\tlabel: \"文字色\",\r\n\t\tgroup: \"フォント\",\r\n\t\tComponent: ColorPicker,\r\n\t\tconfig: {\r\n\t\t\tallowUndefined: true, // 明示的に許可(デフォルトtrueなので省略可)\r\n\t\t},\r\n\t},\r\n\r\n\tfontWeight: {\r\n\t\tdefaultValue: false,\r\n\t\tlabel: \"太字\",\r\n\t\tgroup: \"フォント\",\r\n\t\tdescription: \"テキストを太字にします\",\r\n\t\tComponent: Checkbox,\r\n\t},\r\n\r\n\titalic: {\r\n\t\tdefaultValue: false,\r\n\t\tlabel: \"斜体\",\r\n\t\tgroup: \"フォント\",\r\n\t\tdescription: \"テキストを斜体にします\",\r\n\t\tComponent: Checkbox,\r\n\t},\r\n\r\n\tunderline: {\r\n\t\tdefaultValue: false,\r\n\t\tlabel: \"下線\",\r\n\t\tgroup: \"フォント\",\r\n\t\tdescription: \"テキストに下線を引きます\",\r\n\t\tComponent: Checkbox,\r\n\t},\r\n\r\n\tlineThrough: {\r\n\t\tdefaultValue: false,\r\n\t\tlabel: \"取り消し線\",\r\n\t\tgroup: \"フォント\",\r\n\t\tdescription: \"テキストに取り消し線を引きます\",\r\n\t\tComponent: Checkbox,\r\n\t},\r\n\r\n\tlineHeight: {\r\n\t\tdefaultValue: 1.2,\r\n\t\tlabel: \"行の高さ\",\r\n\t\tgroup: \"フォント\",\r\n\t\tdescription: \"行の高さを設定します(1.0〜3.0)\",\r\n\t\tComponent: NumberInput,\r\n\t\tconfig: {\r\n\t\t\tmin: 1,\r\n\t\t\tmax: 3,\r\n\t\t\tstep: 0.1,\r\n\t\t},\r\n\t},\r\n};\r\n","import type { Value } from \"@/types/value\";\r\nimport type { BlockPlugin } from \"../types\";\r\n\r\nexport type AnyBlockPlugin = BlockPlugin<Record<string, Value>, Value>;\r\n\r\n/**\r\n * プラグイン配列からプラグインレジストリを作成\r\n *\r\n * @remarks\r\n * - プラグインの kind をキーとしたオブジェクトを生成します\r\n * - 型推論により、配列内の具体的なプラグイン型が保持されます\r\n *\r\n * @template T - BlockPlugin の配列型\r\n * @param plugins プラグインの配列 (as const推奨)\r\n * @returns kind をキーとしたプラグインレジストリ\r\n *\r\n * @example\r\n * ```typescript\r\n * const registry = createPluginRegistry([\r\n * TextPlugin,\r\n * SelectPlugin,\r\n * CheckboxPlugin,\r\n * ] as const);\r\n * // registry.text, registry.select, registry.checkbox が型推論される\r\n * ```\r\n */\r\nexport function createPluginRegistry<T extends readonly BlockPlugin[]>(\r\n\tplugins: T,\r\n): Record<string, T[number]> {\r\n\treturn plugins.reduce(\r\n\t\t(acc, plugin) => {\r\n\t\t\tacc[plugin.kind] = plugin;\r\n\t\t\treturn acc;\r\n\t\t},\r\n\t\t{} as Record<string, T[number]>,\r\n\t);\r\n}\r\n","/**\r\n * 画像プロパティのスキーマ(フラット)\r\n */\r\n\r\nexport enum ImageObjectFit {\r\n\tContain = \"contain\",\r\n\tCover = \"cover\",\r\n\tFill = \"fill\",\r\n\tNone = \"none\",\r\n\tScaleDown = \"scale-down\",\r\n}\r\n\r\nexport interface ImageSchema {\r\n\tobjectFit?: ImageObjectFit;\r\n\talt?: string;\r\n}\r\n","// UIコンポーネントをインポート\r\n\r\nimport { ImageObjectFit, type ImageSchema } from \"./schemas\";\r\n\r\nimport { Select } from \"@/properties/components/Select\";\r\nimport { TextInput } from \"@/properties/components/TextInput\";\r\n\r\n// ★ 型安全な定義型をインポート\r\nimport type { PluginProperties } from \"@/plugin\";\r\n\r\n/**\r\n * ImageSchema の実体定義\r\n */\r\nexport const imageDefinition: PluginProperties<ImageSchema> = {\r\n\tobjectFit: {\r\n\t\tdefaultValue: ImageObjectFit.Contain,\r\n\t\tlabel: \"表示方法\",\r\n\t\tgroup: \"画像\",\r\n\t\tdescription: \"画像のサイズが枠と合わない場合の表示方法を設定します\",\r\n\t\tComponent: Select,\r\n\t\tconfig: {\r\n\t\t\toptions: [\r\n\t\t\t\t{\r\n\t\t\t\t\tlabel: \"全体を表示\",\r\n\t\t\t\t\tvalue: ImageObjectFit.Contain,\r\n\t\t\t\t},\r\n\t\t\t\t{\r\n\t\t\t\t\tlabel: \"枠を埋める/切り抜き\",\r\n\t\t\t\t\tvalue: ImageObjectFit.Cover,\r\n\t\t\t\t},\r\n\t\t\t\t{\r\n\t\t\t\t\tlabel: \"引き伸ばす/縮小する\",\r\n\t\t\t\t\tvalue: ImageObjectFit.Fill,\r\n\t\t\t\t},\r\n\t\t\t\t{\r\n\t\t\t\t\tlabel: \"元のサイズ\",\r\n\t\t\t\t\tvalue: ImageObjectFit.None,\r\n\t\t\t\t},\r\n\t\t\t\t{\r\n\t\t\t\t\tlabel: \"縮小のみ\",\r\n\t\t\t\t\tvalue: ImageObjectFit.ScaleDown,\r\n\t\t\t\t},\r\n\t\t\t],\r\n\t\t},\r\n\t},\r\n\r\n\talt: {\r\n\t\tdefaultValue: \"\",\r\n\t\tlabel: \"代替テキスト\",\r\n\t\tgroup: \"画像\",\r\n\t\tdescription: \"画像が表示できない場合に表示されるテキスト\",\r\n\t\tComponent: TextInput,\r\n\t\tconfig: {\r\n\t\t\tplaceholder: \"画像の説明\",\r\n\t\t},\r\n\t},\r\n};\r\n","// 複数行プロパティ\r\nexport enum MultilineWordWrap {\r\n\tNormal = \"normal\",\r\n\tBreakWord = \"break-word\",\r\n\tBreakAll = \"break-all\",\r\n}\r\n\r\nexport enum MultilineWhiteSpace {\r\n\tNormal = \"normal\",\r\n\tNoWrap = \"nowrap\",\r\n\tPre = \"pre\",\r\n\tPreWrap = \"pre-wrap\",\r\n\tPreLine = \"pre-line\",\r\n}\r\n\r\nexport interface MultilineSchema {\r\n\tmultiline?: boolean;\r\n\twordWrap?: MultilineWordWrap;\r\n\twhiteSpace?: MultilineWhiteSpace;\r\n}\r\n","import {\r\n\ttype MultilineSchema,\r\n\tMultilineWhiteSpace,\r\n\tMultilineWordWrap,\r\n} from \"./schemas\";\r\n\r\nimport { Checkbox, Select } from \"@/properties/components\";\r\n\r\nimport type { PluginProperties } from \"../definition\";\r\n\r\nexport const multilineDefinition: PluginProperties<MultilineSchema> = {\r\n\tmultiline: {\r\n\t\tdefaultValue: false,\r\n\t\tlabel: \"複数行モード\",\r\n\t\tgroup: \"設定\",\r\n\t\tComponent: Checkbox,\r\n\t\tconfig: { label: \"有効にする\" },\r\n\t},\r\n\r\n\twordWrap: {\r\n\t\tdefaultValue: MultilineWordWrap.Normal,\r\n\t\tlabel: \"単語の折り返し\",\r\n\t\tgroup: \"設定\",\r\n\t\tComponent: Select,\r\n\t\tconfig: {\r\n\t\t\toptions: [\r\n\t\t\t\t{ label: \"通常\", value: MultilineWordWrap.Normal },\r\n\t\t\t\t{ label: \"単語で改行\", value: MultilineWordWrap.BreakWord },\r\n\t\t\t\t{ label: \"強制改行\", value: MultilineWordWrap.BreakAll },\r\n\t\t\t],\r\n\t\t},\r\n\t\tcondition: (data) => data.multiline === true,\r\n\t},\r\n\r\n\twhiteSpace: {\r\n\t\tdefaultValue: MultilineWhiteSpace.Normal,\r\n\t\tlabel: \"空白文字の扱い\",\r\n\t\tgroup: \"設定\",\r\n\t\tComponent: Select,\r\n\t\tconfig: {\r\n\t\t\toptions: [\r\n\t\t\t\t{ label: \"通常\", value: MultilineWhiteSpace.Normal },\r\n\t\t\t\t{ label: \"折り返しなし\", value: MultilineWhiteSpace.NoWrap },\r\n\t\t\t\t{ label: \"そのまま表示\", value: MultilineWhiteSpace.Pre },\r\n\t\t\t],\r\n\t\t},\r\n\t\tcondition: (data) => data.multiline === true,\r\n\t},\r\n};\r\n","// 型定義とコンポーネントをインポート\r\n\r\nimport { TextInput } from \"@/properties/components/TextInput\";\r\n\r\nimport type { PluginProperties } from \"../definition\";\r\nimport type { PlaceholderSchema } from \"./schemas\";\r\n\r\n/**\r\n * PlaceholderSchema の実体定義\r\n */\r\nexport const placeholderDefinition: PluginProperties<PlaceholderSchema> = {\r\n\tplaceholder: {\r\n\t\tdefaultValue: undefined,\r\n\t\tlabel: \"プレースホルダー\",\r\n\t\tgroup: \"設定\",\r\n\t\tdescription: \"入力欄に表示するプレースホルダーテキストを設定します\",\r\n\r\n\t\tComponent: TextInput,\r\n\r\n\t\tconfig: {\r\n\t\t\tplaceholder: \"例: テキストを入力してください\",\r\n\t\t},\r\n\t},\r\n};\r\n","// UIコンポーネントと定数\r\nimport { DimensionInput } from \"@/properties/components/DimensionInput\";\r\nimport { SIZE_UNITS } from \"@/types/unit\";\r\n\r\nimport type { PluginProperties } from \"../definition\"; // パスは環境に合わせてください\r\nimport type { SizeSchema } from \"./schemas\";\r\n\r\n/**\r\n * SizeSchema の実体定義\r\n */\r\nexport const sizeDefinition: PluginProperties<SizeSchema> = {\r\n\twidth: {\r\n\t\tdefaultValue: undefined, // undefinedなら auto として扱う想定\r\n\t\tlabel: \"幅\",\r\n\t\tgroup: \"サイズ\",\r\n\t\tdescription: \"要素の幅を設定します\",\r\n\r\n\t\tComponent: DimensionInput,\r\n\t\tconfig: {\r\n\t\t\tmin: 0,\r\n\t\t\tallowedUnits: SIZE_UNITS, // px, %, mm など\r\n\t\t\tplaceholder: \"auto\", // 未設定時は \"auto\" と表示されると親切\r\n\t\t},\r\n\t},\r\n\r\n\theight: {\r\n\t\tdefaultValue: undefined,\r\n\t\tlabel: \"高さ\",\r\n\t\tgroup: \"サイズ\",\r\n\t\tdescription: \"要素の高さを設定します\",\r\n\r\n\t\tComponent: DimensionInput,\r\n\t\tconfig: {\r\n\t\t\tmin: 0,\r\n\t\t\tallowedUnits: SIZE_UNITS,\r\n\t\t\tplaceholder: \"auto\",\r\n\t\t},\r\n\t},\r\n};\r\n","// packages/core/src/utils/plugin.ts\r\n\r\nimport type { BlockPlugin } from \"../types\";\r\n\r\n/**\r\n * プラグインの properties 定義から初期Propsを生成\r\n *\r\n * @remarks\r\n * - フラットなプロパティ定義から defaultValue を抽出してオブジェクトを生成します\r\n * - false で無効化されたプロパティはスキップします\r\n * - defaultValue が undefined のプロパティも含めます(CSS変数対応のため)\r\n *\r\n * @param plugin BlockPlugin オブジェクト\r\n * @returns 初期化されたプロパティオブジェクト\r\n */\r\nexport const createInitialProps = <P>(plugin: BlockPlugin<P>): P => {\r\n\tconst initialProps: Record<string, unknown> = {};\r\n\r\n\tObject.entries(plugin.properties).forEach(([key, config]) => {\r\n\t\t// false (無効) の場合はスキップ\r\n\t\tif (config === false) return;\r\n\r\n\t\t// プロパティ定義オブジェクトの場合、defaultValue を取得\r\n\t\t// (今の設計ではすべての定義がフラットなので再帰処理は不要)\r\n\t\tif (\r\n\t\t\ttypeof config === \"object\" &&\r\n\t\t\tconfig !== null &&\r\n\t\t\t\"defaultValue\" in config\r\n\t\t) {\r\n\t\t\tinitialProps[key] = config.defaultValue;\r\n\t\t}\r\n\t});\r\n\r\n\treturn initialProps as P;\r\n};\r\n","// packages/core/src/utils/block.ts\r\n\r\nimport { createInitialProps } from \"./func\";\r\n\r\nimport type { Block } from \"@/types/block\";\r\nimport type { BlockPlugin } from \"../types\";\r\n\r\n/**\r\n * ブロック ID を生成\r\n *\r\n * @remarks\r\n * UUID/nanoid は使わず、カスタム ID 方式\r\n * タイムスタンプ + ランダム文字列で一意性を保証\r\n */\r\nexport function createBlockId(kind: string): string {\r\n\tconst timestamp = Date.now();\r\n\tconst random = Math.random().toString(36).slice(2);\r\n\treturn `${kind}_${timestamp}_${random}`;\r\n}\r\n\r\n/**\r\n * 新規ブロックを作成\r\n *\r\n * @remarks\r\n * Interaction層(D&Dでの配置)や初期化時に使用されます。\r\n *\r\n * @param plugin ブロックプラグイン\r\n * @param position グリッド上の配置情報\r\n * @param overrideProps プロパティの上書き(オプション)\r\n * @returns 新しい Block オブジェクト\r\n */\r\nexport function createBlock<P = Record<string, unknown>>(\r\n\tplugin: BlockPlugin<P>,\r\n\tposition: { x: number; y: number; w: number; h: number },\r\n\toverrideProps?: Partial<P>,\r\n): Block<P> {\r\n\t// プラグインの properties 定義から初期Propsを生成\r\n\tconst initialProps = createInitialProps(plugin);\r\n\r\n\treturn {\r\n\t\tid: createBlockId(plugin.kind),\r\n\t\tkind: plugin.kind,\r\n\t\tlayout: {\r\n\t\t\tx: position.x,\r\n\t\t\ty: position.y,\r\n\t\t\tw: position.w,\r\n\t\t\th: position.h,\r\n\t\t},\r\n\t\tstyle: {},\r\n\t\tbehavior: {},\r\n\t\tprops: {\r\n\t\t\t...initialProps,\r\n\t\t\t...overrideProps, // 上書き可能\r\n\t\t},\r\n\t};\r\n}\r\n","// UIコンポーネント\r\nimport { Checkbox, NumberInput, TextInput } from \"@/properties/components\";\r\n\r\nimport type { PluginProperties } from \"../definition\";\r\nimport type { ValidationSchema } from \"./schemas\";\r\n\r\n/**\r\n * ValidationSchema の実体定義\r\n */\r\nexport const validationDefinition: PluginProperties<ValidationSchema> = {\r\n\trequired: {\r\n\t\tdefaultValue: false,\r\n\t\tlabel: \"必須項目\",\r\n\t\tgroup: \"バリデーション\",\r\n\t\tdescription: \"この項目を必須入力にします\",\r\n\t\tComponent: Checkbox,\r\n\t\tconfig: {\r\n\t\t\tlabel: \"必須にする\",\r\n\t\t},\r\n\t},\r\n\r\n\tminLength: {\r\n\t\tdefaultValue: undefined,\r\n\t\tlabel: \"最小文字数\",\r\n\t\tgroup: \"バリデーション\",\r\n\t\tdescription: \"入力可能な最小文字数を設定します\",\r\n\t\tComponent: NumberInput,\r\n\t\tconfig: {\r\n\t\t\tmin: 0,\r\n\t\t\tinteger: true, // 文字数は整数のみ\r\n\t\t\tplaceholder: \"制限なし\",\r\n\t\t},\r\n\t},\r\n\r\n\tmaxLength: {\r\n\t\tdefaultValue: undefined,\r\n\t\tlabel: \"最大文字数\",\r\n\t\tgroup: \"バリデーション\",\r\n\t\tdescription: \"入力可能な最大文字数を設定します\",\r\n\t\tComponent: NumberInput,\r\n\t\tconfig: {\r\n\t\t\tmin: 0,\r\n\t\t\tinteger: true,\r\n\t\t\tplaceholder: \"制限なし\",\r\n\t\t},\r\n\t},\r\n\r\n\tpattern: {\r\n\t\tdefaultValue: undefined,\r\n\t\tlabel: \"入力パターン (正規表現)\",\r\n\t\tgroup: \"バリデーション\",\r\n\t\tdescription: \"入力値を検証する正規表現パターンを設定します\",\r\n\t\tComponent: TextInput,\r\n\t\tconfig: {\r\n\t\t\tplaceholder: \"例: ^[0-9]+$\", // 正規表現の例を表示\r\n\t\t},\r\n\t\tdisableInMultiSelection: true, // 複雑な設定なので複数選択時は無効化が無難\r\n\t},\r\n};\r\n","// ブロック変更イベント関連型定義\r\n\r\nimport type { Block } from \"./types\";\r\n\r\n// ブロック変更操作種別\r\nexport enum BlockChangeType {\r\n\t/** ブロック追加 */\r\n\tADD = \"add\",\r\n\t/** ブロック更新 */\r\n\tUPDATE = \"update\",\r\n\t/** ブロック削除 */\r\n\tDELETE = \"delete\",\r\n\t/** ブロック移動 */\r\n\tMOVE = \"move\",\r\n\t/** ブロックリサイズ */\r\n\tRESIZE = \"resize\",\r\n\t/** ブロック複製 */\r\n\tDUPLICATE = \"duplicate\",\r\n\t/** ブロック貼り付け */\r\n\tPASTE = \"paste\",\r\n}\r\n\r\n// ブロック変更イベント\r\nexport interface BlockChangeEvent {\r\n\ttype: BlockChangeType;\r\n\tblockIds: string[];\r\n\tblocks?: Block[];\r\n\tupdates?: Record<string, Partial<Block>>;\r\n}\r\n","// グリッド関連型定義\r\n\r\nimport type { Dimension, GridUnit } from \"../unit\";\r\n\r\n// グリッドオブジェクト(物理単位)\r\nexport interface Grid {\r\n\tcols: Dimension<GridUnit>[]; // 列幅配列\r\n\trows: Dimension<GridUnit>[]; // 行高配列\r\n}\r\n\r\n// デフォルトグリッド設定 (12列x16行、均等配分)\r\nexport const DEFAULT_GRID: Grid = {\r\n\tcols: Array.from({ length: 12 }).map(() => ({ value: 1, unit: \"fr\" })),\r\n\trows: Array.from({ length: 16 }).map(() => ({ value: 1, unit: \"fr\" })),\r\n};\r\n\r\n// グリッド位置(ピクセル単位)\r\nexport interface GridPosPx {\r\n\tcols: number[]; // 列インデックス配列 (px単位)\r\n\trows: number[]; // 行インデックス配列 (px単位)\r\n}\r\n","// 線関連型定義\r\n\r\nimport type { BorderUnit, Dimension } from \"../unit\";\r\n\r\n// 線スタイル列挙型\r\nexport enum LineType {\r\n\tSOLID = \"solid\", // 実線\r\n\tDASHED = \"dashed\", // 破線\r\n\tDOTTED = \"dotted\", // 点線\r\n}\r\n\r\n// 線スタイル定義\r\nexport interface LineStyle {\r\n\tcolor: string; // 線の色 (CSS color値)\r\n\twidth: Dimension<BorderUnit>; // 線の幅\r\n\ttype: LineType; // 線のスタイル\r\n}\r\n\r\n// 枠線スタイル定義\r\nexport interface BorderStyle {\r\n\tall?: LineStyle; // 全辺共通スタイル\r\n\ttop?: LineStyle; // 上辺スタイル\r\n\tright?: LineStyle; // 右辺スタイル\r\n\tbottom?: LineStyle; // 下辺スタイル\r\n\tleft?: LineStyle; // 左辺スタイル\r\n}\r\n","export const DEFAULT_DPI = 96;\r\n","// 数値のアサーション\r\n\r\n/**\r\n * 値が正 (> 0) であることを検証し、失敗時は例外を投げる\r\n * @param value 検証する値\r\n * @param name 値の名前(エラーメッセージに含まれる)\r\n * @throws {Error} 値が0以下の場合\r\n */\r\nexport function assertPositive(value: number, name?: string): void {\r\n\tif (value <= 0) {\r\n\t\tconst label = name ?? \"Value\";\r\n\t\tthrow new Error(`${label} must be positive (> 0): got ${value}`);\r\n\t}\r\n}\r\n\r\n/**\r\n * 値が非負(>= 0)であることを検証し、失敗時は例外を投げる\r\n * @param value 検証する値\r\n * @param name 値の名前(エラーメッセージに含まれる)\r\n * @throws {Error} 値が負の場合\r\n */\r\nexport function assertNonNegative(value: number, name?: string): void {\r\n\tif (value < 0) {\r\n\t\tconst label = name ?? \"Value\";\r\n\t\tthrow new Error(`${label} must be non-negative (>= 0): got ${value}`);\r\n\t}\r\n}\r\n\r\n/**\r\n * 値が指定範囲内であることを検証し、失敗時は例外を投げる\r\n * @param value 検証する値\r\n * @param min 最小値(含む)\r\n * @param max 最大値(含む)\r\n * @param name 値の名前(エラーメッセージに含まれる)\r\n * @throws {Error} 値が範囲外の場合\r\n */\r\nexport function assertRange(\r\n\tvalue: number,\r\n\tmin: number,\r\n\tmax: number,\r\n\tname?: string,\r\n): void {\r\n\tif (value < min || value > max) {\r\n\t\tconst label = name ?? \"Value\";\r\n\t\tthrow new Error(`${label} must be between ${min} and ${max}: got ${value}`);\r\n\t}\r\n}\r\n\r\n/**\r\n * 値が整数であることを検証し、失敗時は例外を投げる\r\n * @param value 検証する値\r\n * @param name 値の名前(エラーメッセージに含まれる)\r\n * @throws {Error} 値が整数でない場合\r\n */\r\nexport function assertInteger(value: number, name?: string): void {\r\n\tif (!Number.isInteger(value)) {\r\n\t\tconst label = name ?? \"Value\";\r\n\t\tthrow new Error(`${label} must be an integer: got ${value}`);\r\n\t}\r\n}\r\n\r\n/**\r\n * 値が有限数であることを検証し、失敗時は例外を投げる\r\n * @param value 検証する値\r\n * @param name 値の名前(エラーメッセージに含まれる)\r\n * @throws {Error} 値がInfinityまたはNaNの場合\r\n */\r\nexport function assertFinite(value: number, name?: string): void {\r\n\tif (!Number.isFinite(value)) {\r\n\t\tconst label = name ?? \"Value\";\r\n\t\tthrow new Error(`${label} must be a finite number: got ${value}`);\r\n\t}\r\n}\r\n","import {\r\n\tassertInteger,\r\n\tassertNonNegative,\r\n\tassertPositive,\r\n} from \"../assert/number\";\r\n\r\nimport { DEFAULT_DPI } from \"@/constants\";\r\n\r\nimport type { Dimension, Unit } from \"@/types\";\r\n\r\nconst MM_PER_INCH = 25.4;\r\nconst CM_PER_INCH = 2.54;\r\nconst PT_PER_INCH = 72;\r\n\r\nexport const toPx = {\r\n\t_assertDpi(dpi: number) {\r\n\t\tassertPositive(dpi, \"DPI\");\r\n\t\tassertInteger(dpi, \"DPI\");\r\n\t},\r\n\r\n\tfromMm(mm: number, dpi: number = DEFAULT_DPI): number {\r\n\t\ttoPx._assertDpi(dpi);\r\n\t\tassertNonNegative(mm, `Millimeter value`);\r\n\t\treturn (mm * dpi) / MM_PER_INCH;\r\n\t},\r\n\r\n\tfromCm(cm: number, dpi: number = DEFAULT_DPI): number {\r\n\t\ttoPx._assertDpi(dpi);\r\n\t\tassertNonNegative(cm, `Centimeter value`);\r\n\t\treturn (cm * dpi) / CM_PER_INCH;\r\n\t},\r\n\r\n\tfromInch(inch: number, dpi: number = DEFAULT_DPI): number {\r\n\t\ttoPx._assertDpi(dpi);\r\n\t\tassertNonNegative(inch, `Inch value`);\r\n\t\treturn inch * dpi;\r\n\t},\r\n\r\n\tfromPt(pt: number, dpi: number = DEFAULT_DPI): number {\r\n\t\ttoPx._assertDpi(dpi);\r\n\t\tassertNonNegative(pt, `Point value`);\r\n\t\treturn (pt * dpi) / PT_PER_INCH;\r\n\t},\r\n\r\n\t// データ上のpxはDPI=96として扱う\r\n\tfromPx(px: number, dpi: number = DEFAULT_DPI): number {\r\n\t\ttoPx._assertDpi(dpi);\r\n\t\tassertNonNegative(px, `Pixel value`);\r\n\t\treturn (px * dpi) / DEFAULT_DPI;\r\n\t},\r\n\r\n\tfromDim<U extends Unit>(\r\n\t\tdim: Dimension<U>,\r\n\t\tdpi: number = DEFAULT_DPI,\r\n\t\tbaseSizePx?: number,\r\n\t): number {\r\n\t\ttoPx._assertDpi(dpi);\r\n\t\tassertNonNegative(dim.value, `Dimension value`);\r\n\t\tswitch (dim.unit) {\r\n\t\t\tcase \"mm\":\r\n\t\t\t\treturn toPx.fromMm(dim.value, dpi);\r\n\t\t\tcase \"cm\":\r\n\t\t\t\treturn toPx.fromCm(dim.value, dpi);\r\n\t\t\tcase \"inch\":\r\n\t\t\t\treturn toPx.fromInch(dim.value, dpi);\r\n\t\t\tcase \"pt\":\r\n\t\t\t\treturn toPx.fromPt(dim.value, dpi);\r\n\t\t\tcase \"px\":\r\n\t\t\t\treturn toPx.fromPx(dim.value, dpi);\r\n\t\t\tcase \"%\":\r\n\t\t\t\tif (baseSizePx === undefined) {\r\n\t\t\t\t\tthrow new Error(`Base size must be defined for percentage values.`);\r\n\t\t\t\t}\r\n\t\t\t\treturn (dim.value / 100) * baseSizePx;\r\n\t\t\tcase \"fr\":\r\n\t\t\t\tthrow new Error(\r\n\t\t\t\t\t`Cannot convert ${dim.unit} to px. Use physical units only.`,\r\n\t\t\t\t);\r\n\t\t\tdefault: {\r\n\t\t\t\tconst _exhaustive: never = dim.unit;\r\n\t\t\t\tthrow new Error(`Unsupported unit: ${_exhaustive}`);\r\n\t\t\t}\r\n\t\t}\r\n\t},\r\n};\r\n","import { type BorderStyle, type LineStyle, LineType } from \"./types\";\r\n\r\nimport { DEFAULT_DPI } from \"@/constants\";\r\nimport { toPx } from \"@/utils/convert/toPx\";\r\n\r\nexport const getStrokeDasharray = (\r\n\tlineStyle?: LineStyle,\r\n): string | undefined => {\r\n\tif (!lineStyle?.width || !lineStyle?.type) return undefined;\r\n\tconst actualLineWidth = lineStyle.width.value;\r\n\t// widthが0の場合はundefinedを返す\r\n\tif (actualLineWidth === 0) return undefined;\r\n\tif (lineStyle.type === LineType.DASHED) {\r\n\t\treturn `${actualLineWidth * 4} ${actualLineWidth * 2}`;\r\n\t}\r\n\tif (lineStyle.type === LineType.DOTTED) {\r\n\t\treturn `${actualLineWidth * 1} ${actualLineWidth * 2}`;\r\n\t}\r\n\treturn undefined;\r\n};\r\n\r\nexport class Border {\r\n\tconstructor(private readonly style: BorderStyle) {}\r\n\r\n\tget top(): LineStyle | undefined {\r\n\t\tif (!this.style.top) return this.style.all;\r\n\t\treturn {\r\n\t\t\t...this.style.all,\r\n\t\t\t...this.style.top,\r\n\t\t} as LineStyle;\r\n\t}\r\n\r\n\tget right(): LineStyle | undefined {\r\n\t\tif (!this.style.right) return this.style.all;\r\n\t\treturn {\r\n\t\t\t...this.style.all,\r\n\t\t\t...this.style.right,\r\n\t\t} as LineStyle;\r\n\t}\r\n\r\n\tget bottom(): LineStyle | undefined {\r\n\t\tif (!this.style.bottom) return this.style.all;\r\n\t\treturn {\r\n\t\t\t...this.style.all,\r\n\t\t\t...this.style.bottom,\r\n\t\t} as LineStyle;\r\n\t}\r\n\r\n\tget left(): LineStyle | undefined {\r\n\t\tif (!this.style.left) return this.style.all;\r\n\t\treturn {\r\n\t\t\t...this.style.all,\r\n\t\t\t...this.style.left,\r\n\t\t} as LineStyle;\r\n\t}\r\n\r\n\tget hasAnyBorder(): boolean {\r\n\t\treturn !!(this.top || this.right || this.bottom || this.left);\r\n\t}\r\n\r\n\tgetTopSVGProps(widthPx: number, dpi: number = DEFAULT_DPI) {\r\n\t\tconst style = this.top;\r\n\t\tif (!style) return null;\r\n\t\treturn {\r\n\t\t\tx1: 0,\r\n\t\t\ty1: 0,\r\n\t\t\tx2: widthPx,\r\n\t\t\ty2: 0,\r\n\t\t\tstroke: style.color,\r\n\t\t\tstrokeWidth: toPx.fromDim(style.width, dpi),\r\n\t\t\tstrokeDasharray: getStrokeDasharray(style),\r\n\t\t\tvectorEffect: \"non-scaling-stroke\",\r\n\t\t\t\"data-edge\": \"top\",\r\n\t\t};\r\n\t}\r\n\r\n\tgetRightSVGProps(\r\n\t\twidthPx: number,\r\n\t\theightPx: number,\r\n\t\tdpi: number = DEFAULT_DPI,\r\n\t) {\r\n\t\tconst style = this.right;\r\n\t\tif (!style) return null;\r\n\t\treturn {\r\n\t\t\tx1: widthPx,\r\n\t\t\ty1: 0,\r\n\t\t\tx2: widthPx,\r\n\t\t\ty2: heightPx,\r\n\t\t\tstroke: style.color,\r\n\t\t\tstrokeWidth: toPx.fromDim(style.width, dpi),\r\n\t\t\tstrokeDasharray: getStrokeDasharray(style),\r\n\t\t\tvectorEffect: \"non-scaling-stroke\",\r\n\t\t\t\"data-edge\": \"right\",\r\n\t\t};\r\n\t}\r\n\r\n\tgetBottomSVGProps(\r\n\t\twidthPx: number,\r\n\t\theightPx: number,\r\n\t\tdpi: number = DEFAULT_DPI,\r\n\t) {\r\n\t\tconst style = this.bottom;\r\n\t\tif (!style) return null;\r\n\t\treturn {\r\n\t\t\tx1: 0,\r\n\t\t\ty1: heightPx,\r\n\t\t\tx2: widthPx,\r\n\t\t\ty2: heightPx,\r\n\t\t\tstroke: style.color,\r\n\t\t\tstrokeWidth: toPx.fromDim(style.width, dpi),\r\n\t\t\tstrokeDasharray: getStrokeDasharray(style),\r\n\t\t\tvectorEffect: \"non-scaling-stroke\",\r\n\t\t\t\"data-edge\": \"bottom\",\r\n\t\t};\r\n\t}\r\n\r\n\tgetLeftSVGProps(heightPx: number, dpi: number = DEFAULT_DPI) {\r\n\t\tconst style = this.left;\r\n\t\tif (!style) return null;\r\n\t\treturn {\r\n\t\t\tx1: 0,\r\n\t\t\ty1: 0,\r\n\t\t\tx2: 0,\r\n\t\t\ty2: heightPx,\r\n\t\t\tstroke: style.color,\r\n\t\t\tstrokeWidth: toPx.fromDim(style.width, dpi),\r\n\t\t\tstrokeDasharray: getStrokeDasharray(style),\r\n\t\t\tvectorEffect: \"non-scaling-stroke\",\r\n\t\t\t\"data-edge\": \"left\",\r\n\t\t};\r\n\t}\r\n}\r\n","// モード列挙型\r\n\r\nexport enum NoteMode {\r\n\tFORM = \"Form\", // テンプレート作成モード\r\n\tEDIT = \"Edit\", // 値入力モード\r\n\tVIEW = \"View\", // 閲覧モード\r\n}\r\n","// 用紙関連型定義\r\n\r\nimport type { Dimension, PaperUnit } from \"../unit\";\r\n\r\n// 用紙サイズプリセット名\r\nexport enum PaperSizePreset {\r\n\tA4 = \"A4\",\r\n\tB5 = \"B5\",\r\n\tA3 = \"A3\",\r\n\tLETTER = \"Letter\",\r\n\tLEGAL = \"Legal\",\r\n\tCUSTOM = \"Custom\",\r\n}\r\n\r\n// 用紙サイズ設定\r\nexport interface PaperSize {\r\n\tpreset: PaperSizePreset; // プリセット名\r\n\twidth: Dimension<PaperUnit>; // 幅 (物理単位)\r\n\theight: Dimension<PaperUnit>; // 高さ (物理単位)\r\n}\r\n\r\n// デフォルト用紙サイズ設定\r\nexport const DEFAULT_PAPER_SIZES: Record<PaperSizePreset, PaperSize> = {\r\n\t[PaperSizePreset.A4]: {\r\n\t\tpreset: PaperSizePreset.A4,\r\n\t\twidth: { value: 210, unit: \"mm\" },\r\n\t\theight: { value: 297, unit: \"mm\" },\r\n\t},\r\n\t[PaperSizePreset.A3]: {\r\n\t\tpreset: PaperSizePreset.A3,\r\n\t\twidth: { value: 297, unit: \"mm\" },\r\n\t\theight: { value: 420, unit: \"mm\" },\r\n\t},\r\n\t[PaperSizePreset.B5]: {\r\n\t\tpreset: PaperSizePreset.B5,\r\n\t\twidth: { value: 182, unit: \"mm\" },\r\n\t\theight: { value: 257, unit: \"mm\" },\r\n\t},\r\n\t[PaperSizePreset.LETTER]: {\r\n\t\tpreset: PaperSizePreset.LETTER,\r\n\t\twidth: { value: 8.5, unit: \"inch\" },\r\n\t\theight: { value: 11, unit: \"inch\" },\r\n\t},\r\n\t[PaperSizePreset.LEGAL]: {\r\n\t\tpreset: PaperSizePreset.LEGAL,\r\n\t\twidth: { value: 8.5, unit: \"inch\" },\r\n\t\theight: { value: 14, unit: \"inch\" },\r\n\t},\r\n\t[PaperSizePreset.CUSTOM]: {\r\n\t\tpreset: PaperSizePreset.CUSTOM,\r\n\t\twidth: { value: 210, unit: \"mm\" },\r\n\t\theight: { value: 297, unit: \"mm\" },\r\n\t},\r\n};\r\n\r\n// 用紙マージン設定\r\nexport interface PaperMargin {\r\n\ttop: Dimension<PaperUnit>; // 上マージン\r\n\tright: Dimension<PaperUnit>; // 右マージン\r\n\tbottom: Dimension<PaperUnit>; // 下マージン\r\n\tleft: Dimension<PaperUnit>; // 左マージン\r\n}\r\n\r\n// デフォルト用紙マージン設定\r\nexport const DEFAULT_PAPER_MARGIN: PaperMargin = {\r\n\ttop: { value: 10, unit: \"mm\" },\r\n\tright: { value: 10, unit: \"mm\" },\r\n\tbottom: { value: 10, unit: \"mm\" },\r\n\tleft: { value: 10, unit: \"mm\" },\r\n};\r\n\r\n// 用紙設定\r\nexport interface Paper {\r\n\tsize: PaperSize;\r\n\tmargin: PaperMargin;\r\n}\r\n\r\n// デフォルト用紙設定\r\nexport const DEFAULT_PAPER: Paper = {\r\n\tsize: DEFAULT_PAPER_SIZES[PaperSizePreset.A4],\r\n\tmargin: DEFAULT_PAPER_MARGIN,\r\n};\r\n\r\n// 用紙サイズ設定(ピクセル単位)\r\nexport interface PaperCanvasPx {\r\n\twidth: number; // 幅 (px)\r\n\theight: number; // 高さ (px)\r\n}\r\n\r\n// 用紙マージン設定(ピクセル単位)\r\nexport interface PaperMarginPx {\r\n\ttop: number; // 上マージン (px)\r\n\tright: number; // 右マージン (px)\r\n\tbottom: number; // 下マージン (px)\r\n\tleft: number; // 左マージン (px)\r\n}\r\n\r\nexport interface PaperContentPx {\r\n\twidth: number; // コンテンツ幅 (px)\r\n\theight: number; // コンテンツ高さ (px)\r\n}\r\n\r\n// 用紙設定(ピクセル単位)\r\nexport interface PaperPx {\r\n\tcanvas: PaperCanvasPx;\r\n\tmargin: PaperMarginPx;\r\n\tcontent: PaperContentPx;\r\n}\r\n","// 用紙・スキーマ関連タイプ定義\r\n\r\nimport { DEFAULT_GRID, type Grid } from \"../grid\";\r\nimport { DEFAULT_PAPER, type Paper } from \"../paper\";\r\n\r\nimport type { Block } from \"../block\";\r\nimport type { Value } from \"../value\";\r\n\r\n// フォームスキーマ定義\r\nexport interface FormSchema {\r\n\tpaper: Paper; // 用紙設定\r\n\tgrid: Grid; // グリッド設定\r\n\tblocks: Block[]; // 配置されているブロック一覧\r\n\r\n\t// 追加のメタデータ(オプション)\r\n\t// バージョン管理などが必要になった場合に備えておく\r\n\tmetaData?: Record<string, Value>;\r\n}\r\n\r\n// デフォルトフォームスキーマ\r\nexport const DEFAULT_SCHEMA: FormSchema = {\r\n\tpaper: DEFAULT_PAPER,\r\n\tgrid: DEFAULT_GRID,\r\n\tblocks: [],\r\n};\r\n","// バリデーション関連型定義\r\n\r\nimport type { Value } from \"../value\";\r\n\r\n/**\r\n * エラーの重大度レベル\r\n */\r\nexport enum ValidationSeverity {\r\n\tERROR = \"error\",\r\n\tWARNING = \"warning\",\r\n\tINFO = \"info\",\r\n}\r\n\r\n/**\r\n * バリデーションエラー情報\r\n */\r\nexport interface ValidationError {\r\n\tmessage: string; // エラーメッセージ\r\n\tcode: string; // エラーコード\r\n\tfield?: string; // 関連するフィールド名(オプション)\r\n\tseverity: ValidationSeverity; // 重大度レベル\r\n\tmetadata?: Record<string, Value>; // 追加のメタデータ(オプション)\r\n}\r\n\r\n/**\r\n * バリデーション結果\r\n */\r\nexport interface ValidationResult {\r\n\tvalid: boolean; // バリデーション結果(有効/無効)\r\n\terrors: ValidationError[]; // 発生したエラーの配列\r\n}\r\n\r\n/**\r\n * Block単位のバリデーター関数型\r\n */\r\nexport type BlockValidator<P = unknown, V = unknown> = (\r\n\tprops: P,\r\n\tvalue: V,\r\n) => ValidationError | null;\r\n\r\n/**\r\n * 複数のBlockバリデーター関数型\r\n */\r\nexport type BlockValidators<P = unknown, V = unknown> = (\r\n\tprops: P,\r\n\tvalue: V,\r\n) => ValidationError[];\r\n","/**\r\n * @file BorderRenderer.tsx\r\n * @description 枠線SVG描画の共通コンポーネント\r\n */\r\nimport { memo } from \"react\";\r\n\r\nimport { DEFAULT_DPI } from \"@/constants\";\r\n\r\nimport type { Border } from \"@/types/line\";\r\n\r\nexport interface BorderRendererProps {\r\n\twidth: number;\r\n\theight: number;\r\n\tborder: Border;\r\n\tdpi?: number;\r\n\tclassName?: string;\r\n}\r\n\r\nexport const BorderRenderer = memo(\r\n\t({\r\n\t\twidth,\r\n\t\theight,\r\n\t\tborder,\r\n\t\tdpi = DEFAULT_DPI,\r\n\t\tclassName = \"\",\r\n\t}: BorderRendererProps) => {\r\n\t\t// 枠線が一つもない場合は描画しない\r\n\t\tif (!border.hasAnyBorder) return null;\r\n\r\n\t\treturn (\r\n\t\t\t<svg\r\n\t\t\t\twidth={width}\r\n\t\t\t\theight={height}\r\n\t\t\t\txmlns=\"http://www.w3.org/2000/svg\"\r\n\t\t\t\tclassName={className}\r\n\t\t\t\tstyle={{ overflow: \"visible\" }} // 線幅によってはみ出るのを許容\r\n\t\t\t>\r\n\t\t\t\t<title>border SVG</title>\r\n\t\t\t\t{/* 上辺 */}\r\n\t\t\t\t{border.top && <line {...border.getTopSVGProps(width, dpi)} />}\r\n\r\n\t\t\t\t{/* 右辺 */}\r\n\t\t\t\t{border.right && (\r\n\t\t\t\t\t<line {...border.getRightSVGProps(width, height, dpi)} />\r\n\t\t\t\t)}\r\n\r\n\t\t\t\t{/* 下辺 */}\r\n\t\t\t\t{border.bottom && (\r\n\t\t\t\t\t<line {...border.getBottomSVGProps(width, height, dpi)} />\r\n\t\t\t\t)}\r\n\r\n\t\t\t\t{/* 左辺 */}\r\n\t\t\t\t{border.left && <line {...border.getLeftSVGProps(height, dpi)} />}\r\n\t\t\t</svg>\r\n\t\t);\r\n\t},\r\n);\r\n\r\nBorderRenderer.displayName = \"BorderRenderer\";\r\n","/**\r\n * @file helpers.ts\r\n * @description z-index計算ヘルパー関数\r\n */\r\n\r\nimport { Z_INDEX } from \"./constants\";\r\n\r\n/**\r\n * ブロックの基底z-indexを計算\r\n *\r\n * @param index - ブロックの配列インデックス (0-based)\r\n * @returns 基底z-index(ブロックはbase ~ base+9を使用可能)\r\n *\r\n * @example\r\n * ```ts\r\n * getBlockZIndex(0); // 100\r\n * getBlockZIndex(1); // 200\r\n * getBlockZIndex(10); // 1100\r\n * ```\r\n */\r\nexport function getBlockZIndex(index: number): number {\r\n\tconst zIndex = Z_INDEX.BLOCK_LAYER_MIN + index * Z_INDEX.BLOCK_LAYER_STEP;\r\n\r\n\t// 最大値を超えないようにクランプ\r\n\tif (zIndex >= Z_INDEX.BLOCK_LAYER_MAX) {\r\n\t\treturn Z_INDEX.BLOCK_LAYER_MAX;\r\n\t}\r\n\r\n\treturn zIndex;\r\n}\r\n\r\n/**\r\n * ブロック内のサブレイヤーz-indexを計算\r\n *\r\n * @param baseZIndex - ブロックの基底z-index\r\n * @param subIndex - サブレイヤーのオフセット (0-99)\r\n * @returns サブレイヤーのz-index\r\n *\r\n * @example\r\n * ```ts\r\n * const baseZ = getBlockZIndex(0); // 100\r\n * getSubLayerZIndex(baseZ, BLOCK_SUB_INDEX.BG); // 110 (Blockの背景色)\r\n * getSubLayerZIndex(baseZ, BLOCK_SUB_INDEX.CONTENT); // 150 (Blockのコンテンツ)\r\n * ```\r\n */\r\nexport function getSubZIndex(baseZIndex: number, subIndex: number): number {\r\n\t// subIndexを範囲内にクランプ\r\n\tconst clampedOffset = Math.min(\r\n\t\tMath.max(0, subIndex),\r\n\t\tZ_INDEX.BLOCK_LAYER_STEP - 1,\r\n\t);\r\n\treturn baseZIndex + clampedOffset;\r\n}\r\n\r\n/**\r\n * サポートされる最大ブロック数を取得\r\n *\r\n * @returns 最大ブロック数\r\n *\r\n * @example\r\n * ```ts\r\n * getMaxBlockCount(); // 9999 (99,999 - 10) / 10\r\n * ```\r\n */\r\nexport function getMaxBlockCount(): number {\r\n\treturn Math.floor(\r\n\t\t(Z_INDEX.BLOCK_LAYER_MAX - Z_INDEX.BLOCK_LAYER_MIN) /\r\n\t\t\tZ_INDEX.BLOCK_LAYER_STEP,\r\n\t);\r\n}\r\n","/**\r\n * @file BlockBorder.tsx\r\n * @description ブロック境界線描画コンポーネント\r\n * @z-index BlockLayer内の上層(BlockCanvasとBlockRendererより上)\r\n */\r\n\r\nimport { memo, useMemo } from \"react\";\r\nimport { Border } from \"@types\";\r\n\r\nimport { BorderRenderer } from \"@/canvas/components/BorderRenderer\";\r\nimport { DEFAULT_DPI } from \"@/constants\";\r\nimport { BLOCK_SUB_INDEX } from \"@/utils/zIndex\";\r\nimport { getSubZIndex } from \"@/utils/zIndex/helpers\";\r\n\r\nimport type React from \"react\";\r\nimport type { BlockSizePx } from \"@/types/block\";\r\nimport type { BorderStyle } from \"@/types/line\";\r\n\r\n/**\r\n * BlockBorderコンポーネントのProps\r\n */\r\nexport interface BlockBorderProps {\r\n\tblockSizePx: BlockSizePx; // ブロックのサイズ(px)\r\n\tborderStyle?: BorderStyle; // 境界線スタイル\r\n\tblockZIndex: number; // ブロックのベースz-index\r\n\tsubZIndex?: number; // ブロック内でのレイヤーz-index(デフォルト:BLOCK_SUB_INDEX.BORDER)\r\n\tvisible?: boolean; // 表示/非表示(デフォルト: true)\r\n\tdpi?: number; // DPI(デフォルト: DEFAULT_DPI)\r\n\tclassName?: string; // 追加のクラス名\r\n}\r\n\r\n/**\r\n * BlockBorder\r\n *\r\n * ブロックの境界線を描画するコンポーネント\r\n * - block.style?.borderで設定された枠線を描画\r\n * - pointer-events: none (クリックイベント透過)\r\n *\r\n * @remarks\r\n * - ユーザー設定の枠線を描画\r\n * - BlockBaseBorderと構造は同じだが、用途とz-indexが異なる\r\n * - BlockBaseBorder: ガイド線(GUIDE層)\r\n * - BlockBorder: 実際の枠線(BORDER層)\r\n */\r\nexport const BlockBorder: React.FC<BlockBorderProps> = memo(\r\n\t({\r\n\t\tblockSizePx,\r\n\t\tborderStyle,\r\n\t\tblockZIndex,\r\n\t\tsubZIndex = BLOCK_SUB_INDEX.BORDER,\r\n\t\tvisible = true,\r\n\t\tdpi = DEFAULT_DPI,\r\n\t\tclassName = \"\",\r\n\t}) => {\r\n\t\tconst border: Border | undefined = useMemo(() => {\r\n\t\t\tif (!borderStyle) return undefined;\r\n\t\t\treturn new Border(borderStyle);\r\n\t\t}, [borderStyle]);\r\n\r\n\t\tif (!visible || !border || !border.hasAnyBorder) return null;\r\n\r\n\t\tconst zIndex = getSubZIndex(blockZIndex, subZIndex);\r\n\r\n\t\tconst overlayStyle: React.CSSProperties = {\r\n\t\t\tposition: \"absolute\",\r\n\t\t\tleft: 0,\r\n\t\t\ttop: 0,\r\n\t\t\twidth: `${blockSizePx.width}px`,\r\n\t\t\theight: `${blockSizePx.height}px`,\r\n\t\t\tpointerEvents: \"none\",\r\n\t\t\toverflow: \"visible\",\r\n\t\t\tzIndex,\r\n\t\t};\r\n\r\n\t\treturn (\r\n\t\t\t<div\r\n\t\t\t\tclassName={className}\r\n\t\t\t\tstyle={overlayStyle}\r\n\t\t\t\tdata-testid=\"block-border\"\r\n\t\t\t>\r\n\t\t\t\t<BorderRenderer\r\n\t\t\t\t\twidth={blockSizePx.width}\r\n\t\t\t\t\theight={blockSizePx.height}\r\n\t\t\t\t\tborder={border}\r\n\t\t\t\t\tdpi={dpi}\r\n\t\t\t\t/>\r\n\t\t\t</div>\r\n\t\t);\r\n\t},\r\n);\r\n","/**\r\n * @file BlockCanvas.tsx\r\n * @description ブロック背景描画コンポーネント\r\n * @z-index BLOCK_LAYER_MIN + blockIndex * BLOCK_LAYER_STEP + 0 (各ブロックの最下層)\r\n */\r\n\r\nimport { memo } from \"react\";\r\n\r\nimport { BLOCK_SUB_INDEX, getSubZIndex } from \"@/utils/zIndex\";\r\n\r\nimport type React from \"react\";\r\nimport type { BlockSizePx } from \"@/types/block\";\r\n\r\n/**\r\n * BlockCanvasコンポーネントのProps\r\n */\r\nexport interface BlockCanvasProps {\r\n\tblockSizePx: BlockSizePx; // ブロックのサイズ(px)\r\n\tblockZIndex: number; // z-index(ブロック基底値)\r\n\tsubZIndex?: number; // ブロック内でのレイヤーz-index(デフォルト:BLOCK_SUB_INDEX.BG)\r\n\tbackgroundColor?: string; // ブロックの背景色\r\n\tclassName?: string; // 追加のクラス名\r\n}\r\n\r\n/**\r\n * BlockCanvas\r\n *\r\n * ブロック背景を描画するコンポーネント\r\n * - z-index: ブロック基底値 + 0 (各ブロックの最下層)\r\n * - pointer-events: none (クリックイベント透過)\r\n * - 背景色のみを描画(境界線はBlockBaseBorderが担当)\r\n */\r\nexport const BlockCanvas: React.FC<BlockCanvasProps> = memo(\r\n\t({\r\n\t\tblockSizePx,\r\n\t\tblockZIndex,\r\n\t\tsubZIndex = BLOCK_SUB_INDEX.BG,\r\n\t\tbackgroundColor = \"transparent\",\r\n\t\tclassName = \"\",\r\n\t}) => {\r\n\t\tconst zIndex = getSubZIndex(blockZIndex, subZIndex);\r\n\r\n\t\tconst canvasStyle: React.CSSProperties = {\r\n\t\t\tposition: \"absolute\",\r\n\t\t\tinset: 0,\r\n\t\t\twidth: `${blockSizePx.width}px`,\r\n\t\t\theight: `${blockSizePx.height}px`,\r\n\t\t\tbackgroundColor,\r\n\t\t\tpointerEvents: \"none\",\r\n\t\t\tzIndex: zIndex,\r\n\t\t};\r\n\r\n\t\treturn (\r\n\t\t\t<div\r\n\t\t\t\tclassName={className}\r\n\t\t\t\tstyle={canvasStyle}\r\n\t\t\t\trole=\"presentation\"\r\n\t\t\t\taria-label=\"Block background\"\r\n\t\t\t\tdata-testid=\"block-canvas\"\r\n\t\t\t/>\r\n\t\t);\r\n\t},\r\n);\r\n","import { type BorderStyle, type LineStyle, LineType } from \"@/types/line\";\r\n\r\nexport const DEFAULT_GUIDE_LINE: LineStyle = {\r\n\tcolor: \"#cccccc\",\r\n\twidth: { value: 1, unit: \"pt\" },\r\n\ttype: LineType.SOLID,\r\n};\r\n\r\nexport const DEFAULT_GUIDE_BORDER: BorderStyle = {\r\n\tall: DEFAULT_GUIDE_LINE,\r\n};\r\n","/**\r\n * @file BlockBaseBorder.tsx\r\n * @description レイアウト編集時のブロック境界ガイド線コンポーネント\r\n * @z-index BlockLayer内の中層(BlockCanvasより上、BlockRendererより下)\r\n */\r\n\r\nimport { memo, useMemo } from \"react\";\r\nimport { Border } from \"@types\";\r\n\r\nimport { DEFAULT_GUIDE_BORDER } from \"./constants\";\r\n\r\nimport { BorderRenderer } from \"@/canvas/components/BorderRenderer\";\r\nimport { DEFAULT_DPI } from \"@/constants\";\r\nimport { BLOCK_SUB_INDEX } from \"@/utils/zIndex\";\r\nimport { getSubZIndex } from \"@/utils/zIndex/helpers\";\r\n\r\nimport type React from \"react\";\r\nimport type { BlockSizePx } from \"@/types/block\";\r\nimport type { BorderStyle } from \"@/types/line\";\r\n\r\n/**\r\n * BlockBaseBorderコンポーネントのProps\r\n */\r\nexport interface BlockGuideBorderProps {\r\n\tblockSizePx: BlockSizePx; // ブロックのサイズ(px)\r\n\tblockZIndex: number; // ブロックのベースz-index\r\n\tsubZIndex?: number; // ブロック内でのレイヤーz-index(デフォルト:BLOCK_SUB_INDEX.GUIDE)\r\n\tborderStyle?: BorderStyle; // 境界線スタイル\r\n\tvisible?: boolean; // 表示/非表示(デフォルト: true)\r\n\tdpi?: number; // DPI(デフォルト: DEFAULT_DPI)\r\n\tclassName?: string; // 追加のクラス名\r\n}\r\n\r\n/**\r\n * BlockBaseBorder\r\n *\r\n * レイアウト編集時にブロックの境界を可視化するガイド線コンポーネント\r\n * - formモードでのみ使用される\r\n * - block.style?.borderが未設定のブロックに表示\r\n * - pointer-events: none (クリックイベント透過)\r\n *\r\n * @remarks\r\n * - 固定スタイル(薄いグレーの実線)でブロック境界を描画\r\n * - ユーザー設定の枠線とは別の、編集補助用のガイド\r\n * - BorderOverlayと構造は同じだが、用途と表示条件が異なる\r\n */\r\nexport const BlockGuideBorder: React.FC<BlockGuideBorderProps> = memo(\r\n\t({\r\n\t\tblockSizePx,\r\n\t\tblockZIndex,\r\n\t\tsubZIndex = BLOCK_SUB_INDEX.GUIDE,\r\n\t\tborderStyle = DEFAULT_GUIDE_BORDER,\r\n\t\tvisible = true,\r\n\t\tdpi = DEFAULT_DPI,\r\n\t\tclassName = \"\",\r\n\t}) => {\r\n\t\tconst border: Border | undefined = useMemo(() => {\r\n\t\t\tif (!borderStyle) return undefined;\r\n\t\t\treturn new Border(borderStyle);\r\n\t\t}, [borderStyle]);\r\n\r\n\t\tif (!visible || !border || !border.hasAnyBorder) return null;\r\n\r\n\t\tconst zIndex = getSubZIndex(blockZIndex, subZIndex);\r\n\r\n\t\tconst overlayStyle: React.CSSProperties = {\r\n\t\t\tposition: \"absolute\",\r\n\t\t\tleft: 0,\r\n\t\t\ttop: 0,\r\n\t\t\twidth: `${blockSizePx.width}px`,\r\n\t\t\theight: `${blockSizePx.height}px`,\r\n\t\t\tpointerEvents: \"none\",\r\n\t\t\toverflow: \"visible\",\r\n\t\t\tzIndex,\r\n\t\t};\r\n\r\n\t\treturn (\r\n\t\t\t<div\r\n\t\t\t\tclassName={className}\r\n\t\t\t\tstyle={overlayStyle}\r\n\t\t\t\tdata-testid=\"block-base-border\"\r\n\t\t\t>\r\n\t\t\t\t<BorderRenderer\r\n\t\t\t\t\twidth={blockSizePx.width}\r\n\t\t\t\t\theight={blockSizePx.height}\r\n\t\t\t\t\tborder={border}\r\n\t\t\t\t\tdpi={dpi}\r\n\t\t\t\t/>\r\n\t\t\t</div>\r\n\t\t);\r\n\t},\r\n);\r\n","/**\r\n * @file BlockRenderer.tsx\r\n * @description ブロックコンテンツ描画コンポーネント\r\n * @z-index BLOCK_LAYER_MIN + blockIndex * BLOCK_LAYER_STEP + 100 (ブロック中層)\r\n */\r\n\r\nimport { forwardRef, memo, useImperativeHandle, useRef } from \"react\";\r\n\r\nimport { BLOCK_SUB_INDEX, getSubZIndex } from \"@/utils/zIndex\";\r\n\r\nimport type React from \"react\";\r\nimport type { BlockPlugin, BlockRef, RendererProps } from \"@/plugin\";\r\nimport type { BlockSizePx } from \"@/types/block\";\r\nimport type { NoteMode } from \"@/types/mode\";\r\nimport type { Value } from \"@/types/value\";\r\n\r\n/**\r\n * BlockRendererコンポーネントのProps\r\n *\r\n * @template P - プラグイン固有プロパティ型\r\n * @template V - プラグインが扱う値の型\r\n */\r\nexport interface BlockRendererProps<P = Record<string, Value>, V = Value> {\r\n\t/** ブロックID */\r\n\tid: string;\r\n\r\n\t/** プラグイン定義 */\r\n\tplugin: BlockPlugin<P, V>;\r\n\r\n\t/** プラグイン固有プロパティ */\r\n\tprops: P;\r\n\r\n\t/** ブロックの現在値 */\r\n\tvalue: V;\r\n\r\n\t/** 値変更コールバック (オプション) */\r\n\tonChange?: (value: V) => void;\r\n\r\n\t/** 値確定コールバック (オプション) */\r\n\tonBlur?: (value: V) => void;\r\n\r\n\t/** 読み取り専用フラグ */\r\n\treadOnly: boolean;\r\n\r\n\t/** 現在のモード */\r\n\tmode: NoteMode;\r\n\r\n\t/** ブロックの位置とサイズ(ピクセル単位) */\r\n\tblockSizePx: BlockSizePx;\r\n\r\n\t/** ブロック基底z-index */\r\n\tblockZIndex: number;\r\n\r\n\t/** ブロック内でのレイヤーz-index (オプション) */\r\n\tsubZIndex?: number;\r\n\r\n\t/** バリデーション状態 (オプション) */\r\n\tvalidationState?: \"valid\" | \"invalid\" | \"warning\";\r\n\r\n\t/** 追加のクラス名 */\r\n\tclassName?: string;\r\n}\r\n\r\n/**\r\n * BlockRenderer\r\n *\r\n * プラグインのRendererコンポーネントをラップし、適切な位置・z-indexで配置します\r\n *\r\n * @template P - プラグイン固有プロパティ型\r\n * @template V - プラグインが扱う値の型\r\n *\r\n * @remarks\r\n * - プラグインのRendererを動的に描画\r\n * - 位置とz-indexを管理\r\n * - BlockRef経由でfocusメソッドを公開\r\n */\r\nconst BlockRendererInner = <P extends Record<string, Value>, V extends Value>(\r\n\t{\r\n\t\tid,\r\n\t\tplugin,\r\n\t\tprops,\r\n\t\tvalue,\r\n\t\tonChange,\r\n\t\tonBlur,\r\n\t\treadOnly,\r\n\t\tmode,\r\n\t\tblockSizePx,\r\n\t\tblockZIndex,\r\n\t\tsubZIndex = BLOCK_SUB_INDEX.CONTENT,\r\n\t\tvalidationState,\r\n\t\tclassName = \"\",\r\n\t}: BlockRendererProps<P, V>,\r\n\tref: React.ForwardedRef<BlockRef>,\r\n) => {\r\n\t// プラグインのRendererコンポーネントへの参照\r\n\tconst pluginRendererRef = useRef<BlockRef>(null);\r\n\r\n\t// 親コンポーネントにfocusメソッドを公開\r\n\tuseImperativeHandle(\r\n\t\tref,\r\n\t\t() => ({\r\n\t\t\tfocus: () => pluginRendererRef.current?.focus(),\r\n\t\t}),\r\n\t\t[],\r\n\t);\r\n\r\n\t// z-index計算\r\n\tconst zIndex = getSubZIndex(blockZIndex, subZIndex);\r\n\r\n\t// コンテナスタイル\r\n\tconst containerStyle: React.CSSProperties = {\r\n\t\tposition: \"absolute\",\r\n\t\tinset: 0,\r\n\t\twidth: `${blockSizePx.width}px`,\r\n\t\theight: `${blockSizePx.height}px`,\r\n\t\tzIndex,\r\n\t\tpointerEvents: \"auto\", // クリックイベントを受け取る\r\n\t};\r\n\r\n\t// プラグインRendererに渡すprops\r\n\tconst pluginProps: RendererProps<P, V> = {\r\n\t\tid,\r\n\t\tprops,\r\n\t\tvalue,\r\n\t\tonChange: onChange ?? (() => {}),\r\n\t\tonBlur,\r\n\t\treadOnly,\r\n\t\tmode,\r\n\t\tdimensions: {\r\n\t\t\twidthPx: blockSizePx.width,\r\n\t\t\theightPx: blockSizePx.height,\r\n\t\t},\r\n\t\tvalidationState,\r\n\t};\r\n\r\n\t// プラグインのRendererコンポーネントを取得\r\n\tconst PluginRendererComponent = plugin.Renderer;\r\n\r\n\treturn (\r\n\t\t<div\r\n\t\t\tclassName={className}\r\n\t\t\tstyle={containerStyle}\r\n\t\t\tdata-testid=\"block-renderer\"\r\n\t\t\tdata-block-id={id}\r\n\t\t\tdata-plugin-kind={plugin.kind}\r\n\t\t>\r\n\t\t\t<PluginRendererComponent ref={pluginRendererRef} {...pluginProps} />\r\n\t\t</div>\r\n\t);\r\n};\r\n\r\nconst ForwardedBlockRenderer = forwardRef(BlockRendererInner) as <\r\n\tP extends Record<string, Value> = Record<string, Value>,\r\n\tV extends Value = Value,\r\n>(\r\n\tprops: BlockRendererProps<P, V> & { ref?: React.Ref<BlockRef> },\r\n) => React.ReactElement;\r\n\r\nexport const BlockRenderer = memo(\r\n\tForwardedBlockRenderer,\r\n) as typeof ForwardedBlockRenderer;\r\n","/**\r\n * @file getBlockContainerStyle.ts\r\n * @description ブロックコンテナの共通スタイル生成関数\r\n *\r\n * @remarks\r\n * BlockContainer と EditingBlock で共通のレイアウト計算ロジックを提供します。\r\n * 位置とサイズは BlockRectPx から計算され、z-index と pointerEvents はオプションで指定可能です。\r\n */\r\n\r\nimport type React from \"react\";\r\nimport type { BlockRectPx } from \"@/types/block\";\r\n\r\n/**\r\n * ブロックコンテナスタイルのオプション\r\n */\r\nexport interface BlockContainerStyleOptions {\r\n\t/** z-index値 (オプション) */\r\n\tzIndex?: number;\r\n\t/** ポインターイベントの制御 (デフォルト: \"auto\") */\r\n\tpointerEvents?: \"auto\" | \"none\";\r\n}\r\n\r\n/**\r\n * ブロックコンテナの共通スタイルを生成\r\n *\r\n * @param blockRectPx - ブロックの位置とサイズ (ピクセル単位)\r\n * @param options - オプション設定\r\n * @returns React CSSProperties オブジェクト\r\n *\r\n * @example\r\n * ```tsx\r\n * const style = getBlockContainerStyle(blockRectPx, {\r\n * zIndex: 2400000,\r\n * pointerEvents: \"auto\"\r\n * });\r\n * ```\r\n */\r\nexport function getBlockContainerStyle(\r\n\tblockRectPx: BlockRectPx,\r\n\toptions?: BlockContainerStyleOptions,\r\n): React.CSSProperties {\r\n\treturn {\r\n\t\tposition: \"absolute\",\r\n\t\tleft: `${blockRectPx.left}px`,\r\n\t\ttop: `${blockRectPx.top}px`,\r\n\t\twidth: `${blockRectPx.width}px`,\r\n\t\theight: `${blockRectPx.height}px`,\r\n\t\tzIndex: options?.zIndex,\r\n\t\tpointerEvents: options?.pointerEvents ?? \"auto\",\r\n\t};\r\n}\r\n","/**\r\n * @file BlockContainer.tsx\r\n * @description 1つのブロックを構成するコンテナコンポーネント\r\n */\r\nimport { forwardRef, memo, useMemo } from \"react\";\r\n\r\nimport { BlockBorder } from \"../BlockBorder\";\r\nimport { BlockCanvas } from \"../BlockCanvas\";\r\nimport { BlockGuideBorder, DEFAULT_GUIDE_BORDER } from \"../BlockGuideBorder\";\r\nimport { BlockRenderer } from \"../BlockRenderer\";\r\n\r\nimport { DEFAULT_DPI } from \"@/constants\";\r\nimport { NoteMode } from \"@/types/mode\";\r\nimport { getBlockContainerStyle } from \"@/utils/blockLayout\";\r\nimport { BLOCK_SUB_INDEX } from \"@/utils/zIndex\";\r\n\r\nimport type { BlockPlugin, BlockRef } from \"@/plugin\";\r\nimport type { Block, BlockRectPx, BlockSizePx } from \"@/types/block\";\r\nimport type { BorderStyle } from \"@/types/line\";\r\nimport type { Value } from \"@/types/value\";\r\n\r\nexport interface BlockContainerProps {\r\n\tblock: Block;\r\n\tplugin: BlockPlugin;\r\n\tblockRectPx: BlockRectPx;\r\n\tblockZIndex: number;\r\n\tmode: NoteMode;\r\n\tvalue: Value;\r\n\tonValueChange?: (val: Value) => void;\r\n\tonValueBlur?: (val: Value) => void;\r\n\tshowGuides?: boolean;\r\n\tshowBorder?: boolean;\r\n\tblockSubZIndex?: Record<string, number>;\r\n\tdefaultGuideBorder?: BorderStyle;\r\n\tdpi?: number;\r\n\tclassName?: string;\r\n\tpointerEvents?: \"auto\" | \"none\";\r\n}\r\n\r\nexport const BlockContainer = memo(\r\n\tforwardRef<BlockRef, BlockContainerProps>(\r\n\t\t(\r\n\t\t\t{\r\n\t\t\t\tblock,\r\n\t\t\t\tplugin,\r\n\t\t\t\tblockRectPx,\r\n\t\t\t\tblockZIndex,\r\n\t\t\t\tmode,\r\n\t\t\t\tvalue,\r\n\t\t\t\tonValueChange,\r\n\t\t\t\tonValueBlur,\r\n\t\t\t\tshowGuides = true,\r\n\t\t\t\tshowBorder = true,\r\n\t\t\t\tblockSubZIndex = {\r\n\t\t\t\t\tbg: BLOCK_SUB_INDEX.BG,\r\n\t\t\t\t\tguide: BLOCK_SUB_INDEX.GUIDE,\r\n\t\t\t\t\tcontent: BLOCK_SUB_INDEX.CONTENT,\r\n\t\t\t\t\tborder: BLOCK_SUB_INDEX.BORDER,\r\n\t\t\t\t},\r\n\t\t\t\tdefaultGuideBorder = DEFAULT_GUIDE_BORDER,\r\n\t\t\t\tdpi = DEFAULT_DPI,\r\n\t\t\t\tclassName = \"\",\r\n\t\t\t\tpointerEvents = \"none\",\r\n\t\t\t}: BlockContainerProps,\r\n\t\t\tref,\r\n\t\t) => {\r\n\t\t\t// コンテナスタイル (共通関数を使用)\r\n\t\t\tconst containerStyle = getBlockContainerStyle(blockRectPx, {\r\n\t\t\t\tzIndex: blockZIndex,\r\n\t\t\t\tpointerEvents,\r\n\t\t\t});\r\n\r\n\t\t\tconst blockSizePx: BlockSizePx = useMemo(() => {\r\n\t\t\t\treturn {\r\n\t\t\t\t\twidth: blockRectPx.width,\r\n\t\t\t\t\theight: blockRectPx.height,\r\n\t\t\t\t};\r\n\t\t\t}, [blockRectPx.width, blockRectPx.height]);\r\n\r\n\t\t\treturn (\r\n\t\t\t\t<div\r\n\t\t\t\t\tstyle={containerStyle}\r\n\t\t\t\t\tdata-block-id={block.id}\r\n\t\t\t\t\tclassName={className}\r\n\t\t\t\t>\r\n\t\t\t\t\t{/* 1. 背景 (最下層) */}\r\n\t\t\t\t\t<BlockCanvas\r\n\t\t\t\t\t\tblockSizePx={blockSizePx}\r\n\t\t\t\t\t\tblockZIndex={blockZIndex}\r\n\t\t\t\t\t\tbackgroundColor={block.style?.backgroundColor}\r\n\t\t\t\t\t\tsubZIndex={blockSubZIndex.bg}\r\n\t\t\t\t\t/>\r\n\t\t\t\t\t{/* 2. ガイド線 (編集モードかつ枠線なしの場合) */}\r\n\t\t\t\t\t{showGuides && !block.style?.border && (\r\n\t\t\t\t\t\t<BlockGuideBorder\r\n\t\t\t\t\t\t\tblockSizePx={blockSizePx}\r\n\t\t\t\t\t\t\tblockZIndex={blockZIndex}\r\n\t\t\t\t\t\t\tsubZIndex={blockSubZIndex.guide}\r\n\t\t\t\t\t\t\tborderStyle={defaultGuideBorder}\r\n\t\t\t\t\t\t\tdpi={dpi}\r\n\t\t\t\t\t\t/>\r\n\t\t\t\t\t)}\r\n\t\t\t\t\t{/* 3. コンテンツ (Renderer) */}\r\n\t\t\t\t\t<BlockRenderer\r\n\t\t\t\t\t\tid={block.id}\r\n\t\t\t\t\t\tref={ref}\r\n\t\t\t\t\t\tplugin={plugin}\r\n\t\t\t\t\t\tprops={block.props}\r\n\t\t\t\t\t\tvalue={value}\r\n\t\t\t\t\t\tonChange={onValueChange}\r\n\t\t\t\t\t\tonBlur={onValueBlur}\r\n\t\t\t\t\t\treadOnly={\r\n\t\t\t\t\t\t\tmode === NoteMode.EDIT\r\n\t\t\t\t\t\t\t\t? (block.behavior?.readOnly ?? false)\r\n\t\t\t\t\t\t\t\t: true\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tmode={mode}\r\n\t\t\t\t\t\tblockSizePx={blockSizePx}\r\n\t\t\t\t\t\tblockZIndex={blockZIndex}\r\n\t\t\t\t\t\tsubZIndex={blockSubZIndex.content}\r\n\t\t\t\t\t/>\r\n\t\t\t\t\t{/* 4. 枠線 (最上層) */}\r\n\t\t\t\t\t<BlockBorder\r\n\t\t\t\t\t\tblockSizePx={blockSizePx}\r\n\t\t\t\t\t\tblockZIndex={blockZIndex}\r\n\t\t\t\t\t\tborderStyle={block.style?.border}\r\n\t\t\t\t\t\tsubZIndex={blockSubZIndex.border}\r\n\t\t\t\t\t\tvisible={showBorder}\r\n\t\t\t\t\t\tdpi={dpi}\r\n\t\t\t\t\t/>\r\n\t\t\t\t</div>\r\n\t\t\t);\r\n\t\t},\r\n\t),\r\n);\r\n\r\nBlockContainer.displayName = \"BlockContainer\";\r\n","import { memo, useRef } from \"react\";\r\n\r\nimport { BlockContainer } from \"./BlockContainer\";\r\nimport { DEFAULT_GUIDE_BORDER } from \"./BlockGuideBorder\";\r\n\r\nimport { DEFAULT_DPI } from \"@/constants\";\r\nimport { BLOCK_SUB_INDEX, getBlockZIndex, Z_INDEX } from \"@/utils/zIndex\";\r\n\r\nimport type { BlockPlugin, BlockRef } from \"@/plugin\";\r\nimport type { Block, BlockRectPx } from \"@/types/block\";\r\nimport type { OnBlur, OnChange } from \"@/types/callbacks\";\r\nimport type { BorderStyle } from \"@/types/line\";\r\nimport type { NoteMode } from \"@/types/mode\";\r\nimport type { Value } from \"@/types/value\";\r\n\r\nexport interface BlockLayerProps {\r\n\tblocks: Block[];\r\n\tpluginRegistry: Record<string, BlockPlugin>;\r\n\tmode: NoteMode;\r\n\tvalues: Record<string, Value>;\r\n\tselectedBlockIds?: string[];\r\n\tgetBlockRectPx: (block: Block) => BlockRectPx;\r\n\tonValueChange?: OnChange;\r\n\tonValueBlur?: OnBlur;\r\n\tshowGuides?: boolean;\r\n\tshowBorder?: boolean;\r\n\tblockSubZIndex?: Record<string, number>;\r\n\tdefaultGuideBorder?: BorderStyle;\r\n\tdpi?: number;\r\n\tclassName?: string;\r\n}\r\n\r\nexport const BlockLayer = memo(\r\n\t({\r\n\t\tblocks,\r\n\t\tpluginRegistry,\r\n\t\tmode,\r\n\t\tvalues,\r\n\t\tselectedBlockIds = [],\r\n\t\tgetBlockRectPx,\r\n\t\tonValueChange,\r\n\t\tonValueBlur,\r\n\t\tshowGuides = true,\r\n\t\tshowBorder = true,\r\n\t\tblockSubZIndex = {\r\n\t\t\tbg: BLOCK_SUB_INDEX.BG,\r\n\t\t\tguide: BLOCK_SUB_INDEX.GUIDE,\r\n\t\t\tcontent: BLOCK_SUB_INDEX.CONTENT,\r\n\t\t\tborder: BLOCK_SUB_INDEX.BORDER,\r\n\t\t},\r\n\t\tdefaultGuideBorder = DEFAULT_GUIDE_BORDER,\r\n\t\tdpi = DEFAULT_DPI,\r\n\t\tclassName = \"\",\r\n\t}: BlockLayerProps) => {\r\n\t\tconst blockRefs = useRef<Map<string, BlockRef>>(new Map());\r\n\r\n\t\tconst layerStyle: React.CSSProperties = {\r\n\t\t\tposition: \"absolute\",\r\n\t\t\tinset: 0,\r\n\t\t\tpointerEvents: \"none\",\r\n\t\t};\r\n\r\n\t\treturn (\r\n\t\t\t<div className={className} style={layerStyle} data-testid=\"block-layer\">\r\n\t\t\t\t{blocks.map((block, index) => {\r\n\t\t\t\t\tconst plugin = pluginRegistry[block.kind];\r\n\t\t\t\t\tif (!plugin) return null;\r\n\r\n\t\t\t\t\tconst blockRectPx = getBlockRectPx(block);\r\n\t\t\t\t\tconst isSelected = selectedBlockIds.includes(block.id);\r\n\r\n\t\t\t\t\tlet blockZIndex = getBlockZIndex(index);\r\n\t\t\t\t\tif (isSelected) {\r\n\t\t\t\t\t\tblockZIndex = Z_INDEX.SELECT_BLOCK;\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tconst value = values[block.id] ?? block.initValue;\r\n\t\t\t\t\treturn (\r\n\t\t\t\t\t\t<BlockContainer\r\n\t\t\t\t\t\t\tkey={block.id}\r\n\t\t\t\t\t\t\tref={(ref) => {\r\n\t\t\t\t\t\t\t\tif (ref) blockRefs.current.set(block.id, ref);\r\n\t\t\t\t\t\t\t\telse blockRefs.current.delete(block.id);\r\n\t\t\t\t\t\t\t}}\r\n\t\t\t\t\t\t\tblock={block}\r\n\t\t\t\t\t\t\tplugin={plugin}\r\n\t\t\t\t\t\t\tblockRectPx={blockRectPx}\r\n\t\t\t\t\t\t\tblockZIndex={blockZIndex}\r\n\t\t\t\t\t\t\tmode={mode}\r\n\t\t\t\t\t\t\tvalue={value}\r\n\t\t\t\t\t\t\tonValueChange={\r\n\t\t\t\t\t\t\t\tonValueChange\r\n\t\t\t\t\t\t\t\t\t? (val) => onValueChange(block.id, val)\r\n\t\t\t\t\t\t\t\t\t: undefined\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\tonValueBlur={(val) => onValueBlur?.(block.id, val)}\r\n\t\t\t\t\t\t\tshowGuides={showGuides}\r\n\t\t\t\t\t\t\tshowBorder={showBorder}\r\n\t\t\t\t\t\t\tblockSubZIndex={blockSubZIndex}\r\n\t\t\t\t\t\t\tdefaultGuideBorder={defaultGuideBorder}\r\n\t\t\t\t\t\t\tdpi={dpi}\r\n\t\t\t\t\t\t\tpointerEvents=\"none\"\r\n\t\t\t\t\t\t/>\r\n\t\t\t\t\t);\r\n\t\t\t\t})}\r\n\t\t\t</div>\r\n\t\t);\r\n\t},\r\n);\r\n\r\nBlockLayer.displayName = \"BlockLayer\";\r\n","/**\r\n * @file BorderOverlay.tsx\r\n * @description 印刷可能領域の境界線オーバーレイコンポーネント\r\n * @z-index 3 (GridLayerの最上層)\r\n */\r\n\r\nimport { memo, useMemo } from \"react\";\r\nimport { Border } from \"@types\";\r\n\r\nimport { BorderRenderer } from \"@/canvas/components/BorderRenderer\";\r\nimport { DEFAULT_DPI } from \"@/constants\";\r\nimport { Z_INDEX } from \"@/utils/zIndex\";\r\n\r\nimport type { PaperContentPx } from \"@types\";\r\nimport type React from \"react\";\r\nimport type { BorderStyle } from \"@/types/line/types\";\r\n\r\n/**\r\n * BorderOverlayコンポーネントのProps\r\n */\r\nexport interface BorderOverlayProps {\r\n\tcontentPx: PaperContentPx; // コンテンツエリア(印刷可能領域)のサイズ(px)\r\n\tmarginLeftPx: number; // 左マージン(px) - SVGの配置位置調整用\r\n\tmarginTopPx: number; // 上マージン(px) - SVGの配置位置調整用\r\n\tborderStyle?: BorderStyle; // 境界線スタイル\r\n\tvisible?: boolean; // 表示/非表示\r\n\tdpi?: number; // DPI(デフォルト: DEFAULT_DPI)\r\n\tzIndex?: number; // z-index(デフォルト: Z_INDEX.BORDER_OVERLAY)\r\n\tclassName?: string; // 追加のクラス名\r\n}\r\n\r\n/**\r\n * BorderOverlay\r\n *\r\n * 印刷可能領域の境界線をSVGで描画するオーバーレイコンポーネント\r\n * - z-index: 3 (GridLayerの最上層)\r\n * - pointer-events: none (クリックイベント透過)\r\n * - 印刷可能領域の4辺に境界線を描画\r\n *\r\n * @remarks\r\n * - 境界線は印刷可能領域(contentArea)の外枠に描画される\r\n * - 個別設定(topBorderStyle等)が優先され、なければborderStyleを使用\r\n * - すべてのスタイルが未指定の場合、その辺は描画されない\r\n */\r\nexport const BorderOverlay: React.FC<BorderOverlayProps> = memo(\r\n\t({\r\n\t\tcontentPx,\r\n\t\tmarginLeftPx,\r\n\t\tmarginTopPx,\r\n\t\tborderStyle,\r\n\t\tvisible = true,\r\n\t\tdpi = DEFAULT_DPI,\r\n\t\tzIndex = Z_INDEX.BORDER_OVERLAY,\r\n\t\tclassName = \"\",\r\n\t}) => {\r\n\t\tconst border: Border | undefined = useMemo(() => {\r\n\t\t\tif (!borderStyle) return undefined;\r\n\t\t\treturn new Border(borderStyle);\r\n\t\t}, [borderStyle]);\r\n\r\n\t\tif (!visible || !border || !border.hasAnyBorder) return null;\r\n\r\n\t\tconst overlayStyle: React.CSSProperties = {\r\n\t\t\tposition: \"absolute\",\r\n\t\t\tleft: `${marginLeftPx}px`,\r\n\t\t\ttop: `${marginTopPx}px`,\r\n\t\t\twidth: `${contentPx.width}px`,\r\n\t\t\theight: `${contentPx.height}px`,\r\n\t\t\tpointerEvents: \"none\",\r\n\t\t\toverflow: \"visible\",\r\n\t\t\tzIndex,\r\n\t\t};\r\n\r\n\t\treturn (\r\n\t\t\t<div\r\n\t\t\t\tclassName={className}\r\n\t\t\t\tstyle={overlayStyle}\r\n\t\t\t\tdata-testid=\"border-overlay\"\r\n\t\t\t>\r\n\t\t\t\t<BorderRenderer\r\n\t\t\t\t\twidth={contentPx.width}\r\n\t\t\t\t\theight={contentPx.height}\r\n\t\t\t\t\tborder={border}\r\n\t\t\t\t\tdpi={dpi}\r\n\t\t\t\t/>\r\n\t\t\t</div>\r\n\t\t);\r\n\t},\r\n);\r\n","/**\r\n * @file GridCanvas.tsx\r\n * @description 用紙背景描画コンポーネント\r\n * @z-index 0 (GridLayerの最下層)\r\n */\r\n\r\nimport { memo } from \"react\";\r\n\r\nimport { Z_INDEX } from \"@/utils/zIndex\";\r\n\r\nimport type { PaperCanvasPx } from \"@/types\";\r\n\r\n/**\r\n * GridCanvasコンポーネントのProps\r\n */\r\nexport interface GridCanvasProps {\r\n\tcanvasPx: PaperCanvasPx; // 用紙キャンバスのサイズ(px)\r\n\tbackgroundColor?: string; // 用紙の背景色\r\n\tboxShadow?: string; // 用紙のボックスシャドウ\r\n\tzIndex?: number; // z-index(デフォルト: Z_INDEX.GRID_CANVAS)\r\n\tclassName?: string; // 追加のクラス名\r\n}\r\n\r\n/**\r\n * GridCanvas\r\n *\r\n * 用紙背景を描画するコンポーネント\r\n * - z-index: 0 (GridLayerの最下層)\r\n * - pointer-events: none (クリックイベント透過)\r\n * - 白い用紙背景を表示\r\n */\r\nexport const GridCanvas: React.FC<GridCanvasProps> = memo(\r\n\t({\r\n\t\tcanvasPx,\r\n\t\tbackgroundColor = \"#ffffff\",\r\n\t\tboxShadow = \"0 2px 8px rgba(0, 0, 0, 0.1)\",\r\n\t\tzIndex = Z_INDEX.GRID_CANVAS,\r\n\t\tclassName,\r\n\t}) => {\r\n\t\tconst canvasStyle: React.CSSProperties = {\r\n\t\t\tposition: \"absolute\",\r\n\t\t\tinset: 0,\r\n\t\t\twidth: `${canvasPx.width}px`,\r\n\t\t\theight: `${canvasPx.height}px`,\r\n\t\t\tbackgroundColor,\r\n\t\t\tboxShadow,\r\n\t\t\tpointerEvents: \"none\",\r\n\t\t\tzIndex: zIndex,\r\n\t\t};\r\n\r\n\t\treturn (\r\n\t\t\t<div\r\n\t\t\t\tclassName={className}\r\n\t\t\t\tstyle={canvasStyle}\r\n\t\t\t\trole=\"presentation\"\r\n\t\t\t\taria-label=\"Paper background\"\r\n\t\t\t\tdata-testid=\"grid-canvas\"\r\n\t\t\t/>\r\n\t\t);\r\n\t},\r\n);\r\n","// 文字列を寸法オブジェクトに変換\r\n\r\nimport { assertNonNegative } from \"../assert\";\r\n\r\nimport type { Dimension, Unit } from \"@/types/unit\";\r\n\r\n// 文字列を寸法オブジェクトに変換\r\nexport function stringToDimension<U extends Unit>(\r\n\tstr: string,\r\n\tallowedUnits: readonly U[],\r\n): Dimension<U> {\r\n\tconst match = str.match(/^(\\d+(?:\\.\\d+)?)([a-zA-Z%]+)$/);\r\n\tif (!match) {\r\n\t\tthrow new Error(`Invalid dimension string: ${str}`);\r\n\t}\r\n\r\n\tconst value = Number(match[1]);\r\n\tconst unit = match[2] as U;\r\n\r\n\tassertNonNegative(value, `Dimension value`);\r\n\tif (!allowedUnits.includes(unit)) {\r\n\t\tthrow new Error(`Unit not allowed: ${unit}`);\r\n\t}\r\n\r\n\treturn { value, unit };\r\n}\r\n\r\n// 文字列の配列を寸法オブジェクトの配列に変換\r\nexport function stringsToDimensions<U extends Unit>(\r\n\tstrs: string[],\r\n\tallowedUnits: readonly U[],\r\n): Dimension<U>[] {\r\n\treturn strs.map((str) => stringToDimension(str, allowedUnits));\r\n}\r\n","import { assertNonNegative } from \"../assert/number\";\r\n\r\nimport type { Dimension, Unit } from \"@/types\";\r\n\r\nconst CM_TO_MM = 10;\r\nconst INCH_TO_MM = 25.4;\r\nconst PT_TO_MM = 0.352778;\r\nconst PX_TO_MM = 0.264583;\r\n\r\nexport const toMm = {\r\n\tfromCm(cm: number): number {\r\n\t\tassertNonNegative(cm, `Centimeter value`);\r\n\t\treturn cm * CM_TO_MM;\r\n\t},\r\n\r\n\tfromInch(inch: number): number {\r\n\t\tassertNonNegative(inch, `Inch value`);\r\n\t\treturn inch * INCH_TO_MM;\r\n\t},\r\n\r\n\tfromPt(pt: number): number {\r\n\t\tassertNonNegative(pt, `Point value`);\r\n\t\treturn pt * PT_TO_MM;\r\n\t},\r\n\r\n\t// データ上のpxはDPI=96として扱う\r\n\tfromPx(px: number): number {\r\n\t\tassertNonNegative(px, `Pixel value`);\r\n\t\treturn px * PX_TO_MM;\r\n\t},\r\n\r\n\tfromDim<U extends Unit>(dim: Dimension<U>): number {\r\n\t\tassertNonNegative(dim.value, `Dimension value`);\r\n\t\tswitch (dim.unit) {\r\n\t\t\tcase \"mm\":\r\n\t\t\t\treturn dim.value;\r\n\t\t\tcase \"cm\":\r\n\t\t\t\treturn toMm.fromCm(dim.value);\r\n\t\t\tcase \"inch\":\r\n\t\t\t\treturn toMm.fromInch(dim.value);\r\n\t\t\tcase \"pt\":\r\n\t\t\t\treturn toMm.fromPt(dim.value);\r\n\t\t\tcase \"px\":\r\n\t\t\t\treturn toMm.fromPx(dim.value);\r\n\t\t\tcase \"fr\":\r\n\t\t\tcase \"%\":\r\n\t\t\t\tthrow new Error(\r\n\t\t\t\t\t`Cannot convert ${dim.unit} to mm. Use physical units only.`,\r\n\t\t\t\t);\r\n\t\t\tdefault: {\r\n\t\t\t\tconst _exhaustive: never = dim.unit;\r\n\t\t\t\tthrow new Error(`Unsupported unit: ${_exhaustive}`);\r\n\t\t\t}\r\n\t\t}\r\n\t},\r\n};\r\n","// 寸法オブジェクトを文字列に変換\r\n\r\nimport { assertNonNegative } from \"@/utils/assert/number\";\r\n\r\nimport type { Dimension, Unit } from \"@/types/unit\";\r\n\r\n// 寸法オブジェクトを文字列に変換\r\nexport function dimensionToString<U extends Unit>(dim: Dimension<U>): string {\r\n\tassertNonNegative(dim.value, \"Dimension\");\r\n\treturn `${dim.value}${dim.unit}`;\r\n}\r\n\r\n// 寸法オブジェクトの配列を文字列の配列に変換\r\nexport function dimensionsToStrings<U extends Unit>(\r\n\tdims: Dimension<U>[],\r\n): string[] {\r\n\treturn dims.map(dimensionToString);\r\n}\r\n","/**\r\n * @file GridUnitEditor.tsx\r\n * @description グリッド寸法の単位を編集するポップアップUIコンポーネント\r\n */\r\n\r\nimport { memo, useEffect, useRef, useState } from \"react\";\r\n\r\nimport styles from \"./GridUnitEditor.module.css\";\r\n\r\nimport { toMm } from \"@/utils/convert\";\r\n\r\nimport type { Dimension, GridUnit } from \"@types\";\r\n\r\nexport interface GridUnitEditorProps {\r\n\t/** エディタの方向 */\r\n\tdirection: \"column\" | \"row\";\r\n\t/** 現在の寸法 */\r\n\tdimension: Dimension<GridUnit>;\r\n\t/** 現在のpxサイズ(単位変換用) */\r\n\tcurrentPxSize: number;\r\n\t/** エディタの位置 (px) */\r\n\tposition: number;\r\n\t/** 印刷可能領域の左マージン (px) */\r\n\tmarginLeftPx: number;\r\n\t/** 印刷可能領域の上マージン (px) */\r\n\tmarginTopPx: number;\r\n\t/** 寸法変更時のコールバック */\r\n\tonChange: (dimension: Dimension<GridUnit>) => void;\r\n\t/** キャンセル時のコールバック */\r\n\tonCancel: () => void;\r\n}\r\n\r\nconst SUPPORTED_UNITS: GridUnit[] = [\"fr\", \"px\", \"mm\", \"cm\", \"pt\", \"inch\"];\r\n\r\n/**\r\n * 単位変換: 現在のpxサイズから新しい単位の値を計算\r\n */\r\nfunction convertPxToUnit(pxSize: number, targetUnit: GridUnit): number {\r\n\tif (targetUnit === \"fr\") {\r\n\t\t// frは比率なので、元の値を保持\r\n\t\treturn 1;\r\n\t}\r\n\r\n\tswitch (targetUnit) {\r\n\t\tcase \"px\":\r\n\t\t\t// pxはそのまま(DPI=96基準)\r\n\t\t\treturn pxSize;\r\n\t\tcase \"mm\": {\r\n\t\t\tconst mm = toMm.fromPx(pxSize);\r\n\t\t\treturn Math.round(mm * 10) / 10; // 小数第1位まで\r\n\t\t}\r\n\t\tcase \"cm\": {\r\n\t\t\tconst mm = toMm.fromPx(pxSize);\r\n\t\t\tconst cm = mm / 10;\r\n\t\t\treturn Math.round(cm * 100) / 100; // 小数第2位まで\r\n\t\t}\r\n\t\tcase \"inch\": {\r\n\t\t\tconst mm = toMm.fromPx(pxSize);\r\n\t\t\tconst inch = mm / 25.4;\r\n\t\t\treturn Math.round(inch * 100) / 100; // 小数第2位まで\r\n\t\t}\r\n\t\tcase \"pt\": {\r\n\t\t\tconst mm = toMm.fromPx(pxSize);\r\n\t\t\tconst inch = mm / 25.4;\r\n\t\t\tconst pt = inch * 72;\r\n\t\t\treturn Math.round(pt * 10) / 10; // 小数第1位まで\r\n\t\t}\r\n\t\tdefault: {\r\n\t\t\tconst _exhaustive: never = targetUnit;\r\n\t\t\tthrow new Error(`Unsupported unit: ${_exhaustive}`);\r\n\t\t}\r\n\t}\r\n}\r\n\r\n/**\r\n * GridUnitEditor - グリッド寸法編集UI\r\n *\r\n * グリッド線間の寸法を編集するためのポップアップUIです。\r\n */\r\nexport const GridUnitEditor = memo(\r\n\t({\r\n\t\tdirection,\r\n\t\tdimension,\r\n\t\tcurrentPxSize,\r\n\t\tposition,\r\n\t\tmarginLeftPx,\r\n\t\tmarginTopPx,\r\n\t\tonChange,\r\n\t\tonCancel,\r\n\t}: GridUnitEditorProps) => {\r\n\t\tconst [value, setValue] = useState(dimension.value.toString());\r\n\t\tconst [unit, setUnit] = useState<GridUnit>(dimension.unit as GridUnit);\r\n\t\tconst inputRef = useRef<HTMLInputElement>(null);\r\n\t\tconst containerRef = useRef<HTMLDivElement>(null);\r\n\r\n\t\t// エディタの表示位置\r\n\t\tconst editorStyle: React.CSSProperties =\r\n\t\t\tdirection === \"column\"\r\n\t\t\t\t? {\r\n\t\t\t\t\t\tleft: `${marginLeftPx + position}px`,\r\n\t\t\t\t\t\ttop: `${marginTopPx + 24}px`,\r\n\t\t\t\t\t\ttransform: \"translateX(-50%)\",\r\n\t\t\t\t\t}\r\n\t\t\t\t: {\r\n\t\t\t\t\t\tleft: `${marginLeftPx + 24}px`,\r\n\t\t\t\t\t\ttop: `${marginTopPx + position}px`,\r\n\t\t\t\t\t\ttransform: \"translateY(-50%)\",\r\n\t\t\t\t\t};\r\n\r\n\t\t// マウント時にinputにフォーカス\r\n\t\tuseEffect(() => {\r\n\t\t\tinputRef.current?.focus();\r\n\t\t\tinputRef.current?.select();\r\n\t\t}, []);\r\n\r\n\t\t// 外部クリックでキャンセル\r\n\t\tuseEffect(() => {\r\n\t\t\tconst handleClickOutside = (event: MouseEvent) => {\r\n\t\t\t\tif (\r\n\t\t\t\t\tcontainerRef.current &&\r\n\t\t\t\t\t!containerRef.current.contains(event.target as Node)\r\n\t\t\t\t) {\r\n\t\t\t\t\tonCancel();\r\n\t\t\t\t}\r\n\t\t\t};\r\n\r\n\t\t\tdocument.addEventListener(\"mousedown\", handleClickOutside);\r\n\t\t\treturn () => {\r\n\t\t\t\tdocument.removeEventListener(\"mousedown\", handleClickOutside);\r\n\t\t\t};\r\n\t\t}, [onCancel]);\r\n\r\n\t\tconst handleSubmit = () => {\r\n\t\t\tconst numValue = Number.parseFloat(value);\r\n\t\t\tif (!Number.isNaN(numValue) && numValue >= 0.1) {\r\n\t\t\t\tonChange({ unit, value: numValue });\r\n\t\t\t} else {\r\n\t\t\t\tonCancel();\r\n\t\t\t}\r\n\t\t};\r\n\r\n\t\tconst handleKeyDown = (e: React.KeyboardEvent) => {\r\n\t\t\tif (e.key === \"Enter\") {\r\n\t\t\t\te.preventDefault();\r\n\t\t\t\thandleSubmit();\r\n\t\t\t} else if (e.key === \"Escape\") {\r\n\t\t\t\te.preventDefault();\r\n\t\t\t\tonCancel();\r\n\t\t\t}\r\n\t\t};\r\n\r\n\t\tconst handleUnitChange = (e: React.ChangeEvent<HTMLSelectElement>) => {\r\n\t\t\tconst newUnit = e.target.value as GridUnit;\r\n\t\t\tsetUnit(newUnit);\r\n\r\n\t\t\t// 単位変更時: 現在のpxサイズから新しい単位に変換\r\n\t\t\tconst convertedValue = convertPxToUnit(currentPxSize, newUnit);\r\n\t\t\tsetValue(convertedValue.toString());\r\n\t\t};\r\n\t\treturn (\r\n\t\t\t<div\r\n\t\t\t\tref={containerRef}\r\n\t\t\t\tclassName={styles.editor}\r\n\t\t\t\tstyle={editorStyle}\r\n\t\t\t\tdata-testid={`grid-unit-editor-${direction}`}\r\n\t\t\t>\r\n\t\t\t\t<input\r\n\t\t\t\t\tref={inputRef}\r\n\t\t\t\t\ttype=\"number\"\r\n\t\t\t\t\tclassName={styles.input}\r\n\t\t\t\t\tvalue={value}\r\n\t\t\t\t\tonChange={(e) => setValue(e.target.value)}\r\n\t\t\t\t\tonKeyDown={handleKeyDown}\r\n\t\t\t\t\tmin=\"0.1\"\r\n\t\t\t\t\tstep={unit === \"fr\" ? \"0.1\" : \"1\"}\r\n\t\t\t\t/>\r\n\t\t\t\t<select\r\n\t\t\t\t\tclassName={styles.select}\r\n\t\t\t\t\tvalue={unit}\r\n\t\t\t\t\tonChange={handleUnitChange}\r\n\t\t\t\t>\r\n\t\t\t\t\t{SUPPORTED_UNITS.map((u) => (\r\n\t\t\t\t\t\t<option key={u} value={u}>\r\n\t\t\t\t\t\t\t{u}\r\n\t\t\t\t\t\t</option>\r\n\t\t\t\t\t))}\r\n\t\t\t\t</select>\r\n\t\t\t\t<button\r\n\t\t\t\t\ttype=\"button\"\r\n\t\t\t\t\tclassName={styles.button}\r\n\t\t\t\t\tonClick={handleSubmit}\r\n\t\t\t\t\ttitle=\"確定\"\r\n\t\t\t\t>\r\n\t\t\t\t\t✓\r\n\t\t\t\t</button>\r\n\t\t\t</div>\r\n\t\t);\r\n\t},\r\n);\r\n\r\nGridUnitEditor.displayName = \"GridUnitEditor\";\r\n","/**\r\n * @file GridDimensionLabel.tsx\r\n * @description グリッド線間の寸法を表示するラベルコンポーネント\r\n */\r\n\r\nimport { memo, useState } from \"react\";\r\n\r\nimport styles from \"./GridDimensionLabel.module.css\";\r\nimport { GridUnitEditor } from \"./GridUnitEditor\";\r\n\r\nimport { toMm } from \"@/utils/convert\";\r\n\r\nimport type { Dimension, GridUnit } from \"@types\";\r\n\r\nexport interface GridDimensionLabelProps {\r\n\t/** ラベルの方向 ('column' or 'row') */\r\n\tdirection: \"column\" | \"row\";\r\n\t/** 次元のインデックス(配列のインデックス) */\r\n\tindex: number;\r\n\t/** 寸法の値(Dimensionオブジェクト) */\r\n\tdimension: Dimension<GridUnit>;\r\n\t/** ラベルの位置 (px) - 中央座標 */\r\n\tposition: number;\r\n\t/** 現在のpxサイズ(単位変換用) */\r\n\tcurrentPxSize: number;\r\n\t/** 印刷可能領域の左マージン (px) */\r\n\tmarginLeftPx: number;\r\n\t/** 印刷可能領域の上マージン (px) */\r\n\tmarginTopPx: number;\r\n\t/** カーソルが近い場合にのみ表示 */\r\n\tisNearCursor: boolean;\r\n\t/** リサイズ中のプレビューサイズ(px) - 指定時は単位変換して表示 */\r\n\tresizingPxSize?: number;\r\n\t/** 寸法更新時のコールバック */\r\n\tonDimensionChange?: (\r\n\t\tdirection: \"column\" | \"row\",\r\n\t\tindex: number,\r\n\t\tdimension: Dimension<GridUnit>,\r\n\t) => void;\r\n}\r\n\r\n/**\r\n * px値を指定単位に変換\r\n * @param pxSize - 変換するpxサイズ\r\n * @param targetUnit - 変換先の単位\r\n * @param originalValue - 元の値(fr計算用)\r\n * @param originalPxSize - 元のpxサイズ(fr計算用)\r\n */\r\nfunction convertPxToUnit(\r\n\tpxSize: number,\r\n\ttargetUnit: GridUnit,\r\n\toriginalValue?: number,\r\n\toriginalPxSize?: number,\r\n): number {\r\n\tif (targetUnit === \"fr\") {\r\n\t\t// frは比率なので、元のサイズとの比率から計算\r\n\t\tif (\r\n\t\t\toriginalValue !== undefined &&\r\n\t\t\toriginalPxSize !== undefined &&\r\n\t\t\toriginalPxSize > 0\r\n\t\t) {\r\n\t\t\tconst ratio = pxSize / originalPxSize;\r\n\t\t\treturn Math.round(originalValue * ratio * 100) / 100;\r\n\t\t}\r\n\t\treturn 1;\r\n\t}\r\n\r\n\tswitch (targetUnit) {\r\n\t\tcase \"px\":\r\n\t\t\treturn Math.round(pxSize);\r\n\t\tcase \"mm\": {\r\n\t\t\tconst mm = toMm.fromPx(pxSize);\r\n\t\t\treturn Math.round(mm * 10) / 10;\r\n\t\t}\r\n\t\tcase \"cm\": {\r\n\t\t\tconst mm = toMm.fromPx(pxSize);\r\n\t\t\treturn Math.round((mm / 10) * 100) / 100;\r\n\t\t}\r\n\t\tcase \"inch\": {\r\n\t\t\tconst mm = toMm.fromPx(pxSize);\r\n\t\t\treturn Math.round((mm / 25.4) * 100) / 100;\r\n\t\t}\r\n\t\tcase \"pt\": {\r\n\t\t\tconst mm = toMm.fromPx(pxSize);\r\n\t\t\treturn Math.round((mm / 25.4) * 72 * 10) / 10;\r\n\t\t}\r\n\t\tdefault: {\r\n\t\t\tconst _exhaustive: never = targetUnit;\r\n\t\t\tthrow new Error(`Unsupported unit: ${_exhaustive}`);\r\n\t\t}\r\n\t}\r\n}\r\n\r\n/**\r\n * GridDimensionLabel - グリッド線間の寸法表示\r\n *\r\n * グリッド線と線の間に寸法(値と単位)を表示します。\r\n * ダブルクリックで単位編集UIを表示します。\r\n */\r\nexport const GridDimensionLabel = memo(\r\n\t({\r\n\t\tdirection,\r\n\t\tindex,\r\n\t\tdimension,\r\n\t\tposition,\r\n\t\tcurrentPxSize,\r\n\t\tmarginLeftPx,\r\n\t\tmarginTopPx,\r\n\t\tisNearCursor,\r\n\t\tresizingPxSize,\r\n\t\tonDimensionChange,\r\n\t}: GridDimensionLabelProps) => {\r\n\t\tconst [isEditing, setIsEditing] = useState(false);\r\n\r\n\t\t// カーソルが近くないか編集中でなければ非表示\r\n\t\tif (!isNearCursor && !isEditing) {\r\n\t\t\treturn null;\r\n\t\t}\r\n\r\n\t\t// ラベルの表示スタイル(キャンバス外に配置)\r\n\t\tconst labelStyle: React.CSSProperties =\r\n\t\t\tdirection === \"column\"\r\n\t\t\t\t? {\r\n\t\t\t\t\t\t// 列のラベル: 上端外側に水平表示\r\n\t\t\t\t\t\tleft: `${marginLeftPx + position}px`,\r\n\t\t\t\t\t\ttop: `${marginTopPx - 20}px`, // キャンバス外(上)\r\n\t\t\t\t\t\ttransform: \"translateX(-50%)\",\r\n\t\t\t\t\t}\r\n\t\t\t\t: {\r\n\t\t\t\t\t\t// 行のラベル: 左端外側に垂直表示\r\n\t\t\t\t\t\tleft: `${marginLeftPx - 20}px`, // キャンバス外(左)\r\n\t\t\t\t\t\ttop: `${marginTopPx + position}px`,\r\n\t\t\t\t\t\ttransform: \"translateY(-50%)\",\r\n\t\t\t\t\t\twritingMode: \"vertical-rl\",\r\n\t\t\t\t\t};\r\n\r\n\t\tconst handleDoubleClick = () => {\r\n\t\t\tsetIsEditing(true);\r\n\t\t};\r\n\r\n\t\tconst handleDimensionChange = (newDimension: Dimension<GridUnit>) => {\r\n\t\t\tonDimensionChange?.(direction, index, newDimension);\r\n\t\t\tsetIsEditing(false);\r\n\t\t};\r\n\r\n\t\tconst handleCancel = () => {\r\n\t\t\tsetIsEditing(false);\r\n\t\t};\r\n\r\n\t\t// 寸法のフォーマット表示\r\n\t\tconst formatDimension = (dim: Dimension<GridUnit>): string => {\r\n\t\t\tif (dim.unit === \"fr\") {\r\n\t\t\t\treturn `${dim.value}fr`;\r\n\t\t\t}\r\n\t\t\treturn `${dim.value}${dim.unit}`;\r\n\t\t};\r\n\r\n\t\t// リサイズ中はプレビュー表示(元の単位に変換)\r\n\t\tconst displayText = resizingPxSize\r\n\t\t\t? (() => {\r\n\t\t\t\t\tconst convertedValue = convertPxToUnit(\r\n\t\t\t\t\t\tresizingPxSize,\r\n\t\t\t\t\t\tdimension.unit,\r\n\t\t\t\t\t\tdimension.value,\r\n\t\t\t\t\t\tcurrentPxSize,\r\n\t\t\t\t\t);\r\n\t\t\t\t\tif (dimension.unit === \"fr\") {\r\n\t\t\t\t\t\treturn `${convertedValue}fr`;\r\n\t\t\t\t\t}\r\n\t\t\t\t\treturn `${convertedValue}${dimension.unit}`;\r\n\t\t\t\t})()\r\n\t\t\t: formatDimension(dimension);\r\n\r\n\t\treturn (\r\n\t\t\t<>\r\n\t\t\t\t<button\r\n\t\t\t\t\ttype=\"button\"\r\n\t\t\t\t\tclassName={styles.label}\r\n\t\t\t\t\tstyle={labelStyle}\r\n\t\t\t\t\tonDoubleClick={handleDoubleClick}\r\n\t\t\t\t\tdata-testid={`grid-dimension-${direction}-${index}`}\r\n\t\t\t\t\taria-label={`グリッド寸法: ${displayText}`}\r\n\t\t\t\t>\r\n\t\t\t\t\t{displayText}\r\n\t\t\t\t</button>{\" \"}\r\n\t\t\t\t{isEditing && (\r\n\t\t\t\t\t<GridUnitEditor\r\n\t\t\t\t\t\tdirection={direction}\r\n\t\t\t\t\t\tdimension={dimension}\r\n\t\t\t\t\t\tcurrentPxSize={currentPxSize}\r\n\t\t\t\t\t\tposition={position}\r\n\t\t\t\t\t\tmarginLeftPx={marginLeftPx}\r\n\t\t\t\t\t\tmarginTopPx={marginTopPx}\r\n\t\t\t\t\t\tonChange={handleDimensionChange}\r\n\t\t\t\t\t\tonCancel={handleCancel}\r\n\t\t\t\t\t/>\r\n\t\t\t\t)}\r\n\t\t\t</>\r\n\t\t);\r\n\t},\r\n);\r\n\r\nGridDimensionLabel.displayName = \"GridDimensionLabel\";\r\n","// グリッド線用のPathデータ(d属性)を生成する関数\r\n\r\nexport function getGridPathD(\r\n\tcolPxs: number[],\r\n\trowPxs: number[],\r\n\twidth: number,\r\n\theight: number,\r\n): string {\r\n\tlet d = \"\";\r\n\r\n\t// 縦線のコマンド生成 (Move to -> Line to)\r\n\tfor (const x of colPxs) {\r\n\t\t// 小数点以下のズレによる滲みを防ぐため Math.round や toFixed を使う場合もあります\r\n\t\td += `M ${x} 0 L ${x} ${height} `;\r\n\t}\r\n\r\n\t// 横線のコマンド生成\r\n\tfor (const y of rowPxs) {\r\n\t\td += `M 0 ${y} L ${width} ${y} `;\r\n\t}\r\n\r\n\treturn d;\r\n}\r\n","/**\r\n * @file GridOverlay.tsx\r\n * @description グリッド線オーバーレイコンポーネント\r\n * @z-index 2 (GridLayerの最上層)\r\n */\r\n\r\nimport { memo, useMemo } from \"react\";\r\nimport { getStrokeDasharray } from \"@types\";\r\n\r\nimport { getGridPathD } from \"./getGridPathD\";\r\n\r\nimport { DEFAULT_DPI } from \"@/constants\";\r\nimport { toPx } from \"@/utils/convert/toPx\";\r\nimport { Z_INDEX } from \"@/utils/zIndex\";\r\n\r\nimport type { GridPosPx, LineStyle, PaperContentPx } from \"@types\";\r\nimport type React from \"react\";\r\n\r\n/**\r\n * GridOverlayコンポーネントのProps\r\n */\r\nexport interface GridOverlayProps {\r\n\tgridPosPx: GridPosPx; // グリッド線の位置(px配列)\r\n\tcontentPx: PaperContentPx; // コンテンツエリア(印刷可能領域)のサイズ(px)\r\n\tmarginLeftPx: number; // 左マージン(px) - SVGの配置位置調整用\r\n\tmarginTopPx: number; // 上マージン(px) - SVGの配置位置調整用\r\n\tlineStyle?: LineStyle; // グリッド線のスタイル\r\n\tvisible?: boolean; // 表示/非表示\r\n\tzIndex?: number; // z-index(デフォルト: Z_INDEX.GRID_OVERLAY)\r\n\tdpi?: number; // DPI(デフォルト: DEFAULT_DPI)\r\n\tclassName?: string; // 追加のクラス名\r\n}\r\n\r\n/**\r\n * GridOverlay\r\n *\r\n * グリッド線をSVGで描画するオーバーレイコンポーネント\r\n * - z-index: 2 (GridLayerの最上層)\r\n * - pointer-events: none (クリックイベント透過)\r\n * - コンテンツエリア(印刷可能領域)内にグリッド線を描画\r\n */\r\nexport const GridOverlay: React.FC<GridOverlayProps> = memo(\r\n\t({\r\n\t\tgridPosPx,\r\n\t\tcontentPx,\r\n\t\tmarginLeftPx,\r\n\t\tmarginTopPx,\r\n\t\tlineStyle,\r\n\t\tvisible = true,\r\n\t\tzIndex = Z_INDEX.GRID_OVERLAY,\r\n\t\tdpi = DEFAULT_DPI,\r\n\t\tclassName = \"\",\r\n\t}) => {\r\n\t\tconst pathData = useMemo(() => {\r\n\t\t\treturn getGridPathD(\r\n\t\t\t\tgridPosPx.cols.slice(1, -1),\r\n\t\t\t\tgridPosPx.rows.slice(1, -1),\r\n\t\t\t\tcontentPx.width,\r\n\t\t\t\tcontentPx.height,\r\n\t\t\t);\r\n\t\t}, [gridPosPx, contentPx]);\r\n\r\n\t\tif (!visible || !lineStyle) return null;\r\n\r\n\t\tconst strokeDasharray = getStrokeDasharray(lineStyle);\r\n\t\tconst borderWidth = toPx.fromDim(lineStyle.width, dpi);\r\n\r\n\t\t// SVGコンテナのスタイル\r\n\t\tconst svgStyle: React.CSSProperties = {\r\n\t\t\tposition: \"absolute\",\r\n\t\t\tleft: `${marginLeftPx}px`,\r\n\t\t\ttop: `${marginTopPx}px`,\r\n\t\t\tpointerEvents: \"none\",\r\n\t\t\tzIndex: zIndex,\r\n\t\t};\r\n\r\n\t\treturn (\r\n\t\t\t<svg\r\n\t\t\t\tclassName={className}\r\n\t\t\t\tstyle={svgStyle}\r\n\t\t\t\twidth={contentPx.width}\r\n\t\t\t\theight={contentPx.height}\r\n\t\t\t\txmlns=\"http://www.w3.org/2000/svg\"\r\n\t\t\t\trole=\"img\"\r\n\t\t\t\taria-label=\"Grid overlay lines\"\r\n\t\t\t>\r\n\t\t\t\t<path\r\n\t\t\t\t\td={pathData}\r\n\t\t\t\t\tstroke={lineStyle.color}\r\n\t\t\t\t\tstrokeWidth={borderWidth}\r\n\t\t\t\t\tstrokeDasharray={strokeDasharray}\r\n\t\t\t\t\tfill=\"none\"\r\n\t\t\t\t/>\r\n\t\t\t</svg>\r\n\t\t);\r\n\t},\r\n);\r\n","/**\r\n * @file GridResizeHandle.tsx\r\n * @description グリッドリサイズ用のハンドルコンポーネント\r\n */\r\n\r\nimport { memo, useCallback, useState } from \"react\";\r\n\r\nimport styles from \"./GridResizeHandle.module.css\";\r\n\r\nexport interface GridResizeHandleProps {\r\n\t/** ハンドルの方向 ('column' or 'row') */\r\n\tdirection: \"column\" | \"row\";\r\n\t/** グリッドのインデックス (列なら列番号、行なら行番号) */\r\n\tindex: number;\r\n\t/** ハンドルの位置 (px) - グリッド線の位置 */\r\n\tposition: number;\r\n\t/** 印刷可能領域の左マージン (px) */\r\n\tmarginLeftPx: number;\r\n\t/** 印刷可能領域の上マージン (px) */\r\n\tmarginTopPx: number;\r\n\t/** リサイズ開始時のコールバック */\r\n\tonResizeStart?: (direction: \"column\" | \"row\", index: number) => void;\r\n\t/** リサイズ中のコールバック */\r\n\tonResize?: (\r\n\t\tdirection: \"column\" | \"row\",\r\n\t\tindex: number,\r\n\t\tdelta: number,\r\n\t) => void;\r\n\t/** リサイズ終了時のコールバック */\r\n\tonResizeEnd?: (\r\n\t\tdirection: \"column\" | \"row\",\r\n\t\tindex: number,\r\n\t\tdelta: number,\r\n\t) => void;\r\n}\r\n\r\n/**\r\n * GridResizeHandle - グリッドリサイズ用のハンドル\r\n *\r\n * グリッド線の両端にハンドルを配置し、ドラッグでリサイズ可能にします。\r\n * 設計文書に従い、「グリッド線そのもののドラッグは禁止」し、\r\n * 「グリッド線の両端ハンドル」のみをドラッグ可能とします。\r\n */\r\nexport const GridResizeHandle = memo(\r\n\t({\r\n\t\tdirection,\r\n\t\tindex,\r\n\t\tposition,\r\n\t\tmarginLeftPx,\r\n\t\tmarginTopPx,\r\n\t\tonResizeStart,\r\n\t\tonResize,\r\n\t\tonResizeEnd,\r\n\t}: GridResizeHandleProps) => {\r\n\t\tconst [isDragging, setIsDragging] = useState(false);\r\n\r\n\t\t// ハンドルの配置スタイル(端点の外側に配置、ブロックリサイズハンドルと同じデザイン)\r\n\t\tconst HANDLE_SIZE = 12; // ブロックハンドルと同じサイズ\r\n\t\tconst HANDLE_OFFSET = HANDLE_SIZE / 2; // 中央揃え用オフセット\r\n\r\n\t\tconst handleStyle: React.CSSProperties =\r\n\t\t\tdirection === \"column\"\r\n\t\t\t\t? {\r\n\t\t\t\t\t\t// 列のハンドル: 上端の外側に配置\r\n\t\t\t\t\t\tleft: `${marginLeftPx + position - HANDLE_OFFSET}px`,\r\n\t\t\t\t\t\ttop: `${marginTopPx - HANDLE_OFFSET}px`, // キャンバス外(上)\r\n\t\t\t\t\t\twidth: `${HANDLE_SIZE}px`,\r\n\t\t\t\t\t\theight: `${HANDLE_SIZE}px`,\r\n\t\t\t\t\t\tcursor: \"col-resize\",\r\n\t\t\t\t\t}\r\n\t\t\t\t: {\r\n\t\t\t\t\t\t// 行のハンドル: 左端の外側に配置\r\n\t\t\t\t\t\tleft: `${marginLeftPx - HANDLE_OFFSET}px`, // キャンバス外(左)\r\n\t\t\t\t\t\ttop: `${marginTopPx + position - HANDLE_OFFSET}px`,\r\n\t\t\t\t\t\twidth: `${HANDLE_SIZE}px`,\r\n\t\t\t\t\t\theight: `${HANDLE_SIZE}px`,\r\n\t\t\t\t\t\tcursor: \"row-resize\",\r\n\t\t\t\t\t};\r\n\r\n\t\tconst handlePointerDown = useCallback(\r\n\t\t\t(e: React.PointerEvent) => {\r\n\t\t\t\te.stopPropagation();\r\n\t\t\t\te.preventDefault();\r\n\r\n\t\t\t\tconst initialPos = direction === \"column\" ? e.clientX : e.clientY;\r\n\t\t\t\tsetIsDragging(true);\r\n\r\n\t\t\t\tonResizeStart?.(direction, index);\r\n\r\n\t\t\t\t// グローバルなポインターイベントをリスン\r\n\t\t\t\tconst handlePointerMove = (moveEvent: PointerEvent) => {\r\n\t\t\t\t\tconst currentPos =\r\n\t\t\t\t\t\tdirection === \"column\" ? moveEvent.clientX : moveEvent.clientY;\r\n\t\t\t\t\tconst delta = currentPos - initialPos;\r\n\r\n\t\t\t\t\tonResize?.(direction, index, delta);\r\n\t\t\t\t};\r\n\r\n\t\t\t\tconst handlePointerUp = (upEvent: PointerEvent) => {\r\n\t\t\t\t\tconst currentPos =\r\n\t\t\t\t\t\tdirection === \"column\" ? upEvent.clientX : upEvent.clientY;\r\n\t\t\t\t\tconst delta = currentPos - initialPos;\r\n\r\n\t\t\t\t\tsetIsDragging(false);\r\n\t\t\t\t\tonResizeEnd?.(direction, index, delta);\r\n\r\n\t\t\t\t\twindow.removeEventListener(\"pointermove\", handlePointerMove);\r\n\t\t\t\t\twindow.removeEventListener(\"pointerup\", handlePointerUp);\r\n\t\t\t\t};\r\n\r\n\t\t\t\twindow.addEventListener(\"pointermove\", handlePointerMove);\r\n\t\t\t\twindow.addEventListener(\"pointerup\", handlePointerUp);\r\n\t\t\t},\r\n\t\t\t[direction, index, onResizeStart, onResize, onResizeEnd],\r\n\t\t);\r\n\r\n\t\treturn (\r\n\t\t\t<div\r\n\t\t\t\tclassName={`${styles.handle} ${styles[direction]} ${isDragging ? styles.dragging : \"\"}`}\r\n\t\t\t\tstyle={handleStyle}\r\n\t\t\t\tonPointerDown={handlePointerDown}\r\n\t\t\t\tdata-testid={`grid-resize-handle-${direction}-${index}`}\r\n\t\t\t/>\r\n\t\t);\r\n\t},\r\n);\r\n\r\nGridResizeHandle.displayName = \"GridResizeHandle\";\r\n","/**\r\n * @file MarginOverlay.tsx\r\n * @description 用紙マージン表示コンポーネント\r\n * @z-index 1 (GridLayerの中間層)\r\n */\r\n\r\nimport { memo } from \"react\";\r\n\r\nimport { Z_INDEX } from \"@/utils/zIndex\";\r\n\r\nimport type React from \"react\";\r\nimport type { PaperPx } from \"@/types\";\r\n\r\n/**\r\n * MarginOverlayコンポーネントのProps\r\n */\r\nexport interface MarginOverlayProps {\r\n\tpaperPx: PaperPx; // 用紙設定(ピクセル単位)\r\n\tvisible?: boolean; // 表示/非表示\r\n\tmarginColor?: string; // マージン領域の塗りつぶし色\r\n\tzIndex?: number; // z-index(デフォルト: Z_INDEX.MARGIN_OVERLAY)\r\n\tclassName?: string; // 追加のクラス名\r\n}\r\n\r\n/**\r\n * MarginOverlay\r\n *\r\n * 用紙のマージン(印刷不可領域)を視覚的に表示するコンポーネント\r\n * - z-index: 1 (GridCanvasの上、GridOverlayの下)\r\n * - pointer-events: none (クリックイベント透過)\r\n * - 半透明の影でマージン領域を表現\r\n */\r\nexport const MarginOverlay: React.FC<MarginOverlayProps> = memo(\r\n\t({\r\n\t\tpaperPx,\r\n\t\tvisible = true,\r\n\t\tmarginColor,\r\n\t\tzIndex = Z_INDEX.MARGIN_OVERLAY,\r\n\t\tclassName = \"\",\r\n\t}) => {\r\n\t\tif (!visible) return null;\r\n\r\n\t\tconst overlayStyle: React.CSSProperties = {\r\n\t\t\tposition: \"absolute\",\r\n\t\t\tinset: 0,\r\n\t\t\tpointerEvents: \"none\",\r\n\t\t\twidth: `${paperPx.canvas.width}px`,\r\n\t\t\theight: `${paperPx.canvas.height}px`,\r\n\t\t\tzIndex: zIndex,\r\n\t\t};\r\n\r\n\t\tconst marginBoxStyle: React.CSSProperties = {\r\n\t\t\tposition: \"absolute\",\r\n\t\t\tbackgroundColor: marginColor || \"rgba(0, 0, 0, 0.05)\",\r\n\t\t\tpointerEvents: \"none\",\r\n\t\t};\r\n\r\n\t\treturn (\r\n\t\t\t<div\r\n\t\t\t\tclassName={className}\r\n\t\t\t\tstyle={overlayStyle}\r\n\t\t\t\trole=\"presentation\"\r\n\t\t\t\taria-label=\"Printable area margin\"\r\n\t\t\t\tdata-testid=\"margin-overlay\"\r\n\t\t\t>\r\n\t\t\t\t{/* 上マージン */}\r\n\t\t\t\t{paperPx.margin.top > 0 && (\r\n\t\t\t\t\t<div\r\n\t\t\t\t\t\tdata-testid=\"margin-top\"\r\n\t\t\t\t\t\tstyle={{\r\n\t\t\t\t\t\t\t...marginBoxStyle,\r\n\t\t\t\t\t\t\ttop: 0,\r\n\t\t\t\t\t\t\tleft: 0,\r\n\t\t\t\t\t\t\twidth: \"100%\",\r\n\t\t\t\t\t\t\theight: `${paperPx.margin.top}px`,\r\n\t\t\t\t\t\t}}\r\n\t\t\t\t\t/>\r\n\t\t\t\t)}\r\n\r\n\t\t\t\t{/* 下マージン */}\r\n\t\t\t\t{paperPx.margin.bottom > 0 && (\r\n\t\t\t\t\t<div\r\n\t\t\t\t\t\tdata-testid=\"margin-bottom\"\r\n\t\t\t\t\t\tstyle={{\r\n\t\t\t\t\t\t\t...marginBoxStyle,\r\n\t\t\t\t\t\t\tbottom: 0,\r\n\t\t\t\t\t\t\tleft: 0,\r\n\t\t\t\t\t\t\twidth: \"100%\",\r\n\t\t\t\t\t\t\theight: `${paperPx.margin.bottom}px`,\r\n\t\t\t\t\t\t}}\r\n\t\t\t\t\t/>\r\n\t\t\t\t)}\r\n\r\n\t\t\t\t{/* 左マージン */}\r\n\t\t\t\t{paperPx.margin.left > 0 && (\r\n\t\t\t\t\t<div\r\n\t\t\t\t\t\tdata-testid=\"margin-left\"\r\n\t\t\t\t\t\tstyle={{\r\n\t\t\t\t\t\t\t...marginBoxStyle,\r\n\t\t\t\t\t\t\tleft: 0,\r\n\t\t\t\t\t\t\ttop: `${paperPx.margin.top}px`,\r\n\t\t\t\t\t\t\theight: `${paperPx.content.height}px`,\r\n\t\t\t\t\t\t\twidth: `${paperPx.margin.left}px`,\r\n\t\t\t\t\t\t}}\r\n\t\t\t\t\t/>\r\n\t\t\t\t)}\r\n\r\n\t\t\t\t{/* 右マージン */}\r\n\t\t\t\t{paperPx.margin.right > 0 && (\r\n\t\t\t\t\t<div\r\n\t\t\t\t\t\tdata-testid=\"margin-right\"\r\n\t\t\t\t\t\tstyle={{\r\n\t\t\t\t\t\t\t...marginBoxStyle,\r\n\t\t\t\t\t\t\tright: 0,\r\n\t\t\t\t\t\t\ttop: `${paperPx.margin.top}px`,\r\n\t\t\t\t\t\t\theight: `${paperPx.content.height}px`,\r\n\t\t\t\t\t\t\twidth: `${paperPx.margin.right}px`,\r\n\t\t\t\t\t\t}}\r\n\t\t\t\t\t/>\r\n\t\t\t\t)}\r\n\t\t\t</div>\r\n\t\t);\r\n\t},\r\n);\r\n","import { memo, useCallback, useEffect, useMemo, useRef, useState } from \"react\";\r\n\r\nimport { Z_INDEX } from \"../../utils/zIndex\";\r\nimport { BorderOverlay } from \"./BorderOverlay/BorderOverlay\";\r\nimport { GridCanvas } from \"./GridCanvas/GridCanvas\";\r\nimport { GridDimensionLabel } from \"./GridDimensionLabel\";\r\nimport { GridOverlay } from \"./GridOverlay/GridOverlay\";\r\nimport { GridResizeHandle } from \"./GridResizeHandle\";\r\nimport { MarginOverlay } from \"./MarginOverlay/MarginOverlay\";\r\n\r\nimport { DEFAULT_DPI } from \"@/constants\";\r\n\r\nimport type {\r\n\tBorderStyle,\r\n\tDimension,\r\n\tGridPosPx,\r\n\tGridUnit,\r\n\tLineStyle,\r\n\tPaperPx,\r\n} from \"@types\";\r\n\r\n/**\r\n * GridLayerのプロパティ\r\n */\r\nexport interface GridLayerProps {\r\n\tpaperPx: PaperPx; // 用紙設定(ピクセル単位)\r\n\tgridPosPxs: GridPosPx; // グリッド線の位置(px配列)\r\n\tgridDimensions?: {\r\n\t\tcols: Array<Dimension<GridUnit>>;\r\n\t\trows: Array<Dimension<GridUnit>>;\r\n\t}; // グリッド寸法(単位付き)\r\n\tgridLineStyle?: LineStyle; // グリッド線のスタイル\r\n\tborderStyle?: BorderStyle; // 印刷可能領域枠のスタイル\r\n\tbackgroundColor?: string; // 用紙背景色\r\n\tboxShadow?: string; // 用紙のボックスシャドウ\r\n\tmarginFillColor?: string; // マージン領域の塗りつぶし色\r\n\tshowGridLines?: boolean; // グリッド線を表示するか\r\n\tshowMargins?: boolean; // マージン領域を表示するか\r\n\tshowBorder?: boolean; // 印刷可能領域枠を表示するか\r\n\tshowResizeHandles?: boolean; // リサイズハンドルを表示するか\r\n\tshowDimensionLabels?: boolean; // 寸法ラベルを表示するか\r\n\tonGridResize?: (\r\n\t\tdirection: \"column\" | \"row\",\r\n\t\tindex: number,\r\n\t\tdelta: number,\r\n\t) => void; // リサイズコールバック\r\n\tonDimensionChange?: (\r\n\t\tdirection: \"column\" | \"row\",\r\n\t\tindex: number,\r\n\t\tdimension: Dimension<GridUnit>,\r\n\t) => void; // 寸法変更コールバック\r\n\tclassName?: string; // 追加のクラス名\r\n\tzIndex?: {\r\n\t\t// 各レイヤーのz-indexオーバーライド\r\n\t\tcanvas?: number;\r\n\t\tmargin?: number;\r\n\t\tgrid?: number;\r\n\t\tborder?: number;\r\n\t};\r\n}\r\n\r\n/**\r\n * GridLayer - グリッドシステムの統合コンポーネント\r\n *\r\n * 4つのレイヤーを統合して提供します:\r\n * 1. GridCanvas (z-index: 0) - 用紙背景\r\n * 2. MarginOverlay (z-index: 1) - 印刷不可領域の視覚化\r\n * 3. GridOverlay (z-index: 2) - グリッド線\r\n * 4. BorderOverlay (z-index: 3) - 印刷可能領域の境界線\r\n *\r\n * @example\r\n * ```tsx\r\n * <GridLayer\r\n * paper={schema.paper}\r\n * grid={schema.grid}\r\n * paperWidthPx={794}\r\n * paperHeightPx={1123}\r\n * contentAreaWidthPx={718}\r\n * contentAreaHeightPx={1047}\r\n * marginLeftPx={38}\r\n * marginRightPx={38}\r\n * marginTopPx={38}\r\n * marginBottomPx={38}\r\n * colWidthPxs={[100, 150, 200, 268]}\r\n * rowHeightPxs={[50, 75, 100, 125, 697]}\r\n * />\r\n * ```\r\n */\r\nexport const GridLayer: React.FC<GridLayerProps> = memo(\r\n\t({\r\n\t\tpaperPx,\r\n\t\tgridPosPxs,\r\n\t\tgridDimensions,\r\n\t\tgridLineStyle,\r\n\t\tborderStyle,\r\n\t\tbackgroundColor = \"#ffffff\",\r\n\t\tboxShadow = \"0 2px 8px rgba(0, 0, 0, 0.1)\",\r\n\t\tmarginFillColor = \"rgba(0, 0, 0, 0.05)\",\r\n\t\tshowGridLines = true,\r\n\t\tshowMargins = true,\r\n\t\tshowBorder = true,\r\n\t\tshowResizeHandles = false,\r\n\t\tshowDimensionLabels = false,\r\n\t\tonGridResize,\r\n\t\tonDimensionChange,\r\n\t\tclassName = \"\",\r\n\t\tzIndex = {},\r\n\t}) => {\r\n\t\t// グリッドリサイズ中のゴースト線の状態\r\n\t\tconst [ghostLine, setGhostLine] = useState<{\r\n\t\t\tdirection: \"column\" | \"row\";\r\n\t\t\tposition: number;\r\n\t\t} | null>(null);\r\n\r\n\t\t// ドラッグ中の状態(隣接するラベルを表示するため)\r\n\t\tconst [draggingHandle, setDraggingHandle] = useState<{\r\n\t\t\tdirection: \"column\" | \"row\";\r\n\t\t\tindex: number;\r\n\t\t} | null>(null);\r\n\r\n\t\t// マウス位置の状態(寸法ラベルの表示判定用)\r\n\t\t// windowレベルでマウス位置を監視(z-indexの高い要素に邪魔されない)\r\n\t\tconst [mousePos, setMousePos] = useState<{ x: number; y: number } | null>(\r\n\t\t\tnull,\r\n\t\t);\r\n\t\tconst containerRef = useRef<HTMLDivElement>(null);\r\n\t\tuseEffect(() => {\r\n\t\t\tconst handleMouseMove = (e: MouseEvent) => {\r\n\t\t\t\tif (!containerRef.current) return;\r\n\t\t\t\tconst rect = containerRef.current.getBoundingClientRect();\r\n\t\t\t\tsetMousePos({\r\n\t\t\t\t\tx: e.clientX - rect.left,\r\n\t\t\t\t\ty: e.clientY - rect.top,\r\n\t\t\t\t});\r\n\t\t\t};\r\n\r\n\t\t\tconst handleMouseLeave = (e: MouseEvent) => {\r\n\t\t\t\tif (!containerRef.current) return;\r\n\t\t\t\tconst rect = containerRef.current.getBoundingClientRect();\r\n\t\t\t\t// コンテナの外に出たかチェック\r\n\t\t\t\tconst isOutside =\r\n\t\t\t\t\te.clientX < rect.left ||\r\n\t\t\t\t\te.clientX > rect.right ||\r\n\t\t\t\t\te.clientY < rect.top ||\r\n\t\t\t\t\te.clientY > rect.bottom;\r\n\t\t\t\tif (isOutside) {\r\n\t\t\t\t\tsetMousePos(null);\r\n\t\t\t\t}\r\n\t\t\t};\r\n\r\n\t\t\twindow.addEventListener(\"mousemove\", handleMouseMove);\r\n\t\t\twindow.addEventListener(\"mouseleave\", handleMouseLeave);\r\n\r\n\t\t\treturn () => {\r\n\t\t\t\twindow.removeEventListener(\"mousemove\", handleMouseMove);\r\n\t\t\t\twindow.removeEventListener(\"mouseleave\", handleMouseLeave);\r\n\t\t\t};\r\n\t\t}, []); // 寸法ラベル表示判定: カーソルがキャンバス外にあるかどうか\r\n\t\tconst shouldShowDimensionLabels = useMemo(() => {\r\n\t\t\tif (!mousePos) return false;\r\n\r\n\t\t\t// カーソルがキャンバス内にあるかどうか\r\n\t\t\tconst contentWidth = paperPx.content.width;\r\n\t\t\tconst contentHeight = paperPx.content.height;\r\n\t\t\tconst marginLeftPx = paperPx.margin.left;\r\n\t\t\tconst marginTopPx = paperPx.margin.top;\r\n\r\n\t\t\tconst isInsideCanvas =\r\n\t\t\t\tmousePos.x >= marginLeftPx &&\r\n\t\t\t\tmousePos.x <= marginLeftPx + contentWidth &&\r\n\t\t\t\tmousePos.y >= marginTopPx &&\r\n\t\t\t\tmousePos.y <= marginTopPx + contentHeight;\r\n\r\n\t\t\t// キャンバス外なら表示\r\n\t\t\treturn !isInsideCanvas;\r\n\t\t}, [mousePos, paperPx]); // リサイズ開始時\r\n\t\tconst handleResizeStart = useCallback(\r\n\t\t\t(direction: \"column\" | \"row\", index: number) => {\r\n\t\t\t\tsetDraggingHandle({ direction, index });\r\n\t\t\t},\r\n\t\t\t[],\r\n\t\t);\r\n\r\n\t\t// リサイズ中のプレビューサイズを計算\r\n\t\tconst resizingPreviewSizes = useMemo(() => {\r\n\t\t\tif (!ghostLine || !draggingHandle) return null;\r\n\r\n\t\t\tconst gridLines =\r\n\t\t\t\tdraggingHandle.direction === \"column\"\r\n\t\t\t\t\t? gridPosPxs.cols\r\n\t\t\t\t\t: gridPosPxs.rows;\r\n\t\t\tconst index = draggingHandle.index;\r\n\r\n\t\t\t// 左/上のグリッド(index-1からindexまで)\r\n\t\t\tconst prevStart = gridLines[index - 1];\r\n\t\t\tconst prevEnd = ghostLine.position;\r\n\t\t\tconst prevSize = prevStart !== undefined ? prevEnd - prevStart : 0;\r\n\r\n\t\t\t// 右/下のグリッド(indexからindex+1まで)\r\n\t\t\tconst nextStart = ghostLine.position;\r\n\t\t\tconst nextEnd = gridLines[index + 1];\r\n\t\t\tconst nextSize = nextEnd !== undefined ? nextEnd - nextStart : 0;\r\n\r\n\t\t\treturn {\r\n\t\t\t\tdirection: draggingHandle.direction,\r\n\t\t\t\tprevIndex: index - 1,\r\n\t\t\t\tprevSize,\r\n\t\t\t\tnextIndex: index,\r\n\t\t\t\tnextSize,\r\n\t\t\t};\r\n\t\t}, [ghostLine, draggingHandle, gridPosPxs]);\r\n\r\n\t\t// リサイズ中(ゴースト線を表示)\r\n\t\tconst handleResize = useCallback(\r\n\t\t\t(direction: \"column\" | \"row\", index: number, delta: number) => {\r\n\t\t\t\t// 元の位置を取得\r\n\t\t\t\tconst gridLines =\r\n\t\t\t\t\tdirection === \"column\" ? gridPosPxs.cols : gridPosPxs.rows;\r\n\t\t\t\tconst originalPos = gridLines[index];\r\n\r\n\t\t\t\tif (originalPos === undefined) return;\r\n\r\n\t\t\t\t// 隣のグリッド線の位置を取得\r\n\t\t\t\tconst prevLinePos = gridLines[index - 1];\r\n\t\t\t\tconst nextLinePos = gridLines[index + 1];\r\n\r\n\t\t\t\t// 最小間隔(10px)\r\n\t\t\t\tconst MIN_GAP = 10;\r\n\r\n\t\t\t\t// deltaを制限(隣のグリッド線を超えないように)\r\n\t\t\t\tlet clampedDelta = delta;\r\n\t\t\t\tif (prevLinePos !== undefined) {\r\n\t\t\t\t\tconst minDelta = prevLinePos + MIN_GAP - originalPos;\r\n\t\t\t\t\tclampedDelta = Math.max(clampedDelta, minDelta);\r\n\t\t\t\t}\r\n\t\t\t\tif (nextLinePos !== undefined) {\r\n\t\t\t\t\tconst maxDelta = nextLinePos - MIN_GAP - originalPos;\r\n\t\t\t\t\tclampedDelta = Math.min(clampedDelta, maxDelta);\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// ゴースト線の位置を更新(制限付き)\r\n\t\t\t\tsetGhostLine({\r\n\t\t\t\t\tdirection,\r\n\t\t\t\t\tposition: originalPos + clampedDelta,\r\n\t\t\t\t});\r\n\t\t\t},\r\n\t\t\t[gridPosPxs],\r\n\t\t); // リサイズ終了時(ゴースト線を非表示)\r\n\t\tconst handleResizeEnd = useCallback(\r\n\t\t\t(direction: \"column\" | \"row\", index: number, delta: number) => {\r\n\t\t\t\t// 元の位置を取得\r\n\t\t\t\tconst gridLines =\r\n\t\t\t\t\tdirection === \"column\" ? gridPosPxs.cols : gridPosPxs.rows;\r\n\t\t\t\tconst originalPos = gridLines[index];\r\n\r\n\t\t\t\tif (originalPos === undefined) {\r\n\t\t\t\t\tsetGhostLine(null);\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// 隣のグリッド線の位置を取得\r\n\t\t\t\tconst prevLinePos = gridLines[index - 1];\r\n\t\t\t\tconst nextLinePos = gridLines[index + 1];\r\n\r\n\t\t\t\t// 最小間隔(10px)\r\n\t\t\t\tconst MIN_GAP = 10;\r\n\r\n\t\t\t\t// deltaを制限(隣のグリッド線を超えないように)\r\n\t\t\t\tlet clampedDelta = delta;\r\n\t\t\t\tif (prevLinePos !== undefined) {\r\n\t\t\t\t\tconst minDelta = prevLinePos + MIN_GAP - originalPos;\r\n\t\t\t\t\tclampedDelta = Math.max(clampedDelta, minDelta);\r\n\t\t\t\t}\r\n\t\t\t\tif (nextLinePos !== undefined) {\r\n\t\t\t\t\tconst maxDelta = nextLinePos - MIN_GAP - originalPos;\r\n\t\t\t\t\tclampedDelta = Math.min(clampedDelta, maxDelta);\r\n\t\t\t\t}\r\n\r\n\t\t\t\tsetGhostLine(null);\r\n\t\t\t\tsetDraggingHandle(null);\r\n\t\t\t\t// 制限されたdeltaで実際のリサイズを実行\r\n\t\t\t\tonGridResize?.(direction, index, clampedDelta);\r\n\t\t\t},\r\n\t\t\t[gridPosPxs, onGridResize],\r\n\t\t);\r\n\t\tconst containerStyle: React.CSSProperties = {\r\n\t\t\tposition: \"relative\",\r\n\t\t\twidth: \"100%\",\r\n\t\t\theight: \"100%\",\r\n\t\t};\r\n\r\n\t\treturn (\r\n\t\t\t<div ref={containerRef} className={className} style={containerStyle}>\r\n\t\t\t\t{/* レイヤー1: 用紙背景 (z-index: 0) */}\r\n\t\t\t\t<GridCanvas\r\n\t\t\t\t\tcanvasPx={paperPx.canvas}\r\n\t\t\t\t\tbackgroundColor={backgroundColor}\r\n\t\t\t\t\tboxShadow={boxShadow}\r\n\t\t\t\t\tzIndex={zIndex?.canvas ?? Z_INDEX.GRID_CANVAS}\r\n\t\t\t\t\tclassName={className}\r\n\t\t\t\t/>\r\n\r\n\t\t\t\t{/* レイヤー2: マージン領域 (z-index: 1) */}\r\n\t\t\t\t{showMargins && (\r\n\t\t\t\t\t<MarginOverlay\r\n\t\t\t\t\t\tpaperPx={paperPx}\r\n\t\t\t\t\t\tvisible={showMargins}\r\n\t\t\t\t\t\tmarginColor={marginFillColor}\r\n\t\t\t\t\t\tzIndex={zIndex?.margin ?? Z_INDEX.MARGIN_OVERLAY}\r\n\t\t\t\t\t\tclassName={className}\r\n\t\t\t\t\t/>\r\n\t\t\t\t)}\r\n\r\n\t\t\t\t{/* レイヤー3: グリッド線 (z-index: 2) */}\r\n\t\t\t\t{showGridLines && (\r\n\t\t\t\t\t<GridOverlay\r\n\t\t\t\t\t\tgridPosPx={gridPosPxs}\r\n\t\t\t\t\t\tcontentPx={paperPx.content}\r\n\t\t\t\t\t\tmarginLeftPx={paperPx.margin.left}\r\n\t\t\t\t\t\tmarginTopPx={paperPx.margin.top}\r\n\t\t\t\t\t\tlineStyle={gridLineStyle}\r\n\t\t\t\t\t\tvisible={showGridLines}\r\n\t\t\t\t\t\tzIndex={zIndex?.grid ?? Z_INDEX.GRID_OVERLAY}\r\n\t\t\t\t\t\tdpi={DEFAULT_DPI}\r\n\t\t\t\t\t\tclassName={className}\r\n\t\t\t\t\t/>\r\n\t\t\t\t)}\r\n\r\n\t\t\t\t{/* レイヤー4: 境界線 (z-index: 3) */}\r\n\t\t\t\t{showBorder && (\r\n\t\t\t\t\t<BorderOverlay\r\n\t\t\t\t\t\tcontentPx={paperPx.content}\r\n\t\t\t\t\t\tmarginLeftPx={paperPx.margin.left}\r\n\t\t\t\t\t\tmarginTopPx={paperPx.margin.top}\r\n\t\t\t\t\t\tborderStyle={borderStyle}\r\n\t\t\t\t\t\tvisible={showBorder}\r\n\t\t\t\t\t\tdpi={DEFAULT_DPI}\r\n\t\t\t\t\t\tzIndex={zIndex?.border ?? Z_INDEX.BORDER_OVERLAY}\r\n\t\t\t\t\t\tclassName={className}\r\n\t\t\t\t\t/>\r\n\t\t\t\t)}\r\n\r\n\t\t\t\t{/* レイヤー5: リサイズハンドル */}\r\n\t\t\t\t{showResizeHandles && onGridResize && (\r\n\t\t\t\t\t<>\r\n\t\t\t\t\t\t{/* 列のリサイズハンドル */}\r\n\t\t\t\t\t\t{gridPosPxs.cols.map((colPos, index) => {\r\n\t\t\t\t\t\t\t// 最初と最後の列は除外(端は動かせない)\r\n\t\t\t\t\t\t\tif (index === 0 || index === gridPosPxs.cols.length - 1) {\r\n\t\t\t\t\t\t\t\treturn null;\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\tconst key = `col-${index}`;\r\n\r\n\t\t\t\t\t\t\treturn (\r\n\t\t\t\t\t\t\t\t<GridResizeHandle\r\n\t\t\t\t\t\t\t\t\tkey={key}\r\n\t\t\t\t\t\t\t\t\tdirection=\"column\"\r\n\t\t\t\t\t\t\t\t\tindex={index}\r\n\t\t\t\t\t\t\t\t\tposition={colPos}\r\n\t\t\t\t\t\t\t\t\tmarginLeftPx={paperPx.margin.left}\r\n\t\t\t\t\t\t\t\t\tmarginTopPx={paperPx.margin.top}\r\n\t\t\t\t\t\t\t\t\tonResizeStart={handleResizeStart}\r\n\t\t\t\t\t\t\t\t\tonResize={handleResize}\r\n\t\t\t\t\t\t\t\t\tonResizeEnd={handleResizeEnd}\r\n\t\t\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t\t);\r\n\t\t\t\t\t\t})}\r\n\r\n\t\t\t\t\t\t{/* 行のリサイズハンドル */}\r\n\t\t\t\t\t\t{gridPosPxs.rows.map((rowPos, index) => {\r\n\t\t\t\t\t\t\t// 最初と最後の行は除外(端は動かせない)\r\n\t\t\t\t\t\t\tif (index === 0 || index === gridPosPxs.rows.length - 1) {\r\n\t\t\t\t\t\t\t\treturn null;\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\tconst key = `row-${index}`;\r\n\r\n\t\t\t\t\t\t\treturn (\r\n\t\t\t\t\t\t\t\t<GridResizeHandle\r\n\t\t\t\t\t\t\t\t\tkey={key}\r\n\t\t\t\t\t\t\t\t\tdirection=\"row\"\r\n\t\t\t\t\t\t\t\t\tindex={index}\r\n\t\t\t\t\t\t\t\t\tposition={rowPos}\r\n\t\t\t\t\t\t\t\t\tmarginLeftPx={paperPx.margin.left}\r\n\t\t\t\t\t\t\t\t\tmarginTopPx={paperPx.margin.top}\r\n\t\t\t\t\t\t\t\t\tonResizeStart={handleResizeStart}\r\n\t\t\t\t\t\t\t\t\tonResize={handleResize}\r\n\t\t\t\t\t\t\t\t\tonResizeEnd={handleResizeEnd}\r\n\t\t\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t\t);\r\n\t\t\t\t\t\t})}\r\n\t\t\t\t\t</>\r\n\t\t\t\t)}\r\n\r\n\t\t\t\t{/* レイヤー6: 寸法ラベル */}\r\n\t\t\t\t{showDimensionLabels && gridDimensions && (\r\n\t\t\t\t\t<>\r\n\t\t\t\t\t\t{/* 列の寸法ラベル */}\r\n\t\t\t\t\t\t{gridDimensions.cols.map((dimension, index) => {\r\n\t\t\t\t\t\t\t// 隣接する2つのグリッド線の中央位置を計算\r\n\t\t\t\t\t\t\tconst startPos = gridPosPxs.cols[index];\r\n\t\t\t\t\t\t\tconst endPos = gridPosPxs.cols[index + 1];\r\n\t\t\t\t\t\t\tif (startPos === undefined || endPos === undefined) return null;\r\n\r\n\t\t\t\t\t\t\t// ドラッグ中の隣接ラベルかどうか判定\r\n\t\t\t\t\t\t\tconst isDraggingAdjacentColumn =\r\n\t\t\t\t\t\t\t\tdraggingHandle?.direction === \"column\" &&\r\n\t\t\t\t\t\t\t\t(draggingHandle.index === index ||\r\n\t\t\t\t\t\t\t\t\tdraggingHandle.index === index + 1);\r\n\r\n\t\t\t\t\t\t\t// リサイズ中のプレビューサイズを取得\r\n\t\t\t\t\t\t\tlet resizingPxSize: number | undefined;\r\n\t\t\t\t\t\t\tif (\r\n\t\t\t\t\t\t\t\tresizingPreviewSizes &&\r\n\t\t\t\t\t\t\t\tresizingPreviewSizes.direction === \"column\"\r\n\t\t\t\t\t\t\t) {\r\n\t\t\t\t\t\t\t\tif (resizingPreviewSizes.prevIndex === index) {\r\n\t\t\t\t\t\t\t\t\tresizingPxSize = resizingPreviewSizes.prevSize;\r\n\t\t\t\t\t\t\t\t} else if (resizingPreviewSizes.nextIndex === index) {\r\n\t\t\t\t\t\t\t\t\tresizingPxSize = resizingPreviewSizes.nextSize;\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t\tconst centerPos = (startPos + endPos) / 2;\r\n\t\t\t\t\t\t\tconst currentPxSize = endPos - startPos;\r\n\t\t\t\t\t\t\tconst key = `col-dim-${index}`;\r\n\r\n\t\t\t\t\t\t\treturn (\r\n\t\t\t\t\t\t\t\t<GridDimensionLabel\r\n\t\t\t\t\t\t\t\t\tkey={key}\r\n\t\t\t\t\t\t\t\t\tdirection=\"column\"\r\n\t\t\t\t\t\t\t\t\tindex={index}\r\n\t\t\t\t\t\t\t\t\tdimension={dimension}\r\n\t\t\t\t\t\t\t\t\tposition={centerPos}\r\n\t\t\t\t\t\t\t\t\tcurrentPxSize={currentPxSize}\r\n\t\t\t\t\t\t\t\t\tmarginLeftPx={paperPx.margin.left}\r\n\t\t\t\t\t\t\t\t\tmarginTopPx={paperPx.margin.top}\r\n\t\t\t\t\t\t\t\t\tisNearCursor={\r\n\t\t\t\t\t\t\t\t\t\tshouldShowDimensionLabels || isDraggingAdjacentColumn\r\n\t\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t\tresizingPxSize={resizingPxSize}\r\n\t\t\t\t\t\t\t\t\tonDimensionChange={onDimensionChange}\r\n\t\t\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t\t);\r\n\t\t\t\t\t\t})}{\" \"}\r\n\t\t\t\t\t\t{/* 行の寸法ラベル */}\r\n\t\t\t\t\t\t{gridDimensions.rows.map((dimension, index) => {\r\n\t\t\t\t\t\t\t// 隣接する2つのグリッド線の中央位置を計算\r\n\t\t\t\t\t\t\tconst startPos = gridPosPxs.rows[index];\r\n\t\t\t\t\t\t\tconst endPos = gridPosPxs.rows[index + 1];\r\n\t\t\t\t\t\t\tif (startPos === undefined || endPos === undefined) return null;\r\n\r\n\t\t\t\t\t\t\t// ドラッグ中の隣接ラベルかどうか判定\r\n\t\t\t\t\t\t\tconst isDraggingAdjacentRow =\r\n\t\t\t\t\t\t\t\tdraggingHandle?.direction === \"row\" &&\r\n\t\t\t\t\t\t\t\t(draggingHandle.index === index ||\r\n\t\t\t\t\t\t\t\t\tdraggingHandle.index === index + 1);\r\n\r\n\t\t\t\t\t\t\tconst centerPos = (startPos + endPos) / 2;\r\n\t\t\t\t\t\t\tconst currentPxSize = endPos - startPos;\r\n\t\t\t\t\t\t\tconst key = `row-dim-${index}`;\r\n\r\n\t\t\t\t\t\t\treturn (\r\n\t\t\t\t\t\t\t\t<GridDimensionLabel\r\n\t\t\t\t\t\t\t\t\tkey={key}\r\n\t\t\t\t\t\t\t\t\tdirection=\"row\"\r\n\t\t\t\t\t\t\t\t\tindex={index}\r\n\t\t\t\t\t\t\t\t\tdimension={dimension}\r\n\t\t\t\t\t\t\t\t\tposition={centerPos}\r\n\t\t\t\t\t\t\t\t\tcurrentPxSize={currentPxSize}\r\n\t\t\t\t\t\t\t\t\tmarginLeftPx={paperPx.margin.left}\r\n\t\t\t\t\t\t\t\t\tmarginTopPx={paperPx.margin.top}\r\n\t\t\t\t\t\t\t\t\tisNearCursor={\r\n\t\t\t\t\t\t\t\t\t\tshouldShowDimensionLabels || isDraggingAdjacentRow\r\n\t\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t\tonDimensionChange={onDimensionChange}\r\n\t\t\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t\t);\r\n\t\t\t\t\t\t})}\r\n\t\t\t\t\t</>\r\n\t\t\t\t)}\r\n\r\n\t\t\t\t{/* レイヤー7: ゴースト線 (ドラッグ中の予覧) */}\r\n\t\t\t\t{ghostLine && (\r\n\t\t\t\t\t<div\r\n\t\t\t\t\t\tstyle={{\r\n\t\t\t\t\t\t\tposition: \"absolute\",\r\n\t\t\t\t\t\t\tleft:\r\n\t\t\t\t\t\t\t\tghostLine.direction === \"column\"\r\n\t\t\t\t\t\t\t\t\t? paperPx.margin.left + ghostLine.position\r\n\t\t\t\t\t\t\t\t\t: paperPx.margin.left,\r\n\t\t\t\t\t\t\ttop:\r\n\t\t\t\t\t\t\t\tghostLine.direction === \"row\"\r\n\t\t\t\t\t\t\t\t\t? paperPx.margin.top + ghostLine.position\r\n\t\t\t\t\t\t\t\t\t: paperPx.margin.top,\r\n\t\t\t\t\t\t\twidth:\r\n\t\t\t\t\t\t\t\tghostLine.direction === \"column\"\r\n\t\t\t\t\t\t\t\t\t? \"2px\"\r\n\t\t\t\t\t\t\t\t\t: paperPx.content.width,\r\n\t\t\t\t\t\t\theight:\r\n\t\t\t\t\t\t\t\tghostLine.direction === \"row\" ? \"2px\" : paperPx.content.height,\r\n\t\t\t\t\t\t\tbackgroundColor: \"#3b82f6\",\r\n\t\t\t\t\t\t\topacity: 0.5,\r\n\t\t\t\t\t\t\tpointerEvents: \"none\",\r\n\t\t\t\t\t\t\tzIndex: Z_INDEX.GRID_GHOST,\r\n\t\t\t\t\t\t}}\r\n\t\t\t\t\t/>\r\n\t\t\t\t)}\r\n\t\t\t</div>\r\n\t\t);\r\n\t},\r\n);\r\n","/**\r\n * GlobalDragStore\r\n *\r\n * Palette → Canvas 間のドラッグ&ドロップで使用するグローバル状態管理\r\n * 「現在ドラッグ中のアイテム」を保持し、NoteFormが必要に応じて参照する\r\n *\r\n * ## 使用方法\r\n *\r\n * ### Palette側 (ホストアプリ)\r\n * ```tsx\r\n * const handlePointerDown = (e: React.PointerEvent) => {\r\n * globalDragStore.start('text', { w: 200, h: 100 });\r\n *\r\n * const handleWindowUp = () => {\r\n * globalDragStore.end();\r\n * window.removeEventListener('pointerup', handleWindowUp);\r\n * };\r\n * window.addEventListener('pointerup', handleWindowUp);\r\n * };\r\n * ```\r\n *\r\n * ### NoteForm側 (core)\r\n * ```tsx\r\n * const handlePointerEnter = () => {\r\n * const item = globalDragStore.get();\r\n * if (item) {\r\n * handleInteractionChange({\r\n * type: InteractionEventType.START_INSERT,\r\n * pluginKind: item.kind,\r\n * defaultSize: item.defaultSize,\r\n * });\r\n * }\r\n * };\r\n * ```\r\n */\r\n\r\n/**\r\n * ドラッグ中のアイテム情報\r\n */\r\nexport type DragState = {\r\n\t/** プラグインの種類 (例: 'text', 'image') */\r\n\tkind: string;\r\n\t/** デフォルトサイズ (グリッド単位) */\r\n\tdefaultSize: { w: number; h: number };\r\n} | null;\r\n\r\n/**\r\n * 状態変化を監視するリスナー関数\r\n */\r\ntype Listener = (state: DragState) => void;\r\n\r\n/**\r\n * グローバルドラッグストア\r\n * シングルトンパターンで実装\r\n */\r\nclass GlobalDragStore {\r\n\tprivate state: DragState = null;\r\n\tprivate listeners: Listener[] = [];\r\n\r\n\t/**\r\n\t * ドラッグ開始\r\n\t * Paletteから呼ばれる\r\n\t *\r\n\t * @param kind プラグインの種類\r\n\t * @param defaultSize デフォルトサイズ (グリッド単位)\r\n\t */\r\n\tstart(kind: string, defaultSize: { w: number; h: number }): void {\r\n\t\tthis.state = { kind, defaultSize };\r\n\t\tthis.notify();\r\n\t}\r\n\r\n\t/**\r\n\t * ドラッグ終了\r\n\t * window.pointerup で呼ばれる\r\n\t */\r\n\tend(): void {\r\n\t\tthis.state = null;\r\n\t\tthis.notify();\r\n\t}\r\n\r\n\t/**\r\n\t * 現在の状態を取得\r\n\t * NoteFormのonPointerEnterから呼ばれる\r\n\t *\r\n\t * @returns 現在ドラッグ中のアイテム (なければ null)\r\n\t */\r\n\tget(): DragState {\r\n\t\treturn this.state;\r\n\t}\r\n\r\n\t/**\r\n\t * 状態変化を監視\r\n\t * (現在は使用していないが、将来的なデバッグ用に実装)\r\n\t *\r\n\t * @param listener 状態変化時に呼ばれる関数\r\n\t * @returns アンサブスクライブ関数\r\n\t */\r\n\tsubscribe(listener: Listener): () => void {\r\n\t\tthis.listeners.push(listener);\r\n\t\treturn () => {\r\n\t\t\tthis.listeners = this.listeners.filter((l) => l !== listener);\r\n\t\t};\r\n\t}\r\n\r\n\t/**\r\n\t * 全リスナーに状態変化を通知\r\n\t */\r\n\tprivate notify(): void {\r\n\t\tfor (const listener of this.listeners) {\r\n\t\t\tlistener(this.state);\r\n\t\t}\r\n\t}\r\n}\r\n\r\n/**\r\n * グローバルドラッグストアのシングルトンインスタンス\r\n */\r\nexport const globalDragStore = new GlobalDragStore();\r\n","/**\r\n * @file calculateGridResize.ts\r\n * @description グリッドリサイズ時のDimension計算ロジック\r\n */\r\n\r\nimport { toMm, toPx } from \"@/utils/convert\";\r\n\r\nimport type { Dimension, GridUnit } from \"@/types/unit\";\r\n\r\n/**\r\n * px単位でのデルタ値をGridDimensionに反映\r\n *\r\n * @param dimensions - 現在のDimension配列\r\n * @param index - リサイズするグリッドのインデックス\r\n * @param deltaPx - ピクセル単位での変更量\r\n * @param totalContentPx - コンテンツ全体のサイズ(px)\r\n * @returns 更新されたDimension配列\r\n */\r\nexport function calculateGridResize(\r\n\tdimensions: Dimension<GridUnit>[],\r\n\tindex: number,\r\n\tdeltaPx: number,\r\n\ttotalContentPx: number,\r\n): Dimension<GridUnit>[] {\r\n\t// インデックスの範囲チェック\r\n\tif (index < 0 || index >= dimensions.length) {\r\n\t\treturn dimensions;\r\n\t}\r\n\r\n\tconst newDimensions = [...dimensions];\r\n\tconst current = newDimensions[index];\r\n\tconst next = newDimensions[index + 1];\r\n\r\n\tif (!current || !next) {\r\n\t\treturn dimensions;\r\n\t}\r\n\r\n\t// ケース1: 両方がfr単位\r\n\tif (current.unit === \"fr\" && next.unit === \"fr\") {\r\n\t\treturn resizeFrPair(newDimensions, index, deltaPx, totalContentPx);\r\n\t}\r\n\r\n\t// ケース2: 両方が固定単位\r\n\tif (current.unit !== \"fr\" && next.unit !== \"fr\") {\r\n\t\treturn resizeFixedPair(newDimensions, index, deltaPx);\r\n\t}\r\n\r\n\t// ケース3: frと固定単位の混在\r\n\t// frは変えず、固定単位だけ調整\r\n\tif (current.unit === \"fr\" && next.unit !== \"fr\") {\r\n\t\t// currentはfr、nextは固定値\r\n\t\treturn resizeFrAndFixed(\r\n\t\t\tnewDimensions,\r\n\t\t\tindex,\r\n\t\t\tdeltaPx,\r\n\t\t\t\"next\",\r\n\t\t\ttotalContentPx,\r\n\t\t);\r\n\t} else {\r\n\t\t// currentは固定値、nextはfr\r\n\t\treturn resizeFrAndFixed(\r\n\t\t\tnewDimensions,\r\n\t\t\tindex,\r\n\t\t\tdeltaPx,\r\n\t\t\t\"current\",\r\n\t\t\ttotalContentPx,\r\n\t\t);\r\n\t}\r\n}\r\n\r\n/**\r\n * 両方がfr単位の場合のリサイズ\r\n */\r\nfunction resizeFrPair(\r\n\tdimensions: Dimension<GridUnit>[],\r\n\tindex: number,\r\n\tdeltaPx: number,\r\n\ttotalContentPx: number,\r\n): Dimension<GridUnit>[] {\r\n\tconst current = dimensions[index];\r\n\tconst next = dimensions[index + 1];\r\n\tif (!current || !next) return dimensions;\r\n\r\n\t// 現在のfr値の合計を計算\r\n\tconst totalFr = dimensions.reduce(\r\n\t\t(sum, dim) => (dim.unit === \"fr\" ? sum + dim.value : sum),\r\n\t\t0,\r\n\t);\r\n\r\n\t// px単位での現在のサイズを計算\r\n\tconst frToPx = totalContentPx / totalFr;\r\n\tconst currentPx = current.value * frToPx;\r\n\tconst nextPx = next.value * frToPx;\r\n\r\n\t// 新しいサイズを計算\r\n\tconst newCurrentPx = Math.max(10, currentPx + deltaPx);\r\n\tconst newNextPx = Math.max(10, nextPx - deltaPx);\r\n\r\n\t// frに変換\r\n\tconst newCurrentFr = newCurrentPx / frToPx;\r\n\tconst newNextFr = newNextPx / frToPx;\r\n\r\n\t// 小数第2位まで丸める\r\n\tdimensions[index] = {\r\n\t\t...current,\r\n\t\tvalue: Math.round(newCurrentFr * 100) / 100,\r\n\t};\r\n\tdimensions[index + 1] = {\r\n\t\t...next,\r\n\t\tvalue: Math.round(newNextFr * 100) / 100,\r\n\t};\r\n\r\n\treturn dimensions;\r\n}\r\n\r\n/**\r\n * 両方が固定単位の場合のリサイズ\r\n */\r\nfunction resizeFixedPair(\r\n\tdimensions: Dimension<GridUnit>[],\r\n\tindex: number,\r\n\tdeltaPx: number,\r\n): Dimension<GridUnit>[] {\r\n\tconst current = dimensions[index];\r\n\tconst next = dimensions[index + 1];\r\n\tif (!current || !next) return dimensions;\r\n\r\n\t// px値を取得\r\n\tconst currentPx = toPx.fromDim(current);\r\n\tconst nextPx = toPx.fromDim(next);\r\n\r\n\t// 新しいサイズを計算\r\n\tconst newCurrentPx = Math.max(10, currentPx + deltaPx);\r\n\tconst newNextPx = Math.max(10, nextPx - deltaPx);\r\n\r\n\t// 単位に応じて変換\r\n\tdimensions[index] = {\r\n\t\t...current,\r\n\t\tvalue: convertPxToUnit(newCurrentPx, current.unit),\r\n\t};\r\n\tdimensions[index + 1] = {\r\n\t\t...next,\r\n\t\tvalue: convertPxToUnit(newNextPx, next.unit),\r\n\t};\r\n\r\n\treturn dimensions;\r\n}\r\n\r\n/**\r\n * frと実寸値が混在する場合のリサイズ\r\n * 実寸値を変更し、frは現在のpx/fr比率から逆算して再計算\r\n */\r\nfunction resizeFrAndFixed(\r\n\tdimensions: Dimension<GridUnit>[],\r\n\tindex: number,\r\n\tdeltaPx: number,\r\n\tfixedSide: \"current\" | \"next\",\r\n\ttotalContentPx: number,\r\n): Dimension<GridUnit>[] {\r\n\tconst current = dimensions[index];\r\n\tconst next = dimensions[index + 1];\r\n\tif (!current || !next) return dimensions;\r\n\r\n\t// 全体のfr合計と固定値合計を計算\r\n\tlet totalFr = 0;\r\n\tlet totalFixedPx = 0;\r\n\r\n\tfor (const dim of dimensions) {\r\n\t\tif (dim.unit === \"fr\") {\r\n\t\t\ttotalFr += dim.value;\r\n\t\t} else {\r\n\t\t\ttotalFixedPx += toPx.fromDim(dim);\r\n\t\t}\r\n\t}\r\n\r\n\t// 現在のfr利用可能スペース\r\n\tconst availableForFrPx = totalContentPx - totalFixedPx;\r\n\tconst currentFrToPx = totalFr > 0 ? availableForFrPx / totalFr : 0;\r\n\r\n\tif (fixedSide === \"next\") {\r\n\t\t// nextが実寸値、currentはfr\r\n\t\tconst nextPx = toPx.fromDim(next);\r\n\t\tconst newNextPx = Math.max(10, nextPx - deltaPx);\r\n\r\n\t\t// nextの実寸値を更新\r\n\t\tdimensions[index + 1] = {\r\n\t\t\t...next,\r\n\t\t\tvalue: convertPxToUnit(newNextPx, next.unit),\r\n\t\t};\r\n\r\n\t\t// 固定値の変化量\r\n\t\tconst fixedDelta = newNextPx - nextPx;\r\n\r\n\t\t// frの利用可能スペースが変わる\r\n\t\tconst newAvailableForFrPx = availableForFrPx - fixedDelta;\r\n\r\n\t\t// currentのfrを、新しいpx値から逆算\r\n\t\tconst currentPx = current.value * currentFrToPx;\r\n\t\tconst newCurrentPx = Math.max(10, currentPx + deltaPx);\r\n\t\tconst newCurrentFr =\r\n\t\t\ttotalFr > 0 ? (newCurrentPx / newAvailableForFrPx) * totalFr : 1;\r\n\r\n\t\tdimensions[index] = {\r\n\t\t\t...current,\r\n\t\t\tvalue: Math.round(newCurrentFr * 100) / 100,\r\n\t\t};\r\n\t} else {\r\n\t\t// currentが実寸値、nextはfr\r\n\t\tconst currentPx = toPx.fromDim(current);\r\n\t\tconst newCurrentPx = Math.max(10, currentPx + deltaPx);\r\n\r\n\t\t// currentの実寸値を更新\r\n\t\tdimensions[index] = {\r\n\t\t\t...current,\r\n\t\t\tvalue: convertPxToUnit(newCurrentPx, current.unit),\r\n\t\t};\r\n\r\n\t\t// 固定値の変化量\r\n\t\tconst fixedDelta = newCurrentPx - currentPx;\r\n\r\n\t\t// frの利用可能スペースが変わる\r\n\t\tconst newAvailableForFrPx = availableForFrPx - fixedDelta;\r\n\r\n\t\t// nextのfrを、新しいpx値から逆算\r\n\t\tconst nextPx = next.value * currentFrToPx;\r\n\t\tconst newNextPx = Math.max(10, nextPx - deltaPx);\r\n\t\tconst newNextFr =\r\n\t\t\ttotalFr > 0 ? (newNextPx / newAvailableForFrPx) * totalFr : 1;\r\n\r\n\t\tdimensions[index + 1] = {\r\n\t\t\t...next,\r\n\t\t\tvalue: Math.round(newNextFr * 100) / 100,\r\n\t\t};\r\n\t}\r\n\r\n\treturn dimensions;\r\n}\r\n\r\n/**\r\n * px値を指定単位に変換\r\n */\r\nfunction convertPxToUnit(pxValue: number, unit: GridUnit): number {\r\n\tswitch (unit) {\r\n\t\tcase \"px\":\r\n\t\t\treturn Math.round(pxValue);\r\n\t\tcase \"mm\": {\r\n\t\t\tconst mm = toMm.fromPx(pxValue);\r\n\t\t\treturn Math.round(mm * 10) / 10;\r\n\t\t}\r\n\t\tcase \"cm\": {\r\n\t\t\tconst mm = toMm.fromPx(pxValue);\r\n\t\t\treturn Math.round((mm / 10) * 100) / 100;\r\n\t\t}\r\n\t\tcase \"inch\": {\r\n\t\t\tconst mm = toMm.fromPx(pxValue);\r\n\t\t\treturn Math.round((mm / 25.4) * 100) / 100;\r\n\t\t}\r\n\t\tcase \"pt\": {\r\n\t\t\tconst mm = toMm.fromPx(pxValue);\r\n\t\t\treturn Math.round((mm / 25.4) * 72 * 10) / 10;\r\n\t\t}\r\n\t\tcase \"fr\":\r\n\t\t\t// frの場合は変換しない\r\n\t\t\treturn 1;\r\n\t\tdefault: {\r\n\t\t\tconst _exhaustive: never = unit;\r\n\t\t\tthrow new Error(`Unsupported unit: ${_exhaustive}`);\r\n\t\t}\r\n\t}\r\n}\r\n","// 浮動小数点ピクセル配列を整数ピクセル配列に変換(累積誤差補正アルゴリズム)\r\n\r\nimport { assertNonNegative } from \"../assert\";\r\n\r\n/**\r\n * 浮動小数点のピクセル配列を整数ピクセル配列に変換します。\r\n *\r\n * Bresenhamアルゴリズムに基づく累積誤差補正により、\r\n * 境界位置(prefix sum)のズレを最小化します。\r\n * これにより視覚的なバランスが保たれ、ピクセルギャップを防ぎます。\r\n *\r\n * @example\r\n * // 767px ÷ 3 = 255.666...\r\n * distributeRemainder([255.666, 255.666, 255.666])\r\n * // → [256, 255, 256] (合計767px、累積誤差を均等に分散)\r\n *\r\n * @example\r\n * // 100px ÷ 3 = 33.333...\r\n * distributeRemainder([33.333, 33.333, 33.333])\r\n * // → [33, 34, 33] (合計100px、累積誤差を補正)\r\n *\r\n * @param floatPixels - 浮動小数点のピクセル値配列\r\n * @returns 整数のピクセル値配列(合計値は元の合計を四捨五入した値と一致)\r\n *\r\n * @see https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm\r\n * @see Zen Grids - Responsive Design's Dirty Little Secret\r\n */\r\nexport function distributeRemainder(floatPixels: number[]): number[] {\r\n\tif (floatPixels.length === 0) {\r\n\t\treturn [];\r\n\t}\r\n\r\n\tconst result: number[] = [];\r\n\tlet accumulatedError = 0;\r\n\r\n\tfor (const px of floatPixels) {\r\n\t\tassertNonNegative(px, \"Pixel value\");\r\n\r\n\t\t// 1. 誤差を含めた目標値を計算\r\n\t\tconst target = px + accumulatedError;\r\n\r\n\t\t// 2. 四捨五入で整数化\r\n\t\tconst rounded = Math.round(target);\r\n\r\n\t\t// 3. 結果に追加\r\n\t\tresult.push(rounded);\r\n\r\n\t\t// 4. 新たな誤差を計算(目標値 - 実際の値)\r\n\t\taccumulatedError = target - rounded;\r\n\t}\r\n\r\n\treturn result;\r\n}\r\n","// 現在のpx値からグリッドインデックスを取得するユーティリティ関数\r\n// 正直過剰実装気味かも\r\n\r\n// ここらへんは経験的な値、調整の余地あり\r\n// 一般的にステップ数は8〜32の間、らしい(多いのは16)\r\nconst MIN_STEP = 8;\r\nconst MAX_STEP = 32;\r\n\r\n// 大きく動いたとみなすpx値\r\nconst MIN_WINDOW_PX = 64;\r\nconst MAX_WINDOW_PX = 512;\r\n\r\nconst _clamp = (x: number, lo: number, hi: number): number => {\r\n\treturn Math.min(Math.max(x, lo), hi);\r\n};\r\n\r\n// fingerSearchから二分探索に切り替える歩数と領域を取得する関数\r\n// useMemoでキャッシュして使うことを想定\r\nexport function getMaxStep(starts: number[]): {\r\n\treadonly step: number;\r\n\treadonly windowPx: number;\r\n} {\r\n\tconst count = starts.length - 1;\r\n\tconst total = count >= 1 ? (starts[count] ?? 0) : 0;\r\n\tconst avg = starts.length >= 1 ? total / count : 0;\r\n\r\n\t// 現在位置からたどる最大ステップ\r\n\tconst step = _clamp(Math.ceil(Math.log2(count + 1)), MIN_STEP, MAX_STEP);\r\n\r\n\t// 小さい幅のグリッドがたくさん並ぶほど窓を小さくし、二分探索に早く切り替える\r\n\tconst windowPx = _clamp(avg * 2, MIN_WINDOW_PX, MAX_WINDOW_PX);\r\n\r\n\treturn { step, windowPx };\r\n}\r\n\r\n// 整列済み配列に対する二分探索\r\nexport function binarySearch(num: number, arr: readonly number[]): number {\r\n\tconst cnt = arr.length - 1;\r\n\tif (cnt <= 0) return -1;\r\n\tif (arr[0] === undefined || num < arr[0]) return -1;\r\n\tif (arr[cnt] === undefined) return -1;\r\n\tif (num >= arr[cnt]) return cnt - 1;\r\n\r\n\tlet lo = 1;\r\n\tlet hi = cnt;\r\n\twhile (lo <= hi) {\r\n\t\tconst mid = (lo + hi) >>> 1;\r\n\t\tconst midValue = arr[mid];\r\n\t\tif (midValue === undefined) {\r\n\t\t\thi = mid - 1;\r\n\t\t\tcontinue;\r\n\t\t}\r\n\t\tif (midValue <= num) {\r\n\t\t\tlo = mid + 1;\r\n\t\t} else {\r\n\t\t\thi = mid - 1;\r\n\t\t}\r\n\t}\r\n\treturn lo - 1;\r\n}\r\n\r\n// finger search + 二分探索によるグリッドインデックス探索\r\nexport function findGridIndex(\r\n\tstarts: readonly number[],\r\n\tmaxStep: number,\r\n\twindowPx: number,\r\n): (px: number) => number {\r\n\tconst cnt = starts.length - 1;\r\n\tlet last = 0;\r\n\r\n\treturn (px: number) => {\r\n\t\t// 前提\r\n\t\tif (cnt <= 0) return -1;\r\n\t\tif (starts[0] === undefined || px < starts[0]) return -1;\r\n\t\tif (starts[cnt] === undefined) return -1;\r\n\t\tif (px >= starts[cnt]) return cnt - 1;\r\n\r\n\t\t// 同じ位置ならキャッシュを使う\r\n\t\tconst startValue = starts[last];\r\n\t\tconst nextValue = starts[last + 1];\r\n\t\tif (startValue === undefined || nextValue === undefined) {\r\n\t\t\treturn -1;\r\n\t\t}\r\n\t\tif (startValue <= px && px < nextValue) return last;\r\n\r\n\t\t// 大ジャンプ判定(windowPx超え)\r\n\t\tconst leftPx = startValue - windowPx;\r\n\t\tconst rightPx = nextValue + windowPx;\r\n\t\tif (px < leftPx || px >= rightPx) {\r\n\t\t\t// 二分探索に切り替え\r\n\t\t\tlast = binarySearch(px, starts);\r\n\t\t\treturn last;\r\n\t\t}\r\n\r\n\t\t// finger search(近い所から順にたどる)\r\n\t\tlet steps = 0;\r\n\t\tconst nextStart = starts[last + 1];\r\n\t\tif (nextStart !== undefined && px >= nextStart) {\r\n\t\t\t// 右方向\r\n\t\t\twhile (last + 1 < cnt) {\r\n\t\t\t\tconst next = starts[last + 1];\r\n\t\t\t\tif (next === undefined || px < next) break;\r\n\t\t\t\tlast++;\r\n\t\t\t\tif (++steps > maxStep) {\r\n\t\t\t\t\tlast = binarySearch(px, starts);\r\n\t\t\t\t\treturn last;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\t// 左方向\r\n\t\t\twhile (last > 0) {\r\n\t\t\t\tconst current = starts[last];\r\n\t\t\t\tif (current === undefined || px >= current) break;\r\n\t\t\t\tlast--;\r\n\t\t\t\tif (++steps > maxStep) {\r\n\t\t\t\t\tlast = binarySearch(px, starts);\r\n\t\t\t\t\treturn last;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn last;\r\n\t};\r\n}\r\n","// 複数の単位が混在するグリッド寸法配列をmm配列に変換するユーティリティ関数\r\n\r\nimport { assertNonNegative, assertRange } from \"../assert\";\r\nimport { toMm } from \"../convert\";\r\n\r\nimport type { Dimension, GridUnit } from \"@/types/unit\";\r\n\r\n// グリッド寸法配列をmm配列に変換する関数\r\nexport function gridToMms(\r\n\tdims: Dimension<GridUnit>[],\r\n\tcontentSizeMm: number,\r\n): number[] {\r\n\t// 入力値チェック\r\n\tif (dims.length === 0) return [];\r\n\tassertNonNegative(contentSizeMm, \"Content size\");\r\n\r\n\t// 各要素をmmに変換、frはnullに置き換え\r\n\tlet totalFr = 0;\r\n\tlet fixedTotalMm = 0;\r\n\r\n\tconst mmsWithoutFr: (number | null)[] = dims.map((dim) => {\r\n\t\tassertNonNegative(dim.value, `Grid dimension value`);\r\n\t\tif (dim.unit === \"fr\") {\r\n\t\t\ttotalFr += dim.value;\r\n\t\t\treturn null;\r\n\t\t} else {\r\n\t\t\tconst mm = toMm.fromDim(dim);\r\n\t\t\tfixedTotalMm += mm;\r\n\t\t\treturn mm;\r\n\t\t}\r\n\t});\r\n\r\n\t// frがない場合はそのまま返す\r\n\tif (totalFr === 0) {\r\n\t\tassertRange(fixedTotalMm, 0, contentSizeMm, \"Total fixed size\");\r\n\t\treturn mmsWithoutFr as number[];\r\n\t}\r\n\r\n\t// 残りのサイズを計算\r\n\tconst remainingMm = contentSizeMm - fixedTotalMm;\r\n\tassertNonNegative(remainingMm, \"Content size - fixed sizes\");\r\n\r\n\t// 1frあたりのサイズを計算\r\n\tconst mmPerFr = remainingMm / totalFr;\r\n\r\n\t// frをmmに変換して最終結果を作成\r\n\treturn mmsWithoutFr.map((val, i) => {\r\n\t\tconst dim = dims[i];\r\n\t\tif (val !== null && val !== undefined) return val;\r\n\t\tif (!dim) throw new Error(`dims[${i}] is undefined`);\r\n\t\treturn dim.value * mmPerFr;\r\n\t});\r\n}\r\n","// mm単位をpx単位に変換(剰余配布あり)\r\n\r\nimport { assertInteger, assertPositive } from \"../assert/number\";\r\nimport { toPx } from \"../convert\";\r\nimport { distributeRemainder } from \"./distributeRemainder\";\r\n\r\n// mm単位の数字配列をpx単位の数字配列に変換\r\nexport function mmsToPxs(mms: number[], dpi: number = 96): number[] {\r\n\t// 入力値チェック\r\n\tassertPositive(dpi, \"DPI\");\r\n\tassertInteger(dpi, \"DPI\");\r\n\r\n\t// mm配列をpx配列に変換(一旦float許容)\r\n\tconst gridPxsFloat = mms.map((mm) => toPx.fromMm(mm, dpi));\r\n\r\n\t// float配列を整数配列に変換(剰余配布あり)\r\n\tconst gridPxs = distributeRemainder(gridPxsFloat);\r\n\r\n\treturn gridPxs;\r\n}\r\n","// 複数の単位が混在するグリッド寸法配列をピクセル単位の整数配列に変換するユーティリティ関数\r\n\r\nimport {\r\n\tassertInteger,\r\n\tassertNonNegative,\r\n\tassertPositive,\r\n} from \"../assert/number\";\r\nimport { gridToMms } from \"./gridToMms\";\r\nimport { mmsToPxs } from \"./mmsToPxs\";\r\n\r\nimport type { Dimension, GridUnit } from \"@/types\";\r\n\r\nexport function gridToPxs(\r\n\tdims: Dimension<GridUnit>[],\r\n\tcontentSizeMm: number,\r\n\tdpi: number,\r\n): number[] {\r\n\t// 入力値チェック\r\n\tif (dims.length === 0) return [];\r\n\tassertPositive(dpi, \"DPI\");\r\n\tassertInteger(dpi, \"DPI\");\r\n\tassertNonNegative(contentSizeMm, \"Content size\");\r\n\r\n\t// グリッド寸法配列をmm配列に変換\r\n\tconst mms = gridToMms(dims, contentSizeMm);\r\n\r\n\t// mm配列をpx配列に変換\r\n\treturn mmsToPxs(mms, dpi);\r\n}\r\n","/**\r\n * @file objectUtils.ts\r\n * @description オブジェクト操作のユーティリティ関数\r\n */\r\n\r\n/**\r\n * オブジェクトからundefined/nullプロパティを再帰的に削除する\r\n * 空オブジェクト{}は保持される(削除指示として重要)\r\n */\r\nexport function removeUndefinedProps<T extends Record<string, unknown>>(\r\n\tobj: T,\r\n): T {\r\n\tconst result: Record<string, unknown> = {};\r\n\r\n\tfor (const [key, value] of Object.entries(obj)) {\r\n\t\tif (value === undefined || value === null) {\r\n\t\t\t// undefined/null は削除(resultに含めない)\r\n\t\t\tcontinue;\r\n\t\t}\r\n\r\n\t\tif (typeof value === \"object\" && !Array.isArray(value) && value !== null) {\r\n\t\t\t// ネストしたオブジェクトを再帰的に処理\r\n\t\t\tconst cleaned = removeUndefinedProps(value as Record<string, unknown>);\r\n\t\t\t// 空オブジェクトも保持する(削除指示として重要)\r\n\t\t\tresult[key] = cleaned;\r\n\t\t} else {\r\n\t\t\t// プリミティブ値や配列はそのまま保持\r\n\t\t\tresult[key] = value;\r\n\t\t}\r\n\t}\r\n\r\n\treturn result as T;\r\n}\r\n","/**\r\n * @file utils/print/index.ts\r\n * @description 印刷機能のユーティリティ\r\n */\r\n\r\nimport type { Orientation, PrintPaperSize } from \"@/types/print\";\r\n\r\n/**\r\n * 用紙サイズの寸法を取得(mm単位)\r\n */\r\nexport function getPaperSize(\r\n\tpaperSize: PrintPaperSize,\r\n\torientation: Orientation,\r\n): { width: number; height: number } {\r\n\tconst sizes: Record<PrintPaperSize, { width: number; height: number }> = {\r\n\t\tA4: { width: 210, height: 297 },\r\n\t\tA3: { width: 297, height: 420 },\r\n\t\tB4: { width: 257, height: 364 },\r\n\t\tB5: { width: 182, height: 257 },\r\n\t\tLetter: { width: 215.9, height: 279.4 },\r\n\t\tLegal: { width: 215.9, height: 355.6 },\r\n\t};\r\n\r\n\tconst size = sizes[paperSize];\r\n\r\n\tif (orientation === \"landscape\") {\r\n\t\treturn { width: size.height, height: size.width };\r\n\t}\r\n\r\n\treturn size;\r\n}\r\n\r\n/**\r\n * 印刷前の準備処理\r\n */\r\nexport function preparePrint(options?: {\r\n\ttitle?: string;\r\n\tremoveScrollbars?: boolean;\r\n}): void {\r\n\tif (options?.title) {\r\n\t\tdocument.title = options.title;\r\n\t}\r\n\r\n\tif (options?.removeScrollbars) {\r\n\t\tdocument.body.style.overflow = \"hidden\";\r\n\t}\r\n}\r\n\r\n/**\r\n * 印刷後のクリーンアップ処理\r\n */\r\nexport function cleanupPrint(options?: { restoreScrollbars?: boolean }): void {\r\n\tif (options?.restoreScrollbars) {\r\n\t\tdocument.body.style.overflow = \"\";\r\n\t}\r\n}\r\n\r\n/**\r\n * 特定の要素だけを印刷\r\n * 非破壊的な方法: 一時的なクラスを使用して、CSSで他の要素を非表示化\r\n */\r\nexport function printElement(\r\n\telement: HTMLElement,\r\n\toptions?: {\r\n\t\ttitle?: string;\r\n\t\tonBeforePrint?: () => void;\r\n\t\tonAfterPrint?: () => void;\r\n\t},\r\n): void {\r\n\tconst originalTitle = document.title;\r\n\r\n\t// 印刷用の一時的なスタイル要素を作成\r\n\tconst printStyle = document.createElement(\"style\");\r\n\tprintStyle.id = \"tatamicks-print-style\";\r\n\tprintStyle.textContent = `\r\n\t\t@media print {\r\n\t\t\t/* bodyとhtmlのマージン・パディングをリセット */\r\n\t\t\thtml, body {\r\n\t\t\t\tmargin: 0 !important;\r\n\t\t\t\tpadding: 0 !important;\r\n\t\t\t\twidth: 100% !important;\r\n\t\t\t\theight: 100% !important;\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\t/* すべての要素を非表示 */\r\n\t\t\tbody * {\r\n\t\t\t\tvisibility: hidden !important;\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\t/* 印刷対象の要素とその子孫を表示 */\r\n\t\t\t.tatamicks-print-target,\r\n\t\t\t.tatamicks-print-target * {\r\n\t\t\t\tvisibility: visible !important;\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\t/* 印刷対象の要素を左上に固定 */\r\n\t\t\t.tatamicks-print-target {\r\n\t\t\t\tposition: fixed !important;\r\n\t\t\t\tleft: 0 !important;\r\n\t\t\t\ttop: 0 !important;\r\n\t\t\t\tmargin: 0 !important;\r\n\t\t\t\tpadding: 0 !important;\r\n\t\t\t\ttransform: none !important;\r\n\t\t\t\t/* 親要素のスタイルを完全にオーバーライド */\r\n\t\t\t\tinset: 0 auto auto 0 !important;\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\t/* 背景色を印刷に含める */\r\n\t\t\t* {\r\n\t\t\t\t-webkit-print-color-adjust: exact !important;\r\n\t\t\t\tprint-color-adjust: exact !important;\r\n\t\t\t\tcolor-adjust: exact !important;\r\n\t\t\t}\r\n\t\t}\r\n\t`;\r\n\r\n\ttry {\r\n\t\t// スタイルを追加\r\n\t\tdocument.head.appendChild(printStyle);\r\n\r\n\t\t// 印刷対象の要素にクラスを追加\r\n\t\telement.classList.add(\"tatamicks-print-target\");\r\n\r\n\t\t// タイトル設定\r\n\t\tif (options?.title) {\r\n\t\t\tdocument.title = options.title;\r\n\t\t}\r\n\r\n\t\t// beforeprint コールバック\r\n\t\toptions?.onBeforePrint?.();\r\n\r\n\t\t// 印刷実行\r\n\t\twindow.print();\r\n\r\n\t\t// afterprint コールバック\r\n\t\toptions?.onAfterPrint?.();\r\n\t} finally {\r\n\t\t// クリーンアップ: クラスを削除\r\n\t\telement.classList.remove(\"tatamicks-print-target\");\r\n\r\n\t\t// スタイル要素を削除\r\n\t\tconst styleElement = document.getElementById(\"tatamicks-print-style\");\r\n\t\tif (styleElement) {\r\n\t\t\tstyleElement.remove();\r\n\t\t}\r\n\r\n\t\t// タイトルを復元\r\n\t\tdocument.title = originalTitle;\r\n\t}\r\n}\r\n\r\n/**\r\n * 印刷を実行(準備 + 印刷 + クリーンアップ)\r\n */\r\nexport function executePrint(options?: {\r\n\ttitle?: string;\r\n\tonBeforePrint?: () => void;\r\n\tonAfterPrint?: () => void;\r\n}): void {\r\n\t// 準備\r\n\tpreparePrint({ title: options?.title, removeScrollbars: true });\r\n\r\n\t// beforeprint イベント\r\n\tconst handleBeforePrint = () => {\r\n\t\toptions?.onBeforePrint?.();\r\n\t};\r\n\r\n\t// afterprint イベント\r\n\tconst handleAfterPrint = () => {\r\n\t\toptions?.onAfterPrint?.();\r\n\t\tcleanupPrint({ restoreScrollbars: true });\r\n\r\n\t\t// イベントリスナーを削除\r\n\t\twindow.removeEventListener(\"beforeprint\", handleBeforePrint);\r\n\t\twindow.removeEventListener(\"afterprint\", handleAfterPrint);\r\n\t};\r\n\r\n\t// イベントリスナーを登録\r\n\twindow.addEventListener(\"beforeprint\", handleBeforePrint);\r\n\twindow.addEventListener(\"afterprint\", handleAfterPrint);\r\n\r\n\t// 印刷実行\r\n\twindow.print();\r\n}\r\n","/**\r\n * @file validate.ts\r\n * @description スキーマのバリデーション機能\r\n */\r\n\r\nimport type { Block } from \"@/types/block\";\r\nimport type { Grid } from \"@/types/grid\";\r\nimport type { Paper } from \"@/types/paper\";\r\nimport type { FormSchema } from \"@/types/schema\";\r\nimport type { GridUnit } from \"@/types/unit\";\r\nimport type { Value } from \"@/types/value\";\r\n\r\n/**\r\n * 未知の値がBlockかどうかを型ガード\r\n */\r\nfunction isBlock(value: unknown): value is Block {\r\n\tif (typeof value !== \"object\" || value === null) return false;\r\n\r\n\tconst obj = value as Record<string, unknown>;\r\n\r\n\t// 必須プロパティのチェック\r\n\tif (typeof obj.id !== \"string\") return false;\r\n\tif (typeof obj.kind !== \"string\") return false;\r\n\r\n\t// layoutのチェック\r\n\tif (typeof obj.layout !== \"object\" || obj.layout === null) return false;\r\n\tconst layout = obj.layout as Record<string, unknown>;\r\n\tif (\r\n\t\ttypeof layout.x !== \"number\" ||\r\n\t\ttypeof layout.y !== \"number\" ||\r\n\t\ttypeof layout.w !== \"number\" ||\r\n\t\ttypeof layout.h !== \"number\"\r\n\t) {\r\n\t\treturn false;\r\n\t}\r\n\r\n\t// propsのチェック(存在する場合)\r\n\tif (obj.props !== undefined && typeof obj.props !== \"object\") {\r\n\t\treturn false;\r\n\t}\r\n\r\n\treturn true;\r\n}\r\n\r\n/**\r\n * 未知の値がGridUnitかどうかを型ガード\r\n */\r\nfunction isGridUnit(value: unknown): value is GridUnit {\r\n\treturn value === \"fr\" || value === \"px\" || value === \"%\";\r\n}\r\n\r\n/**\r\n * 未知の値がDimension配列かどうかを型ガード\r\n */\r\nfunction isDimensionArray(\r\n\tvalue: unknown,\r\n): value is Array<{ value: number; unit: GridUnit }> {\r\n\tif (!Array.isArray(value)) return false;\r\n\r\n\treturn value.every((item) => {\r\n\t\tif (typeof item !== \"object\" || item === null) return false;\r\n\t\tconst dim = item as Record<string, unknown>;\r\n\t\treturn typeof dim.value === \"number\" && isGridUnit(dim.unit);\r\n\t});\r\n}\r\n\r\n/**\r\n * 未知の値がGridかどうかを型ガード\r\n */\r\nfunction isGrid(value: unknown): value is Grid {\r\n\tif (typeof value !== \"object\" || value === null) return false;\r\n\r\n\tconst obj = value as Record<string, unknown>;\r\n\r\n\treturn isDimensionArray(obj.cols) && isDimensionArray(obj.rows);\r\n}\r\n\r\n/**\r\n * 未知の値がPaperかどうかを型ガード\r\n */\r\nfunction isPaper(value: unknown): value is Paper {\r\n\tif (typeof value !== \"object\" || value === null) return false;\r\n\r\n\tconst obj = value as Record<string, unknown>;\r\n\r\n\t// sizeのチェック\r\n\tif (typeof obj.size !== \"object\" || obj.size === null) return false;\r\n\tconst size = obj.size as Record<string, unknown>;\r\n\tif (typeof size.preset !== \"string\") return false;\r\n\r\n\t// size.widthのチェック (Dimension<PaperUnit>)\r\n\tif (typeof size.width !== \"object\" || size.width === null) return false;\r\n\tconst width = size.width as Record<string, unknown>;\r\n\tif (typeof width.value !== \"number\" || typeof width.unit !== \"string\") {\r\n\t\treturn false;\r\n\t}\r\n\r\n\t// size.heightのチェック (Dimension<PaperUnit>)\r\n\tif (typeof size.height !== \"object\" || size.height === null) return false;\r\n\tconst height = size.height as Record<string, unknown>;\r\n\tif (typeof height.value !== \"number\" || typeof height.unit !== \"string\") {\r\n\t\treturn false;\r\n\t}\r\n\r\n\t// marginのチェック\r\n\tif (typeof obj.margin !== \"object\" || obj.margin === null) return false;\r\n\tconst margin = obj.margin as Record<string, unknown>;\r\n\r\n\t// 各マージンがDimension<PaperUnit>かチェック\r\n\tfor (const key of [\"top\", \"right\", \"bottom\", \"left\"]) {\r\n\t\tconst marginSide = margin[key];\r\n\t\tif (typeof marginSide !== \"object\" || marginSide === null) return false;\r\n\t\tconst dim = marginSide as Record<string, unknown>;\r\n\t\tif (typeof dim.value !== \"number\" || typeof dim.unit !== \"string\") {\r\n\t\t\treturn false;\r\n\t\t}\r\n\t}\r\n\r\n\treturn true;\r\n}\r\n\r\n/**\r\n * 未知の値がValueかどうかを型ガード\r\n */\r\nfunction isValue(value: unknown): value is Value {\r\n\t// Valueは string | number | boolean | null | undefined | Record<string, unknown>\r\n\tif (value === null || value === undefined) return true;\r\n\tif (typeof value === \"string\") return true;\r\n\tif (typeof value === \"number\") return true;\r\n\tif (typeof value === \"boolean\") return true;\r\n\tif (typeof value === \"object\" && !Array.isArray(value)) return true;\r\n\r\n\treturn false;\r\n}\r\n\r\n/**\r\n * 未知の値がFormSchemaかどうかをバリデーションし、型安全に変換\r\n *\r\n * @param value - バリデーションする値\r\n * @returns FormSchema (バリデーション済み)\r\n * @throws バリデーションエラー時にエラーをスロー\r\n *\r\n * @example\r\n * ```ts\r\n * const unknownData = JSON.parse(jsonString);\r\n * const schema = validateSchema(unknownData);\r\n * ```\r\n */\r\nexport function validateSchema(value: unknown): FormSchema {\r\n\tif (typeof value !== \"object\" || value === null) {\r\n\t\tthrow new Error(\"Schema must be an object\");\r\n\t}\r\n\r\n\tconst obj = value as Record<string, unknown>;\r\n\r\n\t// paperのバリデーション\r\n\tif (!isPaper(obj.paper)) {\r\n\t\tthrow new Error(\"Invalid paper definition\");\r\n\t}\r\n\r\n\t// gridのバリデーション\r\n\tif (!isGrid(obj.grid)) {\r\n\t\tthrow new Error(\"Invalid grid definition\");\r\n\t}\r\n\r\n\t// blocksのバリデーション\r\n\tif (!Array.isArray(obj.blocks)) {\r\n\t\tthrow new Error(\"blocks must be an array\");\r\n\t}\r\n\r\n\tif (!obj.blocks.every(isBlock)) {\r\n\t\tthrow new Error(\"Invalid block definition in blocks array\");\r\n\t}\r\n\r\n\t// metaDataのバリデーション(オプション)\r\n\tif (obj.metaData !== undefined) {\r\n\t\tif (typeof obj.metaData !== \"object\" || obj.metaData === null) {\r\n\t\t\tthrow new Error(\"metaData must be an object if provided\");\r\n\t\t}\r\n\r\n\t\tconst metaData = obj.metaData as Record<string, unknown>;\r\n\t\tfor (const key in metaData) {\r\n\t\t\tif (!isValue(metaData[key])) {\r\n\t\t\t\tthrow new Error(`Invalid value in metaData.${key}`);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\treturn obj as unknown as FormSchema;\r\n}\r\n","/**\r\n * @file deserialize.ts\r\n * @description スキーマのデシリアライズ機能\r\n */\r\n\r\nimport { validateSchema } from \"./validate\";\r\n\r\nimport type { FormSchema } from \"@/types/schema\";\r\n\r\n/**\r\n * JSON文字列をFormSchemaにデシリアライズ\r\n *\r\n * @param json - デシリアライズするJSON文字列\r\n * @returns FormSchema (バリデーション済み)\r\n * @throws バリデーションエラー時にエラーをスロー\r\n *\r\n * @example\r\n * ```ts\r\n * const json = '{\"paper\": {...}, \"grid\": {...}, \"blocks\": [...]}';\r\n * const schema = deserializeSchema(json);\r\n * ```\r\n */\r\nexport function deserializeSchema(json: string): FormSchema {\r\n\ttry {\r\n\t\tconst parsed = JSON.parse(json);\r\n\t\treturn validateSchema(parsed);\r\n\t} catch (error) {\r\n\t\tif (error instanceof SyntaxError) {\r\n\t\t\tthrow new Error(`Invalid JSON format: ${error.message}`);\r\n\t\t}\r\n\t\tthrow error;\r\n\t}\r\n}\r\n","/**\r\n * @file serialize.ts\r\n * @description スキーマのシリアライズ機能\r\n */\r\n\r\nimport type { FormSchema } from \"@/types/schema\";\r\n\r\n/**\r\n * FormSchemaをJSON文字列にシリアライズ\r\n *\r\n * @param schema - シリアライズするスキーマ\r\n * @param pretty - 整形して出力するか (デフォルト: false)\r\n * @returns JSON文字列\r\n *\r\n * @example\r\n * ```ts\r\n * const schema: FormSchema = { ... };\r\n * const json = serializeSchema(schema);\r\n * // または整形版\r\n * const prettyJson = serializeSchema(schema, true);\r\n * ```\r\n */\r\nexport function serializeSchema(schema: FormSchema, pretty = false): string {\r\n\ttry {\r\n\t\treturn pretty ? JSON.stringify(schema, null, 2) : JSON.stringify(schema);\r\n\t} catch (error) {\r\n\t\tthrow new Error(\r\n\t\t\t`Failed to serialize schema: ${error instanceof Error ? error.message : \"Unknown error\"}`,\r\n\t\t);\r\n\t}\r\n}\r\n","/**\r\n * @file validate.ts\r\n * @description 入力値のバリデーション機能\r\n */\r\n\r\nimport type { Value } from \"@/types/value\";\r\n\r\n/**\r\n * 未知の値がValueかどうかを型ガード\r\n */\r\nfunction isValue(value: unknown): value is Value {\r\n\t// Valueは string | number | boolean | null | undefined | Record<string, unknown>\r\n\tif (value === null || value === undefined) return true;\r\n\tif (typeof value === \"string\") return true;\r\n\tif (typeof value === \"number\") return true;\r\n\tif (typeof value === \"boolean\") return true;\r\n\tif (typeof value === \"object\" && !Array.isArray(value)) {\r\n\t\t// オブジェクトの場合、再帰的にチェック\r\n\t\tconst obj = value as Record<string, unknown>;\r\n\t\treturn Object.values(obj).every(isValue);\r\n\t}\r\n\r\n\treturn false;\r\n}\r\n\r\n/**\r\n * 未知の値がRecord<string, Value>かどうかをバリデーションし、型安全に変換\r\n *\r\n * @param value - バリデーションする値\r\n * @returns Record<string, Value> (バリデーション済み)\r\n * @throws バリデーションエラー時にエラーをスロー\r\n *\r\n * @example\r\n * ```ts\r\n * const unknownData = JSON.parse(jsonString);\r\n * const values = validateValues(unknownData);\r\n * ```\r\n */\r\nexport function validateValues(value: unknown): Record<string, Value> {\r\n\tif (typeof value !== \"object\" || value === null) {\r\n\t\tthrow new Error(\"Values must be an object\");\r\n\t}\r\n\r\n\tif (Array.isArray(value)) {\r\n\t\tthrow new Error(\"Values must be an object, not an array\");\r\n\t}\r\n\r\n\tconst obj = value as Record<string, unknown>;\r\n\r\n\t// すべてのプロパティがValidなValueかチェック\r\n\tfor (const key in obj) {\r\n\t\tif (!isValue(obj[key])) {\r\n\t\t\tthrow new Error(`Invalid value at key \"${key}\"`);\r\n\t\t}\r\n\t}\r\n\r\n\treturn obj as Record<string, Value>;\r\n}\r\n","/**\r\n * @file deserialize.ts\r\n * @description 入力値のデシリアライズ機能\r\n */\r\n\r\nimport { validateValues } from \"./validate\";\r\n\r\nimport type { Value } from \"@/types/value\";\r\n\r\n/**\r\n * JSON文字列を入力値(values)にデシリアライズ\r\n *\r\n * @param json - デシリアライズするJSON文字列\r\n * @returns Record<string, Value> (バリデーション済み)\r\n * @throws バリデーションエラー時にエラーをスロー\r\n *\r\n * @example\r\n * ```ts\r\n * const json = '{\"block-1\": \"Hello\", \"block-2\": 42}';\r\n * const values = deserializeValues(json);\r\n * ```\r\n */\r\nexport function deserializeValues(json: string): Record<string, Value> {\r\n\ttry {\r\n\t\tconst parsed = JSON.parse(json);\r\n\t\treturn validateValues(parsed);\r\n\t} catch (error) {\r\n\t\tif (error instanceof SyntaxError) {\r\n\t\t\tthrow new Error(`Invalid JSON format: ${error.message}`);\r\n\t\t}\r\n\t\tthrow error;\r\n\t}\r\n}\r\n","/**\r\n * @file serialize.ts\r\n * @description 入力値のシリアライズ機能\r\n */\r\n\r\nimport type { Value } from \"@/types/value\";\r\n\r\n/**\r\n * 入力値(values)をJSON文字列にシリアライズ\r\n *\r\n * @param values - シリアライズする入力値\r\n * @param pretty - 整形して出力するか (デフォルト: false)\r\n * @returns JSON文字列\r\n *\r\n * @example\r\n * ```ts\r\n * const values: Record<string, Value> = {\r\n * 'block-1': 'Hello',\r\n * 'block-2': 42,\r\n * };\r\n * const json = serializeValues(values);\r\n * // または整形版\r\n * const prettyJson = serializeValues(values, true);\r\n * ```\r\n */\r\nexport function serializeValues(\r\n\tvalues: Record<string, Value>,\r\n\tpretty = false,\r\n): string {\r\n\ttry {\r\n\t\treturn pretty ? JSON.stringify(values, null, 2) : JSON.stringify(values);\r\n\t} catch (error) {\r\n\t\tthrow new Error(\r\n\t\t\t`Failed to serialize values: ${error instanceof Error ? error.message : \"Unknown error\"}`,\r\n\t\t);\r\n\t}\r\n}\r\n","import { type BorderStyle, LineType } from \"@/types/line\";\r\nimport { Z_INDEX } from \"@/utils\";\r\n\r\nimport type { ResizeHandleStyle } from \"./ResizeHandles\";\r\n\r\nexport const SELECTION_STYLE: BorderStyle = {\r\n\tall: {\r\n\t\tcolor: \"#3b82f688\",\r\n\t\twidth: { value: 4, unit: \"px\" },\r\n\t\ttype: LineType.SOLID,\r\n\t},\r\n};\r\n\r\nexport const RESIZE_HANDLE_STYLE: ResizeHandleStyle = {\r\n\tsize: 12,\r\n\tbackgroundColor: \"#ffffff\",\r\n\tborderColor: \"#3b82f6\",\r\n\tborderWidth: 1,\r\n\tborderRadius: \"50%\",\r\n};\r\n\r\nexport const interactionZIndexs = {\r\n\tbase: Z_INDEX.INTERACTION_LAYER_BASE,\r\n\tselect_block: Z_INDEX.SELECT_BLOCK,\r\n\tblock_ghost: Z_INDEX.BLOCK_GHOST,\r\n\thover_outline: Z_INDEX.HOVER_OUTLINE,\r\n\tedit_block: Z_INDEX.EDIT_BLOCK,\r\n\tgrid_ghost: Z_INDEX.GRID_GHOST,\r\n\tgrid_handles: Z_INDEX.GRID_HANDLES,\r\n\tselect_border: Z_INDEX.BLOCK_SELECT_BORDER,\r\n\tblock_handles: Z_INDEX.BLOCK_HANDLES,\r\n\trubber_band: Z_INDEX.RUBBER_BAND,\r\n} as const;\r\n","/**\r\n * インタラクションモード\r\n *\r\n * @remarks\r\n * インタラクション操作の状態を型安全に扱うための列挙型\r\n */\r\nexport enum InteractionMode {\r\n\t/** 待機状態 */\r\n\tIDLE = \"idle\",\r\n\t/** マウスダウン中(クリックかドラッグか判定前) */\r\n\tPRESSING = \"pressing\",\r\n\t/** ドラッグ確定 */\r\n\tDRAGGING = \"dragging\",\r\n\t/** 編集中 */\r\n\tEDITING = \"editing\",\r\n}\r\n\r\n/**\r\n * リサイズハンドル方向\r\n *\r\n * @remarks\r\n * 8方向のリサイズハンドルを型安全に扱うための列挙型\r\n */\r\nexport enum ResizeHandle {\r\n\t/** 北(上) */\r\n\tN = \"n\",\r\n\t/** 北東(右上) */\r\n\tNE = \"ne\",\r\n\t/** 東(右) */\r\n\tE = \"e\",\r\n\t/** 南東(右下) */\r\n\tSE = \"se\",\r\n\t/** 南(下) */\r\n\tS = \"s\",\r\n\t/** 南西(左下) */\r\n\tSW = \"sw\",\r\n\t/** 西(左) */\r\n\tW = \"w\",\r\n\t/** 北西(左上) */\r\n\tNW = \"nw\",\r\n}\r\n\r\n/**\r\n * ドラッグ種別\r\n *\r\n * @remarks\r\n * ドラッグ操作の種類を型安全に扱うための列挙型\r\n */\r\nexport enum DragType {\r\n\t/** ブロックの移動 */\r\n\tMOVE = \"move\",\r\n\t/** ブロックのリサイズ */\r\n\tRESIZE = \"resize\",\r\n\t/** 新規ブロックの挿入 */\r\n\tINSERT = \"insert\",\r\n}\r\n\r\n/**\r\n * インタラクション変更イベント種別\r\n *\r\n * @remarks\r\n * インタラクション変更イベントの種類を型安全に扱うための列挙型\r\n */\r\nexport enum InteractionEventType {\r\n\t/** ブロックを選択 */\r\n\tSELECT = \"select\",\r\n\t/** 選択を解除 */\r\n\tDESELECT = \"deselect\",\r\n\t/** プレス開始(ドラッグ判定前) */\r\n\tSTART_PRESS = \"startPress\",\r\n\t/** ドラッグ更新 */\r\n\tUPDATE_DRAG = \"updateDrag\",\r\n\t/** ドラッグ終了 */\r\n\tEND_DRAG = \"endDrag\",\r\n\t/** ドラッグキャンセル */\r\n\tCANCEL_DRAG = \"cancelDrag\",\r\n\t/** 編集開始 */\r\n\tEDIT = \"edit\",\r\n\t/** 編集終了 */\r\n\tEND_EDIT = \"endEdit\",\r\n\t/** 挿入開始 */\r\n\tSTART_INSERT = \"startInsert\",\r\n\t/** 挿入キャンセル */\r\n\tCANCEL_INSERT = \"cancelInsert\",\r\n\t/** リサイズ開始 */\r\n\tSTART_RESIZE = \"startResize\",\r\n}\r\n\r\n/**\r\n * ドラッグ状態の詳細情報\r\n */\r\nexport interface DraggingState {\r\n\t/** ドラッグ種別 */\r\n\ttype: DragType;\r\n\r\n\t/** ドラッグ対象のブロックID群 */\r\n\tblockIds: string[];\r\n\r\n\t/** 開始グリッド座標 */\r\n\tstartGrid: { col: number; row: number };\r\n\r\n\t/** 現在のグリッド座標 */\r\n\tcurrentGrid: { col: number; row: number };\r\n\r\n\t/** 現在のマウス座標 (px, キャンバス相対) - キャンバス外でのゴースト表示用 */\r\n\tcurrentMousePx?: { x: number; y: number };\r\n\r\n\t/** リサイズ用: ハンドル位置 */\r\n\thandle?: ResizeHandle;\r\n\r\n\t/** 挿入用: プラグイン種別 */\r\n\tpluginKind?: string;\r\n\r\n\t/** 挿入用: デフォルトサイズ */\r\n\tdefaultSize?: { w: number; h: number };\r\n\r\n\t/** キャンバス外フラグ (true: 範囲外でドロップすると削除) */\r\n\tisOutside?: boolean;\r\n}\r\n\r\n/**\r\n * インタラクション状態 (単一オブジェクト)\r\n *\r\n * @remarks\r\n * Pluginの `value` に相当する統合状態\r\n * 全ての操作状態をこのオブジェクト1つで管理する\r\n */\r\nexport interface InteractionState {\r\n\t/** 現在のモード */\r\n\tmode: InteractionMode;\r\n\r\n\t/** 選択中のブロックID群 */\r\n\tselectedBlockIds: string[];\r\n\r\n\t/** 編集中のブロックID (nullの場合は編集モードではない) */\r\n\teditingBlockId: string | null;\r\n\r\n\t/** ドラッグ中の状態 (ドラッグ中のみ有効) */\r\n\tdragging?: DraggingState;\r\n}\r\n\r\n/**\r\n * インタラクション変更イベント\r\n *\r\n * @remarks\r\n * OnBlockChangeと同じパターン (type付きUnion型)\r\n * 全ての操作をこのイベントで表現する\r\n */\r\nexport type InteractionChangeEvent =\r\n\t| {\r\n\t\t\ttype: InteractionEventType.SELECT;\r\n\t\t\tblockIds: string[];\r\n\t\t\tshiftKey?: boolean;\r\n\t }\r\n\t| { type: InteractionEventType.DESELECT }\r\n\t| {\r\n\t\t\ttype: InteractionEventType.START_PRESS;\r\n\t\t\tblockId: string;\r\n\t\t\tstartGrid: { col: number; row: number };\r\n\t\t\tselectedBlockIds?: string[]; // 複数選択時のドラッグ対象\r\n\t }\r\n\t| {\r\n\t\t\ttype: InteractionEventType.UPDATE_DRAG;\r\n\t\t\tcurrentGrid: { col: number; row: number };\r\n\t\t\tcurrentMousePx: { x: number; y: number };\r\n\t\t\tisOutside?: boolean;\r\n\t }\r\n\t| { type: InteractionEventType.END_DRAG }\r\n\t| { type: InteractionEventType.CANCEL_DRAG }\r\n\t| { type: InteractionEventType.EDIT; blockId: string }\r\n\t| { type: InteractionEventType.END_EDIT }\r\n\t| {\r\n\t\t\ttype: InteractionEventType.START_INSERT;\r\n\t\t\tpluginKind: string;\r\n\t\t\tdefaultSize: { w: number; h: number };\r\n\t }\r\n\t| { type: InteractionEventType.CANCEL_INSERT }\r\n\t| {\r\n\t\t\ttype: InteractionEventType.START_RESIZE;\r\n\t\t\tblockId: string;\r\n\t\t\thandle: ResizeHandle;\r\n\t\t\tstartGrid: { col: number; row: number };\r\n\t };\r\n\r\n/**\r\n * インタラクション変更コールバック\r\n *\r\n * @remarks\r\n * Pluginの `onChange` に相当\r\n * 全ての操作変更をこの1つのコールバックで処理する\r\n */\r\nexport type OnInteractionChange = (event: InteractionChangeEvent) => void;\r\n","/**\r\n * @file ResizeHandles.tsx\r\n * @description リサイズ用ハンドル(8方向)を描画するコンポーネント\r\n */\r\nimport { memo } from \"react\";\r\n\r\nimport { ResizeHandle } from \"../types\";\r\nimport { RESIZE_HANDLE_STYLE } from \"./constants\";\r\nimport styles from \"./InteractionBlock.module.css\";\r\n\r\nimport { Z_INDEX } from \"@/utils/zIndex\";\r\n\r\nimport type React from \"react\";\r\n\r\nexport interface ResizeHandleStyle {\r\n\tsize: number;\r\n\tbackgroundColor: string;\r\n\tborderColor: string;\r\n\tborderWidth: number;\r\n\tborderRadius: string;\r\n}\r\n\r\nexport interface ResizeHandlesProps {\r\n\tonResizeStart: (e: React.PointerEvent, handle: ResizeHandle) => void;\r\n\tactiveHandle?: ResizeHandle | null;\r\n\thandleStyle?: ResizeHandleStyle;\r\n\tzIndex?: number;\r\n}\r\n\r\n// ハンドル定義(位置とカーソル)\r\nconst HANDLES = [\r\n\t{ id: ResizeHandle.NW, cursor: \"nwse-resize\", x: 0, y: 0 },\r\n\t{ id: ResizeHandle.N, cursor: \"ns-resize\", x: 50, y: 0 },\r\n\t{ id: ResizeHandle.NE, cursor: \"nesw-resize\", x: 100, y: 0 },\r\n\t{ id: ResizeHandle.W, cursor: \"ew-resize\", x: 0, y: 50 },\r\n\t{ id: ResizeHandle.E, cursor: \"ew-resize\", x: 100, y: 50 },\r\n\t{ id: ResizeHandle.SW, cursor: \"nesw-resize\", x: 0, y: 100 },\r\n\t{ id: ResizeHandle.S, cursor: \"ns-resize\", x: 50, y: 100 },\r\n\t{ id: ResizeHandle.SE, cursor: \"nwse-resize\", x: 100, y: 100 },\r\n] as const;\r\n\r\nexport const ResizeHandles = memo(\r\n\t({\r\n\t\tonResizeStart,\r\n\t\tactiveHandle,\r\n\t\thandleStyle = RESIZE_HANDLE_STYLE,\r\n\t\tzIndex = Z_INDEX.BLOCK_HANDLES,\r\n\t}: ResizeHandlesProps) => {\r\n\t\t// ハンドルのサイズ\r\n\t\tconst handleSize = handleStyle.size;\r\n\t\tconst offset = handleSize / 2;\r\n\r\n\t\treturn (\r\n\t\t\t<>\r\n\t\t\t\t{HANDLES.map(({ id, cursor, x, y }) => {\r\n\t\t\t\t\t// 位置計算: 0, 50(center), 100(end) からCSSを生成\r\n\t\t\t\t\tconst left =\r\n\t\t\t\t\t\tx === 50\r\n\t\t\t\t\t\t\t? `calc(50% - ${offset}px)`\r\n\t\t\t\t\t\t\t: x === 100\r\n\t\t\t\t\t\t\t\t? `calc(100% - ${offset}px)`\r\n\t\t\t\t\t\t\t\t: `-${offset}px`;\r\n\t\t\t\t\tconst top =\r\n\t\t\t\t\t\ty === 50\r\n\t\t\t\t\t\t\t? `calc(50% - ${offset}px)`\r\n\t\t\t\t\t\t\t: y === 100\r\n\t\t\t\t\t\t\t\t? `calc(100% - ${offset}px)`\r\n\t\t\t\t\t\t\t\t: `-${offset}px`;\r\n\r\n\t\t\t\t\tconst isActive = activeHandle === id;\r\n\r\n\t\t\t\t\treturn (\r\n\t\t\t\t\t\t<div\r\n\t\t\t\t\t\t\tkey={id}\r\n\t\t\t\t\t\t\tclassName={styles.resizeHandle}\r\n\t\t\t\t\t\t\tonPointerDown={(e) => {\r\n\t\t\t\t\t\t\t\te.stopPropagation(); // 親の移動開始イベントを止める\r\n\t\t\t\t\t\t\t\tonResizeStart(e, id);\r\n\t\t\t\t\t\t\t}}\r\n\t\t\t\t\t\t\tstyle={{\r\n\t\t\t\t\t\t\t\tposition: \"absolute\",\r\n\t\t\t\t\t\t\t\tleft,\r\n\t\t\t\t\t\t\t\ttop,\r\n\t\t\t\t\t\t\t\twidth: `${handleSize}px`,\r\n\t\t\t\t\t\t\t\theight: `${handleSize}px`,\r\n\t\t\t\t\t\t\t\tbackgroundColor: isActive\r\n\t\t\t\t\t\t\t\t\t? handleStyle.borderColor\r\n\t\t\t\t\t\t\t\t\t: handleStyle.backgroundColor, // アクティブ時は青で塗りつぶし\r\n\t\t\t\t\t\t\t\tborder: `${handleStyle.borderWidth}px solid ${handleStyle.borderColor}`,\r\n\t\t\t\t\t\t\t\tborderRadius: handleStyle.borderRadius,\r\n\t\t\t\t\t\t\t\tcursor,\r\n\t\t\t\t\t\t\t\tzIndex: zIndex,\r\n\t\t\t\t\t\t\t\tpointerEvents: \"auto\", // ハンドルはクリック可能\r\n\t\t\t\t\t\t\t\tboxSizing: \"border-box\",\r\n\t\t\t\t\t\t\t\topacity: isActive ? 1 : undefined, // アクティブなら常に表示、それ以外はCSSホバーで制御\r\n\t\t\t\t\t\t\t\ttransition:\r\n\t\t\t\t\t\t\t\t\t\"opacity 0.2s, background-color 0.2s, transform 0.2s\",\r\n\t\t\t\t\t\t\t\ttransform: isActive ? \"scale(1.2)\" : undefined, // アクティブ時に拡大\r\n\t\t\t\t\t\t\t}}\r\n\t\t\t\t\t\t\tdata-testid={`resize-handle-${id}`}\r\n\t\t\t\t\t\t/>\r\n\t\t\t\t\t);\r\n\t\t\t\t})}\r\n\t\t\t</>\r\n\t\t);\r\n\t},\r\n);\r\n\r\nResizeHandles.displayName = \"ResizeHandles\";\r\n","import { memo, useMemo } from \"react\";\r\n\r\nimport { SELECTION_STYLE } from \"./constants\";\r\n\r\nimport { BorderRenderer } from \"@/canvas/components/BorderRenderer/BorderRenderer\";\r\nimport { Border, type BorderStyle } from \"@/types/line\";\r\nimport { Z_INDEX } from \"@/utils/zIndex\";\r\n\r\ninterface SelectionBorderProps {\r\n\twidth: number;\r\n\theight: number;\r\n\tzIndex?: number;\r\n\tborderStyle?: BorderStyle;\r\n}\r\n\r\nexport const SelectionBorder = memo(\r\n\t({\r\n\t\twidth,\r\n\t\theight,\r\n\t\tzIndex = Z_INDEX.BLOCK_SELECT_BORDER,\r\n\t\tborderStyle = SELECTION_STYLE,\r\n\t}: SelectionBorderProps) => {\r\n\t\tconst border = useMemo(() => new Border(borderStyle), [borderStyle]);\r\n\r\n\t\tconst style: React.CSSProperties = {\r\n\t\t\tposition: \"absolute\",\r\n\t\t\tinset: 0,\r\n\t\t\tpointerEvents: \"none\",\r\n\t\t\tzIndex: zIndex,\r\n\t\t};\r\n\r\n\t\treturn (\r\n\t\t\t<div style={style}>\r\n\t\t\t\t<BorderRenderer width={width} height={height} border={border} />\r\n\t\t\t</div>\r\n\t\t);\r\n\t},\r\n);\r\n","/**\r\n * @file InteractionBlock.tsx\r\n */\r\nimport { memo } from \"react\";\r\n\r\nimport {\r\n\tinteractionZIndexs,\r\n\tRESIZE_HANDLE_STYLE,\r\n\tSELECTION_STYLE,\r\n} from \"./constants\";\r\nimport styles from \"./InteractionBlock.module.css\";\r\nimport { ResizeHandles } from \"./ResizeHandles\";\r\nimport { SelectionBorder } from \"./SelectionBorder\";\r\n\r\nimport type React from \"react\";\r\nimport type { Block, BlockRectPx } from \"@/types/block\";\r\nimport type { BorderStyle } from \"@/types/line\";\r\nimport type { ResizeHandle } from \"../types\";\r\n\r\nexport interface InteractionBlockProps {\r\n\tblock: Block;\r\n\trect: BlockRectPx;\r\n\t// リサイズ関連\r\n\tshowHandles?: boolean;\r\n\tonResizeStart?: (e: React.PointerEvent, handle: ResizeHandle) => void;\r\n\tactiveHandle?: ResizeHandle | null;\r\n\t// スタイル関連\r\n\tselectionStyle?: BorderStyle;\r\n\thandleStyle?: typeof RESIZE_HANDLE_STYLE;\r\n\t/** 選択枠のz-index (デフォルト: interactionZIndexs.select_border) */\r\n\tselectBorderZIndex?: number;\r\n\t/** リサイズハンドルのz-index (デフォルト: interactionZIndexs.block_handles) */\r\n\tblockHandlesZIndex?: number;\r\n}\r\n\r\nexport const InteractionBlock = memo(\r\n\t({\r\n\t\tblock,\r\n\t\trect,\r\n\t\tshowHandles = false,\r\n\t\tonResizeStart,\r\n\t\tactiveHandle,\r\n\t\tselectionStyle = SELECTION_STYLE,\r\n\t\thandleStyle = RESIZE_HANDLE_STYLE,\r\n\t\tselectBorderZIndex = interactionZIndexs.select_border,\r\n\t\tblockHandlesZIndex = interactionZIndexs.block_handles,\r\n\t}: InteractionBlockProps) => {\r\n\t\tconst style: React.CSSProperties = {\r\n\t\t\tposition: \"absolute\",\r\n\t\t\tleft: `${rect.left}px`,\r\n\t\t\ttop: `${rect.top}px`,\r\n\t\t\twidth: `${rect.width}px`,\r\n\t\t\theight: `${rect.height}px`,\r\n\t\t\tpointerEvents: \"none\",\r\n\t\t\t// zIndexを削除: 親にz-indexを設定すると子要素のz-indexが親に制約される\r\n\t\t};\r\n\r\n\t\treturn (\r\n\t\t\t<div\r\n\t\t\t\tclassName={styles.interactionBlock}\r\n\t\t\t\tstyle={style}\r\n\t\t\t\tdata-testid=\"interaction-block\"\r\n\t\t\t\tdata-block-id={block.id}\r\n\t\t\t>\r\n\t\t\t\t{/* 1. 選択枠 */}\r\n\t\t\t\t<SelectionBorder\r\n\t\t\t\t\twidth={rect.width}\r\n\t\t\t\t\theight={rect.height}\r\n\t\t\t\t\tzIndex={selectBorderZIndex}\r\n\t\t\t\t\tborderStyle={selectionStyle}\r\n\t\t\t\t/>\r\n\r\n\t\t\t\t{/* 2. リサイズハンドル */}\r\n\t\t\t\t{showHandles && onResizeStart && (\r\n\t\t\t\t\t<ResizeHandles\r\n\t\t\t\t\t\tonResizeStart={onResizeStart}\r\n\t\t\t\t\t\tactiveHandle={activeHandle}\r\n\t\t\t\t\t\thandleStyle={handleStyle}\r\n\t\t\t\t\t\tzIndex={blockHandlesZIndex}\r\n\t\t\t\t\t/>\r\n\t\t\t\t)}\r\n\t\t\t</div>\r\n\t\t);\r\n\t},\r\n);\r\n\r\nInteractionBlock.displayName = \"InteractionBlock\";\r\n","import { memo } from \"react\";\r\n\r\nimport { BlockRenderer } from \"../../BlockLayer/BlockRenderer\";\r\nimport { InteractionBlock } from \"../InteractionBlock\";\r\nimport { interactionZIndexs } from \"../InteractionBlock/constants\";\r\n\r\nimport { createBlock } from \"@/plugin/utils/block\";\r\nimport { NoteMode } from \"@/types/mode\";\r\n\r\nimport type { BlockPlugin } from \"@/plugin\";\r\nimport type { Block, BlockRectPx } from \"@/types/block\";\r\nimport type { BorderStyle } from \"@/types/line\";\r\n\r\nexport interface InsertGhostProps {\r\n\tpluginRegistry: Record<string, BlockPlugin>;\r\n\tgridLength: { cols: number; rows: number };\r\n\tgetBlockRectPx: (block: Block) => BlockRectPx;\r\n\tcurrentGrid: { col: number; row: number };\r\n\tcurrentMousePx?: { x: number; y: number }; // マウス座標を追加\r\n\tpluginKind: string;\r\n\tdefaultSize: { w: number; h: number };\r\n\tisOutside: boolean;\r\n\tselectionStyle: BorderStyle;\r\n\tghostZIndex?: number;\r\n\tselectBorderZIndex?: number;\r\n\tblockHandlesZIndex?: number;\r\n}\r\n\r\nexport const InsertGhost = memo(\r\n\t({\r\n\t\tpluginRegistry,\r\n\t\tgridLength,\r\n\t\tgetBlockRectPx,\r\n\t\tcurrentGrid,\r\n\t\tcurrentMousePx, // TODO: キャンバス外でマウス追従ゴースト表示用(将来実装)\r\n\t\tpluginKind,\r\n\t\tdefaultSize,\r\n\t\tisOutside,\r\n\t\tselectionStyle,\r\n\t\tghostZIndex = interactionZIndexs.block_ghost,\r\n\t\tselectBorderZIndex = interactionZIndexs.select_border,\r\n\t\tblockHandlesZIndex = interactionZIndexs.block_handles,\r\n\t}: InsertGhostProps) => {\r\n\t\tconst plugin = pluginRegistry[pluginKind];\r\n\r\n\t\tif (!plugin) return null;\r\n\r\n\t\tlet ghostRect: BlockRectPx;\r\n\r\n\t\t// キャンバス外ではマウス座標に追従するゴーストを表示\r\n\t\tif (isOutside && currentMousePx) {\r\n\t\t\t// 仮のブロックデータを生成(サイズ計算用)\r\n\t\t\tconst tempBlock = createBlock(plugin, {\r\n\t\t\t\tx: 0,\r\n\t\t\t\ty: 0,\r\n\t\t\t\tw: defaultSize.w,\r\n\t\t\t\th: defaultSize.h,\r\n\t\t\t});\r\n\t\t\tconst tempRect = getBlockRectPx(tempBlock);\r\n\r\n\t\t\t// マウス位置を中心にゴーストを配置\r\n\t\t\tghostRect = {\r\n\t\t\t\tleft: currentMousePx.x - tempRect.width / 2,\r\n\t\t\t\ttop: currentMousePx.y - tempRect.height / 2,\r\n\t\t\t\twidth: tempRect.width,\r\n\t\t\t\theight: tempRect.height,\r\n\t\t\t};\r\n\t\t} else {\r\n\t\t\t// キャンバス内ではグリッドに吸着\r\n\t\t\t// 1. グリッド範囲内にクランプ(はみ出し防止)\r\n\t\t\tconst maxX = gridLength.cols - defaultSize.w;\r\n\t\t\tconst maxY = gridLength.rows - defaultSize.h;\r\n\r\n\t\t\tconst x = Math.max(0, Math.min(currentGrid.col, maxX));\r\n\t\t\tconst y = Math.max(0, Math.min(currentGrid.row, maxY));\r\n\r\n\t\t\t// 2. 仮のブロックデータを生成(表示用)\r\n\t\t\tconst ghostBlock = createBlock(plugin, {\r\n\t\t\t\tx,\r\n\t\t\t\ty,\r\n\t\t\t\tw: defaultSize.w,\r\n\t\t\t\th: defaultSize.h,\r\n\t\t\t});\r\n\r\n\t\t\t// 3. ピクセル座標を取得 (getBlockRectPxを使用)\r\n\t\t\tghostRect = getBlockRectPx(ghostBlock);\r\n\t\t}\r\n\r\n\t\t// 4. 実際に表示するブロックデータ(レンダリング用)\r\n\t\tconst ghostBlock = createBlock(plugin, {\r\n\t\t\tx: 0,\r\n\t\t\ty: 0,\r\n\t\t\tw: defaultSize.w,\r\n\t\t\th: defaultSize.h,\r\n\t\t});\r\n\r\n\t\treturn (\r\n\t\t\t<div\r\n\t\t\t\tdata-testid=\"insert-ghost\"\r\n\t\t\t\tstyle={{\r\n\t\t\t\t\tposition: \"absolute\",\r\n\t\t\t\t\tinset: 0,\r\n\t\t\t\t\tpointerEvents: \"none\",\r\n\t\t\t\t}}\r\n\t\t\t>\r\n\t\t\t\t<div\r\n\t\t\t\t\tstyle={{\r\n\t\t\t\t\t\tposition: \"absolute\",\r\n\t\t\t\t\t\tleft: `${ghostRect.left}px`,\r\n\t\t\t\t\t\ttop: `${ghostRect.top}px`,\r\n\t\t\t\t\t\twidth: `${ghostRect.width}px`,\r\n\t\t\t\t\t\theight: `${ghostRect.height}px`,\r\n\t\t\t\t\t\topacity: isOutside ? 0.3 : 0.6,\r\n\t\t\t\t\t\tfilter: isOutside ? \"grayscale(100%)\" : \"none\",\r\n\t\t\t\t\t\tzIndex: ghostZIndex,\r\n\t\t\t\t\t}}\r\n\t\t\t\t>\r\n\t\t\t\t\t<BlockRenderer\r\n\t\t\t\t\t\tid={ghostBlock.id}\r\n\t\t\t\t\t\tplugin={plugin}\r\n\t\t\t\t\t\tprops={ghostBlock.props}\r\n\t\t\t\t\t\tvalue={ghostBlock.initValue}\r\n\t\t\t\t\t\tonChange={() => {}}\r\n\t\t\t\t\t\treadOnly={true}\r\n\t\t\t\t\t\tmode={NoteMode.EDIT}\r\n\t\t\t\t\t\tblockSizePx={ghostRect}\r\n\t\t\t\t\t\tblockZIndex={ghostZIndex}\r\n\t\t\t\t\t/>\r\n\t\t\t\t</div>\r\n\t\t\t\t<InteractionBlock\r\n\t\t\t\t\tblock={ghostBlock}\r\n\t\t\t\t\trect={ghostRect}\r\n\t\t\t\t\tselectionStyle={selectionStyle}\r\n\t\t\t\t\tselectBorderZIndex={selectBorderZIndex}\r\n\t\t\t\t\tblockHandlesZIndex={blockHandlesZIndex}\r\n\t\t\t\t/>\r\n\t\t\t</div>\r\n\t\t);\r\n\t},\r\n);\r\n\r\nInsertGhost.displayName = \"InsertGhost\";\r\n","/**\r\n * @file clampMultipleBlocks.ts\r\n * @description 複数ブロックの移動時に全体をまとめてクランプする処理\r\n */\r\n\r\nimport type { Block } from \"@/types/block\";\r\n\r\nexport interface ClampedBlockPosition {\r\n\tblockId: string;\r\n\tx: number;\r\n\ty: number;\r\n}\r\n\r\n/**\r\n * 複数ブロックの移動をクランプ\r\n * 全体のバウンディングボックスを計算し、グリッド範囲内に収めた上で\r\n * 相対位置を保持したまま各ブロックの新しい座標を返す\r\n *\r\n * @param blocks - 移動対象のブロック配列\r\n * @param deltaCol - 列方向の移動量\r\n * @param deltaRow - 行方向の移動量\r\n * @param gridCols - グリッドの列数\r\n * @param gridRows - グリッドの行数\r\n * @returns クランプ後の各ブロックの座標配列\r\n */\r\nexport function clampMultipleBlocks(\r\n\tblocks: Block[],\r\n\tdeltaCol: number,\r\n\tdeltaRow: number,\r\n\tgridCols: number,\r\n\tgridRows: number,\r\n): ClampedBlockPosition[] {\r\n\tif (blocks.length === 0) {\r\n\t\treturn [];\r\n\t}\r\n\r\n\t// 単一ブロックの場合\r\n\tif (blocks.length === 1) {\r\n\t\tconst block = blocks[0];\r\n\t\tif (!block) return [];\r\n\r\n\t\tconst maxX = gridCols - block.layout.w;\r\n\t\tconst maxY = gridRows - block.layout.h;\r\n\t\tconst newX = Math.max(0, Math.min(block.layout.x + deltaCol, maxX));\r\n\t\tconst newY = Math.max(0, Math.min(block.layout.y + deltaRow, maxY));\r\n\r\n\t\treturn [{ blockId: block.id, x: newX, y: newY }];\r\n\t}\r\n\r\n\t// 複数ブロックの場合: バウンディングボックス計算\r\n\tconst minX = Math.min(...blocks.map((b) => b.layout.x));\r\n\tconst minY = Math.min(...blocks.map((b) => b.layout.y));\r\n\tconst maxX = Math.max(...blocks.map((b) => b.layout.x + b.layout.w));\r\n\tconst maxY = Math.max(...blocks.map((b) => b.layout.y + b.layout.h));\r\n\r\n\tconst boundingW = maxX - minX;\r\n\tconst boundingH = maxY - minY;\r\n\r\n\t// バウンディングボックス全体の新しい最小座標を計算\r\n\tconst newMinX = minX + deltaCol;\r\n\tconst newMinY = minY + deltaRow;\r\n\r\n\t// グリッド範囲内にクランプ\r\n\tconst clampedMinX = Math.max(0, Math.min(newMinX, gridCols - boundingW));\r\n\tconst clampedMinY = Math.max(0, Math.min(newMinY, gridRows - boundingH));\r\n\r\n\t// 実際に適用する移動量 (クランプによって制限される可能性がある)\r\n\tconst actualDeltaCol = clampedMinX - minX;\r\n\tconst actualDeltaRow = clampedMinY - minY;\r\n\r\n\t// 各ブロックに同じオフセットを適用\r\n\treturn blocks.map((block) => ({\r\n\t\tblockId: block.id,\r\n\t\tx: block.layout.x + actualDeltaCol,\r\n\t\ty: block.layout.y + actualDeltaRow,\r\n\t}));\r\n}\r\n","/**\r\n * @file MovingGhost.tsx\r\n * @description ブロック移動中のゴースト表示コンポーネント\r\n */\r\n\r\nimport { memo } from \"react\";\r\n\r\nimport { BlockRenderer } from \"../../BlockLayer/BlockRenderer\";\r\nimport { InteractionBlock } from \"../InteractionBlock\";\r\nimport { interactionZIndexs } from \"../InteractionBlock/constants\";\r\nimport { clampMultipleBlocks } from \"../utils/clampMultipleBlocks\";\r\n\r\nimport { NoteMode } from \"@/types/mode\";\r\n\r\nimport type { BlockPlugin } from \"@/plugin\";\r\nimport type { Block, BlockRectPx } from \"@/types/block\";\r\nimport type { BorderStyle } from \"@/types/line\";\r\n\r\nexport interface MovingGhostProps {\r\n\tblocks: Block[];\r\n\tpluginRegistry: Record<string, BlockPlugin>;\r\n\tgridLength: { cols: number; rows: number };\r\n\tgetBlockRectPx: (block: Block) => BlockRectPx;\r\n\tselectedBlockIds: string[];\r\n\tdeltaCol: number;\r\n\tdeltaRow: number;\r\n\tisOutside: boolean;\r\n\tcurrentMousePx?: { x: number; y: number }; // マウス座標を追加\r\n\tselectionStyle: BorderStyle;\r\n\tghostZIndex?: number;\r\n\tselectBorderZIndex?: number;\r\n\tblockHandlesZIndex?: number;\r\n}\r\n\r\nexport const MovingGhost = memo(\r\n\t({\r\n\t\tblocks,\r\n\t\tpluginRegistry,\r\n\t\tgridLength,\r\n\t\tgetBlockRectPx,\r\n\t\tselectedBlockIds,\r\n\t\tdeltaCol,\r\n\t\tdeltaRow,\r\n\t\tisOutside,\r\n\t\tcurrentMousePx,\r\n\t\tselectionStyle,\r\n\t\tghostZIndex = interactionZIndexs.block_ghost,\r\n\t\tselectBorderZIndex = interactionZIndexs.select_border,\r\n\t\tblockHandlesZIndex = interactionZIndexs.block_handles,\r\n\t}: MovingGhostProps) => {\r\n\t\t// 共通のクランプ処理を使用して各ブロックの新しい座標を計算\r\n\t\tconst dragTargets = selectedBlockIds\r\n\t\t\t.map((id) => blocks.find((b) => b.id === id))\r\n\t\t\t.filter(Boolean) as Block[];\r\n\r\n\t\tconst clampedPositions = clampMultipleBlocks(\r\n\t\t\tdragTargets,\r\n\t\t\tdeltaCol,\r\n\t\t\tdeltaRow,\r\n\t\t\tgridLength.cols,\r\n\t\t\tgridLength.rows,\r\n\t\t);\r\n\r\n\t\treturn (\r\n\t\t\t<div\r\n\t\t\t\tdata-testid=\"moving-ghost\"\r\n\t\t\t\tstyle={{\r\n\t\t\t\t\tposition: \"absolute\",\r\n\t\t\t\t\tinset: 0,\r\n\t\t\t\t\tpointerEvents: \"none\",\r\n\t\t\t\t}}\r\n\t\t\t>\r\n\t\t\t\t{selectedBlockIds.map((id) => {\r\n\t\t\t\t\tconst block = blocks.find((b) => b.id === id);\r\n\t\t\t\t\tif (!block) return null;\r\n\r\n\t\t\t\t\tconst plugin = pluginRegistry[block.kind];\r\n\t\t\t\t\tif (!plugin) return null;\r\n\r\n\t\t\t\t\tlet ghostRect: BlockRectPx;\r\n\r\n\t\t\t\t\t// キャンバス外ではマウス座標に追従するゴーストを表示\r\n\t\t\t\t\tif (isOutside && currentMousePx) {\r\n\t\t\t\t\t\t// 元のブロックのサイズを取得\r\n\t\t\t\t\t\tconst originalRect = getBlockRectPx(block);\r\n\r\n\t\t\t\t\t\t// マウス位置を中心にゴーストを配置\r\n\t\t\t\t\t\tghostRect = {\r\n\t\t\t\t\t\t\tleft: currentMousePx.x - originalRect.width / 2,\r\n\t\t\t\t\t\t\ttop: currentMousePx.y - originalRect.height / 2,\r\n\t\t\t\t\t\t\twidth: originalRect.width,\r\n\t\t\t\t\t\t\theight: originalRect.height,\r\n\t\t\t\t\t\t};\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\t// キャンバス内ではクランプ済みの座標を使用\r\n\t\t\t\t\t\tconst clampedPos = clampedPositions.find(\r\n\t\t\t\t\t\t\t(p) => p.blockId === block.id,\r\n\t\t\t\t\t\t);\r\n\r\n\t\t\t\t\t\tif (!clampedPos) return null;\r\n\r\n\t\t\t\t\t\tconst ghostBlock: Block = {\r\n\t\t\t\t\t\t\t...block,\r\n\t\t\t\t\t\t\tlayout: {\r\n\t\t\t\t\t\t\t\t...block.layout,\r\n\t\t\t\t\t\t\t\tx: clampedPos.x,\r\n\t\t\t\t\t\t\t\ty: clampedPos.y,\r\n\t\t\t\t\t\t\t},\r\n\t\t\t\t\t\t};\r\n\r\n\t\t\t\t\t\tghostRect = getBlockRectPx(ghostBlock);\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// 表示用のブロックデータ\r\n\t\t\t\t\tconst ghostBlock: Block = {\r\n\t\t\t\t\t\t...block,\r\n\t\t\t\t\t\tlayout: {\r\n\t\t\t\t\t\t\t...block.layout,\r\n\t\t\t\t\t\t\tx: 0,\r\n\t\t\t\t\t\t\ty: 0,\r\n\t\t\t\t\t\t},\r\n\t\t\t\t\t};\r\n\r\n\t\t\t\t\treturn (\r\n\t\t\t\t\t\t<div key={id}>\r\n\t\t\t\t\t\t\t<div\r\n\t\t\t\t\t\t\t\tstyle={{\r\n\t\t\t\t\t\t\t\t\tposition: \"absolute\",\r\n\t\t\t\t\t\t\t\t\tleft: `${ghostRect.left}px`,\r\n\t\t\t\t\t\t\t\t\ttop: `${ghostRect.top}px`,\r\n\t\t\t\t\t\t\t\t\twidth: `${ghostRect.width}px`,\r\n\t\t\t\t\t\t\t\t\theight: `${ghostRect.height}px`,\r\n\t\t\t\t\t\t\t\t\topacity: isOutside ? 0.3 : 0.5,\r\n\t\t\t\t\t\t\t\t\tfilter: isOutside ? \"grayscale(100%)\" : \"none\",\r\n\t\t\t\t\t\t\t\t\tzIndex: ghostZIndex,\r\n\t\t\t\t\t\t\t\t}}\r\n\t\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t\t<BlockRenderer\r\n\t\t\t\t\t\t\t\t\tid={ghostBlock.id}\r\n\t\t\t\t\t\t\t\t\tplugin={plugin}\r\n\t\t\t\t\t\t\t\t\tprops={ghostBlock.props}\r\n\t\t\t\t\t\t\t\t\tvalue={ghostBlock.initValue}\r\n\t\t\t\t\t\t\t\t\tonChange={() => {}}\r\n\t\t\t\t\t\t\t\t\treadOnly={true}\r\n\t\t\t\t\t\t\t\t\tmode={NoteMode.EDIT}\r\n\t\t\t\t\t\t\t\t\tblockSizePx={ghostRect}\r\n\t\t\t\t\t\t\t\t\tblockZIndex={ghostZIndex}\r\n\t\t\t\t\t\t\t\t\tclassName=\"ghost-content\"\r\n\t\t\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t\t</div>\r\n\t\t\t\t\t\t\t<InteractionBlock\r\n\t\t\t\t\t\t\t\tblock={ghostBlock}\r\n\t\t\t\t\t\t\t\trect={ghostRect}\r\n\t\t\t\t\t\t\t\tselectionStyle={selectionStyle}\r\n\t\t\t\t\t\t\t\tselectBorderZIndex={selectBorderZIndex}\r\n\t\t\t\t\t\t\t\tblockHandlesZIndex={blockHandlesZIndex}\r\n\t\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t</div>\r\n\t\t\t\t\t);\r\n\t\t\t\t})}\r\n\t\t\t</div>\r\n\t\t);\r\n\t},\r\n);\r\n\r\nMovingGhost.displayName = \"MovingGhost\";\r\n","/**\r\n * @file calcResize.ts\r\n * @description リサイズ計算ロジックの共通関数\r\n *\r\n * @remarks\r\n * InteractionLayerとResizeGhostで共通使用される計算ロジック。\r\n * DRY原則に従い、1箇所に集約することで保守性を向上。\r\n */\r\n\r\nimport { ResizeHandle } from \"../types\";\r\n\r\n/**\r\n * ブロックレイアウト(グリッド座標系)\r\n */\r\nexport interface BlockLayout {\r\n\tx: number;\r\n\ty: number;\r\n\tw: number;\r\n\th: number;\r\n}\r\n\r\n/**\r\n * リサイズ計算パラメータ\r\n */\r\nexport interface ResizeParams {\r\n\t/** 現在のレイアウト */\r\n\tlayout: BlockLayout;\r\n\t/** リサイズハンドル */\r\n\thandle: ResizeHandle;\r\n\t/** 列方向の移動量 */\r\n\tdeltaCol: number;\r\n\t/** 行方向の移動量 */\r\n\tdeltaRow: number;\r\n\t/** グリッドの列数 */\r\n\tgridCols: number;\r\n\t/** グリッドの行数 */\r\n\tgridRows: number;\r\n}\r\n\r\n/**\r\n * リサイズ後のレイアウトを計算\r\n *\r\n * @param params - リサイズパラメータ\r\n * @returns 新しいレイアウト\r\n *\r\n * @remarks\r\n * - 最小サイズは1x1\r\n * - グリッド範囲外にははみ出さない\r\n * - 左端・上端を超える場合は自動的にクランプ\r\n *\r\n * @example\r\n * ```typescript\r\n * const newLayout = calculateResizedLayout({\r\n * layout: { x: 2, y: 2, w: 3, h: 3 },\r\n * handle: ResizeHandle.SE,\r\n * deltaCol: 2,\r\n * deltaRow: 1,\r\n * gridCols: 10,\r\n * gridRows: 10,\r\n * });\r\n * // => { x: 2, y: 2, w: 5, h: 4 }\r\n * ```\r\n */\r\nexport function calculateResizedLayout({\r\n\tlayout,\r\n\thandle,\r\n\tdeltaCol,\r\n\tdeltaRow,\r\n\tgridCols,\r\n\tgridRows,\r\n}: ResizeParams): BlockLayout {\r\n\tconst newLayout = { ...layout };\r\n\r\n\t// --- 横方向のリサイズ ---\r\n\tif (\r\n\t\thandle === ResizeHandle.E ||\r\n\t\thandle === ResizeHandle.NE ||\r\n\t\thandle === ResizeHandle.SE\r\n\t) {\r\n\t\t// 右へ拡大・縮小\r\n\t\tconst maxW = gridCols - layout.x;\r\n\t\tnewLayout.w = Math.max(1, Math.min(layout.w + deltaCol, maxW));\r\n\t} else if (\r\n\t\thandle === ResizeHandle.W ||\r\n\t\thandle === ResizeHandle.NW ||\r\n\t\thandle === ResizeHandle.SW\r\n\t) {\r\n\t\t// 左へ拡大・縮小\r\n\t\t// 幅が1未満にならないようにdeltaを制限\r\n\t\tconst maxShrink = layout.w - 1;\r\n\t\tconst validDCol = deltaCol > 0 ? Math.min(deltaCol, maxShrink) : deltaCol;\r\n\r\n\t\t// 左端(x=0)を超えないように制限\r\n\t\tif (layout.x + validDCol >= 0) {\r\n\t\t\tnewLayout.x = layout.x + validDCol;\r\n\t\t\tnewLayout.w = layout.w - validDCol;\r\n\t\t} else {\r\n\t\t\t// 左端に張り付く場合\r\n\t\t\tnewLayout.x = 0;\r\n\t\t\tnewLayout.w = layout.w + layout.x;\r\n\t\t}\r\n\t}\r\n\r\n\t// --- 縦方向のリサイズ ---\r\n\tif (\r\n\t\thandle === ResizeHandle.S ||\r\n\t\thandle === ResizeHandle.SE ||\r\n\t\thandle === ResizeHandle.SW\r\n\t) {\r\n\t\t// 下へ拡大・縮小\r\n\t\tconst maxH = gridRows - layout.y;\r\n\t\tnewLayout.h = Math.max(1, Math.min(layout.h + deltaRow, maxH));\r\n\t} else if (\r\n\t\thandle === ResizeHandle.N ||\r\n\t\thandle === ResizeHandle.NE ||\r\n\t\thandle === ResizeHandle.NW\r\n\t) {\r\n\t\t// 上へ拡大・縮小\r\n\t\tconst maxShrink = layout.h - 1;\r\n\t\tconst validDRow = deltaRow > 0 ? Math.min(deltaRow, maxShrink) : deltaRow;\r\n\r\n\t\t// 上端(y=0)を超えないように制限\r\n\t\tif (layout.y + validDRow >= 0) {\r\n\t\t\tnewLayout.y = layout.y + validDRow;\r\n\t\t\tnewLayout.h = layout.h - validDRow;\r\n\t\t} else {\r\n\t\t\t// 上端に張り付く場合\r\n\t\t\tnewLayout.y = 0;\r\n\t\t\tnewLayout.h = layout.h + layout.y;\r\n\t\t}\r\n\t}\r\n\r\n\treturn newLayout;\r\n}\r\n","/**\r\n * @file ResizeGhost.tsx\r\n * @description ブロックリサイズ中のゴースト表示コンポーネント\r\n */\r\n\r\nimport { memo } from \"react\";\r\n\r\nimport { BlockRenderer } from \"../../BlockLayer/BlockRenderer\";\r\nimport { InteractionBlock } from \"../InteractionBlock\";\r\nimport { interactionZIndexs } from \"../InteractionBlock/constants\";\r\nimport { calculateResizedLayout } from \"../utils/calcResize\";\r\n\r\nimport { NoteMode } from \"@/types/mode\";\r\n\r\nimport type { BlockPlugin } from \"@/plugin\";\r\nimport type { Block, BlockRectPx } from \"@/types/block\";\r\nimport type { BorderStyle } from \"@/types/line\";\r\nimport type { ResizeHandle } from \"../types\";\r\n\r\nexport interface ResizeGhostProps {\r\n\tblocks: Block[];\r\n\tpluginRegistry: Record<string, BlockPlugin>;\r\n\tgridLength: { cols: number; rows: number };\r\n\tgetBlockRectPx: (block: Block) => BlockRectPx;\r\n\tblockId: string;\r\n\thandle: ResizeHandle;\r\n\tdeltaCol: number;\r\n\tdeltaRow: number;\r\n\tisOutside: boolean;\r\n\tselectionStyle: BorderStyle;\r\n\tghostZIndex?: number;\r\n\tselectBorderZIndex?: number;\r\n\tblockHandlesZIndex?: number;\r\n}\r\n\r\nexport const ResizeGhost = memo(\r\n\t({\r\n\t\tblocks,\r\n\t\tpluginRegistry,\r\n\t\tgridLength,\r\n\t\tgetBlockRectPx,\r\n\t\tblockId,\r\n\t\thandle,\r\n\t\tdeltaCol,\r\n\t\tdeltaRow,\r\n\t\tisOutside,\r\n\t\tselectionStyle,\r\n\t\tghostZIndex = interactionZIndexs.block_ghost,\r\n\t\tselectBorderZIndex = interactionZIndexs.select_border,\r\n\t\tblockHandlesZIndex = interactionZIndexs.block_handles,\r\n\t}: ResizeGhostProps) => {\r\n\t\tconst block = blocks.find((b) => b.id === blockId);\r\n\t\tconst plugin = pluginRegistry[block?.kind ?? \"\"];\r\n\t\tif (!block || !plugin) return null;\r\n\r\n\t\tconst newLayout = calculateResizedLayout({\r\n\t\t\tlayout: block.layout,\r\n\t\t\thandle,\r\n\t\t\tdeltaCol,\r\n\t\t\tdeltaRow,\r\n\t\t\tgridCols: gridLength.cols,\r\n\t\t\tgridRows: gridLength.rows,\r\n\t\t});\r\n\r\n\t\tconst ghostBlock: Block = {\r\n\t\t\t...block,\r\n\t\t\tlayout: newLayout,\r\n\t\t};\r\n\r\n\t\tconst ghostRect = getBlockRectPx(ghostBlock);\r\n\r\n\t\treturn (\r\n\t\t\t<div\r\n\t\t\t\tdata-testid=\"resize-ghost\"\r\n\t\t\t\tstyle={{\r\n\t\t\t\t\tposition: \"absolute\",\r\n\t\t\t\t\tinset: 0,\r\n\t\t\t\t\tpointerEvents: \"none\",\r\n\t\t\t\t}}\r\n\t\t\t>\r\n\t\t\t\t<div key={block.id}>\r\n\t\t\t\t\t<div\r\n\t\t\t\t\t\tstyle={{\r\n\t\t\t\t\t\t\tposition: \"absolute\",\r\n\t\t\t\t\t\t\tleft: `${ghostRect.left}px`,\r\n\t\t\t\t\t\t\ttop: `${ghostRect.top}px`,\r\n\t\t\t\t\t\t\twidth: `${ghostRect.width}px`,\r\n\t\t\t\t\t\t\theight: `${ghostRect.height}px`,\r\n\t\t\t\t\t\t\topacity: isOutside ? 0.3 : 0.5,\r\n\t\t\t\t\t\t\tfilter: isOutside ? \"grayscale(100%)\" : \"none\",\r\n\t\t\t\t\t\t\tzIndex: ghostZIndex,\r\n\t\t\t\t\t\t}}\r\n\t\t\t\t\t>\r\n\t\t\t\t\t\t<BlockRenderer\r\n\t\t\t\t\t\t\tid={ghostBlock.id}\r\n\t\t\t\t\t\t\tplugin={plugin}\r\n\t\t\t\t\t\t\tprops={ghostBlock.props}\r\n\t\t\t\t\t\t\tvalue={ghostBlock.initValue}\r\n\t\t\t\t\t\t\tonChange={() => {}}\r\n\t\t\t\t\t\t\treadOnly={true}\r\n\t\t\t\t\t\t\tmode={NoteMode.EDIT}\r\n\t\t\t\t\t\t\tblockSizePx={ghostRect}\r\n\t\t\t\t\t\t\tblockZIndex={ghostZIndex}\r\n\t\t\t\t\t\t\tclassName=\"resize-ghost-content\"\r\n\t\t\t\t\t\t/>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t\t<InteractionBlock\r\n\t\t\t\t\t\tblock={ghostBlock}\r\n\t\t\t\t\t\trect={ghostRect}\r\n\t\t\t\t\t\tselectionStyle={selectionStyle}\r\n\t\t\t\t\t\tselectBorderZIndex={selectBorderZIndex}\r\n\t\t\t\t\t\tblockHandlesZIndex={blockHandlesZIndex}\r\n\t\t\t\t\t/>\r\n\t\t\t\t</div>\r\n\t\t\t</div>\r\n\t\t);\r\n\t},\r\n);\r\n\r\nResizeGhost.displayName = \"ResizeGhost\";\r\n","/**\r\n * @file DragLayer.tsx\r\n * @description ドラッグ移動・リサイズ中のゴーストを表示するレイヤー\r\n */\r\n\r\nimport { memo } from \"react\";\r\n\r\nimport {\r\n\tinteractionZIndexs,\r\n\tSELECTION_STYLE,\r\n} from \"../InteractionBlock/constants\";\r\nimport { type DraggingState, DragType } from \"../types\";\r\nimport { InsertGhost } from \"./InsertGhost\";\r\nimport { MovingGhost } from \"./MovingGhost\";\r\nimport { ResizeGhost } from \"./ResizeGhost\";\r\n\r\nimport type { BlockPlugin } from \"@/plugin\";\r\nimport type { Block, BlockRectPx } from \"@/types/block\";\r\nimport type { BorderStyle } from \"@/types/line\";\r\n\r\nexport interface DragLayerProps {\r\n\tblocks: Block[];\r\n\tpluginRegistry: Record<string, BlockPlugin>;\r\n\tgridLength: { cols: number; rows: number };\r\n\tdraggingState: DraggingState | undefined;\r\n\tgetBlockRectPx: (block: Block) => BlockRectPx;\r\n\tselectionStyle?: BorderStyle;\r\n\tghostZIndex?: number;\r\n\tselectBorderZIndex?: number;\r\n\tblockHandlesZIndex?: number;\r\n}\r\n\r\nexport const DragLayer = memo(\r\n\t({\r\n\t\tblocks,\r\n\t\tpluginRegistry,\r\n\t\tgridLength,\r\n\t\tdraggingState,\r\n\t\tgetBlockRectPx,\r\n\t\tselectionStyle = SELECTION_STYLE,\r\n\t\tghostZIndex = interactionZIndexs.block_ghost,\r\n\t\tselectBorderZIndex = interactionZIndexs.select_border,\r\n\t\tblockHandlesZIndex = interactionZIndexs.block_handles,\r\n\t}: DragLayerProps) => {\r\n\t\t// ドラッグ中でなければ何も表示しない\r\n\t\tif (!draggingState) return null;\r\n\r\n\t\tconst deltaCol =\r\n\t\t\tdraggingState.currentGrid.col - draggingState.startGrid.col;\r\n\t\tconst deltaRow =\r\n\t\t\tdraggingState.currentGrid.row - draggingState.startGrid.row;\r\n\r\n\t\tswitch (draggingState.type) {\r\n\t\t\t// 移動モード\r\n\t\t\tcase DragType.MOVE:\r\n\t\t\t\treturn (\r\n\t\t\t\t\t<MovingGhost\r\n\t\t\t\t\t\tblocks={blocks}\r\n\t\t\t\t\t\tpluginRegistry={pluginRegistry}\r\n\t\t\t\t\t\tgridLength={gridLength}\r\n\t\t\t\t\t\tgetBlockRectPx={getBlockRectPx}\r\n\t\t\t\t\t\tselectedBlockIds={draggingState.blockIds}\r\n\t\t\t\t\t\tdeltaCol={deltaCol}\r\n\t\t\t\t\t\tdeltaRow={deltaRow}\r\n\t\t\t\t\t\tisOutside={draggingState.isOutside ?? false}\r\n\t\t\t\t\t\tcurrentMousePx={draggingState.currentMousePx}\r\n\t\t\t\t\t\tselectionStyle={selectionStyle}\r\n\t\t\t\t\t\tghostZIndex={ghostZIndex}\r\n\t\t\t\t\t\tselectBorderZIndex={selectBorderZIndex}\r\n\t\t\t\t\t\tblockHandlesZIndex={blockHandlesZIndex}\r\n\t\t\t\t\t/>\r\n\t\t\t\t);\r\n\r\n\t\t\t// リサイズモード\r\n\t\t\tcase DragType.RESIZE: {\r\n\t\t\t\tconst resizeBlockId = draggingState.blockIds[0];\r\n\t\t\t\tif (!resizeBlockId || !draggingState.handle) return null;\r\n\r\n\t\t\t\treturn (\r\n\t\t\t\t\t<ResizeGhost\r\n\t\t\t\t\t\tblocks={blocks}\r\n\t\t\t\t\t\tpluginRegistry={pluginRegistry}\r\n\t\t\t\t\t\tgridLength={gridLength}\r\n\t\t\t\t\t\tgetBlockRectPx={getBlockRectPx}\r\n\t\t\t\t\t\tblockId={resizeBlockId}\r\n\t\t\t\t\t\thandle={draggingState.handle}\r\n\t\t\t\t\t\tdeltaCol={deltaCol}\r\n\t\t\t\t\t\tdeltaRow={deltaRow}\r\n\t\t\t\t\t\tisOutside={draggingState.isOutside ?? false}\r\n\t\t\t\t\t\tselectionStyle={selectionStyle}\r\n\t\t\t\t\t\tghostZIndex={ghostZIndex}\r\n\t\t\t\t\t\tselectBorderZIndex={selectBorderZIndex}\r\n\t\t\t\t\t\tblockHandlesZIndex={blockHandlesZIndex}\r\n\t\t\t\t\t/>\r\n\t\t\t\t);\r\n\t\t\t}\r\n\r\n\t\t\t// 挿入モード\r\n\t\t\tcase DragType.INSERT: {\r\n\t\t\t\t// defaultSizeが未定義の場合は何も表示しない\r\n\t\t\t\tif (!draggingState.defaultSize) return null;\r\n\r\n\t\t\t\treturn (\r\n\t\t\t\t\t<InsertGhost\r\n\t\t\t\t\t\tpluginRegistry={pluginRegistry}\r\n\t\t\t\t\t\tgridLength={gridLength}\r\n\t\t\t\t\t\tgetBlockRectPx={getBlockRectPx}\r\n\t\t\t\t\t\tcurrentGrid={draggingState.currentGrid}\r\n\t\t\t\t\t\tcurrentMousePx={draggingState.currentMousePx}\r\n\t\t\t\t\t\tpluginKind={draggingState.pluginKind || \"\"}\r\n\t\t\t\t\t\tdefaultSize={draggingState.defaultSize}\r\n\t\t\t\t\t\tisOutside={draggingState.isOutside ?? false}\r\n\t\t\t\t\t\tselectionStyle={selectionStyle}\r\n\t\t\t\t\t\tghostZIndex={ghostZIndex}\r\n\t\t\t\t\t\tselectBorderZIndex={selectBorderZIndex}\r\n\t\t\t\t\t\tblockHandlesZIndex={blockHandlesZIndex}\r\n\t\t\t\t\t/>\r\n\t\t\t\t);\r\n\t\t\t}\r\n\r\n\t\t\t// その他のモードは何も表示しない\r\n\t\t\tdefault:\r\n\t\t\t\treturn null;\r\n\t\t}\r\n\t},\r\n);\r\n\r\nDragLayer.displayName = \"DragLayer\";\r\n","/**\r\n * @file EditingBlock.tsx\r\n * @description 編集中ブロックのRendererをInteractionLayer上に表示するコンポーネント\r\n *\r\n * @remarks\r\n * - BlockLayerとは独立して、InteractionLayer内でブロックの編集UIを表示\r\n * - z-indexはInteractionLayer内の順序(EDIT_BLOCK: 2,400,000)で管理\r\n * - SelectionBorderやResizeHandlesと同じStacking Context内にあるため、正しく重なり順を制御可能\r\n */\r\n\r\nimport { forwardRef, memo, useImperativeHandle, useRef } from \"react\";\r\n\r\nimport { NoteMode } from \"@/types/mode\";\r\nimport { getBlockContainerStyle } from \"@/utils/blockLayout\";\r\nimport { Z_INDEX } from \"@/utils/zIndex\";\r\n\r\nimport type React from \"react\";\r\nimport type { BlockPlugin, BlockRef, RendererProps } from \"@/plugin\";\r\nimport type { BlockRectPx, BlockSizePx } from \"@/types/block\";\r\nimport type { Value } from \"@/types/value\";\r\n\r\nexport interface EditingBlockProps<P = Record<string, Value>, V = Value> {\r\n\t/** ブロックID */\r\n\tid: string;\r\n\r\n\t/** プラグイン定義 */\r\n\tplugin: BlockPlugin<P, V>;\r\n\r\n\t/** プラグイン固有プロパティ */\r\n\tprops: P;\r\n\r\n\t/** ブロックの現在値 */\r\n\tvalue: V;\r\n\r\n\t/** 値変更コールバック */\r\n\tonChange: (value: V) => void;\r\n\r\n\t/** 値確定コールバック (オプション) */\r\n\tonBlur?: (value: V) => void;\r\n\r\n\t/** ブロックの位置とサイズ(ピクセル単位) */\r\n\tblockRectPx: BlockRectPx;\r\n\r\n\t/** z-index (オプション、デフォルト: Z_INDEX.EDIT_BLOCK) */\r\n\tzIndex?: number;\r\n\r\n\t/** バリデーション状態 (オプション) */\r\n\tvalidationState?: \"valid\" | \"invalid\" | \"warning\";\r\n\r\n\t/** 追加のクラス名 */\r\n\tclassName?: string;\r\n}\r\n\r\n/**\r\n * EditingBlock\r\n *\r\n * 編集中ブロックのRendererをInteractionLayer上に表示\r\n * - BlockLayerのブロックと同じ位置・サイズで表示\r\n * - プラグインのRendererコンポーネントを動的にレンダリング\r\n * - BlockRef経由でfocusメソッドを公開\r\n */\r\nconst EditingBlockInner = <P extends Record<string, Value>, V extends Value>(\r\n\t{\r\n\t\tid,\r\n\t\tplugin,\r\n\t\tprops,\r\n\t\tvalue,\r\n\t\tonChange,\r\n\t\tonBlur,\r\n\t\tblockRectPx,\r\n\t\tzIndex = Z_INDEX.EDIT_BLOCK,\r\n\t\tvalidationState,\r\n\t\tclassName = \"\",\r\n\t}: EditingBlockProps<P, V>,\r\n\tref: React.ForwardedRef<BlockRef>,\r\n) => {\r\n\t// プラグインのRendererコンポーネントへの参照\r\n\tconst pluginRendererRef = useRef<BlockRef>(null);\r\n\r\n\t// 外部から呼び出し可能なfocusメソッドを公開\r\n\tuseImperativeHandle(\r\n\t\tref,\r\n\t\t() => ({\r\n\t\t\tfocus: () => {\r\n\t\t\t\tpluginRendererRef.current?.focus();\r\n\t\t\t},\r\n\t\t}),\r\n\t\t[],\r\n\t);\r\n\r\n\t// コンテナスタイル (共通関数を使用)\r\n\tconst containerStyle = getBlockContainerStyle(blockRectPx, {\r\n\t\tzIndex,\r\n\t\tpointerEvents: \"auto\", // クリックイベントを受け取る\r\n\t});\r\n\r\n\t// ブロックサイズ\r\n\tconst blockSizePx: BlockSizePx = {\r\n\t\twidth: blockRectPx.width,\r\n\t\theight: blockRectPx.height,\r\n\t};\r\n\r\n\t// プラグインRendererに渡すprops\r\n\tconst pluginProps: RendererProps<P, V> = {\r\n\t\tid,\r\n\t\tprops,\r\n\t\tvalue,\r\n\t\tonChange,\r\n\t\tonBlur,\r\n\t\treadOnly: false, // 編集中は常に編集可能\r\n\t\tmode: NoteMode.FORM, // EditingBlockはFormモード専用\r\n\t\tdimensions: {\r\n\t\t\twidthPx: blockSizePx.width,\r\n\t\t\theightPx: blockSizePx.height,\r\n\t\t},\r\n\t\tvalidationState,\r\n\t};\r\n\r\n\t// プラグインのRendererコンポーネントを取得\r\n\tconst PluginRendererComponent = plugin.Renderer;\r\n\r\n\treturn (\r\n\t\t<div\r\n\t\t\tclassName={className}\r\n\t\t\tstyle={containerStyle}\r\n\t\t\tdata-testid=\"editing-block\"\r\n\t\t\tdata-block-id={id}\r\n\t\t\tdata-plugin-kind={plugin.kind}\r\n\t\t>\r\n\t\t\t<PluginRendererComponent ref={pluginRendererRef} {...pluginProps} />\r\n\t\t</div>\r\n\t);\r\n};\r\n\r\nconst ForwardedEditingBlock = forwardRef(EditingBlockInner) as <\r\n\tP extends Record<string, Value>,\r\n\tV extends Value,\r\n>(\r\n\tprops: EditingBlockProps<P, V> & { ref?: React.ForwardedRef<BlockRef> },\r\n) => React.ReactElement;\r\n\r\nexport const EditingBlock = memo(\r\n\tForwardedEditingBlock,\r\n) as typeof ForwardedEditingBlock;\r\n","import { useCallback, useState } from \"react\";\r\n\r\nimport {\r\n\tDragType,\r\n\ttype InteractionChangeEvent,\r\n\tInteractionEventType,\r\n\tInteractionMode,\r\n\ttype InteractionState,\r\n} from \"../types\";\r\n\r\n/**\r\n * インタラクション状態管理Hook\r\n *\r\n * @remarks\r\n * Reducer的なロジックを内包、外部からはシンプルなAPIのみ公開\r\n *\r\n * **核心機能**: グリッド変化判定によるドラッグ確定\r\n * - `mode: 'pressing'` でグリッドをまたいだら → `mode: 'dragging'` に遷移\r\n * - ピクセル閾値 (5px) は使わない\r\n *\r\n * @param initialState - 初期状態 (オプション)\r\n * @returns [state, handleChange] - 状態とコールバック\r\n *\r\n * @example\r\n * ```tsx\r\n * const [state, onChange] = useInteractionState();\r\n *\r\n * // ブロックをクリック\r\n * onChange({ type: InteractionEventType.SELECT, blockIds: ['block-1'] });\r\n *\r\n * // ドラッグ開始 (まだpressing)\r\n * onChange({ type: InteractionEventType.START_PRESS, blockId: 'block-1', startGrid: { col: 0, row: 0 } });\r\n *\r\n * // グリッドをまたぐ (自動的にdraggingへ遷移)\r\n * onChange({ type: InteractionEventType.UPDATE_DRAG, currentGrid: { col: 1, row: 0 } });\r\n * ```\r\n */\r\nexport function useInteractionState(initialState?: Partial<InteractionState>) {\r\n\tconst [state, setState] = useState<InteractionState>({\r\n\t\tmode: InteractionMode.IDLE,\r\n\t\tselectedBlockIds: [],\r\n\t\teditingBlockId: null,\r\n\t\t...initialState,\r\n\t});\r\n\r\n\tconst handleChange = useCallback((event: InteractionChangeEvent) => {\r\n\t\tsetState((prev) => {\r\n\t\t\tswitch (event.type) {\r\n\t\t\t\tcase InteractionEventType.SELECT: {\r\n\t\t\t\t\t// 選択\r\n\t\t\t\t\t// InteractionLayer側で既にShift+クリックのトグル処理が完了しているため、\r\n\t\t\t\t\t// 渡された配列をそのまま使用する\r\n\t\t\t\t\tconst newBlockIds = event.blockIds;\r\n\r\n\t\t\t\t\treturn {\r\n\t\t\t\t\t\t...prev,\r\n\t\t\t\t\t\tmode: InteractionMode.IDLE,\r\n\t\t\t\t\t\tselectedBlockIds: newBlockIds,\r\n\t\t\t\t\t};\r\n\t\t\t\t}\r\n\t\t\t\tcase InteractionEventType.DESELECT:\r\n\t\t\t\t\t// 選択解除\r\n\t\t\t\t\treturn {\r\n\t\t\t\t\t\t...prev,\r\n\t\t\t\t\t\tmode: InteractionMode.IDLE,\r\n\t\t\t\t\t\tselectedBlockIds: [],\r\n\t\t\t\t\t};\r\n\r\n\t\t\t\tcase InteractionEventType.START_PRESS: {\r\n\t\t\t\t\t// プレス開始 (まだドラッグではない、監視状態に入る)\r\n\t\t\t\t\t// selectedBlockIdsが指定されていれば複数選択のドラッグ、なければ単一ドラッグ\r\n\t\t\t\t\tconst dragTargetIds = event.selectedBlockIds || [event.blockId];\r\n\t\t\t\t\treturn {\r\n\t\t\t\t\t\t...prev,\r\n\t\t\t\t\t\tmode: InteractionMode.PRESSING,\r\n\t\t\t\t\t\tdragging: {\r\n\t\t\t\t\t\t\ttype: DragType.MOVE,\r\n\t\t\t\t\t\t\tblockIds: dragTargetIds,\r\n\t\t\t\t\t\t\tstartGrid: event.startGrid,\r\n\t\t\t\t\t\t\tcurrentGrid: event.startGrid,\r\n\t\t\t\t\t\t\tisOutside: false,\r\n\t\t\t\t\t\t},\r\n\t\t\t\t\t};\r\n\t\t\t\t}\r\n\r\n\t\t\t\tcase InteractionEventType.UPDATE_DRAG: {\r\n\t\t\t\t\tif (!prev.dragging) return prev;\r\n\r\n\t\t\t\t\t// ★ グリッド変化判定 ★\r\n\t\t\t\t\tconst gridChanged =\r\n\t\t\t\t\t\tevent.currentGrid.col !== prev.dragging.startGrid.col ||\r\n\t\t\t\t\t\tevent.currentGrid.row !== prev.dragging.startGrid.row;\r\n\r\n\t\t\t\t\tif (prev.mode === InteractionMode.PRESSING) {\r\n\t\t\t\t\t\tif (gridChanged) {\r\n\t\t\t\t\t\t\t// ✅ グリッドをまたいだ瞬間にドラッグ確定\r\n\t\t\t\t\t\t\treturn {\r\n\t\t\t\t\t\t\t\t...prev,\r\n\t\t\t\t\t\t\t\tmode: InteractionMode.DRAGGING,\r\n\t\t\t\t\t\t\t\tdragging: {\r\n\t\t\t\t\t\t\t\t\t...prev.dragging,\r\n\t\t\t\t\t\t\t\t\tcurrentGrid: event.currentGrid,\r\n\t\t\t\t\t\t\t\t\tcurrentMousePx: event.currentMousePx, // マウス座標を追加\r\n\t\t\t\t\t\t\t\t\tisOutside: event.isOutside ?? false,\r\n\t\t\t\t\t\t\t\t},\r\n\t\t\t\t\t\t\t};\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\t// グリッド変化なしでもisOutsideは更新(範囲外判定用)\r\n\t\t\t\t\t\treturn {\r\n\t\t\t\t\t\t\t...prev,\r\n\t\t\t\t\t\t\tdragging: {\r\n\t\t\t\t\t\t\t\t...prev.dragging,\r\n\t\t\t\t\t\t\t\tcurrentGrid: event.currentGrid,\r\n\t\t\t\t\t\t\t\tcurrentMousePx: event.currentMousePx, // マウス座標を追加\r\n\t\t\t\t\t\t\t\tisOutside: event.isOutside ?? false,\r\n\t\t\t\t\t\t\t},\r\n\t\t\t\t\t\t};\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tif (prev.mode === InteractionMode.DRAGGING) {\r\n\t\t\t\t\t\t// ドラッグ中は座標とisOutsideを更新\r\n\t\t\t\t\t\treturn {\r\n\t\t\t\t\t\t\t...prev,\r\n\t\t\t\t\t\t\tdragging: {\r\n\t\t\t\t\t\t\t\t...prev.dragging,\r\n\t\t\t\t\t\t\t\tcurrentGrid: event.currentGrid,\r\n\t\t\t\t\t\t\t\tcurrentMousePx: event.currentMousePx, // マウス座標を追加\r\n\t\t\t\t\t\t\t\tisOutside: event.isOutside ?? false,\r\n\t\t\t\t\t\t\t},\r\n\t\t\t\t\t\t};\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\treturn prev;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tcase InteractionEventType.END_DRAG:\r\n\t\t\t\t\t// ドラッグ確定\r\n\t\t\t\t\treturn {\r\n\t\t\t\t\t\t...prev,\r\n\t\t\t\t\t\tmode: InteractionMode.IDLE,\r\n\t\t\t\t\t\tdragging: undefined,\r\n\t\t\t\t\t};\r\n\r\n\t\t\t\tcase InteractionEventType.CANCEL_DRAG:\r\n\t\t\t\t\t// ドラッグキャンセル (クリック扱い)\r\n\t\t\t\t\treturn {\r\n\t\t\t\t\t\t...prev,\r\n\t\t\t\t\t\tmode: InteractionMode.IDLE,\r\n\t\t\t\t\t\tdragging: undefined,\r\n\t\t\t\t\t};\r\n\r\n\t\t\t\tcase InteractionEventType.EDIT:\r\n\t\t\t\t\treturn {\r\n\t\t\t\t\t\t...prev,\r\n\t\t\t\t\t\tmode: InteractionMode.EDITING,\r\n\t\t\t\t\t\teditingBlockId: event.blockId,\r\n\t\t\t\t\t};\r\n\r\n\t\t\t\tcase InteractionEventType.END_EDIT:\r\n\t\t\t\t\treturn {\r\n\t\t\t\t\t\t...prev,\r\n\t\t\t\t\t\tmode: InteractionMode.IDLE,\r\n\t\t\t\t\t\teditingBlockId: null,\r\n\t\t\t\t\t};\r\n\r\n\t\t\t\tcase InteractionEventType.START_INSERT:\r\n\t\t\t\t\t// 挿入開始\r\n\t\t\t\t\treturn {\r\n\t\t\t\t\t\t...prev,\r\n\t\t\t\t\t\tmode: InteractionMode.DRAGGING,\r\n\t\t\t\t\t\tdragging: {\r\n\t\t\t\t\t\t\ttype: DragType.INSERT,\r\n\t\t\t\t\t\t\tblockIds: [],\r\n\t\t\t\t\t\t\tstartGrid: { col: 0, row: 0 },\r\n\t\t\t\t\t\t\tcurrentGrid: { col: 0, row: 0 },\r\n\t\t\t\t\t\t\tpluginKind: event.pluginKind,\r\n\t\t\t\t\t\t\tdefaultSize: event.defaultSize,\r\n\t\t\t\t\t\t\tisOutside: false,\r\n\t\t\t\t\t\t},\r\n\t\t\t\t\t};\r\n\r\n\t\t\t\tcase InteractionEventType.CANCEL_INSERT:\r\n\t\t\t\t\t// 挿入キャンセル\r\n\t\t\t\t\treturn {\r\n\t\t\t\t\t\t...prev,\r\n\t\t\t\t\t\tmode: InteractionMode.IDLE,\r\n\t\t\t\t\t\tdragging: undefined,\r\n\t\t\t\t\t};\r\n\r\n\t\t\t\tcase InteractionEventType.START_RESIZE: {\r\n\t\t\t\t\t// リサイズ開始\r\n\t\t\t\t\treturn {\r\n\t\t\t\t\t\t...prev,\r\n\t\t\t\t\t\tmode: InteractionMode.DRAGGING,\r\n\t\t\t\t\t\tdragging: {\r\n\t\t\t\t\t\t\ttype: DragType.RESIZE,\r\n\t\t\t\t\t\t\tblockIds: [event.blockId],\r\n\t\t\t\t\t\t\tstartGrid: event.startGrid,\r\n\t\t\t\t\t\t\tcurrentGrid: event.startGrid,\r\n\t\t\t\t\t\t\thandle: event.handle,\r\n\t\t\t\t\t\t\tisOutside: false,\r\n\t\t\t\t\t\t},\r\n\t\t\t\t\t};\r\n\t\t\t\t}\r\n\r\n\t\t\t\tdefault:\r\n\t\t\t\t\treturn prev;\r\n\t\t\t}\r\n\t\t});\r\n\t}, []);\r\n\r\n\treturn [state, handleChange] as const;\r\n}\r\n","/**\r\n * @file SelectionLayer.tsx\r\n */\r\nimport { memo } from \"react\";\r\n\r\nimport { InteractionBlock } from \"../InteractionBlock\";\r\nimport {\r\n\tinteractionZIndexs,\r\n\tRESIZE_HANDLE_STYLE,\r\n\tSELECTION_STYLE,\r\n} from \"../InteractionBlock/constants\";\r\nimport { type DraggingState, DragType, type ResizeHandle } from \"../types\";\r\n\r\nimport type React from \"react\";\r\nimport type { Block, BlockRectPx } from \"@/types/block\";\r\nimport type { BorderStyle } from \"@/types/line\";\r\n\r\nexport interface SelectionLayerProps {\r\n\tblocks: Block[];\r\n\tselectedBlockIds: string[];\r\n\tisDragging: boolean;\r\n\tdraggingState?: DraggingState;\r\n\tgetBlockRectPx: (block: Block) => BlockRectPx;\r\n\tonResizeStart: (\r\n\t\te: React.PointerEvent,\r\n\t\thandle: ResizeHandle,\r\n\t\tblockId: string,\r\n\t) => void;\r\n\tselectionStyle?: BorderStyle;\r\n\thandleStyle?: typeof RESIZE_HANDLE_STYLE;\r\n\t/** 選択枠のz-index (デフォルト: interactionZIndexs.select_border) */\r\n\tselectBorderZIndex?: number;\r\n\t/** リサイズハンドルのz-index (デフォルト: interactionZIndexs.block_handles) */\r\n\tblockHandlesZIndex?: number;\r\n}\r\n\r\nexport const SelectionLayer = memo(\r\n\t({\r\n\t\tblocks,\r\n\t\tselectedBlockIds,\r\n\t\tisDragging,\r\n\t\tdraggingState,\r\n\t\tgetBlockRectPx,\r\n\t\tonResizeStart,\r\n\t\tselectionStyle = SELECTION_STYLE,\r\n\t\thandleStyle = RESIZE_HANDLE_STYLE,\r\n\t\tselectBorderZIndex = interactionZIndexs.select_border,\r\n\t\tblockHandlesZIndex = interactionZIndexs.block_handles,\r\n\t}: SelectionLayerProps) => {\r\n\t\t// 移動中(move/insert)は枠を消す。ただしリサイズ中は枠が必要なので除外\r\n\t\tconst isMoving = isDragging && draggingState?.type !== DragType.RESIZE;\r\n\r\n\t\tif (isMoving) {\r\n\t\t\treturn null;\r\n\t\t}\r\n\r\n\t\t// 重複を除去(念のため)\r\n\t\tconst uniqueSelectedIds = Array.from(new Set(selectedBlockIds));\r\n\r\n\t\treturn (\r\n\t\t\t<div\r\n\t\t\t\tstyle={{\r\n\t\t\t\t\tposition: \"absolute\",\r\n\t\t\t\t\tinset: 0,\r\n\t\t\t\t\tpointerEvents: \"none\",\r\n\t\t\t\t}}\r\n\t\t\t>\r\n\t\t\t\t{uniqueSelectedIds.map((id) => {\r\n\t\t\t\t\tconst block = blocks.find((b) => b.id === id);\r\n\t\t\t\t\tif (!block) return null;\r\n\r\n\t\t\t\t\t// リサイズ中のハンドル特定\r\n\t\t\t\t\tconst isResizing =\r\n\t\t\t\t\t\tdraggingState?.type === DragType.RESIZE &&\r\n\t\t\t\t\t\tdraggingState.blockIds.includes(id);\r\n\t\t\t\t\tconst activeHandle = isResizing ? draggingState?.handle : null;\r\n\r\n\t\t\t\t\treturn (\r\n\t\t\t\t\t\t<InteractionBlock\r\n\t\t\t\t\t\t\tkey={block.id}\r\n\t\t\t\t\t\t\tblock={block}\r\n\t\t\t\t\t\t\trect={getBlockRectPx(block)}\r\n\t\t\t\t\t\t\tshowHandles={true}\r\n\t\t\t\t\t\t\tonResizeStart={(e, handle) => onResizeStart(e, handle, id)}\r\n\t\t\t\t\t\t\tactiveHandle={activeHandle}\r\n\t\t\t\t\t\t\tselectionStyle={selectionStyle}\r\n\t\t\t\t\t\t\thandleStyle={handleStyle}\r\n\t\t\t\t\t\t\tselectBorderZIndex={selectBorderZIndex}\r\n\t\t\t\t\t\t\tblockHandlesZIndex={blockHandlesZIndex}\r\n\t\t\t\t\t\t/>\r\n\t\t\t\t\t);\r\n\t\t\t\t})}\r\n\t\t\t</div>\r\n\t\t);\r\n\t},\r\n);\r\n\r\nSelectionLayer.displayName = \"SelectionLayer\";\r\n","/**\r\n * @file clampBlock.ts\r\n * @description ブロックをグリッド範囲内にクランプする共通ロジック\r\n *\r\n * @remarks\r\n * 移動・挿入・リサイズ時のはみ出し防止処理を集約。\r\n * DRY原則に従い、InteractionLayer内の重複コードを排除。\r\n */\r\n\r\n/**\r\n * ブロックの位置をグリッド範囲内にクランプ\r\n *\r\n * @param position - ブロックの位置 (x, y)\r\n * @param size - ブロックのサイズ (w, h)\r\n * @param gridCols - グリッドの列数\r\n * @param gridRows - グリッドの行数\r\n * @returns クランプされた位置 { x, y }\r\n *\r\n * @remarks\r\n * - x は 0 ~ (gridCols - w) の範囲にクランプ\r\n * - y は 0 ~ (gridRows - h) の範囲にクランプ\r\n * - ブロックがグリッドからはみ出さないことを保証\r\n *\r\n * @example\r\n * ```typescript\r\n * const clamped = clampBlockToGrid(\r\n * { x: -1, y: 5 },\r\n * { w: 2, h: 3 },\r\n * 10, // gridCols\r\n * 10 // gridRows\r\n * );\r\n * // => { x: 0, y: 5 }\r\n * ```\r\n */\r\nexport function clampBlockToGrid(\r\n\tposition: { x: number; y: number },\r\n\tsize: { w: number; h: number },\r\n\tgridCols: number,\r\n\tgridRows: number,\r\n): { x: number; y: number } {\r\n\tconst maxX = gridCols - size.w;\r\n\tconst maxY = gridRows - size.h;\r\n\r\n\treturn {\r\n\t\tx: Math.max(0, Math.min(position.x, maxX)),\r\n\t\ty: Math.max(0, Math.min(position.y, maxY)),\r\n\t};\r\n}\r\n","/**\r\n * @file hitTest.ts\r\n * @description 座標に基づく当たり判定ユーティリティ\r\n */\r\n\r\nimport type { Block, BlockRectPx } from \"@/types/block\";\r\n\r\n/**\r\n * 指定された座標にあるブロックを検索します\r\n *\r\n * @param point - 検索対象の座標 (Client/Offset座標ではなく、InteractionLayer内の相対座標)\r\n * @param blocks - ブロックのリスト\r\n * @param getBlockRectPx - ブロックからピクセル矩形を計算する関数 (useGridCalc由来)\r\n * @returns 見つかったブロックのID。見つからない場合は null\r\n */\r\nexport function findBlockAtPoint(\r\n\tpoint: { x: number; y: number },\r\n\tblocks: Block[],\r\n\tgetBlockRectPx: (block: Block) => BlockRectPx,\r\n): string | null {\r\n\tconst { x, y } = point;\r\n\r\n\t// Z-indexを考慮して、配列の「後ろ(描画順で手前)」から走査する\r\n\tfor (let i = blocks.length - 1; i >= 0; i--) {\r\n\t\tconst block = blocks[i];\r\n\t\tif (!block) continue;\r\n\t\tconst rect = getBlockRectPx(block);\r\n\r\n\t\tconst isInBounds =\r\n\t\t\tx >= rect.left &&\r\n\t\t\tx <= rect.left + rect.width &&\r\n\t\t\ty >= rect.top &&\r\n\t\t\ty <= rect.top + rect.height;\r\n\r\n\t\t// 矩形範囲内判定\r\n\t\tif (isInBounds) {\r\n\t\t\treturn block.id;\r\n\t\t}\r\n\t}\r\n\r\n\treturn null;\r\n}\r\n","import { memo, useCallback, useEffect, useRef } from \"react\";\r\n\r\nimport { DragLayer } from \"./DragLayer\";\r\nimport { EditingBlock } from \"./EditingBlock\";\r\nimport {\r\n\tinteractionZIndexs,\r\n\ttype RESIZE_HANDLE_STYLE,\r\n} from \"./InteractionBlock/constants\";\r\nimport { SelectionLayer } from \"./SelectionLayer\";\r\nimport { DragType, InteractionEventType, InteractionMode } from \"./types\";\r\nimport { calculateResizedLayout } from \"./utils/calcResize\";\r\nimport { clampBlockToGrid } from \"./utils/clampBlock\";\r\nimport { clampMultipleBlocks } from \"./utils/clampMultipleBlocks\";\r\nimport { findBlockAtPoint } from \"./utils/hitTest\";\r\n\r\nimport { createBlock } from \"@/plugin/utils/block\";\r\nimport { type Block, BlockChangeType, type BlockRectPx } from \"@/types/block\";\r\nimport { Z_INDEX } from \"@/utils/zIndex\";\r\n\r\nimport type { BlockPlugin, BlockRef } from \"@/plugin\";\r\nimport type { OnBlockChange } from \"@/types/callbacks\";\r\nimport type { BorderStyle } from \"@/types/line\";\r\nimport type { InteractionState, OnInteractionChange } from \"./types\";\r\n\r\n/**\r\n * InteractionLayerProps\r\n */\r\nexport interface InteractionLayerProps {\r\n\t// --- データ ---\r\n\tblocks: Block[];\r\n\tpluginRegistry: Record<string, BlockPlugin>;\r\n\tgridLength: { cols: number; rows: number };\r\n\r\n\t// --- 座標変換 ---\r\n\tgetBlockRectPx: (block: Block) => BlockRectPx;\r\n\tgetColIndex: (px: number) => number;\r\n\tgetRowIndex: (px: number) => number;\r\n\r\n\t// --- Controlled State ---\r\n\tstate: InteractionState;\r\n\tonChange: OnInteractionChange;\r\n\r\n\t// --- ブロック変更 ---\r\n\tonBlockChange?: OnBlockChange;\r\n\r\n\t// --- スケール ---\r\n\tscale?: number;\r\n\r\n\t// --- スタイル ---\r\n\tclassName?: string;\r\n\tselectionStyle?: BorderStyle;\r\n\thandleStyle?: typeof RESIZE_HANDLE_STYLE;\r\n\r\n\t// --- Z-Index (個別指定、全てオプション) ---\r\n\teditBlockZIndex?: number;\r\n\tselectBorderZIndex?: number;\r\n\tblockHandlesZIndex?: number;\r\n\tdragGhostZIndex?: number;\r\n}\r\n\r\nexport const InteractionLayer = memo(\r\n\t({\r\n\t\tblocks,\r\n\t\tpluginRegistry,\r\n\t\tgridLength,\r\n\t\tgetBlockRectPx,\r\n\t\tgetColIndex,\r\n\t\tgetRowIndex,\r\n\t\tstate,\r\n\t\tonChange,\r\n\t\tonBlockChange,\r\n\t\tscale = 1.0,\r\n\t\tclassName = \"\",\r\n\t\tselectionStyle,\r\n\t\thandleStyle,\r\n\t\teditBlockZIndex = Z_INDEX.EDIT_BLOCK,\r\n\t\tselectBorderZIndex = interactionZIndexs.select_border,\r\n\t\tblockHandlesZIndex = interactionZIndexs.block_handles,\r\n\t\tdragGhostZIndex = interactionZIndexs.block_ghost,\r\n\t}: InteractionLayerProps) => {\r\n\t\tconst layerRef = useRef<HTMLDivElement>(null);\r\n\t\tconst editingBlockRef = useRef<BlockRef>(null);\r\n\r\n\t\t// 編集モード時のフォーカス処理\r\n\t\tuseEffect(() => {\r\n\t\t\tif (state.mode === InteractionMode.EDITING && state.editingBlockId) {\r\n\t\t\t\tsetTimeout(() => {\r\n\t\t\t\t\teditingBlockRef.current?.focus();\r\n\t\t\t\t}, 0);\r\n\t\t\t}\r\n\t\t}, [state.mode, state.editingBlockId]);\r\n\r\n\t\t// ブロックが削除された時、存在しないブロックIDを選択から除外\r\n\t\tuseEffect(() => {\r\n\t\t\tconst blockIds = new Set(blocks.map((b) => b.id));\r\n\t\t\tconst validSelectedIds = state.selectedBlockIds.filter((id) =>\r\n\t\t\t\tblockIds.has(id),\r\n\t\t\t);\r\n\r\n\t\t\t// 選択中のブロックが存在しなくなった場合\r\n\t\t\tif (validSelectedIds.length !== state.selectedBlockIds.length) {\r\n\t\t\t\tonChange({\r\n\t\t\t\t\ttype: InteractionEventType.SELECT,\r\n\t\t\t\t\tblockIds: validSelectedIds,\r\n\t\t\t\t\tshiftKey: false,\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t}, [blocks, state.selectedBlockIds, onChange]);\r\n\r\n\t\t// --- PointerDown ---\r\n\t\tconst handlePointerDown = useCallback(\r\n\t\t\t(e: React.PointerEvent) => {\r\n\t\t\t\tif (e.button !== 0) return;\r\n\r\n\t\t\t\tconst rect = layerRef.current?.getBoundingClientRect();\r\n\t\t\t\tif (!rect) return;\r\n\t\t\t\tconst scaleFactor = scale ?? 1.0;\r\n\t\t\t\tconst px = {\r\n\t\t\t\t\tx: (e.clientX - rect.left) / scaleFactor,\r\n\t\t\t\t\ty: (e.clientY - rect.top) / scaleFactor,\r\n\t\t\t\t};\r\n\r\n\t\t\t\tconst targetId = findBlockAtPoint(px, blocks, getBlockRectPx);\r\n\r\n\t\t\t\t// 編集モード中の処理\r\n\t\t\t\tif (state.mode === InteractionMode.EDITING) {\r\n\t\t\t\t\t// 編集中ブロック以外をクリックした場合のみ編集終了\r\n\t\t\t\t\tif (targetId !== state.editingBlockId) {\r\n\t\t\t\t\t\tonChange({ type: InteractionEventType.END_EDIT });\r\n\t\t\t\t\t\t// 空白クリックの場合は選択も解除\r\n\t\t\t\t\t\tif (!targetId) {\r\n\t\t\t\t\t\t\tonChange({ type: InteractionEventType.DESELECT });\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tconst gridCol = getColIndex(px.x);\r\n\t\t\t\tconst gridRow = getRowIndex(px.y);\r\n\r\n\t\t\t\tif (targetId) {\r\n\t\t\t\t\te.stopPropagation();\r\n\r\n\t\t\t\t\tconst isAlreadySelected = state.selectedBlockIds.includes(targetId);\r\n\r\n\t\t\t\t\tif (isAlreadySelected && e.shiftKey) {\r\n\t\t\t\t\t\tconst newSelectedIds = state.selectedBlockIds.filter(\r\n\t\t\t\t\t\t\t(id) => id !== targetId,\r\n\t\t\t\t\t\t);\r\n\t\t\t\t\t\tonChange({\r\n\t\t\t\t\t\t\ttype: InteractionEventType.SELECT,\r\n\t\t\t\t\t\t\tblockIds: newSelectedIds,\r\n\t\t\t\t\t\t\tshiftKey: true,\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t\treturn;\r\n\t\t\t\t\t} else if (isAlreadySelected) {\r\n\t\t\t\t\t\t// 既に選択済み(Shiftなし): 複数選択状態を維持してドラッグ開始\r\n\t\t\t\t\t\t(e.currentTarget as Element).setPointerCapture(e.pointerId);\r\n\t\t\t\t\t\tonChange({\r\n\t\t\t\t\t\t\ttype: InteractionEventType.START_PRESS,\r\n\t\t\t\t\t\t\tblockId: targetId,\r\n\t\t\t\t\t\t\tstartGrid: { col: gridCol, row: gridRow },\r\n\t\t\t\t\t\t\t// 複数選択時は全選択ブロックを移動対象にする\r\n\t\t\t\t\t\t\tselectedBlockIds: state.selectedBlockIds,\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\t// 未選択: 選択してから即座にドラッグ開始\r\n\t\t\t\t\t\t(e.currentTarget as Element).setPointerCapture(e.pointerId);\r\n\t\t\t\t\t\tif (e.shiftKey) {\r\n\t\t\t\t\t\t\t// Shiftキー: 複数選択に追加\r\n\t\t\t\t\t\t\tonChange({\r\n\t\t\t\t\t\t\t\ttype: InteractionEventType.SELECT,\r\n\t\t\t\t\t\t\t\tblockIds: [...state.selectedBlockIds, targetId],\r\n\t\t\t\t\t\t\t\tshiftKey: true,\r\n\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\t// 通常クリック: 単一選択してから即座にドラッグ開始\r\n\t\t\t\t\t\t\tonChange({\r\n\t\t\t\t\t\t\t\ttype: InteractionEventType.SELECT,\r\n\t\t\t\t\t\t\t\tblockIds: [targetId],\r\n\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t\t// 選択後、即座にドラッグ可能状態に遷移\r\n\t\t\t\t\t\t\tonChange({\r\n\t\t\t\t\t\t\t\ttype: InteractionEventType.START_PRESS,\r\n\t\t\t\t\t\t\t\tblockId: targetId,\r\n\t\t\t\t\t\t\t\tstartGrid: { col: gridCol, row: gridRow },\r\n\t\t\t\t\t\t\t\tselectedBlockIds: [targetId],\r\n\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t} else {\r\n\t\t\t\t\t// 空白クリック: 選択解除\r\n\t\t\t\t\te.stopPropagation();\r\n\t\t\t\t\tonChange({ type: InteractionEventType.DESELECT });\r\n\t\t\t\t}\r\n\t\t\t},\r\n\t\t\t[\r\n\t\t\t\tblocks,\r\n\t\t\t\tgetBlockRectPx,\r\n\t\t\t\tgetColIndex,\r\n\t\t\t\tgetRowIndex,\r\n\t\t\t\tstate.mode,\r\n\t\t\t\tstate.selectedBlockIds,\r\n\t\t\t\tonChange,\r\n\t\t\t\tscale,\r\n\t\t\t\tstate.editingBlockId,\r\n\t\t\t],\r\n\t\t);\r\n\r\n\t\t// --- PointerMove ---\r\n\t\tconst handlePointerMove = useCallback(\r\n\t\t\t(e: React.PointerEvent) => {\r\n\t\t\t\tif (\r\n\t\t\t\t\tstate.mode !== InteractionMode.PRESSING &&\r\n\t\t\t\t\tstate.mode !== InteractionMode.DRAGGING\r\n\t\t\t\t)\r\n\t\t\t\t\treturn;\r\n\t\t\t\tif (!state.dragging) return;\r\n\r\n\t\t\t\tconst rect = layerRef.current?.getBoundingClientRect();\r\n\t\t\t\tif (!rect) return;\r\n\r\n\t\t\t\tconst scaleFactor = scale ?? 1.0;\r\n\t\t\t\tconst canvasWidth = rect.width / scaleFactor;\r\n\t\t\t\tconst canvasHeight = rect.height / scaleFactor;\r\n\r\n\t\t\t\t// クランプなしの生座標(範囲外判定用)\r\n\t\t\t\tconst rawX = (e.clientX - rect.left) / scaleFactor;\r\n\t\t\t\tconst rawY = (e.clientY - rect.top) / scaleFactor;\r\n\r\n\t\t\t\t// 1. 範囲外判定(リサイズ中は無視)\r\n\t\t\t\tconst isOutside =\r\n\t\t\t\t\tstate.dragging.type !== DragType.RESIZE &&\r\n\t\t\t\t\t(rawX < 0 || rawX > canvasWidth || rawY < 0 || rawY > canvasHeight);\r\n\r\n\t\t\t\t// 2. グリッド計算用にクランプ\r\n\t\t\t\tconst clampedX = Math.max(0, Math.min(rawX, canvasWidth));\r\n\t\t\t\tconst clampedY = Math.max(0, Math.min(rawY, canvasHeight));\r\n\r\n\t\t\t\tconst currentCol = getColIndex(clampedX);\r\n\t\t\t\tconst currentRow = getRowIndex(clampedY);\r\n\r\n\t\t\t\tonChange({\r\n\t\t\t\t\ttype: InteractionEventType.UPDATE_DRAG,\r\n\t\t\t\t\tcurrentGrid: { col: currentCol, row: currentRow },\r\n\t\t\t\t\tcurrentMousePx: { x: rawX, y: rawY },\r\n\t\t\t\t\tisOutside: isOutside,\r\n\t\t\t\t});\r\n\t\t\t},\r\n\t\t\t[state.mode, state.dragging, getColIndex, getRowIndex, onChange, scale],\r\n\t\t);\r\n\r\n\t\t// --- PointerUp ---\r\n\t\tconst handlePointerUp = useCallback(\r\n\t\t\t(e: React.PointerEvent) => {\r\n\t\t\t\tif (state.mode === InteractionMode.DRAGGING && state.dragging) {\r\n\t\t\t\t\t// 1. 範囲外なら処理\r\n\t\t\t\t\tif (state.dragging.isOutside) {\r\n\t\t\t\t\t\tif (state.dragging.type === DragType.MOVE) {\r\n\t\t\t\t\t\t\tonBlockChange?.({\r\n\t\t\t\t\t\t\t\ttype: BlockChangeType.DELETE,\r\n\t\t\t\t\t\t\t\tblockIds: state.dragging.blockIds,\r\n\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t\t// 削除したブロックの選択を解除\r\n\t\t\t\t\t\t\tonChange({ type: InteractionEventType.DESELECT });\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\t// INSERT/RESIZEの場合は何もしない(キャンセル)\r\n\t\t\t\t\t\tonChange({ type: InteractionEventType.END_DRAG });\r\n\t\t\t\t\t\t(e.currentTarget as Element).releasePointerCapture(e.pointerId);\r\n\t\t\t\t\t\treturn;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tconst deltaCol =\r\n\t\t\t\t\t\tstate.dragging.currentGrid.col - state.dragging.startGrid.col;\r\n\t\t\t\t\tconst deltaRow =\r\n\t\t\t\t\t\tstate.dragging.currentGrid.row - state.dragging.startGrid.row;\r\n\r\n\t\t\t\t\t// 2. 移動 (Move) の確定\r\n\t\t\t\t\tif (state.dragging.type === DragType.MOVE) {\r\n\t\t\t\t\t\tif (deltaCol !== 0 || deltaRow !== 0) {\r\n\t\t\t\t\t\t\tconst dragTargets = state.dragging.blockIds\r\n\t\t\t\t\t\t\t\t.map((id) => blocks.find((b) => b.id === id))\r\n\t\t\t\t\t\t\t\t.filter(Boolean) as Block[];\r\n\r\n\t\t\t\t\t\t\tif (dragTargets.length === 0) {\r\n\t\t\t\t\t\t\t\tonChange({ type: InteractionEventType.END_DRAG });\r\n\t\t\t\t\t\t\t\t(e.currentTarget as Element).releasePointerCapture(e.pointerId);\r\n\t\t\t\t\t\t\t\treturn;\r\n\t\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t\t// 共通のクランプ処理を使用\r\n\t\t\t\t\t\t\tconst clampedPositions = clampMultipleBlocks(\r\n\t\t\t\t\t\t\t\tdragTargets,\r\n\t\t\t\t\t\t\t\tdeltaCol,\r\n\t\t\t\t\t\t\t\tdeltaRow,\r\n\t\t\t\t\t\t\t\tgridLength.cols,\r\n\t\t\t\t\t\t\t\tgridLength.rows,\r\n\t\t\t\t\t\t\t);\r\n\r\n\t\t\t\t\t\t\t// クランプ後の座標で各ブロックを更新\r\n\t\t\t\t\t\t\tconst movedBlocks = dragTargets.map((block) => {\r\n\t\t\t\t\t\t\t\tconst clampedPos = clampedPositions.find(\r\n\t\t\t\t\t\t\t\t\t(p) => p.blockId === block.id,\r\n\t\t\t\t\t\t\t\t);\r\n\t\t\t\t\t\t\t\tif (!clampedPos) return block;\r\n\r\n\t\t\t\t\t\t\t\treturn {\r\n\t\t\t\t\t\t\t\t\t...block,\r\n\t\t\t\t\t\t\t\t\tlayout: {\r\n\t\t\t\t\t\t\t\t\t\t...block.layout,\r\n\t\t\t\t\t\t\t\t\t\tx: clampedPos.x,\r\n\t\t\t\t\t\t\t\t\t\ty: clampedPos.y,\r\n\t\t\t\t\t\t\t\t\t},\r\n\t\t\t\t\t\t\t\t};\r\n\t\t\t\t\t\t\t});\r\n\r\n\t\t\t\t\t\t\tonBlockChange?.({\r\n\t\t\t\t\t\t\t\ttype: BlockChangeType.MOVE,\r\n\t\t\t\t\t\t\t\tblockIds: state.dragging.blockIds,\r\n\t\t\t\t\t\t\t\tblocks: movedBlocks,\r\n\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t\t// 3. 挿入 (Insert) の確定\r\n\t\t\t\t\telse if (state.dragging.type === DragType.INSERT) {\r\n\t\t\t\t\t\tconst { pluginKind, currentGrid, defaultSize } = state.dragging;\r\n\t\t\t\t\t\tif (pluginKind && defaultSize) {\r\n\t\t\t\t\t\t\tconst plugin = pluginRegistry[pluginKind];\r\n\t\t\t\t\t\t\tif (plugin) {\r\n\t\t\t\t\t\t\t\t// はみ出し防止クランプ\r\n\t\t\t\t\t\t\t\tconst { x, y } = clampBlockToGrid(\r\n\t\t\t\t\t\t\t\t\t{ x: currentGrid.col, y: currentGrid.row },\r\n\t\t\t\t\t\t\t\t\t{ w: defaultSize.w, h: defaultSize.h },\r\n\t\t\t\t\t\t\t\t\tgridLength.cols,\r\n\t\t\t\t\t\t\t\t\tgridLength.rows,\r\n\t\t\t\t\t\t\t\t);\r\n\r\n\t\t\t\t\t\t\t\t// 新規ブロック作成\r\n\t\t\t\t\t\t\t\tconst newBlock = createBlock(plugin, {\r\n\t\t\t\t\t\t\t\t\tx,\r\n\t\t\t\t\t\t\t\t\ty,\r\n\t\t\t\t\t\t\t\t\tw: defaultSize.w,\r\n\t\t\t\t\t\t\t\t\th: defaultSize.h,\r\n\t\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t\t\tonBlockChange?.({\r\n\t\t\t\t\t\t\t\t\ttype: BlockChangeType.ADD,\r\n\t\t\t\t\t\t\t\t\tblockIds: [newBlock.id],\r\n\t\t\t\t\t\t\t\t\tblocks: [newBlock],\r\n\t\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t\t// 4. リサイズ (Resize) の確定\r\n\t\t\t\t\telse if (state.dragging.type === DragType.RESIZE) {\r\n\t\t\t\t\t\tconst targetId = state.dragging.blockIds[0];\r\n\t\t\t\t\t\tconst block = blocks.find((b) => b.id === targetId);\r\n\t\t\t\t\t\tconst handle = state.dragging.handle;\r\n\r\n\t\t\t\t\t\tif (block && handle && (deltaCol !== 0 || deltaRow !== 0)) {\r\n\t\t\t\t\t\t\tconst newLayout = calculateResizedLayout({\r\n\t\t\t\t\t\t\t\tlayout: block.layout,\r\n\t\t\t\t\t\t\t\thandle,\r\n\t\t\t\t\t\t\t\tdeltaCol,\r\n\t\t\t\t\t\t\t\tdeltaRow,\r\n\t\t\t\t\t\t\t\tgridCols: gridLength.cols,\r\n\t\t\t\t\t\t\t\tgridRows: gridLength.rows,\r\n\t\t\t\t\t\t\t});\r\n\r\n\t\t\t\t\t\t\t// 変更があった場合のみ通知\r\n\t\t\t\t\t\t\tif (\r\n\t\t\t\t\t\t\t\tnewLayout.x !== block.layout.x ||\r\n\t\t\t\t\t\t\t\tnewLayout.y !== block.layout.y ||\r\n\t\t\t\t\t\t\t\tnewLayout.w !== block.layout.w ||\r\n\t\t\t\t\t\t\t\tnewLayout.h !== block.layout.h\r\n\t\t\t\t\t\t\t) {\r\n\t\t\t\t\t\t\t\tonBlockChange?.({\r\n\t\t\t\t\t\t\t\t\ttype: BlockChangeType.RESIZE,\r\n\t\t\t\t\t\t\t\t\tblockIds: [block.id],\r\n\t\t\t\t\t\t\t\t\tblocks: [{ ...block, layout: newLayout }],\r\n\t\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tonChange({ type: InteractionEventType.END_DRAG });\r\n\t\t\t\t} else if (state.mode === InteractionMode.PRESSING && state.dragging) {\r\n\t\t\t\t\t// PRESSING状態でもisOutsideなら削除\r\n\t\t\t\t\tif (\r\n\t\t\t\t\t\tstate.dragging.isOutside &&\r\n\t\t\t\t\t\tstate.dragging.type === DragType.MOVE\r\n\t\t\t\t\t) {\r\n\t\t\t\t\t\tonBlockChange?.({\r\n\t\t\t\t\t\t\ttype: BlockChangeType.DELETE,\r\n\t\t\t\t\t\t\tblockIds: state.dragging.blockIds,\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t\t// 削除したブロックの選択を解除\r\n\t\t\t\t\t\tonChange({ type: InteractionEventType.DESELECT });\r\n\t\t\t\t\t}\r\n\t\t\t\t\tonChange({ type: InteractionEventType.CANCEL_DRAG });\r\n\t\t\t\t}\r\n\r\n\t\t\t\t(e.currentTarget as Element).releasePointerCapture(e.pointerId);\r\n\t\t\t},\r\n\t\t\t[\r\n\t\t\t\tstate.mode,\r\n\t\t\t\tstate.dragging,\r\n\t\t\t\tblocks,\r\n\t\t\t\tgridLength,\r\n\t\t\t\tpluginRegistry,\r\n\t\t\t\tonBlockChange,\r\n\t\t\t\tonChange,\r\n\t\t\t],\r\n\t\t);\r\n\r\n\t\t// --- DoubleClick ---\r\n\t\tconst handleDoubleClick = useCallback(\r\n\t\t\t(e: React.MouseEvent) => {\r\n\t\t\t\tconst rect = layerRef.current?.getBoundingClientRect();\r\n\t\t\t\tif (!rect) return;\r\n\r\n\t\t\t\tconst scaleFactor = scale ?? 1.0;\r\n\t\t\t\tconst px = {\r\n\t\t\t\t\tx: (e.clientX - rect.left) / scaleFactor,\r\n\t\t\t\t\ty: (e.clientY - rect.top) / scaleFactor,\r\n\t\t\t\t};\r\n\r\n\t\t\t\tconst targetId = findBlockAtPoint(px, blocks, getBlockRectPx);\r\n\r\n\t\t\t\tif (targetId) {\r\n\t\t\t\t\t// ブロックが選択されていない場合は先に選択\r\n\t\t\t\t\tif (!state.selectedBlockIds.includes(targetId)) {\r\n\t\t\t\t\t\tonChange({\r\n\t\t\t\t\t\t\ttype: InteractionEventType.SELECT,\r\n\t\t\t\t\t\t\tblockIds: [targetId],\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t}\r\n\t\t\t\t\tonChange({ type: InteractionEventType.EDIT, blockId: targetId });\r\n\t\t\t\t}\r\n\t\t\t},\r\n\t\t\t[blocks, getBlockRectPx, onChange, scale, state.selectedBlockIds],\r\n\t\t);\r\n\r\n\t\t// キャンバス外処理\r\n\t\tconst handlePointerLeave = useCallback(\r\n\t\t\t(e: React.PointerEvent) => {\r\n\t\t\t\t// キャンバスを出た場合の処理\r\n\t\t\t\tif (\r\n\t\t\t\t\t(state.mode === InteractionMode.PRESSING ||\r\n\t\t\t\t\t\tstate.mode === InteractionMode.DRAGGING) &&\r\n\t\t\t\t\tstate.dragging\r\n\t\t\t\t) {\r\n\t\t\t\t\tconst rect = layerRef.current?.getBoundingClientRect();\r\n\t\t\t\t\tif (rect) {\r\n\t\t\t\t\t\tconst scaleFactor = scale ?? 1.0;\r\n\t\t\t\t\t\tconst rawX = (e.clientX - rect.left) / scaleFactor;\r\n\t\t\t\t\t\tconst rawY = (e.clientY - rect.top) / scaleFactor;\r\n\t\t\t\t\t\tconst canvasWidth = rect.width / scaleFactor;\r\n\t\t\t\t\t\tconst canvasHeight = rect.height / scaleFactor;\r\n\t\t\t\t\t\tconst clampedX = Math.max(0, Math.min(rawX, canvasWidth));\r\n\t\t\t\t\t\tconst clampedY = Math.max(0, Math.min(rawY, canvasHeight));\r\n\r\n\t\t\t\t\t\t// isOutside=trueを設定してゴーストをマウス追従モードに\r\n\t\t\t\t\t\tonChange({\r\n\t\t\t\t\t\t\ttype: InteractionEventType.UPDATE_DRAG,\r\n\t\t\t\t\t\t\tcurrentGrid: {\r\n\t\t\t\t\t\t\t\tcol: getColIndex(clampedX),\r\n\t\t\t\t\t\t\t\trow: getRowIndex(clampedY),\r\n\t\t\t\t\t\t\t},\r\n\t\t\t\t\t\t\tcurrentMousePx: { x: rawX, y: rawY },\r\n\t\t\t\t\t\t\tisOutside: true,\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t},\r\n\t\t\t[state.mode, state.dragging, scale, getColIndex, getRowIndex, onChange],\r\n\t\t);\r\n\t\treturn (\r\n\t\t\t<div\r\n\t\t\t\tref={layerRef}\r\n\t\t\t\tclassName={className}\r\n\t\t\t\tstyle={{\r\n\t\t\t\t\tposition: \"absolute\",\r\n\t\t\t\t\tinset: 0,\r\n\t\t\t\t\tzIndex: Z_INDEX.INTERACTION_LAYER_BASE,\r\n\t\t\t\t\tpointerEvents: \"auto\",\r\n\t\t\t\t\ttouchAction: \"none\",\r\n\t\t\t\t}}\r\n\t\t\t\trole=\"application\"\r\n\t\t\t\taria-label=\"Interactive canvas layer\"\r\n\t\t\t\ttabIndex={-1}\r\n\t\t\t\tonPointerDown={handlePointerDown}\r\n\t\t\t\tonPointerMove={handlePointerMove}\r\n\t\t\t\tonPointerUp={handlePointerUp}\r\n\t\t\t\tonPointerLeave={handlePointerLeave}\r\n\t\t\t\tonDoubleClick={handleDoubleClick}\r\n\t\t\t\tdata-testid=\"interaction-layer\"\r\n\t\t\t>\r\n\t\t\t\t{/* 編集中ブロックのRenderer (InteractionLayer上で表示) */}\r\n\t\t\t\t{state.editingBlockId &&\r\n\t\t\t\t\t(() => {\r\n\t\t\t\t\t\tconst editingBlock = blocks.find(\r\n\t\t\t\t\t\t\t(b) => b.id === state.editingBlockId,\r\n\t\t\t\t\t\t);\r\n\t\t\t\t\t\tconst plugin = editingBlock\r\n\t\t\t\t\t\t\t? pluginRegistry[editingBlock.kind]\r\n\t\t\t\t\t\t\t: null;\r\n\r\n\t\t\t\t\t\tif (!editingBlock || !plugin) return null;\r\n\r\n\t\t\t\t\t\treturn (\r\n\t\t\t\t\t\t\t<EditingBlock\r\n\t\t\t\t\t\t\t\tref={editingBlockRef}\r\n\t\t\t\t\t\t\t\tid={editingBlock.id}\r\n\t\t\t\t\t\t\t\tplugin={plugin}\r\n\t\t\t\t\t\t\t\tprops={editingBlock.props}\r\n\t\t\t\t\t\t\t\tvalue={editingBlock.initValue}\r\n\t\t\t\t\t\t\t\tonChange={(val) => {\r\n\t\t\t\t\t\t\t\t\tonBlockChange?.({\r\n\t\t\t\t\t\t\t\t\t\ttype: BlockChangeType.UPDATE,\r\n\t\t\t\t\t\t\t\t\t\tblockIds: [editingBlock.id],\r\n\t\t\t\t\t\t\t\t\t\tblocks: [{ ...editingBlock, initValue: val }],\r\n\t\t\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t\t\t}}\r\n\t\t\t\t\t\t\t\tonBlur={(val) => {\r\n\t\t\t\t\t\t\t\t\tonBlockChange?.({\r\n\t\t\t\t\t\t\t\t\t\ttype: BlockChangeType.UPDATE,\r\n\t\t\t\t\t\t\t\t\t\tblockIds: [editingBlock.id],\r\n\t\t\t\t\t\t\t\t\t\tblocks: [{ ...editingBlock, initValue: val }],\r\n\t\t\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t\t\t}}\r\n\t\t\t\t\t\t\t\tblockRectPx={getBlockRectPx(editingBlock)}\r\n\t\t\t\t\t\t\t\tzIndex={editBlockZIndex}\r\n\t\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t);\r\n\t\t\t\t\t})()}\r\n\r\n\t\t\t\t{/* 選択枠 */}\r\n\t\t\t\t<SelectionLayer\r\n\t\t\t\t\tblocks={blocks}\r\n\t\t\t\t\tselectedBlockIds={state.selectedBlockIds}\r\n\t\t\t\t\tisDragging={state.mode === InteractionMode.DRAGGING}\r\n\t\t\t\t\tdraggingState={state.dragging}\r\n\t\t\t\t\tgetBlockRectPx={getBlockRectPx}\r\n\t\t\t\t\tonResizeStart={(e, handle, blockId) => {\r\n\t\t\t\t\t\tconst rect = layerRef.current?.getBoundingClientRect();\r\n\t\t\t\t\t\tif (!rect) return;\r\n\r\n\t\t\t\t\t\t// リサイズ開始時に編集モードを終了\r\n\t\t\t\t\t\tif (state.mode === InteractionMode.EDITING) {\r\n\t\t\t\t\t\t\tonChange({ type: InteractionEventType.END_EDIT });\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t// Pointer Captureを設定(ハンドルから外れても追従)\r\n\t\t\t\t\t\t(e.currentTarget as Element).setPointerCapture(e.pointerId);\r\n\r\n\t\t\t\t\t\tconst scaleFactor = scale ?? 1.0;\r\n\t\t\t\t\t\tconst px = {\r\n\t\t\t\t\t\t\tx: (e.clientX - rect.left) / scaleFactor,\r\n\t\t\t\t\t\t\ty: (e.clientY - rect.top) / scaleFactor,\r\n\t\t\t\t\t\t};\r\n\r\n\t\t\t\t\t\tonChange({\r\n\t\t\t\t\t\t\ttype: InteractionEventType.START_RESIZE,\r\n\t\t\t\t\t\t\tblockId,\r\n\t\t\t\t\t\t\thandle,\r\n\t\t\t\t\t\t\tstartGrid: { col: getColIndex(px.x), row: getRowIndex(px.y) },\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t}}\r\n\t\t\t\t\tselectionStyle={selectionStyle}\r\n\t\t\t\t\thandleStyle={handleStyle}\r\n\t\t\t\t\tselectBorderZIndex={selectBorderZIndex}\r\n\t\t\t\t\tblockHandlesZIndex={blockHandlesZIndex}\r\n\t\t\t\t/>\r\n\r\n\t\t\t\t{/* ドラッグ時のゴースト */}\r\n\t\t\t\t<DragLayer\r\n\t\t\t\t\tblocks={blocks}\r\n\t\t\t\t\tpluginRegistry={pluginRegistry}\r\n\t\t\t\t\tgridLength={gridLength}\r\n\t\t\t\t\tdraggingState={state.dragging}\r\n\t\t\t\t\tgetBlockRectPx={getBlockRectPx}\r\n\t\t\t\t\tselectionStyle={selectionStyle}\r\n\t\t\t\t\tghostZIndex={dragGhostZIndex}\r\n\t\t\t\t\tselectBorderZIndex={selectBorderZIndex}\r\n\t\t\t\t\tblockHandlesZIndex={blockHandlesZIndex}\r\n\t\t\t\t/>\r\n\t\t\t</div>\r\n\t\t);\r\n\t},\r\n);\r\n\r\nInteractionLayer.displayName = \"InteractionLayer\";\r\n","import { useCallback, useMemo } from \"react\";\r\n\r\nimport { DEFAULT_DPI } from \"@/constants\";\r\nimport { toMm, toPx } from \"@/utils\";\r\nimport { findGridIndex, getMaxStep, gridToMms, mmsToPxs } from \"@/utils/grid\";\r\n\r\nimport type {\r\n\tBlock,\r\n\tBlockRectPx,\r\n\tGrid,\r\n\tGridPosPx,\r\n\tPaper,\r\n\tPaperCanvasPx,\r\n\tPaperMarginPx,\r\n\tPaperPx,\r\n} from \"@/types\";\r\n\r\nexport function useGridCalc(\r\n\tpaper: Paper,\r\n\tgrid: Grid,\r\n\tdpi: number = DEFAULT_DPI,\r\n) {\r\n\t// Paperをmm単位で保持\r\n\tconst canvasWidthMm = useMemo(\r\n\t\t() => toMm.fromDim(paper.size.width),\r\n\t\t[paper.size.width],\r\n\t);\r\n\tconst canvasHeightMm = useMemo(\r\n\t\t() => toMm.fromDim(paper.size.height),\r\n\t\t[paper.size.height],\r\n\t);\r\n\tconst marginTopMm = useMemo(\r\n\t\t() => toMm.fromDim(paper.margin.top),\r\n\t\t[paper.margin.top],\r\n\t);\r\n\tconst marginBottomMm = useMemo(\r\n\t\t() => toMm.fromDim(paper.margin.bottom),\r\n\t\t[paper.margin.bottom],\r\n\t);\r\n\tconst marginLeftMm = useMemo(\r\n\t\t() => toMm.fromDim(paper.margin.left),\r\n\t\t[paper.margin.left],\r\n\t);\r\n\tconst marginRightMm = useMemo(\r\n\t\t() => toMm.fromDim(paper.margin.right),\r\n\t\t[paper.margin.right],\r\n\t);\r\n\r\n\t// 描画領域の寸法をmm単位で計算\r\n\tconst contentWidthMm = useMemo(\r\n\t\t() => canvasWidthMm - marginLeftMm - marginRightMm,\r\n\t\t[canvasWidthMm, marginLeftMm, marginRightMm],\r\n\t);\r\n\tconst contentHeightMm = useMemo(\r\n\t\t() => canvasHeightMm - marginTopMm - marginBottomMm,\r\n\t\t[canvasHeightMm, marginTopMm, marginBottomMm],\r\n\t);\r\n\r\n\t// Gridをmm単位で保持\r\n\tconst colMms = useMemo(\r\n\t\t() => gridToMms(grid.cols, contentWidthMm),\r\n\t\t[grid.cols, contentWidthMm],\r\n\t);\r\n\tconst rowMms = useMemo(\r\n\t\t() => gridToMms(grid.rows, contentHeightMm),\r\n\t\t[grid.rows, contentHeightMm],\r\n\t);\r\n\r\n\t// Paperをpx単位で保持\r\n\tconst canvasWidthPx = useMemo(\r\n\t\t() => toPx.fromMm(canvasWidthMm, dpi),\r\n\t\t[canvasWidthMm, dpi],\r\n\t);\r\n\tconst canvasHeightPx = useMemo(\r\n\t\t() => toPx.fromMm(canvasHeightMm, dpi),\r\n\t\t[canvasHeightMm, dpi],\r\n\t);\r\n\tconst marginTopPx = useMemo(\r\n\t\t() => toPx.fromMm(marginTopMm, dpi),\r\n\t\t[marginTopMm, dpi],\r\n\t);\r\n\tconst marginBottomPx = useMemo(\r\n\t\t() => toPx.fromMm(marginBottomMm, dpi),\r\n\t\t[marginBottomMm, dpi],\r\n\t);\r\n\tconst marginLeftPx = useMemo(\r\n\t\t() => toPx.fromMm(marginLeftMm, dpi),\r\n\t\t[marginLeftMm, dpi],\r\n\t);\r\n\tconst marginRightPx = useMemo(\r\n\t\t() => toPx.fromMm(marginRightMm, dpi),\r\n\t\t[marginRightMm, dpi],\r\n\t);\r\n\r\n\t// 描画領域の寸法をpx単位で計算\r\n\tconst contentWidthPx = useMemo(\r\n\t\t() => toPx.fromMm(contentWidthMm, dpi),\r\n\t\t[contentWidthMm, dpi],\r\n\t);\r\n\tconst contentHeightPx = useMemo(\r\n\t\t() => toPx.fromMm(contentHeightMm, dpi),\r\n\t\t[contentHeightMm, dpi],\r\n\t);\r\n\r\n\t// Gridをpx単位で保持\r\n\tconst colPxs = useMemo(() => mmsToPxs(colMms, dpi), [colMms, dpi]);\r\n\tconst rowPxs = useMemo(() => mmsToPxs(rowMms, dpi), [rowMms, dpi]);\r\n\r\n\t// Gridのスタート位置を累積和配列で保持\r\n\tconst colPosPxs = useMemo(() => {\r\n\t\tconst starts = [0];\r\n\t\tfor (const width of colPxs) {\r\n\t\t\tconst last = starts[starts.length - 1] ?? 0;\r\n\t\t\tstarts.push(last + width);\r\n\t\t}\r\n\t\treturn starts;\r\n\t}, [colPxs]);\r\n\tconst rowPosPxs = useMemo(() => {\r\n\t\tconst starts = [0];\r\n\t\tfor (const height of rowPxs) {\r\n\t\t\tconst last = starts[starts.length - 1] ?? 0;\r\n\t\t\tstarts.push(last + height);\r\n\t\t}\r\n\t\treturn starts;\r\n\t}, [rowPxs]);\r\n\r\n\t// pxからグリッドの列・行番号を取得する関数\r\n\tconst { step: colMaxStep, windowPx: colWindowPx } = useMemo(\r\n\t\t() => getMaxStep(colPosPxs),\r\n\t\t[colPosPxs],\r\n\t);\r\n\tconst { step: rowMaxStep, windowPx: rowWindowPx } = useMemo(\r\n\t\t() => getMaxStep(rowPosPxs),\r\n\t\t[rowPosPxs],\r\n\t);\r\n\tconst colIndexer = useMemo(\r\n\t\t() => findGridIndex(colPosPxs, colMaxStep, colWindowPx),\r\n\t\t[colPosPxs, colMaxStep, colWindowPx],\r\n\t);\r\n\tconst rowIndexer = useMemo(\r\n\t\t() => findGridIndex(rowPosPxs, rowMaxStep, rowWindowPx),\r\n\t\t[rowPosPxs, rowMaxStep, rowWindowPx],\r\n\t);\r\n\tconst getColIndex = useCallback(\r\n\t\t(px: number) => colIndexer(px - marginLeftPx),\r\n\t\t[colIndexer, marginLeftPx],\r\n\t);\r\n\tconst getRowIndex = useCallback(\r\n\t\t(px: number) => rowIndexer(px - marginTopPx),\r\n\t\t[rowIndexer, marginTopPx],\r\n\t);\r\n\r\n\t// 変数まとめ\r\n\tconst gridPosPx = useMemo(() => {\r\n\t\treturn {\r\n\t\t\tcols: colPosPxs,\r\n\t\t\trows: rowPosPxs,\r\n\t\t} as GridPosPx;\r\n\t}, [colPosPxs, rowPosPxs]);\r\n\r\n\tconst paperCanvasPx = useMemo(() => {\r\n\t\treturn {\r\n\t\t\twidth: canvasWidthPx,\r\n\t\t\theight: canvasHeightPx,\r\n\t\t} as PaperCanvasPx;\r\n\t}, [canvasWidthPx, canvasHeightPx]);\r\n\r\n\tconst paperMarginPx = useMemo(() => {\r\n\t\treturn {\r\n\t\t\ttop: marginTopPx,\r\n\t\t\tbottom: marginBottomPx,\r\n\t\t\tleft: marginLeftPx,\r\n\t\t\tright: marginRightPx,\r\n\t\t} as PaperMarginPx;\r\n\t}, [marginTopPx, marginBottomPx, marginLeftPx, marginRightPx]);\r\n\r\n\tconst paperContentPx = useMemo(() => {\r\n\t\treturn {\r\n\t\t\twidth: contentWidthPx,\r\n\t\t\theight: contentHeightPx,\r\n\t\t};\r\n\t}, [contentWidthPx, contentHeightPx]);\r\n\r\n\tconst paperPx = useMemo(() => {\r\n\t\treturn {\r\n\t\t\tcanvas: paperCanvasPx,\r\n\t\t\tmargin: paperMarginPx,\r\n\t\t\tcontent: paperContentPx,\r\n\t\t} as PaperPx;\r\n\t}, [paperCanvasPx, paperMarginPx, paperContentPx]);\r\n\r\n\tconst getBlockRectPx = useCallback(\r\n\t\t(block: Block): BlockRectPx => {\r\n\t\t\tconst { x, y, w, h } = block.layout;\r\n\t\t\tconst colLines = gridPosPx.cols;\r\n\t\t\tconst rowLines = gridPosPx.rows;\r\n\r\n\t\t\t// 安全策: グリッド定義がない場合は0を返す\r\n\t\t\tif (!colLines.length || !rowLines.length) {\r\n\t\t\t\treturn { left: 0, top: 0, width: 0, height: 0 };\r\n\t\t\t}\r\n\r\n\t\t\t// インデックス範囲制限 (clamp)\r\n\t\t\tconst x1 = Math.min(Math.max(0, x), colLines.length - 1);\r\n\t\t\tconst x2 = Math.min(Math.max(0, x + w), colLines.length - 1);\r\n\t\t\tconst y1 = Math.min(Math.max(0, y), rowLines.length - 1);\r\n\t\t\tconst y2 = Math.min(Math.max(0, y + h), rowLines.length - 1);\r\n\r\n\t\t\tconst left = (colLines[x1] ?? 0) + marginLeftPx;\r\n\t\t\tconst top = (rowLines[y1] ?? 0) + marginTopPx;\r\n\t\t\tconst width = (colLines[x2] ?? 0) - (colLines[x1] ?? 0);\r\n\t\t\tconst height = (rowLines[y2] ?? 0) - (rowLines[y1] ?? 0);\r\n\r\n\t\t\treturn { left, top, width, height };\r\n\t\t},\r\n\t\t[gridPosPx, marginLeftPx, marginTopPx],\r\n\t);\r\n\r\n\treturn {\r\n\t\tpaperPx,\r\n\t\tgridPosPx,\r\n\t\tgetColIndex,\r\n\t\tgetRowIndex,\r\n\t\tgetBlockRectPx,\r\n\t};\r\n}\r\n","/**\r\n * @file NoteEdit.tsx\r\n * @description 値入力モード(Editモード)専用コンポーネント\r\n * - ブロックの配置・サイズ変更は不可\r\n * - 直接valueを編集可能\r\n * - InteractionLayerなし(pointerEvents常に\"auto\")\r\n */\r\n\r\nimport { memo, useCallback } from \"react\";\r\n\r\nimport { BlockLayer } from \"./BlockLayer\";\r\nimport { GridLayer } from \"./GridLayer\";\r\n\r\nimport { DEFAULT_DPI } from \"@/constants\";\r\nimport { useGridCalc } from \"@/hooks/useGridCalc\";\r\nimport { NoteMode } from \"@/types/mode\";\r\n\r\nimport type { BlockPlugin } from \"@/plugin\";\r\nimport type { OnChange } from \"@/types/callbacks\";\r\nimport type { FormSchema } from \"@/types/schema\";\r\nimport type { Value } from \"@/types/value\";\r\n\r\nexport interface NoteEditProps {\r\n\tschema: FormSchema;\r\n\tvalues: Record<string, Value>;\r\n\tpluginRegistry: Record<string, BlockPlugin>;\r\n\tonValueChange?: OnChange;\r\n\tscale?: number;\r\n\tclassName?: string;\r\n}\r\n\r\nconst NoteEditBase = ({\r\n\tschema,\r\n\tvalues,\r\n\tpluginRegistry,\r\n\tonValueChange,\r\n\tscale = 1.0,\r\n\tclassName,\r\n}: NoteEditProps) => {\r\n\tconst { paperPx, gridPosPx, getBlockRectPx } = useGridCalc(\r\n\t\tschema.paper,\r\n\t\tschema.grid,\r\n\t\tDEFAULT_DPI,\r\n\t);\r\n\r\n\t// 値変更ハンドラ\r\n\tconst handleValueChange = useCallback(\r\n\t\t(id: string, val: Value) => {\r\n\t\t\tif (!onValueChange) return;\r\n\t\t\tonValueChange(id, val);\r\n\t\t},\r\n\t\t[onValueChange],\r\n\t);\r\n\r\n\treturn (\r\n\t\t<div\r\n\t\t\tclassName={className}\r\n\t\t\tstyle={{\r\n\t\t\t\tposition: \"relative\",\r\n\t\t\t\twidth: `${paperPx.canvas.width}px`,\r\n\t\t\t\theight: `${paperPx.canvas.height}px`,\r\n\t\t\t\tmargin: \"0 auto\",\r\n\t\t\t\tboxShadow: \"0 2px 8px rgba(0,0,0,0.1)\",\r\n\t\t\t\tbackgroundColor: \"#fff\",\r\n\t\t\t\ttransform: scale !== 1 ? `scale(${scale})` : undefined,\r\n\t\t\t\ttransformOrigin: \"top center\",\r\n\t\t\t}}\r\n\t\t>\r\n\t\t\t<GridLayer\r\n\t\t\t\tpaperPx={paperPx}\r\n\t\t\t\tgridPosPxs={gridPosPx}\r\n\t\t\t\tshowGridLines={false}\r\n\t\t\t\tshowMargins={false}\r\n\t\t\t\tshowBorder={false}\r\n\t\t\t/>\r\n\r\n\t\t\t<BlockLayer\r\n\t\t\t\tblocks={schema.blocks}\r\n\t\t\t\tpluginRegistry={pluginRegistry}\r\n\t\t\t\tmode={NoteMode.EDIT}\r\n\t\t\t\tvalues={values}\r\n\t\t\t\tgetBlockRectPx={getBlockRectPx}\r\n\t\t\t\tonValueChange={handleValueChange}\r\n\t\t\t\tshowGuides={true}\r\n\t\t\t\tshowBorder={true}\r\n\t\t\t/>\r\n\t\t</div>\r\n\t);\r\n};\r\n\r\nNoteEditBase.displayName = \"NoteEdit\";\r\n\r\nexport const NoteEdit = memo(NoteEditBase);\r\n","/**\r\n * @file NoteForm.tsx\r\n * @description テンプレート作成モード(Formモード)専用コンポーネント\r\n * - ブロックの配置・サイズ変更が可能\r\n * - ダブルクリックでinitValueを編集\r\n * - InteractionLayerが有効\r\n */\r\n\r\nimport { memo, useCallback, useEffect, useMemo, useRef } from \"react\";\r\n\r\nimport { BlockLayer } from \"./BlockLayer\";\r\nimport { GridLayer } from \"./GridLayer\";\r\nimport {\r\n\tDragType,\r\n\tInteractionEventType,\r\n\tInteractionLayer,\r\n\tInteractionMode,\r\n\tuseInteractionState,\r\n} from \"./InteractionLayer\";\r\n\r\nimport { DEFAULT_DPI } from \"@/constants\";\r\nimport { useGridCalc } from \"@/hooks/useGridCalc\";\r\nimport { BlockChangeType } from \"@/types\";\r\nimport { LineType } from \"@/types/line\";\r\nimport { NoteMode } from \"@/types/mode\";\r\nimport { globalDragStore } from \"@/utils/GlobalDragStore\";\r\nimport { calculateGridResize } from \"@/utils/grid\";\r\nimport { removeUndefinedProps } from \"@/utils/objectUtils\";\r\n\r\nimport type { BlockPlugin } from \"@/plugin\";\r\nimport type { OnBlockChange, OnSchemaChange } from \"@/types/callbacks\";\r\nimport type { FormSchema } from \"@/types/schema\";\r\nimport type { Value } from \"@/types/value\";\r\n\r\nexport interface NoteFormProps {\r\n\tschema: FormSchema;\r\n\tpluginRegistry: Record<string, BlockPlugin>;\r\n\tonSchemaChange?: OnSchemaChange;\r\n\tonSelectionChange?: (selectedBlockIds: string[]) => void;\r\n\tscale?: number;\r\n\tclassName?: string;\r\n}\r\n\r\nconst NoteFormBase = ({\r\n\tschema,\r\n\tpluginRegistry,\r\n\tonSchemaChange,\r\n\tonSelectionChange,\r\n\tscale = 1.0,\r\n\tclassName,\r\n}: NoteFormProps) => {\r\n\t// ✅ 新しいHookで状態管理\r\n\tconst [interactionState, handleInteractionChange] = useInteractionState();\r\n\r\n\t// 用紙要素への参照\r\n\tconst paperRef = useRef<HTMLDivElement>(null);\r\n\r\n\tconst { paperPx, gridPosPx, getBlockRectPx, getColIndex, getRowIndex } =\r\n\t\tuseGridCalc(schema.paper, schema.grid, DEFAULT_DPI);\r\n\r\n\t// ブロック配置変更ハンドラ\r\n\tconst handleBlockChange: OnBlockChange = useCallback(\r\n\t\t(event) => {\r\n\t\t\tif (!onSchemaChange) return;\r\n\r\n\t\t\tswitch (event.type) {\r\n\t\t\t\tcase BlockChangeType.MOVE:\r\n\t\t\t\tcase BlockChangeType.RESIZE: {\r\n\t\t\t\t\tif (!event.blocks) return;\r\n\t\t\t\t\tconst nextBlocks = schema.blocks.map((block) => {\r\n\t\t\t\t\t\tconst updated = event.blocks?.find((b) => b.id === block.id);\r\n\t\t\t\t\t\treturn updated || block;\r\n\t\t\t\t\t});\r\n\t\t\t\t\tonSchemaChange({ ...schema, blocks: nextBlocks });\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tcase BlockChangeType.ADD: {\r\n\t\t\t\t\tif (!event.blocks) return;\r\n\t\t\t\t\tonSchemaChange({\r\n\t\t\t\t\t\t...schema,\r\n\t\t\t\t\t\tblocks: [...schema.blocks, ...event.blocks],\r\n\t\t\t\t\t});\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tcase BlockChangeType.DELETE: {\r\n\t\t\t\t\tconst deletedIds = new Set(event.blockIds);\r\n\t\t\t\t\tconst nextBlocks = schema.blocks.filter(\r\n\t\t\t\t\t\t(block) => !deletedIds.has(block.id),\r\n\t\t\t\t\t);\r\n\t\t\t\t\tonSchemaChange({ ...schema, blocks: nextBlocks });\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tcase BlockChangeType.UPDATE: {\r\n\t\t\t\t\tif (!event.blocks) return;\r\n\t\t\t\t\tconst nextBlocks = schema.blocks.map((block) => {\r\n\t\t\t\t\t\tconst updated = event.blocks?.find((b) => b.id === block.id);\r\n\t\t\t\t\t\tif (!updated) return block;\r\n\r\n\t\t\t\t\t\t// styleやpropsからundefined/nullプロパティを削除\r\n\t\t\t\t\t\tconst cleanedStyle = updated.style\r\n\t\t\t\t\t\t\t? (removeUndefinedProps(\r\n\t\t\t\t\t\t\t\t\tupdated.style as Record<string, unknown>,\r\n\t\t\t\t\t\t\t\t) as typeof updated.style)\r\n\t\t\t\t\t\t\t: updated.style;\r\n\r\n\t\t\t\t\t\tconst cleanedProps = updated.props\r\n\t\t\t\t\t\t\t? (removeUndefinedProps(\r\n\t\t\t\t\t\t\t\t\tupdated.props as Record<string, unknown>,\r\n\t\t\t\t\t\t\t\t) as typeof updated.props)\r\n\t\t\t\t\t\t\t: updated.props;\r\n\r\n\t\t\t\t\t\treturn {\r\n\t\t\t\t\t\t\t...block,\r\n\t\t\t\t\t\t\t...updated,\r\n\t\t\t\t\t\t\tstyle: cleanedStyle,\r\n\t\t\t\t\t\t\tprops: cleanedProps,\r\n\t\t\t\t\t\t};\r\n\t\t\t\t\t});\r\n\t\t\t\t\tonSchemaChange({ ...schema, blocks: nextBlocks });\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tdefault:\r\n\t\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t},\r\n\t\t[schema, onSchemaChange],\r\n\t);\r\n\r\n\t// initValue変更ハンドラ(ダブルクリックで編集時)\r\n\tconst handleInitValueChange = useCallback(\r\n\t\t(id: string, val: Value) => {\r\n\t\t\tif (!onSchemaChange) return;\r\n\t\t\tconst nextBlocks = schema.blocks.map((block) => {\r\n\t\t\t\tif (block.id === id) {\r\n\t\t\t\t\treturn { ...block, initValue: val };\r\n\t\t\t\t}\r\n\t\t\t\treturn block;\r\n\t\t\t});\r\n\t\t\tonSchemaChange({ ...schema, blocks: nextBlocks });\r\n\t\t},\r\n\t\t[schema, onSchemaChange],\r\n\t);\r\n\r\n\t// 選択状態の変更を通知\r\n\tuseEffect(() => {\r\n\t\tif (onSelectionChange) {\r\n\t\t\tonSelectionChange(interactionState.selectedBlockIds);\r\n\t\t}\r\n\t}, [interactionState.selectedBlockIds, onSelectionChange]);\r\n\r\n\t// globalDragStoreの状態を監視し、ドラッグ終了時にINSERT操作をキャンセル\r\n\tuseEffect(() => {\r\n\t\tconst unsubscribe = globalDragStore.subscribe((dragState) => {\r\n\t\t\t// グローバルドラッグが終了し、かつINSERT操作中の場合はキャンセル\r\n\t\t\tif (\r\n\t\t\t\t!dragState &&\r\n\t\t\t\tinteractionState.mode === InteractionMode.DRAGGING &&\r\n\t\t\t\tinteractionState.dragging?.type === DragType.INSERT\r\n\t\t\t) {\r\n\t\t\t\thandleInteractionChange({ type: InteractionEventType.CANCEL_INSERT });\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\treturn () => unsubscribe();\r\n\t}, [\r\n\t\tinteractionState.mode,\r\n\t\tinteractionState.dragging,\r\n\t\thandleInteractionChange,\r\n\t]);\r\n\r\n\t// 用紙外のクリックを検知して選択を解除\r\n\tuseEffect(() => {\r\n\t\tconst handleClickOutside = (event: MouseEvent) => {\r\n\t\t\t// ブロックが選択されていない場合は何もしない\r\n\t\t\tif (interactionState.selectedBlockIds.length === 0) return;\r\n\r\n\t\t\t// クリックされた要素を取得\r\n\t\t\tconst target = event.target as Node;\r\n\r\n\t\t\t// 1. まずSidebar内のクリックかチェック(最優先で除外)\r\n\t\t\tif (target instanceof HTMLElement) {\r\n\t\t\t\tconst isSidebar = target.closest('[data-sidebar=\"true\"]');\r\n\t\t\t\tif (isSidebar) return;\r\n\t\t\t}\r\n\r\n\t\t\t// 2. 用紙要素が存在し、クリックが用紙の外側の場合のみ選択解除\r\n\t\t\tif (paperRef.current && !paperRef.current.contains(target)) {\r\n\t\t\t\thandleInteractionChange({ type: InteractionEventType.DESELECT });\r\n\t\t\t}\r\n\t\t};\r\n\r\n\t\t// documentにイベントリスナーを追加\r\n\t\tdocument.addEventListener(\"mousedown\", handleClickOutside);\r\n\r\n\t\treturn () => {\r\n\t\t\t// クリーンアップ\r\n\t\t\tdocument.removeEventListener(\"mousedown\", handleClickOutside);\r\n\t\t};\r\n\t}, [interactionState.selectedBlockIds, handleInteractionChange]);\r\n\r\n\t// グリッドリサイズハンドラ\r\n\tconst handleGridResize = useCallback(\r\n\t\t(direction: \"column\" | \"row\", index: number, deltaPx: number) => {\r\n\t\t\tif (!onSchemaChange) return;\r\n\r\n\t\t\t// グリッド線のindexをdimension配列のindexに変換\r\n\t\t\t// グリッド線index=1 → dimension[0]とdimension[1]の境界\r\n\t\t\tconst dimensionIndex = index - 1;\r\n\r\n\t\t\tif (direction === \"column\") {\r\n\t\t\t\t// 列幅を変更\r\n\t\t\t\tconst newCols = calculateGridResize(\r\n\t\t\t\t\tschema.grid.cols,\r\n\t\t\t\t\tdimensionIndex,\r\n\t\t\t\t\tdeltaPx,\r\n\t\t\t\t\tpaperPx.content.width,\r\n\t\t\t\t);\r\n\t\t\t\tonSchemaChange({\r\n\t\t\t\t\t...schema,\r\n\t\t\t\t\tgrid: { ...schema.grid, cols: newCols },\r\n\t\t\t\t});\r\n\t\t\t} else {\r\n\t\t\t\t// 行高を変更\r\n\t\t\t\tconst newRows = calculateGridResize(\r\n\t\t\t\t\tschema.grid.rows,\r\n\t\t\t\t\tdimensionIndex,\r\n\t\t\t\t\tdeltaPx,\r\n\t\t\t\t\tpaperPx.content.height,\r\n\t\t\t\t);\r\n\t\t\t\tonSchemaChange({\r\n\t\t\t\t\t...schema,\r\n\t\t\t\t\tgrid: { ...schema.grid, rows: newRows },\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t},\r\n\t\t[schema, paperPx, onSchemaChange],\r\n\t);\r\n\r\n\t/**\r\n\t * グリッド寸法の単位/値を変更した際のハンドラ\r\n\t */\r\n\tconst handleDimensionChange = useCallback(\r\n\t\t(\r\n\t\t\tdirection: \"column\" | \"row\",\r\n\t\t\tindex: number,\r\n\t\t\tdimension: import(\"@types\").Dimension<import(\"@types\").GridUnit>,\r\n\t\t) => {\r\n\t\t\tif (!onSchemaChange) return;\r\n\r\n\t\t\tif (direction === \"column\") {\r\n\t\t\t\tconst newCols = [...schema.grid.cols];\r\n\t\t\t\tnewCols[index] = dimension;\r\n\t\t\t\tonSchemaChange({\r\n\t\t\t\t\t...schema,\r\n\t\t\t\t\tgrid: { ...schema.grid, cols: newCols },\r\n\t\t\t\t});\r\n\t\t\t} else {\r\n\t\t\t\tconst newRows = [...schema.grid.rows];\r\n\t\t\t\tnewRows[index] = dimension;\r\n\t\t\t\tonSchemaChange({\r\n\t\t\t\t\t...schema,\r\n\t\t\t\t\tgrid: { ...schema.grid, rows: newRows },\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t},\r\n\t\t[onSchemaChange, schema],\r\n\t); // initValueをvaluesとして使用\r\n\tconst values = useMemo(\r\n\t\t() =>\r\n\t\t\tschema.blocks.reduce(\r\n\t\t\t\t(acc, block) => {\r\n\t\t\t\t\tacc[block.id] = block.initValue;\r\n\t\t\t\t\treturn acc;\r\n\t\t\t\t},\r\n\t\t\t\t{} as Record<string, Value>,\r\n\t\t\t),\r\n\t\t[schema.blocks],\r\n\t); /**\r\n\t * マウスがCanvas上に入ってきた時の処理\r\n\t * Paletteからドラッグ中のアイテムがあれば、INSERT操作を開始\r\n\t */\r\n\tconst handlePointerEnter = useCallback(() => {\r\n\t\t// 1. グローバルストアから「今ドラッグ中のもの」を取得\r\n\t\tconst draggingItem = globalDragStore.get();\r\n\r\n\t\t// 2. 何も持ってなければ無視\r\n\t\tif (!draggingItem) return;\r\n\r\n\t\t// 3. すでにドラッグ中またはドラッグ状態が存在する場合は無視 (二重起動防止)\r\n\t\tif (\r\n\t\t\tinteractionState.mode === InteractionMode.DRAGGING ||\r\n\t\t\tinteractionState.dragging\r\n\t\t) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// 4. ここで初めて INSERT モードを開始\r\n\t\thandleInteractionChange({\r\n\t\t\ttype: InteractionEventType.START_INSERT,\r\n\t\t\tpluginKind: draggingItem.kind,\r\n\t\t\tdefaultSize: draggingItem.defaultSize,\r\n\t\t});\r\n\t}, [\r\n\t\tinteractionState.mode,\r\n\t\tinteractionState.dragging,\r\n\t\thandleInteractionChange,\r\n\t]);\r\n\r\n\t/**\r\n\t * マウスがCanvasから出た時の処理\r\n\t * INSERT操作中なら、範囲外フラグを立てる\r\n\t */\r\n\tconst handlePointerLeave = useCallback(() => {\r\n\t\t// INSERT操作中なら何もしない(InteractionLayerで処理)\r\n\t\t// ここでキャンセルすると、マウスが一瞬外に出ただけでキャンセルされてしまう\r\n\t}, []);\r\n\r\n\treturn (\r\n\t\t<div\r\n\t\t\tref={paperRef}\r\n\t\t\tclassName={className}\r\n\t\t\tonPointerEnter={handlePointerEnter}\r\n\t\t\tonPointerLeave={handlePointerLeave}\r\n\t\t\tstyle={{\r\n\t\t\t\tposition: \"relative\",\r\n\t\t\t\twidth: `${paperPx.canvas.width}px`,\r\n\t\t\t\theight: `${paperPx.canvas.height}px`,\r\n\t\t\t\tmargin: \"0 auto\",\r\n\t\t\t\tboxShadow: \"0 2px 8px rgba(0,0,0,0.1)\",\r\n\t\t\t\tbackgroundColor: \"#fff\",\r\n\t\t\t\ttransform: scale !== 1 ? `scale(${scale})` : undefined,\r\n\t\t\t\ttransformOrigin: \"top center\",\r\n\t\t\t}}\r\n\t\t>\r\n\t\t\t<GridLayer\r\n\t\t\t\tpaperPx={paperPx}\r\n\t\t\t\tgridPosPxs={gridPosPx}\r\n\t\t\t\tgridDimensions={{\r\n\t\t\t\t\tcols: schema.grid.cols,\r\n\t\t\t\t\trows: schema.grid.rows,\r\n\t\t\t\t}}\r\n\t\t\t\tshowGridLines={true}\r\n\t\t\t\tshowMargins={true}\r\n\t\t\t\tshowBorder={true}\r\n\t\t\t\tshowResizeHandles={true}\r\n\t\t\t\tshowDimensionLabels={true}\r\n\t\t\t\tonGridResize={handleGridResize}\r\n\t\t\t\tonDimensionChange={handleDimensionChange}\r\n\t\t\t\tgridLineStyle={{\r\n\t\t\t\t\tcolor: \"#e5e7eb\",\r\n\t\t\t\t\twidth: { value: 1, unit: \"px\" },\r\n\t\t\t\t\ttype: LineType.SOLID,\r\n\t\t\t\t}}\r\n\t\t\t\tborderStyle={{\r\n\t\t\t\t\tall: {\r\n\t\t\t\t\t\tcolor: \"#000000\",\r\n\t\t\t\t\t\twidth: { value: 1, unit: \"px\" },\r\n\t\t\t\t\t\ttype: LineType.SOLID,\r\n\t\t\t\t\t},\r\n\t\t\t\t}}\r\n\t\t\t/>\r\n\t\t\t<BlockLayer\r\n\t\t\t\tblocks={schema.blocks}\r\n\t\t\t\tpluginRegistry={pluginRegistry}\r\n\t\t\t\tmode={NoteMode.FORM}\r\n\t\t\t\tvalues={values}\r\n\t\t\t\tselectedBlockIds={interactionState.selectedBlockIds}\r\n\t\t\t\tgetBlockRectPx={getBlockRectPx}\r\n\t\t\t\tonValueChange={handleInitValueChange}\r\n\t\t\t\tshowGuides={true}\r\n\t\t\t\tshowBorder={true}\r\n\t\t\t/>\r\n\t\t\t<InteractionLayer\r\n\t\t\t\tblocks={schema.blocks}\r\n\t\t\t\tgridLength={{\r\n\t\t\t\t\tcols: schema.grid.cols.length,\r\n\t\t\t\t\trows: schema.grid.rows.length,\r\n\t\t\t\t}}\r\n\t\t\t\tpluginRegistry={pluginRegistry}\r\n\t\t\t\tgetBlockRectPx={getBlockRectPx}\r\n\t\t\t\tgetColIndex={getColIndex}\r\n\t\t\t\tgetRowIndex={getRowIndex}\r\n\t\t\t\tstate={interactionState}\r\n\t\t\t\tonChange={handleInteractionChange}\r\n\t\t\t\tonBlockChange={handleBlockChange}\r\n\t\t\t\tscale={scale}\r\n\t\t\t/>\r\n\t\t</div>\r\n\t);\r\n};\r\n\r\nNoteFormBase.displayName = \"NoteForm\";\r\n\r\nexport const NoteForm = memo(NoteFormBase);\r\n","/**\r\n * @file NoteView.tsx\r\n * @description 閲覧モード(Viewモード)専用コンポーネント\r\n * - すべて読み取り専用\r\n * - ブロックの配置・サイズ変更不可\r\n * - 値の編集不可\r\n * - InteractionLayerなし\r\n */\r\n\r\nimport { memo } from \"react\";\r\n\r\nimport { BlockLayer } from \"./BlockLayer\";\r\nimport { GridLayer } from \"./GridLayer\";\r\n\r\nimport { DEFAULT_DPI } from \"@/constants\";\r\nimport { useGridCalc } from \"@/hooks/useGridCalc\";\r\nimport { NoteMode } from \"@/types/mode\";\r\n\r\nimport type { BlockPlugin } from \"@/plugin\";\r\nimport type { FormSchema } from \"@/types/schema\";\r\nimport type { Value } from \"@/types/value\";\r\n\r\nexport interface NoteViewProps {\r\n\tschema: FormSchema;\r\n\tvalues: Record<string, Value>;\r\n\tpluginRegistry: Record<string, BlockPlugin>;\r\n\tscale?: number;\r\n\tclassName?: string;\r\n}\r\n\r\nconst NoteViewBase = ({\r\n\tschema,\r\n\tvalues,\r\n\tpluginRegistry,\r\n\tscale = 1.0,\r\n\tclassName,\r\n}: NoteViewProps) => {\r\n\tconst { paperPx, gridPosPx, getBlockRectPx } = useGridCalc(\r\n\t\tschema.paper,\r\n\t\tschema.grid,\r\n\t\tDEFAULT_DPI,\r\n\t);\r\n\r\n\treturn (\r\n\t\t<div\r\n\t\t\tclassName={className}\r\n\t\t\tstyle={{\r\n\t\t\t\tposition: \"relative\",\r\n\t\t\t\twidth: `${paperPx.canvas.width}px`,\r\n\t\t\t\theight: `${paperPx.canvas.height}px`,\r\n\t\t\t\tmargin: \"0 auto\",\r\n\t\t\t\tboxShadow: \"0 2px 8px rgba(0,0,0,0.1)\",\r\n\t\t\t\tbackgroundColor: \"#fff\",\r\n\t\t\t\ttransform: scale !== 1 ? `scale(${scale})` : undefined,\r\n\t\t\t\ttransformOrigin: \"top center\",\r\n\t\t\t}}\r\n\t\t>\r\n\t\t\t<GridLayer\r\n\t\t\t\tpaperPx={paperPx}\r\n\t\t\t\tgridPosPxs={gridPosPx}\r\n\t\t\t\tshowGridLines={false}\r\n\t\t\t\tshowMargins={false}\r\n\t\t\t\tshowBorder={false}\r\n\t\t\t/>\r\n\r\n\t\t\t<BlockLayer\r\n\t\t\t\tblocks={schema.blocks}\r\n\t\t\t\tpluginRegistry={pluginRegistry}\r\n\t\t\t\tmode={NoteMode.VIEW}\r\n\t\t\t\tvalues={values}\r\n\t\t\t\tgetBlockRectPx={getBlockRectPx}\r\n\t\t\t\tshowGuides={false}\r\n\t\t\t\tshowBorder={true}\r\n\t\t\t/>\r\n\t\t</div>\r\n\t);\r\n};\r\n\r\nNoteViewBase.displayName = \"NoteView\";\r\n\r\nexport const NoteView = memo(NoteViewBase);\r\n","/**\r\n * @file NoteEditor.tsx\r\n * @description 帳票エディタのメインコンポーネント(モード振り分け専用)\r\n * - modeに応じてNoteForm/NoteEdit/NoteViewを振り分ける\r\n */\r\n\r\nimport { memo, useCallback } from \"react\";\r\n\r\nimport { NoteEdit } from \"./NoteEdit\";\r\nimport { NoteForm } from \"./NoteForm\";\r\nimport { NoteView } from \"./NoteView\";\r\n\r\nimport { NoteMode } from \"@/types/mode\";\r\n\r\nimport type { BlockPlugin } from \"@/plugin\";\r\nimport type { OnSchemaChange, OnValuesChange } from \"@/types/callbacks\";\r\nimport type { FormSchema } from \"@/types/schema\";\r\nimport type { Value } from \"@/types/value\";\r\n\r\nexport interface NoteEditorProps {\r\n\tschema: FormSchema;\r\n\tvalues: Record<string, Value>;\r\n\tmode: NoteMode;\r\n\tpluginRegistry: Record<string, BlockPlugin>;\r\n\tonSchemaChange?: OnSchemaChange;\r\n\tonValuesChange?: OnValuesChange;\r\n\tonSelectionChange?: (selectedBlockIds: string[]) => void;\r\n\tscale?: number;\r\n\tclassName?: string;\r\n}\r\n\r\nconst NoteEditorBase = ({\r\n\tschema,\r\n\tvalues,\r\n\tmode,\r\n\tpluginRegistry,\r\n\tonSchemaChange,\r\n\tonValuesChange,\r\n\tonSelectionChange,\r\n\tscale = 1.0,\r\n\tclassName,\r\n}: NoteEditorProps) => {\r\n\t// 値変更ハンドラ(Edit/Formモード用)\r\n\tconst handleValueChange = useCallback(\r\n\t\t(id: string, val: Value) => {\r\n\t\t\tif (!onValuesChange) return;\r\n\t\t\tif (val === undefined || val === null) {\r\n\t\t\t\tconst { [id]: _, ...rest } = values;\r\n\t\t\t\tonValuesChange(rest);\r\n\t\t\t} else {\r\n\t\t\t\tonValuesChange({ ...values, [id]: val });\r\n\t\t\t}\r\n\t\t},\r\n\t\t[values, onValuesChange],\r\n\t);\r\n\r\n\t// モード別にコンポーネントを振り分け\r\n\tif (mode === NoteMode.FORM) {\r\n\t\treturn (\r\n\t\t\t<NoteForm\r\n\t\t\t\tschema={schema}\r\n\t\t\t\tpluginRegistry={pluginRegistry}\r\n\t\t\t\tonSchemaChange={onSchemaChange}\r\n\t\t\t\tonSelectionChange={onSelectionChange}\r\n\t\t\t\tscale={scale}\r\n\t\t\t\tclassName={className}\r\n\t\t\t/>\r\n\t\t);\r\n\t}\r\n\r\n\tif (mode === NoteMode.EDIT) {\r\n\t\treturn (\r\n\t\t\t<NoteEdit\r\n\t\t\t\tschema={schema}\r\n\t\t\t\tvalues={values}\r\n\t\t\t\tpluginRegistry={pluginRegistry}\r\n\t\t\t\tonValueChange={handleValueChange}\r\n\t\t\t\tscale={scale}\r\n\t\t\t\tclassName={className}\r\n\t\t\t/>\r\n\t\t);\r\n\t}\r\n\r\n\t// mode === NoteMode.VIEW\r\n\treturn (\r\n\t\t<NoteView\r\n\t\t\tschema={schema}\r\n\t\t\tvalues={values}\r\n\t\t\tpluginRegistry={pluginRegistry}\r\n\t\t\tscale={scale}\r\n\t\t\tclassName={className}\r\n\t\t/>\r\n\t);\r\n};\r\n\r\nNoteEditorBase.displayName = \"NoteEditor\";\r\n\r\nexport const NoteEditor = memo(NoteEditorBase);\r\n","/**\r\n * @file PrintableNote.tsx\r\n * @description 印刷専用コンポーネント\r\n * - FormSchemaとvaluesを受け取り、BlockLayerのみをレンダリング\r\n * - 余計な装飾(box-shadow, transformなど)なし\r\n * - FormSchema.paperから直接サイズとマージンを取得\r\n * - refを通じてprint()メソッドを提供\r\n */\r\n\r\nimport {\r\n\ttype ForwardedRef,\r\n\tforwardRef,\r\n\tmemo,\r\n\tuseEffect,\r\n\tuseImperativeHandle,\r\n\tuseRef,\r\n} from \"react\";\r\n\r\nimport { BlockLayer } from \"./BlockLayer\";\r\n\r\nimport { DEFAULT_DPI } from \"@/constants\";\r\nimport { useGridCalc } from \"@/hooks/useGridCalc\";\r\nimport { NoteMode } from \"@/types/mode\";\r\nimport { toMm } from \"@/utils/convert\";\r\nimport { printElement } from \"@/utils/print\";\r\n\r\nimport type { BlockPlugin } from \"@/plugin\";\r\nimport type { NoteViewPrintRef } from \"@/types/print\";\r\nimport type { FormSchema } from \"@/types/schema\";\r\nimport type { Value } from \"@/types/value\";\r\n\r\nexport interface NotePrintProps {\r\n\tschema: FormSchema;\r\n\tvalues?: Record<string, Value>;\r\n\tpluginRegistry: Record<string, BlockPlugin>;\r\n\tclassName?: string;\r\n}\r\n\r\nconst NotePrintBase = (\r\n\t{ schema, values, pluginRegistry, className }: NotePrintProps,\r\n\tref: ForwardedRef<NoteViewPrintRef>,\r\n) => {\r\n\tconst containerRef = useRef<HTMLDivElement>(null);\r\n\tconst { paperPx, getBlockRectPx } = useGridCalc(\r\n\t\tschema.paper,\r\n\t\tschema.grid,\r\n\t\tDEFAULT_DPI,\r\n\t);\r\n\r\n\t// FormSchema.paperから用紙サイズを取得し、@pageルールを設定\r\n\t// 注意: @pageのmarginは0に設定し、要素側でマージンを表現する\r\n\t// 理由: @pageのmarginを設定すると、position:absoluteの座標原点がマージン後の領域になるため\r\n\tuseEffect(() => {\r\n\t\tconst { size } = schema.paper;\r\n\r\n\t\t// 用紙サイズをmm単位に変換\r\n\t\tconst widthMm = toMm.fromDim(size.width);\r\n\t\tconst heightMm = toMm.fromDim(size.height);\r\n\r\n\t\t// 既存のstyle要素を削除\r\n\t\tconst existingStyle = document.getElementById(\"printable-note-page-style\");\r\n\t\tif (existingStyle) {\r\n\t\t\texistingStyle.remove();\r\n\t\t}\r\n\r\n\t\t// 新しいstyle要素を作成\r\n\t\tconst style = document.createElement(\"style\");\r\n\t\tstyle.id = \"printable-note-page-style\";\r\n\t\tstyle.textContent = `\r\n\t\t\t@media print {\r\n\t\t\t\t@page {\r\n\t\t\t\t\tsize: ${widthMm}mm ${heightMm}mm;\r\n\t\t\t\t\tmargin: 0;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t`;\r\n\r\n\t\tdocument.head.appendChild(style);\r\n\r\n\t\treturn () => {\r\n\t\t\t// クリーンアップ\r\n\t\t\tconst styleElement = document.getElementById(\"printable-note-page-style\");\r\n\t\t\tif (styleElement) {\r\n\t\t\t\tstyleElement.remove();\r\n\t\t\t}\r\n\t\t};\r\n\t}, [schema.paper]);\r\n\r\n\t// 印刷メソッドをrefに公開\r\n\tuseImperativeHandle(\r\n\t\tref,\r\n\t\t() => ({\r\n\t\t\tprint: () => {\r\n\t\t\t\tif (!containerRef.current) return;\r\n\t\t\t\tprintElement(containerRef.current, {\r\n\t\t\t\t\ttitle: \"Document\",\r\n\t\t\t\t});\r\n\t\t\t},\r\n\t\t\topenPrintPreview: () => {\r\n\t\t\t\tif (!containerRef.current) return;\r\n\t\t\t\tprintElement(containerRef.current, {\r\n\t\t\t\t\ttitle: \"Document\",\r\n\t\t\t\t});\r\n\t\t\t},\r\n\t\t}),\r\n\t\t[],\r\n\t);\r\n\r\n\treturn (\r\n\t\t<div\r\n\t\t\tref={containerRef}\r\n\t\t\tclassName={className}\r\n\t\t\tstyle={{\r\n\t\t\t\twidth: `${paperPx.canvas.width}px`,\r\n\t\t\t\theight: `${paperPx.canvas.height}px`,\r\n\t\t\t\tbackgroundColor: \"#fff\",\r\n\t\t\t\tpaddingTop: `${paperPx.margin.top}px`,\r\n\t\t\t\tpaddingLeft: `${paperPx.margin.left}px`,\r\n\t\t\t\tpaddingRight: `${paperPx.margin.right}px`,\r\n\t\t\t\tpaddingBottom: `${paperPx.margin.bottom}px`,\r\n\t\t\t\tboxSizing: \"border-box\",\r\n\t\t\t}}\r\n\t\t>\r\n\t\t\t{/* コンテンツ領域 */}\r\n\t\t\t<div\r\n\t\t\t\tstyle={{\r\n\t\t\t\t\tposition: \"relative\",\r\n\t\t\t\t\twidth: `${paperPx.content.width}px`,\r\n\t\t\t\t\theight: `${paperPx.content.height}px`,\r\n\t\t\t\t}}\r\n\t\t\t>\r\n\t\t\t\t<BlockLayer\r\n\t\t\t\t\tblocks={schema.blocks}\r\n\t\t\t\t\tpluginRegistry={pluginRegistry}\r\n\t\t\t\t\tmode={NoteMode.VIEW}\r\n\t\t\t\t\tvalues={values ?? {}}\r\n\t\t\t\t\tgetBlockRectPx={getBlockRectPx}\r\n\t\t\t\t\tshowGuides={false}\r\n\t\t\t\t\tshowBorder={true}\r\n\t\t\t\t/>\r\n\t\t\t</div>\r\n\t\t</div>\r\n\t);\r\n};\r\n\r\nNotePrintBase.displayName = \"NotePrint\";\r\n\r\nexport const NotePrint = memo(forwardRef(NotePrintBase));\r\n","// src/properties/utils/getCommonValue.ts\r\nimport type { Block, Value } from \"@/types\";\r\n\r\n/**\r\n * 選択中のブロックから共通の値を取得する\r\n * 値がバラバラの場合は undefined を返す\r\n *\r\n * @param blocks 選択中のブロック配列\r\n * @param path プロパティへのパス (例: \"props.text\", \"layout.x\", \"style.backgroundColor\")\r\n * @returns 全ブロックで共通の値、または値が異なる場合は undefined\r\n *\r\n * @example\r\n * ```ts\r\n * // propsの値を取得\r\n * const textValue = getCommonValue(blocks, \"props.text\");\r\n *\r\n * // layoutの値を取得\r\n * const xPos = getCommonValue<number>(blocks, \"layout.x\");\r\n *\r\n * // styleの値を取得\r\n * const bgColor = getCommonValue(blocks, \"style.backgroundColor\");\r\n * ```\r\n */\r\nexport function getCommonValue<T = Value>(\r\n\tblocks: Block[],\r\n\tpath: string,\r\n): T | undefined {\r\n\tif (blocks.length === 0) return undefined;\r\n\r\n\t// パスから値を取得するヘルパー関数\r\n\tconst getValueByPath = (obj: unknown, keys: string[]): unknown => {\r\n\t\tlet current: unknown = obj;\r\n\r\n\t\tfor (const key of keys) {\r\n\t\t\tif (current == null) return undefined;\r\n\t\t\tif (typeof current !== \"object\" || Array.isArray(current))\r\n\t\t\t\treturn undefined;\r\n\r\n\t\t\tcurrent = (current as Record<string, unknown>)[key];\r\n\t\t}\r\n\r\n\t\treturn current;\r\n\t};\r\n\r\n\tconst keys = path.split(\".\");\r\n\r\n\t// 最初のブロックの値を取得\r\n\tconst firstValue = getValueByPath(blocks[0], keys);\r\n\r\n\t// 全てのブロックが同じ値を持つか確認\r\n\tconst allSame = blocks.every((block) => {\r\n\t\tconst value = getValueByPath(block, keys);\r\n\t\t// 厳密等価性でチェック(オブジェクトや配列は参照比較)\r\n\t\treturn value === firstValue;\r\n\t});\r\n\r\n\treturn allSame ? (firstValue as T) : undefined;\r\n}\r\n","import { ColorPicker } from \"../../../components\";\r\nimport { getCommonValue } from \"../../../utils/getCommonValue\";\r\nimport styles from \"./BackgroundPanel.module.css\";\r\n\r\nimport type React from \"react\";\r\nimport type { Block } from \"@/types\";\r\n\r\nexport interface BackgroundPanelProps {\r\n\tselectedBlocks: Block[];\r\n\tonUpdateBlocks: (updates: Record<string, Partial<Block>>) => void;\r\n}\r\n\r\nexport const BackgroundPanel: React.FC<BackgroundPanelProps> = ({\r\n\tselectedBlocks,\r\n\tonUpdateBlocks,\r\n}) => {\r\n\tif (selectedBlocks.length === 0) return null;\r\n\r\n\tconst handleChange = (color: string | undefined) => {\r\n\t\tconst updates: Record<string, Partial<Block>> = {};\r\n\t\tselectedBlocks.forEach((b) => {\r\n\t\t\tupdates[b.id] = {\r\n\t\t\t\tstyle: {\r\n\t\t\t\t\t...b.style,\r\n\t\t\t\t\tbackgroundColor: color,\r\n\t\t\t\t},\r\n\t\t\t};\r\n\t\t});\r\n\t\tonUpdateBlocks(updates);\r\n\t};\r\n\r\n\treturn (\r\n\t\t<div className={styles.container}>\r\n\t\t\t<div className={styles.row}>\r\n\t\t\t\t<div className={styles.inputWrapper}>\r\n\t\t\t\t\t<ColorPicker\r\n\t\t\t\t\t\tvalue={getCommonValue(selectedBlocks, \"style.backgroundColor\")}\r\n\t\t\t\t\t\tonChange={handleChange}\r\n\t\t\t\t\t\tallowUndefined\r\n\t\t\t\t\t\tplaceholder=\"無色\"\r\n\t\t\t\t\t\theight={24}\r\n\t\t\t\t\t/>\r\n\t\t\t\t</div>\r\n\t\t\t</div>\r\n\t\t</div>\r\n\t);\r\n};\r\n","import { useMemo } from \"react\";\r\n\r\nimport { ColorPicker, DimensionInput, Select } from \"../../../components\";\r\nimport {\r\n\tTabs,\r\n\tTabsContent,\r\n\tTabsList,\r\n\tTabsTrigger,\r\n} from \"../../../components/Tabs\";\r\nimport { getCommonValue } from \"../../../utils/getCommonValue\";\r\n\r\nimport { BorderRenderer } from \"@/canvas/components/BorderRenderer\";\r\nimport { Border, LineType } from \"@/types/line\";\r\nimport { BORDER_UNITS } from \"@/types/unit\";\r\n\r\nimport type React from \"react\";\r\nimport type { Block, Value } from \"@/types\";\r\n\r\n/**\r\n * オブジェクトの特定パスの値を更新した新しいオブジェクトを返す (Immutable)\r\n * valueがundefinedまたはnullの場合、そのプロパティを削除する\r\n */\r\nfunction setNestedValue<T>(obj: T, path: string, value: Value): T {\r\n\tconst keys = path.split(\".\");\r\n\r\n\tconst update = (\r\n\t\tcurrent: Record<string, unknown>,\r\n\t\tdepth: number,\r\n\t): Record<string, unknown> => {\r\n\t\tconst key = keys[depth] as string;\r\n\t\tif (depth === keys.length - 1) {\r\n\t\t\t// 最後のキー: valueがundefined/nullの場合はプロパティを削除\r\n\t\t\tif (value === undefined || value === null) {\r\n\t\t\t\tconst { [key]: _, ...rest } = current;\r\n\t\t\t\treturn rest;\r\n\t\t\t}\r\n\t\t\treturn { ...current, [key]: value };\r\n\t\t}\r\n\t\tconst nextValue =\r\n\t\t\t(current?.[key] as Record<string, unknown> | undefined) || {};\r\n\t\tconst updated = update(nextValue, depth + 1);\r\n\r\n\t\t// 更新後のオブジェクトが空なら、このキーも削除\r\n\t\tif (Object.keys(updated).length === 0) {\r\n\t\t\tconst { [key]: _, ...rest } = current;\r\n\t\t\treturn rest;\r\n\t\t}\r\n\r\n\t\treturn {\r\n\t\t\t...current,\r\n\t\t\t[key]: updated,\r\n\t\t};\r\n\t};\r\n\r\n\treturn update(obj as Record<string, unknown>, 0) as T;\r\n}\r\n\r\nexport interface BorderPanelProps {\r\n\tselectedBlocks: Block[];\r\n\tonUpdateBlocks: (updates: Record<string, Partial<Block>>) => void;\r\n}\r\n\r\ntype BorderEdge = \"all\" | \"top\" | \"right\" | \"bottom\" | \"left\";\r\n\r\nexport const BorderPanel: React.FC<BorderPanelProps> = ({\r\n\tselectedBlocks,\r\n\tonUpdateBlocks,\r\n}) => {\r\n\t// --- ハンドラ ---\r\n\tconst handleChange = (\r\n\t\tedge: BorderEdge,\r\n\t\tprop: \"type\" | \"width\" | \"color\",\r\n\t\tval: Value,\r\n\t) => {\r\n\t\tconst updates: Record<string, Partial<Block>> = {};\r\n\r\n\t\tselectedBlocks.forEach((b) => {\r\n\t\t\tlet newStyle = setNestedValue(\r\n\t\t\t\tb.style || {},\r\n\t\t\t\t`border.${edge}.${prop}`,\r\n\t\t\t\tval,\r\n\t\t\t);\r\n\r\n\t\t\t// typeが「なし」(undefined)に設定された場合、widthとcolorも削除\r\n\t\t\tif (prop === \"type\" && (val === undefined || val === null)) {\r\n\t\t\t\tnewStyle = setNestedValue(newStyle, `border.${edge}.width`, undefined);\r\n\t\t\t\tnewStyle = setNestedValue(newStyle, `border.${edge}.color`, undefined);\r\n\t\t\t}\r\n\r\n\t\t\t// typeやcolorが設定された場合(なし以外)、widthとcolorが未設定ならデフォルト値を設定\r\n\t\t\tif (prop === \"type\" && val !== undefined && val !== null) {\r\n\t\t\t\tconst currentBorder = (b.style as { border?: Record<string, unknown> })\r\n\t\t\t\t\t?.border as\r\n\t\t\t\t\t| Record<string, { width?: unknown; color?: unknown }>\r\n\t\t\t\t\t| undefined;\r\n\t\t\t\tconst edgeStyle = currentBorder?.[edge];\r\n\r\n\t\t\t\t// widthが未設定なら1pxをデフォルト設定\r\n\t\t\t\tif (!edgeStyle?.width) {\r\n\t\t\t\t\tnewStyle = setNestedValue(newStyle, `border.${edge}.width`, {\r\n\t\t\t\t\t\tvalue: 1,\r\n\t\t\t\t\t\tunit: \"px\",\r\n\t\t\t\t\t});\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// colorが未設定なら#000000をデフォルト設定\r\n\t\t\t\tif (!edgeStyle?.color) {\r\n\t\t\t\t\tnewStyle = setNestedValue(\r\n\t\t\t\t\t\tnewStyle,\r\n\t\t\t\t\t\t`border.${edge}.color`,\r\n\t\t\t\t\t\t\"#000000\",\r\n\t\t\t\t\t);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t// colorが設定された場合、typeとwidthが未設定ならデフォルト値を設定\r\n\t\t\tif (prop === \"color\" && val !== undefined && val !== null) {\r\n\t\t\t\tconst currentBorder = (b.style as { border?: Record<string, unknown> })\r\n\t\t\t\t\t?.border as\r\n\t\t\t\t\t| Record<string, { type?: unknown; width?: unknown }>\r\n\t\t\t\t\t| undefined;\r\n\t\t\t\tconst edgeStyle = currentBorder?.[edge];\r\n\r\n\t\t\t\t// typeが未設定ならsolidをデフォルト設定\r\n\t\t\t\tif (!edgeStyle?.type) {\r\n\t\t\t\t\tnewStyle = setNestedValue(\r\n\t\t\t\t\t\tnewStyle,\r\n\t\t\t\t\t\t`border.${edge}.type`,\r\n\t\t\t\t\t\tLineType.SOLID,\r\n\t\t\t\t\t);\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// widthが未設定なら1pxをデフォルト設定\r\n\t\t\t\tif (!edgeStyle?.width) {\r\n\t\t\t\t\tnewStyle = setNestedValue(newStyle, `border.${edge}.width`, {\r\n\t\t\t\t\t\tvalue: 1,\r\n\t\t\t\t\t\tunit: \"px\",\r\n\t\t\t\t\t});\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t// widthが設定された場合、typeとcolorが未設定ならデフォルト値を設定\r\n\t\t\tif (prop === \"width\" && val !== undefined && val !== null) {\r\n\t\t\t\tconst currentBorder = (b.style as { border?: Record<string, unknown> })\r\n\t\t\t\t\t?.border as\r\n\t\t\t\t\t| Record<string, { type?: unknown; color?: unknown }>\r\n\t\t\t\t\t| undefined;\r\n\t\t\t\tconst edgeStyle = currentBorder?.[edge];\r\n\r\n\t\t\t\t// typeが未設定ならsolidをデフォルト設定\r\n\t\t\t\tif (!edgeStyle?.type) {\r\n\t\t\t\t\tnewStyle = setNestedValue(\r\n\t\t\t\t\t\tnewStyle,\r\n\t\t\t\t\t\t`border.${edge}.type`,\r\n\t\t\t\t\t\tLineType.SOLID,\r\n\t\t\t\t\t);\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// colorが未設定なら#000000をデフォルト設定\r\n\t\t\t\tif (!edgeStyle?.color) {\r\n\t\t\t\t\tnewStyle = setNestedValue(\r\n\t\t\t\t\t\tnewStyle,\r\n\t\t\t\t\t\t`border.${edge}.color`,\r\n\t\t\t\t\t\t\"#000000\",\r\n\t\t\t\t\t);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tupdates[b.id] = { style: newStyle };\r\n\t\t});\r\n\r\n\t\tonUpdateBlocks(updates);\r\n\t};\r\n\r\n\t// --- プレビュー用 ---\r\n\tconst previewBorder = useMemo(() => {\r\n\t\tif (selectedBlocks.length !== 1) return null;\r\n\t\tconst firstBlock = selectedBlocks[0];\r\n\t\tif (!firstBlock?.style?.border) return null;\r\n\r\n\t\tconst borderStyle = firstBlock.style.border;\r\n\t\tif (!borderStyle) return null;\r\n\r\n\t\tconst validateEdge = (edge?: { type?: unknown; width?: unknown }) => {\r\n\t\t\tif (!edge) return true;\r\n\t\t\tif (edge.type && !edge.width) return false;\r\n\t\t\treturn true;\r\n\t\t};\r\n\r\n\t\tconst edges = [\"all\", \"top\", \"right\", \"bottom\", \"left\"] as const;\r\n\t\tif (\r\n\t\t\t!edges.every((e) =>\r\n\t\t\t\tvalidateEdge(\r\n\t\t\t\t\tborderStyle[e] as { type?: unknown; width?: unknown } | undefined,\r\n\t\t\t\t),\r\n\t\t\t)\r\n\t\t) {\r\n\t\t\treturn null;\r\n\t\t}\r\n\r\n\t\treturn new Border(borderStyle);\r\n\t}, [selectedBlocks]);\r\n\r\n\t// --- 入力フォーム ---\r\n\tconst renderInputs = (edge: BorderEdge) => (\r\n\t\t<div\r\n\t\t\tstyle={{\r\n\t\t\t\tdisplay: \"flex\",\r\n\t\t\t\tflexDirection: \"column\",\r\n\t\t\t\tgap: \"4px\",\r\n\t\t\t}}\r\n\t\t>\r\n\t\t\t<Select\r\n\t\t\t\tvalue={getCommonValue(selectedBlocks, `style.border.${edge}.type`)}\r\n\t\t\t\tonChange={(val) => handleChange(edge, \"type\", val)}\r\n\t\t\t\tplaceholder=\"スタイル\"\r\n\t\t\t\theight={24}\r\n\t\t\t\toptions={[\r\n\t\t\t\t\t{ label: \"\", value: undefined },\r\n\t\t\t\t\t{ label: \"実線\", value: LineType.SOLID },\r\n\t\t\t\t\t{ label: \"破線\", value: LineType.DASHED },\r\n\t\t\t\t\t{ label: \"点線\", value: LineType.DOTTED },\r\n\t\t\t\t]}\r\n\t\t\t/>\r\n\r\n\t\t\t<DimensionInput\r\n\t\t\t\tvalue={\r\n\t\t\t\t\tgetCommonValue(\r\n\t\t\t\t\t\tselectedBlocks,\r\n\t\t\t\t\t\t`style.border.${edge}.width`,\r\n\t\t\t\t\t) as (typeof BORDER_UNITS)[number] extends infer U extends string\r\n\t\t\t\t\t\t? { value: number; unit: U } | undefined\r\n\t\t\t\t\t\t: never\r\n\t\t\t\t}\r\n\t\t\t\tonChange={(val) => handleChange(edge, \"width\", val as Value)}\r\n\t\t\t\tplaceholder=\"太さ\"\r\n\t\t\t\theight={24}\r\n\t\t\t\tallowedUnits={BORDER_UNITS}\r\n\t\t\t\tmin={1}\r\n\t\t\t/>\r\n\r\n\t\t\t<ColorPicker\r\n\t\t\t\tvalue={getCommonValue(selectedBlocks, `style.border.${edge}.color`)}\r\n\t\t\t\tonChange={(val) => handleChange(edge, \"color\", val)}\r\n\t\t\t\tplaceholder=\"色\"\r\n\t\t\t\theight={24}\r\n\t\t\t\tallowUndefined\r\n\t\t\t/>\r\n\t\t</div>\r\n\t);\r\n\r\n\t// タブの共通スタイル\r\n\tconst triggerStyle: React.CSSProperties = {\r\n\t\tflex: 1, // 均等割付\r\n\t\tpadding: \"0 2px\", // 左右パディングを詰める\r\n\t\tfontSize: \"12px\",\r\n\t\tminWidth: 0, // Flexアイテムの縮小許可\r\n\t\twhiteSpace: \"nowrap\", // 折り返し禁止\r\n\t\toverflow: \"hidden\", // はみ出し非表示\r\n\t\ttextOverflow: \"ellipsis\", // 省略記号\r\n\t};\r\n\r\n\treturn (\r\n\t\t<div\r\n\t\t\tstyle={{\r\n\t\t\t\tdisplay: \"flex\",\r\n\t\t\t\tflexDirection: \"row\",\r\n\t\t\t\tpadding: \"4px\",\r\n\t\t\t\talignItems: \"stretch\",\r\n\t\t\t}}\r\n\t\t>\r\n\t\t\t{/* --- 左側: プレビュー (30%) --- */}\r\n\t\t\t<div\r\n\t\t\t\tstyle={{\r\n\t\t\t\t\tflex: \"0 0 30%\",\r\n\t\t\t\t\tdisplay: \"flex\",\r\n\t\t\t\t\tflexDirection: \"column\",\r\n\t\t\t\t\talignItems: \"center\",\r\n\t\t\t\t\tjustifyContent: \"center\",\r\n\t\t\t\t}}\r\n\t\t\t>\r\n\t\t\t\t<div\r\n\t\t\t\t\tstyle={{\r\n\t\t\t\t\t\twidth: \"80px\",\r\n\t\t\t\t\t\theight: \"80px\",\r\n\t\t\t\t\t\tbackgroundColor: \"transparent\",\r\n\t\t\t\t\t\tborder: \"transparent\",\r\n\t\t\t\t\t\tborderRadius: \"0.25rem\",\r\n\t\t\t\t\t\tdisplay: \"flex\",\r\n\t\t\t\t\t\talignItems: \"center\",\r\n\t\t\t\t\t\tjustifyContent: \"center\",\r\n\t\t\t\t\t\tposition: \"relative\",\r\n\t\t\t\t\t}}\r\n\t\t\t\t>\r\n\t\t\t\t\t{/* 十字線(常に表示) */}\r\n\t\t\t\t\t<svg\r\n\t\t\t\t\t\twidth=\"80\"\r\n\t\t\t\t\t\theight=\"80\"\r\n\t\t\t\t\t\tviewBox=\"0 0 80 80\"\r\n\t\t\t\t\t\tstyle={{\r\n\t\t\t\t\t\t\tposition: \"absolute\",\r\n\t\t\t\t\t\t\ttop: 0,\r\n\t\t\t\t\t\t\tleft: 0,\r\n\t\t\t\t\t\t\topacity: 0.3,\r\n\t\t\t\t\t\t\tpointerEvents: \"none\",\r\n\t\t\t\t\t\t}}\r\n\t\t\t\t\t>\r\n\t\t\t\t\t\t<title>枠線ガイド</title>\r\n\t\t\t\t\t\t{/* 十字の縦線 */}\r\n\t\t\t\t\t\t<line\r\n\t\t\t\t\t\t\tx1=\"40\"\r\n\t\t\t\t\t\t\ty1=\"0\"\r\n\t\t\t\t\t\t\tx2=\"40\"\r\n\t\t\t\t\t\t\ty2=\"80\"\r\n\t\t\t\t\t\t\tstroke=\"#9ca3af\"\r\n\t\t\t\t\t\t\tstrokeWidth=\"1\"\r\n\t\t\t\t\t\t\tstrokeDasharray=\"4 2\"\r\n\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t{/* 十字の横線 */}\r\n\t\t\t\t\t\t<line\r\n\t\t\t\t\t\t\tx1=\"0\"\r\n\t\t\t\t\t\t\ty1=\"40\"\r\n\t\t\t\t\t\t\tx2=\"80\"\r\n\t\t\t\t\t\t\ty2=\"40\"\r\n\t\t\t\t\t\t\tstroke=\"#9ca3af\"\r\n\t\t\t\t\t\t\tstrokeWidth=\"1\"\r\n\t\t\t\t\t\t\tstrokeDasharray=\"4 2\"\r\n\t\t\t\t\t\t/>\r\n\t\t\t\t\t</svg>\r\n\r\n\t\t\t\t\t{/* 枠線プレビューまたは未設定の四角 */}\r\n\t\t\t\t\t{previewBorder ? (\r\n\t\t\t\t\t\t<div\r\n\t\t\t\t\t\t\tstyle={{\r\n\t\t\t\t\t\t\t\tposition: \"absolute\",\r\n\t\t\t\t\t\t\t\ttop: 0,\r\n\t\t\t\t\t\t\t\tleft: 0,\r\n\t\t\t\t\t\t\t\twidth: \"80px\",\r\n\t\t\t\t\t\t\t\theight: \"80px\",\r\n\t\t\t\t\t\t\t\tpointerEvents: \"none\",\r\n\t\t\t\t\t\t\t}}\r\n\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t<BorderRenderer width={80} height={80} border={previewBorder} />\r\n\t\t\t\t\t\t</div>\r\n\t\t\t\t\t) : (\r\n\t\t\t\t\t\t<svg\r\n\t\t\t\t\t\t\twidth=\"80\"\r\n\t\t\t\t\t\t\theight=\"80\"\r\n\t\t\t\t\t\t\tviewBox=\"0 0 80 80\"\r\n\t\t\t\t\t\t\tstyle={{\r\n\t\t\t\t\t\t\t\tposition: \"absolute\",\r\n\t\t\t\t\t\t\t\ttop: 0,\r\n\t\t\t\t\t\t\t\tleft: 0,\r\n\t\t\t\t\t\t\t\topacity: 0.3,\r\n\t\t\t\t\t\t\t}}\r\n\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t<title>枠線未設定</title>\r\n\t\t\t\t\t\t\t{/* 点線の四角 */}\r\n\t\t\t\t\t\t\t<rect\r\n\t\t\t\t\t\t\t\tx=\"0\"\r\n\t\t\t\t\t\t\t\ty=\"0\"\r\n\t\t\t\t\t\t\t\twidth=\"80\"\r\n\t\t\t\t\t\t\t\theight=\"80\"\r\n\t\t\t\t\t\t\t\tfill=\"none\"\r\n\t\t\t\t\t\t\t\tstroke=\"#9ca3af\"\r\n\t\t\t\t\t\t\t\tstrokeWidth=\"1\"\r\n\t\t\t\t\t\t\t\tstrokeDasharray=\"4 2\"\r\n\t\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t</svg>\r\n\t\t\t\t\t)}\r\n\t\t\t\t</div>\r\n\t\t\t</div>\r\n\r\n\t\t\t{/* --- 右側: 設定項目 (70%) --- */}\r\n\t\t\t<div\r\n\t\t\t\tstyle={{\r\n\t\t\t\t\tflex: \"0 0 70%\",\r\n\t\t\t\t\tminWidth: 0,\r\n\t\t\t\t\tpadding: \"0 0 2px 0\",\r\n\t\t\t\t}}\r\n\t\t\t>\r\n\t\t\t\t<Tabs defaultValue=\"all\" variant=\"segmented\">\r\n\t\t\t\t\t{/* TabsList に width: 100% と display: flex を直接指定して強制的に横並びにする */}\r\n\t\t\t\t\t<div style={{ width: \"100%\" }}>\r\n\t\t\t\t\t\t<TabsList style={{ width: \"100%\", display: \"flex\" }}>\r\n\t\t\t\t\t\t\t<TabsTrigger value=\"all\" height={24} style={triggerStyle}>\r\n\t\t\t\t\t\t\t\t共通\r\n\t\t\t\t\t\t\t</TabsTrigger>\r\n\t\t\t\t\t\t\t<TabsTrigger value=\"top\" height={24} style={triggerStyle}>\r\n\t\t\t\t\t\t\t\t上\r\n\t\t\t\t\t\t\t</TabsTrigger>\r\n\t\t\t\t\t\t\t<TabsTrigger value=\"bottom\" height={24} style={triggerStyle}>\r\n\t\t\t\t\t\t\t\t下\r\n\t\t\t\t\t\t\t</TabsTrigger>\r\n\t\t\t\t\t\t\t<TabsTrigger value=\"left\" height={24} style={triggerStyle}>\r\n\t\t\t\t\t\t\t\t左\r\n\t\t\t\t\t\t\t</TabsTrigger>\r\n\t\t\t\t\t\t\t<TabsTrigger value=\"right\" height={24} style={triggerStyle}>\r\n\t\t\t\t\t\t\t\t右\r\n\t\t\t\t\t\t\t</TabsTrigger>\r\n\t\t\t\t\t\t</TabsList>\r\n\t\t\t\t\t</div>\r\n\r\n\t\t\t\t\t<div style={{ marginTop: \"4px\" }}>\r\n\t\t\t\t\t\t<TabsContent value=\"all\">{renderInputs(\"all\")}</TabsContent>\r\n\t\t\t\t\t\t<TabsContent value=\"top\">{renderInputs(\"top\")}</TabsContent>\r\n\t\t\t\t\t\t<TabsContent value=\"bottom\">{renderInputs(\"bottom\")}</TabsContent>\r\n\t\t\t\t\t\t<TabsContent value=\"left\">{renderInputs(\"left\")}</TabsContent>\r\n\t\t\t\t\t\t<TabsContent value=\"right\">{renderInputs(\"right\")}</TabsContent>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t</Tabs>\r\n\t\t\t</div>\r\n\t\t</div>\r\n\t);\r\n};\r\n","import { NumberInput } from \"../../../components\";\r\nimport { getCommonValue } from \"../../../utils/getCommonValue\";\r\nimport styles from \"./LayoutPanel.module.css\";\r\n\r\nimport type React from \"react\";\r\nimport type { Block } from \"@/types\";\r\n\r\nexport interface LayoutPanelProps {\r\n\tselectedBlocks: Block[];\r\n\tonUpdateBlocks: (updates: Record<string, Partial<Block>>) => void;\r\n\tgridSize?: { cols: number; rows: number };\r\n}\r\n\r\nexport const LayoutPanel: React.FC<LayoutPanelProps> = ({\r\n\tselectedBlocks,\r\n\tonUpdateBlocks,\r\n\tgridSize,\r\n}) => {\r\n\tif (selectedBlocks.length === 0) return null;\r\n\r\n\tconst isMultipleSelection = selectedBlocks.length > 1;\r\n\r\n\t// 複数選択時: 最も左上の座標を取得\r\n\tconst minX = isMultipleSelection\r\n\t\t? Math.min(...selectedBlocks.map((b) => b.layout.x))\r\n\t\t: undefined;\r\n\tconst minY = isMultipleSelection\r\n\t\t? Math.min(...selectedBlocks.map((b) => b.layout.y))\r\n\t\t: undefined;\r\n\r\n\tconst handleChange = (\r\n\t\tkey: \"x\" | \"y\" | \"w\" | \"h\",\r\n\t\tval: number | undefined,\r\n\t) => {\r\n\t\tif (val === undefined) return;\r\n\r\n\t\tconst updates: Record<string, Partial<Block>> = {};\r\n\r\n\t\tif (isMultipleSelection && (key === \"x\" || key === \"y\")) {\r\n\t\t\t// 複数選択時のX, Y変更: 相対位置を保持して全ブロックを移動\r\n\t\t\tconst currentMin = key === \"x\" ? minX : minY;\r\n\t\t\tif (currentMin === undefined) return;\r\n\r\n\t\t\t// バウンディングボックスを計算\r\n\t\t\tconst maxX = Math.max(\r\n\t\t\t\t...selectedBlocks.map((b) => b.layout.x + b.layout.w),\r\n\t\t\t);\r\n\t\t\tconst maxY = Math.max(\r\n\t\t\t\t...selectedBlocks.map((b) => b.layout.y + b.layout.h),\r\n\t\t\t);\r\n\t\t\tconst boundingW = maxX - (minX ?? 0);\r\n\t\t\tconst boundingH = maxY - (minY ?? 0);\r\n\r\n\t\t\t// 入力値をバウンディングボックスを考慮してクランプ\r\n\t\t\tlet clampedVal = val;\r\n\t\t\tif (key === \"x\" && gridSize) {\r\n\t\t\t\t// 最小値は0、最大値はcols - boundingW\r\n\t\t\t\tclampedVal = Math.max(0, Math.min(val, gridSize.cols - boundingW));\r\n\t\t\t} else if (key === \"y\" && gridSize) {\r\n\t\t\t\t// 最小値は0、最大値はrows - boundingH\r\n\t\t\t\tclampedVal = Math.max(0, Math.min(val, gridSize.rows - boundingH));\r\n\t\t\t} else {\r\n\t\t\t\tclampedVal = Math.max(0, val);\r\n\t\t\t}\r\n\r\n\t\t\t// クランプ後のオフセットを計算\r\n\t\t\tconst offset = clampedVal - currentMin;\r\n\r\n\t\t\t// 全ブロックに同じオフセットを適用(相対位置を保持)\r\n\t\t\tselectedBlocks.forEach((b) => {\r\n\t\t\t\tconst newValue = b.layout[key] + offset;\r\n\t\t\t\tupdates[b.id] = {\r\n\t\t\t\t\tlayout: { ...b.layout, [key]: newValue },\r\n\t\t\t\t};\r\n\t\t\t});\r\n\t\t} else {\r\n\t\t\t// 単一選択時 または W, H変更時\r\n\t\t\tselectedBlocks.forEach((b) => {\r\n\t\t\t\tlet clampedVal = val;\r\n\r\n\t\t\t\t// クランプ処理(ブロックサイズを考慮)\r\n\t\t\t\tif (key === \"x\" && gridSize) {\r\n\t\t\t\t\t// X座標: 0 ~ (cols - w)\r\n\t\t\t\t\tclampedVal = Math.max(0, Math.min(val, gridSize.cols - b.layout.w));\r\n\t\t\t\t} else if (key === \"y\" && gridSize) {\r\n\t\t\t\t\t// Y座標: 0 ~ (rows - h)\r\n\t\t\t\t\tclampedVal = Math.max(0, Math.min(val, gridSize.rows - b.layout.h));\r\n\t\t\t\t} else if (key === \"w\" && gridSize) {\r\n\t\t\t\t\t// 幅: 1 ~ (cols - x)\r\n\t\t\t\t\tconst maxW = gridSize.cols - b.layout.x;\r\n\t\t\t\t\tclampedVal = Math.max(1, Math.min(val, maxW));\r\n\t\t\t\t} else if (key === \"h\" && gridSize) {\r\n\t\t\t\t\t// 高さ: 1 ~ (rows - y)\r\n\t\t\t\t\tconst maxH = gridSize.rows - b.layout.y;\r\n\t\t\t\t\tclampedVal = Math.max(1, Math.min(val, maxH));\r\n\t\t\t\t} else if (key === \"w\" || key === \"h\") {\r\n\t\t\t\t\t// gridSizeがない場合は最小値1のみ\r\n\t\t\t\t\tclampedVal = Math.max(1, val);\r\n\t\t\t\t} else {\r\n\t\t\t\t\t// x, yでgridSizeがない場合は0以上\r\n\t\t\t\t\tclampedVal = Math.max(0, val);\r\n\t\t\t\t}\r\n\r\n\t\t\t\tupdates[b.id] = {\r\n\t\t\t\t\tlayout: { ...b.layout, [key]: clampedVal },\r\n\t\t\t\t};\r\n\t\t\t});\r\n\t\t}\r\n\t\tonUpdateBlocks(updates);\r\n\t};\r\n\r\n\treturn (\r\n\t\t<div className={styles.container}>\r\n\t\t\t<div className={styles.grid}>\r\n\t\t\t\t{/* X (列) */}\r\n\t\t\t\t<div className={styles.field}>\r\n\t\t\t\t\t<span className={styles.label}>X</span>\r\n\t\t\t\t\t<div className={styles.inputWrapper}>\r\n\t\t\t\t\t\t<NumberInput\r\n\t\t\t\t\t\t\tvalue={\r\n\t\t\t\t\t\t\t\tisMultipleSelection\r\n\t\t\t\t\t\t\t\t\t? minX\r\n\t\t\t\t\t\t\t\t\t: getCommonValue(selectedBlocks, \"layout.x\")\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\tonChange={(v) => handleChange(\"x\", v)}\r\n\t\t\t\t\t\t\tmin={0}\r\n\t\t\t\t\t\t\tmax={gridSize ? gridSize.cols - 1 : undefined}\r\n\t\t\t\t\t\t\tinteger\r\n\t\t\t\t\t\t\theight={22}\r\n\t\t\t\t\t\t\tplaceholder=\"-\"\r\n\t\t\t\t\t\t/>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t</div>\r\n\r\n\t\t\t\t{/* Y (行) */}\r\n\t\t\t\t<div className={styles.field}>\r\n\t\t\t\t\t<span className={styles.label}>Y</span>\r\n\t\t\t\t\t<div className={styles.inputWrapper}>\r\n\t\t\t\t\t\t<NumberInput\r\n\t\t\t\t\t\t\tvalue={\r\n\t\t\t\t\t\t\t\tisMultipleSelection\r\n\t\t\t\t\t\t\t\t\t? minY\r\n\t\t\t\t\t\t\t\t\t: getCommonValue(selectedBlocks, \"layout.y\")\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\tonChange={(v) => handleChange(\"y\", v)}\r\n\t\t\t\t\t\t\tmin={0}\r\n\t\t\t\t\t\t\tmax={gridSize ? gridSize.rows - 1 : undefined}\r\n\t\t\t\t\t\t\tinteger\r\n\t\t\t\t\t\t\theight={22}\r\n\t\t\t\t\t\t\tplaceholder=\"-\"\r\n\t\t\t\t\t\t/>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t</div>\r\n\r\n\t\t\t\t{/* W (幅) - 複数選択時は非表示 */}\r\n\t\t\t\t{!isMultipleSelection && (\r\n\t\t\t\t\t<div className={styles.field}>\r\n\t\t\t\t\t\t<span className={styles.label}>W</span>\r\n\t\t\t\t\t\t<div className={styles.inputWrapper}>\r\n\t\t\t\t\t\t\t<NumberInput\r\n\t\t\t\t\t\t\t\tvalue={getCommonValue(selectedBlocks, \"layout.w\")}\r\n\t\t\t\t\t\t\t\tonChange={(v) => handleChange(\"w\", v)}\r\n\t\t\t\t\t\t\t\tmin={1}\r\n\t\t\t\t\t\t\t\tmax={gridSize?.cols}\r\n\t\t\t\t\t\t\t\tinteger\r\n\t\t\t\t\t\t\t\theight={22}\r\n\t\t\t\t\t\t\t\tplaceholder=\"-\"\r\n\t\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t</div>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t)}\r\n\r\n\t\t\t\t{/* H (高さ) - 複数選択時は非表示 */}\r\n\t\t\t\t{!isMultipleSelection && (\r\n\t\t\t\t\t<div className={styles.field}>\r\n\t\t\t\t\t\t<span className={styles.label}>H</span>\r\n\t\t\t\t\t\t<div className={styles.inputWrapper}>\r\n\t\t\t\t\t\t\t<NumberInput\r\n\t\t\t\t\t\t\t\tvalue={getCommonValue(selectedBlocks, \"layout.h\")}\r\n\t\t\t\t\t\t\t\tonChange={(v) => handleChange(\"h\", v)}\r\n\t\t\t\t\t\t\t\tmin={1}\r\n\t\t\t\t\t\t\t\tmax={gridSize?.rows}\r\n\t\t\t\t\t\t\t\tinteger\r\n\t\t\t\t\t\t\t\theight={22}\r\n\t\t\t\t\t\t\t\tplaceholder=\"-\"\r\n\t\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t</div>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t)}\r\n\t\t\t</div>\r\n\t\t</div>\r\n\t);\r\n};\r\n","import { useEffect, useState } from \"react\";\r\n\r\nimport { Checkbox, TextInput } from \"../../../components\";\r\nimport { getCommonValue } from \"../../../utils/getCommonValue\";\r\nimport styles from \"./MetaPanel.module.css\";\r\n\r\nimport type React from \"react\";\r\nimport type { Block } from \"@/types\";\r\n\r\nexport interface MetaPanelProps {\r\n\tselectedBlocks: Block[];\r\n\tonUpdateBlocks: (updates: Record<string, Partial<Block>>) => void;\r\n}\r\n\r\nexport const MetaPanel: React.FC<MetaPanelProps> = ({\r\n\tselectedBlocks,\r\n\tonUpdateBlocks,\r\n}) => {\r\n\tconst [localId, setLocalId] = useState(\"\");\r\n\r\n\tconst primaryBlock = selectedBlocks[0];\r\n\r\n\tuseEffect(() => {\r\n\t\tif (selectedBlocks.length === 1 && primaryBlock) {\r\n\t\t\tsetLocalId(primaryBlock.id);\r\n\t\t}\r\n\t}, [selectedBlocks, primaryBlock]);\r\n\r\n\t// ID確定時の処理 (onBlur)\r\n\tconst handleIdBlur = () => {\r\n\t\tif (!primaryBlock) return;\r\n\r\n\t\tconst currentId = primaryBlock.id;\r\n\t\tconst newId = localId.trim();\r\n\r\n\t\t// 変更がない、または空の場合は元に戻す\r\n\t\tif (newId === currentId || !newId) {\r\n\t\t\tsetLocalId(currentId);\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// TODO: ここでIDの重複チェックを行うのが望ましい\r\n\t\t// 重複していなければ更新\r\n\t\tonUpdateBlocks({\r\n\t\t\t[currentId]: { id: newId },\r\n\t\t});\r\n\t};\r\n\r\n\t// --- ID onChange ---\r\n\tconst handleIdChange = (val: string | undefined) => {\r\n\t\tsetLocalId(val ?? \"\");\r\n\t};\r\n\r\n\t// --- ReadOnly ---\r\n\tconst handleReadOnlyChange = (val: boolean | undefined) => {\r\n\t\tconst updates: Record<string, Partial<Block>> = {};\r\n\t\tselectedBlocks.forEach((b) => {\r\n\t\t\tupdates[b.id] = {\r\n\t\t\t\tbehavior: { ...b.behavior, readOnly: !!val },\r\n\t\t\t};\r\n\t\t});\r\n\t\tonUpdateBlocks(updates);\r\n\t};\r\n\r\n\treturn (\r\n\t\t<div className={styles.container}>\r\n\t\t\t{/* ID */}\r\n\t\t\t{selectedBlocks.length === 1 && (\r\n\t\t\t\t<div className={styles.row}>\r\n\t\t\t\t\t<span className={styles.label}>ID</span>\r\n\t\t\t\t\t<div className={styles.inputWrapper}>\r\n\t\t\t\t\t\t<TextInput\r\n\t\t\t\t\t\t\tvalue={localId}\r\n\t\t\t\t\t\t\tonChange={handleIdChange}\r\n\t\t\t\t\t\t\tonBlur={handleIdBlur}\r\n\t\t\t\t\t\t\tplaceholder=\"IDを入力\"\r\n\t\t\t\t\t\t\theight={16} // 他のパネルと高さを統一\r\n\t\t\t\t\t\t/>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t</div>\r\n\t\t\t)}\r\n\r\n\t\t\t{/* 振る舞い (Behavior) */}\r\n\t\t\t{selectedBlocks.length > 0 && (\r\n\t\t\t\t<div className={styles.row}>\r\n\t\t\t\t\t<div className={styles.inputWrapper}>\r\n\t\t\t\t\t\t<Checkbox\r\n\t\t\t\t\t\t\tlabel=\"読み取り専用\"\r\n\t\t\t\t\t\t\tvalue={!!getCommonValue(selectedBlocks, \"behavior.readOnly\")}\r\n\t\t\t\t\t\t\tonChange={handleReadOnlyChange}\r\n\t\t\t\t\t\t/>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t</div>\r\n\t\t\t)}\r\n\t\t</div>\r\n\t);\r\n};\r\n","import { memo } from \"react\";\r\n\r\nimport { getCommonValue } from \"../../utils/getCommonValue\";\r\nimport styles from \"./PropertyField.module.css\";\r\n\r\nimport type { PropertyDefinition } from \"@/plugin\";\r\nimport type { Block, Value } from \"@/types\";\r\n\r\nexport interface PropertyFieldProps {\r\n\tpropertyKey: string;\r\n\tdefinition: PropertyDefinition<Value, Record<string, Value>>;\r\n\tselectedBlocks: Block[];\r\n\tonChange: (key: string, val: Value) => void;\r\n}\r\n\r\nexport const PropertyField = memo(\r\n\t({\r\n\t\tpropertyKey,\r\n\t\tdefinition,\r\n\t\tselectedBlocks,\r\n\t\tonChange,\r\n\t}: PropertyFieldProps) => {\r\n\t\tconst Component = definition.Component;\r\n\r\n\t\t// コンポーネントがない場合は何も描画しない\r\n\t\tif (!Component) return null;\r\n\r\n\t\t// 値の計算ロジック\r\n\t\tconst displayValue = getCommonValue(selectedBlocks, `props.${propertyKey}`);\r\n\t\tconst vals = selectedBlocks.map((b) => b.props[propertyKey]);\r\n\t\tconst allUndefined = vals.every((v) => v === undefined);\r\n\r\n\t\t// 混在判定: 全てがundefinedではなく、かつ共通値がundefinedの場合\r\n\t\tconst isMixed =\r\n\t\t\t!allUndefined && displayValue === undefined && selectedBlocks.length > 1;\r\n\r\n\t\t// コンポーネントに渡すPropsの構築\r\n\t\tconst componentProps = {\r\n\t\t\tvalue: isMixed\r\n\t\t\t\t? undefined\r\n\t\t\t\t: displayValue !== undefined\r\n\t\t\t\t\t? displayValue\r\n\t\t\t\t\t: definition.defaultValue,\r\n\t\t\tonChange: (val: Value) => onChange(propertyKey, val),\r\n\t\t\treadOnly: false,\r\n\t\t\tconfig: {\r\n\t\t\t\t...definition.config,\r\n\t\t\t\t// 混在時はプレースホルダーを上書きしてユーザーに知らせる\r\n\t\t\t\tplaceholder: isMixed\r\n\t\t\t\t\t? \"複数選択中 (値が異なります)\"\r\n\t\t\t\t\t: definition.config?.placeholder,\r\n\t\t\t},\r\n\t\t};\r\n\r\n\t\treturn (\r\n\t\t\t<div className={styles.field}>\r\n\t\t\t\t{definition.label && (\r\n\t\t\t\t\t<div className={styles.label} title={definition.description}>\r\n\t\t\t\t\t\t{definition.label}\r\n\t\t\t\t\t</div>\r\n\t\t\t\t)}\r\n\r\n\t\t\t\t{/* 入力コンポーネントの描画 */}\r\n\t\t\t\t<Component {...componentProps} />\r\n\r\n\t\t\t\t{isMixed && <span className={styles.mixed}>(混在)</span>}\r\n\r\n\t\t\t\t{definition.description && (\r\n\t\t\t\t\t<p className={styles.description}>{definition.description}</p>\r\n\t\t\t\t)}\r\n\t\t\t</div>\r\n\t\t);\r\n\t},\r\n);\r\n\r\nPropertyField.displayName = \"PropertyField\";\r\n","import { memo, useMemo } from \"react\";\r\n\r\nimport {\r\n\tBackgroundPanel,\r\n\tBorderPanel,\r\n\tLayoutPanel,\r\n\tMetaPanel,\r\n} from \"./BasePanels\";\r\nimport styles from \"./BlockPropertyPanel.module.css\";\r\nimport { PropertyField } from \"./PluginPanels/PropertyField\";\r\n\r\nimport type { BlockPlugin, PropertyConfig, PropertyDefinition } from \"@/plugin\";\r\nimport type { Block, Value } from \"@/types\";\r\n\r\nfunction isPropertyDefinition(\r\n\tconfig: PropertyConfig<Value, Record<string, Value>>,\r\n): config is PropertyDefinition<Value, Record<string, Value>> {\r\n\treturn config !== false;\r\n}\r\n\r\nexport interface BlockPropertyPanelProps {\r\n\tselectedBlocks: Block[];\r\n\tpluginRegistry: Record<string, BlockPlugin>;\r\n\tonUpdateBlocks: (updates: Record<string, Partial<Block>>) => void;\r\n\tgridSize?: { cols: number; rows: number };\r\n\tclassName?: string;\r\n}\r\n\r\n/**\r\n * PropertyPanel\r\n *\r\n * 選択されたブロックのプロパティを編集するための統合サイドバーコンポーネント。\r\n * BasePanels(共通設定)と PluginPanels(固有設定)を組み合わせて表示します。\r\n */\r\nexport const BlockPropertyPanel = memo(\r\n\t({\r\n\t\tselectedBlocks,\r\n\t\tpluginRegistry,\r\n\t\tonUpdateBlocks,\r\n\t\tgridSize,\r\n\t\tclassName = \"\",\r\n\t}: BlockPropertyPanelProps) => {\r\n\t\tconst primaryBlock = selectedBlocks[0];\r\n\t\tconst plugin = primaryBlock ? pluginRegistry[primaryBlock.kind] : undefined;\r\n\r\n\t\t// 選択されたブロックがすべて同じ種類(kind)かチェック\r\n\t\tconst allSameKind = useMemo(() => {\r\n\t\t\tif (selectedBlocks.length === 0) return false;\r\n\t\t\tconst firstKind = selectedBlocks[0]?.kind;\r\n\t\t\treturn selectedBlocks.every((block) => block.kind === firstKind);\r\n\t\t}, [selectedBlocks]);\r\n\r\n\t\t// プロパティ定義のグルーピング\r\n\t\tconst groupedProps = useMemo(() => {\r\n\t\t\tif (!primaryBlock || !plugin) return {};\r\n\r\n\t\t\tconst groups: Record<\r\n\t\t\t\tstring,\r\n\t\t\t\tArray<{\r\n\t\t\t\t\tkey: string;\r\n\t\t\t\t\tdefinition: PropertyDefinition<Value, Record<string, Value>> & {\r\n\t\t\t\t\t\tComponent: React.ComponentType<{\r\n\t\t\t\t\t\t\tvalue: Value;\r\n\t\t\t\t\t\t\tonChange: (value: Value) => void;\r\n\t\t\t\t\t\t}>;\r\n\t\t\t\t\t};\r\n\t\t\t\t}>\r\n\t\t\t> = {};\r\n\r\n\t\t\t// 異なる種類のブロックが混在している場合は、共通プロパティのみを表示\r\n\t\t\tlet propertiesToShow: [\r\n\t\t\t\tstring,\r\n\t\t\t\tPropertyConfig<Value, Record<string, Value>>,\r\n\t\t\t][];\r\n\r\n\t\t\tif (allSameKind) {\r\n\t\t\t\t// 同じ種類のブロックのみ: すべてのプロパティを表示\r\n\t\t\t\tpropertiesToShow = Object.entries(plugin.properties);\r\n\t\t\t} else {\r\n\t\t\t\t// 異なる種類のブロックが混在: 共通プロパティのみを表示\r\n\t\t\t\tconst allPlugins = selectedBlocks\r\n\t\t\t\t\t.map((block) => pluginRegistry[block.kind])\r\n\t\t\t\t\t.filter((p): p is BlockPlugin => p !== undefined);\r\n\r\n\t\t\t\tif (allPlugins.length === 0) return {};\r\n\r\n\t\t\t\t// すべてのプラグインで共通しているプロパティキーを抽出\r\n\t\t\t\tconst firstPlugin = allPlugins[0];\r\n\t\t\t\tif (!firstPlugin) return {};\r\n\r\n\t\t\t\tconst firstPluginKeys = new Set(Object.keys(firstPlugin.properties));\r\n\t\t\t\tconst commonKeys = Array.from(firstPluginKeys).filter((key) =>\r\n\t\t\t\t\tallPlugins.every((p) => key in p.properties),\r\n\t\t\t\t);\r\n\r\n\t\t\t\t// primaryBlockのプラグインから共通プロパティを取得\r\n\t\t\t\tpropertiesToShow = commonKeys\r\n\t\t\t\t\t.map(\r\n\t\t\t\t\t\t(\r\n\t\t\t\t\t\t\tkey,\r\n\t\t\t\t\t\t):\r\n\t\t\t\t\t\t\t| [string, PropertyConfig<Value, Record<string, Value>>]\r\n\t\t\t\t\t\t\t| null => {\r\n\t\t\t\t\t\t\tconst prop = plugin.properties[key];\r\n\t\t\t\t\t\t\treturn prop ? [key, prop] : null;\r\n\t\t\t\t\t\t},\r\n\t\t\t\t\t)\r\n\t\t\t\t\t.filter(\r\n\t\t\t\t\t\t(\r\n\t\t\t\t\t\t\tentry,\r\n\t\t\t\t\t\t): entry is [\r\n\t\t\t\t\t\t\tstring,\r\n\t\t\t\t\t\t\tPropertyConfig<Value, Record<string, Value>>,\r\n\t\t\t\t\t\t] => entry !== null,\r\n\t\t\t\t\t);\r\n\t\t\t}\r\n\r\n\t\t\tpropertiesToShow.forEach(([key, propertyConfig]) => {\r\n\t\t\t\t// 無効な定義を除外\r\n\t\t\t\tif (!isPropertyDefinition(propertyConfig)) return;\r\n\r\n\t\t\t\t// 複数選択時の制限チェック\r\n\t\t\t\tif (selectedBlocks.length > 1 && propertyConfig.disableInMultiSelection)\r\n\t\t\t\t\treturn;\r\n\r\n\t\t\t\t// 表示条件(condition)のチェック\r\n\t\t\t\tif (\r\n\t\t\t\t\tpropertyConfig.condition &&\r\n\t\t\t\t\t!propertyConfig.condition(primaryBlock.props)\r\n\t\t\t\t)\r\n\t\t\t\t\treturn;\r\n\r\n\t\t\t\t// グループ分け\r\n\t\t\t\tconst groupName = propertyConfig.group || \"基本\";\r\n\t\t\t\tif (!groups[groupName]) groups[groupName] = [];\r\n\t\t\t\t// Componentが存在しない場合はスキップ\r\n\t\t\t\tif (!propertyConfig.Component) return;\r\n\t\t\t\tgroups[groupName].push({\r\n\t\t\t\t\tkey,\r\n\t\t\t\t\tdefinition: propertyConfig as PropertyDefinition<\r\n\t\t\t\t\t\tValue,\r\n\t\t\t\t\t\tRecord<string, Value>\r\n\t\t\t\t\t> & {\r\n\t\t\t\t\t\tComponent: React.ComponentType<{\r\n\t\t\t\t\t\t\tvalue: Value;\r\n\t\t\t\t\t\t\tonChange: (value: Value) => void;\r\n\t\t\t\t\t\t}>;\r\n\t\t\t\t\t},\r\n\t\t\t\t});\r\n\t\t\t});\r\n\r\n\t\t\treturn groups;\r\n\t\t}, [plugin, pluginRegistry, selectedBlocks, primaryBlock, allSameKind]); // プラグインプロパティ変更ハンドラ\r\n\t\tconst handlePluginPropertyChange = (key: string, newValue: Value) => {\r\n\t\t\tconst updates: Record<string, Partial<Block>> = {};\r\n\t\t\tselectedBlocks.forEach((block) => {\r\n\t\t\t\tupdates[block.id] = {\r\n\t\t\t\t\tprops: {\r\n\t\t\t\t\t\t...block.props,\r\n\t\t\t\t\t\t[key]: newValue,\r\n\t\t\t\t\t},\r\n\t\t\t\t};\r\n\t\t\t});\r\n\t\t\tonUpdateBlocks(updates);\r\n\t\t};\r\n\r\n\t\t// ブロックが選択されていない場合\r\n\t\tif (selectedBlocks.length === 0) {\r\n\t\t\treturn (\r\n\t\t\t\t<div className={`${styles.container} ${className}`}>\r\n\t\t\t\t\t<div className={styles.emptyState}>\r\n\t\t\t\t\t\tブロックを選択すると\r\n\t\t\t\t\t\t<br />\r\n\t\t\t\t\t\tプロパティが表示されます\r\n\t\t\t\t\t</div>\r\n\t\t\t\t</div>\r\n\t\t\t);\r\n\t\t}\r\n\r\n\t\treturn (\r\n\t\t\t<div className={`${styles.container} ${className}`}>\r\n\t\t\t\t<div className={styles.scrollArea}>\r\n\t\t\t\t\t{/* 2. レイアウト (X, Y, W, H) */}\r\n\t\t\t\t\t<div className={styles.section}>\r\n\t\t\t\t\t\t<div className={styles.sectionTitle}>配置・サイズ</div>\r\n\t\t\t\t\t\t<LayoutPanel\r\n\t\t\t\t\t\t\tselectedBlocks={selectedBlocks}\r\n\t\t\t\t\t\t\tonUpdateBlocks={onUpdateBlocks}\r\n\t\t\t\t\t\t\tgridSize={gridSize}\r\n\t\t\t\t\t\t/>\r\n\t\t\t\t\t</div>\r\n\r\n\t\t\t\t\t{/* 4. スタイル (背景色) */}\r\n\t\t\t\t\t<div className={styles.section}>\r\n\t\t\t\t\t\t<div className={styles.sectionTitle}>背景</div>\r\n\t\t\t\t\t\t<BackgroundPanel\r\n\t\t\t\t\t\t\tselectedBlocks={selectedBlocks}\r\n\t\t\t\t\t\t\tonUpdateBlocks={onUpdateBlocks}\r\n\t\t\t\t\t\t/>\r\n\t\t\t\t\t</div>\r\n\r\n\t\t\t\t\t{/* 5. スタイル (枠線) */}\r\n\t\t\t\t\t<div className={styles.section}>\r\n\t\t\t\t\t\t<div className={styles.sectionTitle}>枠線</div>\r\n\t\t\t\t\t\t<BorderPanel\r\n\t\t\t\t\t\t\tselectedBlocks={selectedBlocks}\r\n\t\t\t\t\t\t\tonUpdateBlocks={onUpdateBlocks}\r\n\t\t\t\t\t\t/>\r\n\t\t\t\t\t</div>\r\n\r\n\t\t\t\t\t{/* 3. プラグイン固有プロパティ (TextPlugin等) */}\r\n\t\t\t\t\t{plugin && Object.keys(groupedProps).length > 0 && (\r\n\t\t\t\t\t\t<div className={styles.section}>\r\n\t\t\t\t\t\t\t{Object.entries(groupedProps).map(([groupName, items]) => (\r\n\t\t\t\t\t\t\t\t<div key={groupName} className={styles.subsection}>\r\n\t\t\t\t\t\t\t\t\t<div className={styles.subsectionTitle}>{groupName}</div>\r\n\t\t\t\t\t\t\t\t\t<div className={styles.fields}>\r\n\t\t\t\t\t\t\t\t\t\t{items.map(({ key, definition }) => (\r\n\t\t\t\t\t\t\t\t\t\t\t<PropertyField\r\n\t\t\t\t\t\t\t\t\t\t\t\tkey={key}\r\n\t\t\t\t\t\t\t\t\t\t\t\tpropertyKey={key}\r\n\t\t\t\t\t\t\t\t\t\t\t\tdefinition={definition}\r\n\t\t\t\t\t\t\t\t\t\t\t\tselectedBlocks={selectedBlocks}\r\n\t\t\t\t\t\t\t\t\t\t\t\tonChange={handlePluginPropertyChange}\r\n\t\t\t\t\t\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t\t\t\t\t))}\r\n\t\t\t\t\t\t\t\t\t</div>\r\n\t\t\t\t\t\t\t\t</div>\r\n\t\t\t\t\t\t\t))}\r\n\t\t\t\t\t\t</div>\r\n\t\t\t\t\t)}\r\n\r\n\t\t\t\t\t{/* 1. メタ情報 (ID, ReadOnly) */}\r\n\t\t\t\t\t<div className={styles.section}>\r\n\t\t\t\t\t\t<div className={styles.sectionTitle}>基本設定</div>\r\n\t\t\t\t\t\t<MetaPanel\r\n\t\t\t\t\t\t\tselectedBlocks={selectedBlocks}\r\n\t\t\t\t\t\t\tonUpdateBlocks={onUpdateBlocks}\r\n\t\t\t\t\t\t/>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t</div>\r\n\t\t\t</div>\r\n\t\t);\r\n\t},\r\n);\r\n\r\nBlockPropertyPanel.displayName = \"BlockPropertyPanel\";\r\n","import { useMemo } from \"react\";\r\n\r\nimport styles from \"./PluginPanels.module.css\";\r\nimport { PropertyField } from \"./PropertyField\";\r\n\r\nimport type { BlockPlugin, PropertyConfig, PropertyDefinition } from \"@/plugin\";\r\nimport type { Block, Value } from \"@/types\";\r\n\r\nexport interface PluginPanelsProps {\r\n\tselectedBlocks: Block[];\r\n\tpluginRegistry: Record<string, BlockPlugin>;\r\n\tonUpdateBlocks: (updates: Record<string, Partial<Block>>) => void;\r\n}\r\n\r\nfunction isPropertyDefinition(\r\n\tconfig: PropertyConfig<Value, Record<string, Value>>,\r\n): config is PropertyDefinition<Value, Record<string, Value>> {\r\n\treturn config !== false;\r\n}\r\n\r\nexport const PluginPanels: React.FC<PluginPanelsProps> = ({\r\n\tselectedBlocks,\r\n\tpluginRegistry,\r\n\tonUpdateBlocks,\r\n}) => {\r\n\tconst primaryBlock = selectedBlocks[0];\r\n\tconst plugin = primaryBlock ? pluginRegistry[primaryBlock.kind] : undefined;\r\n\r\n\t// プロパティ定義のグルーピング\r\n\tconst groupedProps = useMemo(() => {\r\n\t\tif (!primaryBlock || !plugin) return {};\r\n\t\tconst groups: Record<\r\n\t\t\tstring,\r\n\t\t\tArray<{\r\n\t\t\t\tkey: string;\r\n\t\t\t\tdefinition: PropertyDefinition<Value, Record<string, Value>> & {\r\n\t\t\t\t\tComponent: React.ComponentType<{\r\n\t\t\t\t\t\tvalue: Value;\r\n\t\t\t\t\t\tonChange: (value: Value) => void;\r\n\t\t\t\t\t}>;\r\n\t\t\t\t};\r\n\t\t\t}>\r\n\t\t> = {};\r\n\r\n\t\tObject.entries(plugin.properties).forEach(([key, propertyConfig]) => {\r\n\t\t\t// 無効な定義を除外\r\n\t\t\tif (!isPropertyDefinition(propertyConfig)) return;\r\n\r\n\t\t\t// 複数選択時の制限チェック\r\n\t\t\tif (selectedBlocks.length > 1 && propertyConfig.disableInMultiSelection)\r\n\t\t\t\treturn;\r\n\r\n\t\t\t// 表示条件(condition)のチェック\r\n\t\t\tif (\r\n\t\t\t\tpropertyConfig.condition &&\r\n\t\t\t\t!propertyConfig.condition(primaryBlock.props)\r\n\t\t\t)\r\n\t\t\t\treturn;\r\n\r\n\t\t\t// グループ分け\r\n\t\t\tconst groupName = propertyConfig.group || \"基本\";\r\n\t\t\tif (!groups[groupName]) groups[groupName] = [];\r\n\t\t\t// Componentが存在しない場合はスキップ\r\n\t\t\tif (!propertyConfig.Component) return;\r\n\t\t\tgroups[groupName].push({\r\n\t\t\t\tkey,\r\n\t\t\t\tdefinition: propertyConfig as PropertyDefinition<\r\n\t\t\t\t\tValue,\r\n\t\t\t\t\tRecord<string, Value>\r\n\t\t\t\t> & {\r\n\t\t\t\t\tComponent: React.ComponentType<{\r\n\t\t\t\t\t\tvalue: Value;\r\n\t\t\t\t\t\tonChange: (value: Value) => void;\r\n\t\t\t\t\t}>;\r\n\t\t\t\t},\r\n\t\t\t});\r\n\t\t});\r\n\r\n\t\treturn groups;\r\n\t}, [plugin, selectedBlocks.length, primaryBlock]);\r\n\r\n\t// ハンドラ\r\n\tconst handleChange = (key: string, newValue: Value) => {\r\n\t\tconst updates: Record<string, Partial<Block>> = {};\r\n\t\tselectedBlocks.forEach((block) => {\r\n\t\t\tupdates[block.id] = {\r\n\t\t\t\tprops: {\r\n\t\t\t\t\t...block.props,\r\n\t\t\t\t\t[key]: newValue,\r\n\t\t\t\t},\r\n\t\t\t};\r\n\t\t});\r\n\t\tonUpdateBlocks(updates);\r\n\t};\r\n\r\n\tif (!primaryBlock) return null;\r\n\tif (!plugin) return null;\r\n\tif (selectedBlocks.length === 0) return null;\r\n\r\n\treturn (\r\n\t\t<div className={styles.panel}>\r\n\t\t\t<div className={styles.header}>\r\n\t\t\t\t{selectedBlocks.length > 1\r\n\t\t\t\t\t? `${selectedBlocks.length}個のブロック`\r\n\t\t\t\t\t: plugin.meta.displayName}\r\n\t\t\t</div>\r\n\r\n\t\t\t{Object.entries(groupedProps).map(([groupName, items]) => (\r\n\t\t\t\t<div key={groupName} className={styles.group}>\r\n\t\t\t\t\t<div className={styles.groupTitle}>{groupName}</div>\r\n\t\t\t\t\t<div className={styles.groupContent}>\r\n\t\t\t\t\t\t{items.map(({ key, definition }) => (\r\n\t\t\t\t\t\t\t<PropertyField\r\n\t\t\t\t\t\t\t\tkey={key}\r\n\t\t\t\t\t\t\t\tpropertyKey={key}\r\n\t\t\t\t\t\t\t\tdefinition={definition}\r\n\t\t\t\t\t\t\t\tselectedBlocks={selectedBlocks}\r\n\t\t\t\t\t\t\t\tonChange={handleChange}\r\n\t\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t))}\r\n\t\t\t\t\t</div>\r\n\t\t\t\t</div>\r\n\t\t\t))}\r\n\t\t</div>\r\n\t);\r\n};\r\n","/**\r\n * @file BlockOrderPanel.tsx\r\n * @description ブロック配列順番変更パネル\r\n */\r\n\r\nimport { useCallback, useState } from \"react\";\r\n\r\nimport styles from \"./BlockOrderPanel.module.css\";\r\n\r\nimport type { Block } from \"@/types/block\";\r\n\r\nexport interface BlockOrderPanelProps {\r\n\t/** ブロック一覧 */\r\n\tblocks: Block[];\r\n\t/** ブロック更新時のコールバック (blocks配列全体を更新) */\r\n\tonBlocksChange: (blocks: Block[]) => void;\r\n}\r\n\r\n/**\r\n * BlockOrderPanel\r\n * ブロックの配列順序を変更するパネル\r\n * UIでは上が最前面、下が最背面(一般的なデザインソフトと同じ)\r\n * 内部配列では最後が最前面\r\n */\r\nexport const BlockOrderPanel = ({\r\n\tblocks,\r\n\tonBlocksChange,\r\n}: BlockOrderPanelProps) => {\r\n\t// ドラッグ中のブロックインデックス\r\n\tconst [draggedIndex, setDraggedIndex] = useState<number | null>(null);\r\n\tconst [dragOverIndex, setDragOverIndex] = useState<number | null>(null);\r\n\r\n\t// UIでは逆順で表示(上が最前面)\r\n\tconst displayBlocks = [...blocks].reverse();\r\n\r\n\t// 最前面へ移動(配列の最後に移動)\r\n\tconst handleBringToFront = useCallback(\r\n\t\t(blockId: string) => {\r\n\t\t\tconst index = blocks.findIndex((b) => b.id === blockId);\r\n\t\t\tif (index === -1 || index === blocks.length - 1) return;\r\n\r\n\t\t\tconst newBlocks = [...blocks];\r\n\t\t\tconst [block] = newBlocks.splice(index, 1);\r\n\t\t\tif (!block) return;\r\n\t\t\tnewBlocks.push(block);\r\n\t\t\tonBlocksChange(newBlocks);\r\n\t\t},\r\n\t\t[blocks, onBlocksChange],\r\n\t);\r\n\r\n\t// 最背面へ移動(配列の先頭に移動)\r\n\tconst handleSendToBack = useCallback(\r\n\t\t(blockId: string) => {\r\n\t\t\tconst index = blocks.findIndex((b) => b.id === blockId);\r\n\t\t\tif (index === -1 || index === 0) return;\r\n\r\n\t\t\tconst newBlocks = [...blocks];\r\n\t\t\tconst [block] = newBlocks.splice(index, 1);\r\n\t\t\tif (!block) return;\r\n\t\t\tnewBlocks.unshift(block);\r\n\t\t\tonBlocksChange(newBlocks);\r\n\t\t},\r\n\t\t[blocks, onBlocksChange],\r\n\t);\r\n\r\n\t// 前面へ移動(1つ後ろに移動)\r\n\tconst handleBringForward = useCallback(\r\n\t\t(blockId: string) => {\r\n\t\t\tconst index = blocks.findIndex((b) => b.id === blockId);\r\n\t\t\tif (index === -1 || index === blocks.length - 1) return;\r\n\r\n\t\t\tconst newBlocks = [...blocks];\r\n\t\t\tconst temp = newBlocks[index];\r\n\t\t\tconst next = newBlocks[index + 1];\r\n\t\t\tif (!temp || !next) return;\r\n\t\t\tnewBlocks[index] = next;\r\n\t\t\tnewBlocks[index + 1] = temp;\r\n\t\t\tonBlocksChange(newBlocks);\r\n\t\t},\r\n\t\t[blocks, onBlocksChange],\r\n\t);\r\n\r\n\t// 背面へ移動(1つ前に移動)\r\n\tconst handleSendBackward = useCallback(\r\n\t\t(blockId: string) => {\r\n\t\t\tconst index = blocks.findIndex((b) => b.id === blockId);\r\n\t\t\tif (index === -1 || index === 0) return;\r\n\r\n\t\t\tconst newBlocks = [...blocks];\r\n\t\t\tconst temp = newBlocks[index];\r\n\t\t\tconst prev = newBlocks[index - 1];\r\n\t\t\tif (!temp || !prev) return;\r\n\t\t\tnewBlocks[index] = prev;\r\n\t\t\tnewBlocks[index - 1] = temp;\r\n\t\t\tonBlocksChange(newBlocks);\r\n\t\t},\r\n\t\t[blocks, onBlocksChange],\r\n\t);\r\n\r\n\t// ドラッグ開始\r\n\tconst handleDragStart = useCallback(\r\n\t\t(e: React.DragEvent<HTMLElement>, displayIndex: number) => {\r\n\t\t\tsetDraggedIndex(displayIndex);\r\n\t\t\te.dataTransfer.effectAllowed = \"move\";\r\n\t\t\t// 実際のブロックインデックスを取得(逆順)\r\n\t\t\tconst actualIndex = blocks.length - 1 - displayIndex;\r\n\t\t\tif (e.currentTarget) {\r\n\t\t\t\te.dataTransfer.setData(\"text/plain\", blocks[actualIndex]?.id || \"\");\r\n\t\t\t}\r\n\t\t},\r\n\t\t[blocks],\r\n\t);\r\n\r\n\t// ドラッグ終了\r\n\tconst handleDragEnd = useCallback(() => {\r\n\t\tsetDraggedIndex(null);\r\n\t\tsetDragOverIndex(null);\r\n\t}, []);\r\n\r\n\t// ドラッグオーバー\r\n\tconst handleDragOver = useCallback(\r\n\t\t(e: React.DragEvent<HTMLElement>, displayIndex: number) => {\r\n\t\t\te.preventDefault();\r\n\t\t\te.dataTransfer.dropEffect = \"move\";\r\n\r\n\t\t\tif (draggedIndex === null || draggedIndex === displayIndex) return;\r\n\t\t\tsetDragOverIndex(displayIndex);\r\n\t\t},\r\n\t\t[draggedIndex],\r\n\t);\r\n\r\n\t// ドラッグリーブ\r\n\tconst handleDragLeave = useCallback(() => {\r\n\t\tsetDragOverIndex(null);\r\n\t}, []);\r\n\r\n\t// ドロップ\r\n\tconst handleDrop = useCallback(\r\n\t\t(e: React.DragEvent<HTMLElement>, displayDropIndex: number) => {\r\n\t\t\te.preventDefault();\r\n\r\n\t\t\tif (draggedIndex === null || draggedIndex === displayDropIndex) {\r\n\t\t\t\tsetDraggedIndex(null);\r\n\t\t\t\tsetDragOverIndex(null);\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\t// 表示インデックスを実際の配列インデックスに変換\r\n\t\t\tconst actualDraggedIndex = blocks.length - 1 - draggedIndex;\r\n\t\t\tconst actualDropIndex = blocks.length - 1 - displayDropIndex;\r\n\r\n\t\t\tconst newBlocks = [...blocks];\r\n\t\t\tconst [draggedBlock] = newBlocks.splice(actualDraggedIndex, 1);\r\n\t\t\tif (!draggedBlock) return;\r\n\r\n\t\t\tnewBlocks.splice(actualDropIndex, 0, draggedBlock);\r\n\r\n\t\t\tonBlocksChange(newBlocks);\r\n\t\t\tsetDraggedIndex(null);\r\n\t\t\tsetDragOverIndex(null);\r\n\t\t},\r\n\t\t[blocks, draggedIndex, onBlocksChange],\r\n\t);\r\n\r\n\treturn (\r\n\t\t<div className={styles.panel}>\r\n\t\t\t<h3 className={styles.title}>ブロック順序</h3>\r\n\r\n\t\t\t<div className={styles.content}>\r\n\t\t\t\t<p className={styles.description}>上が最前面、下が最背面</p>\r\n\r\n\t\t\t\t<ul className={styles.list}>\r\n\t\t\t\t\t{displayBlocks.map((block, displayIndex) => {\r\n\t\t\t\t\t\t// 実際の配列インデックス\r\n\t\t\t\t\t\tconst actualIndex = blocks.length - 1 - displayIndex;\r\n\t\t\t\t\t\treturn (\r\n\t\t\t\t\t\t\t<li\r\n\t\t\t\t\t\t\t\tkey={block.id}\r\n\t\t\t\t\t\t\t\tclassName={`${styles.item} ${\r\n\t\t\t\t\t\t\t\t\tdraggedIndex === displayIndex ? styles.dragging : \"\"\r\n\t\t\t\t\t\t\t\t} ${dragOverIndex === displayIndex ? styles.dragOver : \"\"}`}\r\n\t\t\t\t\t\t\t\tonDragOver={(e) => handleDragOver(e, displayIndex)}\r\n\t\t\t\t\t\t\t\tonDragLeave={handleDragLeave}\r\n\t\t\t\t\t\t\t\tonDrop={(e) => handleDrop(e, displayIndex)}\r\n\t\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t\t<button\r\n\t\t\t\t\t\t\t\t\ttype=\"button\"\r\n\t\t\t\t\t\t\t\t\tclassName={styles.dragHandle}\r\n\t\t\t\t\t\t\t\t\ttitle=\"ドラッグして並び替え\"\r\n\t\t\t\t\t\t\t\t\tdraggable\r\n\t\t\t\t\t\t\t\t\tonDragStart={(e) => handleDragStart(e, displayIndex)}\r\n\t\t\t\t\t\t\t\t\tonDragEnd={handleDragEnd}\r\n\t\t\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t\t\t<svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\r\n\t\t\t\t\t\t\t\t\t\t<title>ドラッグハンドル</title>\r\n\t\t\t\t\t\t\t\t\t\t<circle cx=\"6\" cy=\"4\" r=\"1\" fill=\"currentColor\" />\r\n\t\t\t\t\t\t\t\t\t\t<circle cx=\"10\" cy=\"4\" r=\"1\" fill=\"currentColor\" />\r\n\t\t\t\t\t\t\t\t\t\t<circle cx=\"6\" cy=\"8\" r=\"1\" fill=\"currentColor\" />\r\n\t\t\t\t\t\t\t\t\t\t<circle cx=\"10\" cy=\"8\" r=\"1\" fill=\"currentColor\" />\r\n\t\t\t\t\t\t\t\t\t\t<circle cx=\"6\" cy=\"12\" r=\"1\" fill=\"currentColor\" />\r\n\t\t\t\t\t\t\t\t\t\t<circle cx=\"10\" cy=\"12\" r=\"1\" fill=\"currentColor\" />\r\n\t\t\t\t\t\t\t\t\t</svg>\r\n\t\t\t\t\t\t\t\t</button>\r\n\t\t\t\t\t\t\t\t<div className={styles.itemInfo}>\r\n\t\t\t\t\t\t\t\t\t<div className={styles.itemId}>{block.id}</div>\r\n\t\t\t\t\t\t\t\t\t<div className={styles.itemMeta}>\r\n\t\t\t\t\t\t\t\t\t\t<span className={styles.itemKind}>{block.kind}</span>\r\n\t\t\t\t\t\t\t\t\t</div>\r\n\t\t\t\t\t\t\t\t</div>\r\n\r\n\t\t\t\t\t\t\t\t<div className={styles.itemActions}>\r\n\t\t\t\t\t\t\t\t\t<button\r\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\r\n\t\t\t\t\t\t\t\t\t\tclassName={styles.actionButton}\r\n\t\t\t\t\t\t\t\t\t\tonClick={() => handleBringToFront(block.id)}\r\n\t\t\t\t\t\t\t\t\t\ttitle=\"最前面へ\"\r\n\t\t\t\t\t\t\t\t\t\taria-label=\"最前面へ移動\"\r\n\t\t\t\t\t\t\t\t\t\tdisabled={actualIndex === blocks.length - 1}\r\n\t\t\t\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t\t\t\t<svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\r\n\t\t\t\t\t\t\t\t\t\t\t<title>最前面へ</title>\r\n\t\t\t\t\t\t\t\t\t\t\t<path\r\n\t\t\t\t\t\t\t\t\t\t\t\td=\"M4 12v-8M8 12v-8M12 12v-8\"\r\n\t\t\t\t\t\t\t\t\t\t\t\tstroke=\"currentColor\"\r\n\t\t\t\t\t\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t\t\t\t\t\t<path\r\n\t\t\t\t\t\t\t\t\t\t\t\td=\"M12 4h-8\"\r\n\t\t\t\t\t\t\t\t\t\t\t\tstroke=\"currentColor\"\r\n\t\t\t\t\t\t\t\t\t\t\t\tstrokeWidth=\"2\"\r\n\t\t\t\t\t\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t\t\t\t\t</svg>\r\n\t\t\t\t\t\t\t\t\t</button>\r\n\t\t\t\t\t\t\t\t\t<button\r\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\r\n\t\t\t\t\t\t\t\t\t\tclassName={styles.actionButton}\r\n\t\t\t\t\t\t\t\t\t\tonClick={() => handleBringForward(block.id)}\r\n\t\t\t\t\t\t\t\t\t\ttitle=\"前面へ\"\r\n\t\t\t\t\t\t\t\t\t\taria-label=\"前面へ移動\"\r\n\t\t\t\t\t\t\t\t\t\tdisabled={actualIndex === blocks.length - 1}\r\n\t\t\t\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t\t\t\t<svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\r\n\t\t\t\t\t\t\t\t\t\t\t<title>前面へ</title>\r\n\t\t\t\t\t\t\t\t\t\t\t<path d=\"M8 4v8\" stroke=\"currentColor\" />\r\n\t\t\t\t\t\t\t\t\t\t\t<path d=\"M5 7l3-3 3 3\" stroke=\"currentColor\" />\r\n\t\t\t\t\t\t\t\t\t\t</svg>\r\n\t\t\t\t\t\t\t\t\t</button>\r\n\t\t\t\t\t\t\t\t\t<button\r\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\r\n\t\t\t\t\t\t\t\t\t\tclassName={styles.actionButton}\r\n\t\t\t\t\t\t\t\t\t\tonClick={() => handleSendBackward(block.id)}\r\n\t\t\t\t\t\t\t\t\t\ttitle=\"背面へ\"\r\n\t\t\t\t\t\t\t\t\t\taria-label=\"背面へ移動\"\r\n\t\t\t\t\t\t\t\t\t\tdisabled={actualIndex === 0}\r\n\t\t\t\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t\t\t\t<svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\r\n\t\t\t\t\t\t\t\t\t\t\t<title>背面へ</title>\r\n\t\t\t\t\t\t\t\t\t\t\t<path d=\"M8 12v-8\" stroke=\"currentColor\" />\r\n\t\t\t\t\t\t\t\t\t\t\t<path d=\"M5 9l3 3 3-3\" stroke=\"currentColor\" />\r\n\t\t\t\t\t\t\t\t\t\t</svg>\r\n\t\t\t\t\t\t\t\t\t</button>\r\n\t\t\t\t\t\t\t\t\t<button\r\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\r\n\t\t\t\t\t\t\t\t\t\tclassName={styles.actionButton}\r\n\t\t\t\t\t\t\t\t\t\tonClick={() => handleSendToBack(block.id)}\r\n\t\t\t\t\t\t\t\t\t\ttitle=\"最背面へ\"\r\n\t\t\t\t\t\t\t\t\t\taria-label=\"最背面へ移動\"\r\n\t\t\t\t\t\t\t\t\t\tdisabled={actualIndex === 0}\r\n\t\t\t\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t\t\t\t<svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\r\n\t\t\t\t\t\t\t\t\t\t\t<title>最背面へ</title>\r\n\t\t\t\t\t\t\t\t\t\t\t<path\r\n\t\t\t\t\t\t\t\t\t\t\t\td=\"M4 12v-8M8 12v-8M12 12v-8\"\r\n\t\t\t\t\t\t\t\t\t\t\t\tstroke=\"currentColor\"\r\n\t\t\t\t\t\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t\t\t\t\t\t<path\r\n\t\t\t\t\t\t\t\t\t\t\t\td=\"M12 12h-8\"\r\n\t\t\t\t\t\t\t\t\t\t\t\tstroke=\"currentColor\"\r\n\t\t\t\t\t\t\t\t\t\t\t\tstrokeWidth=\"2\"\r\n\t\t\t\t\t\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t\t\t\t\t</svg>\r\n\t\t\t\t\t\t\t\t\t</button>\r\n\t\t\t\t\t\t\t\t</div>\r\n\t\t\t\t\t\t\t</li>\r\n\t\t\t\t\t\t);\r\n\t\t\t\t\t})}\r\n\t\t\t\t</ul>\r\n\r\n\t\t\t\t{blocks.length === 0 && (\r\n\t\t\t\t\t<div className={styles.empty}>ブロックがありません</div>\r\n\t\t\t\t)}\r\n\t\t\t</div>\r\n\t\t</div>\r\n\t);\r\n};\r\n\r\nBlockOrderPanel.displayName = \"BlockOrderPanel\";\r\n","/**\r\n * @file CanvasPanel.tsx\r\n * @description キャンバス設定統合パネル\r\n */\r\n\r\nimport { useCallback } from \"react\";\r\n\r\nimport { TabPanel } from \"../components/TabPanel\";\r\nimport { BlockOrderPanel, GridSizePanel, MarginPanel, PaperSizePanel } from \".\";\r\n\r\nimport type { Block } from \"@/types/block\";\r\nimport type { Grid } from \"@/types/grid\";\r\nimport type { Paper } from \"@/types/paper\";\r\nimport type { FormSchema } from \"@/types/schema\";\r\n\r\nexport interface CanvasPanelProps {\r\n\t/** フォームスキーマ */\r\n\tschema: FormSchema;\r\n\t/** スキーマ変更時のコールバック */\r\n\tonSchemaChange: (newSchema: FormSchema) => void;\r\n}\r\n\r\n/**\r\n * CanvasPanel\r\n * キャンバス設定の統合パネル\r\n * - PaperSizePanel: 用紙サイズ設定\r\n * - MarginPanel: マージン設定\r\n * - GridSizePanel: グリッドサイズ設定\r\n * - BlockOrderPanel: ブロック順序設定\r\n */\r\nexport const CanvasPanel = ({ schema, onSchemaChange }: CanvasPanelProps) => {\r\n\t// 用紙設定変更\r\n\tconst handlePaperChange = useCallback(\r\n\t\t(newPaper: Paper) => {\r\n\t\t\tonSchemaChange({\r\n\t\t\t\t...schema,\r\n\t\t\t\tpaper: newPaper,\r\n\t\t\t});\r\n\t\t},\r\n\t\t[schema, onSchemaChange],\r\n\t);\r\n\r\n\t// グリッド設定変更\r\n\tconst handleGridChange = useCallback(\r\n\t\t(newGrid: Grid) => {\r\n\t\t\tonSchemaChange({\r\n\t\t\t\t...schema,\r\n\t\t\t\tgrid: newGrid,\r\n\t\t\t});\r\n\t\t},\r\n\t\t[schema, onSchemaChange],\r\n\t);\r\n\r\n\t// ブロック順序変更\r\n\tconst handleBlocksChange = useCallback(\r\n\t\t(newBlocks: Block[]) => {\r\n\t\t\tonSchemaChange({\r\n\t\t\t\t...schema,\r\n\t\t\t\tblocks: newBlocks,\r\n\t\t\t});\r\n\t\t},\r\n\t\t[schema, onSchemaChange],\r\n\t);\r\n\r\n\treturn (\r\n\t\t<TabPanel>\r\n\t\t\t<PaperSizePanel paper={schema.paper} onPaperChange={handlePaperChange} />\r\n\t\t\t<MarginPanel paper={schema.paper} onPaperChange={handlePaperChange} />\r\n\t\t\t<GridSizePanel grid={schema.grid} onGridChange={handleGridChange} />\r\n\t\t\t<BlockOrderPanel\r\n\t\t\t\tblocks={schema.blocks}\r\n\t\t\t\tonBlocksChange={handleBlocksChange}\r\n\t\t\t/>\r\n\t\t</TabPanel>\r\n\t);\r\n};\r\n\r\nCanvasPanel.displayName = \"CanvasPanel\";\r\n","/**\r\n * @file GridSizePanel.tsx\r\n * @description 行・列数変更パネル\r\n */\r\n\r\nimport { useCallback } from \"react\";\r\n\r\nimport { NumberInput } from \"../../components/NumberInput\";\r\nimport styles from \"./GridSizePanel.module.css\";\r\n\r\nimport type { Grid } from \"@/types/grid\";\r\nimport type { Dimension, GridUnit } from \"@/types/unit\";\r\n\r\nexport interface GridSizePanelProps {\r\n\t/** グリッド設定 */\r\n\tgrid: Grid;\r\n\t/** グリッド変更時のコールバック */\r\n\tonGridChange: (grid: Grid) => void;\r\n}\r\n\r\n/**\r\n * GridSizePanel\r\n * 行・列数を変更するパネル\r\n */\r\nexport const GridSizePanel = ({ grid, onGridChange }: GridSizePanelProps) => {\r\n\t// 列数変更ハンドラ\r\n\tconst handleColsChange = useCallback(\r\n\t\t(newColCount: number | undefined) => {\r\n\t\t\tif (!newColCount || newColCount < 1 || newColCount > 100) return;\r\n\r\n\t\t\tconst currentColCount = grid.cols.length;\r\n\t\t\tconst newCols: Dimension<GridUnit>[] = [];\r\n\r\n\t\t\tif (newColCount > currentColCount) {\r\n\t\t\t\t// 列を追加\r\n\t\t\t\tnewCols.push(...grid.cols);\r\n\t\t\t\tfor (let i = currentColCount; i < newColCount; i++) {\r\n\t\t\t\t\tnewCols.push({ value: 1, unit: \"fr\" });\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\t// 列を削除\r\n\t\t\t\tnewCols.push(...grid.cols.slice(0, newColCount));\r\n\t\t\t}\r\n\r\n\t\t\tonGridChange({\r\n\t\t\t\t...grid,\r\n\t\t\t\tcols: newCols,\r\n\t\t\t});\r\n\t\t},\r\n\t\t[grid, onGridChange],\r\n\t);\r\n\r\n\t// 行数変更ハンドラ\r\n\tconst handleRowsChange = useCallback(\r\n\t\t(newRowCount: number | undefined) => {\r\n\t\t\tif (!newRowCount || newRowCount < 1 || newRowCount > 100) return;\r\n\r\n\t\t\tconst currentRowCount = grid.rows.length;\r\n\t\t\tconst newRows: Dimension<GridUnit>[] = [];\r\n\r\n\t\t\tif (newRowCount > currentRowCount) {\r\n\t\t\t\t// 行を追加\r\n\t\t\t\tnewRows.push(...grid.rows);\r\n\t\t\t\tfor (let i = currentRowCount; i < newRowCount; i++) {\r\n\t\t\t\t\tnewRows.push({ value: 1, unit: \"fr\" });\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\t// 行を削除\r\n\t\t\t\tnewRows.push(...grid.rows.slice(0, newRowCount));\r\n\t\t\t}\r\n\r\n\t\t\tonGridChange({\r\n\t\t\t\t...grid,\r\n\t\t\t\trows: newRows,\r\n\t\t\t});\r\n\t\t},\r\n\t\t[grid, onGridChange],\r\n\t);\r\n\r\n\treturn (\r\n\t\t<div className={styles.panel}>\r\n\t\t\t<h3 className={styles.title}>グリッドサイズ</h3>\r\n\r\n\t\t\t<div className={styles.content}>\r\n\t\t\t\t<div className={styles.gridSizeRow}>\r\n\t\t\t\t\t<div className={`${styles.field} ${styles.horizontal}`}>\r\n\t\t\t\t\t\t<span className={styles.label}>列数</span>\r\n\t\t\t\t\t\t<NumberInput\r\n\t\t\t\t\t\t\tvalue={grid.cols.length}\r\n\t\t\t\t\t\t\tonChange={handleColsChange}\r\n\t\t\t\t\t\t\tmin={1}\r\n\t\t\t\t\t\t\tmax={100}\r\n\t\t\t\t\t\t\tstep={1}\r\n\t\t\t\t\t\t/>\r\n\t\t\t\t\t</div>\r\n\r\n\t\t\t\t\t<div className={`${styles.field} ${styles.horizontal}`}>\r\n\t\t\t\t\t\t<span className={styles.label}>行数</span>\r\n\t\t\t\t\t\t<NumberInput\r\n\t\t\t\t\t\t\tvalue={grid.rows.length}\r\n\t\t\t\t\t\t\tonChange={handleRowsChange}\r\n\t\t\t\t\t\t\tmin={1}\r\n\t\t\t\t\t\t\tmax={100}\r\n\t\t\t\t\t\t\tstep={1}\r\n\t\t\t\t\t\t/>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t</div>\r\n\t\t\t</div>\r\n\t\t</div>\r\n\t);\r\n};\r\n\r\nGridSizePanel.displayName = \"GridSizePanel\";\r\n","/**\r\n * @file MarginPanel.tsx\r\n * @description マージン変更パネル\r\n */\r\n\r\nimport { useCallback, useState } from \"react\";\r\n\r\nimport { Checkbox } from \"../../components/Checkbox\";\r\nimport { DimensionInput } from \"../../components/DimensionInput\";\r\nimport styles from \"./MarginPanel.module.css\";\r\n\r\nimport type { Paper, PaperMargin } from \"@/types/paper\";\r\nimport type { Dimension, PaperUnit } from \"@/types/unit\";\r\n\r\nexport interface MarginPanelProps {\r\n\t/** 用紙設定 */\r\n\tpaper: Paper;\r\n\t/** 用紙変更時のコールバック */\r\n\tonPaperChange: (paper: Paper) => void;\r\n}\r\n\r\n/**\r\n * MarginPanel\r\n * マージンを変更するパネル\r\n */\r\nexport const MarginPanel = ({ paper, onPaperChange }: MarginPanelProps) => {\r\n\t// 全辺一括設定モード\r\n\tconst [linkMargins, setLinkMargins] = useState(false);\r\n\r\n\t// リンク変更ハンドラ\r\n\tconst handleLinkChange = useCallback((checked: boolean | undefined) => {\r\n\t\tif (checked !== undefined) {\r\n\t\t\tsetLinkMargins(checked);\r\n\t\t}\r\n\t}, []);\r\n\r\n\t// 上マージン変更ハンドラ\r\n\tconst handleTopChange = useCallback(\r\n\t\t(top: Dimension<PaperUnit> | undefined) => {\r\n\t\t\tif (!top) return;\r\n\r\n\t\t\tconst newMargin: PaperMargin = linkMargins\r\n\t\t\t\t? {\r\n\t\t\t\t\t\ttop,\r\n\t\t\t\t\t\tright: top,\r\n\t\t\t\t\t\tbottom: top,\r\n\t\t\t\t\t\tleft: top,\r\n\t\t\t\t\t}\r\n\t\t\t\t: {\r\n\t\t\t\t\t\t...paper.margin,\r\n\t\t\t\t\t\ttop,\r\n\t\t\t\t\t};\r\n\r\n\t\t\tonPaperChange({\r\n\t\t\t\t...paper,\r\n\t\t\t\tmargin: newMargin,\r\n\t\t\t});\r\n\t\t},\r\n\t\t[paper, onPaperChange, linkMargins],\r\n\t);\r\n\r\n\t// 右マージン変更ハンドラ\r\n\tconst handleRightChange = useCallback(\r\n\t\t(right: Dimension<PaperUnit> | undefined) => {\r\n\t\t\tif (!right) return;\r\n\r\n\t\t\tonPaperChange({\r\n\t\t\t\t...paper,\r\n\t\t\t\tmargin: {\r\n\t\t\t\t\t...paper.margin,\r\n\t\t\t\t\tright,\r\n\t\t\t\t},\r\n\t\t\t});\r\n\t\t},\r\n\t\t[paper, onPaperChange],\r\n\t);\r\n\r\n\t// 下マージン変更ハンドラ\r\n\tconst handleBottomChange = useCallback(\r\n\t\t(bottom: Dimension<PaperUnit> | undefined) => {\r\n\t\t\tif (!bottom) return;\r\n\r\n\t\t\tonPaperChange({\r\n\t\t\t\t...paper,\r\n\t\t\t\tmargin: {\r\n\t\t\t\t\t...paper.margin,\r\n\t\t\t\t\tbottom,\r\n\t\t\t\t},\r\n\t\t\t});\r\n\t\t},\r\n\t\t[paper, onPaperChange],\r\n\t);\r\n\r\n\t// 左マージン変更ハンドラ\r\n\tconst handleLeftChange = useCallback(\r\n\t\t(left: Dimension<PaperUnit> | undefined) => {\r\n\t\t\tif (!left) return;\r\n\r\n\t\t\tonPaperChange({\r\n\t\t\t\t...paper,\r\n\t\t\t\tmargin: {\r\n\t\t\t\t\t...paper.margin,\r\n\t\t\t\t\tleft,\r\n\t\t\t\t},\r\n\t\t\t});\r\n\t\t},\r\n\t\t[paper, onPaperChange],\r\n\t);\r\n\r\n\treturn (\r\n\t\t<div className={styles.panel}>\r\n\t\t\t<div className={styles.header}>\r\n\t\t\t\t<h3 className={styles.title}>マージン</h3>\r\n\t\t\t\t<div className={styles.headerActions}>\r\n\t\t\t\t\t<Checkbox\r\n\t\t\t\t\t\tvalue={linkMargins}\r\n\t\t\t\t\t\tonChange={handleLinkChange}\r\n\t\t\t\t\t\tlabel=\"全辺を一括設定\"\r\n\t\t\t\t\t/>\r\n\t\t\t\t</div>\r\n\t\t\t</div>\r\n\r\n\t\t\t<div className={styles.content}>\r\n\t\t\t\t{linkMargins ? (\r\n\t\t\t\t\t<div className={`${styles.field} ${styles.horizontal}`}>\r\n\t\t\t\t\t\t<span className={styles.label}>全辺</span>\r\n\t\t\t\t\t\t<DimensionInput\r\n\t\t\t\t\t\t\tvalue={paper.margin.top}\r\n\t\t\t\t\t\t\tonChange={handleTopChange}\r\n\t\t\t\t\t\t\tallowedUnits={[\"mm\", \"cm\", \"inch\"]}\r\n\t\t\t\t\t\t\tmin={0}\r\n\t\t\t\t\t\t\tmax={1000}\r\n\t\t\t\t\t\t/>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t) : (\r\n\t\t\t\t\t<div className={styles.marginsGrid}>\r\n\t\t\t\t\t\t<div\r\n\t\t\t\t\t\t\tclassName={`${styles.field} ${styles.horizontal} ${styles.topMargin}`}\r\n\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t<DimensionInput\r\n\t\t\t\t\t\t\t\tvalue={paper.margin.top}\r\n\t\t\t\t\t\t\t\tonChange={handleTopChange}\r\n\t\t\t\t\t\t\t\tallowedUnits={[\"mm\", \"cm\", \"inch\"]}\r\n\t\t\t\t\t\t\t\tmin={0}\r\n\t\t\t\t\t\t\t\tmax={1000}\r\n\t\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t</div>\r\n\r\n\t\t\t\t\t\t<div className={styles.sideMargins}>\r\n\t\t\t\t\t\t\t<div className={`${styles.field} ${styles.horizontal}`}>\r\n\t\t\t\t\t\t\t\t<DimensionInput\r\n\t\t\t\t\t\t\t\t\tvalue={paper.margin.left}\r\n\t\t\t\t\t\t\t\t\tonChange={handleLeftChange}\r\n\t\t\t\t\t\t\t\t\tallowedUnits={[\"mm\", \"cm\", \"inch\"]}\r\n\t\t\t\t\t\t\t\t\tmin={0}\r\n\t\t\t\t\t\t\t\t\tmax={1000}\r\n\t\t\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t\t</div>\r\n\r\n\t\t\t\t\t\t\t<div className={`${styles.field} ${styles.horizontal}`}>\r\n\t\t\t\t\t\t\t\t<DimensionInput\r\n\t\t\t\t\t\t\t\t\tvalue={paper.margin.right}\r\n\t\t\t\t\t\t\t\t\tonChange={handleRightChange}\r\n\t\t\t\t\t\t\t\t\tallowedUnits={[\"mm\", \"cm\", \"inch\"]}\r\n\t\t\t\t\t\t\t\t\tmin={0}\r\n\t\t\t\t\t\t\t\t\tmax={1000}\r\n\t\t\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t\t</div>\r\n\t\t\t\t\t\t</div>\r\n\r\n\t\t\t\t\t\t<div\r\n\t\t\t\t\t\t\tclassName={`${styles.field} ${styles.horizontal} ${styles.bottomMargin}`}\r\n\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t<DimensionInput\r\n\t\t\t\t\t\t\t\tvalue={paper.margin.bottom}\r\n\t\t\t\t\t\t\t\tonChange={handleBottomChange}\r\n\t\t\t\t\t\t\t\tallowedUnits={[\"mm\", \"cm\", \"inch\"]}\r\n\t\t\t\t\t\t\t\tmin={0}\r\n\t\t\t\t\t\t\t\tmax={1000}\r\n\t\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t</div>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t)}\r\n\t\t\t</div>\r\n\t\t</div>\r\n\t);\r\n};\r\n\r\nMarginPanel.displayName = \"MarginPanel\";\r\n","/**\r\n * @file PaperSizePanel.tsx\r\n * @description 用紙サイズ変更パネル\r\n */\r\n\r\nimport { useCallback, useMemo } from \"react\";\r\n\r\nimport { DimensionInput } from \"../../components/DimensionInput\";\r\nimport { Select } from \"../../components/Select\";\r\nimport styles from \"./PaperSizePanel.module.css\";\r\n\r\nimport {\r\n\tDEFAULT_PAPER_SIZES,\r\n\ttype Paper,\r\n\ttype PaperSize,\r\n\tPaperSizePreset,\r\n} from \"@/types/paper\";\r\n\r\nimport type { Dimension, PaperUnit } from \"@/types/unit\";\r\n\r\nexport interface PaperSizePanelProps {\r\n\t/** 用紙設定 */\r\n\tpaper: Paper;\r\n\t/** 用紙変更時のコールバック */\r\n\tonPaperChange: (paper: Paper) => void;\r\n}\r\n\r\n/**\r\n * PaperSizePanel\r\n * 用紙サイズを変更するパネル\r\n */\r\nexport const PaperSizePanel = ({\r\n\tpaper,\r\n\tonPaperChange,\r\n}: PaperSizePanelProps) => {\r\n\t// プリセット選択肢\r\n\tconst presetOptions = useMemo(\r\n\t\t() => [\r\n\t\t\t{ value: PaperSizePreset.A4, label: \"A4 (210 × 297 mm)\" },\r\n\t\t\t{ value: PaperSizePreset.A3, label: \"A3 (297 × 420 mm)\" },\r\n\t\t\t{ value: PaperSizePreset.B5, label: \"B5 (182 × 257 mm)\" },\r\n\t\t\t{ value: PaperSizePreset.LETTER, label: \"Letter (8.5 × 11 inch)\" },\r\n\t\t\t{ value: PaperSizePreset.LEGAL, label: \"Legal (8.5 × 14 inch)\" },\r\n\t\t\t{ value: PaperSizePreset.CUSTOM, label: \"カスタム\" },\r\n\t\t],\r\n\t\t[],\r\n\t);\r\n\r\n\t// プリセット変更ハンドラ\r\n\tconst handlePresetChange = useCallback(\r\n\t\t(preset: PaperSizePreset | undefined) => {\r\n\t\t\tif (!preset) return;\r\n\t\t\tconst newSize = DEFAULT_PAPER_SIZES[preset];\r\n\r\n\t\t\tonPaperChange({\r\n\t\t\t\t...paper,\r\n\t\t\t\tsize: newSize,\r\n\t\t\t});\r\n\t\t},\r\n\t\t[paper, onPaperChange],\r\n\t);\r\n\r\n\t// 幅変更ハンドラ\r\n\tconst handleWidthChange = useCallback(\r\n\t\t(width: Dimension<PaperUnit> | undefined) => {\r\n\t\t\tif (!width) return;\r\n\t\t\tconst newSize: PaperSize = {\r\n\t\t\t\t...paper.size,\r\n\t\t\t\tpreset: PaperSizePreset.CUSTOM,\r\n\t\t\t\twidth,\r\n\t\t\t};\r\n\r\n\t\t\tonPaperChange({\r\n\t\t\t\t...paper,\r\n\t\t\t\tsize: newSize,\r\n\t\t\t});\r\n\t\t},\r\n\t\t[paper, onPaperChange],\r\n\t);\r\n\r\n\t// 高さ変更ハンドラ\r\n\tconst handleHeightChange = useCallback(\r\n\t\t(height: Dimension<PaperUnit> | undefined) => {\r\n\t\t\tif (!height) return;\r\n\t\t\tconst newSize: PaperSize = {\r\n\t\t\t\t...paper.size,\r\n\t\t\t\tpreset: PaperSizePreset.CUSTOM,\r\n\t\t\t\theight,\r\n\t\t\t};\r\n\r\n\t\t\tonPaperChange({\r\n\t\t\t\t...paper,\r\n\t\t\t\tsize: newSize,\r\n\t\t\t});\r\n\t\t},\r\n\t\t[paper, onPaperChange],\r\n\t);\r\n\r\n\t// カスタムサイズかどうか\r\n\tconst isCustom = paper.size.preset === PaperSizePreset.CUSTOM;\r\n\r\n\treturn (\r\n\t\t<div className={styles.panel}>\r\n\t\t\t<h3 className={styles.title}>用紙サイズ</h3>\r\n\r\n\t\t\t<div className={styles.content}>\r\n\t\t\t\t<div className={styles.field}>\r\n\t\t\t\t\t<Select\r\n\t\t\t\t\t\tvalue={paper.size.preset}\r\n\t\t\t\t\t\toptions={presetOptions}\r\n\t\t\t\t\t\tonChange={handlePresetChange}\r\n\t\t\t\t\t/>\r\n\t\t\t\t</div>\r\n\r\n\t\t\t\t{isCustom && (\r\n\t\t\t\t\t<div className={styles.dimensionsRow}>\r\n\t\t\t\t\t\t<div className={`${styles.field} ${styles.horizontal}`}>\r\n\t\t\t\t\t\t\t<span className={styles.label}>幅</span>\r\n\t\t\t\t\t\t\t<DimensionInput\r\n\t\t\t\t\t\t\t\tvalue={paper.size.width}\r\n\t\t\t\t\t\t\t\tonChange={handleWidthChange}\r\n\t\t\t\t\t\t\t\tallowedUnits={[\"mm\", \"cm\", \"inch\"]}\r\n\t\t\t\t\t\t\t\tmin={paper.margin.left.value + paper.margin.right.value + 1}\r\n\t\t\t\t\t\t\t\tmax={500}\r\n\t\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t</div>\r\n\r\n\t\t\t\t\t\t<div className={`${styles.field} ${styles.horizontal}`}>\r\n\t\t\t\t\t\t\t<span className={styles.label}>高さ</span>\r\n\t\t\t\t\t\t\t<DimensionInput\r\n\t\t\t\t\t\t\t\tvalue={paper.size.height}\r\n\t\t\t\t\t\t\t\tonChange={handleHeightChange}\r\n\t\t\t\t\t\t\t\tallowedUnits={[\"mm\", \"cm\", \"inch\"]}\r\n\t\t\t\t\t\t\t\tmin={paper.margin.top.value + paper.margin.bottom.value + 1}\r\n\t\t\t\t\t\t\t\tmax={500}\r\n\t\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t</div>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t)}\r\n\t\t\t</div>\r\n\t\t</div>\r\n\t);\r\n};\r\n\r\nPaperSizePanel.displayName = \"PaperSizePanel\";\r\n","/**\r\n * @file ImportExportPanel.tsx\r\n * @description スキーマ・値のImport/Exportパネル\r\n */\r\n\r\nimport { useCallback, useRef, useState } from \"react\";\r\n\r\nimport styles from \"./ImportExportPanel.module.css\";\r\n\r\nimport {\r\n\tdeserializeSchema,\r\n\tdeserializeValues,\r\n\tserializeSchema,\r\n\tserializeValues,\r\n} from \"@/utils\";\r\n\r\nimport type { FormSchema } from \"@/types/schema\";\r\nimport type { Value } from \"@/types/value\";\r\n\r\nexport interface ImportExportPanelProps {\r\n\t/** スキーマ */\r\n\tschema: FormSchema;\r\n\t/** 値 */\r\n\tvalues: Record<string, Value>;\r\n\t/** スキーマ変更時のコールバック */\r\n\tonSchemaChange: (schema: FormSchema) => void;\r\n\t/** 値変更時のコールバック */\r\n\tonValuesChange: (values: Record<string, Value>) => void;\r\n}\r\n\r\n/**\r\n * ImportExportPanel\r\n * スキーマと値のインポート/エクスポート機能を提供\r\n */\r\nexport const ImportExportPanel = ({\r\n\tschema,\r\n\tvalues,\r\n\tonSchemaChange,\r\n\tonValuesChange,\r\n}: ImportExportPanelProps) => {\r\n\tconst [error, setError] = useState<string>(\"\");\r\n\tconst schemaFileInputRef = useRef<HTMLInputElement>(null);\r\n\tconst valuesFileInputRef = useRef<HTMLInputElement>(null);\r\n\r\n\t// スキーマをファイルにエクスポート\r\n\tconst handleExportSchemaFile = useCallback(() => {\r\n\t\ttry {\r\n\t\t\tconst json = serializeSchema(schema, true);\r\n\t\t\tconst blob = new Blob([json], { type: \"application/json\" });\r\n\t\t\tconst url = URL.createObjectURL(blob);\r\n\t\t\tconst a = document.createElement(\"a\");\r\n\t\t\ta.href = url;\r\n\t\t\ta.download = \"schema.json\";\r\n\t\t\ta.click();\r\n\t\t\tURL.revokeObjectURL(url);\r\n\t\t\tsetError(\"\");\r\n\t\t} catch (err) {\r\n\t\t\tsetError(\r\n\t\t\t\t`エクスポートエラー: ${err instanceof Error ? err.message : String(err)}`,\r\n\t\t\t);\r\n\t\t}\r\n\t}, [schema]);\r\n\r\n\t// スキーマをクリップボードにコピー\r\n\tconst handleExportSchemaClipboard = useCallback(async () => {\r\n\t\ttry {\r\n\t\t\tconst json = serializeSchema(schema, true);\r\n\t\t\tawait navigator.clipboard.writeText(json);\r\n\t\t\tsetError(\"\");\r\n\t\t\talert(\"スキーマをクリップボードにコピーしました\");\r\n\t\t} catch (err) {\r\n\t\t\tsetError(\r\n\t\t\t\t`クリップボードエラー: ${err instanceof Error ? err.message : String(err)}`,\r\n\t\t\t);\r\n\t\t}\r\n\t}, [schema]);\r\n\r\n\t// スキーマをファイルからインポート\r\n\tconst handleImportSchemaFile = useCallback(() => {\r\n\t\tschemaFileInputRef.current?.click();\r\n\t}, []);\r\n\r\n\t// ファイル選択時の処理\r\n\tconst handleSchemaFileChange = useCallback(\r\n\t\t(event: React.ChangeEvent<HTMLInputElement>) => {\r\n\t\t\tconst file = event.target.files?.[0];\r\n\t\t\tif (!file) return;\r\n\r\n\t\t\tconst reader = new FileReader();\r\n\t\t\treader.onload = (e) => {\r\n\t\t\t\ttry {\r\n\t\t\t\t\tconst json = e.target?.result as string;\r\n\t\t\t\t\tconst newSchema = deserializeSchema(json);\r\n\t\t\t\t\tonSchemaChange(newSchema);\r\n\t\t\t\t\tsetError(\"\");\r\n\t\t\t\t\talert(\"スキーマをインポートしました\");\r\n\t\t\t\t} catch (err) {\r\n\t\t\t\t\tsetError(\r\n\t\t\t\t\t\t`インポートエラー: ${err instanceof Error ? err.message : String(err)}`,\r\n\t\t\t\t\t);\r\n\t\t\t\t}\r\n\t\t\t};\r\n\t\t\treader.readAsText(file);\r\n\r\n\t\t\t// リセット(同じファイルを再度選択できるように)\r\n\t\t\tevent.target.value = \"\";\r\n\t\t},\r\n\t\t[onSchemaChange],\r\n\t);\r\n\r\n\t// スキーマをクリップボードからインポート\r\n\tconst handleImportSchemaClipboard = useCallback(async () => {\r\n\t\ttry {\r\n\t\t\tconst json = await navigator.clipboard.readText();\r\n\t\t\tconst newSchema = deserializeSchema(json);\r\n\t\t\tonSchemaChange(newSchema);\r\n\t\t\tsetError(\"\");\r\n\t\t\talert(\"スキーマをインポートしました\");\r\n\t\t} catch (err) {\r\n\t\t\tsetError(\r\n\t\t\t\t`インポートエラー: ${err instanceof Error ? err.message : String(err)}`,\r\n\t\t\t);\r\n\t\t}\r\n\t}, [onSchemaChange]);\r\n\r\n\t// 値をファイルにエクスポート\r\n\tconst handleExportValuesFile = useCallback(() => {\r\n\t\ttry {\r\n\t\t\tconst json = serializeValues(values, true);\r\n\t\t\tconst blob = new Blob([json], { type: \"application/json\" });\r\n\t\t\tconst url = URL.createObjectURL(blob);\r\n\t\t\tconst a = document.createElement(\"a\");\r\n\t\t\ta.href = url;\r\n\t\t\ta.download = \"values.json\";\r\n\t\t\ta.click();\r\n\t\t\tURL.revokeObjectURL(url);\r\n\t\t\tsetError(\"\");\r\n\t\t} catch (err) {\r\n\t\t\tsetError(\r\n\t\t\t\t`エクスポートエラー: ${err instanceof Error ? err.message : String(err)}`,\r\n\t\t\t);\r\n\t\t}\r\n\t}, [values]);\r\n\r\n\t// 値をクリップボードにコピー\r\n\tconst handleExportValuesClipboard = useCallback(async () => {\r\n\t\ttry {\r\n\t\t\tconst json = serializeValues(values, true);\r\n\t\t\tawait navigator.clipboard.writeText(json);\r\n\t\t\tsetError(\"\");\r\n\t\t\talert(\"値をクリップボードにコピーしました\");\r\n\t\t} catch (err) {\r\n\t\t\tsetError(\r\n\t\t\t\t`クリップボードエラー: ${err instanceof Error ? err.message : String(err)}`,\r\n\t\t\t);\r\n\t\t}\r\n\t}, [values]);\r\n\r\n\t// 値をファイルからインポート\r\n\tconst handleImportValuesFile = useCallback(() => {\r\n\t\tvaluesFileInputRef.current?.click();\r\n\t}, []);\r\n\r\n\t// ファイル選択時の処理\r\n\tconst handleValuesFileChange = useCallback(\r\n\t\t(event: React.ChangeEvent<HTMLInputElement>) => {\r\n\t\t\tconst file = event.target.files?.[0];\r\n\t\t\tif (!file) return;\r\n\r\n\t\t\tconst reader = new FileReader();\r\n\t\t\treader.onload = (e) => {\r\n\t\t\t\ttry {\r\n\t\t\t\t\tconst json = e.target?.result as string;\r\n\t\t\t\t\tconst newValues = deserializeValues(json);\r\n\t\t\t\t\tonValuesChange(newValues);\r\n\t\t\t\t\tsetError(\"\");\r\n\t\t\t\t\talert(\"値をインポートしました\");\r\n\t\t\t\t} catch (err) {\r\n\t\t\t\t\tsetError(\r\n\t\t\t\t\t\t`インポートエラー: ${err instanceof Error ? err.message : String(err)}`,\r\n\t\t\t\t\t);\r\n\t\t\t\t}\r\n\t\t\t};\r\n\t\t\treader.readAsText(file);\r\n\r\n\t\t\t// リセット\r\n\t\t\tevent.target.value = \"\";\r\n\t\t},\r\n\t\t[onValuesChange],\r\n\t);\r\n\r\n\t// 値をクリップボードからインポート\r\n\tconst handleImportValuesClipboard = useCallback(async () => {\r\n\t\ttry {\r\n\t\t\tconst json = await navigator.clipboard.readText();\r\n\t\t\tconst newValues = deserializeValues(json);\r\n\t\t\tonValuesChange(newValues);\r\n\t\t\tsetError(\"\");\r\n\t\t\talert(\"値をインポートしました\");\r\n\t\t} catch (err) {\r\n\t\t\tsetError(\r\n\t\t\t\t`インポートエラー: ${err instanceof Error ? err.message : String(err)}`,\r\n\t\t\t);\r\n\t\t}\r\n\t}, [onValuesChange]);\r\n\r\n\treturn (\r\n\t\t<>\r\n\t\t\t<div className={styles.section}>\r\n\t\t\t\t<h3 className={styles.title}>スキーマ</h3>\r\n\r\n\t\t\t\t<div className={styles.content}>\r\n\t\t\t\t\t<div className={styles.buttonGroup}>\r\n\t\t\t\t\t\t<button\r\n\t\t\t\t\t\t\ttype=\"button\"\r\n\t\t\t\t\t\t\tclassName={styles.button}\r\n\t\t\t\t\t\t\tonClick={handleExportSchemaFile}\r\n\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t📥 ファイルにエクスポート\r\n\t\t\t\t\t\t</button>\r\n\t\t\t\t\t\t<button\r\n\t\t\t\t\t\t\ttype=\"button\"\r\n\t\t\t\t\t\t\tclassName={styles.button}\r\n\t\t\t\t\t\t\tonClick={handleExportSchemaClipboard}\r\n\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t📋 クリップボードにコピー\r\n\t\t\t\t\t\t</button>\r\n\t\t\t\t\t</div>\r\n\r\n\t\t\t\t\t<div className={styles.buttonGroup}>\r\n\t\t\t\t\t\t<button\r\n\t\t\t\t\t\t\ttype=\"button\"\r\n\t\t\t\t\t\t\tclassName={styles.button}\r\n\t\t\t\t\t\t\tonClick={handleImportSchemaFile}\r\n\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t📤 ファイルからインポート\r\n\t\t\t\t\t\t</button>\r\n\t\t\t\t\t\t<button\r\n\t\t\t\t\t\t\ttype=\"button\"\r\n\t\t\t\t\t\t\tclassName={styles.button}\r\n\t\t\t\t\t\t\tonClick={handleImportSchemaClipboard}\r\n\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t📋 クリップボードからペースト\r\n\t\t\t\t\t\t</button>\r\n\t\t\t\t\t</div>\r\n\r\n\t\t\t\t\t<input\r\n\t\t\t\t\t\tref={schemaFileInputRef}\r\n\t\t\t\t\t\ttype=\"file\"\r\n\t\t\t\t\t\taccept=\".json\"\r\n\t\t\t\t\t\tstyle={{ display: \"none\" }}\r\n\t\t\t\t\t\tonChange={handleSchemaFileChange}\r\n\t\t\t\t\t/>\r\n\t\t\t\t</div>\r\n\t\t\t</div>\r\n\r\n\t\t\t<div className={styles.section}>\r\n\t\t\t\t<h3 className={styles.title}>値</h3>\r\n\r\n\t\t\t\t<div className={styles.content}>\r\n\t\t\t\t\t<div className={styles.buttonGroup}>\r\n\t\t\t\t\t\t<button\r\n\t\t\t\t\t\t\ttype=\"button\"\r\n\t\t\t\t\t\t\tclassName={styles.button}\r\n\t\t\t\t\t\t\tonClick={handleExportValuesFile}\r\n\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t📥 ファイルにエクスポート\r\n\t\t\t\t\t\t</button>\r\n\t\t\t\t\t\t<button\r\n\t\t\t\t\t\t\ttype=\"button\"\r\n\t\t\t\t\t\t\tclassName={styles.button}\r\n\t\t\t\t\t\t\tonClick={handleExportValuesClipboard}\r\n\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t📋 クリップボードにコピー\r\n\t\t\t\t\t\t</button>\r\n\t\t\t\t\t</div>\r\n\r\n\t\t\t\t\t<div className={styles.buttonGroup}>\r\n\t\t\t\t\t\t<button\r\n\t\t\t\t\t\t\ttype=\"button\"\r\n\t\t\t\t\t\t\tclassName={styles.button}\r\n\t\t\t\t\t\t\tonClick={handleImportValuesFile}\r\n\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t📤 ファイルからインポート\r\n\t\t\t\t\t\t</button>\r\n\t\t\t\t\t\t<button\r\n\t\t\t\t\t\t\ttype=\"button\"\r\n\t\t\t\t\t\t\tclassName={styles.button}\r\n\t\t\t\t\t\t\tonClick={handleImportValuesClipboard}\r\n\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t📋 クリップボードからペースト\r\n\t\t\t\t\t\t</button>\r\n\t\t\t\t\t</div>\r\n\r\n\t\t\t\t\t<input\r\n\t\t\t\t\t\tref={valuesFileInputRef}\r\n\t\t\t\t\t\ttype=\"file\"\r\n\t\t\t\t\t\taccept=\".json\"\r\n\t\t\t\t\t\tstyle={{ display: \"none\" }}\r\n\t\t\t\t\t\tonChange={handleValuesFileChange}\r\n\t\t\t\t\t/>\r\n\t\t\t\t</div>\r\n\t\t\t</div>\r\n\r\n\t\t\t{error && (\r\n\t\t\t\t<div className={styles.error} role=\"alert\">\r\n\t\t\t\t\t{error}\r\n\t\t\t\t</div>\r\n\t\t\t)}\r\n\t\t</>\r\n\t);\r\n};\r\n\r\nImportExportPanel.displayName = \"ImportExportPanel\";\r\n","/**\r\n * @file OtherPanel.tsx\r\n * @description その他の設定統合パネル\r\n */\r\n\r\nimport { TabPanel } from \"../components/TabPanel\";\r\nimport { ImportExportPanel } from \".\";\r\n\r\nimport type { FormSchema } from \"@/types/schema\";\r\nimport type { Value } from \"@/types/value\";\r\n\r\nexport interface OtherPanelProps {\r\n\t/** フォームスキーマ */\r\n\tschema: FormSchema;\r\n\t/** 入力データ */\r\n\tvalues: Record<string, Value>;\r\n\t/** スキーマ変更時のコールバック */\r\n\tonSchemaChange: (newSchema: FormSchema) => void;\r\n\t/** 入力データ変更時のコールバック */\r\n\tonValuesChange: (newValues: Record<string, Value>) => void;\r\n}\r\n\r\n/**\r\n * OtherPanel\r\n * その他の設定の統合パネル\r\n * - ImportExportPanel: スキーマ・値のインポート/エクスポート\r\n */\r\nexport const OtherPanel = ({\r\n\tschema,\r\n\tvalues,\r\n\tonSchemaChange,\r\n\tonValuesChange,\r\n}: OtherPanelProps) => {\r\n\treturn (\r\n\t\t<TabPanel>\r\n\t\t\t<ImportExportPanel\r\n\t\t\t\tschema={schema}\r\n\t\t\t\tvalues={values}\r\n\t\t\t\tonSchemaChange={onSchemaChange}\r\n\t\t\t\tonValuesChange={onValuesChange}\r\n\t\t\t/>\r\n\t\t</TabPanel>\r\n\t);\r\n};\r\n\r\nOtherPanel.displayName = \"OtherPanel\";\r\n","/**\r\n * @file PalettePanel.tsx\r\n * @description ブロック挿入用パレットパネル\r\n * ブロック未選択時にサイドバーに表示される\r\n */\r\n\r\nimport { useCallback, useMemo, useState } from \"react\";\r\n\r\nimport styles from \"./PalettePanel.module.css\";\r\n\r\nimport { createBlock } from \"@/plugin/utils/block\";\r\nimport { NoteMode } from \"@/types/mode\";\r\nimport { globalDragStore } from \"@/utils/GlobalDragStore\";\r\n\r\nimport type { BlockPlugin } from \"@/plugin\";\r\n\r\nexport interface PalettePanelProps {\r\n\t/** 利用可能なプラグイン一覧 */\r\n\tplugins: BlockPlugin[];\r\n\t/** カスタムクラス名 */\r\n\tclassName?: string;\r\n}\r\n\r\n/**\r\n * PalettePanel\r\n * ブロックをドラッグ&ドロップで挿入するためのパレット\r\n */\r\nexport const PalettePanel = ({ plugins, className }: PalettePanelProps) => {\r\n\t// ドラッグ中のゴースト表示用の状態\r\n\tconst [dragState, setDragState] = useState<{\r\n\t\tplugin: BlockPlugin;\r\n\t\tmousePos: { x: number; y: number };\r\n\t\tisOverCanvas: boolean;\r\n\t} | null>(null);\r\n\r\n\tconst handleDragStart = useCallback(\r\n\t\t(plugin: BlockPlugin, initialPos: { x: number; y: number }) => {\r\n\t\t\tsetDragState({ plugin, mousePos: initialPos, isOverCanvas: false });\r\n\r\n\t\t\t// マウス移動を追跡\r\n\t\t\tconst handleMove = (e: PointerEvent) => {\r\n\t\t\t\t// マウス位置の要素を取得してキャンバス上かチェック\r\n\t\t\t\tconst elementUnderMouse = document.elementFromPoint(\r\n\t\t\t\t\te.clientX,\r\n\t\t\t\t\te.clientY,\r\n\t\t\t\t);\r\n\t\t\t\tconst isOverCanvas = !!elementUnderMouse?.closest(\r\n\t\t\t\t\t'[data-testid=\"interaction-layer\"]',\r\n\t\t\t\t);\r\n\r\n\t\t\t\tsetDragState((prev) =>\r\n\t\t\t\t\tprev\r\n\t\t\t\t\t\t? {\r\n\t\t\t\t\t\t\t\t...prev,\r\n\t\t\t\t\t\t\t\tmousePos: { x: e.clientX, y: e.clientY },\r\n\t\t\t\t\t\t\t\tisOverCanvas,\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t: null,\r\n\t\t\t\t);\r\n\t\t\t};\r\n\r\n\t\t\t// ドラッグ終了\r\n\t\t\tconst handleUp = () => {\r\n\t\t\t\tsetDragState(null);\r\n\t\t\t\twindow.removeEventListener(\"pointermove\", handleMove);\r\n\t\t\t\twindow.removeEventListener(\"pointerup\", handleUp);\r\n\t\t\t};\r\n\r\n\t\t\twindow.addEventListener(\"pointermove\", handleMove);\r\n\t\t\twindow.addEventListener(\"pointerup\", handleUp);\r\n\t\t},\r\n\t\t[],\r\n\t);\r\n\r\n\treturn (\r\n\t\t<>\r\n\t\t\t<div className={`${styles.container} ${className || \"\"}`}>\r\n\t\t\t\t<div className={styles.paletteItems}>\r\n\t\t\t\t\t{plugins.map((plugin) => (\r\n\t\t\t\t\t\t<PaletteItem\r\n\t\t\t\t\t\t\tkey={plugin.kind}\r\n\t\t\t\t\t\t\tplugin={plugin}\r\n\t\t\t\t\t\t\tonDragStart={handleDragStart}\r\n\t\t\t\t\t\t/>\r\n\t\t\t\t\t))}\r\n\t\t\t\t</div>\r\n\t\t\t</div>\r\n\r\n\t\t\t{/* \r\n\t\t\t\tドラッグ中のゴースト表示(キャンバス外のみ)\r\n\t\t\t\tNOTE: キャンバス内に入ったらInteractionLayerのInsertGhostが表示されるため、\r\n\t\t\t\tここではキャンバス外(isOverCanvas=false)の時だけ表示する。\r\n\t\t\t*/}\r\n\t\t\t{dragState && !dragState.isOverCanvas && (\r\n\t\t\t\t<DragGhost plugin={dragState.plugin} mousePos={dragState.mousePos} />\r\n\t\t\t)}\r\n\t\t</>\r\n\t);\r\n};\r\n\r\nPalettePanel.displayName = \"PalettePanel\";\r\n\r\n/**\r\n * PaletteItem\r\n * 個々のブロックアイテム\r\n */\r\ninterface PaletteItemProps {\r\n\tplugin: BlockPlugin;\r\n\tonDragStart: (\r\n\t\tplugin: BlockPlugin,\r\n\t\tinitialPos: { x: number; y: number },\r\n\t) => void;\r\n}\r\n\r\nconst PaletteItem = ({ plugin, onDragStart }: PaletteItemProps) => {\r\n\t// プレビュー用のブロックオブジェクトを作成\r\n\tconst previewBlock = useMemo(() => {\r\n\t\treturn createBlock(\r\n\t\t\tplugin,\r\n\t\t\t{\r\n\t\t\t\tx: 0,\r\n\t\t\t\ty: 0,\r\n\t\t\t\tw: plugin.meta.defaultSize.w,\r\n\t\t\t\th: plugin.meta.defaultSize.h,\r\n\t\t\t},\r\n\t\t\t{}, // overrideProps\r\n\t\t);\r\n\t}, [plugin]);\r\n\r\n\t// プレビュー表示用のデフォルト値\r\n\tconst previewValue = useMemo(() => {\r\n\t\t// validateValue が存在する場合のみ使用\r\n\t\tif (plugin.validateValue) {\r\n\t\t\treturn plugin.validateValue(undefined, previewBlock.props);\r\n\t\t}\r\n\t\treturn undefined;\r\n\t}, [plugin, previewBlock.props]);\r\n\r\n\tconst handlePointerDown = useCallback(\r\n\t\t(e: React.PointerEvent) => {\r\n\t\t\te.preventDefault();\r\n\r\n\t\t\t// 1. グローバルストアにセット\r\n\t\t\tglobalDragStore.start(plugin.kind, plugin.meta.defaultSize);\r\n\r\n\t\t\t// 2. ドラッグゴースト表示開始\r\n\t\t\tonDragStart(plugin, { x: e.clientX, y: e.clientY });\r\n\r\n\t\t\t// 3. どこで離してもドラッグ終了するように監視\r\n\t\t\tconst handleWindowUp = () => {\r\n\t\t\t\tglobalDragStore.end();\r\n\t\t\t\twindow.removeEventListener(\"pointerup\", handleWindowUp);\r\n\t\t\t};\r\n\t\t\twindow.addEventListener(\"pointerup\", handleWindowUp);\r\n\t\t},\r\n\t\t[plugin, onDragStart],\r\n\t);\r\n\r\n\treturn (\r\n\t\t<div className={styles.item}>\r\n\t\t\t{/* ドラッグ可能なヘッダー部分 */}\r\n\t\t\t<button\r\n\t\t\t\ttype=\"button\"\r\n\t\t\t\tonPointerDown={handlePointerDown}\r\n\t\t\t\tclassName={styles.itemName}\r\n\t\t\t\taria-label={`${plugin.meta.displayName}ブロックを追加`}\r\n\t\t\t>\r\n\t\t\t\t{plugin.meta.displayName}\r\n\t\t\t</button>\r\n\t\t\t{/* プレビュー部分(非インタラクティブ) */}\r\n\t\t\t<div\r\n\t\t\t\tclassName={styles.itemPreview}\r\n\t\t\t\tonPointerDown={handlePointerDown}\r\n\t\t\t\taria-hidden=\"true\"\r\n\t\t\t>\r\n\t\t\t\t<plugin.Renderer\r\n\t\t\t\t\tid={previewBlock.id}\r\n\t\t\t\t\tprops={previewBlock.props}\r\n\t\t\t\t\tvalue={previewValue}\r\n\t\t\t\t\tonChange={() => {\r\n\t\t\t\t\t\t/* プレビューなので変更不可 */\r\n\t\t\t\t\t}}\r\n\t\t\t\t\treadOnly={true}\r\n\t\t\t\t\tmode={NoteMode.FORM}\r\n\t\t\t\t/>\r\n\t\t\t</div>\r\n\t\t</div>\r\n\t);\r\n};\r\n\r\nPaletteItem.displayName = \"PaletteItem\";\r\n\r\n/**\r\n * DragGhost\r\n * ドラッグ中のゴースト表示(position: fixed)\r\n * キャンバス外でのみ表示される\r\n */\r\ninterface DragGhostProps {\r\n\tplugin: BlockPlugin;\r\n\tmousePos: { x: number; y: number };\r\n}\r\n\r\nconst DragGhost = ({ plugin, mousePos }: DragGhostProps) => {\r\n\t// ゴースト用のブロックオブジェクトを作成\r\n\tconst ghostBlock = useMemo(() => {\r\n\t\treturn createBlock(\r\n\t\t\tplugin,\r\n\t\t\t{\r\n\t\t\t\tx: 0,\r\n\t\t\t\ty: 0,\r\n\t\t\t\tw: plugin.meta.defaultSize.w,\r\n\t\t\t\th: plugin.meta.defaultSize.h,\r\n\t\t\t},\r\n\t\t\t{},\r\n\t\t);\r\n\t}, [plugin]);\r\n\r\n\t// ゴースト表示用のデフォルト値\r\n\tconst ghostValue = useMemo(() => {\r\n\t\tif (plugin.validateValue) {\r\n\t\t\treturn plugin.validateValue(undefined, ghostBlock.props);\r\n\t\t}\r\n\t\treturn undefined;\r\n\t}, [plugin, ghostBlock.props]);\r\n\r\n\t// ゴーストのサイズ(仮の固定サイズ、実際はgetBlockRectPxで計算すべき)\r\n\tconst ghostSize = {\r\n\t\twidth: plugin.meta.defaultSize.w * 50, // 仮の計算(グリッド1単位=50px想定)\r\n\t\theight: plugin.meta.defaultSize.h * 50,\r\n\t};\r\n\r\n\treturn (\r\n\t\t<div\r\n\t\t\tdata-testid=\"palette-drag-ghost\"\r\n\t\t\tstyle={{\r\n\t\t\t\tposition: \"fixed\",\r\n\t\t\t\tleft: `${mousePos.x - ghostSize.width / 2}px`,\r\n\t\t\t\ttop: `${mousePos.y - ghostSize.height / 2}px`,\r\n\t\t\t\twidth: `${ghostSize.width}px`,\r\n\t\t\t\theight: `${ghostSize.height}px`,\r\n\t\t\t\tpointerEvents: \"none\",\r\n\t\t\t\topacity: 0.5,\r\n\t\t\t\tfilter: \"grayscale(50%)\",\r\n\t\t\t\tzIndex: 9999,\r\n\t\t\t\tborder: \"2px dashed #3b82f6\",\r\n\t\t\t\tbackgroundColor: \"#fff\",\r\n\t\t\t}}\r\n\t\t>\r\n\t\t\t<plugin.Renderer\r\n\t\t\t\tid={ghostBlock.id}\r\n\t\t\t\tprops={ghostBlock.props}\r\n\t\t\t\tvalue={ghostValue}\r\n\t\t\t\tonChange={() => {}}\r\n\t\t\t\treadOnly={true}\r\n\t\t\t\tmode={NoteMode.FORM}\r\n\t\t\t/>\r\n\t\t</div>\r\n\t);\r\n};\r\n\r\nDragGhost.displayName = \"DragGhost\";\r\n","/**\r\n * @file Sidebar.tsx\r\n * @description プロパティパネルとパレットを切り替えるサイドバー\r\n */\r\n\r\nimport { useMemo } from \"react\";\r\n\r\nimport { BlockPropertyPanel } from \"../BlockPropertyPanel\";\r\nimport { CanvasPanel } from \"../CanvasPanel\";\r\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from \"../components/Tabs\";\r\nimport { OtherPanel } from \"../OtherPanel\";\r\nimport { PalettePanel } from \"../PalettePanel\";\r\nimport styles from \"./Sidebar.module.css\";\r\n\r\nimport type { BlockPlugin } from \"@/plugin\";\r\nimport type { Block } from \"@/types/block\";\r\nimport type { FormSchema } from \"@/types/schema\";\r\nimport type { Value } from \"@/types/value\";\r\n\r\nexport interface SidebarProps {\r\n\t/** 全ブロック */\r\n\tblocks: Block[];\r\n\t/** 選択中のブロックID一覧 */\r\n\tselectedBlockIds: string[];\r\n\t/** プラグインレジストリ */\r\n\tpluginRegistry: Record<string, BlockPlugin>;\r\n\t/** ブロック更新時のコールバック */\r\n\tonUpdateBlocks: (updates: Record<string, Partial<Block>>) => void;\r\n\t/** フォームスキーマ (CanvasPanel/OtherPanelで使用) */\r\n\tschema: FormSchema;\r\n\t/** 入力データ (OtherPanelで使用) */\r\n\tvalues: Record<string, Value>;\r\n\t/** スキーマ変更時のコールバック */\r\n\tonSchemaChange: (newSchema: FormSchema) => void;\r\n\t/** 入力データ変更時のコールバック */\r\n\tonValuesChange: (newValues: Record<string, Value>) => void;\r\n\t/** グリッドサイズ (LayoutPanelで使用) */\r\n\tgridSize?: { cols: number; rows: number };\r\n\t/** カスタムクラス名 */\r\n\tclassName?: string;\r\n}\r\n\r\n/**\r\n * Sidebar\r\n * タブ切り替え機能を持つサイドバー\r\n * - ブロックタブ: BlockPropertyPanel / PalettePanel\r\n * - キャンバスタブ: CanvasPanel (用紙設定、マージン設定、グリッド設定、ブロック順序)\r\n * - その他タブ: OtherPanel (スキーマ/値のインポート/エクスポート)\r\n */\r\nexport const Sidebar = ({\r\n\tblocks,\r\n\tselectedBlockIds,\r\n\tpluginRegistry,\r\n\tonUpdateBlocks,\r\n\tschema,\r\n\tvalues,\r\n\tonSchemaChange,\r\n\tonValuesChange,\r\n\tgridSize,\r\n\tclassName,\r\n}: SidebarProps) => {\r\n\t// 利用可能なプラグイン一覧\r\n\tconst availablePlugins = useMemo(\r\n\t\t() => Object.values(pluginRegistry),\r\n\t\t[pluginRegistry],\r\n\t);\r\n\r\n\t// 選択中のブロック一覧\r\n\tconst selectedBlocks = useMemo(\r\n\t\t() => blocks.filter((block) => selectedBlockIds.includes(block.id)),\r\n\t\t[blocks, selectedBlockIds],\r\n\t);\r\n\r\n\t// ブロックが選択されているかどうか\r\n\tconst hasSelection = selectedBlockIds.length > 0;\r\n\r\n\treturn (\r\n\t\t<div\r\n\t\t\tclassName={`${styles.container} ${className || \"\"}`}\r\n\t\t\tdata-sidebar=\"true\"\r\n\t\t>\r\n\t\t\t<Tabs defaultValue=\"block\" variant=\"default\">\r\n\t\t\t\t<TabsList className={styles.tabHeader}>\r\n\t\t\t\t\t<TabsTrigger value=\"block\">ブロック</TabsTrigger>\r\n\t\t\t\t\t<TabsTrigger value=\"canvas\">キャンバス</TabsTrigger>\r\n\t\t\t\t\t<TabsTrigger value=\"other\">その他</TabsTrigger>\r\n\t\t\t\t</TabsList>\r\n\r\n\t\t\t\t<TabsContent value=\"block\" className={styles.tabContent}>\r\n\t\t\t\t\t{hasSelection ? (\r\n\t\t\t\t\t\t<BlockPropertyPanel\r\n\t\t\t\t\t\t\tselectedBlocks={selectedBlocks}\r\n\t\t\t\t\t\t\tpluginRegistry={pluginRegistry}\r\n\t\t\t\t\t\t\tonUpdateBlocks={onUpdateBlocks}\r\n\t\t\t\t\t\t\tgridSize={gridSize}\r\n\t\t\t\t\t\t/>\r\n\t\t\t\t\t) : (\r\n\t\t\t\t\t\t<PalettePanel plugins={availablePlugins} />\r\n\t\t\t\t\t)}\r\n\t\t\t\t</TabsContent>\r\n\r\n\t\t\t\t<TabsContent value=\"canvas\" className={styles.tabContent}>\r\n\t\t\t\t\t<CanvasPanel schema={schema} onSchemaChange={onSchemaChange} />\r\n\t\t\t\t</TabsContent>\r\n\r\n\t\t\t\t<TabsContent value=\"other\" className={styles.tabContent}>\r\n\t\t\t\t\t<OtherPanel\r\n\t\t\t\t\t\tschema={schema}\r\n\t\t\t\t\t\tvalues={values}\r\n\t\t\t\t\t\tonSchemaChange={onSchemaChange}\r\n\t\t\t\t\t\tonValuesChange={onValuesChange}\r\n\t\t\t\t\t/>\r\n\t\t\t\t</TabsContent>\r\n\t\t\t</Tabs>\r\n\t\t</div>\r\n\t);\r\n};\r\n\r\nSidebar.displayName = \"Sidebar\";\r\n"],"names":["REACT_ELEMENT_TYPE","REACT_FRAGMENT_TYPE","jsxProd","type","config","maybeKey","key","propName","reactJsxRuntime_production","getComponentNameFromType","REACT_CLIENT_REFERENCE","REACT_PROFILER_TYPE","REACT_STRICT_MODE_TYPE","REACT_SUSPENSE_TYPE","REACT_SUSPENSE_LIST_TYPE","REACT_ACTIVITY_TYPE","REACT_PORTAL_TYPE","REACT_CONTEXT_TYPE","REACT_CONSUMER_TYPE","REACT_FORWARD_REF_TYPE","innerType","REACT_MEMO_TYPE","REACT_LAZY_TYPE","testStringCoercion","value","checkKeyStringCoercion","JSCompiler_inline_result","JSCompiler_temp_const","JSCompiler_inline_result$jscomp$0","getTaskName","name","getOwner","dispatcher","ReactSharedInternals","UnknownOwner","hasValidKey","hasOwnProperty","getter","defineKeyPropWarningGetter","props","displayName","warnAboutAccessingKey","specialPropKeyWarningShown","elementRefGetterWithDeprecationWarning","componentName","didWarnAboutElementRef","ReactElement","owner","debugStack","debugTask","refProp","jsxDEVImpl","isStaticChildren","children","isArrayImpl","validateChildKeys","keys","k","didWarnAboutKeySpread","node","isValidElement","object","React","require$$0","createTask","callStackForError","unknownOwnerDebugStack","unknownOwnerDebugTask","reactJsxRuntime_development","trackActualOwner","jsxRuntimeModule","require$$1","HorizontalAlign","VerticalAlign","Select","onChange","readOnly","options","placeholder","width","height","handleChange","useCallback","e","selectedValue","option","opt","displayValue","hasValue","containerStyle","elementStyle","styles","jsx","alignmentDefinition","Checkbox","propLabel","label","jsxs","parseColor","hexMatch","hex","r","g","b","a","rgbaMatch","toHex","rgba","rHex","gHex","bHex","aHex","toRgbaString","isValidHex","COLOR_PALETTE","ColorPalette","onColorSelect","selectedColor","color","index","isUndefined","isSelected","buttonStyle","NumberInput","propMin","propMax","propStep","propInteger","propPlaceholder","propWidth","propHeight","onBlur","min","max","step","integer","text","num","style","RGBAInputs","v","Z_INDEX","BLOCK_SUB_INDEX","ColorPickerPopover","isOpen","onClose","onRgbaChange","popoverRef","useRef","useEffect","handleClickOutside","ColorPicker","showTextInput","propAllowUndefined","allowUndefined","setIsOpen","useState","containerRef","rgbaValues","setRgbaValues","parsed","handleColorButtonClick","prev","textInputValue","setTextInputValue","handleTextChange","confirmTextInput","handleTextBlur","handleTextKeyDown","handlePaletteClick","colorValue","handleRgbaChange","channel","newValue","newRgba","displayColor","colorStyle","DimensionInput","allowedUnits","currentUnit","handleValueChange","inputValue","effectiveMin","handleBlur","handleUnitChange","newUnit","displayUnit","u","TabPanel","emptyMessage","className","TabsContext","createContext","Tabs","defaultValue","propValue","onValueChange","variant","localValue","setLocalValue","TabsList","propStyle","context","useContext","computedStyle","TabsTrigger","disabled","TabsContent","TextInput","propMaxLength","propMultiline","propRows","maxLength","multiline","rows","commonProps","ALL_UNITS","ACTUAL_UNITS","PAPER_UNITS","GRID_UNITS","BORDER_UNITS","FONT_UNITS","PADDING_UNITS","SIZE_UNITS","paddingDefinition","data","universalProperties","DEFAULT_FONT_FAMILY","fontStyleDefinition","createPluginRegistry","plugins","acc","plugin","ImageObjectFit","imageDefinition","MultilineWordWrap","MultilineWhiteSpace","multilineDefinition","placeholderDefinition","sizeDefinition","createInitialProps","initialProps","createBlockId","kind","timestamp","random","createBlock","position","overrideProps","validationDefinition","BlockChangeType","DEFAULT_GRID","LineType","DEFAULT_DPI","assertPositive","assertNonNegative","assertRange","assertInteger","assertFinite","MM_PER_INCH","CM_PER_INCH","PT_PER_INCH","toPx","dpi","mm","cm","inch","pt","px","dim","baseSizePx","_exhaustive","getStrokeDasharray","lineStyle","actualLineWidth","Border","widthPx","heightPx","NoteMode","PaperSizePreset","DEFAULT_PAPER_SIZES","DEFAULT_PAPER_MARGIN","DEFAULT_PAPER","DEFAULT_SCHEMA","ValidationSeverity","BorderRenderer","memo","border","getBlockZIndex","zIndex","getSubZIndex","baseZIndex","subIndex","clampedOffset","getMaxBlockCount","BlockBorder","blockSizePx","borderStyle","blockZIndex","subZIndex","visible","useMemo","overlayStyle","BlockCanvas","backgroundColor","canvasStyle","DEFAULT_GUIDE_LINE","DEFAULT_GUIDE_BORDER","BlockGuideBorder","BlockRendererInner","id","mode","validationState","ref","pluginRendererRef","useImperativeHandle","_a","pluginProps","PluginRendererComponent","ForwardedBlockRenderer","forwardRef","BlockRenderer","getBlockContainerStyle","blockRectPx","BlockContainer","block","onValueBlur","showGuides","showBorder","blockSubZIndex","defaultGuideBorder","pointerEvents","_b","_c","_d","BlockLayer","blocks","pluginRegistry","values","selectedBlockIds","getBlockRectPx","blockRefs","layerStyle","val","BorderOverlay","contentPx","marginLeftPx","marginTopPx","GridCanvas","canvasPx","boxShadow","stringToDimension","str","match","unit","stringsToDimensions","strs","CM_TO_MM","INCH_TO_MM","PT_TO_MM","PX_TO_MM","toMm","dimensionToString","dimensionsToStrings","dims","SUPPORTED_UNITS","convertPxToUnit","pxSize","targetUnit","GridUnitEditor","direction","dimension","currentPxSize","onCancel","setValue","setUnit","inputRef","editorStyle","event","handleSubmit","numValue","handleKeyDown","convertedValue","originalValue","originalPxSize","ratio","GridDimensionLabel","isNearCursor","resizingPxSize","onDimensionChange","isEditing","setIsEditing","labelStyle","handleDoubleClick","handleDimensionChange","newDimension","handleCancel","displayText","Fragment","getGridPathD","colPxs","rowPxs","d","x","y","GridOverlay","gridPosPx","pathData","strokeDasharray","borderWidth","svgStyle","GridResizeHandle","onResizeStart","onResize","onResizeEnd","isDragging","setIsDragging","HANDLE_SIZE","HANDLE_OFFSET","handleStyle","handlePointerDown","initialPos","handlePointerMove","moveEvent","delta","handlePointerUp","upEvent","MarginOverlay","paperPx","marginColor","marginBoxStyle","GridLayer","gridPosPxs","gridDimensions","gridLineStyle","marginFillColor","showGridLines","showMargins","showResizeHandles","showDimensionLabels","onGridResize","ghostLine","setGhostLine","draggingHandle","setDraggingHandle","mousePos","setMousePos","handleMouseMove","rect","handleMouseLeave","shouldShowDimensionLabels","contentWidth","contentHeight","handleResizeStart","resizingPreviewSizes","gridLines","prevStart","prevEnd","prevSize","nextStart","nextEnd","nextSize","handleResize","originalPos","prevLinePos","nextLinePos","MIN_GAP","clampedDelta","minDelta","maxDelta","handleResizeEnd","colPos","rowPos","startPos","endPos","isDraggingAdjacentColumn","centerPos","isDraggingAdjacentRow","GlobalDragStore","__publicField","defaultSize","listener","l","globalDragStore","calculateGridResize","dimensions","deltaPx","totalContentPx","newDimensions","current","next","resizeFrPair","resizeFixedPair","resizeFrAndFixed","totalFr","sum","frToPx","currentPx","nextPx","newCurrentPx","newNextPx","newCurrentFr","newNextFr","fixedSide","totalFixedPx","availableForFrPx","currentFrToPx","fixedDelta","newAvailableForFrPx","pxValue","distributeRemainder","floatPixels","result","accumulatedError","target","rounded","MIN_STEP","MAX_STEP","MIN_WINDOW_PX","MAX_WINDOW_PX","_clamp","lo","hi","getMaxStep","starts","count","total","avg","windowPx","binarySearch","arr","cnt","mid","midValue","findGridIndex","maxStep","last","startValue","nextValue","leftPx","rightPx","steps","gridToMms","contentSizeMm","fixedTotalMm","mmsWithoutFr","remainingMm","mmPerFr","i","mmsToPxs","mms","gridPxsFloat","gridToPxs","removeUndefinedProps","obj","cleaned","getPaperSize","paperSize","orientation","size","preparePrint","cleanupPrint","printElement","element","originalTitle","printStyle","styleElement","executePrint","handleBeforePrint","handleAfterPrint","isBlock","layout","isGridUnit","isDimensionArray","item","isGrid","isPaper","margin","marginSide","isValue","validateSchema","metaData","deserializeSchema","json","error","serializeSchema","schema","pretty","validateValues","deserializeValues","serializeValues","SELECTION_STYLE","RESIZE_HANDLE_STYLE","interactionZIndexs","InteractionMode","ResizeHandle","DragType","InteractionEventType","HANDLES","ResizeHandles","activeHandle","handleSize","offset","cursor","left","top","isActive","SelectionBorder","InteractionBlock","showHandles","selectionStyle","selectBorderZIndex","blockHandlesZIndex","InsertGhost","gridLength","currentGrid","currentMousePx","pluginKind","isOutside","ghostZIndex","ghostRect","tempBlock","tempRect","maxX","maxY","ghostBlock","clampMultipleBlocks","deltaCol","deltaRow","gridCols","gridRows","newX","newY","minX","minY","boundingW","boundingH","newMinX","newMinY","clampedMinX","clampedMinY","actualDeltaCol","actualDeltaRow","MovingGhost","dragTargets","clampedPositions","originalRect","clampedPos","p","calculateResizedLayout","handle","newLayout","maxW","maxShrink","validDCol","maxH","validDRow","ResizeGhost","blockId","DragLayer","draggingState","resizeBlockId","EditingBlockInner","ForwardedEditingBlock","EditingBlock","useInteractionState","initialState","state","setState","newBlockIds","dragTargetIds","gridChanged","SelectionLayer","uniqueSelectedIds","clampBlockToGrid","findBlockAtPoint","point","InteractionLayer","getColIndex","getRowIndex","onBlockChange","scale","editBlockZIndex","dragGhostZIndex","layerRef","editingBlockRef","blockIds","validSelectedIds","scaleFactor","targetId","gridCol","gridRow","isAlreadySelected","newSelectedIds","canvasWidth","canvasHeight","rawX","rawY","clampedX","clampedY","currentCol","currentRow","movedBlocks","newBlock","handlePointerLeave","editingBlock","useGridCalc","paper","grid","canvasWidthMm","canvasHeightMm","marginTopMm","marginBottomMm","marginLeftMm","marginRightMm","contentWidthMm","contentHeightMm","colMms","rowMms","canvasWidthPx","canvasHeightPx","marginBottomPx","marginRightPx","contentWidthPx","contentHeightPx","colPosPxs","rowPosPxs","colMaxStep","colWindowPx","rowMaxStep","rowWindowPx","colIndexer","rowIndexer","paperCanvasPx","paperMarginPx","paperContentPx","w","h","colLines","rowLines","x1","x2","y1","y2","NoteEditBase","NoteEdit","NoteFormBase","onSchemaChange","onSelectionChange","interactionState","handleInteractionChange","paperRef","handleBlockChange","nextBlocks","deletedIds","updated","cleanedStyle","cleanedProps","handleInitValueChange","unsubscribe","dragState","handleGridResize","dimensionIndex","newCols","newRows","handlePointerEnter","draggingItem","NoteForm","NoteViewBase","NoteView","NoteEditorBase","onValuesChange","_","rest","NoteEditor","NotePrintBase","widthMm","heightMm","existingStyle","NotePrint","getCommonValue","path","getValueByPath","firstValue","BackgroundPanel","selectedBlocks","onUpdateBlocks","updates","setNestedValue","update","depth","BorderPanel","edge","prop","newStyle","currentBorder","edgeStyle","previewBorder","firstBlock","validateEdge","renderInputs","triggerStyle","LayoutPanel","gridSize","isMultipleSelection","currentMin","clampedVal","MetaPanel","localId","setLocalId","primaryBlock","handleIdBlur","currentId","newId","handleIdChange","handleReadOnlyChange","PropertyField","propertyKey","definition","Component","isMixed","componentProps","isPropertyDefinition","BlockPropertyPanel","allSameKind","firstKind","groupedProps","groups","propertiesToShow","allPlugins","firstPlugin","firstPluginKeys","entry","propertyConfig","groupName","handlePluginPropertyChange","items","PluginPanels","BlockOrderPanel","onBlocksChange","draggedIndex","setDraggedIndex","dragOverIndex","setDragOverIndex","displayBlocks","handleBringToFront","newBlocks","handleSendToBack","handleBringForward","temp","handleSendBackward","handleDragStart","displayIndex","actualIndex","handleDragEnd","handleDragOver","handleDragLeave","handleDrop","displayDropIndex","actualDraggedIndex","actualDropIndex","draggedBlock","CanvasPanel","handlePaperChange","newPaper","handleGridChange","newGrid","handleBlocksChange","PaperSizePanel","MarginPanel","GridSizePanel","onGridChange","handleColsChange","newColCount","currentColCount","handleRowsChange","newRowCount","currentRowCount","onPaperChange","linkMargins","setLinkMargins","handleLinkChange","checked","handleTopChange","newMargin","handleRightChange","right","handleBottomChange","bottom","handleLeftChange","presetOptions","handlePresetChange","preset","newSize","handleWidthChange","handleHeightChange","isCustom","ImportExportPanel","setError","schemaFileInputRef","valuesFileInputRef","handleExportSchemaFile","blob","url","err","handleExportSchemaClipboard","handleImportSchemaFile","handleSchemaFileChange","file","reader","newSchema","handleImportSchemaClipboard","handleExportValuesFile","handleExportValuesClipboard","handleImportValuesFile","handleValuesFileChange","newValues","handleImportValuesClipboard","OtherPanel","PalettePanel","setDragState","handleMove","elementUnderMouse","isOverCanvas","handleUp","PaletteItem","DragGhost","onDragStart","previewBlock","previewValue","handleWindowUp","ghostValue","ghostSize","Sidebar","availablePlugins","hasSelection"],"mappings":"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","x_google_ignoreList":[0,1,2]}