@allxsmith/bestax-bulma 5.65.1 → 5.66.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.
Files changed (106) hide show
  1. package/dist/bestax.css +1 -1
  2. package/dist/bestax.css.map +1 -1
  3. package/dist/esm/components/Card.js +6 -6
  4. package/dist/esm/components/Card.js.map +1 -1
  5. package/dist/esm/components/Carousel.js +19 -7
  6. package/dist/esm/components/Carousel.js.map +1 -1
  7. package/dist/esm/components/Message.js +1 -1
  8. package/dist/esm/components/Message.js.map +1 -1
  9. package/dist/esm/components/Modal.js +1 -1
  10. package/dist/esm/components/Modal.js.map +1 -1
  11. package/dist/esm/components/Popover.js +4 -1
  12. package/dist/esm/components/Popover.js.map +1 -1
  13. package/dist/esm/components/SegmentedControl.js +4 -4
  14. package/dist/esm/components/SegmentedControl.js.map +1 -1
  15. package/dist/esm/components/Sidebar.js +1 -1
  16. package/dist/esm/components/Sidebar.js.map +1 -1
  17. package/dist/esm/elements/Figure.js +1 -1
  18. package/dist/esm/elements/Figure.js.map +1 -1
  19. package/dist/esm/form/ColorInputBase.js +1 -1
  20. package/dist/esm/form/ColorInputBase.js.map +1 -1
  21. package/dist/esm/form/DateInput.js +4 -1
  22. package/dist/esm/form/DateInput.js.map +1 -1
  23. package/dist/esm/form/DateInputBase.js +1 -1
  24. package/dist/esm/form/DateInputBase.js.map +1 -1
  25. package/dist/esm/form/DateRangeInput.js +4 -1
  26. package/dist/esm/form/DateRangeInput.js.map +1 -1
  27. package/dist/esm/form/DateRangeInputBase.js +1 -1
  28. package/dist/esm/form/DateRangeInputBase.js.map +1 -1
  29. package/dist/esm/form/DateTimeInput.js +4 -1
  30. package/dist/esm/form/DateTimeInput.js.map +1 -1
  31. package/dist/esm/form/DateTimeInputBase.js +1 -1
  32. package/dist/esm/form/DateTimeInputBase.js.map +1 -1
  33. package/dist/esm/form/Slider.js +19 -9
  34. package/dist/esm/form/Slider.js.map +1 -1
  35. package/dist/esm/form/TimeInput.js +4 -1
  36. package/dist/esm/form/TimeInput.js.map +1 -1
  37. package/dist/esm/form/TimeInputBase.js +1 -1
  38. package/dist/esm/form/TimeInputBase.js.map +1 -1
  39. package/dist/esm/form/TreeSelect.js.map +1 -1
  40. package/dist/esm/form/_pickerInternals/PickerPopover.js +4 -1
  41. package/dist/esm/form/_pickerInternals/PickerPopover.js.map +1 -1
  42. package/dist/esm/form/_pickerInternals/TimeWheels.js +1 -1
  43. package/dist/esm/form/_pickerInternals/TimeWheels.js.map +1 -1
  44. package/dist/esm/form/_pickerInternals/useLocaleDefaults.js +15 -1
  45. package/dist/esm/form/_pickerInternals/useLocaleDefaults.js.map +1 -1
  46. package/dist/esm/form/_selectInternals/DialogSelect.js +1 -1
  47. package/dist/esm/form/_selectInternals/DialogSelect.js.map +1 -1
  48. package/dist/esm/helpers/useAnchoredPosition.js +11 -3
  49. package/dist/esm/helpers/useAnchoredPosition.js.map +1 -1
  50. package/dist/extras.css +1 -1
  51. package/dist/extras.css.map +1 -1
  52. package/dist/index.cjs +122 -40
  53. package/dist/index.cjs.map +1 -1
  54. package/dist/index.esm.js +6 -6
  55. package/dist/types/components/Card.d.ts +52 -0
  56. package/dist/types/components/Carousel.d.ts +12 -3
  57. package/dist/types/components/Message.d.ts +16 -0
  58. package/dist/types/components/Modal.d.ts +71 -0
  59. package/dist/types/components/Popover.d.ts +5 -1
  60. package/dist/types/components/SegmentedControl.d.ts +9 -0
  61. package/dist/types/components/Sidebar.d.ts +45 -5
  62. package/dist/types/elements/Figure.d.ts +11 -0
  63. package/dist/types/form/ColorInputBase.d.ts +7 -1
  64. package/dist/types/form/DateInputBase.d.ts +7 -1
  65. package/dist/types/form/DateRangeInputBase.d.ts +7 -1
  66. package/dist/types/form/DateTimeInputBase.d.ts +7 -1
  67. package/dist/types/form/TimeInputBase.d.ts +7 -1
  68. package/dist/types/form/TreeSelect.d.ts +4 -1
  69. package/dist/types/form/_pickerInternals/PickerPopover.d.ts +5 -0
  70. package/dist/types/form/_pickerInternals/useLocaleDefaults.d.ts +12 -0
  71. package/dist/types/form/_selectInternals/DialogSelect.d.ts +1 -0
  72. package/dist/types/helpers/useAnchoredPosition.d.ts +9 -2
  73. package/dist/types-cjs/components/Card.d.ts +52 -0
  74. package/dist/types-cjs/components/Carousel.d.ts +12 -3
  75. package/dist/types-cjs/components/Message.d.ts +16 -0
  76. package/dist/types-cjs/components/Modal.d.ts +71 -0
  77. package/dist/types-cjs/components/Popover.d.ts +5 -1
  78. package/dist/types-cjs/components/SegmentedControl.d.ts +9 -0
  79. package/dist/types-cjs/components/Sidebar.d.ts +45 -5
  80. package/dist/types-cjs/elements/Figure.d.ts +11 -0
  81. package/dist/types-cjs/form/ColorInputBase.d.ts +7 -1
  82. package/dist/types-cjs/form/DateInputBase.d.ts +7 -1
  83. package/dist/types-cjs/form/DateRangeInputBase.d.ts +7 -1
  84. package/dist/types-cjs/form/DateTimeInputBase.d.ts +7 -1
  85. package/dist/types-cjs/form/TimeInputBase.d.ts +7 -1
  86. package/dist/types-cjs/form/TreeSelect.d.ts +4 -1
  87. package/dist/types-cjs/form/_pickerInternals/PickerPopover.d.ts +5 -0
  88. package/dist/types-cjs/form/_pickerInternals/useLocaleDefaults.d.ts +12 -0
  89. package/dist/types-cjs/form/_selectInternals/DialogSelect.d.ts +1 -0
  90. package/dist/types-cjs/helpers/useAnchoredPosition.d.ts +9 -2
  91. package/dist/versions/bestax-no-dark-mode.css +1 -1
  92. package/dist/versions/bestax-no-dark-mode.css.map +1 -1
  93. package/dist/versions/bestax-no-helpers-prefixed.css +1 -1
  94. package/dist/versions/bestax-no-helpers-prefixed.css.map +1 -1
  95. package/dist/versions/bestax-no-helpers.css +1 -1
  96. package/dist/versions/bestax-no-helpers.css.map +1 -1
  97. package/dist/versions/bestax-prefixed.css +1 -1
  98. package/dist/versions/bestax-prefixed.css.map +1 -1
  99. package/package.json +1 -1
  100. package/src/scss/_input-trigger.scss +24 -5
  101. package/src/scss/components/_carousel.scss +22 -4
  102. package/src/scss/components/_popover.scss +11 -0
  103. package/src/scss/form/_dateinput.scss +6 -0
  104. package/src/scss/form/_passwordinput.scss +6 -5
  105. package/src/scss/form/_picker-popover.scss +45 -5
  106. package/src/scss/form/_slider.scss +39 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@allxsmith/bestax-bulma",
