rei-kit 2.13.0 → 2.15.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.
package/dist/styles.css CHANGED
@@ -632,6 +632,79 @@
632
632
  color: var(--color-ink-soft);
633
633
  }
634
634
 
635
+ /* The buttons are out of the Tab order: the keyboard already has the arrows,
636
+ and three stops for one number is two too many. They stay reachable by
637
+ pointer and by touch, which is who they are for. */
638
+ .rk-number[data-v-082bd3d7] {
639
+ display: flex;
640
+ align-items: center;
641
+ height: 2.75rem;
642
+ border-radius: var(--radius-card);
643
+ padding: 0 0.25rem;
644
+ }
645
+ .rk-number[data-v-082bd3d7]:focus-within {
646
+ outline: 2px solid var(--color-primary);
647
+ outline-offset: 1px;
648
+ }
649
+ .rk-number.is-invalid[data-v-082bd3d7] {
650
+ --surface-border-color: var(--color-negative);
651
+ }
652
+ .rk-number.is-disabled[data-v-082bd3d7] {
653
+ opacity: 0.5;
654
+ }
655
+ .rk-number-field[data-v-082bd3d7] {
656
+ min-width: 0;
657
+ flex: 1;
658
+ background: transparent;
659
+ text-align: center;
660
+ font-size: 1rem;
661
+ font-variant-numeric: tabular-nums;
662
+ color: var(--color-ink);
663
+ outline: none;
664
+ }
665
+ .rk-number-step[data-v-082bd3d7] {
666
+ display: grid;
667
+ width: 2.25rem;
668
+ height: 2.25rem;
669
+ flex-shrink: 0;
670
+ place-items: center;
671
+ border-radius: calc(var(--radius-card) - 4px);
672
+ color: var(--color-ink);
673
+ transition: background-color var(--duration-fast) var(--ease-standard);
674
+ }
675
+ .rk-number-step[data-v-082bd3d7]:hover:not(:disabled) {
676
+ background: var(--color-muted);
677
+ }
678
+ .rk-number-step[data-v-082bd3d7]:disabled {
679
+ opacity: 0.35;
680
+ }
681
+
682
+ /* The slider takes the room; the field is as wide as its digits need and no
683
+ wider, so the pair does not read as two fields of equal weight. */
684
+ .rk-slider-field[data-v-6ec3163a] {
685
+ display: flex;
686
+ flex-wrap: wrap;
687
+ /* Centred rather than bottom-aligned: the slider's block grows when its
688
+ hint wraps to a second line, and aligning to the bottom edge sank the
689
+ field down with it. */
690
+ align-items: center;
691
+ gap: 0.75rem;
692
+ }
693
+
694
+ /* It wraps rather than squeezing: a slider shorter than this is one nobody
695
+ can aim with, and then the field belongs under it instead of beside it.
696
+ Wrapping does that by itself, so it needs no container query -- which
697
+ would have been a rule that silently never matched unless the app had
698
+ declared a container above it. */
699
+ .rk-slider-field[data-v-6ec3163a] > :first-child {
700
+ min-width: 12rem;
701
+ flex: 1 1 12rem;
702
+ }
703
+ .rk-slider-field-number[data-v-6ec3163a] {
704
+ width: 7.5rem;
705
+ flex: 0 1 7.5rem;
706
+ }
707
+
635
708
  .rk-spin-wrap[data-v-842da62c] {
636
709
  display: inline-flex;
637
710
  align-items: center;
@@ -1827,53 +1900,6 @@ to {
1827
1900
  height: 1rem;
1828
1901
  }
1829
1902
 
1830
- /* The buttons are out of the Tab order: the keyboard already has the arrows,
1831
- and three stops for one number is two too many. They stay reachable by
1832
- pointer and by touch, which is who they are for. */
1833
- .rk-number[data-v-082bd3d7] {
1834
- display: flex;
1835
- align-items: center;
1836
- height: 2.75rem;
1837
- border-radius: var(--radius-card);
1838
- padding: 0 0.25rem;
1839
- }
1840
- .rk-number[data-v-082bd3d7]:focus-within {
1841
- outline: 2px solid var(--color-primary);
1842
- outline-offset: 1px;
1843
- }
1844
- .rk-number.is-invalid[data-v-082bd3d7] {
1845
- --surface-border-color: var(--color-negative);
1846
- }
1847
- .rk-number.is-disabled[data-v-082bd3d7] {
1848
- opacity: 0.5;
1849
- }
1850
- .rk-number-field[data-v-082bd3d7] {
1851
- min-width: 0;
1852
- flex: 1;
1853
- background: transparent;
1854
- text-align: center;
1855
- font-size: 1rem;
1856
- font-variant-numeric: tabular-nums;
1857
- color: var(--color-ink);
1858
- outline: none;
1859
- }
1860
- .rk-number-step[data-v-082bd3d7] {
1861
- display: grid;
1862
- width: 2.25rem;
1863
- height: 2.25rem;
1864
- flex-shrink: 0;
1865
- place-items: center;
1866
- border-radius: calc(var(--radius-card) - 4px);
1867
- color: var(--color-ink);
1868
- transition: background-color var(--duration-fast) var(--ease-standard);
1869
- }
1870
- .rk-number-step[data-v-082bd3d7]:hover:not(:disabled) {
1871
- background: var(--color-muted);
1872
- }
1873
- .rk-number-step[data-v-082bd3d7]:disabled {
1874
- opacity: 0.35;
1875
- }
1876
-
1877
1903
  .rk-pin-cells[data-v-ba322d9c] {
1878
1904
  display: flex;
1879
1905
  gap: 0.5rem;
@@ -3068,11 +3094,11 @@ to {
3068
3094
  outline-offset: 2px;
3069
3095
  }
3070
3096
 
3071
- .rk-tip[data-v-3a572640] {
3097
+ .rk-tip[data-v-c31426f8] {
3072
3098
  position: relative;
3073
3099
  display: inline-flex;
3074
3100
  }
3075
- .rk-tip-bubble[data-v-3a572640] {
3101
+ .rk-tip-bubble[data-v-c31426f8] {
3076
3102
  position: absolute;
3077
3103
  left: 50%;
3078
3104
  z-index: 60;
@@ -3091,22 +3117,138 @@ to {
3091
3117
  pointer-events: none;
3092
3118
  transition: opacity var(--duration-fast) ease;
3093
3119
  }
3094
- .rk-tip-bubble.is-top[data-v-3a572640] {
3120
+ .rk-tip-bubble.is-top[data-v-c31426f8] {
3095
3121
  bottom: calc(100% + 0.375rem);
3096
3122
  }
3097
- .rk-tip-bubble.is-bottom[data-v-3a572640] {
3123
+ .rk-tip-bubble.is-bottom[data-v-c31426f8] {
3098
3124
  top: calc(100% + 0.375rem);
3099
3125
  }
3100
- .rk-tip:hover .rk-tip-bubble[data-v-3a572640],
3101
- .rk-tip:focus-within .rk-tip-bubble[data-v-3a572640] {
3126
+
3127
+ /* Following: placed from the pointer rather than from the trigger's edges,
3128
+ so `top` and `bottom` both have to give way to the inline style. */
3129
+ .rk-tip-bubble.is-following[data-v-c31426f8] {
3130
+ bottom: auto;
3131
+ /* No transition on the position, or the bubble lags the pointer it is
3132
+ supposed to be under. */
3133
+ transition: opacity var(--duration-fast) ease;
3134
+ }
3135
+ .rk-tip-bubble.is-following.is-top[data-v-c31426f8] {
3136
+ transform: translate(-50%, -100%);
3137
+ }
3138
+ .rk-tip:hover .rk-tip-bubble[data-v-c31426f8],
3139
+ .rk-tip:focus-within .rk-tip-bubble[data-v-c31426f8] {
3102
3140
  opacity: 1;
3103
3141
  }
3104
3142
  @media (prefers-reduced-motion: reduce) {
3105
- .rk-tip-bubble[data-v-3a572640] {
3143
+ .rk-tip-bubble[data-v-c31426f8] {
3106
3144
  transition: none;
3107
3145
  }
3108
3146
  }
3109
3147
 
3148
+ .rk-mega[data-v-343f9362] {
3149
+ position: relative;
3150
+ }
3151
+ .rk-mega-bar[data-v-343f9362] {
3152
+ display: flex;
3153
+ align-items: center;
3154
+ gap: 0.25rem;
3155
+ }
3156
+ .rk-mega-item[data-v-343f9362] {
3157
+ position: static;
3158
+ }
3159
+ .rk-mega-top[data-v-343f9362] {
3160
+ display: inline-flex;
3161
+ align-items: center;
3162
+ gap: 0.25rem;
3163
+ border-radius: var(--radius-cell);
3164
+ padding: 0.5rem 0.75rem;
3165
+ font-size: 0.875rem;
3166
+ font-weight: 500;
3167
+ color: var(--color-ink-soft);
3168
+ transition: color var(--duration-fast) var(--ease-standard);
3169
+ }
3170
+ .rk-mega-top[data-v-343f9362]:hover,
3171
+ .rk-mega-top[aria-expanded='true'][data-v-343f9362] {
3172
+ color: var(--color-ink);
3173
+ }
3174
+ .rk-mega-top.is-active[data-v-343f9362] {
3175
+ color: var(--color-primary);
3176
+ }
3177
+ .rk-mega-twist[data-v-343f9362] {
3178
+ width: 0.875rem;
3179
+ height: 0.875rem;
3180
+ transition: rotate var(--duration-fast) var(--ease-standard);
3181
+ }
3182
+ .rk-mega-twist.is-open[data-v-343f9362] {
3183
+ rotate: 180deg;
3184
+ }
3185
+
3186
+ /* Full width of the bar rather than of the button: that is what makes it a
3187
+ mega menu and not a dropdown. */
3188
+ .rk-mega-panel[data-v-343f9362] {
3189
+ position: absolute;
3190
+ top: calc(100% + 0.5rem);
3191
+ left: 0;
3192
+ z-index: 50;
3193
+ width: 100%;
3194
+ border-radius: var(--radius-card);
3195
+ padding: 1.25rem;
3196
+ }
3197
+ .rk-mega-panel[hidden][data-v-343f9362] {
3198
+ display: none;
3199
+ }
3200
+ .rk-mega-columns[data-v-343f9362] {
3201
+ display: grid;
3202
+ grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
3203
+ gap: 1.5rem;
3204
+ }
3205
+ .rk-mega-column-title[data-v-343f9362] {
3206
+ margin-bottom: 0.5rem;
3207
+ font-size: 0.6875rem;
3208
+ font-weight: 600;
3209
+ letter-spacing: 0.04em;
3210
+ text-transform: uppercase;
3211
+ color: var(--color-ink-soft);
3212
+ }
3213
+ .rk-mega-links[data-v-343f9362] {
3214
+ display: flex;
3215
+ flex-direction: column;
3216
+ gap: 1px;
3217
+ }
3218
+ .rk-mega-link[data-v-343f9362] {
3219
+ display: block;
3220
+ border-radius: var(--radius-cell);
3221
+ padding: 0.375rem 0.5rem;
3222
+ transition: background-color var(--duration-fast) var(--ease-standard);
3223
+ }
3224
+ .rk-mega-link[data-v-343f9362]:hover {
3225
+ background: var(--color-muted);
3226
+ }
3227
+ .rk-mega-link-label[data-v-343f9362] {
3228
+ display: block;
3229
+ font-size: 0.875rem;
3230
+ color: var(--color-ink);
3231
+ }
3232
+ .rk-mega-link-note[data-v-343f9362] {
3233
+ display: block;
3234
+ margin-top: 0.125rem;
3235
+ font-size: 0.75rem;
3236
+ line-height: 1.4;
3237
+ color: var(--color-ink-soft);
3238
+ }
3239
+
3240
+ /* On a narrow screen the panel is the page width and the columns stack,
3241
+ because a four-column grid in a 390px column is four unreadable columns. */
3242
+ @media (max-width: 48rem) {
3243
+ .rk-mega-panel[data-v-343f9362] {
3244
+ padding: 1rem;
3245
+ }
3246
+ .rk-mega-columns[data-v-343f9362] {
3247
+ grid-template-columns: minmax(0, 1fr);
3248
+ gap: 1rem;
3249
+ }
3250
+ }
3251
+
3110
3252
  /* The root carries no layout of its own, and that is the fix for a real bug
3111
3253
  rather than a style preference.
3112
3254
 
@@ -18,6 +18,19 @@
18
18
  * description of the control rather than as loose text nearby. That is why the
19
19
  * trigger goes in a slot: the component has to own the id on both ends.
20
20
  *
21
+ * ## `follow`, and what it costs
22
+ *
23
+ * With `follow` the bubble tracks the pointer across the trigger, which is
24
+ * what a large target wants — a chart, a map, a calendar cell — where a
25
+ * bubble pinned to the middle can be nowhere near what is under the cursor.
26
+ *
27
+ * It is opt-in because it is the one thing here that needs JavaScript: a
28
+ * `follow` tooltip does nothing until the bundle arrives, while the default
29
+ * works in a prerendered page with scripting switched off. It also stops
30
+ * following for a reader who asked their system for less motion, and for a
31
+ * keyboard, which has no cursor to follow — both fall back to the anchored
32
+ * position, so the tooltip is never lost, only still.
33
+ *
21
34
  * ## When not to use it
22
35
  *
23
36
  * For anything the reader must have. A tooltip is unreachable on a touch screen
@@ -27,6 +40,10 @@ type __VLS_Props = {
27
40
  /** The description. Already translated. */
28
41
  label: string;
29
42
  placement?: 'top' | 'bottom' | undefined;
43
+ /** Track the pointer across the trigger instead of pinning to its middle. */
44
+ follow?: boolean | undefined;
45
+ /** How far the bubble sits from the pointer, in pixels. */
46
+ offset?: number | undefined;
30
47
  };
31
48
  type __VLS_Slots = {
32
49
  /** The control being described. */
@@ -0,0 +1,53 @@
1
+ export interface MegaMenuLink {
2
+ key: string;
3
+ /** Router destination. */
4
+ to: string;
5
+ /** Already translated. */
6
+ label: string;
7
+ /** A line under the label, for a link whose name is not enough. */
8
+ description?: string | undefined;
9
+ }
10
+ export interface MegaMenuColumn {
11
+ key: string;
12
+ /** A heading over the column. Already translated. */
13
+ title?: string | undefined;
14
+ links: readonly MegaMenuLink[];
15
+ }
16
+ export interface MegaMenuItem<K extends string> {
17
+ /** Identity, compared against `active`. */
18
+ key: K;
19
+ /** Already translated. */
20
+ label: string;
21
+ /** A plain link, for a top-level item with nothing under it. */
22
+ to?: string | undefined;
23
+ /** What the panel holds. With none, the item is just a link. */
24
+ columns?: readonly MegaMenuColumn[] | undefined;
25
+ }
26
+ declare const __VLS_export: <K extends string>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_exposed?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
27
+ props: import('vue').PublicProps & __VLS_PrettifyLocal<{
28
+ items: readonly MegaMenuItem<K>[];
29
+ /** Which section is current. Usually derived from the route. */
30
+ active?: K | undefined;
31
+ /** Accessible name for the navigation landmark. */
32
+ label?: string | undefined;
33
+ /** Whether a pointer opens a panel as well as a click. */
34
+ openOnHover?: boolean | undefined;
35
+ /** How long the pointer has to leave before the panel closes, in ms. */
36
+ hoverDelay?: number | undefined;
37
+ }> & (typeof globalThis extends {
38
+ __VLS_PROPS_FALLBACK: infer P;
39
+ } ? P : {});
40
+ expose: (exposed: {}) => void;
41
+ attrs: any;
42
+ slots: { [K_1 in K]?: (props: {}) => any; };
43
+ emit: {};
44
+ }>) => import('vue').VNode & {
45
+ __ctx?: NonNullable<Awaited<typeof __VLS_setup>>;
46
+ };
47
+ declare const _default: typeof __VLS_export;
48
+ export default _default;
49
+ type __VLS_PrettifyLocal<T> = (T extends any ? {
50
+ [K in keyof T]: T[K];
51
+ } : {
52
+ [K in keyof T as K]: T[K];
53
+ }) & {};
@@ -65,5 +65,7 @@ export { default as ResponsiveDialog } from './ResponsiveDialog.vue';
65
65
  export { default as BaseTabs } from './BaseTabs.vue';
66
66
  export type { TabPanel } from './BaseTabs.vue';
67
67
  export { default as BaseTooltip } from './BaseTooltip.vue';
68
+ export { default as MegaMenu } from './MegaMenu.vue';
69
+ export type { MegaMenuColumn, MegaMenuItem, MegaMenuLink } from './MegaMenu.vue';
68
70
  export { default as NavLinks } from './NavLinks.vue';
69
71
  export type { NavLinkItem } from './NavLinks.vue';