From b4eddbacdce67c3b03d065646848974f2e5af0eb Mon Sep 17 00:00:00 2001 From: Brandon Jordan Date: Sun, 3 Sep 2023 14:55:35 -0400 Subject: [PATCH 01/19] Fix element store if() method --- src/element.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/element.js b/src/element.js index c880a0c..296df13 100644 --- a/src/element.js +++ b/src/element.js @@ -13,7 +13,7 @@ export class Element extends Events { } if(store) { - store.model(store, (value) => { + store.model((value) => { if ((value) === true) { this.show(); } else if ((value) === false) { From b84052483d8ff9ba1c04e4e0a7baad067ff0b146 Mon Sep 17 00:00:00 2001 From: Brandon Jordan Date: Sun, 3 Sep 2023 15:30:52 -0400 Subject: [PATCH 02/19] Fix autofocus and required --- src/elements/Input.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/elements/Input.js b/src/elements/Input.js index 0113cfa..f247562 100644 --- a/src/elements/Input.js +++ b/src/elements/Input.js @@ -71,11 +71,11 @@ class BaseTextInput extends InputTag { } autofocus(state = null) { - this.toggleAttribute('autofocus', state); + return this.toggleAttribute('autofocus', state); } required(state = null) { - this.toggleAttribute('required', state); + return this.toggleAttribute('required', state); } } From a55f1f669dcf712543b0a81e2cd9e44a3f8d1a7f Mon Sep 17 00:00:00 2001 From: Brandon Jordan Date: Sun, 3 Sep 2023 15:44:49 -0400 Subject: [PATCH 03/19] Add X and Y methods for padding and margin --- src/style.js | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/style.js b/src/style.js index 37c221b..444c7ca 100644 --- a/src/style.js +++ b/src/style.js @@ -429,6 +429,16 @@ export class Style extends StandardAnimation { return this.style('marginBottom', margin); } + marginX(padding) { + this.style('marginLeft', padding); + return this.style('marginRight', padding); + } + + marginY(padding) { + this.style('marginTop', padding); + return this.style('marginBottom', padding); + } + padding(padding) { return this.style('padding', padding); } @@ -453,6 +463,16 @@ export class Style extends StandardAnimation { return this.style('paddingBottom', padding); } + paddingX(padding) { + this.style('paddingLeft', padding); + return this.style('paddingRight', padding); + } + + paddingY(padding) { + this.style('paddingTop', padding); + return this.style('paddingBottom', padding); + } + // overflow overflow(overflow) { From a385f1411530f80fa39d85a0be5e9d7708518c29 Mon Sep 17 00:00:00 2001 From: Brandon Jordan Date: Fri, 8 Sep 2023 23:06:00 -0400 Subject: [PATCH 04/19] Add dev warning to html() method --- src/base-element.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/base-element.js b/src/base-element.js index 22d05b3..856f3c2 100644 --- a/src/base-element.js +++ b/src/base-element.js @@ -111,6 +111,9 @@ export class BaseElement { } html(html) { + if (import.meta.env.DEV) { + console.warn('Do not use the html() method to render user generated content. This creates a risk of cross-site scripting (XSS) attacks.'); + } return this.property('innerHTML', html); } From 233986359526c0f9f38caf471d028c94e825b7f7 Mon Sep 17 00:00:00 2001 From: Brandon Jordan Date: Fri, 8 Sep 2023 23:10:04 -0400 Subject: [PATCH 05/19] Only warn about html() method once --- src/base-element.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/base-element.js b/src/base-element.js index 856f3c2..e540f3c 100644 --- a/src/base-element.js +++ b/src/base-element.js @@ -3,6 +3,7 @@ */ let references = {}; +let htmlWarn = false; export class BaseElement { element; @@ -111,8 +112,9 @@ export class BaseElement { } html(html) { - if (import.meta.env.DEV) { + if (import.meta.env.DEV && !htmlWarn) { console.warn('Do not use the html() method to render user generated content. This creates a risk of cross-site scripting (XSS) attacks.'); + htmlWarn = true; } return this.property('innerHTML', html); } From e82b0fadc1b88c6529fa6f58a2c54e37bcef8903 Mon Sep 17 00:00:00 2001 From: Brandon Jordan Date: Fri, 8 Sep 2023 23:28:40 -0400 Subject: [PATCH 06/19] Fix warning typo --- src/base-element.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/base-element.js b/src/base-element.js index e540f3c..b595ba6 100644 --- a/src/base-element.js +++ b/src/base-element.js @@ -113,7 +113,7 @@ export class BaseElement { html(html) { if (import.meta.env.DEV && !htmlWarn) { - console.warn('Do not use the html() method to render user generated content. This creates a risk of cross-site scripting (XSS) attacks.'); + console.warn('Do not use the html() method to render user-generated content. This creates a risk of cross-site scripting (XSS) attacks.'); htmlWarn = true; } return this.property('innerHTML', html); From 46c6c7f36c21f989037f3b2c07d17e3a2b33cea9 Mon Sep 17 00:00:00 2001 From: Brandon Jordan Date: Fri, 8 Sep 2023 23:28:55 -0400 Subject: [PATCH 07/19] Add HTML() component for rendering an HTML string inline --- src/elements/Text.js | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/src/elements/Text.js b/src/elements/Text.js index 1852fb0..8f5cb1d 100644 --- a/src/elements/Text.js +++ b/src/elements/Text.js @@ -97,4 +97,30 @@ class LabelTag extends Element { this.attribute('for', forName); } } -} \ No newline at end of file +} + +let htmlWarn = false; + +export function HTML(html) { + if (import.meta.env.DEV && !htmlWarn) { + console.warn('Do not use the HTML() component to render user-generated content. This creates a risk of cross-site scripting (XSS) attacks.'); + htmlWarn = true; + } + return new RawHTML(html); +} + +class RawHTML extends Element { + constructor(html) { + const temp = document.createElement('div'); + temp.innerHTML = html; + temp.style.display = 'none'; + + const element = document.createDocumentFragment(); + super(element); + element.append(...temp.children); + this.element = element; + this.element.innerHTML = html; + + temp.remove(); + } +} From e472462d8bf075c1a58fa45189dbbcaa029aa17c Mon Sep 17 00:00:00 2001 From: Brandon Jordan Date: Sun, 10 Sep 2023 19:02:21 -0400 Subject: [PATCH 08/19] Update README.md --- README.md | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index aaae600..093ae6f 100644 --- a/README.md +++ b/README.md @@ -30,10 +30,9 @@ npm i javascript-ui Import and add elements to the `view()` function. ```javascript -import * as jsUI from 'javascript-ui'; -import {Section, Paragraph} from 'javascript-ui'; +import {view, Section, Paragraph} from 'javascript-ui'; -jsUI.view([ +view([ Section([ Paragraph('Hello, World!') .textColor('green') @@ -56,9 +55,4 @@ Result in browser: --- -Thanks for taking interest in this project :) I work on jsUI because it's fun and because I feel like I discover more -and more uses for it the more I work on it. I've come to find it's very hackable, it has more possibilities than I -originally thought when I started the project and I love stuff like that. - -This project aims to create a framework that allows you to create UI in a way that feels more natural and fun and not a -chore. +This project aims to create a framework that allows you to create UI in a way that feels natural and easy. From 3c75b575d94a8778d6df65c60e2625c5f71ddb5a Mon Sep 17 00:00:00 2001 From: Brandon Jordan Date: Sun, 10 Sep 2023 19:14:02 -0400 Subject: [PATCH 09/19] Set default for rounded() --- src/style.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/style.js b/src/style.js index 444c7ca..aacd63e 100644 --- a/src/style.js +++ b/src/style.js @@ -217,7 +217,7 @@ export class Style extends StandardAnimation { return this.style('borderColor', color); } - rounded(radius) { + rounded(radius = '4px') { return this.style('border-radius', radius); } From c1fedc5862ccc4f7a46869b7e018d6b68243d453 Mon Sep 17 00:00:00 2001 From: Brandon Jordan Date: Sun, 10 Sep 2023 19:24:44 -0400 Subject: [PATCH 10/19] Add default transition method --- src/style.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/style.js b/src/style.js index aacd63e..e90b4bc 100644 --- a/src/style.js +++ b/src/style.js @@ -86,7 +86,11 @@ export class Style extends StandardAnimation { return this.style('resize', 'none'); } - transition(property, duration, easing, delay) { + transition() { + return this.style('transition', 'all 0.3s'); + } + + transitionProperty(property, duration, easing, delay) { return this.style('transition', [property, duration, easing, delay].join(' ')); } From fef9ee1ad9a22fe092b0e73792770d4af52f9769 Mon Sep 17 00:00:00 2001 From: Brandon Jordan Date: Sun, 10 Sep 2023 19:24:55 -0400 Subject: [PATCH 11/19] Add separate viewport fit methods --- src/style.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/style.js b/src/style.js index e90b4bc..b075bf3 100644 --- a/src/style.js +++ b/src/style.js @@ -595,6 +595,14 @@ export class Style extends StandardAnimation { return this; } + fitViewportWidth() { + return this.style('width', '100vw'); + } + + fitViewportHeight() { + return this.style('height', '100vh'); + } + aspectRatio(ratio) { return this.style('aspect-ratio', ratio); } From aff13123fef8c94dee9f6ec9e73a3ad8b59591b6 Mon Sep 17 00:00:00 2001 From: Brandon Jordan Date: Fri, 29 Sep 2023 18:26:56 -0400 Subject: [PATCH 12/19] HTML(): Don't hide temp and don't set innerHTML after adding temp childen --- src/elements/Text.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/elements/Text.js b/src/elements/Text.js index 8f5cb1d..f7fc2db 100644 --- a/src/elements/Text.js +++ b/src/elements/Text.js @@ -113,13 +113,11 @@ class RawHTML extends Element { constructor(html) { const temp = document.createElement('div'); temp.innerHTML = html; - temp.style.display = 'none'; const element = document.createDocumentFragment(); super(element); element.append(...temp.children); this.element = element; - this.element.innerHTML = html; temp.remove(); } From 49a7325f9b3819542e1a042674e4fd1c5f572ca2 Mon Sep 17 00:00:00 2001 From: Brandon Jordan Date: Fri, 29 Sep 2023 18:28:58 -0400 Subject: [PATCH 13/19] Remove redundant set innerText on text node --- src/elements/Text.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/elements/Text.js b/src/elements/Text.js index f7fc2db..d945736 100644 --- a/src/elements/Text.js +++ b/src/elements/Text.js @@ -13,7 +13,6 @@ class TextTag extends Element { const element = document.createTextNode(text); super(element); this.element = element; - this.element.innerText = text; } } From e7e3f18296bdaf4d374fa744b02b627c404eb77e Mon Sep 17 00:00:00 2001 From: Brandon Jordan Date: Fri, 29 Sep 2023 18:29:27 -0400 Subject: [PATCH 14/19] Add non breaking space: Space() --- src/elements/Spacer.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/elements/Spacer.js b/src/elements/Spacer.js index 8a89bc7..5433f2a 100644 --- a/src/elements/Spacer.js +++ b/src/elements/Spacer.js @@ -4,6 +4,18 @@ import {Element} from '../element.js'; +export function Space() { + return new NonBreakingSpace(); +} + +class NonBreakingSpace extends Element { + constructor() { + const element = document.createTextNode(' '); + super(element); + this.element = element; + } +} + export function Spacer(times = 1) { return new BreakTag(times); } From 89330823a7460dc05ca3e6bd5f4fcdf73f114d1f Mon Sep 17 00:00:00 2001 From: Brandon Jordan Date: Fri, 29 Sep 2023 18:34:42 -0400 Subject: [PATCH 15/19] Add parent() method --- src/element.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/element.js b/src/element.js index 296df13..3b314d4 100644 --- a/src/element.js +++ b/src/element.js @@ -12,6 +12,10 @@ export class Element extends Events { this.element = element; } + parent() { + return this.element.parentElement; + } + if(store) { store.model((value) => { if ((value) === true) { From b9143c57a3339432963a60f0233872975513642f Mon Sep 17 00:00:00 2001 From: Brandon Jordan Date: Fri, 29 Sep 2023 18:44:01 -0400 Subject: [PATCH 16/19] Allow for multiple created and mounted callbacks --- src/base-element.js | 8 ++++---- src/main.js | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/base-element.js b/src/base-element.js index b595ba6..ec15549 100644 --- a/src/base-element.js +++ b/src/base-element.js @@ -8,8 +8,8 @@ let htmlWarn = false; export class BaseElement { element; reference; - mountedCallback; - createdCallback; + mountedCallbacks = []; + createdCallbacks = []; inputTypes = ['text', 'search', 'url', 'number', 'password', 'email', 'tel']; constructor(element) { @@ -60,12 +60,12 @@ export class BaseElement { } created(callback) { - this.createdCallback = callback; + this.createdCallbacks.push(callback); return this; } mounted(callback) { - this.mountedCallback = callback; + this.mountedCallbacks.push(callback); return this; } diff --git a/src/main.js b/src/main.js index cb64ec4..ca2cf88 100644 --- a/src/main.js +++ b/src/main.js @@ -113,12 +113,12 @@ export function render(parent, elements) { } function mount(parent, element) { - if (element.createdCallback) { - element.createdCallback(element); + if (element.createdCallbacks) { + element.createdCallbacks.map(c => c(element)); } parent.appendChild(element.element); - if (element.mountedCallback) { - element.mountedCallback(element); + if (element.mountedCallbacks) { + element.mountedCallbacks.map(m => m(element)); } if (element.elements) { render(element.element, element.elements); From 8b7e50449b2a6505f6f136f462f169080b44ae72 Mon Sep 17 00:00:00 2001 From: Brandon Jordan Date: Fri, 29 Sep 2023 18:44:17 -0400 Subject: [PATCH 17/19] Fix raw HTML component --- src/elements/Text.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/elements/Text.js b/src/elements/Text.js index d945736..4f3fa3b 100644 --- a/src/elements/Text.js +++ b/src/elements/Text.js @@ -115,9 +115,6 @@ class RawHTML extends Element { const element = document.createDocumentFragment(); super(element); - element.append(...temp.children); - this.element = element; - - temp.remove(); + element.append(...temp.childNodes); } } From c5a95105ac54af03cbee3e23799a003f39f8d1f6 Mon Sep 17 00:00:00 2001 From: Brandon Jordan Date: Sun, 22 Oct 2023 00:31:24 -0400 Subject: [PATCH 18/19] Update README.md --- README.md | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 093ae6f..70e3f3f 100644 --- a/README.md +++ b/README.md @@ -7,14 +7,21 @@ [![License](https://img.shields.io/github/license/electrikmilk/javascript-ui)](https://github.com/electrikmilk/javascript-ui/blob/main/LICENSE) [![Version](https://img.shields.io/npm/v/javascript-ui)](https://www.npmjs.com/package/javascript-ui) -Javascript UI is a JavaScript framework. It describes HTML and CSS in Javascript simliar to SwiftUI. - -- Useful shorthands for HTML tags and css properties -- Built-in standard animations like rotate, fade, flip, shake, and more... -- Built-in CSS tricks like truncation, font smoothing, fit, etc. -- CSS properties are abtracted into views and stacks like ScrollView, GridStack, HStack, VStack, etc. -- Built-in router -- Store and state management +Javascript UI is a JavaScript framework. It describes HTML and CSS in Javascript similar to SwiftUI. + +## ❇️ Features + +- ✔️ Declarative syntax, functions nest within each other, similar to HTML, but with methods instead of CSS properties and HTML attributes. +- 😎 Useful shorthands for HTML tags and attributes and CSS properties (e.g. `Image().caption()`). +- 🦋 Built-in standard animations like rotate, fade, flip, shake, and more! +- 🤓 Methods for CSS tricks like `truncate()`, `fontSmoothing()`, fit, etc. More CSS tricks are abstracted into views and stacks like `ScrollView()`, `GridStack()`, `HStack()`, `VStack()`, etc. +- 🐰 It's fast! Element objects simply provide helpful methods and are used during the first render, but they keep a reference to their element or document fragment. They modify the element directly rather than re-rendering it. There are never entire page re-renders, only selective re-renders when needed for state management. + +## 🔧 Built-ins + +- 💾 Stores +- ⚛️ State management +- 🧭 Router [Playground](https://codepen.io/internetgho5t/pen/ZExgBbm) • [Documentation](https://github.com/electrikmilk/jsUI/wiki) From 92c60f618a8491f92b81cfa631acf42e3a068572 Mon Sep 17 00:00:00 2001 From: Brandon Jordan Date: Sun, 22 Oct 2023 00:44:04 -0400 Subject: [PATCH 19/19] Update version number --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ea06953..ed58e21 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "javascript-ui", - "version": "1.0.9", + "version": "1.1.0", "author": "Brandon Jordan (https://github.com/electrikmilk)", "repository": { "type": "git",