@hyphen/hyphen-components 4.13.0 → 5.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.
Files changed (39) hide show
  1. package/dist/components/Formik/{FormikToggle/FormikToggle.d.ts → FormikSwitch/FormikSwitch.d.ts} +2 -2
  2. package/dist/components/Formik/FormikToggleGroup/FormikToggleGroup.d.ts +20 -0
  3. package/dist/components/Switch/Switch.d.ts +64 -0
  4. package/dist/components/Switch/Switch.stories.d.ts +12 -0
  5. package/dist/components/Toggle/Toggle.d.ts +7 -64
  6. package/dist/components/Toggle/Toggle.stories.d.ts +4 -5
  7. package/dist/components/ToggleGroup/ToggleGroup.d.ts +19 -0
  8. package/dist/components/ToggleGroup/ToggleGroup.stories.d.ts +12 -0
  9. package/dist/css/index.css +3 -1
  10. package/dist/css/utilities.css +13 -1
  11. package/dist/css/variables.css +6 -2
  12. package/dist/hyphen-components.cjs.development.js +341 -239
  13. package/dist/hyphen-components.cjs.development.js.map +1 -1
  14. package/dist/hyphen-components.cjs.production.min.js +1 -1
  15. package/dist/hyphen-components.cjs.production.min.js.map +1 -1
  16. package/dist/hyphen-components.esm.js +335 -239
  17. package/dist/hyphen-components.esm.js.map +1 -1
  18. package/dist/index.d.ts +4 -1
  19. package/dist/lib/tokens.d.ts +1 -1
  20. package/package.json +18 -16
  21. package/src/components/Formik/Formik.stories.tsx +81 -2
  22. package/src/components/Formik/{FormikToggle/FormikToggle.test.tsx → FormikSwitch/FormikSwitch.test.tsx} +3 -3
  23. package/src/components/Formik/{FormikToggle/FormikToggle.tsx → FormikSwitch/FormikSwitch.tsx} +4 -4
  24. package/src/components/Formik/FormikToggleGroup/FormikToggleGroup.test.tsx +117 -0
  25. package/src/components/Formik/FormikToggleGroup/FormikToggleGroup.tsx +71 -0
  26. package/src/components/Switch/Switch.mdx +47 -0
  27. package/src/components/Switch/Switch.module.scss +294 -0
  28. package/src/components/Switch/Switch.stories.tsx +128 -0
  29. package/src/components/{Toggle/Toggle.test.tsx → Switch/Switch.test.tsx} +75 -75
  30. package/src/components/Switch/Switch.tsx +185 -0
  31. package/src/components/Toggle/Toggle.mdx +11 -31
  32. package/src/components/Toggle/Toggle.module.scss +28 -280
  33. package/src/components/Toggle/Toggle.stories.tsx +46 -111
  34. package/src/components/Toggle/Toggle.tsx +28 -180
  35. package/src/components/ToggleGroup/ToggleGroup.mdx +39 -0
  36. package/src/components/ToggleGroup/ToggleGroup.module.scss +42 -0
  37. package/src/components/ToggleGroup/ToggleGroup.stories.tsx +195 -0
  38. package/src/components/ToggleGroup/ToggleGroup.tsx +89 -0
  39. package/src/index.ts +4 -1
