@nisoku/sazami 0.1.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 +261 -0
- package/dist/config/generator.d.ts +3 -0
- package/dist/config/tokens.d.ts +1 -0
- package/dist/curvomorphism/index.d.ts +10 -0
- package/dist/errors.d.ts +16 -0
- package/dist/escape.d.ts +26 -0
- package/dist/icons/index.d.ts +1 -0
- package/dist/index.cjs +9473 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.mjs +9473 -0
- package/dist/index.mjs.map +1 -0
- package/dist/primitives/accordion.d.ts +35 -0
- package/dist/primitives/avatar.d.ts +54 -0
- package/dist/primitives/badge.d.ts +34 -0
- package/dist/primitives/base.d.ts +129 -0
- package/dist/primitives/button.d.ts +55 -0
- package/dist/primitives/card.d.ts +44 -0
- package/dist/primitives/checkbox.d.ts +43 -0
- package/dist/primitives/chip.d.ts +57 -0
- package/dist/primitives/column.d.ts +24 -0
- package/dist/primitives/coverart.d.ts +34 -0
- package/dist/primitives/divider.d.ts +24 -0
- package/dist/primitives/generic.d.ts +4 -0
- package/dist/primitives/grid.d.ts +29 -0
- package/dist/primitives/heading.d.ts +35 -0
- package/dist/primitives/icon-button.d.ts +45 -0
- package/dist/primitives/icon.d.ts +32 -0
- package/dist/primitives/image.d.ts +36 -0
- package/dist/primitives/input.d.ts +53 -0
- package/dist/primitives/label.d.ts +26 -0
- package/dist/primitives/modal.d.ts +34 -0
- package/dist/primitives/modifier-map.d.ts +3 -0
- package/dist/primitives/progress.d.ts +49 -0
- package/dist/primitives/radio.d.ts +48 -0
- package/dist/primitives/registry.d.ts +2 -0
- package/dist/primitives/row.d.ts +29 -0
- package/dist/primitives/section.d.ts +39 -0
- package/dist/primitives/select.d.ts +58 -0
- package/dist/primitives/shared.d.ts +15 -0
- package/dist/primitives/slider.d.ts +60 -0
- package/dist/primitives/spacer.d.ts +14 -0
- package/dist/primitives/spinner.d.ts +29 -0
- package/dist/primitives/stack.d.ts +19 -0
- package/dist/primitives/switch.d.ts +53 -0
- package/dist/primitives/tabs.d.ts +30 -0
- package/dist/primitives/tag.d.ts +25 -0
- package/dist/primitives/text.d.ts +39 -0
- package/dist/primitives/toast.d.ts +45 -0
- package/dist/primitives/toggle.d.ts +51 -0
- package/dist/runtime/renderer.d.ts +2 -0
- package/dist/runtime/transformer.d.ts +8 -0
- package/package.json +55 -0
package/README.md
ADDED
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
# Sazami
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@nisoku/sazami)
|
|
4
|
+
[](LICENSE)
|
|
5
|
+
|
|
6
|
+
[Documentation](https://nisoku.github.io/Sazami/) | [API Reference](https://nisoku.github.io/Sazami/api-reference/) | [Playground](https://nisoku.github.io/Sazami/playground/)
|
|
7
|
+
|
|
8
|
+
**A zero-dependency UI engine for the web.**
|
|
9
|
+
|
|
10
|
+
Sazami is available on [npm](https://www.npmjs.com/package/@nisoku/sazami)!
|
|
11
|
+
|
|
12
|
+
Write concise, readable markup in the Sakko language. Get real web components, automatic theming, and a unique directional corner-rounding effect called *[curvomorphism](https://github.com/NellowTCS/Curvomorphism/)*: all without installing a single external dependency.
|
|
13
|
+
|
|
14
|
+
## What does it look like?
|
|
15
|
+
|
|
16
|
+
```sako
|
|
17
|
+
<card {
|
|
18
|
+
heading: "Hello, world"
|
|
19
|
+
text: "This compiles to real web components."
|
|
20
|
+
button(primary): "Get Started"
|
|
21
|
+
}>
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
That is the entire source. No HTML boilerplate, no CSS classes, no imports. Sakko compiles it into a styled `<saz-card>` web component with a heading, a paragraph, and a themed button, all rendered into the DOM.
|
|
25
|
+
|
|
26
|
+
Here is a more realistic example:
|
|
27
|
+
|
|
28
|
+
```sako
|
|
29
|
+
<card(row center) {
|
|
30
|
+
image(src "album.jpg" round): ""
|
|
31
|
+
stack(gap small) {
|
|
32
|
+
heading: "Midnight City"
|
|
33
|
+
text(dim): "M83"
|
|
34
|
+
}
|
|
35
|
+
row(gap small) {
|
|
36
|
+
icon-btn: "previous"
|
|
37
|
+
icon-btn(accent large): "play"
|
|
38
|
+
icon-btn: "next"
|
|
39
|
+
}
|
|
40
|
+
}>
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
This produces a horizontal card with a round album cover, stacked song info, and SVG icon buttons.
|
|
44
|
+
|
|
45
|
+
## Getting started
|
|
46
|
+
|
|
47
|
+
### Install
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
npm install @nisoku/sazami
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Use
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
import { compileSakko, injectThemeCSS } from "@nisoku/sazami";
|
|
57
|
+
|
|
58
|
+
// Inject the default theme (CSS variables on :root)
|
|
59
|
+
injectThemeCSS();
|
|
60
|
+
|
|
61
|
+
// Compile Sakko source and mount it
|
|
62
|
+
const source = `
|
|
63
|
+
<card {
|
|
64
|
+
heading: "Welcome"
|
|
65
|
+
text: "Built with Sakko + Sazami"
|
|
66
|
+
button(accent): "Get Started"
|
|
67
|
+
}>
|
|
68
|
+
`;
|
|
69
|
+
|
|
70
|
+
compileSakko(source, document.getElementById("app"));
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Custom theme
|
|
74
|
+
|
|
75
|
+
Override any design token:
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
injectThemeCSS({
|
|
79
|
+
"color.primary": "#4a9eff",
|
|
80
|
+
"color.accent": "#ff6b9d",
|
|
81
|
+
"color.background": "#1a1a2e",
|
|
82
|
+
"color.surface": "#16213e",
|
|
83
|
+
});
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Tokens cover colors, spacing, typography, radii, shadows, and icon sizes. See the [theming docs](https://nisoku.github.io/Sazami/config-theming/) for the full list.
|
|
87
|
+
|
|
88
|
+
## How it works
|
|
89
|
+
|
|
90
|
+
Sazami is a two-layer system built on top of Sakko:
|
|
91
|
+
|
|
92
|
+
1. **Sakko**: a bracket-based DSL you write in `.sako` files (installed separately via `@nisoku/sakko`)
|
|
93
|
+
2. **Sazami Primitives**: semantic web components (`saz-card`, `saz-button`, etc.)
|
|
94
|
+
3. **Sazami Config**: a CSS-variable theme engine driven by design tokens
|
|
95
|
+
|
|
96
|
+
The pipeline:
|
|
97
|
+
|
|
98
|
+
```text
|
|
99
|
+
source text -> tokenize -> parse -> AST -> transform -> VNode tree -> render to DOM
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Everything is compiled at runtime in the browser. No build step required. Additionally, the library ships as ESM and CJS with TypeScript declarations!
|
|
103
|
+
|
|
104
|
+
## Primitives
|
|
105
|
+
|
|
106
|
+
48 web components, grouped by purpose:
|
|
107
|
+
|
|
108
|
+
| Category | Components |
|
|
109
|
+
|---|---|
|
|
110
|
+
| Layout | `row`, `column`, `grid`, `stack`, `section` |
|
|
111
|
+
| Content | `card`, `text`, `heading`, `label` |
|
|
112
|
+
| Interactive | `button`, `icon-btn`, `input`, `checkbox`, `toggle`, `radio`, `switch`, `slider`, `select` |
|
|
113
|
+
| Navigation | `tabs`, `accordion` |
|
|
114
|
+
| Feedback | `spinner`, `progress`, `toast` |
|
|
115
|
+
| Overlay | `modal` |
|
|
116
|
+
| Display | `avatar`, `chip` |
|
|
117
|
+
| Media | `image`, `coverart`, `icon` |
|
|
118
|
+
| Indicators | `badge`, `tag`, `divider`, `spacer` |
|
|
119
|
+
| Grouping | `details`, `controls` |
|
|
120
|
+
|
|
121
|
+
Every interactive primitive has:
|
|
122
|
+
- ARIA roles and `aria-*` attributes
|
|
123
|
+
- Keyboard navigation (Enter / Space)
|
|
124
|
+
- Focus-visible outlines
|
|
125
|
+
- Attribute reflection (`checked`, `disabled`)
|
|
126
|
+
|
|
127
|
+
## Icons
|
|
128
|
+
|
|
129
|
+
Sazami ships with 41 SVG icons. Icons inherit the current text color and scale with the `size` modifier:
|
|
130
|
+
|
|
131
|
+
```sako
|
|
132
|
+
<row(gap medium) {
|
|
133
|
+
icon: "play"
|
|
134
|
+
icon(large primary): "heart"
|
|
135
|
+
icon-btn: "settings"
|
|
136
|
+
}>
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Available: play, pause, stop, previous, next, skip, close, menu, search, settings, heart, star, check, plus, minus, edit, share, download, upload, refresh, home, back, forward, up, down, mail, phone, calendar, clock, user, users, folder, file, image, camera, bell, lock, link, trash, copy, bookmark, pin, globe.
|
|
140
|
+
|
|
141
|
+
## Modifiers
|
|
142
|
+
|
|
143
|
+
Modifiers are parenthesized flags or key-value pairs:
|
|
144
|
+
|
|
145
|
+
```sako
|
|
146
|
+
button(primary large): "Submit"
|
|
147
|
+
input(placeholder "Your email" type "email"): ""
|
|
148
|
+
grid(cols 3 gap medium): [...]
|
|
149
|
+
card(row center curved): { ... }
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Flags like `primary`, `large`, `center`, `bold`, `disabled`, and `checked` map to HTML attributes. Key-value pairs like `cols 3` or `placeholder "Enter name"` set attributes directly.
|
|
153
|
+
|
|
154
|
+
## Curvomorphism
|
|
155
|
+
|
|
156
|
+
Curvomorphism rounds corners directionally based on each element's position relative to a center point. Elements closer to the center round their inward-facing corners more.
|
|
157
|
+
|
|
158
|
+
Enable it per-node with the `curved` flag, and set the center point on a parent:
|
|
159
|
+
|
|
160
|
+
```sako
|
|
161
|
+
<grid(cols 2 gap medium center-point) {
|
|
162
|
+
card(curved) {
|
|
163
|
+
text: "Top Left"
|
|
164
|
+
},
|
|
165
|
+
card(curved) {
|
|
166
|
+
text: "Top Right"
|
|
167
|
+
},
|
|
168
|
+
card(curved) {
|
|
169
|
+
text: "Bottom Left"
|
|
170
|
+
},
|
|
171
|
+
card(curved)
|
|
172
|
+
{
|
|
173
|
+
text: "Bottom Right"
|
|
174
|
+
}
|
|
175
|
+
}>
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## Playground
|
|
179
|
+
|
|
180
|
+
Open the [playground](https://nisoku.github.io/Sazami/playground/) in a browser to use the live editor.
|
|
181
|
+
|
|
182
|
+
Type your Sakko code on the left; see the rendered output on the right. Includes example presets and error display with line/column info.
|
|
183
|
+
|
|
184
|
+
## Project structure
|
|
185
|
+
|
|
186
|
+
```text
|
|
187
|
+
Build/ Library source code
|
|
188
|
+
src/
|
|
189
|
+
primitives/ Primitives (Web Components)
|
|
190
|
+
config/ Design tokens and CSS variable generation
|
|
191
|
+
runtime/ AST-to-VNode transformer and DOM renderer
|
|
192
|
+
curvomorphism/ Directional corner rounding algorithm
|
|
193
|
+
icons/ All icon stuff
|
|
194
|
+
svgs/ The minimal built-in icon library
|
|
195
|
+
tests/ Tests
|
|
196
|
+
Demo/ Live demo and interactive playground
|
|
197
|
+
Examples/ Example .sako source files
|
|
198
|
+
Docs/ Documentation (powered by DocMD)
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## Development
|
|
202
|
+
|
|
203
|
+
```bash
|
|
204
|
+
cd Build
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### Install dependencies
|
|
208
|
+
```bash
|
|
209
|
+
npm install
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### Run tests
|
|
213
|
+
```bash
|
|
214
|
+
npm test
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### Build
|
|
218
|
+
```bash
|
|
219
|
+
npm run build
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### Type checking
|
|
223
|
+
|
|
224
|
+
```bash
|
|
225
|
+
npm run typecheck
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
## Documentation
|
|
229
|
+
|
|
230
|
+
| Document | Summary |
|
|
231
|
+
| --- | --- |
|
|
232
|
+
| [Language Reference](https://nisoku.github.io/Sazami/language-reference/) | Full Sakko syntax guide |
|
|
233
|
+
| [Primitives](https://nisoku.github.io/Sazami/primitives/) | Every component with examples |
|
|
234
|
+
| [Config & Theming](https://nisoku.github.io/Sazami/config-theming/) | Token system and custom themes |
|
|
235
|
+
| [Curvomorphism](https://nisoku.github.io/Sazami/curvomorphism/) | How directional rounding works |
|
|
236
|
+
| [API Reference](https://nisoku.github.io/Sazami/api-reference/) | Public API surface |
|
|
237
|
+
|
|
238
|
+
### Run locally
|
|
239
|
+
|
|
240
|
+
```bash
|
|
241
|
+
cd Docs
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
### Install dependencies
|
|
245
|
+
```bash
|
|
246
|
+
npm install
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### Build
|
|
250
|
+
```bash
|
|
251
|
+
npm run build
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
### Run dev server
|
|
255
|
+
```bash
|
|
256
|
+
npm run dev
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
## License
|
|
260
|
+
|
|
261
|
+
[Apache License v2.0](LICENSE)
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export declare function generateCSSVariables(tokens: Record<string, string>): string;
|
|
2
|
+
export declare function generateThemeCSS(customTokens?: Record<string, string>): string;
|
|
3
|
+
export declare function getTokenValue(key: string, customTokens?: Record<string, string>): string | undefined;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const defaultTokens: Record<string, string>;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare function applyCurvomorphism(element: HTMLElement, centerX: number, centerY: number, radiusValue?: string, groupLeft?: number, groupRight?: number, groupTop?: number, groupBottom?: number): void;
|
|
2
|
+
export declare function enableCurvomorphism(element: HTMLElement, options?: {
|
|
3
|
+
radius?: string;
|
|
4
|
+
centerX?: number;
|
|
5
|
+
centerY?: number;
|
|
6
|
+
groupLeft?: number;
|
|
7
|
+
groupRight?: number;
|
|
8
|
+
groupTop?: number;
|
|
9
|
+
groupBottom?: number;
|
|
10
|
+
}): () => void;
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface ComponentErrorOptions {
|
|
2
|
+
tag?: string;
|
|
3
|
+
suggestion?: string;
|
|
4
|
+
cause?: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function unknownComponentError(component: string, suggestion?: string): void;
|
|
7
|
+
export declare function propertyError(message: string, options: ComponentErrorOptions): void;
|
|
8
|
+
export declare function eventError(message: string, options: ComponentErrorOptions): void;
|
|
9
|
+
export declare function renderError(message: string, options: {
|
|
10
|
+
suggestion?: string;
|
|
11
|
+
cause?: string;
|
|
12
|
+
}): void;
|
|
13
|
+
export declare function bindingError(message: string, options: {
|
|
14
|
+
property?: string;
|
|
15
|
+
suggestion?: string;
|
|
16
|
+
}): void;
|
package/dist/escape.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* String escaping utilities for preventing injection in various contexts.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Escape HTML special characters for safe insertion into HTML.
|
|
6
|
+
* Escapes: & < > " '
|
|
7
|
+
*
|
|
8
|
+
* Use this for:
|
|
9
|
+
* - Text content in elements
|
|
10
|
+
* - Attribute values
|
|
11
|
+
* - Any context where the value will be parsed as HTML
|
|
12
|
+
*/
|
|
13
|
+
export declare function escapeHtml(str: string): string;
|
|
14
|
+
/**
|
|
15
|
+
* Unescape HTML entities back to characters.
|
|
16
|
+
*/
|
|
17
|
+
export declare function unescapeHtml(str: string): string;
|
|
18
|
+
/**
|
|
19
|
+
* Escape a string for safe use in a URL (encodes special chars).
|
|
20
|
+
*/
|
|
21
|
+
export declare function escapeUrl(str: string): string;
|
|
22
|
+
/**
|
|
23
|
+
* Escape a string for safe use in a CSS selector.
|
|
24
|
+
* Escapes characters that have special meaning in CSS.
|
|
25
|
+
*/
|
|
26
|
+
export declare function escapeCss(str: string): string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const ICON_SVGS: Record<string, string>;
|