3
- "version": "5.65.1",
3
+ "version": "5.66.0",
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",
@@ -8,7 +8,7 @@
8
8
  @use 'bulma/sass/utilities/css-variables' as cv;
9
9
  @use 'mixins' as *;
10
10
 
11
- // A button over the input's right edge, in Bulma's 2.5em icon slot. Bulma's
11
+ // A button over one edge of the input, in Bulma's 2.5em icon slot. Bulma's
12
12
  // Control icons are decorative (`pointer-events: none`), so a button there
13
13
  // needs rules of its own. Include it on the element that holds the input and
14
14
  // the button, which it positions. A content block, when given, lands in that
@@ -22,25 +22,44 @@
22
22
  // every value a theme can change is a registered variable. The color change
23
23
  // on hover takes Bulma's duration and easing through `extras-transition`. The
24
24
  // button takes the input's `is-small`, `is-medium` or `is-large` font size,
25
- // so its em-based width tracks the input's.
25
+ // so its em-based width tracks the input's. `$logical` puts the slot on the
26
+ // inline end (the pickers). Left out, it stays on the physical right
27
+ // (PasswordInput).
26
28
  @mixin extras-input-trigger(
27
29
  $trigger,
28
30
  $width,
29
31
  $color,
30
32
  $hover-color,
31
- $disabled-opacity
33
+ $disabled-opacity,
34
+ $logical: false
32
35
  ) {
33
36
  position: relative;
34
37
  @content;
35
38
 
36
39
  > .#{iv.$class-prefix}input {
37
- padding-right: $width;
40
+ @if $logical {
41
+ padding-inline-end: $width;
42
+ } @else {
43
+ padding-right: $width;
44
+ }
45
+ }
46
+
47
+ // Bulma's `.input.is-rounded` sets its own side padding at two classes,
48
+ // which ties the rule above. At three this wins whichever sheet loads first.
49
+ @if $logical {
50
+ > .#{iv.$class-prefix}input.#{iv.$class-prefix}is-rounded {
51
+ padding-inline-end: $width;
52
+ }
38
53
  }
