@rettangoli/ui 0.1.1 → 0.1.2-rc2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rettangoli/ui",
3
- "version": "0.1.1",
3
+ "version": "0.1.2-rc2",
4
4
  "description": "A UI component library for building web interfaces.",
5
5
  "main": "dist/rettangoli-esm.min.js",
6
6
  "type": "module",
@@ -22,8 +22,12 @@
22
22
  },
23
23
  "license": "MIT",
24
24
  "scripts": {
25
- "build:dev": "bun run ../rettangoli-cli/cli.js fe build && bun run esbuild-dev.js",
26
- "build": "bun run ../rettangoli-cli/cli.js fe build && bun run esbuild.js"
25
+ "build:dev": "rtgl fe build && bun run esbuild-dev.js",
26
+ "build": "rtgl fe build && bun run esbuild.js",
27
+ "vt:generate": "rtgl fe build && bun run esbuild-dev.js && rtgl vt generate --skip-screenshots",
28
+ "vt:report": "bun run build:dev && rtgl vt generate && rtgl vt report",
29
+ "vt:accept": "rtgl vt accept",
30
+ "serve": "bunx serve .rettangoli/vt/_site"
27
31
  },
28
32
  "devDependencies": {
29
33
  "esbuild": "^0.20.0",
@@ -47,7 +51,7 @@
47
51
  "commander": "^13.1.0",
48
52
  "js-yaml": "^4.1.0",
49
53
  "liquidjs": "^10.21.0",
50
- "@rettangoli/fe": "0.0.6",
54
+ "@rettangoli/fe": "0.0.7-rc4",
51
55
  "snabbdom": "^3.6.2"
52
56
  }
53
57
  }
@@ -3,6 +3,18 @@ export const handleOnMount = (deps) => {
3
3
  store.setDefaultValues(props.defaultValues);
4
4
  };
5
5
 
6
+ const dispatchFormChange = (fieldName, fieldValue, formValues, dispatchEvent) => {
7
+ dispatchEvent(
8
+ new CustomEvent("form-change", {
9
+ detail: {
10
+ fieldName,
11
+ fieldValue,
12
+ formValues,
13
+ },
14
+ }),
15
+ );
16
+ };
17
+
6
18
  export const handleActionClick = (e, deps) => {
7
19
  const { store, dispatchEvent } = deps;
8
20
  const id = e.currentTarget.id.replace("action-", "");
@@ -17,7 +29,7 @@ export const handleActionClick = (e, deps) => {
17
29
  };
18
30
 
19
31
  export const handleInputChange = (e, deps) => {
20
- const { store } = deps;
32
+ const { store, dispatchEvent } = deps;
21
33
  const id = e.currentTarget.id.replace("input-", "");
22
34
  // TODO fix double event
23
35
  if (id && e.detail.value !== undefined) {
@@ -26,38 +38,42 @@ export const handleInputChange = (e, deps) => {
26
38
  fieldName: id,
27
39
  value: e.detail.value,
28
40
  });
41
+ dispatchFormChange(id, e.detail.value, store.selectFormValues(), dispatchEvent);
29
42
  }
30
43
  };
31
44
 
32
45
  export const handleSelectChange = (e, deps) => {
33
- const { store } = deps;
46
+ const { store, dispatchEvent } = deps;
34
47
  const id = e.currentTarget.id.replace("select-", "");
35
48
  if (id && e.detail.selectedValue !== undefined) {
36
49
  store.setFormFieldValue({
37
50
  fieldName: id,
38
51
  value: e.detail.selectedValue,
39
52
  });
53
+ dispatchFormChange(id, e.detail.selectedValue, store.selectFormValues(), dispatchEvent);
40
54
  }
41
55
  };
42
56
 
