summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO.norg4
-rw-r--r--src/declarations.ts3
-rw-r--r--src/eval.ts9
-rw-r--r--src/index.ts3
-rw-r--r--tests/eval.spec.ts44
-rw-r--r--tests/fixtures/todo-app/index.html4
-rw-r--r--tests/todo-app.spec.ts25
7 files changed, 79 insertions, 13 deletions
diff --git a/TODO.norg b/TODO.norg
index c3c3c25..2dc3b78 100644
--- a/TODO.norg
+++ b/TODO.norg
@@ -17,9 +17,9 @@
- (x) component system (with variables. `instance(button#my-btn)`)
- (x) More complex selector support for cssx-children
- (x) `add-element` & `remove-element`
- - ( ) conditionals
- - ( ) figure out how to manage element on change of css variables
+ - (x) conditionals
- ( ) children of instance must also be instantiated
+ - ( ) figure out how to manage element on change of css variables
- ( ) access an instance of component
- ( ) string concatenation
- ( ) `request` error handling
diff --git a/src/declarations.ts b/src/declarations.ts
index 17306bd..0571116 100644
--- a/src/declarations.ts
+++ b/src/declarations.ts
@@ -5,6 +5,7 @@ import { match, matchString } from './utils/adt'
export interface Declaration {
selector: Selector
properties: Map<string, Expr>
+ isInstance: boolean
}
export interface DeclarationEval {
@@ -87,7 +88,7 @@ export const toDeclaration = (expr: Expr): Declaration | undefined => {
selector.selectors.push(SelectorComp.Attr(['data-instance', baseId]))
}
- return { selector, properties }
+ return { selector, properties, isInstance }
}
export const expressionsToDeclrs = async (
diff --git a/src/eval.ts b/src/eval.ts
index a70c760..1a55364 100644
--- a/src/eval.ts
+++ b/src/eval.ts
@@ -70,6 +70,15 @@ const getFunctions = (name: string, args: Expr[], actions: EvalActions) =>
}
},
+ if: async () => {
+ const cond = await evalExpr(args[0], actions)
+ const FALSEY = ['0', 'false']
+ if (cond && !FALSEY.includes(cond.replace(/(^'|")|('|"$)/g, ''))) {
+ return evalExpr(args[1], actions)
+ } else {
+ return evalExpr(args[2], actions)
+ }
+ },
delay: async () => {
const num = await evalExpr(args[0], actions)
num && (await actions.delay(parseInt(num, 10)))
diff --git a/src/index.ts b/src/index.ts
index af8eb23..47e65fe 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -210,12 +210,11 @@ export const manageElement = async (
const text = getPropertyValue($element, '--cssx-text')
if (text) {
- const exprs = parse(text)
try {
+ const exprs = parse(text)
$element.textContent =
(exprs[0] ? await evalExpr(exprs[0], actions) : text) ?? text
} catch (e) {
- console.log(e, exprs)
$element.textContent = text
}
}
diff --git a/tests/eval.spec.ts b/tests/eval.spec.ts
index 2212ba4..1d8b161 100644
--- a/tests/eval.spec.ts
+++ b/tests/eval.spec.ts
@@ -26,6 +26,50 @@ describe('eval', () => {
expect(deps.addClass).toHaveBeenCalledWith('element-id', 'class-name')
})
+ it('should allow conditionals classes', async () => {
+ expect(
+ await evalExpr(
+ Expr.Call({
+ name: 'if',
+ args: [
+ Expr.Identifier('true'),
+ Expr.Identifier('yes'),
+ Expr.Identifier('no'),
+ ],
+ }),
+ deps,
+ ),
+ ).toBe('yes')
+
+ expect(
+ await evalExpr(
+ Expr.Call({
+ name: 'if',
+ args: [
+ Expr.Identifier('false'),
+ Expr.Identifier('yes'),
+ Expr.Identifier('no'),
+ ],
+ }),
+ deps,
+ ),
+ ).toBe('no')
+
+ expect(
+ await evalExpr(
+ Expr.Call({
+ name: 'if',
+ args: [
+ Expr.Identifier('0'),
+ Expr.Identifier('yes'),
+ Expr.Identifier('no'),
+ ],
+ }),
+ deps,
+ ),
+ ).toBe('no')
+ })
+
it('should remove classes', async () => {
await evalExpr(
Expr.Call({
diff --git a/tests/fixtures/todo-app/index.html b/tests/fixtures/todo-app/index.html
index bbf0963..4dea1b4 100644
--- a/tests/fixtures/todo-app/index.html
+++ b/tests/fixtures/todo-app/index.html
@@ -31,10 +31,10 @@
[data-instance='task-item'] {
--text: default text;
- --checked: '0';
+ --checked: false;
--cssx-on-mount: set-attr('data-testid', attr(id));
- --cssx-on-click: update(--checked, '1');
+ --cssx-on-click: update(--checked, if(var(--checked), false, true));
}
[data-instance='task-item']::after {
content: var(--text);
diff --git a/tests/todo-app.spec.ts b/tests/todo-app.spec.ts
index 6595bbf..624efb9 100644
--- a/tests/todo-app.spec.ts
+++ b/tests/todo-app.spec.ts
@@ -1,4 +1,4 @@
-import { getByTestId, prettyDOM } from '@testing-library/dom'
+import { getByTestId } from '@testing-library/dom'
import '@testing-library/jest-dom'
import { delay, loadHTMLFixture } from './util'
@@ -13,7 +13,7 @@ describe('todo-app example', () => {
$textInput.value = text
$addBtn.click()
- await delay(100)
+ await delay(10)
$taskItems = [
...document.querySelectorAll<HTMLElement>(
'[data-instance="task-item"]',
@@ -50,18 +50,31 @@ describe('todo-app example', () => {
)
})
- // TODO: Add toggle state after implementing conditionals
it('should check item when clicked', async () => {
expect(
getComputedStyle($taskItems[0]).getPropertyValue('--checked'),
- ).toBe(`'0'`)
+ ).toBe(`false`)
$taskItems[0].click()
- await delay(100)
+ await delay(10)
expect(
getComputedStyle($taskItems[0]).getPropertyValue('--checked'),
- ).toBe(`"1"`) // TODO: look into the quotes issue
+ ).toBe(`"true"`) // TODO: look into the quotes issue
+
+ $taskItems[0].click()
+ await delay(10)
+
+ expect(
+ getComputedStyle($taskItems[0]).getPropertyValue('--checked'),
+ ).toBe(`"false"`) // TODO: look into the quotes issue
+
+ $taskItems[0].click()
+ await delay(10)
+
+ expect(
+ getComputedStyle($taskItems[0]).getPropertyValue('--checked'),
+ ).toBe(`"true"`) // TODO: look into the quotes issue
})
})
})