39
54
 
40
55
  > .#{iv.$class-prefix}#{$trigger} {
41
56
  position: absolute;
42
57
  top: 0;
43
- right: 0;
58
+ @if $logical {
59
+ inset-inline-end: 0;
60
+ } @else {
61
+ right: 0;
62
+ }
44
63
  z-index: 4;
45
64
  height: 100%;
46
65
  width: $width;
@@ -220,6 +220,16 @@ $carousel-indicator-line-radius: cv.getVar("radius-small") !default;
220
220
  gap: cv.getVar("carousel-item-gap");
221
221
  width: 100%;
222
222
  will-change: transform;
223
+ // The flex row reverses right to left, so the inline transform's
224
+ // negative shift would park every slide off the inline start. The
225
+ // transform multiplies by this: -1 left to right, +1 right to left. Set
226
+ // on every track, since a custom property inherits and a left-to-right
227
+ // carousel inside a right-to-left one would otherwise take its `1`.
228
+ --carousel-shift-sign: -1;
229
+
230
+ &:dir(rtl) {
231
+ --carousel-shift-sign: 1;
232
+ }
223
233
  }
224
234
 
225
235
  // Individual slide: an equal share of the track, less the gaps between
@@ -327,11 +337,19 @@ $carousel-indicator-line-radius: cv.getVar("radius-small") !default;
327
337
  }
328
338
 
329
339
  &.#{iv.$class-prefix}is-prev {
330
- left: cv.getVar("carousel-arrow-offset");
340
+ inset-inline-start: cv.getVar("carousel-arrow-offset");
331
341
  }
332
342
 
333
343
  &.#{iv.$class-prefix}is-next {
