@allxsmith/bestax-bulma 5.60.0 → 5.61.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 (59) hide show
  1. package/dist/bestax.css +1 -1
  2. package/dist/bestax.css.map +1 -1
  3. package/dist/esm/components/Carousel.js +3 -43
  4. package/dist/esm/components/Carousel.js.map +1 -1
  5. package/dist/esm/components/Command.js +3 -3
  6. package/dist/esm/components/Navbar.js +3 -1
  7. package/dist/esm/components/Navbar.js.map +1 -1
  8. package/dist/esm/components/Popover.js +7 -27
  9. package/dist/esm/components/Popover.js.map +1 -1
  10. package/dist/esm/components/Sidebar.js +17 -58
  11. package/dist/esm/components/Sidebar.js.map +1 -1
  12. package/dist/esm/form/ColorPicker.js +4 -4
  13. package/dist/esm/form/ColorPicker.js.map +1 -1
  14. package/dist/esm/form/Combobox.js +3 -3
  15. package/dist/esm/helpers/overlayStack.js +33 -1
  16. package/dist/esm/helpers/overlayStack.js.map +1 -1
  17. package/dist/esm/helpers/useBulmaViewport.js +82 -0
  18. package/dist/esm/helpers/useBulmaViewport.js.map +1 -0
  19. package/dist/esm/helpers/useInertSiblings.js +7 -3
  20. package/dist/esm/helpers/useInertSiblings.js.map +1 -1
  21. package/dist/esm/helpers/useOutsidePress.js +53 -0
  22. package/dist/esm/helpers/useOutsidePress.js.map +1 -0
  23. package/dist/esm/helpers/useOverlayFocus.js +74 -0
  24. package/dist/esm/helpers/useOverlayFocus.js.map +1 -0
  25. package/dist/esm/layout/AppFrame.js +438 -0
  26. package/dist/esm/layout/AppFrame.js.map +1 -0
  27. package/dist/extras.css +1 -1
  28. package/dist/extras.css.map +1 -1
  29. package/dist/index.cjs +678 -136
  30. package/dist/index.cjs.map +1 -1
  31. package/dist/index.esm.js +1 -0
  32. package/dist/index.esm.js.map +1 -1
  33. package/dist/types/components/Navbar.d.ts +4 -3
  34. package/dist/types/helpers/overlayStack.d.ts +17 -0
  35. package/dist/types/helpers/useBulmaViewport.d.ts +34 -0
  36. package/dist/types/helpers/useInertSiblings.d.ts +4 -1
  37. package/dist/types/helpers/useOutsidePress.d.ts +24 -0
  38. package/dist/types/helpers/useOverlayFocus.d.ts +44 -0
  39. package/dist/types/index.d.ts +1 -0
  40. package/dist/types/layout/AppFrame.d.ts +306 -0
  41. package/dist/types-cjs/components/Navbar.d.ts +4 -3
  42. package/dist/types-cjs/helpers/overlayStack.d.ts +17 -0
  43. package/dist/types-cjs/helpers/useBulmaViewport.d.ts +34 -0
  44. package/dist/types-cjs/helpers/useInertSiblings.d.ts +4 -1
  45. package/dist/types-cjs/helpers/useOutsidePress.d.ts +24 -0
  46. package/dist/types-cjs/helpers/useOverlayFocus.d.ts +44 -0
  47. package/dist/types-cjs/index.d.ts +1 -0
  48. package/dist/types-cjs/layout/AppFrame.d.ts +306 -0
  49. package/dist/versions/bestax-no-dark-mode.css +1 -1
  50. package/dist/versions/bestax-no-dark-mode.css.map +1 -1
  51. package/dist/versions/bestax-no-helpers-prefixed.css +1 -1
  52. package/dist/versions/bestax-no-helpers-prefixed.css.map +1 -1
  53. package/dist/versions/bestax-no-helpers.css +1 -1
  54. package/dist/versions/bestax-no-helpers.css.map +1 -1
  55. package/dist/versions/bestax-prefixed.css +1 -1
  56. package/dist/versions/bestax-prefixed.css.map +1 -1
  57. package/package.json +1 -1
  58. package/src/scss/layout/_appframe.scss +306 -0
  59. package/src/scss/layout/_index.scss +1 -0
