@vygruppen/spor-react 3.0.3 → 3.1.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.
- package/.turbo/turbo-build.log +9 -9
- package/CHANGELOG.md +18 -0
- package/dist/{CountryCodeSelect-7ASYXAQD.mjs → CountryCodeSelect-WPMTKT2L.mjs} +308 -423
- package/dist/{chunk-B2RY6AU2.mjs → chunk-V6MFUVYF.mjs} +407 -371
- package/dist/index.d.ts +116 -110
- package/dist/index.js +1014 -989
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
- package/src/datepicker/DateField.tsx +47 -27
- package/src/datepicker/DatePicker.tsx +122 -107
- package/src/datepicker/DateTimeSegment.tsx +41 -32
- package/src/input/Combobox.tsx +3 -7
- package/src/input/Popover.tsx +7 -1
- package/src/input/Textarea.tsx +12 -6
- package/src/loader/SkeletonText.tsx +3 -2
- package/src/theme/components/textarea.ts +9 -1
package/dist/index.mjs
CHANGED
@@ -1 +1 @@
|
|
1
|
-
export { Accordion, AccordionButton, AccordionIcon, AccordionItem, AccordionPanel, AttachedInputs, Badge, Box, Button, ButtonGroup, Card, CardSelect, Center, Checkbox, CheckboxGroup, ChoiceChip, ClosableAlert, CloseButton, Code, Collapse, ColorInlineLoader, ColorSpinner, Combobox, Container, ContentLoader, DarkFullScreenLoader, DarkInlineLoader, DarkMode, DarkSpinner, DatePicker, DateRangePicker, Divider, Drawer, DrawerBody, DrawerCloseButton, DrawerContent, DrawerFooter, ModalHeader as DrawerHeader, DrawerOverlay, Expandable, ExpandableAlert, ExpandableItem, Fade, Flex, FloatingActionButton, FormControl, FormErrorMessage, FormHelperText, FormLabel, Grid, GridItem, HStack, Heading, IconButton, Image, Img, InfoSelect, InfoTag, Input, InputGroup, InputLeftElement, InputRightElement, Item, ItemDescription, ItemLabel, JumpButton, Language, LanguageProvider, LightFullScreenLoader, LightInlineLoader, LightMode, LightSpinner, LineIcon, ListBox, Modal, ModalBody, ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalOverlay, NativeSelect, NumericStepper, PasswordInput, PhoneNumberInput, PlayPauseButton, Popover, PopoverAnchor, PopoverArrow, PopoverBody, PopoverCloseButton, PopoverContent, PopoverFooter, PopoverHeader, PopoverTrigger, PopoverWizardBody, ProgressBar, ProgressLoader, Radio, RadioGroup, ScaleFade, SearchInput, Section, SimpleDrawer, SimpleGrid, SimplePopover, Skeleton, SkeletonCircle, SkeletonText, SkipButton, Slide, SlideFade, Spacer, SporProvider, Stack, StaticAlert, Stepper, StepperStep, Switch, Tab, TabList, TabPanel, TabPanels, Table, TableCaption, Tabs, Tbody, Td, Text, TextLink, Textarea, Tfoot, Th, Thead, Time, TimePicker, Tr, TravelTag, VStack, VyLogo, WizardPopover, Wrap, WrapItem, createTexts, extendTheme, fontFaces, theme, tokens, useBreakpointValue, useClipboard, useColorMode, useColorModePreference, useColorModeValue, useControllableProp, useDisclosure, useMediaQuery, useMergeRefs, useOutsideClick, usePrefersReducedMotion, useTheme, useToast, useToken, useTranslation } from './chunk-
|
1
|
+
export { Accordion, AccordionButton, AccordionIcon, AccordionItem, AccordionPanel, AttachedInputs, Badge, Box, Button, ButtonGroup, Card, CardSelect, Center, Checkbox, CheckboxGroup, ChoiceChip, ClosableAlert, CloseButton, Code, Collapse, ColorInlineLoader, ColorSpinner, Combobox, Container, ContentLoader, DarkFullScreenLoader, DarkInlineLoader, DarkMode, DarkSpinner, DatePicker, DateRangePicker, Divider, Drawer, DrawerBody, DrawerCloseButton, DrawerContent, DrawerFooter, ModalHeader as DrawerHeader, DrawerOverlay, Expandable, ExpandableAlert, ExpandableItem, Fade, Flex, FloatingActionButton, FormControl, FormErrorMessage, FormHelperText, FormLabel, Grid, GridItem, HStack, Heading, IconButton, Image, Img, InfoSelect, InfoTag, Input, InputGroup, InputLeftElement, InputRightElement, Item, ItemDescription, ItemLabel, JumpButton, Language, LanguageProvider, LightFullScreenLoader, LightInlineLoader, LightMode, LightSpinner, LineIcon, ListBox, Modal, ModalBody, ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalOverlay, NativeSelect, NumericStepper, PasswordInput, PhoneNumberInput, PlayPauseButton, Popover, PopoverAnchor, PopoverArrow, PopoverBody, PopoverCloseButton, PopoverContent, PopoverFooter, PopoverHeader, PopoverTrigger, PopoverWizardBody, ProgressBar, ProgressLoader, Radio, RadioGroup, ScaleFade, SearchInput, Section, SimpleDrawer, SimpleGrid, SimplePopover, Skeleton, SkeletonCircle, SkeletonText, SkipButton, Slide, SlideFade, Spacer, SporProvider, Stack, StaticAlert, Stepper, StepperStep, Switch, Tab, TabList, TabPanel, TabPanels, Table, TableCaption, Tabs, Tbody, Td, Text, TextLink, Textarea, Tfoot, Th, Thead, Time, TimePicker, Tr, TravelTag, VStack, VyLogo, WizardPopover, Wrap, WrapItem, createTexts, extendTheme, fontFaces, theme, tokens, useBreakpointValue, useClipboard, useColorMode, useColorModePreference, useColorModeValue, useControllableProp, useDisclosure, useMediaQuery, useMergeRefs, useOutsideClick, usePrefersReducedMotion, useTheme, useToast, useToken, useTranslation } from './chunk-V6MFUVYF.mjs';
|
package/package.json
CHANGED
@@ -2,7 +2,7 @@ import { Box, Flex, FormLabel, useMultiStyleConfig } from "@chakra-ui/react";
|
|
2
2
|
import { DateValue, GregorianCalendar } from "@internationalized/date";
|
3
3
|
import { useDateFieldState } from "@react-stately/datepicker";
|
4
4
|
import { DOMAttributes, FocusableElement } from "@react-types/shared";
|
5
|
-
import React, { useRef } from "react";
|
5
|
+
import React, { RefObject, forwardRef, useRef } from "react";
|
6
6
|
import { AriaDateFieldProps, useDateField } from "react-aria";
|
7
7
|
import { DateTimeSegment } from "./DateTimeSegment";
|
8
8
|
import { useCurrentLocale } from "./utils";
|
@@ -21,31 +21,51 @@ type DateFieldProps = AriaDateFieldProps<DateValue> & {
|
|
21
21
|
labelProps?: DOMAttributes<FocusableElement>;
|
22
22
|
name?: string;
|
23
23
|
};
|
24
|
-
export
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
24
|
+
export const DateField = forwardRef<HTMLDivElement, DateFieldProps>(
|
25
|
+
(props, externalRef) => {
|
26
|
+
const locale = useCurrentLocale();
|
27
|
+
const styles = useMultiStyleConfig("Datepicker", {});
|
28
|
+
const state = useDateFieldState({
|
29
|
+
...props,
|
30
|
+
locale,
|
31
|
+
createCalendar,
|
32
|
+
});
|
32
33
|
|
33
|
-
|
34
|
-
|
34
|
+
const internalRef = useRef(null);
|
35
|
+
const ref = externalRef ?? internalRef;
|
36
|
+
const { fieldProps, labelProps } = useDateField(
|
37
|
+
props,
|
38
|
+
state,
|
39
|
+
ref as RefObject<HTMLDivElement>
|
40
|
+
);
|
35
41
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
)
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
}
|
42
|
+
return (
|
43
|
+
<Box minWidth="6rem" width="100%">
|
44
|
+
{props.label && (
|
45
|
+
<FormLabel
|
46
|
+
{...props.labelProps}
|
47
|
+
{...labelProps}
|
48
|
+
sx={styles.inputLabel}
|
49
|
+
>
|
50
|
+
{props.label}
|
51
|
+
</FormLabel>
|
52
|
+
)}
|
53
|
+
<Flex {...fieldProps}>
|
54
|
+
{state.segments.map((segment, i) => (
|
55
|
+
<DateTimeSegment
|
56
|
+
ref={i === 0 ? ref : undefined}
|
57
|
+
key={i}
|
58
|
+
segment={segment}
|
59
|
+
state={state}
|
60
|
+
/>
|
61
|
+
))}
|
62
|
+
</Flex>
|
63
|
+
<input
|
64
|
+
type="hidden"
|
65
|
+
value={state.value?.toString()}
|
66
|
+
name={props.name}
|
67
|
+
/>
|
68
|
+
</Box>
|
69
|
+
);
|
70
|
+
}
|
71
|
+
);
|
@@ -16,7 +16,7 @@ import {
|
|
16
16
|
import { DateValue } from "@internationalized/date";
|
17
17
|
import { useDatePickerState } from "@react-stately/datepicker";
|
18
18
|
import { CalendarOutline24Icon } from "@vygruppen/spor-icon-react";
|
19
|
-
import React, { useRef } from "react";
|
19
|
+
import React, { forwardRef, useRef } from "react";
|
20
20
|
import { AriaDatePickerProps, I18nProvider, useDatePicker } from "react-aria";
|
21
21
|
import { FormErrorMessage } from "..";
|
22
22
|
import { Calendar } from "./Calendar";
|
@@ -40,118 +40,133 @@ type DatePickerProps = AriaDatePickerProps<DateValue> &
|
|
40
40
|
* <DatePicker label="Dato" variant="simple" />
|
41
41
|
* ```
|
42
42
|
*/
|
43
|
-
export
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
43
|
+
export const DatePicker = forwardRef<HTMLDivElement, DatePickerProps>(
|
44
|
+
(
|
45
|
+
{
|
46
|
+
variant,
|
47
|
+
errorMessage,
|
48
|
+
minHeight,
|
49
|
+
showYearNavigation,
|
50
|
+
width = "auto",
|
51
|
+
...props
|
52
|
+
},
|
53
|
+
externalRef
|
54
|
+
) => {
|
55
|
+
const formControlProps = useFormControlContext();
|
56
|
+
const state = useDatePickerState({
|
57
|
+
...props,
|
58
|
+
shouldCloseOnSelect: true,
|
59
|
+
errorMessage,
|
60
|
+
isRequired: props.isRequired ?? formControlProps?.isRequired,
|
61
|
+
validationState: formControlProps?.isInvalid ? "invalid" : "valid",
|
62
|
+
});
|
63
|
+
const internalRef = useRef<HTMLDivElement>(null);
|
64
|
+
const ref = externalRef ?? internalRef;
|
65
|
+
const {
|
66
|
+
groupProps,
|
67
|
+
labelProps,
|
68
|
+
fieldProps,
|
69
|
+
buttonProps,
|
70
|
+
dialogProps,
|
71
|
+
calendarProps,
|
72
|
+
errorMessageProps,
|
73
|
+
} = useDatePicker(
|
74
|
+
props,
|
75
|
+
state,
|
76
|
+
ref as React.MutableRefObject<HTMLDivElement>
|
77
|
+
);
|
69
78
|
|
70
|
-
|
71
|
-
|
72
|
-
|
79
|
+
const responsiveVariant =
|
80
|
+
useBreakpointValue(typeof variant === "string" ? [variant] : variant) ??
|
81
|
+
"simple";
|
73
82
|
|
74
|
-
|
83
|
+
const locale = useCurrentLocale();
|
75
84
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
85
|
+
const handleEnterClick = (e: React.KeyboardEvent) => {
|
86
|
+
if (
|
87
|
+
responsiveVariant === "simple" &&
|
88
|
+
e.key === "Enter" &&
|
89
|
+
!state.isOpen
|
90
|
+
) {
|
91
|
+
// Don't submit the form
|
92
|
+
e.stopPropagation();
|
93
|
+
state.setOpen(true);
|
94
|
+
}
|
95
|
+
};
|
83
96
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
97
|
+
const onFieldClick = () => {
|
98
|
+
if (!hasTrigger) {
|
99
|
+
state.setOpen(true);
|
100
|
+
}
|
101
|
+
};
|
89
102
|
|
90
|
-
|
103
|
+
const hasTrigger = responsiveVariant === "with-trigger";
|
91
104
|
|
92
|
-
|
105
|
+
const styles = useMultiStyleConfig("Datepicker", {});
|
93
106
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
>
|
102
|
-
<Popover
|
103
|
-
{...dialogProps}
|
104
|
-
isOpen={state.isOpen}
|
105
|
-
onClose={() => state.setOpen(false)}
|
106
|
-
onOpen={() => state.setOpen(true)}
|
107
|
-
closeOnBlur
|
108
|
-
closeOnEsc
|
109
|
-
returnFocusOnClose
|
107
|
+
return (
|
108
|
+
<I18nProvider locale={locale}>
|
109
|
+
<Box
|
110
|
+
position="relative"
|
111
|
+
display="inline-flex"
|
112
|
+
flexDirection="column"
|
113
|
+
width={width}
|
110
114
|
>
|
111
|
-
<
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
{
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
<PopoverContent
|
139
|
-
color="darkGrey"
|
140
|
-
boxShadow="md"
|
141
|
-
sx={styles.calendar}
|
142
|
-
>
|
143
|
-
<PopoverArrow sx={styles.arrow} />
|
144
|
-
<PopoverBody>
|
145
|
-
<Calendar
|
146
|
-
{...calendarProps}
|
147
|
-
showYearNavigation={showYearNavigation}
|
115
|
+
<Popover
|
116
|
+
{...dialogProps}
|
117
|
+
isOpen={state.isOpen}
|
118
|
+
onClose={state.close}
|
119
|
+
onOpen={state.open}
|
120
|
+
closeOnBlur
|
121
|
+
closeOnEsc
|
122
|
+
returnFocusOnClose
|
123
|
+
>
|
124
|
+
<InputGroup {...groupProps} display="inline-flex">
|
125
|
+
<PopoverAnchor>
|
126
|
+
<StyledField
|
127
|
+
variant={responsiveVariant}
|
128
|
+
onClick={onFieldClick}
|
129
|
+
onKeyPress={handleEnterClick}
|
130
|
+
paddingX={3}
|
131
|
+
minHeight={minHeight}
|
132
|
+
>
|
133
|
+
{!hasTrigger && (
|
134
|
+
<CalendarOutline24Icon marginRight={2} alignSelf="center" />
|
135
|
+
)}
|
136
|
+
<DateField
|
137
|
+
label={props.label}
|
138
|
+
labelProps={labelProps}
|
139
|
+
name={props.name}
|
140
|
+
ref={ref}
|
141
|
+
{...fieldProps}
|
148
142
|
/>
|
149
|
-
</
|
150
|
-
</
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
143
|
+
</StyledField>
|
144
|
+
</PopoverAnchor>
|
145
|
+
{hasTrigger && <CalendarTriggerButton {...buttonProps} />}
|
146
|
+
</InputGroup>
|
147
|
+
<FormErrorMessage {...errorMessageProps}>
|
148
|
+
{errorMessage}
|
149
|
+
</FormErrorMessage>
|
150
|
+
{state.isOpen && !props.isDisabled && (
|
151
|
+
<Portal>
|
152
|
+
<PopoverContent
|
153
|
+
color="darkGrey"
|
154
|
+
boxShadow="md"
|
155
|
+
sx={styles.calendar}
|
156
|
+
>
|
157
|
+
<PopoverArrow sx={styles.arrow} />
|
158
|
+
<PopoverBody>
|
159
|
+
<Calendar
|
160
|
+
{...calendarProps}
|
161
|
+
showYearNavigation={showYearNavigation}
|
162
|
+
/>
|
163
|
+
</PopoverBody>
|
164
|
+
</PopoverContent>
|
165
|
+
</Portal>
|
166
|
+
)}
|
167
|
+
</Popover>
|
168
|
+
</Box>
|
169
|
+
</I18nProvider>
|
170
|
+
);
|
171
|
+
}
|
172
|
+
);
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import { Box, useMultiStyleConfig } from "@chakra-ui/react";
|
2
|
-
import React, { useRef } from "react";
|
2
|
+
import React, { RefObject, forwardRef, useRef } from "react";
|
3
3
|
import { useDateSegment } from "react-aria";
|
4
4
|
import { DateFieldState, DateSegment } from "react-stately";
|
5
5
|
|
@@ -14,40 +14,49 @@ type DateTimeSegmentProps = {
|
|
14
14
|
*
|
15
15
|
* This component should be used with the react-aria library, and is not meant to be used directly.
|
16
16
|
* */
|
17
|
-
export const DateTimeSegment =
|
18
|
-
|
17
|
+
export const DateTimeSegment = forwardRef<HTMLDivElement, DateTimeSegmentProps>(
|
18
|
+
({ segment, state }, externalRef) => {
|
19
|
+
const internalRef = useRef(null);
|
20
|
+
const ref = externalRef ?? internalRef;
|
19
21
|
|
20
|
-
|
22
|
+
const { segmentProps } = useDateSegment(
|
23
|
+
segment,
|
24
|
+
state,
|
25
|
+
ref as RefObject<HTMLDivElement>
|
26
|
+
);
|
21
27
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
28
|
+
const styles = useMultiStyleConfig("Datepicker", {
|
29
|
+
isPlaceholder: segment.isPlaceholder,
|
30
|
+
isEditable: segment.isEditable,
|
31
|
+
});
|
26
32
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
33
|
+
return (
|
34
|
+
<Box
|
35
|
+
{...segmentProps}
|
36
|
+
ref={ref}
|
37
|
+
style={{
|
38
|
+
...segmentProps.style,
|
39
|
+
fontVariantNumeric: "tabular-nums",
|
40
|
+
boxSizing: "content-box",
|
41
|
+
}}
|
42
|
+
paddingX="1px"
|
43
|
+
textAlign="end"
|
44
|
+
outline="none"
|
45
|
+
borderRadius="xs"
|
46
|
+
fontSize="mobile.md"
|
47
|
+
sx={styles.dateTimeSegment}
|
48
|
+
_focus={{
|
49
|
+
backgroundColor: "darkTeal",
|
50
|
+
color: "white",
|
51
|
+
}}
|
52
|
+
>
|
53
|
+
{isPaddable(segment.type)
|
54
|
+
? segment.text.padStart(2, "0")
|
55
|
+
: segment.text}
|
56
|
+
</Box>
|
57
|
+
);
|
58
|
+
}
|
59
|
+
);
|
51
60
|
|
52
61
|
const isPaddable = (segmentType: DateSegment["type"]) =>
|
53
62
|
segmentType === "month" ||
|
package/src/input/Combobox.tsx
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
import React, { useEffect, useRef, useState } from "react";
|
2
2
|
import { AriaComboBoxProps, useComboBox, useFilter } from "react-aria";
|
3
3
|
import { useComboBoxState } from "react-stately";
|
4
|
-
import { ColorSpinner, Input, InputProps, ListBox
|
4
|
+
import { ColorSpinner, Input, InputProps, ListBox } from "..";
|
5
5
|
import { Popover } from "./Popover";
|
6
6
|
|
7
7
|
export type ComboboxProps<T> = AriaComboBoxProps<T> & {
|
@@ -96,12 +96,6 @@ export function Combobox<T extends object>({
|
|
96
96
|
label,
|
97
97
|
});
|
98
98
|
|
99
|
-
useOutsideClick({
|
100
|
-
ref: listBoxRef,
|
101
|
-
handler: state.close,
|
102
|
-
enabled: true,
|
103
|
-
});
|
104
|
-
|
105
99
|
const {
|
106
100
|
inputProps: { size, ...inputProps },
|
107
101
|
listBoxProps,
|
@@ -165,8 +159,10 @@ export function Combobox<T extends object>({
|
|
165
159
|
state={state}
|
166
160
|
triggerRef={inputRef as any}
|
167
161
|
ref={popoverRef}
|
162
|
+
isNonModal
|
168
163
|
placement="bottom start"
|
169
164
|
shouldFlip={false}
|
165
|
+
hasBackdrop={false}
|
170
166
|
>
|
171
167
|
<ListBox
|
172
168
|
{...listBoxProps}
|
package/src/input/Popover.tsx
CHANGED
@@ -39,6 +39,11 @@ type PopoverProps = {
|
|
39
39
|
* Defaults to false.
|
40
40
|
*/
|
41
41
|
isNonModal?: boolean;
|
42
|
+
/** Whether or not the popover renders a backdrop that stops the user from interacting with background elements
|
43
|
+
*
|
44
|
+
* Defaults to true
|
45
|
+
*/
|
46
|
+
hasBackdrop?: boolean;
|
42
47
|
};
|
43
48
|
/**
|
44
49
|
* Internal popover component.
|
@@ -56,6 +61,7 @@ export const Popover = forwardRef<HTMLDivElement, PopoverProps>(
|
|
56
61
|
placement = "bottom",
|
57
62
|
shouldFlip = false,
|
58
63
|
isNonModal = false,
|
64
|
+
hasBackdrop = true,
|
59
65
|
},
|
60
66
|
ref
|
61
67
|
) => {
|
@@ -77,7 +83,7 @@ export const Popover = forwardRef<HTMLDivElement, PopoverProps>(
|
|
77
83
|
|
78
84
|
return (
|
79
85
|
<Overlay>
|
80
|
-
<Box {...underlayProps} position="fixed" inset="0" />
|
86
|
+
{hasBackdrop && <Box {...underlayProps} position="fixed" inset="0" />}
|
81
87
|
<Box
|
82
88
|
{...popoverProps}
|
83
89
|
ref={popoverRef}
|
package/src/input/Textarea.tsx
CHANGED
@@ -5,16 +5,17 @@ import {
|
|
5
5
|
Textarea as ChakraTextarea,
|
6
6
|
TextareaProps as ChakraTextareaProps,
|
7
7
|
useFormControlContext,
|
8
|
+
InputGroup,
|
8
9
|
} from "@chakra-ui/react";
|
9
10
|
import React, { useId } from "react";
|
10
11
|
|
11
12
|
export type TextareaProps = Exclude<ChakraTextareaProps, "variant" | "size"> & {
|
12
|
-
label
|
13
|
+
label?: string;
|
13
14
|
};
|
14
15
|
/**
|
15
16
|
* Text area that works with the `FormControl` component.
|
16
17
|
*
|
17
|
-
*
|
18
|
+
* Providing a label is optional.
|
18
19
|
*
|
19
20
|
* ```tsx
|
20
21
|
* <FormControl>
|
@@ -30,11 +31,16 @@ export const Textarea = forwardRef<TextareaProps, "textarea">((props, ref) => {
|
|
30
31
|
const formControlProps = useFormControlContext();
|
31
32
|
const fallbackId = `textarea-${useId()}`;
|
32
33
|
const inputId = props.id ?? formControlProps?.id ?? fallbackId;
|
34
|
+
|
33
35
|
return (
|
34
|
-
<
|
35
|
-
<
|
36
|
-
|
37
|
-
|
36
|
+
<InputGroup position="relative" {...spacingProps}>
|
37
|
+
<ChakraTextarea {...rest} id={inputId} ref={ref} placeholder=" " />
|
38
|
+
{label && (
|
39
|
+
<FormLabel htmlFor={inputId} id={`${inputId}-label`}>
|
40
|
+
{label}
|
41
|
+
</FormLabel>
|
42
|
+
)}
|
43
|
+
</InputGroup>
|
38
44
|
);
|
39
45
|
});
|
40
46
|
|
@@ -1,7 +1,8 @@
|
|
1
|
-
import {
|
1
|
+
import { SkeletonText as ChakraSkeletonText, SkeletonTextProps as ChakraSkeletonTextProps } from "@chakra-ui/react";
|
2
2
|
import React from "react";
|
3
3
|
|
4
|
-
export type SkeletonTextProps =
|
4
|
+
export type SkeletonTextProps = ChakraSkeletonTextProps
|
5
|
+
|
5
6
|
/**
|
6
7
|
* SkeletonText renders a loading animation for a given text. It works great as a placeholder to avoid layout shifts.
|
7
8
|
*/
|
@@ -5,9 +5,17 @@ const config = defineStyleConfig({
|
|
5
5
|
baseStyle: (props) => ({
|
6
6
|
...Input.baseStyle!(props).field,
|
7
7
|
minHeight: "5rem",
|
8
|
-
py: 3,
|
9
8
|
verticalAlign: "top",
|
10
9
|
appearance: "none",
|
10
|
+
paddingTop: 2,
|
11
|
+
"&:not(:placeholder-shown)": {
|
12
|
+
"&:has(+ label)": {
|
13
|
+
paddingTop: 4
|
14
|
+
},
|
15
|
+
"& + label": {
|
16
|
+
transform: "scale(0.825) translateY(-10px)",
|
17
|
+
},
|
18
|
+
},
|
11
19
|
}),
|
12
20
|
});
|
13
21
|
|