334
- right: cv.getVar("carousel-arrow-offset");
344
+ inset-inline-end: cv.getVar("carousel-arrow-offset");
345
+ }
346
+
347
+ // Previous sits on the inline start, so its chevron points that way.
348
+ // Only the built-in chevron, the button's own svg: an `iconPrev` or
349
+ // `iconNext` is the caller's to point, and an svg inside its `.icon`, as
350
+ // Font Awesome's SVG mode renders, would flip twice under a broader rule.
351
+ > svg:dir(rtl) {
352
+ transform: scaleX(-1);
335
353
  }
336
354
 
337
355
  // Transparent variant (no background)
@@ -626,11 +644,11 @@ $carousel-indicator-line-radius: cv.getVar("radius-small") !default;
626
644
  }
627
645
 
628
646
  &.#{iv.$class-prefix}is-prev {
629
- left: cv.getVar("carousel-arrow-offset-mobile");
647
+ inset-inline-start: cv.getVar("carousel-arrow-offset-mobile");
630
648
  }
631
649
 
632
650
  &.#{iv.$class-prefix}is-next {
633
- right: cv.getVar("carousel-arrow-offset-mobile");
651
+ inset-inline-end: cv.getVar("carousel-arrow-offset-mobile");
634
652
  }
635
653
  }
636
654
 
@@ -91,6 +91,17 @@ $popover-animation-duration: 0.15s !default;
91
91
  &.#{iv.$class-prefix}is-top-right {
92
92
  right: 0;
93
93
  }
94
+ // With no `position`, the panel lines up with the trigger's inline start,
95
+ // so a trigger at the start of a right-to-left line doesn't push it off the
96
+ // screen. A corner the caller names stays physical. Portaled, the
97
+ // component sets the edge inline instead. `:where()` keeps this at the
98
+ // corner rules' weight, so a theme's own placement still wins.
99
+ &.#{iv.$class-prefix}is-start-aligned:where(
100
+ :not(.#{iv.$class-prefix}is-portal):dir(rtl)
101
+ ) {
102
+ left: auto;
103
+ right: 0;
104
+ }
94
105
 
95
106
  // Portaled: fixed to the viewport at the trigger's edge, which the
96
107
  // component sets inline, so only the gap comes from here.
@@ -154,6 +154,12 @@ $dateinput-cell-range-preview-bg: color-mix(
154
154
  opacity: 0.4;
155
155
  cursor: not-allowed;
156
156
  }
157
+
158
+ // The row reverses right to left, so the glyph has to as well: previous
159
+ // month points at the inline start.
160
+ svg:dir(rtl) {
161
+ transform: scaleX(-1);
162
+ }
157
163
  }
158
164
 
159
165
  // The day names and each week of the grid lay out in seven columns. The
@@ -4,10 +4,10 @@
4
4
  // input's right edge, with the date pickers' launcher rule, which the two
5
5
  // share through the `extras-input-trigger` mixin.
6
6
  //
7
- // The toggle sits on the physical right, as the pickers' launcher and Bulma's
8
- // right icon do, so in a right-to-left page it's at the start of the field
9
- // rather than its end. Moving them to the inline end is one change, for all
10
- // of them together.
7
+ // The toggle sits on the physical right, as Bulma's right icon does, so in a
8
+ // right-to-left page it's at the start of the field rather than its end. The
9
+ // date pickers' launcher used to share that side and now sits on the inline
10
+ // end; this one stays physical.
11
11
 
12
12
  @use 'bulma/sass/utilities/initial-variables' as iv;
13
13
  @use 'bulma/sass/utilities/css-variables' as cv;
@@ -30,7 +30,8 @@ $password-input-toggle-disabled-opacity: 0.5 !default;
30
30
  'password-input-toggle-text-width': #{$password-input-toggle-text-width},
31
31
  'password-input-toggle-color': #{$password-input-toggle-color},
32
32
  'password-input-toggle-hover-color': #{$password-input-toggle-hover-color},
33
- 'password-input-toggle-disabled-opacity': #{$password-input-toggle-disabled-opacity},
33
+ 'password-input-toggle-disabled-opacity':
34
+ #{$password-input-toggle-disabled-opacity},
34
35
  )
