diff --git a/packages/doenetml-worker/src/components/CallAction.js b/packages/doenetml-worker/src/components/CallAction.js
index 72496e8a7..a4b94581c 100644
--- a/packages/doenetml-worker/src/components/CallAction.js
+++ b/packages/doenetml-worker/src/components/CallAction.js
@@ -10,7 +10,7 @@ import {
returnStandardTriggeringAttributes,
} from "../utils/triggering";
import InlineComponent from "./abstract/InlineComponent";
-import me from "math-expressions";
+import { returnSelectedStyleStateVariableDefinition } from "@doenet/utils";
export default class CallAction extends InlineComponent {
constructor(args) {
@@ -109,6 +109,11 @@ export default class CallAction extends InlineComponent {
static returnStateVariableDefinitions() {
let stateVariableDefinitions = super.returnStateVariableDefinitions();
+ let selectedStyleDefinition =
+ returnSelectedStyleStateVariableDefinition();
+
+ Object.assign(stateVariableDefinitions, selectedStyleDefinition);
+
addStandardTriggeringStateVariableDefinitions(
stateVariableDefinitions,
"callAction",
diff --git a/packages/doenetml-worker/src/components/TriggerSet.js b/packages/doenetml-worker/src/components/TriggerSet.js
index 26f282b20..cf73ae85c 100644
--- a/packages/doenetml-worker/src/components/TriggerSet.js
+++ b/packages/doenetml-worker/src/components/TriggerSet.js
@@ -9,7 +9,7 @@ import {
returnStandardTriggeringAttributes,
} from "../utils/triggering";
import InlineComponent from "./abstract/InlineComponent";
-import me from "math-expressions";
+import { returnSelectedStyleStateVariableDefinition } from "@doenet/utils";
export default class triggerSet extends InlineComponent {
constructor(args) {
@@ -72,6 +72,11 @@ export default class triggerSet extends InlineComponent {
static returnStateVariableDefinitions() {
let stateVariableDefinitions = super.returnStateVariableDefinitions();
+ let selectedStyleDefinition =
+ returnSelectedStyleStateVariableDefinition();
+
+ Object.assign(stateVariableDefinitions, selectedStyleDefinition);
+
addStandardTriggeringStateVariableDefinitions(
stateVariableDefinitions,
"triggerActions",
diff --git a/packages/doenetml-worker/src/components/UpdateValue.js b/packages/doenetml-worker/src/components/UpdateValue.js
index 2c645cf21..bfb29b78f 100644
--- a/packages/doenetml-worker/src/components/UpdateValue.js
+++ b/packages/doenetml-worker/src/components/UpdateValue.js
@@ -10,6 +10,7 @@ import {
returnStandardTriggeringAttributes,
} from "../utils/triggering";
import InlineComponent from "./abstract/InlineComponent";
+import { returnSelectedStyleStateVariableDefinition } from "@doenet/utils";
export default class UpdateValue extends InlineComponent {
constructor(args) {
@@ -130,6 +131,11 @@ export default class UpdateValue extends InlineComponent {
static returnStateVariableDefinitions() {
let stateVariableDefinitions = super.returnStateVariableDefinitions();
+ let selectedStyleDefinition =
+ returnSelectedStyleStateVariableDefinition();
+
+ Object.assign(stateVariableDefinitions, selectedStyleDefinition);
+
addStandardTriggeringStateVariableDefinitions(
stateVariableDefinitions,
"updateValue",
diff --git a/packages/doenetml-worker/src/test/tagSpecific/callAction.test.ts b/packages/doenetml-worker/src/test/tagSpecific/callAction.test.ts
index f8ae883e3..924bec46a 100644
--- a/packages/doenetml-worker/src/test/tagSpecific/callAction.test.ts
+++ b/packages/doenetml-worker/src/test/tagSpecific/callAction.test.ts
@@ -2613,4 +2613,28 @@ describe("callAction tag tests", async () => {
"Disabled 2: true",
);
});
+
+ it("buttons can be styled", async () => {
+ let core = await createTestCore({
+ doenetML: `
+
+
+
+
+
+
+
+
+
+ `,
+ });
+
+ let stateVariables = await returnAllStateVariables(core);
+ expect(stateVariables["/ca1"].stateValues.selectedStyle.fillColor).eq(
+ "green",
+ );
+ expect(stateVariables["/ca2"].stateValues.selectedStyle.fillColor).eq(
+ "yellow",
+ );
+ });
});
diff --git a/packages/doenetml-worker/src/test/tagSpecific/mathinput.test.ts b/packages/doenetml-worker/src/test/tagSpecific/mathinput.test.ts
index b96a28338..1dbba0e81 100644
--- a/packages/doenetml-worker/src/test/tagSpecific/mathinput.test.ts
+++ b/packages/doenetml-worker/src/test/tagSpecific/mathinput.test.ts
@@ -6,8 +6,6 @@ import {
updateMathInputImmediateValue,
updateMathInputValue,
updateMathInputValueToImmediateValue,
- updateMatrixInputValue,
- updateTextInputValue,
} from "../utils/actions";
const Mock = vi.fn();
diff --git a/packages/doenetml-worker/src/test/tagSpecific/selectsamplerandomnumbers.test.ts b/packages/doenetml-worker/src/test/tagSpecific/selectsamplerandomnumbers.test.ts
index 7d612f52d..de726755b 100644
--- a/packages/doenetml-worker/src/test/tagSpecific/selectsamplerandomnumbers.test.ts
+++ b/packages/doenetml-worker/src/test/tagSpecific/selectsamplerandomnumbers.test.ts
@@ -1597,7 +1597,7 @@ describe("SelectRandomNumbers and SampleRandomNumbers tag tests", async () => {
specifiedTo,
specifiedStep,
sampleComponent: stateVariables["/samples"],
- allowedErrorInMean: 0.4,
+ allowedErrorInMean: 0.6,
allowedErrorInVariance: 0.4,
checkAllSamples: false,
stateVariables,
diff --git a/packages/doenetml-worker/src/test/tagSpecific/triggerset.test.ts b/packages/doenetml-worker/src/test/tagSpecific/triggerset.test.ts
index e43851bc6..eb05c837b 100644
--- a/packages/doenetml-worker/src/test/tagSpecific/triggerset.test.ts
+++ b/packages/doenetml-worker/src/test/tagSpecific/triggerset.test.ts
@@ -1558,4 +1558,28 @@ describe("TriggerSet tag tests", async () => {
"Disabled 2: true",
);
});
+
+ it("buttons can be styled", async () => {
+ let core = await createTestCore({
+ doenetML: `
+
+
+
+
+
+
+
+
+
+ `,
+ });
+
+ let stateVariables = await returnAllStateVariables(core);
+ expect(stateVariables["/ts1"].stateValues.selectedStyle.fillColor).eq(
+ "green",
+ );
+ expect(stateVariables["/ts2"].stateValues.selectedStyle.fillColor).eq(
+ "yellow",
+ );
+ });
});
diff --git a/packages/doenetml-worker/src/test/tagSpecific/updatevalue.test.ts b/packages/doenetml-worker/src/test/tagSpecific/updatevalue.test.ts
index bc01b0094..5804474a9 100644
--- a/packages/doenetml-worker/src/test/tagSpecific/updatevalue.test.ts
+++ b/packages/doenetml-worker/src/test/tagSpecific/updatevalue.test.ts
@@ -2898,4 +2898,28 @@ describe("UpdateValue tag tests", async () => {
.length,
).eq(2);
});
+
+ it("buttons can be styled", async () => {
+ let core = await createTestCore({
+ doenetML: `
+
+
+
+
+
+
+
+
+
+ `,
+ });
+
+ let stateVariables = await returnAllStateVariables(core);
+ expect(stateVariables["/uv1"].stateValues.selectedStyle.fillColor).eq(
+ "green",
+ );
+ expect(stateVariables["/uv2"].stateValues.selectedStyle.fillColor).eq(
+ "yellow",
+ );
+ });
});
diff --git a/packages/doenetml/src/DoenetML.css b/packages/doenetml/src/DoenetML.css
index 91b32fca4..2d83ad57f 100644
--- a/packages/doenetml/src/DoenetML.css
+++ b/packages/doenetml/src/DoenetML.css
@@ -144,18 +144,12 @@ div.jxgbox input {
}
div.jxgbox button {
margin: 0;
- border-radius: var(--mainBorderRadius);
- border-width: 2px;
- border-color: var(--mainBlue);
- border-style: solid;
- padding: 1px 6px;
- background-color: var(--mainBlue);
+ border-radius: 20px;
+ border-width: 0px;
+ border-style: hidden;
+ padding: 0px 10px;
color: white;
-}
-div.jxgbox button:hover {
- background-color: var(--lightBlue);
- color: black;
- border-color: var(--lightBlue);
+ height: 24px;
}
div.jxgbox input[type="checkbox"] {
margin: 3px 3px 3px 4px;
diff --git a/packages/doenetml/src/Viewer/renderers/button.jsx b/packages/doenetml/src/Viewer/renderers/button.jsx
index bc77200c3..8bca4b116 100644
--- a/packages/doenetml/src/Viewer/renderers/button.jsx
+++ b/packages/doenetml/src/Viewer/renderers/button.jsx
@@ -4,6 +4,7 @@ import { Button } from "@doenet/ui-components";
import { BoardContext } from "./graph";
import me from "math-expressions";
import { getPositionFromAnchorByCoordinate } from "./utils/graph";
+import { cesc } from "@doenet/utils";
export default React.memo(function ButtonComponent(props) {
let { name, id, SVs, actions, callAction } = useDoenetRenderer(
@@ -38,6 +39,8 @@ export default React.memo(function ButtonComponent(props) {
let label = SVs.label ? SVs.label : "Button";
+ let fillColor = SVs.selectedStyle.fillColor;
+
useEffect(() => {
//On unmount
return () => {
@@ -54,6 +57,7 @@ export default React.memo(function ButtonComponent(props) {
disabled: SVs.disabled,
useMathJax: SVs.labelHasLatex,
parse: false,
+ highlight: false,
};
let newAnchorPointJXG;
@@ -366,7 +370,26 @@ export default React.memo(function ButtonComponent(props) {
board.updateRenderer();
}
- return ;
+ // Create css to color the button based on the fillColor from the style definition.
+ // Note: couldn't figure out how to do it with JSXgraphs cssStyle attribute,
+ // as that styled the div container rather than the button itself.
+ // Instead, we're just using an inline style.
+ let containerId = buttonJXG.current.rendNode.id;
+ let buttonCSS = `
+ #${cesc(containerId)} button {
+ background-color: ${fillColor};
+ }
+ #${cesc(containerId)} button:hover {
+ background-color: oklch(from ${fillColor} calc(l * 1.5) c h);
+ color: black;
+ }`;
+
+ return (
+
+
+
+
+ );
}
// not in board
@@ -384,6 +407,7 @@ export default React.memo(function ButtonComponent(props) {
disabled={SVs.disabled}
value={label}
valueHasLatex={SVs.labelHasLatex}
+ fillColor={fillColor}
/>
);
diff --git a/packages/ui-components/package.json b/packages/ui-components/package.json
index 3592f4ca1..5a17879e3 100644
--- a/packages/ui-components/package.json
+++ b/packages/ui-components/package.json
@@ -26,6 +26,9 @@
"command": "vite build",
"files": [
"src/**/*.ts",
+ "src/**/*.js",
+ "src/**/*.tsx",
+ "src/**/*.jsx",
"tsconfig.json"
],
"output": [
diff --git a/packages/ui-components/src/uiComponents/Button.jsx b/packages/ui-components/src/uiComponents/Button.jsx
index ad43429dd..1355c2240 100644
--- a/packages/ui-components/src/uiComponents/Button.jsx
+++ b/packages/ui-components/src/uiComponents/Button.jsx
@@ -11,7 +11,9 @@ const ButtonStyling = styled.button`
// border-width: 2px;
color: white;
background-color: ${(props) =>
- props.alert ? "var(--mainRed)" : "var(--mainBlue)"};
+ props.alert
+ ? "var(--mainRed)"
+ : (props.fillColor ?? "var(--mainBlue)")};
border-radius: ${(props) => props.theme.borderRadius};
padding: ${(props) => props.theme.padding};
cursor: pointer;
@@ -20,7 +22,11 @@ const ButtonStyling = styled.button`
&:hover {
background-color: ${(props) =>
- props.alert ? "var(--lightRed)" : "var(--lightBlue)"};
+ props.alert
+ ? "var(--lightRed)"
+ : props.fillColor
+ ? `oklch(from ${props.fillColor} calc(l * 1.5) c h)`
+ : "var(--lightBlue)"};
color: black;
}