@bysages/core 0.0.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/LICENSE +21 -0
- package/README.md +59 -0
- package/dist/index.d.mts +131 -0
- package/dist/index.mjs +9940 -0
- package/package.json +46 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 By Sages
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# @bysages/core
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+

|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
> The visual core of By Sages Elements: the only style layer of the design system, the theme engine, and the lighting engine β framework-agnostic, consumed by every wrapper package.
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- π¨ **The only visual layer** β every component's stylesheet lives here, native CSS scoped by `[data-scope][data-part]`, so one stylesheet serves React, Vue, Solid, and Svelte alike
|
|
12
|
+
- π **Theme engine** β `applyTheme()` drives light/dark, accent pigments (qinghua / celadon / zhusha), contrast tiers, density tiers, and scene presets, all expressed as data on the document root
|
|
13
|
+
- π‘ **Lighting engine** β elevation, pigment bleed, and pointer-carried light computed into CSS variables (`setLight`, `attachDynamicLight`); component styles only ever consume light (δ»₯ε
δΈΊε½± β light as shadow)
|
|
14
|
+
- ποΈ **Ink ripple** β a press feedback pass that bleeds pigment from the pointer, delegated at the root and tuneable per element
|
|
15
|
+
- π§© **Style injection** β `injectComponentStyle()` ships each family's stylesheet at import time, guarded by a head marker so SSR builds that inline styles never double-inject
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
# pnpm
|
|
21
|
+
pnpm add @bysages/core @bysages/tokens
|
|
22
|
+
|
|
23
|
+
# npm
|
|
24
|
+
npm install @bysages/core @bysages/tokens
|
|
25
|
+
|
|
26
|
+
# yarn
|
|
27
|
+
yarn add @bysages/core @bysages/tokens
|
|
28
|
+
|
|
29
|
+
# bun
|
|
30
|
+
bun add @bysages/core @bysages/tokens
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Quick Start
|
|
34
|
+
|
|
35
|
+
Load the compiled tokens, theme the document, and the component styles arrive with the wrappers:
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
import "@bysages/tokens/css";
|
|
39
|
+
import { applyTheme, attachDynamicLight } from "@bysages/core";
|
|
40
|
+
|
|
41
|
+
applyTheme({ mode: "system", accent: "ink", density: "default" });
|
|
42
|
+
attachDynamicLight();
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Architecture
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
@bysages/tokens DTCG source β CSS custom properties
|
|
49
|
+
β
|
|
50
|
+
@bysages/core theme engine Β· lighting engine Β· per-component styles
|
|
51
|
+
β
|
|
52
|
+
wrappers Vue Β· React Β· Solid Β· Svelte β thin adapters over headless machines
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
The core owns no interaction; it renders nothing but light. Wrappers bring the headless state machines, the core dresses them.
|
|
56
|
+
|
|
57
|
+
## License
|
|
58
|
+
|
|
59
|
+
- [MIT](../../LICENSE) Β© [By Sages](https://www.bysages.com/)
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
//#region src/theme.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Theme engine β the runtime half of the token system. Tokens declare how
|
|
4
|
+
* themes look (`@layer bs.tokens`); this module drives which theme is active
|
|
5
|
+
* via data attributes on the root element: `data-theme`, `data-contrast`,
|
|
6
|
+
* `data-density`, `data-scene`, and `data-accent`.
|
|
7
|
+
*
|
|
8
|
+
* @module
|
|
9
|
+
*/
|
|
10
|
+
export type ThemeMode = "light" | "dark" | "system";
|
|
11
|
+
export type ThemeContrast = "auto" | "normal" | "high";
|
|
12
|
+
export type ThemeDensity = "compact" | "default" | "comfortable" | "spacious";
|
|
13
|
+
export type ThemeScene = "auto" | "civic" | "enterprise" | "studio" | "tech";
|
|
14
|
+
export type ThemeAccent = "auto" | "ink" | "qinghua" | "celadon" | "zhusha";
|
|
15
|
+
export interface Theme {
|
|
16
|
+
mode: ThemeMode;
|
|
17
|
+
contrast: ThemeContrast;
|
|
18
|
+
density: ThemeDensity;
|
|
19
|
+
scene: ThemeScene;
|
|
20
|
+
accent: ThemeAccent;
|
|
21
|
+
}
|
|
22
|
+
/** Each scene pairs with a default accent β the pigment that carries its
|
|
23
|
+
* context (civic identity is zhusha, never an error color; tech stays
|
|
24
|
+
* ink). "auto" accent resolves through this table; explicit accents win. */
|
|
25
|
+
export declare const SCENE_DEFAULT_ACCENT: Record<Exclude<ThemeScene, "auto">, ThemeAccent>;
|
|
26
|
+
/** Each scene also pairs with a contrast tier β civic serves elders, so it
|
|
27
|
+
* speaks at the loud tier by default. "auto" contrast resolves here;
|
|
28
|
+
* explicit choices win. */
|
|
29
|
+
export declare const SCENE_DEFAULT_CONTRAST: Record<Exclude<ThemeScene, "auto">, "normal" | "high">;
|
|
30
|
+
export interface ApplyThemeOptions extends Partial<Theme> {
|
|
31
|
+
/** Persist the theme to localStorage so `initTheme` can restore it. Defaults to true. */
|
|
32
|
+
persist?: boolean;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Apply a theme to the document root. Omitted fields keep the current value;
|
|
36
|
+
* `mode: "system"` resolves against `prefers-color-scheme`, and an "auto"
|
|
37
|
+
* accent resolves against the active scene.
|
|
38
|
+
*/
|
|
39
|
+
export declare function applyTheme(options?: ApplyThemeOptions): Theme;
|
|
40
|
+
/** Read the active theme (in-memory state first, then root attributes,
|
|
41
|
+
* then storage). */
|
|
42
|
+
export declare function getTheme(): Theme;
|
|
43
|
+
/**
|
|
44
|
+
* Restore the persisted theme and keep `mode: "system"` in sync with the OS
|
|
45
|
+
* while it is active. Safe to call more than once; SSR is a no-op.
|
|
46
|
+
*/
|
|
47
|
+
export declare function initTheme(): void;
|
|
48
|
+
//#endregion
|
|
49
|
+
//#region src/lighting.d.ts
|
|
50
|
+
/**
|
|
51
|
+
* Lighting engine β the dynamic half of the light pipeline. Every elevation
|
|
52
|
+
* token computes its shadow from four CSS variables (`--bs-light-x/-y`,
|
|
53
|
+
* `--bs-light-reach`, `--bs-shadow-ink`), so writing those variables re-lights
|
|
54
|
+
* the whole interface and every component follows without owning any shadow
|
|
55
|
+
* code of its own.
|
|
56
|
+
*
|
|
57
|
+
* `setLight` places the key light once (a scene's bundled light, or an
|
|
58
|
+
* application's choice). `attachDynamicLight` lets the pointer carry it:
|
|
59
|
+
* the element under the cursor is lit locally, its shadow leaning away from
|
|
60
|
+
* the pointer as the light would cast it.
|
|
61
|
+
*
|
|
62
|
+
* @module
|
|
63
|
+
*/
|
|
64
|
+
export interface LightState {
|
|
65
|
+
/** Shadow offset along x β the direction the light pushes away from. */
|
|
66
|
+
x?: string;
|
|
67
|
+
/** Shadow offset along y. */
|
|
68
|
+
y?: string;
|
|
69
|
+
/** How far shadows spread; multiplies every elevation's reach. */
|
|
70
|
+
reach?: number;
|
|
71
|
+
/** Shadow hue, any CSS color (themes use oklch). */
|
|
72
|
+
ink?: string;
|
|
73
|
+
}
|
|
74
|
+
/** Place the key light on the document root. Omitted parts keep their
|
|
75
|
+
* current value. Inline styles set here outrank scene and theme defaults. */
|
|
76
|
+
export declare function setLight(state: LightState): void;
|
|
77
|
+
/** Read the key light currently in force on the document root. */
|
|
78
|
+
export declare function getLight(): LightState;
|
|
79
|
+
/** Remove the inline light so theme and scene declarations take over. */
|
|
80
|
+
export declare function resetLight(): void;
|
|
81
|
+
export interface DynamicLightOptions {
|
|
82
|
+
/** Largest shadow shift, in px, when the pointer sits at an element's
|
|
83
|
+
* edge. Defaults to 3 β enough to feel alive, never enough to wobble. */
|
|
84
|
+
strength?: number;
|
|
85
|
+
}
|
|
86
|
+
/** Let the pointer carry the light across every lit element. Skips touch
|
|
87
|
+
* pointers and honors `prefers-reduced-motion`; safe to call more than
|
|
88
|
+
* once (the previous listener is replaced). Returns the detach function. */
|
|
89
|
+
export declare function attachDynamicLight(options?: DynamicLightOptions): () => void;
|
|
90
|
+
/** Stop the pointer from carrying the light and clear any local shifts. */
|
|
91
|
+
export declare function detachDynamicLight(): void;
|
|
92
|
+
//#endregion
|
|
93
|
+
//#region src/ink-ripple.d.ts
|
|
94
|
+
/**
|
|
95
|
+
* Ink ripple β the press feedback of the paper-and-ink register. Where
|
|
96
|
+
* Material spreads a hard circle, ink bleeds: a soft wash of the element's
|
|
97
|
+
* own pigment diluting outward from the press point, gone before it draws
|
|
98
|
+
* attention to itself.
|
|
99
|
+
*
|
|
100
|
+
* The bleed's CSS lives in the base stylesheet, keyed on
|
|
101
|
+
* `data-motion~="ink-ripple"`; this module watches presses and marks the
|
|
102
|
+
* press point. Reduced motion collapses the bleed to a state change, as
|
|
103
|
+
* everywhere else in the system.
|
|
104
|
+
*
|
|
105
|
+
* @module
|
|
106
|
+
*/
|
|
107
|
+
/** Watch for presses anywhere inside `root` (default: the document) and
|
|
108
|
+
* bleed ink from the press point of the nearest opt-in element. Safe to
|
|
109
|
+
* call more than once; returns the detach function. */
|
|
110
|
+
export declare function attachInkRipple(root?: HTMLElement): () => void;
|
|
111
|
+
/** Stop watching presses. */
|
|
112
|
+
export declare function detachInkRipple(): void;
|
|
113
|
+
//#endregion
|
|
114
|
+
//#region src/styles/components/index.d.ts
|
|
115
|
+
/** Component style registry β every component contributes its stylesheet
|
|
116
|
+
* here, keyed by the name wrappers pass to `injectComponentStyle`. */
|
|
117
|
+
export declare const componentStyles: Record<string, string>;
|
|
118
|
+
//#endregion
|
|
119
|
+
//#region src/styles.d.ts
|
|
120
|
+
/** The complete token layer (`@layer bs.tokens`): themes, density, contrast,
|
|
121
|
+
* typography, motion, z-index, plus the document-level base guard and the
|
|
122
|
+
* ink-ripple motion grammar. */
|
|
123
|
+
export declare const tokensCss: string;
|
|
124
|
+
/** Inject the token layer into the document head once β the inheritance
|
|
125
|
+
* root that carries themes, density, and the motion grammar. SSR is a
|
|
126
|
+
* no-op; for SSR pass `tokensCss` to a head tag instead. */
|
|
127
|
+
export declare function injectTokens(): void;
|
|
128
|
+
/** Inject one component stylesheet (plus the token layer on first use).
|
|
129
|
+
* Idempotent per component; SSR is a no-op. */
|
|
130
|
+
export declare function injectComponentStyle(key: string): void;
|
|
131
|
+
//#endregion
|