35
36
  );
36
37
  }
@@ -64,6 +64,18 @@ $picker-trigger-disabled-opacity: 0.5 !default;
64
64
  right: 0;
65
65
  margin-bottom: cv.getVar('picker-popover-offset');
66
66
  }
67
+ // With no `position`, the panel lines up with the field's inline start, so
68
+ // a field at the start of a right-to-left line doesn't push it off the
69
+ // screen. A corner the caller names stays physical. Portaled, the picker
70
+ // sets the edge inline instead. `:where()` keeps this at the corner rules'
71
+ // weight, so a rule that moves the panel elsewhere, as TimeInput's
72
+ // narrow-screen sheet does, still wins.
73
+ &.#{iv.$class-prefix}is-start-aligned:where(
74
+ :not(.#{iv.$class-prefix}is-portal):dir(rtl)
75
+ ) {
76
+ left: auto;
77
+ right: 0;
78
+ }
67
79
  // At least as wide as the anchor it's placed against, as a list under a
68
80
  // field is. Portaled, the anchor's width comes inline instead, since 100%
69
81
  // there would be the viewport's.
@@ -134,12 +146,14 @@ $picker-containers: (
134
146
  }
135
147
  }
136
148
 
137
- // Right-side launcher button. The picker bases render this real <button>
138
- // inside their *-container (Bulma's Control icons are decorative —
149
+ // Launcher button on the inline end. The picker bases render this real
150
+ // <button> inside their *-container (Bulma's Control icons are decorative —
139
151
  // `pointer-events: none` — so they can't open the popover). It toggles the
140
152
  // popover and is keyboard-focusable. Its rules are the `extras-input-trigger`
141
- // mixin's, which PasswordInput's toggle shares: Bulma's 2.5em icon slot,
142
- // tracking the input's size modifier through the sibling selector.
153
+ // mixin's, which PasswordInput's toggle shares except the side: the toggle
154
+ // stays on the physical right, and this slot follows the writing direction.
155
+ // Bulma's 2.5em width tracks the input's size modifier through the sibling
156
+ // selector. Left to right the end is the right, as before.
143
157
  $picker-trigger-pairs: (
144
158
  ('dateinput-container' 'dateinput-trigger'),
145
159
  ('timeinput-container' 'timeinput-trigger'),
@@ -153,7 +167,8 @@ $picker-trigger-pairs: (
153
167
  $width: cv.getVar('picker-trigger-width'),
154
168
  $color: cv.getVar('picker-trigger-color'),
155
169
  $hover-color: cv.getVar('picker-trigger-hover-color'),
156
- $disabled-opacity: cv.getVar('picker-trigger-disabled-opacity')
170
+ $disabled-opacity: cv.getVar('picker-trigger-disabled-opacity'),
171
+ $logical: true
157
172
  ) {
158
173
  @include cv.register-vars(
159
174
  (
@@ -166,3 +181,28 @@ $picker-trigger-pairs: (
166
181
  }
167
182
  }
168
183
  }
184
+
185
+ // The calendar or clock icon is Bulma's `has-icons-left`, pinned to the
186
+ // physical left with `padding-left`. Moving only the launcher onto the inline
187
+ // end would stack it on that icon right to left, so the icon goes to the
188
+ // inline start with it. Only these containers: a plain Control's icons stay
189
+ // physical. The zeros lose to the logical properties after them, which are
190
+ // the sides Bulma's physical padding was setting left to right.
191
+ @each $container in $picker-containers {
192
+ .#{iv.$class-prefix}control.#{iv.$class-prefix}has-icons-left
193
+ > .#{$container}
194
+ > .#{iv.$class-prefix}input {
195
+ padding-left: 0;
196
+ padding-right: 0;
197
+ padding-inline-start: cv.getVar('input-height');
198
+ padding-inline-end: cv.getVar('picker-trigger-width');
199
+ }
200
+
201
+ .#{iv.$class-prefix}control.#{iv.$class-prefix}has-icons-left
202
+ > .#{$container}
203
+ ~ .#{iv.$class-prefix}icon.#{iv.$class-prefix}is-left {
204
+ left: auto;
205
+ right: auto;
206
+ inset-inline-start: 0;
207
+ }
208
+ }
@@ -92,6 +92,17 @@ $slider-vertical-height: 200px !default;
92
92
  cv.getVar("slider-track-color") var(--slider-progress, 0%),
