@fpkit/acss 0.5.7 → 0.5.9
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/libs/components/alert/alert.css +1 -0
- package/libs/components/alert/alert.css.map +1 -0
- package/libs/components/alert/alert.min.css +3 -0
- package/libs/components/badge/badge.css +1 -0
- package/libs/components/badge/badge.css.map +1 -0
- package/libs/components/badge/badge.min.css +3 -0
- package/libs/components/breadcrumbs/breadcrumb.css +1 -0
- package/libs/components/breadcrumbs/breadcrumb.css.map +1 -0
- package/libs/components/breadcrumbs/breadcrumb.min.css +3 -0
- package/libs/components/buttons/button.css +1 -0
- package/libs/components/buttons/button.css.map +1 -0
- package/libs/components/buttons/button.min.css +3 -0
- package/libs/components/cards/card-style.css +1 -0
- package/libs/components/cards/card-style.css.map +1 -0
- package/libs/components/cards/card-style.min.css +3 -0
- package/libs/components/cards/card.css +1 -0
- package/libs/components/cards/card.css.map +1 -0
- package/libs/components/cards/card.min.css +3 -0
- package/libs/components/details/details.css +1 -0
- package/libs/components/details/details.css.map +1 -0
- package/libs/components/details/details.min.css +3 -0
- package/libs/components/dialog/dialog.css +1 -0
- package/libs/components/dialog/dialog.css.map +1 -0
- package/libs/components/dialog/dialog.min.css +3 -0
- package/libs/components/form/form.css +1 -0
- package/libs/components/form/form.css.map +1 -0
- package/libs/components/form/form.min.css +3 -0
- package/libs/components/icons/icon.css +1 -0
- package/libs/components/icons/icon.css.map +1 -0
- package/libs/components/icons/icon.min.css +3 -0
- package/libs/components/images/img.css +1 -0
- package/libs/components/images/img.css.map +1 -0
- package/libs/components/images/img.min.css +3 -0
- package/libs/components/layout/landmarks.css +1 -0
- package/libs/components/layout/landmarks.css.map +1 -0
- package/libs/components/layout/landmarks.min.css +3 -0
- package/libs/components/link/link.css +1 -0
- package/libs/components/link/link.css.map +1 -0
- package/libs/components/link/link.min.css +3 -0
- package/libs/components/nav/nav.css +1 -0
- package/libs/components/nav/nav.css.map +1 -0
- package/libs/components/nav/nav.min.css +3 -0
- package/libs/components/progress/progress.css +1 -0
- package/libs/components/progress/progress.css.map +1 -0
- package/libs/components/progress/progress.min.css +3 -0
- package/libs/components/styles/index.css +1 -0
- package/libs/components/styles/index.css.map +1 -0
- package/libs/components/styles/index.min.css +3 -0
- package/libs/components/tag/tag.css +1 -0
- package/libs/components/tag/tag.css.map +1 -0
- package/libs/components/tag/tag.min.css +3 -0
- package/libs/components/text-to-speech/text-to-speech.css +1 -0
- package/libs/components/text-to-speech/text-to-speech.css.map +1 -0
- package/libs/components/text-to-speech/text-to-speech.min.css +3 -0
- package/libs/index.cjs +2 -2
- package/libs/index.cjs.map +1 -1
- package/libs/index.css +1 -0
- package/libs/index.css.map +1 -0
- package/libs/index.d.cts +23 -22
- package/libs/index.d.ts +23 -22
- package/libs/index.js +2 -2
- package/libs/index.js.map +1 -1
- package/package.json +2 -2
- package/src/components/alert/README.mdx +44 -56
- package/src/components/alert/alert.scss +1 -1
- package/src/components/alert/alert.stories.tsx +7 -7
- package/src/components/alert/alert.tsx +10 -2
- package/src/components/badge/badge.tsx +19 -11
- package/src/components/breadcrumbs/README.mdx +91 -0
- package/src/components/breadcrumbs/breadcrumb.tsx +92 -87
- package/src/components/buttons/README.mdx +96 -0
- package/src/components/buttons/button.scss +4 -2
- package/src/components/cards/README.mdx +133 -0
- package/src/components/details/README.mdx +101 -0
- package/src/components/details/details.scss +21 -15
- package/src/components/details/details.stories.tsx +35 -7
- package/src/components/details/details.tsx +18 -11
- package/src/components/dialog/dialog-modal.stories.tsx +1 -1
- package/src/components/form/inputs.tsx +18 -24
- package/src/components/heading/heading.tsx +24 -12
- package/src/components/text/README.mdx +98 -0
- package/src/components/text/text.tsx +49 -50
- package/src/styles/alert/alert.css +0 -1
- package/src/styles/alert/alert.css.map +1 -1
- package/src/styles/buttons/button.css +4 -2
- package/src/styles/buttons/button.css.map +1 -1
- package/src/styles/details/details.css +18 -13
- package/src/styles/details/details.css.map +1 -1
- package/src/styles/index.css +22 -16
- package/src/styles/index.css.map +1 -1
- package/src/components/alert/alert.mdx +0 -74
- package/src/components/cards/README.md +0 -80
|
@@ -118,13 +118,13 @@ export const InteractionTest: Story = {
|
|
|
118
118
|
expect(dismissButton).toBeInTheDocument();
|
|
119
119
|
}
|
|
120
120
|
);
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
121
|
+
await step(
|
|
122
|
+
"Tab through the alert and check if the button gets focused",
|
|
123
|
+
async () => {
|
|
124
|
+
await userEvent.tab({ delay: 500 });
|
|
125
|
+
expect(dismissButton).toHaveFocus();
|
|
126
|
+
}
|
|
127
|
+
);
|
|
128
128
|
await step("Click the button to dismiss the alert", async () => {
|
|
129
129
|
await userEvent.click(dismissButton, { delay: 500 });
|
|
130
130
|
expect(alert).not.toBeInTheDocument();
|
|
@@ -44,6 +44,11 @@ export type AlertProps = {
|
|
|
44
44
|
*/
|
|
45
45
|
iconSize?: number;
|
|
46
46
|
|
|
47
|
+
/**
|
|
48
|
+
* Whether to hide the icon.
|
|
49
|
+
*/
|
|
50
|
+
hideIcon?: boolean;
|
|
51
|
+
|
|
47
52
|
/**
|
|
48
53
|
* Additional props to pass to the Icon component.
|
|
49
54
|
*/
|
|
@@ -75,7 +80,9 @@ export type AlertProps = {
|
|
|
75
80
|
* ```
|
|
76
81
|
*
|
|
77
82
|
* @see {@link AlertProps} for available configuration options
|
|
78
|
-
*/
|
|
83
|
+
*/
|
|
84
|
+
|
|
85
|
+
const Alert: React.FC<AlertProps> = ({
|
|
79
86
|
open,
|
|
80
87
|
severity = "default",
|
|
81
88
|
children,
|
|
@@ -84,6 +91,7 @@ export type AlertProps = {
|
|
|
84
91
|
onDismiss,
|
|
85
92
|
iconSize,
|
|
86
93
|
iconProps,
|
|
94
|
+
hideIcon,
|
|
87
95
|
...props
|
|
88
96
|
}) => {
|
|
89
97
|
const [isVisible, setIsVisible] = React.useState(open);
|
|
@@ -137,7 +145,7 @@ export type AlertProps = {
|
|
|
137
145
|
data-alert={severity}
|
|
138
146
|
{...props}
|
|
139
147
|
>
|
|
140
|
-
<UI aria-hidden="true">{severityIcons[severity]}</UI>
|
|
148
|
+
{!hideIcon && <UI aria-hidden="true">{severityIcons[severity]}</UI>}
|
|
141
149
|
<UI as="div" className="alert-message">
|
|
142
150
|
{title && (
|
|
143
151
|
<UI as="h3" className="alert-title">
|
|
@@ -1,17 +1,25 @@
|
|
|
1
|
-
import UI from
|
|
2
|
-
import React from
|
|
1
|
+
import UI from "#components/ui";
|
|
2
|
+
import React from "react";
|
|
3
3
|
|
|
4
|
-
export
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
export interface BadgeProps extends React.ComponentProps<typeof UI> {
|
|
5
|
+
id?: string;
|
|
6
|
+
styles?: React.CSSProperties;
|
|
7
|
+
className?: string;
|
|
8
|
+
children: React.ReactNode;
|
|
9
|
+
}
|
|
7
10
|
|
|
8
|
-
const Badge
|
|
11
|
+
const Badge: React.FC<BadgeProps> = ({
|
|
12
|
+
id,
|
|
13
|
+
styles,
|
|
14
|
+
className,
|
|
15
|
+
children,
|
|
16
|
+
...props
|
|
17
|
+
}) => {
|
|
9
18
|
return (
|
|
10
|
-
<UI as="sup" id={id} styles={styles} className={
|
|
19
|
+
<UI as="sup" id={id} styles={styles} className={className} {...props}>
|
|
11
20
|
<UI as="span">{children}</UI>
|
|
12
21
|
</UI>
|
|
13
|
-
)
|
|
14
|
-
}
|
|
22
|
+
);
|
|
23
|
+
};
|
|
15
24
|
|
|
16
|
-
export default Badge
|
|
17
|
-
Badge.displayName = 'Badge'
|
|
25
|
+
export default Badge;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { Meta } from "@storybook/blocks";
|
|
2
|
+
|
|
3
|
+
<Meta title="FP.REACT Components/Breadcrumb/Readme" />
|
|
4
|
+
|
|
5
|
+
# Breadcrumb Component
|
|
6
|
+
|
|
7
|
+
## Summary
|
|
8
|
+
|
|
9
|
+
The `Breadcrumb` component is used to display a breadcrumb navigation for the
|
|
10
|
+
current page. It supports custom routes, starting routes, and truncation of long
|
|
11
|
+
breadcrumb names.
|
|
12
|
+
|
|
13
|
+
## Features
|
|
14
|
+
|
|
15
|
+
- Customizable routes and starting route
|
|
16
|
+
- Truncation of long breadcrumb names
|
|
17
|
+
- Customizable spacer between breadcrumb items
|
|
18
|
+
- Accessible with ARIA labels
|
|
19
|
+
|
|
20
|
+
## Props
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
type customRoute = {
|
|
24
|
+
path?: string;
|
|
25
|
+
name: string;
|
|
26
|
+
url?: string;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
type BreadcrumbProps = {
|
|
30
|
+
routes?: customRoute[];
|
|
31
|
+
startRoute?: React.ReactNode;
|
|
32
|
+
startRouteUrl?: string;
|
|
33
|
+
spacer?: React.ReactNode;
|
|
34
|
+
currentRoute?: string;
|
|
35
|
+
ariaLabelPrefix?: string;
|
|
36
|
+
truncateLength?: number;
|
|
37
|
+
linkProps?: React.ComponentProps<typeof Link>;
|
|
38
|
+
} & React.ComponentProps<typeof UI>;
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Technical Details
|
|
42
|
+
|
|
43
|
+
The `Breadcrumb` component uses the `UI` and `Link` components for rendering the
|
|
44
|
+
breadcrumb items and links. It also uses the `Truncate` utility to truncate long
|
|
45
|
+
breadcrumb names.
|
|
46
|
+
|
|
47
|
+
## Usage Example
|
|
48
|
+
|
|
49
|
+
### Basic Usage
|
|
50
|
+
|
|
51
|
+
```tsx
|
|
52
|
+
import Breadcrumb from './breadcrumb'
|
|
53
|
+
|
|
54
|
+
const routes = [
|
|
55
|
+
{ path: '/home', name: 'Home' },
|
|
56
|
+
{ path: '/about', name: 'About' },
|
|
57
|
+
{ path: '/contact', name: 'Contact' },
|
|
58
|
+
]
|
|
59
|
+
|
|
60
|
+
<Breadcrumb routes={routes} currentRoute="/about" />
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Advanced Usage
|
|
64
|
+
|
|
65
|
+
```tsx
|
|
66
|
+
import Breadcrumb from './breadcrumb'
|
|
67
|
+
|
|
68
|
+
const routes = [
|
|
69
|
+
{ path: '/home', name: 'Home' },
|
|
70
|
+
{ path: '/about', name: 'About Us', url: '/about-us' },
|
|
71
|
+
{ path: '/contact', name: 'Contact Us', url: '/contact-us' },
|
|
72
|
+
]
|
|
73
|
+
|
|
74
|
+
<Breadcrumb
|
|
75
|
+
routes={routes}
|
|
76
|
+
currentRoute="/contact"
|
|
77
|
+
startRoute="Dashboard"
|
|
78
|
+
startRouteUrl="/dashboard"
|
|
79
|
+
spacer={<span className="mx-2">/</span>}
|
|
80
|
+
ariaLabelPrefix="You are here:"
|
|
81
|
+
truncateLength={10}
|
|
82
|
+
linkProps={{ className: 'text-blue-500 hover:underline' }}
|
|
83
|
+
/>
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Additional Notes
|
|
87
|
+
|
|
88
|
+
- Ensure to provide meaningful names for the routes to enhance accessibility.
|
|
89
|
+
- Customize the `spacer` prop to match your design requirements.
|
|
90
|
+
- Use the `truncateLength` prop to control the maximum length of breadcrumb
|
|
91
|
+
names.
|
|
@@ -1,38 +1,38 @@
|
|
|
1
1
|
// Code: Breadcrumb component
|
|
2
|
-
import React from
|
|
3
|
-
import UI from
|
|
4
|
-
import { Truncate } from
|
|
5
|
-
import Link from
|
|
2
|
+
import React from "react";
|
|
3
|
+
import UI from "#components/ui";
|
|
4
|
+
import { Truncate } from "#libs/content";
|
|
5
|
+
import Link from "#components/link/link";
|
|
6
6
|
|
|
7
7
|
// TYPES
|
|
8
8
|
|
|
9
9
|
type customRoute = {
|
|
10
10
|
/** The path or id for routing */
|
|
11
|
-
path?: string
|
|
11
|
+
path?: string;
|
|
12
12
|
/** The display name */
|
|
13
|
-
name: string
|
|
13
|
+
name: string;
|
|
14
14
|
/** The url if linking out */
|
|
15
|
-
url?: string
|
|
16
|
-
}
|
|
15
|
+
url?: string;
|
|
16
|
+
};
|
|
17
17
|
|
|
18
18
|
type BreadcrumbProps = {
|
|
19
19
|
/** Array of custom route objects */
|
|
20
|
-
routes?: customRoute[]
|
|
20
|
+
routes?: customRoute[];
|
|
21
21
|
/** Starting route node */
|
|
22
|
-
startRoute?: React.ReactNode
|
|
22
|
+
startRoute?: React.ReactNode;
|
|
23
23
|
/* Starting route url */
|
|
24
|
-
startRouteUrl?: string
|
|
24
|
+
startRouteUrl?: string;
|
|
25
25
|
/** Spacer node between routes */
|
|
26
|
-
spacer?: React.ReactNode
|
|
26
|
+
spacer?: React.ReactNode;
|
|
27
27
|
/** String representing current route */
|
|
28
|
-
currentRoute?: string
|
|
28
|
+
currentRoute?: string;
|
|
29
29
|
/** Prefix breadcrumb aria-label - "prefix breadcrumb" */
|
|
30
|
-
ariaLabelPrefix?: string
|
|
30
|
+
ariaLabelPrefix?: string;
|
|
31
31
|
/** Truncate breadcrumb text after this length */
|
|
32
|
-
truncateLength?: number
|
|
32
|
+
truncateLength?: number;
|
|
33
33
|
/** Link props for breadcrumb links */
|
|
34
|
-
linkProps?: React.ComponentProps<typeof Link
|
|
35
|
-
} & React.ComponentProps<typeof UI
|
|
34
|
+
linkProps?: React.ComponentProps<typeof Link>;
|
|
35
|
+
} & React.ComponentProps<typeof UI>;
|
|
36
36
|
|
|
37
37
|
// Components
|
|
38
38
|
|
|
@@ -53,11 +53,17 @@ const Items = ({
|
|
|
53
53
|
...props
|
|
54
54
|
}: React.ComponentProps<typeof UI>) => {
|
|
55
55
|
return (
|
|
56
|
-
<li
|
|
56
|
+
<li
|
|
57
|
+
id={id}
|
|
58
|
+
style={styles}
|
|
59
|
+
className={classes}
|
|
60
|
+
data-list="unstyled inline"
|
|
61
|
+
{...props}
|
|
62
|
+
>
|
|
57
63
|
{children}
|
|
58
64
|
</li>
|
|
59
|
-
)
|
|
60
|
-
}
|
|
65
|
+
);
|
|
66
|
+
};
|
|
61
67
|
|
|
62
68
|
/**
|
|
63
69
|
* List component.
|
|
@@ -70,8 +76,8 @@ const List = ({ children, ...props }: React.ComponentProps<typeof UI>) => {
|
|
|
70
76
|
<UI as="ol" data-list="unstyled inline" {...props}>
|
|
71
77
|
{children}
|
|
72
78
|
</UI>
|
|
73
|
-
)
|
|
74
|
-
}
|
|
79
|
+
);
|
|
80
|
+
};
|
|
75
81
|
|
|
76
82
|
/**
|
|
77
83
|
* Nav component.
|
|
@@ -93,8 +99,8 @@ const Nav = ({
|
|
|
93
99
|
<UI as="nav" id={id} styles={styles} className={classes} {...props}>
|
|
94
100
|
<List>{children}</List>
|
|
95
101
|
</UI>
|
|
96
|
-
)
|
|
97
|
-
}
|
|
102
|
+
);
|
|
103
|
+
};
|
|
98
104
|
|
|
99
105
|
/**
|
|
100
106
|
* Navigation component for breadcrumbs.
|
|
@@ -110,7 +116,7 @@ const Nav = ({
|
|
|
110
116
|
* @param props.children - Child components.
|
|
111
117
|
*/
|
|
112
118
|
export const Breadcrumb = ({
|
|
113
|
-
startRoute =
|
|
119
|
+
startRoute = "Home",
|
|
114
120
|
startRouteUrl = "/",
|
|
115
121
|
currentRoute,
|
|
116
122
|
spacer = <>/</>,
|
|
@@ -123,13 +129,13 @@ export const Breadcrumb = ({
|
|
|
123
129
|
linkProps,
|
|
124
130
|
...props
|
|
125
131
|
}: BreadcrumbProps): React.JSX.Element => {
|
|
126
|
-
const [currentPath, setCurrentPath] = React.useState(
|
|
132
|
+
const [currentPath, setCurrentPath] = React.useState("");
|
|
127
133
|
React.useEffect(() => {
|
|
128
|
-
const path = currentRoute || window.location.pathname
|
|
134
|
+
const path = currentRoute || window.location.pathname;
|
|
129
135
|
if (path.length) {
|
|
130
|
-
setCurrentPath(path)
|
|
136
|
+
setCurrentPath(path);
|
|
131
137
|
}
|
|
132
|
-
}, [currentRoute])
|
|
138
|
+
}, [currentRoute]);
|
|
133
139
|
|
|
134
140
|
/**
|
|
135
141
|
* Gets the path name for the given path segment.
|
|
@@ -138,23 +144,22 @@ export const Breadcrumb = ({
|
|
|
138
144
|
* @returns The path name object for the given path segment.
|
|
139
145
|
*/
|
|
140
146
|
const getPathName = (pathSegment: string): customRoute => {
|
|
141
|
-
const route = routes?.find((route) => route.path === pathSegment)
|
|
147
|
+
const route = routes?.find((route) => route.path === pathSegment);
|
|
142
148
|
|
|
143
149
|
return {
|
|
144
150
|
path: route?.path || pathSegment,
|
|
145
151
|
name: route?.name || pathSegment,
|
|
146
152
|
url: route?.url || pathSegment,
|
|
147
|
-
}
|
|
148
|
-
}
|
|
153
|
+
};
|
|
154
|
+
};
|
|
149
155
|
|
|
150
156
|
/** Array of path segments from current path */
|
|
151
|
-
const segments = currentPath.split(
|
|
157
|
+
const segments = currentPath.split("/").filter((segment) => segment);
|
|
152
158
|
/** Index of last item in segments array */
|
|
153
|
-
const lastSegment = segments.length - 1
|
|
159
|
+
const lastSegment = segments.length - 1;
|
|
154
160
|
|
|
155
161
|
/** Unique id for breadcrumb */
|
|
156
|
-
const uuid = React.useId()
|
|
157
|
-
|
|
162
|
+
const uuid = React.useId();
|
|
158
163
|
|
|
159
164
|
return currentPath.length ? (
|
|
160
165
|
<Nav
|
|
@@ -165,62 +170,62 @@ export const Breadcrumb = ({
|
|
|
165
170
|
aria-label={ariaLabelPrefix}
|
|
166
171
|
>
|
|
167
172
|
<Items key={`${startRoute}-${uuid}`}>
|
|
168
|
-
<Link href={startRouteUrl} {...linkProps}>
|
|
173
|
+
<Link href={startRouteUrl} {...linkProps}>
|
|
174
|
+
{startRoute}
|
|
175
|
+
</Link>
|
|
169
176
|
</Items>
|
|
170
177
|
<>
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
</
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
null
|
|
213
|
-
)}
|
|
178
|
+
{segments.length
|
|
179
|
+
? segments.map((segment: string, index: number) => {
|
|
180
|
+
const currentSegment = getPathName(segment);
|
|
181
|
+
const { name, url, path } = currentSegment;
|
|
182
|
+
return index === lastSegment ? (
|
|
183
|
+
<>
|
|
184
|
+
{typeof segments[lastSegment] === "string" &&
|
|
185
|
+
segments[lastSegment].length > 3 &&
|
|
186
|
+
segments[lastSegment] !== segments[lastSegment - 1] && (
|
|
187
|
+
<Items key={`${path || index}-${uuid}`}>
|
|
188
|
+
<span aria-hidden="true">{spacer}</span>
|
|
189
|
+
<a
|
|
190
|
+
href="#"
|
|
191
|
+
aria-current="page"
|
|
192
|
+
aria-label={
|
|
193
|
+
name.length > truncateLength ? name : undefined
|
|
194
|
+
}
|
|
195
|
+
>
|
|
196
|
+
{Truncate(decodeURIComponent(name), truncateLength)}
|
|
197
|
+
</a>
|
|
198
|
+
</Items>
|
|
199
|
+
)}
|
|
200
|
+
</>
|
|
201
|
+
) : (
|
|
202
|
+
<Items key={`${currentSegment?.name}-${uuid}`}>
|
|
203
|
+
<span aria-hidden="true">{spacer}</span>
|
|
204
|
+
<span>
|
|
205
|
+
<Link
|
|
206
|
+
href={url}
|
|
207
|
+
aria-label={
|
|
208
|
+
name.length > truncateLength ? name : undefined
|
|
209
|
+
}
|
|
210
|
+
{...linkProps}
|
|
211
|
+
>
|
|
212
|
+
{Truncate(decodeURIComponent(name), truncateLength)}
|
|
213
|
+
</Link>
|
|
214
|
+
</span>
|
|
215
|
+
</Items>
|
|
216
|
+
);
|
|
217
|
+
})
|
|
218
|
+
: null}
|
|
214
219
|
</>
|
|
215
220
|
</Nav>
|
|
216
221
|
) : (
|
|
217
222
|
<></>
|
|
218
|
-
)
|
|
219
|
-
}
|
|
223
|
+
);
|
|
224
|
+
};
|
|
220
225
|
|
|
221
|
-
export default Breadcrumb
|
|
226
|
+
export default Breadcrumb;
|
|
222
227
|
|
|
223
|
-
Breadcrumb.displayName =
|
|
224
|
-
Breadcrumb.Nav = Nav
|
|
225
|
-
Breadcrumb.List = List
|
|
226
|
-
Breadcrumb.Items = Items
|
|
228
|
+
Breadcrumb.displayName = "BreadCrumb";
|
|
229
|
+
Breadcrumb.Nav = Nav;
|
|
230
|
+
Breadcrumb.List = List;
|
|
231
|
+
Breadcrumb.Items = Items;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { Meta } from "@storybook/blocks";
|
|
2
|
+
|
|
3
|
+
<Meta title="FP.REACT Components/Buttons/Readme" />
|
|
4
|
+
|
|
5
|
+
# Button
|
|
6
|
+
|
|
7
|
+
## Summary
|
|
8
|
+
|
|
9
|
+
The `Button` component is a versatile and customizable button element that
|
|
10
|
+
supports various types and styles. It is designed to be reusable and accessible.
|
|
11
|
+
|
|
12
|
+
## Features
|
|
13
|
+
|
|
14
|
+
- Supports `button`, `submit`, and `reset` types
|
|
15
|
+
- Customizable styles and classes
|
|
16
|
+
- Handles various pointer events
|
|
17
|
+
- Accessible with `aria-disabled` attribute
|
|
18
|
+
|
|
19
|
+
## Props
|
|
20
|
+
|
|
21
|
+
| Name | Type | Default | Description |
|
|
22
|
+
| ---------------- | ---------------------------------------------------- | ---------- | -------------------------------------- |
|
|
23
|
+
| `type` | `'button' \| 'submit' \| 'reset'` | `'button'` | The button type |
|
|
24
|
+
| `styles` | `React.CSSProperties` | - | Inline styles for the button |
|
|
25
|
+
| `disabled` | `boolean` | `false` | Disables the button when set to `true` |
|
|
26
|
+
| `classes` | `string` | - | Additional CSS classes for the button |
|
|
27
|
+
| `onPointerDown` | `(e: React.PointerEvent<HTMLButtonElement>) => void` | - | Callback for pointer down event |
|
|
28
|
+
| `onPointerOver` | `(e: React.PointerEvent<HTMLButtonElement>) => void` | - | Callback for pointer over event |
|
|
29
|
+
| `onPointerLeave` | `(e: React.PointerEvent<HTMLButtonElement>) => void` | - | Callback for pointer leave event |
|
|
30
|
+
| `onClick` | `(e: React.MouseEvent<HTMLButtonElement>) => void` | - | Callback for click event |
|
|
31
|
+
|
|
32
|
+
## Technical Details
|
|
33
|
+
|
|
34
|
+
The `Button` component uses the `UI` component from the `#components/ui`
|
|
35
|
+
library. It handles various pointer events and ensures accessibility by using
|
|
36
|
+
the `aria-disabled` attribute.
|
|
37
|
+
|
|
38
|
+
## Usage Example
|
|
39
|
+
|
|
40
|
+
### Basic Usage
|
|
41
|
+
|
|
42
|
+
```tsx
|
|
43
|
+
import React from "react";
|
|
44
|
+
import Button from "#components/buttons/button";
|
|
45
|
+
|
|
46
|
+
const handleClick = () => {
|
|
47
|
+
console.log("Button clicked");
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const BasicButton = () => (
|
|
51
|
+
<Button type="button" onClick={handleClick}>
|
|
52
|
+
Click Me
|
|
53
|
+
</Button>
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
export default BasicButton;
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Advanced Usage
|
|
60
|
+
|
|
61
|
+
```tsx
|
|
62
|
+
import React from "react";
|
|
63
|
+
import Button from "#components/buttons/button";
|
|
64
|
+
|
|
65
|
+
const handlePointerDown = (e: React.PointerEvent<HTMLButtonElement>) => {
|
|
66
|
+
console.log("Pointer down", e);
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const handlePointerOver = (e: React.PointerEvent<HTMLButtonElement>) => {
|
|
70
|
+
console.log("Pointer over", e);
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const handlePointerLeave = (e: React.PointerEvent<HTMLButtonElement>) => {
|
|
74
|
+
console.log("Pointer leave", e);
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
const AdvancedButton = () => (
|
|
78
|
+
<Button
|
|
79
|
+
type="submit"
|
|
80
|
+
styles={{ backgroundColor: "blue", color: "white" }}
|
|
81
|
+
onPointerDown={handlePointerDown}
|
|
82
|
+
onPointerOver={handlePointerOver}
|
|
83
|
+
onPointerLeave={handlePointerLeave}
|
|
84
|
+
>
|
|
85
|
+
Submit
|
|
86
|
+
</Button>
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
export default AdvancedButton;
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Additional Notes
|
|
93
|
+
|
|
94
|
+
- Ensure the `type` prop is set to one of `'button'`, `'submit'`, or `'reset'`.
|
|
95
|
+
- The `styles` prop can be used to apply inline styles to the button.
|
|
96
|
+
- The `disabled` prop can be used to disable the button.
|
|
@@ -2,18 +2,20 @@ button {
|
|
|
2
2
|
--btn-xs: 0.6rem;
|
|
3
3
|
--btn-sm: 0.7rem;
|
|
4
4
|
--btn-md: 0.85rem;
|
|
5
|
-
--btn-lg:
|
|
5
|
+
--btn-lg: 1.3125rem;
|
|
6
6
|
--btn-pill: 100rem;
|
|
7
7
|
--btn-height: 2.5rem;
|
|
8
8
|
--fs: 0.95rem;
|
|
9
9
|
--btn-fs: 0.9375rem;
|
|
10
10
|
--btn-bg: lightgray;
|
|
11
11
|
--btn-width: max-content;
|
|
12
|
+
--btn-calc-height: var(--btn-height, calc(40rem / 16));
|
|
12
13
|
|
|
13
14
|
font-size: var(--btn-fs);
|
|
14
15
|
font-weight: var(--btn-fw, 500);
|
|
15
16
|
height: var(--btn-height, calc(40rem / 16));
|
|
16
|
-
|
|
17
|
+
max-height: var(--btn-calc-height);
|
|
18
|
+
min-height: 1.5rem;
|
|
17
19
|
place-items: var(--btn-place, center);
|
|
18
20
|
padding-inline: var(--btn-px, calc(var(--btn-fs) + 1.1%));
|
|
19
21
|
padding-block: var(--btn-py, calc(var(--btn-fs) + 0.75%));
|