@transferwise/components 0.0.0-experimental-5f4dd6a → 0.0.0-experimental-cdd318f
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/build/field/Field.js +63 -32
- package/build/field/Field.js.map +1 -1
- package/build/field/Field.messages.js +14 -0
- package/build/field/Field.messages.js.map +1 -0
- package/build/field/Field.messages.mjs +10 -0
- package/build/field/Field.messages.mjs.map +1 -0
- package/build/field/Field.mjs +65 -34
- package/build/field/Field.mjs.map +1 -1
- package/build/i18n/en.json +1 -0
- package/build/i18n/en.json.js +1 -0
- package/build/i18n/en.json.js.map +1 -1
- package/build/i18n/en.json.mjs +1 -0
- package/build/i18n/en.json.mjs.map +1 -1
- package/build/inputs/TextArea.js +43 -0
- package/build/inputs/TextArea.js.map +1 -1
- package/build/inputs/TextArea.mjs +45 -2
- package/build/inputs/TextArea.mjs.map +1 -1
- package/build/inputs/contexts.js +16 -0
- package/build/inputs/contexts.js.map +1 -1
- package/build/inputs/contexts.mjs +16 -2
- package/build/inputs/contexts.mjs.map +1 -1
- package/build/main.css +21 -3
- package/build/styles/field/Field.css +19 -3
- package/build/styles/main.css +21 -3
- package/build/types/field/Field.d.ts.map +1 -1
- package/build/types/field/Field.messages.d.ts +8 -0
- package/build/types/field/Field.messages.d.ts.map +1 -0
- package/build/types/inputs/TextArea.d.ts.map +1 -1
- package/build/types/inputs/contexts.d.ts +6 -0
- package/build/types/inputs/contexts.d.ts.map +1 -1
- package/build/types/test-utils/index.d.ts +2 -0
- package/build/types/test-utils/index.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/field/Field.css +19 -3
- package/src/field/Field.less +17 -3
- package/src/field/Field.messages.ts +8 -0
- package/src/field/Field.story.tsx +5 -1
- package/src/field/Field.test.tsx +90 -0
- package/src/field/Field.tsx +84 -37
- package/src/i18n/en.json +1 -0
- package/src/inputs/TextArea.story.tsx +93 -0
- package/src/inputs/TextArea.test.story.tsx +142 -0
- package/src/inputs/TextArea.tsx +54 -3
- package/src/inputs/contexts.tsx +18 -1
- package/src/main.css +21 -3
- package/src/textareaWithDisplayFormat/TextareaWithDisplayFormat.story.tsx +1 -0
package/build/field/Field.js
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
var clsx = require('clsx');
|
|
4
4
|
var React = require('react');
|
|
5
|
+
var reactIntl = require('react-intl');
|
|
6
|
+
var Body = require('../body/Body.js');
|
|
5
7
|
require('../common/theme.js');
|
|
6
8
|
require('../common/direction.js');
|
|
7
9
|
require('../common/propsValues/control.js');
|
|
@@ -23,11 +25,10 @@ require('../common/propsValues/markdownNodeType.js');
|
|
|
23
25
|
require('../common/fileType.js');
|
|
24
26
|
require('@transferwise/formatting');
|
|
25
27
|
require('@transferwise/icons');
|
|
26
|
-
require('react-intl');
|
|
27
28
|
require('../common/closeButton/CloseButton.messages.js');
|
|
28
29
|
var jsxRuntime = require('react/jsx-runtime');
|
|
30
|
+
var Field_messages = require('./Field.messages.js');
|
|
29
31
|
var InlinePrompt = require('../prompt/InlinePrompt/InlinePrompt.js');
|
|
30
|
-
require('../body/Body.js');
|
|
31
32
|
require('../button/Button.resolver.js');
|
|
32
33
|
require('../prompt/PrimitivePrompt/PrimitivePrompt.js');
|
|
33
34
|
require('../badge/Badge.js');
|
|
@@ -56,6 +57,9 @@ const Field = ({
|
|
|
56
57
|
children,
|
|
57
58
|
...props
|
|
58
59
|
}) => {
|
|
60
|
+
const {
|
|
61
|
+
formatMessage
|
|
62
|
+
} = reactIntl.useIntl();
|
|
59
63
|
const labelRef = React.useRef(null);
|
|
60
64
|
const sentiment$1 = props.error ? sentiment.Sentiment.NEGATIVE : propType;
|
|
61
65
|
const message = propMessage || props.error;
|
|
@@ -65,6 +69,10 @@ const Field = ({
|
|
|
65
69
|
const inputId = id !== null ? id ?? fallbackInputId : undefined;
|
|
66
70
|
const messageId = React.useId();
|
|
67
71
|
const descriptionId = React.useId();
|
|
72
|
+
const textareaCharCounterId = React.useId();
|
|
73
|
+
const [textareaCharacterCount, setTextareaCharacterCount] = React.useState(null);
|
|
74
|
+
const handleTextareaCharacterCount = React.useCallback(state => setTextareaCharacterCount(state), []);
|
|
75
|
+
const isNearCharLimit = textareaCharacterCount != null && textareaCharacterCount.current >= textareaCharacterCount.max * 0.8;
|
|
68
76
|
/**
|
|
69
77
|
* form control can have multiple messages to describe it,
|
|
70
78
|
* e.g the description underneath the label and inline alert
|
|
@@ -77,6 +85,9 @@ const Field = ({
|
|
|
77
85
|
if (message) {
|
|
78
86
|
messageIds.push(messageId);
|
|
79
87
|
}
|
|
88
|
+
if (textareaCharacterCount) {
|
|
89
|
+
messageIds.push(textareaCharCounterId);
|
|
90
|
+
}
|
|
80
91
|
return messageIds.length > 0 ? messageIds.join(' ') : undefined;
|
|
81
92
|
}
|
|
82
93
|
return /*#__PURE__*/jsxRuntime.jsx(contexts.FieldLabelContextProvider, {
|
|
@@ -90,37 +101,57 @@ const Field = ({
|
|
|
90
101
|
value: ariaDescribedbyByIds(),
|
|
91
102
|
children: /*#__PURE__*/jsxRuntime.jsx(contexts.InputInvalidProvider, {
|
|
92
103
|
value: hasError,
|
|
93
|
-
children: /*#__PURE__*/jsxRuntime.
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
'
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
104
|
+
children: /*#__PURE__*/jsxRuntime.jsx(contexts.TextareaCharacterCountProvider, {
|
|
105
|
+
value: handleTextareaCharacterCount,
|
|
106
|
+
children: /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
107
|
+
className: clsx.clsx('np-field form-group d-block', {
|
|
108
|
+
'has-success': sentiment$1 === sentiment.Sentiment.POSITIVE,
|
|
109
|
+
'has-warning': sentiment$1 === sentiment.Sentiment.WARNING,
|
|
110
|
+
'has-error': hasError,
|
|
111
|
+
'has-info': sentiment$1 === sentiment.Sentiment.NEUTRAL
|
|
112
|
+
}, className),
|
|
113
|
+
children: [label != null ? /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
|
|
114
|
+
children: [/*#__PURE__*/jsxRuntime.jsx(Label.Label, {
|
|
115
|
+
ref: labelRef,
|
|
116
|
+
id: labelId,
|
|
117
|
+
htmlFor: inputId,
|
|
118
|
+
children: required ? label : /*#__PURE__*/jsxRuntime.jsx(Label.Label.Optional, {
|
|
119
|
+
children: label
|
|
120
|
+
})
|
|
121
|
+
}), /*#__PURE__*/jsxRuntime.jsx(Label.Label.Description, {
|
|
122
|
+
id: descriptionId,
|
|
123
|
+
children: description
|
|
124
|
+
}), /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
125
|
+
className: "np-field-control",
|
|
126
|
+
children: children
|
|
127
|
+
})]
|
|
128
|
+
}) : children, (message || textareaCharacterCount) && /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
129
|
+
className: "np-field-validation",
|
|
130
|
+
children: [message && /*#__PURE__*/jsxRuntime.jsx(InlinePrompt.InlinePrompt, {
|
|
131
|
+
sentiment: sentiment$1,
|
|
132
|
+
id: messageId,
|
|
133
|
+
mediaLabel: messageIconLabel,
|
|
134
|
+
className: "np-field__prompt",
|
|
135
|
+
loading: messageLoading,
|
|
136
|
+
width: "full",
|
|
137
|
+
children: message
|
|
138
|
+
}), textareaCharacterCount && /*#__PURE__*/jsxRuntime.jsxs(Body.default, {
|
|
139
|
+
as: "span",
|
|
140
|
+
id: textareaCharCounterId,
|
|
141
|
+
...(isNearCharLimit ? {
|
|
142
|
+
role: 'status',
|
|
143
|
+
'aria-live': 'polite',
|
|
144
|
+
'aria-atomic': 'true'
|
|
145
|
+
} : {}),
|
|
146
|
+
"aria-label": formatMessage(Field_messages.default.characterCount, {
|
|
147
|
+
current: textareaCharacterCount.current,
|
|
148
|
+
max: textareaCharacterCount.max
|
|
149
|
+
}),
|
|
150
|
+
className: "np-field-textarea-char-counter",
|
|
151
|
+
children: [textareaCharacterCount.current, "/", textareaCharacterCount.max]
|
|
152
|
+
})]
|
|
114
153
|
})]
|
|
115
|
-
})
|
|
116
|
-
sentiment: sentiment$1,
|
|
117
|
-
id: messageId,
|
|
118
|
-
mediaLabel: messageIconLabel,
|
|
119
|
-
className: "np-field__prompt",
|
|
120
|
-
loading: messageLoading,
|
|
121
|
-
width: "full",
|
|
122
|
-
children: message
|
|
123
|
-
})]
|
|
154
|
+
})
|
|
124
155
|
})
|
|
125
156
|
})
|
|
126
157
|
})
|
package/build/field/Field.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Field.js","sources":["../../src/field/Field.tsx"],"sourcesContent":["import { clsx } from 'clsx';\nimport { useId, useRef } from 'react';\n\nimport { Sentiment } from '../common';\nimport { InlinePrompt, type InlinePromptProps } from '../prompt';\nimport {\n FieldLabelContextProvider,\n InputDescribedByProvider,\n InputIdContextProvider,\n InputInvalidProvider,\n} from '../inputs/contexts';\nimport { Label } from '../label';\n\nexport type FieldProps = {\n /** `null` disables auto-generating the `id` attribute, falling back to nesting-based label association over setting `htmlFor` explicitly. */\n id?: string | null;\n /** Should be specified unless the wrapped control has its own labeling mechanism, e.g. `Checkbox`. */\n label?: React.ReactNode;\n /** @default true */\n required?: boolean;\n /** @deprecated Use `description` prop instead. */\n hint?: React.ReactNode;\n message?: React.ReactNode;\n /**\n * Override for the [InlinePrompt icon's default, accessible name](/?path=/docs/other-statusicon-accessibility--docs)\n * announced by the screen readers\n * */\n messageIconLabel?: string;\n /**\n * If true, shows a loading spinner in place of the message icon of the InlinePrompt\n * @default false\n */\n messageLoading?: boolean;\n description?: React.ReactNode;\n /** @deprecated Use `message` and `type={Sentiment.NEGATIVE}` prop instead. */\n error?: React.ReactNode;\n /** @default Sentiment.NEUTRAL */\n sentiment?: InlinePromptProps['sentiment'];\n className?: string;\n children?: React.ReactNode;\n};\n\nexport const Field = ({\n id,\n label,\n required = true,\n message: propMessage,\n messageIconLabel,\n messageLoading,\n hint,\n description = hint,\n sentiment: propType = Sentiment.NEUTRAL,\n className,\n children,\n ...props\n}: FieldProps) => {\n const labelRef = useRef<HTMLLabelElement>(null);\n const sentiment = props.error ? Sentiment.NEGATIVE : propType;\n const message = propMessage || props.error;\n const hasError = sentiment === Sentiment.NEGATIVE;\n\n const labelId = useId();\n\n const fallbackInputId = useId();\n const inputId = id !== null ? (id ?? fallbackInputId) : undefined;\n\n const messageId = useId();\n const descriptionId = useId();\n\n /**\n * form control can have multiple messages to describe it,\n * e.g the description underneath the label and inline alert\n */\n function ariaDescribedbyByIds() {\n const messageIds = [];\n if (description) {\n messageIds.push(descriptionId);\n }\n if (message) {\n messageIds.push(messageId);\n }\n return messageIds.length > 0 ? messageIds.join(' ') : undefined;\n }\n\n return (\n <FieldLabelContextProvider value={{ id: labelId, ref: labelRef }}>\n <InputIdContextProvider value={inputId}>\n <InputDescribedByProvider value={ariaDescribedbyByIds()}>\n <InputInvalidProvider value={hasError}>\n <div\n className={clsx(\n 'np-field form-group d-block',\n {\n 'has-success': sentiment === Sentiment.POSITIVE,\n 'has-warning': sentiment === Sentiment.WARNING,\n 'has-error': hasError,\n 'has-info': sentiment === Sentiment.NEUTRAL,\n },\n className,\n )}\n >\n {label != null ? (\n <>\n <Label ref={labelRef} id={labelId} htmlFor={inputId}>\n {required ? label : <Label.Optional>{label}</Label.Optional>}\n </Label>\n <Label.Description id={descriptionId}>{description}</Label.Description>\n <div className=\"np-field-control\">{children}</div>\n </>\n ) : (\n children\n )}\n\n {message && (\n <InlinePrompt\n sentiment={sentiment}\n id={messageId}\n mediaLabel={messageIconLabel}\n className=\"np-field__prompt\"\n loading={messageLoading}\n width=\"full\"\n >\n {message}\n </InlinePrompt>\n )}\n </div>\n </InputInvalidProvider>\n </InputDescribedByProvider>\n </InputIdContextProvider>\n </FieldLabelContextProvider>\n );\n};\n"],"names":["Field","id","label","required","message","propMessage","messageIconLabel","messageLoading","hint","description","sentiment","propType","Sentiment","NEUTRAL","className","children","props","labelRef","useRef","error","NEGATIVE","hasError","labelId","useId","fallbackInputId","inputId","undefined","messageId","descriptionId","ariaDescribedbyByIds","messageIds","push","length","join","_jsx","FieldLabelContextProvider","value","ref","InputIdContextProvider","InputDescribedByProvider","InputInvalidProvider","_jsxs","clsx","POSITIVE","WARNING","_Fragment","Label","htmlFor","Optional","Description","InlinePrompt","mediaLabel","loading","width"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Field.js","sources":["../../src/field/Field.tsx"],"sourcesContent":["import { clsx } from 'clsx';\nimport { useCallback, useId, useRef, useState } from 'react';\nimport { useIntl } from 'react-intl';\n\nimport Body from '../body';\nimport { Sentiment } from '../common';\nimport messages from './Field.messages';\nimport { InlinePrompt, type InlinePromptProps } from '../prompt';\nimport {\n TextareaCharacterCountProvider,\n type TextareaCharacterCountState,\n FieldLabelContextProvider,\n InputDescribedByProvider,\n InputIdContextProvider,\n InputInvalidProvider,\n} from '../inputs/contexts';\nimport { Label } from '../label';\n\nexport type FieldProps = {\n /** `null` disables auto-generating the `id` attribute, falling back to nesting-based label association over setting `htmlFor` explicitly. */\n id?: string | null;\n /** Should be specified unless the wrapped control has its own labeling mechanism, e.g. `Checkbox`. */\n label?: React.ReactNode;\n /** @default true */\n required?: boolean;\n /** @deprecated Use `description` prop instead. */\n hint?: React.ReactNode;\n message?: React.ReactNode;\n /**\n * Override for the [InlinePrompt icon's default, accessible name](/?path=/docs/other-statusicon-accessibility--docs)\n * announced by the screen readers\n * */\n messageIconLabel?: string;\n /**\n * If true, shows a loading spinner in place of the message icon of the InlinePrompt\n * @default false\n */\n messageLoading?: boolean;\n description?: React.ReactNode;\n /** @deprecated Use `message` and `type={Sentiment.NEGATIVE}` prop instead. */\n error?: React.ReactNode;\n /** @default Sentiment.NEUTRAL */\n sentiment?: InlinePromptProps['sentiment'];\n className?: string;\n children?: React.ReactNode;\n};\n\nexport const Field = ({\n id,\n label,\n required = true,\n message: propMessage,\n messageIconLabel,\n messageLoading,\n hint,\n description = hint,\n sentiment: propType = Sentiment.NEUTRAL,\n className,\n children,\n ...props\n}: FieldProps) => {\n const { formatMessage } = useIntl();\n const labelRef = useRef<HTMLLabelElement>(null);\n const sentiment = props.error ? Sentiment.NEGATIVE : propType;\n const message = propMessage || props.error;\n const hasError = sentiment === Sentiment.NEGATIVE;\n\n const labelId = useId();\n\n const fallbackInputId = useId();\n const inputId = id !== null ? (id ?? fallbackInputId) : undefined;\n\n const messageId = useId();\n const descriptionId = useId();\n const textareaCharCounterId = useId();\n\n const [textareaCharacterCount, setTextareaCharacterCount] =\n useState<TextareaCharacterCountState>(null);\n const handleTextareaCharacterCount = useCallback(\n (state: TextareaCharacterCountState) => setTextareaCharacterCount(state),\n [],\n );\n\n const isNearCharLimit =\n textareaCharacterCount != null &&\n textareaCharacterCount.current >= textareaCharacterCount.max * 0.8;\n\n /**\n * form control can have multiple messages to describe it,\n * e.g the description underneath the label and inline alert\n */\n function ariaDescribedbyByIds() {\n const messageIds = [];\n if (description) {\n messageIds.push(descriptionId);\n }\n if (message) {\n messageIds.push(messageId);\n }\n if (textareaCharacterCount) {\n messageIds.push(textareaCharCounterId);\n }\n return messageIds.length > 0 ? messageIds.join(' ') : undefined;\n }\n\n return (\n <FieldLabelContextProvider value={{ id: labelId, ref: labelRef }}>\n <InputIdContextProvider value={inputId}>\n <InputDescribedByProvider value={ariaDescribedbyByIds()}>\n <InputInvalidProvider value={hasError}>\n <TextareaCharacterCountProvider value={handleTextareaCharacterCount}>\n <div\n className={clsx(\n 'np-field form-group d-block',\n {\n 'has-success': sentiment === Sentiment.POSITIVE,\n 'has-warning': sentiment === Sentiment.WARNING,\n 'has-error': hasError,\n 'has-info': sentiment === Sentiment.NEUTRAL,\n },\n className,\n )}\n >\n {label != null ? (\n <>\n <Label ref={labelRef} id={labelId} htmlFor={inputId}>\n {required ? label : <Label.Optional>{label}</Label.Optional>}\n </Label>\n <Label.Description id={descriptionId}>{description}</Label.Description>\n <div className=\"np-field-control\">{children}</div>\n </>\n ) : (\n children\n )}\n\n {(message || textareaCharacterCount) && (\n <div className=\"np-field-validation\">\n {message && (\n <InlinePrompt\n sentiment={sentiment}\n id={messageId}\n mediaLabel={messageIconLabel}\n className=\"np-field__prompt\"\n loading={messageLoading}\n width=\"full\"\n >\n {message}\n </InlinePrompt>\n )}\n {textareaCharacterCount && (\n <Body\n as=\"span\"\n id={textareaCharCounterId}\n {...(isNearCharLimit\n ? {\n role: 'status' as const,\n 'aria-live': 'polite' as const,\n 'aria-atomic': 'true' as const,\n }\n : {})}\n aria-label={formatMessage(messages.characterCount, {\n current: textareaCharacterCount.current,\n max: textareaCharacterCount.max,\n })}\n className=\"np-field-textarea-char-counter\"\n >\n {textareaCharacterCount.current}/{textareaCharacterCount.max}\n </Body>\n )}\n </div>\n )}\n </div>\n </TextareaCharacterCountProvider>\n </InputInvalidProvider>\n </InputDescribedByProvider>\n </InputIdContextProvider>\n </FieldLabelContextProvider>\n );\n};\n"],"names":["Field","id","label","required","message","propMessage","messageIconLabel","messageLoading","hint","description","sentiment","propType","Sentiment","NEUTRAL","className","children","props","formatMessage","useIntl","labelRef","useRef","error","NEGATIVE","hasError","labelId","useId","fallbackInputId","inputId","undefined","messageId","descriptionId","textareaCharCounterId","textareaCharacterCount","setTextareaCharacterCount","useState","handleTextareaCharacterCount","useCallback","state","isNearCharLimit","current","max","ariaDescribedbyByIds","messageIds","push","length","join","_jsx","FieldLabelContextProvider","value","ref","InputIdContextProvider","InputDescribedByProvider","InputInvalidProvider","TextareaCharacterCountProvider","_jsxs","clsx","POSITIVE","WARNING","_Fragment","Label","htmlFor","Optional","Description","InlinePrompt","mediaLabel","loading","width","Body","as","role","messages","characterCount"],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var reactIntl = require('react-intl');
|
|
6
|
+
|
|
7
|
+
var messages = reactIntl.defineMessages({
|
|
8
|
+
characterCount: {
|
|
9
|
+
id: "neptune.Field.characterCount"
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
exports.default = messages;
|
|
14
|
+
//# sourceMappingURL=Field.messages.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Field.messages.js","sources":["../../src/field/Field.messages.ts"],"sourcesContent":["import { defineMessages } from 'react-intl';\n\nexport default defineMessages({\n characterCount: {\n id: 'neptune.Field.characterCount',\n defaultMessage: '{current} of {max} characters used',\n },\n});\n"],"names":["defineMessages","characterCount","id"],"mappings":";;;;;;AAEA,eAAeA,wBAAc,CAAC;AAC5BC,EAAAA,cAAc,EAAE;IACdC,EAAE,EAAA;AAEH;AACF,CAAA,CAAC;;;;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Field.messages.mjs","sources":["../../src/field/Field.messages.ts"],"sourcesContent":["import { defineMessages } from 'react-intl';\n\nexport default defineMessages({\n characterCount: {\n id: 'neptune.Field.characterCount',\n defaultMessage: '{current} of {max} characters used',\n },\n});\n"],"names":["defineMessages","characterCount","id"],"mappings":";;AAEA,eAAeA,cAAc,CAAC;AAC5BC,EAAAA,cAAc,EAAE;IACdC,EAAE,EAAA;AAEH;AACF,CAAA,CAAC;;;;"}
|
package/build/field/Field.mjs
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { clsx } from 'clsx';
|
|
2
|
-
import { useRef, useId } from 'react';
|
|
2
|
+
import { useRef, useId, useState, useCallback } from 'react';
|
|
3
|
+
import { useIntl } from 'react-intl';
|
|
4
|
+
import Body from '../body/Body.mjs';
|
|
3
5
|
import '../common/theme.mjs';
|
|
4
6
|
import '../common/direction.mjs';
|
|
5
7
|
import '../common/propsValues/control.mjs';
|
|
@@ -21,11 +23,10 @@ import '../common/propsValues/markdownNodeType.mjs';
|
|
|
21
23
|
import '../common/fileType.mjs';
|
|
22
24
|
import '@transferwise/formatting';
|
|
23
25
|
import '@transferwise/icons';
|
|
24
|
-
import 'react-intl';
|
|
25
26
|
import '../common/closeButton/CloseButton.messages.mjs';
|
|
26
27
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
28
|
+
import messages from './Field.messages.mjs';
|
|
27
29
|
import { InlinePrompt } from '../prompt/InlinePrompt/InlinePrompt.mjs';
|
|
28
|
-
import '../body/Body.mjs';
|
|
29
30
|
import '../button/Button.resolver.mjs';
|
|
30
31
|
import '../prompt/PrimitivePrompt/PrimitivePrompt.mjs';
|
|
31
32
|
import '../badge/Badge.mjs';
|
|
@@ -37,7 +38,7 @@ import '../primitives/PrimitiveButton/PrimitiveButton.mjs';
|
|
|
37
38
|
import '../primitives/PrimitiveAnchor/PrimitiveAnchor.mjs';
|
|
38
39
|
import '../link/Link.messages.mjs';
|
|
39
40
|
import '../prompt/common/Expander/Expander.messages.mjs';
|
|
40
|
-
import { FieldLabelContextProvider, InputIdContextProvider, InputDescribedByProvider, InputInvalidProvider } from '../inputs/contexts.mjs';
|
|
41
|
+
import { FieldLabelContextProvider, InputIdContextProvider, InputDescribedByProvider, InputInvalidProvider, TextareaCharacterCountProvider } from '../inputs/contexts.mjs';
|
|
41
42
|
import { Label as LabelNamespace } from '../label/Label.mjs';
|
|
42
43
|
|
|
43
44
|
const Field = ({
|
|
@@ -54,6 +55,9 @@ const Field = ({
|
|
|
54
55
|
children,
|
|
55
56
|
...props
|
|
56
57
|
}) => {
|
|
58
|
+
const {
|
|
59
|
+
formatMessage
|
|
60
|
+
} = useIntl();
|
|
57
61
|
const labelRef = useRef(null);
|
|
58
62
|
const sentiment = props.error ? Sentiment.NEGATIVE : propType;
|
|
59
63
|
const message = propMessage || props.error;
|
|
@@ -63,6 +67,10 @@ const Field = ({
|
|
|
63
67
|
const inputId = id !== null ? id ?? fallbackInputId : undefined;
|
|
64
68
|
const messageId = useId();
|
|
65
69
|
const descriptionId = useId();
|
|
70
|
+
const textareaCharCounterId = useId();
|
|
71
|
+
const [textareaCharacterCount, setTextareaCharacterCount] = useState(null);
|
|
72
|
+
const handleTextareaCharacterCount = useCallback(state => setTextareaCharacterCount(state), []);
|
|
73
|
+
const isNearCharLimit = textareaCharacterCount != null && textareaCharacterCount.current >= textareaCharacterCount.max * 0.8;
|
|
66
74
|
/**
|
|
67
75
|
* form control can have multiple messages to describe it,
|
|
68
76
|
* e.g the description underneath the label and inline alert
|
|
@@ -75,6 +83,9 @@ const Field = ({
|
|
|
75
83
|
if (message) {
|
|
76
84
|
messageIds.push(messageId);
|
|
77
85
|
}
|
|
86
|
+
if (textareaCharacterCount) {
|
|
87
|
+
messageIds.push(textareaCharCounterId);
|
|
88
|
+
}
|
|
78
89
|
return messageIds.length > 0 ? messageIds.join(' ') : undefined;
|
|
79
90
|
}
|
|
80
91
|
return /*#__PURE__*/jsx(FieldLabelContextProvider, {
|
|
@@ -88,37 +99,57 @@ const Field = ({
|
|
|
88
99
|
value: ariaDescribedbyByIds(),
|
|
89
100
|
children: /*#__PURE__*/jsx(InputInvalidProvider, {
|
|
90
101
|
value: hasError,
|
|
91
|
-
children: /*#__PURE__*/
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
'
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
102
|
+
children: /*#__PURE__*/jsx(TextareaCharacterCountProvider, {
|
|
103
|
+
value: handleTextareaCharacterCount,
|
|
104
|
+
children: /*#__PURE__*/jsxs("div", {
|
|
105
|
+
className: clsx('np-field form-group d-block', {
|
|
106
|
+
'has-success': sentiment === Sentiment.POSITIVE,
|
|
107
|
+
'has-warning': sentiment === Sentiment.WARNING,
|
|
108
|
+
'has-error': hasError,
|
|
109
|
+
'has-info': sentiment === Sentiment.NEUTRAL
|
|
110
|
+
}, className),
|
|
111
|
+
children: [label != null ? /*#__PURE__*/jsxs(Fragment, {
|
|
112
|
+
children: [/*#__PURE__*/jsx(LabelNamespace, {
|
|
113
|
+
ref: labelRef,
|
|
114
|
+
id: labelId,
|
|
115
|
+
htmlFor: inputId,
|
|
116
|
+
children: required ? label : /*#__PURE__*/jsx(LabelNamespace.Optional, {
|
|
117
|
+
children: label
|
|
118
|
+
})
|
|
119
|
+
}), /*#__PURE__*/jsx(LabelNamespace.Description, {
|
|
120
|
+
id: descriptionId,
|
|
121
|
+
children: description
|
|
122
|
+
}), /*#__PURE__*/jsx("div", {
|
|
123
|
+
className: "np-field-control",
|
|
124
|
+
children: children
|
|
125
|
+
})]
|
|
126
|
+
}) : children, (message || textareaCharacterCount) && /*#__PURE__*/jsxs("div", {
|
|
127
|
+
className: "np-field-validation",
|
|
128
|
+
children: [message && /*#__PURE__*/jsx(InlinePrompt, {
|
|
129
|
+
sentiment: sentiment,
|
|
130
|
+
id: messageId,
|
|
131
|
+
mediaLabel: messageIconLabel,
|
|
132
|
+
className: "np-field__prompt",
|
|
133
|
+
loading: messageLoading,
|
|
134
|
+
width: "full",
|
|
135
|
+
children: message
|
|
136
|
+
}), textareaCharacterCount && /*#__PURE__*/jsxs(Body, {
|
|
137
|
+
as: "span",
|
|
138
|
+
id: textareaCharCounterId,
|
|
139
|
+
...(isNearCharLimit ? {
|
|
140
|
+
role: 'status',
|
|
141
|
+
'aria-live': 'polite',
|
|
142
|
+
'aria-atomic': 'true'
|
|
143
|
+
} : {}),
|
|
144
|
+
"aria-label": formatMessage(messages.characterCount, {
|
|
145
|
+
current: textareaCharacterCount.current,
|
|
146
|
+
max: textareaCharacterCount.max
|
|
147
|
+
}),
|
|
148
|
+
className: "np-field-textarea-char-counter",
|
|
149
|
+
children: [textareaCharacterCount.current, "/", textareaCharacterCount.max]
|
|
150
|
+
})]
|
|
112
151
|
})]
|
|
113
|
-
})
|
|
114
|
-
sentiment: sentiment,
|
|
115
|
-
id: messageId,
|
|
116
|
-
mediaLabel: messageIconLabel,
|
|
117
|
-
className: "np-field__prompt",
|
|
118
|
-
loading: messageLoading,
|
|
119
|
-
width: "full",
|
|
120
|
-
children: message
|
|
121
|
-
})]
|
|
152
|
+
})
|
|
122
153
|
})
|
|
123
154
|
})
|
|
124
155
|
})
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Field.mjs","sources":["../../src/field/Field.tsx"],"sourcesContent":["import { clsx } from 'clsx';\nimport { useId, useRef } from 'react';\n\nimport { Sentiment } from '../common';\nimport { InlinePrompt, type InlinePromptProps } from '../prompt';\nimport {\n FieldLabelContextProvider,\n InputDescribedByProvider,\n InputIdContextProvider,\n InputInvalidProvider,\n} from '../inputs/contexts';\nimport { Label } from '../label';\n\nexport type FieldProps = {\n /** `null` disables auto-generating the `id` attribute, falling back to nesting-based label association over setting `htmlFor` explicitly. */\n id?: string | null;\n /** Should be specified unless the wrapped control has its own labeling mechanism, e.g. `Checkbox`. */\n label?: React.ReactNode;\n /** @default true */\n required?: boolean;\n /** @deprecated Use `description` prop instead. */\n hint?: React.ReactNode;\n message?: React.ReactNode;\n /**\n * Override for the [InlinePrompt icon's default, accessible name](/?path=/docs/other-statusicon-accessibility--docs)\n * announced by the screen readers\n * */\n messageIconLabel?: string;\n /**\n * If true, shows a loading spinner in place of the message icon of the InlinePrompt\n * @default false\n */\n messageLoading?: boolean;\n description?: React.ReactNode;\n /** @deprecated Use `message` and `type={Sentiment.NEGATIVE}` prop instead. */\n error?: React.ReactNode;\n /** @default Sentiment.NEUTRAL */\n sentiment?: InlinePromptProps['sentiment'];\n className?: string;\n children?: React.ReactNode;\n};\n\nexport const Field = ({\n id,\n label,\n required = true,\n message: propMessage,\n messageIconLabel,\n messageLoading,\n hint,\n description = hint,\n sentiment: propType = Sentiment.NEUTRAL,\n className,\n children,\n ...props\n}: FieldProps) => {\n const labelRef = useRef<HTMLLabelElement>(null);\n const sentiment = props.error ? Sentiment.NEGATIVE : propType;\n const message = propMessage || props.error;\n const hasError = sentiment === Sentiment.NEGATIVE;\n\n const labelId = useId();\n\n const fallbackInputId = useId();\n const inputId = id !== null ? (id ?? fallbackInputId) : undefined;\n\n const messageId = useId();\n const descriptionId = useId();\n\n /**\n * form control can have multiple messages to describe it,\n * e.g the description underneath the label and inline alert\n */\n function ariaDescribedbyByIds() {\n const messageIds = [];\n if (description) {\n messageIds.push(descriptionId);\n }\n if (message) {\n messageIds.push(messageId);\n }\n return messageIds.length > 0 ? messageIds.join(' ') : undefined;\n }\n\n return (\n <FieldLabelContextProvider value={{ id: labelId, ref: labelRef }}>\n <InputIdContextProvider value={inputId}>\n <InputDescribedByProvider value={ariaDescribedbyByIds()}>\n <InputInvalidProvider value={hasError}>\n <div\n className={clsx(\n 'np-field form-group d-block',\n {\n 'has-success': sentiment === Sentiment.POSITIVE,\n 'has-warning': sentiment === Sentiment.WARNING,\n 'has-error': hasError,\n 'has-info': sentiment === Sentiment.NEUTRAL,\n },\n className,\n )}\n >\n {label != null ? (\n <>\n <Label ref={labelRef} id={labelId} htmlFor={inputId}>\n {required ? label : <Label.Optional>{label}</Label.Optional>}\n </Label>\n <Label.Description id={descriptionId}>{description}</Label.Description>\n <div className=\"np-field-control\">{children}</div>\n </>\n ) : (\n children\n )}\n\n {message && (\n <InlinePrompt\n sentiment={sentiment}\n id={messageId}\n mediaLabel={messageIconLabel}\n className=\"np-field__prompt\"\n loading={messageLoading}\n width=\"full\"\n >\n {message}\n </InlinePrompt>\n )}\n </div>\n </InputInvalidProvider>\n </InputDescribedByProvider>\n </InputIdContextProvider>\n </FieldLabelContextProvider>\n );\n};\n"],"names":["Field","id","label","required","message","propMessage","messageIconLabel","messageLoading","hint","description","sentiment","propType","Sentiment","NEUTRAL","className","children","props","labelRef","useRef","error","NEGATIVE","hasError","labelId","useId","fallbackInputId","inputId","undefined","messageId","descriptionId","ariaDescribedbyByIds","messageIds","push","length","join","_jsx","FieldLabelContextProvider","value","ref","InputIdContextProvider","InputDescribedByProvider","InputInvalidProvider","_jsxs","clsx","POSITIVE","WARNING","_Fragment","Label","htmlFor","Optional","Description","InlinePrompt","mediaLabel","loading","width"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Field.mjs","sources":["../../src/field/Field.tsx"],"sourcesContent":["import { clsx } from 'clsx';\nimport { useCallback, useId, useRef, useState } from 'react';\nimport { useIntl } from 'react-intl';\n\nimport Body from '../body';\nimport { Sentiment } from '../common';\nimport messages from './Field.messages';\nimport { InlinePrompt, type InlinePromptProps } from '../prompt';\nimport {\n TextareaCharacterCountProvider,\n type TextareaCharacterCountState,\n FieldLabelContextProvider,\n InputDescribedByProvider,\n InputIdContextProvider,\n InputInvalidProvider,\n} from '../inputs/contexts';\nimport { Label } from '../label';\n\nexport type FieldProps = {\n /** `null` disables auto-generating the `id` attribute, falling back to nesting-based label association over setting `htmlFor` explicitly. */\n id?: string | null;\n /** Should be specified unless the wrapped control has its own labeling mechanism, e.g. `Checkbox`. */\n label?: React.ReactNode;\n /** @default true */\n required?: boolean;\n /** @deprecated Use `description` prop instead. */\n hint?: React.ReactNode;\n message?: React.ReactNode;\n /**\n * Override for the [InlinePrompt icon's default, accessible name](/?path=/docs/other-statusicon-accessibility--docs)\n * announced by the screen readers\n * */\n messageIconLabel?: string;\n /**\n * If true, shows a loading spinner in place of the message icon of the InlinePrompt\n * @default false\n */\n messageLoading?: boolean;\n description?: React.ReactNode;\n /** @deprecated Use `message` and `type={Sentiment.NEGATIVE}` prop instead. */\n error?: React.ReactNode;\n /** @default Sentiment.NEUTRAL */\n sentiment?: InlinePromptProps['sentiment'];\n className?: string;\n children?: React.ReactNode;\n};\n\nexport const Field = ({\n id,\n label,\n required = true,\n message: propMessage,\n messageIconLabel,\n messageLoading,\n hint,\n description = hint,\n sentiment: propType = Sentiment.NEUTRAL,\n className,\n children,\n ...props\n}: FieldProps) => {\n const { formatMessage } = useIntl();\n const labelRef = useRef<HTMLLabelElement>(null);\n const sentiment = props.error ? Sentiment.NEGATIVE : propType;\n const message = propMessage || props.error;\n const hasError = sentiment === Sentiment.NEGATIVE;\n\n const labelId = useId();\n\n const fallbackInputId = useId();\n const inputId = id !== null ? (id ?? fallbackInputId) : undefined;\n\n const messageId = useId();\n const descriptionId = useId();\n const textareaCharCounterId = useId();\n\n const [textareaCharacterCount, setTextareaCharacterCount] =\n useState<TextareaCharacterCountState>(null);\n const handleTextareaCharacterCount = useCallback(\n (state: TextareaCharacterCountState) => setTextareaCharacterCount(state),\n [],\n );\n\n const isNearCharLimit =\n textareaCharacterCount != null &&\n textareaCharacterCount.current >= textareaCharacterCount.max * 0.8;\n\n /**\n * form control can have multiple messages to describe it,\n * e.g the description underneath the label and inline alert\n */\n function ariaDescribedbyByIds() {\n const messageIds = [];\n if (description) {\n messageIds.push(descriptionId);\n }\n if (message) {\n messageIds.push(messageId);\n }\n if (textareaCharacterCount) {\n messageIds.push(textareaCharCounterId);\n }\n return messageIds.length > 0 ? messageIds.join(' ') : undefined;\n }\n\n return (\n <FieldLabelContextProvider value={{ id: labelId, ref: labelRef }}>\n <InputIdContextProvider value={inputId}>\n <InputDescribedByProvider value={ariaDescribedbyByIds()}>\n <InputInvalidProvider value={hasError}>\n <TextareaCharacterCountProvider value={handleTextareaCharacterCount}>\n <div\n className={clsx(\n 'np-field form-group d-block',\n {\n 'has-success': sentiment === Sentiment.POSITIVE,\n 'has-warning': sentiment === Sentiment.WARNING,\n 'has-error': hasError,\n 'has-info': sentiment === Sentiment.NEUTRAL,\n },\n className,\n )}\n >\n {label != null ? (\n <>\n <Label ref={labelRef} id={labelId} htmlFor={inputId}>\n {required ? label : <Label.Optional>{label}</Label.Optional>}\n </Label>\n <Label.Description id={descriptionId}>{description}</Label.Description>\n <div className=\"np-field-control\">{children}</div>\n </>\n ) : (\n children\n )}\n\n {(message || textareaCharacterCount) && (\n <div className=\"np-field-validation\">\n {message && (\n <InlinePrompt\n sentiment={sentiment}\n id={messageId}\n mediaLabel={messageIconLabel}\n className=\"np-field__prompt\"\n loading={messageLoading}\n width=\"full\"\n >\n {message}\n </InlinePrompt>\n )}\n {textareaCharacterCount && (\n <Body\n as=\"span\"\n id={textareaCharCounterId}\n {...(isNearCharLimit\n ? {\n role: 'status' as const,\n 'aria-live': 'polite' as const,\n 'aria-atomic': 'true' as const,\n }\n : {})}\n aria-label={formatMessage(messages.characterCount, {\n current: textareaCharacterCount.current,\n max: textareaCharacterCount.max,\n })}\n className=\"np-field-textarea-char-counter\"\n >\n {textareaCharacterCount.current}/{textareaCharacterCount.max}\n </Body>\n )}\n </div>\n )}\n </div>\n </TextareaCharacterCountProvider>\n </InputInvalidProvider>\n </InputDescribedByProvider>\n </InputIdContextProvider>\n </FieldLabelContextProvider>\n );\n};\n"],"names":["Field","id","label","required","message","propMessage","messageIconLabel","messageLoading","hint","description","sentiment","propType","Sentiment","NEUTRAL","className","children","props","formatMessage","useIntl","labelRef","useRef","error","NEGATIVE","hasError","labelId","useId","fallbackInputId","inputId","undefined","messageId","descriptionId","textareaCharCounterId","textareaCharacterCount","setTextareaCharacterCount","useState","handleTextareaCharacterCount","useCallback","state","isNearCharLimit","current","max","ariaDescribedbyByIds","messageIds","push","length","join","_jsx","FieldLabelContextProvider","value","ref","InputIdContextProvider","InputDescribedByProvider","InputInvalidProvider","TextareaCharacterCountProvider","_jsxs","clsx","POSITIVE","WARNING","_Fragment","Label","htmlFor","Optional","Description","InlinePrompt","mediaLabel","loading","width","Body","as","role","messages","characterCount"],"mappings":"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"}
|
package/build/i18n/en.json
CHANGED
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
"neptune.Expander.expandAriaLabel": "Expand",
|
|
21
21
|
"neptune.ExpressiveMoneyInput.currency.search.placeholder": "Type a currency / country",
|
|
22
22
|
"neptune.ExpressiveMoneyInput.currency.select.currency": "Select currency",
|
|
23
|
+
"neptune.Field.characterCount": "{current} of {max} characters used",
|
|
23
24
|
"neptune.FlowNavigation.back": "back to previous step",
|
|
24
25
|
"neptune.Info.ariaLabel": "More information",
|
|
25
26
|
"neptune.Label.optional": "(Optional)",
|
package/build/i18n/en.json.js
CHANGED
|
@@ -24,6 +24,7 @@ var en = {
|
|
|
24
24
|
"neptune.Expander.expandAriaLabel": "Expand",
|
|
25
25
|
"neptune.ExpressiveMoneyInput.currency.search.placeholder": "Type a currency / country",
|
|
26
26
|
"neptune.ExpressiveMoneyInput.currency.select.currency": "Select currency",
|
|
27
|
+
"neptune.Field.characterCount": "{current} of {max} characters used",
|
|
27
28
|
"neptune.FlowNavigation.back": "back to previous step",
|
|
28
29
|
"neptune.Info.ariaLabel": "More information",
|
|
29
30
|
"neptune.Label.optional": "(Optional)",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"en.json.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"en.json.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/build/i18n/en.json.mjs
CHANGED
|
@@ -20,6 +20,7 @@ var en = {
|
|
|
20
20
|
"neptune.Expander.expandAriaLabel": "Expand",
|
|
21
21
|
"neptune.ExpressiveMoneyInput.currency.search.placeholder": "Type a currency / country",
|
|
22
22
|
"neptune.ExpressiveMoneyInput.currency.select.currency": "Select currency",
|
|
23
|
+
"neptune.Field.characterCount": "{current} of {max} characters used",
|
|
23
24
|
"neptune.FlowNavigation.back": "back to previous step",
|
|
24
25
|
"neptune.Info.ariaLabel": "More information",
|
|
25
26
|
"neptune.Label.optional": "(Optional)",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"en.json.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"en.json.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/build/inputs/TextArea.js
CHANGED
|
@@ -8,16 +8,59 @@ var jsxRuntime = require('react/jsx-runtime');
|
|
|
8
8
|
|
|
9
9
|
const TextArea = /*#__PURE__*/React.forwardRef(function TextArea({
|
|
10
10
|
className,
|
|
11
|
+
maxLength,
|
|
12
|
+
onChange,
|
|
11
13
|
...restProps
|
|
12
14
|
}, reference) {
|
|
13
15
|
const inputAttributes = contexts.useInputAttributes();
|
|
16
|
+
const value = restProps.value ?? restProps.defaultValue ?? '';
|
|
17
|
+
const currentLength = getGraphemeLength(typeof value === 'string' ? value : String(value));
|
|
18
|
+
contexts.useTextareaCharacterCount(currentLength, maxLength);
|
|
19
|
+
const handleChange = React.useCallback(e => {
|
|
20
|
+
if (maxLength != null) {
|
|
21
|
+
const truncated = truncateToGraphemes(e.target.value, maxLength);
|
|
22
|
+
if (truncated !== e.target.value) {
|
|
23
|
+
Object.getOwnPropertyDescriptor(HTMLTextAreaElement.prototype, 'value')?.set?.call(e.target, truncated);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
onChange?.(e);
|
|
27
|
+
}, [maxLength, onChange]);
|
|
14
28
|
return /*#__PURE__*/jsxRuntime.jsx("textarea", {
|
|
15
29
|
ref: reference,
|
|
16
30
|
className: clsx.clsx(className, _common.inputClassNameBase(), 'np-text-area'),
|
|
31
|
+
onChange: handleChange,
|
|
17
32
|
...inputAttributes,
|
|
18
33
|
...restProps
|
|
19
34
|
});
|
|
20
35
|
});
|
|
36
|
+
const segmenter = typeof Intl.Segmenter === 'function' ? new Intl.Segmenter(undefined, {
|
|
37
|
+
granularity: 'grapheme'
|
|
38
|
+
}) : undefined;
|
|
39
|
+
function getGraphemeLength(str) {
|
|
40
|
+
if (segmenter) {
|
|
41
|
+
let count = 0;
|
|
42
|
+
for (const _ of segmenter.segment(str)) {
|
|
43
|
+
count += 1;
|
|
44
|
+
}
|
|
45
|
+
return count;
|
|
46
|
+
}
|
|
47
|
+
return Array.from(str).length;
|
|
48
|
+
}
|
|
49
|
+
function truncateToGraphemes(str, max) {
|
|
50
|
+
if (segmenter) {
|
|
51
|
+
let result = '';
|
|
52
|
+
let count = 0;
|
|
53
|
+
for (const {
|
|
54
|
+
segment
|
|
55
|
+
} of segmenter.segment(str)) {
|
|
56
|
+
if (count >= max) break;
|
|
57
|
+
result += segment;
|
|
58
|
+
count += 1;
|
|
59
|
+
}
|
|
60
|
+
return result;
|
|
61
|
+
}
|
|
62
|
+
return Array.from(str).slice(0, max).join('');
|
|
63
|
+
}
|
|
21
64
|
|
|
22
65
|
exports.TextArea = TextArea;
|
|
23
66
|
//# sourceMappingURL=TextArea.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TextArea.js","sources":["../../src/inputs/TextArea.tsx"],"sourcesContent":["import { clsx } from 'clsx';\nimport { forwardRef } from 'react';\n\nimport { Merge } from '../utils';\nimport { inputClassNameBase } from './_common';\nimport { useInputAttributes } from './contexts';\n\nexport interface TextAreaProps extends Merge<\n React.ComponentPropsWithRef<'textarea'>,\n {\n 'aria-invalid'?: boolean;\n }\n> {}\n\nexport const TextArea = forwardRef(function TextArea(\n { className, ...restProps }: TextAreaProps,\n reference: React.ForwardedRef<HTMLTextAreaElement | null>,\n) {\n const inputAttributes = useInputAttributes();\n\n return (\n <textarea\n ref={reference}\n className={clsx(className, inputClassNameBase(), 'np-text-area')}\n {...inputAttributes}\n {...restProps}\n />\n );\n});\n"],"names":["TextArea","forwardRef","className","restProps","reference","inputAttributes","useInputAttributes","_jsx","ref","clsx","inputClassNameBase"],"mappings":";;;;;;;;MAcaA,QAAQ,gBAAGC,gBAAU,CAAC,SAASD,QAAQA,CAClD;EAAEE,SAAS;EAAE,GAAGC;AAAS,CAAiB,
|
|
1
|
+
{"version":3,"file":"TextArea.js","sources":["../../src/inputs/TextArea.tsx"],"sourcesContent":["import { clsx } from 'clsx';\nimport { forwardRef, useCallback } from 'react';\n\nimport { Merge } from '../utils';\nimport { inputClassNameBase } from './_common';\nimport { useTextareaCharacterCount, useInputAttributes } from './contexts';\n\nexport interface TextAreaProps extends Merge<\n React.ComponentPropsWithRef<'textarea'>,\n {\n 'aria-invalid'?: boolean;\n }\n> {}\n\nexport const TextArea = forwardRef(function TextArea(\n { className, maxLength, onChange, ...restProps }: TextAreaProps,\n reference: React.ForwardedRef<HTMLTextAreaElement | null>,\n) {\n const inputAttributes = useInputAttributes();\n const value = restProps.value ?? restProps.defaultValue ?? '';\n const currentLength = getGraphemeLength(typeof value === 'string' ? value : String(value));\n\n useTextareaCharacterCount(currentLength, maxLength);\n\n const handleChange = useCallback(\n (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n if (maxLength != null) {\n const truncated = truncateToGraphemes(e.target.value, maxLength);\n if (truncated !== e.target.value) {\n Object.getOwnPropertyDescriptor(HTMLTextAreaElement.prototype, 'value')?.set?.call(\n e.target,\n truncated,\n );\n }\n }\n onChange?.(e);\n },\n [maxLength, onChange],\n );\n\n return (\n <textarea\n ref={reference}\n className={clsx(className, inputClassNameBase(), 'np-text-area')}\n onChange={handleChange}\n {...inputAttributes}\n {...restProps}\n />\n );\n});\n\nconst segmenter =\n typeof Intl.Segmenter === 'function'\n ? new Intl.Segmenter(undefined, { granularity: 'grapheme' })\n : undefined;\n\nfunction getGraphemeLength(str: string): number {\n if (segmenter) {\n let count = 0;\n for (const _ of segmenter.segment(str)) {\n count += 1;\n }\n return count;\n }\n return Array.from(str).length;\n}\n\nfunction truncateToGraphemes(str: string, max: number): string {\n if (segmenter) {\n let result = '';\n let count = 0;\n for (const { segment } of segmenter.segment(str)) {\n if (count >= max) break;\n result += segment;\n count += 1;\n }\n return result;\n }\n return Array.from(str).slice(0, max).join('');\n}\n"],"names":["TextArea","forwardRef","className","maxLength","onChange","restProps","reference","inputAttributes","useInputAttributes","value","defaultValue","currentLength","getGraphemeLength","String","useTextareaCharacterCount","handleChange","useCallback","e","truncated","truncateToGraphemes","target","Object","getOwnPropertyDescriptor","HTMLTextAreaElement","prototype","set","call","_jsx","ref","clsx","inputClassNameBase","segmenter","Intl","Segmenter","undefined","granularity","str","count","_","segment","Array","from","length","max","result","slice","join"],"mappings":";;;;;;;;MAcaA,QAAQ,gBAAGC,gBAAU,CAAC,SAASD,QAAQA,CAClD;EAAEE,SAAS;EAAEC,SAAS;EAAEC,QAAQ;EAAE,GAAGC;AAAS,CAAiB,EAC/DC,SAAyD,EAAA;AAEzD,EAAA,MAAMC,eAAe,GAAGC,2BAAkB,EAAE;EAC5C,MAAMC,KAAK,GAAGJ,SAAS,CAACI,KAAK,IAAIJ,SAAS,CAACK,YAAY,IAAI,EAAE;AAC7D,EAAA,MAAMC,aAAa,GAAGC,iBAAiB,CAAC,OAAOH,KAAK,KAAK,QAAQ,GAAGA,KAAK,GAAGI,MAAM,CAACJ,KAAK,CAAC,CAAC;AAE1FK,EAAAA,kCAAyB,CAACH,aAAa,EAAER,SAAS,CAAC;AAEnD,EAAA,MAAMY,YAAY,GAAGC,iBAAW,CAC7BC,CAAyC,IAAI;IAC5C,IAAId,SAAS,IAAI,IAAI,EAAE;MACrB,MAAMe,SAAS,GAAGC,mBAAmB,CAACF,CAAC,CAACG,MAAM,CAACX,KAAK,EAAEN,SAAS,CAAC;AAChE,MAAA,IAAIe,SAAS,KAAKD,CAAC,CAACG,MAAM,CAACX,KAAK,EAAE;AAChCY,QAAAA,MAAM,CAACC,wBAAwB,CAACC,mBAAmB,CAACC,SAAS,EAAE,OAAO,CAAC,EAAEC,GAAG,EAAEC,IAAI,CAChFT,CAAC,CAACG,MAAM,EACRF,SAAS,CACV;AACH,MAAA;AACF,IAAA;IACAd,QAAQ,GAAGa,CAAC,CAAC;AACf,EAAA,CAAC,EACD,CAACd,SAAS,EAAEC,QAAQ,CAAC,CACtB;AAED,EAAA,oBACEuB,cAAA,CAAA,UAAA,EAAA;AACEC,IAAAA,GAAG,EAAEtB,SAAU;IACfJ,SAAS,EAAE2B,SAAI,CAAC3B,SAAS,EAAE4B,0BAAkB,EAAE,EAAE,cAAc,CAAE;AACjE1B,IAAAA,QAAQ,EAAEW,YAAa;AAAA,IAAA,GACnBR,eAAe;IAAA,GACfF;AAAS,GAAC,CACd;AAEN,CAAC;AAED,MAAM0B,SAAS,GACb,OAAOC,IAAI,CAACC,SAAS,KAAK,UAAU,GAChC,IAAID,IAAI,CAACC,SAAS,CAACC,SAAS,EAAE;AAAEC,EAAAA,WAAW,EAAE;CAAY,CAAC,GAC1DD,SAAS;AAEf,SAAStB,iBAAiBA,CAACwB,GAAW,EAAA;AACpC,EAAA,IAAIL,SAAS,EAAE;IACb,IAAIM,KAAK,GAAG,CAAC;IACb,KAAK,MAAMC,CAAC,IAAIP,SAAS,CAACQ,OAAO,CAACH,GAAG,CAAC,EAAE;AACtCC,MAAAA,KAAK,IAAI,CAAC;AACZ,IAAA;AACA,IAAA,OAAOA,KAAK;AACd,EAAA;AACA,EAAA,OAAOG,KAAK,CAACC,IAAI,CAACL,GAAG,CAAC,CAACM,MAAM;AAC/B;AAEA,SAASvB,mBAAmBA,CAACiB,GAAW,EAAEO,GAAW,EAAA;AACnD,EAAA,IAAIZ,SAAS,EAAE;IACb,IAAIa,MAAM,GAAG,EAAE;IACf,IAAIP,KAAK,GAAG,CAAC;AACb,IAAA,KAAK,MAAM;AAAEE,MAAAA;AAAO,KAAE,IAAIR,SAAS,CAACQ,OAAO,CAACH,GAAG,CAAC,EAAE;MAChD,IAAIC,KAAK,IAAIM,GAAG,EAAE;AAClBC,MAAAA,MAAM,IAAIL,OAAO;AACjBF,MAAAA,KAAK,IAAI,CAAC;AACZ,IAAA;AACA,IAAA,OAAOO,MAAM;AACf,EAAA;AACA,EAAA,OAAOJ,KAAK,CAACC,IAAI,CAACL,GAAG,CAAC,CAACS,KAAK,CAAC,CAAC,EAAEF,GAAG,CAAC,CAACG,IAAI,CAAC,EAAE,CAAC;AAC/C;;;;"}
|
|
@@ -1,21 +1,64 @@
|
|
|
1
1
|
import { clsx } from 'clsx';
|
|
2
|
-
import { forwardRef } from 'react';
|
|
2
|
+
import { forwardRef, useCallback } from 'react';
|
|
3
3
|
import { inputClassNameBase } from './_common.mjs';
|
|
4
|
-
import { useInputAttributes } from './contexts.mjs';
|
|
4
|
+
import { useInputAttributes, useTextareaCharacterCount } from './contexts.mjs';
|
|
5
5
|
import { jsx } from 'react/jsx-runtime';
|
|
6
6
|
|
|
7
7
|
const TextArea = /*#__PURE__*/forwardRef(function TextArea({
|
|
8
8
|
className,
|
|
9
|
+
maxLength,
|
|
10
|
+
onChange,
|
|
9
11
|
...restProps
|
|
10
12
|
}, reference) {
|
|
11
13
|
const inputAttributes = useInputAttributes();
|
|
14
|
+
const value = restProps.value ?? restProps.defaultValue ?? '';
|
|
15
|
+
const currentLength = getGraphemeLength(typeof value === 'string' ? value : String(value));
|
|
16
|
+
useTextareaCharacterCount(currentLength, maxLength);
|
|
17
|
+
const handleChange = useCallback(e => {
|
|
18
|
+
if (maxLength != null) {
|
|
19
|
+
const truncated = truncateToGraphemes(e.target.value, maxLength);
|
|
20
|
+
if (truncated !== e.target.value) {
|
|
21
|
+
Object.getOwnPropertyDescriptor(HTMLTextAreaElement.prototype, 'value')?.set?.call(e.target, truncated);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
onChange?.(e);
|
|
25
|
+
}, [maxLength, onChange]);
|
|
12
26
|
return /*#__PURE__*/jsx("textarea", {
|
|
13
27
|
ref: reference,
|
|
14
28
|
className: clsx(className, inputClassNameBase(), 'np-text-area'),
|
|
29
|
+
onChange: handleChange,
|
|
15
30
|
...inputAttributes,
|
|
16
31
|
...restProps
|
|
17
32
|
});
|
|
18
33
|
});
|
|
34
|
+
const segmenter = typeof Intl.Segmenter === 'function' ? new Intl.Segmenter(undefined, {
|
|
35
|
+
granularity: 'grapheme'
|
|
36
|
+
}) : undefined;
|
|
37
|
+
function getGraphemeLength(str) {
|
|
38
|
+
if (segmenter) {
|
|
39
|
+
let count = 0;
|
|
40
|
+
for (const _ of segmenter.segment(str)) {
|
|
41
|
+
count += 1;
|
|
42
|
+
}
|
|
43
|
+
return count;
|
|
44
|
+
}
|
|
45
|
+
return Array.from(str).length;
|
|
46
|
+
}
|
|
47
|
+
function truncateToGraphemes(str, max) {
|
|
48
|
+
if (segmenter) {
|
|
49
|
+
let result = '';
|
|
50
|
+
let count = 0;
|
|
51
|
+
for (const {
|
|
52
|
+
segment
|
|
53
|
+
} of segmenter.segment(str)) {
|
|
54
|
+
if (count >= max) break;
|
|
55
|
+
result += segment;
|
|
56
|
+
count += 1;
|
|
57
|
+
}
|
|
58
|
+
return result;
|
|
59
|
+
}
|
|
60
|
+
return Array.from(str).slice(0, max).join('');
|
|
61
|
+
}
|
|
19
62
|
|
|
20
63
|
export { TextArea };
|
|
21
64
|
//# sourceMappingURL=TextArea.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TextArea.mjs","sources":["../../src/inputs/TextArea.tsx"],"sourcesContent":["import { clsx } from 'clsx';\nimport { forwardRef } from 'react';\n\nimport { Merge } from '../utils';\nimport { inputClassNameBase } from './_common';\nimport { useInputAttributes } from './contexts';\n\nexport interface TextAreaProps extends Merge<\n React.ComponentPropsWithRef<'textarea'>,\n {\n 'aria-invalid'?: boolean;\n }\n> {}\n\nexport const TextArea = forwardRef(function TextArea(\n { className, ...restProps }: TextAreaProps,\n reference: React.ForwardedRef<HTMLTextAreaElement | null>,\n) {\n const inputAttributes = useInputAttributes();\n\n return (\n <textarea\n ref={reference}\n className={clsx(className, inputClassNameBase(), 'np-text-area')}\n {...inputAttributes}\n {...restProps}\n />\n );\n});\n"],"names":["TextArea","forwardRef","className","restProps","reference","inputAttributes","useInputAttributes","_jsx","ref","clsx","inputClassNameBase"],"mappings":";;;;;;MAcaA,QAAQ,gBAAGC,UAAU,CAAC,SAASD,QAAQA,CAClD;EAAEE,SAAS;EAAE,GAAGC;AAAS,CAAiB,
|
|
1
|
+
{"version":3,"file":"TextArea.mjs","sources":["../../src/inputs/TextArea.tsx"],"sourcesContent":["import { clsx } from 'clsx';\nimport { forwardRef, useCallback } from 'react';\n\nimport { Merge } from '../utils';\nimport { inputClassNameBase } from './_common';\nimport { useTextareaCharacterCount, useInputAttributes } from './contexts';\n\nexport interface TextAreaProps extends Merge<\n React.ComponentPropsWithRef<'textarea'>,\n {\n 'aria-invalid'?: boolean;\n }\n> {}\n\nexport const TextArea = forwardRef(function TextArea(\n { className, maxLength, onChange, ...restProps }: TextAreaProps,\n reference: React.ForwardedRef<HTMLTextAreaElement | null>,\n) {\n const inputAttributes = useInputAttributes();\n const value = restProps.value ?? restProps.defaultValue ?? '';\n const currentLength = getGraphemeLength(typeof value === 'string' ? value : String(value));\n\n useTextareaCharacterCount(currentLength, maxLength);\n\n const handleChange = useCallback(\n (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n if (maxLength != null) {\n const truncated = truncateToGraphemes(e.target.value, maxLength);\n if (truncated !== e.target.value) {\n Object.getOwnPropertyDescriptor(HTMLTextAreaElement.prototype, 'value')?.set?.call(\n e.target,\n truncated,\n );\n }\n }\n onChange?.(e);\n },\n [maxLength, onChange],\n );\n\n return (\n <textarea\n ref={reference}\n className={clsx(className, inputClassNameBase(), 'np-text-area')}\n onChange={handleChange}\n {...inputAttributes}\n {...restProps}\n />\n );\n});\n\nconst segmenter =\n typeof Intl.Segmenter === 'function'\n ? new Intl.Segmenter(undefined, { granularity: 'grapheme' })\n : undefined;\n\nfunction getGraphemeLength(str: string): number {\n if (segmenter) {\n let count = 0;\n for (const _ of segmenter.segment(str)) {\n count += 1;\n }\n return count;\n }\n return Array.from(str).length;\n}\n\nfunction truncateToGraphemes(str: string, max: number): string {\n if (segmenter) {\n let result = '';\n let count = 0;\n for (const { segment } of segmenter.segment(str)) {\n if (count >= max) break;\n result += segment;\n count += 1;\n }\n return result;\n }\n return Array.from(str).slice(0, max).join('');\n}\n"],"names":["TextArea","forwardRef","className","maxLength","onChange","restProps","reference","inputAttributes","useInputAttributes","value","defaultValue","currentLength","getGraphemeLength","String","useTextareaCharacterCount","handleChange","useCallback","e","truncated","truncateToGraphemes","target","Object","getOwnPropertyDescriptor","HTMLTextAreaElement","prototype","set","call","_jsx","ref","clsx","inputClassNameBase","segmenter","Intl","Segmenter","undefined","granularity","str","count","_","segment","Array","from","length","max","result","slice","join"],"mappings":";;;;;;MAcaA,QAAQ,gBAAGC,UAAU,CAAC,SAASD,QAAQA,CAClD;EAAEE,SAAS;EAAEC,SAAS;EAAEC,QAAQ;EAAE,GAAGC;AAAS,CAAiB,EAC/DC,SAAyD,EAAA;AAEzD,EAAA,MAAMC,eAAe,GAAGC,kBAAkB,EAAE;EAC5C,MAAMC,KAAK,GAAGJ,SAAS,CAACI,KAAK,IAAIJ,SAAS,CAACK,YAAY,IAAI,EAAE;AAC7D,EAAA,MAAMC,aAAa,GAAGC,iBAAiB,CAAC,OAAOH,KAAK,KAAK,QAAQ,GAAGA,KAAK,GAAGI,MAAM,CAACJ,KAAK,CAAC,CAAC;AAE1FK,EAAAA,yBAAyB,CAACH,aAAa,EAAER,SAAS,CAAC;AAEnD,EAAA,MAAMY,YAAY,GAAGC,WAAW,CAC7BC,CAAyC,IAAI;IAC5C,IAAId,SAAS,IAAI,IAAI,EAAE;MACrB,MAAMe,SAAS,GAAGC,mBAAmB,CAACF,CAAC,CAACG,MAAM,CAACX,KAAK,EAAEN,SAAS,CAAC;AAChE,MAAA,IAAIe,SAAS,KAAKD,CAAC,CAACG,MAAM,CAACX,KAAK,EAAE;AAChCY,QAAAA,MAAM,CAACC,wBAAwB,CAACC,mBAAmB,CAACC,SAAS,EAAE,OAAO,CAAC,EAAEC,GAAG,EAAEC,IAAI,CAChFT,CAAC,CAACG,MAAM,EACRF,SAAS,CACV;AACH,MAAA;AACF,IAAA;IACAd,QAAQ,GAAGa,CAAC,CAAC;AACf,EAAA,CAAC,EACD,CAACd,SAAS,EAAEC,QAAQ,CAAC,CACtB;AAED,EAAA,oBACEuB,GAAA,CAAA,UAAA,EAAA;AACEC,IAAAA,GAAG,EAAEtB,SAAU;IACfJ,SAAS,EAAE2B,IAAI,CAAC3B,SAAS,EAAE4B,kBAAkB,EAAE,EAAE,cAAc,CAAE;AACjE1B,IAAAA,QAAQ,EAAEW,YAAa;AAAA,IAAA,GACnBR,eAAe;IAAA,GACfF;AAAS,GAAC,CACd;AAEN,CAAC;AAED,MAAM0B,SAAS,GACb,OAAOC,IAAI,CAACC,SAAS,KAAK,UAAU,GAChC,IAAID,IAAI,CAACC,SAAS,CAACC,SAAS,EAAE;AAAEC,EAAAA,WAAW,EAAE;CAAY,CAAC,GAC1DD,SAAS;AAEf,SAAStB,iBAAiBA,CAACwB,GAAW,EAAA;AACpC,EAAA,IAAIL,SAAS,EAAE;IACb,IAAIM,KAAK,GAAG,CAAC;IACb,KAAK,MAAMC,CAAC,IAAIP,SAAS,CAACQ,OAAO,CAACH,GAAG,CAAC,EAAE;AACtCC,MAAAA,KAAK,IAAI,CAAC;AACZ,IAAA;AACA,IAAA,OAAOA,KAAK;AACd,EAAA;AACA,EAAA,OAAOG,KAAK,CAACC,IAAI,CAACL,GAAG,CAAC,CAACM,MAAM;AAC/B;AAEA,SAASvB,mBAAmBA,CAACiB,GAAW,EAAEO,GAAW,EAAA;AACnD,EAAA,IAAIZ,SAAS,EAAE;IACb,IAAIa,MAAM,GAAG,EAAE;IACf,IAAIP,KAAK,GAAG,CAAC;AACb,IAAA,KAAK,MAAM;AAAEE,MAAAA;AAAO,KAAE,IAAIR,SAAS,CAACQ,OAAO,CAACH,GAAG,CAAC,EAAE;MAChD,IAAIC,KAAK,IAAIM,GAAG,EAAE;AAClBC,MAAAA,MAAM,IAAIL,OAAO;AACjBF,MAAAA,KAAK,IAAI,CAAC;AACZ,IAAA;AACA,IAAA,OAAOO,MAAM;AACf,EAAA;AACA,EAAA,OAAOJ,KAAK,CAACC,IAAI,CAACL,GAAG,CAAC,CAACS,KAAK,CAAC,CAAC,EAAEF,GAAG,CAAC,CAACG,IAAI,CAAC,EAAE,CAAC;AAC/C;;;;"}
|