@allxsmith/bestax-bulma 5.66.0 → 5.66.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@allxsmith/bestax-bulma",
3
- "version": "5.66.0",
3
+ "version": "5.66.2",
4
4
  "description": "Component library based on React, Bulma, with Agent Skills and MCP",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.esm.js",
@@ -1,9 +1,10 @@
1
1
  # scss/ — styles for the bestax "extras"
2
2
 
3
- **Only extras get SCSS.** Components that are stock Bulma (Box, Card, Navbar, …) ship no CSS
3
+ **Only extras get SCSS.** Components that are stock Bulma (Box, Card, Modal, …) ship no CSS
4
4
  of their own — Bulma provides it. A partial exists only for components that extend beyond Bulma
5
5
  (Carousel, Collapse, Dialog, the extended form inputs, …) — or that extend a stock component
6
- (e.g. `_tabs.scss` adds vertical Tabs). The `_index.scss` files are the authoritative inventory.
6
+ (e.g. `_tabs.scss` adds vertical Tabs, `_navbar.scss` keeps the burger's bars in forced
7
+ colors). The `_index.scss` files are the authoritative inventory.
7
8
 
8
9
  ## Structure
9
10
 
@@ -76,3 +77,25 @@ Rules the pattern encodes:
76
77
  CSS & Sass Variables section, which is how LinkButton shipped its variables invisibly
77
78
  (#464). The orphan rule in `check:conformance` now fails on a partial that no component
78
79
  claims, so the miss is loud, but the fix is still yours to make.
80
+
81
+ ## A partial that adjusts stock Bulma
82
+
83
+ Some partials change a stock component rather than add one (`elements/_button.scss`,
84
+ `components/_pagination.scss`, `components/_menu.scss`). They follow the pattern above, plus:
85
+
86
+ - **Outrank Bulma whichever stylesheet loads first.** An app may load `extras.css` before or
87
+ after Bulma, so match Bulma's selector and add one class or ancestor (`.button.button`,
88
+ `.pagination .pagination-link`), and test both load orders.
89
+ - **Check every case the selector reaches.** A loop over Bulma's `$colors` also reaches `text`,
90
+ which `LinkButton` uses by default. A rule for one state can erase another state's only cue: a
91
+ border at rest in forced colors is the same border Bulma draws for focus. List the variants,
92
+ sizes and states the rule touches, and check each.
93
+ - **Forced colors:** scope the rule to `@media (forced-colors: active)`, paint with system colors
94
+ (`CanvasText`, `ButtonText`), and put `forced-color-adjust: none` only on the smallest element
95
+ that needs it, so everything else keeps the user's palette.
96
+ - **Name the `@use`.** Docs that show the partial beside the Bulma module it adjusts load it
97
+ `as bestax-<name>`, since Sass refuses two `@use` lines with the same name.
98
+ - `ORPHAN_EXEMPT` in `scripts/check-conformance.mjs` is for a partial no component can claim. Its
99
+ reason says why that stays true, not which issue added it.
100
+ - A new partial also means updating every page that lists the partials: see "Finishing a change"
101
+ in the root `CLAUDE.md`.
@@ -29,3 +29,4 @@
29
29
  @use 'datatable';
30
30
  @use 'pagination';
31
31
  @use 'affix';
32
+ @use 'navbar';
@@ -0,0 +1,20 @@
1
+ // Bestax Extras - Navbar Styles
2
+ // Bulma draws `.navbar-burger`'s bars as `background-color: currentColor`
3
+ // on a button with no background. Forced colors (Windows' contrast themes)
4
+ // replaces background colors, and Chromium paints the bars in the page's
5
+ // Canvas color, so the burger vanishes while it still works. This keeps
6
+ // the bars in ButtonText. Outside forced colors it changes nothing.
7
+ //
8
+ // Bulma's CSS can land on either side of this partial, as it can for
9
+ // `_delete.scss`, so the selector names its class twice to outrank Bulma's
10
+ // `.navbar-burger span`, wherever the two load.
11
+
12
+ @use 'bulma/sass/utilities/initial-variables' as iv;
13
+
14
+ @media (forced-colors: active) {
15
+ .#{iv.$class-prefix}navbar-burger.#{iv.$class-prefix}navbar-burger span {
16
+ // Opt out so Chromium keeps these bars in ButtonText, not Canvas.
17
+ forced-color-adjust: none;
18
+ background-color: ButtonText;
19
+ }
20
+ }
@@ -4,15 +4,23 @@
4
4
  // replaces all three with the system's, so the current page looks like every
5
5
  // other page there. This draws it in Highlight and HighlightText, the pair the
6
6
  // system keeps for a selection, the way the themed Checkbox marks a checked
7
- // box. `forced-color-adjust: none` keeps them. Outside forced colors it
8
- // changes nothing.
7
+ // box. `forced-color-adjust: none` keeps them. Outside forced colors those
8
+ // colors change nothing.
9
9
  //
10
10
  // It reads the classes Bulma highlights, `is-current` and its other name
11
11
  // `is-selected`, so a hand-written current link gets it too, and so does
12
12
  // `DataTable`'s pager, which is a `Pagination`. Two classes outrank Bulma's
13
13
  // colors for a link, wherever the two stylesheets load.
