@syncedco/flow 0.1.0 → 0.1.2
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 +1 -0
- package/bin/synced-flow.mjs +14 -6
- package/docs/api-contract.md +12 -1
- package/docs/cli-reference.md +4 -0
- package/docs/quick-start.md +10 -0
- package/docs/release-readiness.md +18 -0
- package/docs/tokens.md +11 -0
- package/package.json +3 -2
- package/styles.css +1 -3
- package/tokens.css +1 -3
package/README.md
CHANGED
|
@@ -44,6 +44,7 @@ brand drift, or generated class chaos.
|
|
|
44
44
|
## Links
|
|
45
45
|
|
|
46
46
|
- GitHub: [github.com/SyncedCo/synced-flow](https://github.com/SyncedCo/synced-flow)
|
|
47
|
+
- Docs: [docs.syncedflow.dev](https://docs.syncedflow.dev)
|
|
47
48
|
- Website: [syncedco.com](https://syncedco.com)
|
|
48
49
|
- Issues: [github.com/SyncedCo/synced-flow/issues](https://github.com/SyncedCo/synced-flow/issues)
|
|
49
50
|
- Support: [SUPPORT.md](SUPPORT.md)
|
package/bin/synced-flow.mjs
CHANGED
|
@@ -2909,7 +2909,7 @@ function selectorFor(token, variants) {
|
|
|
2909
2909
|
function colourValue(name) {
|
|
2910
2910
|
const [raw, opacity] = name.split('/')
|
|
2911
2911
|
const paletteMatch = raw.match(/^([a-z]+)-(\d+)$/)
|
|
2912
|
-
const base = semanticColours[raw] ?? (paletteMatch ? palette[paletteMatch[1]]?.[paletteMatch[2]] : null)
|
|
2912
|
+
const base = semanticColours[raw] ?? configuredThemeColourValue(raw) ?? (paletteMatch ? palette[paletteMatch[1]]?.[paletteMatch[2]] : null)
|
|
2913
2913
|
if (!base) return null
|
|
2914
2914
|
if (!opacity) return base
|
|
2915
2915
|
const amount = Number(opacity)
|
|
@@ -2918,6 +2918,16 @@ function colourValue(name) {
|
|
|
2918
2918
|
return `color-mix(in oklch, ${base} ${amount}%, transparent)`
|
|
2919
2919
|
}
|
|
2920
2920
|
|
|
2921
|
+
function configuredThemeColourValue(name) {
|
|
2922
|
+
const token = cssTokenName(name)
|
|
2923
|
+
const colourNames = [
|
|
2924
|
+
...Object.keys(config.theme?.colours ?? {}),
|
|
2925
|
+
...Object.keys(config.theme?.darkColours ?? {}),
|
|
2926
|
+
].map(cssTokenName)
|
|
2927
|
+
|
|
2928
|
+
return colourNames.includes(token) ? `var(--color-${token}, var(--sf-colour-${token}))` : null
|
|
2929
|
+
}
|
|
2930
|
+
|
|
2921
2931
|
function declarationsFor(base) {
|
|
2922
2932
|
if (base.startsWith('sf-')) return []
|
|
2923
2933
|
|
|
@@ -3562,7 +3572,7 @@ function buildThemeCss(theme) {
|
|
|
3562
3572
|
sections.push(` :where(.sf-theme-dark, [data-sf-theme="dark"]) {\n${dark.join('\n')}\n }`)
|
|
3563
3573
|
}
|
|
3564
3574
|
|
|
3565
|
-
return
|
|
3575
|
+
return sections.join('\n\n')
|
|
3566
3576
|
}
|
|
3567
3577
|
|
|
3568
3578
|
function buildTokensCss() {
|
|
@@ -3604,8 +3614,7 @@ function buildTokensCss() {
|
|
|
3604
3614
|
|
|
3605
3615
|
const colours = fluidConfig.colours
|
|
3606
3616
|
|
|
3607
|
-
return
|
|
3608
|
-
:root {
|
|
3617
|
+
return `:root {
|
|
3609
3618
|
color-scheme: light;
|
|
3610
3619
|
--font-sans: var(--sf-font-sans, ui-sans-serif, system-ui, sans-serif);
|
|
3611
3620
|
--font-display: var(--sf-font-display, ui-serif, Georgia, serif);
|
|
@@ -3725,8 +3734,7 @@ ${pairs.join('\n')}
|
|
|
3725
3734
|
--ease-standard: cubic-bezier(.2, 0, 0, 1);
|
|
3726
3735
|
--icon-size: 1em;
|
|
3727
3736
|
--icon-stroke: 2;
|
|
3728
|
-
}
|
|
3729
|
-
}`
|
|
3737
|
+
}`
|
|
3730
3738
|
}
|
|
3731
3739
|
|
|
3732
3740
|
function buildBaseCss() {
|
package/docs/api-contract.md
CHANGED
|
@@ -11,7 +11,7 @@ These are intended for application code and examples.
|
|
|
11
11
|
| Surface | Public API |
|
|
12
12
|
| --- | --- |
|
|
13
13
|
| Imports | `@syncedco/flow/styles.css`, `tokens.css`, `reset.css`, `base.css`, `defaults.css`, `layout.css`, `components.css`, `utilities.css` |
|
|
14
|
-
| Tokens | `--sf-*` custom properties emitted by `tokens.css` |
|
|
14
|
+
| Tokens | Unlayered `--sf-*` custom properties emitted by `tokens.css` |
|
|
15
15
|
| Theme config | `theme.fonts`, `theme.colours`, `theme.darkColours`, `theme.radii`, `theme.layout`, `theme.components` |
|
|
16
16
|
| Layout classes | `sf-container`, `sf-section`, `sf-stack`, `sf-flow`, `sf-cluster`, `sf-repel`, `sf-toolbar`, `sf-app-shell`, `sf-app-sidebar`, `sf-app-main`, `sf-auto-grid`, `sf-switcher`, `sf-sidebar`, `sf-split`, `sf-frame`, `sf-cover`, `sf-metric-grid`, `sf-pipeline` |
|
|
17
17
|
| Components | `sf-button`, `sf-icon`, `sf-icon-button`, `sf-avatar`, `sf-chart`, `sf-meter`, `sf-card`, `sf-surface`, `sf-hero`, `sf-nav`, `sf-form`, `sf-field`, `sf-input`, `sf-select`, `sf-textarea`, `sf-check`, `sf-alert`, `sf-badge`, `sf-section-header`, `sf-kicker` |
|
|
@@ -46,6 +46,17 @@ These can change more freely.
|
|
|
46
46
|
They are useful for migration output, but `--sf-*` tokens are the preferred
|
|
47
47
|
long-term API.
|
|
48
48
|
|
|
49
|
+
## Theme Cascade Policy
|
|
50
|
+
|
|
51
|
+
Design tokens are intentionally emitted outside CSS layers. Synced Flow uses
|
|
52
|
+
layers for reset, base, layout, components, and utilities, but foundational
|
|
53
|
+
theme variables need the normal cascade so values from `synced-flow.config.mjs`
|
|
54
|
+
are not weaker than unlayered project CSS.
|
|
55
|
+
|
|
56
|
+
Put reusable brand decisions in `theme.colours`, `theme.darkColours`,
|
|
57
|
+
`theme.radii`, `theme.layout`, and `theme.components`. Theme switcher CSS should
|
|
58
|
+
only style the toggle/control UI; it should not redefine `--sf-*` colour tokens.
|
|
59
|
+
|
|
49
60
|
## Unit Policy
|
|
50
61
|
|
|
51
62
|
Design decisions should use `rem`, fluid `clamp()` tokens, logical properties,
|
package/docs/cli-reference.md
CHANGED
|
@@ -78,6 +78,10 @@ Use `--check` in CI to fail when the generated file is stale.
|
|
|
78
78
|
Generated CSS only includes source-scanned utility classes, configured theme
|
|
79
79
|
overrides, and keyframes needed by scanned animation classes.
|
|
80
80
|
|
|
81
|
+
Configured theme tokens are emitted outside CSS layers so they are not weaker
|
|
82
|
+
than unlayered project CSS. Use `theme.darkColours` for dark theme values rather
|
|
83
|
+
than maintaining duplicate colour overrides in a theme switcher stylesheet.
|
|
84
|
+
|
|
81
85
|
## watch
|
|
82
86
|
|
|
83
87
|
Run `build`, then rebuild when configured scan files change.
|
package/docs/quick-start.md
CHANGED
|
@@ -154,8 +154,14 @@ export default defineConfig({
|
|
|
154
154
|
},
|
|
155
155
|
colours: {
|
|
156
156
|
primary: 'oklch(68% 0.18 44)',
|
|
157
|
+
secondary: 'oklch(62% 0.12 205)',
|
|
158
|
+
tertiary: 'oklch(64% 0.14 185)',
|
|
157
159
|
primaryForeground: 'oklch(100% 0 0)',
|
|
158
160
|
},
|
|
161
|
+
darkColours: {
|
|
162
|
+
primary: 'oklch(76% 0.14 44)',
|
|
163
|
+
tertiary: 'oklch(82% 0.12 205)',
|
|
164
|
+
},
|
|
159
165
|
},
|
|
160
166
|
})
|
|
161
167
|
```
|
|
@@ -172,6 +178,10 @@ Use the CSS entry file for one-off local overrides.
|
|
|
172
178
|
}
|
|
173
179
|
```
|
|
174
180
|
|
|
181
|
+
Synced Flow emits theme tokens outside CSS layers so config values are the site
|
|
182
|
+
theme source of truth. Keep theme switcher styles focused on the toggle UI; do
|
|
183
|
+
not mirror colour tokens into a separate `theme-switcher.css` file.
|
|
184
|
+
|
|
175
185
|
## Config
|
|
176
186
|
|
|
177
187
|
```js
|
|
@@ -61,3 +61,21 @@ node bin/synced-flow.mjs doctor --cwd examples/plain-html
|
|
|
61
61
|
|
|
62
62
|
If a browser-visible example changes, inspect it at mobile and desktop widths
|
|
63
63
|
before calling the release ready.
|
|
64
|
+
|
|
65
|
+
## npm Trusted Publishing
|
|
66
|
+
|
|
67
|
+
Publishing is handled by `.github/workflows/npm-publish.yml` when a `v*` tag is
|
|
68
|
+
pushed. The workflow checks that the tag matches `package.json`, installs with
|
|
69
|
+
pnpm, runs tests, verifies package contents, and publishes with npm trusted
|
|
70
|
+
publishing.
|
|
71
|
+
|
|
72
|
+
Configure npm package trusted publishing for `@syncedco/flow` with:
|
|
73
|
+
|
|
74
|
+
- Provider: GitHub Actions
|
|
75
|
+
- Organization or user: `SyncedCo`
|
|
76
|
+
- Repository: `synced-flow`
|
|
77
|
+
- Workflow filename: `npm-publish.yml`
|
|
78
|
+
- Allowed action: `npm publish`
|
|
79
|
+
|
|
80
|
+
After this is verified, prefer npm's package setting to require two-factor
|
|
81
|
+
authentication and disallow token publishing.
|
package/docs/tokens.md
CHANGED
|
@@ -28,6 +28,11 @@ Semantic tokens describe intent.
|
|
|
28
28
|
--sf-colour-success-soft: oklch(62% 0.13 150 / 0.12);
|
|
29
29
|
```
|
|
30
30
|
|
|
31
|
+
Tokens are emitted outside CSS layers so configured themes can act as the
|
|
32
|
+
source of truth for brand colours, radius, layout, and component decisions.
|
|
33
|
+
Use `theme.darkColours` for dark-mode values instead of maintaining a separate
|
|
34
|
+
CSS file that redefines `--sf-*` variables.
|
|
35
|
+
|
|
31
36
|
Use semantic utilities in projects:
|
|
32
37
|
|
|
33
38
|
```html
|
|
@@ -77,3 +82,9 @@ The generated core includes enough semantic variables for common website UI:
|
|
|
77
82
|
`--sf-radius-control`, `--sf-radius-panel`, `--sf-shadow-*`
|
|
78
83
|
|
|
79
84
|
For class-level usage, see [System primitives](system-primitives.md).
|
|
85
|
+
|
|
86
|
+
Custom semantic colour names from `theme.colours`, such as `secondary` or
|
|
87
|
+
`tertiary`, are emitted as CSS variables and can be consumed directly with
|
|
88
|
+
`var(--sf-colour-tertiary)`. Generated colour utilities are available when the
|
|
89
|
+
class token is present in scanned source, for example `text-tertiary` or
|
|
90
|
+
`bg-tertiary`.
|
package/package.json
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@syncedco/flow",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "AI-native fluid CSS design system for brand-consistent websites and agency builds.",
|
|
5
5
|
"type": "module",
|
|
6
|
+
"packageManager": "pnpm@11.2.2",
|
|
6
7
|
"license": "MIT",
|
|
7
8
|
"keywords": [
|
|
8
9
|
"css",
|
|
@@ -21,7 +22,7 @@
|
|
|
21
22
|
"type": "git",
|
|
22
23
|
"url": "git+https://github.com/SyncedCo/synced-flow.git"
|
|
23
24
|
},
|
|
24
|
-
"homepage": "https://
|
|
25
|
+
"homepage": "https://docs.syncedflow.dev",
|
|
25
26
|
"bugs": {
|
|
26
27
|
"url": "https://github.com/SyncedCo/synced-flow/issues"
|
|
27
28
|
},
|
package/styles.css
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
/* Generated by @syncedco/flow. Edit src/tokens.mjs or scripts/build-css.mjs, then run pnpm build. */
|
|
2
2
|
@layer reset, tokens, base, app, layout, components, utilities;
|
|
3
|
-
|
|
4
|
-
:root {
|
|
3
|
+
:root {
|
|
5
4
|
color-scheme: light;
|
|
6
5
|
|
|
7
6
|
--sf-font-sans: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
|
@@ -195,7 +194,6 @@
|
|
|
195
194
|
--sf-colour-link: var(--sf-colour-orange-500);
|
|
196
195
|
--sf-colour-link-hover: oklch(80% 0.14 50);
|
|
197
196
|
}
|
|
198
|
-
}
|
|
199
197
|
@layer reset {
|
|
200
198
|
*, *::before, *::after { box-sizing: border-box; }
|
|
201
199
|
*:where(:not(dialog)) { margin: 0; }
|
package/tokens.css
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
/* Generated by @syncedco/flow. Edit src/tokens.mjs or scripts/build-css.mjs, then run pnpm build. */
|
|
2
2
|
@layer reset, tokens, base, app, layout, components, utilities;
|
|
3
|
-
|
|
4
|
-
:root {
|
|
3
|
+
:root {
|
|
5
4
|
color-scheme: light;
|
|
6
5
|
|
|
7
6
|
--sf-font-sans: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
|
@@ -195,4 +194,3 @@
|
|
|
195
194
|
--sf-colour-link: var(--sf-colour-orange-500);
|
|
196
195
|
--sf-colour-link-hover: oklch(80% 0.14 50);
|
|
197
196
|
}
|
|
198
|
-
}
|