@indietabletop/appkit 4.1.0 → 5.0.0-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.
@@ -7,7 +7,7 @@ import { ExternalLink } from "../ExternalLink.tsx";
7
7
  import {
8
8
  FormSubmitButton,
9
9
  type FormSubmitButtonProps,
10
- } from "../FormSubmitButton.tsx";
10
+ } from "../form/FormSubmitButton.tsx";
11
11
  import { IndieTabletopClubLogo } from "../IndieTabletopClubLogo.tsx";
12
12
  import { IndieTabletopClubSymbol } from "../IndieTabletopClubSymbol.tsx";
13
13
  import { LoadingIndicator } from "../LoadingIndicator.tsx";
@@ -5,11 +5,10 @@ import {
5
5
  FormInput,
6
6
  type FormInputProps,
7
7
  FormLabel,
8
- useFormContext,
9
- useStoreState,
10
8
  } from "@ariakit/react";
11
9
  import { type ReactNode } from "react";
12
10
  import { cx } from "../class-names.ts";
11
+ import { SubmitErrorAlert } from "../form/SubmitErrorAlert.tsx";
13
12
  import * as css from "./style.css.ts";
14
13
 
15
14
  export type LetterheadTextFieldProps = FormInputProps & {
@@ -101,16 +100,7 @@ type LetterheadSubmitErrorProps = {
101
100
  * is no need to guard it with an if statement.
102
101
  */
103
102
  export function LetterheadSubmitError(props: LetterheadSubmitErrorProps) {
104
- const form = useFormContext();
105
- const message = useStoreState(form, (s) => {
106
- return s?.errors[props.name] as string | undefined;
107
- });
108
-
109
- return (
110
- <div role="alert" className={css.submitError}>
111
- {message}
112
- </div>
113
- );
103
+ return <SubmitErrorAlert {...props} className={css.submitError} />;
114
104
  }
115
105
 
116
106
  export function LetterheadHeader(props: { children: ReactNode }) {
@@ -82,10 +82,6 @@ export const submitError = style({
82
82
  backgroundColor: Color.PALE_GRAY,
83
83
  borderRadius: "0.75rem",
84
84
  textAlign: "start",
85
-
86
- ":empty": {
87
- display: "none",
88
- },
89
85
  });
90
86
 
91
87
  export const header = style({
@@ -5,7 +5,7 @@ import {
5
5
  useStoreState,
6
6
  } from "@ariakit/react";
7
7
  import type { ReactNode } from "react";
8
- import { fadeIn } from "./animations.css.ts";
8
+ import { fadeIn } from "../animations.css.ts";
9
9
 
10
10
  export type FormSubmitButtonProps = FormSubmitProps & {
11
11
  children: ReactNode;
@@ -0,0 +1,21 @@
1
+ import { useFormContext, useStoreState } from "@ariakit/react";
2
+ import { cx } from "../class-names.ts";
3
+ import { submitErrorAlert } from "./style.css.ts";
4
+
5
+ export type SubmitErrorMessageProps = {
6
+ name: string;
7
+ className?: string;
8
+ };
9
+
10
+ export function SubmitErrorAlert(props: SubmitErrorMessageProps) {
11
+ const form = useFormContext();
12
+ const message = useStoreState(form, (s) => {
13
+ return s?.errors[props.name] as string | undefined;
14
+ });
15
+
16
+ return (
17
+ <div role="alert" {...cx(props, submitErrorAlert.container)}>
18
+ {message}
19
+ </div>
20
+ );
21
+ }
@@ -0,0 +1,9 @@
1
+ import { style } from "@vanilla-extract/css";
2
+
3
+ export const submitErrorAlert = {
4
+ container: style({
5
+ ":empty": {
6
+ display: "none",
7
+ },
8
+ }),
9
+ };
package/lib/index.ts CHANGED
@@ -8,7 +8,8 @@ export * from "./AuthCard/AuthCard.tsx";
8
8
  export * from "./DialogTrigger/index.tsx";
9
9
  export * from "./DocumentTitle/DocumentTitle.tsx";
10
10
  export * from "./ExternalLink.tsx";
11
- export * from "./FormSubmitButton.tsx";
11
+ export * from "./form/FormSubmitButton.tsx";
12
+ export * from "./form/SubmitErrorAlert.tsx";
12
13
  export * from "./FullscreenDismissBlocker.tsx";
13
14
  export * from "./IndieTabletopClubLogo.tsx";
14
15
  export * from "./IndieTabletopClubSymbol.tsx";
@@ -212,7 +212,7 @@ const config = setup({
212
212
  export const machine = config.createMachine({
213
213
  /** @xstate-layout N4IgpgJg5mDOIC5QEMAOqDEAnOYAuA2gAwC6ioqA9rAJZ42UB25IAHogLQBMRAbAHQBOQbwCMggOy8ALES7DRAGhABPTvIn8AzAA5B0rdN4BWCRKKDRvAL7XlaVPwCujZE7wALMI3oBjZHiQGL5OWDg+AKqwYFjEZEggVLT0TCzsCMai0vzSejrGRIayvLwSymoIHLmi-MZcvIa6+bk8xrb26M6u7l4+NP6BEMGh4XhRMQSi8RTUdAzMCem5RPw6WlziZryWEqJKqojCK1oSgvXrRMZXRu0gDl1unt5+AUEhYc-jsVzTibMpC1ASx05UOolu9xcj16L0GGGiWAAbjEvnEWEk5qlFoguDoiKDKntwXY7p1oc9+q8hu9RqjSOj-vM0ohpCIhKJClwuFIdnsCaIuEZ+LxcdzpLtpFxMhCyT0KQM3iNPgjJr8MQDmYSOfzBDLHOS+gqhtFYLQmABJRgAM0oaIS6qZ2IQOiF6y0gh0OismQken5goEIp0YolUuJHX1csNVPhcDNjAAoqxUDQcBA7TNko6gYhDDUtIUBUQDBIpTxeASOO6uPwNroJNIBcZPQ2bCT7gbYZB+LAVIxfD2+74aIwoBgIEwwD28K9+B2o12IIP+8vh6OM38s1icwguTJaqIG4IC3sG1oCdzjPxzJJjFpxBz78W9XOF5TBqvVyOx6gnLAPBuDrbmwiAckQNT6HogimPopiGAS0imPwoh6Fy5iSmsegvp277dr2K74WuUD8L+AA2pHfuOk78COiKUAA1lO85PNGH6EV+o4kU45HfggtGUAM8xxIBjLAekRbZPk+gGAWLolOeBwIFYqynMe+QSuB0nYW+RqfoR35cTxo4YDEWCUFgJGkQENpYAAtnOsosYuelDgZZEUaOfGMHRglMMJ9L2qJgIgUpWTZGI5imKWDY6BWilZFotasiYDS5MYurto5MK4Uu7H6Zxv7-pRE6MFO-GMQ5kZOTlLn9m5f4eLx-G+Yw-lqkFmpWL6qzgeYBZELs3L7BUBbIXwBSiLouJiMGXDadVul5a5BUNZRpnmZZ1nmfZzHZYtQ4ccRhWNZ5zUBEJpAiVuwXicYJSrDJvAuni+goRegq1IYZYeqeWRtJlVV7VSn40BApFgBgx1XZiN2gYIfAHkeJxELFLoElI2QodBJ6CnoDbzUDbEHaD4OQ9xpHQxqTobPUPUCp6hQlFKxgEg0gi1FyxjSIhWiyVKBPysD7EkxDlPZiFKFiNovMnOYoqIVwBJeolMtaHUkoNMG4akoDgtEyuADuyBzMZUMBZmMOdVINY+qyBY-WUilPTWWOtJK7oNBIAusXhB1GybY6sLAM6BHOVqBFgAAUogFEQACUGC7XrvuG8b9Drubm6W06WRcrW1vine0HSQSzaaCKyO8EQcgDdztgkowlAQHALAOAy12atwXNCCImwyHICiVmIAhyKlTRc8GL5QjpVLt9nO4cIe2TmIU1exWXa+VkYNQx8GDQyJN-X-RGr4LbPgUd06wbZFwuiXEjIjHlvUjCgYrLwwK3ImN7zkjmAFFQBoAAI3BnPKmO5PSJVOOBXQx4Ni+gJEcVYVxgymCsDoUsc0Aan0JinXwYDxbpAwTWW+eJTB20fgpCoVZuav0MEcT+Uhj46xwcnXKB18pQAIWJQ4PBax33IceShlZDw6Doe-cCaEZBthPjhfaBFlpHXJt+bhsMEAiDEaQ++FDthUNAuFca4FeqyA9BlWRM99YDk4VxIqo5VGdQwjkBoVgUYum9HopSkleZ8DVjwSaVhDw-xqktOqnFCKQHsTnSwNRIrNmELkSUjsKiTW0HdWOHozC3zqDoIJ8irGKP4FaY24MICRJ3H4zQaDGzpQ5DHBBilb7s0PDFQUgoRBbFyULYmYMwBlJChsFC2hJEYLWOYDB6MRSpIihIK4DYhqdMsfwf26cuEX3nhLRsYiTiHyyKWSUAoJk1jVtM2ZiStD12sEAA */
214
214
  id: "app",
215
- context: createInitialContext(),
215
+ context: () => createInitialContext(),
216
216
 
217
217
  invoke: {
218
218
  id: "auth",
package/lib/use-form.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { type FormStoreState, useFormStore } from "@ariakit/react";
2
2
  import { useState } from "react";
3
3
  import { Failure, Success } from "./async-op.ts";
4
+ import { caughtValueToString } from "./caught-value.ts";
4
5
 
5
6
  type Validator<T> = (value: T) => string | null;
6
7
 
@@ -39,17 +40,21 @@ export function useForm<T extends object, R>(props: {
39
40
  });
40
41
 
41
42
  form.useSubmit(async (state) => {
42
- const submitOp = await props.onSubmit(state);
43
+ try {
44
+ const submitOp = await props.onSubmit(state);
43
45
 
44
- if (submitOp.isFailure) {
45
- form.setError(submitName, submitOp.failure);
46
- }
46
+ if (submitOp.isFailure) {
47
+ form.setError(submitName, submitOp.failure);
48
+ }
47
49
 
48
- if (submitOp.isSuccess) {
49
- await props.onSuccess?.(submitOp.value, state);
50
- }
50
+ if (submitOp.isSuccess) {
51
+ await props.onSuccess?.(submitOp.value, state);
52
+ }
51
53
 
52
- setOp(submitOp);
54
+ setOp(submitOp);
55
+ } catch (error) {
56
+ form.setError(submitName, caughtValueToString(error));
57
+ }
53
58
  });
54
59
 
55
60
  form.useValidate((state) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@indietabletop/appkit",
3
- "version": "4.1.0",
3
+ "version": "5.0.0-0",
4
4
  "description": "A collection of modules used in apps built by Indie Tabletop Club",
5
5
  "private": false,
6
6
  "type": "module",