@xenosystem/components 0.5.0 → 0.7.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.
@@ -44,8 +44,10 @@ interface SignInFormProps {
44
44
  animate?: boolean;
45
45
  /** Diagnostic hook the panel sets to its phase; carried to the DOM as `data-phase`. */
46
46
  phase?: string;
47
+ /** One callback for every action (a declaration binds this once); an action's own `onClick` still wins. */
48
+ onAction?: (id: string) => void;
47
49
  }
48
- declare function SignInForm({ tag, title, body, actions, note, warning, identity, animate, phase }: SignInFormProps): react.JSX.Element;
50
+ declare function SignInForm({ tag, title, body, actions, note, warning, identity, animate, phase, onAction }: SignInFormProps): react.JSX.Element;
49
51
  /** The licence plates are the same form with a tag; kept as a name so a panel reads honestly. */
50
52
  declare const LicencePlate: typeof SignInForm;
51
53
 
@@ -19,7 +19,7 @@ var CSS = `
19
19
  .xc-auth[data-aspect=square] .xc-brand svg,.xc-auth__head .xc-brand svg{width:20px;height:20px}
20
20
  .xc-brand__word{font-size:13px;font-weight:700;letter-spacing:.2em;text-transform:uppercase}
21
21
  .xc-auth[data-aspect=square] .xc-brand__word,.xc-auth__head .xc-brand__word{font-size:11px}
22
- .xc-hero__h1{font-size:3.5rem;font-weight:700;line-height:1.1;letter-spacing:-.02em;max-width:32rem}
22
+ .xc-hero__h1{font-size:3.5rem;font-weight:700;line-height:1.1;letter-spacing:-.02em;max-width:32rem;white-space:pre-line}
23
23
  .xc-auth[data-aspect=square] .xc-hero__h1{font-size:2rem}
24
24
  .xc-hero__lead{margin-top:16px;max-width:24rem;font-size:16px;line-height:1.6}
25
25
  .xc-hero__stats{display:flex;align-items:center;gap:32px}
@@ -134,7 +134,7 @@ function AuthHero({ headline, lead, stats, imageSrc, compact }) {
134
134
  import { useEffect, useState } from "react";
135
135
  import { Button } from "@xenosystem/elements-react";
136
136
  import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
137
- function SignInForm({ tag, title, body, actions, note, warning, identity, animate = true, phase }) {
137
+ function SignInForm({ tag, title, body, actions, note, warning, identity, animate = true, phase, onAction }) {
138
138
  useAuthStyles();
139
139
  const [visible, setVisible] = useState(!animate);
140
140
  useEffect(() => {
@@ -146,7 +146,7 @@ function SignInForm({ tag, title, body, actions, note, warning, identity, animat
146
146
  tag && /* @__PURE__ */ jsx3("span", { className: "xc-form__tag", children: tag }),
147
147
  /* @__PURE__ */ jsx3("h2", { className: "xc-form__h2", children: title }),
148
148
  /* @__PURE__ */ jsx3("p", { className: "xc-form__sub", children: body }),
149
- actions.length > 0 && /* @__PURE__ */ jsx3("div", { className: "xc-form__actions", children: actions.map((a) => /* @__PURE__ */ jsx3(Button, { variant: a.variant ?? "secondary", size: "lg", disabled: a.disabled, onClick: a.onClick, "data-intent": a.id, children: a.label }, a.id)) }),
149
+ actions.length > 0 && /* @__PURE__ */ jsx3("div", { className: "xc-form__actions", children: actions.map((a) => /* @__PURE__ */ jsx3(Button, { variant: a.variant ?? "secondary", size: "lg", disabled: a.disabled, onClick: a.onClick ?? (onAction ? () => onAction(a.id) : void 0), "data-intent": a.id, children: a.label }, a.id)) }),
150
150
  note && /* @__PURE__ */ jsx3("p", { className: "xc-form__note", children: note }),
151
151
  warning && /* @__PURE__ */ jsx3("p", { className: "xc-form__warn", children: warning }),
152
152
  identity && /* @__PURE__ */ jsxs3("p", { className: "xc-form__who", children: [
@@ -0,0 +1,7 @@
1
+ /** The shape of `@xenosystem/components/catalog` (dist/catalog.json) — see scripts/catalog.mjs. */
2
+ export interface CatalogProp { name: string; type: string; optional: boolean; doc: string }
3
+ export interface CatalogUnit { name: string; file: string; doc: string; props: string | null; propList: CatalogProp[] }
4
+ export interface CatalogFamily { family: string; units: CatalogUnit[] }
5
+ export interface Catalog { generatedFrom: string; families: CatalogFamily[] }
6
+ declare const catalog: Catalog
7
+ export default catalog
@@ -0,0 +1,337 @@
1
+ {
2
+ "generatedFrom": "@xenosystem/components (source, at build)",
3
+ "families": [
4
+ {
5
+ "family": "auth",
6
+ "units": [
7
+ {
8
+ "name": "AuthDoor",
9
+ "file": "AuthDoor.tsx",
10
+ "doc": "Hub's three aspect modes, measured on the door's OWN box — in a product the door is `inset: 0`\nand the two agree; in a harness it is a tile, and a component lays itself out for the box it\nwas given.",
11
+ "props": "AuthDoorProps",
12
+ "propList": [
13
+ {
14
+ "name": "hero",
15
+ "type": "Omit<AuthHeroProps, 'compact'>",
16
+ "optional": false,
17
+ "doc": ""
18
+ },
19
+ {
20
+ "name": "label",
21
+ "type": "string",
22
+ "optional": false,
23
+ "doc": "Aria label of the dialog."
24
+ },
25
+ {
26
+ "name": "children",
27
+ "type": "ReactNode",
28
+ "optional": false,
29
+ "doc": ""
30
+ },
31
+ {
32
+ "name": "rootAttributes",
33
+ "type": "Record<string, string | undefined>",
34
+ "optional": true,
35
+ "doc": "Diagnostic: carried to the root as `data-xeno-auth-gate` by the panel."
36
+ }
37
+ ]
38
+ },
39
+ {
40
+ "name": "AuthHero",
41
+ "file": "AuthHero.tsx",
42
+ "doc": "",
43
+ "props": "AuthHeroProps",
44
+ "propList": [
45
+ {
46
+ "name": "headline",
47
+ "type": "ReactNode",
48
+ "optional": false,
49
+ "doc": ""
50
+ },
51
+ {
52
+ "name": "lead",
53
+ "type": "ReactNode",
54
+ "optional": true,
55
+ "doc": ""
56
+ },
57
+ {
58
+ "name": "stats",
59
+ "type": "AuthHeroStat[]",
60
+ "optional": true,
61
+ "doc": ""
62
+ },
63
+ {
64
+ "name": "imageSrc",
65
+ "type": "string",
66
+ "optional": true,
67
+ "doc": ""
68
+ },
69
+ {
70
+ "name": "compact",
71
+ "type": "boolean",
72
+ "optional": true,
73
+ "doc": "`banner` is the short form (the square aspect): brand + headline only."
74
+ }
75
+ ]
76
+ },
77
+ {
78
+ "name": "CredentialForm",
79
+ "file": "CredentialForm.tsx",
80
+ "doc": "",
81
+ "props": "CredentialFormProps",
82
+ "propList": [
83
+ {
84
+ "name": "mode",
85
+ "type": "CredentialMode",
86
+ "optional": false,
87
+ "doc": ""
88
+ },
89
+ {
90
+ "name": "onModeChange",
91
+ "type": "(mode: CredentialMode) => void",
92
+ "optional": false,
93
+ "doc": ""
94
+ },
95
+ {
96
+ "name": "values",
97
+ "type": "CredentialValues",
98
+ "optional": false,
99
+ "doc": ""
100
+ },
101
+ {
102
+ "name": "onChange",
103
+ "type": "(values: CredentialValues) => void",
104
+ "optional": false,
105
+ "doc": ""
106
+ },
107
+ {
108
+ "name": "errors",
109
+ "type": "CredentialErrors",
110
+ "optional": true,
111
+ "doc": ""
112
+ },
113
+ {
114
+ "name": "submitting",
115
+ "type": "boolean",
116
+ "optional": true,
117
+ "doc": ""
118
+ },
119
+ {
120
+ "name": "onSubmit",
121
+ "type": "() => void",
122
+ "optional": false,
123
+ "doc": ""
124
+ },
125
+ {
126
+ "name": "title",
127
+ "type": "ReactNode",
128
+ "optional": true,
129
+ "doc": "Rendered above the switch — the page's \"Welcome back\" / \"Get started\" copy."
130
+ },
131
+ {
132
+ "name": "body",
133
+ "type": "ReactNode",
134
+ "optional": true,
135
+ "doc": ""
136
+ },
137
+ {
138
+ "name": "before",
139
+ "type": "ReactNode",
140
+ "optional": true,
141
+ "doc": "Rendered between the switch and the fields — `SocialSignIn` + `OrDivider`, when the page has them."
142
+ },
143
+ {
144
+ "name": "after",
145
+ "type": "ReactNode",
146
+ "optional": true,
147
+ "doc": "Rendered under the submit — \"Forgot password?\", terms, the other-mode link."
148
+ },
149
+ {
150
+ "name": "passwordRules",
151
+ "type": "{ label: string; met: boolean }[]",
152
+ "optional": true,
153
+ "doc": "Live password rules (sign-up): shown while the field is focused or partly filled — never before,\n a list of things you have failed before you typed is a telling-off for a crime not yet committed."
154
+ },
155
+ {
156
+ "name": "passwordAside",
157
+ "type": "ReactNode",
158
+ "optional": true,
159
+ "doc": "Rendered beside the password label — the page's \"Forgot?\" link on sign-in."
160
+ },
161
+ {
162
+ "name": "open",
163
+ "type": "boolean",
164
+ "optional": true,
165
+ "doc": "When false, the fields collapse (0fr grid) and leave the accessibility tree; the page's disclosure\n controls it. Default open."
166
+ },
167
+ {
168
+ "name": "id",
169
+ "type": "string",
170
+ "optional": true,
171
+ "doc": "id for the collapsible region (matched by `EmailDisclosure.controls`)."
172
+ },
173
+ {
174
+ "name": "labels",
175
+ "type": "Partial<Record<'name' | 'email' | 'password' | 'submitSignIn' | 'submitSignUp' | 'signin' | 'signup', string>>",
176
+ "optional": true,
177
+ "doc": "Copy overrides; defaults are the platform page's."
178
+ }
179
+ ]
180
+ },
181
+ {
182
+ "name": "EmailDisclosure",
183
+ "file": "EmailDisclosure.tsx",
184
+ "doc": "",
185
+ "props": "EmailDisclosureProps",
186
+ "propList": [
187
+ {
188
+ "name": "open",
189
+ "type": "boolean",
190
+ "optional": false,
191
+ "doc": ""
192
+ },
193
+ {
194
+ "name": "onToggle",
195
+ "type": "() => void",
196
+ "optional": false,
197
+ "doc": ""
198
+ },
199
+ {
200
+ "name": "controls",
201
+ "type": "string",
202
+ "optional": false,
203
+ "doc": "id of the form region it controls."
204
+ },
205
+ {
206
+ "name": "openLabel",
207
+ "type": "string",
208
+ "optional": true,
209
+ "doc": ""
210
+ },
211
+ {
212
+ "name": "closedLabel",
213
+ "type": "string",
214
+ "optional": true,
215
+ "doc": ""
216
+ }
217
+ ]
218
+ },
219
+ {
220
+ "name": "OrDivider",
221
+ "file": "OrDivider.tsx",
222
+ "doc": "The \"or continue with email\" rule between the social row and the fields.",
223
+ "props": null,
224
+ "propList": [
225
+ {
226
+ "name": "children",
227
+ "type": "string",
228
+ "optional": true,
229
+ "doc": ""
230
+ }
231
+ ]
232
+ },
233
+ {
234
+ "name": "SignInForm",
235
+ "file": "SignInForm.tsx",
236
+ "doc": "",
237
+ "props": "SignInFormProps",
238
+ "propList": [
239
+ {
240
+ "name": "tag",
241
+ "type": "string",
242
+ "optional": true,
243
+ "doc": "A small uppercase tag above the heading — `No active plan`, `Update required`."
244
+ },
245
+ {
246
+ "name": "title",
247
+ "type": "ReactNode",
248
+ "optional": false,
249
+ "doc": ""
250
+ },
251
+ {
252
+ "name": "body",
253
+ "type": "ReactNode",
254
+ "optional": false,
255
+ "doc": ""
256
+ },
257
+ {
258
+ "name": "actions",
259
+ "type": "SignInAction[]",
260
+ "optional": false,
261
+ "doc": ""
262
+ },
263
+ {
264
+ "name": "note",
265
+ "type": "ReactNode",
266
+ "optional": true,
267
+ "doc": "Explanatory note under the actions (where the credential is entered, etc)."
268
+ },
269
+ {
270
+ "name": "warning",
271
+ "type": "ReactNode",
272
+ "optional": true,
273
+ "doc": "A warning line — the host's own sentence about what went wrong."
274
+ },
275
+ {
276
+ "name": "identity",
277
+ "type": "string",
278
+ "optional": true,
279
+ "doc": "Who is signed in, when known — display only."
280
+ },
281
+ {
282
+ "name": "animate",
283
+ "type": "boolean",
284
+ "optional": true,
285
+ "doc": "The entrance fade; `false` renders settled (tests, screenshots)."
286
+ },
287
+ {
288
+ "name": "phase",
289
+ "type": "string",
290
+ "optional": true,
291
+ "doc": "Diagnostic hook the panel sets to its phase; carried to the DOM as `data-phase`."
292
+ },
293
+ {
294
+ "name": "onAction",
295
+ "type": "(id: string) => void",
296
+ "optional": true,
297
+ "doc": "One callback for every action (a declaration binds this once); an action's own `onClick` still wins."
298
+ }
299
+ ]
300
+ },
301
+ {
302
+ "name": "SocialSignIn",
303
+ "file": "SocialSignIn.tsx",
304
+ "doc": "",
305
+ "props": "SocialSignInProps",
306
+ "propList": [
307
+ {
308
+ "name": "providers",
309
+ "type": "readonly SocialProvider[]",
310
+ "optional": true,
311
+ "doc": ""
312
+ },
313
+ {
314
+ "name": "onSelect",
315
+ "type": "(provider: SocialProvider) => void",
316
+ "optional": false,
317
+ "doc": ""
318
+ },
319
+ {
320
+ "name": "disabled",
321
+ "type": "boolean",
322
+ "optional": true,
323
+ "doc": ""
324
+ }
325
+ ]
326
+ },
327
+ {
328
+ "name": "XenoMark",
329
+ "file": "XenoMark.tsx",
330
+ "doc": "",
331
+ "props": null,
332
+ "propList": []
333
+ }
334
+ ]
335
+ }
336
+ ]
337
+ }
package/dist/index.d.ts CHANGED
@@ -3,6 +3,6 @@
3
3
  * Families are subpaths: `@xenosystem/components/auth`, `/navigation`, `/feedback`, `/data`.
4
4
  * This root re-exports nothing on purpose: import the family you use, so a bundle carries only it.
5
5
  */
6
- declare const COMPONENTS_VERSION = "0.5.0";
6
+ declare const COMPONENTS_VERSION = "0.6.0";
7
7
 
8
8
  export { COMPONENTS_VERSION };
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/index.ts
2
- var COMPONENTS_VERSION = "0.5.0";
2
+ var COMPONENTS_VERSION = "0.6.0";
3
3
  export {
4
4
  COMPONENTS_VERSION
5
5
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@xenosystem/components",
3
- "version": "0.5.0",
4
- "description": "XENO Components rung 2 of the front ladder: molecules composed from @xenosystem/elements, with no host contract. Families as subpaths: /auth, /navigation, /feedback, /data.",
3
+ "version": "0.7.0",
4
+ "description": "XENO Components \u2014 rung 2 of the front ladder: molecules composed from @xenosystem/elements, with no host contract. Families as subpaths: /auth, /navigation, /feedback, /data.",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",
7
7
  "sideEffects": false,
@@ -13,6 +13,10 @@
13
13
  "./auth": {
14
14
  "types": "./dist/auth/index.d.ts",
15
15
  "import": "./dist/auth/index.js"
16
+ },
17
+ "./catalog": {
18
+ "types": "./dist/catalog.d.ts",
19
+ "default": "./dist/catalog.json"
16
20
  }
17
21
  },
18
22
  "files": [
@@ -20,10 +24,11 @@
20
24
  "README.md"
21
25
  ],
22
26
  "scripts": {
23
- "build": "tsup",
27
+ "build": "tsup && node scripts/catalog.mjs",
24
28
  "typecheck": "tsc --noEmit",
25
29
  "test": "vitest run",
26
- "prepublishOnly": "node scripts/verify-dist.mjs"
30
+ "prepublishOnly": "node scripts/verify-dist.mjs",
31
+ "catalog:check": "node scripts/catalog.mjs --check"
27
32
  },
28
33
  "peerDependencies": {
29
34
  "@xenosystem/elements-react": ">=0.0.1",