rei-kit 2.13.0 → 2.14.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/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # rei-kit
2
2
 
3
- **One kit. Every look.** 88 accessible components for Vue 3 and Tailwind 4.
3
+ **One kit. Every look.** 89 accessible components for Vue 3 and Tailwind 4.
4
4
  Change the **material** with one attribute and the **palette** with another —
5
5
  every component follows, and none of them knows your brand.
6
6
 
@@ -112,7 +112,7 @@ Each claim here is enforced by something that fails, not by a promise.
112
112
 
113
113
  | Standard | How it is held |
114
114
  | ---------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
115
- | **Open for extension, closed for edits** | A new look is a token, a material or a palette — never an edit to a component. Materials and palettes restyle all 88 without touching one, and a test fails if a component holds a colour. |
115
+ | **Open for extension, closed for edits** | A new look is a token, a material or a palette — never an edit to a component. Materials and palettes restyle all 89 without touching one, and a test fails if a component holds a colour. |
116
116
  | **Single responsibility** | One part, one job. Label-and-error wiring lives in `FormField`, not in five inputs; taking the page behind a layer out of reach lives in one helper the modal, the sheet and the guide share. |
117
117
  | **Depend on roles, not values** | Components read `primary`, `surface`, `--shadow-card` — never a hex or a pixel shadow. An app's brand wins in both modes, tested. |
118
118
  | **WAI-ARIA Authoring Practices** | Menus, comboboxes, tabs, sliders, dialogs and accordions follow their APG pattern: arrows move, Tab leaves, Escape closes, focus returns. Behaviour tests drive each with the keyboard. |
@@ -124,11 +124,11 @@ Each claim here is enforced by something that fails, not by a promise.
124
124
 
125
125
  ## Status
126
126
 
127
- **v2.13.0 — three consumers.**
127
+ **v2.14.0 — three consumers.**
128
128
 
129
129
  | | |
130
130
  | ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
131
- | Components | 88 (`AuthForm`, `BaseTable`, `BaseCombobox`, `BaseSlider`, `TabShell`, `BaseModal`, `BaseTabs`, `BaseTooltip`, `BasePagination`, `BaseBreadcrumb`, `BaseDisclosure`, `BaseAccordion`, `NavLinks`, `OfflineBanner`, `FabButton`, `BaseButton`, `BaseCard`, `BaseInput`, `BaseSelect`, `BaseTextarea`, `BaseCheckbox`, `BaseSwitch`, `BaseRadioGroup`, `BaseMenu`, `BaseAvatar`, `BaseSpinner`, `BaseAlert`, `BaseBadge`, `BaseSheet`, `ProgressBar`, `PriceCard`, `ToastHost`, `TabBar`, `GoogleButton`, `LocaleLinks`, `LocaleSheet`, `AuthShell`, `TourShell`, `InstallPrompt`, `UpdatePrompt`, `InstallSettings`, `SkeletonList`, `PageContainer`, `ErrorBoundary`, etc.) |
131
+ | Components | 89 (`AuthForm`, `BaseTable`, `BaseCombobox`, `BaseSlider`, `TabShell`, `BaseModal`, `BaseTabs`, `BaseTooltip`, `BasePagination`, `BaseBreadcrumb`, `BaseDisclosure`, `BaseAccordion`, `NavLinks`, `OfflineBanner`, `FabButton`, `BaseButton`, `BaseCard`, `BaseInput`, `BaseSelect`, `BaseTextarea`, `BaseCheckbox`, `BaseSwitch`, `BaseRadioGroup`, `BaseMenu`, `BaseAvatar`, `BaseSpinner`, `BaseAlert`, `BaseBadge`, `BaseSheet`, `ProgressBar`, `PriceCard`, `ToastHost`, `TabBar`, `GoogleButton`, `LocaleLinks`, `LocaleSheet`, `AuthShell`, `TourShell`, `InstallPrompt`, `UpdatePrompt`, `InstallSettings`, `SkeletonList`, `PageContainer`, `ErrorBoundary`, etc.) |
132
132
  | Composables | 16 (`useToast`, `useTheme`, `useMaterial`, `usePalette`, `useToday`, `useMediaQuery`, `useInstall`, `watchInstallability`, `createTabTransition`, `useThemeSync`, `useVisualViewport`, etc.) |