@@ -0,0 +1,39 @@
1
+ import { Canvas, Meta, ArgTypes } from '@storybook/blocks';
2
+ import { ToggleGroup } from './ToggleGroup';
3
+ import * as Stories from './ToggleGroup.stories';
4
+
5
+ <Meta of={Stories} />
6
+
7
+ # ToggleGroup
8
+
9
+ A set of two-state buttons that can be toggled on or off.
10
+
11
+ This component is extended from [Radix](https://www.radix-ui.com/primitives/docs/components/toggle-group).
12
+
13
+ [API Reference](https://www.radix-ui.com/primitives/docs/components/toggle-group#api-reference)
14
+
15
+ <Canvas of={Stories.Uncontrolled} />
16
+
17
+ ## Multiple
18
+
19
+ By default, one value is allowed, but you can allow for multiple selections by setting the `type` to `multiple`.
20
+
21
+ <Canvas of={Stories.Multiple} />
22
+
23
+ ## Controlled
24
+
25
+ The `onChange` prop can be used to handle changes to the selected value.
26
+
27
+ <Canvas of={Stories.Controlled} />
28
+
29
+ ## Variants
30
+
31
+ An outlined alternative variant is available.
32
+
33
+ <Canvas of={Stories.Outlined} />
34
+
35
+ ## Disabled
36
+
37
+ The `disabled` prop can be used to disable the ToggleGroup component, preventing user interaction. Individual item may also be disabled.
38
+
39
+ <Canvas of={Stories.Disabled} />
@@ -0,0 +1,42 @@
1
+ @import '@hyphen/hyphen-design-tokens/build/scss/variables';
2
+
3
+ .item {
4
+ line-height: 1;
5
+ padding: var(--size-spacing-sm);
6
+ color: var(--color-font-secondary);
7
+ font-size: var(--size-font-size-sm);
8
+ background-color: var(--color-background-transparent);
9
+ border-width: 0;
10
+ cursor: pointer;
11
+
12
+ &:hover {
13
+ background-color: var(--color-background-toggle-group-item-hover);
14
+ }
15
+ &[data-state='on'] {
16
+ background-color: var(--color-background-toggle-group-item-active);
17
+ color: var(--color-font-base);
18
+ }
19
+ &:focus-visible {
20
+ position: relative;
21
+ box-shadow: 0 0 0 2px black;
22
+ }
23
+
24
+ &:disabled {
25
+ opacity: 0.5;
26
+ pointer-events: none;
27
+ }
28
+ }
29
+
30
+ .outline {
31
+ border: 1px solid var(--color-border-default);
32
+ box-shadow: var(--size-box-shadow-xs);
33
+
34
+ &:disabled,
35
+ &[data-state='on'] {
36
+ box-shadow: none;
37
+ }
38
+
39
+ &:disabled {
40
+ pointer-events: none;
41
+ }
42
+ }
@@ -0,0 +1,195 @@
1
+ import React from 'react';
2
+ import type { Meta } from '@storybook/react';
3
+
4
+ import { ToggleGroup, ToggleGroupItem } from './ToggleGroup';
5
+ import { Box } from '../Box/Box';
6
+ import {
7
+ Tooltip,
8
+ TooltipContent,
9
+ TooltipProvider,
10
+ TooltipTrigger,
11
+ } from '../Tooltip/Tooltip';
12
+
13
+ const meta: Meta<typeof ToggleGroup> = {
14
+ title: 'Components/ToggleGroup',
15
+ component: ToggleGroup,
16
+ };
17
+
18
+ export default meta;
19
+
20
+ export const Uncontrolled = () => (
21
+ <ToggleGroup type="single" defaultValue="option2">
22
+ <ToggleGroupItem value="option1">99%</ToggleGroupItem>
23
+ <ToggleGroupItem value="option2">99.9%</ToggleGroupItem>
24
+ <ToggleGroupItem value="option3">99.99%</ToggleGroupItem>
25
+ <ToggleGroupItem value="option4">99.999%</ToggleGroupItem>
26
+ </ToggleGroup>
27
+ );
28
+
29
+ export const Multiple = () => (
30
+ <ToggleGroup type="multiple">
31
+ <ToggleGroupItem value="option1">99%</ToggleGroupItem>
32
+ <ToggleGroupItem value="option2">99.9%</ToggleGroupItem>
33
+ <ToggleGroupItem value="option3">99.99%</ToggleGroupItem>
34
+ <ToggleGroupItem value="option4">99.999%</ToggleGroupItem>
35
+ </ToggleGroup>
36
+ );
37
+
38
+ export const Controlled = () => {
39
+ const [value, setValue] = React.useState('option1');
40
+
41
+ const handleValueChange = (newValue: string) => {
42
+ setValue(newValue);
43
+ };
44
+
45
+ return (
46
+ <ToggleGroup type="single" value={value} onValueChange={handleValueChange}>
47
+ <ToggleGroupItem value="option1">99%</ToggleGroupItem>
48
+ <ToggleGroupItem value="option2">99.9%</ToggleGroupItem>
49
+ <ToggleGroupItem value="option3">99.99%</ToggleGroupItem>
50
+ <ToggleGroupItem value="option4">99.999%</ToggleGroupItem>
51
+ </ToggleGroup>
52
+ );
53
+ };
54
+
55
+ export const Outlined = () => (
56
+ <ToggleGroup type="single" variant="outline" defaultValue="option1">
57
+ <ToggleGroupItem value="option1">99%</ToggleGroupItem>
58
+ <ToggleGroupItem value="option2">99.9%</ToggleGroupItem>
59
+ <ToggleGroupItem value="option3">99.99%</ToggleGroupItem>
60
+ <ToggleGroupItem value="option4">99.999%</ToggleGroupItem>
61
+ </ToggleGroup>
62
+ );
63
+
64
+ export const Disabled = () => (
65
+ <ToggleGroup type="single" disabled>
66
+ <ToggleGroupItem value="option1">99%</ToggleGroupItem>
67
+ <ToggleGroupItem value="option2">99.9%</ToggleGroupItem>
68
+ <ToggleGroupItem value="option3">99.99%</ToggleGroupItem>
69
+ <ToggleGroupItem value="option4">99.999%</ToggleGroupItem>
70
+ </ToggleGroup>
71
+ );
72
+
73
+ export const CustomLabel = () => (
74
+ <TooltipProvider delayDuration={0}>
75
+ <ToggleGroup
76
+ type="single"
77
+ gap="lg"
78
+ defaultValue="option2"
79
+ variant="outline"
80
+ >
81
+ <ToggleGroupItem value="option1">
82
+ <Tooltip>
83
+ <TooltipTrigger asChild>
84
+ <Box textAlign="left" alignItems="flex-start" gap="xs">
85
+ <Box fontSize="xl" fontWeight="semibold">
86
+ 99%
87
+ </Box>
88
+ <Box color="tertiary" fontSize="xs">
89
+ Standard
90
+ </Box>
91
+ </Box>
92
+ </TooltipTrigger>
93
+ <TooltipContent sideOffset={10}>
94
+ Up to 3.65 days/year downtime
95
+ </TooltipContent>
96
+ </Tooltip>
97
+ </ToggleGroupItem>
98
+ <ToggleGroupItem value="option2">
99
+ <Tooltip>
100
+ <TooltipTrigger asChild>
101
+ <Box textAlign="left" alignItems="flex-start" gap="xs">
102
+ <Box fontSize="xl" fontWeight="semibold">
103
+ 99.9%
104
+ </Box>
105
+ <Box
106
+ color="tertiary"
107
+ fontSize="xs"
108
+ direction="row"
109
+ alignItems="center"
110
+ gap="sm"
111
+ >
112
+ High
113
+ </Box>
114
+ </Box>
115
+ </TooltipTrigger>
116
+ <TooltipContent sideOffset={10}>
117
+ Up to 8.76 hours/year downtime
118
+ </TooltipContent>
119
+ </Tooltip>
120
+ </ToggleGroupItem>
121
+ <ToggleGroupItem value="option3">
122
+ <Tooltip>
123
+ <TooltipTrigger asChild>
124
+ <Box textAlign="left" alignItems="flex-start" gap="xs">
125
+ <Box fontSize="xl" fontWeight="semibold">
126
+ 99.99%
127
+ </Box>
128
+ <Box color="tertiary" fontSize="xs">
129
+ Very High
130
+ </Box>
131
+ </Box>
132
+ </TooltipTrigger>
133
+ <TooltipContent sideOffset={10}>
134
+ Up to 52.56 minutes/year downtime
135
+ </TooltipContent>
136
+ </Tooltip>
137
+ </ToggleGroupItem>
138
+ <ToggleGroupItem value="option4">
139
+ <Tooltip>
140
+ <TooltipTrigger asChild>
141
+ <Box textAlign="left" alignItems="flex-start" gap="xs">
142
+ <Box fontSize="xl" fontWeight="semibold">
143
+ 99.999%
144
+ </Box>
145
+ <Box color="tertiary" fontSize="xs">
146
+ Mission Critical
147
+ </Box>
148
+ </Box>
149
+ </TooltipTrigger>
150
+ <TooltipContent sideOffset={10}>
151
+ Up to 5.26 minutes/year downtime
152
+ </TooltipContent>
153
+ </Tooltip>
154
+ </ToggleGroupItem>
155
+ </ToggleGroup>
156
+ </TooltipProvider>
157
+ );
158
+
159
+ export const BackgroundTest = () => (
160
+ <>
161
+ <Box background="primary" padding="2xl">
162
+ <ToggleGroup type="single" defaultValue="option2">
163
+ <ToggleGroupItem value="option1">99%</ToggleGroupItem>
164
+ <ToggleGroupItem value="option2">99.9%</ToggleGroupItem>
165
+ <ToggleGroupItem value="option3">99.99%</ToggleGroupItem>
166
+ <ToggleGroupItem value="option4">99.999%</ToggleGroupItem>
167
+ <ToggleGroupItem value="disabled" disabled>
168
+ disabled
169
+ </ToggleGroupItem>
170
+ </ToggleGroup>
171
+ </Box>
172
+ <Box background="secondary" padding="2xl">
173
+ <ToggleGroup type="single" defaultValue="option2">
174
+ <ToggleGroupItem value="option1">99%</ToggleGroupItem>
175
+ <ToggleGroupItem value="option2">99.9%</ToggleGroupItem>
176
+ <ToggleGroupItem value="option3">99.99%</ToggleGroupItem>
177
+ <ToggleGroupItem value="option4">99.999%</ToggleGroupItem>
178
+ <ToggleGroupItem value="disabled" disabled>
179
+ disabled
180
+ </ToggleGroupItem>
181
+ </ToggleGroup>
182
+ </Box>
183
+ <Box background="tertiary" padding="2xl">
184
+ <ToggleGroup type="single" defaultValue="option2">
185
+ <ToggleGroupItem value="option1">99%</ToggleGroupItem>
186
+ <ToggleGroupItem value="option2">99.9%</ToggleGroupItem>
187
+ <ToggleGroupItem value="option3">99.99%</ToggleGroupItem>
188
+ <ToggleGroupItem value="option4">99.999%</ToggleGroupItem>
189
+ <ToggleGroupItem value="disabled" disabled>
190
+ disabled
191
+ </ToggleGroupItem>
192
+ </ToggleGroup>
193
+ </Box>
194
+ </>
195
+ );
@@ -0,0 +1,89 @@
1
+ import React, { createContext, useContext, forwardRef, ReactNode } from 'react';
2
+ import * as ToggleGroupPrimitive from '@radix-ui/react-toggle-group';
3
+ import styles from './ToggleGroup.module.scss';
4
+
5
+ import classNames from 'classnames';
6
+ import { InputValidationMessage } from '../InputValidationMessage/InputValidationMessage';
7
+ import { BaseSpacing, ResponsiveProp } from '../../types';
8
+ import { cssShorthandToClasses } from '../../lib';
9
+
10
+ type ToggleVariant = 'default' | 'outline';
11
+
12
+ const ToggleGroupContext = createContext<{ variant: ToggleVariant }>({
13
+ variant: 'default',
14
+ });
15
+
16
+ type ToggleGroupProps = React.ComponentPropsWithoutRef<
17
+ typeof ToggleGroupPrimitive.Root
18
+ > & {
19
+ variant?: ToggleVariant;
20
+ name?: string;
21
+ gap?: BaseSpacing | ResponsiveProp<BaseSpacing>;
22
+ /**
23
+ * Mark the toggle group as invalid and display a validation message.
24
+ * Pass a string or node to render a validation message below the input.
25
+ */
26
+ error?: ReactNode;
27
+ };
28
+
29
+ const ToggleGroup = forwardRef<
30
+ React.ElementRef<typeof ToggleGroupPrimitive.Root>,
31
+ ToggleGroupProps
32
+ >(
33
+ (
34
+ { className, variant = 'default', children, gap = 'xs', error, ...props },
35
+ ref
36
+ ) => (
37
+ <div>
38
+ <ToggleGroupPrimitive.Root
39
+ ref={ref}
40
+ className={classNames(
41
+ 'display-flex align-items-center justify-content-start',
42
+ className,
43
+ cssShorthandToClasses('g', gap)
44
+ )}
45
+ {...props}
46
+ >
47
+ <ToggleGroupContext.Provider value={{ variant }}>
48
+ {children}
49
+ </ToggleGroupContext.Provider>
50
+ </ToggleGroupPrimitive.Root>
51
+
52
+ {error && <InputValidationMessage>{error}</InputValidationMessage>}
53
+ </div>
54
+ )
55
+ );
56
+
57
+ type ToggleGroupItemProps = React.ComponentPropsWithoutRef<
58
+ typeof ToggleGroupPrimitive.Item
59
+ > & {
60
+ variant?: ToggleVariant;
61
+ };
62
+
63
+ const ToggleGroupItem = forwardRef<
64
+ React.ElementRef<typeof ToggleGroupPrimitive.Item>,
65
+ ToggleGroupItemProps
66
+ >(({ className, children, value, variant, ...props }, ref) => {
67
+ const { variant: contextVariant } = useContext(ToggleGroupContext);
68
+ const appliedVariant = variant || contextVariant;
69
+
70
+ return (
71
+ <ToggleGroupPrimitive.Item
72
+ ref={ref}
73
+ className={classNames(
74
+ 'br-sm display-flex g-sm p-sm',
75
+ styles.item,
76
+ appliedVariant === 'outline' && styles.outline,
77
+ className
78
+ )}
79
+ value={value}
80
+ {...props}
81
+ >
82
+ {children}
83
+ </ToggleGroupPrimitive.Item>
84
+ );
85
+ });
86
+
87
+ ToggleGroupItem.displayName = ToggleGroupPrimitive.Item.displayName;
88
+
89
+ export { ToggleGroup, ToggleGroupItem };
package/src/index.ts CHANGED
@@ -24,7 +24,8 @@ export * from './components/Formik/FormikTextInput/FormikTextInput';
24
24
  export * from './components/Formik/FormikTextareaInput/FormikTextareaInput';
25
25
  export * from './components/Formik/FormikTimePicker/FormikTimePicker';
26
26
  export * from './components/Formik/FormikTimePickerNative/FormikTimePickerNative';
27
- export * from './components/Formik/FormikToggle/FormikToggle';
27
+ export * from './components/Formik/FormikSwitch/FormikSwitch';
28
+ export * from './components/Formik/FormikToggleGroup/FormikToggleGroup';
28
29
  export * from './components/FormLabel/FormLabel';
29
30
  export * from './components/Heading/Heading';
30
31
  export * from './components/Icon/Icon';
@@ -39,6 +40,7 @@ export * from './components/SelectInputInset/SelectInputInset';
39
40
  export * from './components/SelectInputNative/SelectInputNative';
40
41
  export * from './components/Sidebar/Sidebar';
41
42
  export * from './components/Spinner/Spinner';
43
+ export * from './components/Switch/Switch';
42
44
  export * from './components/Table/Table';
43
45
  export * from './components/TextareaInput/TextareaInput';
44
46
  export * from './components/TextareaInputInset/TextareaInputInset';
@@ -49,5 +51,6 @@ export * from './components/TimePicker/TimePicker';
49
51
  export * from './components/TimePickerNative/TimePickerNative';
50
52
  export * from './components/Toast';
51
53
  export * from './components/Toggle/Toggle';
54
+ export * from './components/ToggleGroup/ToggleGroup';
52
55
  export * from './components/Tooltip/Tooltip';
53
56
  export * from './hooks';