@vygruppen/spor-react 11.3.10 → 12.0.1
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 +33 -11
- package/.turbo/turbo-typegen.log +22 -0
- package/CHANGELOG.md +247 -0
- package/dist/index.d.mts +2589 -8303
- package/dist/index.d.ts +2589 -8303
- package/dist/index.js +9609 -8608
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +9487 -8455
- package/dist/index.mjs.map +1 -1
- package/package.json +23 -15
- 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 +70 -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 -101
- 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 +36 -21
- 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
@@ -1,41 +1,56 @@
|
|
1
|
+
"use client";
|
2
|
+
|
3
|
+
import React, { forwardRef } from "react";
|
1
4
|
import {
|
2
5
|
Breadcrumb as ChakraBreadcrumb,
|
3
|
-
|
6
|
+
BreadcrumbRootProps,
|
4
7
|
BreadcrumbLink as ChakraBreadcrumbLink,
|
5
|
-
|
6
|
-
|
8
|
+
BreadcrumbCurrentLink as ChakraBreadcrumbCurrentLink,
|
9
|
+
BreadcrumbEllipsis as ChakraBreadcrumbEllipsis,
|
7
10
|
} from "@chakra-ui/react";
|
8
11
|
import { DropdownRightFill18Icon } from "@vygruppen/spor-icon-react";
|
9
|
-
import React from "react";
|
10
|
-
|
11
|
-
type BreadcrumbProps = Omit<ChakraBreadcrumbProps, "variant"> & {
|
12
|
-
variant?: "base" | "ghost";
|
13
|
-
};
|
14
12
|
/**
|
15
13
|
* A breadcrumb component.
|
16
14
|
*
|
17
15
|
* Used to create customizable breadcrumbs.
|
18
|
-
*
|
16
|
+
* BreadcrumbCurrentLink is used to set the last breadcrumb.
|
17
|
+
* BreadcrumbLink is used to set the other breadcrumbs.
|
19
18
|
* ```tsx
|
20
19
|
* <Breadcrumb>
|
21
|
-
* <BreadcrumbItem>
|
22
20
|
* <BreadcrumbLink href="/">Home</BreadcrumbLink>
|
23
|
-
*
|
24
|
-
*
|
25
|
-
* <BreadcrumbLink href="/about">About</BreadcrumbLink>
|
26
|
-
* </BreadcrumbItem>
|
21
|
+
* <BreadcrumbLink href="/Breadcrumb">Breadcrumb</BreadcrumbLink>
|
22
|
+
* <BreadcrumbCurrentLink href="/about">About</BreadcrumbCurrentLink>
|
27
23
|
* </Breadcrumb>
|
28
24
|
* ```
|
29
25
|
*/
|
30
|
-
export const Breadcrumb = (
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
26
|
+
export const Breadcrumb = forwardRef<HTMLDivElement, BreadcrumbRootProps>(
|
27
|
+
({ children, ...props }, ref) => {
|
28
|
+
const validChildren = React.Children.toArray(children).filter(
|
29
|
+
React.isValidElement,
|
30
|
+
);
|
31
|
+
|
32
|
+
return (
|
33
|
+
<ChakraBreadcrumb.Root ref={ref} {...props}>
|
34
|
+
<ChakraBreadcrumb.List>
|
35
|
+
{validChildren.map((child, index) => {
|
36
|
+
const isLast = index === validChildren.length - 1;
|
37
|
+
return (
|
38
|
+
<React.Fragment key={index}>
|
39
|
+
<ChakraBreadcrumb.Item>{child}</ChakraBreadcrumb.Item>
|
40
|
+
{!isLast && (
|
41
|
+
<ChakraBreadcrumb.Separator aria-hidden="true">
|
42
|
+
<DropdownRightFill18Icon />
|
43
|
+
</ChakraBreadcrumb.Separator>
|
44
|
+
)}
|
45
|
+
</React.Fragment>
|
46
|
+
);
|
47
|
+
})}
|
48
|
+
</ChakraBreadcrumb.List>
|
49
|
+
</ChakraBreadcrumb.Root>
|
50
|
+
);
|
51
|
+
},
|
52
|
+
);
|
39
53
|
|
40
|
-
export const BreadcrumbItem = ChakraBreadcrumbItem;
|
41
54
|
export const BreadcrumbLink = ChakraBreadcrumbLink;
|
55
|
+
export const BreadcrumbCurrentLink = ChakraBreadcrumbCurrentLink;
|
56
|
+
export const BreadcrumbEllipsis = ChakraBreadcrumbEllipsis;
|
package/src/button/Button.tsx
CHANGED
@@ -1,41 +1,41 @@
|
|
1
1
|
import {
|
2
2
|
Box,
|
3
3
|
Center,
|
4
|
-
|
4
|
+
Button as ChakraButton,
|
5
5
|
Flex,
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
useStyleConfig,
|
6
|
+
Span,
|
7
|
+
type ButtonProps as ChakraButtonProps,
|
8
|
+
type RecipeVariantProps,
|
10
9
|
} from "@chakra-ui/react";
|
11
|
-
import React from "react";
|
10
|
+
import React, { forwardRef, PropsWithChildren } from "react";
|
12
11
|
import { createTexts, useTranslation } from "../i18n";
|
13
12
|
import { ColorInlineLoader } from "../loader";
|
13
|
+
import { buttonRecipe } from "../theme/recipes/button";
|
14
|
+
|
15
|
+
export type ButtonVariantProps = RecipeVariantProps<typeof buttonRecipe>;
|
14
16
|
|
15
17
|
export type ButtonProps = Exclude<
|
16
18
|
ChakraButtonProps,
|
17
|
-
"
|
18
|
-
> &
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
| "floating";
|
38
|
-
};
|
19
|
+
"size" | "variant" | "colorPalette"
|
20
|
+
> &
|
21
|
+
PropsWithChildren<ButtonVariantProps> & {
|
22
|
+
/* Boolean value for loading state */
|
23
|
+
loading?: boolean;
|
24
|
+
/* You may display a different loading text */
|
25
|
+
loadingText?: React.ReactNode;
|
26
|
+
/* Display icon to the left */
|
27
|
+
leftIcon?: React.ReactNode;
|
28
|
+
/* Display icon to the right */
|
29
|
+
rightIcon?: React.ReactNode;
|
30
|
+
/* "primary" | "secondary" | "tertiary" | "ghost" | "floating". Defaults to primary. */
|
31
|
+
variant: "primary" | "secondary" | "tertiary" | "ghost" | "floating";
|
32
|
+
/* "lg" | "md" | "sm" | "xs". Defaults to md. */
|
33
|
+
size?: "lg" | "md" | "sm" | "xs";
|
34
|
+
/* Link to a downloadable resource. */
|
35
|
+
download?: string;
|
36
|
+
/* Use this to specify a path combined with as="a" */
|
37
|
+
href?: string;
|
38
|
+
};
|
39
39
|
/**
|
40
40
|
* Buttons are used to trigger actions.
|
41
41
|
*
|
@@ -63,86 +63,67 @@ export type ButtonProps = Exclude<
|
|
63
63
|
*
|
64
64
|
* @see https://spor.vy.no/components/button
|
65
65
|
*/
|
66
|
-
export const Button = forwardRef<ButtonProps, "button">((props, ref) => {
|
67
|
-
const {
|
68
|
-
as = "button",
|
69
|
-
type = "button",
|
70
|
-
fontWeight,
|
71
|
-
size,
|
72
|
-
children,
|
73
|
-
isLoading,
|
74
|
-
isDisabled,
|
75
|
-
leftIcon,
|
76
|
-
rightIcon,
|
77
|
-
sx,
|
78
|
-
...rest
|
79
|
-
} = props;
|
80
|
-
const ariaLabel = useCorrectAriaLabel(props);
|
81
|
-
const buttonGroup = useButtonGroup();
|
82
|
-
const finalSize = (size ?? buttonGroup?.size ?? "md") as Required<
|
83
|
-
ButtonProps["size"]
|
84
|
-
>;
|
85
|
-
const styles = useStyleConfig("Button", {
|
86
|
-
...buttonGroup,
|
87
|
-
...rest,
|
88
|
-
size: finalSize,
|
89
|
-
leftIcon,
|
90
|
-
rightIcon,
|
91
|
-
});
|
92
66
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
67
|
+
export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
|
68
|
+
(props, ref) => {
|
69
|
+
const {
|
70
|
+
loading,
|
71
|
+
disabled,
|
72
|
+
loadingText,
|
73
|
+
variant = "primary",
|
74
|
+
size = "md",
|
75
|
+
leftIcon,
|
76
|
+
rightIcon,
|
77
|
+
type = "button",
|
78
|
+
children,
|
79
|
+
...rest
|
80
|
+
} = props;
|
81
|
+
const ariaLabel = useCorrectAriaLabel(props);
|
82
|
+
|
83
|
+
const buttonContent = (
|
84
|
+
<>
|
85
|
+
{leftIcon}
|
86
|
+
{children}
|
87
|
+
{rightIcon && <Span marginLeft="auto">{rightIcon}</Span>}
|
88
|
+
</>
|
89
|
+
);
|
97
90
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
fontFamily={"Vy Sans"}
|
110
|
-
>
|
111
|
-
{isLoading && (
|
112
|
-
<Center position="absolute" right={0} left={0} top={1} bottom={0}>
|
113
|
-
<ColorInlineLoader
|
114
|
-
maxWidth={getLoaderWidth(finalSize)}
|
115
|
-
width="80%"
|
116
|
-
marginX={2}
|
117
|
-
marginY={2}
|
118
|
-
/>
|
119
|
-
</Center>
|
120
|
-
)}
|
121
|
-
<Flex
|
122
|
-
gap={1}
|
123
|
-
flex={1}
|
124
|
-
alignItems="center"
|
125
|
-
justifyContent={rightIcon ? "space-between" : "center"}
|
126
|
-
visibility={isLoading ? "hidden" : "visible"}
|
127
|
-
aria-hidden={isLoading}
|
91
|
+
return (
|
92
|
+
<ChakraButton
|
93
|
+
type={type}
|
94
|
+
ref={ref}
|
95
|
+
aria-label={ariaLabel}
|
96
|
+
aria-busy={loading}
|
97
|
+
disabled={disabled || loading}
|
98
|
+
position="relative"
|
99
|
+
variant={variant}
|
100
|
+
size={size}
|
101
|
+
{...rest}
|
128
102
|
>
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
103
|
+
{loading ? (
|
104
|
+
<>
|
105
|
+
<Flex gap="1" visibility="hidden">
|
106
|
+
{buttonContent}
|
107
|
+
</Flex>
|
108
|
+
<Center position="absolute" right={0} left={0} top={1} bottom={0}>
|
109
|
+
<ColorInlineLoader
|
110
|
+
maxWidth={getLoaderWidth(size)}
|
111
|
+
width="80%"
|
112
|
+
marginX={2}
|
113
|
+
marginY={2}
|
114
|
+
/>
|
115
|
+
{loadingText && <Box>{loadingText}</Box>}
|
116
|
+
</Center>
|
117
|
+
</>
|
118
|
+
) : (
|
119
|
+
buttonContent
|
120
|
+
)}
|
121
|
+
</ChakraButton>
|
122
|
+
);
|
123
|
+
},
|
124
|
+
);
|
144
125
|
|
145
|
-
function getLoaderWidth(size:
|
126
|
+
function getLoaderWidth(size: ButtonProps["size"]): string {
|
146
127
|
switch (size) {
|
147
128
|
case "xs":
|
148
129
|
return "4rem";
|
@@ -158,7 +139,7 @@ function getLoaderWidth(size: Required<ButtonProps["size"]>) {
|
|
158
139
|
|
159
140
|
function useCorrectAriaLabel(props: ButtonProps): string {
|
160
141
|
const { t } = useTranslation();
|
161
|
-
if (props.
|
142
|
+
if (props.loading) {
|
162
143
|
return String(props.loadingText) ?? t(texts.loadingText);
|
163
144
|
}
|
164
145
|
return props["aria-label"] as string;
|
@@ -1,13 +1,21 @@
|
|
1
|
+
"use client";
|
2
|
+
|
1
3
|
import {
|
2
|
-
|
3
|
-
|
4
|
-
|
4
|
+
type GroupProps as ChakraGroupProps,
|
5
|
+
Group as ChakraGroup,
|
6
|
+
type RecipeVariantProps,
|
7
|
+
chakra,
|
5
8
|
} from "@chakra-ui/react";
|
6
|
-
import React from "react";
|
9
|
+
import React, { forwardRef, PropsWithChildren } from "react";
|
10
|
+
import { groupRecipe } from "../theme/recipes/group";
|
11
|
+
|
12
|
+
export type GroupVariantProps = RecipeVariantProps<typeof groupRecipe>;
|
13
|
+
|
14
|
+
export type ButtonGroupProps = ChakraGroupProps &
|
15
|
+
PropsWithChildren<GroupVariantProps>;
|
7
16
|
|
8
|
-
export type ButtonGroupProps = ChakraButtonGroupProps;
|
9
17
|
/**
|
10
|
-
*
|
18
|
+
* Used to group or attach buttons together.
|
11
19
|
*
|
12
20
|
* If you have more than one button next to eachother, you might want to add a `ButtonGroup` to group them.
|
13
21
|
*
|
@@ -18,26 +26,43 @@ export type ButtonGroupProps = ChakraButtonGroupProps;
|
|
18
26
|
* </ButtonGroup>
|
19
27
|
* ```
|
20
28
|
*
|
21
|
-
*
|
29
|
+
*
|
30
|
+
* Attach buttons together with the `attached` prop.
|
22
31
|
*
|
23
32
|
* ```tsx
|
24
|
-
* <ButtonGroup
|
25
|
-
* <Button>Open</Button>
|
26
|
-
* <
|
33
|
+
* <ButtonGroup attached>
|
34
|
+
* <Button variant="primary">Open</Button>
|
35
|
+
* <IconButton variant="ghost">
|
36
|
+
* <SaveIcon aria-label="Save"/>
|
37
|
+
* </IconButton>
|
27
38
|
* </ButtonGroup>
|
28
39
|
* ```
|
29
40
|
*
|
30
|
-
*
|
41
|
+
* Use the `grow` prop to make the buttons grow to fill the available space.
|
31
42
|
*
|
32
43
|
* ```tsx
|
33
|
-
* <ButtonGroup
|
34
|
-
*
|
35
|
-
*
|
36
|
-
* <SaveIcon aria-label="Save"/>
|
37
|
-
* </IconButton>
|
44
|
+
* <ButtonGroup grow>
|
45
|
+
* <Button variant="primary">Open</Button>
|
46
|
+
* <Button variant="secondary">Save</Button>
|
38
47
|
* </ButtonGroup>
|
39
|
-
* ```
|
40
48
|
*/
|
41
|
-
|
42
|
-
|
43
|
-
|
49
|
+
|
50
|
+
const Group = chakra(ChakraGroup, groupRecipe);
|
51
|
+
|
52
|
+
export const ButtonGroup = forwardRef<HTMLDivElement, ButtonGroupProps>(
|
53
|
+
(props, ref) => {
|
54
|
+
const { children, disabled, grow, attached, ...rest } = props;
|
55
|
+
|
56
|
+
return (
|
57
|
+
<Group
|
58
|
+
{...rest}
|
59
|
+
ref={ref}
|
60
|
+
attached={attached}
|
61
|
+
grow={grow}
|
62
|
+
disabled={disabled}
|
63
|
+
>
|
64
|
+
{children}
|
65
|
+
</Group>
|
66
|
+
);
|
67
|
+
},
|
68
|
+
);
|
@@ -0,0 +1,82 @@
|
|
1
|
+
import { Clipboard as ChakraClipboard } from "@chakra-ui/react";
|
2
|
+
import * as React from "react";
|
3
|
+
import { createTexts, useTranslation } from "@/i18n";
|
4
|
+
import {
|
5
|
+
CheckmarkFill18Icon,
|
6
|
+
CopyOutline18Icon,
|
7
|
+
} from "@vygruppen/spor-icon-react";
|
8
|
+
import { Button, ButtonProps } from "./Button";
|
9
|
+
import { Text } from "@/typography";
|
10
|
+
|
11
|
+
/**
|
12
|
+
*
|
13
|
+
* Creates a button that copies text to the clipboard.
|
14
|
+
*
|
15
|
+
* ```tsx
|
16
|
+
* <Clipboard value="Some value to be copied">
|
17
|
+
* <ClipboardButton />
|
18
|
+
* </Clipboard>
|
19
|
+
*/
|
20
|
+
|
21
|
+
const ClipboardIcon = React.forwardRef<
|
22
|
+
HTMLDivElement,
|
23
|
+
ChakraClipboard.IndicatorProps
|
24
|
+
>((props, ref) => {
|
25
|
+
return (
|
26
|
+
<ChakraClipboard.Indicator
|
27
|
+
copied={<CheckmarkFill18Icon />}
|
28
|
+
{...props}
|
29
|
+
ref={ref}
|
30
|
+
>
|
31
|
+
<CopyOutline18Icon />
|
32
|
+
</ChakraClipboard.Indicator>
|
33
|
+
);
|
34
|
+
});
|
35
|
+
|
36
|
+
const ClipboardCopyText = React.forwardRef<
|
37
|
+
HTMLDivElement,
|
38
|
+
ChakraClipboard.IndicatorProps
|
39
|
+
>((props, ref) => {
|
40
|
+
const { t } = useTranslation();
|
41
|
+
return (
|
42
|
+
<ChakraClipboard.Indicator
|
43
|
+
copied={<Text variant="xs">{t(texts.copied)}</Text>}
|
44
|
+
{...props}
|
45
|
+
ref={ref}
|
46
|
+
>
|
47
|
+
<Text variant="xs">{t(texts.copy)}</Text>
|
48
|
+
</ChakraClipboard.Indicator>
|
49
|
+
);
|
50
|
+
});
|
51
|
+
|
52
|
+
type ClipboardButtonProps = ButtonProps;
|
53
|
+
|
54
|
+
export const ClipboardButton = React.forwardRef<
|
55
|
+
HTMLButtonElement,
|
56
|
+
ClipboardButtonProps
|
57
|
+
>((props, ref) => {
|
58
|
+
return (
|
59
|
+
<ChakraClipboard.Trigger asChild>
|
60
|
+
<Button ref={ref} size="xs" leftIcon={<ClipboardIcon />} {...props}>
|
61
|
+
<ClipboardCopyText />
|
62
|
+
</Button>
|
63
|
+
</ChakraClipboard.Trigger>
|
64
|
+
);
|
65
|
+
});
|
66
|
+
|
67
|
+
export const Clipboard = ChakraClipboard.Root;
|
68
|
+
|
69
|
+
const texts = createTexts({
|
70
|
+
copy: {
|
71
|
+
nb: "Kopier",
|
72
|
+
nn: "Kopier",
|
73
|
+
en: "Copy",
|
74
|
+
sv: "Kopiera",
|
75
|
+
},
|
76
|
+
copied: {
|
77
|
+
nb: "Kopiert",
|
78
|
+
nn: "Kopiert",
|
79
|
+
en: "Copied",
|
80
|
+
sv: "Kopierad",
|
81
|
+
},
|
82
|
+
});
|
@@ -1,10 +1,11 @@
|
|
1
|
-
|
1
|
+
"use client";
|
2
|
+
|
2
3
|
import {
|
3
4
|
CloseFill18Icon,
|
4
5
|
CloseFill24Icon,
|
5
6
|
CloseFill30Icon,
|
6
7
|
} from "@vygruppen/spor-icon-react";
|
7
|
-
import React from "react";
|
8
|
+
import React, { forwardRef } from "react";
|
8
9
|
import { createTexts, useTranslation } from "../i18n";
|
9
10
|
import { IconButton, IconButtonProps } from "./IconButton";
|
10
11
|
|
@@ -25,7 +26,7 @@ export type CloseButtonProps = Omit<
|
|
25
26
|
* <CloseButton onClick={closeModal} />
|
26
27
|
* ```
|
27
28
|
*/
|
28
|
-
export const CloseButton = forwardRef<
|
29
|
+
export const CloseButton = forwardRef<HTMLButtonElement, CloseButtonProps>(
|
29
30
|
({ size = "sm", ...props }, ref) => {
|
30
31
|
const { t } = useTranslation();
|
31
32
|
return (
|
@@ -1,22 +1,27 @@
|
|
1
|
+
"use client";
|
2
|
+
|
1
3
|
import {
|
2
4
|
Box,
|
3
5
|
BoxProps,
|
4
|
-
|
5
|
-
|
6
|
-
|
6
|
+
RecipeVariantProps,
|
7
|
+
Text,
|
8
|
+
useSlotRecipe,
|
7
9
|
} from "@chakra-ui/react";
|
8
|
-
import {
|
9
|
-
import
|
10
|
+
import React, { forwardRef, PropsWithChildren, useEffect } from "react";
|
11
|
+
import { floatingActionButtonSlotRecipe } from "../theme/slot-recipes/floating-action-button";
|
10
12
|
|
11
|
-
|
13
|
+
type FloatingActionButtonVariantProps = RecipeVariantProps<
|
14
|
+
typeof floatingActionButtonSlotRecipe
|
15
|
+
>;
|
12
16
|
|
13
|
-
type FloatingActionButtonProps = BoxProps &
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
17
|
+
type FloatingActionButtonProps = BoxProps &
|
18
|
+
PropsWithChildren<FloatingActionButtonVariantProps> & {
|
19
|
+
variant?: "accent" | "core" | "brand";
|
20
|
+
placement?: "bottom right" | "bottom left" | "top right" | "top left";
|
21
|
+
icon: React.ReactNode;
|
22
|
+
children: React.ReactNode;
|
23
|
+
isTextVisible?: boolean;
|
24
|
+
};
|
20
25
|
|
21
26
|
/**
|
22
27
|
* Creates a floating action button.
|
@@ -31,8 +36,8 @@ type FloatingActionButtonProps = BoxProps & {
|
|
31
36
|
* />
|
32
37
|
*/
|
33
38
|
export const FloatingActionButton = forwardRef<
|
34
|
-
|
35
|
-
|
39
|
+
HTMLButtonElement,
|
40
|
+
FloatingActionButtonProps
|
36
41
|
>(
|
37
42
|
(
|
38
43
|
{
|
@@ -65,39 +70,28 @@ export const FloatingActionButton = forwardRef<
|
|
65
70
|
setIsTextVisible(!!externalIsTextVisible);
|
66
71
|
}, [externalIsTextVisible]);
|
67
72
|
|
68
|
-
const
|
73
|
+
const recipe = useSlotRecipe({ key: "floatingActionButton" });
|
74
|
+
const style = recipe({
|
69
75
|
variant,
|
70
|
-
isTextVisible,
|
71
76
|
placement,
|
72
77
|
});
|
78
|
+
|
73
79
|
return (
|
74
|
-
<
|
75
|
-
|
76
|
-
|
80
|
+
<Box
|
81
|
+
css={style.root}
|
82
|
+
as="button"
|
83
|
+
aria-label={typeof children === "string" ? children : undefined}
|
77
84
|
ref={ref}
|
78
85
|
{...props}
|
86
|
+
aria-expanded={isTextVisible}
|
79
87
|
>
|
80
|
-
<Box
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
width: "auto",
|
88
|
-
visibility: "visible",
|
89
|
-
},
|
90
|
-
hide: {
|
91
|
-
opacity: 0,
|
92
|
-
width: 0,
|
93
|
-
visibility: "hidden",
|
94
|
-
},
|
95
|
-
}}
|
96
|
-
__css={style.text}
|
97
|
-
>
|
98
|
-
{children}
|
99
|
-
</MotionBox>
|
100
|
-
</MotionBox>
|
88
|
+
<Box css={style.icon}>{icon}</Box>
|
89
|
+
{isTextVisible && (
|
90
|
+
<Text data-state="open" css={style.text}>
|
91
|
+
{children}
|
92
|
+
</Text>
|
93
|
+
)}
|
94
|
+
</Box>
|
101
95
|
);
|
102
96
|
},
|
103
97
|
);
|