@fpkit/acss 3.1.0 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/libs/{chunk-2NRIP6RB.cjs → chunk-2C3YLBWP.cjs} +3 -3
- package/libs/{chunk-NWJDAHP6.cjs → chunk-2GJHKWEK.cjs} +3 -3
- package/libs/{chunk-FVROL3V5.js → chunk-2JCDEC32.js} +3 -3
- package/libs/{chunk-IRLFZ3OL.js → chunk-3XJC4XUG.js} +2 -2
- package/libs/{chunk-23ANBDCR.js → chunk-4I5MF54P.js} +3 -3
- package/libs/chunk-4I5MF54P.js.map +1 -0
- package/libs/chunk-5CJPTDK3.cjs +31 -0
- package/libs/chunk-5CJPTDK3.cjs.map +1 -0
- package/libs/{chunk-E4OSROCA.cjs → chunk-5QSNJQVH.cjs} +3 -3
- package/libs/{chunk-O3JIHC5M.cjs → chunk-6BUJZ4DJ.cjs} +3 -3
- package/libs/{chunk-WXBFBWYF.cjs → chunk-AFINOD2L.cjs} +3 -3
- package/libs/{chunk-HRRHPLER.js → chunk-AWZLSWDO.js} +2 -2
- package/libs/chunk-DDSXKOUB.js +7 -0
- package/libs/chunk-DDSXKOUB.js.map +1 -0
- package/libs/{chunk-CWRNJA4P.js → chunk-DIJBIOFE.js} +3 -3
- package/libs/chunk-EJ6KYBFE.cjs +13 -0
- package/libs/chunk-EJ6KYBFE.cjs.map +1 -0
- package/libs/{chunk-GUJSMQ3V.cjs → chunk-EKJYOCLY.cjs} +3 -3
- package/libs/{chunk-X5RKCLDC.cjs → chunk-F64GE6RG.cjs} +4 -4
- package/libs/chunk-FMIM3332.js +8 -0
- package/libs/chunk-FMIM3332.js.map +1 -0
- package/libs/{chunk-5RAWNUVD.js → chunk-IBUTNPTQ.js} +2 -2
- package/libs/chunk-IWP4VJEP.cjs +18 -0
- package/libs/chunk-IWP4VJEP.cjs.map +1 -0
- package/libs/{chunk-ZFJ4U45S.js → chunk-KDMX3FAW.js} +2 -2
- package/libs/{chunk-DYFAUAB7.cjs → chunk-LXODKKA3.cjs} +4 -4
- package/libs/chunk-M7JLT62Q.js +9 -0
- package/libs/chunk-M7JLT62Q.js.map +1 -0
- package/libs/{chunk-IQ76HGVP.js → chunk-MBWI67UT.js} +2 -2
- package/libs/{chunk-O5XAJ7BY.cjs → chunk-NCGVF2QS.cjs} +4 -4
- package/libs/{chunk-W2UIN7EV.cjs → chunk-NPWHQVYB.cjs} +3 -3
- package/libs/{chunk-G55UJ53G.cjs → chunk-NZVSXRTB.cjs} +3 -3
- package/libs/chunk-NZVSXRTB.cjs.map +1 -0
- package/libs/{chunk-43TK2ICH.js → chunk-PMWL5XZ4.js} +3 -3
- package/libs/{chunk-KVKQLRJG.js → chunk-TF3GQKOY.js} +2 -2
- package/libs/chunk-TNEJXNZA.cjs +22 -0
- package/libs/chunk-TNEJXNZA.cjs.map +1 -0
- package/libs/{chunk-IEB64SWY.js → chunk-U5VA34SU.js} +2 -2
- package/libs/chunk-UGMP72J2.js +8 -0
- package/libs/chunk-UGMP72J2.js.map +1 -0
- package/libs/{chunk-MGPWZRBX.cjs → chunk-URBGDUFN.cjs} +6 -6
- package/libs/{chunk-QKHPHMG2.js → chunk-ZF6Y7W57.js} +5 -5
- package/libs/component-props-50e69975.d.ts +66 -0
- package/libs/components/box/box.css +1 -0
- package/libs/components/box/box.css.map +1 -0
- package/libs/components/box/box.min.css +3 -0
- package/libs/components/breadcrumbs/breadcrumb.cjs +6 -6
- package/libs/components/breadcrumbs/breadcrumb.js +3 -3
- package/libs/components/button.cjs +4 -4
- package/libs/components/button.d.cts +10 -3
- package/libs/components/button.d.ts +10 -3
- package/libs/components/button.js +2 -2
- package/libs/components/card.cjs +7 -7
- package/libs/components/card.d.cts +13 -85
- package/libs/components/card.d.ts +13 -85
- package/libs/components/card.js +2 -2
- package/libs/components/cards/card.css +1 -1
- package/libs/components/cards/card.css.map +1 -1
- package/libs/components/cards/card.min.css +2 -2
- package/libs/components/cluster/cluster.css +1 -0
- package/libs/components/cluster/cluster.css.map +1 -0
- package/libs/components/cluster/cluster.min.css +3 -0
- package/libs/components/dialog/dialog.cjs +7 -7
- package/libs/components/dialog/dialog.js +5 -5
- package/libs/components/form/fields.cjs +4 -4
- package/libs/components/form/fields.js +2 -2
- package/libs/components/form/textarea.cjs +4 -4
- package/libs/components/form/textarea.js +2 -2
- package/libs/components/grid/grid.css +1 -0
- package/libs/components/grid/grid.css.map +1 -0
- package/libs/components/grid/grid.min.css +3 -0
- package/libs/components/heading/heading.cjs +3 -3
- package/libs/components/heading/heading.js +2 -2
- package/libs/components/icons/icon.cjs +4 -4
- package/libs/components/icons/icon.d.cts +2 -2
- package/libs/components/icons/icon.d.ts +2 -2
- package/libs/components/icons/icon.js +2 -2
- package/libs/components/link/link.cjs +6 -6
- package/libs/components/link/link.js +2 -2
- package/libs/components/list/list.cjs +5 -5
- package/libs/components/list/list.js +2 -2
- package/libs/components/modal.cjs +4 -4
- package/libs/components/modal.d.cts +1 -1
- package/libs/components/modal.d.ts +1 -1
- package/libs/components/modal.js +3 -3
- package/libs/components/nav/nav.cjs +7 -7
- package/libs/components/nav/nav.js +3 -3
- package/libs/components/popover/popover.cjs +4 -4
- package/libs/components/popover/popover.d.cts +1 -1
- package/libs/components/popover/popover.d.ts +1 -1
- package/libs/components/popover/popover.js +1 -1
- package/libs/components/stack/stack.css +1 -0
- package/libs/components/stack/stack.css.map +1 -0
- package/libs/components/stack/stack.min.css +3 -0
- package/libs/components/tables/table.cjs +4 -4
- package/libs/components/tables/table.d.cts +2 -2
- package/libs/components/tables/table.d.ts +2 -2
- package/libs/components/tables/table.js +1 -1
- package/libs/components/text/text.cjs +5 -5
- package/libs/components/text/text.js +2 -2
- package/libs/hooks.cjs +4 -4
- package/libs/hooks.js +3 -3
- package/libs/{icons-287fce3a.d.ts → icons-df8e744f.d.ts} +1 -1
- package/libs/icons.cjs +3 -3
- package/libs/icons.d.cts +2 -2
- package/libs/icons.d.ts +2 -2
- package/libs/icons.js +2 -2
- package/libs/index.cjs +74 -73
- package/libs/index.cjs.map +1 -1
- package/libs/index.css +1 -1
- package/libs/index.css.map +1 -1
- package/libs/index.d.cts +925 -6
- package/libs/index.d.ts +925 -6
- package/libs/index.js +30 -30
- package/libs/index.js.map +1 -1
- package/package.json +2 -2
- package/src/App.tsx +1 -3
- package/src/components/alert/STYLES.mdx +790 -0
- package/src/components/badge/STYLES.mdx +610 -0
- package/src/components/box/README.mdx +401 -0
- package/src/components/box/STYLES.mdx +360 -0
- package/src/components/box/box.scss +245 -0
- package/src/components/box/box.stories.tsx +395 -0
- package/src/components/box/box.test.tsx +425 -0
- package/src/components/box/box.tsx +170 -0
- package/src/components/box/box.types.ts +166 -0
- package/src/components/breadcrumbs/STYLES.mdx +99 -0
- package/src/components/breadcrumbs/bc-item.tsx +0 -1
- package/src/components/buttons/STYLES.mdx +766 -0
- package/src/components/cards/STYLES.mdx +835 -0
- package/src/components/cards/card.scss +29 -21
- package/src/components/cards/card.tsx +13 -3
- package/src/components/cards/card.types.ts +13 -0
- package/src/components/cluster/README.mdx +595 -0
- package/src/components/cluster/STYLES.mdx +626 -0
- package/src/components/cluster/cluster.scss +86 -0
- package/src/components/cluster/cluster.stories.tsx +385 -0
- package/src/components/cluster/cluster.test.tsx +655 -0
- package/src/components/cluster/cluster.tsx +94 -0
- package/src/components/cluster/cluster.types.ts +75 -0
- package/src/components/details/STYLES.mdx +445 -0
- package/src/components/dialog/STYLES.mdx +888 -0
- package/src/components/flexbox/STYLES.mdx +857 -0
- package/src/components/flexbox/flex.stories.tsx +842 -141
- package/src/components/flexbox/flex.types.ts +25 -6
- package/src/components/form/STYLES.mdx +821 -0
- package/src/components/grid/README.mdx +709 -0
- package/src/components/grid/STYLES.mdx +785 -0
- package/src/components/grid/grid.scss +287 -0
- package/src/components/grid/grid.stories.tsx +486 -0
- package/src/components/grid/grid.test.tsx +981 -0
- package/src/components/grid/grid.tsx +222 -0
- package/src/components/grid/grid.types.ts +344 -0
- package/src/components/icons/STYLES.mdx +56 -0
- package/src/components/icons/components/arrow-right.tsx +0 -5
- package/src/components/images/STYLES.mdx +75 -0
- package/src/components/kit.tsx +8 -4
- package/src/components/layout/STYLES.mdx +556 -0
- package/src/components/link/STYLES.mdx +75 -0
- package/src/components/list/STYLES.mdx +631 -0
- package/src/components/nav/STYLES.mdx +460 -0
- package/src/components/popover/popover.tsx +1 -1
- package/src/components/progress/STYLES.mdx +64 -0
- package/src/components/stack/README.mdx +400 -0
- package/src/components/stack/STYLES.mdx +414 -0
- package/src/components/stack/stack.scss +109 -0
- package/src/components/stack/stack.stories.tsx +559 -0
- package/src/components/stack/stack.test.tsx +426 -0
- package/src/components/stack/stack.tsx +141 -0
- package/src/components/stack/stack.types.ts +133 -0
- package/src/components/tables/table-elements.tsx +1 -1
- package/src/components/tables/table.tsx +2 -2
- package/src/components/tag/STYLES.mdx +105 -0
- package/src/components/text-to-speech/STYLES.mdx +80 -0
- package/src/components/text-to-speech/TextToSpeech.tsx +0 -4
- package/src/components/text-to-speech/useTextToSpeech.tsx +2 -6
- package/src/components/ui.tsx +3 -3
- package/src/decorators/instructions.tsx +22 -18
- package/src/hooks/popover/popover.tsx +1 -1
- package/src/index.scss +5 -1
- package/src/index.ts +305 -12
- package/src/sass/GLOBALS-STYLES.md +631 -0
- package/src/sass/_globals.scss +45 -24
- package/src/styles/box/box.css +220 -0
- package/src/styles/box/box.css.map +1 -0
- package/src/styles/cards/card.css +22 -17
- package/src/styles/cards/card.css.map +1 -1
- package/src/styles/cluster/cluster.css +71 -0
- package/src/styles/cluster/cluster.css.map +1 -0
- package/src/styles/grid/grid.css +238 -0
- package/src/styles/grid/grid.css.map +1 -0
- package/src/styles/index.css +667 -49
- package/src/styles/index.css.map +1 -1
- package/src/styles/stack/stack.css +86 -0
- package/src/styles/stack/stack.css.map +1 -0
- package/src/types/component-props.ts +42 -13
- package/src/types/layout-primitives.ts +48 -0
- package/src/types/shared.ts +10 -26
- package/libs/chunk-23ANBDCR.js.map +0 -1
- package/libs/chunk-5QD3DWFI.js +0 -9
- package/libs/chunk-5QD3DWFI.js.map +0 -1
- package/libs/chunk-6WTC4JXH.cjs +0 -31
- package/libs/chunk-6WTC4JXH.cjs.map +0 -1
- package/libs/chunk-ENTCUJ3A.cjs +0 -13
- package/libs/chunk-ENTCUJ3A.cjs.map +0 -1
- package/libs/chunk-G55UJ53G.cjs.map +0 -1
- package/libs/chunk-HHLNOC5T.js +0 -7
- package/libs/chunk-HHLNOC5T.js.map +0 -1
- package/libs/chunk-KK47SYZI.js +0 -8
- package/libs/chunk-KK47SYZI.js.map +0 -1
- package/libs/chunk-US2I5GI7.cjs +0 -22
- package/libs/chunk-US2I5GI7.cjs.map +0 -1
- package/libs/chunk-W5TKWBFC.cjs +0 -18
- package/libs/chunk-W5TKWBFC.cjs.map +0 -1
- package/libs/chunk-Y2PFDELK.js +0 -8
- package/libs/chunk-Y2PFDELK.js.map +0 -1
- package/libs/component-props-67d978a2.d.ts +0 -38
- /package/libs/{chunk-2NRIP6RB.cjs.map → chunk-2C3YLBWP.cjs.map} +0 -0
- /package/libs/{chunk-NWJDAHP6.cjs.map → chunk-2GJHKWEK.cjs.map} +0 -0
- /package/libs/{chunk-FVROL3V5.js.map → chunk-2JCDEC32.js.map} +0 -0
- /package/libs/{chunk-IRLFZ3OL.js.map → chunk-3XJC4XUG.js.map} +0 -0
- /package/libs/{chunk-E4OSROCA.cjs.map → chunk-5QSNJQVH.cjs.map} +0 -0
- /package/libs/{chunk-O3JIHC5M.cjs.map → chunk-6BUJZ4DJ.cjs.map} +0 -0
- /package/libs/{chunk-WXBFBWYF.cjs.map → chunk-AFINOD2L.cjs.map} +0 -0
- /package/libs/{chunk-HRRHPLER.js.map → chunk-AWZLSWDO.js.map} +0 -0
- /package/libs/{chunk-CWRNJA4P.js.map → chunk-DIJBIOFE.js.map} +0 -0
- /package/libs/{chunk-GUJSMQ3V.cjs.map → chunk-EKJYOCLY.cjs.map} +0 -0
- /package/libs/{chunk-X5RKCLDC.cjs.map → chunk-F64GE6RG.cjs.map} +0 -0
- /package/libs/{chunk-5RAWNUVD.js.map → chunk-IBUTNPTQ.js.map} +0 -0
- /package/libs/{chunk-ZFJ4U45S.js.map → chunk-KDMX3FAW.js.map} +0 -0
- /package/libs/{chunk-DYFAUAB7.cjs.map → chunk-LXODKKA3.cjs.map} +0 -0
- /package/libs/{chunk-IQ76HGVP.js.map → chunk-MBWI67UT.js.map} +0 -0
- /package/libs/{chunk-O5XAJ7BY.cjs.map → chunk-NCGVF2QS.cjs.map} +0 -0
- /package/libs/{chunk-W2UIN7EV.cjs.map → chunk-NPWHQVYB.cjs.map} +0 -0
- /package/libs/{chunk-43TK2ICH.js.map → chunk-PMWL5XZ4.js.map} +0 -0
- /package/libs/{chunk-KVKQLRJG.js.map → chunk-TF3GQKOY.js.map} +0 -0
- /package/libs/{chunk-IEB64SWY.js.map → chunk-U5VA34SU.js.map} +0 -0
- /package/libs/{chunk-MGPWZRBX.cjs.map → chunk-URBGDUFN.cjs.map} +0 -0
- /package/libs/{chunk-QKHPHMG2.js.map → chunk-ZF6Y7W57.js.map} +0 -0
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import UI from "../ui";
|
|
3
|
+
import type { ClusterProps } from "./cluster.types";
|
|
4
|
+
|
|
5
|
+
// Re-export types for convenience
|
|
6
|
+
export type { ClusterProps } from "./cluster.types";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Cluster - A wrapping flex layout primitive for inline groups.
|
|
10
|
+
*
|
|
11
|
+
* Cluster provides a flexible layout for inline content that wraps naturally,
|
|
12
|
+
* perfect for tags, badges, button groups, navigation links, or any inline
|
|
13
|
+
* content that needs to flow and wrap responsively.
|
|
14
|
+
*
|
|
15
|
+
* ## Key Features
|
|
16
|
+
* - **Auto-Wrapping**: Items wrap to next line when container is full
|
|
17
|
+
* - **Fluid Spacing**: Responsive gap using CSS clamp()
|
|
18
|
+
* - **Semantic Naming**: Clear intent for inline grouped content
|
|
19
|
+
* - **Polymorphic**: Render as any semantic HTML element
|
|
20
|
+
* - **Type-Safe**: Full TypeScript support
|
|
21
|
+
*
|
|
22
|
+
* ## Use Cases
|
|
23
|
+
* - Tag clouds and keyword lists
|
|
24
|
+
* - Button groups with wrapping
|
|
25
|
+
* - Navigation breadcrumbs
|
|
26
|
+
* - Badge clusters
|
|
27
|
+
* - Inline action groups
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* // Tag cloud
|
|
31
|
+
* <Cluster gap="sm" justify="center">
|
|
32
|
+
* <Tag>React</Tag>
|
|
33
|
+
* <Tag>TypeScript</Tag>
|
|
34
|
+
* <Tag>CSS</Tag>
|
|
35
|
+
* </Cluster>
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* // Button group
|
|
39
|
+
* <Cluster gap="md">
|
|
40
|
+
* <Button>Action 1</Button>
|
|
41
|
+
* <Button>Action 2</Button>
|
|
42
|
+
* <Button>Action 3</Button>
|
|
43
|
+
* </Cluster>
|
|
44
|
+
*
|
|
45
|
+
* @see {@link ClusterProps} for complete props documentation
|
|
46
|
+
*/
|
|
47
|
+
export const Cluster = React.forwardRef<HTMLElement, ClusterProps>(
|
|
48
|
+
(
|
|
49
|
+
{
|
|
50
|
+
gap,
|
|
51
|
+
justify,
|
|
52
|
+
align,
|
|
53
|
+
as = "div",
|
|
54
|
+
className,
|
|
55
|
+
classes,
|
|
56
|
+
children,
|
|
57
|
+
...props
|
|
58
|
+
},
|
|
59
|
+
ref
|
|
60
|
+
) => {
|
|
61
|
+
// Build utility classes array based on props
|
|
62
|
+
const utilityClasses: string[] = ["cluster"];
|
|
63
|
+
|
|
64
|
+
// Gap utilities
|
|
65
|
+
if (gap) {
|
|
66
|
+
utilityClasses.push(`cluster-gap-${gap}`);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Justify utilities
|
|
70
|
+
if (justify) {
|
|
71
|
+
utilityClasses.push(`cluster-justify-${justify}`);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Align utilities
|
|
75
|
+
if (align) {
|
|
76
|
+
utilityClasses.push(`cluster-align-${align}`);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Merge all classes
|
|
80
|
+
const allClasses = [...utilityClasses, className, classes]
|
|
81
|
+
.filter(Boolean)
|
|
82
|
+
.join(" ");
|
|
83
|
+
|
|
84
|
+
return (
|
|
85
|
+
<UI as={as} ref={ref} classes={allClasses} {...props}>
|
|
86
|
+
{children}
|
|
87
|
+
</UI>
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
Cluster.displayName = "Cluster";
|
|
93
|
+
|
|
94
|
+
export default Cluster;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import type { ComponentProps } from "../../types/component-props";
|
|
2
|
+
import type { SpacingScale, ClusterElement } from "../../types/layout-primitives";
|
|
3
|
+
import type React from "react";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Props for the Cluster component - a wrapping flex layout for inline groups.
|
|
7
|
+
*
|
|
8
|
+
* Cluster provides a flexible layout for inline content that needs to wrap naturally,
|
|
9
|
+
* such as tags, badges, button groups, or navigation links. Items wrap to the next line
|
|
10
|
+
* when they exceed the container width.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* // Tag cloud
|
|
14
|
+
* <Cluster gap="sm">
|
|
15
|
+
* <Tag>React</Tag>
|
|
16
|
+
* <Tag>TypeScript</Tag>
|
|
17
|
+
* <Tag>CSS</Tag>
|
|
18
|
+
* </Cluster>
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* // Button group
|
|
22
|
+
* <Cluster gap="md" justify="center">
|
|
23
|
+
* <Button>Action 1</Button>
|
|
24
|
+
* <Button>Action 2</Button>
|
|
25
|
+
* <Button>Action 3</Button>
|
|
26
|
+
* </Cluster>
|
|
27
|
+
*/
|
|
28
|
+
export interface ClusterProps
|
|
29
|
+
extends Partial<ComponentProps>,
|
|
30
|
+
Omit<React.HTMLAttributes<HTMLElement>, "className"> {
|
|
31
|
+
/**
|
|
32
|
+
* Gap between items.
|
|
33
|
+
* Uses unified spacing scale: '0' | 'xs' | 'sm' | 'md' | 'lg' | 'xl'
|
|
34
|
+
* @default 'sm'
|
|
35
|
+
*/
|
|
36
|
+
gap?: SpacingScale;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Horizontal alignment of items.
|
|
40
|
+
* - 'start': Items at start (left in LTR)
|
|
41
|
+
* - 'center': Items centered
|
|
42
|
+
* - 'end': Items at end (right in LTR)
|
|
43
|
+
* - 'between': Space evenly between items
|
|
44
|
+
* @example
|
|
45
|
+
* <Cluster justify="center">Centered items</Cluster>
|
|
46
|
+
*/
|
|
47
|
+
justify?: "start" | "center" | "end" | "between";
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Vertical alignment of items.
|
|
51
|
+
* - 'start': Align to top
|
|
52
|
+
* - 'center': Vertically centered
|
|
53
|
+
* - 'end': Align to bottom
|
|
54
|
+
* - 'baseline': Align baselines (good for text)
|
|
55
|
+
* @example
|
|
56
|
+
* <Cluster align="baseline">Baseline-aligned text</Cluster>
|
|
57
|
+
*/
|
|
58
|
+
align?: "start" | "center" | "end" | "baseline";
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Polymorphic element type to render.
|
|
62
|
+
* @default 'div'
|
|
63
|
+
*/
|
|
64
|
+
as?: ClusterElement;
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Additional CSS classes to apply.
|
|
68
|
+
*/
|
|
69
|
+
className?: string;
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Children elements to render inside the Cluster.
|
|
73
|
+
*/
|
|
74
|
+
children?: React.ReactNode;
|
|
75
|
+
}
|
|
@@ -0,0 +1,445 @@
|
|
|
1
|
+
import { Meta } from "@storybook/addon-docs/blocks";
|
|
2
|
+
|
|
3
|
+
<Meta title="FP.REACT Components/Details/Styles" />
|
|
4
|
+
|
|
5
|
+
# Details Styles
|
|
6
|
+
|
|
7
|
+
Collapsible disclosure widget styling using native HTML5 `<details>` and
|
|
8
|
+
`<summary>` elements with smooth animations and CSS custom properties.
|
|
9
|
+
|
|
10
|
+
## Overview
|
|
11
|
+
|
|
12
|
+
The fpkit details styling system provides accordion-style collapsible content
|
|
13
|
+
using semantic `<details>` elements. Features smooth height animations, focus
|
|
14
|
+
indicators, and automatic styling for adjacent details elements.
|
|
15
|
+
|
|
16
|
+
### Key Features
|
|
17
|
+
|
|
18
|
+
- **Native HTML5** - Uses `<details>` and `<summary>` elements
|
|
19
|
+
- **Smooth animations** - Height transitions using modern CSS
|
|
20
|
+
- **Accordion styling** - Automatic grouping for adjacent details
|
|
21
|
+
- **Focus indicators** - Keyboard accessibility
|
|
22
|
+
- **Hidden markers** - Custom styling without default disclosure triangle
|
|
23
|
+
- **CSS custom properties** - Full theming control
|
|
24
|
+
- **Rem-based sizing** - All measurements use rem units (1rem = 16px)
|
|
25
|
+
- **Modern CSS** - Uses `interpolate-size` and `@starting-style`
|
|
26
|
+
|
|
27
|
+
## CSS Custom Properties
|
|
28
|
+
|
|
29
|
+
### Details Properties
|
|
30
|
+
|
|
31
|
+
```css
|
|
32
|
+
details {
|
|
33
|
+
/* Layout */
|
|
34
|
+
--details-display: flex;
|
|
35
|
+
--details-direction: column;
|
|
36
|
+
--details-justify: flex-start;
|
|
37
|
+
--details-gap: 0;
|
|
38
|
+
--details-width: 100%;
|
|
39
|
+
--details-height: max-content;
|
|
40
|
+
|
|
41
|
+
/* Borders */
|
|
42
|
+
--details-border: 0.0625rem solid #dfdfdf; /* 1px */
|
|
43
|
+
--details-radius: 0;
|
|
44
|
+
|
|
45
|
+
/* Spacing */
|
|
46
|
+
--details-padding-inline: 1.5rem; /* 24px */
|
|
47
|
+
--details-padding-block: 1rem; /* 16px */
|
|
48
|
+
|
|
49
|
+
/* Animation */
|
|
50
|
+
--summary-transitions: all 0.75s ease-in-out;
|
|
51
|
+
|
|
52
|
+
/* Height Constraints */
|
|
53
|
+
--details-max-height-closed: 6.25rem; /* 100px */
|
|
54
|
+
--details-max-height-open: 50rem; /* 800px */
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Summary Properties
|
|
59
|
+
|
|
60
|
+
```css
|
|
61
|
+
details {
|
|
62
|
+
/* Summary Layout */
|
|
63
|
+
--summary-display: flex;
|
|
64
|
+
--summary-justify: flex-start;
|
|
65
|
+
--summary-align: center;
|
|
66
|
+
--summary-gap: 0.5rem; /* 8px */
|
|
67
|
+
|
|
68
|
+
/* Summary Interaction */
|
|
69
|
+
--summary-cursor: pointer;
|
|
70
|
+
|
|
71
|
+
/* Summary Spacing */
|
|
72
|
+
--summary-padding-inline: var(--details-padding-inline);
|
|
73
|
+
--summary-padding-block: var(--details-padding-block);
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Basic Structure
|
|
78
|
+
|
|
79
|
+
### Simple Details
|
|
80
|
+
|
|
81
|
+
```html
|
|
82
|
+
<details>
|
|
83
|
+
<summary>Click to expand</summary>
|
|
84
|
+
<section>
|
|
85
|
+
<p>Hidden content that appears when expanded.</p>
|
|
86
|
+
</section>
|
|
87
|
+
</details>
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
**CSS Applied:**
|
|
91
|
+
|
|
92
|
+
```css
|
|
93
|
+
details {
|
|
94
|
+
display: flex;
|
|
95
|
+
flex-direction: column;
|
|
96
|
+
width: 100%;
|
|
97
|
+
border: 0.0625rem solid #dfdfdf;
|
|
98
|
+
border-left: none;
|
|
99
|
+
border-right: none;
|
|
100
|
+
max-height: 6.25rem; /* Closed state */
|
|
101
|
+
overflow: clip;
|
|
102
|
+
transition: all 0.75s ease-in-out;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
details::marker {
|
|
106
|
+
content: none; /* Hide default triangle */
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
summary {
|
|
110
|
+
display: flex;
|
|
111
|
+
justify-content: flex-start;
|
|
112
|
+
align-items: center;
|
|
113
|
+
padding: 1rem 1.5rem;
|
|
114
|
+
gap: 0.5rem;
|
|
115
|
+
list-style: none;
|
|
116
|
+
cursor: pointer;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
details[open] {
|
|
120
|
+
max-height: max-content;
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Accordion Pattern
|
|
125
|
+
|
|
126
|
+
### Multiple Details (Accordion)
|
|
127
|
+
|
|
128
|
+
Adjacent details elements automatically style as accordion:
|
|
129
|
+
|
|
130
|
+
```html
|
|
131
|
+
<details>
|
|
132
|
+
<summary>Section 1</summary>
|
|
133
|
+
<section>
|
|
134
|
+
<p>Content for section 1</p>
|
|
135
|
+
</section>
|
|
136
|
+
</details>
|
|
137
|
+
|
|
138
|
+
<details>
|
|
139
|
+
<summary>Section 2</summary>
|
|
140
|
+
<section>
|
|
141
|
+
<p>Content for section 2</p>
|
|
142
|
+
</section>
|
|
143
|
+
</details>
|
|
144
|
+
|
|
145
|
+
<details>
|
|
146
|
+
<summary>Section 3</summary>
|
|
147
|
+
<section>
|
|
148
|
+
<p>Content for section 3</p>
|
|
149
|
+
</section>
|
|
150
|
+
</details>
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
**CSS:**
|
|
154
|
+
|
|
155
|
+
```css
|
|
156
|
+
/* First details */
|
|
157
|
+
details:first-of-type {
|
|
158
|
+
border-radius: var(--details-radius) var(--details-radius) 0 0;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/* Middle details */
|
|
162
|
+
details + details {
|
|
163
|
+
border-radius: 0;
|
|
164
|
+
border-top: none; /* Remove double borders */
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/* Last details */
|
|
168
|
+
details:last-of-type {
|
|
169
|
+
border-radius: 0 0 var(--details-radius) var(--details-radius);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/* Single details */
|
|
173
|
+
details:only-of-type {
|
|
174
|
+
border-radius: var(--details-radius);
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## States
|
|
179
|
+
|
|
180
|
+
### Closed State (Default)
|
|
181
|
+
|
|
182
|
+
```html
|
|
183
|
+
<details>
|
|
184
|
+
<summary>Closed (default)</summary>
|
|
185
|
+
<section>
|
|
186
|
+
<p>Content hidden</p>
|
|
187
|
+
</section>
|
|
188
|
+
</details>
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### Open State
|
|
192
|
+
|
|
193
|
+
```html
|
|
194
|
+
<details open>
|
|
195
|
+
<summary>Open by default</summary>
|
|
196
|
+
<section>
|
|
197
|
+
<p>Content visible</p>
|
|
198
|
+
</section>
|
|
199
|
+
</details>
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
**CSS:**
|
|
203
|
+
|
|
204
|
+
```css
|
|
205
|
+
details[open] {
|
|
206
|
+
max-height: max-content;
|
|
207
|
+
transition: all 0.75s ease-in-out;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
details[open] > summary {
|
|
211
|
+
border-bottom: 0.0625rem solid #dfdfdf;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
details[open] > section {
|
|
215
|
+
max-height: 50rem;
|
|
216
|
+
}
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### Focus State
|
|
220
|
+
|
|
221
|
+
```css
|
|
222
|
+
summary:focus-within {
|
|
223
|
+
outline: none;
|
|
224
|
+
border-bottom: solid 2px currentColor;
|
|
225
|
+
background-color: whitesmoke;
|
|
226
|
+
}
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
## Animation Features
|
|
230
|
+
|
|
231
|
+
### Height Animation
|
|
232
|
+
|
|
233
|
+
Uses modern CSS `interpolate-size` for smooth height transitions:
|
|
234
|
+
|
|
235
|
+
```css
|
|
236
|
+
details {
|
|
237
|
+
interpolate-size: allow-keywords; /* Enables height animation */
|
|
238
|
+
transition: all 0.75s ease-in-out;
|
|
239
|
+
}
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### Starting Style
|
|
243
|
+
|
|
244
|
+
Initial state for animations:
|
|
245
|
+
|
|
246
|
+
```css
|
|
247
|
+
@starting-style {
|
|
248
|
+
details {
|
|
249
|
+
max-height: 0;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
### Browser Support Check
|
|
255
|
+
|
|
256
|
+
```css
|
|
257
|
+
@supports (transition-behavior: allow-discrete) {
|
|
258
|
+
@starting-style {
|
|
259
|
+
details {
|
|
260
|
+
max-height: 0;
|
|
261
|
+
transition: all 0.75s ease-in-out;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
## Real-World Examples
|
|
268
|
+
|
|
269
|
+
### FAQ Section
|
|
270
|
+
|
|
271
|
+
```html
|
|
272
|
+
<h2>Frequently Asked Questions</h2>
|
|
273
|
+
|
|
274
|
+
<details style="--details-radius: 0.5rem">
|
|
275
|
+
<summary>What is your return policy?</summary>
|
|
276
|
+
<section>
|
|
277
|
+
<p>You can return items within 30 days of purchase for a full refund.</p>
|
|
278
|
+
</section>
|
|
279
|
+
</details>
|
|
280
|
+
|
|
281
|
+
<details>
|
|
282
|
+
<summary>Do you ship internationally?</summary>
|
|
283
|
+
<section>
|
|
284
|
+
<p>Yes, we ship to over 100 countries worldwide.</p>
|
|
285
|
+
</section>
|
|
286
|
+
</details>
|
|
287
|
+
|
|
288
|
+
<details>
|
|
289
|
+
<summary>How long does shipping take?</summary>
|
|
290
|
+
<section>
|
|
291
|
+
<p>Domestic shipping typically takes 3-5 business days.</p>
|
|
292
|
+
</section>
|
|
293
|
+
</details>
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
### Settings Panel
|
|
297
|
+
|
|
298
|
+
```html
|
|
299
|
+
<details>
|
|
300
|
+
<summary>
|
|
301
|
+
<strong>General Settings</strong>
|
|
302
|
+
</summary>
|
|
303
|
+
<section>
|
|
304
|
+
<label> <input type="checkbox" /> Enable notifications </label>
|
|
305
|
+
<label> <input type="checkbox" /> Dark mode </label>
|
|
306
|
+
</section>
|
|
307
|
+
</details>
|
|
308
|
+
|
|
309
|
+
<details>
|
|
310
|
+
<summary>
|
|
311
|
+
<strong>Privacy Settings</strong>
|
|
312
|
+
</summary>
|
|
313
|
+
<section>
|
|
314
|
+
<label> <input type="checkbox" /> Public profile </label>
|
|
315
|
+
<label> <input type="checkbox" /> Show email </label>
|
|
316
|
+
</section>
|
|
317
|
+
</details>
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
### Product Details
|
|
321
|
+
|
|
322
|
+
```html
|
|
323
|
+
<details>
|
|
324
|
+
<summary>Product Specifications</summary>
|
|
325
|
+
<section>
|
|
326
|
+
<dl>
|
|
327
|
+
<dt>Dimensions</dt>
|
|
328
|
+
<dd>10" x 8" x 2"</dd>
|
|
329
|
+
|
|
330
|
+
<dt>Weight</dt>
|
|
331
|
+
<dd>1.5 lbs</dd>
|
|
332
|
+
|
|
333
|
+
<dt>Material</dt>
|
|
334
|
+
<dd>100% Cotton</dd>
|
|
335
|
+
</dl>
|
|
336
|
+
</section>
|
|
337
|
+
</details>
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
### Nested Details
|
|
341
|
+
|
|
342
|
+
```html
|
|
343
|
+
<details>
|
|
344
|
+
<summary>Parent Section</summary>
|
|
345
|
+
<section>
|
|
346
|
+
<p>Parent content</p>
|
|
347
|
+
|
|
348
|
+
<details style="margin-block: 1rem">
|
|
349
|
+
<summary>Nested Section</summary>
|
|
350
|
+
<section>
|
|
351
|
+
<p>Nested content</p>
|
|
352
|
+
</section>
|
|
353
|
+
</details>
|
|
354
|
+
</section>
|
|
355
|
+
</details>
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
## Accessibility Considerations
|
|
359
|
+
|
|
360
|
+
### Keyboard Navigation
|
|
361
|
+
|
|
362
|
+
- **Enter** or **Space** - Toggle expand/collapse
|
|
363
|
+
- **Tab** - Focus next element
|
|
364
|
+
- **Shift+Tab** - Focus previous element
|
|
365
|
+
|
|
366
|
+
### Screen Reader Support
|
|
367
|
+
|
|
368
|
+
```html
|
|
369
|
+
<details aria-label="Product details">
|
|
370
|
+
<summary>More Information</summary>
|
|
371
|
+
<section>
|
|
372
|
+
<p>Content...</p>
|
|
373
|
+
</section>
|
|
374
|
+
</details>
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
### ARIA Attributes
|
|
378
|
+
|
|
379
|
+
```html
|
|
380
|
+
<details id="faq1">
|
|
381
|
+
<summary aria-controls="faq1-content">Question 1</summary>
|
|
382
|
+
<section id="faq1-content">
|
|
383
|
+
<p>Answer 1</p>
|
|
384
|
+
</section>
|
|
385
|
+
</details>
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
## CSS Variable Naming Convention
|
|
389
|
+
|
|
390
|
+
| Category | Variable Pattern | Example |
|
|
391
|
+
| ----------- | ---------------------- | ------------------------------------- |
|
|
392
|
+
| **Details** | `--details-{property}` | `--details-border`, `--details-width` |
|
|
393
|
+
| **Summary** | `--summary-{property}` | `--summary-display`, `--summary-gap` |
|
|
394
|
+
|
|
395
|
+
## Browser Support
|
|
396
|
+
|
|
397
|
+
- **`<details>` element:** All modern browsers (Chrome 12+, Firefox 49+, Safari
|
|
398
|
+
6+)
|
|
399
|
+
- **CSS Custom Properties:** All modern browsers
|
|
400
|
+
- **`interpolate-size`:** Chrome 129+, Firefox 133+ (Experimental)
|
|
401
|
+
- **`@starting-style`:** Chrome 117+, Firefox 129+ (Experimental)
|
|
402
|
+
- **Flexbox:** All modern browsers
|
|
403
|
+
|
|
404
|
+
### Progressive Enhancement
|
|
405
|
+
|
|
406
|
+
Basic functionality works without modern features. Advanced animations enhance
|
|
407
|
+
experience in supporting browsers.
|
|
408
|
+
|
|
409
|
+
## Performance Tips
|
|
410
|
+
|
|
411
|
+
```css
|
|
412
|
+
.details-compact {
|
|
413
|
+
--details-padding-inline: 1rem;
|
|
414
|
+
--details-padding-block: 0.75rem;
|
|
415
|
+
--summary-transitions: all 0.3s ease;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
.details-rounded {
|
|
419
|
+
--details-radius: 0.5rem;
|
|
420
|
+
}
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
## Migration from Other Systems
|
|
424
|
+
|
|
425
|
+
### From Tailwind CSS
|
|
426
|
+
|
|
427
|
+
| Tailwind | fpkit Details |
|
|
428
|
+
| ------------------------- | ----------------------------- |
|
|
429
|
+
| Custom collapse component | Native `<details>` |
|
|
430
|
+
| `class="accordion"` | Adjacent `<details>` elements |
|
|
431
|
+
|
|
432
|
+
### From Bootstrap
|
|
433
|
+
|
|
434
|
+
| Bootstrap | fpkit Details |
|
|
435
|
+
| ------------------- | ----------------------------- |
|
|
436
|
+
| `class="accordion"` | Adjacent `<details>` elements |
|
|
437
|
+
| `class="collapse"` | Native `<details>` element |
|
|
438
|
+
|
|
439
|
+
## Related Resources
|
|
440
|
+
|
|
441
|
+
- **React Component** - See README for React Details component API
|
|
442
|
+
- **MDN: `<details>` element** -
|
|
443
|
+
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/details
|
|
444
|
+
- **W3C: Disclosure Pattern** -
|
|
445
|
+
https://www.w3.org/WAI/ARIA/apg/patterns/disclosure/
|