@marianmeres/stuic 3.158.0 → 3.160.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.
@@ -40,35 +40,36 @@ interface RegisterFieldConfig {
40
40
 
41
41
  ## RegisterForm — Props
42
42
 
43
- | Prop | Type | Default | Description |
44
- | --------------------------- | --------------------------------------- | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
45
- | `formData` | `RegisterFormData` | empty | Bindable form data. |
46
- | `onSubmit` | `(data: RegisterFormData) => void` | required | Called after client-side validation passes. |
47
- | `isSubmitting` | `boolean` | `false` | Disables the CTA during submission. |
48
- | `submitDisabled` | `boolean` | `false` | Consumer-owned submit block. Disables the CTA **and** blocks `onSubmit`. |
49
- | `errors` | `RegisterFormValidationError[]` | `[]` | Field-specific server errors (merged with internal validation). See [Server errors](#server-supplied-errors). |
50
- | `error` | `string` | - | General error rendered as a `DismissibleMessage` above the form. |
51
- | `showEmail` | `boolean` | `true` | Render the email field. `false` **unmounts** it and skips its validation. |
52
- | `showPassword` | `boolean` | `true` | Render the password field (and, transitively, the confirm field). |
53
- | `showPasswordConfirm` | `boolean` | `true` | Render the password-confirm field. Subordinate to `showPassword`. |
54
- | `passwordMinLength` | `number` | `8` | Minimum password length (fed into both the FieldInput attribute and the validator). |
55
- | `credentialsSlot` | `Snippet<[{ formData, fieldError }]>` | - | Rendered at the credentials position (after the core fields, before bottom extra fields). |
56
- | `emailFieldProps` | `Partial<FieldInputProps>` | - | Passthrough props for the built-in email field. |
57
- | `passwordFieldProps` | `Partial<FieldInputProps>` | - | Passthrough props for the built-in password field. |
58
- | `passwordConfirmFieldProps` | `Partial<FieldInputProps>` | - | Passthrough props for the built-in confirm field. |
59
- | `extraFields` | `RegisterFieldConfig[]` | `[]` | Declarative extra fields. Rendered as `FieldInput`s positioned top or bottom. |
60
- | `extraFieldsSlot` | `Snippet<[{ formData, fieldError }]>` | - | Escape hatch for non-FieldInput extras. Rendered after declarative bottom fields. |
61
- | `submitLabel` | `string` | i18n | Override the CTA label. |
62
- | `submittingLabel` | `string` | i18n | Override the CTA label while submitting. |
63
- | `submitButton` | `Snippet<[{ isSubmitting, disabled }]>` | - | Override the entire CTA section. `disabled` is `isSubmitting \|\| submitDisabled`. |
64
- | `socialLogins` | `Snippet` | - | Social/OAuth buttons. A divider is shown when set. |
65
- | `socialPosition` | `"top" \| "bottom"` | `"bottom"` | `"top"` renders the block above the credentials, with the divider **below** the buttons. |
66
- | `socialDividerLabel` | `string \| false` | i18n | Override (or hide with `false`) the divider. Defaults to `social_divider` ("or continue with") at the bottom, `social_divider_alt` ("or") at the top. |
67
- | `footer` | `Snippet` | - | Content below the form (e.g., "Already have an account? Log in"). |
68
- | `notifications` | `NotificationsStack` | - | When set, general errors are also pushed via `notifications.error()`. |
69
- | `t` | `TranslateFn` | English | i18n function. |
70
- | `unstyled` / `class` | - | - | Standard styling escape hatches. |
71
- | `el` | `HTMLFormElement` | - | Bindable form element. |
43
+ | Prop | Type | Default | Description |
44
+ | --------------------------- | --------------------------------------- | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
45
+ | `formData` | `RegisterFormData` | empty | Bindable form data. |
46
+ | `onSubmit` | `(data: RegisterFormData) => void` | required | Called after client-side validation passes. |
47
+ | `isSubmitting` | `boolean` | `false` | Disables the CTA during submission. |
48
+ | `submitDisabled` | `boolean` | `false` | Consumer-owned submit block. Disables the CTA **and** blocks `onSubmit`. |
49
+ | `errors` | `RegisterFormValidationError[]` | `[]` | Field-specific server errors (merged with internal validation). See [Server errors](#server-supplied-errors). |
50
+ | `error` | `string` | - | General error rendered as a `DismissibleMessage` above the form. |
51
+ | `showEmail` | `boolean` | `true` | Render the email field. `false` **unmounts** it and skips its validation. |
52
+ | `showPassword` | `boolean` | `true` | Render the password field (and, transitively, the confirm field). |
53
+ | `showPasswordConfirm` | `boolean` | `true` | Render the password-confirm field. Subordinate to `showPassword`. |
54
+ | `passwordMinLength` | `number` | `8` | Minimum password length (fed into both the FieldInput attribute and the validator). |
55
+ | `credentialsSlot` | `Snippet<[{ formData, fieldError }]>` | - | Rendered at the credentials position (after the core fields, before bottom extra fields). |
56
+ | `emailFieldProps` | `Partial<FieldInputProps>` | - | Passthrough props for the built-in email field. |
57
+ | `passwordFieldProps` | `Partial<FieldInputProps>` | - | Passthrough props for the built-in password field. |
58
+ | `passwordConfirmFieldProps` | `Partial<FieldInputProps>` | - | Passthrough props for the built-in confirm field. |
59
+ | `extraFields` | `RegisterFieldConfig[]` | `[]` | Declarative extra fields. Rendered as `FieldInput`s positioned top or bottom. |
60
+ | `extraFieldsSlot` | `Snippet<[{ formData, fieldError }]>` | - | Escape hatch for non-FieldInput extras. Rendered after declarative bottom fields. |
61
+ | `topFieldsSeparator` | `boolean` | auto | Section rule below the top-position extra fields. Auto-on when they are followed by the top social block or by a `credentialsSlot` that has replaced the credentials. |
62
+ | `submitLabel` | `string` | i18n | Override the CTA label. |
63
+ | `submittingLabel` | `string` | i18n | Override the CTA label while submitting. |
64
+ | `submitButton` | `Snippet<[{ isSubmitting, disabled }]>` | - | Override the entire CTA section. `disabled` is `isSubmitting \|\| submitDisabled`. |
65
+ | `socialLogins` | `Snippet` | - | Social/OAuth buttons. A divider is shown when set. |
66
+ | `socialPosition` | `"top" \| "bottom"` | `"bottom"` | `"top"` renders the block above the credentials, with the divider **below** the buttons. |
67
+ | `socialDividerLabel` | `string \| false` | i18n | Override (or hide with `false`) the divider. Defaults to `social_divider` ("or continue with") at the bottom, `social_divider_alt` ("or") at the top. |
68
+ | `footer` | `Snippet` | - | Content below the form (e.g., "Already have an account? Log in"). |
69
+ | `notifications` | `NotificationsStack` | - | When set, general errors are also pushed via `notifications.error()`. |
70
+ | `t` | `TranslateFn` | English | i18n function. |
71
+ | `unstyled` / `class` | - | - | Standard styling escape hatches. |
72
+ | `el` | `HTMLFormElement` | - | Bindable form element. |
72
73
 
73
74
  ### Imperative methods (via `bind:this`)
74
75
 
@@ -82,7 +83,7 @@ interface RegisterFieldConfig {
82
83
 
83
84
  ```
84
85
  general error alert (`error`)
85
- top-position extra fields
86
+ top-position extra fields ← wrapped as a group, optionally closed with a section rule
86
87
  social block ← only when socialPosition="top" (divider BELOW the buttons)
87
88
  email / password / confirm ← each present only if its show* prop is true
88
89
  credentialsSlot
@@ -214,6 +215,8 @@ Once an external party has confirmed who the user is, the credential fields are
214
215
 
215
216
  Call `form.focusField("tenant_id")` right after the provider confirms: the button the user clicked is about to unmount, and without an explicit move focus falls to `<body>` — a keyboard user's next Tab restarts at the top of the document.
216
217
 
218
+ Those top-position fields are closed off with a section rule here, automatically. At the form's ordinary field rhythm the last of them sits one field-gap above the first provider button and reads as a caption for it; the break says instead that the fields are settled and what follows is a choice. It turns itself on exactly when the fields are followed by something that is not another input — the top social block, or a `credentialsSlot` standing in for the whole credential block — so it survives the switch from "pick a provider" to "signing up as jane@…" without the layout moving. `topFieldsSeparator={true | false}` overrides the decision in either direction.
219
+
217
220
  Other shapes the same three props cover:
218
221
 
219
222
  | Flow | Props |
@@ -299,11 +302,16 @@ Prefix: `--stuic-register-form-*`
299
302
  | `--stuic-register-form-social-divider-margin-top` | Divider top margin (`socialPosition="top"`) |
300
303
  | `--stuic-register-form-credentials-margin-bottom` | Bottom margin of the `credentialsSlot` wrapper |
301
304
  | `--stuic-register-form-field-margin-bottom` | Bottom margin of each field inside the form |
305
+ | `--stuic-register-form-fields-top-padding-bottom` | Space added above the top-fields section rule |
306
+ | `--stuic-register-form-fields-top-margin-bottom` | Space below the top-fields section rule |
307
+ | `--stuic-register-form-fields-top-border-color` | Color of the top-fields section rule |
302
308
 
303
309
  The social block carries `data-position="top" \| "bottom"` (suppressed under `unstyled`) if you want to target either placement from your own CSS. Note that the `top` variant hard-resets `margin-top` to `0`, so `--stuic-register-form-social-margin-top` applies to the default position only.
304
310
 
305
311
  `credentialsSlot` content is wrapped in `.stuic-register-form-credentials` (suppressed under `unstyled`) so it inherits the same bottom rhythm the fields have — the form itself is a zero-gap flex column.
306
312
 
313
+ Top-position extra fields are wrapped in `.stuic-register-form-fields-top` (suppressed under `unstyled`), which carries `data-separator` when the rule is on. The wrapper is otherwise inert — the fields keep their own margins — so targeting `[data-separator]` is the way to restyle the break without touching the ungrouped case. The default padding stacks on top of the last field's own `margin-bottom`, which is why the two spacing tokens are not equal.
314
+
307
315
  ## Gotchas
308
316
 
309
317
  - **Empty social slot.** `socialLogins` is gated on the _snippet being passed_, not on it rendering anything. A consumer that passes a placeholder snippet while it discovers which providers exist gets the wrapper margins and a divider around nothing — pass `socialLogins={undefined}` until you know, or reserve the height inside the snippet and pass `socialDividerLabel={false}`.
@@ -124,6 +124,24 @@
124
124
  ]
125
125
  >;
126
126
 
127
+ /**
128
+ * Close the top-position extra fields with a section break — a hairline
129
+ * rule plus extra space below the group.
130
+ *
131
+ * Those fields are the ones required whichever way the user signs up (a
132
+ * workspace id, an invite code), so what follows them in an identity-first
133
+ * layout is a *choice*: provider buttons, or a block standing in for the
134
+ * credentials. At the form's ordinary field rhythm the last of them reads
135
+ * as a caption for the first button below it — the break makes the group a
136
+ * section of its own instead.
137
+ *
138
+ * Default: auto — on when the top fields are followed by the top-position
139
+ * social block or by a `credentialsSlot` that has replaced the credentials
140
+ * entirely; off otherwise, since a plain column of inputs does not want a
141
+ * rule drawn through the middle of it.
142
+ */
143
+ topFieldsSeparator?: boolean;
144
+
127
145
  /** Override CTA label */
128
146
  submitLabel?: string;
129
147
 
@@ -217,6 +235,7 @@
217
235
  passwordConfirmFieldProps,
218
236
  extraFields = [],
219
237
  extraFieldsSlot,
238
+ topFieldsSeparator,
220
239
  submitLabel,
221
240
  submittingLabel,
222
241
  submitButton,
@@ -249,6 +268,16 @@
249
268
  // validated against it).
250
269
  let renderPasswordConfirm = $derived(showPassword && showPasswordConfirm);
251
270
 
271
+ // The section break below the top fields earns its place only when the next
272
+ // thing down is NOT another plain input: the top social block, or a slot that
273
+ // has taken the credentials' place. Anywhere else the form is a single column
274
+ // of fields and a rule through the middle of it is noise.
275
+ let renderTopFieldsSeparator = $derived(
276
+ topFieldsSeparator ??
277
+ ((socialPosition === "top" && !!socialLogins) ||
278
+ (!!credentialsSlot && !showEmail && !showPassword))
279
+ );
280
+
252
281
  // Internal validation errors (set on submit)
253
282
  let internalErrors = $state<RegisterFormValidationError[]>([]);
254
283
 
@@ -511,28 +540,37 @@
511
540
  <!-- General error alert -->
512
541
  <DismissibleMessage message={error} intent="destructive" />
513
542
 
514
- <!-- Top-position extra fields -->
515
- {#each topFields as cfg (cfg.name)}
516
- <FieldInput
517
- bind:this={extraFieldRefs[cfg.name]}
518
- value={extraValue(cfg)}
519
- oninput={(e: Event) =>
520
- setExtraValue(cfg, (e.currentTarget as HTMLInputElement).value)}
521
- label={cfg.label}
522
- type={cfg.type ?? "text"}
523
- placeholder={cfg.placeholder}
524
- autocomplete={cfg.autocomplete}
525
- required={cfg.required}
526
- name={`register-extra-${cfg.name}`}
527
- labelLeftBreakpoint={0}
528
- validate={{
529
- customValidator() {
530
- return fieldError(cfg.name) || "";
531
- },
532
- }}
533
- {...cfg.props}
534
- />
535
- {/each}
543
+ <!-- Top-position extra fields. Wrapped as a group so `topFieldsSeparator` can
544
+ close it off from the sign-up choice below — the wrapper is inert without
545
+ `data-separator`, the fields keep their own rhythm. -->
546
+ {#if topFields.length}
547
+ <div
548
+ class={unstyled ? undefined : "stuic-register-form-fields-top"}
549
+ data-separator={unstyled || !renderTopFieldsSeparator ? undefined : ""}
550
+ >
551
+ {#each topFields as cfg (cfg.name)}
552
+ <FieldInput
553
+ bind:this={extraFieldRefs[cfg.name]}
554
+ value={extraValue(cfg)}
555
+ oninput={(e: Event) =>
556
+ setExtraValue(cfg, (e.currentTarget as HTMLInputElement).value)}
557
+ label={cfg.label}
558
+ type={cfg.type ?? "text"}
559
+ placeholder={cfg.placeholder}
560
+ autocomplete={cfg.autocomplete}
561
+ required={cfg.required}
562
+ name={`register-extra-${cfg.name}`}
563
+ labelLeftBreakpoint={0}
564
+ validate={{
565
+ customValidator() {
566
+ return fieldError(cfg.name) || "";
567
+ },
568
+ }}
569
+ {...cfg.props}
570
+ />
571
+ {/each}
572
+ </div>
573
+ {/if}
536
574
 
537
575
  <!-- Social logins above the credentials -->
538
576
  {#if socialPosition === "top"}
@@ -97,6 +97,23 @@ export interface Props extends Omit<HTMLAttributes<HTMLFormElement>, "children">
97
97
  fieldError: (name: string) => string | undefined;
98
98
  }
99
99
  ]>;
100
+ /**
101
+ * Close the top-position extra fields with a section break — a hairline
102
+ * rule plus extra space below the group.
103
+ *
104
+ * Those fields are the ones required whichever way the user signs up (a
105
+ * workspace id, an invite code), so what follows them in an identity-first
106
+ * layout is a *choice*: provider buttons, or a block standing in for the
107
+ * credentials. At the form's ordinary field rhythm the last of them reads
108
+ * as a caption for the first button below it — the break makes the group a
109
+ * section of its own instead.
110
+ *
111
+ * Default: auto — on when the top fields are followed by the top-position
112
+ * social block or by a `credentialsSlot` that has replaced the credentials
113
+ * entirely; off otherwise, since a plain column of inputs does not want a
114
+ * rule drawn through the middle of it.
115
+ */
116
+ topFieldsSeparator?: boolean;
100
117
  /** Override CTA label */
101
118
  submitLabel?: string;
102
119
  /** Override CTA label while submitting */
@@ -75,6 +75,9 @@
75
75
  ]
76
76
  >;
77
77
 
78
+ /** Section break below the top-position extra fields. Default: auto. */
79
+ topFieldsSeparator?: InnerProps["topFieldsSeparator"];
80
+
78
81
  /** Override CTA label */
79
82
  submitLabel?: string;
80
83
 
@@ -164,6 +167,7 @@
164
167
  passwordConfirmFieldProps,
165
168
  extraFields,
166
169
  extraFieldsSlot,
170
+ topFieldsSeparator,
167
171
  submitLabel,
168
172
  submittingLabel,
169
173
  submitButton,
@@ -273,6 +277,7 @@
273
277
  {passwordConfirmFieldProps}
274
278
  {extraFields}
275
279
  {extraFieldsSlot}
280
+ {topFieldsSeparator}
276
281
  {submitLabel}
277
282
  {submittingLabel}
278
283
  {submitButton}
@@ -51,6 +51,8 @@ export interface Props {
51
51
  fieldError: (name: string) => string | undefined;
52
52
  }
53
53
  ]>;
54
+ /** Section break below the top-position extra fields. Default: auto. */
55
+ topFieldsSeparator?: InnerProps["topFieldsSeparator"];
54
56
  /** Override CTA label */
55
57
  submitLabel?: string;
56
58
  /** Override CTA label while submitting */
@@ -18,6 +18,13 @@
18
18
  /* credentialsSlot wrapper + the per-field rhythm inside the form */
19
19
  --stuic-register-form-credentials-margin-bottom: 1rem;
20
20
  --stuic-register-form-field-margin-bottom: 1rem;
21
+
22
+ /* Section break below the top-position extra fields (`topFieldsSeparator`).
23
+ The padding stacks on top of the last field's own margin-bottom, so the
24
+ default reads as 1.5rem of air on either side of the rule. */
25
+ --stuic-register-form-fields-top-padding-bottom: 0.5rem;
26
+ --stuic-register-form-fields-top-margin-bottom: 1.5rem;
27
+ --stuic-register-form-fields-top-border-color: var(--stuic-color-border);
21
28
  }
22
29
 
23
30
  @layer components {
@@ -39,6 +46,17 @@
39
46
  margin-bottom: var(--stuic-register-form-credentials-margin-bottom);
40
47
  }
41
48
 
49
+ /* Top-position extra fields. The group wrapper is deliberately inert until
50
+ `data-separator` is set — those fields are otherwise just the first rows of
51
+ the same single column, and a rule through the middle of a column of inputs
52
+ is noise. With it, the group becomes its own section: what follows is a
53
+ choice of sign-up path, not another field. */
54
+ .stuic-register-form-fields-top[data-separator] {
55
+ padding-bottom: var(--stuic-register-form-fields-top-padding-bottom);
56
+ margin-bottom: var(--stuic-register-form-fields-top-margin-bottom);
57
+ border-bottom: 1px solid var(--stuic-register-form-fields-top-border-color);
58
+ }
59
+
42
60
  /* Social login container */
43
61
  .stuic-register-form-social {
44
62
  margin-top: var(--stuic-register-form-social-margin-top);
@@ -300,7 +300,7 @@ Prefix: `--stuic-login-form-*`
300
300
 
301
301
  Standalone registration form. Mirrors `LoginForm` conventions: `formData`, `onSubmit`, validation, errors, i18n, notifications, social-logins. Adds declarative `extraFields` (top/bottom positioning, custom validators) and an `extraFieldsSlot` escape hatch (e.g., terms checkbox).
302
302
 
303
- Also covers **identity-first signup** (identity established by an OAuth provider / invite / magic link before the account exists): `showEmail` / `showPassword` unmount the credential fields, `credentialsSlot` replaces them, `socialPosition="top"` moves the provider buttons above the credentials.
303
+ Also covers **identity-first signup** (identity established by an OAuth provider / invite / magic link before the account exists): `showEmail` / `showPassword` unmount the credential fields, `credentialsSlot` replaces them, `socialPosition="top"` moves the provider buttons above the credentials, and the top-position extra fields (workspace id, invite code — required on every path) are closed off with a section rule so they don't read as a caption for the first provider button (`topFieldsSeparator`, auto).
304
304
 
305
305
  ### Exports
306
306
 
@@ -317,28 +317,29 @@ Also covers **identity-first signup** (identity established by an OAuth provider
317
317
 
318
318
  ### Key Props
319
319
 
320
- | Prop | Type | Default | Description |
321
- | ---------------------------------------------------------------------- | ------------------------------- | ---------- | ----------------------------------------------------------------------- |
322
- | `formData` | `RegisterFormData` | empty | Bindable form data |
323
- | `onSubmit` | `(data) => void` | required | Submit callback |
324
- | `isSubmitting` | `boolean` | `false` | Disables CTA |
325
- | `submitDisabled` | `boolean` | `false` | Consumer-owned block: disables CTA + blocks submit |
326
- | `errors` | `RegisterFormValidationError[]` | `[]` | Server field errors — self-clearing (see below) |
327
- | `error` | `string` | — | General error (alert above form) |
328
- | `showEmail` | `boolean` | `true` | Render (mount) the email field |
329
- | `showPassword` | `boolean` | `true` | Render (mount) the password + confirm fields |
330
- | `showPasswordConfirm` | `boolean` | `true` | Render password-confirm field |
331
- | `passwordMinLength` | `number` | `8` | Min password length (input + validator) |
332
- | `credentialsSlot` | `Snippet` | — | Content at the credentials position |
333
- | `emailFieldProps` / `passwordFieldProps` / `passwordConfirmFieldProps` | `Partial<FieldInputProps>` | — | Passthrough props per core field (`validate` composed, `value` ignored) |
334
- | `extraFields` | `RegisterFieldConfig[]` | `[]` | Declarative extra fields (top/bottom) |
335
- | `extraFieldsSlot` | `Snippet` | — | Escape-hatch for non-FieldInput extras |
336
- | `submitButton` | `Snippet` | | Custom CTA section |
337
- | `socialLogins` | `Snippet` | — | OAuth buttons |
338
- | `socialPosition` | `"top" \| "bottom"` | `"bottom"` | Social block above the credentials or after the CTA |
339
- | `footer` | `Snippet` | | Content below form |
340
- | `notifications` | `NotificationsStack` | — | Route errors to notifications |
341
- | `t` | `TranslateFn` | built-in | Translation function |
320
+ | Prop | Type | Default | Description |
321
+ | ---------------------------------------------------------------------- | ------------------------------- | ---------- | -------------------------------------------------------------------------------- |
322
+ | `formData` | `RegisterFormData` | empty | Bindable form data |
323
+ | `onSubmit` | `(data) => void` | required | Submit callback |
324
+ | `isSubmitting` | `boolean` | `false` | Disables CTA |
325
+ | `submitDisabled` | `boolean` | `false` | Consumer-owned block: disables CTA + blocks submit |
326
+ | `errors` | `RegisterFormValidationError[]` | `[]` | Server field errors — self-clearing (see below) |
327
+ | `error` | `string` | — | General error (alert above form) |
328
+ | `showEmail` | `boolean` | `true` | Render (mount) the email field |
329
+ | `showPassword` | `boolean` | `true` | Render (mount) the password + confirm fields |
330
+ | `showPasswordConfirm` | `boolean` | `true` | Render password-confirm field |
331
+ | `passwordMinLength` | `number` | `8` | Min password length (input + validator) |
332
+ | `credentialsSlot` | `Snippet` | — | Content at the credentials position |
333
+ | `emailFieldProps` / `passwordFieldProps` / `passwordConfirmFieldProps` | `Partial<FieldInputProps>` | — | Passthrough props per core field (`validate` composed, `value` ignored) |
334
+ | `extraFields` | `RegisterFieldConfig[]` | `[]` | Declarative extra fields (top/bottom) |
335
+ | `extraFieldsSlot` | `Snippet` | — | Escape-hatch for non-FieldInput extras |
336
+ | `topFieldsSeparator` | `boolean` | auto | Section rule below the top-position extra fields (auto-on when a choice follows) |
337
+ | `submitButton` | `Snippet` | — | Custom CTA section |
338
+ | `socialLogins` | `Snippet` | | OAuth buttons |
339
+ | `socialPosition` | `"top" \| "bottom"` | `"bottom"` | Social block above the credentials or after the CTA |
340
+ | `footer` | `Snippet` | — | Content below form |
341
+ | `notifications` | `NotificationsStack` | | Route errors to notifications |
342
+ | `t` | `TranslateFn` | built-in | Translation function |
342
343
 
343
344
  **Imperative** (`bind:this`): `validate()`, `scrollToFirstError(opts?)`, `focusField(name)` — also forwarded by `RegisterFormModal`.
344
345
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marianmeres/stuic",
3
- "version": "3.158.0",
3
+ "version": "3.160.0",
4
4
  "packageManager": "pnpm@11.5.0",
5
5
  "scripts": {
6
6
  "dev": "vite dev",