pixelize-design-library 2.4.2-beta.54 → 2.4.2-beta.56
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/CHANGELOG.md +12 -0
- package/COMPONENT-GOTCHAS.md +22 -2
- package/DESIGN-GUIDE.md +8 -6
- package/dist/Components/AppSwitcher/AppSwitcher.js +1 -2
- package/dist/Components/Button/Button.styles.js +1 -1
- package/dist/Components/Button/ButtonProps.d.ts +1 -1
- package/dist/Components/Common/fieldStyles.d.ts +1 -1
- package/dist/Components/Common/fieldStyles.js +1 -1
- package/dist/Components/DatePicker/DatePickerProps.d.ts +1 -1
- package/dist/Components/Dropdown/DropDown.js +4 -4
- package/dist/Components/Dropdown/DropdownProps.d.ts +1 -1
- package/dist/Components/Input/PhoneNumberInputProps.d.ts +1 -1
- package/dist/Components/MultiSelect/MultiSelectProps.d.ts +1 -1
- package/dist/Components/NotificationBell/NotificationBellProps.d.ts +1 -1
- package/dist/Components/OrgSwitcher/OrgSwitcher.js +3 -4
- package/dist/Components/PinInput/PinInputProps.d.ts +1 -1
- package/dist/Components/RangeSlider/RangeSliderProps.d.ts +1 -1
- package/dist/Components/RangeSlider/rangeSliderSize.d.ts +1 -1
- package/dist/Components/RangeSlider/rangeSliderSize.js +1 -1
- package/dist/Components/Search/SearchProps.d.ts +1 -1
- package/dist/Components/SearchSelect/SearchSelectProps.d.ts +1 -1
- package/dist/Components/SegmentedControl/SegmentedControl.js +1 -1
- package/dist/Components/SegmentedControl/SegmentedControlProps.d.ts +1 -1
- package/dist/Components/Select/SelectProps.d.ts +1 -1
- package/dist/Components/SelectSearch/SelectSearchProps.d.ts +1 -1
- package/dist/Components/SelectV2/SelectV2Props.d.ts +1 -1
- package/dist/Components/Tabs/TabsProps.d.ts +1 -1
- package/dist/Components/Tabs/components/Tab.js +1 -1
- package/dist/Components/Toggle/TableToggle.js +1 -1
- package/dist/Theme/tokens/primitives/controlSizes.d.ts +2 -1
- package/dist/Theme/tokens/primitives/controlSizes.js +10 -4
- package/dist/Theme/tokens/primitives/optionRowSizes.js +6 -6
- package/dist/esm/Components/AppSwitcher/AppSwitcher.js +1 -2
- package/dist/esm/Components/Button/Button.styles.js +2 -2
- package/dist/esm/Components/Common/fieldStyles.js +1 -1
- package/dist/esm/Components/Dropdown/DropDown.js +5 -5
- package/dist/esm/Components/OrgSwitcher/OrgSwitcher.js +3 -4
- package/dist/esm/Components/RangeSlider/rangeSliderSize.js +1 -1
- package/dist/esm/Components/SegmentedControl/SegmentedControl.js +2 -2
- package/dist/esm/Components/Tabs/components/Tab.js +2 -2
- package/dist/esm/Components/Toggle/TableToggle.js +2 -2
- package/dist/esm/Theme/tokens/primitives/controlSizes.js +9 -3
- package/dist/esm/Theme/tokens/primitives/optionRowSizes.js +6 -6
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -81,6 +81,18 @@ next major.
|
|
|
81
81
|
|
|
82
82
|
### Fixed
|
|
83
83
|
|
|
84
|
+
- **Control-size regression: field and button heights are two scales again, not one.** A
|
|
85
|
+
form-field-only bump had leaked into `Button`, `SegmentedControl`, `Tabs`, `TableToggle` and
|
|
86
|
+
`Dropdown`'s trigger through one shared token. `CONTROL_SIZES` (fields/selects: xs 24 · sm 38 ·
|
|
87
|
+
md 40 · lg 48) and `BUTTON_SIZES` (buttons and every button-like trigger: xs 24 · sm 32 · md 40 ·
|
|
88
|
+
lg 48, back to pre-regression) are now separate exports, gated by
|
|
89
|
+
`Common/sizeScaleOwnership.test.ts` so they can't silently merge again. `OPTION_ROW_SIZES`
|
|
90
|
+
(dropdown/select/menu row heights) is reverted to xs 24 · sm 30 · md 34 · lg 40; `OrgSwitcher`/
|
|
91
|
+
`AppSwitcher` are back on their own hardcoded literal sizes, not a shared token.
|
|
92
|
+
- **`CONTROL_SIZES.xs` (fields only) raised 24px → 32px.** `TextInput`, `Select`, `MultiSelect`,
|
|
93
|
+
`SearchSelect`, `SelectSearch`, `SelectV2`, `NumberInput`, `PinInput`, `Search` and the
|
|
94
|
+
`DatePicker` family at `size="xs"` are now 32px tall. `BUTTON_SIZES.xs` (`Button`,
|
|
95
|
+
`SegmentedControl`, `Tabs`, `TableToggle`, `Dropdown`'s trigger) is untouched, still 24px.
|
|
84
96
|
- **`SideBar`'s nav scrollbar thumb was the brand `primary` color.** Every other scrollbar in the
|
|
85
97
|
library reads a neutral chrome token; the sidebar's hand-rolled CSS (`Constants/Sidebar.ts`) was
|
|
86
98
|
the one place still reaching for `primary[500]`/`primary[700]`. It now reads
|
package/COMPONENT-GOTCHAS.md
CHANGED
|
@@ -312,7 +312,7 @@ not enough when the overlay sits inside a transition wrapper — the wrapper kee
|
|
|
312
312
|
|
|
313
313
|
| Component | beta.43 → beta.44 | Restore the old look |
|
|
314
314
|
| --- | --- | --- |
|
|
315
|
-
| Fields, selects, buttons (`Button`, `TextInput`, `InputTextArea`, `NumberInput`, DatePicker family, `Select`, `SelectV2`, `SearchSelect`, `SelectSearch`, `Search`, `Dropdown`, `SegmentedControl`) | Default size `md` → `sm` (38px). One scale for all: xs
|
|
315
|
+
| Fields, selects, buttons (`Button`, `TextInput`, `InputTextArea`, `NumberInput`, DatePicker family, `Select`, `SelectV2`, `SearchSelect`, `SelectSearch`, `Search`, `Dropdown`, `SegmentedControl`) | Default size `md` → `sm` (38px). One scale for all: xs 24 / sm 38 / md 40 / lg 48 — the same height in every field, select and button. `TimePicker` has no `size` (fixed `sm`); `SegmentedControl` has no `xs`. **Since decoupled** — fields/selects now read `CONTROL_SIZES` (xs 24 / sm 38 / md 40 / lg 48 at the time of the split; xs later raised to 32px), `Button`/`SegmentedControl`/`Tabs`/`TableToggle`/`Dropdown`'s trigger read the separate `BUTTON_SIZES` (xs 24 / sm 32 / md 40 / lg 48, back to pre-regression) — see the gotcha below | `size="md"` |
|
|
316
316
|
| `Button` | Text one step smaller (sm 14→13px, md 16→14, lg 18→16). Busy = spinner only, width kept (was "Loading" + spinner). Outline: 1px border, hover is a tint, not a fill | `loadingText="Loading"` |
|
|
317
317
|
| `Tag` | `solid`/`md` → `subtle`/`sm`. Hover + pointer only with `onTagClick`; `maxW` truncates with the full text as a title. Exact heights 20/24/28/32, weight 500, 1px inset ring (never adds height); subtle is a light tint with ink ≥ 6.5:1 | `variant="solid" size="md"` |
|
|
318
318
|
| `resolveSoftTone` | `bg`/`border` are now translucent (alpha hex) — composite onto the surface before `contrastRatio`; optional 3rd `surface` arg; adds `hoverBg`/`activeBg`. Badge/Alert/Toaster/EmptyState follow | — |
|
|
@@ -359,7 +359,7 @@ not enough when the overlay sits inside a transition wrapper — the wrapper kee
|
|
|
359
359
|
| `Tag` | Label line-height 1.45 so descenders (`p`, `g`, `y`) are no longer clipped by the ellipsis overflow | — |
|
|
360
360
|
| `Toaster` | `error` toasts announce assertively (`role="alert"`); status icons have a text equivalent | — |
|
|
361
361
|
| `FeedbackForm` | Built on `TextInput`/`InputTextArea`/`RadioButtonGroup`; required fields show `*` in the label | — |
|
|
362
|
-
| `PinInput` | `size` now works (square cells
|
|
362
|
+
| `PinInput` | `size` now works (square cells 24 / 38 / 40 / 48, default `sm`) — it was silently ignored | `size="md"` |
|
|
363
363
|
| `Tag` | New `leadingIcon` (decorative, before the label) and `isDisabled` (sets `aria-disabled` + native `disabled` on the clickable/remove buttons, so they leave the tab order — not just dimmed) | — |
|
|
364
364
|
| `ToolTip` | Defaults a Popper `preventOverflow` padding of 8px, so a bubble near the right edge no longer overhangs by a subpixel and raises page scrollbars. A caller-supplied `preventOverflow` modifier still wins | pass your own `modifiers` |
|
|
365
365
|
| `Table` / `KanbanBoard` | Column sort buttons and draggable cards now show the library focus ring on keyboard focus (was an opacity flicker / the browser default outline). Kanban card wrappers render as Chakra `Box`; keyboard drag (Space, arrows, Space) is unchanged | — |
|
|
@@ -388,6 +388,26 @@ differ — this is a rewrite of the call site, not a rename.
|
|
|
388
388
|
`RangeSlider`, `Spinner`, `Tab`, `TabList`, `TabPanel`, `TabPanels`, `Tabs`. They now point at the
|
|
389
389
|
library's own themed component rather than the Chakra passthrough.
|
|
390
390
|
|
|
391
|
+
### `CONTROL_SIZES` (fields) and `BUTTON_SIZES` (buttons) are separate scales — changing one never changes the other
|
|
392
|
+
|
|
393
|
+
Fields/selects (`TextInput`, `Select`, `MultiSelect`, `SearchSelect`, `NumberInput`, `PinInput`, the
|
|
394
|
+
`DatePicker` family, …) read `CONTROL_SIZES` — xs 32 · sm 38 · md 40 · lg 48. `Button` and every
|
|
395
|
+
button-like trigger (`SegmentedControl`, `Tabs`, `TableToggle`, `Dropdown`'s trigger) read the
|
|
396
|
+
separate `BUTTON_SIZES` — xs 24 · sm 32 · md 40 · lg 48. They used to share one token, which is what
|
|
397
|
+
let a field-only size bump leak into buttons — the split is now gate-tested
|
|
398
|
+
(`Common/sizeScaleOwnership.test.ts`).
|
|
399
|
+
|
|
400
|
+
**Apply:** a PR that "just" bumps a form-field size should never touch `Button.styles.ts`,
|
|
401
|
+
`SegmentedControl`, `Tab`, `TableToggle` or `Dropdown` — if it does, it's reading the wrong token.
|
|
402
|
+
|
|
403
|
+
### `controlSizeStyles()`'s `minH` silently overrides a smaller `h` override
|
|
404
|
+
|
|
405
|
+
`fieldStyles.ts`'s `controlSizeStyles()` sets both `h` and `minH` to the same token value. A caller
|
|
406
|
+
overriding only `h` with a smaller literal compiles and renders, but the inherited `minH` still
|
|
407
|
+
wins, so the field stays at the token height.
|
|
408
|
+
|
|
409
|
+
**Apply:** override both `h` and `minH` together, or don't override either.
|
|
410
|
+
|
|
391
411
|
### `Tag`'s `onIconClick` renders nothing without `icon` — the remove button silently never appears
|
|
392
412
|
|
|
393
413
|
`onIconClick` only turns `icon` into a remove button; it has no effect on its own (`Tag.tsx`
|
package/DESIGN-GUIDE.md
CHANGED
|
@@ -87,12 +87,14 @@ stay light in dark mode.
|
|
|
87
87
|
`secondary` and `tertiary` render as the same hex on most brands (see `COMPONENT-GOTCHAS.md`) —
|
|
88
88
|
don't lean on that pair to distinguish two categories; reach for a utility scheme instead.
|
|
89
89
|
|
|
90
|
-
## 5. Controls —
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
`
|
|
95
|
-
|
|
90
|
+
## 5. Controls — two scales, `sm` by default
|
|
91
|
+
|
|
92
|
+
Fields (`TextInput`, `InputTextArea`, `NumberInput`, `Select`, `Search`, `RangeSlider`, the
|
|
93
|
+
`DatePicker` family) sit on `CONTROL_SIZES` — `xs` 32px · `sm` 38px · `md` 40px · `lg` 48px.
|
|
94
|
+
`Button` and every button-like trigger (`SegmentedControl`, `Tabs`, `TableToggle`, `Dropdown`)
|
|
95
|
+
sit on the separate `BUTTON_SIZES` scale — `xs` 24px · `sm` 32px · `md` 40px · `lg` 48px. Both
|
|
96
|
+
**default to `sm`**, so on a desktop page **don't pass `size`**. They line up at `md`/`lg`; at
|
|
97
|
+
`sm` a button reads 6px shorter than the field beside it.
|
|
96
98
|
|
|
97
99
|
| Button role | Props |
|
|
98
100
|
| --- | --- |
|
|
@@ -46,10 +46,9 @@ const useExclusiveOverlay_1 = require("../../Hooks/useExclusiveOverlay");
|
|
|
46
46
|
const AppMark_1 = __importStar(require("./AppMark"));
|
|
47
47
|
const AppSwitcherProps_1 = require("./AppSwitcherProps");
|
|
48
48
|
const useAppSwitcherShortcut_1 = require("./useAppSwitcherShortcut");
|
|
49
|
-
const controlSizes_1 = require("../../Theme/tokens/primitives/controlSizes");
|
|
50
49
|
const COLUMNS = 2;
|
|
51
50
|
const HEADING = "Your apps";
|
|
52
|
-
const s = { trigger:
|
|
51
|
+
const s = { trigger: "36px", mark: "32px", icon: 17, name: "0.875rem", sub: "0.75rem", row: "52px" };
|
|
53
52
|
const warned = new Set();
|
|
54
53
|
const warnOnce = (key, message) => {
|
|
55
54
|
if (process.env.NODE_ENV === "production" || warned.has(key))
|
|
@@ -8,7 +8,7 @@ const focusRing_styles_1 = require("../../Theme/chakra/focusRing.styles");
|
|
|
8
8
|
const motion_1 = require("../../Theme/chakra/motion");
|
|
9
9
|
const primitives_1 = require("../../Theme/tokens/primitives");
|
|
10
10
|
const controlSize = (size) => {
|
|
11
|
-
const { height, fontSize, paddingX } = primitives_1.
|
|
11
|
+
const { height, fontSize, paddingX } = primitives_1.BUTTON_SIZES[size];
|
|
12
12
|
return { h: height, minW: height, fontSize, px: paddingX };
|
|
13
13
|
};
|
|
14
14
|
// NOTE: [500] alone measures ~4.2 on a dark canvas — resolved per-mode so outline/ghost/link text stays readable.
|
|
@@ -11,7 +11,7 @@ export type ButtonProps = LayoutProps & DataAttributes & Pick<ChakraButtonProps,
|
|
|
11
11
|
loadingText?: string;
|
|
12
12
|
/** Defaults to "fit-content", not 100%; the w alias only applies when width is unset — width wins if both are passed. */
|
|
13
13
|
width?: string | number;
|
|
14
|
-
/** Control height xs
|
|
14
|
+
/** Control height xs 24 · sm 32 · md 40 · lg 48 (xl 56); defaults to "sm" via the theme, so a ButtonGroup size still applies. */
|
|
15
15
|
size?: "lg" | "md" | "sm" | "xs" | "xl";
|
|
16
16
|
/** Defaults to "solid"; "gradient" paints the theme's fixed brand gradient. */
|
|
17
17
|
variant?: "solid" | "outline" | "ghost" | "link" | "unstyled" | "gradient";
|
|
@@ -5,7 +5,7 @@ import { type ControlSize } from "../../Theme/tokens/primitives/controlSizes";
|
|
|
5
5
|
export declare const FIELD_RADIUS = "lg";
|
|
6
6
|
export declare const FIELD_BORDER_WIDTH = "1px";
|
|
7
7
|
export declare const FIELD_TRANSITION: string;
|
|
8
|
-
/** Chakra `h`/`fontSize`/`px` for a
|
|
8
|
+
/** Chakra `h`/`fontSize`/`px` for a field or select of this size. */
|
|
9
9
|
export declare const controlSizeStyles: (size: ControlSize) => {
|
|
10
10
|
h: string;
|
|
11
11
|
minH: string;
|
|
@@ -9,7 +9,7 @@ const focusRing_styles_1 = require("../../Theme/chakra/focusRing.styles");
|
|
|
9
9
|
exports.FIELD_RADIUS = "lg";
|
|
10
10
|
exports.FIELD_BORDER_WIDTH = "1px";
|
|
11
11
|
exports.FIELD_TRANSITION = (0, motion_1.transitionFor)(["border-color", "box-shadow", "background-color"]);
|
|
12
|
-
/** Chakra `h`/`fontSize`/`px` for a
|
|
12
|
+
/** Chakra `h`/`fontSize`/`px` for a field or select of this size. */
|
|
13
13
|
const controlSizeStyles = (size) => {
|
|
14
14
|
const spec = controlSizes_1.CONTROL_SIZES[size];
|
|
15
15
|
return { h: spec.height, minH: spec.height, fontSize: spec.fontSize, px: spec.paddingX };
|
|
@@ -44,7 +44,7 @@ export type BaseDatePickerProps = {
|
|
|
44
44
|
width?: string | number;
|
|
45
45
|
/** Blocks today in the calendar and in typed input; the single picker preselects tomorrow instead. */
|
|
46
46
|
disableToday?: boolean;
|
|
47
|
-
/** Control-scale height: xs
|
|
47
|
+
/** Control-scale height: xs 32 · sm 38 · md 40 · lg 48px (default `sm`, like TextInput); also scales the calendar/clock icon. */
|
|
48
48
|
size?: "xs" | "sm" | "md" | "lg";
|
|
49
49
|
};
|
|
50
50
|
/** Single-date variant, Date API (default) — `isRange` must be false or omitted; this is the discriminant the DatePickerProps union switches on. */
|
|
@@ -17,10 +17,10 @@ const motion_2 = require("../../Theme/chakra/motion");
|
|
|
17
17
|
const focusRing_styles_1 = require("../../Theme/chakra/focusRing.styles");
|
|
18
18
|
const MotionBox = (0, framer_motion_1.motion)((0, react_1.forwardRef)((props, ref) => ((0, jsx_runtime_1.jsx)(react_2.Box, { ref: ref, ...props }))));
|
|
19
19
|
const SIZE_MAP = {
|
|
20
|
-
xs: { btn: "xs", img: "1rem", chevron: controlSizes_1.
|
|
21
|
-
sm: { btn: "sm", img: "1rem", chevron: controlSizes_1.
|
|
22
|
-
md: { btn: "md", img: "1.125rem", chevron: controlSizes_1.
|
|
23
|
-
lg: { btn: "lg", img: "1.25rem", chevron: controlSizes_1.
|
|
20
|
+
xs: { btn: "xs", img: "1rem", chevron: controlSizes_1.BUTTON_SIZES.xs.iconSize, minW: "8rem", gap: 1.5, rowSize: "xs" },
|
|
21
|
+
sm: { btn: "sm", img: "1rem", chevron: controlSizes_1.BUTTON_SIZES.sm.iconSize, minW: "9rem", gap: 2, rowSize: "sm" },
|
|
22
|
+
md: { btn: "md", img: "1.125rem", chevron: controlSizes_1.BUTTON_SIZES.md.iconSize, minW: "11rem", gap: 2, rowSize: "md" },
|
|
23
|
+
lg: { btn: "lg", img: "1.25rem", chevron: controlSizes_1.BUTTON_SIZES.lg.iconSize, minW: "12rem", gap: 2.5, rowSize: "lg" },
|
|
24
24
|
xl: { btn: "lg", img: "1.4rem", chevron: 20, minW: "13rem", gap: 3, rowSize: "lg" },
|
|
25
25
|
};
|
|
26
26
|
const TRIGGER_TRANSITION = (0, motion_1.transitionFor)(["background-color", "border-color", "color", "box-shadow"]);
|
|
@@ -28,7 +28,7 @@ export type DropdownProps = {
|
|
|
28
28
|
LabelStyle?: React.CSSProperties;
|
|
29
29
|
/** Inline style on each row's `image` icon; ignored for options without one. */
|
|
30
30
|
ImageStyle?: React.CSSProperties;
|
|
31
|
-
/** Trigger
|
|
31
|
+
/** Trigger on the button scale, menu rows on the option-row scale; defaults to `sm`. `xl` renders an `lg` trigger. */
|
|
32
32
|
size?: "xs" | "sm" | "md" | "lg" | "xl";
|
|
33
33
|
/** @deprecated Use `size` instead. Kept for backward compatibility. */
|
|
34
34
|
optionsSize?: "sm" | "md" | "lg";
|
|
@@ -10,7 +10,7 @@ export type PhoneNumberInputProps = {
|
|
|
10
10
|
label?: string;
|
|
11
11
|
/** Falls back to an auto-generated id (shared with `inputId` when that's omitted too), so the label is always bound. */
|
|
12
12
|
id?: string;
|
|
13
|
-
/** Control-scale height:
|
|
13
|
+
/** Control-scale height: xs 32 · sm 38 · md 40 · lg 48px. Defaults to "sm", like TextInput, so it lines up in a form. */
|
|
14
14
|
size?: string;
|
|
15
15
|
value?: string;
|
|
16
16
|
codeValueReturn?: boolean;
|
|
@@ -18,7 +18,7 @@ export type MultiSelectProps = {
|
|
|
18
18
|
addOnBlur?: boolean;
|
|
19
19
|
/** Marks the field invalid (`aria-invalid` + error border) and swaps `helperText` for `errorMessage`; a rejected email sets this internally too. */
|
|
20
20
|
error?: boolean;
|
|
21
|
-
/** Height on the
|
|
21
|
+
/** Height on the field control scale (xs 32 · sm 38 · md 40 · lg 48px). Defaults to `sm`. */
|
|
22
22
|
size?: "xs" | "sm" | "md" | "lg";
|
|
23
23
|
inputStyle?: object;
|
|
24
24
|
/** Rendered only while `error` is true; a rejected email's internal "Invalid email address" text wins over this until the input changes. */
|
|
@@ -4,7 +4,7 @@ import type { Tone } from "../../Theme/tokens/builders/tone";
|
|
|
4
4
|
import type { DaySectionLabels } from "./notificationHelpers";
|
|
5
5
|
/** Shared tone vocabulary for the badge, row tile and zone/filter buttons — an alias of the theme's Tone. */
|
|
6
6
|
export type NotificationTone = Tone;
|
|
7
|
-
/**
|
|
7
|
+
/** Button size scale for the bell trigger. */
|
|
8
8
|
export type NotificationBellSize = "xs" | "sm" | "md" | "lg";
|
|
9
9
|
/** Bell trigger with the three-state badge (capped count -> dot -> nothing); renders no panel itself. */
|
|
10
10
|
export interface NotificationBellProps {
|
|
@@ -11,11 +11,10 @@ const outlineRung_1 = require("../../Theme/tokens/builders/outlineRung");
|
|
|
11
11
|
const rowStates_1 = require("../../Theme/tokens/builders/rowStates");
|
|
12
12
|
const useExclusiveOverlay_1 = require("../../Hooks/useExclusiveOverlay");
|
|
13
13
|
const OrgSwitcherProps_1 = require("./OrgSwitcherProps");
|
|
14
|
-
const controlSizes_1 = require("../../Theme/tokens/primitives/controlSizes");
|
|
15
14
|
const sizeMap = {
|
|
16
|
-
sm: { h:
|
|
17
|
-
md: { h:
|
|
18
|
-
lg: { h:
|
|
15
|
+
sm: { h: "32px", avatar: "22px", font: "0.8rem", sub: "0.65rem", px: 2 },
|
|
16
|
+
md: { h: "40px", avatar: "28px", font: "0.9rem", sub: "0.7rem", px: 3 },
|
|
17
|
+
lg: { h: "48px", avatar: "34px", font: "1rem", sub: "0.78rem", px: 4 },
|
|
19
18
|
};
|
|
20
19
|
const Avatar = ({ org, boxSize, fontSize, }) => {
|
|
21
20
|
const { colors } = (0, useCustomTheme_1.useCustomTheme)();
|
|
@@ -2,7 +2,7 @@ import { PinInputProps } from "@chakra-ui/react";
|
|
|
2
2
|
/** The only pin/OTP component exported from the package. */
|
|
3
3
|
export type ChakraPinInputProps = Pick<PinInputProps, "otp" | "mask" | "defaultValue" | "placeholder" | "manageFocus" | "errorBorderColor" | "focusBorderColor" | "onChange" | "onComplete"> & {
|
|
4
4
|
type?: "alphanumeric" | "number";
|
|
5
|
-
/** Square cell size, aligned to CONTROL_SIZES heights (xs
|
|
5
|
+
/** Square cell size, aligned to CONTROL_SIZES heights (xs 32 · sm 38 · md 40 · lg 48). Defaults to "sm". */
|
|
6
6
|
size?: "xs" | "sm" | "md" | "lg";
|
|
7
7
|
variant?: "flushed" | "outline" | "filled" | "unstyled";
|
|
8
8
|
color?: "gray" | "red" | "orange" | "yellow" | "green" | "teal" | "blue" | "cyan" | "purple" | "pink" | "whiteAlpha" | "blackAlpha" | "primary";
|
|
@@ -23,7 +23,7 @@ interface RangeSliderSharedProps {
|
|
|
23
23
|
scale?: SliderScale;
|
|
24
24
|
/** Formats a raw value for display — value labels, tooltip and aria-valuetext. Defaults to String. */
|
|
25
25
|
formatValue?: (value: number) => string;
|
|
26
|
-
/** Track thickness and thumb size,
|
|
26
|
+
/** Track thickness and thumb size, keyed by ControlSize name — its own values, not the field or button scale. Defaults to "sm". */
|
|
27
27
|
size?: ControlSize;
|
|
28
28
|
/** Heading shown above the track. Pass "" to render none. Defaults to "Range". */
|
|
29
29
|
label?: string;
|
|
@@ -3,5 +3,5 @@ export type RangeSliderSizeSpec = {
|
|
|
3
3
|
trackHeight: string;
|
|
4
4
|
thumbSize: string;
|
|
5
5
|
};
|
|
6
|
-
/** Track thickness and thumb diameter for a size,
|
|
6
|
+
/** Track thickness and thumb diameter for a size — its own values, keyed by the same size names. */
|
|
7
7
|
export declare const rangeSliderSize: (size: ControlSize) => RangeSliderSizeSpec;
|
|
@@ -7,6 +7,6 @@ const RANGE_SLIDER_SIZES = {
|
|
|
7
7
|
md: { trackHeight: "4px", thumbSize: "1.25rem" },
|
|
8
8
|
lg: { trackHeight: "5px", thumbSize: "1.5rem" },
|
|
9
9
|
};
|
|
10
|
-
/** Track thickness and thumb diameter for a size,
|
|
10
|
+
/** Track thickness and thumb diameter for a size — its own values, keyed by the same size names. */
|
|
11
11
|
const rangeSliderSize = (size) => RANGE_SLIDER_SIZES[size];
|
|
12
12
|
exports.rangeSliderSize = rangeSliderSize;
|
|
@@ -15,7 +15,7 @@ export type SearchProps = {
|
|
|
15
15
|
onClear?: () => void;
|
|
16
16
|
/** @deprecated Use `onClear` — same behaviour, consistent casing. */
|
|
17
17
|
onclose?: () => void;
|
|
18
|
-
/** Height on the
|
|
18
|
+
/** Height on the field control scale (xs 32 · sm 38 · md 40 · lg 48px). Defaults to `sm`. */
|
|
19
19
|
size?: ControlSize;
|
|
20
20
|
name?: string;
|
|
21
21
|
/** Disables the input and hides the clear button; the hotkey still focuses it. */
|
|
@@ -38,7 +38,7 @@ export type SearchSelectProps = {
|
|
|
38
38
|
width?: string | number;
|
|
39
39
|
/** Only sets the insideSelect segment's height, not the main field's — that's driven by `size`. */
|
|
40
40
|
height?: string | number;
|
|
41
|
-
/** Height on the
|
|
41
|
+
/** Height on the field control scale (xs 32 · sm 38 · md 40 · lg 48px). Defaults to `sm`. */
|
|
42
42
|
size?: "xs" | "sm" | "md" | "lg";
|
|
43
43
|
/** Blocks opening, typing, chip removal and clearing; renders the shared disabled field look. */
|
|
44
44
|
isDisabled?: boolean;
|
|
@@ -27,7 +27,7 @@ const formatCount = (count) => (count > MAX_COUNT ? `${MAX_COUNT}+` : `${count}`
|
|
|
27
27
|
/** Renders role="radiogroup" of role="radio" buttons with roving tabindex, not a native form radio group; shares variant with Toggle/TableToggle (see MODULE.md). */
|
|
28
28
|
function SegmentedControl({ options, value, onChange, size = "sm", isFullWidth = false, variant = "default", surface, "aria-label": ariaLabel, }) {
|
|
29
29
|
const { colors, radii } = (0, useCustomTheme_1.useCustomTheme)();
|
|
30
|
-
const control = controlSizes_1.
|
|
30
|
+
const control = controlSizes_1.BUTTON_SIZES[size];
|
|
31
31
|
const isBrandSlide = variant === "brandSlide";
|
|
32
32
|
const isUnderlineSlide = variant === "underlineSlide";
|
|
33
33
|
const hasIndicator = isBrandSlide || isUnderlineSlide;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ControlSize } from "../../Theme/tokens/primitives/controlSizes";
|
|
2
|
-
/** Whole-track height on the
|
|
2
|
+
/** Whole-track height on the button control scale (sm 32 · md 40 · lg 48px); defaults to "sm". */
|
|
3
3
|
export type SegmentedControlSize = Exclude<ControlSize, "xs">;
|
|
4
4
|
/** brandSlide = primary view switcher; underlineSlide = dense toolbar; default = plain buttons. */
|
|
5
5
|
export type SegmentedControlVariant = "default" | "brandSlide" | "underlineSlide";
|
|
@@ -24,7 +24,7 @@ type SelectCommonProps = {
|
|
|
24
24
|
label?: string;
|
|
25
25
|
/** Native: the built-in placeholder `<option>`. Popup: trigger text when nothing is selected. Defaults to "Select Option". */
|
|
26
26
|
placeholder?: string;
|
|
27
|
-
/** Height on the
|
|
27
|
+
/** Height on the field control scale (xs 32 · sm 38 · md 40 · lg 48px). Defaults to `sm`. */
|
|
28
28
|
size?: ControlSize;
|
|
29
29
|
/** Applied to the wrapping FormControl. */
|
|
30
30
|
width?: string | number;
|
|
@@ -49,7 +49,7 @@ export type SelectSearchProps = {
|
|
|
49
49
|
errorMessage?: string | undefined;
|
|
50
50
|
/** Hint under the field; replaced by `errorMessage` while `error` is true. */
|
|
51
51
|
helperText?: string;
|
|
52
|
-
/** Height on the
|
|
52
|
+
/** Height on the field control scale (xs 32 · sm 38 · md 40 · lg 48px). Defaults to `sm`. */
|
|
53
53
|
size?: ControlSize;
|
|
54
54
|
/** Shows a sticky "Add New"-style footer row in the popup; required for all Bottom* props. */
|
|
55
55
|
isBottomIcon?: boolean | undefined;
|
|
@@ -33,7 +33,7 @@ type SelectV2CommonProps = {
|
|
|
33
33
|
isReadOnly?: boolean;
|
|
34
34
|
/** Label asterisk + `aria-required` only; never blocks an empty submit. */
|
|
35
35
|
isRequired?: boolean;
|
|
36
|
-
/**
|
|
36
|
+
/** Field control scale (xs 32 · sm 38 · md 40 · lg 48px). Defaults to `sm`. */
|
|
37
37
|
size?: ControlSize;
|
|
38
38
|
/** Shows a type-ahead filter input at the top of the popup. Defaults to true. */
|
|
39
39
|
isSearchable?: boolean;
|
|
@@ -32,7 +32,7 @@ export interface TabsProps {
|
|
|
32
32
|
defaultValue?: string;
|
|
33
33
|
onChange?: (value: string) => void;
|
|
34
34
|
variant?: TabsVariant;
|
|
35
|
-
/** Defaults to "sm",
|
|
35
|
+
/** Defaults to "sm", on the button control scale (sm 32 · md 40 · lg 48px), not form fields. */
|
|
36
36
|
size?: ControlSize;
|
|
37
37
|
colorScheme?: TabsColorScheme;
|
|
38
38
|
orientation?: TabsOrientation;
|
|
@@ -29,7 +29,7 @@ const Tab = ({ value, children, icon, count, isDisabled }) => {
|
|
|
29
29
|
const canvas = colors.backgroundColor.main;
|
|
30
30
|
const scale = (0, tabStyles_1.scaleForColorScheme)(colors, ctx.colorScheme);
|
|
31
31
|
const style = (0, tabStyles_1.resolveTabStyle)(colors, scale, canvas, ctx.variant, isSelected);
|
|
32
|
-
const spec = controlSizes_1.
|
|
32
|
+
const spec = controlSizes_1.BUTTON_SIZES[ctx.size];
|
|
33
33
|
// The list scrolls on both axes, so an outer ring is clipped into arcs; a negative offset draws it
|
|
34
34
|
// inside the tab, clear of its own border rather than thickening it.
|
|
35
35
|
const focusRing = {
|
|
@@ -13,7 +13,7 @@ const ToolTip_1 = __importDefault(require("../ToolTip/ToolTip"));
|
|
|
13
13
|
const useSlidingPill_1 = require("../SegmentedControl/useSlidingPill");
|
|
14
14
|
const controlSizes_1 = require("../../Theme/tokens/primitives/controlSizes");
|
|
15
15
|
const MODES = ["grid", "list"];
|
|
16
|
-
const TRACK_HEIGHT = controlSizes_1.
|
|
16
|
+
const TRACK_HEIGHT = controlSizes_1.BUTTON_SIZES.sm.height;
|
|
17
17
|
const SEGMENT_HEIGHT = `calc(${TRACK_HEIGHT} - 0.25rem)`;
|
|
18
18
|
/** Two icon-only IconButtons (Grid/List), aria-pressed marks the active one; shares variant with SegmentedControl (see MODULE.md). */
|
|
19
19
|
const TableToggle = ({ value, onChange, variant = "default" }) => {
|
|
@@ -5,8 +5,9 @@ export type ControlSizeSpec = {
|
|
|
5
5
|
paddingX: string;
|
|
6
6
|
iconSize: number;
|
|
7
7
|
};
|
|
8
|
-
/**
|
|
8
|
+
/** Height scale for form fields and selects — text inputs, pickers, anything typed or picked into. */
|
|
9
9
|
export declare const CONTROL_SIZES: Readonly<Record<ControlSize, ControlSizeSpec>>;
|
|
10
|
+
export declare const BUTTON_SIZES: Readonly<Record<ControlSize, ControlSizeSpec>>;
|
|
10
11
|
export declare const CONTROL_SIZE_NAMES: readonly ControlSize[];
|
|
11
12
|
export declare const DEFAULT_CONTROL_SIZE: ControlSize;
|
|
12
13
|
export declare const isControlSize: (value: unknown) => value is ControlSize;
|
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.isControlSize = exports.DEFAULT_CONTROL_SIZE = exports.CONTROL_SIZE_NAMES = exports.CONTROL_SIZES = void 0;
|
|
4
|
-
/**
|
|
3
|
+
exports.isControlSize = exports.DEFAULT_CONTROL_SIZE = exports.CONTROL_SIZE_NAMES = exports.BUTTON_SIZES = exports.CONTROL_SIZES = void 0;
|
|
4
|
+
/** Height scale for form fields and selects — text inputs, pickers, anything typed or picked into. */
|
|
5
5
|
exports.CONTROL_SIZES = {
|
|
6
|
-
xs: { height: "
|
|
6
|
+
xs: { height: "2rem", fontSize: "0.75rem", paddingX: "0.5rem", iconSize: 12 },
|
|
7
7
|
sm: { height: "2.375rem", fontSize: "0.8125rem", paddingX: "0.75rem", iconSize: 14 },
|
|
8
|
-
md: { height: "2.
|
|
8
|
+
md: { height: "2.5rem", fontSize: "0.875rem", paddingX: "1rem", iconSize: 16 },
|
|
9
|
+
lg: { height: "3rem", fontSize: "1rem", paddingX: "1.5rem", iconSize: 18 },
|
|
10
|
+
};
|
|
11
|
+
exports.BUTTON_SIZES = {
|
|
12
|
+
xs: { height: "1.5rem", fontSize: "0.75rem", paddingX: "0.5rem", iconSize: 12 },
|
|
13
|
+
sm: { height: "2rem", fontSize: "0.8125rem", paddingX: "0.75rem", iconSize: 14 },
|
|
14
|
+
md: { height: "2.5rem", fontSize: "0.875rem", paddingX: "1rem", iconSize: 16 },
|
|
9
15
|
lg: { height: "3rem", fontSize: "1rem", paddingX: "1.5rem", iconSize: 18 },
|
|
10
16
|
};
|
|
11
17
|
exports.CONTROL_SIZE_NAMES = ["xs", "sm", "md", "lg"];
|
|
@@ -4,19 +4,19 @@ exports.optionRowSpec = exports.OPTION_ROW_RADIUS = exports.OPTION_ROW_SIZES = v
|
|
|
4
4
|
/** One density for every option row — Select, SearchSelect, SelectSearch, table filters and Chakra's MenuItem. */
|
|
5
5
|
exports.OPTION_ROW_SIZES = {
|
|
6
6
|
xs: {
|
|
7
|
-
minH: "1.
|
|
7
|
+
minH: "1.5rem", px: "0.5rem", py: "0.125rem", gap: "0.375rem", mx: "0.25rem",
|
|
8
8
|
fontSize: "0.75rem", descriptionFontSize: "0.6875rem", iconSize: 12,
|
|
9
|
-
avatarSize: "2xs", virtualRowHeightPx:
|
|
9
|
+
avatarSize: "2xs", virtualRowHeightPx: 24,
|
|
10
10
|
},
|
|
11
11
|
sm: {
|
|
12
|
-
minH: "
|
|
12
|
+
minH: "1.875rem", px: "0.625rem", py: "0.25rem", gap: "0.5rem", mx: "0.375rem",
|
|
13
13
|
fontSize: "0.8125rem", descriptionFontSize: "0.75rem", iconSize: 14,
|
|
14
|
-
avatarSize: "xs", virtualRowHeightPx:
|
|
14
|
+
avatarSize: "xs", virtualRowHeightPx: 30,
|
|
15
15
|
},
|
|
16
16
|
md: {
|
|
17
|
-
minH: "2.
|
|
17
|
+
minH: "2.125rem", px: "0.75rem", py: "0.3125rem", gap: "0.5rem", mx: "0.375rem",
|
|
18
18
|
fontSize: "0.875rem", descriptionFontSize: "0.75rem", iconSize: 16,
|
|
19
|
-
avatarSize: "xs", virtualRowHeightPx:
|
|
19
|
+
avatarSize: "xs", virtualRowHeightPx: 34,
|
|
20
20
|
},
|
|
21
21
|
lg: {
|
|
22
22
|
minH: "2.5rem", px: "0.875rem", py: "0.375rem", gap: "0.625rem", mx: "0.5rem",
|
|
@@ -11,10 +11,9 @@ import { useExclusiveOverlay } from "../../Hooks/useExclusiveOverlay.js";
|
|
|
11
11
|
import AppMark, { assignAppHues } from "./AppMark.js";
|
|
12
12
|
import { filterApps, formatShortcut, } from "./AppSwitcherProps.js";
|
|
13
13
|
import { useAppSwitcherShortcut } from "./useAppSwitcherShortcut.js";
|
|
14
|
-
import { CONTROL_SIZES } from "../../Theme/tokens/primitives/controlSizes.js";
|
|
15
14
|
const COLUMNS = 2;
|
|
16
15
|
const HEADING = "Your apps";
|
|
17
|
-
const s = { trigger:
|
|
16
|
+
const s = { trigger: "36px", mark: "32px", icon: 17, name: "0.875rem", sub: "0.75rem", row: "52px" };
|
|
18
17
|
const warned = new Set();
|
|
19
18
|
const warnOnce = (key, message) => {
|
|
20
19
|
if (process.env.NODE_ENV === "production" || warned.has(key))
|
|
@@ -3,9 +3,9 @@ import { darkerFillRung, labelOnFill, solidFillRung, } from "../../Theme/tokens/
|
|
|
3
3
|
import { resolveGradient, gradientCss } from "../../Theme/tokens/builders/gradientInk.js";
|
|
4
4
|
import { focusVisibleStyles } from "../../Theme/chakra/focusRing.styles.js";
|
|
5
5
|
import { reducedMotionSx } from "../../Theme/chakra/motion.js";
|
|
6
|
-
import {
|
|
6
|
+
import { BUTTON_SIZES, DEFAULT_CONTROL_SIZE, transitionFor } from "../../Theme/tokens/primitives/index.js";
|
|
7
7
|
const controlSize = (size) => {
|
|
8
|
-
const { height, fontSize, paddingX } =
|
|
8
|
+
const { height, fontSize, paddingX } = BUTTON_SIZES[size];
|
|
9
9
|
return { h: height, minW: height, fontSize, px: paddingX };
|
|
10
10
|
};
|
|
11
11
|
// NOTE: [500] alone measures ~4.2 on a dark canvas — resolved per-mode so outline/ghost/link text stays readable.
|
|
@@ -6,7 +6,7 @@ import { fieldFocusVisible, focusGlowShadow } from "../../Theme/chakra/focusRing
|
|
|
6
6
|
export const FIELD_RADIUS = "lg";
|
|
7
7
|
export const FIELD_BORDER_WIDTH = "1px";
|
|
8
8
|
export const FIELD_TRANSITION = transitionFor(["border-color", "box-shadow", "background-color"]);
|
|
9
|
-
/** Chakra `h`/`fontSize`/`px` for a
|
|
9
|
+
/** Chakra `h`/`fontSize`/`px` for a field or select of this size. */
|
|
10
10
|
export const controlSizeStyles = (size) => {
|
|
11
11
|
const spec = CONTROL_SIZES[size];
|
|
12
12
|
return { h: spec.height, minH: spec.height, fontSize: spec.fontSize, px: spec.paddingX };
|
|
@@ -8,17 +8,17 @@ import { listRowBackgrounds } from "../../Theme/tokens/builders/rowStates.js";
|
|
|
8
8
|
import { useExclusiveOverlay } from "../../Hooks/useExclusiveOverlay.js";
|
|
9
9
|
import { ChevronDown } from "lucide-react";
|
|
10
10
|
import { rafThrottle } from "../../Utils/rafThrottle.js";
|
|
11
|
-
import {
|
|
11
|
+
import { BUTTON_SIZES } from "../../Theme/tokens/primitives/controlSizes.js";
|
|
12
12
|
import { optionRowSpec, OPTION_ROW_RADIUS } from "../../Theme/tokens/primitives/optionRowSizes.js";
|
|
13
13
|
import { transitionFor } from "../../Theme/tokens/primitives/motion.js";
|
|
14
14
|
import { reducedMotionSx } from "../../Theme/chakra/motion.js";
|
|
15
15
|
import { focusVisibleStyles } from "../../Theme/chakra/focusRing.styles.js";
|
|
16
16
|
const MotionBox = motion(forwardRef((props, ref) => (_jsx(Box, { ref: ref, ...props }))));
|
|
17
17
|
const SIZE_MAP = {
|
|
18
|
-
xs: { btn: "xs", img: "1rem", chevron:
|
|
19
|
-
sm: { btn: "sm", img: "1rem", chevron:
|
|
20
|
-
md: { btn: "md", img: "1.125rem", chevron:
|
|
21
|
-
lg: { btn: "lg", img: "1.25rem", chevron:
|
|
18
|
+
xs: { btn: "xs", img: "1rem", chevron: BUTTON_SIZES.xs.iconSize, minW: "8rem", gap: 1.5, rowSize: "xs" },
|
|
19
|
+
sm: { btn: "sm", img: "1rem", chevron: BUTTON_SIZES.sm.iconSize, minW: "9rem", gap: 2, rowSize: "sm" },
|
|
20
|
+
md: { btn: "md", img: "1.125rem", chevron: BUTTON_SIZES.md.iconSize, minW: "11rem", gap: 2, rowSize: "md" },
|
|
21
|
+
lg: { btn: "lg", img: "1.25rem", chevron: BUTTON_SIZES.lg.iconSize, minW: "12rem", gap: 2.5, rowSize: "lg" },
|
|
22
22
|
xl: { btn: "lg", img: "1.4rem", chevron: 20, minW: "13rem", gap: 3, rowSize: "lg" },
|
|
23
23
|
};
|
|
24
24
|
const TRIGGER_TRANSITION = transitionFor(["background-color", "border-color", "color", "box-shadow"]);
|
|
@@ -9,11 +9,10 @@ import { resolveHoverTint } from "../../Theme/tokens/builders/outlineRung.js";
|
|
|
9
9
|
import { listRowBackgrounds } from "../../Theme/tokens/builders/rowStates.js";
|
|
10
10
|
import { useExclusiveOverlay } from "../../Hooks/useExclusiveOverlay.js";
|
|
11
11
|
import { avatarColor, orgInitial, } from "./OrgSwitcherProps.js";
|
|
12
|
-
import { CONTROL_SIZES } from "../../Theme/tokens/primitives/controlSizes.js";
|
|
13
12
|
const sizeMap = {
|
|
14
|
-
sm: { h:
|
|
15
|
-
md: { h:
|
|
16
|
-
lg: { h:
|
|
13
|
+
sm: { h: "32px", avatar: "22px", font: "0.8rem", sub: "0.65rem", px: 2 },
|
|
14
|
+
md: { h: "40px", avatar: "28px", font: "0.9rem", sub: "0.7rem", px: 3 },
|
|
15
|
+
lg: { h: "48px", avatar: "34px", font: "1rem", sub: "0.78rem", px: 4 },
|
|
17
16
|
};
|
|
18
17
|
const Avatar = ({ org, boxSize, fontSize, }) => {
|
|
19
18
|
const { colors } = useCustomTheme();
|
|
@@ -4,5 +4,5 @@ const RANGE_SLIDER_SIZES = {
|
|
|
4
4
|
md: { trackHeight: "4px", thumbSize: "1.25rem" },
|
|
5
5
|
lg: { trackHeight: "5px", thumbSize: "1.5rem" },
|
|
6
6
|
};
|
|
7
|
-
/** Track thickness and thumb diameter for a size,
|
|
7
|
+
/** Track thickness and thumb diameter for a size — its own values, keyed by the same size names. */
|
|
8
8
|
export const rangeSliderSize = (size) => RANGE_SLIDER_SIZES[size];
|
|
@@ -3,7 +3,7 @@ import { useState } from "react";
|
|
|
3
3
|
import { Box, Flex } from "@chakra-ui/react";
|
|
4
4
|
import { useCustomTheme } from "../../Theme/useCustomTheme.js";
|
|
5
5
|
import { resolveFilledSurface } from "../../Theme/tokens/builders/filledSurface.js";
|
|
6
|
-
import {
|
|
6
|
+
import { BUTTON_SIZES } from "../../Theme/tokens/primitives/controlSizes.js";
|
|
7
7
|
import { transitionFor } from "../../Theme/tokens/primitives/motion.js";
|
|
8
8
|
import { FOCUS_VISIBLE_OVER_STATE } from "../../Theme/chakra/focusRing.styles.js";
|
|
9
9
|
import { reducedMotionSx } from "../../Theme/chakra/motion.js";
|
|
@@ -21,7 +21,7 @@ const formatCount = (count) => (count > MAX_COUNT ? `${MAX_COUNT}+` : `${count}`
|
|
|
21
21
|
/** Renders role="radiogroup" of role="radio" buttons with roving tabindex, not a native form radio group; shares variant with Toggle/TableToggle (see MODULE.md). */
|
|
22
22
|
export default function SegmentedControl({ options, value, onChange, size = "sm", isFullWidth = false, variant = "default", surface, "aria-label": ariaLabel, }) {
|
|
23
23
|
const { colors, radii } = useCustomTheme();
|
|
24
|
-
const control =
|
|
24
|
+
const control = BUTTON_SIZES[size];
|
|
25
25
|
const isBrandSlide = variant === "brandSlide";
|
|
26
26
|
const isUnderlineSlide = variant === "underlineSlide";
|
|
27
27
|
const hasIndicator = isBrandSlide || isUnderlineSlide;
|
|
@@ -7,7 +7,7 @@ import { AA_NON_TEXT, liftToContrast } from "../../../Theme/tokens/builders/outl
|
|
|
7
7
|
import { compositeOver } from "../../../Theme/tokens/builders/color.js";
|
|
8
8
|
import { transitionFor } from "../../../Theme/tokens/primitives/motion.js";
|
|
9
9
|
import { reducedMotionSx } from "../../../Theme/chakra/motion.js";
|
|
10
|
-
import {
|
|
10
|
+
import { BUTTON_SIZES } from "../../../Theme/tokens/primitives/controlSizes.js";
|
|
11
11
|
import { iconBoxSx } from "../../Common/iconBox.js";
|
|
12
12
|
import { resolveTabStyle, scaleForColorScheme } from "../tabStyles.js";
|
|
13
13
|
import { panelId, tabId, useTabsContext } from "../TabsContext.js";
|
|
@@ -24,7 +24,7 @@ const Tab = ({ value, children, icon, count, isDisabled }) => {
|
|
|
24
24
|
const canvas = colors.backgroundColor.main;
|
|
25
25
|
const scale = scaleForColorScheme(colors, ctx.colorScheme);
|
|
26
26
|
const style = resolveTabStyle(colors, scale, canvas, ctx.variant, isSelected);
|
|
27
|
-
const spec =
|
|
27
|
+
const spec = BUTTON_SIZES[ctx.size];
|
|
28
28
|
// The list scrolls on both axes, so an outer ring is clipped into arcs; a negative offset draws it
|
|
29
29
|
// inside the tab, clear of its own border rather than thickening it.
|
|
30
30
|
const focusRing = {
|
|
@@ -6,9 +6,9 @@ import { AA_NON_TEXT, liftToContrast } from "../../Theme/tokens/builders/outline
|
|
|
6
6
|
import { resolveFilledSurface } from "../../Theme/tokens/builders/filledSurface.js";
|
|
7
7
|
import ToolTip from "../ToolTip/ToolTip.js";
|
|
8
8
|
import { useSlidingPill } from "../SegmentedControl/useSlidingPill.js";
|
|
9
|
-
import {
|
|
9
|
+
import { BUTTON_SIZES } from "../../Theme/tokens/primitives/controlSizes.js";
|
|
10
10
|
const MODES = ["grid", "list"];
|
|
11
|
-
const TRACK_HEIGHT =
|
|
11
|
+
const TRACK_HEIGHT = BUTTON_SIZES.sm.height;
|
|
12
12
|
const SEGMENT_HEIGHT = `calc(${TRACK_HEIGHT} - 0.25rem)`;
|
|
13
13
|
/** Two icon-only IconButtons (Grid/List), aria-pressed marks the active one; shares variant with SegmentedControl (see MODULE.md). */
|
|
14
14
|
const TableToggle = ({ value, onChange, variant = "default" }) => {
|
|
@@ -1,8 +1,14 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/** Height scale for form fields and selects — text inputs, pickers, anything typed or picked into. */
|
|
2
2
|
export const CONTROL_SIZES = {
|
|
3
|
-
xs: { height: "
|
|
3
|
+
xs: { height: "2rem", fontSize: "0.75rem", paddingX: "0.5rem", iconSize: 12 },
|
|
4
4
|
sm: { height: "2.375rem", fontSize: "0.8125rem", paddingX: "0.75rem", iconSize: 14 },
|
|
5
|
-
md: { height: "2.
|
|
5
|
+
md: { height: "2.5rem", fontSize: "0.875rem", paddingX: "1rem", iconSize: 16 },
|
|
6
|
+
lg: { height: "3rem", fontSize: "1rem", paddingX: "1.5rem", iconSize: 18 },
|
|
7
|
+
};
|
|
8
|
+
export const BUTTON_SIZES = {
|
|
9
|
+
xs: { height: "1.5rem", fontSize: "0.75rem", paddingX: "0.5rem", iconSize: 12 },
|
|
10
|
+
sm: { height: "2rem", fontSize: "0.8125rem", paddingX: "0.75rem", iconSize: 14 },
|
|
11
|
+
md: { height: "2.5rem", fontSize: "0.875rem", paddingX: "1rem", iconSize: 16 },
|
|
6
12
|
lg: { height: "3rem", fontSize: "1rem", paddingX: "1.5rem", iconSize: 18 },
|
|
7
13
|
};
|
|
8
14
|
export const CONTROL_SIZE_NAMES = ["xs", "sm", "md", "lg"];
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
/** One density for every option row — Select, SearchSelect, SelectSearch, table filters and Chakra's MenuItem. */
|
|
2
2
|
export const OPTION_ROW_SIZES = {
|
|
3
3
|
xs: {
|
|
4
|
-
minH: "1.
|
|
4
|
+
minH: "1.5rem", px: "0.5rem", py: "0.125rem", gap: "0.375rem", mx: "0.25rem",
|
|
5
5
|
fontSize: "0.75rem", descriptionFontSize: "0.6875rem", iconSize: 12,
|
|
6
|
-
avatarSize: "2xs", virtualRowHeightPx:
|
|
6
|
+
avatarSize: "2xs", virtualRowHeightPx: 24,
|
|
7
7
|
},
|
|
8
8
|
sm: {
|
|
9
|
-
minH: "
|
|
9
|
+
minH: "1.875rem", px: "0.625rem", py: "0.25rem", gap: "0.5rem", mx: "0.375rem",
|
|
10
10
|
fontSize: "0.8125rem", descriptionFontSize: "0.75rem", iconSize: 14,
|
|
11
|
-
avatarSize: "xs", virtualRowHeightPx:
|
|
11
|
+
avatarSize: "xs", virtualRowHeightPx: 30,
|
|
12
12
|
},
|
|
13
13
|
md: {
|
|
14
|
-
minH: "2.
|
|
14
|
+
minH: "2.125rem", px: "0.75rem", py: "0.3125rem", gap: "0.5rem", mx: "0.375rem",
|
|
15
15
|
fontSize: "0.875rem", descriptionFontSize: "0.75rem", iconSize: 16,
|
|
16
|
-
avatarSize: "xs", virtualRowHeightPx:
|
|
16
|
+
avatarSize: "xs", virtualRowHeightPx: 34,
|
|
17
17
|
},
|
|
18
18
|
lg: {
|
|
19
19
|
minH: "2.5rem", px: "0.875rem", py: "0.375rem", gap: "0.625rem", mx: "0.5rem",
|
package/package.json
CHANGED