@zohodesk/components 1.6.7 → 1.6.11-exp-6
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/README.md +15 -0
- package/assets/Appearance/dark/mode/Component_v1_DarkMode.module.css +68 -0
- package/assets/Appearance/light/mode/Component_v1_LightMode.module.css +68 -0
- package/assets/Appearance/pureDark/mode/Component_v1_PureDarkMode.module.css +68 -0
- package/es/Buttongroup/Buttongroup.module.css +10 -30
- package/es/CheckBox/CheckBox.module.css +3 -10
- package/es/DateTime/DateTime.module.css +22 -35
- package/es/DateTime/YearView.module.css +8 -10
- package/es/DropBox/DropBoxElement/css/DropBoxElement.module.css +3 -2
- package/es/DropDown/DropDown.module.css +2 -1
- package/es/DropDown/DropDownItem.module.css +1 -8
- package/es/DropDown/DropDownSeparator.module.css +2 -1
- package/es/ListItem/ListItem.module.css +4 -15
- package/es/MultiSelect/MobileHeader/MobileHeader.module.css +3 -2
- package/es/MultiSelect/MultiSelect.module.css +21 -34
- package/es/MultiSelect/SelectedOptions.module.css +6 -10
- package/es/Radio/Radio.module.css +3 -3
- package/es/ResponsiveDropBox/ResponsiveDropBox.module.css +1 -1
- package/es/Ribbon/Ribbon.module.css +9 -12
- package/es/Select/Select.module.css +22 -17
- package/es/Switch/Switch.module.css +1 -8
- package/es/Tab/Tab.module.css +8 -15
- package/es/Tab/Tabs.module.css +12 -22
- package/es/Tag/Tag.module.css +4 -3
- package/es/Tooltip/Tooltip.module.css +3 -2
- package/es/Typography/Typography.js +18 -8
- package/es/Typography/__tests__/Typography.spec.js +198 -6
- package/es/Typography/__tests__/__snapshots__/Typography.spec.js.snap +1235 -2
- package/es/Typography/css/Typography.module.css +4 -0
- package/es/Typography/css/cssJSLogic.js +53 -21
- package/es/Typography/props/defaultProps.js +4 -3
- package/es/Typography/props/propTypes.js +68 -26
- package/es/Typography/utils/textHighlighter.js +4 -2
- package/es/shared/ArrowIcon/ArrowIcon.module.css +3 -2
- package/es/v1/Button/Button.js +201 -0
- package/es/v1/Button/README.md +110 -0
- package/es/v1/Button/__tests__/Button.spec.js +272 -0
- package/es/v1/Button/__tests__/__snapshots__/Button.spec.js.snap +1160 -0
- package/es/v1/Button/_shared/Loader/Loader.js +33 -0
- package/es/v1/Button/_shared/Loader/Loader.module.css +42 -0
- package/es/v1/Button/_shared/Loader/__tests__/Loader.spec.js +21 -0
- package/es/v1/Button/_shared/Loader/__tests__/__snapshots__/Loader.spec.js.snap +49 -0
- package/es/v1/Button/_shared/Loader/props/defaultProps.js +4 -0
- package/es/v1/Button/_shared/Loader/props/propTypes.js +7 -0
- package/es/v1/Button/_shared/SuccessTick/SuccessTick.js +25 -0
- package/es/v1/Button/_shared/SuccessTick/SuccessTick.module.css +21 -0
- package/es/v1/Button/_shared/SuccessTick/__tests__/SuccessTick.spec.js +21 -0
- package/es/v1/Button/_shared/SuccessTick/__tests__/__snapshots__/SuccessTick.spec.js.snap +31 -0
- package/es/v1/Button/_shared/SuccessTick/props/defaultProps.js +4 -0
- package/es/v1/Button/_shared/SuccessTick/props/propTypes.js +7 -0
- package/es/v1/Button/constants/index.js +82 -0
- package/es/v1/Button/css/Button_v1.module.css +119 -0
- package/es/v1/Button/css/cssJSLogic.js +96 -0
- package/es/v1/Button/index.js +2 -0
- package/es/v1/Button/props/defaultProps.js +26 -0
- package/es/v1/Button/props/propTypes.js +43 -0
- package/es/v1/helpers/colorHelpers/background/backgroundColor.module.css +629 -0
- package/es/v1/helpers/colorHelpers/border/borderColor.module.css +489 -0
- package/es/v1/helpers/colorHelpers/colorHelper.js +176 -0
- package/es/v1/helpers/colorHelpers/constants/index.js +79 -0
- package/es/v1/helpers/colorHelpers/index.js +4 -0
- package/es/v1/helpers/colorHelpers/paletteUtilities.README.md +415 -0
- package/es/v1/helpers/colorHelpers/text/textColor.module.css +368 -0
- package/lib/Buttongroup/Buttongroup.module.css +10 -30
- package/lib/CheckBox/CheckBox.module.css +3 -10
- package/lib/DateTime/DateTime.module.css +22 -35
- package/lib/DateTime/YearView.module.css +8 -10
- package/lib/DropBox/DropBoxElement/css/DropBoxElement.module.css +3 -2
- package/lib/DropDown/DropDown.module.css +2 -1
- package/lib/DropDown/DropDownItem.module.css +1 -8
- package/lib/DropDown/DropDownSeparator.module.css +2 -1
- package/lib/ListItem/ListItem.module.css +4 -15
- package/lib/MultiSelect/MobileHeader/MobileHeader.module.css +3 -2
- package/lib/MultiSelect/MultiSelect.module.css +21 -34
- package/lib/MultiSelect/SelectedOptions.module.css +6 -10
- package/lib/Radio/Radio.module.css +3 -3
- package/lib/ResponsiveDropBox/ResponsiveDropBox.module.css +1 -1
- package/lib/Ribbon/Ribbon.module.css +9 -12
- package/lib/Select/Select.module.css +22 -17
- package/lib/Switch/Switch.module.css +1 -8
- package/lib/Tab/Tab.module.css +8 -15
- package/lib/Tab/Tabs.module.css +12 -22
- package/lib/Tag/Tag.module.css +4 -3
- package/lib/Tooltip/Tooltip.module.css +3 -2
- package/lib/Typography/Typography.js +15 -5
- package/lib/Typography/__tests__/Typography.spec.js +284 -92
- package/lib/Typography/__tests__/__snapshots__/Typography.spec.js.snap +1235 -2
- package/lib/Typography/css/Typography.module.css +4 -0
- package/lib/Typography/css/cssJSLogic.js +38 -6
- package/lib/Typography/props/defaultProps.js +6 -3
- package/lib/Typography/props/propTypes.js +67 -23
- package/lib/Typography/utils/textHighlighter.js +6 -3
- package/lib/shared/ArrowIcon/ArrowIcon.module.css +3 -2
- package/lib/v1/Button/Button.js +239 -0
- package/lib/v1/Button/README.md +110 -0
- package/lib/v1/Button/__tests__/Button.spec.js +293 -0
- package/lib/v1/Button/__tests__/__snapshots__/Button.spec.js.snap +1160 -0
- package/lib/v1/Button/_shared/Loader/Loader.js +43 -0
- package/lib/v1/Button/_shared/Loader/Loader.module.css +42 -0
- package/lib/v1/Button/_shared/Loader/__tests__/Loader.spec.js +28 -0
- package/lib/v1/Button/_shared/Loader/__tests__/__snapshots__/Loader.spec.js.snap +49 -0
- package/lib/v1/Button/_shared/Loader/props/defaultProps.js +11 -0
- package/lib/v1/Button/_shared/Loader/props/propTypes.js +18 -0
- package/lib/v1/Button/_shared/SuccessTick/SuccessTick.js +35 -0
- package/lib/v1/Button/_shared/SuccessTick/SuccessTick.module.css +21 -0
- package/lib/v1/Button/_shared/SuccessTick/__tests__/SuccessTick.spec.js +28 -0
- package/lib/v1/Button/_shared/SuccessTick/__tests__/__snapshots__/SuccessTick.spec.js.snap +31 -0
- package/lib/v1/Button/_shared/SuccessTick/props/defaultProps.js +11 -0
- package/lib/v1/Button/_shared/SuccessTick/props/propTypes.js +18 -0
- package/lib/v1/Button/constants/index.js +114 -0
- package/lib/v1/Button/css/Button_v1.module.css +119 -0
- package/lib/v1/Button/css/cssJSLogic.js +88 -0
- package/lib/v1/Button/index.js +21 -0
- package/lib/v1/Button/props/defaultProps.js +36 -0
- package/lib/v1/Button/props/propTypes.js +56 -0
- package/lib/v1/helpers/colorHelpers/background/backgroundColor.module.css +629 -0
- package/lib/v1/helpers/colorHelpers/border/borderColor.module.css +489 -0
- package/lib/v1/helpers/colorHelpers/colorHelper.js +190 -0
- package/lib/v1/helpers/colorHelpers/constants/index.js +87 -0
- package/lib/v1/helpers/colorHelpers/index.js +57 -0
- package/lib/v1/helpers/colorHelpers/paletteUtilities.README.md +415 -0
- package/lib/v1/helpers/colorHelpers/text/textColor.module.css +368 -0
- package/package.json +9 -9
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.TONE_INTENSITY = exports.PALETTE_CONFIG = void 0;
|
|
7
|
+
var TONE_INTENSITY = {
|
|
8
|
+
brand: {
|
|
9
|
+
base: 80,
|
|
10
|
+
hover: 100,
|
|
11
|
+
light: 10,
|
|
12
|
+
lightHover: 20,
|
|
13
|
+
borderLight: 10
|
|
14
|
+
},
|
|
15
|
+
grey: {
|
|
16
|
+
base: 65,
|
|
17
|
+
hover: 55,
|
|
18
|
+
light: 10,
|
|
19
|
+
lightHover: 15,
|
|
20
|
+
borderLight: 15,
|
|
21
|
+
textHover: 100
|
|
22
|
+
},
|
|
23
|
+
blue: {
|
|
24
|
+
base: 80,
|
|
25
|
+
hover: 100,
|
|
26
|
+
light: 10,
|
|
27
|
+
lightHover: 20,
|
|
28
|
+
borderLight: 10
|
|
29
|
+
},
|
|
30
|
+
green: {
|
|
31
|
+
base: 80,
|
|
32
|
+
hover: 100,
|
|
33
|
+
light: 10,
|
|
34
|
+
lightHover: 30,
|
|
35
|
+
borderLight: 30
|
|
36
|
+
},
|
|
37
|
+
orange: {
|
|
38
|
+
base: 80,
|
|
39
|
+
hover: 100,
|
|
40
|
+
light: 10,
|
|
41
|
+
lightHover: 15,
|
|
42
|
+
borderLight: 15
|
|
43
|
+
},
|
|
44
|
+
red: {
|
|
45
|
+
base: 70,
|
|
46
|
+
hover: 100,
|
|
47
|
+
light: 10,
|
|
48
|
+
lightHover: 30,
|
|
49
|
+
borderLight: 30
|
|
50
|
+
},
|
|
51
|
+
yellow: {
|
|
52
|
+
base: 80,
|
|
53
|
+
hover: 100,
|
|
54
|
+
light: 10,
|
|
55
|
+
lightHover: 20,
|
|
56
|
+
borderLight: 20
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
exports.TONE_INTENSITY = TONE_INTENSITY;
|
|
60
|
+
var PALETTE_CONFIG = {
|
|
61
|
+
"default": {
|
|
62
|
+
tone: 'brand',
|
|
63
|
+
textTone: 'brand',
|
|
64
|
+
filledTextTone: 'brand-filled'
|
|
65
|
+
},
|
|
66
|
+
primary: {
|
|
67
|
+
tone: 'blue',
|
|
68
|
+
textTone: 'blue',
|
|
69
|
+
filledTextTone: 'white'
|
|
70
|
+
},
|
|
71
|
+
secondary: {
|
|
72
|
+
tone: 'grey',
|
|
73
|
+
textTone: 'grey',
|
|
74
|
+
filledTextTone: 'white'
|
|
75
|
+
},
|
|
76
|
+
danger: {
|
|
77
|
+
tone: 'red',
|
|
78
|
+
textTone: 'red',
|
|
79
|
+
filledTextTone: 'white'
|
|
80
|
+
},
|
|
81
|
+
success: {
|
|
82
|
+
tone: 'green',
|
|
83
|
+
textTone: 'green',
|
|
84
|
+
filledTextTone: 'white'
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
exports.PALETTE_CONFIG = PALETTE_CONFIG;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
|
|
4
|
+
|
|
5
|
+
Object.defineProperty(exports, "__esModule", {
|
|
6
|
+
value: true
|
|
7
|
+
});
|
|
8
|
+
Object.defineProperty(exports, "PALETTE_CONFIG", {
|
|
9
|
+
enumerable: true,
|
|
10
|
+
get: function get() {
|
|
11
|
+
return _constants.PALETTE_CONFIG;
|
|
12
|
+
}
|
|
13
|
+
});
|
|
14
|
+
Object.defineProperty(exports, "TONE_INTENSITY", {
|
|
15
|
+
enumerable: true,
|
|
16
|
+
get: function get() {
|
|
17
|
+
return _constants.TONE_INTENSITY;
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
Object.defineProperty(exports, "default", {
|
|
21
|
+
enumerable: true,
|
|
22
|
+
get: function get() {
|
|
23
|
+
return _colorHelper["default"];
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
Object.defineProperty(exports, "getBgClass", {
|
|
27
|
+
enumerable: true,
|
|
28
|
+
get: function get() {
|
|
29
|
+
return _colorHelper.getBgClass;
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
Object.defineProperty(exports, "getBorderClass", {
|
|
33
|
+
enumerable: true,
|
|
34
|
+
get: function get() {
|
|
35
|
+
return _colorHelper.getBorderClass;
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
Object.defineProperty(exports, "getPaletteClasses", {
|
|
39
|
+
enumerable: true,
|
|
40
|
+
get: function get() {
|
|
41
|
+
return _colorHelper["default"];
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
Object.defineProperty(exports, "getTextClass", {
|
|
45
|
+
enumerable: true,
|
|
46
|
+
get: function get() {
|
|
47
|
+
return _colorHelper.getTextClass;
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
var _colorHelper = _interopRequireWildcard(require("./colorHelper"));
|
|
52
|
+
|
|
53
|
+
var _constants = require("./constants");
|
|
54
|
+
|
|
55
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
56
|
+
|
|
57
|
+
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
@@ -0,0 +1,415 @@
|
|
|
1
|
+
# Color Helpers
|
|
2
|
+
|
|
3
|
+
Tailwind-inspired color utility classes and a `colorHelper` for DOT components.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## File Structure
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
colorHelpers/
|
|
11
|
+
├── background/
|
|
12
|
+
│ └── backgroundColor.module.css # Background color utilities
|
|
13
|
+
├── text/
|
|
14
|
+
│ └── textColor.module.css # Text color utilities
|
|
15
|
+
├── border/
|
|
16
|
+
│ └── borderColor.module.css # Border color utilities
|
|
17
|
+
├── constants/
|
|
18
|
+
│ └── index.js # PALETTE_CONFIG (palette → tone mapping)
|
|
19
|
+
├── colorHelper.js # getPaletteClasses + getBgClass, getTextClass, getBorderClass
|
|
20
|
+
└── paletteUtilities.README.md # This file
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Available Colors
|
|
26
|
+
|
|
27
|
+
All three CSS files share the same 7 color tones:
|
|
28
|
+
|
|
29
|
+
| Tone | Token Family | Use Case |
|
|
30
|
+
|------|--------------|----------|
|
|
31
|
+
| **default** | `--zdt_v1_palette_default_*` | Default/neutral actions |
|
|
32
|
+
| **grey** | `--zdt_v1_palette_grey_*` | Secondary, muted elements |
|
|
33
|
+
| **blue** | `--zdt_v1_palette_blue_*` | Information, primary actions |
|
|
34
|
+
| **green** | `--zdt_v1_palette_green_*` | Success, positive status |
|
|
35
|
+
| **orange** | `--zdt_v1_palette_orange_*` | Warning, caution |
|
|
36
|
+
| **red** | `--zdt_v1_palette_red_*` | Error, danger, destructive actions |
|
|
37
|
+
| **yellow** | `--zdt_v1_palette_yellow_*` | Alerts, highlights |
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Available Utilities
|
|
42
|
+
|
|
43
|
+
### Background (`background/backgroundColor.module.css`)
|
|
44
|
+
|
|
45
|
+
Per color (`default`, `grey`, `blue`, `green`, `orange`, `red`, `yellow`):
|
|
46
|
+
|
|
47
|
+
| Class Pattern | Description |
|
|
48
|
+
|---------------|-------------|
|
|
49
|
+
| `.bg-{color}` | Base background |
|
|
50
|
+
| `.bg-{color}-light` | Light background variant |
|
|
51
|
+
| `.hover\:bg-{color}:hover` | Hover state |
|
|
52
|
+
| `.hover\:bg-{color}-light:hover` | Light hover state |
|
|
53
|
+
| `.focus\:bg-{color}:focus` | Focus state |
|
|
54
|
+
| `.focus\:bg-{color}-light:focus` | Light focus state |
|
|
55
|
+
| `.active\:bg-{color}:active` | Active state |
|
|
56
|
+
| `.active\:bg-{color}-light:active` | Light active state |
|
|
57
|
+
| `.selected\:bg-{color}` | Selected state |
|
|
58
|
+
| `.selected\:bg-{color}-light` | Light selected state |
|
|
59
|
+
|
|
60
|
+
**Utility classes:** `.bg-transparent`, `.bg-white`, `.bg-black`
|
|
61
|
+
|
|
62
|
+
### Text (`text/textColor.module.css`)
|
|
63
|
+
|
|
64
|
+
Per color (`default`, `grey`, `blue`, `green`, `orange`, `red`, `yellow`):
|
|
65
|
+
|
|
66
|
+
| Class Pattern | Description |
|
|
67
|
+
|---------------|-------------|
|
|
68
|
+
| `.text-{color}` | Base text color |
|
|
69
|
+
| `.hover\:text-{color}:hover` | Hover state |
|
|
70
|
+
| `.focus\:text-{color}:focus` | Focus state |
|
|
71
|
+
| `.active\:text-{color}:active` | Active state |
|
|
72
|
+
| `.selected\:text-{color}` | Selected state |
|
|
73
|
+
|
|
74
|
+
**Special:** `.text-default-filled` (+ hover/focus/active/selected) — uses `--zdt_v1_palette_default_filled_text` for filled default backgrounds.
|
|
75
|
+
|
|
76
|
+
**Utility classes:** `.text-transparent`, `.text-white`, `.text-black`
|
|
77
|
+
|
|
78
|
+
> **Note:** Text has no `-light` variant. The `colorHelper` switches to `filledTextTone` (e.g., `white`) when the background is filled.
|
|
79
|
+
|
|
80
|
+
### Border (`border/borderColor.module.css`)
|
|
81
|
+
|
|
82
|
+
Per color (`default`, `grey`, `blue`, `green`, `orange`, `red`, `yellow`):
|
|
83
|
+
|
|
84
|
+
| Class Pattern | Description |
|
|
85
|
+
|---------------|-------------|
|
|
86
|
+
| `.border-{color}` | Base border |
|
|
87
|
+
| `.border-{color}-light` | Light border variant (resting state only) |
|
|
88
|
+
| `.hover\:border-{color}:hover` | Hover state |
|
|
89
|
+
| `.focus\:border-{color}:focus` | Focus state |
|
|
90
|
+
| `.active\:border-{color}:active` | Active state |
|
|
91
|
+
| `.selected\:border-{color}` | Selected state |
|
|
92
|
+
|
|
93
|
+
**Utility classes:** `.border-transparent`, `.border-white`, `.border-black`
|
|
94
|
+
|
|
95
|
+
> **Note:** Border state classes only use the base tone — no `-light` state variants. The `-light` class is available for the resting state only.
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## Direct CSS Usage (Examples)
|
|
100
|
+
|
|
101
|
+
Import only the CSS modules you need and compose classes directly.
|
|
102
|
+
|
|
103
|
+
### Example 1: Status Tag (text + background)
|
|
104
|
+
|
|
105
|
+
```javascript
|
|
106
|
+
import bgStyle from './background/backgroundColor.module.css';
|
|
107
|
+
import textStyle from './text/textColor.module.css';
|
|
108
|
+
|
|
109
|
+
function StatusTag({ status }) {
|
|
110
|
+
const className = compileClassNames({
|
|
111
|
+
[bgStyle['bg-green-light']]: status === 'success',
|
|
112
|
+
[bgStyle['bg-red-light']]: status === 'error',
|
|
113
|
+
[bgStyle['bg-orange-light']]: status === 'warning',
|
|
114
|
+
[textStyle['text-green']]: status === 'success',
|
|
115
|
+
[textStyle['text-red']]: status === 'error',
|
|
116
|
+
[textStyle['text-orange']]: status === 'warning',
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
return <span className={className}>{status}</span>;
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Example 2: Bordered Card (border + background)
|
|
124
|
+
|
|
125
|
+
```javascript
|
|
126
|
+
import bgStyle from './background/backgroundColor.module.css';
|
|
127
|
+
import borderStyle from './border/borderColor.module.css';
|
|
128
|
+
|
|
129
|
+
function Card({ children, variant }) {
|
|
130
|
+
const className = compileClassNames({
|
|
131
|
+
[bgStyle['bg-blue-light']]: variant === 'info',
|
|
132
|
+
[bgStyle['bg-red-light']]: variant === 'error',
|
|
133
|
+
[borderStyle['border-blue']]: variant === 'info',
|
|
134
|
+
[borderStyle['border-red']]: variant === 'error',
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
return <div className={className}>{children}</div>;
|
|
138
|
+
}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Example 3: Interactive Button (text + background + border + hover)
|
|
142
|
+
|
|
143
|
+
```javascript
|
|
144
|
+
import bgStyle from './background/backgroundColor.module.css';
|
|
145
|
+
import textStyle from './text/textColor.module.css';
|
|
146
|
+
import borderStyle from './border/borderColor.module.css';
|
|
147
|
+
|
|
148
|
+
function Button({ label, variant }) {
|
|
149
|
+
// Primary: blue bg, white text, blue border
|
|
150
|
+
const primaryClasses = compileClassNames({
|
|
151
|
+
[bgStyle['bg-blue']]: true,
|
|
152
|
+
[bgStyle['hover:bg-blue']]: true,
|
|
153
|
+
[textStyle['text-white']]: true,
|
|
154
|
+
[borderStyle['border-blue']]: true,
|
|
155
|
+
[borderStyle['hover:border-blue']]: true,
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
// Danger: red bg, white text, red border
|
|
159
|
+
const dangerClasses = compileClassNames({
|
|
160
|
+
[bgStyle['bg-red']]: true,
|
|
161
|
+
[bgStyle['hover:bg-red']]: true,
|
|
162
|
+
[textStyle['text-white']]: true,
|
|
163
|
+
[borderStyle['border-red']]: true,
|
|
164
|
+
[borderStyle['hover:border-red']]: true,
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
return <button className={variant === 'danger' ? dangerClasses : primaryClasses}>{label}</button>;
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## Using `colorHelper.js`
|
|
173
|
+
|
|
174
|
+
### Named Exports
|
|
175
|
+
|
|
176
|
+
Three utility functions return individual CSS module classes:
|
|
177
|
+
|
|
178
|
+
```javascript
|
|
179
|
+
import { getBgClass, getTextClass, getBorderClass } from './colorHelper';
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
#### `getBgClass({ state?, tone, isLighter? })`
|
|
183
|
+
|
|
184
|
+
Returns a background CSS class from `backgroundColor.module.css`.
|
|
185
|
+
|
|
186
|
+
| Parameter | Type | Required | Description |
|
|
187
|
+
|-----------|------|----------|-------------|
|
|
188
|
+
| `tone` | `string` | Yes | Color tone (`default`, `grey`, `blue`, `green`, `orange`, `red`, `yellow`, `white`, `black`) |
|
|
189
|
+
| `state` | `string` | No | State prefix (`hover`, `focus`, `active`, `selected`). Omit for base class. |
|
|
190
|
+
| `isLighter` | `boolean` | No | `true` → appends `-light` to the tone |
|
|
191
|
+
|
|
192
|
+
**Generated key pattern:** `[state:]bg-{tone}[-light]`
|
|
193
|
+
|
|
194
|
+
```javascript
|
|
195
|
+
getBgClass({ tone: 'blue' }) // → paletteBgStyle['bg-blue']
|
|
196
|
+
getBgClass({ tone: 'blue', isLighter: true }) // → paletteBgStyle['bg-blue-light']
|
|
197
|
+
getBgClass({ state: 'hover', tone: 'red' }) // → paletteBgStyle['hover:bg-red']
|
|
198
|
+
getBgClass({ state: 'hover', tone: 'red', isLighter: true }) // → paletteBgStyle['hover:bg-red-light']
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
#### `getTextClass({ state?, textTone })`
|
|
202
|
+
|
|
203
|
+
Returns a text CSS class from `textColor.module.css`.
|
|
204
|
+
|
|
205
|
+
| Parameter | Type | Required | Description |
|
|
206
|
+
|-----------|------|----------|-------------|
|
|
207
|
+
| `textTone` | `string` | Yes | Text tone (`default`, `grey`, `blue`, `green`, `orange`, `red`, `yellow`, `white`, `black`, `default-filled`) |
|
|
208
|
+
| `state` | `string` | No | State prefix (`hover`, `focus`, `active`, `selected`). Omit for base class. |
|
|
209
|
+
|
|
210
|
+
> **Note:** `textTone` has no `isLighter` equivalent. Use `filledTextTone` (e.g. `white`) directly when needed.
|
|
211
|
+
|
|
212
|
+
**Generated key pattern:** `[state:]text-{textTone}`
|
|
213
|
+
|
|
214
|
+
```javascript
|
|
215
|
+
getTextClass({ textTone: 'green' }) // → paletteTextStyle['text-green']
|
|
216
|
+
getTextClass({ state: 'hover', textTone: 'white' }) // → paletteTextStyle['hover:text-white']
|
|
217
|
+
getTextClass({ textTone: 'default-filled' }) // → paletteTextStyle['text-default-filled']
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
#### `getBorderClass({ state?, tone, isLighter? })`
|
|
221
|
+
|
|
222
|
+
Returns a border CSS class from `borderColor.module.css`.
|
|
223
|
+
|
|
224
|
+
| Parameter | Type | Required | Description |
|
|
225
|
+
|-----------|------|----------|-------------|
|
|
226
|
+
| `tone` | `string` | Yes | Color tone (`default`, `grey`, `blue`, `green`, `orange`, `red`, `yellow`) |
|
|
227
|
+
| `state` | `string` | No | State prefix (`hover`, `focus`, `active`, `selected`). Omit for base class. |
|
|
228
|
+
| `isLighter` | `boolean` | No | `true` → appends `-light` to the tone (resting state only by convention) |
|
|
229
|
+
|
|
230
|
+
**Generated key pattern:** `[state:]border-{tone}[-light]`
|
|
231
|
+
|
|
232
|
+
```javascript
|
|
233
|
+
getBorderClass({ tone: 'blue' }) // → paletteBorderStyle['border-blue']
|
|
234
|
+
getBorderClass({ tone: 'blue', isLighter: true }) // → paletteBorderStyle['border-blue-light']
|
|
235
|
+
getBorderClass({ state: 'hover', tone: 'red' }) // → paletteBorderStyle['hover:border-red']
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
#### Internal Helpers (not exported)
|
|
239
|
+
|
|
240
|
+
- **`toTone(tone, isLighter)`** — returns `'{tone}-light'` if `isLighter` is truthy, else `'{tone}'`
|
|
241
|
+
- **`withState(state, key)`** — returns `'{state}:{key}'` if `state` is truthy, else `'{key}'`
|
|
242
|
+
|
|
243
|
+
---
|
|
244
|
+
|
|
245
|
+
### Default Export: `getPaletteClasses`
|
|
246
|
+
|
|
247
|
+
For components accepting `palette`, `bgAppearance`, `borderAppearance`, and `paletteShade` props.
|
|
248
|
+
|
|
249
|
+
```javascript
|
|
250
|
+
import getPaletteClasses from './colorHelper';
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
#### Palette → Tone Mapping (from `PALETTE_CONFIG`)
|
|
254
|
+
|
|
255
|
+
| Palette | Tone (bg/border) | Text Tone | Filled Text Tone |
|
|
256
|
+
|---------|-------------------|-----------|-------------------|
|
|
257
|
+
| `default` | `default` | `default` | `default-filled` |
|
|
258
|
+
| `primary` | `blue` | `blue` | `white` |
|
|
259
|
+
| `secondary` | `grey` | `grey` | `white` |
|
|
260
|
+
| `danger` | `red` | `red` | `white` |
|
|
261
|
+
| `success` | `green` | `green` | `white` |
|
|
262
|
+
|
|
263
|
+
Unknown palettes return `DUMMY_OBJECT` (empty frozen object).
|
|
264
|
+
|
|
265
|
+
#### Parameters
|
|
266
|
+
|
|
267
|
+
| Parameter | Values | Effect |
|
|
268
|
+
|-----------|--------|--------|
|
|
269
|
+
| `palette` | `default` \| `primary` \| `secondary` \| `danger` \| `success` | Selects the color tone config from `PALETTE_CONFIG` |
|
|
270
|
+
| `bgAppearance` | `'none'` \| `'filled'` \| other | `'filled'` → base bg + state bg; `'none'` → no bg, no state bg, no filled text logic; other → no base bg but state bg + filled text logic |
|
|
271
|
+
| `borderAppearance` | `'none'` \| `'onHover'` \| other | `'none'` → transparent base, no state borders; `'onHover'` → transparent base, with state borders; other → visible base + state borders |
|
|
272
|
+
| `paletteShade` | `'lighter'` \| other | `'lighter'` → `-light` variant for bg and base border; also keeps text as `textTone` instead of `filledTextTone` |
|
|
273
|
+
|
|
274
|
+
#### Text Tone Logic
|
|
275
|
+
|
|
276
|
+
The text color depends on both `bgAppearance` and `paletteShade`:
|
|
277
|
+
|
|
278
|
+
| Condition | Base text (`text`) | State text (`hoverText`, etc.) |
|
|
279
|
+
|---|---|---|
|
|
280
|
+
| `bgAppearance: 'filled'` + default shade | `filledTextTone` (e.g. `white`) | `filledTextTone` |
|
|
281
|
+
| `bgAppearance: 'filled'` + `'lighter'` shade | `textTone` (e.g. `blue`) | `textTone` |
|
|
282
|
+
| `bgAppearance:` other (not `'none'`) + default shade | `textTone` | `filledTextTone` |
|
|
283
|
+
| `bgAppearance:` other (not `'none'`) + `'lighter'` shade | `textTone` | `textTone` |
|
|
284
|
+
| `bgAppearance: 'none'` | `textTone` | `textTone` |
|
|
285
|
+
|
|
286
|
+
> **Key insight:** `baseTextTone = isFilledBg && !isLighter ? filledTextTone : textTone`. `stateTextTone = hasBgState && !isLighter ? filledTextTone : textTone`. This means state text can differ from base text when `bgAppearance` is not `'filled'` but also not `'none'`.
|
|
287
|
+
|
|
288
|
+
#### Return Value
|
|
289
|
+
|
|
290
|
+
```javascript
|
|
291
|
+
{
|
|
292
|
+
bg, // getBgClass({ tone, isLighter }) — only if bgAppearance === 'filled'
|
|
293
|
+
hoverBg, // getBgClass({ state: 'hover', tone, isLighter }) — if bgAppearance !== 'none'
|
|
294
|
+
focusBg, // getBgClass({ state: 'focus', tone, isLighter }) — if bgAppearance !== 'none'
|
|
295
|
+
activeBg, // getBgClass({ state: 'active', tone, isLighter }) — if bgAppearance !== 'none'
|
|
296
|
+
selectedBg, // getBgClass({ state: 'selected', tone, isLighter }) — if bgAppearance !== 'none'
|
|
297
|
+
text, // getTextClass({ textTone: baseTextTone })
|
|
298
|
+
hoverText, // getTextClass({ state: 'hover', textTone: stateTextTone })
|
|
299
|
+
focusText, // getTextClass({ state: 'focus', textTone: stateTextTone })
|
|
300
|
+
activeText, // getTextClass({ state: 'active', textTone: stateTextTone })
|
|
301
|
+
selectedText, // getTextClass({ state: 'selected', textTone: stateTextTone })
|
|
302
|
+
border, // 'border-transparent' if onHover/none — else getBorderClass({ tone, isLighter })
|
|
303
|
+
hoverBorder, // getBorderClass({ state: 'hover', tone }) — if borderAppearance !== 'none'
|
|
304
|
+
focusBorder, // getBorderClass({ state: 'focus', tone }) — if borderAppearance !== 'none'
|
|
305
|
+
activeBorder, // getBorderClass({ state: 'active', tone }) — if borderAppearance !== 'none'
|
|
306
|
+
selectedBorder // getBorderClass({ state: 'selected', tone }) — if borderAppearance !== 'none'
|
|
307
|
+
}
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
> **Note:** State border classes always use the base tone (no `isLighter`), even when the resting border uses `-light`.
|
|
311
|
+
|
|
312
|
+
#### Example: Filled Primary Button
|
|
313
|
+
|
|
314
|
+
```javascript
|
|
315
|
+
const classes = getPaletteClasses({
|
|
316
|
+
palette: 'primary',
|
|
317
|
+
bgAppearance: 'filled',
|
|
318
|
+
borderAppearance: 'visible',
|
|
319
|
+
paletteShade: 'default',
|
|
320
|
+
});
|
|
321
|
+
// classes.bg → 'bg-blue' (filled + default shade)
|
|
322
|
+
// classes.hoverBg → 'hover:bg-blue'
|
|
323
|
+
// classes.text → 'text-white' (filledTextTone — filled + not lighter)
|
|
324
|
+
// classes.hoverText → 'hover:text-white' (filledTextTone — hasBgState + not lighter)
|
|
325
|
+
// classes.border → 'border-blue' (visible appearance)
|
|
326
|
+
// classes.hoverBorder → 'hover:border-blue'
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
#### Example: Light Danger Tag
|
|
330
|
+
|
|
331
|
+
```javascript
|
|
332
|
+
const classes = getPaletteClasses({
|
|
333
|
+
palette: 'danger',
|
|
334
|
+
bgAppearance: 'filled',
|
|
335
|
+
borderAppearance: 'none',
|
|
336
|
+
paletteShade: 'lighter',
|
|
337
|
+
});
|
|
338
|
+
// classes.bg → 'bg-red-light' (filled + lighter shade)
|
|
339
|
+
// classes.hoverBg → 'hover:bg-red-light'
|
|
340
|
+
// classes.text → 'text-red' (textTone — lighter shade overrides filledTextTone)
|
|
341
|
+
// classes.hoverText → 'hover:text-red' (textTone — lighter shade)
|
|
342
|
+
// classes.border → 'border-transparent' (borderAppearance: 'none')
|
|
343
|
+
// classes.hoverBorder → undefined (no state borders with 'none')
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
#### Example: Ghost Secondary Button
|
|
347
|
+
|
|
348
|
+
```javascript
|
|
349
|
+
const classes = getPaletteClasses({
|
|
350
|
+
palette: 'secondary',
|
|
351
|
+
bgAppearance: 'none',
|
|
352
|
+
borderAppearance: 'onHover',
|
|
353
|
+
paletteShade: 'default',
|
|
354
|
+
});
|
|
355
|
+
// classes.bg → undefined (not filled)
|
|
356
|
+
// classes.hoverBg → undefined (bgAppearance: 'none')
|
|
357
|
+
// classes.text → 'text-grey' (textTone — not filled)
|
|
358
|
+
// classes.hoverText → 'hover:text-grey' (textTone — bgAppearance 'none' → no filled text)
|
|
359
|
+
// classes.border → 'border-transparent' (onHover → transparent base)
|
|
360
|
+
// classes.hoverBorder → 'hover:border-grey' (onHover → state borders present)
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
#### Example: Hover-fill Button (bgAppearance: non-standard value)
|
|
364
|
+
|
|
365
|
+
```javascript
|
|
366
|
+
const classes = getPaletteClasses({
|
|
367
|
+
palette: 'primary',
|
|
368
|
+
bgAppearance: 'hover-fill', // any value that isn't 'none' or 'filled'
|
|
369
|
+
borderAppearance: 'visible',
|
|
370
|
+
paletteShade: 'default',
|
|
371
|
+
});
|
|
372
|
+
// classes.bg → undefined (not 'filled' → no base bg)
|
|
373
|
+
// classes.hoverBg → 'hover:bg-blue' (not 'none' → state bg present)
|
|
374
|
+
// classes.text → 'text-blue' (baseTextTone — not filled, so textTone)
|
|
375
|
+
// classes.hoverText → 'hover:text-white' (stateTextTone — hasBgState + not lighter → filledTextTone!)
|
|
376
|
+
// classes.border → 'border-blue' (visible)
|
|
377
|
+
// classes.hoverBorder → 'hover:border-blue'
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
> This shows a key behavior: the base text is the normal tone, but **state text switches to `filledTextTone`** because the hover/state background will be filled (dark).
|
|
381
|
+
|
|
382
|
+
---
|
|
383
|
+
|
|
384
|
+
## Behavior Summary
|
|
385
|
+
|
|
386
|
+
| Property | Lighter shade (`paletteShade: 'lighter'`) | Default shade |
|
|
387
|
+
|----------|-------------------------------------------|---------------|
|
|
388
|
+
| **Background** | Uses `-light` variant (e.g. `bg-blue-light`) | Uses base (e.g. `bg-blue`) |
|
|
389
|
+
| **Base text** | Always `textTone` (e.g. `text-blue`) | `filledTextTone` when filled (e.g. `text-white`), else `textTone` |
|
|
390
|
+
| **State text** | Always `textTone` (e.g. `hover:text-blue`) | `filledTextTone` when `bgAppearance !== 'none'` (e.g. `hover:text-white`), else `textTone` |
|
|
391
|
+
| **Border (base)** | Uses `-light` variant if not transparent (e.g. `border-blue-light`) | Uses base if not transparent (e.g. `border-blue`) |
|
|
392
|
+
| **Border (states)** | Always base tone (e.g. `hover:border-blue`) | Always base tone |
|
|
393
|
+
|
|
394
|
+
---
|
|
395
|
+
|
|
396
|
+
## FAQ
|
|
397
|
+
|
|
398
|
+
**Q: Why do text classes have no `-light` variant?**
|
|
399
|
+
A: Text on a light background should stay the base color for readability. When the background is filled (dark), text switches to a contrasting tone (e.g. `white`) instead.
|
|
400
|
+
|
|
401
|
+
**Q: Why do border state classes not use `-light`?**
|
|
402
|
+
A: Border hover/focus/active/selected states always use the full-intensity base tone for visibility, even when the resting border uses a lighter shade.
|
|
403
|
+
|
|
404
|
+
**Q: What happens if I pass an unknown palette to `getPaletteClasses`?**
|
|
405
|
+
A: It returns `DUMMY_OBJECT` (an empty frozen object), so no classes are applied.
|
|
406
|
+
|
|
407
|
+
**Q: Can I use CSS classes directly without `getPaletteClasses`?**
|
|
408
|
+
A: Yes. The CSS modules are standalone. `getPaletteClasses` is a convenience for components that accept palette/appearance/shade props.
|
|
409
|
+
|
|
410
|
+
**Q: When does state text differ from base text?**
|
|
411
|
+
A: When `bgAppearance` is neither `'none'` nor `'filled'` with default (non-lighter) shade. Base text uses `textTone` (colored), but state text uses `filledTextTone` (e.g. `white`) — because the hover/state will show a filled background.
|
|
412
|
+
|
|
413
|
+
---
|
|
414
|
+
|
|
415
|
+
**Last Updated:** March 2026
|