rei-kit 0.7.1 → 0.9.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 +19 -8
- package/dist/components/BaseSheet.vue.d.ts +2 -2
- package/dist/components/ToastHost.vue.d.ts +24 -0
- package/dist/composables/use-toast.d.ts +85 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +276 -79
- package/dist/index.js.map +1 -1
- package/dist/shell/mobile.css +93 -0
- package/dist/shell/web.css +78 -0
- package/dist/styles.css +40 -10
- package/dist/tokens.css +0 -82
- package/package.json +3 -1
package/README.md
CHANGED
|
@@ -108,12 +108,13 @@ import { createSupabaseClient } from 'rei-kit/supabase'
|
|
|
108
108
|
|
|
109
109
|
### Wiring the styles
|
|
110
110
|
|
|
111
|
-
Four lines, and
|
|
111
|
+
Four lines, and every one is load-bearing:
|
|
112
112
|
|
|
113
113
|
```css
|
|
114
114
|
/* your app's main.css */
|
|
115
115
|
@import 'tailwindcss';
|
|
116
116
|
@import 'rei-kit/tokens.css'; /* colour roles, the dark variant, measures, utilities */
|
|
117
|
+
@import 'rei-kit/shell/mobile.css'; /* or shell/web.css — see The shell, below */
|
|
117
118
|
@import 'rei-kit/styles.css'; /* compiled component styles */
|
|
118
119
|
|
|
119
120
|
/* Tailwind generates a utility only where it has seen the class, and it does
|
|
@@ -125,10 +126,10 @@ Four lines, and all four are load-bearing:
|
|
|
125
126
|
The path is relative to the CSS file, so adjust the `../` depth to where your
|
|
126
127
|
`main.css` sits.
|
|
127
128
|
|
|
128
|
-
**Leaving any of
|
|
129
|
+
**Leaving any of these out fails quietly:** the build succeeds, the
|
|
129
130
|
components mount, and they come out unstyled. Nothing type-checks this, so it
|
|
130
131
|
is worth a test — Hibi's `kit-styling.spec.ts` reads its own stylesheet and
|
|
131
|
-
asserts
|
|
132
|
+
asserts them, at unit-test speed. Copy it.
|
|
132
133
|
|
|
133
134
|
That test exists because the failure is real: Hibi shipped with the tab bar
|
|
134
135
|
invisible once, and separately spent three versions restating `tokens.css`
|
|
@@ -183,12 +184,22 @@ it — the same mistake as a hex inside a component, one axis over.
|
|
|
183
184
|
}
|
|
184
185
|
```
|
|
185
186
|
|
|
186
|
-
### The
|
|
187
|
+
### The shell
|
|
187
188
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
189
|
+
Tokens are what every app needs. A shell is a decision about what shape the app
|
|
190
|
+
is, so it is a separate import and there are two of them.
|
|
191
|
+
|
|
192
|
+
| | |
|
|
193
|
+
| -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
194
|
+
| `rei-kit/shell/mobile.css` | `shell-frame` (a 430px column at viewport height), `page-slide` and `page-auth` scroll containers, and the sliding transition between screens |
|
|
195
|
+
| `rei-kit/shell/web.css` | `.shell` — the page's column as a class, for a header or footer whose bar spans the window while its contents line up with the text — and a short fade between pages |
|
|
196
|
+
|
|
197
|
+
Both are opt-in throughout: nothing applies until a class lands on an element,
|
|
198
|
+
and both read `--measure-page` rather than declaring a width of their own.
|
|
199
|
+
|
|
200
|
+
They were one file until 0.9.0, and it was `tokens.css` — so a wide course site
|
|
201
|
+
downloaded a 430px column, a full-viewport height and an iOS sheet curve in
|
|
202
|
+
order to ignore them, and had no counterpart of its own.
|
|
192
203
|
|
|
193
204
|
### Prerendering
|
|
194
205
|
|
|
@@ -13,9 +13,9 @@ type __VLS_ModelProps = {
|
|
|
13
13
|
modelValue: boolean;
|
|
14
14
|
};
|
|
15
15
|
type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
|
|
16
|
-
declare var
|
|
16
|
+
declare var __VLS_26: {};
|
|
17
17
|
type __VLS_Slots = {} & {
|
|
18
|
-
default?: (props: typeof
|
|
18
|
+
default?: (props: typeof __VLS_26) => any;
|
|
19
19
|
};
|
|
20
20
|
declare const __VLS_base: import('vue').DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
|
|
21
21
|
"update:modelValue": (value: boolean) => any;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where the toasts land. One of these, at the app root.
|
|
3
|
+
*
|
|
4
|
+
* @example
|
|
5
|
+
* ```vue
|
|
6
|
+
* <!-- App.vue -->
|
|
7
|
+
* <ToastHost :close-label="$t('common.close')" />
|
|
8
|
+
* ```
|
|
9
|
+
*/
|
|
10
|
+
type __VLS_Props = {
|
|
11
|
+
/**
|
|
12
|
+
* The accessible name of each dismiss button. Required, because the button
|
|
13
|
+
* is an X and an X has no name — and the kit does not know the language.
|
|
14
|
+
*/
|
|
15
|
+
closeLabel: string;
|
|
16
|
+
/**
|
|
17
|
+
* Stack from the bottom instead of the top. For a phone shell, where the top
|
|
18
|
+
* is a status bar and a header and the thumb is nowhere near it.
|
|
19
|
+
*/
|
|
20
|
+
bottom?: boolean | undefined;
|
|
21
|
+
};
|
|
22
|
+
declare const __VLS_export: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
|
|
23
|
+
declare const _default: typeof __VLS_export;
|
|
24
|
+
export default _default;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Saying that something happened.
|
|
3
|
+
*
|
|
4
|
+
* The reason this exists is a measurement rather than a preference: the word
|
|
5
|
+
* "toast" appeared **zero times** across all three consuming apps. Not because
|
|
6
|
+
* they had decided against it — because there was no mechanism, so every save,
|
|
7
|
+
* every delete and every export finished in silence and the only way to know
|
|
8
|
+
* it had worked was that nothing had visibly broken.
|
|
9
|
+
*
|
|
10
|
+
* ── What is deliberately not here ──
|
|
11
|
+
*
|
|
12
|
+
* **No text.** The kit never knows a sentence. Callers pass the message; a
|
|
13
|
+
* component that called a translator would force one on the app.
|
|
14
|
+
*
|
|
15
|
+
* **Not for form errors.** A field that was rejected says so beside itself,
|
|
16
|
+
* where the reader's eye already is and where it stays until fixed. A toast
|
|
17
|
+
* that disappears after four seconds is the wrong place for something the
|
|
18
|
+
* reader has to act on. Use `BaseAlert` and `FormField` for those; use this
|
|
19
|
+
* for what has already happened.
|
|
20
|
+
*
|
|
21
|
+
* **A singleton, on purpose.** Two hosts would mean two stacks racing for the
|
|
22
|
+
* same corner. The store lives at module scope and `ToastHost` renders it.
|
|
23
|
+
*/
|
|
24
|
+
export type ToastTone = 'info' | 'success' | 'warning' | 'danger';
|
|
25
|
+
export interface Toast {
|
|
26
|
+
readonly id: number;
|
|
27
|
+
readonly message: string;
|
|
28
|
+
readonly tone: ToastTone;
|
|
29
|
+
/** Milliseconds on screen. `0` stays until dismissed. */
|
|
30
|
+
readonly duration: number;
|
|
31
|
+
}
|
|
32
|
+
export interface ToastOptions {
|
|
33
|
+
/** Milliseconds on screen; `0` stays until dismissed. */
|
|
34
|
+
duration?: number | undefined;
|
|
35
|
+
}
|
|
36
|
+
/** Removes a toast, whether it timed out or was dismissed. */
|
|
37
|
+
declare function dismiss(id: number): void;
|
|
38
|
+
/** Removes everything on screen. For a route change, or a sign-out. */
|
|
39
|
+
declare function dismissAll(): void;
|
|
40
|
+
/**
|
|
41
|
+
* Stops the clock on a toast the reader is pointing at.
|
|
42
|
+
*
|
|
43
|
+
* Somebody who has moved the pointer onto it is reading it, and taking it away
|
|
44
|
+
* mid-sentence is the one thing a notification must not do.
|
|
45
|
+
*/
|
|
46
|
+
declare function pause(id: number): void;
|
|
47
|
+
/** Starts it again, from where it stopped rather than from the beginning. */
|
|
48
|
+
declare function resume(id: number): void;
|
|
49
|
+
/**
|
|
50
|
+
* The stack, and the four ways to add to it.
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```ts
|
|
54
|
+
* const toast = useToast()
|
|
55
|
+
*
|
|
56
|
+
* toast.success(t('habit.saved'))
|
|
57
|
+
* toast.danger(t('common.failed'), { duration: 0 }) // stays until dismissed
|
|
58
|
+
*
|
|
59
|
+
* const id = toast.info(t('export.preparing'), { duration: 0 })
|
|
60
|
+
* toast.dismiss(id)
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
export declare function useToast(): {
|
|
64
|
+
/** Every toast on screen, oldest first. `ToastHost` renders this. */
|
|
65
|
+
toasts: Readonly<import('vue').Ref<readonly {
|
|
66
|
+
readonly id: number;
|
|
67
|
+
readonly message: string;
|
|
68
|
+
readonly tone: ToastTone;
|
|
69
|
+
readonly duration: number;
|
|
70
|
+
}[], readonly {
|
|
71
|
+
readonly id: number;
|
|
72
|
+
readonly message: string;
|
|
73
|
+
readonly tone: ToastTone;
|
|
74
|
+
readonly duration: number;
|
|
75
|
+
}[]>>;
|
|
76
|
+
info: (message: string, options?: ToastOptions) => number;
|
|
77
|
+
success: (message: string, options?: ToastOptions) => number;
|
|
78
|
+
warning: (message: string, options?: ToastOptions) => number;
|
|
79
|
+
danger: (message: string, options?: ToastOptions) => number;
|
|
80
|
+
dismiss: typeof dismiss;
|
|
81
|
+
dismissAll: typeof dismissAll;
|
|
82
|
+
pause: typeof pause;
|
|
83
|
+
resume: typeof resume;
|
|
84
|
+
};
|
|
85
|
+
export {};
|
package/dist/index.d.ts
CHANGED
|
@@ -40,6 +40,8 @@ export { useDebouncedCallback } from './composables/use-debounced-callback';
|
|
|
40
40
|
export { useDragScroll } from './composables/use-drag-scroll';
|
|
41
41
|
export { useMediaQuery } from './composables/use-media-query';
|
|
42
42
|
export { useVisualViewport } from './composables/use-visual-viewport';
|
|
43
|
+
export { useToast } from './composables/use-toast';
|
|
44
|
+
export type { Toast, ToastOptions, ToastTone } from './composables/use-toast';
|
|
43
45
|
export type { VisualViewportRect } from './composables/use-visual-viewport';
|
|
44
46
|
export { default as BaseAlert } from './components/BaseAlert.vue';
|
|
45
47
|
export { default as BaseBadge } from './components/BaseBadge.vue';
|
|
@@ -64,6 +66,7 @@ export { default as SettingsGroup } from './components/SettingsGroup.vue';
|
|
|
64
66
|
export { default as SettingsRow } from './components/SettingsRow.vue';
|
|
65
67
|
export { default as SkeletonList } from './components/SkeletonList.vue';
|
|
66
68
|
export { default as StatCard } from './components/StatCard.vue';
|
|
69
|
+
export { default as ToastHost } from './components/ToastHost.vue';
|
|
67
70
|
export { default as ToneDot } from './components/ToneDot.vue';
|
|
68
71
|
export type { Tone } from './components/SectionHeading.vue';
|
|
69
72
|
export { default as LocaleLinks } from './components/LocaleLinks.vue';
|