@signal9/era-ui 2.18.0 → 2.18.1

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.
@@ -43,7 +43,17 @@ export interface Gaps {
43
43
  readonly bottom: number;
44
44
  readonly left: number;
45
45
  }
46
- /** Rect + resolved radius, relative to the viewport. */
46
+ /**
47
+ * Rect + the radius the browser ACTUALLY PAINTS, relative to the viewport.
48
+ *
49
+ * getComputedStyle returns the SPECIFIED radius, but CSS clamps a radius to half
50
+ * the box — a 7px dot asking for an 8px radius renders as a 3.5px circle, not an
51
+ * 8px one. Reading the specified value therefore lies about round things, and it
52
+ * lied here: the radio group's dot (h=7, specified 8.06) inside its button (h=14,
53
+ * specified 8.06) looked like "radius step 0 against a 3.5px gap" — a violation —
54
+ * when both are in fact perfect circles, which are trivially concentric. Clamping
55
+ * gives step 3.5 == implied 3.5 == gap 3.5, and the finding correctly disappears.
56
+ */
47
57
  export declare function getRect(el: Element): Box;
48
58
  /** Rect relative to an offset root, so overlays can draw in the root's space. */
49
59
  export declare function getRelativeRect(el: Element, root: Element): Box;
@@ -72,15 +72,26 @@ export function cssPath(el, root) {
72
72
  }
73
73
  return parts.join(' > ');
74
74
  }
75
- /** Rect + resolved radius, relative to the viewport. */
75
+ /**
76
+ * Rect + the radius the browser ACTUALLY PAINTS, relative to the viewport.
77
+ *
78
+ * getComputedStyle returns the SPECIFIED radius, but CSS clamps a radius to half
79
+ * the box — a 7px dot asking for an 8px radius renders as a 3.5px circle, not an
80
+ * 8px one. Reading the specified value therefore lies about round things, and it
81
+ * lied here: the radio group's dot (h=7, specified 8.06) inside its button (h=14,
82
+ * specified 8.06) looked like "radius step 0 against a 3.5px gap" — a violation —
83
+ * when both are in fact perfect circles, which are trivially concentric. Clamping
84
+ * gives step 3.5 == implied 3.5 == gap 3.5, and the finding correctly disappears.
85
+ */
76
86
  export function getRect(el) {
77
87
  const r = el.getBoundingClientRect();
88
+ const specified = parseFloat(getComputedStyle(el).borderTopLeftRadius) || 0;
78
89
  return {
79
90
  x: r.x,
80
91
  y: r.y,
81
92
  width: r.width,
82
93
  height: r.height,
83
- radius: parseFloat(getComputedStyle(el).borderTopLeftRadius) || 0
94
+ radius: Math.min(specified, r.width / 2, r.height / 2)
84
95
  };
85
96
  }
86
97
  /** Rect relative to an offset root, so overlays can draw in the root's space. */
@@ -115,14 +126,31 @@ export function isEven(g, tol = TOL) {
115
126
  const { top, right, bottom, left } = g;
116
127
  return (Math.abs(top - bottom) <= tol && Math.abs(left - right) <= tol && Math.abs(top - left) <= tol);
117
128
  }
129
+ /**
130
+ * The corner radius a box paints given its HEIGHT — the radius the tier system
131
+ * is actually talking about.
132
+ *
133
+ * Box.radius clamps by width as well, because that is what the browser paints.
134
+ * But the concentricity law is a statement about VERTICAL nesting (a tier inside
135
+ * a tier), and width-clamping is driven by CONTENT, not by design: the ":"
136
+ * literal in a time field is a ~6px-wide span, so its rd-sm corners get pinched
137
+ * to ~3px by its own narrowness. Measured with the painted radius it reported
138
+ * "step 4.1 ≠ gap 1.0" — a violation of nothing, since its siblings on the same
139
+ * tier paint the correct 7px and the literal has no fill to show a corner with.
140
+ * Clamping by height only asks the question the law actually poses.
141
+ */
142
+ function tierRadius(el) {
143
+ const specified = parseFloat(getComputedStyle(el).borderTopLeftRadius) || 0;
144
+ return Math.min(specified, el.getBoundingClientRect().height / 2);
145
+ }
118
146
  /**
119
147
  * The concentricity law. Nested corners share a centre of curvature only when
120
148
  * the radius step equals the gap — checking any two of the three terms passes
121
149
  * boxes that are visibly wrong, so assert all three at once.
122
150
  */