133
133
  | Utilities | 33 (`applyTheme`, `applyMaterial`, `applyPalette`, `MATERIALS`, `PALETTES`, `formatDate`, `fieldErrors`, `toAuthMessageKey`, `createAuthGuard`, `createQueryDefaults`, `createWriteReport`, `toRedirectPath`, `Supabase error mapper`, i18n runtime, etc.) |
134
134
  | Entry Points | `rei-kit`, `rei-kit/app`, `rei-kit/web`, `rei-kit/pwa`, `rei-kit/supabase`, `rei-kit/mobile.css`, `rei-kit/web.css`, and each stylesheet on its own |
package/dist/index.js CHANGED
@@ -4174,7 +4174,7 @@ function createI18nRuntime(options) {
4174
4174
  *
4175
4175
  * The fallback keeps `vitest` and `vite dev` honest, where no define runs.
4176
4176
  */
4177
- var VERSION = "2.13.0";
4177
+ var VERSION = "2.14.0";
4178
4178
  //#endregion
4179
4179
  export { AppError, AvatarStack_default as AvatarStack, BaseAlert_default as BaseAlert, BaseAvatar_default as BaseAvatar, BaseBadge_default as BaseBadge, BaseButton_default as BaseButton, BaseCalendar_default as BaseCalendar, BaseCard_default as BaseCard, BaseCheckbox_default as BaseCheckbox, BaseChip_default as BaseChip, BaseCombobox_default as BaseCombobox, BaseDatePicker_default as BaseDatePicker, BaseInput_default as BaseInput, BaseKbd_default as BaseKbd, BaseLink_default as BaseLink, BaseListbox_default as BaseListbox, BaseMenu_default as BaseMenu, BasePopconfirm_default as BasePopconfirm, BasePopover_default as BasePopover, BaseRadioGroup_default as BaseRadioGroup, BaseRating_default as BaseRating, BaseSelect_default as BaseSelect, BaseSeparator_default as BaseSeparator, BaseSheet_default as BaseSheet, BaseSkeleton_default as BaseSkeleton, BaseSlider_default as BaseSlider, BaseSpinner_default as BaseSpinner, BaseStepper_default as BaseStepper, BaseSwitch_default as BaseSwitch, BaseTable_default as BaseTable, BaseTextarea_default as BaseTextarea, CircularProgress_default as CircularProgress, CopyButton_default as CopyButton, DescriptionList_default as DescriptionList, EmptyState_default as EmptyState, ErrorBoundary_default as ErrorBoundary, FileDrop_default as FileDrop, FormField_default as FormField, GoogleButton_default as GoogleButton, LocaleLinks_default as LocaleLinks, MATERIALS, NumberInput_default as NumberInput, PALETTES, PageContainer_default as PageContainer, PageHeader_default as PageHeader, PinInput_default as PinInput, PriceCard_default as PriceCard, ProgressBar_default as ProgressBar, SHEET_ROOT_ID, SectionHeading_default as SectionHeading, SegmentedControl_default as SegmentedControl, SettingsGroup_default as SettingsGroup, SettingsRow_default as SettingsRow, SkeletonList_default as SkeletonList, StatCard_default as StatCard, TabBar_default as TabBar, TagsInput_default as TagsInput, TimePicker_default as TimePicker, ToastHost_default as ToastHost, ToggleGroup_default as ToggleGroup, ToneDot_default as ToneDot, VERSION, addDays, applyMaterial, applyPalette, applyTheme, createI18nRuntime, downloadJson, eachDayOfYear, ensureSheetRoot, formatDate, formatNumber, fromDateKey, isApplePortable, isInstalled, isMaterial, isPaletteName, isThemePreference, lastNDays, leadingBlanks, needsIosInstall, readStoredTheme, registerErrorMapper, relativeDayLabel, safeRedirect, setFormatLocale, setMaterialStorageKey, setPaletteStorageKey, setThemeStorageKey, startOfWeek, tapFeedback, toAppError, toDateKey, toRedirectPath, todayKey, useDebouncedCallback, useDragScroll, useMaterial, useMediaQuery, useOnline, usePalette, useTheme, useToast, useToday, useVisualViewport };
4180
4180
 
package/dist/styles.css CHANGED
@@ -3107,6 +3107,110 @@ to {
3107
3107
  }
3108
3108
  }
3109
3109
 
