@webjsdev/ui 0.3.11 → 0.3.12
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 +5 -2
- package/package.json +1 -1
- package/packages/registry/README.md +4 -2
- package/packages/registry/lib/utils.ts +61 -6
- package/packages/registry/package.json +1 -1
- package/packages/registry/themes/base-colors.js +1 -1
- package/src/commands/add.js +2 -2
- package/src/commands/diff.js +2 -2
- package/src/commands/info.js +1 -1
- package/src/commands/init.js +1 -1
- package/src/registry/example.js +7 -4
- package/src/registry/fetcher.js +7 -7
- package/src/registry/local.js +1 -1
package/README.md
CHANGED
|
@@ -64,7 +64,9 @@ so on. Follow that block and the markup is fully accessible.
|
|
|
64
64
|
|
|
65
65
|
Nothing to install. `@webjsdev/ui` is a hard dependency of `@webjsdev/cli`,
|
|
66
66
|
so a global webjs install already includes it. Apps scaffolded with
|
|
67
|
-
`webjs create`
|
|
67
|
+
`webjs create` reach it the same way. The scaffold deliberately does not pin
|
|
68
|
+
it, because the kit copies source into your project rather than being
|
|
69
|
+
imported at runtime, so the CLI resolves it from its own install.
|
|
68
70
|
|
|
69
71
|
```sh
|
|
70
72
|
webjs ui init
|
|
@@ -105,7 +107,8 @@ configured alias). Resolves transitive deps via `registryDependencies` and
|
|
|
105
107
|
auto-installs npm deps like `@floating-ui/dom` for popover-style components. For
|
|
106
108
|
a Tier-1 class-helper component it copies the helpers plus a lean header and a
|
|
107
109
|
one-line pointer, and leaves the worked structural example OUT of the file (get
|
|
108
|
-
it on demand with `
|
|
110
|
+
it on demand with `npx @webjsdev/ui view <name>`, which is what the pointer it
|
|
111
|
+
leaves behind says too). It also self-heals the theme tokens if
|
|
109
112
|
they are missing.
|
|
110
113
|
|
|
111
114
|
Resolution is LOCAL-FIRST: `init` / `add` / `list` / `view` read the registry
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webjsdev/ui",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.12",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "The AI-first component library for WebJs, a full-stack JavaScript framework built on web components with server-side rendering and no build step. Class-helper functions for visuals, custom elements only where state matters, source-copied into your repo so you own it.",
|
|
6
6
|
"bin": {
|
|
@@ -10,8 +10,10 @@ fetches. There is no build step, no generated output, no `prestart` hook.
|
|
|
10
10
|
|
|
11
11
|
The composer and the routes moved out of this package with #1099, when the
|
|
12
12
|
gallery merged into the marketing site. The old `ui.webjs.dev/registry/**`
|
|
13
|
-
URLs
|
|
14
|
-
|
|
13
|
+
URLs now redirect to the gallery page rather than to their new equivalents,
|
|
14
|
+
so they no longer serve registry JSON. That breaks `webjsui add` on the
|
|
15
|
+
published 0.3.1 through 0.3.8, which hardcode them; 0.3.9 onward resolves
|
|
16
|
+
local-first and never fetches them.
|
|
15
17
|
|
|
16
18
|
## Layout
|
|
17
19
|
|
|
@@ -5,8 +5,10 @@
|
|
|
5
5
|
* - Concatenates truthy arguments separated by spaces.
|
|
6
6
|
* - Later Tailwind utilities win when they target the same property, mimicking
|
|
7
7
|
* `tailwind-merge`'s behaviour for the cases components actually hit
|
|
8
|
-
* (background colour,
|
|
9
|
-
*
|
|
8
|
+
* (background colour, image, clip, origin, blend mode, position, size,
|
|
9
|
+
* repeat, attachment; text colour, size, alignment, wrapping, overflow;
|
|
10
|
+
* box-shadow and text-shadow, each split into size and colour; padding,
|
|
11
|
+
* margin, width, height, border, rounded, opacity, display).
|
|
10
12
|
*
|
|
11
13
|
* For projects that want the full tailwind-merge behaviour, install
|
|
12
14
|
* `clsx` + `tailwind-merge` and replace this file:
|
|
@@ -60,12 +62,39 @@ const GROUPS: Array<[RegExp, string]> = [
|
|
|
60
62
|
[/^bg-(no-repeat|repeat|repeat-x|repeat-y|repeat-round|repeat-space)$/, 'bg-repeat'],
|
|
61
63
|
[/^bg-(fixed|local|scroll)$/, 'bg-attach'],
|
|
62
64
|
[/^bg-(auto|cover|contain)$/, 'bg-size'],
|
|
63
|
-
[/^bg-
|
|
65
|
+
[/^bg-size-/, 'bg-size'],
|
|
66
|
+
// Two entries rather than one alternation: the first covers the live v4
|
|
67
|
+
// compounds (`bg-top-left`), the second the bare keywords plus the v4.1
|
|
68
|
+
// deprecated reversed compounds (`bg-left-top`), which tailwind-merge still
|
|
69
|
+
// carries. An unmatched `bg-*` token falls into the colour catch-all below and
|
|
70
|
+
// evicts a real colour, so admitting a dead spelling is the safe direction.
|
|
71
|
+
[/^bg-(top|bottom)(-(left|right))?$/, 'bg-position'],
|
|
72
|
+
[/^bg-(left|right|center)(-(top|bottom))?$/, 'bg-position'],
|
|
73
|
+
[/^bg-position-/, 'bg-position'],
|
|
74
|
+
// Clip, origin, and blend mode are three more properties under the same
|
|
75
|
+
// prefix. Each sat in `bg-color` before, so `bg-clip-text` evicted a real
|
|
76
|
+
// background colour (the gradient-text idiom lost its clip silently).
|
|
77
|
+
[/^bg-clip-(border|padding|content|text)$/, 'bg-clip'],
|
|
78
|
+
[/^bg-origin-(border|padding|content)$/, 'bg-origin'],
|
|
79
|
+
[/^bg-blend-(normal|multiply|screen|overlay|darken|lighten|color-dodge|color-burn|hard-light|soft-light|difference|exclusion|hue|saturation|color|luminosity)$/, 'bg-blend'],
|
|
64
80
|
[/^bg-/, 'bg-color'],
|
|
81
|
+
// text-shadow is its own property, and its size scale and its colour are two
|
|
82
|
+
// properties again. All three entries precede the text- patterns below, which
|
|
83
|
+
// is what keeps a `text-shadow-*` token out of `text-size` and `text-color`.
|
|
84
|
+
[/^text-shadow(-(2xs|xs|sm|md|lg|none))?(\/([\d.]+|\[[^\]]*\]))?$/, 'text-shadow'],
|
|
85
|
+
[/^text-shadow-(\[(inset|-|\.|\d|var\()|\(--)/, 'text-shadow'],
|
|
86
|
+
[/^text-shadow-/, 'text-shadow-color'],
|
|
65
87
|
// Font size: explicit list of Tailwind size scale.
|
|
66
88
|
[/^text-(xs|sm|base|lg|xl|2xl|3xl|4xl|5xl|6xl|7xl|8xl|9xl)$/, 'text-size'],
|
|
67
|
-
//
|
|
68
|
-
|
|
89
|
+
// Alignment, wrapping, and overflow are three more properties under the same
|
|
90
|
+
// prefix. Each was previously excluded from text-color by a lookahead and then
|
|
91
|
+
// matched nothing at all, so two alignments never collapsed.
|
|
92
|
+
[/^text-(left|center|right|justify|start|end)$/, 'text-align'],
|
|
93
|
+
[/^text-(wrap|nowrap|balance|pretty)$/, 'text-wrap'],
|
|
94
|
+
[/^text-(ellipsis|clip)$/, 'text-overflow'],
|
|
95
|
+
// Text color: anything else under the prefix. The specific groups above are
|
|
96
|
+
// the whole carve-out, so no negative lookahead is needed here as well.
|
|
97
|
+
[/^text-/, 'text-color'],
|
|
69
98
|
// Border sub-properties that are neither a width nor a colour. These come
|
|
70
99
|
// FIRST so the width / colour classifier below never sees them.
|
|
71
100
|
[/^border-(collapse|separate)$/, 'border-collapse'],
|
|
@@ -76,7 +105,27 @@ const GROUPS: Array<[RegExp, string]> = [
|
|
|
76
105
|
[/^rounded-/, 'rounded'],
|
|
77
106
|
[/^opacity-/, 'opacity'],
|
|
78
107
|
[/^font-(thin|light|normal|medium|semibold|bold|black|extralight|extrabold)$/, 'font-weight'],
|
|
79
|
-
|
|
108
|
+
// Box-shadow SIZE and box-shadow COLOUR are two properties (`box-shadow` and
|
|
109
|
+
// `--tw-shadow-color`), so they need two groups. `shadow-none` is a size,
|
|
110
|
+
// `shadow-inherit` / `shadow-initial` are colours, and Tailwind accepts an
|
|
111
|
+
// alpha modifier on a size as well as on a colour, so `shadow-lg/25` has to
|
|
112
|
+
// stay on the size side. An unhinted arbitrary value is a SIZE when it opens
|
|
113
|
+
// with `inset`, a sign, a dot, or a digit (a shadow offset list) and also
|
|
114
|
+
// when it is a bare `var()` or the `(--x)` variable shorthand: Tailwind
|
|
115
|
+
// itself resolves an ambiguous arbitrary shadow to `box-shadow` unless the
|
|
116
|
+
// value is provably a colour, and `shadow-[var(--shadow-glow)]` is the normal
|
|
117
|
+
// way to write a design-token shadow. This is the one place the
|
|
118
|
+
// `borderGroups()` convention inverts, because a bare `border-[var(--x)]` is
|
|
119
|
+
// far more often a colour while a bare `shadow-[var(--x)]` is far more often
|
|
120
|
+
// a shadow. The size entries must precede the colour catch-all, or every
|
|
121
|
+
// size lands in the colour group and the bug inverts rather than being fixed.
|
|
122
|
+
[/^shadow(-(2xs|xs|sm|md|lg|xl|2xl|inner|none))?(\/([\d.]+|\[[^\]]*\]))?$/, 'shadow'],
|
|
123
|
+
[/^shadow-(\[(inset|-|\.|\d|var\()|\(--)/, 'shadow'],
|
|
124
|
+
// A bare name the size scale does not list reads as a colour, because
|
|
125
|
+
// `shadow-primary` is overwhelmingly more common than a `@theme`-extended
|
|
126
|
+
// `--shadow-card`. A project that adds a custom shadow NAME is the residual
|
|
127
|
+
// gap, and the docs say so rather than claiming the split is total.
|
|
128
|
+
[/^shadow-/, 'shadow-color'],
|
|
80
129
|
[/^z-/, 'z'],
|
|
81
130
|
// A bare `flex` / `grid` is a DISPLAY value, not a member of the flex / grid
|
|
82
131
|
// sub-property groups below, so it must never dedupe against them: an element
|
|
@@ -165,6 +214,12 @@ const HINTED_GROUPS: Record<string, string> = {
|
|
|
165
214
|
'bg:length': 'bg-size',
|
|
166
215
|
'text:color': '',
|
|
167
216
|
'text:length': 'text-size',
|
|
217
|
+
// Both shadow prefixes carry a colour that is a DIFFERENT property from the
|
|
218
|
+
// prefix's own default (the size), so the hint has a named group to point at
|
|
219
|
+
// and must, or `shadow-[color:red]` keeps an isolated bucket and stops
|
|
220
|
+
// deduping against `shadow-red-500`, which sets the identical property.
|
|
221
|
+
'shadow:color': 'shadow-color',
|
|
222
|
+
'text-shadow:color': 'text-shadow-color',
|
|
168
223
|
};
|
|
169
224
|
|
|
170
225
|
/**
|
|
@@ -3,5 +3,5 @@
|
|
|
3
3
|
"version": "0.1.0",
|
|
4
4
|
"private": true,
|
|
5
5
|
"type": "module",
|
|
6
|
-
"description": "Source registry for @webjsdev/ui
|
|
6
|
+
"description": "Source registry for @webjsdev/ui, holding component sources, themes, and lib. Read on demand by the website gallery to compose registry JSON at request time."
|
|
7
7
|
}
|
|
@@ -165,7 +165,7 @@ export const BASE_OVERRIDES = {
|
|
|
165
165
|
* the original file's formatting + comments verbatim: only the values
|
|
166
166
|
* change.
|
|
167
167
|
*
|
|
168
|
-
* @param {string} neutralCss
|
|
168
|
+
* @param {string} neutralCss Verbatim contents of `themes/index.css`
|
|
169
169
|
* @param {{ light: Record<string,string>, dark: Record<string,string> }} overrides
|
|
170
170
|
*/
|
|
171
171
|
export function mergeThemeCss(neutralCss, overrides) {
|
package/src/commands/add.js
CHANGED
|
@@ -25,13 +25,13 @@ export const add = new Command()
|
|
|
25
25
|
const config = getConfig(cwd);
|
|
26
26
|
if (!config) {
|
|
27
27
|
logger.error(`No ${logger.cyan('components.json')} found in ${cwd}.`);
|
|
28
|
-
logger.info(`Run ${logger.cyan('npx
|
|
28
|
+
logger.info(`Run ${logger.cyan('npx @webjsdev/ui init')} first.`);
|
|
29
29
|
process.exit(1);
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
if (!components || components.length === 0) {
|
|
33
33
|
logger.error('No components specified.');
|
|
34
|
-
logger.info(`Try ${logger.cyan('npx
|
|
34
|
+
logger.info(`Try ${logger.cyan('npx @webjsdev/ui add button')} or ${logger.cyan('npx @webjsdev/ui list')}.`);
|
|
35
35
|
process.exit(1);
|
|
36
36
|
}
|
|
37
37
|
|
package/src/commands/diff.js
CHANGED
|
@@ -15,7 +15,7 @@ export const diff = new Command()
|
|
|
15
15
|
.action(async (name, opts) => {
|
|
16
16
|
const config = getConfig(opts.cwd);
|
|
17
17
|
if (!config) {
|
|
18
|
-
logger.error('No components.json. Run `
|
|
18
|
+
logger.error('No components.json. Run `npx @webjsdev/ui init` first.');
|
|
19
19
|
process.exit(1);
|
|
20
20
|
}
|
|
21
21
|
|
|
@@ -52,5 +52,5 @@ export const diff = new Command()
|
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
if (changed === 0) logger.success('All local components match the registry.');
|
|
55
|
-
else logger.info(`\n${changed} file${changed === 1 ? '' : 's'} differ. Re-add with ${logger.cyan('
|
|
55
|
+
else logger.info(`\n${changed} file${changed === 1 ? '' : 's'} differ. Re-add with ${logger.cyan('npx @webjsdev/ui add <name> -o')} to overwrite.`);
|
|
56
56
|
});
|
package/src/commands/info.js
CHANGED
|
@@ -15,7 +15,7 @@ export const info = new Command()
|
|
|
15
15
|
|
|
16
16
|
logger.info(`${logger.bold('cwd')} ${cwd}`);
|
|
17
17
|
logger.info(`${logger.bold('Registry')} ${DEFAULT_REGISTRY_URL}`);
|
|
18
|
-
logger.info(`${logger.bold('Config')} ${config ? 'components.json ✔' : 'components.json ✖ (run `
|
|
18
|
+
logger.info(`${logger.bold('Config')} ${config ? 'components.json ✔' : 'components.json ✖ (run `npx @webjsdev/ui init`)'}`);
|
|
19
19
|
if (config) {
|
|
20
20
|
logger.info(`${logger.bold('Base color')} ${config.tailwind.baseColor}`);
|
|
21
21
|
logger.info(`${logger.bold('Tailwind CSS')} ${config.tailwind.css}`);
|
package/src/commands/init.js
CHANGED
|
@@ -162,7 +162,7 @@ export const init = new Command()
|
|
|
162
162
|
logger.break();
|
|
163
163
|
logger.success('Done.');
|
|
164
164
|
logger.info('');
|
|
165
|
-
logger.info(`Add components with: ${logger.cyan('npx
|
|
165
|
+
logger.info(`Add components with: ${logger.cyan('npx @webjsdev/ui add button card dialog')}`);
|
|
166
166
|
});
|
|
167
167
|
|
|
168
168
|
/**
|
package/src/registry/example.js
CHANGED
|
@@ -79,10 +79,13 @@ export function extractExample(src) {
|
|
|
79
79
|
|
|
80
80
|
/**
|
|
81
81
|
* The one-line pointer left in place of a stripped example. Uses the EXPLICIT
|
|
82
|
-
* `npx @webjsdev/ui view` form
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
82
|
+
* `npx @webjsdev/ui view` form, not the bare `webjsui` bin name. `webjsui` is a
|
|
83
|
+
* bin declared INSIDE `@webjsdev/ui` and is not a published package name (the
|
|
84
|
+
* registry 404s on it), so `npx webjsui` resolves through a local
|
|
85
|
+
* `node_modules/.bin` link or not at all. This pointer is written into a file
|
|
86
|
+
* the user keeps, and it cannot know whether the project reading it later has
|
|
87
|
+
* the kit in its tree. The explicit form resolves either way. See invariant 8
|
|
88
|
+
* in this package's AGENTS.md for the rule every printed hint follows (#1264).
|
|
86
89
|
*/
|
|
87
90
|
export function pointerLine(name) {
|
|
88
91
|
return `Full usage example: npx @webjsdev/ui view ${name} (or the MCP tool: ui ${name})`;
|
package/src/registry/fetcher.js
CHANGED
|
@@ -6,12 +6,12 @@ import { loadRegistryItem, loadRegistryIndex } from './local.js';
|
|
|
6
6
|
* exact URL: it is the one registry whose sources ship inside the package.
|
|
7
7
|
*
|
|
8
8
|
* This moved from `https://ui.webjs.dev/registry` when the gallery merged into
|
|
9
|
-
* the marketing site (#1099).
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* `
|
|
13
|
-
* 0.3.
|
|
14
|
-
*
|
|
9
|
+
* the marketing site (#1099). That old URL no longer serves the registry: it
|
|
10
|
+
* now redirects to the gallery PAGE, so a fetch of it follows the redirect and
|
|
11
|
+
* gets HTML. Versions 0.3.1 through 0.3.8 hardcode it and hit the network, so
|
|
12
|
+
* `webjsui add` is broken on those and cannot be corrected after publish.
|
|
13
|
+
* Since 0.3.9 the kit resolves LOCAL-first, which is why the break stops
|
|
14
|
+
* there: `add` / `list` / `view` never reach the network on this URL.
|
|
15
15
|
*/
|
|
16
16
|
export const HOSTED_REGISTRY_URL = 'https://webjs.dev/ui/registry';
|
|
17
17
|
|
|
@@ -55,7 +55,7 @@ export async function getRegistryItem(name, registryUrl) {
|
|
|
55
55
|
const item = loadRegistryItem(name);
|
|
56
56
|
if (!item) {
|
|
57
57
|
throw new Error(
|
|
58
|
-
`Unknown registry item "${name}". Run \`
|
|
58
|
+
`Unknown registry item "${name}". Run \`npx @webjsdev/ui list\` to see the available components.`,
|
|
59
59
|
);
|
|
60
60
|
}
|
|
61
61
|
return item;
|
package/src/registry/local.js
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* item shape the hosted registry serves, so a local read and a network fetch
|
|
9
9
|
* are interchangeable for every consumer.
|
|
10
10
|
*
|
|
11
|
-
* It is the plain-JS twin of the
|
|
11
|
+
* It is the plain-JS twin of the website gallery composer
|
|
12
12
|
* (`website/modules/ui/queries/registry.server.ts`): both read
|
|
13
13
|
* `packages/registry/registry.json` + the `components/*.ts` sources and
|
|
14
14
|
* synthesize the 6 non-neutral base-colour themes from `themes/base-colors.js`.
|