@vygruppen/spor-react 11.3.9 → 12.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.
- package/.turbo/turbo-build.log +32 -11
- package/.turbo/turbo-typegen.log +23 -0
- package/CHANGELOG.md +245 -0
- package/dist/index.d.mts +2552 -8319
- package/dist/index.d.ts +2552 -8319
- package/dist/index.js +9609 -8607
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +9487 -8454
- package/dist/index.mjs.map +1 -1
- package/package.json +21 -13
- package/src/accordion/Accordion.tsx +96 -45
- package/src/accordion/Expandable.tsx +54 -127
- package/src/accordion/helpers.ts +31 -0
- package/src/accordion/types.ts +60 -0
- package/src/alert/Alert.tsx +101 -0
- package/src/alert/AlertIcon.tsx +63 -45
- package/src/alert/ExpandableAlert.tsx +96 -64
- package/src/alert/ServiceAlert.tsx +127 -125
- package/src/alert/{index.tsx → index.ts} +1 -2
- package/src/breadcrumb/Breadcrumb.tsx +39 -24
- package/src/button/Button.tsx +86 -105
- package/src/button/ButtonGroup.tsx +45 -20
- package/src/button/Clipboard.tsx +82 -0
- package/src/button/CloseButton.tsx +4 -3
- package/src/button/FloatingActionButton.tsx +35 -41
- package/src/button/IconButton.tsx +34 -30
- package/src/button/index.tsx +1 -0
- package/src/color-mode/color-mode.tsx +75 -0
- package/src/color-mode/index.ts +1 -0
- package/src/datepicker/Calendar.tsx +17 -8
- package/src/datepicker/CalendarCell.tsx +20 -13
- package/src/datepicker/CalendarGrid.tsx +18 -10
- package/src/datepicker/CalendarHeader.tsx +2 -0
- package/src/datepicker/CalendarNavigationButton.tsx +1 -0
- package/src/datepicker/CalendarTriggerButton.tsx +43 -45
- package/src/datepicker/DateField.tsx +21 -12
- package/src/datepicker/DatePicker.tsx +61 -58
- package/src/datepicker/DateRangePicker.tsx +52 -58
- package/src/datepicker/DateTimeSegment.tsx +13 -5
- package/src/datepicker/RangeCalendar.tsx +13 -7
- package/src/datepicker/StyledField.tsx +25 -17
- package/src/datepicker/TimeField.tsx +10 -8
- package/src/datepicker/TimePicker.tsx +48 -45
- package/src/datepicker/types.ts +5 -0
- package/src/dialog/Dialog.tsx +56 -0
- package/src/dialog/Drawer.tsx +187 -0
- package/src/dialog/index.ts +2 -0
- package/src/dialog/types.ts +26 -0
- package/src/image/index.tsx +2 -2
- package/src/index.tsx +5 -3
- package/src/input/AttachedInputs.tsx +17 -42
- package/src/input/CardSelect.tsx +75 -162
- package/src/input/Checkbox.tsx +30 -6
- package/src/input/CheckboxGroup.tsx +25 -16
- package/src/input/ChoiceChip.tsx +58 -77
- package/src/input/Combobox.tsx +172 -172
- package/src/input/CountryCodeSelect.tsx +42 -28
- package/src/input/Dialog.tsx +1 -0
- package/src/input/Field.tsx +71 -0
- package/src/input/Fieldset.tsx +7 -0
- package/src/input/Input.tsx +68 -73
- package/src/input/InputGroup.tsx +66 -0
- package/src/input/ListBox.tsx +83 -70
- package/src/input/NativeSelect.tsx +68 -33
- package/src/input/NumericStepper.tsx +173 -171
- package/src/input/PasswordInput.tsx +99 -52
- package/src/input/PhoneNumberInput.tsx +69 -72
- package/src/input/Popover.tsx +1 -0
- package/src/input/Radio.tsx +37 -17
- package/src/input/SearchInput.tsx +24 -86
- package/src/input/Select.tsx +237 -0
- package/src/input/Switch.tsx +60 -18
- package/src/input/Textarea.tsx +53 -101
- package/src/input/{index.tsx → index.ts} +2 -8
- package/src/layout/PressableCard.tsx +12 -21
- package/src/layout/RadioCard.tsx +68 -100
- package/src/layout/Separator.tsx +32 -0
- package/src/layout/StaticCard.tsx +13 -33
- package/src/layout/index.tsx +3 -7
- package/src/linjetag/InfoTag.tsx +16 -9
- package/src/linjetag/LineIcon.tsx +74 -28
- package/src/linjetag/TravelTag.tsx +38 -27
- package/src/link/TextLink.tsx +25 -16
- package/src/list/index.tsx +24 -2
- package/src/loader/ClientOnly.tsx +8 -7
- package/src/loader/ColorInlineLoader.tsx +4 -3
- package/src/loader/ColorSpinner.tsx +5 -4
- package/src/loader/ContentLoader.tsx +6 -4
- package/src/loader/DarkFullScreenLoader.tsx +11 -3
- package/src/loader/DarkInlineLoader.tsx +5 -3
- package/src/loader/DarkSpinner.tsx +7 -3
- package/src/loader/LightFullScreenLoader.tsx +11 -3
- package/src/loader/LightInlineLoader.tsx +11 -3
- package/src/loader/LightSpinner.tsx +5 -3
- package/src/loader/Lottie.tsx +3 -3
- package/src/loader/ProgressBar.tsx +83 -84
- package/src/loader/ProgressLoader.tsx +120 -75
- package/src/loader/Skeleton.tsx +94 -19
- package/src/loader/index.tsx +0 -2
- package/src/loader/useHydrated.tsx +1 -0
- package/src/loader/useRotatingLabel.tsx +2 -1
- package/src/logo/CargonetLogo.tsx +89 -89
- package/src/logo/VyLogo.tsx +61 -42
- package/src/logo/VyLogoPride.tsx +137 -139
- package/src/media-controller/JumpButton.tsx +48 -38
- package/src/media-controller/PlayPauseButton.tsx +31 -29
- package/src/media-controller/SkipButton.tsx +38 -37
- package/src/nudge/Nudge.tsx +195 -123
- package/src/nudge/index.tsx +0 -1
- package/src/pagination/Pagination.tsx +221 -118
- package/src/pagination/types.ts +23 -0
- package/src/popover/index.tsx +67 -0
- package/src/progress-indicator/ProgressDot.tsx +11 -10
- package/src/progress-indicator/ProgressIndicator.tsx +28 -15
- package/src/provider/SporProvider.tsx +17 -14
- package/src/stepper/Stepper.tsx +88 -85
- package/src/stepper/StepperContext.tsx +2 -1
- package/src/stepper/StepperStep.tsx +28 -21
- package/src/tab/Tabs.tsx +62 -12
- package/src/tab/index.tsx +1 -9
- package/src/table/Table.tsx +35 -30
- package/src/table/index.tsx +11 -7
- package/src/theme/brand.ts +7 -0
- package/src/theme/index.ts +45 -37
- package/src/theme/recipes/attached-inputs.ts +43 -0
- package/src/theme/recipes/badge.ts +104 -0
- package/src/theme/recipes/button.ts +124 -0
- package/src/theme/recipes/choice-chip.ts +144 -0
- package/src/theme/recipes/close-button.ts +41 -0
- package/src/theme/recipes/code.ts +14 -0
- package/src/theme/recipes/group.ts +19 -0
- package/src/theme/recipes/index.ts +29 -0
- package/src/theme/recipes/input.ts +89 -0
- package/src/theme/recipes/link.ts +64 -0
- package/src/theme/recipes/nudge.ts +12 -0
- package/src/theme/recipes/pressable-card.ts +83 -0
- package/src/theme/recipes/progress-loader.ts +14 -0
- package/src/theme/recipes/separator.ts +85 -0
- package/src/theme/recipes/skeleton.ts +57 -0
- package/src/theme/recipes/static-card.ts +39 -0
- package/src/theme/recipes/textarea.ts +27 -0
- package/src/theme/semantic-tokens/colors.ts +22 -0
- package/src/theme/semantic-tokens/index.ts +24 -0
- package/src/theme/semantic-tokens/radii.ts +14 -0
- package/src/theme/semantic-tokens/shadows.ts +17 -0
- package/src/theme/slot-recipes/accordion.ts +131 -0
- package/src/theme/slot-recipes/alert-expandable.ts +133 -0
- package/src/theme/slot-recipes/alert-service.ts +66 -0
- package/src/theme/slot-recipes/alert.ts +72 -0
- package/src/theme/slot-recipes/anatomy.ts +269 -0
- package/src/theme/slot-recipes/breadcrumb.ts +61 -0
- package/src/theme/slot-recipes/checkbox.ts +89 -0
- package/src/theme/slot-recipes/datepicker.ts +214 -0
- package/src/theme/slot-recipes/dialog.ts +221 -0
- package/src/theme/slot-recipes/drawer.ts +205 -0
- package/src/theme/slot-recipes/field.ts +79 -0
- package/src/theme/slot-recipes/floating-action-button.ts +131 -0
- package/src/theme/slot-recipes/index.ts +65 -0
- package/src/theme/slot-recipes/info-tag.ts +62 -0
- package/src/theme/slot-recipes/line-icon.ts +140 -0
- package/src/theme/slot-recipes/list.ts +45 -0
- package/src/theme/slot-recipes/listbox.ts +72 -0
- package/src/theme/slot-recipes/media-controller-button.ts +131 -0
- package/src/theme/slot-recipes/native-select.ts +54 -0
- package/src/theme/slot-recipes/numeric-stepper.ts +65 -0
- package/src/theme/slot-recipes/pagination.ts +41 -0
- package/src/theme/slot-recipes/popover.ts +78 -0
- package/src/theme/slot-recipes/progress-bar.ts +39 -0
- package/src/theme/slot-recipes/progress-indicator.ts +22 -0
- package/src/theme/slot-recipes/radio-card.ts +112 -0
- package/src/theme/slot-recipes/radio.ts +80 -0
- package/src/theme/slot-recipes/select.ts +243 -0
- package/src/theme/slot-recipes/stepper.ts +92 -0
- package/src/theme/slot-recipes/switch.ts +147 -0
- package/src/theme/slot-recipes/table.ts +200 -0
- package/src/theme/slot-recipes/tabs.ts +169 -0
- package/src/theme/slot-recipes/toast.ts +56 -0
- package/src/theme/slot-recipes/travel-tag.ts +192 -0
- package/src/theme/tokens/animation-styles.ts +50 -0
- package/src/theme/tokens/animations.ts +22 -0
- package/src/theme/tokens/aspect-ratios.ts +22 -0
- package/src/theme/tokens/blurs.ts +28 -0
- package/src/theme/tokens/borders.ts +26 -0
- package/src/theme/{foundations → tokens}/breakpoints.ts +0 -1
- package/src/theme/tokens/colors.ts +10 -0
- package/src/theme/tokens/config.ts +10 -0
- package/src/theme/tokens/cursor.ts +28 -0
- package/src/theme/tokens/durations.ts +25 -0
- package/src/theme/tokens/easings.ts +16 -0
- package/src/theme/tokens/font-sizes.ts +30 -0
- package/src/theme/tokens/font-weights.ts +31 -0
- package/src/theme/tokens/fonts.ts +8 -0
- package/src/theme/tokens/global-css.ts +18 -0
- package/src/theme/tokens/index.ts +37 -0
- package/src/theme/tokens/keyframes.ts +255 -0
- package/src/theme/tokens/letter-spacings.ts +19 -0
- package/src/theme/tokens/line-heights.ts +19 -0
- package/src/theme/tokens/radii.ts +13 -0
- package/src/theme/tokens/sizes.ts +51 -0
- package/src/theme/tokens/spacing.ts +20 -0
- package/src/theme/tokens/text-styles.ts +89 -0
- package/src/theme/tokens/z-index.ts +17 -0
- package/src/theme/utils/accent-utils.ts +8 -21
- package/src/theme/utils/bg-utils.ts +4 -6
- package/src/theme/utils/brand-utils.ts +6 -19
- package/src/theme/utils/core-utils.ts +91 -0
- package/src/theme/utils/floating-utils.ts +20 -39
- package/src/theme/utils/ghost-utils.ts +7 -21
- package/src/theme/utils/input-utils.ts +32 -37
- package/src/theme/utils/outline-utils.ts +4 -11
- package/src/theme/utils/surface-utils.ts +5 -19
- package/src/theme/utils/types.ts +1 -0
- package/src/toast/index.tsx +1 -1
- package/src/toast/toast.tsx +105 -0
- package/src/transition/index.ts +2 -8
- package/src/typography/Badge.tsx +15 -61
- package/src/typography/Code.tsx +16 -28
- package/src/typography/Heading.tsx +34 -19
- package/src/typography/Text.tsx +9 -6
- package/src/typography/{index.tsx → index.ts} +1 -0
- package/src/util/externals.tsx +13 -27
- package/tsconfig.json +5 -1
- package/src/accordion/Accordion.test.tsx +0 -20
- package/src/alert/BaseAlert.test.tsx +0 -37
- package/src/alert/BaseAlert.tsx +0 -34
- package/src/alert/ClosableAlert.test.tsx +0 -37
- package/src/alert/ClosableAlert.tsx +0 -85
- package/src/alert/ExpandableAlert.test.tsx +0 -84
- package/src/alert/StaticAlert.tsx +0 -33
- package/src/button/Button.test.tsx +0 -23
- package/src/datepicker/TimePicker.test.tsx +0 -74
- package/src/input/FormControl.tsx +0 -2
- package/src/input/FormErrorMessage.tsx +0 -95
- package/src/input/FormLabel.tsx +0 -11
- package/src/input/InfoSelect.tsx +0 -274
- package/src/input/InputElement.tsx +0 -44
- package/src/input/RadioGroup.tsx +0 -47
- package/src/layout/Divider.tsx +0 -27
- package/src/layout/RadioCardGroup.tsx +0 -79
- package/src/layout/Stack.tsx +0 -42
- package/src/loader/SkeletonCircle.tsx +0 -13
- package/src/loader/SkeletonText.tsx +0 -14
- package/src/media-controller/index.test.tsx +0 -59
- package/src/modal/Drawer.tsx +0 -120
- package/src/modal/FullScreenDrawer.tsx +0 -239
- package/src/modal/Modal.tsx +0 -15
- package/src/modal/ModalHeader.tsx +0 -31
- package/src/modal/SimpleDrawer.tsx +0 -51
- package/src/modal/index.tsx +0 -5
- package/src/nudge/WizardNudge.tsx +0 -107
- package/src/theme/components/accordion.ts +0 -102
- package/src/theme/components/alert-expandable.ts +0 -125
- package/src/theme/components/alert-service.ts +0 -98
- package/src/theme/components/alert.ts +0 -71
- package/src/theme/components/badge.ts +0 -109
- package/src/theme/components/breadcrumb.ts +0 -60
- package/src/theme/components/button.ts +0 -125
- package/src/theme/components/card-select.ts +0 -117
- package/src/theme/components/checkbox.ts +0 -88
- package/src/theme/components/choice-chip.ts +0 -161
- package/src/theme/components/close-button.ts +0 -48
- package/src/theme/components/code.ts +0 -17
- package/src/theme/components/datepicker.ts +0 -198
- package/src/theme/components/divider.ts +0 -50
- package/src/theme/components/drawer.ts +0 -95
- package/src/theme/components/fab.ts +0 -109
- package/src/theme/components/form-label.ts +0 -17
- package/src/theme/components/form.ts +0 -27
- package/src/theme/components/index.ts +0 -45
- package/src/theme/components/info-select.ts +0 -85
- package/src/theme/components/info-tag.ts +0 -63
- package/src/theme/components/input.ts +0 -28
- package/src/theme/components/line-icon.ts +0 -129
- package/src/theme/components/link.ts +0 -78
- package/src/theme/components/list.ts +0 -23
- package/src/theme/components/listbox.ts +0 -77
- package/src/theme/components/media-controller-button.ts +0 -97
- package/src/theme/components/modal.ts +0 -96
- package/src/theme/components/numeric-stepper.ts +0 -65
- package/src/theme/components/pagination.ts +0 -74
- package/src/theme/components/popover.ts +0 -68
- package/src/theme/components/pressable-card.ts +0 -72
- package/src/theme/components/progress-bar.ts +0 -47
- package/src/theme/components/progress-indicator.ts +0 -44
- package/src/theme/components/radio-card.ts +0 -134
- package/src/theme/components/radio.ts +0 -68
- package/src/theme/components/select.ts +0 -74
- package/src/theme/components/skeleton.ts +0 -40
- package/src/theme/components/static-card.ts +0 -82
- package/src/theme/components/stepper.ts +0 -100
- package/src/theme/components/switch.ts +0 -112
- package/src/theme/components/table.ts +0 -161
- package/src/theme/components/tabs.ts +0 -135
- package/src/theme/components/textarea.ts +0 -33
- package/src/theme/components/toast.ts +0 -28
- package/src/theme/components/travel-tag.ts +0 -256
- package/src/theme/foundations/borders.ts +0 -11
- package/src/theme/foundations/colors.ts +0 -12
- package/src/theme/foundations/config.ts +0 -5
- package/src/theme/foundations/fontSizes.ts +0 -29
- package/src/theme/foundations/fontWeights.ts +0 -5
- package/src/theme/foundations/fonts.ts +0 -7
- package/src/theme/foundations/index.ts +0 -15
- package/src/theme/foundations/lineHeights.ts +0 -6
- package/src/theme/foundations/radii.ts +0 -12
- package/src/theme/foundations/shadows.ts +0 -8
- package/src/theme/foundations/sizes.ts +0 -36
- package/src/theme/foundations/spacing.ts +0 -31
- package/src/theme/foundations/styles.ts +0 -12
- package/src/theme/foundations/textStyles.ts +0 -74
- package/src/theme/foundations/zIndices.ts +0 -17
- package/src/theme/utils/base-utils.ts +0 -104
- package/src/theme/utils/focus-utils.ts +0 -10
- package/src/toast/ActionToast.test.tsx +0 -22
- package/src/toast/ActionToast.tsx +0 -28
- package/src/toast/BaseToast.test.tsx +0 -27
- package/src/toast/BaseToast.tsx +0 -75
- package/src/toast/ClosableToast.test.tsx +0 -17
- package/src/toast/ClosableToast.tsx +0 -40
- package/src/toast/useToast.tsx +0 -121
- package/src/tooltip/Tooltip.tsx +0 -70
- package/src/tooltip/index.tsx +0 -1
package/src/input/CardSelect.tsx
CHANGED
@@ -1,189 +1,102 @@
|
|
1
|
+
"use client";
|
1
2
|
import {
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
forwardRef,
|
7
|
-
ResponsiveValue,
|
8
|
-
useMultiStyleConfig,
|
3
|
+
PopoverRootProps,
|
4
|
+
usePopoverContext,
|
5
|
+
Portal,
|
6
|
+
Popover as ChakraPopover,
|
9
7
|
} from "@chakra-ui/react";
|
10
8
|
import {
|
11
9
|
DropdownDownFill18Icon,
|
12
10
|
DropdownDownFill24Icon,
|
13
11
|
} from "@vygruppen/spor-icon-react";
|
14
|
-
import React, {
|
15
|
-
import {
|
16
|
-
import { useOverlayTriggerState } from "react-stately";
|
17
|
-
import { StaticCard } from "..";
|
18
|
-
import { Dialog } from "./Dialog";
|
19
|
-
import { Popover } from "./Popover";
|
12
|
+
import React, { forwardRef, ReactNode } from "react";
|
13
|
+
import { Button, ButtonProps, StaticCard, StaticCardProps } from "..";
|
20
14
|
|
21
|
-
|
15
|
+
export const CardSelect = ({ size = "md", ...props }: PopoverRootProps) => {
|
16
|
+
return <ChakraPopover.Root size={size} {...props} />;
|
17
|
+
};
|
18
|
+
|
19
|
+
export const CardSelectContent = forwardRef<HTMLDivElement, StaticCardProps>(
|
20
|
+
({ children, ...props }, ref) => {
|
21
|
+
return (
|
22
|
+
<Portal>
|
23
|
+
<ChakraPopover.Positioner>
|
24
|
+
<ChakraPopover.Content ref={ref} padding={0} bg="none">
|
25
|
+
<ChakraPopover.Body {...props}>
|
26
|
+
<StaticCard
|
27
|
+
p="2"
|
28
|
+
bg="bg"
|
29
|
+
border="sm"
|
30
|
+
borderColor="floating.outline"
|
31
|
+
{...props}
|
32
|
+
>
|
33
|
+
{children}
|
34
|
+
</StaticCard>
|
35
|
+
</ChakraPopover.Body>
|
36
|
+
</ChakraPopover.Content>
|
37
|
+
</ChakraPopover.Positioner>
|
38
|
+
</Portal>
|
39
|
+
);
|
40
|
+
},
|
41
|
+
);
|
42
|
+
|
43
|
+
export type CardSelectTriggerProps = {
|
22
44
|
/** The design of the trigger button.
|
23
45
|
*
|
24
46
|
* - `ghost` is a transparent button with text
|
25
|
-
* - `
|
47
|
+
* - `core` is a button with a border and text
|
26
48
|
* - `floating` is a button with a drop shadow (like a card) and text
|
27
49
|
*/
|
28
|
-
variant
|
29
|
-
/** The size of the trigger button */
|
30
|
-
size: "sm" | "md" | "lg";
|
31
|
-
/** Whether the card select is open / active, if controlled */
|
32
|
-
isOpen?: boolean;
|
33
|
-
/** The default state of the card select. Defaults to false (closed) */
|
34
|
-
defaultOpen?: boolean;
|
35
|
-
/** Callback for when the card select opens or closes. */
|
36
|
-
onToggle?: (isOpen: boolean) => void;
|
50
|
+
variant?: "core" | "ghost" | "floating";
|
37
51
|
/** An optional trigger button icon, rendered to the left of the label */
|
38
|
-
icon?:
|
39
|
-
/** The content of the card select */
|
40
|
-
children: React.ReactNode;
|
41
|
-
/** The horizontalOffset of the popover card */
|
42
|
-
crossOffset?: number;
|
43
|
-
/** The position of the popover card */
|
44
|
-
placement?: AriaPositionProps["placement"];
|
52
|
+
icon?: ReactNode;
|
45
53
|
/** Whether or not to show the chevron. Defaults to true */
|
46
54
|
withChevron?: boolean;
|
47
|
-
|
48
|
-
fontWeight?: ResponsiveValue<"normal" | "bold">;
|
49
|
-
} & (
|
50
|
-
| {
|
51
|
-
/** The text label of the trigger button */
|
52
|
-
label: string;
|
53
|
-
}
|
54
|
-
| {
|
55
|
-
/** Accessible label for the trigger button */
|
56
|
-
"aria-label": string;
|
57
|
-
}
|
58
|
-
);
|
55
|
+
} & Omit<ButtonProps, "variant" | "rightIcon" | "leftIcon">;
|
59
56
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
*
|
71
|
-
* @see https://spor.vy.no/components/card-select
|
72
|
-
*
|
73
|
-
*/
|
74
|
-
export const CardSelect = forwardRef<CardSelectProps, "button">(
|
57
|
+
const bgActiveStyleMap = {
|
58
|
+
core: "core.surface.active",
|
59
|
+
ghost: "ghost.surface.active",
|
60
|
+
floating: "floating.surface.active",
|
61
|
+
};
|
62
|
+
|
63
|
+
export const CardSelectTrigger = forwardRef<
|
64
|
+
HTMLButtonElement,
|
65
|
+
CardSelectTriggerProps
|
66
|
+
>(
|
75
67
|
(
|
76
|
-
{
|
77
|
-
|
78
|
-
size,
|
79
|
-
isOpen: externalIsOpen,
|
80
|
-
defaultOpen = false,
|
81
|
-
onToggle,
|
82
|
-
icon,
|
83
|
-
children,
|
84
|
-
width = "fit-content",
|
85
|
-
crossOffset = 0,
|
86
|
-
placement = "bottom",
|
87
|
-
withChevron = true,
|
88
|
-
fontWeight = "normal",
|
89
|
-
...props
|
90
|
-
},
|
91
|
-
externalRef,
|
68
|
+
{ icon, variant = "core", withChevron = true, size, children, ...props },
|
69
|
+
ref,
|
92
70
|
) => {
|
93
|
-
const label = "label" in props ? props.label : props["aria-label"];
|
94
|
-
const internalRef = useRef<HTMLButtonElement>(null);
|
95
|
-
const triggerRef = (externalRef ??
|
96
|
-
internalRef) as React.RefObject<HTMLButtonElement>;
|
97
|
-
|
98
|
-
const state = useOverlayTriggerState({
|
99
|
-
isOpen: externalIsOpen,
|
100
|
-
onOpenChange: onToggle,
|
101
|
-
defaultOpen,
|
102
|
-
});
|
103
|
-
const { triggerProps, overlayProps } = useOverlayTrigger(
|
104
|
-
{ type: "dialog" },
|
105
|
-
state,
|
106
|
-
triggerRef,
|
107
|
-
);
|
108
|
-
|
109
|
-
const { buttonProps } = useButton(triggerProps, triggerRef);
|
110
|
-
|
111
|
-
const styles = useMultiStyleConfig("CardSelect", {
|
112
|
-
variant,
|
113
|
-
size,
|
114
|
-
});
|
115
|
-
useForceRerender(state.isOpen);
|
116
|
-
|
117
71
|
const ChevronIcon =
|
118
72
|
size === "sm" ? DropdownDownFill18Icon : DropdownDownFill24Icon;
|
119
73
|
|
74
|
+
const { open } = usePopoverContext();
|
75
|
+
|
120
76
|
return (
|
121
|
-
<
|
122
|
-
<
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
<Box as="span" display={props["aria-label"] ? "none" : "inline"}>
|
134
|
-
{label}
|
135
|
-
</Box>
|
136
|
-
{withChevron ? (
|
77
|
+
<ChakraPopover.Trigger asChild ref={ref}>
|
78
|
+
<Button
|
79
|
+
leftIcon={icon}
|
80
|
+
variant={
|
81
|
+
variant === "core"
|
82
|
+
? "tertiary"
|
83
|
+
: (variant as ButtonProps["variant"])
|
84
|
+
}
|
85
|
+
size={size}
|
86
|
+
bg={open ? bgActiveStyleMap[variant] : undefined}
|
87
|
+
rightIcon={
|
88
|
+
withChevron ? (
|
137
89
|
<ChevronIcon
|
138
|
-
transform={
|
90
|
+
transform={open ? "rotate(180deg)" : undefined}
|
91
|
+
transition="transform 0.3s"
|
139
92
|
/>
|
140
|
-
) : null
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
offset={size === "sm" ? 6 : 12}
|
148
|
-
crossOffset={crossOffset}
|
149
|
-
placement={placement}
|
150
|
-
containerPadding={0}
|
151
|
-
>
|
152
|
-
<StaticCard
|
153
|
-
colorScheme="white"
|
154
|
-
size="md"
|
155
|
-
fontSize={"xs"}
|
156
|
-
border={"sm"}
|
157
|
-
borderColor={"silver"}
|
158
|
-
sx={styles.card}
|
159
|
-
{...overlayProps}
|
160
|
-
maxWidth={(triggerRef.current?.clientWidth ?? 1) * 2}
|
161
|
-
>
|
162
|
-
<Dialog aria-label={label}>{children}</Dialog>
|
163
|
-
</StaticCard>
|
164
|
-
</Popover>
|
165
|
-
)}
|
166
|
-
</Box>
|
93
|
+
) : null
|
94
|
+
}
|
95
|
+
{...props}
|
96
|
+
>
|
97
|
+
{children}
|
98
|
+
</Button>
|
99
|
+
</ChakraPopover.Trigger>
|
167
100
|
);
|
168
101
|
},
|
169
102
|
);
|
170
|
-
|
171
|
-
/**
|
172
|
-
* Hold my beer.
|
173
|
-
*
|
174
|
-
* This is a workaround for a "bug" in react-aria where the overlay doesn't
|
175
|
-
* calculate the placement correctly for some reason.
|
176
|
-
*
|
177
|
-
* This is a hack, which forces React to rerender the component one extra time
|
178
|
-
* after the state changes from closed to open.
|
179
|
-
*
|
180
|
-
* There is probably a better way to do this, but I could not come up with one.
|
181
|
-
*/
|
182
|
-
function useForceRerender(shouldRerender: boolean) {
|
183
|
-
const [_, update] = useState(false);
|
184
|
-
useEffect(() => {
|
185
|
-
if (shouldRerender) {
|
186
|
-
update((x) => !x);
|
187
|
-
}
|
188
|
-
}, [shouldRerender]);
|
189
|
-
}
|
package/src/input/Checkbox.tsx
CHANGED
@@ -1,11 +1,19 @@
|
|
1
|
+
import { checkboxSlotRecipe } from "@/theme/slot-recipes/checkbox";
|
1
2
|
import {
|
2
3
|
Checkbox as ChakraCheckbox,
|
3
|
-
|
4
|
-
forwardRef,
|
4
|
+
RecipeVariantProps,
|
5
5
|
} from "@chakra-ui/react";
|
6
|
-
import React from "react";
|
6
|
+
import * as React from "react";
|
7
|
+
import { PropsWithChildren } from "react";
|
8
|
+
|
9
|
+
type CheckboxVariantProps = RecipeVariantProps<typeof checkboxSlotRecipe>;
|
10
|
+
|
11
|
+
type CheckboxProps = ChakraCheckbox.RootProps &
|
12
|
+
PropsWithChildren<CheckboxVariantProps> & {
|
13
|
+
inputProps?: React.InputHTMLAttributes<HTMLInputElement>;
|
14
|
+
rootRef?: React.Ref<HTMLLabelElement>;
|
15
|
+
};
|
7
16
|
|
8
|
-
export type CheckboxProps = ChakraCheckboxProps;
|
9
17
|
/**
|
10
18
|
* Creates a checkbox.
|
11
19
|
*
|
@@ -15,8 +23,24 @@ export type CheckboxProps = ChakraCheckboxProps;
|
|
15
23
|
* <Checkbox>Accept the terms</Checkbox>
|
16
24
|
* ```
|
17
25
|
*
|
18
|
-
* Unlike regular inputs, it doesn't require its own `
|
26
|
+
* Unlike regular inputs, it doesn't require its own `Field`.
|
19
27
|
*
|
20
28
|
* You can group several of these together with a `CheckboxGroup`.
|
21
29
|
*/
|
22
|
-
|
30
|
+
|
31
|
+
export const Checkbox = React.forwardRef<HTMLInputElement, CheckboxProps>(
|
32
|
+
(props, ref) => {
|
33
|
+
const { children, inputProps, rootRef, ...rest } = props;
|
34
|
+
return (
|
35
|
+
<ChakraCheckbox.Root ref={rootRef} {...rest}>
|
36
|
+
<ChakraCheckbox.HiddenInput ref={ref} {...inputProps} />
|
37
|
+
<ChakraCheckbox.Control>
|
38
|
+
<ChakraCheckbox.Indicator />
|
39
|
+
</ChakraCheckbox.Control>
|
40
|
+
{children != null && (
|
41
|
+
<ChakraCheckbox.Label>{children}</ChakraCheckbox.Label>
|
42
|
+
)}
|
43
|
+
</ChakraCheckbox.Root>
|
44
|
+
);
|
45
|
+
},
|
46
|
+
);
|
@@ -2,19 +2,25 @@ import {
|
|
2
2
|
CheckboxGroup as ChakraCheckboxGroup,
|
3
3
|
CheckboxGroupProps as ChakraCheckboxGroupProps,
|
4
4
|
Stack,
|
5
|
-
StackDirection,
|
6
5
|
} from "@chakra-ui/react";
|
7
|
-
import React from "react";
|
6
|
+
import React, { forwardRef } from "react";
|
8
7
|
|
9
8
|
export type CheckboxGroupProps = Exclude<
|
10
9
|
ChakraCheckboxGroupProps,
|
11
|
-
"
|
12
|
-
> & {
|
10
|
+
"colorPalette" | "size" | "variant"
|
11
|
+
> & {
|
12
|
+
/* Defaults to row */
|
13
|
+
direction?: "row" | "column";
|
14
|
+
children: React.ReactNode;
|
15
|
+
/* Defaults to 1 */
|
16
|
+
gap?: number | string;
|
17
|
+
[key: string]: any;
|
18
|
+
};
|
13
19
|
/**
|
14
20
|
* Used to group several checkboxes together. You can pass the default value, as well as whether or not they're all disabled
|
15
21
|
*
|
16
22
|
* ```tsx
|
17
|
-
* <CheckboxGroup
|
23
|
+
* <CheckboxGroup disabled defaultValue={['red', 'blue']}>
|
18
24
|
* <Checkbox value="red">Red</Checkbox>
|
19
25
|
* <Checkbox value="blue">Blue</Checkbox>
|
20
26
|
* <Checkbox value="green">Green</Checkbox>
|
@@ -30,14 +36,17 @@ export type CheckboxGroupProps = Exclude<
|
|
30
36
|
* <Checkbox>First Class</Checkbox>
|
31
37
|
* </CheckboxGroup>
|
32
38
|
*/
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
39
|
+
|
40
|
+
export const CheckboxGroup = forwardRef<HTMLDivElement, CheckboxGroupProps>(
|
41
|
+
(props, ref) => {
|
42
|
+
const { direction = "row", children, gap = 1, ...rest } = props;
|
43
|
+
|
44
|
+
return (
|
45
|
+
<ChakraCheckboxGroup ref={ref} {...rest}>
|
46
|
+
<Stack direction={direction} gap={gap}>
|
47
|
+
{children}
|
48
|
+
</Stack>
|
49
|
+
</ChakraCheckboxGroup>
|
50
|
+
);
|
51
|
+
},
|
52
|
+
);
|
package/src/input/ChoiceChip.tsx
CHANGED
@@ -1,17 +1,20 @@
|
|
1
|
+
"use client";
|
2
|
+
import { choiceChipRecipe } from "@/theme/recipes/choice-chip";
|
1
3
|
import {
|
2
4
|
chakra,
|
3
|
-
|
5
|
+
RecipeVariantProps,
|
6
|
+
Span,
|
4
7
|
useCheckbox,
|
5
|
-
useMultiStyleConfig,
|
6
8
|
} from "@chakra-ui/react";
|
7
|
-
import { dataAttr } from "@chakra-ui/utils";
|
8
9
|
import { CloseOutline24Icon } from "@vygruppen/spor-icon-react";
|
9
|
-
import React, { ChangeEvent, useId } from "react";
|
10
|
+
import React, { ChangeEvent, PropsWithChildren, useId } from "react";
|
10
11
|
|
11
|
-
|
12
|
+
type ChoiceChipVariantProps = RecipeVariantProps<typeof choiceChipRecipe>;
|
13
|
+
|
14
|
+
export type ChoiceChipProps = PropsWithChildren<ChoiceChipVariantProps> & {
|
12
15
|
onChange?: (value: ChangeEvent<HTMLInputElement>) => void;
|
13
|
-
|
14
|
-
|
16
|
+
checked?: boolean;
|
17
|
+
disabled?: boolean;
|
15
18
|
defaultChecked?: boolean;
|
16
19
|
/** The button text */
|
17
20
|
children: React.ReactNode;
|
@@ -19,10 +22,10 @@ export type ChoiceChipProps = {
|
|
19
22
|
default: React.ReactNode;
|
20
23
|
checked: React.ReactNode;
|
21
24
|
};
|
22
|
-
size?: "xs" | "sm" | "md" | "lg";
|
23
25
|
chipType?: "icon" | "choice" | "filter";
|
24
|
-
|
26
|
+
"aria-label"?: string;
|
25
27
|
};
|
28
|
+
|
26
29
|
/**
|
27
30
|
* Choice chips are checkboxes that look like selectable buttons.
|
28
31
|
*
|
@@ -44,82 +47,60 @@ export type ChoiceChipProps = {
|
|
44
47
|
* <ChoiceChip chipType="filter" icon={<Bus24Icon />}>Bus</ChoiceChip>
|
45
48
|
* </Stack>
|
46
49
|
*
|
47
|
-
* There are also three different variants - `
|
50
|
+
* There are also three different variants - `core`, `accent` and `floating`.
|
48
51
|
*
|
49
52
|
* ```tsx
|
50
53
|
* <Stack flexDirection="row">
|
51
|
-
* <ChoiceChip variant="
|
54
|
+
* <ChoiceChip variant="core">Bus</ChoiceChip>
|
52
55
|
* <ChoiceChip variant="accent">Boat</ChoiceChip>
|
53
56
|
* <ChoiceChip variant="floating">Train</ChoiceChip>
|
54
57
|
* </Stack>
|
55
58
|
* ```
|
56
59
|
*/
|
57
|
-
export const ChoiceChip = forwardRef(
|
58
|
-
(
|
59
|
-
{
|
60
|
-
children,
|
61
|
-
icon,
|
62
|
-
isDisabled,
|
63
|
-
size = "sm",
|
64
|
-
chipType = "choice",
|
65
|
-
variant = "base",
|
66
|
-
...props
|
67
|
-
}: ChoiceChipProps,
|
68
|
-
ref,
|
69
|
-
) => {
|
70
|
-
const {
|
71
|
-
state,
|
72
|
-
getInputProps,
|
73
|
-
getCheckboxProps,
|
74
|
-
getRootProps,
|
75
|
-
getLabelProps,
|
76
|
-
} = useCheckbox(props);
|
77
|
-
const styles = useMultiStyleConfig("ChoiceChip", {
|
78
|
-
size,
|
79
|
-
chipType,
|
80
|
-
variant,
|
81
|
-
icon,
|
82
|
-
hasLabel: chipType !== "icon",
|
83
|
-
});
|
84
60
|
|
85
|
-
|
61
|
+
const ChoiceChipStyledDiv = chakra("div", choiceChipRecipe);
|
86
62
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
data-focus={dataAttr(state.isFocused)}
|
104
|
-
data-active={dataAttr(state.isActive)}
|
105
|
-
data-disabled={dataAttr(isDisabled || state.isDisabled)}
|
106
|
-
>
|
107
|
-
{icon && (
|
108
|
-
<chakra.span __css={styles.icon}>
|
109
|
-
{state.isChecked ? icon.checked : icon.default}
|
110
|
-
</chakra.span>
|
111
|
-
)}
|
112
|
-
{chipType !== "icon" && (
|
113
|
-
<chakra.span __css={styles.label} {...getCheckboxProps()}>
|
114
|
-
{children}
|
115
|
-
</chakra.span>
|
116
|
-
)}
|
63
|
+
export const ChoiceChip = ({
|
64
|
+
children,
|
65
|
+
icon,
|
66
|
+
size = "sm",
|
67
|
+
chipType = "choice",
|
68
|
+
variant = "core",
|
69
|
+
...props
|
70
|
+
}: ChoiceChipProps) => {
|
71
|
+
const {
|
72
|
+
getControlProps,
|
73
|
+
disabled,
|
74
|
+
getLabelProps,
|
75
|
+
getHiddenInputProps,
|
76
|
+
setChecked,
|
77
|
+
checked,
|
78
|
+
} = useCheckbox(props);
|
117
79
|
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
80
|
+
return (
|
81
|
+
<chakra.label
|
82
|
+
{...getLabelProps()}
|
83
|
+
aria-label={props["aria-label"] ?? String(children)}
|
84
|
+
>
|
85
|
+
<chakra.input
|
86
|
+
{...getHiddenInputProps()}
|
87
|
+
disabled={disabled}
|
88
|
+
defaultChecked={checked}
|
89
|
+
value={checked ? "on" : "off"}
|
90
|
+
type="checkbox"
|
91
|
+
aria-checked={checked}
|
92
|
+
onClick={() => {
|
93
|
+
setChecked(!checked);
|
94
|
+
}}
|
95
|
+
/>
|
96
|
+
<ChoiceChipStyledDiv {...getControlProps()} size={size} variant={variant}>
|
97
|
+
{icon && <Span>{checked ? icon.checked : icon.default}</Span>}
|
98
|
+
{chipType !== "icon" && <Span>{children}</Span>}
|
99
|
+
|
100
|
+
{chipType === "filter" && checked && (
|
101
|
+
<CloseOutline24Icon marginLeft={1.5} />
|
102
|
+
)}
|
103
|
+
</ChoiceChipStyledDiv>
|
104
|
+
</chakra.label>
|
105
|
+
);
|
106
|
+
};
|