Skip to content

Commit 735c375

Browse files
committed
Merge branch 'docs/update'
2 parents 0776234 + 7d54144 commit 735c375

File tree

15 files changed

+618
-223
lines changed

15 files changed

+618
-223
lines changed
Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
<script setup>
2+
import { reactive } from 'vue'
3+
4+
const emit = defineEmits(['solve', 'reset'])
5+
6+
const state = reactive({
7+
input: '',
8+
})
9+
10+
function setExample(expr) {
11+
state.input = expr
12+
}
13+
14+
function clearInput() {
15+
state.input = ''
16+
}
17+
18+
</script>
19+
20+
<template>
21+
<div class="input">
22+
<div class="panel-header">
23+
<span>Input</span>
24+
<span>{{ state.input.length }} chars</span>
25+
</div>
26+
27+
<div class="input-section">
28+
<div class="input-group">
29+
<label for="expression">Mathematical Expression</label>
30+
<textarea v-model.trim="state.input"
31+
placeholder="Enter your mathematical expression...&#10;Example: 2sin(pi/4)"
32+
spellcheck="false"></textarea>
33+
</div>
34+
35+
<div class="controls">
36+
<button class="btn btn-secondary" @click="() => { clearInput(); emit('reset') }">
37+
RESET
38+
</button>
39+
<div></div>
40+
<button class="btn btn-primary" @click="emit('solve', state.input)">
41+
Evaluate
42+
</button>
43+
</div>
44+
45+
<div class="examples">
46+
<h4>Quick Examples</h4>
47+
<div class="example-list">
48+
<button class="btn" @click="setExample('2 + 3 * 4')">2 + 3 * 4</button>
49+
<button class="btn" @click="setExample('sin(pi/2)')">sin(pi/2)</button>
50+
<button class="btn" @click="setExample(`x = 5\ny = x^2 + 1`)">Variables</button>
51+
<button class="btn" @click="setExample('sqrt(16) + abs(-5)')">Functions</button>
52+
<button class="btn" @click="setExample('log(100) + ln(2.718)')">Logarithms</button>
53+
<button class="btn" @click="setExample('2x + 3(y - 1)')">Implicit &times;</button>
54+
</div>
55+
</div>
56+
</div>
57+
</div>
58+
</template>
59+
60+
<style scoped>
61+
.input {
62+
background: var(--vp-c-bg-soft);
63+
border-right: 1px solid var(--vp-c-divider);
64+
}
65+
66+
@media (max-width: 768px) {
67+
.input {
68+
border-right: none;
69+
}
70+
}
71+
72+
.panel-header {
73+
padding: 16px 20px;
74+
background: var(--vp-c-bg-alt);
75+
border-bottom: 1px solid var(--vp-c-divider);
76+
font-weight: 600;
77+
display: flex;
78+
justify-content: space-between;
79+
align-items: center;
80+
}
81+
82+
.input-section {
83+
padding: 20px;
84+
}
85+
86+
.input-group {
87+
margin-bottom: 20px;
88+
}
89+
90+
.input-group label {
91+
display: block;
92+
margin-bottom: 8px;
93+
font-weight: 500;
94+
color: var(--vp-c-text-2);
95+
font-size: 14px;
96+
}
97+
98+
textarea {
99+
resize: vertical;
100+
width: 100%;
101+
min-height: 200px;
102+
padding: 12px 16px;
103+
border: 1px solid var(--vp-c-border);
104+
border-radius: 8px;
105+
font-family: var(--vp-font-family-mono);
106+
font-size: 16px;
107+
background: var(--vp-c-bg);
108+
transition: border-color 0.2s ease;
109+
}
110+
111+
textarea:focus {
112+
outline: none;
113+
border-color: var(--vp-c-brand-1);
114+
box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
115+
}
116+
117+
.controls {
118+
display: flex;
119+
gap: 12px;
120+
margin-top: 16px;
121+
}
122+
123+
.controls div {
124+
flex-grow: 1;
125+
}
126+
127+
.btn {
128+
padding: 6px 12px;
129+
border: none;
130+
border-radius: 6px;
131+
font-weight: 500;
132+
font-size: 14px;
133+
cursor: pointer;
134+
transition: all 0.2s ease;
135+
display: flex;
136+
align-items: center;
137+
gap: 8px;
138+
}
139+
140+
.btn-primary {
141+
background: var(--vp-c-brand-1);
142+
color: var(--vp-c-text-1);
143+
}
144+
145+
.btn-primary:hover {
146+
transform: translateY(-1px);
147+
}
148+
149+
.btn-secondary {
150+
background: transparent;
151+
color: var(--vp-c-text-2);
152+
}
153+
154+
.btn-secondary:hover {
155+
color: var(--vp-c-text-1);
156+
}
157+
158+
.examples {
159+
margin-top: 20px;
160+
padding-top: 20px;
161+
border-top: 1px solid var(--vp-c-divider);
162+
}
163+
164+
.examples h4 {
165+
font-size: 12px;
166+
color: var(--vp-c-text-2);
167+
margin-bottom: 12px;
168+
text-transform: uppercase;
169+
letter-spacing: 0.05em;
170+
}
171+
172+
.example-list {
173+
display: flex;
174+
flex-wrap: wrap;
175+
gap: 8px;
176+
}
177+
178+
.example-list .btn {
179+
background: var(--vp-c-bg);
180+
color: var(--vp-c-text-1);
181+
border: 1px solid transparent;
182+
}
183+
184+
.example-list .btn:hover {
185+
border: 1px solid var(--vp-c-brand-1);
186+
background: var(--vp-c-bg);
187+
}
188+
</style>
Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
<script setup>
2+
import { reactive } from "vue";
3+
4+
const props = defineProps([
5+
"result",
6+
"solution",
7+
"time",
8+
"tokens",
9+
"html",
10+
"latex",
11+
"error",
12+
]);
13+
14+
const tabs = [
15+
{ id: "result", title: "Result" },
16+
{ id: "tokens", title: "Tokens" },
17+
{ id: "html", title: "HTML" },
18+
{ id: "latex", title: "LaTeX" },
19+
];
20+
21+
const state = reactive({
22+
active: "result",
23+
});
24+
</script>
25+
26+
<template>
27+
<div class="output">
28+
<div class="tabs">
29+
<button v-for="tab in tabs" :key="tab.id" :class="{ active: state.active === tab.id }"
30+
@click="state.active = tab.id">
31+
{{ tab.title }}
32+
</button>
33+
</div>
34+
35+
<div class="tab-content">
36+
<!-- Result Tab -->
37+
<div v-show="state.active === 'result'">
38+
<div class="output-group">
39+
<h3>Result</h3>
40+
<div :class="[
41+
'output-content',
42+
props.error ? 'error' : 'result',
43+
]">
44+
<div v-if="props.error">
45+
{{ props.error?.toString() }}
46+
</div>
47+
<textarea v-else-if="props.result" rows="15"
48+
style="width: 100%;background: transparent;">{{ JSON.stringify(props.result, null, 4) }}</textarea>
49+
<span v-else>Ready to evaluate...</span>
50+
</div>
51+
</div>
52+
53+
<div class="output-group">
54+
<h3>Solution</h3>
55+
<div class="output-content" v-html="props.solution"></div>
56+
</div>
57+
58+
<div class="output-group">
59+
<h3>Execution Info</h3>
60+
<div class="output-content">
61+
<strong>Execution Time:</strong> {{ props.time }}ms
62+
</div>
63+
</div>
64+
</div>
65+
66+
<!-- Tokens Tab -->
67+
<div v-show="state.active === 'tokens'">
68+
<div class="output-group">
69+
<h3>Token Stream</h3>
70+
<div class="output-content token-list">
71+
<div v-for="(t, i) in props.tokens" :key="i" class="token"
72+
:title="`Type: ${t.type}, Line: ${t.line}, Column: ${t.column}`">
73+
<span>{{ t.type }}({{ t.value }})</span>
74+
<span>{{ t.line }}:{{ t.column }}</span>
75+
</div>
76+
<span v-if="!props.tokens.length">
77+
No tokens to display
78+
</span>
79+
</div>
80+
</div>
81+
</div>
82+
83+
<!-- HTML Tab -->
84+
<div v-show="state.active === 'html'">
85+
<div class="output-group">
86+
<h3>HTML Render</h3>
87+
<div v-html="props.html"></div>
88+
</div>
89+
<div class="output-group">
90+
<h3>HTML Code</h3>
91+
<div class="output-content">
92+
<textarea readonly rows="15" style="width: 100%">{{
93+
props.html
94+
}}</textarea>
95+
</div>
96+
</div>
97+
</div>
98+
99+
<!-- LaTeX Tab -->
100+
<div v-show="state.active === 'latex'">
101+
<div class="output-group">
102+
<h3>LaTeX Output</h3>
103+
<div class="output-content">
104+
<textarea readonly rows="15" style="width: 100%">{{
105+
props.latex
106+
}}</textarea>
107+
</div>
108+
</div>
109+
</div>
110+
</div>
111+
</div>
112+
</template>
113+
114+
<style scoped>
115+
.output {
116+
background: var(--vp-c-bg);
117+
/* border: 1px solid var(--vp-c-divider); */
118+
/* border-left: 0; */
119+
}
120+
121+
.tabs {
122+
display: flex;
123+
border-bottom: 1px solid var(--vp-c-divider);
124+
background: var(--vp-c-bg-alt);
125+
}
126+
127+
.tabs button {
128+
padding: 15px 20px;
129+
border: none;
130+
background: none;
131+
color: var(--vp-c-text-1);
132+
font-weight: 500;
133+
cursor: pointer;
134+
border-bottom: 2px solid transparent;
135+
transition: all 0.2s ease;
136+
}
137+
138+
.tabs button.active {
139+
color: var(--vp-c-brand-1);
140+
border-bottom-color: var(--vp-c-brand-1);
141+
}
142+
143+
.tab-content {
144+
padding: 20px;
145+
overflow-y: auto;
146+
}
147+
148+
.output-group {
149+
margin-bottom: 24px;
150+
/* max-height: 75vh; */
151+
}
152+
153+
.output-group h3 {
154+
font-size: 14px;
155+
font-weight: 600;
156+
color: var(--vp-c-text-2);
157+
margin-bottom: 12px;
158+
text-transform: uppercase;
159+
letter-spacing: 0.05em;
160+
}
161+
162+
.output-content {
163+
background: var(--vp-c-bg-soft);
164+
border: 1px solid var(--vp-c-divider);
165+
border-radius: 8px;
166+
padding: 16px;
167+
font-family: var(--vp-font-family-mono);
168+
font-size: 14px;
169+
line-height: 1.6;
170+
overflow-x: auto;
171+
min-height: 60px;
172+
}
173+
174+
.output-content.result {
175+
background: var(--vp-c-success-soft);
176+
border-color: var(--vp-c-success-soft);
177+
color: var(--vp-c-green-1);
178+
font-size: 18px;
179+
font-weight: 600;
180+
}
181+
182+
.output-content.error {
183+
background: var(--vp-c-danger-soft);
184+
border-color: var(--vp-c-danger-soft);
185+
color: var(--vp-c-danger);
186+
}
187+
188+
.token-list {
189+
display: grid;
190+
gap: 1rem;
191+
}
192+
193+
.token {
194+
display: block;
195+
padding: 4px 8px;
196+
border-radius: 4px;
197+
font-weight: 500;
198+
clear: both;
199+
}
200+
201+
.token>span:first-child {
202+
float: left;
203+
}
204+
205+
.token>span:last-child {
206+
float: right;
207+
}
208+
</style>

0 commit comments

Comments
 (0)