14
+ //
15
+ // Bulma's control mixin also sets `outline: none` on `:focus-visible`, which
16
+ // outranks Bulma's own link ring, so a keyboard user sees only the hover
17
+ // shade. The rules below bring that outline back. The `.pagination` ancestor
18
+ // outranks the mixin's `outline: none` whichever stylesheet loads first.
19
+ // `:focus-visible` keeps the ring off a mouse click, and an item without
20
+ // keyboard focus looks as it does now.
14
21
 
15
22
  @use 'bulma/sass/utilities/initial-variables' as iv;
23
+ @use 'bulma/sass/utilities/css-variables' as cv;
16
24
 
17
25
  @media (forced-colors: active) {
18
26
  .#{iv.$class-prefix}pagination-link.#{iv.$class-prefix}is-current,
@@ -23,3 +31,24 @@
23
31
  color: HighlightText;
24
32
  }
25
33
  }
34
+
35
+ .#{iv.$class-prefix}pagination .#{iv.$class-prefix}pagination-previous:focus-visible,
36
+ .#{iv.$class-prefix}pagination .#{iv.$class-prefix}pagination-next:focus-visible,
37
+ .#{iv.$class-prefix}pagination .#{iv.$class-prefix}pagination-link:focus-visible {
38
+ outline-color: hsl(
39
+ cv.getVar('focus-h'),
40
+ cv.getVar('focus-s'),
41
+ cv.getVar('focus-l')
42
+ );
43
+ outline-style: cv.getVar('focus-style');
44
+ outline-width: cv.getVar('focus-width');
45
+ outline-offset: cv.getVar('focus-offset');
46
+ }
47
+
48
+ // The current page is filled with the link color, which the focus color
49
+ // matches by default, so its ring takes the page's text color, inside the fill.
50
+ .#{iv.$class-prefix}pagination .#{iv.$class-prefix}pagination-link.#{iv.$class-prefix}is-current:focus-visible,
51
+ .#{iv.$class-prefix}pagination .#{iv.$class-prefix}pagination-link.#{iv.$class-prefix}is-selected:focus-visible {
52
+ outline-color: currentColor;
53
+ outline-offset: calc(-2 * #{cv.getVar('focus-width')});
54
+ }
@@ -323,3 +323,22 @@ $tooltip-large-arrow-size: 7px !default;
323
323
  )
324
324
  );
325
325
  }
326
+
327
+ // Forced colors turns the box's background into the page's and paints every
328
+ // side of the arrow. An outline, not a border, so the tooltip doesn't grow.
329
+ // Only the arrow opts out, so its transparent sides stay transparent and the
330
+ // side that points takes the system's text color.
331
+ @media (forced-colors: active) {
332
+ .#{iv.$class-prefix}tooltip-content {
333
+ outline: 1px solid CanvasText;
334
+ }
335
+
336
+ .#{iv.$class-prefix}tooltip-content::before {
337
+ forced-color-adjust: none;
338
+ @include cv.register-vars(
339
+ (
340
+ "tooltip-background": CanvasText,
341
+ )
342
+ );
343
+ }
344
+ }
@@ -17,13 +17,29 @@
17
17
  // The ghost rule doesn't ask for LinkButton's class, since a ghost Button has
18
18
  // none.
19
19
  //
20
+ // Forced colors also replaces a colored button's fill, and Bulma sets its
21
+ // border width to 0, so in Chromium the button has no edge and an icon-only
22
+ // one shows only its glyph. The last rule gives those buttons back a 1px
23
+ // border there. An outlined button keeps the width it sets, and Bulma
24
+ // subtracts the width from the padding, so the size stays the same. Bulma
25
+ // gives a colored button that same border only while it's focused, so with
26
+ // one at rest the outline above is what shows focus.
27
+ //
28
+ // Bulma's colors include `text`, but `.button.is-text` is a text button, as
29
+ // `Button color="text"` and LinkButton's text and underline variants render
30
+ // it. It has no fill to lose, and a border at rest would draw a box around a
31
+ // link, so the loop leaves it out.
32
+ //
20
33
  // Bulma's CSS can land on either side of this partial, as `_loader.scss`
21
- // says, so each selector outranks the mixin's rules by its classes: the
22
- // ghost rule has three to Bulma's two, and the forced colors rule names
23
- // `.button` twice, as `_delete.scss` does.
34
+ // says, so each selector outranks Bulma's rule by its classes: the ghost rule
35
+ // has three to the mixin's two, the forced colors outline names `.button`
36
+ // twice, as `_delete.scss` does, and the border names the color class twice
37
+ // to outrank Bulma's `.button.is-<color>`.
24
38
 
39
+ @use 'sass:map';
25
40
  @use 'bulma/sass/utilities/initial-variables' as iv;
26
41
  @use 'bulma/sass/utilities/css-variables' as cv;
42
+ @use 'bulma/sass/utilities/derived-variables' as dv;
27
43
 
28
44
  @mixin -focus-outline {
29
45
  outline-color: hsl(
@@ -46,4 +62,12 @@
46
62
  .#{iv.$class-prefix}button.#{iv.$class-prefix}button:not(.#{iv.$class-prefix}is-loading).#{iv.$class-prefix}is-focused {
47
63
  @include -focus-outline;
48
64
  }
65
+
66
+ @each $name in map.keys(map.remove(dv.$colors, 'text')) {
67
+ .#{iv.$class-prefix}button.#{iv.$class-prefix}is-#{$name}.#{iv.$class-prefix}is-#{$name}:not(
68
+ .#{iv.$class-prefix}is-outlined
69
+ ) {
70
+ @include cv.register-var('button-border-width', 1px);
71
+ }
72
+ }
49
73
  }