3110
+ .rk-mega[data-v-343f9362] {
3111
+ position: relative;
3112
+ }
3113
+ .rk-mega-bar[data-v-343f9362] {
3114
+ display: flex;
3115
+ align-items: center;
3116
+ gap: 0.25rem;
3117
+ }
3118
+ .rk-mega-item[data-v-343f9362] {
3119
+ position: static;
3120
+ }
3121
+ .rk-mega-top[data-v-343f9362] {
3122
+ display: inline-flex;
3123
+ align-items: center;
3124
+ gap: 0.25rem;
3125
+ border-radius: var(--radius-cell);
3126
+ padding: 0.5rem 0.75rem;
3127
+ font-size: 0.875rem;
3128
+ font-weight: 500;
3129
+ color: var(--color-ink-soft);
3130
+ transition: color var(--duration-fast) var(--ease-standard);
3131
+ }
3132
+ .rk-mega-top[data-v-343f9362]:hover,
3133
+ .rk-mega-top[aria-expanded='true'][data-v-343f9362] {
3134
+ color: var(--color-ink);
3135
+ }
3136
+ .rk-mega-top.is-active[data-v-343f9362] {
3137
+ color: var(--color-primary);
3138
+ }
3139
+ .rk-mega-twist[data-v-343f9362] {
3140
+ width: 0.875rem;
3141
+ height: 0.875rem;
3142
+ transition: rotate var(--duration-fast) var(--ease-standard);
3143
+ }
3144
+ .rk-mega-twist.is-open[data-v-343f9362] {
3145
+ rotate: 180deg;
3146
+ }
3147
+
3148
+ /* Full width of the bar rather than of the button: that is what makes it a
3149
+ mega menu and not a dropdown. */
3150
+ .rk-mega-panel[data-v-343f9362] {
3151
+ position: absolute;
3152
+ top: calc(100% + 0.5rem);
3153
+ left: 0;
3154
+ z-index: 50;
3155
+ width: 100%;
3156
+ border-radius: var(--radius-card);
3157
+ padding: 1.25rem;
3158
+ }
3159
+ .rk-mega-panel[hidden][data-v-343f9362] {
3160
+ display: none;
3161
+ }
3162
+ .rk-mega-columns[data-v-343f9362] {
3163
+ display: grid;
3164
+ grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
3165
+ gap: 1.5rem;
3166
+ }
3167
+ .rk-mega-column-title[data-v-343f9362] {
3168
+ margin-bottom: 0.5rem;
3169
+ font-size: 0.6875rem;
3170
+ font-weight: 600;
3171
+ letter-spacing: 0.04em;
3172
+ text-transform: uppercase;
3173
+ color: var(--color-ink-soft);
3174
+ }
3175
+ .rk-mega-links[data-v-343f9362] {
3176
+ display: flex;
3177
+ flex-direction: column;
3178
+ gap: 1px;
3179
+ }
3180
+ .rk-mega-link[data-v-343f9362] {
3181
+ display: block;
3182
+ border-radius: var(--radius-cell);
3183
+ padding: 0.375rem 0.5rem;
3184
+ transition: background-color var(--duration-fast) var(--ease-standard);
3185
+ }
3186
+ .rk-mega-link[data-v-343f9362]:hover {
3187
+ background: var(--color-muted);
3188
+ }
3189
+ .rk-mega-link-label[data-v-343f9362] {
3190
+ display: block;
3191
+ font-size: 0.875rem;
3192
+ color: var(--color-ink);
3193
+ }
3194
+ .rk-mega-link-note[data-v-343f9362] {
3195
+ display: block;
3196
+ margin-top: 0.125rem;
3197
+ font-size: 0.75rem;
3198
+ line-height: 1.4;
3199
+ color: var(--color-ink-soft);
3200
+ }
3201
+
3202
+ /* On a narrow screen the panel is the page width and the columns stack,
3203
+ because a four-column grid in a 390px column is four unreadable columns. */
3204
+ @media (max-width: 48rem) {
3205
+ .rk-mega-panel[data-v-343f9362] {
3206
+ padding: 1rem;
3207
+ }
3208
+ .rk-mega-columns[data-v-343f9362] {
3209
+ grid-template-columns: minmax(0, 1fr);
3210
+ gap: 1rem;
3211
+ }
3212
+ }
3213
+
3110
3214
  /* The root carries no layout of its own, and that is the fix for a real bug
3111
3215
  rather than a style preference.
3112
3216
 
@@ -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';