93
93
  cv.getVar("slider-track-color") 100%
94
94
  );
95
+ // The native range mirrors, so 0% of this gradient is the inline start
96
+ // (the right), where the minimum sits. `to right` would paint the left.
97
+ &:dir(rtl) {
98
+ background: linear-gradient(
99
+ to left,
100
+ cv.getVar("slider-fill-color") 0%,
101
+ cv.getVar("slider-fill-color") var(--slider-progress, 0%),
102
+ cv.getVar("slider-track-color") var(--slider-progress, 0%),
103
+ cv.getVar("slider-track-color") 100%
104
+ );
105
+ }
95
106
  border-radius: cv.getVar("slider-radius");
96
107
  outline: none;
97
108
  cursor: pointer;
@@ -198,6 +209,11 @@ $slider-vertical-height: 200px !default;
198
209
  top: -2rem;
199
210
  // Default transform; overridden by inline style when nudge is applied
200
211
  transform: translateX(-50%);
212
+ // The inline transform centres a horizontal bubble on the thumb by this.
213
+ // It's placed from the inline start, which is its right edge right to
214
+ // left, so there it shifts the other way. Set on every bubble, so none
215
+ // takes another slider's.
216
+ --slider-output-shift: -50%;
201
217
  padding: 0.25rem 0.5rem;
202
218
  font-size: cv.getVar("slider-output-font-size");
203
219
  font-weight: cv.getVar("slider-output-font-weight");
@@ -212,6 +228,10 @@ $slider-vertical-height: 200px !default;
212
228
  transition-duration: cv.getVar("slider-transition-duration");
213
229
  transition-timing-function: ease;
214
230
 
231
+ &:dir(rtl) {
232
+ --slider-output-shift: 50%;
233
+ }
234
+
215
235
  &::after {
216
236
  content: "";
217
237
  position: absolute;
@@ -268,6 +288,12 @@ $slider-vertical-height: 200px !default;
268
288
  .#{iv.$class-prefix}slider-tick {
269
289
  position: absolute;
270
290
  transform: translateX(-50%);
291
+
292
+ // The inline start edge is the right one right to left, so centering
293
+ // shifts the other way. A vertical tick replaces this transform.
294
+ &:dir(rtl) {
295
+ transform: translateX(50%);
296
+ }
271
297
  width: cv.getVar("slider-tick-width");
272
298
  height: cv.getVar("slider-tick-height");
273
299
  background: cv.getVar("slider-tick-color");
@@ -318,6 +344,19 @@ $slider-vertical-height: 200px !default;
318
344
  cv.getVar("slider-track-color") var(--slider-progress-high, 100%),
319
345
  cv.getVar("slider-track-color") 100%
320
346
  );
347
+ // Same mirror as the single thumb: the stops are measured from the
348
+ // inline start, which is the right when the page is.
349
+ &:dir(rtl) {
350
+ background: linear-gradient(
351
+ to left,
352
+ cv.getVar("slider-track-color") 0%,
353
+ cv.getVar("slider-track-color") var(--slider-progress-low, 0%),
354
+ cv.getVar("slider-fill-color") var(--slider-progress-low, 0%),
355
+ cv.getVar("slider-fill-color") var(--slider-progress-high, 100%),
356
+ cv.getVar("slider-track-color") var(--slider-progress-high, 100%),
357
+ cv.getVar("slider-track-color") 100%
358
+ );
359
+ }
321
360
  pointer-events: none;
322
361
  }
323
362