aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--TODO.norg17
-rw-r--r--examples/form/signup.css17
-rw-r--r--examples/form/style.css17
-rw-r--r--examples/todo-list/style.css11
-rw-r--r--src/index.ts30
5 files changed, 55 insertions, 37 deletions
diff --git a/TODO.norg b/TODO.norg
index 59a664f..3c428d9 100644
--- a/TODO.norg
+++ b/TODO.norg
@@ -19,17 +19,14 @@
- (x) `add-element` & `remove-element`
- (x) conditionals
- (x) on update
- - ( ) children of instance must also be instantiated
- - ( ) access child from an instance (update checkbox)
- - ( ) access instance from child (delete task)
- - ( ) filter for on update on specific properties
- - ( ) eval
- - ( ) update property on child on update of parent
- - ( ) functions/lazy properties?
- - ( ) string concatenation
- - ( ) `request` error handling
+ - (x) access child from an instance (update checkbox)
+ - (x) access instance from child (delete task)
+ - ( ) Update --cssx-text on update
- ( ) keyboard events
+ - ( ) string concatenation
+ - ( ) eval
- ( ) Code cleanup
+ - ( ) `request` error handling
* Later
- ( ) `add-class` & `remove-class` should use self if id is not specified?
@@ -37,6 +34,8 @@
- ( ) access an instance of component
- ( ) Additional events
- ( ) Improve error messages
+ - ( ) filter for on update on specific properties
+ - ( ) update property on child on update of parent
* Maybe
- ( ) `list` & `tuple` data structures?
diff --git a/examples/form/signup.css b/examples/form/signup.css
index e633243..3433b87 100644
--- a/examples/form/signup.css
+++ b/examples/form/signup.css
@@ -4,10 +4,11 @@
max-width: 700px;
margin: 1rem auto;
- --cssx-disgustingly-set-innerhtml: "<h1 class='form-title'>Sign-<b>Up</b></h1>";
+ --count: '0';
+ --cssx-disgustingly-set-innerhtml:
+ "<h1 class='form-title'>Sign-<b>Up</b></h1>";
--cssx-children: form#form;
- --count: '0';
}
.form-title {
@@ -25,11 +26,15 @@
#form {
display: block;
- --cssx-on-submit: prevent-default() add-class(form, 'submitting')
- request('/examples/') remove-class(form, 'submitting')
- add-class(form, 'submitted');
+ --cssx-on-submit:
+ prevent-default()
+ add-class(form, 'submitting')
+ request('/examples/')
+ remove-class(form, 'submitting')
+ add-class(form, 'submitted')
+ ;
- --cssx-children: input#input-email input#input-password actions #message;
+ --cssx-children: input#input-email input#input-password #actions #message;
}
#form.submitted #message::after {
display: block;
diff --git a/examples/form/style.css b/examples/form/style.css
index 63f758b..8229ef0 100644
--- a/examples/form/style.css
+++ b/examples/form/style.css
@@ -1,9 +1,7 @@
body {
- --cssx-children: button#signup-btn signup-page;
-}
-body * {
- box-sizing: border-box;
+ --cssx-children: button#signup-btn #signup-page;
}
+body * { box-sizing: border-box; }
#signup-btn {
display: inline-block;
@@ -14,10 +12,13 @@ body * {
padding: 0.5rem 1rem;
cursor: pointer;
- --cssx-on-click: add-class(signup-page, 'loading')
- add-class(signup-btn, 'loading') delay(0.5s)
+ --cssx-on-click:
+ add-class(signup-page, 'loading')
+ add-class(signup-btn, 'loading')
+ delay(0.5s)
load-cssx(signup-page-content, './signup.css')
- remove-class(signup-page, 'loading') remove-class(signup-btn, 'loading');
+ remove-class(signup-page, 'loading')
+ remove-class(signup-btn, 'loading');
}
#signup-btn::after {
content: 'Register now to start your free trial for $99';
@@ -31,7 +32,7 @@ body * {
}
#signup-page {
- --cssx-children: signup-page-content;
+ --cssx-children: div#signup-page-content;
}
#signup-page.loading::after {
content: 'Loading...';
diff --git a/examples/todo-list/style.css b/examples/todo-list/style.css
index b3b9d07..d4cd391 100644
--- a/examples/todo-list/style.css
+++ b/examples/todo-list/style.css
@@ -87,8 +87,10 @@ body * { box-sizing: border-box; }
width: 100%;
align-items: center;
+ --cssx-on-mount: update(--task-item-id, attr(data-element));
+
--cssx-on-click: update(--done, if(get-var(--done), "false", "true"));
- --cssx-on-update: update(checkbox, --checked, if(get-var(--done), true, false));
+ --cssx-on-update: update(":scope [data-element=checkbox]", --checked, if(get-var(--done), true, false));
--cssx-children: div#checkbox div#task-text button#delete-task;
}
@@ -97,7 +99,7 @@ body * { box-sizing: border-box; }
flex: 2;
}
[data-instance=task-item] [data-element=task-text]::after {
- content: "[" var(--done) "] " var(--text);
+ content: var(--text);
padding-left: 0.8rem;
}
@@ -115,11 +117,10 @@ body * { box-sizing: border-box; }
background-color: transparent;
--cssx-on-update:
- update(background-color, if(get-var(--checked), get-var(--color-accent), transparent))
- ;
+ update(background-color, if(get-var(--checked), get-var(--color-accent), transparent));
}
[data-instance=task-item] [data-element=delete-task] {
--cssx-text: 'Delete';
- --cssx-on-click: remove-element(task-item);
+ --cssx-on-click: remove-element(get-var(--task-item-id));
}
diff --git a/src/index.ts b/src/index.ts
index c1b997d..2392c9e 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -64,15 +64,27 @@ export const getDeclarations = (
return extractDeclaration(value, actions)
}
+const getElement = (
+ id: string,
+ $node: HTMLElement | Document = document,
+): HTMLElement | null => {
+ // TODO: Please no ternary
+ const [$element, selector] = /^('|")?[a-z0-9_-]+\1$/gi.test(id)
+ ? [document, `[data-element=${id}]`]
+ : /^:scope/i.test(id)
+ ? [$node, id]
+ : [document, id]
+ return $element.querySelector<HTMLElement>(selector)
+}
+
const getEvalActions = (
$element: HTMLElement,
{ event = null, pure = false }: { event?: any; pure?: boolean },
): EvalActions => {
const actions: EvalActions = {
- addClass: async (id, cls) =>
- document.getElementById(id)?.classList.add(cls),
+ addClass: async (id, cls) => getElement(id, $element)?.classList.add(cls),
removeClass: async (id, cls) =>
- document.getElementById(id)?.classList.remove(cls),
+ getElement(id, $element)?.classList.remove(cls),
delay: delay => new Promise(res => setTimeout(res, delay)),
jsEval: async js => !pure && (0, eval)(js),
loadCssx: async (id, url) =>
@@ -84,7 +96,7 @@ const getEvalActions = (
rel: 'stylesheet',
})
$link.onload = () => {
- const $el = document.getElementById(id)
+ const $el = getElement(id, $element)
if ($el) {
manageElement($el)
resolve(id)
@@ -97,7 +109,7 @@ const getEvalActions = (
}),
getVariable: async varName => getPropertyValue($element, varName),
updateVariable: async (targetId, varName, value) => {
- const $el = targetId ? document.getElementById(targetId) : $element
+ const $el = targetId ? getElement(targetId, $element) : $element
const isCustomProp = varName.startsWith('--')
if ($el) {
const prevValue = getPropertyValue($el, varName)
@@ -114,7 +126,7 @@ const getEvalActions = (
}
},
setAttribute: async (id, name, value) => {
- const $el = id ? document.getElementById(id) : $element
+ const $el = id ? getElement(id, $element) : $element
if (name === 'value') {
;($el as any).value = value
} else if (value) {
@@ -124,7 +136,7 @@ const getEvalActions = (
}
},
getAttribute: async (id, name) => {
- const $el = id ? document.getElementById(id) : $element
+ const $el = id ? getElement(id, $element) : $element
if (name === 'value') return ($el as any).value
return $el?.getAttribute(name) ?? undefined
},
@@ -139,12 +151,12 @@ const getEvalActions = (
// TODO: Handle response?
},
addChildren: async (id, children) => {
- const $el = document.getElementById(id)
+ const $el = getElement(id, $element)
const declarations = await expressionsToDeclrs(children, actions)
$el && createLayer(declarations, $el)
},
removeElement: async id => {
- const $el = id ? document.getElementById(id) : $element
+ const $el = id ? getElement(id, $element) : $element
$el?.parentNode?.removeChild($el)
},
}