rei-kit 0.8.0 → 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/index.js +1 -1
- package/dist/shell/mobile.css +93 -0
- package/dist/shell/web.css +78 -0
- 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
|
|
package/dist/index.js
CHANGED
|
@@ -2385,7 +2385,7 @@ function createI18nRuntime(options) {
|
|
|
2385
2385
|
*
|
|
2386
2386
|
* The fallback keeps `vitest` and `vite dev` honest, where no define runs.
|
|
2387
2387
|
*/
|
|
2388
|
-
var VERSION = "0.
|
|
2388
|
+
var VERSION = "0.9.0";
|
|
2389
2389
|
//#endregion
|
|
2390
2390
|
export { AppError, BaseAlert_default as BaseAlert, BaseBadge_default as BaseBadge, BaseButton_default as BaseButton, BaseCard_default as BaseCard, BaseCheckbox_default as BaseCheckbox, BaseInput_default as BaseInput, BaseRadioGroup_default as BaseRadioGroup, BaseSelect_default as BaseSelect, BaseSheet_default as BaseSheet, BaseTextarea_default as BaseTextarea, EmptyState_default as EmptyState, ErrorBoundary_default as ErrorBoundary, FormField_default as FormField, GoogleButton_default as GoogleButton, LocaleLinks_default as LocaleLinks, PageContainer_default as PageContainer, PageHeader_default as PageHeader, PriceCard_default as PriceCard, ProgressBar_default as ProgressBar, 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, ToastHost_default as ToastHost, ToneDot_default as ToneDot, VERSION, addDays, applyTheme, createI18nRuntime, downloadJson, eachDayOfYear, formatDate, fromDateKey, isApplePortable, isInstalled, isThemePreference, lastNDays, leadingBlanks, needsIosInstall, readStoredTheme, registerErrorMapper, relativeDayLabel, safeRedirect, setFormatLocale, setThemeStorageKey, startOfWeek, tapFeedback, toAppError, toDateKey, todayKey, useDebouncedCallback, useDragScroll, useMediaQuery, useOnline, useTheme, useToast, useToday, useVisualViewport };
|
|
2391
2391
|
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/* rei-kit — the phone shell.
|
|
2
|
+
*
|
|
3
|
+
* Split out of `tokens.css` in 0.9.0. It had been shipped to every consumer
|
|
4
|
+
* including a wide site that used none of it: a 430px column, a full-viewport
|
|
5
|
+
* height and an iOS sheet curve, downloaded by a course site so it could
|
|
6
|
+
* ignore them. Tokens are what every app needs; a shell is a decision about
|
|
7
|
+
* what shape the app is.
|
|
8
|
+
*
|
|
9
|
+
* Import it alongside the tokens when the app is phone-shaped:
|
|
10
|
+
*
|
|
11
|
+
* @import 'rei-kit/tokens.css';
|
|
12
|
+
* @import 'rei-kit/shell/mobile.css';
|
|
13
|
+
*
|
|
14
|
+
* Everything here is opt-in. Nothing applies until a class lands on an element.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
@layer components {
|
|
18
|
+
/* Geometry of the phone shell. Shared by the shell itself and by overlays
|
|
19
|
+
that must line up with it (BaseSheet teleports outside the app tree). */
|
|
20
|
+
.shell-frame {
|
|
21
|
+
height: 100dvh;
|
|
22
|
+
@apply w-full max-w-[430px] md:h-[880px] md:max-h-[92vh];
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/* ---- Screen wrapper ----
|
|
26
|
+
Lands on every view's root element (see App.vue), so this is the one place
|
|
27
|
+
that owns the scroll box, the side gutter and the room the floating tab bar
|
|
28
|
+
needs at the bottom. Views only decide their own inner layout. */
|
|
29
|
+
/* Auth screens have no tab bar and no action button, so they get none of the
|
|
30
|
+
bottom clearance the app screens need. */
|
|
31
|
+
.page-auth {
|
|
32
|
+
@apply no-scrollbar h-full w-full overflow-y-auto px-4;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.page-slide {
|
|
36
|
+
/* pb clears the floating tab bar and the action button above it, so the
|
|
37
|
+
last row of any list stays reachable. */
|
|
38
|
+
@apply no-scrollbar h-full w-full overflow-y-auto px-4 pb-44;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.slide-forward-enter-active,
|
|
42
|
+
.slide-forward-leave-active,
|
|
43
|
+
.slide-backward-enter-active,
|
|
44
|
+
.slide-backward-leave-active {
|
|
45
|
+
position: absolute;
|
|
46
|
+
inset: 0;
|
|
47
|
+
will-change: transform, opacity;
|
|
48
|
+
/* iOS sheet curve: quick take-off, long soft landing. */
|
|
49
|
+
transition:
|
|
50
|
+
transform 340ms cubic-bezier(0.32, 0.72, 0, 1),
|
|
51
|
+
opacity 340ms cubic-bezier(0.32, 0.72, 0, 1),
|
|
52
|
+
filter 340ms cubic-bezier(0.32, 0.72, 0, 1);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/* The incoming screen travels the full width; the outgoing one moves a
|
|
56
|
+
quarter of it and dims. The speed difference reads as depth. */
|
|
57
|
+
.slide-forward-enter-from {
|
|
58
|
+
transform: translate3d(100%, 0, 0);
|
|
59
|
+
}
|
|
60
|
+
.slide-forward-leave-to {
|
|
61
|
+
transform: translate3d(-25%, 0, 0) scale(0.96);
|
|
62
|
+
opacity: 0;
|
|
63
|
+
filter: brightness(0.92);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.slide-backward-enter-from {
|
|
67
|
+
transform: translate3d(-100%, 0, 0);
|
|
68
|
+
}
|
|
69
|
+
.slide-backward-leave-to {
|
|
70
|
+
transform: translate3d(25%, 0, 0) scale(0.96);
|
|
71
|
+
opacity: 0;
|
|
72
|
+
filter: brightness(0.92);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
@media (prefers-reduced-motion: reduce) {
|
|
77
|
+
.slide-forward-enter-active,
|
|
78
|
+
.slide-forward-leave-active,
|
|
79
|
+
.slide-backward-enter-active,
|
|
80
|
+
.slide-backward-leave-active {
|
|
81
|
+
/* Not 0ms: some browsers never fire transitionend at zero, which would
|
|
82
|
+
leave Vue waiting before removing the element. */
|
|
83
|
+
transition-duration: 1ms;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.slide-forward-enter-from,
|
|
87
|
+
.slide-backward-enter-from,
|
|
88
|
+
.slide-forward-leave-to,
|
|
89
|
+
.slide-backward-leave-to {
|
|
90
|
+
transform: none;
|
|
91
|
+
filter: none;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/* rei-kit — the wide shell.
|
|
2
|
+
*
|
|
3
|
+
* The counterpart to `shell/mobile.css`, for an app that is a site rather than
|
|
4
|
+
* a phone: a column with gutters, and a transition between pages that is a
|
|
5
|
+
* fade rather than a slide.
|
|
6
|
+
*
|
|
7
|
+
* Extracted from the kit's first wide consumer rather than invented. A shell
|
|
8
|
+
* is a decision about what shape the app is, and this one had already been
|
|
9
|
+
* made and written down once.
|
|
10
|
+
*
|
|
11
|
+
* @import 'rei-kit/tokens.css';
|
|
12
|
+
* @import 'rei-kit/shell/web.css';
|
|
13
|
+
*
|
|
14
|
+
* Opt-in throughout. Nothing applies until a class lands on an element.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
@layer components {
|
|
18
|
+
/* The page's column, as a class.
|
|
19
|
+
*
|
|
20
|
+
* `PageContainer` is the same measure as a component, and is the right
|
|
21
|
+
* choice when the container is the element. This is for the ones where it is
|
|
22
|
+
* not: a `<header>` whose bar spans the window while its contents line up
|
|
23
|
+
* with the text, a `<footer>`, a hero that paints edge to edge. Wrapping
|
|
24
|
+
* those in a component means an extra div whose only job is a max-width.
|
|
25
|
+
*
|
|
26
|
+
* Both read `--measure-page`, so a page cannot disagree with itself by 80px
|
|
27
|
+
* depending on which one it used. */
|
|
28
|
+
.shell {
|
|
29
|
+
margin-inline: auto;
|
|
30
|
+
inline-size: 100%;
|
|
31
|
+
max-inline-size: var(--measure-page);
|
|
32
|
+
padding-inline: 1.25rem;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
@media (min-width: 640px) {
|
|
36
|
+
.shell {
|
|
37
|
+
padding-inline: 2rem;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/* ---- Between pages ----
|
|
43
|
+
Short, and only ever a fade with a few pixels of travel. A page transition
|
|
44
|
+
that can be described afterwards is too long: the reader asked to go
|
|
45
|
+
somewhere, and the animation's whole job is to stop the new page arriving as
|
|
46
|
+
a flash of unrelated content.
|
|
47
|
+
|
|
48
|
+
Leaving is half the length of arriving. The old page is not worth watching,
|
|
49
|
+
and matching the two makes every navigation feel like it is being
|
|
50
|
+
considered. */
|
|
51
|
+
.page-enter-active {
|
|
52
|
+
transition:
|
|
53
|
+
opacity 260ms ease-out,
|
|
54
|
+
transform 260ms cubic-bezier(0.22, 1, 0.36, 1);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.page-leave-active {
|
|
58
|
+
transition:
|
|
59
|
+
opacity 130ms ease-in,
|
|
60
|
+
transform 130ms ease-in;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.page-enter-from {
|
|
64
|
+
opacity: 0;
|
|
65
|
+
transform: translateY(8px);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.page-leave-to {
|
|
69
|
+
opacity: 0;
|
|
70
|
+
transform: translateY(-4px);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
@media (prefers-reduced-motion: reduce) {
|
|
74
|
+
.page-enter-active,
|
|
75
|
+
.page-leave-active {
|
|
76
|
+
transition: none;
|
|
77
|
+
}
|
|
78
|
+
}
|
package/dist/tokens.css
CHANGED
|
@@ -67,85 +67,3 @@
|
|
|
67
67
|
@utility pb-safe {
|
|
68
68
|
padding-bottom: calc(var(--pb-safe, 0px) + env(safe-area-inset-bottom, 0px));
|
|
69
69
|
}
|
|
70
|
-
|
|
71
|
-
/* ── The phone shell ────────────────────────────────────────────────────────
|
|
72
|
-
Geometry shared by the shell and by anything that has to line up with it —
|
|
73
|
-
a sheet teleported outside the app tree, for instance. Opt in by putting
|
|
74
|
-
.shell-frame on the container; nothing here applies on its own. */
|
|
75
|
-
@layer components {
|
|
76
|
-
/* Geometry of the phone shell. Shared by the shell itself and by overlays
|
|
77
|
-
that must line up with it (BaseSheet teleports outside the app tree). */
|
|
78
|
-
.shell-frame {
|
|
79
|
-
height: 100dvh;
|
|
80
|
-
@apply w-full max-w-[430px] md:h-[880px] md:max-h-[92vh];
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/* ---- Screen wrapper ----
|
|
84
|
-
Lands on every view's root element (see App.vue), so this is the one place
|
|
85
|
-
that owns the scroll box, the side gutter and the room the floating tab bar
|
|
86
|
-
needs at the bottom. Views only decide their own inner layout. */
|
|
87
|
-
/* Auth screens have no tab bar and no action button, so they get none of the
|
|
88
|
-
bottom clearance the app screens need. */
|
|
89
|
-
.page-auth {
|
|
90
|
-
@apply no-scrollbar h-full w-full overflow-y-auto px-4;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
.page-slide {
|
|
94
|
-
/* pb clears the floating tab bar and the action button above it, so the
|
|
95
|
-
last row of any list stays reachable. */
|
|
96
|
-
@apply no-scrollbar h-full w-full overflow-y-auto px-4 pb-44;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
.slide-forward-enter-active,
|
|
100
|
-
.slide-forward-leave-active,
|
|
101
|
-
.slide-backward-enter-active,
|
|
102
|
-
.slide-backward-leave-active {
|
|
103
|
-
position: absolute;
|
|
104
|
-
inset: 0;
|
|
105
|
-
will-change: transform, opacity;
|
|
106
|
-
/* iOS sheet curve: quick take-off, long soft landing. */
|
|
107
|
-
transition:
|
|
108
|
-
transform 340ms cubic-bezier(0.32, 0.72, 0, 1),
|
|
109
|
-
opacity 340ms cubic-bezier(0.32, 0.72, 0, 1),
|
|
110
|
-
filter 340ms cubic-bezier(0.32, 0.72, 0, 1);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
/* The incoming screen travels the full width; the outgoing one moves a
|
|
114
|
-
quarter of it and dims. The speed difference reads as depth. */
|
|
115
|
-
.slide-forward-enter-from {
|
|
116
|
-
transform: translate3d(100%, 0, 0);
|
|
117
|
-
}
|
|
118
|
-
.slide-forward-leave-to {
|
|
119
|
-
transform: translate3d(-25%, 0, 0) scale(0.96);
|
|
120
|
-
opacity: 0;
|
|
121
|
-
filter: brightness(0.92);
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
.slide-backward-enter-from {
|
|
125
|
-
transform: translate3d(-100%, 0, 0);
|
|
126
|
-
}
|
|
127
|
-
.slide-backward-leave-to {
|
|
128
|
-
transform: translate3d(25%, 0, 0) scale(0.96);
|
|
129
|
-
opacity: 0;
|
|
130
|
-
filter: brightness(0.92);
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
@media (prefers-reduced-motion: reduce) {
|
|
135
|
-
.slide-forward-enter-active,
|
|
136
|
-
.slide-forward-leave-active,
|
|
137
|
-
.slide-backward-enter-active,
|
|
138
|
-
.slide-backward-leave-active {
|
|
139
|
-
/* Not 0ms: some browsers never fire transitionend at zero, which would
|
|
140
|
-
leave Vue waiting before removing the element. */
|
|
141
|
-
transition-duration: 1ms;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
.slide-forward-enter-from,
|
|
145
|
-
.slide-backward-enter-from,
|
|
146
|
-
.slide-forward-leave-to,
|
|
147
|
-
.slide-backward-leave-to {
|
|
148
|
-
transform: none;
|
|
149
|
-
filter: none;
|
|
150
|
-
}
|
|
151
|
-
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rei-kit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "Vue 3 and Tailwind 4 design system and shared runtime. Extracted from Hibi.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Ramazan Doğan",
|
|
@@ -21,6 +21,8 @@
|
|
|
21
21
|
"import": "./dist/index.js"
|
|
22
22
|
},
|
|
23
23
|
"./tokens.css": "./dist/tokens.css",
|
|
24
|
+
"./shell/mobile.css": "./dist/shell/mobile.css",
|
|
25
|
+
"./shell/web.css": "./dist/shell/web.css",
|
|
24
26
|
"./styles.css": "./dist/styles.css",
|
|
25
27
|
"./supabase": {
|
|
26
28
|
"types": "./dist/supabase/index.d.ts",
|