@fpkit/acss 0.5.8 → 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/index.cjs +2 -2
- package/libs/index.cjs.map +1 -1
- 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/badge/badge.tsx +19 -11
- package/src/components/breadcrumbs/README.mdx +91 -0
- package/src/components/breadcrumbs/breadcrumb.tsx +92 -87
- package/src/components/cards/README.mdx +133 -0
- package/src/components/details/details.tsx +18 -11
- 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/components/cards/README.md +0 -80
|
@@ -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,133 @@
|
|
|
1
|
+
import { Meta } from "@storybook/blocks";
|
|
2
|
+
|
|
3
|
+
<Meta title="FP.REACT Components/Card/Readme" />
|
|
4
|
+
|
|
5
|
+
# Card Component
|
|
6
|
+
|
|
7
|
+
The Card component is a versatile and reusable React component for creating
|
|
8
|
+
card-like UI elements. It's part of the FPKit React component library.
|
|
9
|
+
|
|
10
|
+
## Usage
|
|
11
|
+
|
|
12
|
+
```tsx
|
|
13
|
+
import Card from "@fpkit/cards";
|
|
14
|
+
|
|
15
|
+
<Card elm="div">
|
|
16
|
+
<Card.Title>Card Title</Card.Title>
|
|
17
|
+
<Card.Content
|
|
18
|
+
className="custom-card-content"
|
|
19
|
+
styles={{ color: "blue", padding: "1rem" }}
|
|
20
|
+
>
|
|
21
|
+
This is the content of the card.
|
|
22
|
+
</Card.Content>
|
|
23
|
+
</Card>;
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Components
|
|
27
|
+
|
|
28
|
+
### Card
|
|
29
|
+
|
|
30
|
+
The main container component for the card.
|
|
31
|
+
|
|
32
|
+
#### Props
|
|
33
|
+
|
|
34
|
+
- `elm?: 'div' | 'aside' | 'section' | 'article'` - HTML element to render as
|
|
35
|
+
(default: 'div')
|
|
36
|
+
- `title?: React.ReactNode` - Card title
|
|
37
|
+
- `footer?: React.ReactNode` - Card footer
|
|
38
|
+
- `styles?: React.CSSProperties` - Inline styles
|
|
39
|
+
- `classes?: string` - Additional CSS classes
|
|
40
|
+
- `id?: string` - Unique ID for the card
|
|
41
|
+
|
|
42
|
+
All other props, such as `aria-*` attributes, `data-*` attributes, and event
|
|
43
|
+
handlers (e.g., `onClick`, `onMouseEnter`), are passed through to the underlying
|
|
44
|
+
UI component. This allows you to customize the behavior and accessibility of the
|
|
45
|
+
Card component as needed.
|
|
46
|
+
|
|
47
|
+
### Card.Title
|
|
48
|
+
|
|
49
|
+
A sub-component for rendering the card's title.
|
|
50
|
+
|
|
51
|
+
#### Props
|
|
52
|
+
|
|
53
|
+
- `as?: React.ElementType` - HTML element to render as (default: 'h3')
|
|
54
|
+
- `className?: string` - Additional CSS classes
|
|
55
|
+
- `styles?: React.CSSProperties` - Inline styles
|
|
56
|
+
|
|
57
|
+
#### Example
|
|
58
|
+
|
|
59
|
+
### Card.Content
|
|
60
|
+
|
|
61
|
+
A sub-component for rendering the card's main content.
|
|
62
|
+
|
|
63
|
+
#### Props
|
|
64
|
+
|
|
65
|
+
- `className?: string` - Additional CSS classes
|
|
66
|
+
- `styles?: React.CSSProperties` - Inline styles
|
|
67
|
+
|
|
68
|
+
## Styling
|
|
69
|
+
|
|
70
|
+
The component uses CSS classes for styling:
|
|
71
|
+
|
|
72
|
+
- `.card-title` for the title
|
|
73
|
+
- `.card-content` for the content
|
|
74
|
+
|
|
75
|
+
To integrate these styles with CSS Modules or SASS/SCSS:
|
|
76
|
+
|
|
77
|
+
1. Create a CSS Module file (e.g., `Card.module.scss`) or a SASS/SCSS file
|
|
78
|
+
(e.g., `Card.scss`).
|
|
79
|
+
|
|
80
|
+
## Accessibility
|
|
81
|
+
|
|
82
|
+
The Card component is designed with accessibility in mind:
|
|
83
|
+
|
|
84
|
+
- It uses semantic HTML elements (`div`, `aside`, `section`, or `article`) for
|
|
85
|
+
the main container.
|
|
86
|
+
- The Title component defaults to using an `h3` element, which can be changed if
|
|
87
|
+
needed.
|
|
88
|
+
- The Content component uses an `article` element for semantic structure.
|
|
89
|
+
|
|
90
|
+
### Example with ARIA Attributes
|
|
91
|
+
|
|
92
|
+
```tsx
|
|
93
|
+
<Card classes={styles.card}>
|
|
94
|
+
<Card.Title className={styles.cardTitle}>Card Title</Card.Title>
|
|
95
|
+
<Card.Content className={styles.cardContent}>
|
|
96
|
+
This is the content of the card.
|
|
97
|
+
</Card.Content>
|
|
98
|
+
</Card>
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
You can override these classes or provide additional styling through the
|
|
102
|
+
`className` and `styles` props.
|
|
103
|
+
|
|
104
|
+
## Accessibility
|
|
105
|
+
|
|
106
|
+
The Card component is designed with accessibility in mind:
|
|
107
|
+
|
|
108
|
+
- It uses semantic HTML elements (`div`, `aside`, `section`, or `article`) for
|
|
109
|
+
the main container.
|
|
110
|
+
- The Title component defaults to using an `h3` element, which can be changed if
|
|
111
|
+
needed.
|
|
112
|
+
- The Content component uses an `article` element for semantic structure.
|
|
113
|
+
|
|
114
|
+
## TypeScript
|
|
115
|
+
|
|
116
|
+
This component is written in TypeScript and provides type definitions for all
|
|
117
|
+
props and sub-components.
|
|
118
|
+
|
|
119
|
+
## Contributing
|
|
120
|
+
|
|
121
|
+
When contributing to this component, please follow the established code style
|
|
122
|
+
and conventions. Ensure all changes are well-tested using **Vitest** and
|
|
123
|
+
documented. Additionally, use **ESLint** and **Prettier** for code formatting
|
|
124
|
+
and linting to maintain consistency.
|
|
125
|
+
|
|
126
|
+
This README provides an overview of the Card component, its usage, available
|
|
127
|
+
props, styling information, and accessibility considerations. It also mentions
|
|
128
|
+
that the component is written in TypeScript and provides guidance for
|
|
129
|
+
contributors.
|
|
130
|
+
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
```
|
|
@@ -15,18 +15,25 @@ type DetailsProps = {
|
|
|
15
15
|
} & React.ComponentProps<"details"> &
|
|
16
16
|
Partial<React.ComponentProps<typeof UI>>;
|
|
17
17
|
|
|
18
|
-
/**
|
|
19
|
-
*
|
|
18
|
+
/**
|
|
19
|
+
* A React component that renders a details element with a summary and content.
|
|
20
20
|
*
|
|
21
|
-
* @param
|
|
22
|
-
* @param
|
|
23
|
-
* @param
|
|
24
|
-
* @param
|
|
25
|
-
* @param
|
|
26
|
-
* @param
|
|
27
|
-
* @param
|
|
28
|
-
* @param
|
|
29
|
-
* @param
|
|
21
|
+
* @param summary - The summary text shown for the details.
|
|
22
|
+
* @param ariaLabel - The aria-label element for accessibility.
|
|
23
|
+
* @param icon - An optional icon to display in the summary.
|
|
24
|
+
* @param styles - Optional styles to apply to the details element.
|
|
25
|
+
* @param classes - Optional CSS classes to apply to the details element.
|
|
26
|
+
* @param name - An optional name for the details element.
|
|
27
|
+
* @param open - Whether the details element should be initially open.
|
|
28
|
+
* @param onPointerDown - A callback function to be called when the summary is clicked.
|
|
29
|
+
* @param onToggle - A callback function to be called when the details element is toggled.
|
|
30
|
+
* @param children - The content to be displayed inside the details element.
|
|
31
|
+
* @param ref - A ref to the details element.
|
|
32
|
+
* @param props - Additional props to be passed to the details element.
|
|
33
|
+
* @example
|
|
34
|
+
* <Details summary="Details" ariaLabel="Details">
|
|
35
|
+
* <p>Details content</p>
|
|
36
|
+
* </Details>
|
|
30
37
|
*/
|
|
31
38
|
export const Details = ({
|
|
32
39
|
summary,
|
|
@@ -1,25 +1,20 @@
|
|
|
1
|
-
import React from
|
|
2
|
-
import FP from
|
|
1
|
+
import React from "react";
|
|
2
|
+
import FP from "../fp";
|
|
3
3
|
|
|
4
4
|
export type InputProps = {
|
|
5
5
|
/**
|
|
6
6
|
* The type of the input.
|
|
7
7
|
*/
|
|
8
|
-
type?:
|
|
8
|
+
type?: "text" | "password" | "email" | "number" | "tel" | "url" | "search";
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Set the element as disabled
|
|
12
12
|
*/
|
|
13
|
-
isDisabled?: boolean
|
|
14
|
-
} & React.ComponentProps<typeof FP
|
|
13
|
+
isDisabled?: boolean;
|
|
14
|
+
} & React.ComponentProps<typeof FP>;
|
|
15
15
|
|
|
16
|
-
/**
|
|
17
|
-
* Input component that renders an HTML input element.
|
|
18
|
-
* @param {InputProps} props - The input component props.
|
|
19
|
-
* @returns {JSX.Element} - The input component.
|
|
20
|
-
*/
|
|
21
16
|
export const Input = ({
|
|
22
|
-
type =
|
|
17
|
+
type = "text",
|
|
23
18
|
name,
|
|
24
19
|
value,
|
|
25
20
|
placeholder,
|
|
@@ -38,29 +33,29 @@ export const Input = ({
|
|
|
38
33
|
}: InputProps): JSX.Element => {
|
|
39
34
|
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
40
35
|
if (onChange && !disabled) {
|
|
41
|
-
onChange?.(e)
|
|
36
|
+
onChange?.(e);
|
|
42
37
|
}
|
|
43
|
-
}
|
|
38
|
+
};
|
|
44
39
|
|
|
45
40
|
const handleBlur = (e: React.FocusEvent<HTMLInputElement>) => {
|
|
46
41
|
if (onBlur && !disabled) {
|
|
47
|
-
onBlur?.(e)
|
|
42
|
+
onBlur?.(e);
|
|
48
43
|
}
|
|
49
|
-
}
|
|
44
|
+
};
|
|
50
45
|
|
|
51
46
|
const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
|
|
52
47
|
if (onPointerDown && !disabled) {
|
|
53
|
-
e.preventDefault()
|
|
54
|
-
onPointerDown?.(e)
|
|
48
|
+
e.preventDefault();
|
|
49
|
+
onPointerDown?.(e);
|
|
55
50
|
}
|
|
56
|
-
}
|
|
51
|
+
};
|
|
57
52
|
|
|
58
53
|
return (
|
|
59
54
|
<FP
|
|
60
55
|
as="input"
|
|
61
56
|
id={id}
|
|
62
57
|
type={type}
|
|
63
|
-
placeholder={placeholder || `${required ?
|
|
58
|
+
placeholder={placeholder || `${required ? "*" : ""} ${type} input `}
|
|
64
59
|
className={classes}
|
|
65
60
|
styles={styles}
|
|
66
61
|
onChange={handleChange}
|
|
@@ -77,8 +72,7 @@ export const Input = ({
|
|
|
77
72
|
readOnly={readonly}
|
|
78
73
|
{...props}
|
|
79
74
|
/>
|
|
80
|
-
)
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
export default Input
|
|
75
|
+
);
|
|
76
|
+
};
|
|
77
|
+
Input.displayName = "Input";
|
|
78
|
+
export default Input;
|
|
@@ -1,15 +1,27 @@
|
|
|
1
|
-
import React from
|
|
2
|
-
import UI from
|
|
3
|
-
import { type } from 'os'
|
|
1
|
+
import React from "react";
|
|
2
|
+
import UI from "#components/ui";
|
|
4
3
|
|
|
5
4
|
export type TitleProps = {
|
|
6
|
-
children: React.ReactNode
|
|
7
|
-
type:
|
|
8
|
-
ui?: string
|
|
9
|
-
} & React.ComponentProps<typeof UI
|
|
5
|
+
children: React.ReactNode;
|
|
6
|
+
type: "h1" | "h2" | "h3" | "h4" | "h5" | "h6";
|
|
7
|
+
ui?: string;
|
|
8
|
+
} & React.ComponentProps<typeof UI>;
|
|
10
9
|
|
|
10
|
+
/**
|
|
11
|
+
* A flexible heading component that renders different heading levels.
|
|
12
|
+
*
|
|
13
|
+
* @component
|
|
14
|
+
* @param {'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'} [props.type='h3'] - The heading level to render
|
|
15
|
+
* @param {string} [props.id] - Optional ID attribute for the heading
|
|
16
|
+
* @param {React.CSSProperties} [props.styles] - Custom styles to apply to the heading
|
|
17
|
+
* @param {string} [props.ui] - Custom UI modifier to be added as a data attribute
|
|
18
|
+
* @param {ReactNode} props.children - The content to be rendered within the heading
|
|
19
|
+
* @param {Object} [props] - Additional props to be spread onto the heading element
|
|
20
|
+
*
|
|
21
|
+
* @returns {JSX.Element} A heading element of the specified type
|
|
22
|
+
*/
|
|
11
23
|
const Heading = ({
|
|
12
|
-
type =
|
|
24
|
+
type = "h3",
|
|
13
25
|
id,
|
|
14
26
|
styles,
|
|
15
27
|
ui,
|
|
@@ -20,8 +32,8 @@ const Heading = ({
|
|
|
20
32
|
<UI as={type} id={id} styles={styles} data-ui={ui} {...props}>
|
|
21
33
|
{children}
|
|
22
34
|
</UI>
|
|
23
|
-
)
|
|
24
|
-
}
|
|
35
|
+
);
|
|
36
|
+
};
|
|
25
37
|
|
|
26
|
-
export default Heading
|
|
27
|
-
Heading.displayName =
|
|
38
|
+
export default Heading;
|
|
39
|
+
Heading.displayName = "Heading";
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { Meta } from "@storybook/blocks";
|
|
2
|
+
|
|
3
|
+
<Meta title="FP.REACT Components/Text/Readme" />
|
|
4
|
+
|
|
5
|
+
# Text Component
|
|
6
|
+
|
|
7
|
+
## Summary
|
|
8
|
+
|
|
9
|
+
The `Text` component is a flexible wrapper for rendering various text elements
|
|
10
|
+
such as paragraphs, spans, and other inline or block-level elements. It supports
|
|
11
|
+
customization through props like `elm`, `text`, and additional styles or
|
|
12
|
+
classes.
|
|
13
|
+
|
|
14
|
+
The `Title` component is a specialized version of `Text` for rendering HTML
|
|
15
|
+
headings (`h1` to `h6`).
|
|
16
|
+
|
|
17
|
+
## Features
|
|
18
|
+
|
|
19
|
+
- Render any valid HTML text element.
|
|
20
|
+
- Pass text content directly or use children for nested elements.
|
|
21
|
+
- Fully customizable with styles and classes.
|
|
22
|
+
- Supports accessibility with `id` and other attributes.
|
|
23
|
+
|
|
24
|
+
## Props
|
|
25
|
+
|
|
26
|
+
### Text Props
|
|
27
|
+
|
|
28
|
+
| Name | Type | Default | Description |
|
|
29
|
+
| ---------- | --------------------- | ------- | ----------------------------------- |
|
|
30
|
+
| `elm` | `TextElements` | `'p'` | The HTML element to render. |
|
|
31
|
+
| `text` | `string` | `''` | Text content to display. |
|
|
32
|
+
| `id` | `string` | `''` | Unique identifier for the element. |
|
|
33
|
+
| `styles` | `React.CSSProperties` | `null` | Inline styles for the element. |
|
|
34
|
+
| `classes` | `string` | `''` | Additional CSS classes for styling. |
|
|
35
|
+
| `children` | `React.ReactNode` | `null` | Nested content inside the element. |
|
|
36
|
+
|
|
37
|
+
### Title Props
|
|
38
|
+
|
|
39
|
+
| Name | Type | Default | Description |
|
|
40
|
+
| ---------- | ---------------------------------------------- | ------- | ----------------------------------- |
|
|
41
|
+
| `elm` | `'h1' \| 'h2' \| 'h3' \| 'h4' \| 'h5' \| 'h6'` | `'h3'` | The HTML heading element to render. |
|
|
42
|
+
| `id` | `string` | `''` | Unique identifier for the element. |
|
|
43
|
+
| `styles` | `React.CSSProperties` | `null` | Inline styles for the element. |
|
|
44
|
+
| `classes` | `string` | `''` | Additional CSS classes for styling. |
|
|
45
|
+
| `children` | `React.ReactNode` | `null` | Nested content inside the element. |
|
|
46
|
+
|
|
47
|
+
## Technical Details
|
|
48
|
+
|
|
49
|
+
- The `Text` component uses the `UI` component internally to render the
|
|
50
|
+
specified element.
|
|
51
|
+
- The `Title` component is a wrapper around `Text` with default settings for
|
|
52
|
+
headings.
|
|
53
|
+
- Both components support additional props inherited from the `UI` component.
|
|
54
|
+
|
|
55
|
+
## Usage Examples
|
|
56
|
+
|
|
57
|
+
### Basic Usage
|
|
58
|
+
|
|
59
|
+
```tsx
|
|
60
|
+
import { Text, Title } from "./text";
|
|
61
|
+
|
|
62
|
+
const App = () => (
|
|
63
|
+
<>
|
|
64
|
+
<Text elm="p" text="This is a paragraph." />
|
|
65
|
+
<Text elm="span" text="This is a span." />
|
|
66
|
+
<Title elm="h1">This is a heading</Title>
|
|
67
|
+
</>
|
|
68
|
+
);
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Advanced Usage
|
|
72
|
+
|
|
73
|
+
```tsx
|
|
74
|
+
import { Text, Title } from "./text";
|
|
75
|
+
|
|
76
|
+
const App = () => (
|
|
77
|
+
<>
|
|
78
|
+
<Text
|
|
79
|
+
elm="blockquote"
|
|
80
|
+
styles={{ fontStyle: "italic", color: "gray" }}
|
|
81
|
+
text="This is a blockquote."
|
|
82
|
+
/>
|
|
83
|
+
<Title
|
|
84
|
+
elm="h2"
|
|
85
|
+
classes="custom-heading"
|
|
86
|
+
styles={{ fontWeight: "bold", fontSize: "2rem" }}
|
|
87
|
+
>
|
|
88
|
+
Custom Heading
|
|
89
|
+
</Title>
|
|
90
|
+
</>
|
|
91
|
+
);
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Additional Notes
|
|
95
|
+
|
|
96
|
+
- Use the `elm` prop to specify the desired HTML element.
|
|
97
|
+
- Combine `styles` and `classes` for advanced styling.
|
|
98
|
+
- Use `children` for nested content when `text` is not sufficient.
|