@rebasepro/ui 0.19.2-canary.gef769df → 0.20.0

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.
@@ -166,7 +166,38 @@ html.dark {
166
166
  @apply text-3xl font-headers font-semibold tracking-display tabular-nums;
167
167
  }
168
168
 
169
- :focus-visible {
170
- @apply outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-0 focus-visible:ring-offset-transparent
169
+ /* The focus ring is drawn INSIDE the focused element, not around it.
170
+
171
+ An outset ring is a box-shadow painted beyond the border box, so any ancestor
172
+ that clips cuts it — a scroller, a truncating cell, a max-height collapse.
173
+ That is not a corner case: the drawer's navigation groups clip for their
174
+ collapse animation, and every row in them rendered a ring with three of its
175
+ four sides missing. Tabbing through the panel produced stray blue slivers
176
+ rather than an indicator. An inset ring is painted within the element's own
177
+ box, which is inside any clip rect the element is itself inside, so nothing
178
+ can cut it. Same 2px, same colour, same radius — 2px in rather than 2px out.
179
+
180
+ Written as an override of `--tw-ring-shadow` rather than as `inset-ring-2`
181
+ because that keeps one vocabulary for turning the ring off. Eleven call sites
182
+ already say `ring-0` / `focusedDisabled` to suppress it, and `inset-ring-*`
183
+ is a different variable that none of them would have silenced — every popover
184
+ and bare table input that had opted out would have got a ring back.
185
+ Not `outline` either: 65 call sites carry `outline-none` from the utilities
186
+ layer, which outranks anything a base-layer rule sets, and those controls
187
+ would have been left with no focus indicator at all.
188
+
189
+ A component that wants the ring OUTSIDE (Checkbox, Slider, Avatar — small
190
+ controls with room around them, where an inset ring would sit on the mark
191
+ itself) still says `focus-visible:ring-2` for itself; a utility outranks
192
+ this.
193
+
194
+ The pseudo-class is doubled on purpose — it is not a typo to tidy up. The
195
+ admin imports this sheet into `layer(base)`, where a utility wins whatever
196
+ the specificity, but the docs site imports it unlayered, and there the rule
197
+ competes with `.something:focus` on specificity alone. (0,2,0) is what the
198
+ rule had before this was written, and dropping to (0,1,0) would quietly hand
199
+ those ties to the other rule. */
200
+ :focus-visible:focus-visible {
201
+ @apply outline-none ring-2 ring-primary ring-offset-0 ring-offset-transparent;
202
+ --tw-ring-shadow: inset 0 0 0 2px var(--tw-ring-color, currentcolor);
171
203
  }
172
-
package/dist/styles.d.ts CHANGED
@@ -26,11 +26,29 @@ export declare const controlPaddingMixin: {
26
26
  readonly xl: "px-6";
27
27
  readonly "2xl": "px-10";
28
28
  };
29
+ /**
30
+ * Suppress the focus ring on a surface that is focusable but is not a control —
31
+ * a popover panel, a menu container, a bare cell input inside a table that
32
+ * indicates focus by other means.
33
+ *
34
+ * Still expressed as `ring-0`, and that is why the default ring in
35
+ * `index.css` overrides `--tw-ring-shadow` rather than switching to
36
+ * `inset-ring-*`: `inset-ring` is a different variable, which this would not
37
+ * have silenced, and every surface that had opted out would have got a ring
38
+ * back.
39
+ */
29
40
  export declare const focusedDisabled = "focus-visible:ring-0 focus-visible:ring-offset-0";
30
41
  export declare const focusedInvisibleMixin = "focus:bg-surface-field-hover";
31
42
  /**
32
- * The focus ring the single most-seen interaction state in the product, and
33
- * until now the least tended.
43
+ * The focus ring, drawn OUTSIDE the element, for a control that opts into it.
44
+ *
45
+ * The product's default ring is the `:focus-visible` rule in `index.css`, and
46
+ * that one is drawn *inside* the border box: an outset ring is paint beyond the
47
+ * box, and any ancestor that clips — a scroller, a truncating cell, a
48
+ * max-height collapse — cuts it. This one is still outset because its only
49
+ * caller is a whole field row sitting inside `p-4`/`p-6` of card padding, where
50
+ * there is room around it and nothing clipping within 16px. Reach for it only
51
+ * where that is true; anywhere else, let the default apply.
34
52
  *
35
53
  * Three dead declarations were removed rather than reshuffled:
36
54
  * `outline-hidden` + `outline-none` — the same instruction twice.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rebasepro/ui",
3
- "version": "0.19.2-canary.gef769df",
3
+ "version": "0.20.0",
4
4
  "description": "Rebase design system — React components and design tokens built on Radix UI, Tailwind CSS and lucide-react",
5
5
  "keywords": [
6
6
  "rebase",
@@ -31,10 +31,9 @@
31
31
  "main": "./dist/index.es.js",
32
32
  "module": "./dist/index.es.js",
33
33
  "types": "./dist/index.d.ts",
34
- "//sideEffects": "The stylesheet is the side effect. `index.css` and the CSS the build emits are imported for what they do, not for what they export, so a bundler told this package is side-effect-free would drop them and ship an unstyled admin panel.",
34
+ "//sideEffects": "The stylesheet is the side effect. The CSS this package emits is imported for what it does, not for what it exports, so a bundler told this package is side-effect-free would drop it and ship an unstyled admin panel. One glob is enough: bundlers match this list against the RESOLVED file path, and `@rebasepro/ui/index.css` resolves through `exports` to `dist/index.css`, which `**/*.css` already claims. A second `./index.css` entry used to sit beside it, naming a package-root file that no tarball has ever contained.",
35
35
  "sideEffects": [
36
- "**/*.css",
37
- "./index.css"
36
+ "**/*.css"
38
37
  ],
39
38
  "engines": {
40
39
  "node": ">=22.22.0"
@@ -112,8 +111,7 @@
112
111
  "vite-plugin-static-copy": "^4.1.1"
113
112
  },
114
113
  "files": [
115
- "dist",
116
- "index.css"
114
+ "dist"
117
115
  ],
118
116
  "gitHead": "d935eefa5aa8d1009a2398cfac2c1e4ee9aeb6b6",
119
117
  "publishConfig": {