123
151
  export function getConcentricity(child, container, tol = TOL) {
124
- const inner = getRect(child);
125
- const outer = getRect(container);
152
+ const inner = { ...getRect(child), radius: tierRadius(child) };
153
+ const outer = { ...getRect(container), radius: tierRadius(container) };
126
154
  const gaps = getGaps(child, container);
127
155
  const radiusDelta = outer.radius - inner.radius;
128
156
  const impliedGap = (outer.height - inner.height) / 2;
@@ -8,7 +8,7 @@
8
8
  <DateField.Segment
9
9
  bind:ref
10
10
  class={cn(
11
- 'rounded-(--era-rd-md) px-[calc(var(--era-sp)/2)] focus:bg-(--era-highlight) focus:text-bright focus:outline-none aria-[valuetext=Empty]:text-muted data-[segment=literal]:text-muted',
11
+ 'inline-flex h-(--era-h-sm) items-center rounded-(--era-rd-sm) px-[calc(var(--era-sp)/2)] focus:bg-(--era-highlight) focus:text-bright focus:outline-none aria-[valuetext=Empty]:text-muted data-[segment=literal]:text-muted',
12
12
  className
13
13
  )}
14
14
  {...restProps}
@@ -8,7 +8,7 @@
8
8
  <DatePicker.Segment
9
9
  bind:ref
10
10
  class={cn(
11
- 'rounded-(--era-rd-md) px-[calc(var(--era-sp)/2)] focus:bg-(--era-highlight) focus:text-bright focus:outline-none aria-[valuetext=Empty]:text-muted data-[segment=literal]:text-muted',
11
+ 'inline-flex h-(--era-h-sm) items-center rounded-(--era-rd-sm) px-[calc(var(--era-sp)/2)] focus:bg-(--era-highlight) focus:text-bright focus:outline-none aria-[valuetext=Empty]:text-muted data-[segment=literal]:text-muted',
12
12
  className
13
13
  )}
14
14
  {...restProps}
@@ -12,7 +12,7 @@
12
12
  <DateRangeField.Segment
13
13
  bind:ref
14
14
  class={cn(
15
- 'rounded-(--era-rd-md) px-[calc(var(--era-sp)/2)] focus:bg-(--era-highlight) focus:text-bright focus:outline-none aria-[valuetext=Empty]:text-muted data-[segment=literal]:text-muted',
15
+ 'inline-flex h-(--era-h-sm) items-center rounded-(--era-rd-sm) px-[calc(var(--era-sp)/2)] focus:bg-(--era-highlight) focus:text-bright focus:outline-none aria-[valuetext=Empty]:text-muted data-[segment=literal]:text-muted',
16
16
  className
17
17
  )}
18
18
  {...restProps}
@@ -12,7 +12,7 @@
12
12
  <DateRangePicker.Segment
13
13
  bind:ref
14
14
  class={cn(
15
- 'rounded-(--era-rd-md) px-[calc(var(--era-sp)/2)] focus:bg-(--era-highlight) focus:text-bright focus:outline-none aria-[valuetext=Empty]:text-muted data-[segment=literal]:text-muted',
15
+ 'inline-flex h-(--era-h-sm) items-center rounded-(--era-rd-sm) px-[calc(var(--era-sp)/2)] focus:bg-(--era-highlight) focus:text-bright focus:outline-none aria-[valuetext=Empty]:text-muted data-[segment=literal]:text-muted',
16
16
  className
17
17
  )}
18
18
  {...restProps}
@@ -8,7 +8,7 @@
8
8
  <TimeField.Segment
9
9
  bind:ref
10
10
  class={cn(
11
- 'rounded-(--era-rd-md) px-[calc(var(--era-sp)/2)] focus:bg-(--era-highlight) focus:text-bright focus:outline-none aria-[valuetext=Empty]:text-muted data-[segment=literal]:text-muted',
11
+ 'inline-flex h-(--era-h-sm) items-center rounded-(--era-rd-sm) px-[calc(var(--era-sp)/2)] focus:bg-(--era-highlight) focus:text-bright focus:outline-none aria-[valuetext=Empty]:text-muted data-[segment=literal]:text-muted',
12
12
  className
13
13
  )}
14
14
  {...restProps}
@@ -12,7 +12,7 @@
12
12
  <TimeRangeField.Segment
13
13
  bind:ref
14
14
  class={cn(
15
- 'rounded-(--era-rd-md) px-[calc(var(--era-sp)/2)] focus:bg-(--era-highlight) focus:text-bright focus:outline-none aria-[valuetext=Empty]:text-muted data-[segment=literal]:text-muted',
15
+ 'inline-flex h-(--era-h-sm) items-center rounded-(--era-rd-sm) px-[calc(var(--era-sp)/2)] focus:bg-(--era-highlight) focus:text-bright focus:outline-none aria-[valuetext=Empty]:text-muted data-[segment=literal]:text-muted',
16
16
  className
17
17
  )}
18
18
  {...restProps}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@signal9/era-ui",
3
- "version": "2.18.0",
3
+ "version": "2.18.1",
4
4
  "scripts": {
5
5
  "dev": "vite dev --host",
6
6
  "build": "vite build && npm run prepack",