pixelize-design-library 2.4.2-beta.4 → 2.4.2-beta.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Components/ButtonGroupIcon/ButtonGroupIcon.js +1 -1
- package/dist/Components/Checkbox/Checkbox.styles.js +2 -0
- package/dist/Components/DatePicker/RangeDatePicker.js +1 -1
- package/dist/Components/DatePicker/SingleDatePicker.js +1 -1
- package/dist/Components/Form/FormWrapper.js +1 -1
- package/dist/Components/Input/TextInput.styles.js +6 -7
- package/dist/Components/InputTextArea/InputTextArea.style.js +5 -3
- package/dist/Components/NavigationBar/NavigationBar.js +3 -3
- package/dist/Components/NoteTextArea/NoteTextArea.js +6 -2
- package/dist/Components/NumberInput/NumberInput.styles.js +5 -3
- package/dist/Components/ProfileCard/ProfileCard.js +1 -1
- package/dist/Components/SearchSelect/SearchSelect.js +2 -1
- package/dist/Components/Select/Select.styles.js +2 -0
- package/dist/Components/SelectSearch/SelectSearch.js +1 -1
- package/dist/Components/SelectV2/SelectV2.js +3 -2
- package/dist/Components/SideBar/SecondaryBar.js +1 -1
- package/dist/Components/Table/Table.js +4 -2
- package/dist/Components/Table/components/TableActions.js +2 -2
- package/dist/Components/Table/components/TableBody.js +1 -1
- package/dist/Components/Table/components/TableGroupRow.js +1 -1
- package/dist/Components/Table/components/TableHeader.js +4 -4
- package/dist/Components/Table/components/TableSearch.js +1 -1
- package/dist/Components/Table/settings/ManageColumns.js +1 -1
- package/dist/Components/Table/settings/TableSettings.js +2 -2
- package/dist/Components/Trail/TrailWorks.js +1 -1
- package/dist/Theme/chakra/Menu.styles.d.ts +1 -1
- package/dist/Theme/chakra/Menu.styles.js +3 -3
- package/dist/Theme/chakra/Popover.styles.d.ts +1 -0
- package/dist/Theme/chakra/Popover.styles.js +3 -1
- package/dist/Theme/chakra/componentStyles.d.ts +4 -3
- package/dist/Theme/provider/ThemeSwitcher.js +5 -2
- package/dist/Theme/tokens/builders/chartColorsFromTheme.js +1 -1
- package/dist/Theme/tokens/builders/index.d.ts +1 -0
- package/dist/Theme/tokens/builders/index.js +1 -0
- package/dist/Theme/tokens/builders/placeholderInk.d.ts +19 -0
- package/dist/Theme/tokens/builders/placeholderInk.js +33 -0
- package/dist/Theme/tokens/builders/resolvedRungs.d.ts +5 -1
- package/dist/Theme/tokens/builders/resolvedRungs.js +7 -2
- package/dist/Theme/tokens/builders/surfaceRungs.d.ts +5 -2
- package/dist/Theme/tokens/builders/surfaceRungs.js +8 -9
- package/dist/esm/Components/ButtonGroupIcon/ButtonGroupIcon.js +1 -1
- package/dist/esm/Components/Checkbox/Checkbox.styles.js +2 -0
- package/dist/esm/Components/DatePicker/RangeDatePicker.js +1 -1
- package/dist/esm/Components/DatePicker/SingleDatePicker.js +1 -1
- package/dist/esm/Components/Form/FormWrapper.js +1 -1
- package/dist/esm/Components/Input/TextInput.styles.js +6 -7
- package/dist/esm/Components/InputTextArea/InputTextArea.style.js +5 -3
- package/dist/esm/Components/NavigationBar/NavigationBar.js +3 -3
- package/dist/esm/Components/NoteTextArea/NoteTextArea.js +6 -2
- package/dist/esm/Components/NumberInput/NumberInput.styles.js +5 -3
- package/dist/esm/Components/ProfileCard/ProfileCard.js +1 -1
- package/dist/esm/Components/SearchSelect/SearchSelect.js +2 -1
- package/dist/esm/Components/Select/Select.styles.js +2 -0
- package/dist/esm/Components/SelectSearch/SelectSearch.js +1 -1
- package/dist/esm/Components/SelectV2/SelectV2.js +3 -2
- package/dist/esm/Components/SideBar/SecondaryBar.js +1 -1
- package/dist/esm/Components/Table/Table.js +4 -2
- package/dist/esm/Components/Table/components/TableActions.js +2 -2
- package/dist/esm/Components/Table/components/TableBody.js +1 -1
- package/dist/esm/Components/Table/components/TableGroupRow.js +1 -1
- package/dist/esm/Components/Table/components/TableHeader.js +4 -4
- package/dist/esm/Components/Table/components/TableSearch.js +1 -1
- package/dist/esm/Components/Table/settings/ManageColumns.js +1 -1
- package/dist/esm/Components/Table/settings/TableSettings.js +2 -2
- package/dist/esm/Components/Trail/TrailWorks.js +1 -1
- package/dist/esm/Theme/chakra/Menu.styles.js +3 -3
- package/dist/esm/Theme/chakra/Popover.styles.js +3 -1
- package/dist/esm/Theme/provider/ThemeSwitcher.js +5 -2
- package/dist/esm/Theme/tokens/builders/chartColorsFromTheme.js +1 -1
- package/dist/esm/Theme/tokens/builders/index.js +1 -0
- package/dist/esm/Theme/tokens/builders/placeholderInk.js +27 -0
- package/dist/esm/Theme/tokens/builders/resolvedRungs.js +7 -2
- package/dist/esm/Theme/tokens/builders/surfaceRungs.js +9 -10
- package/dist/esm/index.js +2 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +9 -1
- package/package.json +4 -2
|
@@ -5,7 +5,7 @@ const react_1 = require("@chakra-ui/react");
|
|
|
5
5
|
const useCustomTheme_1 = require("../../Theme/useCustomTheme");
|
|
6
6
|
const TrailWorks = () => {
|
|
7
7
|
const { colors } = (0, useCustomTheme_1.useCustomTheme)();
|
|
8
|
-
const cellBorder = colors.
|
|
8
|
+
const cellBorder = colors.boxborder[200];
|
|
9
9
|
const data = [
|
|
10
10
|
{
|
|
11
11
|
contact: "John Doe",
|
|
@@ -31,9 +31,9 @@ const baseStyle = definePartsStyle(({ theme }) => {
|
|
|
31
31
|
[$bg.variable]: colors.backgroundColor.light,
|
|
32
32
|
bg: $bg.reference,
|
|
33
33
|
color: colors.text[900],
|
|
34
|
-
//
|
|
35
|
-
//
|
|
36
|
-
|
|
34
|
+
// An elevated surface is separated by its shadow, not a rule. Chakra's default
|
|
35
|
+
// gray.200 border read as a hard edge against our surfaces.
|
|
36
|
+
borderWidth: 0,
|
|
37
37
|
},
|
|
38
38
|
// Own CSS var (`--menu-item-bg`), NOT the list's `--menu-bg` — Chakra's stock item
|
|
39
39
|
// baseStyle rewrites `--menu-bg` itself on hover/focus, so reusing that same var name
|
|
@@ -21,8 +21,10 @@ const baseStyle = definePartsStyle(({ theme }) => {
|
|
|
21
21
|
content: {
|
|
22
22
|
[$popperBg.variable]: colors.backgroundColor.light,
|
|
23
23
|
bg: $popperBg.reference,
|
|
24
|
-
[$arrowShadowColor.variable]: colors.
|
|
24
|
+
[$arrowShadowColor.variable]: colors.boxborder[200],
|
|
25
25
|
color: colors.text[900],
|
|
26
|
+
// Elevated surfaces are separated by their shadow, not a rule.
|
|
27
|
+
borderWidth: 0,
|
|
26
28
|
},
|
|
27
29
|
};
|
|
28
30
|
});
|
|
@@ -70,10 +70,10 @@ export declare const componentStyles: {
|
|
|
70
70
|
Menu: {
|
|
71
71
|
baseStyle?: (({ theme }: StyleFunctionProps) => {
|
|
72
72
|
list: {
|
|
73
|
-
[x: string]: string;
|
|
73
|
+
[x: string]: string | number;
|
|
74
74
|
bg: string;
|
|
75
75
|
color: string;
|
|
76
|
-
|
|
76
|
+
borderWidth: number;
|
|
77
77
|
};
|
|
78
78
|
item: {
|
|
79
79
|
bg: string;
|
|
@@ -140,9 +140,10 @@ export declare const componentStyles: {
|
|
|
140
140
|
Popover: {
|
|
141
141
|
baseStyle?: (({ theme }: StyleFunctionProps) => {
|
|
142
142
|
content: {
|
|
143
|
-
[x: string]: string;
|
|
143
|
+
[x: string]: string | number;
|
|
144
144
|
bg: string;
|
|
145
145
|
color: string;
|
|
146
|
+
borderWidth: number;
|
|
146
147
|
};
|
|
147
148
|
}) | undefined;
|
|
148
149
|
sizes?: {
|
|
@@ -26,7 +26,10 @@ const toBrandLabel = (brand) => brand.charAt(0).toUpperCase() + brand.slice(1);
|
|
|
26
26
|
* regardless of which brand/mode is currently active.
|
|
27
27
|
*/
|
|
28
28
|
const brandSwatchColor = (brand) => index_1.brandThemes[brand].light.colors.primary[500];
|
|
29
|
-
const BrandSwatch = ({ brand }) =>
|
|
29
|
+
const BrandSwatch = ({ brand }) => {
|
|
30
|
+
const { colors } = (0, useCustomTheme_1.useCustomTheme)();
|
|
31
|
+
return ((0, jsx_runtime_1.jsx)(react_2.Box, { as: "span", display: "inline-block", w: "0.625rem", h: "0.625rem", borderRadius: "full", bg: brandSwatchColor(brand), border: "1px solid", borderColor: colors.boxborder[200], flexShrink: 0 }));
|
|
32
|
+
};
|
|
30
33
|
/**
|
|
31
34
|
* Palette values already differ per color mode (`brandThemes[brand].light|dark`), so tokens
|
|
32
35
|
* are read straight from the active theme — no `useColorModeValue` pairing needed here.
|
|
@@ -39,7 +42,7 @@ const useSwitcherColors = () => {
|
|
|
39
42
|
activeColor: colors.primary[500],
|
|
40
43
|
mutedColor: colors.text[600],
|
|
41
44
|
hoverBg: colors.gray[100],
|
|
42
|
-
borderColor: colors.
|
|
45
|
+
borderColor: colors.boxborder[200],
|
|
43
46
|
// NOTE: menuBg lives in Menu.styles.ts — re-pushing it via `sx` flickers on every render.
|
|
44
47
|
menuColor: colors.text[900],
|
|
45
48
|
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { PaletteProps } from "../types";
|
|
2
|
+
/** A field always renders on at least one surface — the first is the reference backdrop. */
|
|
3
|
+
export type FieldSurfaces = readonly [string, ...string[]];
|
|
4
|
+
/**
|
|
5
|
+
* The hint ink for a field: the rung the brand authored, guaranteed to clear `PLACEHOLDER_TEXT`
|
|
6
|
+
* on every surface a field can land on.
|
|
7
|
+
*
|
|
8
|
+
* It does not walk the rung toward AA in either direction. Lifting it to 4.5 made an empty field
|
|
9
|
+
* read as one already typed into; softening it back down again undershot on the next surface.
|
|
10
|
+
* The published library ships this rung untouched and that is the look being matched.
|
|
11
|
+
*/
|
|
12
|
+
export declare const placeholderInkOn: (palette: PaletteProps, surfaces: FieldSurfaces) => string;
|
|
13
|
+
/**
|
|
14
|
+
* Every surface an ENABLED field renders on. Disabled fields are deliberately absent — 1.4.3
|
|
15
|
+
* exempts them, and folding their dimmer fill in here would darken the hint on every other field.
|
|
16
|
+
*/
|
|
17
|
+
export declare const fieldSurfaces: (palette: PaletteProps) => FieldSurfaces;
|
|
18
|
+
/** The hint ink every field in this library reads. Takes no backdrop: see `fieldSurfaces`. */
|
|
19
|
+
export declare const placeholderInk: (palette: PaletteProps) => string;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.placeholderInk = exports.fieldSurfaces = exports.placeholderInkOn = void 0;
|
|
4
|
+
const color_1 = require("./color");
|
|
5
|
+
const outlineRung_1 = require("./outlineRung");
|
|
6
|
+
const surfaceRungs_1 = require("./surfaceRungs");
|
|
7
|
+
/**
|
|
8
|
+
* The hint ink for a field: the rung the brand authored, guaranteed to clear `PLACEHOLDER_TEXT`
|
|
9
|
+
* on every surface a field can land on.
|
|
10
|
+
*
|
|
11
|
+
* It does not walk the rung toward AA in either direction. Lifting it to 4.5 made an empty field
|
|
12
|
+
* read as one already typed into; softening it back down again undershot on the next surface.
|
|
13
|
+
* The published library ships this rung untouched and that is the look being matched.
|
|
14
|
+
*/
|
|
15
|
+
const placeholderInkOn = (palette, surfaces) => {
|
|
16
|
+
const rung = palette.placeholder[500];
|
|
17
|
+
const hardest = surfaces.reduce((worst, s) => (0, color_1.contrastRatio)(rung, s) < (0, color_1.contrastRatio)(rung, worst) ? s : worst);
|
|
18
|
+
return (0, outlineRung_1.liftToContrast)(rung, hardest, surfaceRungs_1.PLACEHOLDER_TEXT);
|
|
19
|
+
};
|
|
20
|
+
exports.placeholderInkOn = placeholderInkOn;
|
|
21
|
+
/**
|
|
22
|
+
* Every surface an ENABLED field renders on. Disabled fields are deliberately absent — 1.4.3
|
|
23
|
+
* exempts them, and folding their dimmer fill in here would darken the hint on every other field.
|
|
24
|
+
*/
|
|
25
|
+
const fieldSurfaces = (palette) => [
|
|
26
|
+
palette.gray[50],
|
|
27
|
+
palette.background[50],
|
|
28
|
+
palette.backgroundColor.main,
|
|
29
|
+
];
|
|
30
|
+
exports.fieldSurfaces = fieldSurfaces;
|
|
31
|
+
/** The hint ink every field in this library reads. Takes no backdrop: see `fieldSurfaces`. */
|
|
32
|
+
const placeholderInk = (palette) => (0, exports.placeholderInkOn)(palette, (0, exports.fieldSurfaces)(palette));
|
|
33
|
+
exports.placeholderInk = placeholderInk;
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { AA_NON_TEXT } from "./outlineRung";
|
|
2
2
|
import type { PaletteProps } from "../types";
|
|
3
|
-
/**
|
|
3
|
+
/**
|
|
4
|
+
* A hint is floored at 3:1, not 4.5:1. Held to body-text contrast it stopped reading as a hint —
|
|
5
|
+
* an empty field looked like one already typed into — and the published library ships this rung
|
|
6
|
+
* as the brand authored it. See CHROME-CONSISTENCY.md.
|
|
7
|
+
*/
|
|
4
8
|
export declare function withPlaceholderRung(palette: PaletteProps): PaletteProps;
|
|
5
9
|
/** The hover row is a SURFACE, so it steps away from the ink rather than the ink moving. */
|
|
6
10
|
export declare function withTableHoverRung(palette: PaletteProps): PaletteProps;
|
|
@@ -6,9 +6,14 @@ exports.withTableHoverRung = withTableHoverRung;
|
|
|
6
6
|
const outlineRung_1 = require("./outlineRung");
|
|
7
7
|
Object.defineProperty(exports, "AA_NON_TEXT", { enumerable: true, get: function () { return outlineRung_1.AA_NON_TEXT; } });
|
|
8
8
|
const accentText_1 = require("./accentText");
|
|
9
|
-
|
|
9
|
+
const surfaceRungs_1 = require("./surfaceRungs");
|
|
10
|
+
/**
|
|
11
|
+
* A hint is floored at 3:1, not 4.5:1. Held to body-text contrast it stopped reading as a hint —
|
|
12
|
+
* an empty field looked like one already typed into — and the published library ships this rung
|
|
13
|
+
* as the brand authored it. See CHROME-CONSISTENCY.md.
|
|
14
|
+
*/
|
|
10
15
|
function withPlaceholderRung(palette) {
|
|
11
|
-
const resolved = (0, outlineRung_1.liftToContrast)(palette.placeholder[500], palette.background[50],
|
|
16
|
+
const resolved = (0, outlineRung_1.liftToContrast)(palette.placeholder[500], palette.background[50], surfaceRungs_1.PLACEHOLDER_TEXT);
|
|
12
17
|
if (resolved === palette.placeholder[500])
|
|
13
18
|
return palette;
|
|
14
19
|
return { ...palette, placeholder: { ...palette.placeholder, 500: resolved } };
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import type { PaletteProps } from "../types";
|
|
2
|
-
/**
|
|
3
|
-
|
|
2
|
+
/**
|
|
3
|
+
* A hint is held to the non-text floor, not the body-text one. Deliberate: at 4.5 an empty field
|
|
4
|
+
* reads as one already typed into. See CHROME-CONSISTENCY.md.
|
|
5
|
+
*/
|
|
6
|
+
export declare const PLACEHOLDER_TEXT = 3;
|
|
4
7
|
export declare const namedSurfaces: (palette: PaletteProps) => string[];
|
|
5
8
|
/** The surface an ink is closest to — clearing it clears every other one. */
|
|
6
9
|
export declare const hardestSurface: (ink: string, surfaces: string[]) => string;
|
|
@@ -6,8 +6,11 @@ const color_1 = require("./color");
|
|
|
6
6
|
const outlineRung_1 = require("./outlineRung");
|
|
7
7
|
const accentText_1 = require("./accentText");
|
|
8
8
|
const semanticText_1 = require("./semanticText");
|
|
9
|
-
/**
|
|
10
|
-
|
|
9
|
+
/**
|
|
10
|
+
* A hint is held to the non-text floor, not the body-text one. Deliberate: at 4.5 an empty field
|
|
11
|
+
* reads as one already typed into. See CHROME-CONSISTENCY.md.
|
|
12
|
+
*/
|
|
13
|
+
exports.PLACEHOLDER_TEXT = outlineRung_1.AA_NON_TEXT;
|
|
11
14
|
const namedSurfaces = (palette) => [
|
|
12
15
|
...Object.values(palette.backgroundColor),
|
|
13
16
|
palette.background[50],
|
|
@@ -21,7 +24,6 @@ exports.hardestSurface = hardestSurface;
|
|
|
21
24
|
function withSurfaceRungs(palette) {
|
|
22
25
|
const surfaces = (0, exports.namedSurfaces)(palette);
|
|
23
26
|
const lift = (ink, target) => (0, outlineRung_1.liftToContrast)(ink, (0, exports.hardestSurface)(ink, surfaces), target);
|
|
24
|
-
const soften = (ink, target) => (0, outlineRung_1.softenToContrast)(ink, (0, exports.hardestSurface)(ink, surfaces), target);
|
|
25
27
|
const semanticText = semanticText_1.SEMANTIC_TONES.reduce((acc, tone) => {
|
|
26
28
|
acc[tone] = lift(palette.semanticText[tone], accentText_1.AA_NORMAL_TEXT);
|
|
27
29
|
return acc;
|
|
@@ -33,12 +35,9 @@ function withSurfaceRungs(palette) {
|
|
|
33
35
|
semanticText,
|
|
34
36
|
text: { ...palette.text, 500: lift(palette.text[500], accentText_1.AA_NORMAL_TEXT) },
|
|
35
37
|
header: { ...palette.header, 500: lift(palette.header[500], accentText_1.AA_NORMAL_TEXT) },
|
|
36
|
-
//
|
|
37
|
-
//
|
|
38
|
-
|
|
39
|
-
...palette.placeholder,
|
|
40
|
-
500: soften(lift(palette.placeholder[500], accentText_1.AA_NORMAL_TEXT), exports.PLACEHOLDER_TEXT),
|
|
41
|
-
},
|
|
38
|
+
// `placeholder` is deliberately absent: the brand authors that rung and the published
|
|
39
|
+
// library ships it untouched. Its floor is enforced in `placeholderInk`, against the
|
|
40
|
+
// surfaces a FIELD renders on — not `table.hover`, which no field sits on.
|
|
42
41
|
boxborder: { ...palette.boxborder, 500: lift(palette.boxborder[500], outlineRung_1.AA_NON_TEXT) },
|
|
43
42
|
};
|
|
44
43
|
}
|
|
@@ -69,7 +69,7 @@ rightIconDropdown, menulistStyle, menuItemStyle, isLoading, divider = true, left
|
|
|
69
69
|
// this theme-swap app never triggers) — our `bg` prop above only recolors the list
|
|
70
70
|
// itself, not the inherited var, so items fell back to white until hover/focus (which
|
|
71
71
|
// our own sx already overrides). Setting the var here fixes the rest state too.
|
|
72
|
-
sx: { "--menu-bg": theme.colors.backgroundColor.light },
|
|
72
|
+
sx: { "--menu-bg": theme.colors.backgroundColor.light }, borderRadius: "xl", boxShadow: "lg", py: "0.375rem", minW: "12rem", overflow: "hidden", children: dropdownOptions === null || dropdownOptions === void 0 ? void 0 : dropdownOptions.map((option, index) => (_jsxs(MenuItem, { onClick: (event) => handleMenuClick(event, option), style: menuItemStyle, sx: {
|
|
73
73
|
display: "flex",
|
|
74
74
|
alignItems: "center",
|
|
75
75
|
gap: "0.5rem",
|
|
@@ -15,6 +15,8 @@ export const Checkbox = {
|
|
|
15
15
|
height: "1.25rem",
|
|
16
16
|
borderWidth: "1.6px",
|
|
17
17
|
borderRadius: "base",
|
|
18
|
+
// Without a resting colour Chakra falls back to its own gray.500.
|
|
19
|
+
borderColor: theme.colors.boxborder[500],
|
|
18
20
|
transition: "background 0.15s, border-color 0.15s, box-shadow 0.15s",
|
|
19
21
|
_disabled: {
|
|
20
22
|
bg: theme.colors.background[50],
|
|
@@ -172,7 +172,7 @@ export const RangeDatePicker = (props) => {
|
|
|
172
172
|
: `0 0 0 1px ${theme.colors.primary[500]}`,
|
|
173
173
|
}, _hover: {
|
|
174
174
|
borderColor: error ? theme.colors.semanticText.error : undefined,
|
|
175
|
-
}, cursor: "pointer" }), _jsx(InputRightElement, { height: "100%", display: "flex", alignItems: "center", pointerEvents: "auto", style: { cursor: "pointer" }, onClick: () => (isOpen ? onClose() : handleOpen()), children: _jsx(Box, { as: "span", sx: calendarIconWrapperSx, children: _jsx(CalendarIcon, { size: calendarIconPx, color: theme.colors.textMuted }) }) })] }) }) }), _jsx(PopoverContent, { w: "18rem", maxW: "18rem", p: 3, ref: popoverRef, boxShadow: "lg", borderRadius: "xl",
|
|
175
|
+
}, cursor: "pointer" }), _jsx(InputRightElement, { height: "100%", display: "flex", alignItems: "center", pointerEvents: "auto", style: { cursor: "pointer" }, onClick: () => (isOpen ? onClose() : handleOpen()), children: _jsx(Box, { as: "span", sx: calendarIconWrapperSx, children: _jsx(CalendarIcon, { size: calendarIconPx, color: theme.colors.textMuted }) }) })] }) }) }), _jsx(PopoverContent, { w: "18rem", maxW: "18rem", p: 3, ref: popoverRef, boxShadow: "lg", borderRadius: "xl", bg: theme.colors.background[50], children: _jsxs(PopoverBody, { p: 0, children: [_jsx(Box, { display: "flex", flexWrap: "wrap", gap: 2, mb: 3, children: presets.map((p) => (_jsx(Button, { size: "xs", variant: "outline", colorScheme: "gray", sx: { flex: "1 1 auto" }, onClick: () => {
|
|
176
176
|
const [from, to] = p.getRange();
|
|
177
177
|
applyPreset(from, to);
|
|
178
178
|
}, children: p.label }, p.label))) }), _jsx(CalendarPanel, { currentMonth: currentMonth, setCurrentMonth: (updater) => setCurrentMonthState((prev) => updater(prev)), today: today, isRange: true, tempDate: null, tempRangeStart: tempRangeStart, tempRangeEnd: tempRangeEnd, hoveredDate: hoveredDate, onDayHover: setHoveredDate, isSameDay: isSameDay, isBefore: isBefore, isAfter: isAfter, minDate: minDate, maxDate: maxDate, disablePastDates: disablePastDates, disableFutureDates: disableFutureDates, disableToday: disableToday, onDaySelect: handleDaySelect }), formatHasTime && (_jsxs(Box, { mt: 3, display: "grid", gridTemplateColumns: "1fr", gap: 2, children: [_jsxs(Box, { children: [_jsx(Box, { fontSize: "xs", color: theme.colors.textMuted, mb: 1, children: "Start time" }), shouldUseSelectTimePicker ? (_jsx(TimePicker, { date: startTimeBaseDate, onChange: (updated) => {
|
|
@@ -956,7 +956,7 @@ export const SingleDatePicker = (props) => {
|
|
|
956
956
|
else {
|
|
957
957
|
onClose();
|
|
958
958
|
}
|
|
959
|
-
}, style: { cursor: "pointer" }, children: _jsx(Box, { as: "span", sx: calendarIconWrapperSx, children: _jsx(CalendarIcon, { size: calendarIconPx, color: theme.colors.textMuted }) }) })] }) }) }), _jsx(PopoverContent, { width: "auto", p: 3, ref: popoverRef, boxShadow: "lg", borderRadius: "xl",
|
|
959
|
+
}, style: { cursor: "pointer" }, children: _jsx(Box, { as: "span", sx: calendarIconWrapperSx, children: _jsx(CalendarIcon, { size: calendarIconPx, color: theme.colors.textMuted }) }) })] }) }) }), _jsx(PopoverContent, { width: "auto", p: 3, ref: popoverRef, boxShadow: "lg", borderRadius: "xl", bg: theme.colors.background[50], children: _jsxs(PopoverBody, { p: 0, children: [showDate && (_jsx(CalendarPanel, { currentMonth: currentMonth, setCurrentMonth: (updater) => setCurrentMonth((prev) => updater(prev)), today: today, isRange: false, tempDate: tempDate, tempRangeStart: null, tempRangeEnd: null, isSameDay: isSameDay, isBefore: isBefore, isAfter: isAfter, minDate: minDate, maxDate: maxDate, disablePastDates: disablePastDates, disableFutureDates: disableFutureDates, disableToday: disableToday, onDaySelect: handleDaySelect })), showTime && (_jsx(Box, { mt: showDate ? 3 : 0, children: resolvedPickerType === "time" ? (_jsx(TimePickerInput, { value: tempDate, onChange: (updatedDate) => {
|
|
960
960
|
setTempDate(updatedDate);
|
|
961
961
|
setInputValue(updatedDate ? format(updatedDate, resolvedDateFormat) : "");
|
|
962
962
|
setIsTyping(false);
|
|
@@ -3,6 +3,6 @@ import { Box, Icon } from "@chakra-ui/react";
|
|
|
3
3
|
import { useCustomTheme } from "../../Theme/useCustomTheme.js";
|
|
4
4
|
const FormWrapper = ({ icon, text, children, }) => {
|
|
5
5
|
const { colors } = useCustomTheme();
|
|
6
|
-
return (_jsxs(Box, { children: [_jsxs(Box, { display: "flex", alignItems: "center", gap: 2, mb: 2, children: [icon && _jsx(Icon, { as: icon, size: "1rem", color: colors.header[500] }), text && (_jsx(Box, { fontFamily: "open-sans, sans-serif", fontWeight: 600, fontSize: 12, lineHeight: "100%", letterSpacing: "4%", textTransform: "uppercase", color: colors.header[500], children: text }))] }), _jsx(Box, { borderRadius: "base", bg: colors.background[50], border: `0.075rem solid ${colors.
|
|
6
|
+
return (_jsxs(Box, { children: [_jsxs(Box, { display: "flex", alignItems: "center", gap: 2, mb: 2, children: [icon && _jsx(Icon, { as: icon, size: "1rem", color: colors.header[500] }), text && (_jsx(Box, { fontFamily: "open-sans, sans-serif", fontWeight: 600, fontSize: 12, lineHeight: "100%", letterSpacing: "4%", textTransform: "uppercase", color: colors.header[500], children: text }))] }), _jsx(Box, { borderRadius: "base", bg: colors.background[50], border: `0.075rem solid ${colors.boxborder[200]}`, boxShadow: `0 0.063rem 0.125rem 0 ${colors.boxShadow.primary}`, p: "1.5rem", children: children })] }));
|
|
7
7
|
};
|
|
8
8
|
export default FormWrapper;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { PLACEHOLDER_TEXT } from "../../Theme/tokens/builders/surfaceRungs.js";
|
|
1
|
+
import { placeholderInk } from "../../Theme/tokens/builders/placeholderInk.js";
|
|
3
2
|
export const Input = {
|
|
4
|
-
baseStyle: {
|
|
3
|
+
baseStyle: ({ theme }) => ({
|
|
5
4
|
field: {
|
|
6
5
|
fontWeight: 500,
|
|
7
6
|
fontSize: "0.875rem",
|
|
@@ -12,11 +11,13 @@ export const Input = {
|
|
|
12
11
|
alignItems: "center",
|
|
13
12
|
borderRadius: "lg",
|
|
14
13
|
transition: "border-color 0.2s, box-shadow 0.2s",
|
|
14
|
+
// Every variant inherits the hint ink; only `outline` used to set it.
|
|
15
15
|
_placeholder: {
|
|
16
16
|
fontStyle: "italic",
|
|
17
|
+
color: placeholderInk(theme.colors),
|
|
17
18
|
},
|
|
18
19
|
},
|
|
19
|
-
},
|
|
20
|
+
}),
|
|
20
21
|
sizes: {
|
|
21
22
|
sm: {
|
|
22
23
|
field: {
|
|
@@ -50,10 +51,8 @@ export const Input = {
|
|
|
50
51
|
bg: theme.colors.gray[50],
|
|
51
52
|
border: "0.063rem solid",
|
|
52
53
|
borderColor,
|
|
53
|
-
// `textMuted` is body copy, so a hint read as a filled value (6.59:1).
|
|
54
|
-
// Settled against the field's own bg to just clear of AA.
|
|
55
54
|
_placeholder: {
|
|
56
|
-
color:
|
|
55
|
+
color: placeholderInk(theme.colors),
|
|
57
56
|
},
|
|
58
57
|
_hover: {
|
|
59
58
|
borderColor: primary,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { placeholderInk } from "../../Theme/tokens/builders/placeholderInk.js";
|
|
1
2
|
export const Textarea = {
|
|
2
|
-
baseStyle: {
|
|
3
|
+
baseStyle: ({ theme }) => ({
|
|
3
4
|
fontWeight: 500,
|
|
4
5
|
fontSize: "0.875rem",
|
|
5
6
|
letterSpacing: "0.044rem",
|
|
@@ -9,8 +10,9 @@ export const Textarea = {
|
|
|
9
10
|
transition: "border-color 0.2s, box-shadow 0.2s",
|
|
10
11
|
_placeholder: {
|
|
11
12
|
fontStyle: "italic",
|
|
13
|
+
color: placeholderInk(theme.colors),
|
|
12
14
|
},
|
|
13
|
-
},
|
|
15
|
+
}),
|
|
14
16
|
sizes: {
|
|
15
17
|
md: {
|
|
16
18
|
fontSize: "0.875rem",
|
|
@@ -30,7 +32,7 @@ export const Textarea = {
|
|
|
30
32
|
borderColor,
|
|
31
33
|
bg: theme.colors.gray[50],
|
|
32
34
|
_placeholder: {
|
|
33
|
-
color: theme.colors
|
|
35
|
+
color: placeholderInk(theme.colors),
|
|
34
36
|
},
|
|
35
37
|
_hover: {
|
|
36
38
|
borderColor: primary,
|
|
@@ -45,17 +45,17 @@ export default function NavBar({ userAvathar, userName, userRole, navMenu, moreI
|
|
|
45
45
|
_focus: { bg: menuHoverBg, color: menuHoverInk },
|
|
46
46
|
_active: { bg: menuHoverBg, color: menuHoverInk },
|
|
47
47
|
};
|
|
48
|
-
return (_jsx(Box, { bg: theme.colors.backgroundColor.light, px: 4, borderBottom: "1px solid", borderColor: theme.colors.
|
|
48
|
+
return (_jsx(Box, { bg: theme.colors.backgroundColor.light, px: 4, borderBottom: "1px solid", borderColor: theme.colors.boxborder[200], children: _jsxs(Flex, { h: 16, alignItems: "center", justifyContent: "space-between", children: [_jsxs(Box, { display: "flex", gap: 1.5, alignItems: "center", children: [_jsx(Box, { as: "button", type: "button", onClick: () => onSideBarToggole === null || onSideBarToggole === void 0 ? void 0 : onSideBarToggole(), onMouseEnter: onSideBarPeek, onFocus: onSideBarPeek, "aria-label": sideBarToggole ? "Close navigation menu" : "Open navigation menu", "aria-expanded": !!sideBarToggole, ...iconButtonStyle, display: forceSideBarToggle ? "flex" : { base: "flex", lg: "none" }, w: SIDEBAR_TOGGLE_HIT, h: SIDEBAR_TOGGLE_HIT, children: sideBarToggole ? (_jsx(PanelLeftClose, { size: "1.25rem" })) : (_jsx(PanelRightClose, { size: "1.25rem" })) }), (navigationBarText === null || navigationBarText === void 0 ? void 0 : navigationBarText.onIconClick) && (_jsx(Box, { ...iconButtonStyle, as: "button", type: "button", "aria-label": "Go back", display: "flex", onClick: () => { var _a; return (_a = navigationBarText === null || navigationBarText === void 0 ? void 0 : navigationBarText.onIconClick) === null || _a === void 0 ? void 0 : _a.call(navigationBarText); }, children: _jsx(CircleArrowLeft, { size: "1.25rem", color: theme.colors.text[500] }) })), (navigationBarText === null || navigationBarText === void 0 ? void 0 : navigationBarText.text) && (_jsx(Text, { color: accentTextOnCanvas(theme.colors.secondary, theme.colors.backgroundColor.light), fontSize: "1.25rem", fontWeight: 600, fontFamily: "open-sans, sans-serif", letterSpacing: "-0.013rem", children: navigationBarText === null || navigationBarText === void 0 ? void 0 : navigationBarText.text }))] }), _jsx(Flex, { minW: 0, flexShrink: 1, children: _jsxs(Stack, { direction: "row", alignItems: "center", spacing: 4, minW: 0, children: [moreIcon && (_jsx(Box, { display: "flex", alignItems: "center", minW: 0, children: moreIcon })), _jsxs(Menu, { children: [_jsx(MenuButton, { as: Button, rounded: "full", variant: "link", cursor: "pointer", minW: 0, flexShrink: 0, children: _jsx(Avatar, { size: "sm", name: userName, src: userAvathar }) }), _jsx(MenuList, { alignItems: "center", zIndex: 5, p: 0, py: "0.375rem",
|
|
49
49
|
// Without a cap one long title stretches the whole dropdown; titles truncate instead.
|
|
50
50
|
maxW: "18rem", bg: theme.colors.backgroundColor.light,
|
|
51
51
|
// Chakra's MenuItem renders `background: var(--menu-bg)` at rest; its MenuList
|
|
52
52
|
// baseStyle hardcodes that var to "#fff" (gated behind `_dark`, which this theme-swap
|
|
53
53
|
// app never triggers). The `bg` prop above only recolors the list itself, not the
|
|
54
54
|
// inherited var, so items fall back to white until hover/focus — set the var too.
|
|
55
|
-
sx: { "--menu-bg": theme.colors.backgroundColor.light },
|
|
55
|
+
sx: { "--menu-bg": theme.colors.backgroundColor.light }, borderRadius: "xl", boxShadow: "lg", color: theme.colors.text[900], overflow: "hidden", children: _jsxs(Box, { display: "flex", flexDirection: "column", maxH: "90vh", children: [_jsx(Center, { pt: 4, pb: 2, children: _jsx(Avatar, { size: "xl", name: userName, src: userAvathar }) }), _jsxs(Center, { flexDirection: "column", gap: "0.125rem", pb: 2, px: 4, children: [_jsx(Text, { fontWeight: 600, fontSize: "14px", color: theme.colors.text[900], isTruncated: true, maxW: "100%", children: userName }), userRole && (_jsx(Text, { fontSize: "11px", color: theme.colors.text[500], isTruncated: true, maxW: "100%", children: userRole }))] }), _jsx(MenuDivider, { borderColor: theme.colors.boxborder[200] }), _jsx(Box, { flex: 1, overflowY: "auto", overflowX: "hidden", children: navMenu === null || navMenu === void 0 ? void 0 : navMenu.map((menu, idx) => {
|
|
56
56
|
var _a, _b, _c, _d;
|
|
57
57
|
return (_jsxs(MenuItem, { onClick: () => handleNavOnClick(menu.url), sx: menuItemStyle, children: [menu.icon && (_jsx(Box, { display: "flex", alignItems: "center", flexShrink: 0, sx: { "& svg": { width: "16px", height: "16px" } }, children: menu === null || menu === void 0 ? void 0 : menu.icon })), _jsx(Box, { minW: 0, isTruncated: true, title: String((_a = menu.title) !== null && _a !== void 0 ? _a : ""), children: menu.title })] }, `${String((_d = (_c = (_b = menu.id) !== null && _b !== void 0 ? _b : menu.url) !== null && _c !== void 0 ? _c : menu.title) !== null && _d !== void 0 ? _d : idx)}-${idx}`));
|
|
58
|
-
}) }), _jsx(MenuDivider, { borderColor: theme.colors.
|
|
58
|
+
}) }), _jsx(MenuDivider, { borderColor: theme.colors.boxborder[200] }), _jsxs(MenuItem, { onClick: handleLogout, sx: {
|
|
59
59
|
...menuItemStyle,
|
|
60
60
|
color: theme.colors.semanticText.error,
|
|
61
61
|
_hover: { bg: dangerTone.bg, color: dangerTone.fg },
|
|
@@ -3,6 +3,7 @@ import { useEffect, useRef, useState } from "react";
|
|
|
3
3
|
import { Box, Flex, Text, Input, Textarea, Button, Divider, Spinner, Tooltip, } from "@chakra-ui/react";
|
|
4
4
|
import { Paperclip, X, SquarePen, File as FileIcon } from "lucide-react";
|
|
5
5
|
import { useCustomTheme } from "../../Theme/useCustomTheme.js";
|
|
6
|
+
import { placeholderInk } from "../../Theme/tokens/builders/placeholderInk.js";
|
|
6
7
|
import { FIELD_RADIUS } from "../Common/fieldStyles.js";
|
|
7
8
|
const countWords = (text = "") => {
|
|
8
9
|
const t = text.trim();
|
|
@@ -120,8 +121,11 @@ export default function NoteTextArea({ width = "100%", handleSubmit, handleCance
|
|
|
120
121
|
setTitleValue(e.target.value);
|
|
121
122
|
}, placeholder: "Add a title...", variant: "unstyled", px: 3, pt: 2.5, pb: 1.5, fontWeight: 600, fontSize: "0.875rem", color: theme.colors.text[700], _placeholder: {
|
|
122
123
|
fontStyle: "italic",
|
|
123
|
-
color: theme.colors
|
|
124
|
-
} }), _jsx(Divider, { borderColor: theme.colors.gray[200] })] })), _jsx(Box, { bg: theme.colors.background[50], minH: "76px", px: 3, pt: 2.5, position: "relative", children: _jsx(Textarea, { ref: noteAreaRef, value: noteValue, onChange: handleNoteChange, placeholder: customPlaceholder, variant: "unstyled", resize: "none", minH: "76px", fontSize: "0.75rem", color: theme.colors.text[700], _placeholder: {
|
|
124
|
+
color: placeholderInk(theme.colors),
|
|
125
|
+
} }), _jsx(Divider, { borderColor: theme.colors.gray[200] })] })), _jsx(Box, { bg: theme.colors.background[50], minH: "76px", px: 3, pt: 2.5, position: "relative", children: _jsx(Textarea, { ref: noteAreaRef, value: noteValue, onChange: handleNoteChange, placeholder: customPlaceholder, variant: "unstyled", resize: "none", minH: "76px", fontSize: "0.75rem", color: theme.colors.text[700], _placeholder: {
|
|
126
|
+
fontStyle: "italic",
|
|
127
|
+
color: placeholderInk(theme.colors),
|
|
128
|
+
}, style: { overflow: "hidden" }, p: 0 }) })] }), _jsx(Divider, { borderColor: theme.colors.gray[200] }), _jsxs(Box, { px: 3, py: 2.5, children: [_jsxs(Flex, { align: "center", justify: "space-between", w: "100%", gap: 3, children: [_jsxs(Flex, { align: "center", gap: 2, minW: 0, children: [_jsx(Tooltip, { label: "Attach files", hasArrow: true, placement: "top", children: _jsx(Box, { as: "label", htmlFor: "file-upload", cursor: "pointer", display: "flex", alignItems: "center", justifyContent: "center", w: "1.75rem", h: "1.75rem", borderRadius: "md", color: theme.colors.textMuted, transition: "background 0.15s", _hover: { bg: theme.colors.gray[100] }, children: _jsx(Paperclip, { size: 16 }) }) }), _jsx(Box, { h: "1rem", w: "1px", bg: theme.colors.gray[200] }), !titleShow ? (_jsx(Box, { as: "button", type: "button", onClick: () => setTitleShow(true), px: 2, py: 1, borderRadius: "md", color: theme.colors.textMuted, fontWeight: 500, fontSize: "sm", transition: "background 0.15s", _hover: { bg: theme.colors.gray[100] }, children: "+ Add a title" })) : (_jsx(Tooltip, { label: titleValue, hasArrow: true, isDisabled: !titleValue, children: _jsx(Text, { color: theme.colors.textMuted, fontSize: "sm", fontWeight: 500, isTruncated: true, maxW: "180px", children: titleValue || "Title" }) }))] }), _jsxs(Flex, { gap: 2.5, align: "center", ml: "auto", flexShrink: 0, children: [_jsxs(Text, { fontSize: "xs", fontWeight: 500, color: isOverLimit ? theme.colors.semanticText.error : theme.colors.textMuted, whiteSpace: "nowrap", children: [noteWordCount, "/", maxNoteWordCount] }), cancelButtonHide ? null : (_jsx(Button, { size: "sm", variant: "ghost", colorScheme: "gray", onClick: handleCloseTextArea, children: "Cancel" })), _jsxs(Button, { size: "sm", variant: "solid", isLoading: !!saveButtonLoading, isDisabled: !noteValue || isSaveDisabled, onClick: () => handleSubmit(noteValue, titleValue, files), children: [saveButtonLoading ? (_jsx(Spinner, { size: "xs", thickness: "2px", mr: 2 })) : null, "Save"] })] })] }), _jsx("input", { id: "file-upload", type: "file", style: { display: "none" }, onChange: (e) => {
|
|
125
129
|
const newFiles = Array.from(e.target.files || []);
|
|
126
130
|
const validFiles = newFiles.filter((f) => f.size <= maxFileSize);
|
|
127
131
|
const invalidFiles = newFiles.filter((f) => f.size > maxFileSize);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { placeholderInk } from "../../Theme/tokens/builders/placeholderInk.js";
|
|
1
2
|
export const NumberInput = {
|
|
2
|
-
baseStyle: {
|
|
3
|
+
baseStyle: ({ theme }) => ({
|
|
3
4
|
field: {
|
|
4
5
|
fontWeight: 500,
|
|
5
6
|
fontSize: "0.875rem",
|
|
@@ -10,9 +11,10 @@ export const NumberInput = {
|
|
|
10
11
|
transition: "border-color 0.2s, box-shadow 0.2s",
|
|
11
12
|
_placeholder: {
|
|
12
13
|
fontStyle: "italic",
|
|
14
|
+
color: placeholderInk(theme.colors),
|
|
13
15
|
},
|
|
14
16
|
},
|
|
15
|
-
},
|
|
17
|
+
}),
|
|
16
18
|
sizes: {
|
|
17
19
|
md: {
|
|
18
20
|
field: {
|
|
@@ -35,7 +37,7 @@ export const NumberInput = {
|
|
|
35
37
|
border: "0.063rem solid",
|
|
36
38
|
borderColor,
|
|
37
39
|
_placeholder: {
|
|
38
|
-
color: theme.colors
|
|
40
|
+
color: placeholderInk(theme.colors),
|
|
39
41
|
},
|
|
40
42
|
_hover: {
|
|
41
43
|
borderColor: primary,
|
|
@@ -13,7 +13,7 @@ export const ProfileCardFooter = ({ children, }) => {
|
|
|
13
13
|
};
|
|
14
14
|
export default function ProfileCard({ maxW, align, variant, direction, justify, children, size, color, overflow, dividercolor, dividersize = "0.5px", dividervariant = "solid", CardStyle, CardHeaderStyle, CardBodyStyle, borderTopColor, borderLeftColor, }) {
|
|
15
15
|
const { colors } = useCustomTheme();
|
|
16
|
-
const resolvedDividerColor = dividercolor !== null && dividercolor !== void 0 ? dividercolor : colors.
|
|
16
|
+
const resolvedDividerColor = dividercolor !== null && dividercolor !== void 0 ? dividercolor : colors.boxborder[200];
|
|
17
17
|
const accentBorder = `2px solid ${colors.primary[500]}`;
|
|
18
18
|
const isReactElement = (child) => {
|
|
19
19
|
return child !== null && typeof child === "object" && "type" in child;
|
|
@@ -5,6 +5,7 @@ import { Check, ChevronDown, ChevronUp, CircleX, Plus, X } from "lucide-react";
|
|
|
5
5
|
import { TextLabel } from "../Common/FormLabel.js";
|
|
6
6
|
import Tag from "../Tag/Tag.js";
|
|
7
7
|
import { useCustomTheme } from "../../Theme/useCustomTheme.js";
|
|
8
|
+
import { placeholderInk } from "../../Theme/tokens/builders/placeholderInk.js";
|
|
8
9
|
import ErrorMessage from "../Common/ErrorMessage.js";
|
|
9
10
|
import HelperText from "../Common/HelperText.js";
|
|
10
11
|
import ToolTip from "../ToolTip/ToolTip.js";
|
|
@@ -457,7 +458,7 @@ const SearchSelect = ({ id, label, options, onSelect, onSearch, isOptionLoading
|
|
|
457
458
|
e.stopPropagation();
|
|
458
459
|
setIsOpen(false);
|
|
459
460
|
setCustomSelectOpen((prev) => !prev);
|
|
460
|
-
}, children: [_jsxs(Box, { minW: "4.5rem", cursor: "pointer", display: "flex", justifyContent: "space-between", alignItems: "center", gap: 1, width: insideSelect.width, height: insideSelectBoxHeight, pl: "0.5rem", pr: "0.375rem", children: [insideLabel ? (_jsx(SelectTruncatedLabel, { label: insideLabel, maxWidth: insideSelect.width || "6rem", fontSize: s.fieldFontSize })) : (_jsx(Text, { fontSize: s.fieldFontSize, fontWeight: 500, color: theme.colors
|
|
461
|
+
}, children: [_jsxs(Box, { minW: "4.5rem", cursor: "pointer", display: "flex", justifyContent: "space-between", alignItems: "center", gap: 1, width: insideSelect.width, height: insideSelectBoxHeight, pl: "0.5rem", pr: "0.375rem", children: [insideLabel ? (_jsx(SelectTruncatedLabel, { label: insideLabel, maxWidth: insideSelect.width || "6rem", fontSize: s.fieldFontSize })) : (_jsx(Text, { fontSize: s.fieldFontSize, fontWeight: 500, color: placeholderInk(theme.colors), isTruncated: true, maxW: insideSelect.width || "6rem", children: insidePlaceholder })), _jsx(Box, { as: "span", display: "inline-flex", flexShrink: 0, color: customSelectOpen ? theme.colors.accentText : theme.colors.textMuted, transition: "transform 0.2s ease, color 0.15s ease", transform: customSelectOpen ? "rotate(180deg)" : "rotate(0deg)", children: _jsx(ChevronDown, { size: s.chevronSize }) })] }), customSelectOpen && (_jsx(Portal, { children: _jsx(Box, { ref: setInsideSelectMenuRef, id: "custom-select-portal", position: "fixed", top: `${customSelectPos.top}px`, left: `${customSelectPos.left}px`, zIndex: 1510, bg: theme.colors.background[50], border: "0.063rem solid", borderColor: theme.colors.boxborder[200], borderRadius: "lg", boxShadow: (_d = (_c = theme.shadows) === null || _c === void 0 ? void 0 : _c.md) !== null && _d !== void 0 ? _d : "md", minW: `${customSelectPos.width}px`, maxW: "20rem", py: 1, overflow: "hidden", children: (_e = insideSelect.option) === null || _e === void 0 ? void 0 : _e.map((item) => {
|
|
461
462
|
var _a;
|
|
462
463
|
const selected = ((_a = insideSelect.value) === null || _a === void 0 ? void 0 : _a.id) === item.id;
|
|
463
464
|
return (_jsxs(Box, { display: "flex", alignItems: "center", justifyContent: "space-between", gap: 2, minH: s.optionRowMinH, py: s.optionRowPy, px: "0.75rem", fontSize: s.dropdownTextFontSize, fontWeight: selected ? 600 : 500, color: selected
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { placeholderInk } from "../../Theme/tokens/builders/placeholderInk.js";
|
|
1
2
|
export const Select = {
|
|
2
3
|
baseStyle: ({ theme }) => ({
|
|
3
4
|
field: {
|
|
@@ -17,6 +18,7 @@ export const Select = {
|
|
|
17
18
|
maxWidth: "100%",
|
|
18
19
|
_placeholder: {
|
|
19
20
|
fontStyle: "italic",
|
|
21
|
+
color: placeholderInk(theme.colors),
|
|
20
22
|
whiteSpace: "nowrap",
|
|
21
23
|
overflow: "hidden",
|
|
22
24
|
textOverflow: "ellipsis",
|
|
@@ -264,7 +264,7 @@ BottomIcon = false, BottomText, handleBottomClick, BottomTextColor, isColorOptio
|
|
|
264
264
|
fontSize: 15,
|
|
265
265
|
letterSpacing: 0.7,
|
|
266
266
|
border: error ? errorBorder : defaultBorderThin,
|
|
267
|
-
} }), rightIcon && (_jsx(InputRightElement, { pointerEvents: "none", children: rightIcon, style: { ...rightElementStyle } }))] }), isOpen && (_jsxs(Box, { ref: dropdownRef, marginTop: "5px", position: "absolute", top: position === "below" ? "100%" : "auto", bottom: position === "above" ? "100%" : "auto", left: 0, right: 0, border: "1px solid", borderColor: theme.colors.boxborder[200], borderRadius: "md", bg: theme.colors.background[50], maxHeight: "150px", overflowY: "auto", zIndex: 10, children: [_jsx(Box, { id: listboxId, role: "listbox", "aria-label": label !== null && label !== void 0 ? label : placeholder, onKeyDown: handleListKeyDown, children: _jsx(RenderOptions, { isOptionLoading: isOptionLoading, filteredOptions: filteredOptions, loadingText: loadingText, handleOptionClick: handleOptionClick, isProfile: isProfile, isColorOptions: isColorOptions, isOptionSelected: isOptionSelected, activeIndex: activeIndex, optionRefs: optionRefs }) }), _jsx("hr", {}), isBottomIcon && (_jsxs(Box, { position: "sticky", bottom: 0, background: theme.colors.background[50], display: "flex", alignItems: "center", pl: "1rem", cursor: "pointer", onClick: handleBottomClick, borderColor: theme.colors.boxborder[200], zIndex: 1, borderTop: `1px solid ${theme.colors.
|
|
267
|
+
} }), rightIcon && (_jsx(InputRightElement, { pointerEvents: "none", children: rightIcon, style: { ...rightElementStyle } }))] }), isOpen && (_jsxs(Box, { ref: dropdownRef, marginTop: "5px", position: "absolute", top: position === "below" ? "100%" : "auto", bottom: position === "above" ? "100%" : "auto", left: 0, right: 0, border: "1px solid", borderColor: theme.colors.boxborder[200], borderRadius: "md", bg: theme.colors.background[50], maxHeight: "150px", overflowY: "auto", zIndex: 10, children: [_jsx(Box, { id: listboxId, role: "listbox", "aria-label": label !== null && label !== void 0 ? label : placeholder, onKeyDown: handleListKeyDown, children: _jsx(RenderOptions, { isOptionLoading: isOptionLoading, filteredOptions: filteredOptions, loadingText: loadingText, handleOptionClick: handleOptionClick, isProfile: isProfile, isColorOptions: isColorOptions, isOptionSelected: isOptionSelected, activeIndex: activeIndex, optionRefs: optionRefs }) }), _jsx("hr", {}), isBottomIcon && (_jsxs(Box, { position: "sticky", bottom: 0, background: theme.colors.background[50], display: "flex", alignItems: "center", pl: "1rem", cursor: "pointer", onClick: handleBottomClick, borderColor: theme.colors.boxborder[200], zIndex: 1, borderTop: `1px solid ${theme.colors.boxborder[200]}`, children: [_jsx(Box, { children: BottomIcon ? BottomIcon : _jsx(PlusIcon, { size: "1rem" }) }), _jsx(Box, { fontSize: "0.875rem", color: BottomTextColor
|
|
268
268
|
? BottomTextColor
|
|
269
269
|
: theme.colors.accentText, padding: "8px 8px", children: BottomText || "Add New" })] }))] })), error && _jsx(ErrorMessage, { errorMessage: errorMessage })] }) }) }));
|
|
270
270
|
}
|
|
@@ -3,6 +3,7 @@ import React, { useCallback, useEffect, useId, useMemo, useRef, useState } from
|
|
|
3
3
|
import { Box, Checkbox, FormControl, Input, Popover, PopoverAnchor, PopoverContent, Portal, useDisclosure, } from "@chakra-ui/react";
|
|
4
4
|
import { ChevronDown } from "lucide-react";
|
|
5
5
|
import { useCustomTheme } from "../../Theme/useCustomTheme.js";
|
|
6
|
+
import { placeholderInk } from "../../Theme/tokens/builders/placeholderInk.js";
|
|
6
7
|
import { scrollbarStyles } from "../../Theme/tokens/builders/scrollbar.js";
|
|
7
8
|
import { getFieldStateStyles } from "../Common/fieldStyles.js";
|
|
8
9
|
import { TextLabel } from "../Common/FormLabel.js";
|
|
@@ -23,7 +24,7 @@ const OptionRow = React.memo(function OptionRow({ option, index, listboxId, isSe
|
|
|
23
24
|
: theme.colors.text[700], bg: isActive ? theme.colors.primary.opacity[8] : "transparent", transition: "background 0.12s ease, color 0.12s ease", children: [isMulti ? (_jsx(Checkbox, { isChecked: isSelected, isDisabled: option.isDisabled, pointerEvents: "none", tabIndex: -1 })) : null, renderOption ? (_jsx(Box, { flex: 1, minW: 0, children: renderOption(option, { isSelected, isActive }) })) : (_jsxs(_Fragment, { children: [option.icon ? (_jsx(Box, { as: "span", display: "inline-flex", flexShrink: 0, children: option.icon })) : null, _jsxs(Box, { flex: 1, minW: 0, isTruncated: true, children: [_jsx(Box, { as: "span", isTruncated: true, children: option.label }), option.description ? (_jsx(Box, { as: "span", display: "block", fontSize: "0.75rem", fontWeight: 400, color: theme.colors.textMuted, isTruncated: true, children: option.description })) : null] })] }))] }));
|
|
24
25
|
});
|
|
25
26
|
export default function SelectV2(props) {
|
|
26
|
-
var _a, _b
|
|
27
|
+
var _a, _b;
|
|
27
28
|
const { options = [], placeholder = "Select Option", label, error = false, errorMessage, helperText, isDisabled = false, isRequired = false, size = "md", isSearchable = true, width, formControlStyle, onBlur, onFocus, renderOption, renderValue, maxMenuHeight = "16rem", defaultOpen = false, "data-testid": dataTestId, "aria-label": ariaLabel, } = props;
|
|
28
29
|
const theme = useCustomTheme();
|
|
29
30
|
const { isOpen, onOpen, onClose } = useDisclosure({ defaultIsOpen: defaultOpen });
|
|
@@ -208,7 +209,7 @@ export default function SelectV2(props) {
|
|
|
208
209
|
return selectedOptions[0] ? selectedOptions[0].label : placeholder;
|
|
209
210
|
};
|
|
210
211
|
const triggerIcon = !props.isMulti && ((_b = selectedOptions[0]) === null || _b === void 0 ? void 0 : _b.icon) ? selectedOptions[0].icon : null;
|
|
211
|
-
return (_jsxs(FormControl, { isInvalid: error, isDisabled: isDisabled, style: formControlStyle, width: width, children: [label && (_jsx(TextLabel, { label: label, id: triggerId, isRequired: isRequired })), _jsxs(Popover, { isOpen: isOpen, onClose: () => resetAndClose(), placement: "bottom-start", matchWidth: true, autoFocus: false, returnFocusOnClose: false, gutter: 4, children: [_jsx(PopoverAnchor, { children: _jsxs(Box, { as: "button", type: "button", id: triggerId, ref: triggerRef, role: "combobox", "aria-haspopup": "listbox", "aria-expanded": isOpen, "aria-controls": listboxId, "aria-activedescendant": activeDescendantId, "aria-disabled": isDisabled, "aria-label": ariaLabel, disabled: isDisabled, onClick: handleOpen, onKeyDown: handleTriggerKeyDown, display: "flex", alignItems: "center", justifyContent: "space-between", width: "100%", h: s.h, px: s.px, fontSize: s.fontSize, fontWeight: 500, textAlign: "left", cursor: isDisabled ? "not-allowed" : "pointer", opacity: isDisabled ? 0.4 : 1, color: selectedOptions.length ? theme.colors.text[900] : theme.colors
|
|
212
|
+
return (_jsxs(FormControl, { isInvalid: error, isDisabled: isDisabled, style: formControlStyle, width: width, children: [label && (_jsx(TextLabel, { label: label, id: triggerId, isRequired: isRequired })), _jsxs(Popover, { isOpen: isOpen, onClose: () => resetAndClose(), placement: "bottom-start", matchWidth: true, autoFocus: false, returnFocusOnClose: false, gutter: 4, children: [_jsx(PopoverAnchor, { children: _jsxs(Box, { as: "button", type: "button", id: triggerId, ref: triggerRef, role: "combobox", "aria-haspopup": "listbox", "aria-expanded": isOpen, "aria-controls": listboxId, "aria-activedescendant": activeDescendantId, "aria-disabled": isDisabled, "aria-label": ariaLabel, disabled: isDisabled, onClick: handleOpen, onKeyDown: handleTriggerKeyDown, display: "flex", alignItems: "center", justifyContent: "space-between", width: "100%", h: s.h, px: s.px, fontSize: s.fontSize, fontWeight: 500, textAlign: "left", cursor: isDisabled ? "not-allowed" : "pointer", opacity: isDisabled ? 0.4 : 1, color: selectedOptions.length ? theme.colors.text[900] : placeholderInk(theme.colors), "data-testid": dataTestId, ...fieldStyles, children: [_jsxs(Box, { as: "span", display: "inline-flex", alignItems: "center", gap: 1.5, minW: 0, isTruncated: true, children: [triggerIcon ? (_jsx(Box, { as: "span", display: "inline-flex", flexShrink: 0, children: triggerIcon })) : null, _jsx(Box, { as: "span", isTruncated: true, fontStyle: selectedOptions.length ? "normal" : "italic", children: renderValue ? renderValue(selectedOptions) : defaultTriggerContent() })] }), _jsx(Box, { as: "span", display: "inline-flex", flexShrink: 0, ml: 2, transition: "transform 0.2s ease", transform: isOpen ? "rotate(180deg)" : "rotate(0deg)", color: theme.colors.textMuted, children: _jsx(ChevronDown, { size: 16 }) })] }) }), _jsx(Portal, { children: _jsxs(PopoverContent, { width: "100%", borderRadius: "xl", boxShadow: theme.shadows.lg, overflow: "hidden", onKeyDown: handleListKeyDown, children: [isSearchable && (_jsx(Box, { p: 2, borderBottom: `0.063rem solid ${theme.colors.boxborder[200]}`, children: _jsx(Input, { ref: filterInputRef, size: "sm", placeholder: "Type to filter...", value: filterText, onChange: (event) => {
|
|
212
213
|
setFilterText(event.target.value);
|
|
213
214
|
setActiveIndex(0);
|
|
214
215
|
}, "aria-activedescendant": activeDescendantId, "aria-label": "Filter options" }) })), _jsxs(Box, { id: listboxId, ref: listRef, role: "listbox", "aria-multiselectable": props.isMulti || undefined, maxH: maxMenuHeight, overflowY: "auto", py: 1, sx: listScrollStyles, children: [filteredOptions.length === 0 && (_jsx(Box, { px: 3, py: 2, fontSize: "0.8125rem", color: theme.colors.textMuted, children: "No Options" })), filteredOptions.map((option, index) => {
|