physical-quantity 1.0.0 → 1.1.2
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/README.md +0 -0
- package/dist/pq.min.js +54 -0
- package/package.json +5 -2
- package/Log.md +0 -10
- package/index.html +0 -12
- package/js/pq.js +0 -66
package/README.md
ADDED
|
File without changes
|
package/dist/pq.min.js
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
class PhysicalQuantity extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"}),this.value=0,this.unit="mm",this.unitCategory="length",this.decimalPlaces=3,// Default decimal places
|
|
2
|
+
this.units={length:["m","cm","mm","in","ft"],mass:["g","kg","lbm"]},this.unitConversion={length:{m:1,cm:.01,mm:.001,in:.0254,ft:12*.0254},
|
|
3
|
+
// Add other category conversion factors as needed
|
|
4
|
+
mass:{kg:1,g:.001,lbm:.454}},this.render()}static get observedAttributes(){return["value","unit","decimal-places"]}attributeChangedCallback(t,e,i){"value"===t?this.value=parseFloat(i):"unit"===t?(this.unit=i,this.unitCategory=this.getUnitCategory(i)):"decimal-places"===t&&(this.decimalPlaces=parseInt(i)||3),this.render()}getUnitCategory(t){for(const e in this.units)if(this.units[e].includes(t))return e;return null}connectedCallback(){this.shadowRoot.addEventListener("change",this.handleUnitChange.bind(this))}disconnectedCallback(){this.shadowRoot.removeEventListener("change",this.handleUnitChange.bind(this))}handleArrowClick(t){t.target.closest(".unit-container")&&(t=this.shadowRoot.querySelector("select"))&&(t.focus(),t.click())}handleUnitChange(t){var e;"SELECT"===t.target.tagName&&(t=t.target.value,e=this.unitConversion[this.unitCategory][this.unit]/this.unitConversion[this.unitCategory][t],this.value=this.value*e,this.unit=t,this.render())}formatValue(t){// https://aistudio.google.com/app/prompts?state=%7B%22ids%22:%5B%221oNb_BksOrN-5hQ_5KjCxxYhMotx5gA-P%22%5D,%22action%22:%22open%22,%22userId%22:%22114169196047837137010%22,%22resourceKeys%22:%7B%7D%7D&usp=sharing
|
|
5
|
+
return Number.isInteger(t)?t.toString():0!==Math.floor(t)?t.toFixed(this.decimalPlaces).replace(/0+$/,"").replace(/\.$/,""):t.toPrecision(3)}render(){this.shadowRoot.innerHTML=`
|
|
6
|
+
<style>
|
|
7
|
+
:host {
|
|
8
|
+
display: inline-block;
|
|
9
|
+
}
|
|
10
|
+
.quantity {
|
|
11
|
+
display: flex;
|
|
12
|
+
align-items: center;
|
|
13
|
+
}
|
|
14
|
+
.value {
|
|
15
|
+
margin-left: 0.25em;
|
|
16
|
+
margin-right: 0.25em;
|
|
17
|
+
}
|
|
18
|
+
.unit-container select {
|
|
19
|
+
position: relative;
|
|
20
|
+
display: inline-flex;
|
|
21
|
+
align-items: center;
|
|
22
|
+
color: blue;
|
|
23
|
+
background-color: lightgray;
|
|
24
|
+
border-radius: 0.25em;
|
|
25
|
+
border: none;
|
|
26
|
+
margin: 0.25em;
|
|
27
|
+
cursor: pointer;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/* .unit-container::after {
|
|
31
|
+
content: "";
|
|
32
|
+
position: absolute;
|
|
33
|
+
top: 50%;
|
|
34
|
+
right: 0;
|
|
35
|
+
transform: translateY(-50%);
|
|
36
|
+
border-left: 5px solid transparent;
|
|
37
|
+
border-right: 5px solid transparent;
|
|
38
|
+
border-top: 8px solid blueviolet;
|
|
39
|
+
width: 0;
|
|
40
|
+
height: 0;
|
|
41
|
+
} */
|
|
42
|
+
|
|
43
|
+
</style>
|
|
44
|
+
|
|
45
|
+
<div class="quantity">
|
|
46
|
+
<span class="value">${this.formatValue(this.value)}</span>
|
|
47
|
+
<div class="unit-container">
|
|
48
|
+
<select>
|
|
49
|
+
${this.units[this.unitCategory].map(t=>`<option value="${t}" ${t===this.unit?"selected":""}>
|
|
50
|
+
${t}</option>`).join("")}
|
|
51
|
+
</select>
|
|
52
|
+
</div>
|
|
53
|
+
</div>
|
|
54
|
+
`}}customElements.define("physical-quantity",PhysicalQuantity);
|
package/package.json
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "physical-quantity",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.2",
|
|
4
4
|
"description": "A web component to represent a physical quantity with unit conversion.",
|
|
5
|
-
"main": "
|
|
5
|
+
"main": "./dist/pq.min.js",
|
|
6
|
+
"files": [
|
|
7
|
+
"dist/"
|
|
8
|
+
],
|
|
6
9
|
"scripts": {
|
|
7
10
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
8
11
|
},
|
package/Log.md
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
# 24011-PqWebComp
|
|
2
|
-
|
|
3
|
-
### 20240526 Su
|
|
4
|
-
Q: I would like to develop a cross framework (angular, react, Vue, web component, etc. ) html element with the following function:
|
|
5
|
-
- it's a value-unit pair to represent a physical quantity , eg: "20 mm"
|
|
6
|
-
- it will allow web page author to create a physical quantity as a measurement of a given unit;
|
|
7
|
-
- when the html page is shown in browser , web visitor can click on the unit portion to show a drop down box allowing the user to switch to a different unit of the same unit category. Eg: for a length, the web page author created an quantity 25.4 mm. When the web visitor click on mm, it will show the drop down list of "m, cm, mm, in, ft, ...". The user can switch to "in", the the value will be changed to 1, thus the same quantity will be shown as "1 in".
|
|
8
|
-
Can you guide me to create this html element?
|
|
9
|
-
|
|
10
|
-
GPT4o:
|
package/index.html
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8">
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
-
<title>Physical Quantity Component</title>
|
|
7
|
-
<script src="./js/pq.js" defer></script>
|
|
8
|
-
</head>
|
|
9
|
-
<body>
|
|
10
|
-
<physical-quantity value="25.4" unit="mm"></physical-quantity>
|
|
11
|
-
</body>
|
|
12
|
-
</html>
|
package/js/pq.js
DELETED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
class PhysicalQuantity extends HTMLElement {
|
|
2
|
-
constructor() {
|
|
3
|
-
super();
|
|
4
|
-
this.attachShadow({ mode: 'open' });
|
|
5
|
-
|
|
6
|
-
this.units = {
|
|
7
|
-
length: {
|
|
8
|
-
mm: 1,
|
|
9
|
-
cm: 10,
|
|
10
|
-
m: 1000,
|
|
11
|
-
in: 25.4,
|
|
12
|
-
ft: 304.8,
|
|
13
|
-
},
|
|
14
|
-
// You can add more unit categories here
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
this.shadowRoot.innerHTML = `
|
|
18
|
-
<style>
|
|
19
|
-
:host {
|
|
20
|
-
display: inline-block;
|
|
21
|
-
}
|
|
22
|
-
input {
|
|
23
|
-
width: 50px;
|
|
24
|
-
}
|
|
25
|
-
select {
|
|
26
|
-
margin-left: 5px;
|
|
27
|
-
}
|
|
28
|
-
</style>
|
|
29
|
-
<input type="number" value="1">
|
|
30
|
-
<select>
|
|
31
|
-
${Object.keys(this.units.length).map(unit => `<option value="${unit}">${unit}</option>`).join('')}
|
|
32
|
-
</select>
|
|
33
|
-
`;
|
|
34
|
-
|
|
35
|
-
this.input = this.shadowRoot.querySelector('input');
|
|
36
|
-
this.select = this.shadowRoot.querySelector('select');
|
|
37
|
-
|
|
38
|
-
this.input.addEventListener('input', () => this.updateValue());
|
|
39
|
-
this.select.addEventListener('change', () => this.updateUnit());
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
connectedCallback() {
|
|
43
|
-
this.value = this.getAttribute('value') || 1;
|
|
44
|
-
this.unit = this.getAttribute('unit') || 'mm';
|
|
45
|
-
this.input.value = this.value;
|
|
46
|
-
this.select.value = this.unit;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
updateValue() {
|
|
50
|
-
this.value = this.input.value;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
updateUnit() {
|
|
54
|
-
const oldUnit = this.unit;
|
|
55
|
-
const newUnit = this.select.value;
|
|
56
|
-
|
|
57
|
-
// Convert value to the new unit
|
|
58
|
-
this.value = (this.value * this.units.length[oldUnit]) / this.units.length[newUnit];
|
|
59
|
-
this.unit = newUnit;
|
|
60
|
-
|
|
61
|
-
// Update the input value to reflect the new unit
|
|
62
|
-
this.input.value = this.value;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
customElements.define('physical-quantity', PhysicalQuantity);
|