@commercetools/nimbus 0.0.1 → 0.0.3
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/dist/index.d.ts +1412 -0
- package/dist/index.js +11183 -0
- package/dist/index.js.map +1 -0
- package/dist/index.umd.cjs +27 -0
- package/dist/index.umd.cjs.map +1 -0
- package/package.json +33 -6
- package/.storybook/apca-check/index.ts +0 -150
- package/.storybook/main.ts +0 -64
- package/.storybook/preview.tsx +0 -92
- package/.storybook/vitest.setup.ts +0 -13
- package/docs/architecture-decisions/adr-0001-consumer-component-apis.md +0 -177
- package/docs/architecture-decisions/adr-0002-compound-component-extraction.md +0 -82
- package/src/components/accordion/accordion-context.tsx +0 -17
- package/src/components/accordion/accordion.mdx +0 -172
- package/src/components/accordion/accordion.recipe.tsx +0 -98
- package/src/components/accordion/accordion.slots.tsx +0 -39
- package/src/components/accordion/accordion.stories.tsx +0 -188
- package/src/components/accordion/accordion.tsx +0 -16
- package/src/components/accordion/accordion.types.tsx +0 -54
- package/src/components/accordion/components/accordion-content.tsx +0 -28
- package/src/components/accordion/components/accordion-group.tsx +0 -27
- package/src/components/accordion/components/accordion-header.tsx +0 -63
- package/src/components/accordion/components/accordion-item.tsx +0 -87
- package/src/components/accordion/index.ts +0 -2
- package/src/components/alert/alert.mdx +0 -92
- package/src/components/alert/alert.recipe.tsx +0 -65
- package/src/components/alert/alert.slots.tsx +0 -46
- package/src/components/alert/alert.stories.tsx +0 -308
- package/src/components/alert/alert.tsx +0 -18
- package/src/components/alert/alert.types.tsx +0 -70
- package/src/components/alert/components/alert.actions.tsx +0 -27
- package/src/components/alert/components/alert.description.tsx +0 -27
- package/src/components/alert/components/alert.dismiss-button.tsx +0 -41
- package/src/components/alert/components/alert.root.tsx +0 -92
- package/src/components/alert/components/alert.title.tsx +0 -29
- package/src/components/alert/index.ts +0 -2
- package/src/components/avatar/avatar.mdx +0 -80
- package/src/components/avatar/avatar.recipe.tsx +0 -36
- package/src/components/avatar/avatar.slots.tsx +0 -16
- package/src/components/avatar/avatar.stories.tsx +0 -136
- package/src/components/avatar/avatar.tsx +0 -34
- package/src/components/avatar/avatar.types.ts +0 -33
- package/src/components/avatar/index.ts +0 -2
- package/src/components/badge/badge.mdx +0 -91
- package/src/components/badge/badge.recipe.tsx +0 -72
- package/src/components/badge/badge.slots.tsx +0 -8
- package/src/components/badge/badge.stories.tsx +0 -124
- package/src/components/badge/badge.tsx +0 -35
- package/src/components/badge/badge.types.tsx +0 -40
- package/src/components/badge/index.ts +0 -2
- package/src/components/bleed/bleed.tsx +0 -1
- package/src/components/bleed/index.ts +0 -1
- package/src/components/box/box.mdx +0 -115
- package/src/components/box/box.stories.tsx +0 -71
- package/src/components/box/box.tsx +0 -11
- package/src/components/box/index.ts +0 -1
- package/src/components/button/button.mdx +0 -169
- package/src/components/button/button.recipe.ts +0 -185
- package/src/components/button/button.slots.tsx +0 -45
- package/src/components/button/button.stories.tsx +0 -369
- package/src/components/button/button.tsx +0 -37
- package/src/components/button/button.types.ts +0 -14
- package/src/components/button/index.ts +0 -2
- package/src/components/card/card.mdx +0 -92
- package/src/components/card/card.recipe.tsx +0 -71
- package/src/components/card/card.slots.tsx +0 -50
- package/src/components/card/card.stories.tsx +0 -175
- package/src/components/card/card.tsx +0 -9
- package/src/components/card/card.types.ts +0 -22
- package/src/components/card/components/card.content.tsx +0 -29
- package/src/components/card/components/card.header.tsx +0 -28
- package/src/components/card/components/card.root.tsx +0 -62
- package/src/components/card/index.ts +0 -2
- package/src/components/checkbox/checkbox.mdx +0 -78
- package/src/components/checkbox/checkbox.recipe.tsx +0 -116
- package/src/components/checkbox/checkbox.slots.tsx +0 -33
- package/src/components/checkbox/checkbox.stories.tsx +0 -200
- package/src/components/checkbox/checkbox.tsx +0 -77
- package/src/components/checkbox/checkbox.types.tsx +0 -22
- package/src/components/checkbox/index.ts +0 -2
- package/src/components/code/code.mdx +0 -17
- package/src/components/code/code.recipe.ts +0 -63
- package/src/components/code/code.tsx +0 -1
- package/src/components/code/index.ts +0 -1
- package/src/components/dialog/dialog.mdx +0 -20
- package/src/components/dialog/dialog.recipe.ts +0 -254
- package/src/components/dialog/dialog.tsx +0 -61
- package/src/components/dialog/index.ts +0 -1
- package/src/components/em/em.mdx +0 -17
- package/src/components/em/em.tsx +0 -1
- package/src/components/em/index.ts +0 -1
- package/src/components/flex/flex.mdx +0 -41
- package/src/components/flex/flex.tsx +0 -1
- package/src/components/flex/index.ts +0 -1
- package/src/components/grid/grid.mdx +0 -156
- package/src/components/grid/grid.stories.tsx +0 -151
- package/src/components/grid/grid.tsx +0 -29
- package/src/components/grid/index.ts +0 -1
- package/src/components/heading/heading.mdx +0 -23
- package/src/components/heading/heading.recipe.ts +0 -49
- package/src/components/heading/heading.tsx +0 -1
- package/src/components/heading/index.ts +0 -1
- package/src/components/highlight/highlight.mdx +0 -18
- package/src/components/highlight/highlight.tsx +0 -1
- package/src/components/highlight/index.ts +0 -1
- package/src/components/icon-button/icon-button.mdx +0 -98
- package/src/components/icon-button/icon-button.stories.tsx +0 -188
- package/src/components/icon-button/icon-button.tsx +0 -21
- package/src/components/icon-button/icon-button.types.tsx +0 -10
- package/src/components/icon-button/index.ts +0 -2
- package/src/components/index.ts +0 -33
- package/src/components/input/index.ts +0 -1
- package/src/components/input/input.mdx +0 -20
- package/src/components/input/input.recipe.ts +0 -95
- package/src/components/input/input.tsx +0 -1
- package/src/components/input-group/index.ts +0 -1
- package/src/components/input-group/input-group.mdx +0 -20
- package/src/components/input-group/input-group.tsx +0 -44
- package/src/components/kbd/index.ts +0 -1
- package/src/components/kbd/kbd.mdx +0 -18
- package/src/components/kbd/kbd.recipe.ts +0 -57
- package/src/components/kbd/kbd.tsx +0 -1
- package/src/components/link/index.ts +0 -2
- package/src/components/link/link.mdx +0 -77
- package/src/components/link/link.recipe.ts +0 -52
- package/src/components/link/link.slots.tsx +0 -29
- package/src/components/link/link.stories.tsx +0 -204
- package/src/components/link/link.tsx +0 -38
- package/src/components/link/link.types.tsx +0 -26
- package/src/components/list/index.ts +0 -1
- package/src/components/list/list.mdx +0 -18
- package/src/components/list/list.recipe.ts +0 -68
- package/src/components/list/list.tsx +0 -9
- package/src/components/loading-spinner/index.ts +0 -2
- package/src/components/loading-spinner/loading-spinner.mdx +0 -92
- package/src/components/loading-spinner/loading-spinner.recipe.tsx +0 -70
- package/src/components/loading-spinner/loading-spinner.slots.tsx +0 -38
- package/src/components/loading-spinner/loading-spinner.stories.tsx +0 -97
- package/src/components/loading-spinner/loading-spinner.tsx +0 -50
- package/src/components/loading-spinner/loading-spinner.types.tsx +0 -21
- package/src/components/nimbus-provider/color-mode.tsx +0 -32
- package/src/components/nimbus-provider/index.ts +0 -2
- package/src/components/nimbus-provider/nimbus-provider.mdx +0 -21
- package/src/components/nimbus-provider/nimbus-provider.tsx +0 -51
- package/src/components/select/components/select.clear-button.tsx +0 -31
- package/src/components/select/components/select.option-group.tsx +0 -48
- package/src/components/select/components/select.option.tsx +0 -21
- package/src/components/select/components/select.options.tsx +0 -23
- package/src/components/select/components/select.root.tsx +0 -81
- package/src/components/select/index.ts +0 -2
- package/src/components/select/select.mdx +0 -170
- package/src/components/select/select.recipe.tsx +0 -216
- package/src/components/select/select.slots.tsx +0 -58
- package/src/components/select/select.stories.tsx +0 -841
- package/src/components/select/select.tsx +0 -18
- package/src/components/select/select.types.tsx +0 -37
- package/src/components/simple-grid/index.ts +0 -1
- package/src/components/simple-grid/simple-grid.mdx +0 -133
- package/src/components/simple-grid/simple-grid.stories.tsx +0 -143
- package/src/components/simple-grid/simple-grid.tsx +0 -31
- package/src/components/stack/index.ts +0 -1
- package/src/components/stack/stack.mdx +0 -88
- package/src/components/stack/stack.stories.tsx +0 -82
- package/src/components/stack/stack.tsx +0 -15
- package/src/components/table/index.ts +0 -1
- package/src/components/table/table.mdx +0 -23
- package/src/components/table/table.recipe.ts +0 -170
- package/src/components/table/table.tsx +0 -43
- package/src/components/text/index.ts +0 -1
- package/src/components/text/text.mdx +0 -244
- package/src/components/text/text.tsx +0 -23
- package/src/components/text-input/index.ts +0 -2
- package/src/components/text-input/text-input.mdx +0 -118
- package/src/components/text-input/text-input.recipe.tsx +0 -68
- package/src/components/text-input/text-input.slots.tsx +0 -24
- package/src/components/text-input/text-input.stories.tsx +0 -282
- package/src/components/text-input/text-input.tsx +0 -39
- package/src/components/text-input/text-input.types.ts +0 -7
- package/src/components/toggle-button-group/components/toggle-button-group.button.tsx +0 -14
- package/src/components/toggle-button-group/components/toggle-button-group.root.tsx +0 -15
- package/src/components/toggle-button-group/index.ts +0 -2
- package/src/components/toggle-button-group/toggle-button-group.mdx +0 -94
- package/src/components/toggle-button-group/toggle-button-group.recipe.tsx +0 -64
- package/src/components/toggle-button-group/toggle-button-group.slots.tsx +0 -26
- package/src/components/toggle-button-group/toggle-button-group.stories.tsx +0 -311
- package/src/components/toggle-button-group/toggle-button-group.tsx +0 -12
- package/src/components/toggle-button-group/toggle-button-group.types.tsx +0 -62
- package/src/components/tooltip/index.ts +0 -4
- package/src/components/tooltip/make-element-focusable.stories.tsx +0 -56
- package/src/components/tooltip/make-element-focusable.tsx +0 -57
- package/src/components/tooltip/tooltip-trigger.stories.tsx +0 -157
- package/src/components/tooltip/tooltip-trigger.tsx +0 -15
- package/src/components/tooltip/tooltip.mdx +0 -48
- package/src/components/tooltip/tooltip.recipe.ts +0 -26
- package/src/components/tooltip/tooltip.slots.ts +0 -35
- package/src/components/tooltip/tooltip.stories.tsx +0 -139
- package/src/components/tooltip/tooltip.tsx +0 -31
- package/src/components/tooltip/tooltip.types.ts +0 -44
- package/src/components/visually-hidden/index.ts +0 -1
- package/src/components/visually-hidden/visually-hidden.mdx +0 -61
- package/src/components/visually-hidden/visually-hidden.stories.tsx +0 -124
- package/src/components/visually-hidden/visually-hidden.tsx +0 -18
- package/src/docs/accessibility.mdx +0 -21
- package/src/docs/background.mdx +0 -154
- package/src/docs/border.mdx +0 -226
- package/src/docs/changelog.mdx +0 -17
- package/src/docs/components-layout.mdx +0 -22
- package/src/docs/components.mdx +0 -17
- package/src/docs/data-display.mdx +0 -23
- package/src/docs/display.mdx +0 -55
- package/src/docs/effects.mdx +0 -73
- package/src/docs/feedback.mdx +0 -22
- package/src/docs/filters.mdx +0 -268
- package/src/docs/flex-and-grid.mdx +0 -445
- package/src/docs/forms.mdx +0 -22
- package/src/docs/generated/index.mdx +0 -16
- package/src/docs/getting-started.mdx +0 -17
- package/src/docs/home.mdx +0 -56
- package/src/docs/hooks.mdx +0 -16
- package/src/docs/inputs.mdx +0 -21
- package/src/docs/installation.mdx +0 -60
- package/src/docs/interactivity.mdx +0 -278
- package/src/docs/known-issues.mdx +0 -19
- package/src/docs/layout.mdx +0 -301
- package/src/docs/list.mdx +0 -82
- package/src/docs/markdown.mdx +0 -234
- package/src/docs/media.mdx +0 -22
- package/src/docs/naivgation.mdx +0 -22
- package/src/docs/playground.mdx +0 -16
- package/src/docs/rfcs-component-structure-rfcs.mdx +0 -17
- package/src/docs/rfcs-component-structure.mdx +0 -74
- package/src/docs/rfcs-hook-structure.mdx +0 -59
- package/src/docs/sizing.mdx +0 -210
- package/src/docs/spacing.mdx +0 -193
- package/src/docs/style-props-typography.mdx +0 -373
- package/src/docs/style-props.mdx +0 -15
- package/src/docs/svg.mdx +0 -58
- package/src/docs/tables.mdx +0 -95
- package/src/docs/toc.mdx +0 -39
- package/src/docs/tokens/animations.mdx +0 -68
- package/src/docs/tokens/aspect-ratios.mdx +0 -21
- package/src/docs/tokens/blurs.mdx +0 -20
- package/src/docs/tokens/borders.mdx +0 -25
- package/src/docs/tokens/breakpoints.mdx +0 -35
- package/src/docs/tokens/colors.mdx +0 -86
- package/src/docs/tokens/cursors.mdx +0 -21
- package/src/docs/tokens/radii.mdx +0 -23
- package/src/docs/tokens/shadows.mdx +0 -21
- package/src/docs/tokens/sizes.mdx +0 -54
- package/src/docs/tokens/spacing.mdx +0 -35
- package/src/docs/tokens/typography.mdx +0 -61
- package/src/docs/tokens/z-indices.mdx +0 -23
- package/src/docs/tokens-other.mdx +0 -17
- package/src/docs/tokens.mdx +0 -16
- package/src/docs/transforms.mdx +0 -150
- package/src/docs/transitions.mdx +0 -164
- package/src/docs/typography.mdx +0 -17
- package/src/docs/utilities.mdx +0 -17
- package/src/hooks/index.ts +0 -2
- package/src/hooks/use-copy-to-clipboard/use-copy-to-clipboard.mdx +0 -54
- package/src/hooks/use-copy-to-clipboard/use-copy-to-clipboard.ts +0 -1
- package/src/hooks/use-hotkeys/use-hotkeys.mdx +0 -48
- package/src/hooks/use-hotkeys/use-hotkeys.stories.tsx +0 -69
- package/src/hooks/use-hotkeys/use-hotkeys.ts +0 -1
- package/src/index.ts +0 -3
- package/src/test/utils.tsx +0 -20
- package/src/theme/animation-styles.ts +0 -52
- package/src/theme/breakpoints.ts +0 -32
- package/src/theme/global-css.ts +0 -53
- package/src/theme/index.ts +0 -35
- package/src/theme/keyframes.ts +0 -192
- package/src/theme/layer-styles.ts +0 -12
- package/src/theme/recipes/index.ts +0 -21
- package/src/theme/semantic-tokens/colors.ts +0 -55
- package/src/theme/semantic-tokens/index.ts +0 -9
- package/src/theme/semantic-tokens/radii.ts +0 -3
- package/src/theme/semantic-tokens/shadows.ts +0 -4
- package/src/theme/slot-recipes/index.ts +0 -15
- package/src/theme/text-styles.ts +0 -8
- package/src/theme/tokens/animations.ts +0 -4
- package/src/theme/tokens/aspect-ratios.ts +0 -5
- package/src/theme/tokens/blurs.ts +0 -5
- package/src/theme/tokens/borders.ts +0 -4
- package/src/theme/tokens/colors.ts +0 -8
- package/src/theme/tokens/cursor.ts +0 -4
- package/src/theme/tokens/durations.ts +0 -4
- package/src/theme/tokens/easings.ts +0 -4
- package/src/theme/tokens/font-sizes.ts +0 -4
- package/src/theme/tokens/font-weights.ts +0 -4
- package/src/theme/tokens/fonts.ts +0 -4
- package/src/theme/tokens/index.ts +0 -57
- package/src/theme/tokens/letter-spacings.ts +0 -24
- package/src/theme/tokens/line-heights.ts +0 -4
- package/src/theme/tokens/radii.ts +0 -4
- package/src/theme/tokens/sizes.ts +0 -120
- package/src/theme/tokens/spacing.ts +0 -4
- package/src/theme/tokens/z-index.ts +0 -4
- package/src/utils/extractStyleProps.ts +0 -26
- package/src/utils/fixedForwardRef.ts +0 -17
- package/tsconfig.json +0 -38
- package/vite.config.ts +0 -54
- package/vitest.config.ts +0 -50
package/package.json
CHANGED
|
@@ -1,11 +1,39 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@commercetools/nimbus",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"main": "./dist/index.umd.cjs",
|
|
5
5
|
"module": "./dist/index.js",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
8
|
-
"
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"default": "./dist/index.js"
|
|
13
|
+
},
|
|
14
|
+
"require": {
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"default": "./dist/index.umd.cjs"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"dist"
|
|
22
|
+
],
|
|
23
|
+
"publishConfig": {
|
|
24
|
+
"access": "public"
|
|
25
|
+
},
|
|
26
|
+
"sideEffects": [
|
|
27
|
+
"*.css"
|
|
28
|
+
],
|
|
29
|
+
"source": "src/index.ts",
|
|
30
|
+
"typesVersions": {
|
|
31
|
+
"*": {
|
|
32
|
+
"*": [
|
|
33
|
+
"./dist/index.d.ts"
|
|
34
|
+
]
|
|
35
|
+
}
|
|
36
|
+
},
|
|
9
37
|
"devDependencies": {
|
|
10
38
|
"@chakra-ui/cli": "catalog:react",
|
|
11
39
|
"@pandacss/types": "catalog:react",
|
|
@@ -20,7 +48,6 @@
|
|
|
20
48
|
"@testing-library/user-event": "catalog:tooling",
|
|
21
49
|
"@types/react": "catalog:react",
|
|
22
50
|
"@types/react-dom": "catalog:react",
|
|
23
|
-
"@types/testing-library__dom": "^7.5.0",
|
|
24
51
|
"@vitejs/plugin-react": "catalog:tooling",
|
|
25
52
|
"@vitest/browser": "catalog:tooling",
|
|
26
53
|
"@vitest/coverage-v8": "catalog:tooling",
|
|
@@ -46,10 +73,10 @@
|
|
|
46
73
|
"@emotion/is-prop-valid": "catalog:react",
|
|
47
74
|
"@react-aria/optimize-locales-plugin": "^1.1.4",
|
|
48
75
|
"next-themes": "catalog:react",
|
|
49
|
-
"react-aria": "
|
|
50
|
-
"react-aria-components": "
|
|
76
|
+
"react-aria": "catalog:react",
|
|
77
|
+
"react-aria-components": "catalog:react",
|
|
51
78
|
"react-hotkeys-hook": "^4.6.1",
|
|
52
|
-
"react-stately": "
|
|
79
|
+
"react-stately": "catalog:react",
|
|
53
80
|
"react-use": "^17.5.1"
|
|
54
81
|
},
|
|
55
82
|
"scripts": {
|
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
import axe, { type Check, Rule } from "axe-core";
|
|
2
|
-
import { calcAPCA } from "apca-w3";
|
|
3
|
-
|
|
4
|
-
type ConformanceLevel = "custom";
|
|
5
|
-
|
|
6
|
-
type ConformanceThresholdFn = (
|
|
7
|
-
fontSize: string,
|
|
8
|
-
fontWeight: string
|
|
9
|
-
) => number | null;
|
|
10
|
-
|
|
11
|
-
// Augment Axe types to include the color utilities we use in this file
|
|
12
|
-
// https://github.com/dequelabs/axe-core/blob/develop/lib/commons/color/color.js
|
|
13
|
-
type Color = {
|
|
14
|
-
red: number;
|
|
15
|
-
green: number;
|
|
16
|
-
blue: number;
|
|
17
|
-
alpha: number;
|
|
18
|
-
toHexString: () => string;
|
|
19
|
-
};
|
|
20
|
-
declare module "axe-core" {
|
|
21
|
-
interface Commons {
|
|
22
|
-
color: {
|
|
23
|
-
getForegroundColor: (
|
|
24
|
-
node: HTMLElement,
|
|
25
|
-
_: unknown,
|
|
26
|
-
bgColor: Color | null
|
|
27
|
-
) => Color | null;
|
|
28
|
-
getBackgroundColor: (node: HTMLElement) => Color | null;
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const generateColorContrastAPCAConformanceCheck = (
|
|
34
|
-
conformanceLevel: string,
|
|
35
|
-
conformanceThresholdFn: ConformanceThresholdFn
|
|
36
|
-
): Check => ({
|
|
37
|
-
id: `color-contrast-apca-${conformanceLevel}-conformance`,
|
|
38
|
-
metadata: {
|
|
39
|
-
impact: "serious",
|
|
40
|
-
messages: {
|
|
41
|
-
pass:
|
|
42
|
-
"Element has sufficient APCA " +
|
|
43
|
-
conformanceLevel +
|
|
44
|
-
" level lightness contrast (Lc) of ${data.apcaContrast}Lc (foreground color: ${data.fgColor}, background color: ${data.bgColor}, font size: ${data.fontSize}, font weight: ${data.fontWeight}). Expected minimum APCA contrast of ${data.apcaThreshold}}",
|
|
45
|
-
fail: {
|
|
46
|
-
default:
|
|
47
|
-
"Element has insufficient APCA " +
|
|
48
|
-
conformanceLevel +
|
|
49
|
-
" level contrast of ${data.apcaContrast}Lc (foreground color: ${data.fgColor}, background color: ${data.bgColor}, font size: ${data.fontSize}, font weight: ${data.fontWeight}). Expected minimum APCA lightness contrast of ${data.apcaThreshold}Lc",
|
|
50
|
-
increaseFont:
|
|
51
|
-
"Element has insufficient APCA " +
|
|
52
|
-
conformanceLevel +
|
|
53
|
-
" level contrast of ${data.apcaContrast}Lc (foreground color: ${data.fgColor}, background color: ${data.bgColor}, font size: ${data.fontSize}, font weight: ${data.fontWeight}). Increase font size and/or font weight to meet APCA conformance minimums",
|
|
54
|
-
placeholder:
|
|
55
|
-
"Element has insufficient APCA " +
|
|
56
|
-
conformanceLevel +
|
|
57
|
-
" level contrast of ${data.apcaContrast}Lc (foreground color: ${data.fgColor}, background color: ${data.bgColor}, font size: ${data.fontSize}, font weight: ${data.fontWeight}). Using reduced threshold of 30Lc for placeholder",
|
|
58
|
-
},
|
|
59
|
-
incomplete: "Unable to determine APCA lightness contrast (Lc)",
|
|
60
|
-
},
|
|
61
|
-
},
|
|
62
|
-
evaluate(n) {
|
|
63
|
-
const node = n as HTMLElement;
|
|
64
|
-
const nodeStyle = window.getComputedStyle(node);
|
|
65
|
-
const fontSize = nodeStyle.getPropertyValue("font-size");
|
|
66
|
-
const fontWeight = nodeStyle.getPropertyValue("font-weight");
|
|
67
|
-
|
|
68
|
-
const bgColor: Color | null = axe.commons.color.getBackgroundColor(node);
|
|
69
|
-
const fgColor: Color | null = axe.commons.color.getForegroundColor(
|
|
70
|
-
node,
|
|
71
|
-
false,
|
|
72
|
-
bgColor
|
|
73
|
-
);
|
|
74
|
-
|
|
75
|
-
// missing data to determine APCA contrast for this node
|
|
76
|
-
if (!bgColor || !fgColor || !fontSize || !fontWeight) {
|
|
77
|
-
return undefined;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
const toRGBA = (color: Color) => {
|
|
81
|
-
return `rgba(${color.red}, ${color.green}, ${color.blue}, ${color.alpha})`;
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
const apcaContrast = Math.abs(
|
|
85
|
-
calcAPCA(toRGBA(fgColor), toRGBA(bgColor)) as number
|
|
86
|
-
);
|
|
87
|
-
|
|
88
|
-
// Check if element has data-placeholder attribute
|
|
89
|
-
const hasPlaceholderAttr = node.hasAttribute("data-placeholder");
|
|
90
|
-
const originalThreshold = conformanceThresholdFn(fontSize, fontWeight);
|
|
91
|
-
|
|
92
|
-
// Use reduced threshold of 30 for placeholders, otherwise use original threshold
|
|
93
|
-
const apcaThreshold = hasPlaceholderAttr ? 30 : originalThreshold;
|
|
94
|
-
|
|
95
|
-
this.data({
|
|
96
|
-
fgColor: fgColor.toHexString(),
|
|
97
|
-
bgColor: bgColor.toHexString(),
|
|
98
|
-
fontSize: `${((parseFloat(fontSize) * 72) / 96).toFixed(
|
|
99
|
-
1
|
|
100
|
-
)}pt (${parseFloat(fontSize)}px)`,
|
|
101
|
-
fontWeight: fontWeight,
|
|
102
|
-
apcaContrast: Math.round(apcaContrast * 100) / 100,
|
|
103
|
-
apcaThreshold: apcaThreshold,
|
|
104
|
-
messageKey:
|
|
105
|
-
apcaThreshold === null
|
|
106
|
-
? "increaseFont"
|
|
107
|
-
: hasPlaceholderAttr
|
|
108
|
-
? "placeholder"
|
|
109
|
-
: "default",
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
return apcaThreshold ? apcaContrast >= apcaThreshold : false;
|
|
113
|
-
},
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
const generateColorContrastAPCARule = (conformanceLevel: string): Rule => ({
|
|
117
|
-
id: `color-contrast-apca-${conformanceLevel}`,
|
|
118
|
-
impact: "serious",
|
|
119
|
-
matches: "color-contrast-matches",
|
|
120
|
-
metadata: {
|
|
121
|
-
description: `Ensures the contrast between foreground and background colors meets APCA ${conformanceLevel} level conformance minimums thresholds`,
|
|
122
|
-
help: "Elements must meet APCA conformance minimums thresholds",
|
|
123
|
-
helpUrl:
|
|
124
|
-
"https://readtech.org/ARC/tests/visual-readability-contrast/?tn=criterion",
|
|
125
|
-
},
|
|
126
|
-
all: [`color-contrast-apca-${conformanceLevel}-conformance`],
|
|
127
|
-
tags: ["apca", "wcag3", `apca-${conformanceLevel}`],
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
const registerAPCACheck = (
|
|
131
|
-
conformanceLevel: ConformanceLevel,
|
|
132
|
-
conformanceThresholdFn: ConformanceThresholdFn
|
|
133
|
-
) => {
|
|
134
|
-
if (typeof conformanceThresholdFn !== "function") {
|
|
135
|
-
throw new Error("Conformance threshold function is required");
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
return {
|
|
139
|
-
rules: [generateColorContrastAPCARule(conformanceLevel)],
|
|
140
|
-
checks: [
|
|
141
|
-
generateColorContrastAPCAConformanceCheck(
|
|
142
|
-
conformanceLevel,
|
|
143
|
-
conformanceThresholdFn
|
|
144
|
-
),
|
|
145
|
-
],
|
|
146
|
-
};
|
|
147
|
-
};
|
|
148
|
-
|
|
149
|
-
export type { ConformanceLevel, ConformanceThresholdFn };
|
|
150
|
-
export default registerAPCACheck;
|
package/.storybook/main.ts
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import type { StorybookConfig } from "@storybook/react-vite";
|
|
2
|
-
|
|
3
|
-
import { join, dirname } from "path";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* This function is used to resolve the absolute path of a package.
|
|
7
|
-
* It is needed in projects that use Yarn PnP or are set up within a monorepo.
|
|
8
|
-
*/
|
|
9
|
-
function getAbsolutePackagePath(value: string): any {
|
|
10
|
-
return dirname(require.resolve(join(value, "package.json")));
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
const config: StorybookConfig = {
|
|
14
|
-
stories: ["../src/**/*.stories.tsx"],
|
|
15
|
-
addons: [
|
|
16
|
-
getAbsolutePackagePath("@storybook/addon-essentials"),
|
|
17
|
-
getAbsolutePackagePath("@storybook/addon-a11y"),
|
|
18
|
-
getAbsolutePackagePath("storybook-dark-mode"),
|
|
19
|
-
getAbsolutePackagePath("@storybook/experimental-addon-test"),
|
|
20
|
-
],
|
|
21
|
-
framework: {
|
|
22
|
-
name: getAbsolutePackagePath("@storybook/react-vite"),
|
|
23
|
-
options: {},
|
|
24
|
-
},
|
|
25
|
-
refs: {
|
|
26
|
-
"@chakra-ui/react": {
|
|
27
|
-
disable: true,
|
|
28
|
-
},
|
|
29
|
-
},
|
|
30
|
-
core: {
|
|
31
|
-
disableTelemetry: true,
|
|
32
|
-
},
|
|
33
|
-
typescript: {
|
|
34
|
-
reactDocgen: "react-docgen-typescript",
|
|
35
|
-
// Provide your own options if necessary.
|
|
36
|
-
// See https://storybook.js.org/docs/configure/typescript for more information.
|
|
37
|
-
reactDocgenTypescriptOptions: {
|
|
38
|
-
compilerOptions: {
|
|
39
|
-
allowSyntheticDefaultImports: false,
|
|
40
|
-
esModuleInterop: false,
|
|
41
|
-
},
|
|
42
|
-
|
|
43
|
-
// Extend if needed...
|
|
44
|
-
propFilter: (prop) => {
|
|
45
|
-
// ... common props that every component may have
|
|
46
|
-
const whitelistedProps = ["ref", "colorScheme", "asChild"];
|
|
47
|
-
|
|
48
|
-
// ... props coming from the nimbus package
|
|
49
|
-
const isOneOfOurTypes = !!prop.parent?.fileName.includes("nimbus/src");
|
|
50
|
-
|
|
51
|
-
// ... props coming from the react-aria package
|
|
52
|
-
const isReactAriaProp =
|
|
53
|
-
!!prop.parent?.fileName.includes("@react-types");
|
|
54
|
-
|
|
55
|
-
return (
|
|
56
|
-
isOneOfOurTypes ||
|
|
57
|
-
isReactAriaProp ||
|
|
58
|
-
whitelistedProps.includes(prop.name)
|
|
59
|
-
);
|
|
60
|
-
},
|
|
61
|
-
},
|
|
62
|
-
},
|
|
63
|
-
};
|
|
64
|
-
export default config;
|
package/.storybook/preview.tsx
DELETED
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
import React, { useEffect, useState } from "react";
|
|
2
|
-
import type { Preview } from "@storybook/react";
|
|
3
|
-
import { NimbusProvider } from "../src";
|
|
4
|
-
import { DARK_MODE_EVENT_NAME } from "storybook-dark-mode";
|
|
5
|
-
import { addons } from "@storybook/preview-api";
|
|
6
|
-
|
|
7
|
-
import APCACheck from "./apca-check";
|
|
8
|
-
|
|
9
|
-
const apca = APCACheck("custom", (fontSize: string) => {
|
|
10
|
-
const size = parseFloat(fontSize);
|
|
11
|
-
switch (true) {
|
|
12
|
-
case size >= 32:
|
|
13
|
-
return 45;
|
|
14
|
-
default:
|
|
15
|
-
return 60;
|
|
16
|
-
}
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
// get channel to listen to event emitter
|
|
20
|
-
const channel = addons.getChannel();
|
|
21
|
-
|
|
22
|
-
const ThemeDecorator = ({ children }) => {
|
|
23
|
-
const [isDark, setDark] = useState(false);
|
|
24
|
-
const theme = isDark ? "dark" : "light";
|
|
25
|
-
|
|
26
|
-
useEffect(() => {
|
|
27
|
-
const { current } = JSON.parse(
|
|
28
|
-
// TODO: find out if there is a more elegant solution
|
|
29
|
-
localStorage.getItem("sb-addon-themes-3") || "{}"
|
|
30
|
-
);
|
|
31
|
-
|
|
32
|
-
setDark(current === "dark");
|
|
33
|
-
|
|
34
|
-
channel.on(DARK_MODE_EVENT_NAME, (darkMode) => {
|
|
35
|
-
setDark(darkMode);
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
return () => channel.off(DARK_MODE_EVENT_NAME, setDark);
|
|
39
|
-
}, [channel]);
|
|
40
|
-
|
|
41
|
-
useEffect(() => {
|
|
42
|
-
document.documentElement.classList.remove("light", "dark");
|
|
43
|
-
document.documentElement.classList.add(theme);
|
|
44
|
-
}, [theme]);
|
|
45
|
-
|
|
46
|
-
return <NimbusProvider defaultTheme={theme}>{children}</NimbusProvider>;
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
const preview: Preview = {
|
|
50
|
-
parameters: {
|
|
51
|
-
darkMode: {
|
|
52
|
-
stylePreview: true,
|
|
53
|
-
classTarget: "html",
|
|
54
|
-
},
|
|
55
|
-
backgrounds: {
|
|
56
|
-
disable: true,
|
|
57
|
-
},
|
|
58
|
-
a11y: {
|
|
59
|
-
config: {
|
|
60
|
-
checks: [...apca.checks],
|
|
61
|
-
rules: [
|
|
62
|
-
{
|
|
63
|
-
// disabled, as radix is using APCA algorithm while Storybook uses WCAG
|
|
64
|
-
// @see https://web.dev/articles/color-and-contrast-accessibility#apca)
|
|
65
|
-
|
|
66
|
-
id: "color-contrast",
|
|
67
|
-
enabled: false,
|
|
68
|
-
},
|
|
69
|
-
...apca.rules,
|
|
70
|
-
],
|
|
71
|
-
},
|
|
72
|
-
/*
|
|
73
|
-
* Axe's options parameter
|
|
74
|
-
* See https://github.com/dequelabs/axe-core/blob/develop/doc/API.md#options-parameter
|
|
75
|
-
* to learn more about the available options.
|
|
76
|
-
*/
|
|
77
|
-
options: {},
|
|
78
|
-
},
|
|
79
|
-
},
|
|
80
|
-
tags: ["autodocs", "a11y-test"],
|
|
81
|
-
decorators: [
|
|
82
|
-
(Story) => {
|
|
83
|
-
return (
|
|
84
|
-
<ThemeDecorator>
|
|
85
|
-
<Story />
|
|
86
|
-
</ThemeDecorator>
|
|
87
|
-
);
|
|
88
|
-
},
|
|
89
|
-
],
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
export default preview;
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import * as a11yAddonAnnotations from "@storybook/addon-a11y/preview";
|
|
2
|
-
import { beforeAll } from "vitest";
|
|
3
|
-
import { setProjectAnnotations } from "@storybook/react";
|
|
4
|
-
import * as projectAnnotations from "./preview";
|
|
5
|
-
|
|
6
|
-
// This is an important step to apply the right configuration when testing your stories.
|
|
7
|
-
// More info at: https://storybook.js.org/docs/api/portable-stories/portable-stories-vitest#setprojectannotations
|
|
8
|
-
const project = setProjectAnnotations([
|
|
9
|
-
a11yAddonAnnotations,
|
|
10
|
-
projectAnnotations,
|
|
11
|
-
]);
|
|
12
|
-
|
|
13
|
-
beforeAll(project.beforeAll);
|
|
@@ -1,177 +0,0 @@
|
|
|
1
|
-
# ADR: On Consumer Component API's
|
|
2
|
-
|
|
3
|
-
## Context
|
|
4
|
-
|
|
5
|
-
We needed an Alert component to show informational or warning messages. The
|
|
6
|
-
component should allow:
|
|
7
|
-
|
|
8
|
-
- A title and description.
|
|
9
|
-
- An optional dismiss button.
|
|
10
|
-
- Additional buttons or controls.
|
|
11
|
-
- Spacing/styling overrides (e.g. px, py).
|
|
12
|
-
|
|
13
|
-
In early explorations, we tried to expose everything via props on the main
|
|
14
|
-
`Alert`—this seemed convenient but would quickly became unwieldy when
|
|
15
|
-
requirements changed. This led to a discussion about how to structure the API
|
|
16
|
-
for components in a way that is both flexible and maintainable.
|
|
17
|
-
|
|
18
|
-
## Early Attempts
|
|
19
|
-
|
|
20
|
-
### Attempt A: One Big Alert with Child Buttons
|
|
21
|
-
|
|
22
|
-
```jsx
|
|
23
|
-
<Alert
|
|
24
|
-
title="title"
|
|
25
|
-
description="description"
|
|
26
|
-
onDismiss={() => void}
|
|
27
|
-
px="4"
|
|
28
|
-
py="2"
|
|
29
|
-
>
|
|
30
|
-
<button>Dismiss</button>
|
|
31
|
-
<button>Click me</button>
|
|
32
|
-
</Alert>
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
1. title and description are top-level props.
|
|
36
|
-
2. children are the alert's buttons.
|
|
37
|
-
|
|
38
|
-
**Issue**: If we need new kinds of controls (e.g., a link, extra text, or
|
|
39
|
-
re-positioned buttons), we must keep adding or repurposing props. The line
|
|
40
|
-
between "belongs in children" vs. "belongs in dedicated props" can become
|
|
41
|
-
blurry.
|
|
42
|
-
|
|
43
|
-
### Attempt B: Specialized Props for Each Slot
|
|
44
|
-
|
|
45
|
-
```jsx
|
|
46
|
-
<Alert
|
|
47
|
-
alertTitleStyle="bold"
|
|
48
|
-
title="title"
|
|
49
|
-
description="description"
|
|
50
|
-
onDismiss={() => void}
|
|
51
|
-
px="4"
|
|
52
|
-
py="2"
|
|
53
|
-
alertControls={
|
|
54
|
-
<>
|
|
55
|
-
<button>Dismiss</button>
|
|
56
|
-
<button>Click me</button>
|
|
57
|
-
</>
|
|
58
|
-
}
|
|
59
|
-
/>
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
1. We introduced an alertControls prop for the buttons.
|
|
63
|
-
2. We also added alertTitleStyle to control how the title looks.
|
|
64
|
-
|
|
65
|
-
**Issue**: As the design evolves (e.g., "Now we need the title right‐aligned, or
|
|
66
|
-
a sub‐title below the main title"), we keep adding ad-hoc props like
|
|
67
|
-
titlePosition, alertControlsAlignment, etc. The `<Alert>` props list grows large
|
|
68
|
-
and messy.
|
|
69
|
-
|
|
70
|
-
### Attempt C: Even More Props for Layout / Positioning
|
|
71
|
-
|
|
72
|
-
```jsx
|
|
73
|
-
<Alert
|
|
74
|
-
alertTitleStyle="bold"
|
|
75
|
-
title="title"
|
|
76
|
-
titlePosition="right"
|
|
77
|
-
description="description"
|
|
78
|
-
onDismiss={() => void}
|
|
79
|
-
px="4"
|
|
80
|
-
py="2"
|
|
81
|
-
alertControls={
|
|
82
|
-
<>
|
|
83
|
-
<button>Dismiss</button>
|
|
84
|
-
<button>Click me</button>
|
|
85
|
-
</>
|
|
86
|
-
}
|
|
87
|
-
/>
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
**Issue**: The top-level `<Alert>` component now has numerous styling, layout,
|
|
91
|
-
and content props all jumbled together. If a new design wants a second dismiss
|
|
92
|
-
button or a multi-line description, we must add more props. This is non-scalable
|
|
93
|
-
and not very semantic.
|
|
94
|
-
|
|
95
|
-
## Final Decision: Compound Components
|
|
96
|
-
|
|
97
|
-
We decided to adopt compound components (a pattern in which sub-elements are
|
|
98
|
-
also React components). The final API looks like:
|
|
99
|
-
|
|
100
|
-
```jsx
|
|
101
|
-
<Alert px="4" py="2">
|
|
102
|
-
<Alert.Title fontStyle="bold">
|
|
103
|
-
Alert Title
|
|
104
|
-
</Alert.Title>
|
|
105
|
-
<Alert.Description>
|
|
106
|
-
A short alert description.
|
|
107
|
-
</Alert.Description>
|
|
108
|
-
<Alert.DismissButton onClick={() => void} />
|
|
109
|
-
</Alert>
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
### Key Changes:
|
|
113
|
-
|
|
114
|
-
1. Children become semantic slots: `<Alert.Title>`, `<Alert.Description>`, and
|
|
115
|
-
`<Alert.DismissButton>`.
|
|
116
|
-
2. Each slot can handle its own styling or props. For instance, Alert.Title
|
|
117
|
-
might accept a fontStyle prop, Alert.DismissButton handles its own click
|
|
118
|
-
event.
|
|
119
|
-
3. The root `<Alert>` only handles general layout or high-level variant props
|
|
120
|
-
(e.g., px, py, severity).
|
|
121
|
-
|
|
122
|
-
### Why this is better:
|
|
123
|
-
|
|
124
|
-
- **Clear separation of concerns**: Layout/styling for each slot belongs to that
|
|
125
|
-
slot. The main `<Alert>` only handles spacing or theming.
|
|
126
|
-
- **Easier to extend**: If we need a second sub-element (e.g., `<Alert.Icon>` or
|
|
127
|
-
`<Alert.Footer>`), we just introduce a new subcomponent. We don't clog
|
|
128
|
-
`<Alert>` with more props.
|
|
129
|
-
- **Semantic**: `<Alert.Title>` and `<Alert.Description>` are more descriptive
|
|
130
|
-
than `title="..."` or `alertControls={...}`.
|
|
131
|
-
|
|
132
|
-
## Consequences
|
|
133
|
-
|
|
134
|
-
- We have a more verbose but much more flexible API.
|
|
135
|
-
- Consumers build their alert in a semantic, composable way.
|
|
136
|
-
- We can add or rearrange subcomponents without rewriting the main `<Alert>`
|
|
137
|
-
props or code.
|
|
138
|
-
- If developers want quick usage (like a single short message), they might find
|
|
139
|
-
passing a couple props simpler – but we've prioritized long-term
|
|
140
|
-
maintainability and clarity.
|
|
141
|
-
|
|
142
|
-
## Examples in Practice
|
|
143
|
-
|
|
144
|
-
### 1. Basic Alert
|
|
145
|
-
|
|
146
|
-
```jsx
|
|
147
|
-
<Alert>
|
|
148
|
-
<Alert.Title>Warning!</Alert.Title>
|
|
149
|
-
<Alert.Description>Please fill out all required fields.</Alert.Description>
|
|
150
|
-
<Alert.DismissButton onClick={onClose} />
|
|
151
|
-
</Alert>
|
|
152
|
-
```
|
|
153
|
-
|
|
154
|
-
### 2. Alert with Extra Controls
|
|
155
|
-
|
|
156
|
-
```jsx
|
|
157
|
-
<Alert px="4" py="3">
|
|
158
|
-
<Alert.Title fontStyle="bold">Network Error</Alert.Title>
|
|
159
|
-
<Alert.Description>
|
|
160
|
-
We could not reach the server. Please try again.
|
|
161
|
-
</Alert.Description>
|
|
162
|
-
<Alert.DismissButton onClick={onClose} />
|
|
163
|
-
<Alert.Controls>
|
|
164
|
-
<Button onClick={onRetry}>Retry</Button>
|
|
165
|
-
</Alert.Controls>
|
|
166
|
-
</Alert>
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
## Summary
|
|
170
|
-
|
|
171
|
-
- Inline props for major sections quickly lead to "prop creep."
|
|
172
|
-
- Compound components keep `<Alert>` minimal and delegate content/markup details
|
|
173
|
-
to semantically named subcomponents.
|
|
174
|
-
- Layout changes or extra features do not require new top-level props on
|
|
175
|
-
`<Alert>`.
|
|
176
|
-
|
|
177
|
-
This approach scales better and is more maintainable as the design evolves.
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
# ADR: Standardizing Compound Component Extraction to a `components` Directory
|
|
2
|
-
|
|
3
|
-
## Context
|
|
4
|
-
|
|
5
|
-
To enhance the organization, maintainability, and scalability of our components
|
|
6
|
-
that utilize the compound component pattern, we are establishing a consistent
|
|
7
|
-
directory structure for their implementation. This ADR outlines the principle of
|
|
8
|
-
extracting the core root component and its associated compound sub-components
|
|
9
|
-
into a dedicated `components` subdirectory.
|
|
10
|
-
|
|
11
|
-
## Decision
|
|
12
|
-
|
|
13
|
-
For any component (`<ComponentName>`) that follows the compound component
|
|
14
|
-
pattern (where sub-components like `<ComponentName.Part>`,
|
|
15
|
-
`<ComponentName.Control>`, etc., are defined as properties of the main
|
|
16
|
-
component), we will adopt the following directory structure:
|
|
17
|
-
|
|
18
|
-
- The main component's directory will be
|
|
19
|
-
`packages/nimbus/src/components/<component-name>/`.
|
|
20
|
-
- A subdirectory named `components` will be created within the main component's
|
|
21
|
-
directory: `packages/nimbus/src/components/<component-name>/components/`.
|
|
22
|
-
- The implementation files for the root component (`<ComponentName.Root>`) and
|
|
23
|
-
all its compound sub-components (`<ComponentName.Part>`,
|
|
24
|
-
`<ComponentName.Control>`, etc.) will reside within this `components`
|
|
25
|
-
subdirectory.
|
|
26
|
-
- The main `<component-name>.tsx` file within the `<component-name>` directory
|
|
27
|
-
will be responsible for:
|
|
28
|
-
- Importing the root component and all sub-components from the `components`
|
|
29
|
-
subdirectory.
|
|
30
|
-
- Re-exporting them as properties of the main `ComponentName` object.
|
|
31
|
-
|
|
32
|
-
Storybook files (`<component-name>.stories.tsx`) will be updated to reflect this
|
|
33
|
-
structure, primarily by referencing the appropriate root component (e.g.,
|
|
34
|
-
`ComponentName.Root` or `ComponentName`) in the `Meta` configuration.
|
|
35
|
-
|
|
36
|
-
## Why this is better:
|
|
37
|
-
|
|
38
|
-
- **Consistent Code Organization:** This standardized structure will make it
|
|
39
|
-
easier for developers to locate the implementation files for any component
|
|
40
|
-
utilizing the compound pattern.
|
|
41
|
-
- **Improved Maintainability:** Isolating the implementation of each part of a
|
|
42
|
-
compound component within its own file reduces the complexity of individual
|
|
43
|
-
files and minimizes the risk of unintended side effects during modifications.
|
|
44
|
-
- **Enhanced Scalability:** As components grow and incorporate more
|
|
45
|
-
sub-components, this structure provides a clear and manageable way to organize
|
|
46
|
-
the increasing number of files.
|
|
47
|
-
- **Clear Separation of Concerns:** Each file within the `components` directory
|
|
48
|
-
will focus on the implementation details of a specific part of the compound
|
|
49
|
-
component.
|
|
50
|
-
|
|
51
|
-
## Consequences
|
|
52
|
-
|
|
53
|
-
- **New Directory Structure:** Developers will need to be aware of this new
|
|
54
|
-
directory structure for all future and refactored compound components.
|
|
55
|
-
- **Import Path Updates:** When working directly with the individual root or
|
|
56
|
-
sub-component implementations, import paths will need to reflect their
|
|
57
|
-
location within the `components` subdirectory. However, the main `index.tsx`
|
|
58
|
-
re-export should abstract this for most consumers using the compound component
|
|
59
|
-
API.
|
|
60
|
-
- **Storybook Updates:** The `Meta` configuration in Storybook files for
|
|
61
|
-
compound components will need to point to the appropriate root component.
|
|
62
|
-
|
|
63
|
-
## Examples
|
|
64
|
-
|
|
65
|
-
**With `components` Subdirectory:**
|
|
66
|
-
|
|
67
|
-
```
|
|
68
|
-
packages/nimbus/src/components/component-name/index.tsx
|
|
69
|
-
packages/nimbus/src/components/component-name/component-name.tsx
|
|
70
|
-
packages/nimbus/src/components/component-name/components/component-name.root.tsx
|
|
71
|
-
packages/nimbus/src/components/component-name/components/component-name.part.tsx
|
|
72
|
-
packages/nimbus/src/components/component-name/components/component-name.control.tsx
|
|
73
|
-
packages/nimbus/src/components/component-name/component-name.stories.tsx
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
## Summary
|
|
77
|
-
|
|
78
|
-
Adopting this standardized directory structure for compound components will lead
|
|
79
|
-
to a more organized, maintainable, and scalable UI Kit. By consistently
|
|
80
|
-
separating the implementation details of the root and sub-components into a
|
|
81
|
-
dedicated `components` subdirectory, we establish a clear pattern for future
|
|
82
|
-
development and refactoring efforts.
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import React, { createContext } from "react";
|
|
2
|
-
import type { DisclosureGroupState } from "react-stately";
|
|
3
|
-
|
|
4
|
-
// Define types for the item context
|
|
5
|
-
export interface ItemContextType {
|
|
6
|
-
isExpanded: boolean;
|
|
7
|
-
triggerRef: React.RefObject<HTMLButtonElement>;
|
|
8
|
-
panelRef: React.RefObject<HTMLDivElement>;
|
|
9
|
-
buttonProps: React.ButtonHTMLAttributes<HTMLButtonElement>;
|
|
10
|
-
panelProps: React.ButtonHTMLAttributes<HTMLButtonElement>;
|
|
11
|
-
isFocusVisible: boolean;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
// Create and export the contexts
|
|
15
|
-
export const ItemContext = createContext<ItemContextType | null>(null);
|
|
16
|
-
export const DisclosureGroupStateContext =
|
|
17
|
-
createContext<DisclosureGroupState | null>(null);
|