rei-kit 0.12.0 → 0.13.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/_plugin-vue_export-helper-3AcMDTtW.js +339 -0
- package/dist/_plugin-vue_export-helper-3AcMDTtW.js.map +1 -0
- package/dist/app/AuthShell.vue.d.ts +29 -0
- package/dist/app/index.d.ts +16 -0
- package/dist/app/use-tab-transition.d.ts +52 -0
- package/dist/app/use-theme-sync.d.ts +23 -0
- package/dist/app.js +140 -0
- package/dist/app.js.map +1 -0
- package/dist/components/BaseCard.vue.d.ts +11 -2
- package/dist/index.js +22 -436
- package/dist/index.js.map +1 -1
- package/dist/pwa/InstallPrompt.vue.d.ts +26 -0
- package/dist/pwa/UpdatePrompt.vue.d.ts +48 -0
- package/dist/pwa/index.d.ts +15 -0
- package/dist/pwa/use-install.d.ts +41 -0
- package/dist/pwa/use-snooze.d.ts +22 -0
- package/dist/pwa.js +236 -0
- package/dist/pwa.js.map +1 -0
- package/dist/styles.css +69 -0
- package/dist/use-theme-_MnaDD5v.js +94 -0
- package/dist/use-theme-_MnaDD5v.js.map +1 -0
- package/package.json +9 -1
package/dist/app.js
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { a as useTheme, n as isThemePreference } from "./use-theme-_MnaDD5v.js";
|
|
2
|
+
import { createCommentVNode, createElementBlock, createElementVNode, defineComponent, openBlock, readonly, ref, renderSlot, watch } from "vue";
|
|
3
|
+
//#region src/app/AuthShell.vue?vue&type=script&setup=true&lang.ts
|
|
4
|
+
var _hoisted_1 = { class: "flex min-h-0 w-full flex-1 flex-col items-center gap-8 overflow-y-auto px-6 pt-10 pb-10" };
|
|
5
|
+
var _hoisted_2 = { class: "w-full max-w-[22rem]" };
|
|
6
|
+
var _hoisted_3 = {
|
|
7
|
+
key: 0,
|
|
8
|
+
class: "mt-auto"
|
|
9
|
+
};
|
|
10
|
+
//#endregion
|
|
11
|
+
//#region src/app/AuthShell.vue
|
|
12
|
+
var AuthShell_default = /* @__PURE__ */ defineComponent({
|
|
13
|
+
__name: "AuthShell",
|
|
14
|
+
setup(__props) {
|
|
15
|
+
/**
|
|
16
|
+
* The frame every sign-in screen sits in.
|
|
17
|
+
*
|
|
18
|
+
* A brand mark, a narrow column, and the language links pinned to the bottom.
|
|
19
|
+
* The two phone apps had this file character for character — thirty-seven
|
|
20
|
+
* lines, no difference at all — and the only thing either would want to change
|
|
21
|
+
* is what goes in the slots.
|
|
22
|
+
*
|
|
23
|
+
* The language links matter more than they look. Sign-in is the first screen a
|
|
24
|
+
* new user sees and Settings is behind it, so without a way to switch here,
|
|
25
|
+
* somebody who does not read the browser's language cannot get to one.
|
|
26
|
+
*/
|
|
27
|
+
return (_ctx, _cache) => {
|
|
28
|
+
return openBlock(), createElementBlock("div", _hoisted_1, [
|
|
29
|
+
renderSlot(_ctx.$slots, "brand"),
|
|
30
|
+
createElementVNode("main", _hoisted_2, [renderSlot(_ctx.$slots, "default")]),
|
|
31
|
+
_ctx.$slots.foot ? (openBlock(), createElementBlock("div", _hoisted_3, [renderSlot(_ctx.$slots, "foot")])) : createCommentVNode("", true)
|
|
32
|
+
]);
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
//#endregion
|
|
37
|
+
//#region src/app/use-tab-transition.ts
|
|
38
|
+
/**
|
|
39
|
+
* Which way a tabbed app is moving.
|
|
40
|
+
*
|
|
41
|
+
* A phone app slides sideways between its tabs, and the direction has to come
|
|
42
|
+
* from somewhere: going from the second tab to the fourth is forward, the
|
|
43
|
+
* other way is back, and arriving from nowhere is neither. That is index
|
|
44
|
+
* arithmetic over the tab order, and it was written twice, identically, in the
|
|
45
|
+
* two phone apps this kit came from — thirty-four lines each, byte for byte
|
|
46
|
+
* the same.
|
|
47
|
+
*
|
|
48
|
+
* Generic over the tab key, so the app keeps its own union and the kit never
|
|
49
|
+
* learns what a tab is called.
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* ```ts
|
|
53
|
+
* // shared/lib/tabs.ts
|
|
54
|
+
* export const tabs = createTabTransition(['today', 'week', 'year', 'profile'] as const)
|
|
55
|
+
*
|
|
56
|
+
* // the router guard
|
|
57
|
+
* router.afterEach((to, from) => tabs.resolve(to.meta.tab, from.meta.tab))
|
|
58
|
+
*
|
|
59
|
+
* // App.vue
|
|
60
|
+
* const name = computed(() =>
|
|
61
|
+
* tabs.direction.value === 'none' ? '' : `slide-${tabs.direction.value}`,
|
|
62
|
+
* )
|
|
63
|
+
* ```
|
|
64
|
+
*
|
|
65
|
+
* The `slide-forward-*` and `slide-backward-*` classes those names refer to
|
|
66
|
+
* ship in `rei-kit/shell/mobile.css`.
|
|
67
|
+
*/
|
|
68
|
+
function createTabTransition(order) {
|
|
69
|
+
const direction = ref("none");
|
|
70
|
+
let override = null;
|
|
71
|
+
return {
|
|
72
|
+
/** Direction of the current tab change. Read by the route transition. */
|
|
73
|
+
direction: readonly(direction),
|
|
74
|
+
/**
|
|
75
|
+
* Resolves the direction for a navigation. Call once per route change.
|
|
76
|
+
*
|
|
77
|
+
* @param to - Tab being entered, if the route has one.
|
|
78
|
+
* @param from - Tab being left, if the route had one.
|
|
79
|
+
*/
|
|
80
|
+
resolve(to, from) {
|
|
81
|
+
if (override) {
|
|
82
|
+
direction.value = override;
|
|
83
|
+
override = null;
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
if (!to || !from || to === from) {
|
|
87
|
+
direction.value = "none";
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
direction.value = order.indexOf(to) > order.indexOf(from) ? "forward" : "backward";
|
|
91
|
+
},
|
|
92
|
+
/**
|
|
93
|
+
* Forces the next navigation's direction, whatever the indices say.
|
|
94
|
+
*
|
|
95
|
+
* For the navigations that are not a tab change at heart: going back from
|
|
96
|
+
* a detail screen, or being sent to sign-in. Without it, leaving a detail
|
|
97
|
+
* page under the fourth tab for the first tab slides backward, which is
|
|
98
|
+
* right, and arriving there slides forward, which is not.
|
|
99
|
+
*/
|
|
100
|
+
force(next) {
|
|
101
|
+
override = next;
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
//#endregion
|
|
106
|
+
//#region src/app/use-theme-sync.ts
|
|
107
|
+
/**
|
|
108
|
+
* Adopts the theme stored on the account, once, as soon as it arrives.
|
|
109
|
+
*
|
|
110
|
+
* Two things make this worth a component rather than four lines at a call
|
|
111
|
+
* site, and both are about *once*.
|
|
112
|
+
*
|
|
113
|
+
* It has to run at the app root rather than on the settings screen, or a user
|
|
114
|
+
* on a fresh device keeps the system theme until they happen to open Profile.
|
|
115
|
+
* And it has to run once and never again, or a later refetch of the profile
|
|
116
|
+
* undoes a choice the user has just made locally — the theme flips back under
|
|
117
|
+
* them a second after they set it, which reads as the app fighting them.
|
|
118
|
+
*
|
|
119
|
+
* The source is a ref rather than a query, so the kit never learns what a
|
|
120
|
+
* profile is or where it came from.
|
|
121
|
+
*
|
|
122
|
+
* @example
|
|
123
|
+
* ```ts
|
|
124
|
+
* const { data: profile } = useProfile()
|
|
125
|
+
* useThemeSync(computed(() => profile.value?.theme))
|
|
126
|
+
* ```
|
|
127
|
+
*/
|
|
128
|
+
function useThemeSync(stored) {
|
|
129
|
+
const theme = useTheme();
|
|
130
|
+
let adopted = false;
|
|
131
|
+
watch(stored, (next) => {
|
|
132
|
+
if (adopted || next === null || next === void 0) return;
|
|
133
|
+
adopted = true;
|
|
134
|
+
if (isThemePreference(next) && next !== theme.value) theme.value = next;
|
|
135
|
+
}, { immediate: true });
|
|
136
|
+
}
|
|
137
|
+
//#endregion
|
|
138
|
+
export { AuthShell_default as AuthShell, createTabTransition, useThemeSync };
|
|
139
|
+
|
|
140
|
+
//# sourceMappingURL=app.js.map
|
package/dist/app.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app.js","names":["$slots"],"sources":["../src/app/AuthShell.vue","../src/app/AuthShell.vue","../src/app/use-tab-transition.ts","../src/app/use-theme-sync.ts"],"sourcesContent":["<script setup lang=\"ts\">\n/**\n * The frame every sign-in screen sits in.\n *\n * A brand mark, a narrow column, and the language links pinned to the bottom.\n * The two phone apps had this file character for character — thirty-seven\n * lines, no difference at all — and the only thing either would want to change\n * is what goes in the slots.\n *\n * The language links matter more than they look. Sign-in is the first screen a\n * new user sees and Settings is behind it, so without a way to switch here,\n * somebody who does not read the browser's language cannot get to one.\n */\ndefineSlots<{\n /** The brand mark. */\n brand?: () => unknown\n /** The form. */\n default: () => unknown\n /** The language links, or anything else that belongs at the foot. */\n foot?: () => unknown\n}>()\n</script>\n\n<template>\n <div\n class=\"flex min-h-0 w-full flex-1 flex-col items-center gap-8 overflow-y-auto px-6 pt-10 pb-10\"\n >\n <slot name=\"brand\" />\n\n <main class=\"w-full max-w-[22rem]\">\n <slot />\n </main>\n\n <div v-if=\"$slots.foot\" class=\"mt-auto\">\n <slot name=\"foot\" />\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\n/**\n * The frame every sign-in screen sits in.\n *\n * A brand mark, a narrow column, and the language links pinned to the bottom.\n * The two phone apps had this file character for character — thirty-seven\n * lines, no difference at all — and the only thing either would want to change\n * is what goes in the slots.\n *\n * The language links matter more than they look. Sign-in is the first screen a\n * new user sees and Settings is behind it, so without a way to switch here,\n * somebody who does not read the browser's language cannot get to one.\n */\ndefineSlots<{\n /** The brand mark. */\n brand?: () => unknown\n /** The form. */\n default: () => unknown\n /** The language links, or anything else that belongs at the foot. */\n foot?: () => unknown\n}>()\n</script>\n\n<template>\n <div\n class=\"flex min-h-0 w-full flex-1 flex-col items-center gap-8 overflow-y-auto px-6 pt-10 pb-10\"\n >\n <slot name=\"brand\" />\n\n <main class=\"w-full max-w-[22rem]\">\n <slot />\n </main>\n\n <div v-if=\"$slots.foot\" class=\"mt-auto\">\n <slot name=\"foot\" />\n </div>\n </div>\n</template>\n","import { readonly, ref } from 'vue'\n\n/** Which way the screens slide during a tab change. */\nexport type SlideDirection = 'forward' | 'backward' | 'none'\n\n/**\n * Which way a tabbed app is moving.\n *\n * A phone app slides sideways between its tabs, and the direction has to come\n * from somewhere: going from the second tab to the fourth is forward, the\n * other way is back, and arriving from nowhere is neither. That is index\n * arithmetic over the tab order, and it was written twice, identically, in the\n * two phone apps this kit came from — thirty-four lines each, byte for byte\n * the same.\n *\n * Generic over the tab key, so the app keeps its own union and the kit never\n * learns what a tab is called.\n *\n * @example\n * ```ts\n * // shared/lib/tabs.ts\n * export const tabs = createTabTransition(['today', 'week', 'year', 'profile'] as const)\n *\n * // the router guard\n * router.afterEach((to, from) => tabs.resolve(to.meta.tab, from.meta.tab))\n *\n * // App.vue\n * const name = computed(() =>\n * tabs.direction.value === 'none' ? '' : `slide-${tabs.direction.value}`,\n * )\n * ```\n *\n * The `slide-forward-*` and `slide-backward-*` classes those names refer to\n * ship in `rei-kit/shell/mobile.css`.\n */\nexport function createTabTransition<K extends string>(order: readonly K[]) {\n const direction = ref<SlideDirection>('none')\n let override: SlideDirection | null = null\n\n return {\n /** Direction of the current tab change. Read by the route transition. */\n direction: readonly(direction),\n\n /**\n * Resolves the direction for a navigation. Call once per route change.\n *\n * @param to - Tab being entered, if the route has one.\n * @param from - Tab being left, if the route had one.\n */\n resolve(to: K | undefined, from: K | undefined): void {\n if (override) {\n direction.value = override\n override = null\n\n return\n }\n\n if (!to || !from || to === from) {\n direction.value = 'none'\n\n return\n }\n\n direction.value = order.indexOf(to) > order.indexOf(from) ? 'forward' : 'backward'\n },\n\n /**\n * Forces the next navigation's direction, whatever the indices say.\n *\n * For the navigations that are not a tab change at heart: going back from\n * a detail screen, or being sent to sign-in. Without it, leaving a detail\n * page under the fourth tab for the first tab slides backward, which is\n * right, and arriving there slides forward, which is not.\n */\n force(next: SlideDirection): void {\n override = next\n },\n }\n}\n","import { watch } from 'vue'\nimport type { Ref } from 'vue'\n\nimport { isThemePreference, useTheme } from '../composables/use-theme'\n\n/**\n * Adopts the theme stored on the account, once, as soon as it arrives.\n *\n * Two things make this worth a component rather than four lines at a call\n * site, and both are about *once*.\n *\n * It has to run at the app root rather than on the settings screen, or a user\n * on a fresh device keeps the system theme until they happen to open Profile.\n * And it has to run once and never again, or a later refetch of the profile\n * undoes a choice the user has just made locally — the theme flips back under\n * them a second after they set it, which reads as the app fighting them.\n *\n * The source is a ref rather than a query, so the kit never learns what a\n * profile is or where it came from.\n *\n * @example\n * ```ts\n * const { data: profile } = useProfile()\n * useThemeSync(computed(() => profile.value?.theme))\n * ```\n */\nexport function useThemeSync(stored: Ref<string | null | undefined>): void {\n const theme = useTheme()\n\n let adopted = false\n\n watch(\n stored,\n (next) => {\n if (adopted || next === null || next === undefined) return\n\n adopted = true\n\n if (isThemePreference(next) && next !== theme.value) {\n theme.value = next\n }\n },\n { immediate: true },\n )\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;GAwBE,OAAA,UAAA,GAAA,mBAYM,OAZN,YAYM;IATJ,WAAqB,KAAA,QAAA,OAAA;IAErB,mBAEO,QAFP,YAEO,CADL,WAAQ,KAAA,QAAA,SAAA,CAAA,CAAA;IAGCA,KAAAA,OAAO,QAAlB,UAAA,GAAA,mBAEM,OAFN,YAEM,CADJ,WAAoB,KAAA,QAAA,MAAA,CAAA,CAAA,KAAA,mBAAA,IAAA,IAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AEC1B,SAAgB,oBAAsC,OAAqB;CACzE,MAAM,YAAY,IAAoB,MAAM;CAC5C,IAAI,WAAkC;CAEtC,OAAO;;EAEL,WAAW,SAAS,SAAS;;;;;;;EAQ7B,QAAQ,IAAmB,MAA2B;GACpD,IAAI,UAAU;IACZ,UAAU,QAAQ;IAClB,WAAW;IAEX;GACF;GAEA,IAAI,CAAC,MAAM,CAAC,QAAQ,OAAO,MAAM;IAC/B,UAAU,QAAQ;IAElB;GACF;GAEA,UAAU,QAAQ,MAAM,QAAQ,EAAE,IAAI,MAAM,QAAQ,IAAI,IAAI,YAAY;EAC1E;;;;;;;;;EAUA,MAAM,MAA4B;GAChC,WAAW;EACb;CACF;AACF;;;;;;;;;;;;;;;;;;;;;;;;ACpDA,SAAgB,aAAa,QAA8C;CACzE,MAAM,QAAQ,SAAS;CAEvB,IAAI,UAAU;CAEd,MACE,SACC,SAAS;EACR,IAAI,WAAW,SAAS,QAAQ,SAAS,KAAA,GAAW;EAEpD,UAAU;EAEV,IAAI,kBAAkB,IAAI,KAAK,SAAS,MAAM,OAC5C,MAAM,QAAQ;CAElB,GACA,EAAE,WAAW,KAAK,CACpB;AACF"}
|
|
@@ -6,6 +6,13 @@
|
|
|
6
6
|
* so a card on one screen had a heavier border than a card on the next and
|
|
7
7
|
* nobody could say why.
|
|
8
8
|
*
|
|
9
|
+
* With no head and no foot there is no wrapper div: the padding lands on the
|
|
10
|
+
* card itself and the card *is* the element. That matters more than a saved
|
|
11
|
+
* node — most cards in the apps lay their contents out (`flex items-center
|
|
12
|
+
* gap-4`, `flex flex-col gap-3`), and with a wrapper in the way those classes
|
|
13
|
+
* reach the border and not the content, so the app has to add back the div
|
|
14
|
+
* this component exists to remove. One that makes you do that is one you skip.
|
|
15
|
+
*
|
|
9
16
|
* `interactive` is for a card that is a link or a button: it adds the lift and
|
|
10
17
|
* the press, and it is opt-in because a card holding a form should not move
|
|
11
18
|
* when the pointer crosses it.
|
|
@@ -28,13 +35,15 @@ type __VLS_Props = {
|
|
|
28
35
|
*/
|
|
29
36
|
padding?: 'none' | 'sm' | 'md' | 'lg' | undefined;
|
|
30
37
|
};
|
|
31
|
-
declare var __VLS_8: {}, __VLS_10: {}, __VLS_12: {};
|
|
38
|
+
declare var __VLS_8: {}, __VLS_10: {}, __VLS_12: {}, __VLS_14: {};
|
|
32
39
|
type __VLS_Slots = {} & {
|
|
33
40
|
head?: (props: typeof __VLS_8) => any;
|
|
34
41
|
} & {
|
|
35
42
|
default?: (props: typeof __VLS_10) => any;
|
|
36
43
|
} & {
|
|
37
|
-
|
|
44
|
+
default?: (props: typeof __VLS_12) => any;
|
|
45
|
+
} & {
|
|
46
|
+
foot?: (props: typeof __VLS_14) => any;
|
|
38
47
|
};
|
|
39
48
|
declare const __VLS_base: 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>;
|
|
40
49
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|