@zumer/orbit 1.4.10 → 1.4.12

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 CHANGED
@@ -18,6 +18,8 @@
18
18
 
19
19
  Radial UIs usually need JavaScript to compute angles, radii, and positions. **Orbit** handles all of that with CSS classes and a couple of Web Components. Drop in two files and start building.
20
20
 
21
+ > **Want ready-made components?** [**orbit-kit**](https://zumerlab.com/orbit-kit) wraps the common Orbit patterns into one-line custom elements — gauges, charts, activity rings, knobs, pie menus, cockpit instruments, analog clocks, compasses and radars.
22
+
21
23
  ## Installation
22
24
 
23
25
  **CDN (fastest):**
@@ -158,8 +160,21 @@ Browse examples on the [Orbit docs site](https://zumerlab.github.io/orbit-docs):
158
160
 
159
161
  ---
160
162
 
163
+ ## Using Orbit with AI / LLMs
164
+
165
+ Orbit's radial model is unlike the box-flow layouts most models were trained on,
166
+ so an assistant generating Orbit markup from scratch will struggle. Give it the
167
+ reference first — these files are written for that purpose:
168
+
169
+ - **[llms.txt](https://zumerlab.github.io/orbit-docs/llms.txt)** — concise overview, structure rules, quick recipes.
170
+ - **[llms-full.txt](https://zumerlab.github.io/orbit-docs/llms-full.txt)** — complete reference: every class, custom property, web component, and copy-paste pattern.
171
+
172
+ Paste the relevant one into your prompt (or your tool's context/rules) before
173
+ asking the model to build a radial UI.
174
+
161
175
  ## Resources
162
176
 
177
+ - [orbit-kit](https://zumerlab.com/orbit-kit) — ready-made radial components built on Orbit
163
178
  - [Full documentation](https://zumerlab.github.io/orbit-docs) — elements, tools, advanced examples
164
179
  - [Contributing](CONTRIBUTING.md)
165
180
  - [GitHub Discussions](https://github.com/zumerlab/orbit/discussions)
package/dist/orbit.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * orbit
3
- * v.1.4.10
3
+ * v.1.4.12
4
4
  * Author Juan Martin Muda - Zumerlab
5
5
  * License MIT
6
6
  */
@@ -84,13 +84,19 @@
84
84
  const upperArcEnd = this.arcPoint(bigRadius, upperAngleEnd);
85
85
  const innerArcStart = this.arcPoint(smallRadius, innerAngleStart);
86
86
  const innerArcEnd = this.arcPoint(smallRadius, innerAngleEnd);
87
- const largeArcFlag = arcAngle <= 180 ? 0 : 1;
87
+ const upperSweep = upperAngleEnd - upperAngleStart;
88
+ const innerSweep = innerAngleEnd - innerAngleStart;
89
+ const largeArcFlagUpper = upperSweep > Math.PI ? 1 : 0;
90
+ const largeArcFlagInner = innerSweep > Math.PI ? 1 : 0;
88
91
  return {
89
92
  upperArcStart,
90
93
  upperArcEnd,
91
94
  innerArcStart,
92
95
  innerArcEnd,
93
- largeArcFlag,
96
+ largeArcFlag: largeArcFlagUpper,
97
+ // back-compat alias; prefer the two below
98
+ largeArcFlagUpper,
99
+ largeArcFlagInner,
94
100
  bigRadius,
95
101
  smallRadius,
96
102
  radius,
@@ -130,8 +136,11 @@
130
136
  return d;
131
137
  }
132
138
  generateRoundedPath(params, arcHeight, orbitNumber) {
133
- const { upperArcStart, upperArcEnd, innerArcStart, innerArcEnd, bigRadius, smallRadius, largeArcFlag } = params;
139
+ const { bigRadius, smallRadius } = params;
134
140
  const curve = arcHeight < 10 ? 5 : arcHeight < 5 ? 2.5 : 10;
141
+ const capRad = curve / orbitNumber * Math.PI / 180;
142
+ const flagU = params.upperAngleEnd - params.upperAngleStart - 2 * capRad > Math.PI ? 1 : 0;
143
+ const flagI = params.innerAngleEnd - params.innerAngleStart - 2 * capRad > Math.PI ? 1 : 0;
135
144
  const newUpperStart = this.arcPoint(bigRadius, params.upperAngleStart, 0, curve / orbitNumber);
136
145
  const newUpperEnd = this.arcPoint(bigRadius, params.upperAngleEnd, 0, -curve / orbitNumber);
137
146
  const newInnerStart = this.arcPoint(smallRadius, params.innerAngleStart, 0, curve / orbitNumber);
@@ -144,10 +153,10 @@
144
153
  const Q1 = this.getControlPoint(innerPointEnd.x, innerPointEnd.y, newInnerEnd.x, newInnerEnd.y);
145
154
  const Q2 = this.getControlPoint(newInnerStart.x, newInnerStart.y, innerPointStart.x, innerPointStart.y);
146
155
  const Q3 = this.getControlPoint(upperPointStart.x, upperPointStart.y, newUpperStart.x, newUpperStart.y);
147
- let d = `M ${newUpperStart.x},${newUpperStart.y} A ${bigRadius},${bigRadius} 0 ${largeArcFlag} 1 ${newUpperEnd.x},${newUpperEnd.y}`;
156
+ let d = `M ${newUpperStart.x},${newUpperStart.y} A ${bigRadius},${bigRadius} 0 ${flagU} 1 ${newUpperEnd.x},${newUpperEnd.y}`;
148
157
  d += `Q ${Q.xc},${Q.yc} ${upperPointEnd.x},${upperPointEnd.y} L ${innerPointEnd.x},${innerPointEnd.y}`;
149
158
  d += `Q ${Q1.xc},${Q1.yc} ${newInnerEnd.x},${newInnerEnd.y}`;
150
- d += `A ${smallRadius},${smallRadius} 0 ${largeArcFlag} 0 ${newInnerStart.x},${newInnerStart.y}`;
159
+ d += `A ${smallRadius},${smallRadius} 0 ${flagI} 0 ${newInnerStart.x},${newInnerStart.y}`;
151
160
  d += `Q ${Q2.xc},${Q2.yc} ${innerPointStart.x},${innerPointStart.y} L ${upperPointStart.x},${upperPointStart.y}`;
152
161
  d += ` Q ${Q3.xc},${Q3.yc} ${newUpperStart.x},${newUpperStart.y}`;
153
162
  d += ` Z`;
@@ -155,54 +164,57 @@
155
164
  }
156
165
  // Dentro de la clase OrbitCommon en orbit-common.js
157
166
  generateCirclePath(params, shape) {
158
- const { upperArcStart, upperArcEnd, innerArcStart, innerArcEnd, bigRadius, smallRadius, largeArcFlag } = params;
159
- let d = `M ${upperArcStart.x},${upperArcStart.y} A ${bigRadius},${bigRadius} 0 ${largeArcFlag} 1 ${upperArcEnd.x},${upperArcEnd.y}`;
167
+ const { upperArcStart, upperArcEnd, innerArcStart, innerArcEnd, bigRadius, smallRadius, largeArcFlagUpper, largeArcFlagInner } = params;
168
+ let d = `M ${upperArcStart.x},${upperArcStart.y} A ${bigRadius},${bigRadius} 0 ${largeArcFlagUpper} 1 ${upperArcEnd.x},${upperArcEnd.y}`;
160
169
  d += ` A 1,1 0 0 1 ${innerArcEnd.x},${innerArcEnd.y} `;
161
- d += ` A ${smallRadius},${smallRadius} 0 ${largeArcFlag} 0 ${innerArcStart.x},${innerArcStart.y}`;
170
+ d += ` A ${smallRadius},${smallRadius} 0 ${largeArcFlagInner} 0 ${innerArcStart.x},${innerArcStart.y}`;
162
171
  d += ` A 1,1 0 0 ${shape === "circle" || shape === "circle-a" ? 1 : 0} ${upperArcStart.x},${upperArcStart.y} `;
163
172
  d += ` Z`;
164
173
  return d;
165
174
  }
166
175
  generateCircleBPath(params, arcHeight, orbitNumber) {
167
- const { upperAngleStart, upperAngleEnd, innerAngleStart, innerAngleEnd, bigRadius, smallRadius, largeArcFlag } = params;
176
+ const { upperAngleStart, upperAngleEnd, innerAngleStart, innerAngleEnd, bigRadius, smallRadius } = params;
168
177
  const segment = arcHeight * 1.36;
178
+ const capRad = segment / orbitNumber * Math.PI / 180;
179
+ const flagU = upperAngleEnd - upperAngleStart - 2 * capRad > Math.PI ? 1 : 0;
180
+ const flagI = innerAngleEnd - innerAngleStart - 2 * capRad > Math.PI ? 1 : 0;
169
181
  const newUpperStart = this.arcPoint(bigRadius, upperAngleStart, 0, segment / orbitNumber);
170
182
  const newUpperEnd = this.arcPoint(bigRadius, upperAngleEnd, 0, -segment / orbitNumber);
171
183
  const newInnerStart = this.arcPoint(smallRadius, innerAngleStart, 0, segment / orbitNumber);
172
184
  const newInnerEnd = this.arcPoint(smallRadius, innerAngleEnd, 0, -segment / orbitNumber);
173
- let d = `M ${newUpperStart.x},${newUpperStart.y} A ${bigRadius},${bigRadius} 0 ${largeArcFlag} 1 ${newUpperEnd.x},${newUpperEnd.y}`;
185
+ let d = `M ${newUpperStart.x},${newUpperStart.y} A ${bigRadius},${bigRadius} 0 ${flagU} 1 ${newUpperEnd.x},${newUpperEnd.y}`;
174
186
  d += ` A 1,1 0 0 1 ${newInnerEnd.x},${newInnerEnd.y} `;
175
- d += ` A ${smallRadius},${smallRadius} 0 ${largeArcFlag} 0 ${newInnerStart.x},${newInnerStart.y}`;
187
+ d += ` A ${smallRadius},${smallRadius} 0 ${flagI} 0 ${newInnerStart.x},${newInnerStart.y}`;
176
188
  d += ` A 1,1 0 0 1 ${newUpperStart.x},${newUpperStart.y} `;
177
189
  d += ` Z`;
178
190
  return d;
179
191
  }
180
192
  generateArrowPath(params, orbitNumber) {
181
- const { upperArcStart, upperArcEnd, innerArcStart, innerArcEnd, bigRadius, smallRadius, largeArcFlag, radius } = params;
193
+ const { upperArcStart, upperArcEnd, innerArcStart, innerArcEnd, bigRadius, smallRadius, largeArcFlagUpper, largeArcFlagInner, radius } = params;
182
194
  const middleEnd = this.arcPoint(radius, params.upperAngleEnd, 0, 24 / orbitNumber / 2);
183
195
  const middleStart = this.arcPoint(radius, params.upperAngleStart, 0, 24 / orbitNumber / 2);
184
- let d = `M ${upperArcStart.x},${upperArcStart.y} A ${bigRadius},${bigRadius} 0 ${largeArcFlag} 1 ${upperArcEnd.x},${upperArcEnd.y}`;
196
+ let d = `M ${upperArcStart.x},${upperArcStart.y} A ${bigRadius},${bigRadius} 0 ${largeArcFlagUpper} 1 ${upperArcEnd.x},${upperArcEnd.y}`;
185
197
  d += `L ${middleEnd.x} ${middleEnd.y}`;
186
198
  d += `L ${innerArcEnd.x} ${innerArcEnd.y}`;
187
- d += `A ${smallRadius},${smallRadius} 0 ${largeArcFlag} 0 ${innerArcStart.x}, ${innerArcStart.y}`;
199
+ d += `A ${smallRadius},${smallRadius} 0 ${largeArcFlagInner} 0 ${innerArcStart.x}, ${innerArcStart.y}`;
188
200
  d += `L ${middleStart.x} ${middleStart.y}`;
189
201
  d += `Z`;
190
202
  return d;
191
203
  }
192
204
  generateSlashPath(params, shape, orbitNumber) {
193
- const { upperAngleStart, upperAngleEnd, innerAngleStart, innerAngleEnd, bigRadius, smallRadius, largeArcFlag } = params;
205
+ const { upperAngleStart, upperAngleEnd, innerAngleStart, innerAngleEnd, bigRadius, smallRadius, largeArcFlagUpper, largeArcFlagInner } = params;
194
206
  const newUpperStart = this.arcPoint(bigRadius, upperAngleStart, 0, shape === "backslash" ? 0 : 24 / orbitNumber / 2);
195
207
  const newUpperEnd = this.arcPoint(bigRadius, upperAngleEnd, 0, shape === "backslash" ? 0 : 24 / orbitNumber / 2);
196
208
  const newInnerStart = this.arcPoint(smallRadius, innerAngleStart, 0, shape === "backslash" ? 24 / orbitNumber / 2 : 0);
197
209
  const newInnerEnd = this.arcPoint(smallRadius, innerAngleEnd, 0, shape === "backslash" ? 24 / orbitNumber / 2 : 0);
198
- let d = `M ${newUpperStart.x},${newUpperStart.y} A ${bigRadius},${bigRadius} 0 ${largeArcFlag} 1 ${newUpperEnd.x},${newUpperEnd.y}`;
210
+ let d = `M ${newUpperStart.x},${newUpperStart.y} A ${bigRadius},${bigRadius} 0 ${largeArcFlagUpper} 1 ${newUpperEnd.x},${newUpperEnd.y}`;
199
211
  d += `L ${newInnerEnd.x} ${newInnerEnd.y}`;
200
- d += `A ${smallRadius},${smallRadius} 0 ${largeArcFlag} 0 ${newInnerStart.x}, ${newInnerStart.y}`;
212
+ d += `A ${smallRadius},${smallRadius} 0 ${largeArcFlagInner} 0 ${newInnerStart.x}, ${newInnerStart.y}`;
201
213
  d += `Z`;
202
214
  return d;
203
215
  }
204
216
  generateZigzagPath(params, arcHeight, orbitNumber) {
205
- const { upperArcStart, upperArcEnd, innerArcStart, innerArcEnd, bigRadius, smallRadius, largeArcFlag, radius } = params;
217
+ const { upperArcStart, upperArcEnd, innerArcStart, innerArcEnd, bigRadius, smallRadius, largeArcFlagUpper, largeArcFlagInner, radius } = params;
206
218
  const h2 = arcHeight / orbitNumber / 2;
207
219
  const s2 = this.arcPoint(radius, params.upperAngleStart, -h2, 3);
208
220
  const s3 = this.arcPoint(radius, params.upperAngleStart, 0, 0);
@@ -210,12 +222,12 @@
210
222
  const e2 = this.arcPoint(radius, params.innerAngleEnd, h2, 3);
211
223
  const e3 = this.arcPoint(radius, params.innerAngleEnd, 0, 0);
212
224
  const e4 = this.arcPoint(radius, params.innerAngleEnd, -h2, 3);
213
- let d = `M ${upperArcStart.x},${upperArcStart.y} A ${bigRadius},${bigRadius} 0 ${largeArcFlag} 1 ${upperArcEnd.x},${upperArcEnd.y}`;
225
+ let d = `M ${upperArcStart.x},${upperArcStart.y} A ${bigRadius},${bigRadius} 0 ${largeArcFlagUpper} 1 ${upperArcEnd.x},${upperArcEnd.y}`;
214
226
  d += `L ${e2.x} ${e2.y}`;
215
227
  d += `L ${e3.x} ${e3.y}`;
216
228
  d += `L ${e4.x} ${e4.y}`;
217
229
  d += `L ${innerArcEnd.x} ${innerArcEnd.y}`;
218
- d += `A ${smallRadius},${smallRadius} 0 ${largeArcFlag} 0 ${innerArcStart.x}, ${innerArcStart.y}`;
230
+ d += `A ${smallRadius},${smallRadius} 0 ${largeArcFlagInner} 0 ${innerArcStart.x}, ${innerArcStart.y}`;
219
231
  d += `L ${s2.x} ${s2.y}`;
220
232
  d += `L ${s3.x} ${s3.y}`;
221
233
  d += `L ${s4.x} ${s4.y}`;
@@ -223,10 +235,10 @@
223
235
  return d;
224
236
  }
225
237
  generateDefaultPath(params) {
226
- const { upperArcStart, upperArcEnd, innerArcStart, innerArcEnd, bigRadius, smallRadius, largeArcFlag } = params;
227
- let d = `M ${upperArcStart.x},${upperArcStart.y} A ${bigRadius},${bigRadius} 0 ${largeArcFlag} 1 ${upperArcEnd.x},${upperArcEnd.y}`;
238
+ const { upperArcStart, upperArcEnd, innerArcStart, innerArcEnd, bigRadius, smallRadius, largeArcFlagUpper, largeArcFlagInner } = params;
239
+ let d = `M ${upperArcStart.x},${upperArcStart.y} A ${bigRadius},${bigRadius} 0 ${largeArcFlagUpper} 1 ${upperArcEnd.x},${upperArcEnd.y}`;
228
240
  d += `L ${innerArcEnd.x} ${innerArcEnd.y}`;
229
- d += `A ${smallRadius},${smallRadius} 0 ${largeArcFlag} 0 ${innerArcStart.x}, ${innerArcStart.y}`;
241
+ d += `A ${smallRadius},${smallRadius} 0 ${largeArcFlagInner} 0 ${innerArcStart.x}, ${innerArcStart.y}`;
230
242
  d += `Z`;
231
243
  return d;
232
244
  }
@@ -261,9 +273,17 @@
261
273
  overflow: visible;
262
274
  pointer-events: none;
263
275
  }
276
+ /* Display element by default: never steals clicks (see orbit-arc).
277
+ Interaction is opt-in via the "interactive" attribute. */
264
278
  svg * {
279
+ pointer-events: none;
280
+ }
281
+ :host([interactive]) svg * {
265
282
  pointer-events: visiblePainted;
266
283
  }
284
+ :host([interactive]) {
285
+ cursor: pointer;
286
+ }
267
287
  .progress-bar {
268
288
  fill: var(--o-fill);
269
289
  stroke: var(--o-stroke);
@@ -276,6 +296,23 @@
276
296
  stroke: var(--o-back-stroke);
277
297
  stroke-width: var(--o-back-stroke-width);
278
298
  }
299
+ /* variant="stroke": the thin, legible gauge (registro "medidor").
300
+ The default band is a FILLED donut wedge, so everyone building a
301
+ thin gauge tripped on --o-fill/--o-back-fill. With this variant the
302
+ paths are open arcs and the data color lives where you expect it:
303
+ --o-stroke for the bar, --o-back-stroke for the track. */
304
+ :host([variant="stroke"]) .progress-bar {
305
+ fill: none;
306
+ stroke: var(--o-stroke);
307
+ stroke-width: var(--o-stroke-width, 2);
308
+ stroke-linecap: round;
309
+ }
310
+ :host([variant="stroke"]) .progress-bg {
311
+ fill: none;
312
+ stroke: var(--o-back-stroke, var(--o-gray-light));
313
+ stroke-width: var(--o-back-stroke-width, 1);
314
+ stroke-linecap: round;
315
+ }
279
316
  </style>
280
317
  <svg viewBox="0 0 100 100">
281
318
  <path class="progress-bg" shape-rendering="geometricPrecision" vector-effect="non-scaling-stroke"></path>
@@ -297,11 +334,28 @@
297
334
  }
298
335
  update() {
299
336
  const attrs = this.getAttributes();
300
- const dBg = this.calculateArcParameters(attrs, true);
301
- const dBar = this.calculateArcParameters(attrs, false);
337
+ const isStroke = this.getAttribute("variant") === "stroke";
338
+ const dBg = isStroke ? this.calculateStrokeArc(attrs, true) : this.calculateArcParameters(attrs, true);
339
+ const dBar = isStroke ? this.calculateStrokeArc(attrs, false) : this.calculateArcParameters(attrs, false);
302
340
  this.shadowRoot.querySelector(".progress-bg").setAttribute("d", dBg);
303
341
  this.shadowRoot.querySelector(".progress-bar").setAttribute("d", dBar);
304
342
  }
343
+ /**
344
+ * variant="stroke": open arc along the orbit radius (no closed band),
345
+ * stroked by CSS. Same progress math as the band variant.
346
+ */
347
+ calculateStrokeArc(attrs, full) {
348
+ const { realRadius } = attrs;
349
+ const arcAngle = Math.max(0, Math.min(this.getProgressAngle(attrs, full), 359.99));
350
+ const a0 = -90 * (Math.PI / 180);
351
+ const a1 = (-90 + arcAngle) * (Math.PI / 180);
352
+ const x0 = 50 + realRadius * Math.cos(a0);
353
+ const y0 = 50 + realRadius * Math.sin(a0);
354
+ const x1 = 50 + realRadius * Math.cos(a1);
355
+ const y1 = 50 + realRadius * Math.sin(a1);
356
+ const largeArcFlag = arcAngle > 180 ? 1 : 0;
357
+ return `M ${x0},${y0} A ${realRadius},${realRadius} 0 ${largeArcFlag} 1 ${x1},${y1}`;
358
+ }
305
359
  getAttributes() {
306
360
  const common = super.getCommonAttributes(this);
307
361
  const range = parseFloat(getComputedStyle(this).getPropertyValue("--o-range") || 360);
@@ -356,9 +410,19 @@
356
410
  overflow: visible;
357
411
  pointer-events: none;
358
412
  }
413
+ /* Arcs are display elements by default: they must NOT steal clicks from
414
+ satellites/controls nearby (a painted arc used to capture clicks even
415
+ at opacity 0, and pointer-events:none on the host could not pierce the
416
+ shadow). Interaction is opt-in via the "interactive" attribute. */
359
417
  svg * {
418
+ pointer-events: none;
419
+ }
420
+ :host([interactive]) svg * {
360
421
  pointer-events: visiblePainted;
361
422
  }
423
+ :host([interactive]) {
424
+ cursor: pointer;
425
+ }
362
426
  #orbitShape {
363
427
  fill: var(--o-fill);
364
428
  stroke: var(--o-stroke);
@@ -432,6 +496,30 @@
432
496
  }
433
497
  textPath.parentElement.style.fontSize = `calc(${fontSize} * (100 / (${length}) * (12 / var(--o-orbit-number)))`;
434
498
  textPath.textContent = this.textContent;
499
+ this.warnIfTextOverflows(orbitPath, textPath, fitRange);
500
+ }
501
+ /**
502
+ * Curved text has an explicit angular budget: glyphs past the end of the
503
+ * arc path are clipped SILENTLY by SVG. Measure and warn so nobody loses
504
+ * time to invisible truncation (~20 chars in 96° at default sizes).
505
+ * fit-range squeezes the text to the path via textLength, so it never clips.
506
+ */
507
+ warnIfTextOverflows(orbitPath, textPath, fitRange) {
508
+ const raw = (this.textContent || "").trim();
509
+ if (!raw || fitRange || !this.isConnected) return;
510
+ requestAnimationFrame(() => {
511
+ try {
512
+ const pathLen = orbitPath.getTotalLength();
513
+ const textLen = textPath.parentElement.getComputedTextLength();
514
+ if (pathLen > 0 && textLen > pathLen && this._truncWarned !== raw) {
515
+ this._truncWarned = raw;
516
+ console.warn(
517
+ `[orbit] <o-arc> text "${raw.length > 34 ? raw.slice(0, 34) + "\u2026" : raw}" overflows its arc (${Math.round(textLen)} > ${Math.round(pathLen)} units) and will clip. Shorten the text, widen --o-range, or use fit-range to squeeze it.`
518
+ );
519
+ }
520
+ } catch (e) {
521
+ }
522
+ });
435
523
  }
436
524
  getAttributes() {
437
525
  const common = super.getCommonAttributes(this);
package/dist/orbit.min.js CHANGED
@@ -1,10 +1,10 @@
1
1
  /*
2
2
  * orbit
3
- * v.1.4.10
3
+ * v.1.4.12
4
4
  * Author Juan Martin Muda - Zumerlab
5
5
  * License MIT
6
6
  */
7
- (()=>{var x=class extends HTMLElement{constructor(){super()}getCommonAttributes(t){let r=parseFloat(getComputedStyle(t).getPropertyValue("r")||0),e=parseFloat(getComputedStyle(t).getPropertyValue("--o-orbit-number")||1),n=parseFloat(getComputedStyle(t).getPropertyValue("--o-size-ratio")||1),o=parseFloat(getComputedStyle(t).getPropertyValue("--o-stroke-width")||1),i=t.getAttribute("shape")||"none",g=r/e*n-o+.3,s=r>0?g/2*100/r/2:0,a=0;t.classList.contains("outer-orbit")?a=s:t.classList.contains("quarter-outer-orbit")?a=s*-.5:t.classList.contains("inner-orbit")?a=s*-1:t.classList.contains("quarter-inner-orbit")&&(a=s*.5);let h=50+a;return{orbitRadius:r,arcHeight:g,realRadius:h,arcAngle:0,shape:i,arcHeightPercentage:s,orbitNumber:e,size:n,strokeWidth:o}}getProgressAngle(t,r,e=100){return r/e*t}getControlPoint(t,r,e,n,o="clockwise"){let i=(t+e)/2,g=(r+n)/2,s=e-t,a=n-r;return o==="clockwise"?{xc:i+a*.4,yc:g-s*.4}:{xc:i-a*.4,yc:g+s*.4}}arcPoint(t,r,e=0,n=0){let o=t+e,i=r+n*Math.PI/180;return{x:50+o*Math.cos(i),y:50+o*Math.sin(i)}}calculateCommonArcParameters(t,r,e,n,o,i,g,s=0){let a=Math.PI/2,h=t*Math.PI/180,c=r+e,l=r-e!==0?r-e:r,u=(s+i*1.25)/n/c,p=(s+i*1.25)/n/l,d=u-a,$=h-u-a,P=p-a,y=h-p-a,A=this.arcPoint(c,d),v=this.arcPoint(c,$),S=this.arcPoint(l,P),k=this.arcPoint(l,y),w=t<=180?0:1;return{upperArcStart:A,upperArcEnd:v,innerArcStart:S,innerArcEnd:k,largeArcFlag:w,bigRadius:c,smallRadius:l,radius:r,upperAngleStart:d,upperAngleEnd:$,innerAngleStart:P,innerAngleEnd:y}}generatePathData(t,r,e,n){let o="";switch(t){case"rounded":o=this.generateRoundedPath(r,e,n);break;case"circle":case"circle-a":case"bullet":o=this.generateCirclePath(r,t);break;case"circle-b":o=this.generateCircleBPath(r,e,n);break;case"arrow":o=this.generateArrowPath(r,n);break;case"backslash":case"slash":o=this.generateSlashPath(r,t,n);break;case"zigzag":o=this.generateZigzagPath(r,e,n);break;default:o=this.generateDefaultPath(r)}return o}generateRoundedPath(t,r,e){let{upperArcStart:n,upperArcEnd:o,innerArcStart:i,innerArcEnd:g,bigRadius:s,smallRadius:a,largeArcFlag:h}=t,c=r<10?5:r<5?2.5:10,l=this.arcPoint(s,t.upperAngleStart,0,c/e),u=this.arcPoint(s,t.upperAngleEnd,0,-c/e),p=this.arcPoint(a,t.innerAngleStart,0,c/e),d=this.arcPoint(a,t.innerAngleEnd,0,-c/e),$=this.arcPoint(s,t.upperAngleStart,-(c/2)/e,0),P=this.arcPoint(s,t.upperAngleEnd,-(c/2)/e,0),y=this.arcPoint(a,t.innerAngleStart,c/2/e,0),A=this.arcPoint(a,t.innerAngleEnd,c/2/e,0),v=this.getControlPoint(u.x,u.y,P.x,P.y),S=this.getControlPoint(A.x,A.y,d.x,d.y),k=this.getControlPoint(p.x,p.y,y.x,y.y),w=this.getControlPoint($.x,$.y,l.x,l.y),f=`M ${l.x},${l.y} A ${s},${s} 0 ${h} 1 ${u.x},${u.y}`;return f+=`Q ${v.xc},${v.yc} ${P.x},${P.y} L ${A.x},${A.y}`,f+=`Q ${S.xc},${S.yc} ${d.x},${d.y}`,f+=`A ${a},${a} 0 ${h} 0 ${p.x},${p.y}`,f+=`Q ${k.xc},${k.yc} ${y.x},${y.y} L ${$.x},${$.y}`,f+=` Q ${w.xc},${w.yc} ${l.x},${l.y}`,f+=" Z",f}generateCirclePath(t,r){let{upperArcStart:e,upperArcEnd:n,innerArcStart:o,innerArcEnd:i,bigRadius:g,smallRadius:s,largeArcFlag:a}=t,h=`M ${e.x},${e.y} A ${g},${g} 0 ${a} 1 ${n.x},${n.y}`;return h+=` A 1,1 0 0 1 ${i.x},${i.y} `,h+=` A ${s},${s} 0 ${a} 0 ${o.x},${o.y}`,h+=` A 1,1 0 0 ${r==="circle"||r==="circle-a"?1:0} ${e.x},${e.y} `,h+=" Z",h}generateCircleBPath(t,r,e){let{upperAngleStart:n,upperAngleEnd:o,innerAngleStart:i,innerAngleEnd:g,bigRadius:s,smallRadius:a,largeArcFlag:h}=t,c=r*1.36,l=this.arcPoint(s,n,0,c/e),u=this.arcPoint(s,o,0,-c/e),p=this.arcPoint(a,i,0,c/e),d=this.arcPoint(a,g,0,-c/e),$=`M ${l.x},${l.y} A ${s},${s} 0 ${h} 1 ${u.x},${u.y}`;return $+=` A 1,1 0 0 1 ${d.x},${d.y} `,$+=` A ${a},${a} 0 ${h} 0 ${p.x},${p.y}`,$+=` A 1,1 0 0 1 ${l.x},${l.y} `,$+=" Z",$}generateArrowPath(t,r){let{upperArcStart:e,upperArcEnd:n,innerArcStart:o,innerArcEnd:i,bigRadius:g,smallRadius:s,largeArcFlag:a,radius:h}=t,c=this.arcPoint(h,t.upperAngleEnd,0,24/r/2),l=this.arcPoint(h,t.upperAngleStart,0,24/r/2),u=`M ${e.x},${e.y} A ${g},${g} 0 ${a} 1 ${n.x},${n.y}`;return u+=`L ${c.x} ${c.y}`,u+=`L ${i.x} ${i.y}`,u+=`A ${s},${s} 0 ${a} 0 ${o.x}, ${o.y}`,u+=`L ${l.x} ${l.y}`,u+="Z",u}generateSlashPath(t,r,e){let{upperAngleStart:n,upperAngleEnd:o,innerAngleStart:i,innerAngleEnd:g,bigRadius:s,smallRadius:a,largeArcFlag:h}=t,c=this.arcPoint(s,n,0,r==="backslash"?0:24/e/2),l=this.arcPoint(s,o,0,r==="backslash"?0:24/e/2),u=this.arcPoint(a,i,0,r==="backslash"?24/e/2:0),p=this.arcPoint(a,g,0,r==="backslash"?24/e/2:0),d=`M ${c.x},${c.y} A ${s},${s} 0 ${h} 1 ${l.x},${l.y}`;return d+=`L ${p.x} ${p.y}`,d+=`A ${a},${a} 0 ${h} 0 ${u.x}, ${u.y}`,d+="Z",d}generateZigzagPath(t,r,e){let{upperArcStart:n,upperArcEnd:o,innerArcStart:i,innerArcEnd:g,bigRadius:s,smallRadius:a,largeArcFlag:h,radius:c}=t,l=r/e/2,u=this.arcPoint(c,t.upperAngleStart,-l,3),p=this.arcPoint(c,t.upperAngleStart,0,0),d=this.arcPoint(c,t.upperAngleStart,l,3),$=this.arcPoint(c,t.innerAngleEnd,l,3),P=this.arcPoint(c,t.innerAngleEnd,0,0),y=this.arcPoint(c,t.innerAngleEnd,-l,3),A=`M ${n.x},${n.y} A ${s},${s} 0 ${h} 1 ${o.x},${o.y}`;return A+=`L ${$.x} ${$.y}`,A+=`L ${P.x} ${P.y}`,A+=`L ${y.x} ${y.y}`,A+=`L ${g.x} ${g.y}`,A+=`A ${a},${a} 0 ${h} 0 ${i.x}, ${i.y}`,A+=`L ${u.x} ${u.y}`,A+=`L ${p.x} ${p.y}`,A+=`L ${d.x} ${d.y}`,A+="Z",A}generateDefaultPath(t){let{upperArcStart:r,upperArcEnd:e,innerArcStart:n,innerArcEnd:o,bigRadius:i,smallRadius:g,largeArcFlag:s}=t,a=`M ${r.x},${r.y} A ${i},${i} 0 ${s} 1 ${e.x},${e.y}`;return a+=`L ${o.x} ${o.y}`,a+=`A ${g},${g} 0 ${s} 0 ${n.x}, ${n.y}`,a+="Z",a}};var m=class extends x{constructor(){super(),this.attachShadow({mode:"open"}),this.shadowRoot.innerHTML=`
7
+ (()=>{var b=class extends HTMLElement{constructor(){super()}getCommonAttributes(t){let r=parseFloat(getComputedStyle(t).getPropertyValue("r")||0),e=parseFloat(getComputedStyle(t).getPropertyValue("--o-orbit-number")||1),s=parseFloat(getComputedStyle(t).getPropertyValue("--o-size-ratio")||1),n=parseFloat(getComputedStyle(t).getPropertyValue("--o-stroke-width")||1),o=t.getAttribute("shape")||"none",l=r/e*s-n+.3,a=r>0?l/2*100/r/2:0,i=0;t.classList.contains("outer-orbit")?i=a:t.classList.contains("quarter-outer-orbit")?i=a*-.5:t.classList.contains("inner-orbit")?i=a*-1:t.classList.contains("quarter-inner-orbit")&&(i=a*.5);let c=50+i;return{orbitRadius:r,arcHeight:l,realRadius:c,arcAngle:0,shape:o,arcHeightPercentage:a,orbitNumber:e,size:s,strokeWidth:n}}getProgressAngle(t,r,e=100){return r/e*t}getControlPoint(t,r,e,s,n="clockwise"){let o=(t+e)/2,l=(r+s)/2,a=e-t,i=s-r;return n==="clockwise"?{xc:o+i*.4,yc:l-a*.4}:{xc:o-i*.4,yc:l+a*.4}}arcPoint(t,r,e=0,s=0){let n=t+e,o=r+s*Math.PI/180;return{x:50+n*Math.cos(o),y:50+n*Math.sin(o)}}calculateCommonArcParameters(t,r,e,s,n,o,l,a=0){let i=Math.PI/2,c=t*Math.PI/180,h=r+e,g=r-e!==0?r-e:r,u=(a+o*1.25)/s/h,d=(a+o*1.25)/s/g,$=u-i,p=c-u-i,A=d-i,P=c-d-i,v=this.arcPoint(h,$),f=this.arcPoint(h,p),k=this.arcPoint(g,A),y=this.arcPoint(g,P),C=p-$,R=P-A,m=C>Math.PI?1:0,I=R>Math.PI?1:0;return{upperArcStart:v,upperArcEnd:f,innerArcStart:k,innerArcEnd:y,largeArcFlag:m,largeArcFlagUpper:m,largeArcFlagInner:I,bigRadius:h,smallRadius:g,radius:r,upperAngleStart:$,upperAngleEnd:p,innerAngleStart:A,innerAngleEnd:P}}generatePathData(t,r,e,s){let n="";switch(t){case"rounded":n=this.generateRoundedPath(r,e,s);break;case"circle":case"circle-a":case"bullet":n=this.generateCirclePath(r,t);break;case"circle-b":n=this.generateCircleBPath(r,e,s);break;case"arrow":n=this.generateArrowPath(r,s);break;case"backslash":case"slash":n=this.generateSlashPath(r,t,s);break;case"zigzag":n=this.generateZigzagPath(r,e,s);break;default:n=this.generateDefaultPath(r)}return n}generateRoundedPath(t,r,e){let{bigRadius:s,smallRadius:n}=t,o=r<10?5:r<5?2.5:10,l=o/e*Math.PI/180,a=t.upperAngleEnd-t.upperAngleStart-2*l>Math.PI?1:0,i=t.innerAngleEnd-t.innerAngleStart-2*l>Math.PI?1:0,c=this.arcPoint(s,t.upperAngleStart,0,o/e),h=this.arcPoint(s,t.upperAngleEnd,0,-o/e),g=this.arcPoint(n,t.innerAngleStart,0,o/e),u=this.arcPoint(n,t.innerAngleEnd,0,-o/e),d=this.arcPoint(s,t.upperAngleStart,-(o/2)/e,0),$=this.arcPoint(s,t.upperAngleEnd,-(o/2)/e,0),p=this.arcPoint(n,t.innerAngleStart,o/2/e,0),A=this.arcPoint(n,t.innerAngleEnd,o/2/e,0),P=this.getControlPoint(h.x,h.y,$.x,$.y),v=this.getControlPoint(A.x,A.y,u.x,u.y),f=this.getControlPoint(g.x,g.y,p.x,p.y),k=this.getControlPoint(d.x,d.y,c.x,c.y),y=`M ${c.x},${c.y} A ${s},${s} 0 ${a} 1 ${h.x},${h.y}`;return y+=`Q ${P.xc},${P.yc} ${$.x},${$.y} L ${A.x},${A.y}`,y+=`Q ${v.xc},${v.yc} ${u.x},${u.y}`,y+=`A ${n},${n} 0 ${i} 0 ${g.x},${g.y}`,y+=`Q ${f.xc},${f.yc} ${p.x},${p.y} L ${d.x},${d.y}`,y+=` Q ${k.xc},${k.yc} ${c.x},${c.y}`,y+=" Z",y}generateCirclePath(t,r){let{upperArcStart:e,upperArcEnd:s,innerArcStart:n,innerArcEnd:o,bigRadius:l,smallRadius:a,largeArcFlagUpper:i,largeArcFlagInner:c}=t,h=`M ${e.x},${e.y} A ${l},${l} 0 ${i} 1 ${s.x},${s.y}`;return h+=` A 1,1 0 0 1 ${o.x},${o.y} `,h+=` A ${a},${a} 0 ${c} 0 ${n.x},${n.y}`,h+=` A 1,1 0 0 ${r==="circle"||r==="circle-a"?1:0} ${e.x},${e.y} `,h+=" Z",h}generateCircleBPath(t,r,e){let{upperAngleStart:s,upperAngleEnd:n,innerAngleStart:o,innerAngleEnd:l,bigRadius:a,smallRadius:i}=t,c=r*1.36,h=c/e*Math.PI/180,g=n-s-2*h>Math.PI?1:0,u=l-o-2*h>Math.PI?1:0,d=this.arcPoint(a,s,0,c/e),$=this.arcPoint(a,n,0,-c/e),p=this.arcPoint(i,o,0,c/e),A=this.arcPoint(i,l,0,-c/e),P=`M ${d.x},${d.y} A ${a},${a} 0 ${g} 1 ${$.x},${$.y}`;return P+=` A 1,1 0 0 1 ${A.x},${A.y} `,P+=` A ${i},${i} 0 ${u} 0 ${p.x},${p.y}`,P+=` A 1,1 0 0 1 ${d.x},${d.y} `,P+=" Z",P}generateArrowPath(t,r){let{upperArcStart:e,upperArcEnd:s,innerArcStart:n,innerArcEnd:o,bigRadius:l,smallRadius:a,largeArcFlagUpper:i,largeArcFlagInner:c,radius:h}=t,g=this.arcPoint(h,t.upperAngleEnd,0,24/r/2),u=this.arcPoint(h,t.upperAngleStart,0,24/r/2),d=`M ${e.x},${e.y} A ${l},${l} 0 ${i} 1 ${s.x},${s.y}`;return d+=`L ${g.x} ${g.y}`,d+=`L ${o.x} ${o.y}`,d+=`A ${a},${a} 0 ${c} 0 ${n.x}, ${n.y}`,d+=`L ${u.x} ${u.y}`,d+="Z",d}generateSlashPath(t,r,e){let{upperAngleStart:s,upperAngleEnd:n,innerAngleStart:o,innerAngleEnd:l,bigRadius:a,smallRadius:i,largeArcFlagUpper:c,largeArcFlagInner:h}=t,g=this.arcPoint(a,s,0,r==="backslash"?0:24/e/2),u=this.arcPoint(a,n,0,r==="backslash"?0:24/e/2),d=this.arcPoint(i,o,0,r==="backslash"?24/e/2:0),$=this.arcPoint(i,l,0,r==="backslash"?24/e/2:0),p=`M ${g.x},${g.y} A ${a},${a} 0 ${c} 1 ${u.x},${u.y}`;return p+=`L ${$.x} ${$.y}`,p+=`A ${i},${i} 0 ${h} 0 ${d.x}, ${d.y}`,p+="Z",p}generateZigzagPath(t,r,e){let{upperArcStart:s,upperArcEnd:n,innerArcStart:o,innerArcEnd:l,bigRadius:a,smallRadius:i,largeArcFlagUpper:c,largeArcFlagInner:h,radius:g}=t,u=r/e/2,d=this.arcPoint(g,t.upperAngleStart,-u,3),$=this.arcPoint(g,t.upperAngleStart,0,0),p=this.arcPoint(g,t.upperAngleStart,u,3),A=this.arcPoint(g,t.innerAngleEnd,u,3),P=this.arcPoint(g,t.innerAngleEnd,0,0),v=this.arcPoint(g,t.innerAngleEnd,-u,3),f=`M ${s.x},${s.y} A ${a},${a} 0 ${c} 1 ${n.x},${n.y}`;return f+=`L ${A.x} ${A.y}`,f+=`L ${P.x} ${P.y}`,f+=`L ${v.x} ${v.y}`,f+=`L ${l.x} ${l.y}`,f+=`A ${i},${i} 0 ${h} 0 ${o.x}, ${o.y}`,f+=`L ${d.x} ${d.y}`,f+=`L ${$.x} ${$.y}`,f+=`L ${p.x} ${p.y}`,f+="Z",f}generateDefaultPath(t){let{upperArcStart:r,upperArcEnd:e,innerArcStart:s,innerArcEnd:n,bigRadius:o,smallRadius:l,largeArcFlagUpper:a,largeArcFlagInner:i}=t,c=`M ${r.x},${r.y} A ${o},${o} 0 ${a} 1 ${e.x},${e.y}`;return c+=`L ${n.x} ${n.y}`,c+=`A ${l},${l} 0 ${i} 0 ${s.x}, ${s.y}`,c+="Z",c}};var S=class extends b{constructor(){super(),this.attachShadow({mode:"open"}),this.shadowRoot.innerHTML=`
8
8
  <style>
9
9
  :host {
10
10
  --o-fill: var(--o-gray-light);
@@ -28,9 +28,17 @@
28
28
  overflow: visible;
29
29
  pointer-events: none;
30
30
  }
31
+ /* Display element by default: never steals clicks (see orbit-arc).
32
+ Interaction is opt-in via the "interactive" attribute. */
31
33
  svg * {
34
+ pointer-events: none;
35
+ }
36
+ :host([interactive]) svg * {
32
37
  pointer-events: visiblePainted;
33
38
  }
39
+ :host([interactive]) {
40
+ cursor: pointer;
41
+ }
34
42
  .progress-bar {
35
43
  fill: var(--o-fill);
36
44
  stroke: var(--o-stroke);
@@ -43,12 +51,29 @@
43
51
  stroke: var(--o-back-stroke);
44
52
  stroke-width: var(--o-back-stroke-width);
45
53
  }
54
+ /* variant="stroke": the thin, legible gauge (registro "medidor").
55
+ The default band is a FILLED donut wedge, so everyone building a
56
+ thin gauge tripped on --o-fill/--o-back-fill. With this variant the
57
+ paths are open arcs and the data color lives where you expect it:
58
+ --o-stroke for the bar, --o-back-stroke for the track. */
59
+ :host([variant="stroke"]) .progress-bar {
60
+ fill: none;
61
+ stroke: var(--o-stroke);
62
+ stroke-width: var(--o-stroke-width, 2);
63
+ stroke-linecap: round;
64
+ }
65
+ :host([variant="stroke"]) .progress-bg {
66
+ fill: none;
67
+ stroke: var(--o-back-stroke, var(--o-gray-light));
68
+ stroke-width: var(--o-back-stroke-width, 1);
69
+ stroke-linecap: round;
70
+ }
46
71
  </style>
47
72
  <svg viewBox="0 0 100 100">
48
73
  <path class="progress-bg" shape-rendering="geometricPrecision" vector-effect="non-scaling-stroke"></path>
49
74
  <path class="progress-bar" shape-rendering="geometricPrecision" vector-effect="non-scaling-stroke"></path>
50
75
  </svg>
51
- `}connectedCallback(){this.update(),this.setupObserver()}setupObserver(){this.observer=new MutationObserver(t=>{this.observer.disconnect(),t.forEach(()=>this.update()),this.observer.observe(this,{attributes:!0,childList:!0})}),this.observer.observe(this,{attributes:!0,childList:!0})}update(){let t=this.getAttributes(),r=this.calculateArcParameters(t,!0),e=this.calculateArcParameters(t,!1);this.shadowRoot.querySelector(".progress-bg").setAttribute("d",r),this.shadowRoot.querySelector(".progress-bar").setAttribute("d",e)}getAttributes(){let t=super.getCommonAttributes(this),r=parseFloat(getComputedStyle(this).getPropertyValue("--o-range")||360),e=parseFloat(getComputedStyle(this).getPropertyValue("--o-progress")||this.getAttribute("value")||0),n=parseFloat(this.getAttribute("max"))||100;return{...t,range:r,progress:e,maxValue:n}}getProgressAngle(t,r){let{range:e,progress:n,maxValue:o}=t;return r?(o-1e-5)/o*e:n/o*e}calculateArcParameters(t,r){let{shape:e,realRadius:n,arcHeightPercentage:o,orbitNumber:i,strokeWidth:g,arcHeight:s}=t,a=this.getProgressAngle(t,r),h=super.calculateCommonArcParameters(a,n,o,i,e,g,s);return super.generatePathData(e,h,s,i)}};var C=document.createElement("template");C.innerHTML=`
76
+ `}connectedCallback(){this.update(),this.setupObserver()}setupObserver(){this.observer=new MutationObserver(t=>{this.observer.disconnect(),t.forEach(()=>this.update()),this.observer.observe(this,{attributes:!0,childList:!0})}),this.observer.observe(this,{attributes:!0,childList:!0})}update(){let t=this.getAttributes(),r=this.getAttribute("variant")==="stroke",e=r?this.calculateStrokeArc(t,!0):this.calculateArcParameters(t,!0),s=r?this.calculateStrokeArc(t,!1):this.calculateArcParameters(t,!1);this.shadowRoot.querySelector(".progress-bg").setAttribute("d",e),this.shadowRoot.querySelector(".progress-bar").setAttribute("d",s)}calculateStrokeArc(t,r){let{realRadius:e}=t,s=Math.max(0,Math.min(this.getProgressAngle(t,r),359.99)),n=-90*(Math.PI/180),o=(-90+s)*(Math.PI/180),l=50+e*Math.cos(n),a=50+e*Math.sin(n),i=50+e*Math.cos(o),c=50+e*Math.sin(o),h=s>180?1:0;return`M ${l},${a} A ${e},${e} 0 ${h} 1 ${i},${c}`}getAttributes(){let t=super.getCommonAttributes(this),r=parseFloat(getComputedStyle(this).getPropertyValue("--o-range")||360),e=parseFloat(getComputedStyle(this).getPropertyValue("--o-progress")||this.getAttribute("value")||0),s=parseFloat(this.getAttribute("max"))||100;return{...t,range:r,progress:e,maxValue:s}}getProgressAngle(t,r){let{range:e,progress:s,maxValue:n}=t;return r?(n-1e-5)/n*e:s/n*e}calculateArcParameters(t,r){let{shape:e,realRadius:s,arcHeightPercentage:n,orbitNumber:o,strokeWidth:l,arcHeight:a}=t,i=this.getProgressAngle(t,r),c=super.calculateCommonArcParameters(i,s,n,o,e,l,a);return super.generatePathData(e,c,a,o)}};var E=document.createElement("template");E.innerHTML=`
52
77
  <style>
53
78
  :host {
54
79
  --o-fill: var(--o-gray-light);
@@ -68,9 +93,19 @@
68
93
  overflow: visible;
69
94
  pointer-events: none;
70
95
  }
96
+ /* Arcs are display elements by default: they must NOT steal clicks from
97
+ satellites/controls nearby (a painted arc used to capture clicks even
98
+ at opacity 0, and pointer-events:none on the host could not pierce the
99
+ shadow). Interaction is opt-in via the "interactive" attribute. */
71
100
  svg * {
101
+ pointer-events: none;
102
+ }
103
+ :host([interactive]) svg * {
72
104
  pointer-events: visiblePainted;
73
105
  }
106
+ :host([interactive]) {
107
+ cursor: pointer;
108
+ }
74
109
  #orbitShape {
75
110
  fill: var(--o-fill);
76
111
  stroke: var(--o-stroke);
@@ -93,4 +128,4 @@
93
128
  <textPath href="#orbitPath" alignment-baseline="middle"></textPath>
94
129
  </text>
95
130
  </svg>
96
- `;var E=class extends x{constructor(){super(),this.attachShadow({mode:"open"}),this.shadowRoot.appendChild(C.content.cloneNode(!0))}connectedCallback(){this.update(),this.setupObservers()}disconnectedCallback(){this.observer&&this.observer.disconnect(),this.textObserver&&this.textObserver.disconnect()}setupObservers(){this.observer=new MutationObserver(t=>{this.observer.disconnect(),t.forEach(()=>this.update()),this.observer.observe(this,{attributes:!0,childList:!0})}),this.observer.observe(this,{attributes:!0,childList:!0}),this.textObserver=new MutationObserver(()=>{let t=this.shadowRoot.querySelector("textPath");t.textContent=this.textContent}),this.textObserver.observe(this,{characterData:!0,subtree:!0})}update(){let t=this.getAttributes(),{length:r,fontSize:e,textAnchor:n,fitRange:o}=t,i=this.shadowRoot.querySelector("#orbitPath"),g=this.shadowRoot.querySelector("#orbitShape"),s=this.shadowRoot.querySelector("textPath");g.setAttribute("d",this.calculateArcParameters(t).dShape),i.setAttribute("d",this.calculateTextArcParameters(t).dPath),n==="start"?(s.setAttribute("startOffset","0%"),s.setAttribute("text-anchor","start")):n==="middle"?(s.setAttribute("startOffset","50%"),s.setAttribute("text-anchor","middle")):n==="end"&&(s.setAttribute("startOffset","100%"),s.setAttribute("text-anchor","end")),o&&s.parentElement.setAttribute("textLength",i.getTotalLength()),s.parentElement.style.fontSize=`calc(${e} * (100 / (${r}) * (12 / var(--o-orbit-number)))`,s.textContent=this.textContent}getAttributes(){let t=super.getCommonAttributes(this),r,e=this.hasAttribute("flip")||this.classList.contains("flip"),n=this.hasAttribute("fit-range")||this.classList.contains("fit-range")||!1,o=parseFloat(getComputedStyle(this).getPropertyValue("--o-force"))||100,i=this.getAttribute("text-anchor")||"middle",g=getComputedStyle(this).getPropertyValue("font-size")||getComputedStyle(this).getPropertyValue("--font-size"),s=parseFloat(getComputedStyle(this).getPropertyValue("--o-range")||360),a=parseFloat(this.getAttribute("value")),h=parseFloat(getComputedStyle(this).getPropertyValue("--o-gap"))||1;if(a){r=super.getProgressAngle(s,a);let c=this.previousElementSibling,l=c?parseFloat(getComputedStyle(c).getPropertyValue("--o_stack")):0;this.style.setProperty("--o_stack",l+r),l>=0&&e&&this.style.setProperty("--o-angle-composite",parseFloat(l)+"deg"),l>0&&!e&&this.style.setProperty("--o-angle-composite",parseFloat(l)+"deg")}else{let c=getComputedStyle(this).getPropertyValue("--o-angle");r=this.calcularExpresionCSS(c)}return{...t,gap:h,arcAngle:r,flip:e,fitRange:n,length:o,fontSize:g,textAnchor:i}}calculateArcParameters(t){let{arcAngle:r,realRadius:e,arcHeightPercentage:n,orbitNumber:o,shape:i,strokeWidth:g,arcHeight:s,gap:a}=t,h=super.calculateCommonArcParameters(r,e,n,o,i,g,s,a);return{dShape:super.generatePathData(i,h,s,o)}}calculateTextArcParameters(t){let{arcAngle:r,realRadius:e,gap:n,flip:o}=t,i=n*.5,g=o?0:1,s=r<=180?0:1,a=50+e*Math.cos((-90+i)*(Math.PI/180)),h=50+e*Math.sin((-90+i)*(Math.PI/180)),c=50+e*Math.cos((r-90-i)*Math.PI/180),l=50+e*Math.sin((r-90-i)*Math.PI/180),[u,p,d,$]=o?[c,l,a,h]:[a,h,c,l];return{dPath:`M ${u},${p} A ${e},${e} 0 ${s} ${g} ${d},${$}`}}calcularExpresionCSS(t){let r=t.match(/calc\(\s*([\d.]+)deg\s*\/\s*\(\s*(\d+)\s*-\s*(\d+)\s*\)\s*\)/);if(r){let e=parseFloat(r[1]),n=parseInt(r[2])-parseInt(r[3]);if(!isNaN(e)&&!isNaN(n)&&n!==0)return e/n}return 0}};var R={resize(b){let t=document.querySelector(b);if(!t){console.error("Orbit.resize: element not found:",b);return}let r=o=>{t.querySelectorAll(".gravity-spot").forEach(i=>{i.style.setProperty("--o-force-ratio",String(o/500))})},e=t.offsetWidth||t.getBoundingClientRect().width;e>0?r(e):requestAnimationFrame(()=>{e=t.offsetWidth||t.getBoundingClientRect().width,e>0&&r(e)}),new ResizeObserver(o=>{for(let i of o)i.contentRect.width>0&&r(i.contentRect.width)}).observe(t)}};customElements.get("o-progress")||customElements.define("o-progress",m);customElements.get("o-arc")||customElements.define("o-arc",E);window.Orbit=R;})();
131
+ `;var w=class extends b{constructor(){super(),this.attachShadow({mode:"open"}),this.shadowRoot.appendChild(E.content.cloneNode(!0))}connectedCallback(){this.update(),this.setupObservers()}disconnectedCallback(){this.observer&&this.observer.disconnect(),this.textObserver&&this.textObserver.disconnect()}setupObservers(){this.observer=new MutationObserver(t=>{this.observer.disconnect(),t.forEach(()=>this.update()),this.observer.observe(this,{attributes:!0,childList:!0})}),this.observer.observe(this,{attributes:!0,childList:!0}),this.textObserver=new MutationObserver(()=>{let t=this.shadowRoot.querySelector("textPath");t.textContent=this.textContent}),this.textObserver.observe(this,{characterData:!0,subtree:!0})}update(){let t=this.getAttributes(),{length:r,fontSize:e,textAnchor:s,fitRange:n}=t,o=this.shadowRoot.querySelector("#orbitPath"),l=this.shadowRoot.querySelector("#orbitShape"),a=this.shadowRoot.querySelector("textPath");l.setAttribute("d",this.calculateArcParameters(t).dShape),o.setAttribute("d",this.calculateTextArcParameters(t).dPath),s==="start"?(a.setAttribute("startOffset","0%"),a.setAttribute("text-anchor","start")):s==="middle"?(a.setAttribute("startOffset","50%"),a.setAttribute("text-anchor","middle")):s==="end"&&(a.setAttribute("startOffset","100%"),a.setAttribute("text-anchor","end")),n&&a.parentElement.setAttribute("textLength",o.getTotalLength()),a.parentElement.style.fontSize=`calc(${e} * (100 / (${r}) * (12 / var(--o-orbit-number)))`,a.textContent=this.textContent,this.warnIfTextOverflows(o,a,n)}warnIfTextOverflows(t,r,e){let s=(this.textContent||"").trim();!s||e||!this.isConnected||requestAnimationFrame(()=>{try{let n=t.getTotalLength(),o=r.parentElement.getComputedTextLength();n>0&&o>n&&this._truncWarned!==s&&(this._truncWarned=s,console.warn(`[orbit] <o-arc> text "${s.length>34?s.slice(0,34)+"\u2026":s}" overflows its arc (${Math.round(o)} > ${Math.round(n)} units) and will clip. Shorten the text, widen --o-range, or use fit-range to squeeze it.`))}catch(n){}})}getAttributes(){let t=super.getCommonAttributes(this),r,e=this.hasAttribute("flip")||this.classList.contains("flip"),s=this.hasAttribute("fit-range")||this.classList.contains("fit-range")||!1,n=parseFloat(getComputedStyle(this).getPropertyValue("--o-force"))||100,o=this.getAttribute("text-anchor")||"middle",l=getComputedStyle(this).getPropertyValue("font-size")||getComputedStyle(this).getPropertyValue("--font-size"),a=parseFloat(getComputedStyle(this).getPropertyValue("--o-range")||360),i=parseFloat(this.getAttribute("value")),c=parseFloat(getComputedStyle(this).getPropertyValue("--o-gap"))||1;if(i){r=super.getProgressAngle(a,i);let h=this.previousElementSibling,g=h?parseFloat(getComputedStyle(h).getPropertyValue("--o_stack")):0;this.style.setProperty("--o_stack",g+r),g>=0&&e&&this.style.setProperty("--o-angle-composite",parseFloat(g)+"deg"),g>0&&!e&&this.style.setProperty("--o-angle-composite",parseFloat(g)+"deg")}else{let h=getComputedStyle(this).getPropertyValue("--o-angle");r=this.calcularExpresionCSS(h)}return{...t,gap:c,arcAngle:r,flip:e,fitRange:s,length:n,fontSize:l,textAnchor:o}}calculateArcParameters(t){let{arcAngle:r,realRadius:e,arcHeightPercentage:s,orbitNumber:n,shape:o,strokeWidth:l,arcHeight:a,gap:i}=t,c=super.calculateCommonArcParameters(r,e,s,n,o,l,a,i);return{dShape:super.generatePathData(o,c,a,n)}}calculateTextArcParameters(t){let{arcAngle:r,realRadius:e,gap:s,flip:n}=t,o=s*.5,l=n?0:1,a=r<=180?0:1,i=50+e*Math.cos((-90+o)*(Math.PI/180)),c=50+e*Math.sin((-90+o)*(Math.PI/180)),h=50+e*Math.cos((r-90-o)*Math.PI/180),g=50+e*Math.sin((r-90-o)*Math.PI/180),[u,d,$,p]=n?[h,g,i,c]:[i,c,h,g];return{dPath:`M ${u},${d} A ${e},${e} 0 ${a} ${l} ${$},${p}`}}calcularExpresionCSS(t){let r=t.match(/calc\(\s*([\d.]+)deg\s*\/\s*\(\s*(\d+)\s*-\s*(\d+)\s*\)\s*\)/);if(r){let e=parseFloat(r[1]),s=parseInt(r[2])-parseInt(r[3]);if(!isNaN(e)&&!isNaN(s)&&s!==0)return e/s}return 0}};var M={resize(x){let t=document.querySelector(x);if(!t){console.error("Orbit.resize: element not found:",x);return}let r=n=>{t.querySelectorAll(".gravity-spot").forEach(o=>{o.style.setProperty("--o-force-ratio",String(n/500))})},e=t.offsetWidth||t.getBoundingClientRect().width;e>0?r(e):requestAnimationFrame(()=>{e=t.offsetWidth||t.getBoundingClientRect().width,e>0&&r(e)}),new ResizeObserver(n=>{for(let o of n)o.contentRect.width>0&&r(o.contentRect.width)}).observe(t)}};customElements.get("o-progress")||customElements.define("o-progress",S);customElements.get("o-arc")||customElements.define("o-arc",w);window.Orbit=M;})();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zumer/orbit",
3
- "version": "1.4.10",
3
+ "version": "1.4.12",
4
4
  "description": "Orbit is a CSS framework for radial interfaces",
5
5
  "main": "./dist/orbit.js",
6
6
  "exports": {