43
57
  export const handleColorPickerChange = (e, deps) => {
44
- const { store } = deps;
58
+ const { store, dispatchEvent } = deps;
45
59
  const id = e.currentTarget.id.replace("colorpicker-", "");
46
60
  if (id && e.detail.value !== undefined) {
47
61
  store.setFormFieldValue({
48
62
  fieldName: id,
49
63
  value: e.detail.value,
50
64
  });
65
+ dispatchFormChange(id, e.detail.value, store.selectFormValues(), dispatchEvent);
51
66
  }
52
67
  };
53
68
 
54
69
  export const handleSliderChange = (e, deps) => {
55
- const { store } = deps;
70
+ const { store, dispatchEvent } = deps;
56
71
  const id = e.currentTarget.id.replace("slider-", "");
57
72
  if (id && e.detail.value !== undefined) {
58
73
  store.setFormFieldValue({
59
74
  fieldName: id,
60
75
  value: e.detail.value,
61
76
  });
77
+ dispatchFormChange(id, e.detail.value, store.selectFormValues(), dispatchEvent);
62
78
  }
63
79
  };
@@ -132,7 +132,7 @@ refs:
132
132
  handler: handleActionClick
133
133
  input-*:
134
134
  eventListeners:
135
- input-keydown:
135
+ input-change:
136
136
  handler: handleInputChange
137
137
  select-*:
138
138
  eventListeners:
@@ -147,7 +147,8 @@ refs:
147
147
  slider-change:
148
148
  handler: handleSliderChange
149
149
 
150
- events: {}
150
+ events:
151
+ form-change: {}
151
152
 
152
153
  template:
153
154
  - rtgl-view w=f h=f p=md g=lg ${containerAttrString}:
@@ -38,8 +38,8 @@ class RettangoliInputElement extends HTMLElement {
38
38
  font-weight: var(--xs-font-weight);
39
39
  line-height: var(--xs-line-height);
40
40
  letter-spacing: var(--xs-letter-spacing);
41
- padding-left: var(--spacing-sm);
42
- padding-right: var(--spacing-sm);
41
+ padding-left: var(--spacing-md);
42
+ padding-right: var(--spacing-md);
43
43
  height: 24px;
44
44
  }
