dishui 0.0.105 → 0.0.106
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/.release-verified.json +2 -2
- package/dist/components/ChoicePicker/index.js +8 -6
- package/dist/components/ChoicePicker/index.js.map +1 -1
- package/dist/components/Column/index.d.ts +3 -2
- package/dist/components/Column/index.js +5 -17
- package/dist/components/Column/index.js.map +1 -1
- package/dist/components/ConfirmDialog/index.d.ts +20 -0
- package/dist/components/ConfirmDialog/index.js +84 -0
- package/dist/components/ConfirmDialog/index.js.map +1 -0
- package/dist/components/DateTimeInput/index.js +28 -26
- package/dist/components/DateTimeInput/index.js.map +1 -1
- package/dist/components/Input/index.js +1 -1
- package/dist/components/Input/index.js.map +1 -1
- package/dist/components/MultipleChoice/index.js +2 -1
- package/dist/components/MultipleChoice/index.js.map +1 -1
- package/dist/components/Row/index.d.ts +3 -2
- package/dist/components/Row/index.js +5 -17
- package/dist/components/Row/index.js.map +1 -1
- package/dist/components/Tab/index.js +80 -0
- package/dist/components/Tab/index.js.map +1 -0
- package/dist/components/Tabs/index.js +28 -33
- package/dist/components/Tabs/index.js.map +1 -1
- package/dist/components/Tabs/tabNavigation.d.ts +2 -0
- package/dist/components/Tabs/tabNavigation.js +14 -0
- package/dist/components/Tabs/tabNavigation.js.map +1 -0
- package/dist/components/pro/CodeEditor/editors/MarkdownEditor.d.ts +1 -1
- package/dist/components/pro/CodeEditor/editors/MarkdownEditor.js +25 -26
- package/dist/components/pro/CodeEditor/editors/MarkdownEditor.js.map +1 -1
- package/dist/components/pro/FileExplorer/Breadcrumb.js +8 -11
- package/dist/components/pro/FileExplorer/Breadcrumb.js.map +1 -1
- package/dist/components/pro/Flow/Flow.js +184 -182
- package/dist/components/pro/Flow/Flow.js.map +1 -1
- package/dist/components/pro/Flow/archify/convert.js +26 -26
- package/dist/components/pro/Flow/archify/convert.js.map +1 -1
- package/dist/components/pro/Flow/hooks/useLayoutActions.js +13 -11
- package/dist/components/pro/Flow/hooks/useLayoutActions.js.map +1 -1
- package/dist/components/pro/RichTextEditor/BubbleToolbar.js +73 -83
- package/dist/components/pro/RichTextEditor/BubbleToolbar.js.map +1 -1
- package/dist/components/pro/RichTextEditor/Toolbar/ColorPicker.d.ts +2 -0
- package/dist/components/pro/RichTextEditor/Toolbar/ColorPicker.js +73 -49
- package/dist/components/pro/RichTextEditor/Toolbar/ColorPicker.js.map +1 -1
- package/dist/components/pro/RichTextEditor/Toolbar/SelectDropdown.d.ts +1 -0
- package/dist/components/pro/RichTextEditor/Toolbar/SelectDropdown.js +12 -14
- package/dist/components/pro/RichTextEditor/Toolbar/SelectDropdown.js.map +1 -1
- package/dist/components/pro/RichTextEditor/extensions/CodeBlockView.js +113 -113
- package/dist/components/pro/RichTextEditor/extensions/CodeBlockView.js.map +1 -1
- package/dist/css.d.ts +1 -0
- package/dist/dishui.css +1 -1
- package/dist/index-nostyled.d.ts +2 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +113 -111
- package/dist/layouts/Sidebar.js +201 -107
- package/dist/layouts/Sidebar.js.map +1 -1
- package/dist/utils/flexLayout.d.ts +5 -0
- package/dist/utils/flexLayout.js +19 -0
- package/dist/utils/flexLayout.js.map +1 -0
- package/package.json +63 -57
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"convert.js","names":[],"sources":["../../../../../src/components/pro/Flow/archify/convert.ts"],"sourcesContent":["/**\n * Convert an Archify spec into a native Flow `FlowDocument`.\n *\n * One converter per diagram type reproduces Archify's fixed layout geometry\n * (constants copied from the reference renderers) so the imported diagram\n * matches the reference artifact, then emits editable Flow nodes/edges/lines.\n *\n * When `meta.animation === \"trace\"`, edges are marked `animated` so the Flow\n * presentation / preview mode plays the traveling gradient pulse.\n */\n\nimport type { FlowDocument, FlowNode, FlowEdge, FlowLine } from '../types';\nimport { ROOT_CANVAS_ID } from '../constants';\nimport type {\n ArchifySpec,\n ArchifyArchitectureSpec,\n ArchifyWorkflowSpec,\n ArchifySequenceSpec,\n ArchifyDataflowSpec,\n ArchifyLifecycleSpec,\n} from './spec';\nimport {\n ARCHIFY_LANE_STROKE,\n ARCHIFY_TEXT_MUTED,\n componentStyle,\n stateStyle,\n variantEdgeStyle,\n messageEdgeStyle,\n} from './palette';\nimport { card, frame, edge, sideHandle, uid } from './build';\n\nfunction isTrace(spec: ArchifySpec): boolean {\n return spec.meta?.animation === 'trace';\n}\n\n/* ========================================================================== */\n/* Architecture */\n/* ========================================================================== */\n\nconst ARCH_GRID = { origin: [40, 80], cols: 4, gapX: 30, gapY: 40, cellW: 130, cellH: 64 };\n\nfunction convertArchitecture(spec: ArchifyArchitectureSpec): FlowDocument {\n const trace = isTrace(spec);\n const grid = { ...ARCH_GRID, ...spec.layout };\n const nodes: FlowNode[] = [];\n const edges: FlowEdge[] = [];\n\n const rect = new Map<string, { x: number; y: number; w: number; h: number }>();\n\n for (const c of spec.components) {\n let x: number;\n let y: number;\n if (Array.isArray(c.pos)) {\n [x, y] = c.pos;\n } else if (Number.isInteger(c.row) && Number.isInteger(c.col)) {\n const stepX = grid.cellW + grid.gapX;\n const stepY = grid.cellH + grid.gapY;\n x = grid.origin[0] + (c.col ?? 0) * stepX;\n y = grid.origin[1] + (c.row ?? 0) * stepY;\n } else {\n x = grid.origin[0];\n y = grid.origin[1];\n }\n const w = c.size?.[0] ?? grid.cellW;\n const h = c.size?.[1] ?? grid.cellH;\n rect.set(c.id, { x, y, w, h });\n const style = componentStyle(c.type);\n nodes.push(\n card({\n id: c.id,\n x,\n y,\n width: w,\n height: h,\n label: c.label,\n sublabel: c.sublabel,\n tag: c.tag,\n fill: style.fill,\n stroke: style.stroke,\n text: style.text,\n sub: style.sub,\n }),\n );\n }\n\n // Boundaries wrap their member components with padding, rendered behind.\n for (const [i, b] of (spec.boundaries ?? []).entries()) {\n const members = b.wraps.map((id) => rect.get(id)).filter(Boolean) as Array<{\n x: number;\n y: number;\n w: number;\n h: number;\n }>;\n if (members.length === 0) continue;\n const pad = b.pad ?? 26;\n const minX = Math.min(...members.map((m) => m.x)) - pad;\n const minY = Math.min(...members.map((m) => m.y)) - pad - 14;\n const maxX = Math.max(...members.map((m) => m.x + m.w)) + pad;\n const maxY = Math.max(...members.map((m) => m.y + m.h)) + pad;\n nodes.push(\n frame({\n id: `boundary_${i}_${uid('b')}`,\n x: minX,\n y: minY,\n width: maxX - minX,\n height: maxY - minY,\n label: b.label,\n stroke: b.kind === 'security-group' ? '#fb7185' : ARCHIFY_LANE_STROKE,\n borderStyle: 'dashed',\n labelColor: b.kind === 'security-group' ? '#fb7185' : ARCHIFY_TEXT_MUTED,\n zIndex: -10 + i,\n }),\n );\n }\n\n for (const conn of spec.connections ?? []) {\n const style = variantEdgeStyle(conn.variant);\n edges.push(\n edge({\n id: conn.id,\n source: conn.from,\n target: conn.to,\n sourceHandle: sideHandle(conn.fromSide),\n targetHandle: sideHandle(conn.toSide),\n label: conn.label,\n color: style.color,\n width: conn.width ?? style.width,\n lineStyle: style.lineStyle,\n animated: trace,\n waypoints: conn.via?.map(([x, y]) => ({ x, y })),\n }),\n );\n }\n\n return wrap(nodes, edges, [], spec.meta.title);\n}\n\n/* ========================================================================== */\n/* Workflow */\n/* ========================================================================== */\n\nconst WF = {\n laneX: 40,\n laneY: 52,\n laneW: 640,\n laneH: 104,\n laneGap: 20,\n laneTitleH: 30,\n colXs: [88, 220, 300, 430, 500, 625],\n nodeW: 92,\n nodeH: 52,\n};\n\nfunction convertWorkflow(spec: ArchifyWorkflowSpec): FlowDocument {\n const trace = isTrace(spec);\n const nodes: FlowNode[] = [];\n const edges: FlowEdge[] = [];\n\n const laneIndex = new Map(spec.lanes.map((l, i) => [l.id, i]));\n const laneTop = (id: string) =>\n WF.laneY + (laneIndex.get(id) ?? 0) * (WF.laneH + WF.laneGap);\n\n // Lane frames (behind everything).\n for (const lane of spec.lanes) {\n const top = laneTop(lane.id);\n nodes.push(\n frame({\n id: `lane_${lane.id}`,\n x: WF.laneX,\n y: top,\n width: WF.laneW,\n height: WF.laneH,\n label: lane.label,\n stroke: lane.variant === 'exception' ? '#fb7185' : ARCHIFY_LANE_STROKE,\n labelColor: lane.variant === 'exception' ? '#fb7185' : ARCHIFY_TEXT_MUTED,\n zIndex: -20,\n }),\n );\n }\n\n // Phase bands (thin frames spanning columns, drawn just above lanes).\n for (const [i, phase] of (spec.phases ?? []).entries()) {\n const x0 = WF.colXs[phase.fromCol] - WF.nodeW / 2 - 12;\n const x1 = WF.colXs[phase.toCol] + WF.nodeW / 2 + 12;\n nodes.push(\n frame({\n id: `phase_${phase.id}`,\n x: x0,\n y: WF.laneY - 34,\n width: x1 - x0,\n height: 26,\n label: phase.label,\n stroke: variantEdgeStyle(phase.variant).color,\n labelColor: ARCHIFY_TEXT_MUTED,\n borderStyle: 'none',\n zIndex: -15 + i,\n }),\n );\n }\n\n // Workflow groups (nested emphasis frames inside a lane).\n for (const [i, g] of (spec.groups ?? []).entries()) {\n const top = laneTop(g.lane);\n const x0 = WF.colXs[g.fromCol] - WF.nodeW / 2 - 8;\n const x1 = WF.colXs[g.toCol] + WF.nodeW / 2 + 8;\n nodes.push(\n frame({\n id: `wfgroup_${g.id}`,\n x: x0,\n y: top + WF.laneTitleH - 6,\n width: x1 - x0,\n height: WF.laneH - WF.laneTitleH,\n label: g.label,\n stroke: variantEdgeStyle(g.variant).color,\n labelColor: ARCHIFY_TEXT_MUTED,\n borderStyle: 'dashed',\n zIndex: -12 + i,\n }),\n );\n }\n\n for (const n of spec.nodes) {\n const width = n.width ?? WF.nodeW;\n const height = n.height ?? (n.tag ? 68 : WF.nodeH);\n const cx = WF.colXs[n.col] ?? WF.colXs[WF.colXs.length - 1];\n const contentH = WF.laneH - WF.laneTitleH;\n const y = laneTop(n.lane) + WF.laneTitleH + (contentH - height) / 2 + (n.yOffset ?? 0);\n const style = componentStyle(n.type);\n nodes.push(\n card({\n id: n.id,\n x: cx - width / 2,\n y,\n width,\n height,\n label: n.label,\n sublabel: n.sublabel,\n tag: n.tag,\n fill: style.fill,\n stroke: style.stroke,\n text: style.text,\n sub: style.sub,\n fontSize: 12,\n }),\n );\n }\n\n const mainPath = new Set<string>();\n const mp = spec.mainPath ?? [];\n for (let i = 0; i < mp.length - 1; i++) mainPath.add(`${mp[i]}->${mp[i + 1]}`);\n\n for (const e of spec.edges) {\n const onMain = mainPath.has(`${e.from}->${e.to}`);\n const style = variantEdgeStyle(e.variant ?? (onMain ? 'emphasis' : 'default'));\n edges.push(\n edge({\n id: e.id,\n source: e.from,\n target: e.to,\n sourceHandle: sideHandle(e.fromSide),\n targetHandle: sideHandle(e.toSide),\n label: e.label,\n color: e.role === 'error' ? '#fb7185' : style.color,\n width: e.width ?? style.width,\n lineStyle: e.role === 'error' ? 'dashed' : style.lineStyle,\n animated: trace && onMain,\n waypoints: e.via?.map(([x, y]) => ({ x, y })),\n }),\n );\n }\n\n return wrap(nodes, edges, [], spec.meta.title);\n}\n\n/* ========================================================================== */\n/* Sequence */\n/* ========================================================================== */\n\nfunction convertSequence(spec: ArchifySequenceSpec): FlowDocument {\n const nodes: FlowNode[] = [];\n const edges: FlowEdge[] = [];\n const lines: FlowLine[] = [];\n\n const viewBox = spec.meta.viewBox ?? [920, 760];\n const sideMargin = 62;\n const participantW = 86;\n const colGap = 108;\n const topY = 72;\n const participantH = 54;\n const lifelineTop = 142;\n const lifelineBottom = viewBox[1] - 65;\n\n const cx = (i: number) => sideMargin + i * colGap;\n const partX = new Map<string, number>();\n\n spec.participants.forEach((p, i) => {\n const x = cx(i);\n partX.set(p.id, x);\n const style = componentStyle(p.type);\n nodes.push(\n card({\n id: p.id,\n x: x - participantW / 2,\n y: topY,\n width: participantW,\n height: participantH,\n label: p.label,\n sublabel: p.sublabel,\n fill: style.fill,\n stroke: style.stroke,\n text: style.text,\n sub: style.sub,\n fontSize: 11,\n zIndex: 5,\n }),\n );\n // Lifeline (dashed vertical guide beneath each participant).\n lines.push({\n id: `lifeline_${p.id}`,\n type: 'straight',\n points: [\n { x, y: lifelineTop },\n { x, y: lifelineBottom },\n ],\n strokeColor: ARCHIFY_LANE_STROKE,\n strokeWidth: 1,\n lineStyle: 'dashed',\n markerEnd: 'none',\n zIndex: -5,\n });\n });\n\n // Segment frames (labelled bands over ranges of the timeline).\n for (const [i, seg] of (spec.segments ?? []).entries()) {\n nodes.push(\n frame({\n id: `segment_${i}`,\n x: 48,\n y: seg.from,\n width: viewBox[0] - 96,\n height: seg.to - seg.from,\n label: seg.label,\n stroke: ARCHIFY_LANE_STROKE,\n labelColor: ARCHIFY_TEXT_MUTED,\n borderStyle: 'dashed',\n zIndex: -10,\n }),\n );\n }\n\n // Activation bars (thin vertical rects on a participant lifeline).\n for (const [i, act] of (spec.activations ?? []).entries()) {\n const x = partX.get(act.participant);\n if (x === undefined) continue;\n const style = componentStyle(act.type ?? 'backend');\n nodes.push({\n id: `activation_${i}_${act.participant}`,\n type: 'shapeRect',\n position: { x: x - 5, y: act.from },\n width: 10,\n height: Math.max(6, act.to - act.from),\n zIndex: 1,\n data: {\n label: '',\n fill: style.fill,\n stroke: style.stroke,\n strokeWidth: 1,\n color: style.text,\n fontSize: 10,\n borderStyle: 'solid',\n attributes: [],\n },\n });\n }\n\n // Messages become horizontal arrow lines at their y with a label above.\n for (const m of spec.messages) {\n const fromX = partX.get(m.from);\n const toX = partX.get(m.to);\n if (fromX === undefined || toX === undefined) continue;\n const dir = toX > fromX ? 1 : -1;\n const start = fromX + dir * 7;\n const end = toX - dir * 7;\n const style = messageEdgeStyle(m.variant);\n lines.push({\n id: m.id ?? uid('msg'),\n type: 'arrow',\n points: [\n { x: start, y: m.y },\n { x: end, y: m.y },\n ],\n strokeColor: style.color,\n strokeWidth: style.width,\n lineStyle: style.lineStyle,\n markerEnd: m.variant === 'return' ? 'arrow' : 'arrowclosed',\n zIndex: 3,\n });\n // Label as a tiny transparent text node centered above the arrow.\n nodes.push({\n id: `mlabel_${m.id ?? uid('m')}`,\n type: 'textLabel',\n position: { x: (start + end) / 2 - 70, y: m.y - 22 },\n width: 140,\n height: 16,\n zIndex: 4,\n data: {\n label: m.label,\n fill: 'transparent',\n stroke: 'transparent',\n strokeWidth: 0,\n color: style.color,\n labelColor: style.color,\n fontSize: 11,\n attributes: [],\n },\n });\n }\n\n return wrap(nodes, edges, lines, spec.meta.title);\n}\n\n/* ========================================================================== */\n/* Dataflow */\n/* ========================================================================== */\n\nconst DF = {\n stageY: 46,\n stageH: 36,\n stageBottomPad: 74,\n leftX: 100,\n colGap: 215,\n stageW: 168,\n nodeW: 112,\n nodeH: 58,\n rowYs: [128, 242, 356, 470, 584],\n};\n\nfunction convertDataflow(spec: ArchifyDataflowSpec): FlowDocument {\n const trace = isTrace(spec);\n const nodes: FlowNode[] = [];\n const edges: FlowEdge[] = [];\n\n const viewBox = spec.meta.viewBox ?? [940, 720];\n const stageX = (i: number) => DF.leftX + i * DF.colGap;\n\n // Stage frames (tall vertical bands).\n for (const [i, stage] of spec.stages.entries()) {\n nodes.push(\n frame({\n id: `stage_${i}`,\n x: stageX(i) - DF.stageW / 2,\n y: DF.stageY,\n width: DF.stageW,\n height: viewBox[1] - DF.stageY - DF.stageBottomPad,\n label: stage.label,\n stroke: ARCHIFY_LANE_STROKE,\n labelColor: ARCHIFY_TEXT_MUTED,\n borderStyle: 'dashed',\n zIndex: -10,\n }),\n );\n }\n\n for (const n of spec.nodes) {\n const width = n.width ?? DF.nodeW;\n const height = n.height ?? DF.nodeH;\n const cx = stageX(n.stage);\n const y = (DF.rowYs[n.row] ?? DF.rowYs[DF.rowYs.length - 1]) + (n.yOffset ?? 0);\n const style = componentStyle(n.type);\n nodes.push(\n card({\n id: n.id,\n x: cx - width / 2,\n y,\n width,\n height,\n label: n.label,\n sublabel: n.sublabel,\n tag: n.tag,\n fill: style.fill,\n stroke: style.stroke,\n text: style.text,\n sub: style.sub,\n fontSize: 12,\n }),\n );\n }\n\n for (const f of spec.flows) {\n const style = variantEdgeStyle(f.variant);\n edges.push(\n edge({\n id: f.id,\n source: f.from,\n target: f.to,\n sourceHandle: sideHandle(f.fromSide),\n targetHandle: sideHandle(f.toSide),\n label: f.label,\n color: style.color,\n width: f.width ?? style.width,\n lineStyle: style.lineStyle,\n animated: trace && f.variant === 'emphasis',\n waypoints: f.via?.map(([x, y]) => ({ x, y })),\n }),\n );\n }\n\n return wrap(nodes, edges, [], spec.meta.title);\n}\n\n/* ========================================================================== */\n/* Lifecycle */\n/* ========================================================================== */\n\nconst LC = {\n phaseY: 126,\n eventY: 278,\n outcomeY: 450,\n phaseW: 118,\n phaseH: 62,\n eventW: 126,\n eventH: 58,\n outcomeW: 118,\n outcomeH: 58,\n phaseXs: [94, 248, 402, 556, 710],\n eventXs: [402, 556, 710],\n outcomeXs: [402, 556, 710],\n};\n\nfunction lifecycleBand(lane: string): 'phase' | 'event' | 'outcome' {\n if (lane === 'main') return 'phase';\n if (lane === 'terminal') return 'outcome';\n return 'event';\n}\n\nfunction convertLifecycle(spec: ArchifyLifecycleSpec): FlowDocument {\n const trace = isTrace(spec);\n const nodes: FlowNode[] = [];\n const edges: FlowEdge[] = [];\n\n const viewBox = spec.meta.viewBox ?? [980, 660];\n\n // Band frames give the three horizontal groupings some structure.\n const laneLabel = new Map(spec.lanes.map((l) => [l.id, l.label]));\n const bandRows: Array<{ band: 'phase' | 'event' | 'outcome'; y: number; h: number; label: string }> = [\n { band: 'phase', y: LC.phaseY - 26, h: LC.phaseH + 40, label: laneLabel.get('main') ?? 'Lifecycle phases' },\n { band: 'event', y: LC.eventY - 26, h: LC.eventH + 40, label: 'Interruptions + Recovery' },\n { band: 'outcome', y: LC.outcomeY - 26, h: LC.outcomeH + 40, label: laneLabel.get('terminal') ?? 'Terminal exits' },\n ];\n for (const [i, b] of bandRows.entries()) {\n nodes.push(\n frame({\n id: `band_${b.band}`,\n x: 40,\n y: b.y,\n width: viewBox[0] - 80,\n height: b.h,\n label: `0${i + 1} / ${b.label}`,\n stroke: ARCHIFY_LANE_STROKE,\n labelColor: ARCHIFY_TEXT_MUTED,\n borderStyle: 'dashed',\n zIndex: -10,\n }),\n );\n }\n\n for (const s of spec.states) {\n const band = lifecycleBand(s.lane);\n const isPhase = band === 'phase';\n const isOutcome = band === 'outcome';\n const width = s.width ?? (isPhase ? LC.phaseW : isOutcome ? LC.outcomeW : LC.eventW);\n const height = s.height ?? (isPhase ? LC.phaseH : isOutcome ? LC.outcomeH : LC.eventH);\n const xs = isPhase ? LC.phaseXs : isOutcome ? LC.outcomeXs : LC.eventXs;\n const cx = xs[s.col] ?? xs[xs.length - 1];\n const y = (isPhase ? LC.phaseY : isOutcome ? LC.outcomeY : LC.eventY) + (s.yOffset ?? 0);\n const style = stateStyle(s.type);\n nodes.push(\n card({\n id: s.id,\n x: cx - width / 2,\n y,\n width,\n height,\n label: s.label,\n sublabel: s.sublabel,\n tag: s.tag ?? s.step,\n fill: style.fill,\n stroke: style.stroke,\n text: style.text,\n sub: style.sub,\n fontSize: 12,\n }),\n );\n }\n\n // Order states along the main lane to build the primary rail. Archify draws\n // this rail decoratively (not as explicit transitions), so synthesize edges\n // between consecutive phase states, connecting right-to-left across columns.\n const mainStates = spec.states\n .filter((s) => s.lane === 'main')\n .sort((a, b) => a.col - b.col);\n const explicitPairs = new Set(spec.transitions.map((t) => `${t.from}->${t.to}`));\n for (let i = 0; i < mainStates.length - 1; i++) {\n const from = mainStates[i];\n const to = mainStates[i + 1];\n // Skip if the author already provided this exact transition.\n if (explicitPairs.has(`${from.id}->${to.id}`)) continue;\n edges.push(\n edge({\n id: `mainrail_${from.id}_${to.id}`,\n source: from.id,\n target: to.id,\n sourceHandle: sideHandle('right'),\n targetHandle: sideHandle('left'),\n label: undefined,\n color: variantEdgeStyle('emphasis').color,\n width: 2.2,\n lineStyle: 'solid',\n animated: trace,\n }),\n );\n }\n\n const mainPairs = new Set<string>();\n for (let i = 0; i < mainStates.length - 1; i++) {\n mainPairs.add(`${mainStates[i].id}->${mainStates[i + 1].id}`);\n }\n\n for (const t of spec.transitions) {\n const style = variantEdgeStyle(t.variant);\n const onMain = mainPairs.has(`${t.from}->${t.to}`);\n edges.push(\n edge({\n id: t.id,\n source: t.from,\n target: t.to,\n sourceHandle: sideHandle(t.fromSide),\n targetHandle: sideHandle(t.toSide),\n label: t.label,\n color: style.color,\n width: t.width ?? style.width,\n lineStyle: style.lineStyle,\n animated: trace && onMain,\n waypoints: t.via?.map(([x, y]) => ({ x, y })),\n }),\n );\n }\n\n return wrap(nodes, edges, [], spec.meta.title);\n}\n\n/* ========================================================================== */\n\nfunction wrap(\n nodes: FlowNode[],\n edges: FlowEdge[],\n lines: FlowLine[],\n title?: string,\n): FlowDocument {\n return {\n canvases: {\n [ROOT_CANVAS_ID]: { nodes, edges, lines },\n },\n stack: [ROOT_CANVAS_ID],\n title,\n };\n}\n\n/** Convert any supported Archify spec into a Flow document. */\nexport function archifyToFlowDocument(spec: ArchifySpec): FlowDocument {\n switch (spec.diagram_type) {\n case 'architecture':\n return convertArchitecture(spec);\n case 'workflow':\n return convertWorkflow(spec);\n case 'sequence':\n return convertSequence(spec);\n case 'dataflow':\n return convertDataflow(spec);\n case 'lifecycle':\n return convertLifecycle(spec);\n default:\n return wrap([], [], []);\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"convert.js","names":[],"sources":["../../../../../src/components/pro/Flow/archify/convert.ts"],"sourcesContent":["/**\n * Convert an Archify spec into a native Flow `FlowDocument`.\n *\n * One converter per diagram type reproduces Archify's fixed layout geometry\n * (constants copied from the reference renderers) so the imported diagram\n * matches the reference artifact, then emits editable Flow nodes/edges/lines.\n *\n * When `meta.animation === \"trace\"`, edges are marked `animated` so the Flow\n * presentation / preview mode plays the traveling gradient pulse.\n */\n\nimport type { FlowDocument, FlowNode, FlowEdge, FlowLine } from '../types';\nimport { ROOT_CANVAS_ID } from '../constants';\nimport type {\n ArchifySpec,\n ArchifyArchitectureSpec,\n ArchifyWorkflowSpec,\n ArchifySequenceSpec,\n ArchifyDataflowSpec,\n ArchifyLifecycleSpec,\n} from './spec';\nimport {\n ARCHIFY_LANE_STROKE,\n ARCHIFY_TEXT_MUTED,\n componentStyle,\n stateStyle,\n variantEdgeStyle,\n messageEdgeStyle,\n} from './palette';\nimport { card, frame, edge, sideHandle, uid } from './build';\n\nfunction isTrace(spec: ArchifySpec): boolean {\n return spec.meta?.animation === 'trace';\n}\n\n/* ========================================================================== */\n/* Architecture */\n/* ========================================================================== */\n\nconst ARCH_GRID = { origin: [40, 80], cols: 4, gapX: 30, gapY: 40, cellW: 130, cellH: 64 };\n\nfunction convertArchitecture(spec: ArchifyArchitectureSpec): FlowDocument {\n const trace = isTrace(spec);\n const grid = { ...ARCH_GRID, ...spec.layout };\n const nodes: FlowNode[] = [];\n const edges: FlowEdge[] = [];\n\n const rect = new Map<string, { x: number; y: number; w: number; h: number }>();\n\n for (const c of spec.components) {\n let x: number;\n let y: number;\n if (Array.isArray(c.pos)) {\n [x, y] = c.pos;\n } else if (Number.isInteger(c.row) && Number.isInteger(c.col)) {\n const stepX = grid.cellW + grid.gapX;\n const stepY = grid.cellH + grid.gapY;\n x = grid.origin[0] + (c.col ?? 0) * stepX;\n y = grid.origin[1] + (c.row ?? 0) * stepY;\n } else {\n x = grid.origin[0];\n y = grid.origin[1];\n }\n const w = c.size?.[0] ?? grid.cellW;\n const h = c.size?.[1] ?? grid.cellH;\n rect.set(c.id, { x, y, w, h });\n const style = componentStyle(c.type);\n nodes.push(\n card({\n id: c.id,\n x,\n y,\n width: w,\n height: h,\n label: c.label,\n sublabel: c.sublabel,\n tag: c.tag,\n fill: style.fill,\n stroke: style.stroke,\n text: style.text,\n sub: style.sub,\n }),\n );\n }\n\n // Boundaries wrap their member components with padding, rendered behind.\n for (const [i, b] of (spec.boundaries ?? []).entries()) {\n const members = b.wraps.map((id) => rect.get(id)).filter(Boolean) as Array<{\n x: number;\n y: number;\n w: number;\n h: number;\n }>;\n if (members.length === 0) continue;\n const pad = b.pad ?? 26;\n const minX = Math.min(...members.map((m) => m.x)) - pad;\n const minY = Math.min(...members.map((m) => m.y)) - pad - 14;\n const maxX = Math.max(...members.map((m) => m.x + m.w)) + pad;\n const maxY = Math.max(...members.map((m) => m.y + m.h)) + pad;\n nodes.push(\n frame({\n id: `boundary_${i}_${uid('b')}`,\n x: minX,\n y: minY,\n width: maxX - minX,\n height: maxY - minY,\n label: b.label,\n stroke: b.kind === 'security-group' ? '#fb7185' : ARCHIFY_LANE_STROKE,\n borderStyle: 'dashed',\n labelColor: b.kind === 'security-group' ? '#fb7185' : ARCHIFY_TEXT_MUTED,\n zIndex: -10 + i,\n }),\n );\n }\n\n for (const conn of spec.connections ?? []) {\n const style = variantEdgeStyle(conn.variant);\n edges.push(\n edge({\n id: conn.id,\n source: conn.from,\n target: conn.to,\n sourceHandle: sideHandle(conn.fromSide),\n targetHandle: sideHandle(conn.toSide),\n label: conn.label,\n color: style.color,\n width: conn.width ?? style.width,\n lineStyle: style.lineStyle,\n animated: trace,\n waypoints: conn.via?.map(([x, y]) => ({ x, y })),\n }),\n );\n }\n\n return wrap(nodes, edges, [], spec.meta.title);\n}\n\n/* ========================================================================== */\n/* Workflow */\n/* ========================================================================== */\n\nconst WF = {\n laneX: 40,\n laneY: 52,\n laneW: 640,\n laneH: 104,\n laneGap: 20,\n laneTitleH: 30,\n colXs: [88, 220, 300, 430, 500, 625],\n nodeW: 92,\n nodeH: 52,\n};\n\nfunction convertWorkflow(spec: ArchifyWorkflowSpec): FlowDocument {\n const trace = isTrace(spec);\n const nodes: FlowNode[] = [];\n const edges: FlowEdge[] = [];\n\n const laneIndex = new Map(spec.lanes.map((l, i) => [l.id, i]));\n const laneTop = (id: string) =>\n WF.laneY + (laneIndex.get(id) ?? 0) * (WF.laneH + WF.laneGap);\n\n // Lane frames (behind everything).\n for (const lane of spec.lanes) {\n const top = laneTop(lane.id);\n nodes.push(\n frame({\n id: `lane_${lane.id}`,\n x: WF.laneX,\n y: top,\n width: WF.laneW,\n height: WF.laneH,\n label: lane.label,\n stroke: lane.variant === 'exception' ? '#fb7185' : ARCHIFY_LANE_STROKE,\n labelColor: lane.variant === 'exception' ? '#fb7185' : ARCHIFY_TEXT_MUTED,\n zIndex: -20,\n }),\n );\n }\n\n // Phase bands (thin frames spanning columns, drawn just above lanes).\n for (const [i, phase] of (spec.phases ?? []).entries()) {\n const x0 = WF.colXs[phase.fromCol] - WF.nodeW / 2 - 12;\n const x1 = WF.colXs[phase.toCol] + WF.nodeW / 2 + 12;\n nodes.push(\n frame({\n id: `phase_${phase.id}`,\n x: x0,\n y: WF.laneY - 34,\n width: x1 - x0,\n height: 26,\n label: phase.label,\n stroke: variantEdgeStyle(phase.variant).color,\n labelColor: ARCHIFY_TEXT_MUTED,\n borderStyle: 'none',\n zIndex: -15 + i,\n }),\n );\n }\n\n // Workflow groups (nested emphasis frames inside a lane).\n for (const [i, g] of (spec.groups ?? []).entries()) {\n const top = laneTop(g.lane);\n const x0 = WF.colXs[g.fromCol] - WF.nodeW / 2 - 8;\n const x1 = WF.colXs[g.toCol] + WF.nodeW / 2 + 8;\n nodes.push(\n frame({\n id: `wfgroup_${g.id}`,\n x: x0,\n y: top + WF.laneTitleH - 6,\n width: x1 - x0,\n height: WF.laneH - WF.laneTitleH,\n label: g.label,\n stroke: variantEdgeStyle(g.variant).color,\n labelColor: ARCHIFY_TEXT_MUTED,\n borderStyle: 'dashed',\n zIndex: -12 + i,\n }),\n );\n }\n\n for (const n of spec.nodes) {\n const width = n.width ?? WF.nodeW;\n const height = n.height ?? (n.tag ? 68 : WF.nodeH);\n const cx = WF.colXs[n.col] ?? WF.colXs[WF.colXs.length - 1];\n const contentH = WF.laneH - WF.laneTitleH;\n const y = laneTop(n.lane) + WF.laneTitleH + (contentH - height) / 2 + (n.yOffset ?? 0);\n const style = componentStyle(n.type);\n nodes.push(\n card({\n id: n.id,\n x: cx - width / 2,\n y,\n width,\n height,\n label: n.label,\n sublabel: n.sublabel,\n tag: n.tag,\n fill: style.fill,\n stroke: style.stroke,\n text: style.text,\n sub: style.sub,\n fontSize: 12,\n }),\n );\n }\n\n const mainPath = new Set<string>();\n const mp = spec.mainPath ?? [];\n for (let i = 0; i < mp.length - 1; i++) mainPath.add(`${mp[i]}->${mp[i + 1]}`);\n\n for (const e of spec.edges) {\n const onMain = mainPath.has(`${e.from}->${e.to}`);\n const style = variantEdgeStyle(e.variant ?? (onMain ? 'emphasis' : 'default'));\n edges.push(\n edge({\n id: e.id,\n source: e.from,\n target: e.to,\n sourceHandle: sideHandle(e.fromSide),\n targetHandle: sideHandle(e.toSide),\n label: e.label,\n color: e.role === 'error' ? '#fb7185' : style.color,\n width: e.width ?? style.width,\n lineStyle: e.role === 'error' ? 'dashed' : style.lineStyle,\n animated: trace && onMain,\n waypoints: e.via?.map(([x, y]) => ({ x, y })),\n }),\n );\n }\n\n return wrap(nodes, edges, [], spec.meta.title);\n}\n\n/* ========================================================================== */\n/* Sequence */\n/* ========================================================================== */\n\nfunction convertSequence(spec: ArchifySequenceSpec): FlowDocument {\n const nodes: FlowNode[] = [];\n const edges: FlowEdge[] = [];\n const lines: FlowLine[] = [];\n\n const viewBox = spec.meta.viewBox ?? [920, 760];\n const sideMargin = 62;\n const participantW = 86;\n const colGap = 108;\n const topY = 72;\n const participantH = 54;\n const lifelineTop = 142;\n const lifelineBottom = viewBox[1] - 65;\n\n const cx = (i: number) => sideMargin + i * colGap;\n const partX = new Map<string, number>();\n\n spec.participants.forEach((p, i) => {\n const x = cx(i);\n partX.set(p.id, x);\n const style = componentStyle(p.type);\n nodes.push(\n card({\n id: p.id,\n x: x - participantW / 2,\n y: topY,\n width: participantW,\n height: participantH,\n label: p.label,\n sublabel: p.sublabel,\n fill: style.fill,\n stroke: style.stroke,\n text: style.text,\n sub: style.sub,\n fontSize: 11,\n zIndex: 5,\n }),\n );\n // Lifeline (dashed vertical guide beneath each participant).\n lines.push({\n id: `lifeline_${p.id}`,\n type: 'straight',\n points: [\n { x, y: lifelineTop },\n { x, y: lifelineBottom },\n ],\n strokeColor: ARCHIFY_LANE_STROKE,\n strokeWidth: 1,\n lineStyle: 'dashed',\n markerEnd: 'none',\n zIndex: -5,\n });\n });\n\n // Segment frames (labelled bands over ranges of the timeline).\n for (const [i, seg] of (spec.segments ?? []).entries()) {\n nodes.push(\n frame({\n id: `segment_${i}`,\n x: 48,\n y: seg.from,\n width: viewBox[0] - 96,\n height: seg.to - seg.from,\n label: seg.label,\n stroke: ARCHIFY_LANE_STROKE,\n labelColor: ARCHIFY_TEXT_MUTED,\n borderStyle: 'dashed',\n zIndex: -10,\n }),\n );\n }\n\n // Activation bars (thin vertical rects on a participant lifeline).\n for (const [i, act] of (spec.activations ?? []).entries()) {\n const x = partX.get(act.participant);\n if (x === undefined) continue;\n const style = componentStyle(act.type ?? 'backend');\n nodes.push({\n id: `activation_${i}_${act.participant}`,\n type: 'shapeRect',\n position: { x: x - 5, y: act.from },\n width: 10,\n height: Math.max(6, act.to - act.from),\n zIndex: 1,\n data: {\n label: '',\n fill: style.fill,\n stroke: style.stroke,\n strokeWidth: 1,\n color: style.text,\n fontSize: 10,\n borderStyle: 'solid',\n attributes: [],\n },\n });\n }\n\n // Messages become horizontal arrow lines at their y with a label above.\n for (const m of spec.messages) {\n const fromX = partX.get(m.from);\n const toX = partX.get(m.to);\n if (fromX === undefined || toX === undefined) continue;\n const dir = toX > fromX ? 1 : -1;\n const start = fromX + dir * 7;\n const end = toX - dir * 7;\n const style = messageEdgeStyle(m.variant);\n lines.push({\n id: m.id ?? uid('msg'),\n type: 'arrow',\n points: [\n { x: start, y: m.y },\n { x: end, y: m.y },\n ],\n strokeColor: style.color,\n strokeWidth: style.width,\n lineStyle: style.lineStyle,\n markerEnd: m.variant === 'return' ? 'arrow' : 'arrowclosed',\n zIndex: 3,\n });\n // Label as a tiny transparent text node centered above the arrow.\n nodes.push({\n id: `mlabel_${m.id ?? uid('m')}`,\n type: 'textLabel',\n position: { x: (start + end) / 2 - 70, y: m.y - 22 },\n width: 140,\n height: 16,\n zIndex: 4,\n data: {\n label: m.label,\n fill: 'transparent',\n stroke: 'transparent',\n strokeWidth: 0,\n color: style.color,\n labelColor: style.color,\n fontSize: 11,\n attributes: [],\n },\n });\n }\n\n return wrap(nodes, edges, lines, spec.meta.title);\n}\n\n/* ========================================================================== */\n/* Dataflow */\n/* ========================================================================== */\n\nconst DF = {\n stageY: 46,\n stageH: 36,\n stageBottomPad: 74,\n leftX: 100,\n colGap: 215,\n stageW: 168,\n nodeW: 112,\n nodeH: 58,\n rowYs: [128, 242, 356, 470, 584],\n};\n\nconst stageX = (i: number) => DF.leftX + i * DF.colGap;\n\nfunction convertDataflow(spec: ArchifyDataflowSpec): FlowDocument {\n const trace = isTrace(spec);\n const nodes: FlowNode[] = [];\n const edges: FlowEdge[] = [];\n\n const viewBox = spec.meta.viewBox ?? [940, 720];\n\n // Stage frames (tall vertical bands).\n for (const [i, stage] of spec.stages.entries()) {\n nodes.push(\n frame({\n id: `stage_${i}`,\n x: stageX(i) - DF.stageW / 2,\n y: DF.stageY,\n width: DF.stageW,\n height: viewBox[1] - DF.stageY - DF.stageBottomPad,\n label: stage.label,\n stroke: ARCHIFY_LANE_STROKE,\n labelColor: ARCHIFY_TEXT_MUTED,\n borderStyle: 'dashed',\n zIndex: -10,\n }),\n );\n }\n\n for (const n of spec.nodes) {\n const width = n.width ?? DF.nodeW;\n const height = n.height ?? DF.nodeH;\n const cx = stageX(n.stage);\n const y = (DF.rowYs[n.row] ?? DF.rowYs[DF.rowYs.length - 1]) + (n.yOffset ?? 0);\n const style = componentStyle(n.type);\n nodes.push(\n card({\n id: n.id,\n x: cx - width / 2,\n y,\n width,\n height,\n label: n.label,\n sublabel: n.sublabel,\n tag: n.tag,\n fill: style.fill,\n stroke: style.stroke,\n text: style.text,\n sub: style.sub,\n fontSize: 12,\n }),\n );\n }\n\n for (const f of spec.flows) {\n const style = variantEdgeStyle(f.variant);\n edges.push(\n edge({\n id: f.id,\n source: f.from,\n target: f.to,\n sourceHandle: sideHandle(f.fromSide),\n targetHandle: sideHandle(f.toSide),\n label: f.label,\n color: style.color,\n width: f.width ?? style.width,\n lineStyle: style.lineStyle,\n animated: trace && f.variant === 'emphasis',\n waypoints: f.via?.map(([x, y]) => ({ x, y })),\n }),\n );\n }\n\n return wrap(nodes, edges, [], spec.meta.title);\n}\n\n/* ========================================================================== */\n/* Lifecycle */\n/* ========================================================================== */\n\nconst LC = {\n phaseY: 126,\n eventY: 278,\n outcomeY: 450,\n phaseW: 118,\n phaseH: 62,\n eventW: 126,\n eventH: 58,\n outcomeW: 118,\n outcomeH: 58,\n phaseXs: [94, 248, 402, 556, 710],\n eventXs: [402, 556, 710],\n outcomeXs: [402, 556, 710],\n};\n\nfunction lifecycleBand(lane: string): 'phase' | 'event' | 'outcome' {\n if (lane === 'main') return 'phase';\n if (lane === 'terminal') return 'outcome';\n return 'event';\n}\n\nfunction convertLifecycle(spec: ArchifyLifecycleSpec): FlowDocument {\n const trace = isTrace(spec);\n const nodes: FlowNode[] = [];\n const edges: FlowEdge[] = [];\n\n const viewBox = spec.meta.viewBox ?? [980, 660];\n\n // Band frames give the three horizontal groupings some structure.\n const laneLabel = new Map(spec.lanes.map((l) => [l.id, l.label]));\n const bandRows: Array<{ band: 'phase' | 'event' | 'outcome'; y: number; h: number; label: string }> = [\n { band: 'phase', y: LC.phaseY - 26, h: LC.phaseH + 40, label: laneLabel.get('main') ?? 'Lifecycle phases' },\n { band: 'event', y: LC.eventY - 26, h: LC.eventH + 40, label: 'Interruptions + Recovery' },\n { band: 'outcome', y: LC.outcomeY - 26, h: LC.outcomeH + 40, label: laneLabel.get('terminal') ?? 'Terminal exits' },\n ];\n for (const [i, b] of bandRows.entries()) {\n nodes.push(\n frame({\n id: `band_${b.band}`,\n x: 40,\n y: b.y,\n width: viewBox[0] - 80,\n height: b.h,\n label: `0${i + 1} / ${b.label}`,\n stroke: ARCHIFY_LANE_STROKE,\n labelColor: ARCHIFY_TEXT_MUTED,\n borderStyle: 'dashed',\n zIndex: -10,\n }),\n );\n }\n\n for (const s of spec.states) {\n const band = lifecycleBand(s.lane);\n const isPhase = band === 'phase';\n const isOutcome = band === 'outcome';\n const width = s.width ?? (isPhase ? LC.phaseW : isOutcome ? LC.outcomeW : LC.eventW);\n const height = s.height ?? (isPhase ? LC.phaseH : isOutcome ? LC.outcomeH : LC.eventH);\n const xs = isPhase ? LC.phaseXs : isOutcome ? LC.outcomeXs : LC.eventXs;\n const cx = xs[s.col] ?? xs[xs.length - 1];\n const y = (isPhase ? LC.phaseY : isOutcome ? LC.outcomeY : LC.eventY) + (s.yOffset ?? 0);\n const style = stateStyle(s.type);\n nodes.push(\n card({\n id: s.id,\n x: cx - width / 2,\n y,\n width,\n height,\n label: s.label,\n sublabel: s.sublabel,\n tag: s.tag ?? s.step,\n fill: style.fill,\n stroke: style.stroke,\n text: style.text,\n sub: style.sub,\n fontSize: 12,\n }),\n );\n }\n\n // Order states along the main lane to build the primary rail. Archify draws\n // this rail decoratively (not as explicit transitions), so synthesize edges\n // between consecutive phase states, connecting right-to-left across columns.\n const mainStates = spec.states\n .filter((s) => s.lane === 'main')\n .sort((a, b) => a.col - b.col);\n const explicitPairs = new Set(spec.transitions.map((t) => `${t.from}->${t.to}`));\n for (let i = 0; i < mainStates.length - 1; i++) {\n const from = mainStates[i];\n const to = mainStates[i + 1];\n // Skip if the author already provided this exact transition.\n if (explicitPairs.has(`${from.id}->${to.id}`)) continue;\n edges.push(\n edge({\n id: `mainrail_${from.id}_${to.id}`,\n source: from.id,\n target: to.id,\n sourceHandle: sideHandle('right'),\n targetHandle: sideHandle('left'),\n label: undefined,\n color: variantEdgeStyle('emphasis').color,\n width: 2.2,\n lineStyle: 'solid',\n animated: trace,\n }),\n );\n }\n\n const mainPairs = new Set<string>();\n for (let i = 0; i < mainStates.length - 1; i++) {\n mainPairs.add(`${mainStates[i].id}->${mainStates[i + 1].id}`);\n }\n\n for (const t of spec.transitions) {\n const style = variantEdgeStyle(t.variant);\n const onMain = mainPairs.has(`${t.from}->${t.to}`);\n edges.push(\n edge({\n id: t.id,\n source: t.from,\n target: t.to,\n sourceHandle: sideHandle(t.fromSide),\n targetHandle: sideHandle(t.toSide),\n label: t.label,\n color: style.color,\n width: t.width ?? style.width,\n lineStyle: style.lineStyle,\n animated: trace && onMain,\n waypoints: t.via?.map(([x, y]) => ({ x, y })),\n }),\n );\n }\n\n return wrap(nodes, edges, [], spec.meta.title);\n}\n\n/* ========================================================================== */\n\nfunction wrap(\n nodes: FlowNode[],\n edges: FlowEdge[],\n lines: FlowLine[],\n title?: string,\n): FlowDocument {\n return {\n canvases: {\n [ROOT_CANVAS_ID]: { nodes, edges, lines },\n },\n stack: [ROOT_CANVAS_ID],\n title,\n };\n}\n\n/** Convert any supported Archify spec into a Flow document. */\nexport function archifyToFlowDocument(spec: ArchifySpec): FlowDocument {\n switch (spec.diagram_type) {\n case 'architecture':\n return convertArchitecture(spec);\n case 'workflow':\n return convertWorkflow(spec);\n case 'sequence':\n return convertSequence(spec);\n case 'dataflow':\n return convertDataflow(spec);\n case 'lifecycle':\n return convertLifecycle(spec);\n default:\n return wrap([], [], []);\n }\n}\n"],"mappings":";;;;AA+BA,SAAS,EAAQ,GAA4B;CAC3C,OAAO,EAAK,MAAM,cAAc;AAClC;AAMA,IAAM,IAAY;CAAE,QAAQ,CAAC,IAAI,EAAE;CAAG,MAAM;CAAG,MAAM;CAAI,MAAM;CAAI,OAAO;CAAK,OAAO;AAAG;AAEzF,SAAS,EAAoB,GAA6C;CACxE,IAAM,IAAQ,EAAQ,CAAI,GACpB,IAAO;EAAE,GAAG;EAAW,GAAG,EAAK;CAAO,GACtC,IAAoB,CAAC,GACrB,IAAoB,CAAC,GAErB,oBAAO,IAAI,IAA4D;CAE7E,KAAK,IAAM,KAAK,EAAK,YAAY;EAC/B,IAAI,GACA;EACJ,IAAI,MAAM,QAAQ,EAAE,GAAG,GACrB,CAAC,GAAG,KAAK,EAAE;OACN,IAAI,OAAO,UAAU,EAAE,GAAG,KAAK,OAAO,UAAU,EAAE,GAAG,GAAG;GAC7D,IAAM,IAAQ,EAAK,QAAQ,EAAK,MAC1B,IAAQ,EAAK,QAAQ,EAAK;GAEhC,AADA,IAAI,EAAK,OAAO,MAAM,EAAE,OAAO,KAAK,GACpC,IAAI,EAAK,OAAO,MAAM,EAAE,OAAO,KAAK;EACtC,OAEE,AADA,IAAI,EAAK,OAAO,IAChB,IAAI,EAAK,OAAO;EAElB,IAAM,IAAI,EAAE,OAAO,MAAM,EAAK,OACxB,IAAI,EAAE,OAAO,MAAM,EAAK;EAC9B,EAAK,IAAI,EAAE,IAAI;GAAE;GAAG;GAAG;GAAG;EAAE,CAAC;EAC7B,IAAM,IAAQ,EAAe,EAAE,IAAI;EACnC,EAAM,KACJ,EAAK;GACH,IAAI,EAAE;GACN;GACA;GACA,OAAO;GACP,QAAQ;GACR,OAAO,EAAE;GACT,UAAU,EAAE;GACZ,KAAK,EAAE;GACP,MAAM,EAAM;GACZ,QAAQ,EAAM;GACd,MAAM,EAAM;GACZ,KAAK,EAAM;EACb,CAAC,CACH;CACF;CAGA,KAAK,IAAM,CAAC,GAAG,OAAO,EAAK,cAAc,CAAC,EAAA,CAAG,QAAQ,GAAG;EACtD,IAAM,IAAU,EAAE,MAAM,KAAK,MAAO,EAAK,IAAI,CAAE,CAAC,CAAC,CAAC,OAAO,OAAO;EAMhE,IAAI,EAAQ,WAAW,GAAG;EAC1B,IAAM,IAAM,EAAE,OAAO,IACf,IAAO,KAAK,IAAI,GAAG,EAAQ,KAAK,MAAM,EAAE,CAAC,CAAC,IAAI,GAC9C,IAAO,KAAK,IAAI,GAAG,EAAQ,KAAK,MAAM,EAAE,CAAC,CAAC,IAAI,IAAM,IACpD,IAAO,KAAK,IAAI,GAAG,EAAQ,KAAK,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,GACpD,IAAO,KAAK,IAAI,GAAG,EAAQ,KAAK,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI;EAC1D,EAAM,KACJ,EAAM;GACJ,IAAI,YAAY,EAAE,GAAG,EAAI,GAAG;GAC5B,GAAG;GACH,GAAG;GACH,OAAO,IAAO;GACd,QAAQ,IAAO;GACf,OAAO,EAAE;GACT,QAAQ,EAAE,SAAS,mBAAmB,YAAY;GAClD,aAAa;GACb,YAAY,EAAE,SAAS,mBAAmB,YAAY;GACtD,QAAQ,MAAM;EAChB,CAAC,CACH;CACF;CAEA,KAAK,IAAM,KAAQ,EAAK,eAAe,CAAC,GAAG;EACzC,IAAM,IAAQ,EAAiB,EAAK,OAAO;EAC3C,EAAM,KACJ,EAAK;GACH,IAAI,EAAK;GACT,QAAQ,EAAK;GACb,QAAQ,EAAK;GACb,cAAc,EAAW,EAAK,QAAQ;GACtC,cAAc,EAAW,EAAK,MAAM;GACpC,OAAO,EAAK;GACZ,OAAO,EAAM;GACb,OAAO,EAAK,SAAS,EAAM;GAC3B,WAAW,EAAM;GACjB,UAAU;GACV,WAAW,EAAK,KAAK,KAAK,CAAC,GAAG,QAAQ;IAAE;IAAG;GAAE,EAAE;EACjD,CAAC,CACH;CACF;CAEA,OAAO,EAAK,GAAO,GAAO,CAAC,GAAG,EAAK,KAAK,KAAK;AAC/C;AAMA,IAAM,IAAK;CACT,OAAO;CACP,OAAO;CACP,OAAO;CACP,OAAO;CACP,SAAS;CACT,YAAY;CACZ,OAAO;EAAC;EAAI;EAAK;EAAK;EAAK;EAAK;CAAG;CACnC,OAAO;CACP,OAAO;AACT;AAEA,SAAS,EAAgB,GAAyC;CAChE,IAAM,IAAQ,EAAQ,CAAI,GACpB,IAAoB,CAAC,GACrB,IAAoB,CAAC,GAErB,IAAY,IAAI,IAAI,EAAK,MAAM,KAAK,GAAG,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,GACvD,KAAW,MACf,EAAG,SAAS,EAAU,IAAI,CAAE,KAAK,MAAM,EAAG,QAAQ,EAAG;CAGvD,KAAK,IAAM,KAAQ,EAAK,OAAO;EAC7B,IAAM,IAAM,EAAQ,EAAK,EAAE;EAC3B,EAAM,KACJ,EAAM;GACJ,IAAI,QAAQ,EAAK;GACjB,GAAG,EAAG;GACN,GAAG;GACH,OAAO,EAAG;GACV,QAAQ,EAAG;GACX,OAAO,EAAK;GACZ,QAAQ,EAAK,YAAY,cAAc,YAAY;GACnD,YAAY,EAAK,YAAY,cAAc,YAAY;GACvD,QAAQ;EACV,CAAC,CACH;CACF;CAGA,KAAK,IAAM,CAAC,GAAG,OAAW,EAAK,UAAU,CAAC,EAAA,CAAG,QAAQ,GAAG;EACtD,IAAM,IAAK,EAAG,MAAM,EAAM,WAAW,EAAG,QAAQ,IAAI,IAC9C,IAAK,EAAG,MAAM,EAAM,SAAS,EAAG,QAAQ,IAAI;EAClD,EAAM,KACJ,EAAM;GACJ,IAAI,SAAS,EAAM;GACnB,GAAG;GACH,GAAG,EAAG,QAAQ;GACd,OAAO,IAAK;GACZ,QAAQ;GACR,OAAO,EAAM;GACb,QAAQ,EAAiB,EAAM,OAAO,CAAC,CAAC;GACxC,YAAY;GACZ,aAAa;GACb,QAAQ,MAAM;EAChB,CAAC,CACH;CACF;CAGA,KAAK,IAAM,CAAC,GAAG,OAAO,EAAK,UAAU,CAAC,EAAA,CAAG,QAAQ,GAAG;EAClD,IAAM,IAAM,EAAQ,EAAE,IAAI,GACpB,IAAK,EAAG,MAAM,EAAE,WAAW,EAAG,QAAQ,IAAI,GAC1C,IAAK,EAAG,MAAM,EAAE,SAAS,EAAG,QAAQ,IAAI;EAC9C,EAAM,KACJ,EAAM;GACJ,IAAI,WAAW,EAAE;GACjB,GAAG;GACH,GAAG,IAAM,EAAG,aAAa;GACzB,OAAO,IAAK;GACZ,QAAQ,EAAG,QAAQ,EAAG;GACtB,OAAO,EAAE;GACT,QAAQ,EAAiB,EAAE,OAAO,CAAC,CAAC;GACpC,YAAY;GACZ,aAAa;GACb,QAAQ,MAAM;EAChB,CAAC,CACH;CACF;CAEA,KAAK,IAAM,KAAK,EAAK,OAAO;EAC1B,IAAM,IAAQ,EAAE,SAAS,EAAG,OACtB,IAAS,EAAE,WAAW,EAAE,MAAM,KAAK,EAAG,QACtC,IAAK,EAAG,MAAM,EAAE,QAAQ,EAAG,MAAM,EAAG,MAAM,SAAS,IACnD,IAAW,EAAG,QAAQ,EAAG,YACzB,IAAI,EAAQ,EAAE,IAAI,IAAI,EAAG,cAAc,IAAW,KAAU,KAAK,EAAE,WAAW,IAC9E,IAAQ,EAAe,EAAE,IAAI;EACnC,EAAM,KACJ,EAAK;GACH,IAAI,EAAE;GACN,GAAG,IAAK,IAAQ;GAChB;GACA;GACA;GACA,OAAO,EAAE;GACT,UAAU,EAAE;GACZ,KAAK,EAAE;GACP,MAAM,EAAM;GACZ,QAAQ,EAAM;GACd,MAAM,EAAM;GACZ,KAAK,EAAM;GACX,UAAU;EACZ,CAAC,CACH;CACF;CAEA,IAAM,oBAAW,IAAI,IAAY,GAC3B,IAAK,EAAK,YAAY,CAAC;CAC7B,KAAK,IAAI,IAAI,GAAG,IAAI,EAAG,SAAS,GAAG,KAAK,EAAS,IAAI,GAAG,EAAG,GAAG,IAAI,EAAG,IAAI,IAAI;CAE7E,KAAK,IAAM,KAAK,EAAK,OAAO;EAC1B,IAAM,IAAS,EAAS,IAAI,GAAG,EAAE,KAAK,IAAI,EAAE,IAAI,GAC1C,IAAQ,EAAiB,EAAE,YAAY,IAAS,aAAa,UAAU;EAC7E,EAAM,KACJ,EAAK;GACH,IAAI,EAAE;GACN,QAAQ,EAAE;GACV,QAAQ,EAAE;GACV,cAAc,EAAW,EAAE,QAAQ;GACnC,cAAc,EAAW,EAAE,MAAM;GACjC,OAAO,EAAE;GACT,OAAO,EAAE,SAAS,UAAU,YAAY,EAAM;GAC9C,OAAO,EAAE,SAAS,EAAM;GACxB,WAAW,EAAE,SAAS,UAAU,WAAW,EAAM;GACjD,UAAU,KAAS;GACnB,WAAW,EAAE,KAAK,KAAK,CAAC,GAAG,QAAQ;IAAE;IAAG;GAAE,EAAE;EAC9C,CAAC,CACH;CACF;CAEA,OAAO,EAAK,GAAO,GAAO,CAAC,GAAG,EAAK,KAAK,KAAK;AAC/C;AAMA,SAAS,EAAgB,GAAyC;CAChE,IAAM,IAAoB,CAAC,GACrB,IAAoB,CAAC,GACrB,IAAoB,CAAC,GAErB,IAAU,EAAK,KAAK,WAAW,CAAC,KAAK,GAAG,GAOxC,IAAiB,EAAQ,KAAK,IAE9B,KAAM,MAAc,KAAa,IAAI,KACrC,oBAAQ,IAAI,IAAoB;CAEtC,EAAK,aAAa,SAAS,GAAG,MAAM;EAClC,IAAM,IAAI,EAAG,CAAC;EACd,EAAM,IAAI,EAAE,IAAI,CAAC;EACjB,IAAM,IAAQ,EAAe,EAAE,IAAI;EAmBnC,AAlBA,EAAM,KACJ,EAAK;GACH,IAAI,EAAE;GACN,GAAG,IAAI;GACP,GAAG;GACH,OAAO;GACP,QAAQ;GACR,OAAO,EAAE;GACT,UAAU,EAAE;GACZ,MAAM,EAAM;GACZ,QAAQ,EAAM;GACd,MAAM,EAAM;GACZ,KAAK,EAAM;GACX,UAAU;GACV,QAAQ;EACV,CAAC,CACH,GAEA,EAAM,KAAK;GACT,IAAI,YAAY,EAAE;GAClB,MAAM;GACN,QAAQ,CACN;IAAE;IAAG,GAAG;GAAY,GACpB;IAAE;IAAG,GAAG;GAAe,CACzB;GACA,aAAa;GACb,aAAa;GACb,WAAW;GACX,WAAW;GACX,QAAQ;EACV,CAAC;CACH,CAAC;CAGD,KAAK,IAAM,CAAC,GAAG,OAAS,EAAK,YAAY,CAAC,EAAA,CAAG,QAAQ,GACnD,EAAM,KACJ,EAAM;EACJ,IAAI,WAAW;EACf,GAAG;EACH,GAAG,EAAI;EACP,OAAO,EAAQ,KAAK;EACpB,QAAQ,EAAI,KAAK,EAAI;EACrB,OAAO,EAAI;EACX,QAAQ;EACR,YAAY;EACZ,aAAa;EACb,QAAQ;CACV,CAAC,CACH;CAIF,KAAK,IAAM,CAAC,GAAG,OAAS,EAAK,eAAe,CAAC,EAAA,CAAG,QAAQ,GAAG;EACzD,IAAM,IAAI,EAAM,IAAI,EAAI,WAAW;EACnC,IAAI,MAAM,KAAA,GAAW;EACrB,IAAM,IAAQ,EAAe,EAAI,QAAQ,SAAS;EAClD,EAAM,KAAK;GACT,IAAI,cAAc,EAAE,GAAG,EAAI;GAC3B,MAAM;GACN,UAAU;IAAE,GAAG,IAAI;IAAG,GAAG,EAAI;GAAK;GAClC,OAAO;GACP,QAAQ,KAAK,IAAI,GAAG,EAAI,KAAK,EAAI,IAAI;GACrC,QAAQ;GACR,MAAM;IACJ,OAAO;IACP,MAAM,EAAM;IACZ,QAAQ,EAAM;IACd,aAAa;IACb,OAAO,EAAM;IACb,UAAU;IACV,aAAa;IACb,YAAY,CAAC;GACf;EACF,CAAC;CACH;CAGA,KAAK,IAAM,KAAK,EAAK,UAAU;EAC7B,IAAM,IAAQ,EAAM,IAAI,EAAE,IAAI,GACxB,IAAM,EAAM,IAAI,EAAE,EAAE;EAC1B,IAAI,MAAU,KAAA,KAAa,MAAQ,KAAA,GAAW;EAC9C,IAAM,IAAM,IAAM,IAAQ,IAAI,IACxB,IAAQ,IAAQ,IAAM,GACtB,IAAM,IAAM,IAAM,GAClB,IAAQ,EAAiB,EAAE,OAAO;EAexC,AAdA,EAAM,KAAK;GACT,IAAI,EAAE,MAAM,EAAI,KAAK;GACrB,MAAM;GACN,QAAQ,CACN;IAAE,GAAG;IAAO,GAAG,EAAE;GAAE,GACnB;IAAE,GAAG;IAAK,GAAG,EAAE;GAAE,CACnB;GACA,aAAa,EAAM;GACnB,aAAa,EAAM;GACnB,WAAW,EAAM;GACjB,WAAW,EAAE,YAAY,WAAW,UAAU;GAC9C,QAAQ;EACV,CAAC,GAED,EAAM,KAAK;GACT,IAAI,UAAU,EAAE,MAAM,EAAI,GAAG;GAC7B,MAAM;GACN,UAAU;IAAE,IAAI,IAAQ,KAAO,IAAI;IAAI,GAAG,EAAE,IAAI;GAAG;GACnD,OAAO;GACP,QAAQ;GACR,QAAQ;GACR,MAAM;IACJ,OAAO,EAAE;IACT,MAAM;IACN,QAAQ;IACR,aAAa;IACb,OAAO,EAAM;IACb,YAAY,EAAM;IAClB,UAAU;IACV,YAAY,CAAC;GACf;EACF,CAAC;CACH;CAEA,OAAO,EAAK,GAAO,GAAO,GAAO,EAAK,KAAK,KAAK;AAClD;AAMA,IAAM,IAAK;CACT,QAAQ;CACR,QAAQ;CACR,gBAAgB;CAChB,OAAO;CACP,QAAQ;CACR,QAAQ;CACR,OAAO;CACP,OAAO;CACP,OAAO;EAAC;EAAK;EAAK;EAAK;EAAK;CAAG;AACjC,GAEM,KAAU,MAAc,EAAG,QAAQ,IAAI,EAAG;AAEhD,SAAS,EAAgB,GAAyC;CAChE,IAAM,IAAQ,EAAQ,CAAI,GACpB,IAAoB,CAAC,GACrB,IAAoB,CAAC,GAErB,IAAU,EAAK,KAAK,WAAW,CAAC,KAAK,GAAG;CAG9C,KAAK,IAAM,CAAC,GAAG,MAAU,EAAK,OAAO,QAAQ,GAC3C,EAAM,KACJ,EAAM;EACJ,IAAI,SAAS;EACb,GAAG,EAAO,CAAC,IAAI,EAAG,SAAS;EAC3B,GAAG,EAAG;EACN,OAAO,EAAG;EACV,QAAQ,EAAQ,KAAK,EAAG,SAAS,EAAG;EACpC,OAAO,EAAM;EACb,QAAQ;EACR,YAAY;EACZ,aAAa;EACb,QAAQ;CACV,CAAC,CACH;CAGF,KAAK,IAAM,KAAK,EAAK,OAAO;EAC1B,IAAM,IAAQ,EAAE,SAAS,EAAG,OACtB,IAAS,EAAE,UAAU,EAAG,OACxB,IAAK,EAAO,EAAE,KAAK,GACnB,KAAK,EAAG,MAAM,EAAE,QAAQ,EAAG,MAAM,EAAG,MAAM,SAAS,OAAO,EAAE,WAAW,IACvE,IAAQ,EAAe,EAAE,IAAI;EACnC,EAAM,KACJ,EAAK;GACH,IAAI,EAAE;GACN,GAAG,IAAK,IAAQ;GAChB;GACA;GACA;GACA,OAAO,EAAE;GACT,UAAU,EAAE;GACZ,KAAK,EAAE;GACP,MAAM,EAAM;GACZ,QAAQ,EAAM;GACd,MAAM,EAAM;GACZ,KAAK,EAAM;GACX,UAAU;EACZ,CAAC,CACH;CACF;CAEA,KAAK,IAAM,KAAK,EAAK,OAAO;EAC1B,IAAM,IAAQ,EAAiB,EAAE,OAAO;EACxC,EAAM,KACJ,EAAK;GACH,IAAI,EAAE;GACN,QAAQ,EAAE;GACV,QAAQ,EAAE;GACV,cAAc,EAAW,EAAE,QAAQ;GACnC,cAAc,EAAW,EAAE,MAAM;GACjC,OAAO,EAAE;GACT,OAAO,EAAM;GACb,OAAO,EAAE,SAAS,EAAM;GACxB,WAAW,EAAM;GACjB,UAAU,KAAS,EAAE,YAAY;GACjC,WAAW,EAAE,KAAK,KAAK,CAAC,GAAG,QAAQ;IAAE;IAAG;GAAE,EAAE;EAC9C,CAAC,CACH;CACF;CAEA,OAAO,EAAK,GAAO,GAAO,CAAC,GAAG,EAAK,KAAK,KAAK;AAC/C;AAMA,IAAM,IAAK;CACT,QAAQ;CACR,QAAQ;CACR,UAAU;CACV,QAAQ;CACR,QAAQ;CACR,QAAQ;CACR,QAAQ;CACR,UAAU;CACV,UAAU;CACV,SAAS;EAAC;EAAI;EAAK;EAAK;EAAK;CAAG;CAChC,SAAS;EAAC;EAAK;EAAK;CAAG;CACvB,WAAW;EAAC;EAAK;EAAK;CAAG;AAC3B;AAEA,SAAS,EAAc,GAA6C;CAGlE,OAFI,MAAS,SAAe,UACxB,MAAS,aAAmB,YACzB;AACT;AAEA,SAAS,EAAiB,GAA0C;CAClE,IAAM,IAAQ,EAAQ,CAAI,GACpB,IAAoB,CAAC,GACrB,IAAoB,CAAC,GAErB,IAAU,EAAK,KAAK,WAAW,CAAC,KAAK,GAAG,GAGxC,IAAY,IAAI,IAAI,EAAK,MAAM,KAAK,MAAM,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,GAC1D,IAAgG;EACpG;GAAE,MAAM;GAAS,GAAG,EAAG,SAAS;GAAI,GAAG,EAAG,SAAS;GAAI,OAAO,EAAU,IAAI,MAAM,KAAK;EAAmB;EAC1G;GAAE,MAAM;GAAS,GAAG,EAAG,SAAS;GAAI,GAAG,EAAG,SAAS;GAAI,OAAO;EAA2B;EACzF;GAAE,MAAM;GAAW,GAAG,EAAG,WAAW;GAAI,GAAG,EAAG,WAAW;GAAI,OAAO,EAAU,IAAI,UAAU,KAAK;EAAiB;CACpH;CACA,KAAK,IAAM,CAAC,GAAG,MAAM,EAAS,QAAQ,GACpC,EAAM,KACJ,EAAM;EACJ,IAAI,QAAQ,EAAE;EACd,GAAG;EACH,GAAG,EAAE;EACL,OAAO,EAAQ,KAAK;EACpB,QAAQ,EAAE;EACV,OAAO,IAAI,IAAI,EAAE,KAAK,EAAE;EACxB,QAAQ;EACR,YAAY;EACZ,aAAa;EACb,QAAQ;CACV,CAAC,CACH;CAGF,KAAK,IAAM,KAAK,EAAK,QAAQ;EAC3B,IAAM,IAAO,EAAc,EAAE,IAAI,GAC3B,IAAU,MAAS,SACnB,IAAY,MAAS,WACrB,IAAQ,EAAE,UAAU,IAAU,EAAG,SAAS,IAAY,EAAG,WAAW,EAAG,SACvE,IAAS,EAAE,WAAW,IAAU,EAAG,SAAS,IAAY,EAAG,WAAW,EAAG,SACzE,IAAK,IAAU,EAAG,UAAU,IAAY,EAAG,YAAY,EAAG,SAC1D,IAAK,EAAG,EAAE,QAAQ,EAAG,EAAG,SAAS,IACjC,KAAK,IAAU,EAAG,SAAS,IAAY,EAAG,WAAW,EAAG,WAAW,EAAE,WAAW,IAChF,IAAQ,EAAW,EAAE,IAAI;EAC/B,EAAM,KACJ,EAAK;GACH,IAAI,EAAE;GACN,GAAG,IAAK,IAAQ;GAChB;GACA;GACA;GACA,OAAO,EAAE;GACT,UAAU,EAAE;GACZ,KAAK,EAAE,OAAO,EAAE;GAChB,MAAM,EAAM;GACZ,QAAQ,EAAM;GACd,MAAM,EAAM;GACZ,KAAK,EAAM;GACX,UAAU;EACZ,CAAC,CACH;CACF;CAKA,IAAM,IAAa,EAAK,OACrB,QAAQ,MAAM,EAAE,SAAS,MAAM,CAAC,CAChC,MAAM,GAAG,MAAM,EAAE,MAAM,EAAE,GAAG,GACzB,IAAgB,IAAI,IAAI,EAAK,YAAY,KAAK,MAAM,GAAG,EAAE,KAAK,IAAI,EAAE,IAAI,CAAC;CAC/E,KAAK,IAAI,IAAI,GAAG,IAAI,EAAW,SAAS,GAAG,KAAK;EAC9C,IAAM,IAAO,EAAW,IAClB,IAAK,EAAW,IAAI;EAEtB,EAAc,IAAI,GAAG,EAAK,GAAG,IAAI,EAAG,IAAI,KAC5C,EAAM,KACJ,EAAK;GACH,IAAI,YAAY,EAAK,GAAG,GAAG,EAAG;GAC9B,QAAQ,EAAK;GACb,QAAQ,EAAG;GACX,cAAc,EAAW,OAAO;GAChC,cAAc,EAAW,MAAM;GAC/B,OAAO,KAAA;GACP,OAAO,EAAiB,UAAU,CAAC,CAAC;GACpC,OAAO;GACP,WAAW;GACX,UAAU;EACZ,CAAC,CACH;CACF;CAEA,IAAM,oBAAY,IAAI,IAAY;CAClC,KAAK,IAAI,IAAI,GAAG,IAAI,EAAW,SAAS,GAAG,KACzC,EAAU,IAAI,GAAG,EAAW,EAAE,CAAC,GAAG,IAAI,EAAW,IAAI,EAAE,CAAC,IAAI;CAG9D,KAAK,IAAM,KAAK,EAAK,aAAa;EAChC,IAAM,IAAQ,EAAiB,EAAE,OAAO,GAClC,IAAS,EAAU,IAAI,GAAG,EAAE,KAAK,IAAI,EAAE,IAAI;EACjD,EAAM,KACJ,EAAK;GACH,IAAI,EAAE;GACN,QAAQ,EAAE;GACV,QAAQ,EAAE;GACV,cAAc,EAAW,EAAE,QAAQ;GACnC,cAAc,EAAW,EAAE,MAAM;GACjC,OAAO,EAAE;GACT,OAAO,EAAM;GACb,OAAO,EAAE,SAAS,EAAM;GACxB,WAAW,EAAM;GACjB,UAAU,KAAS;GACnB,WAAW,EAAE,KAAK,KAAK,CAAC,GAAG,QAAQ;IAAE;IAAG;GAAE,EAAE;EAC9C,CAAC,CACH;CACF;CAEA,OAAO,EAAK,GAAO,GAAO,CAAC,GAAG,EAAK,KAAK,KAAK;AAC/C;AAIA,SAAS,EACP,GACA,GACA,GACA,GACc;CACd,OAAO;EACL,UAAU,GACP,IAAiB;GAAE;GAAO;GAAO;EAAM,EAC1C;EACA,OAAO,CAAC,CAAc;EACtB;CACF;AACF;AAGA,SAAgB,EAAsB,GAAiC;CACrE,QAAQ,EAAK,cAAb;EACE,KAAK,gBACH,OAAO,EAAoB,CAAI;EACjC,KAAK,YACH,OAAO,EAAgB,CAAI;EAC7B,KAAK,YACH,OAAO,EAAgB,CAAI;EAC7B,KAAK,YACH,OAAO,EAAgB,CAAI;EAC7B,KAAK,aACH,OAAO,EAAiB,CAAI;EAC9B,SACE,OAAO,EAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;CAC1B;AACF"}
|
|
@@ -140,23 +140,25 @@ function n() {
|
|
|
140
140
|
]),
|
|
141
141
|
changeZIndex: t((e) => {
|
|
142
142
|
let t = i.nodeIds, a = i.lineIds;
|
|
143
|
-
(t.size
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
let
|
|
143
|
+
if (t.size === 0 && a.size === 0) return;
|
|
144
|
+
let o = (t, n, r) => e === "front" ? n + 1 : e === "back" ? r - 1 : e === "up" ? t + 1 : t - 1;
|
|
145
|
+
n((e) => {
|
|
146
|
+
let n = e.canvases[r];
|
|
147
|
+
if (!n) return e;
|
|
148
|
+
let i = n.nodes.map((e) => e.zIndex ?? 0), s = i.length > 0 ? Math.max(...i) : 0, c = i.length > 0 ? Math.min(...i) : 0, l = n.lines.map((e) => e.zIndex ?? 0), u = l.length > 0 ? Math.max(...l) : 0, d = l.length > 0 ? Math.min(...l) : 0;
|
|
147
149
|
return {
|
|
148
|
-
...
|
|
150
|
+
...e,
|
|
149
151
|
canvases: {
|
|
150
|
-
...
|
|
152
|
+
...e.canvases,
|
|
151
153
|
[r]: {
|
|
152
|
-
...
|
|
153
|
-
nodes:
|
|
154
|
+
...n,
|
|
155
|
+
nodes: n.nodes.map((e) => t.has(e.id) ? {
|
|
154
156
|
...e,
|
|
155
|
-
zIndex:
|
|
157
|
+
zIndex: o(e.zIndex ?? 0, s, c)
|
|
156
158
|
} : e),
|
|
157
|
-
lines:
|
|
159
|
+
lines: n.lines.map((e) => a.has(e.id) ? {
|
|
158
160
|
...e,
|
|
159
|
-
zIndex:
|
|
161
|
+
zIndex: o(e.zIndex ?? 0, u, d)
|
|
160
162
|
} : e)
|
|
161
163
|
}
|
|
162
164
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useLayoutActions.js","names":[],"sources":["../../../../../src/components/pro/Flow/hooks/useLayoutActions.ts"],"sourcesContent":["import { useCallback } from 'react';\nimport { useFlowContext } from '../context/FlowContext';\nimport type { FlowNode } from '../types';\n\ntype Align = 'left' | 'center-h' | 'right' | 'top' | 'center-v' | 'bottom';\ntype Distribute = 'horizontal' | 'vertical';\ntype LayerMode = 'front' | 'back' | 'up' | 'down';\n\nexport function useLayoutActions() {\n const { setDoc, currentCanvasId, selection, currentCanvas } = useFlowContext();\n\n const align = useCallback(\n (direction: Align) => {\n const ids = selection.nodeIds;\n if (ids.size < 2) return;\n const nodes = currentCanvas.nodes.filter(n => ids.has(n.id));\n if (nodes.length < 2) return;\n\n let target: number;\n switch (direction) {\n case 'left':\n target = Math.min(...nodes.map(n => n.position.x));\n break;\n case 'right':\n target = Math.max(...nodes.map(n => n.position.x + n.width));\n break;\n case 'center-h':\n target = nodes.reduce((s, n) => s + n.position.x + n.width / 2, 0) / nodes.length;\n break;\n case 'top':\n target = Math.min(...nodes.map(n => n.position.y));\n break;\n case 'bottom':\n target = Math.max(...nodes.map(n => n.position.y + n.height));\n break;\n case 'center-v':\n target = nodes.reduce((s, n) => s + n.position.y + n.height / 2, 0) / nodes.length;\n break;\n }\n\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n nodes: canvas.nodes.map(n => {\n if (!ids.has(n.id)) return n;\n let newX = n.position.x;\n let newY = n.position.y;\n switch (direction) {\n case 'left': newX = target; break;\n case 'right': newX = target - n.width; break;\n case 'center-h': newX = target - n.width / 2; break;\n case 'top': newY = target; break;\n case 'bottom': newY = target - n.height; break;\n case 'center-v': newY = target - n.height / 2; break;\n }\n return { ...n, position: { x: newX, y: newY } };\n }),\n },\n },\n };\n });\n },\n [setDoc, currentCanvasId, selection, currentCanvas],\n );\n\n const distribute = useCallback(\n (direction: Distribute) => {\n const ids = selection.nodeIds;\n if (ids.size < 3) return;\n const nodes = currentCanvas.nodes.filter(n => ids.has(n.id));\n if (nodes.length < 3) return;\n\n const sorted = [...nodes].sort((a, b) =>\n direction === 'horizontal'\n ? a.position.x - b.position.x\n : a.position.y - b.position.y,\n );\n\n const first = sorted[0];\n const last = sorted[sorted.length - 1];\n\n if (direction === 'horizontal') {\n const totalWidth = sorted.reduce((s, n) => s + n.width, 0);\n const totalSpace = (last.position.x + last.width) - first.position.x - totalWidth;\n const gap = totalSpace / (sorted.length - 1);\n let x = first.position.x;\n\n const posMap = new Map<string, number>();\n for (const n of sorted) {\n posMap.set(n.id, x);\n x += n.width + gap;\n }\n\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n nodes: canvas.nodes.map(n => {\n const newX = posMap.get(n.id);\n return newX !== undefined ? { ...n, position: { ...n.position, x: newX } } : n;\n }),\n },\n },\n };\n });\n } else {\n const totalHeight = sorted.reduce((s, n) => s + n.height, 0);\n const totalSpace = (last.position.y + last.height) - first.position.y - totalHeight;\n const gap = totalSpace / (sorted.length - 1);\n let y = first.position.y;\n\n const posMap = new Map<string, number>();\n for (const n of sorted) {\n posMap.set(n.id, y);\n y += n.height + gap;\n }\n\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n nodes: canvas.nodes.map(n => {\n const newY = posMap.get(n.id);\n return newY !== undefined ? { ...n, position: { ...n.position, y: newY } } : n;\n }),\n },\n },\n };\n });\n }\n },\n [setDoc, currentCanvasId, selection, currentCanvas],\n );\n\n const changeZIndex = useCallback(\n (mode: LayerMode) => {\n const nodeIds = selection.nodeIds;\n const lineIds = selection.lineIds;\n if (nodeIds.size === 0 && lineIds.size === 0) return;\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n const nodeAllZ = canvas.nodes.map(n => n.zIndex ?? 0);\n const nodeMaxZ = nodeAllZ.length > 0 ? Math.max(...nodeAllZ) : 0;\n const nodeMinZ = nodeAllZ.length > 0 ? Math.min(...nodeAllZ) : 0;\n const lineAllZ = canvas.lines.map(l => l.zIndex ?? 0);\n const lineMaxZ = lineAllZ.length > 0 ? Math.max(...lineAllZ) : 0;\n const lineMinZ = lineAllZ.length > 0 ? Math.min(...lineAllZ) : 0;\n const applyZ = (z: number, maxZ: number, minZ: number) => {\n if (mode === 'front') return maxZ + 1;\n if (mode === 'back') return minZ - 1;\n if (mode === 'up') return z + 1;\n return z - 1;\n };\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n nodes: canvas.nodes.map(n => nodeIds.has(n.id) ? { ...n, zIndex: applyZ(n.zIndex ?? 0, nodeMaxZ, nodeMinZ) } : n),\n lines: canvas.lines.map(l => lineIds.has(l.id) ? { ...l, zIndex: applyZ(l.zIndex ?? 0, lineMaxZ, lineMinZ) } : l),\n },\n },\n };\n });\n },\n [setDoc, currentCanvasId, selection],\n );\n\n return { align, distribute, changeZIndex };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"useLayoutActions.js","names":[],"sources":["../../../../../src/components/pro/Flow/hooks/useLayoutActions.ts"],"sourcesContent":["import { useCallback } from 'react';\nimport { useFlowContext } from '../context/FlowContext';\nimport type { FlowNode } from '../types';\n\ntype Align = 'left' | 'center-h' | 'right' | 'top' | 'center-v' | 'bottom';\ntype Distribute = 'horizontal' | 'vertical';\ntype LayerMode = 'front' | 'back' | 'up' | 'down';\n\nexport function useLayoutActions() {\n const { setDoc, currentCanvasId, selection, currentCanvas } = useFlowContext();\n\n const align = useCallback(\n (direction: Align) => {\n const ids = selection.nodeIds;\n if (ids.size < 2) return;\n const nodes = currentCanvas.nodes.filter(n => ids.has(n.id));\n if (nodes.length < 2) return;\n\n let target: number;\n switch (direction) {\n case 'left':\n target = Math.min(...nodes.map(n => n.position.x));\n break;\n case 'right':\n target = Math.max(...nodes.map(n => n.position.x + n.width));\n break;\n case 'center-h':\n target = nodes.reduce((s, n) => s + n.position.x + n.width / 2, 0) / nodes.length;\n break;\n case 'top':\n target = Math.min(...nodes.map(n => n.position.y));\n break;\n case 'bottom':\n target = Math.max(...nodes.map(n => n.position.y + n.height));\n break;\n case 'center-v':\n target = nodes.reduce((s, n) => s + n.position.y + n.height / 2, 0) / nodes.length;\n break;\n }\n\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n nodes: canvas.nodes.map(n => {\n if (!ids.has(n.id)) return n;\n let newX = n.position.x;\n let newY = n.position.y;\n switch (direction) {\n case 'left': newX = target; break;\n case 'right': newX = target - n.width; break;\n case 'center-h': newX = target - n.width / 2; break;\n case 'top': newY = target; break;\n case 'bottom': newY = target - n.height; break;\n case 'center-v': newY = target - n.height / 2; break;\n }\n return { ...n, position: { x: newX, y: newY } };\n }),\n },\n },\n };\n });\n },\n [setDoc, currentCanvasId, selection, currentCanvas],\n );\n\n const distribute = useCallback(\n (direction: Distribute) => {\n const ids = selection.nodeIds;\n if (ids.size < 3) return;\n const nodes = currentCanvas.nodes.filter(n => ids.has(n.id));\n if (nodes.length < 3) return;\n\n const sorted = [...nodes].sort((a, b) =>\n direction === 'horizontal'\n ? a.position.x - b.position.x\n : a.position.y - b.position.y,\n );\n\n const first = sorted[0];\n const last = sorted[sorted.length - 1];\n\n if (direction === 'horizontal') {\n const totalWidth = sorted.reduce((s, n) => s + n.width, 0);\n const totalSpace = (last.position.x + last.width) - first.position.x - totalWidth;\n const gap = totalSpace / (sorted.length - 1);\n let x = first.position.x;\n\n const posMap = new Map<string, number>();\n for (const n of sorted) {\n posMap.set(n.id, x);\n x += n.width + gap;\n }\n\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n nodes: canvas.nodes.map(n => {\n const newX = posMap.get(n.id);\n return newX !== undefined ? { ...n, position: { ...n.position, x: newX } } : n;\n }),\n },\n },\n };\n });\n } else {\n const totalHeight = sorted.reduce((s, n) => s + n.height, 0);\n const totalSpace = (last.position.y + last.height) - first.position.y - totalHeight;\n const gap = totalSpace / (sorted.length - 1);\n let y = first.position.y;\n\n const posMap = new Map<string, number>();\n for (const n of sorted) {\n posMap.set(n.id, y);\n y += n.height + gap;\n }\n\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n nodes: canvas.nodes.map(n => {\n const newY = posMap.get(n.id);\n return newY !== undefined ? { ...n, position: { ...n.position, y: newY } } : n;\n }),\n },\n },\n };\n });\n }\n },\n [setDoc, currentCanvasId, selection, currentCanvas],\n );\n\n const changeZIndex = useCallback(\n (mode: LayerMode) => {\n const nodeIds = selection.nodeIds;\n const lineIds = selection.lineIds;\n if (nodeIds.size === 0 && lineIds.size === 0) return;\n const applyZ = (z: number, maxZ: number, minZ: number) => {\n if (mode === 'front') return maxZ + 1;\n if (mode === 'back') return minZ - 1;\n if (mode === 'up') return z + 1;\n return z - 1;\n };\n setDoc(prev => {\n const canvas = prev.canvases[currentCanvasId];\n if (!canvas) return prev;\n const nodeAllZ = canvas.nodes.map(n => n.zIndex ?? 0);\n const nodeMaxZ = nodeAllZ.length > 0 ? Math.max(...nodeAllZ) : 0;\n const nodeMinZ = nodeAllZ.length > 0 ? Math.min(...nodeAllZ) : 0;\n const lineAllZ = canvas.lines.map(l => l.zIndex ?? 0);\n const lineMaxZ = lineAllZ.length > 0 ? Math.max(...lineAllZ) : 0;\n const lineMinZ = lineAllZ.length > 0 ? Math.min(...lineAllZ) : 0;\n return {\n ...prev,\n canvases: {\n ...prev.canvases,\n [currentCanvasId]: {\n ...canvas,\n nodes: canvas.nodes.map(n => nodeIds.has(n.id) ? { ...n, zIndex: applyZ(n.zIndex ?? 0, nodeMaxZ, nodeMinZ) } : n),\n lines: canvas.lines.map(l => lineIds.has(l.id) ? { ...l, zIndex: applyZ(l.zIndex ?? 0, lineMaxZ, lineMinZ) } : l),\n },\n },\n };\n });\n },\n [setDoc, currentCanvasId, selection],\n );\n\n return { align, distribute, changeZIndex };\n}\n"],"mappings":"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"}
|
|
@@ -1,68 +1,65 @@
|
|
|
1
1
|
import { ColorPicker as e } from "./Toolbar/ColorPicker.js";
|
|
2
|
-
import { FONT_FAMILIES as t, FONT_SIZES as n } from "./Toolbar/SelectDropdown.js";
|
|
3
|
-
import { useEffect as
|
|
4
|
-
import { Fragment as
|
|
5
|
-
import { useEditorState as
|
|
6
|
-
import { TextSelection as
|
|
2
|
+
import { FONT_FAMILIES as t, FONT_SIZES as n, SelectDropdown as r } from "./Toolbar/SelectDropdown.js";
|
|
3
|
+
import { useCallback as i, useEffect as a, useId as o, useLayoutEffect as s, useRef as c, useState as l } from "react";
|
|
4
|
+
import { Fragment as u, jsx as d, jsxs as f } from "react/jsx-runtime";
|
|
5
|
+
import { useEditorState as p } from "@tiptap/react";
|
|
6
|
+
import { TextSelection as m } from "@tiptap/pm/state";
|
|
7
7
|
//#region src/components/pro/RichTextEditor/BubbleToolbar.tsx
|
|
8
|
-
var
|
|
9
|
-
|
|
10
|
-
editor:
|
|
8
|
+
var h = ({ editor: h, onAddComment: g }) => {
|
|
9
|
+
p({
|
|
10
|
+
editor: h,
|
|
11
11
|
selector: ({ transactionNumber: e }) => e
|
|
12
12
|
});
|
|
13
|
-
let [
|
|
13
|
+
let [_, v] = l(!1), [y, b] = l({
|
|
14
14
|
x: 0,
|
|
15
15
|
y: 0
|
|
16
|
-
}),
|
|
17
|
-
if (
|
|
18
|
-
if (
|
|
19
|
-
let e =
|
|
16
|
+
}), x = c(null), S = o(), C = i((e) => e instanceof Element && e.closest(`[data-rte-palette-owner="${S}"]`) !== null, [S]);
|
|
17
|
+
if (a(() => {
|
|
18
|
+
if (h.isDestroyed) return;
|
|
19
|
+
let e = h.view.dom.ownerDocument, t = e.defaultView;
|
|
20
20
|
if (!t) return;
|
|
21
21
|
let n = null, r = () => {
|
|
22
|
-
n !== null && t.cancelAnimationFrame(n), n = null,
|
|
22
|
+
n !== null && t.cancelAnimationFrame(n), n = null, v(!1);
|
|
23
23
|
}, i = () => {
|
|
24
|
-
if (n = null,
|
|
24
|
+
if (n = null, h.isDestroyed) {
|
|
25
25
|
r();
|
|
26
26
|
return;
|
|
27
27
|
}
|
|
28
|
-
let { from: t, to: i } =
|
|
29
|
-
if (!
|
|
30
|
-
|
|
28
|
+
let { from: t, to: i } = h.state.selection;
|
|
29
|
+
if (!h.isEditable || !(h.state.selection instanceof m) || t === i || !h.isFocused && !x.current?.contains(e.activeElement) && !C(e.activeElement)) {
|
|
30
|
+
v(!1);
|
|
31
31
|
return;
|
|
32
32
|
}
|
|
33
|
-
let a =
|
|
33
|
+
let a = h.view.coordsAtPos(t), o = h.view.coordsAtPos(i), s = h.view.dom.closest(".rte-editor-wrapper");
|
|
34
34
|
if (!s) {
|
|
35
35
|
r();
|
|
36
36
|
return;
|
|
37
37
|
}
|
|
38
38
|
let c = s.getBoundingClientRect(), l = (a.left + o.left) / 2 - c.left - s.clientLeft + s.scrollLeft, u = Math.min(a.top, o.top) - c.top - s.clientTop + s.scrollTop - 44;
|
|
39
|
-
|
|
39
|
+
b({
|
|
40
40
|
x: l,
|
|
41
41
|
y: u
|
|
42
|
-
}),
|
|
42
|
+
}), v(!0);
|
|
43
43
|
}, a = () => {
|
|
44
44
|
n !== null && t.cancelAnimationFrame(n), n = t.requestAnimationFrame(i);
|
|
45
45
|
}, o = ({ event: e }) => {
|
|
46
|
-
e.relatedTarget instanceof Node &&
|
|
46
|
+
e.relatedTarget instanceof Node && (x.current?.contains(e.relatedTarget) || C(e.relatedTarget)) || r();
|
|
47
47
|
};
|
|
48
|
-
return
|
|
49
|
-
n !== null && t.cancelAnimationFrame(n),
|
|
48
|
+
return h.on("transaction", a), h.on("selectionUpdate", a), h.on("focus", a), h.on("blur", o), h.on("destroy", r), e.addEventListener("scroll", a, !0), t.addEventListener("resize", a), i(), () => {
|
|
49
|
+
n !== null && t.cancelAnimationFrame(n), h.off("transaction", a), h.off("selectionUpdate", a), h.off("focus", a), h.off("blur", o), h.off("destroy", r), e.removeEventListener("scroll", a, !0), t.removeEventListener("resize", a);
|
|
50
50
|
};
|
|
51
|
-
}, [
|
|
52
|
-
if (!
|
|
53
|
-
let e =
|
|
51
|
+
}, [h, C]), s(() => {
|
|
52
|
+
if (!_ || !x.current) return;
|
|
53
|
+
let e = x.current, t = e.parentElement;
|
|
54
54
|
if (!t) return;
|
|
55
|
-
let n =
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
}));
|
|
60
|
-
}, [m, g.x]), !m || f.isDestroyed || !f.isEditable) return null;
|
|
61
|
-
let y = (e, t, n, r) => /* @__PURE__ */ c("button", {
|
|
55
|
+
let n = e.offsetWidth;
|
|
56
|
+
e.style.left = `${Math.max(0, Math.min(y.x - n / 2, t.clientWidth - n))}px`;
|
|
57
|
+
}, [_, y.x]), !_ || h.isDestroyed || !h.isEditable) return null;
|
|
58
|
+
let w = (e, t, n, r) => /* @__PURE__ */ d("button", {
|
|
62
59
|
type: "button",
|
|
63
60
|
className: `rte-bubble__btn ${n ? "rte-bubble__btn--active" : ""}`,
|
|
64
61
|
onClick: () => {
|
|
65
|
-
!
|
|
62
|
+
!h.isDestroyed && h.isEditable && e();
|
|
66
63
|
},
|
|
67
64
|
title: t,
|
|
68
65
|
"aria-label": t,
|
|
@@ -70,124 +67,117 @@ var f = ({ editor: f, onAddComment: p }) => {
|
|
|
70
67
|
onMouseDown: (e) => e.preventDefault(),
|
|
71
68
|
children: r
|
|
72
69
|
});
|
|
73
|
-
return /* @__PURE__ */
|
|
74
|
-
ref:
|
|
70
|
+
return /* @__PURE__ */ f("div", {
|
|
71
|
+
ref: x,
|
|
75
72
|
className: "rte-bubble",
|
|
76
73
|
role: "group",
|
|
77
74
|
"aria-label": "Selection formatting",
|
|
78
75
|
onBlur: (e) => {
|
|
79
|
-
!e.currentTarget.contains(e.relatedTarget) && !
|
|
76
|
+
!e.currentTarget.contains(e.relatedTarget) && !C(e.relatedTarget) && !h.isFocused && v(!1);
|
|
80
77
|
},
|
|
81
78
|
onKeyDown: (e) => {
|
|
82
|
-
e.key === "Escape" && (e.preventDefault(),
|
|
83
|
-
},
|
|
84
|
-
style: {
|
|
85
|
-
left: g.x,
|
|
86
|
-
top: g.y
|
|
79
|
+
e.key === "Escape" && (e.preventDefault(), h.commands.focus(), v(!1));
|
|
87
80
|
},
|
|
81
|
+
style: { top: y.y },
|
|
88
82
|
children: [
|
|
89
|
-
|
|
83
|
+
w(() => h.chain().focus().toggleBold().run(), "Bold", h.isActive("bold"), /* @__PURE__ */ d("strong", {
|
|
90
84
|
style: { fontSize: 13 },
|
|
91
85
|
children: "B"
|
|
92
86
|
})),
|
|
93
|
-
|
|
87
|
+
w(() => h.chain().focus().toggleItalic().run(), "Italic", h.isActive("italic"), /* @__PURE__ */ d("em", {
|
|
94
88
|
style: { fontSize: 13 },
|
|
95
89
|
children: "I"
|
|
96
90
|
})),
|
|
97
|
-
|
|
91
|
+
w(() => h.chain().focus().toggleUnderline().run(), "Underline", h.isActive("underline"), /* @__PURE__ */ d("span", {
|
|
98
92
|
style: {
|
|
99
93
|
fontSize: 13,
|
|
100
94
|
textDecoration: "underline"
|
|
101
95
|
},
|
|
102
96
|
children: "U"
|
|
103
97
|
})),
|
|
104
|
-
|
|
98
|
+
w(() => h.chain().focus().toggleStrike().run(), "Strike", h.isActive("strike"), /* @__PURE__ */ d("span", {
|
|
105
99
|
style: {
|
|
106
100
|
fontSize: 13,
|
|
107
101
|
textDecoration: "line-through"
|
|
108
102
|
},
|
|
109
103
|
children: "S"
|
|
110
104
|
})),
|
|
111
|
-
|
|
105
|
+
w(() => h.chain().focus().toggleCode().run(), "Code", h.isActive("code"), /* @__PURE__ */ d("span", {
|
|
112
106
|
style: {
|
|
113
107
|
fontSize: 11,
|
|
114
108
|
fontFamily: "monospace"
|
|
115
109
|
},
|
|
116
110
|
children: "</>"
|
|
117
111
|
})),
|
|
118
|
-
|
|
119
|
-
let e = window.prompt("URL:",
|
|
120
|
-
if (e === null ||
|
|
121
|
-
let t =
|
|
112
|
+
w(() => {
|
|
113
|
+
let e = window.prompt("URL:", h.getAttributes("link").href || "");
|
|
114
|
+
if (e === null || h.isDestroyed || !h.isEditable) return;
|
|
115
|
+
let t = h.chain().focus().extendMarkRange("link");
|
|
122
116
|
e.trim() === "" ? t.unsetLink().run() : t.setLink({ href: e.trim() }).run();
|
|
123
|
-
}, "Link",
|
|
117
|
+
}, "Link", h.isActive("link"), /* @__PURE__ */ f("svg", {
|
|
124
118
|
width: "14",
|
|
125
119
|
height: "14",
|
|
126
120
|
viewBox: "0 0 24 24",
|
|
127
121
|
fill: "none",
|
|
128
122
|
stroke: "currentColor",
|
|
129
123
|
strokeWidth: "2",
|
|
130
|
-
children: [/* @__PURE__ */
|
|
124
|
+
children: [/* @__PURE__ */ d("path", { d: "M10 13a5 5 0 007.54.54l3-3a5 5 0 00-7.07-7.07l-1.72 1.71" }), /* @__PURE__ */ d("path", { d: "M14 11a5 5 0 00-7.54-.54l-3 3a5 5 0 007.07 7.07l1.71-1.71" })]
|
|
131
125
|
})),
|
|
132
|
-
/* @__PURE__ */
|
|
133
|
-
/* @__PURE__ */
|
|
134
|
-
value:
|
|
126
|
+
/* @__PURE__ */ d("div", { className: "rte-bubble__divider" }),
|
|
127
|
+
/* @__PURE__ */ d(e, {
|
|
128
|
+
value: h.getAttributes("textStyle").color || "",
|
|
135
129
|
onChange: (e) => {
|
|
136
|
-
!
|
|
130
|
+
!h.isDestroyed && h.isEditable && (e ? h.chain().focus().setColor(e).run() : h.chain().focus().unsetColor().run());
|
|
137
131
|
},
|
|
138
132
|
title: "Text color",
|
|
139
133
|
buttonClassName: "rte-bubble__btn",
|
|
134
|
+
portalOwner: S,
|
|
140
135
|
kind: "text"
|
|
141
136
|
}),
|
|
142
|
-
/* @__PURE__ */
|
|
143
|
-
value:
|
|
137
|
+
/* @__PURE__ */ d(e, {
|
|
138
|
+
value: h.getAttributes("highlight").color || "",
|
|
144
139
|
onChange: (e) => {
|
|
145
|
-
!
|
|
140
|
+
!h.isDestroyed && h.isEditable && (e ? h.chain().focus().toggleHighlight({ color: e }).run() : h.chain().focus().unsetHighlight().run());
|
|
146
141
|
},
|
|
147
142
|
title: "Highlight color",
|
|
148
143
|
buttonClassName: "rte-bubble__btn",
|
|
144
|
+
portalOwner: S,
|
|
149
145
|
kind: "highlight"
|
|
150
146
|
}),
|
|
151
|
-
/* @__PURE__ */
|
|
152
|
-
/* @__PURE__ */
|
|
147
|
+
/* @__PURE__ */ d("div", { className: "rte-bubble__divider" }),
|
|
148
|
+
/* @__PURE__ */ d(r, {
|
|
153
149
|
className: "rte-bubble__select",
|
|
154
|
-
|
|
150
|
+
width: 96,
|
|
151
|
+
value: h.getAttributes("textStyle").fontFamily || "",
|
|
152
|
+
options: t,
|
|
155
153
|
onChange: (e) => {
|
|
156
|
-
!
|
|
154
|
+
!h.isDestroyed && h.isEditable && (e ? h.chain().focus().setFontFamily(e).run() : h.chain().focus().unsetFontFamily().run());
|
|
157
155
|
},
|
|
158
|
-
title: "Font family"
|
|
159
|
-
"aria-label": "Font family",
|
|
160
|
-
children: t.map((e) => /* @__PURE__ */ c("option", {
|
|
161
|
-
value: e.value,
|
|
162
|
-
children: e.label
|
|
163
|
-
}, e.value))
|
|
156
|
+
title: "Font family"
|
|
164
157
|
}),
|
|
165
|
-
/* @__PURE__ */
|
|
158
|
+
/* @__PURE__ */ d(r, {
|
|
166
159
|
className: "rte-bubble__select rte-bubble__select--size",
|
|
167
|
-
|
|
160
|
+
width: 72,
|
|
161
|
+
value: h.getAttributes("textStyle").fontSize || "",
|
|
162
|
+
options: n,
|
|
168
163
|
onChange: (e) => {
|
|
169
|
-
!
|
|
164
|
+
!h.isDestroyed && h.isEditable && (e ? h.chain().focus().setFontSize(e).run() : h.chain().focus().unsetFontSize().run());
|
|
170
165
|
},
|
|
171
|
-
title: "Font size"
|
|
172
|
-
"aria-label": "Font size",
|
|
173
|
-
children: n.map((e) => /* @__PURE__ */ c("option", {
|
|
174
|
-
value: e.value,
|
|
175
|
-
children: e.label
|
|
176
|
-
}, e.value))
|
|
166
|
+
title: "Font size"
|
|
177
167
|
}),
|
|
178
|
-
|
|
168
|
+
g && /* @__PURE__ */ f(u, { children: [/* @__PURE__ */ d("div", { className: "rte-bubble__divider" }), w(g, "Comment", void 0, /* @__PURE__ */ d("svg", {
|
|
179
169
|
width: "14",
|
|
180
170
|
height: "14",
|
|
181
171
|
viewBox: "0 0 24 24",
|
|
182
172
|
fill: "none",
|
|
183
173
|
stroke: "currentColor",
|
|
184
174
|
strokeWidth: "2",
|
|
185
|
-
children: /* @__PURE__ */
|
|
175
|
+
children: /* @__PURE__ */ d("path", { d: "M21 15a2 2 0 01-2 2H7l-4 4V5a2 2 0 012-2h14a2 2 0 012 2z" })
|
|
186
176
|
}))] })
|
|
187
177
|
]
|
|
188
178
|
});
|
|
189
179
|
};
|
|
190
180
|
//#endregion
|
|
191
|
-
export {
|
|
181
|
+
export { h as default };
|
|
192
182
|
|
|
193
183
|
//# sourceMappingURL=BubbleToolbar.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BubbleToolbar.js","names":[],"sources":["../../../../src/components/pro/RichTextEditor/BubbleToolbar.tsx"],"sourcesContent":["import React, { useState, useEffect, useLayoutEffect, useRef } from 'react';\nimport { useEditorState, type Editor } from '@tiptap/react';\nimport { TextSelection } from '@tiptap/pm/state';\nimport { ColorPicker } from './Toolbar/ColorPicker';\nimport { FONT_FAMILIES, FONT_SIZES } from './Toolbar/SelectDropdown';\n\ninterface BubbleToolbarProps {\n editor: Editor;\n onAddComment?: () => void;\n}\n\nconst BubbleToolbar: React.FC<BubbleToolbarProps> = ({ editor, onAddComment }) => {\n useEditorState({ editor, selector: ({ transactionNumber }) => transactionNumber });\n const [visible, setVisible] = useState(false);\n const [pos, setPos] = useState({ x: 0, y: 0 });\n const ref = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (editor.isDestroyed) return;\n const doc = editor.view.dom.ownerDocument;\n const win = doc.defaultView;\n if (!win) return;\n let frame: number | null = null;\n const hide = () => {\n if (frame !== null) win.cancelAnimationFrame(frame);\n frame = null;\n setVisible(false);\n };\n const update = () => {\n frame = null;\n if (editor.isDestroyed) { hide(); return; }\n const { from, to } = editor.state.selection;\n if (!editor.isEditable || !(editor.state.selection instanceof TextSelection) || from === to || (!editor.isFocused && !ref.current?.contains(doc.activeElement))) {\n setVisible(false);\n return;\n }\n const coords = editor.view.coordsAtPos(from);\n const endCoords = editor.view.coordsAtPos(to);\n const wrapperEl = editor.view.dom.closest<HTMLElement>('.rte-editor-wrapper');\n if (!wrapperEl) { hide(); return; }\n const rect = wrapperEl.getBoundingClientRect();\n\n const centerX = (coords.left + endCoords.left) / 2 - rect.left - wrapperEl.clientLeft + wrapperEl.scrollLeft;\n const topY = Math.min(coords.top, endCoords.top) - rect.top - wrapperEl.clientTop + wrapperEl.scrollTop - 44;\n\n setPos({ x: centerX, y: topY });\n setVisible(true);\n };\n\n const scheduleUpdate = () => {\n if (frame !== null) win.cancelAnimationFrame(frame);\n frame = win.requestAnimationFrame(update);\n };\n const onBlur = ({ event }: { event: FocusEvent }) => {\n if (event.relatedTarget instanceof Node && ref.current?.contains(event.relatedTarget)) return;\n hide();\n };\n editor.on('transaction', scheduleUpdate);\n editor.on('selectionUpdate', scheduleUpdate);\n editor.on('focus', scheduleUpdate);\n editor.on('blur', onBlur);\n editor.on('destroy', hide);\n doc.addEventListener('scroll', scheduleUpdate, true);\n win.addEventListener('resize', scheduleUpdate);\n update();\n return () => {\n if (frame !== null) win.cancelAnimationFrame(frame);\n editor.off('transaction', scheduleUpdate);\n editor.off('selectionUpdate', scheduleUpdate);\n editor.off('focus', scheduleUpdate);\n editor.off('blur', onBlur);\n editor.off('destroy', hide);\n doc.removeEventListener('scroll', scheduleUpdate, true);\n win.removeEventListener('resize', scheduleUpdate);\n };\n }, [editor]);\n\n // Keep the bubble inside the wrapper horizontally: with the extra color /\n // font controls it can be wider than a phone-size editor, and transform:\n // translateX(-50%) would otherwise clip it at either edge.\n useLayoutEffect(() => {\n if (!visible || !ref.current) return;\n const el = ref.current;\n const wrapper = el.parentElement;\n if (!wrapper) return;\n const w = wrapper.clientWidth;\n const half = el.offsetWidth / 2;\n const min = Math.min(half + 4, w / 2);\n const max = Math.max(w - half - 4, w / 2);\n const clamped = Math.min(Math.max(pos.x, min), max);\n if (clamped !== pos.x) setPos((p) => ({ ...p, x: clamped }));\n }, [visible, pos.x]);\n\n if (!visible || editor.isDestroyed || !editor.isEditable) return null;\n\n const btn = (onClick: () => void, title: string, isActive: boolean | undefined, children: React.ReactNode) => (\n <button\n type=\"button\"\n className={`rte-bubble__btn ${isActive ? 'rte-bubble__btn--active' : ''}`}\n onClick={() => { if (!editor.isDestroyed && editor.isEditable) onClick(); }}\n title={title}\n aria-label={title}\n aria-pressed={isActive}\n onMouseDown={(e) => e.preventDefault()}\n >\n {children}\n </button>\n );\n\n return (\n <div ref={ref} className=\"rte-bubble\" role=\"group\" aria-label=\"Selection formatting\"\n onBlur={(event) => {\n if (!event.currentTarget.contains(event.relatedTarget) && !editor.isFocused) setVisible(false);\n }}\n onKeyDown={(event) => {\n if (event.key === 'Escape') {\n event.preventDefault();\n editor.commands.focus();\n setVisible(false);\n }\n }}\n style={{ left: pos.x, top: pos.y }}>\n {btn(() => editor.chain().focus().toggleBold().run(), 'Bold', editor.isActive('bold'),\n <strong style={{ fontSize: 13 }}>B</strong>)}\n {btn(() => editor.chain().focus().toggleItalic().run(), 'Italic', editor.isActive('italic'),\n <em style={{ fontSize: 13 }}>I</em>)}\n {btn(() => editor.chain().focus().toggleUnderline().run(), 'Underline', editor.isActive('underline'),\n <span style={{ fontSize: 13, textDecoration: 'underline' }}>U</span>)}\n {btn(() => editor.chain().focus().toggleStrike().run(), 'Strike', editor.isActive('strike'),\n <span style={{ fontSize: 13, textDecoration: 'line-through' }}>S</span>)}\n {btn(() => editor.chain().focus().toggleCode().run(), 'Code', editor.isActive('code'),\n <span style={{ fontSize: 11, fontFamily: 'monospace' }}></></span>)}\n {btn(() => {\n const url = window.prompt('URL:', editor.getAttributes('link').href || '');\n if (url === null || editor.isDestroyed || !editor.isEditable) return;\n const chain = editor.chain().focus().extendMarkRange('link');\n if (url.trim() === '') chain.unsetLink().run();\n else chain.setLink({ href: url.trim() }).run();\n }, 'Link', editor.isActive('link'),\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\"><path d=\"M10 13a5 5 0 007.54.54l3-3a5 5 0 00-7.07-7.07l-1.72 1.71\" /><path d=\"M14 11a5 5 0 00-7.54-.54l-3 3a5 5 0 007.07 7.07l1.71-1.71\" /></svg>)}\n <div className=\"rte-bubble__divider\" />\n <ColorPicker\n value={editor.getAttributes('textStyle').color || ''}\n onChange={(color) => {\n if (editor.isDestroyed || !editor.isEditable) return;\n if (color) editor.chain().focus().setColor(color).run();\n else editor.chain().focus().unsetColor().run();\n }}\n title=\"Text color\"\n buttonClassName=\"rte-bubble__btn\"\n kind=\"text\"\n />\n <ColorPicker\n value={editor.getAttributes('highlight').color || ''}\n onChange={(color) => {\n if (editor.isDestroyed || !editor.isEditable) return;\n if (color) editor.chain().focus().toggleHighlight({ color }).run();\n else editor.chain().focus().unsetHighlight().run();\n }}\n title=\"Highlight color\"\n buttonClassName=\"rte-bubble__btn\"\n kind=\"highlight\"\n />\n <div className=\"rte-bubble__divider\" />\n <select\n className=\"rte-bubble__select\"\n value={editor.getAttributes('textStyle').fontFamily || ''}\n onChange={(e) => {\n if (editor.isDestroyed || !editor.isEditable) return;\n if (e.target.value) editor.chain().focus().setFontFamily(e.target.value).run();\n else editor.chain().focus().unsetFontFamily().run();\n }}\n title=\"Font family\"\n aria-label=\"Font family\"\n >\n {FONT_FAMILIES.map((opt) => (\n <option key={opt.value} value={opt.value}>{opt.label}</option>\n ))}\n </select>\n <select\n className=\"rte-bubble__select rte-bubble__select--size\"\n value={editor.getAttributes('textStyle').fontSize || ''}\n onChange={(e) => {\n if (editor.isDestroyed || !editor.isEditable) return;\n if (e.target.value) (editor.chain().focus() as any).setFontSize(e.target.value).run();\n else (editor.chain().focus() as any).unsetFontSize().run();\n }}\n title=\"Font size\"\n aria-label=\"Font size\"\n >\n {FONT_SIZES.map((opt) => (\n <option key={opt.value} value={opt.value}>{opt.label}</option>\n ))}\n </select>\n {onAddComment && (\n <>\n <div className=\"rte-bubble__divider\" />\n {btn(onAddComment, 'Comment', undefined,\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\"><path d=\"M21 15a2 2 0 01-2 2H7l-4 4V5a2 2 0 012-2h14a2 2 0 012 2z\" /></svg>)}\n </>\n )}\n </div>\n );\n};\n\nexport default BubbleToolbar;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"BubbleToolbar.js","names":[],"sources":["../../../../src/components/pro/RichTextEditor/BubbleToolbar.tsx"],"sourcesContent":["import React, { useState, useEffect, useLayoutEffect, useRef, useId, useCallback } from 'react';\nimport { useEditorState, type Editor } from '@tiptap/react';\nimport { TextSelection } from '@tiptap/pm/state';\nimport { ColorPicker } from './Toolbar/ColorPicker';\nimport { SelectDropdown, FONT_FAMILIES, FONT_SIZES } from './Toolbar/SelectDropdown';\n\ninterface BubbleToolbarProps {\n editor: Editor;\n onAddComment?: () => void;\n}\n\nconst BubbleToolbar: React.FC<BubbleToolbarProps> = ({ editor, onAddComment }) => {\n useEditorState({ editor, selector: ({ transactionNumber }) => transactionNumber });\n const [visible, setVisible] = useState(false);\n const [pos, setPos] = useState({ x: 0, y: 0 });\n const ref = useRef<HTMLDivElement>(null);\n const bubbleId = useId();\n const ownsPalette = useCallback((target: EventTarget | null) =>\n target instanceof Element && target.closest(`[data-rte-palette-owner=\"${bubbleId}\"]`) !== null, [bubbleId]);\n\n useEffect(() => {\n if (editor.isDestroyed) return;\n const doc = editor.view.dom.ownerDocument;\n const win = doc.defaultView;\n if (!win) return;\n let frame: number | null = null;\n const hide = () => {\n if (frame !== null) win.cancelAnimationFrame(frame);\n frame = null;\n setVisible(false);\n };\n const update = () => {\n frame = null;\n if (editor.isDestroyed) { hide(); return; }\n const { from, to } = editor.state.selection;\n if (!editor.isEditable || !(editor.state.selection instanceof TextSelection) || from === to || (!editor.isFocused && !ref.current?.contains(doc.activeElement) && !ownsPalette(doc.activeElement))) {\n setVisible(false);\n return;\n }\n const coords = editor.view.coordsAtPos(from);\n const endCoords = editor.view.coordsAtPos(to);\n const wrapperEl = editor.view.dom.closest<HTMLElement>('.rte-editor-wrapper');\n if (!wrapperEl) { hide(); return; }\n const rect = wrapperEl.getBoundingClientRect();\n\n const centerX = (coords.left + endCoords.left) / 2 - rect.left - wrapperEl.clientLeft + wrapperEl.scrollLeft;\n const topY = Math.min(coords.top, endCoords.top) - rect.top - wrapperEl.clientTop + wrapperEl.scrollTop - 44;\n\n setPos({ x: centerX, y: topY });\n setVisible(true);\n };\n\n const scheduleUpdate = () => {\n if (frame !== null) win.cancelAnimationFrame(frame);\n frame = win.requestAnimationFrame(update);\n };\n const onBlur = ({ event }: { event: FocusEvent }) => {\n if (event.relatedTarget instanceof Node && (ref.current?.contains(event.relatedTarget) || ownsPalette(event.relatedTarget))) return;\n hide();\n };\n editor.on('transaction', scheduleUpdate);\n editor.on('selectionUpdate', scheduleUpdate);\n editor.on('focus', scheduleUpdate);\n editor.on('blur', onBlur);\n editor.on('destroy', hide);\n doc.addEventListener('scroll', scheduleUpdate, true);\n win.addEventListener('resize', scheduleUpdate);\n update();\n return () => {\n if (frame !== null) win.cancelAnimationFrame(frame);\n editor.off('transaction', scheduleUpdate);\n editor.off('selectionUpdate', scheduleUpdate);\n editor.off('focus', scheduleUpdate);\n editor.off('blur', onBlur);\n editor.off('destroy', hide);\n doc.removeEventListener('scroll', scheduleUpdate, true);\n win.removeEventListener('resize', scheduleUpdate);\n };\n }, [editor, ownsPalette]);\n\n // A transform here turns fixed-position color palettes into descendants of\n // the scrolling editor, where overflow clips them. Position the bubble's\n // left edge directly instead of centering it with translateX(-50%).\n useLayoutEffect(() => {\n if (!visible || !ref.current) return;\n const el = ref.current;\n const wrapper = el.parentElement;\n if (!wrapper) return;\n const width = el.offsetWidth;\n el.style.left = `${Math.max(0, Math.min(pos.x - width / 2, wrapper.clientWidth - width))}px`;\n }, [visible, pos.x]);\n\n if (!visible || editor.isDestroyed || !editor.isEditable) return null;\n\n const btn = (onClick: () => void, title: string, isActive: boolean | undefined, children: React.ReactNode) => (\n <button\n type=\"button\"\n className={`rte-bubble__btn ${isActive ? 'rte-bubble__btn--active' : ''}`}\n onClick={() => { if (!editor.isDestroyed && editor.isEditable) onClick(); }}\n title={title}\n aria-label={title}\n aria-pressed={isActive}\n onMouseDown={(e) => e.preventDefault()}\n >\n {children}\n </button>\n );\n\n return (\n <div ref={ref} className=\"rte-bubble\" role=\"group\" aria-label=\"Selection formatting\"\n onBlur={(event) => {\n if (!event.currentTarget.contains(event.relatedTarget) && !ownsPalette(event.relatedTarget) && !editor.isFocused) setVisible(false);\n }}\n onKeyDown={(event) => {\n if (event.key === 'Escape') {\n event.preventDefault();\n editor.commands.focus();\n setVisible(false);\n }\n }}\n style={{ top: pos.y }}>\n {btn(() => editor.chain().focus().toggleBold().run(), 'Bold', editor.isActive('bold'),\n <strong style={{ fontSize: 13 }}>B</strong>)}\n {btn(() => editor.chain().focus().toggleItalic().run(), 'Italic', editor.isActive('italic'),\n <em style={{ fontSize: 13 }}>I</em>)}\n {btn(() => editor.chain().focus().toggleUnderline().run(), 'Underline', editor.isActive('underline'),\n <span style={{ fontSize: 13, textDecoration: 'underline' }}>U</span>)}\n {btn(() => editor.chain().focus().toggleStrike().run(), 'Strike', editor.isActive('strike'),\n <span style={{ fontSize: 13, textDecoration: 'line-through' }}>S</span>)}\n {btn(() => editor.chain().focus().toggleCode().run(), 'Code', editor.isActive('code'),\n <span style={{ fontSize: 11, fontFamily: 'monospace' }}></></span>)}\n {btn(() => {\n const url = window.prompt('URL:', editor.getAttributes('link').href || '');\n if (url === null || editor.isDestroyed || !editor.isEditable) return;\n const chain = editor.chain().focus().extendMarkRange('link');\n if (url.trim() === '') chain.unsetLink().run();\n else chain.setLink({ href: url.trim() }).run();\n }, 'Link', editor.isActive('link'),\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\"><path d=\"M10 13a5 5 0 007.54.54l3-3a5 5 0 00-7.07-7.07l-1.72 1.71\" /><path d=\"M14 11a5 5 0 00-7.54-.54l-3 3a5 5 0 007.07 7.07l1.71-1.71\" /></svg>)}\n <div className=\"rte-bubble__divider\" />\n <ColorPicker\n value={editor.getAttributes('textStyle').color || ''}\n onChange={(color) => {\n if (editor.isDestroyed || !editor.isEditable) return;\n if (color) editor.chain().focus().setColor(color).run();\n else editor.chain().focus().unsetColor().run();\n }}\n title=\"Text color\"\n buttonClassName=\"rte-bubble__btn\"\n portalOwner={bubbleId}\n kind=\"text\"\n />\n <ColorPicker\n value={editor.getAttributes('highlight').color || ''}\n onChange={(color) => {\n if (editor.isDestroyed || !editor.isEditable) return;\n if (color) editor.chain().focus().toggleHighlight({ color }).run();\n else editor.chain().focus().unsetHighlight().run();\n }}\n title=\"Highlight color\"\n buttonClassName=\"rte-bubble__btn\"\n portalOwner={bubbleId}\n kind=\"highlight\"\n />\n <div className=\"rte-bubble__divider\" />\n <SelectDropdown\n className=\"rte-bubble__select\"\n width={96}\n value={editor.getAttributes('textStyle').fontFamily || ''}\n options={FONT_FAMILIES}\n onChange={(value) => {\n if (editor.isDestroyed || !editor.isEditable) return;\n if (value) editor.chain().focus().setFontFamily(value).run();\n else editor.chain().focus().unsetFontFamily().run();\n }}\n title=\"Font family\"\n />\n <SelectDropdown\n className=\"rte-bubble__select rte-bubble__select--size\"\n width={72}\n value={editor.getAttributes('textStyle').fontSize || ''}\n options={FONT_SIZES}\n onChange={(value) => {\n if (editor.isDestroyed || !editor.isEditable) return;\n if (value) (editor.chain().focus() as any).setFontSize(value).run();\n else (editor.chain().focus() as any).unsetFontSize().run();\n }}\n title=\"Font size\"\n />\n {onAddComment && (\n <>\n <div className=\"rte-bubble__divider\" />\n {btn(onAddComment, 'Comment', undefined,\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\"><path d=\"M21 15a2 2 0 01-2 2H7l-4 4V5a2 2 0 012-2h14a2 2 0 012 2z\" /></svg>)}\n </>\n )}\n </div>\n );\n};\n\nexport default BubbleToolbar;\n"],"mappings":"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"}
|
|
@@ -7,6 +7,8 @@ interface ColorPickerProps {
|
|
|
7
7
|
kind?: 'text' | 'highlight';
|
|
8
8
|
/** Button class; defaults to the classic toolbar button. Bubble toolbar passes its own. */
|
|
9
9
|
buttonClassName?: string;
|
|
10
|
+
/** Portals the palette outside scroll-clipped bubble toolbars. */
|
|
11
|
+
portalOwner?: string;
|
|
10
12
|
}
|
|
11
13
|
export declare const ColorPicker: React.FC<ColorPickerProps>;
|
|
12
14
|
export {};
|