lecodes-sdk 2.0.3 → 2.0.5
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 +104 -76
- package/dist/global.d.ts +3 -5
- package/dist/host.d.ts +3 -0
- package/dist/types/inject.d.ts +4 -4
- package/dist/types/net/codec.d.ts +3 -2
- package/dist/types/net/core.d.ts +10 -1
- package/dist/types/net/index.d.ts +22 -5
- package/dist/types/net/replication.d.ts +23 -2
- package/dist/types/runtime/device.d.ts +7 -0
- package/dist/types/runtime/rpc.d.ts +11 -17
- package/dist/types/runtime/wire.d.ts +53 -0
- package/dist/types/server/auth/api.d.ts +42 -0
- package/dist/types/server/auth/appConfig.d.ts +1 -5
- package/dist/types/server/auth/models.d.ts +119 -70
- package/dist/types/server/auth/types.d.ts +19 -43
- package/dist/types/server/channel.d.ts +57 -19
- package/dist/types/server/context.d.ts +2 -2
- package/dist/types/server/db/defineDb.d.ts +10 -0
- package/dist/types/server/db/index.d.ts +1 -1
- package/dist/types/server/db/types.d.ts +76 -6
- package/dist/types/server/inject.d.ts +0 -1
- package/dist/types/ui/UINode.d.ts +19 -5
- package/dist/types/ui/UIScreen.d.ts +1 -0
- package/dist/types/ui/UITabs.d.ts +8 -6
- package/dist/types/ui/theme.d.ts +48 -13
- package/dist/types/version.d.ts +1 -1
- package/dist/types.json +1 -1
- package/package.json +4 -2
- package/prompts/README.md +1 -1
- package/prompts/design.md +19 -19
- package/prompts/dist/2d-game.md +45 -31
- package/prompts/dist/3d-app.md +45 -31
- package/prompts/dist/ar-app.md +45 -31
- package/prompts/dist/design.md +25 -24
- package/prompts/dist/ui-app.md +45 -31
- package/prompts/ui-design.md +6 -5
- package/prompts/ui.md +25 -22
- package/src/animate/tween/read.ts +146 -0
- package/src/bridges/device.d.ts +9 -0
- package/src/bridges/tree.d.ts +5 -0
- package/src/canvas/gen/cssColor.ts +1 -1
- package/src/canvas/gen/recorder.ts +1 -1
- package/src/canvas/gen/spec.ts +1 -1
- package/src/chisel.ts +1 -1
- package/src/compile/bundler.ts +6 -0
- package/src/compile/compileProject.ts +3 -1
- package/src/compile/index.ts +3 -1
- package/src/compile/serverSplit.ts +58 -11
- package/src/compile/serverTypes.ts +189 -8
- package/src/host.d.ts +3 -0
- package/src/inject.ts +7 -7
- package/src/net/codec.ts +19 -10
- package/src/net/core.ts +18 -5
- package/src/net/index.ts +30 -9
- package/src/net/replication.ts +63 -28
- package/src/runtime/device.ts +12 -0
- package/src/runtime/rpc.ts +101 -40
- package/src/runtime/wire.ts +35 -0
- package/src/server/auth/api.ts +94 -0
- package/src/server/auth/appConfig.ts +2 -3
- package/src/server/auth/host.ts +244 -174
- package/src/server/auth/models.ts +45 -62
- package/src/server/auth/types.ts +19 -34
- package/src/server/channel.ts +97 -29
- package/src/server/channelHub.ts +153 -0
- package/src/server/context.ts +2 -2
- package/src/server/db/defineDb.ts +96 -36
- package/src/server/db/index.ts +1 -1
- package/src/server/db/types.ts +76 -8
- package/src/server/host.ts +25 -10
- package/src/server/inject.ts +2 -2
- package/src/server/runtime.ts +34 -12
- package/src/ui/UINode.ts +22 -5
- package/src/ui/UIScreen.ts +5 -0
- package/src/ui/UITabs.ts +19 -17
- package/src/ui/styleColor.ts +10 -1
- package/src/ui/theme.ts +96 -41
- package/src/version.ts +1 -1
- package/tests/helpers/fakeTree.ts +1 -0
- package/dist/types/plugins/oauth.d.ts +0 -25
- package/dist/types/server/auth/global.d.ts +0 -56
- package/src/plugins/oauth.ts +0 -61
- package/src/server/auth/global.ts +0 -80
- package/tests/helpers/memoryMarci.ts +0 -124
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* Naming: `S` = the schema record (model name → Model), `N` = a model name, `F` = a fields record.
|
|
8
8
|
*/
|
|
9
9
|
import type { Field, FieldMeta } from "./fields";
|
|
10
|
+
import type { IdentityPublicFields, SessionPublicFields } from "../auth/models";
|
|
10
11
|
import type { CompareNumValue, CompareRefListValue, CompareRefValue, CompareStrValue, CompareValue, CustomSearchValue, FullTextSearch, JsonCondition, JsonPathWhere, Op, PrimitiveListUpdate, Query as MarciQuery, RefListUpdate, RefListUpdateOrdered, RefUpdate, RefUpdateStruct, Rows, Sub, UpdateNumValue, VectorSearch, WhereValue } from "./marci/query";
|
|
11
12
|
export type Fields = Record<string, Field<any, any>>;
|
|
12
13
|
export type Model<F extends Fields = Fields> = {
|
|
@@ -86,7 +87,7 @@ type StructSelect<S, F extends Fields> = {
|
|
|
86
87
|
[K in keyof F]?: FieldSelect<S, F[K]>;
|
|
87
88
|
};
|
|
88
89
|
type ScalarWhere<T, M extends FieldMeta> = Nullable<M, CompareValue<T>> | (IsNum<M> extends true ? CompareNumValue<T> : M["scalar"] extends "string" ? CompareStrValue<T> : never);
|
|
89
|
-
type FieldWhere<S, Fld, M extends FieldMeta = MetaOf<Fld>> = M["kind"] extends "one" ? CompareRefValue<Where<S, ModelName<S, Fld>> | null> : M["kind"] extends "many" | "list" ? CompareRefListValue<Where<S, ModelName<S, Fld>>> : M["kind"] extends "struct" ? CompareRefValue<WhereValue<StructWhereFields<S, StructFieldsOf<Fld>>> | null> : M["kind"] extends "json" ? JsonPathWhere | JsonCondition : M["array"] extends true ?
|
|
90
|
+
type FieldWhere<S, Fld, M extends FieldMeta = MetaOf<Fld>> = M["kind"] extends "one" ? CompareRefValue<Where<S, ModelName<S, Fld>> | null> : M["kind"] extends "many" | "list" ? CompareRefListValue<Where<S, ModelName<S, Fld>>> : M["kind"] extends "struct" ? CompareRefValue<WhereValue<StructWhereFields<S, StructFieldsOf<Fld>>> | null> : M["kind"] extends "json" ? JsonPathWhere | JsonCondition : M["array"] extends true ? TsOf<Fld>[] : ScalarWhere<TsOf<Fld>, M> | CustomSearchValue<FullTextSearch> | CustomSearchValue<VectorSearch>;
|
|
90
91
|
type WhereFieldsOf<S, F extends Fields> = {
|
|
91
92
|
[K in keyof F]?: FieldWhere<S, F[K]>;
|
|
92
93
|
};
|
|
@@ -95,9 +96,15 @@ type IdWhere<S, N extends keyof S> = {
|
|
|
95
96
|
};
|
|
96
97
|
export type Where<S, N extends keyof S> = WhereValue<WhereFieldsOf<S, FieldsOf<S[N]>> & IdWhere<S, N>>;
|
|
97
98
|
type StructWhereFields<S, F extends Fields> = WhereFieldsOf<S, F>;
|
|
99
|
+
type OrderKeys<S, N extends keyof S> = (ScalarKeys<FieldsOf<S[N]>> | keyof Id<S, N>) & keyof Row<S, N>;
|
|
100
|
+
/** ONE field and its direction: the engine sorts by a single field, so a second key is a type error. */
|
|
98
101
|
export type Order<S, N extends keyof S> = {
|
|
99
|
-
[K in
|
|
100
|
-
|
|
102
|
+
[K in OrderKeys<S, N>]: {
|
|
103
|
+
[P in K]: "asc" | "desc";
|
|
104
|
+
} & {
|
|
105
|
+
[P in Exclude<OrderKeys<S, N>, K>]?: never;
|
|
106
|
+
};
|
|
107
|
+
}[OrderKeys<S, N>];
|
|
101
108
|
/** The query object — marcidb's wire form: a select shape plus the `$`-clauses. */
|
|
102
109
|
export type QueryObject<S, N extends keyof S> = Select<S, N> & {
|
|
103
110
|
$where?: Where<S, N>;
|
|
@@ -140,8 +147,14 @@ export type Query<S, N extends keyof S, Sel = ScalarSelect<S, N>> = MarciQuery<T
|
|
|
140
147
|
export type Result<S, N extends keyof S, Q> = Rows<Types<S, N>, Q>;
|
|
141
148
|
/** `db.<model>` — the root query of a model. */
|
|
142
149
|
export type Collection<S, N extends keyof S> = Query<S, N>;
|
|
143
|
-
|
|
144
|
-
|
|
150
|
+
/** The platform's models a project's own may point at (`t.one("Session")`) — see ../auth/models.ts. */
|
|
151
|
+
type PlatformModels = {
|
|
152
|
+
Session: Model<SessionPublicFields>;
|
|
153
|
+
};
|
|
154
|
+
/** What a db's queries are typed against: the project's models and what they may point at. */
|
|
155
|
+
type Full<S> = S & PlatformModels;
|
|
156
|
+
type DbBase<S extends Schema> = {
|
|
157
|
+
[N in keyof S & string as Uncapitalize<N>]: Query<Full<S>, N>;
|
|
145
158
|
} & {
|
|
146
159
|
/** Atomic batch: all ops commit or none. `ref("0.id")` feeds a generated id into a later op. */
|
|
147
160
|
$transaction<P extends readonly Op<any>[]>(ops: [...P]): Promise<{
|
|
@@ -150,8 +163,65 @@ export type Db<S extends Schema> = {
|
|
|
150
163
|
/** The `.marci` schema text this db syncs with. */
|
|
151
164
|
readonly $schema: string;
|
|
152
165
|
};
|
|
166
|
+
export type Db<S extends Schema> = DbBase<S> & {
|
|
167
|
+
/**
|
|
168
|
+
* Sign-in for this database: `model` is the project's model of a user. Adds the platform's `Session`
|
|
169
|
+
* and `Identity` models beside it and gives the db its `auth`. Part of the definition — call it on
|
|
170
|
+
* `defineDb(...)` itself, before the db is used. Every field of the user model must be optional or
|
|
171
|
+
* have a default: the platform creates the row the first time someone signs in.
|
|
172
|
+
*/
|
|
173
|
+
withAuth<N extends keyof S & string>(options: {
|
|
174
|
+
model: N;
|
|
175
|
+
}): DbWithAuth<S, N>;
|
|
176
|
+
};
|
|
177
|
+
export type DbWithAuth<S extends Schema, N extends keyof S & string> = DbBase<S> & {
|
|
178
|
+
readonly auth: Auth<S, N>;
|
|
179
|
+
};
|
|
180
|
+
/**
|
|
181
|
+
* The user of the current request, as a query over the project's user model: `select(shape)` picks the
|
|
182
|
+
* fields (id + scalars without it), `await` runs it. Nothing happens until it is awaited — a query that
|
|
183
|
+
* is never awaited checks nothing, which is why the compiler refuses one.
|
|
184
|
+
*/
|
|
185
|
+
export interface UserQuery<S, N extends keyof S, Sel, Nil> extends PromiseLike<Result<S, N, Sel> | Nil> {
|
|
186
|
+
select<Q extends Select<S, N>>(shape: Q): UserQuery<S, N, Q, Nil>;
|
|
187
|
+
}
|
|
188
|
+
type AuthTables = {
|
|
189
|
+
Session: Model<SessionPublicFields>;
|
|
190
|
+
Identity: Model<IdentityPublicFields>;
|
|
191
|
+
};
|
|
192
|
+
/** `db.auth` — see ../auth/api.ts. */
|
|
193
|
+
export type Auth<S extends Schema, N extends keyof S & string> = {
|
|
194
|
+
/** The signed-in user, or `null` for a guest. */
|
|
195
|
+
user(): UserQuery<Full<S>, N, ScalarSelect<Full<S>, N>, null>;
|
|
196
|
+
/**
|
|
197
|
+
* The signed-in user; a guest is a 401. With `where` it is a check of access too: a user the filter
|
|
198
|
+
* does not match is a 403 — `await db.auth.requireUser({ role: "admin" }).select({ id: true })`.
|
|
199
|
+
*/
|
|
200
|
+
requireUser(where?: Where<Full<S>, N>): UserQuery<Full<S>, N, ScalarSelect<Full<S>, N>, never>;
|
|
201
|
+
/** The device's session — there from the first request, before any sign-in (a guest's cart points at it). */
|
|
202
|
+
readonly sessionId: number;
|
|
203
|
+
/** A new account: `login` is an email or a name (3–32 letters, digits, `. _ -`), `data` the fields of the
|
|
204
|
+
* user's row. 409 when the login is taken. Signs this device in. */
|
|
205
|
+
signUpWithPassword(login: string, password: string, data?: Insert<Full<S>, N>): Promise<void>;
|
|
206
|
+
/** Signs this device in; 401 on any failure (rate-limited per login and ip). */
|
|
207
|
+
signInWithPassword(login: string, password: string): Promise<void>;
|
|
208
|
+
/** Sets the current user's password; every other device is signed out. */
|
|
209
|
+
setPassword(password: string): Promise<void>;
|
|
210
|
+
/** Emails a 6-digit code (always resolves — no "email exists" oracle; rate-limited). */
|
|
211
|
+
sendCode(email: string): Promise<void>;
|
|
212
|
+
/** Checks the code sent to this device, finds or creates the user, signs this device in. */
|
|
213
|
+
signInWithCode(email: string, code: string): Promise<void>;
|
|
214
|
+
/** For a person the project verified itself (a provider's sign-in, Telegram initData, SSO): binds this device to the user. */
|
|
215
|
+
signIn(userId: number): Promise<void>;
|
|
216
|
+
/** The device stays, as a guest. */
|
|
217
|
+
signOut(): Promise<void>;
|
|
218
|
+
/** The current user's devices, as a query: `await`, `.select()`, `.where(...).updateMany({ revoked: true })`. */
|
|
219
|
+
readonly sessions: Query<AuthTables, "Session">;
|
|
220
|
+
/** How the current user signs in, as a query: provider (`"email"` | `"login"`), subject, verifiedAt. */
|
|
221
|
+
readonly identities: Query<AuthTables, "Identity">;
|
|
222
|
+
};
|
|
153
223
|
type RelKinds = "one" | "many" | "list";
|
|
154
|
-
type CheckField<S, Fld> = MetaOf<Fld>["kind"] extends RelKinds ? MetaOf<Fld>["model"] extends keyof S ? Fld : `Unknown model "${MetaOf<Fld>["model"]}" — not a key of defineDb({...})` : Fld;
|
|
224
|
+
type CheckField<S, Fld> = MetaOf<Fld>["kind"] extends RelKinds ? MetaOf<Fld>["model"] extends keyof S | keyof PlatformModels ? Fld : `Unknown model "${MetaOf<Fld>["model"]}" — not a key of defineDb({...})` : Fld;
|
|
155
225
|
/** Intersected with `S` in `defineDb`'s parameter: an unknown relation target fails to type-check on that field. */
|
|
156
226
|
export type ValidateRefs<S extends Schema> = {
|
|
157
227
|
[N in keyof S]: {
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import type { FetchResponse } from "../runtime/fetch";
|
|
2
|
+
import type { SvgSourceValue } from "../runtime/misc";
|
|
2
3
|
import type { ColorInput } from "../core/color";
|
|
3
4
|
import type { Animation } from "../animate/tween/Animation";
|
|
4
5
|
import { type TweenMeta } from "../animate/tween/spec";
|
|
6
|
+
import { type ThemeRoles } from "./theme";
|
|
5
7
|
import { type TreeElement } from "./tree";
|
|
6
8
|
export interface UINode {
|
|
7
9
|
readonly type: string;
|
|
@@ -18,7 +20,7 @@ export type UINodeChild = UINode | null | undefined | false;
|
|
|
18
20
|
* needs no spread. */
|
|
19
21
|
export type UIChildArg = UINodeChild | UINodeChild[];
|
|
20
22
|
/** A color: any CSS color string (`"#1c1c1e"`, `"rgba(0,0,0,0.5)"`, `"green"`, `"hsl(210 50% 40%)"`),
|
|
21
|
-
* a theme reference (`"var(--
|
|
23
|
+
* a theme reference (`"var(--accent)"`), an opaque `0xRRGGBB` number or `[r, g, b(, a)]` in
|
|
22
24
|
* 0..1; `null` clears. A string is the core's to parse (an unknown one is transparent, as in
|
|
23
25
|
* CSS); a number or an array that is not a color throws at the write. */
|
|
24
26
|
export type Color = ColorInput | null;
|
|
@@ -37,12 +39,13 @@ export type BaseStyle = {
|
|
|
37
39
|
};
|
|
38
40
|
/** Painted-box props: background, gradient, border, radius. */
|
|
39
41
|
export type DrawableStyle = {
|
|
40
|
-
backgroundImage?: FetchResponse | File | string | null;
|
|
42
|
+
backgroundImage?: FetchResponse | File | SvgSourceValue | string | null;
|
|
41
43
|
bgGradient?: string;
|
|
42
44
|
backgroundGradient?: string;
|
|
43
|
-
bgImage?: FetchResponse | File | string | null;
|
|
44
|
-
|
|
45
|
-
|
|
45
|
+
bgImage?: FetchResponse | File | SvgSourceValue | string | null;
|
|
46
|
+
/** How the image fills the box. "tile": repeated at its own size from the top-left corner. */
|
|
47
|
+
backgroundSize?: "cover" | "contain" | "fill" | "tile";
|
|
48
|
+
bgSize?: "cover" | "contain" | "fill" | "tile";
|
|
46
49
|
border?: string | number | null;
|
|
47
50
|
borderWidth?: number;
|
|
48
51
|
borderColor?: Color;
|
|
@@ -223,6 +226,16 @@ export interface UIElementBase<S extends object, A extends object = S> {
|
|
|
223
226
|
name?: string;
|
|
224
227
|
/** Set the semantic name (chainable). */
|
|
225
228
|
named(name: string): this;
|
|
229
|
+
/** Theme variables for THIS element's subtree (chainable): the same keys as the app-wide
|
|
230
|
+
* `theme()`, read by everything under the element — and by the kit components there — before
|
|
231
|
+
* the app's table. `null` takes a key out of the scope. Reaches the element's descendants in
|
|
232
|
+
* the tree (a pager's pages and a list's items included); a screen pushed over it and a widget
|
|
233
|
+
* are roots of their own. Re-calling restyles the live subtree.
|
|
234
|
+
* ```ts
|
|
235
|
+
* promo.theme({ accent: "#FF3B30" }) // one card in another accent
|
|
236
|
+
* sheet.theme({ bg: "#000", text: "#FFF" }) // a dark screen in a light app
|
|
237
|
+
* ``` */
|
|
238
|
+
theme(values: ThemeRoles & Record<string, string | number | null>): this;
|
|
226
239
|
/** Tween to the target style — meta keys `duration`/`delay`/`loop`/…, see {@link AnimateStyle}. */
|
|
227
240
|
animateTo: AnimateStyle<this, A>;
|
|
228
241
|
/** Tween from the given style to the current one (entrance animations). */
|
|
@@ -305,6 +318,7 @@ export declare class Element<T extends string> implements TreeElement {
|
|
|
305
318
|
get name(): string | undefined;
|
|
306
319
|
set name(value: string | undefined);
|
|
307
320
|
named(name: string): this;
|
|
321
|
+
theme(values: Record<string, string | number | null>): this;
|
|
308
322
|
get style(): any;
|
|
309
323
|
/** Tween to the target style and commit it (unless `commit: false` or looping — a loop is an
|
|
310
324
|
* effect, not a state change). A prop value may be an array of keyframes; meta keys
|
|
@@ -48,6 +48,7 @@ export interface UIScreen extends UIContainerBase<UIScreenStyle, DrawableStyle &
|
|
|
48
48
|
onTouchStart(callback: (ev: TouchStartEvent<UIScreen>) => void): this;
|
|
49
49
|
}
|
|
50
50
|
export declare class ScreenElement extends ContainerElement<"screen"> {
|
|
51
|
+
constructor(type: "screen", style: any, children: any);
|
|
51
52
|
open(options?: PresentOptions): void;
|
|
52
53
|
close(options?: DismissOptions): void;
|
|
53
54
|
protected ol: (() => void)[];
|
|
@@ -23,8 +23,9 @@ export type UITabDef = {
|
|
|
23
23
|
* ```
|
|
24
24
|
*
|
|
25
25
|
* In-tab navigation stays the pager's: `UIPager.push(detail)` from any screen (bar stays);
|
|
26
|
-
* `Router.push` opens above the shell (bar covered).
|
|
27
|
-
*
|
|
26
|
+
* `Router.push` opens above the shell (bar covered). The bar is colored by the theme's roles
|
|
27
|
+
* (`accent`, `textMuted`, `surface`, `border`); `tabs.bar.theme({...})` overrides them for this
|
|
28
|
+
* bar alone, the `bar` handle restyles its box; for a fully custom bar build on `UIPager`.
|
|
28
29
|
*/
|
|
29
30
|
export interface UITabs extends UIScreen {
|
|
30
31
|
/** The active tab id. */
|
|
@@ -37,7 +38,8 @@ export interface UITabs extends UIScreen {
|
|
|
37
38
|
badge(id: string, value: number | string | boolean | null): this;
|
|
38
39
|
/** The pager under the bar — in-tab stacks (`push`/`pop`/`depth`). */
|
|
39
40
|
readonly pager: UIPager;
|
|
40
|
-
/** The bar row (named "tabbar") —
|
|
41
|
+
/** The bar row (named "tabbar") — `bar.theme({ accent, textMuted, surface, border })` for this
|
|
42
|
+
* bar's own colors, `bar.style({...})` for its box. */
|
|
41
43
|
readonly bar: UIRowType;
|
|
42
44
|
}
|
|
43
45
|
export declare class TabsElement extends ScreenElement {
|
|
@@ -89,8 +91,8 @@ export type TabsHandle<T extends Record<string, TabDef>> = {
|
|
|
89
91
|
* export default () => mainTabs.screen("home", [ ...content ])
|
|
90
92
|
* ```
|
|
91
93
|
*
|
|
92
|
-
*
|
|
93
|
-
* every bar at once. The built app passes the same keys (plus
|
|
94
|
-
* which renders the identical bar interactively.
|
|
94
|
+
* The bar reads the theme's roles (`accent`, `textMuted`, `surface`, `border`), the screen its
|
|
95
|
+
* `bg` — one `theme({...})` colors every bar at once. The built app passes the same keys (plus
|
|
96
|
+
* each tab's root screen) to `UITabs`, which renders the identical bar interactively.
|
|
95
97
|
*/
|
|
96
98
|
export declare function defineTabs<T extends Record<string, TabDef>>(tabs: T): TabsHandle<T>;
|
package/dist/types/ui/theme.d.ts
CHANGED
|
@@ -1,21 +1,56 @@
|
|
|
1
1
|
import type { Transition } from "./presentable";
|
|
2
2
|
export type ThemeValues = Record<string, string | number | null>;
|
|
3
|
+
/** The keys the SDK itself reads — the ROLES of a theme. An app's own keys sit beside them in the
|
|
4
|
+
* same call; kit components (`UITabs`) and the defaults of screens and text read these and nothing
|
|
5
|
+
* else, so one palette colors the app and the kit alike. A color is a string, never a number. */
|
|
6
|
+
export type ThemeRoles = {
|
|
7
|
+
/** The background of every screen. */
|
|
8
|
+
bg?: string | null;
|
|
9
|
+
/** A raised surface — cards, bars, sheets. The tab bar's background (without it: `bg`). */
|
|
10
|
+
surface?: string | null;
|
|
11
|
+
/** Hairlines and outlines. The tab bar's top line. */
|
|
12
|
+
border?: string | null;
|
|
13
|
+
/** Text that names no `color` of its own. */
|
|
14
|
+
text?: string | null;
|
|
15
|
+
/** Secondary text and inactive controls. The tab bar's inactive tabs. */
|
|
16
|
+
textMuted?: string | null;
|
|
17
|
+
/** The brand / active color. The tab bar's active tab. */
|
|
18
|
+
accent?: string | null;
|
|
19
|
+
/** The font of text that names no `fontFamily` of its own. */
|
|
20
|
+
fontFamily?: string | null;
|
|
21
|
+
};
|
|
22
|
+
/** What only the app-wide `theme()` takes: the comfort knobs (logical px) and the Router's default
|
|
23
|
+
* `replace` transition. */
|
|
24
|
+
export type ThemeAppKeys = {
|
|
25
|
+
"comfort-top"?: number | string | null;
|
|
26
|
+
"comfort-bottom"?: number | string | null;
|
|
27
|
+
"comfort-left"?: number | string | null;
|
|
28
|
+
"comfort-right"?: number | string | null;
|
|
29
|
+
replaceTransition?: Transition | null;
|
|
30
|
+
};
|
|
31
|
+
/** The `var(--key)` strings of the keys a `theme()` call defined — plain strings, so a helper's
|
|
32
|
+
* `(color = colors.accent)` parameter takes any color. */
|
|
3
33
|
export type ThemeAccessors<T> = {
|
|
4
|
-
readonly [K in keyof T]:
|
|
34
|
+
readonly [K in Exclude<keyof T, "replaceTransition">]: string;
|
|
5
35
|
};
|
|
6
36
|
/** App theme: callable to merge variables (`theme({...})` — re-calling re-styles the live UI, so
|
|
7
|
-
* dark mode is just a second call), with the
|
|
8
|
-
*
|
|
9
|
-
export declare const theme: (<T extends Record<string, string | number | Transition | null>>(values: T & { [K in Exclude<keyof T, "replaceTransition">]: string | number | null; }) => ThemeAccessors<
|
|
10
|
-
/** The
|
|
11
|
-
readonly
|
|
12
|
-
/**
|
|
13
|
-
readonly
|
|
14
|
-
/**
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
37
|
+
* dark mode is just a second call), with the roles as static properties (`theme.accent`,
|
|
38
|
+
* `theme["comfort-top"]`, …) for code that has no tokens module to import. */
|
|
39
|
+
export declare const theme: (<T extends ThemeRoles & ThemeAppKeys & Record<string, string | number | Transition | null>>(values: T & { [K in Exclude<keyof T, "replaceTransition">]: string | number | null; }) => ThemeAccessors<T>) & {
|
|
40
|
+
/** The background of every screen. */
|
|
41
|
+
readonly bg: "var(--bg)";
|
|
42
|
+
/** A raised surface — cards, bars, sheets. */
|
|
43
|
+
readonly surface: "var(--surface)";
|
|
44
|
+
/** Hairlines and outlines. */
|
|
45
|
+
readonly border: "var(--border)";
|
|
46
|
+
/** DEFAULT text color — text without a `color` of its own follows it (unset = the host's
|
|
47
|
+
* default: white). Set it once for a light theme instead of a color on every label. */
|
|
48
|
+
readonly text: "var(--text)";
|
|
49
|
+
/** Secondary text and inactive controls. */
|
|
50
|
+
readonly textMuted: "var(--textMuted)";
|
|
51
|
+
/** The brand / active color. */
|
|
52
|
+
readonly accent: "var(--accent)";
|
|
53
|
+
/** DEFAULT text font — text without a `fontFamily` of its own follows it. */
|
|
19
54
|
readonly fontFamily: "var(--fontFamily)";
|
|
20
55
|
/** Raw comfort knobs (logical px). The bare `comfort-top` style TOKEN applies the safe-area
|
|
21
56
|
* formula — these accessors read the knob value itself, for manual composition. */
|
package/dist/types/version.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const SDK_VERSION = "2.0.
|
|
1
|
+
export declare const SDK_VERSION = "2.0.5";
|
|
2
2
|
/** The major of a semver string, or null when it is not one. */
|
|
3
3
|
export declare const sdkMajor: (version: string | null | undefined) => number | null;
|
|
4
4
|
/** The `// sdk: <version>` line of a compiled bundle's header (sdk/src/compile/header.ts), read from
|