45
45
  input:focus {
@@ -78,7 +78,7 @@ class RettangoliInputElement extends HTMLElement {
78
78
  this.shadow.appendChild(this._inputElement);
79
79
 
80
80
  // Bind event handler
81
- this._inputElement.addEventListener('keydown', this._onChange);
81
+ this._inputElement.addEventListener('input', this._onChange);
82
82
  }
83
83
 
84
84
  static get observedAttributes() {
@@ -106,7 +106,7 @@ class RettangoliInputElement extends HTMLElement {
106
106
  }
107
107
 
108
108
  _onChange = (event) => {
109
- this.dispatchEvent(new CustomEvent('input-keydown', {
109
+ this.dispatchEvent(new CustomEvent('input-change', {
110
110
  detail: {
111
111
  value: this._inputElement.value,
112
112
  },
@@ -1,182 +0,0 @@
1
- /**
2
- * Subscribes to all observables and returns a functionthat will unsubscribe
3
- * from all observables when called
4
- * @param {*} observables
5
- * @returns
6
- */
7
- const subscribeAll = (observables) => {
8
- // Subscribe to all observables and store the subscription objects
9
- const subscriptions = observables.map((observable) => observable.subscribe());
10
-
11
- // Return a function that will unsubscribe from all observables when called
12
- return () => {
13
- for (const subscription of subscriptions) {
14
- if (subscription && typeof subscription.unsubscribe === "function") {
15
- subscription.unsubscribe();
16
- }
17
- }
18
- };
19
- };
20
-
21
- /**
22
- * Creates a base web component element to be used in environments
23
- * where the output is strings such as server side rendering environments
24
- * @param {Object} param
25
- * @param {Function} param.render - The render function to be used in the element. compliant with uhtml.render
26
- * @returns
27
- */
28
- export const createSsrBaseElement = ({ render }) => {
29
-
30
- class CSSStyleSheet {
31
- _css = "";
32
-
33
- get css() {
34
- return this._css;
35
- }
36
-
37
- replaceSync(css) {
38
- this._css = css;
39
- }
40
- }
41
- class SsrRenderTarget {
42
- innerHTML = "";
43
- adoptedStyleSheets = [];
44
- write(html) {
45
- this.innerHTML = html;
46
- }
47
- }
48
- class BaseBaseSsrElement {
49
- renderTarget = new SsrRenderTarget();
50
-
51
- constructor() {
52
- const styleSheet = new CSSStyleSheet();
53
- styleSheet.replaceSync(`:host { display: contents; }`);
54
- this.renderTarget.adoptedStyleSheets = [styleSheet];
55
- }
56
- }
57
- return class BaseSsrElement extends createGenericBaseElement({
58
- BaseElement: BaseBaseSsrElement,
59
- render,
60
- skipOnMount: true,
61
- }) {};
62
- };
63
-
64
- /**
65
- * Creates a base web component element to be used in web browser environments
66
- * @param {Object} param
67
- * @param {Function} param.render - The render function to be used in the element. compliant with uhtml.render
68
- * @returns
69
- */
70
- export const createWebComponentBaseElement = ({ render, styleSheet }) => {
71
- let actualStyleSheet;
72
-
73
- if (styleSheet) {
74
- actualStyleSheet = styleSheet;
75
- } else {
76
- actualStyleSheet = new CSSStyleSheet();
77
- actualStyleSheet.replaceSync(`:host { display: contents; }`);
78
- }
79
-
80
- return class BaseWebComponentElement extends createGenericBaseElement({
81
- BaseElement: HTMLElement,
82
- render,
83
- skipOnMount: false,
84
- }) {
85
- static get observedAttributes() {
86
- return ["key"];
87
- }
88
-
89
- constructor() {
90
- super();
91
- this.renderTarget = this.attachShadow({ mode: "closed" });
92
- }
93
-
94
- connectedCallback() {
95
- this.renderTarget.adoptedStyleSheets = [actualStyleSheet];
96
- this.baseOnMount();
97
- }
98
-
99
- disconnectedCallback() {
100
- this.baseOnUnmount();
101
- }
102
-
103
- attributeChangedCallback() {
104
- setTimeout(() => {
105
- this.reRender();
106
- }, 0);
107
- }
108
- };
109
- };
110
-
111
- /**
112
- * Creates a base web component element to be used in environments
113
- * where the output is strings such as server side rendering environments
114
- * @param {Object} param
115
- * @param {Object} param.BaseElement - The base element to be used in the element.
116
- * @param {Function} param.render - The render function to be used in the element. compliant with uhtml.render
117
- * @param {Boolean} param.skipOnMount - Whether to skip the onMount callback. Default is false.
118
- * @returns
119
- */
120
- export const createGenericBaseElement = ({ BaseElement, render, skipOnMount = false }) => {
121
- class GenericBaseElement extends BaseElement {
122
-
123
- _renderKey = 0;
124
- _unmountCallback;
125
- // renderTarget;
126
- disableFirstAutomatedRender = false;
127
-
128
- get renderKey() {
129
- return String(this._renderKey);
130
- }
131
-
132
- baseOnMount = () => {
133
- if (!skipOnMount && this.onMount) {
134
- this._unmountCallback = this.onMount();
135
- }
136
-
137
- if (!this.disableFirstAutomatedRender) {
138
- this.reRender();
139
- }
140
-
141
- if (this.attachedObservables) {
142
- if (Array.isArray(this.attachedObservables)) {
143
- this.unsubscribe = subscribeAll(this.attachedObservables);
144
- } else {
145
- this.unsubscribe = subscribeAll(this.attachedObservables());
146
- }
147
- } else if (this.subscriptions) {
148
- this.unsubscribe = subscribeAll(this.subscriptions);
149
- }
150
- };
151
-
152
- baseOnUnmount = () => {
153
- if (this._unmountCallback) {
154
- this._unmountCallback();
155
- }
156
- if (this.onUnmount) {
157
- this.onUnmount();
158
- }
159
- if (this.unsubscribe) {
160
- this.unsubscribe();
161
- }
162
- };
163
-
164
- /**
165
- * @deprecated
166
- * @see reRender
167
- */
168
- triggerRender = () => {
169
- this.reRender();
170
- };
171
-
172
- /**
173
- * ReRenders the component
174
- */
175
- reRender = () => {
176
- this._renderKey++;
177
- render(this.renderTarget, this.render());
178
- };
179
- }
180
-
181
- return GenericBaseElement;
182
- };
package/src/lib/uhtml.js DELETED
@@ -1,9 +0,0 @@
1
- /**
2
- * Skipped minification because the original files appears to be already minified.
3
- * Original file: /npm/uhtml@4.7.0/keyed.js
4
- *
5
- * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files
6
- */
7
- const{isArray:e}=Array,{getPrototypeOf:t,getOwnPropertyDescriptor:n}=Object,r=[],s=()=>document.createRange(),l=(e,t,n)=>(e.set(t,n),n),i=(e,t)=>t.reduceRight(o,e),o=(e,t)=>e.childNodes[t],{setPrototypeOf:c}=Object;let a;var u=(e,t,n)=>(a||(a=s()),n?a.setStartAfter(e):a.setStartBefore(e),a.setEndAfter(t),a.deleteContents(),e);const h=({firstChild:e,lastChild:t},n)=>u(e,t,n);let d=!1;const f=(e,t)=>d&&11===e.nodeType?1/t<0?t?h(e,!0):e.lastChild:t?e.valueOf():e.firstChild:e,p=e=>document.createComment(e);class g extends((e=>{function t(e){return c(e,new.target.prototype)}return t.prototype=e.prototype,t})(DocumentFragment)){#e=p("<>");#t=p("</>");#n=r;constructor(e){super(e),this.replaceChildren(this.#e,...e.childNodes,this.#t),d=!0}get firstChild(){return this.#e}get lastChild(){return this.#t}get parentNode(){return this.#e.parentNode}remove(){h(this,!1)}replaceWith(e){h(this,!0).replaceWith(e)}valueOf(){const{parentNode:e}=this;if(e===this)this.#n===r&&(this.#n=[...this.childNodes]);else{if(e){let{firstChild:e,lastChild:t}=this;for(this.#n=[e];e!==t;)this.#n.push(e=e.nextSibling)}this.replaceChildren(...this.#n)}return this}}const m=(e,t,n)=>e.setAttribute(t,n),b=(e,t)=>e.removeAttribute(t);let v;const C=(t,n,r)=>{r=r.slice(1),v||(v=new WeakMap);const s=v.get(t)||l(v,t,{});let i=s[r];return i&&i[0]&&t.removeEventListener(r,...i),i=e(n)?n:[n,!1],s[r]=i,i[0]&&t.addEventListener(r,...i),n},w=(e,t)=>{const{t:n,n:r}=e;let s=!1;switch(typeof t){case"object":if(null!==t){(r||n).replaceWith(e.n=t.valueOf());break}case"undefined":s=!0;default:n.data=s?"":t,r&&(e.n=null,r.replaceWith(n))}return t},x=(e,t,n)=>e[n]=t,$=(e,t,n)=>x(e,t,n.slice(1)),y=(e,t,n)=>null==t?(b(e,n),t):x(e,t,n),N=(e,t)=>("function"==typeof t?t(e):t.current=e,t),O=(e,t,n)=>(null==t?b(e,n):m(e,n,t),t),k=(e,t,n)=>(e.toggleAttribute(n.slice(1),t),t),A=(e,t,n)=>{const{length:s}=t;if(e.data=`[${s}]`,s)return((e,t,n,r,s)=>{const l=n.length;let i=t.length,o=l,c=0,a=0,u=null;for(;c<i||a<o;)if(i===c){const t=o<l?a?r(n[a-1],-0).nextSibling:r(n[o],0):s;for(;a<o;)e.insertBefore(r(n[a++],1),t)}else if(o===a)for(;c<i;)u&&u.has(t[c])||e.removeChild(r(t[c],-1)),c++;else if(t[c]===n[a])c++,a++;else if(t[i-1]===n[o-1])i--,o--;else if(t[c]===n[o-1]&&n[a]===t[i-1]){const s=r(t[--i],-0).nextSibling;e.insertBefore(r(n[a++],1),r(t[c++],-0).nextSibling),e.insertBefore(r(n[--o],1),s),t[i]=n[o]}else{if(!u){u=new Map;let e=a;for(;e<o;)u.set(n[e],e++)}if(u.has(t[c])){const s=u.get(t[c]);if(a<s&&s<o){let l=c,h=1;for(;++l<i&&l<o&&u.get(t[l])===s+h;)h++;if(h>s-a){const l=r(t[c],0);for(;a<s;)e.insertBefore(r(n[a++],1),l)}else e.replaceChild(r(n[a++],1),r(t[c++],-1))}else c++}else e.removeChild(r(t[c++],-1))}return n})(e.parentNode,n,t,f,e);switch(n.length){case 1:n[0].remove();case 0:break;default:u(f(n[0],0),f(n.at(-1),-0),!1)}return r},M=new Map([["aria",(e,t)=>{for(const n in t){const r=t[n],s="role"===n?n:`aria-${n}`;null==r?b(e,s):m(e,s,r)}return t}],["class",(e,t)=>y(e,t,null==t?"class":"className")],["data",(e,t)=>{const{dataset:n}=e;for(const e in t)null==t[e]?delete n[e]:n[e]=t[e];return t}],["ref",N],["style",(e,t)=>null==t?y(e,t,"style"):x(e.style,t,"cssText")]]),W=(e,r,s)=>{switch(r[0]){case".":return $;case"?":return k;case"@":return C;default:return s||"ownerSVGElement"in e?"ref"===r?N:O:M.get(r)||(r in e?r.startsWith("on")?x:((e,r)=>{let s;do{s=n(e,r)}while(!s&&(e=t(e)));return s})(e,r)?.set?y:O:O)}},S=(e,t)=>(e.textContent=null==t?"":t,t),E=(e,t,n)=>({a:e,b:t,c:n}),T=()=>E(null,null,r);var B=e=>(t,n)=>{const{a:s,b:l,c:o}=e(t,n),c=document.importNode(s,!0);let a=r;if(l!==r){a=[];for(let e,t,n=0;n<l.length;n++){const{a:s,b:o,c:p}=l[n],g=s===t?e:e=i(c,t=s);a[n]=(u=o,h=g,d=p,f=o===A?[]:o===w?T():null,{v:r,u:u,t:h,n:d,c:f})}}var u,h,d,f;return((e,t)=>({b:e,c:t}))(o?c.firstChild:new g(c),a)};const D=/^(?:plaintext|script|style|textarea|title|xmp)$/i,j=/^(?:area|base|br|col|embed|hr|img|input|keygen|link|menuitem|meta|param|source|track|wbr)$/i,L=/<([a-zA-Z0-9]+[a-zA-Z0-9:._-]*)([^>]*?)(\/?)>/g,P=/([^\s\\>"'=]+)\s*=\s*(['"]?)\x01/g,z=/[\x01\x02]/g;let F,R,Z=document.createElement("template");var G=(e,t)=>{if(t)return F||(F=document.createElementNS("http://www.w3.org/2000/svg","svg"),R=s(),R.selectNodeContents(F)),R.createContextualFragment(e);Z.innerHTML=e;const{content:n}=Z;return Z=Z.cloneNode(!1),n};const H=e=>{const t=[];let n;for(;n=e.parentNode;)t.push(t.indexOf.call(n.childNodes,e)),e=n;return t},V=()=>document.createTextNode(""),_=(t,n,s)=>{const i=G(((e,t,n)=>{let r=0;return e.join("").trim().replace(L,((e,t,r,s)=>`<${t}${r.replace(P,"=$2$1").trimEnd()}${s?n||j.test(t)?" /":`></${t}`:""}>`)).replace(z,(e=>""===e?`\x3c!--${t+r++}--\x3e`:t+r++))})(t,I,s),s),{length:o}=t;let c=r;if(o>1){const t=[],r=document.createTreeWalker(i,129);let l=0,a=`${I}${l++}`;for(c=[];l<o;){const i=r.nextNode();if(8===i.nodeType){if(i.data===a){const r=e(n[l-1])?A:w;r===w&&t.push(i),c.push(E(H(i),r,null)),a=`${I}${l++}`}}else{let e;for(;i.hasAttribute(a);){e||(e=H(i));const t=i.getAttribute(a);c.push(E(e,W(i,t,s),t)),b(i,a),a=`${I}${l++}`}!s&&D.test(i.localName)&&i.textContent.trim()===`\x3c!--${a}--\x3e`&&(c.push(E(e||H(i),S,null)),a=`${I}${l++}`)}}for(l=0;l<t.length;l++)t[l].replaceWith(V())}const{childNodes:a}=i;let{length:u}=a;return u<1?(u=1,i.appendChild(V())):1===u&&1!==o&&1!==a[0].nodeType&&(u=0),l(q,t,E(i,c,1===u))},q=new WeakMap,I="isµ";var J=e=>(t,n)=>q.get(t)||_(t,n,e);const K=B(J(!1)),Q=B(J(!0)),U=(e,{s:t,t:n,v:r})=>{if(e.a!==n){const{b:s,c:l}=(t?Q:K)(n,r);e.a=n,e.b=s,e.c=l}for(let{c:t}=e,n=0;n<t.length;n++){const e=r[n],s=t[n];switch(s.u){case A:s.v=A(s.t,X(s.c,e),s.v);break;case w:const t=e instanceof Y?U(s.c||(s.c=T()),e):(s.c=null,e);t!==s.v&&(s.v=w(s,t));break;default:e!==s.v&&(s.v=s.u(s.t,e,s.n,s.v))}}return e.b},X=(e,t)=>{let n=0,{length:r}=t;for(r<e.length&&e.splice(r);n<r;n++){const r=t[n];r instanceof Y?t[n]=U(e[n]||(e[n]=T()),r):e[n]=null}return t};class Y{constructor(e,t,n){this.s=e,this.t=t,this.v=n}toDOM(e=T()){return U(e,this)}}
8
- /*! (c) Andrea Giammarchi - MIT */const ee=e=>(t,...n)=>new Y(e,t,n),te=ee(!1),ne=ee(!0),re=new WeakMap;var se=(e,t)=>((e,t)=>{const n=re.get(e)||l(re,e,T()),{b:r}=n,s="function"==typeof t?t():t,i=s instanceof Y?s.toDOM(n):s;return r!==i&&e.replaceChildren((n.b=i).valueOf()),e})(e,t)
9
- /*! (c) Andrea Giammarchi - MIT */;const le=new WeakMap,ie=e=>(t,n)=>{const r=le.get(t)||l(le,t,new Map);return r.get(n)||l(r,n,function(t,...n){return new Y(e,t,n).toDOM(this)}.bind(T()))},oe=ie(!1),ce=ie(!0);export{Y as Hole,M as attr,te as html,oe as htmlFor,se as render,ne as svg,ce as svgFor};