Skip to content

Commit 1508812

Browse files
committed
feat(form): FormMessageCounter component added to public API
1 parent bc07a1f commit 1508812

File tree

4 files changed

+77
-8
lines changed

4 files changed

+77
-8
lines changed

packages/form/src/FormMessage.tsx

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import cn from "classnames";
33
import { bem } from "@react-md/utils";
44

55
import { FormTheme, useFormTheme } from "./FormThemeProvider";
6+
import { FormMessageCounter } from "./FormMessageCounter";
67

78
const block = bem("rmd-form-message");
89

@@ -81,8 +82,12 @@ export interface FormMessageProps
8182
* ```
8283
*
8384
* Note: this should not be used alongside form-level messages.
85+
*
86+
* @remarks \@since 2.9.0 Renamed from `FormMessageCounterProps` to
87+
* `FormMessageInputLengthCounterProps` since a `FormMessageCounter` component
88+
* was added
8489
*/
85-
export interface FormMessageCounterProps {
90+
export interface FormMessageInputLengthCounterProps {
8691
/**
8792
* The current length of the value in the related text field.
8893
*/
@@ -106,7 +111,7 @@ export interface FormMessageCounterProps {
106111

107112
export interface FormMessageWithCounterProps
108113
extends FormMessageProps,
109-
FormMessageCounterProps {}
114+
FormMessageInputLengthCounterProps {}
110115

111116
/**
112117
* The `FormMessage` component is used to create additional helper messages or
@@ -119,7 +124,7 @@ export interface FormMessageWithCounterProps
119124
*/
120125
export const FormMessage = forwardRef<
121126
HTMLDivElement,
122-
FormMessageProps & Partial<FormMessageCounterProps>
127+
FormMessageProps & Partial<FormMessageInputLengthCounterProps>
123128
>(function FormMessage(
124129
{
125130
id,
@@ -170,13 +175,13 @@ export const FormMessage = forwardRef<
170175
>
171176
{message}
172177
{typeof length === "number" && typeof maxLength === "number" && (
173-
<span
178+
<FormMessageCounter
174179
id={`${id}-counter`}
175180
style={counterStyle}
176-
className={cn(block("counter"), counterClassName)}
181+
className={counterClassName}
177182
>
178183
{`${length} / ${maxLength}`}
179-
</span>
184+
</FormMessageCounter>
180185
)}
181186
</div>
182187
);
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import React, { HTMLAttributes, ReactElement, ReactNode } from "react";
2+
import cn from "classnames";
3+
import { bem } from "@react-md/utils";
4+
5+
const block = bem("rmd-form-message");
6+
7+
/** @remarks \@since 2.9.0 */
8+
export interface FormMessageCounterProps
9+
extends HTMLAttributes<HTMLSpanElement> {
10+
/**
11+
* The children to display in the counter. This is normally a string like:
12+
*
13+
* @example
14+
* String Example
15+
* ```ts
16+
* `${min} / ${max}`
17+
* ```
18+
*/
19+
children: ReactNode;
20+
}
21+
22+
/**
23+
* This component can be used to create a "counter" within the
24+
* {@link FormMessage} component.
25+
*
26+
* Note: This is really only useful when using the {@link FormMessage} component
27+
* without a {@link TextField}.
28+
*
29+
* @example
30+
* Example Usage
31+
* ```ts
32+
* interface ExampleProps {
33+
* min: number;
34+
* max: number;
35+
* }
36+
*
37+
* function Example({ min, max }: ExampleProps) {
38+
* return (
39+
* <FormMessage disableWrap>
40+
* <FormMessageCounter>
41+
* {`${min} / ${max}`}
42+
* </FormMessageCounter>
43+
* </FormMessage>
44+
* );
45+
* }
46+
* ```
47+
*
48+
* @remarks \@since 2.9.0
49+
*/
50+
export function FormMessageCounter({
51+
children,
52+
className,
53+
...props
54+
}: FormMessageCounterProps): ReactElement {
55+
return (
56+
<span {...props} className={cn(block("counter"), className)}>
57+
{children}
58+
</span>
59+
);
60+
}

packages/form/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export * from "./Fieldset";
66
export * from "./FormThemeProvider";
77
export * from "./FormMessage";
88
export * from "./FormMessageContainer";
9+
export * from "./FormMessageCounter";
910

1011
export * from "./file-input";
1112
export * from "./label";

packages/form/src/text-field/useTextField.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@ import {
1111
} from "react";
1212
import { useIcon } from "@react-md/icon";
1313

14-
import { FormMessageCounterProps, FormMessageProps } from "../FormMessage";
14+
import {
15+
FormMessageInputLengthCounterProps,
16+
FormMessageProps,
17+
} from "../FormMessage";
1518
import { defaultGetErrorIcon, GetErrorIcon } from "./getErrorIcon";
1619
import {
1720
ChangeValidationBehavior,
@@ -157,7 +160,7 @@ export interface TextFieldHookOptions
157160
export interface ProvidedFormMessageProps
158161
extends Pick<FormMessageProps, "id" | "theme" | "children">,
159162
Required<Pick<TextFieldProps, "error">>,
160-
Partial<Pick<FormMessageCounterProps, "length" | "maxLength">> {}
163+
Partial<Pick<FormMessageInputLengthCounterProps, "length" | "maxLength">> {}
161164

162165
/**
163166
* All the props that will be generated and returned by the `useTextField` hook

0 commit comments

Comments
 (0)