From ea1093b2e41d0ad1a315fc95ac44ab778a1b2af8 Mon Sep 17 00:00:00 2001 From: Allison King Date: Mon, 3 Mar 2025 10:57:12 -0800 Subject: [PATCH 1/2] Add math to context editor (#1000) * Initial math * Use two menu buttons for math * Style a bit more * Fix styling * Hide menu in the demo component * Update active states per design * Fix button corners * Fix menu bar height * Add key to fragment Co-authored-by: Thomas F. K. Jorna * Move katex to workspace catalog * Add margins to math-display * Fix blockquote styling * Fix menubar color * Add attribute panel widget to inline math --------- Co-authored-by: Thomas F. K. Jorna --- .../ContextEditor/ContextEditorClient.tsx | 7 +- .../InputComponentConfigurationForm.tsx | 1 + core/package.json | 2 +- packages/context-editor/package.json | 2 + packages/context-editor/src/ContextEditor.tsx | 24 ++- .../context-editor/src/commands/blocks.ts | 2 +- packages/context-editor/src/commands/marks.ts | 2 +- packages/context-editor/src/commands/math.ts | 82 +++++++++ .../src/commands/{utils.ts => util.ts} | 0 .../src/components/AttributePanel.tsx | 7 + .../context-editor/src/components/MenuBar.tsx | 161 ++++++++++++------ packages/context-editor/src/plugins/index.ts | 2 + .../context-editor/src/plugins/inputRules.ts | 12 ++ .../src/plugins/structureDecorations.ts | 7 +- .../context-editor/src/schemas/blockquote.ts | 1 + packages/context-editor/src/schemas/index.ts | 6 +- packages/context-editor/src/schemas/math.ts | 52 ++++++ packages/context-editor/src/style.css | 6 + packages/context-editor/src/utils/nodes.ts | 19 +++ pnpm-lock.yaml | 37 +++- pnpm-workspace.yaml | 1 + 21 files changed, 362 insertions(+), 71 deletions(-) create mode 100644 packages/context-editor/src/commands/math.ts rename packages/context-editor/src/commands/{utils.ts => util.ts} (100%) create mode 100644 packages/context-editor/src/schemas/math.ts create mode 100644 packages/context-editor/src/utils/nodes.ts diff --git a/core/app/components/ContextEditor/ContextEditorClient.tsx b/core/app/components/ContextEditor/ContextEditorClient.tsx index 5801c2111..bf01ece4b 100644 --- a/core/app/components/ContextEditor/ContextEditorClient.tsx +++ b/core/app/components/ContextEditor/ContextEditorClient.tsx @@ -26,13 +26,17 @@ export const ContextEditorClient = ({ initialDoc, onChange, disabled, + hideMenu, }: { pubs: GetPubsResult; pubTypes: GetPubTypesResult; pubId: PubsId; pubTypeId: PubTypesId; // Might be able to use more of this type in the future—for now, this component is a lil more stricty typed than context-editor -} & Pick) => { +} & Pick< + ContextEditorProps, + "onChange" | "initialDoc" | "className" | "disabled" | "hideMenu" +>) => { const getPubs = useCallback( (filter: string) => { return new Promise((resolve, reject) => { @@ -57,6 +61,7 @@ export const ContextEditorClient = ({ initialDoc={initialDoc} disabled={disabled} className={className} + hideMenu={hideMenu} /> ); }, [pubs, pubTypes, disabled]); diff --git a/core/app/components/FormBuilder/ElementPanel/InputComponentConfigurationForm.tsx b/core/app/components/FormBuilder/ElementPanel/InputComponentConfigurationForm.tsx index 66e455ea1..d4d1101a0 100644 --- a/core/app/components/FormBuilder/ElementPanel/InputComponentConfigurationForm.tsx +++ b/core/app/components/FormBuilder/ElementPanel/InputComponentConfigurationForm.tsx @@ -173,6 +173,7 @@ const componentInfo: Record = { pubId={"" as PubsId} pubTypeId={"" as PubTypesId} className="-ml-6 -mt-4 h-full w-full overflow-scroll" + hideMenu /> ); diff --git a/core/package.json b/core/package.json index 56f62dd6a..f0131dcd5 100644 --- a/core/package.json +++ b/core/package.json @@ -100,7 +100,7 @@ "import-in-the-middle": "^1.12.0", "jsonpath-plus": "^10.2.0", "jsonwebtoken": "^9.0.0", - "katex": "^0.16.18", + "katex": "catalog:", "kysely": "^0.27.3", "lodash.partition": "^4.6.0", "logger": "workspace:*", diff --git a/packages/context-editor/package.json b/packages/context-editor/package.json index f80d31ed8..b185d8724 100644 --- a/packages/context-editor/package.json +++ b/packages/context-editor/package.json @@ -50,11 +50,13 @@ "vitest": "catalog:" }, "dependencies": { + "@benrbray/prosemirror-math": "^1.0.0", "@nytimes/react-prosemirror": "^1.0.0", "@prosemirror-adapter/react": "^0.4.0", "deepmerge": "^4.3.1", "fuzzy": "^0.1.3", "install": "^0.13.0", + "katex": "catalog:", "lucide-react": "^0.469.0", "prosemirror-autocomplete": "^0.4.3", "prosemirror-commands": "^1.6.0", diff --git a/packages/context-editor/src/ContextEditor.tsx b/packages/context-editor/src/ContextEditor.tsx index d3aeac1cb..b7ed0d2d0 100644 --- a/packages/context-editor/src/ContextEditor.tsx +++ b/packages/context-editor/src/ContextEditor.tsx @@ -19,6 +19,9 @@ import { baseSchema } from "./schemas"; import "prosemirror-view/style/prosemirror.css"; import "prosemirror-gapcursor/style/gapcursor.css"; +// For math +import "@benrbray/prosemirror-math/dist/prosemirror-math.css"; +import "katex/dist/katex.min.css"; import SuggestPanel from "./components/SuggestPanel"; @@ -41,6 +44,7 @@ export interface ContextEditorProps { atomRenderingComponent: React.ComponentType<{ nodeProp: any; }> /* A react component that is given the ContextAtom pubtype and renders it accordingly */; + hideMenu?: boolean; } export interface PanelProps { @@ -112,14 +116,18 @@ function UnwrappedEditor(props: ContextEditorProps) { suggestData, setSuggestData ), - new Plugin({ - view: pluginViewFactory({ - component: () => , - root: () => { - return document.getElementById(MENU_BAR_ID) as HTMLElement; - }, - }), - }), + ...(props.hideMenu + ? [] + : [ + new Plugin({ + view: pluginViewFactory({ + component: () => , + root: () => { + return document.getElementById(MENU_BAR_ID) as HTMLElement; + }, + }), + }), + ]), ], }); if (viewHost.current) { diff --git a/packages/context-editor/src/commands/blocks.ts b/packages/context-editor/src/commands/blocks.ts index 36c38c451..12e57da7d 100644 --- a/packages/context-editor/src/commands/blocks.ts +++ b/packages/context-editor/src/commands/blocks.ts @@ -3,7 +3,7 @@ import { Node, NodeType } from "prosemirror-model"; import { NodeSelection } from "prosemirror-state"; import type { Attrs, ToggleCommandFn, ToggleOptions } from "./types"; -import { createTypeToggle } from "./utils"; +import { createTypeToggle } from "./util"; const nodeMatchesTypeAndAttrs = (node: Node, type: NodeType, attrs?: Attrs) => { if (node.type === type) { diff --git a/packages/context-editor/src/commands/marks.ts b/packages/context-editor/src/commands/marks.ts index fb43c303f..298b3ab23 100644 --- a/packages/context-editor/src/commands/marks.ts +++ b/packages/context-editor/src/commands/marks.ts @@ -3,7 +3,7 @@ import type { MarkType } from "prosemirror-model"; import { toggleMark as pmToggleMark } from "prosemirror-commands"; import type { ToggleOptions } from "./types"; -import { createTypeToggle } from "./utils"; +import { createTypeToggle } from "./util"; export const markIsActive = (options: ToggleOptions) => { const { type, state } = options; diff --git a/packages/context-editor/src/commands/math.ts b/packages/context-editor/src/commands/math.ts new file mode 100644 index 000000000..13a9bcef4 --- /dev/null +++ b/packages/context-editor/src/commands/math.ts @@ -0,0 +1,82 @@ +import type { Command } from "prosemirror-state"; + +import { EditorState, NodeSelection } from "prosemirror-state"; + +import type { Dispatch } from "./types"; +import { insertNodeIntoEditor } from "../utils/nodes"; +import { createCommandSpec } from "./util"; + +type MathType = "math_inline" | "math_display"; + +const toggleInlineOrBlock: Command = (state: EditorState, dispatch?: Dispatch) => { + const { node } = state.selection as NodeSelection; + const canRun = node && (node.type.name === "math_inline" || node.type.name === "math_display"); + if (!canRun) { + return false; + } + const isDisplay = node.type.name === "math_display"; + if (dispatch) { + const { + schema: { + nodes: { math_display: displayType, math_inline: inlineType }, + }, + } = state; + const swapNodeType = isDisplay ? inlineType : displayType; + const transaction = state.tr.replaceSelectionWith( + swapNodeType.create({}, node.content), + true + ); + dispatch(transaction); + } + return true; +}; + +/** + * If we are not inside any sort of math block, this will add a math element to the editor + * If we are inside a math block of the same type, this will 'undo' it (make it a paragraph). + * If we are inside a math block of the other type, this will transform it to the other type + * (i.e. block <-> inline) + */ +const createMathToggle = (state: EditorState, type: MathType, dispatch?: Dispatch) => { + // Q: should this ever return false? (when can this func not be run?) + const { node } = state.selection as NodeSelection; + const isActive = node && node.type.name === type; + + const other = type === "math_inline" ? "math_display" : "math_inline"; + const isOther = node && node.type.name === other; + if (dispatch) { + if (isOther) { + toggleInlineOrBlock(state, dispatch); + } else { + if (!isActive) { + // Insert a new math block + insertNodeIntoEditor(state, dispatch, type); + } else { + const transaction = state.tr.replaceSelectionWith( + state.schema.nodes.paragraph.create({}, node.content), + true + ); + dispatch(transaction); + } + } + } + + return true; +}; + +const isMathActive = (state: EditorState, type: MathType) => { + const { node } = state.selection as NodeSelection; + return node && node.type.name === type; +}; + +export const mathToggleInline = createCommandSpec((dispatch, state) => ({ + run: () => createMathToggle(state, "math_inline", dispatch), + canRun: createMathToggle(state, "math_inline"), + isActive: isMathActive(state, "math_inline"), +})); + +export const mathToggleBlock = createCommandSpec((dispatch, state) => ({ + run: () => createMathToggle(state, "math_display", dispatch), + canRun: createMathToggle(state, "math_display"), + isActive: isMathActive(state, "math_display"), +})); diff --git a/packages/context-editor/src/commands/utils.ts b/packages/context-editor/src/commands/util.ts similarity index 100% rename from packages/context-editor/src/commands/utils.ts rename to packages/context-editor/src/commands/util.ts diff --git a/packages/context-editor/src/components/AttributePanel.tsx b/packages/context-editor/src/components/AttributePanel.tsx index 328e4c663..bf7aae2e0 100644 --- a/packages/context-editor/src/components/AttributePanel.tsx +++ b/packages/context-editor/src/components/AttributePanel.tsx @@ -108,6 +108,10 @@ export function AttributePanel({ panelPosition, viewRef }: AttributePanelProps) ) ); }; + // Marks will automatically show names, so it is only the 'inline' types + // that are not marks that need to be specifically rendered + const showName = node.type?.name === "math_inline"; + return ( <> {node && ( @@ -135,6 +139,9 @@ export function AttributePanel({ panelPosition, viewRef }: AttributePanelProps) }} >
Attributes
+ {showName ? ( +
{node.type?.name}
+ ) : null} {Object.keys(nodeAttrs).map((attrKey) => { if (attrKey === "data") { return null; diff --git a/packages/context-editor/src/components/MenuBar.tsx b/packages/context-editor/src/components/MenuBar.tsx index 4d618807f..8cf1fbd5e 100644 --- a/packages/context-editor/src/components/MenuBar.tsx +++ b/packages/context-editor/src/components/MenuBar.tsx @@ -1,8 +1,9 @@ +import type { LucideProps } from "lucide-react"; import type { ReactNode } from "react"; -import React from "react"; +import React, { Fragment } from "react"; import { usePluginViewContext } from "@prosemirror-adapter/react"; -import { Quote } from "lucide-react"; +import { Bold, Italic, Quote, Radical, SquareRadical } from "lucide-react"; import { Button } from "ui/button"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "ui/select"; @@ -20,73 +21,97 @@ import { paragraphToggle, } from "../commands/blocks"; import { emToggle, strongToggle } from "../commands/marks"; +import { mathToggleBlock, mathToggleInline } from "../commands/math"; type MenuItem = { key: string; - name?: string; + name: string; icon: ReactNode; command: CommandSpec; }; -const menuItems: MenuItem[] = [ - { - key: "strong", - icon: "B", - command: strongToggle, - }, - { - key: "em", - icon: I, - command: emToggle, - }, - { - key: "blockquote", - icon: , - command: blockquoteToggle, - }, +const iconProps: LucideProps = { + strokeWidth: "1px", +}; + +const menuBlocks: MenuItem[][] = [ + [ + { + key: "strong", + name: "Bold", + icon: , + command: strongToggle, + }, + { + key: "em", + name: "Italic", + icon: , + command: emToggle, + }, + ], + [ + { + key: "blockquote", + name: "Blockquote", + icon: , + command: blockquoteToggle, + }, + { + key: "inline-math", + name: "Inline math", + icon: , + command: mathToggleInline, + }, + { + key: "block-math", + name: "Block math", + icon: , + command: mathToggleBlock, + }, + ], ]; const paragraphTypeItems: MenuItem[] = [ { key: "paragraph", name: "Paragraph", - icon: "Paragraph", + icon: Paragraph, command: paragraphToggle, }, { key: "h1", name: "Heading 1", - icon: Heading 1, + icon: Heading 1, command: heading1Toggle, }, { key: "h2", name: "Heading 2", - icon: Heading 2, + icon: Heading 2, command: heading2Toggle, }, { key: "h3", name: "Heading 3", - icon: Heading 3, + icon: Heading 3, command: heading3Toggle, }, { key: "h4", name: "Heading 4", - icon: Heading 4, + icon: Heading 4, command: heading4Toggle, }, { key: "h5", name: "Heading 5", - icon: Heading 5, + icon: Heading 5, command: heading5Toggle, }, { key: "h6", name: "Heading 6", - icon: Heading 6, + icon: Heading 6, command: heading6Toggle, }, ]; @@ -110,13 +135,13 @@ const ParagraphDropdown = () => { }} disabled={!activeType} > - + - {activeType ? activeType.name || activeType.key : "Paragraph"} + {activeType ? activeType.name : "Paragraph"} - {paragraphTypeItems.map(({ key, icon, command }) => { + {paragraphTypeItems.map(({ key, icon }) => { return ( {icon} @@ -128,35 +153,67 @@ const ParagraphDropdown = () => { ); }; -export const MenuBar = () => { +const MenuItemButton = ({ menuItem }: { menuItem: MenuItem }) => { const { view } = usePluginViewContext(); + const { key, name, icon, command } = menuItem; + const { run, canRun, isActive } = command(view)(view.state); + return ( + + ); +}; + +const Separator = () => { + return ( +
+
+
+ ); +}; + +export const MenuBar = () => { return (
- {menuItems.map((menuItem) => { - const { key, icon, command } = menuItem; - const { run, canRun, isActive } = command(view)(view.state); - return ( - - ); - })} - +
+ + +
+
+ {menuBlocks.map((menuBlock, index) => { + const isLast = index === menuBlocks.length - 1; + return ( + +
+ {menuBlock.map((menuItem) => { + return ( + + ); + })} +
+ {!isLast && } +
+ ); + })} +
); }; diff --git a/packages/context-editor/src/plugins/index.ts b/packages/context-editor/src/plugins/index.ts index 49a39583d..3d50fb96f 100644 --- a/packages/context-editor/src/plugins/index.ts +++ b/packages/context-editor/src/plugins/index.ts @@ -1,3 +1,4 @@ +import { mathPlugin } from "@benrbray/prosemirror-math"; import { exampleSetup } from "prosemirror-example-setup"; import { Schema } from "prosemirror-model"; @@ -24,6 +25,7 @@ export const basePlugins = ( structureDecorations(), attributePanel(panelPosition, setPanelPosition), onChange(), + mathPlugin, inputRules(schema), ]; }; diff --git a/packages/context-editor/src/plugins/inputRules.ts b/packages/context-editor/src/plugins/inputRules.ts index 7a714ea60..a25179a30 100644 --- a/packages/context-editor/src/plugins/inputRules.ts +++ b/packages/context-editor/src/plugins/inputRules.ts @@ -1,6 +1,12 @@ import type { MarkType, NodeType } from "prosemirror-model"; import type { EditorState } from "prosemirror-state"; +import { + makeBlockMathInputRule, + makeInlineMathInputRule, + REGEX_BLOCK_MATH_DOLLARS, + REGEX_INLINE_MATH_DOLLARS, +} from "@benrbray/prosemirror-math"; import { InputRule, inputRules, wrappingInputRule } from "prosemirror-inputrules"; import { Fragment, Schema } from "prosemirror-model"; @@ -40,6 +46,10 @@ const applyMarkRule = (markType: MarkType, regex: RegExp) => { ); }; const blockQuoteRule = (nodeType: NodeType) => wrappingInputRule(/^\s*>\s$/, nodeType); +const inlineMathRule = (nodeType: NodeType) => + makeInlineMathInputRule(REGEX_INLINE_MATH_DOLLARS, nodeType); +const blockMathRule = (nodeType: NodeType) => + makeBlockMathInputRule(REGEX_BLOCK_MATH_DOLLARS, nodeType); export default (schema: Schema) => { const rules = [ @@ -56,6 +66,8 @@ export default (schema: Schema) => { applyMarkRule(schema.marks.strong, boldRegex), applyMarkRule(schema.marks.em, italicsRegex), blockQuoteRule(schema.nodes.blockquote), + inlineMathRule(schema.nodes.math_inline), + blockMathRule(schema.nodes.math_display), ]; return inputRules({ rules }); }; diff --git a/packages/context-editor/src/plugins/structureDecorations.ts b/packages/context-editor/src/plugins/structureDecorations.ts index b46802296..1c32a550a 100644 --- a/packages/context-editor/src/plugins/structureDecorations.ts +++ b/packages/context-editor/src/plugins/structureDecorations.ts @@ -83,8 +83,11 @@ export default () => { Decoration.widget(pos, wrapWidget(state, node, pos, setPanelPosition)) ); } - if (!node.type.isBlock && node.marks.length) { - /* If it's an inline node with marks */ + const isInline = !node.type.isBlock; + const hasMarks = !!node.marks.length; + const isMath = node.type.name === "math_inline"; + if (isInline && (hasMarks || isMath)) { + /* If it's an inline node with marks OR is inline math */ decorations.push( Decoration.widget(pos, wrapWidget(state, node, pos, setPanelPosition)) ); diff --git a/packages/context-editor/src/schemas/blockquote.ts b/packages/context-editor/src/schemas/blockquote.ts index 983567cad..87208fa42 100644 --- a/packages/context-editor/src/schemas/blockquote.ts +++ b/packages/context-editor/src/schemas/blockquote.ts @@ -14,6 +14,7 @@ export default { getAttrs: (node) => { return { id: (node as Element).getAttribute("id"), + class: (node as Element).getAttribute("class"), }; }, }, diff --git a/packages/context-editor/src/schemas/index.ts b/packages/context-editor/src/schemas/index.ts index 2a7fc1272..6ef716b5a 100644 --- a/packages/context-editor/src/schemas/index.ts +++ b/packages/context-editor/src/schemas/index.ts @@ -4,14 +4,11 @@ import blockquote from "./blockquote"; import inlineCode from "./code"; import contextAtom from "./contextAtom"; import contextDoc from "./contextDoc"; -// import { marks, nodes } from "prosemirror-schema-basic"; - -/* Nodes */ import doc from "./doc"; import em from "./em"; import heading from "./heading"; +import math from "./math"; import paragraph from "./paragraph"; -/* Marks */ import strong from "./strong"; import text from "./text"; @@ -24,6 +21,7 @@ export const baseSchema = new Schema({ contextDoc, contextAtom, blockquote, + ...math, }, marks: { strong, diff --git a/packages/context-editor/src/schemas/math.ts b/packages/context-editor/src/schemas/math.ts new file mode 100644 index 000000000..c3780c145 --- /dev/null +++ b/packages/context-editor/src/schemas/math.ts @@ -0,0 +1,52 @@ +import type { DOMOutputSpec, MarkSpec, NodeSpec } from "prosemirror-model"; + +const mathInline = { + attrs: { + id: { default: null }, + class: { default: null }, + }, + content: "text*", + group: "inline math", + inline: true, + atom: true, + parseDOM: [ + { + tag: "math-inline", + getAttrs: (node) => { + return { + id: (node as Element).getAttribute("id"), + class: (node as Element).getAttribute("class"), + }; + }, + }, + ], + toDOM: () => ["math-inline", { class: "math-node" }, 0], +} satisfies NodeSpec; + +const mathDisplay = { + attrs: { + id: { default: null }, + class: { default: null }, + }, + group: "block math", + content: "text*", + atom: true, + code: true, + parseDOM: [ + { + tag: "math-display", + getAttrs: (node) => { + return { + id: (node as Element).getAttribute("id"), + class: (node as Element).getAttribute("class"), + }; + }, + }, + ], + toDOM: () => ["math-display", { class: "math-node" }, 0], +} satisfies NodeSpec; + +export default { + math_inline: mathInline, + math_display: mathDisplay, +}; diff --git a/packages/context-editor/src/style.css b/packages/context-editor/src/style.css index 7f0deda5a..31eaf5fcc 100644 --- a/packages/context-editor/src/style.css +++ b/packages/context-editor/src/style.css @@ -92,6 +92,8 @@ .ProseMirror h6, .ProseMirror p, .ProseMirror code, +.ProseMirror math-display, +.ProseMirror blockquote, .ProseMirror section { border-left: 1px solid #777; padding-left: 5px; @@ -142,3 +144,7 @@ padding-left: 1rem; border-left: solid 4px rgba(181, 181, 181, 0.5); } +.ProseMirror math-inline { + /* Otherwise the widget button is too hard to click without triggering math */ + margin-left: 4px; +} diff --git a/packages/context-editor/src/utils/nodes.ts b/packages/context-editor/src/utils/nodes.ts new file mode 100644 index 000000000..d4305838b --- /dev/null +++ b/packages/context-editor/src/utils/nodes.ts @@ -0,0 +1,19 @@ +import type { EditorState } from "prosemirror-state"; + +import { Node } from "prosemirror-model"; + +import type { Dispatch } from "../commands/types"; + +export const insertNodeIntoEditor = ( + state: EditorState, + dispatch: Dispatch, + nodeType: string, + attrs?: Node["attrs"] +) => { + const { schema, tr } = state; + const nodeSchema = schema.nodes[nodeType]; + + const node = nodeSchema.create(attrs); + const transaction = tr.replaceSelectionWith(node); + dispatch(transaction); +}; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0f1a8566e..df1f3f02d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -48,6 +48,9 @@ catalogs: eslint: specifier: ^9.9.0 version: 9.10.0 + katex: + specifier: ^0.16.18 + version: 0.16.18 next: specifier: ^15.1.0 version: 15.1.4 @@ -371,7 +374,7 @@ importers: specifier: ^9.0.0 version: 9.0.2 katex: - specifier: ^0.16.18 + specifier: 'catalog:' version: 0.16.18 kysely: specifier: ^0.27.3 @@ -672,6 +675,9 @@ importers: packages/context-editor: dependencies: + '@benrbray/prosemirror-math': + specifier: ^1.0.0 + version: 1.0.0(katex@0.16.18)(prosemirror-commands@1.6.1)(prosemirror-history@1.4.1)(prosemirror-inputrules@1.4.0)(prosemirror-keymap@1.2.2)(prosemirror-model@1.24.1)(prosemirror-state@1.4.3)(prosemirror-transform@1.10.2)(prosemirror-view@1.34.3) '@nytimes/react-prosemirror': specifier: ^1.0.0 version: 1.0.0(prosemirror-model@1.24.1)(prosemirror-state@1.4.3)(prosemirror-view@1.34.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) @@ -687,6 +693,9 @@ importers: install: specifier: ^0.13.0 version: 0.13.0 + katex: + specifier: 'catalog:' + version: 0.16.18 lucide-react: specifier: ^0.469.0 version: 0.469.0(react@19.0.0) @@ -2155,6 +2164,19 @@ packages: resolution: {integrity: sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==} engines: {node: '>=6.9.0'} + '@benrbray/prosemirror-math@1.0.0': + resolution: {integrity: sha512-5fPeOKP6SJJ3usXhhf6vnLXGJnfPHPzv0OdsOJlGkCdZvNfCuC6f8fZqgpmnP8vxDKjB8fvSVSmAHTMsaiXc6w==} + peerDependencies: + katex: ^0.16.10 + prosemirror-commands: ^1.5.2 + prosemirror-history: ^1.4.0 + prosemirror-inputrules: ^1.4.0 + prosemirror-keymap: ^1.2.2 + prosemirror-model: ^1.20.0 + prosemirror-state: ^1.4.3 + prosemirror-transform: ^1.8.0 + prosemirror-view: ^1.33.4 + '@chromatic-com/storybook@1.9.0': resolution: {integrity: sha512-vYQ+TcfktEE3GHnLZXHCzXF/sN9dw+KivH8a5cmPyd9YtQs7fZtHrEgsIjWpYycXiweKMo1Lm1RZsjxk8DH3rA==} engines: {node: '>=16.0.0', yarn: '>=1.22.18'} @@ -9051,6 +9073,7 @@ packages: resolution: {integrity: sha512-t0etAxTUk1w5MYdNOkZBZ8rvYYN5iL+2dHCCx/DpkFm/bW28M6y5nUS83D4XdZiHy35Fpaw6LBb+F88fHZnVCw==} engines: {node: '>=8.17.0'} hasBin: true + bundledDependencies: [] jsonfile@6.1.0: resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} @@ -13537,6 +13560,18 @@ snapshots: '@babel/helper-validator-identifier': 7.24.7 to-fast-properties: 2.0.0 + '@benrbray/prosemirror-math@1.0.0(katex@0.16.18)(prosemirror-commands@1.6.1)(prosemirror-history@1.4.1)(prosemirror-inputrules@1.4.0)(prosemirror-keymap@1.2.2)(prosemirror-model@1.24.1)(prosemirror-state@1.4.3)(prosemirror-transform@1.10.2)(prosemirror-view@1.34.3)': + dependencies: + katex: 0.16.18 + prosemirror-commands: 1.6.1 + prosemirror-history: 1.4.1 + prosemirror-inputrules: 1.4.0 + prosemirror-keymap: 1.2.2 + prosemirror-model: 1.24.1 + prosemirror-state: 1.4.3 + prosemirror-transform: 1.10.2 + prosemirror-view: 1.34.3 + '@chromatic-com/storybook@1.9.0(react@19.0.0)': dependencies: chromatic: 11.10.4 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 1be694f94..0de524495 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -9,6 +9,7 @@ packages: catalog: next: ^15.1.0 eslint: ^9.9.0 + katex: ^0.16.18 prettier: ^3.4.2 tailwindcss: ^3.4.10 tailwind-merge: ^2.5.2 From 27b2edd721ab60e64b2868dbf895165f7cc3514b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 4 Mar 2025 11:13:06 +0100 Subject: [PATCH 2/2] github-actions(deps): bump docker/build-push-action from 5 to 6 (#990) * github-actions(deps): bump docker/build-push-action from 5 to 6 Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 5 to 6. - [Release notes](https://github.com/docker/build-push-action/releases) - [Commits](https://github.com/docker/build-push-action/compare/v5...v6) --- updated-dependencies: - dependency-name: docker/build-push-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] * fix: add permissions --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Thomas F. K. Jorna --- .github/workflows/ecrbuild-template.yml | 2 +- .github/workflows/on_pr.yml | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ecrbuild-template.yml b/.github/workflows/ecrbuild-template.yml index d80a72eb5..5aa8934d1 100644 --- a/.github/workflows/ecrbuild-template.yml +++ b/.github/workflows/ecrbuild-template.yml @@ -114,7 +114,7 @@ jobs: fi - name: Build, tag, and push image to Amazon ECR - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6 id: build-image env: REGISTRY_REF: ${{steps.login-ecr.outputs.registry}}/${{env.ECR_REPOSITORY_PREFIX}}-${{env.PACKAGE}}:cache diff --git a/.github/workflows/on_pr.yml b/.github/workflows/on_pr.yml index a0b65beb7..97e96c291 100644 --- a/.github/workflows/on_pr.yml +++ b/.github/workflows/on_pr.yml @@ -11,6 +11,10 @@ on: env: AWS_REGION: us-east-1 +permissions: + id-token: write + contents: read + jobs: ci: uses: ./.github/workflows/ci.yml