@@ -0,0 +1,306 @@
1
+ // Bestax Extras - AppFrame Styles
2
+ // The frame an app's pages sit in: a header across the top, a nav column down
3
+ // the side, the page, an aside and a footer, laid out by a grid. The header
4
+ // and the column stick while the document scrolls. Bulma has no frame.
5
+ //
6
+ // Below the root's breakpoint the nav is a drawer instead: fixed to the
7
+ // inline-start edge, slid out and `visibility: hidden` until it opens, so a
8
+ // closed one is out of the Tab order and the accessibility tree before any
9
+ // script runs. The layout is all in here, with a media query per breakpoint
10
+ // class, so the server's markup lays out as the browser's does.
11
+
12
+ @use 'bulma/sass/utilities/initial-variables' as iv;
13
+ @use 'bulma/sass/utilities/css-variables' as cv;
14
+ @use 'bulma/sass/utilities/mixins' as mx;
15
+ @use '../variables' as *;
16
+ @use '../mixins' as *;
17
+
18
+ // How far down the nav column starts sticking, and how far an in-page link
19
+ // or a Tab scrolls clear of the sticky header. A header taller than Bulma's
20
+ // navbar sets it on `:root`.
21
+ $app-frame-header-height: cv.getVar('navbar-height') !default;
22
+ $app-frame-header-background: cv.getVar('scheme-main') !default;
23
+ $app-frame-nav-width: 16rem !default;
24
+ $app-frame-nav-padding: 0.75rem !default;
25
+ $app-frame-nav-background: cv.getVar('scheme-main') !default;
26
+ $app-frame-aside-width: 20rem !default;
27
+ $app-frame-border-color: cv.getVar('border') !default;
28
+ $app-frame-border-width: 1px !default;
29
+ // The modal background's color: the inverted scheme at 0.86 alpha.
30
+ $app-frame-backdrop-background: hsla(
31
+ #{cv.getVar('scheme-h')},
32
+ #{cv.getVar('scheme-s')},
33
+ #{cv.getVar('scheme-invert-l')},
34
+ 0.86
35
+ ) !default;
36
+ $app-frame-drawer-shadow: cv.getVar('shadow') !default;
37
+ $app-frame-transition-duration: cv.getVar('duration') !default;
38
+ $app-frame-skip-link-background: cv.getVar('scheme-main') !default;
39
+ $app-frame-skip-link-color: cv.getVar('link') !default;
40
+
41
+ // The drawer leaves this much of the window showing beside it, so there's
42
+ // backdrop to press.
43
+ $-drawer-gap: 3rem;
44
+
45
+ // On Bulma's variables host, as `--bulma-navbar-height` is, so the document
46
+ // can read it for `scroll-padding-top`.
47
+ #{iv.$variables-host} {
48
+ @include cv.register-vars(
49
+ (
50
+ 'app-frame-header-height': #{$app-frame-header-height},
51
+ )
52
+ );
53
+ }
54
+
55
+ .#{iv.$class-prefix}app-frame {
56
+ @include cv.register-vars(
57
+ (
58
+ 'app-frame-header-background': #{$app-frame-header-background},
59
+ 'app-frame-nav-width': #{$app-frame-nav-width},
60
+ 'app-frame-nav-padding': #{$app-frame-nav-padding},
61
+ 'app-frame-nav-background': #{$app-frame-nav-background},
62
+ 'app-frame-aside-width': #{$app-frame-aside-width},
63
+ 'app-frame-border-color': #{$app-frame-border-color},
64
+ 'app-frame-border-width': #{$app-frame-border-width},
65
+ 'app-frame-backdrop-background': #{$app-frame-backdrop-background},
66
+ 'app-frame-drawer-shadow': #{$app-frame-drawer-shadow},
67
+ 'app-frame-transition-duration': #{$app-frame-transition-duration},
68
+ 'app-frame-skip-link-background': #{$app-frame-skip-link-background},
69
+ 'app-frame-skip-link-color': #{$app-frame-skip-link-color},
70
+ )
71
+ );
72
+ }
73
+
74
+ // An in-page link or a Tab lands below the sticky header (WCAG technique C43).
75
+ html:has(.#{iv.$class-prefix}app-frame) {
76
+ scroll-padding-top: cv.getVar('app-frame-header-height');
77
+ }
78
+
79
+ // ---- The grid, below the breakpoint ----------------------------------------------
80
+
81
+ // One column: the header, the page, the aside under it, and the footer. A
82
+ // part that isn't there leaves an empty `auto` row, which takes no room.
83
+ .#{iv.$class-prefix}app-frame {
84
+ display: grid;
85
+ grid-template-columns: minmax(0, 1fr);
86
+ grid-template-rows: auto 1fr auto auto;
87
+ grid-template-areas: 'header' 'main' 'aside' 'footer';
88
+ min-height: 100vh;
89
+ min-height: 100dvh;
90
+ }
91
+
92
+ .#{iv.$class-prefix}app-frame-header {
93
+ grid-area: header;
94
+ position: sticky;
95
+ inset-block-start: 0;
96
+ z-index: $extras-z-index-sticky;
97
+ background-color: cv.getVar('app-frame-header-background');
98
+ }
99
+
100
+ .#{iv.$class-prefix}app-frame-main {
101
+ grid-area: main;
102
+ min-width: 0;
103
+
104
+ // Focus lands here from the skip link, to start the Tab order there. It's
105
+ // not a control, so it draws no ring.
106
+ &:focus {
107
+ outline: none;
108
+ }
109
+ }
110
+
111
+ .#{iv.$class-prefix}app-frame-aside {
112
+ grid-area: aside;
113
+ min-width: 0;
114
+ }
115
+
116
+ .#{iv.$class-prefix}app-frame-footer {
117
+ grid-area: footer;
118
+ min-width: 0;
119
+ }
120
+
121
+ // The drawer: over everything, header included, from the inline-start edge.
122
+ // It slides out and hides once the slide is over, and shows at once as it
123
+ // opens, so focus can move in straight away.
124
+ .#{iv.$class-prefix}app-frame-nav {
125
+ position: fixed;
126
+ inset-block: 0;
127
+ inset-inline-start: 0;
128
+ z-index: $extras-z-index-fixed;
129
+ inline-size: min(
130
+ #{cv.getVar('app-frame-nav-width')},
131
+ calc(100vw - #{$-drawer-gap})
132
+ );
133
+ overflow-y: auto;
134
+ overscroll-behavior: contain;
135
+ padding: cv.getVar('app-frame-nav-padding');
136
+ background-color: cv.getVar('app-frame-nav-background');
137
+ box-shadow: cv.getVar('app-frame-drawer-shadow');
138
+ transform: translateX(-100%);
139
+ visibility: hidden;
140
+ transition-property: transform, visibility;
141
+ transition-duration: cv.getVar('app-frame-transition-duration'), 0s;
142
+ transition-delay: 0s, cv.getVar('app-frame-transition-duration');
143
+ transition-timing-function: $extras-easing;
144
+
145
+ &:dir(rtl) {
146
+ transform: translateX(100%);
147
+ }
148
+ }
149
+
150
+ // The open drawer is Bulma's active state, on the nav as on a navbar's menu.
151
+ .#{iv.$class-prefix}app-frame
152
+ > .#{iv.$class-prefix}app-frame-nav.#{iv.$class-prefix}is-active {
153
+ transform: none;
154
+ visibility: visible;
155
+ transition-delay: 0s;
156
+ }
157
+
158
+ // The close button, at the top of the drawer on its far side. Bulma's
159
+ // `.delete` is inline, which an auto margin can't push, whichever loads last.
160
+ .#{iv.$class-prefix}app-frame-nav > .#{iv.$class-prefix}app-frame-close {
161
+ display: flex;
162
+ margin-inline-start: auto;
163
+ margin-block-end: 0.5rem;
164
+ }
165
+
166
+ .#{iv.$class-prefix}app-frame-backdrop {
167
+ position: fixed;
168
+ inset: 0;
169
+ z-index: $extras-z-index-fixed - 1;
170
+ background-color: cv.getVar('app-frame-backdrop-background');
171
+ opacity: 0;
172
+ visibility: hidden;
173
+ transition-property: opacity, visibility;
174
+ transition-duration: cv.getVar('app-frame-transition-duration'), 0s;
175
+ transition-delay: 0s, cv.getVar('app-frame-transition-duration');
176
+ transition-timing-function: $extras-easing;
177
+ }
178
+
179
+ .#{iv.$class-prefix}app-frame
180
+ > .#{iv.$class-prefix}app-frame-backdrop.#{iv.$class-prefix}is-active {
181
+ opacity: 1;
182
+ visibility: visible;
183
+ transition-delay: 0s;
184
+ }
185
+
186
+ // Bulma hides a navbar's burger from desktop up. The frame's shows at every
187
+ // width, since from the breakpoint up it collapses the column.
188
+ .#{iv.$class-prefix}navbar-burger.#{iv.$class-prefix}app-frame-burger {
189
+ display: inline-flex;
190
+ }
191
+
192
+ // Hidden until it has focus, then over the header's start. It shows at once,
193
+ // rather than fading its background in with Bulma's link transition, which
194
+ // leaves its text over the header's while it fades.
195
+ .#{iv.$class-prefix}app-frame-skip-link {
196
+ @include extras-sr-only;
197
+ transition: none;
198
+
199
+ &:focus {
200
+ position: fixed;
201
+ inset-block-start: 0.5rem;
202
+ inset-inline-start: 0.5rem;
203
+ z-index: $extras-z-index-fixed;
204
+ width: auto;
205
+ height: auto;
206
+ margin: 0;
207
+ padding: 0.5em 1em;
208
+ overflow: visible;
209
+ clip: auto;
210
+ white-space: normal;
211
+ border-radius: cv.getVar('radius');
212
+ background-color: cv.getVar('app-frame-skip-link-background');
213
+ color: cv.getVar('app-frame-skip-link-color');
214
+ box-shadow: cv.getVar('shadow');
215
+ @include extras-focus-outline;
216
+ }
217
+ }
218
+
219
+ // ---- From the breakpoint up ------------------------------------------------------
220
+
221
+ // Three columns, the nav's, the page's and the aside's, each as wide as what's
222
+ // in it, under the header. The footer sits under the page. The nav is a
223
+ // column that sticks under the header as tall as the window less the header,
224
+ // and collapsed it slides out past the inline-start edge as its column
225
+ // closes, then hides.
226
+ @mixin -wide {
227
+ grid-template-columns: auto minmax(0, 1fr) auto;
228
+ grid-template-rows: auto 1fr auto;
229
+ grid-template-areas:
230
+ 'header header header'
231
+ 'nav main aside'
232
+ 'nav footer aside';
233
+
234
+ > .#{iv.$class-prefix}app-frame-nav {
235
+ grid-area: nav;
236
+ position: sticky;
237
+ inset: auto;
238
+ inset-block-start: cv.getVar('app-frame-header-height');
239
+ z-index: auto;
240
+ align-self: start;
241
+ inline-size: cv.getVar('app-frame-nav-width');
242
+ block-size: calc(100vh - #{cv.getVar('app-frame-header-height')});
243
+ block-size: calc(100dvh - #{cv.getVar('app-frame-header-height')});
244
+ border-inline-end: cv.getVar('app-frame-border-width') solid
245
+ cv.getVar('app-frame-border-color');
246
+ box-shadow: none;
247
+ transform: none;
248
+ visibility: visible;
249
+ transition-property: margin-inline-start, visibility;
250
+ transition-delay: 0s;
251
+ }
252
+
253
+ &.#{iv.$class-prefix}is-nav-collapsed > .#{iv.$class-prefix}app-frame-nav {
254
+ margin-inline-start: calc(-1 * #{cv.getVar('app-frame-nav-width')});
255
+ visibility: hidden;
256
+ transition-delay: 0s, cv.getVar('app-frame-transition-duration');
257
+ }
258
+
259
+ > .#{iv.$class-prefix}app-frame-nav > .#{iv.$class-prefix}app-frame-close,
260
+ > .#{iv.$class-prefix}app-frame-backdrop {
261
+ display: none;
262
+ }
263
+
264
+ > .#{iv.$class-prefix}app-frame-aside {
265
+ inline-size: cv.getVar('app-frame-aside-width');
266
+ border-inline-start: cv.getVar('app-frame-border-width') solid
267
+ cv.getVar('app-frame-border-color');
268
+ }
269
+ }
270
+
271
+ @include mx.tablet {
272
+ .#{iv.$class-prefix}app-frame.#{iv.$class-prefix}is-tablet {
273
+ @include -wide;
274
+ }
275
+ }
276
+
277
+ @include mx.desktop {
278
+ .#{iv.$class-prefix}app-frame.#{iv.$class-prefix}is-desktop {
279
+ @include -wide;
280
+ }
281
+ }
282
+
283
+ @include mx.widescreen {
284
+ .#{iv.$class-prefix}app-frame.#{iv.$class-prefix}is-widescreen {
285
+ @include -wide;
286
+ }
287
+ }
288
+
289
+ // ---- Media ---------------------------------------------------------------------
290
+
291
+ // The drawer's shadow is dropped in forced colors, so its open edge gets a
292
+ // border, as the column has.
293
+ @media (forced-colors: active) {
294
+ .#{iv.$class-prefix}app-frame-nav {
295
+ border-inline-end: cv.getVar('app-frame-border-width') solid
296
+ cv.getVar('app-frame-border-color');
297
+ }
298
+ }
299
+
300
+ // No slide, collapse or fade: each state shows at once.
301
+ @media (prefers-reduced-motion: reduce) {
302
+ .#{iv.$class-prefix}app-frame-nav,
303
+ .#{iv.$class-prefix}app-frame-backdrop {
304
+ transition: none !important;
305
+ }
306
+ }
@@ -2,5 +2,6 @@
2
2
  // Import all layout partials here: extras that structure a page, as Bulma's
3
3
  // own layout does
4
4
 
5
+ @use 'appframe';
5
6
  @use 'splitter';
6
7
  @use 'stack';