@fpkit/acss 6.2.0 → 6.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/libs/chunk-25KCUE3R.cjs +17 -0
- package/libs/chunk-25KCUE3R.cjs.map +1 -0
- package/libs/chunk-34NWHFHP.js +10 -0
- package/libs/chunk-34NWHFHP.js.map +1 -0
- package/libs/{chunk-SQ44OCJ2.js → chunk-6NMLU5FA.js} +2 -2
- package/libs/{chunk-GVVCXXKI.cjs → chunk-6YVR4TDM.cjs} +3 -3
- package/libs/chunk-DSQ2TUCR.js +7 -0
- package/libs/chunk-DSQ2TUCR.js.map +1 -0
- package/libs/{chunk-H6A2CUWA.js → chunk-VQTCTLFN.js} +2 -2
- package/libs/chunk-ZJ4RUKI2.cjs +14 -0
- package/libs/chunk-ZJ4RUKI2.cjs.map +1 -0
- package/libs/{chunk-H4JRUNKU.cjs → chunk-ZOPHCNFD.cjs} +3 -3
- package/libs/components/alert/alert.css +1 -1
- package/libs/components/alert/alert.css.map +1 -1
- package/libs/components/alert/alert.min.css +2 -2
- package/libs/components/button.cjs +3 -3
- package/libs/components/button.d.cts +34 -1
- package/libs/components/button.d.ts +34 -1
- package/libs/components/button.js +1 -1
- package/libs/components/buttons/button.css +1 -1
- package/libs/components/buttons/button.css.map +1 -1
- package/libs/components/buttons/button.min.css +2 -2
- package/libs/components/buttons/icon-button.css +1 -0
- package/libs/components/buttons/icon-button.css.map +1 -0
- package/libs/components/buttons/icon-button.min.css +3 -0
- package/libs/components/dialog/dialog.cjs +4 -4
- package/libs/components/dialog/dialog.css +1 -1
- package/libs/components/dialog/dialog.css.map +1 -1
- package/libs/components/dialog/dialog.js +2 -2
- package/libs/components/dialog/dialog.min.css +2 -2
- package/libs/components/link/link.css +1 -1
- package/libs/components/link/link.min.css +1 -1
- package/libs/components/modal.cjs +3 -3
- package/libs/components/modal.js +2 -2
- package/libs/components/popover/popover.cjs +3 -8
- package/libs/components/popover/popover.css +1 -0
- package/libs/components/popover/popover.css.map +1 -0
- package/libs/components/popover/popover.d.cts +54 -26
- package/libs/components/popover/popover.d.ts +54 -26
- package/libs/components/popover/popover.js +1 -2
- package/libs/components/popover/popover.min.css +3 -0
- package/libs/hooks.cjs +3 -6
- package/libs/hooks.cjs.map +1 -1
- package/libs/hooks.d.cts +30 -10
- package/libs/hooks.d.ts +30 -10
- package/libs/hooks.js +5 -1
- package/libs/hooks.js.map +1 -1
- package/libs/index.cjs +35 -35
- package/libs/index.cjs.map +1 -1
- package/libs/index.css +1 -1
- package/libs/index.css.map +1 -1
- package/libs/index.d.cts +65 -3
- package/libs/index.d.ts +65 -3
- package/libs/index.js +9 -10
- package/libs/index.js.map +1 -1
- package/package.json +2 -2
- package/src/components/alert/alert.scss +0 -13
- package/src/components/buttons/README.mdx +107 -11
- package/src/components/buttons/STYLES.mdx +182 -47
- package/src/components/buttons/button.scss +93 -16
- package/src/components/buttons/button.stories.tsx +149 -0
- package/src/components/buttons/button.test.tsx +12 -0
- package/src/components/buttons/button.tsx +50 -6
- package/src/components/buttons/icon-button.mdx +204 -0
- package/src/components/buttons/icon-button.scss +83 -0
- package/src/components/buttons/icon-button.stories.tsx +200 -0
- package/src/components/buttons/icon-button.test.tsx +132 -0
- package/src/components/buttons/icon-button.tsx +75 -0
- package/src/components/dialog/dialog-modal.stories.tsx +71 -0
- package/src/components/dialog/dialog-modal.tsx +29 -3
- package/src/components/dialog/dialog.scss +1 -0
- package/src/components/dialog/dialog.test.tsx +119 -0
- package/src/components/dialog/dialog.types.ts +8 -1
- package/src/components/form/select.tsx +55 -51
- package/src/components/link/link.scss +2 -2
- package/src/components/popover/README.mdx +478 -0
- package/src/components/popover/STYLES.mdx +389 -0
- package/src/components/popover/index.ts +3 -0
- package/src/components/popover/popover.scss +249 -0
- package/src/components/popover/popover.stories.tsx +315 -15
- package/src/components/popover/popover.test.tsx +249 -37
- package/src/components/popover/popover.tsx +165 -62
- package/src/hooks/popover/popover.tsx +26 -10
- package/src/hooks/popover/use-popover.tsx +30 -10
- package/src/hooks.ts +5 -0
- package/src/index.scss +1 -0
- package/src/index.ts +1 -0
- package/src/sass/utilities/_display.scss +156 -0
- package/src/sass/utilities/_index.scss +3 -0
- package/src/sass/utilities/display.mdx +203 -0
- package/src/sass/utilities/display.stories.tsx +141 -0
- package/src/styles/alert/alert.css +0 -13
- package/src/styles/alert/alert.css.map +1 -1
- package/src/styles/buttons/button.css +78 -16
- package/src/styles/buttons/button.css.map +1 -1
- package/src/styles/buttons/icon-button.css +71 -0
- package/src/styles/buttons/icon-button.css.map +1 -0
- package/src/styles/dialog/dialog.css +1 -0
- package/src/styles/dialog/dialog.css.map +1 -1
- package/src/styles/index.css +404 -31
- package/src/styles/index.css.map +1 -1
- package/src/styles/link/link.css +2 -2
- package/src/styles/popover/popover.css +190 -0
- package/src/styles/popover/popover.css.map +1 -0
- package/src/types/popover.d.ts +64 -0
- package/libs/chunk-4I5MF54P.js +0 -8
- package/libs/chunk-4I5MF54P.js.map +0 -1
- package/libs/chunk-GCGKYLDG.js +0 -7
- package/libs/chunk-GCGKYLDG.js.map +0 -1
- package/libs/chunk-NZVSXRTB.cjs +0 -16
- package/libs/chunk-NZVSXRTB.cjs.map +0 -1
- package/libs/chunk-PDD4N5P5.cjs +0 -10
- package/libs/chunk-PDD4N5P5.cjs.map +0 -1
- package/libs/chunk-S7NIA6PI.cjs +0 -17
- package/libs/chunk-S7NIA6PI.cjs.map +0 -1
- package/libs/chunk-X2RDXWH5.js +0 -10
- package/libs/chunk-X2RDXWH5.js.map +0 -1
- /package/libs/{chunk-SQ44OCJ2.js.map → chunk-6NMLU5FA.js.map} +0 -0
- /package/libs/{chunk-GVVCXXKI.cjs.map → chunk-6YVR4TDM.cjs.map} +0 -0
- /package/libs/{chunk-H6A2CUWA.js.map → chunk-VQTCTLFN.js.map} +0 -0
- /package/libs/{chunk-H4JRUNKU.cjs.map → chunk-ZOPHCNFD.cjs.map} +0 -0
|
@@ -446,5 +446,124 @@ describe("DialogModal", () => {
|
|
|
446
446
|
expect(triggerButton).toBeInTheDocument();
|
|
447
447
|
expect(triggerButton).not.toBeDisabled();
|
|
448
448
|
});
|
|
449
|
+
|
|
450
|
+
it("adds aria-haspopup='dialog' to the regular button trigger", () => {
|
|
451
|
+
render(
|
|
452
|
+
<DialogModal dialogTitle="Test" btnLabel="Open">
|
|
453
|
+
Content
|
|
454
|
+
</DialogModal>
|
|
455
|
+
);
|
|
456
|
+
|
|
457
|
+
const triggerButton = screen.getByRole("button", { name: /open/i });
|
|
458
|
+
expect(triggerButton).toHaveAttribute("aria-haspopup", "dialog");
|
|
459
|
+
});
|
|
460
|
+
});
|
|
461
|
+
|
|
462
|
+
describe("Icon Button Trigger", () => {
|
|
463
|
+
const TestIcon = () => (
|
|
464
|
+
<svg data-testid="test-icon" aria-hidden="true">
|
|
465
|
+
<circle cx="12" cy="12" r="10" />
|
|
466
|
+
</svg>
|
|
467
|
+
);
|
|
468
|
+
|
|
469
|
+
it("renders IconButton when icon prop is provided", () => {
|
|
470
|
+
render(
|
|
471
|
+
<DialogModal dialogTitle="Test" btnLabel="Settings" icon={<TestIcon />}>
|
|
472
|
+
Content
|
|
473
|
+
</DialogModal>
|
|
474
|
+
);
|
|
475
|
+
|
|
476
|
+
const iconButton = screen.getByRole("button", { name: /settings/i });
|
|
477
|
+
expect(iconButton).toHaveAttribute("data-icon-btn");
|
|
478
|
+
});
|
|
479
|
+
|
|
480
|
+
it("renders regular Button when icon prop is not provided", () => {
|
|
481
|
+
render(
|
|
482
|
+
<DialogModal dialogTitle="Test" btnLabel="Open">
|
|
483
|
+
Content
|
|
484
|
+
</DialogModal>
|
|
485
|
+
);
|
|
486
|
+
|
|
487
|
+
const button = screen.getByRole("button", { name: /open/i });
|
|
488
|
+
expect(button).not.toHaveAttribute("data-icon-btn");
|
|
489
|
+
});
|
|
490
|
+
|
|
491
|
+
it("uses btnLabel as aria-label on the icon button", () => {
|
|
492
|
+
render(
|
|
493
|
+
<DialogModal dialogTitle="Test" btnLabel="Settings" icon={<TestIcon />}>
|
|
494
|
+
Content
|
|
495
|
+
</DialogModal>
|
|
496
|
+
);
|
|
497
|
+
|
|
498
|
+
const iconButton = screen.getByRole("button", { name: /settings/i });
|
|
499
|
+
expect(iconButton).toHaveAttribute("aria-label", "Settings");
|
|
500
|
+
});
|
|
501
|
+
|
|
502
|
+
it("passes btnLabel as visible label on the icon button", () => {
|
|
503
|
+
render(
|
|
504
|
+
<DialogModal dialogTitle="Test" btnLabel="Settings" icon={<TestIcon />}>
|
|
505
|
+
Content
|
|
506
|
+
</DialogModal>
|
|
507
|
+
);
|
|
508
|
+
|
|
509
|
+
// IconButton renders the label in a span with data-icon-label
|
|
510
|
+
const iconButton = screen.getByRole("button", { name: /settings/i });
|
|
511
|
+
expect(iconButton.querySelector("[data-icon-label]")).toHaveTextContent("Settings");
|
|
512
|
+
});
|
|
513
|
+
|
|
514
|
+
it("adds aria-haspopup='dialog' to the icon button trigger", () => {
|
|
515
|
+
render(
|
|
516
|
+
<DialogModal dialogTitle="Test" btnLabel="Settings" icon={<TestIcon />}>
|
|
517
|
+
Content
|
|
518
|
+
</DialogModal>
|
|
519
|
+
);
|
|
520
|
+
|
|
521
|
+
const iconButton = screen.getByRole("button", { name: /settings/i });
|
|
522
|
+
expect(iconButton).toHaveAttribute("aria-haspopup", "dialog");
|
|
523
|
+
});
|
|
524
|
+
|
|
525
|
+
it("opens dialog when icon button is clicked", async () => {
|
|
526
|
+
const user = userEvent.setup();
|
|
527
|
+
|
|
528
|
+
render(
|
|
529
|
+
<DialogModal dialogTitle="Test Dialog" btnLabel="Settings" icon={<TestIcon />}>
|
|
530
|
+
Dialog content
|
|
531
|
+
</DialogModal>
|
|
532
|
+
);
|
|
533
|
+
|
|
534
|
+
const iconButton = screen.getByRole("button", { name: /settings/i });
|
|
535
|
+
await user.click(iconButton);
|
|
536
|
+
|
|
537
|
+
await waitFor(() => {
|
|
538
|
+
expect(screen.getByRole("dialog")).toBeInTheDocument();
|
|
539
|
+
expect(screen.getByText("Dialog content")).toBeInTheDocument();
|
|
540
|
+
});
|
|
541
|
+
});
|
|
542
|
+
|
|
543
|
+
it("applies btnSize to the icon button", () => {
|
|
544
|
+
render(
|
|
545
|
+
<DialogModal dialogTitle="Test" btnLabel="Settings" icon={<TestIcon />} btnSize="lg">
|
|
546
|
+
Content
|
|
547
|
+
</DialogModal>
|
|
548
|
+
);
|
|
549
|
+
|
|
550
|
+
const iconButton = screen.getByRole("button", { name: /settings/i });
|
|
551
|
+
expect(iconButton).toHaveAttribute("data-btn", "lg");
|
|
552
|
+
});
|
|
553
|
+
|
|
554
|
+
it("forwards btnProps to the icon button", () => {
|
|
555
|
+
render(
|
|
556
|
+
<DialogModal
|
|
557
|
+
dialogTitle="Test"
|
|
558
|
+
btnLabel="Settings"
|
|
559
|
+
icon={<TestIcon />}
|
|
560
|
+
btnProps={{ "data-testid": "icon-trigger" }}
|
|
561
|
+
>
|
|
562
|
+
Content
|
|
563
|
+
</DialogModal>
|
|
564
|
+
);
|
|
565
|
+
|
|
566
|
+
expect(screen.getByTestId("icon-trigger")).toBeInTheDocument();
|
|
567
|
+
});
|
|
449
568
|
});
|
|
450
569
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CSSProperties, ReactNode } from "react";
|
|
1
|
+
import { CSSProperties, ReactElement, ReactNode } from "react";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Base properties shared by all dialog variants.
|
|
@@ -70,6 +70,7 @@ export interface DialogProps extends BaseDialogProps {
|
|
|
70
70
|
* @property {string} [btnLabel="Open Dialog"] - Text label for the trigger button
|
|
71
71
|
* @property {"sm" | "md" | "lg"} [btnSize="sm"] - Size variant for the trigger button
|
|
72
72
|
* @property {() => void} [btnOnClick] - Callback fired when trigger button is clicked (before opening)
|
|
73
|
+
* @property {ReactElement} [icon] - Optional icon element. When provided, renders IconButton instead of Button as trigger.
|
|
73
74
|
*/
|
|
74
75
|
export interface DialogModalProps extends BaseDialogProps {
|
|
75
76
|
/** If true, renders as non-modal inline alert using dialog.show() */
|
|
@@ -92,6 +93,12 @@ export interface DialogModalProps extends BaseDialogProps {
|
|
|
92
93
|
btnOnClick?: () => void;
|
|
93
94
|
/** Additional props to pass to the trigger button component */
|
|
94
95
|
btnProps?: Record<string, unknown>;
|
|
96
|
+
/**
|
|
97
|
+
* Optional icon element. When provided, renders an IconButton instead of a regular Button as the trigger.
|
|
98
|
+
* `btnLabel` serves as both `aria-label` and the visible label text (shown at desktop widths via IconButton's responsive label).
|
|
99
|
+
* Note: `aria-labelledby` cannot be passed via `btnProps` when icon is set — use `btnLabel` instead.
|
|
100
|
+
*/
|
|
101
|
+
icon?: ReactElement;
|
|
95
102
|
}
|
|
96
103
|
|
|
97
104
|
/**
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import UI from
|
|
2
|
-
import React from
|
|
3
|
-
import { useDisabledState } from
|
|
1
|
+
import UI from "../ui";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import { useDisabledState } from "../../hooks/use-disabled-state";
|
|
4
4
|
|
|
5
|
-
export type { SelectProps } from
|
|
6
|
-
import type { SelectProps } from
|
|
5
|
+
export type { SelectProps } from "./form.types";
|
|
6
|
+
import type { SelectProps } from "./form.types";
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Option component props interface
|
|
@@ -11,56 +11,57 @@ import type { SelectProps } from './form.types'
|
|
|
11
11
|
*
|
|
12
12
|
* @interface OptionProps
|
|
13
13
|
*/
|
|
14
|
-
export interface OptionProps
|
|
14
|
+
export interface OptionProps
|
|
15
|
+
extends Omit<React.ComponentPropsWithoutRef<"option">, "className"> {
|
|
15
16
|
/**
|
|
16
17
|
* Value for the select option (required, unless using legacy selectValue)
|
|
17
18
|
*/
|
|
18
|
-
value?: string | number
|
|
19
|
+
value?: string | number;
|
|
19
20
|
|
|
20
21
|
/**
|
|
21
22
|
* Display label for the option (defaults to value if not provided)
|
|
22
23
|
*/
|
|
23
|
-
label?: string
|
|
24
|
+
label?: string;
|
|
24
25
|
|
|
25
26
|
/**
|
|
26
27
|
* CSS class names (preferred over 'className' for consistency with fpkit components)
|
|
27
28
|
*/
|
|
28
|
-
classes?: string
|
|
29
|
+
classes?: string;
|
|
29
30
|
|
|
30
31
|
/**
|
|
31
32
|
* Inline CSS styles object
|
|
32
33
|
*/
|
|
33
|
-
styles?: React.CSSProperties
|
|
34
|
+
styles?: React.CSSProperties;
|
|
34
35
|
|
|
35
36
|
/**
|
|
36
37
|
* Disabled state for the option
|
|
37
38
|
* @default false
|
|
38
39
|
*/
|
|
39
|
-
disabled?: boolean
|
|
40
|
+
disabled?: boolean;
|
|
40
41
|
|
|
41
42
|
/**
|
|
42
43
|
* Children content (overrides label if provided)
|
|
43
44
|
*/
|
|
44
|
-
children?: React.ReactNode
|
|
45
|
+
children?: React.ReactNode;
|
|
45
46
|
|
|
46
47
|
/**
|
|
47
48
|
* Visual variant for styling via data-option attribute
|
|
48
49
|
* Use with CSS: option[data-option="primary"] { ... }
|
|
49
50
|
* @example 'primary' | 'secondary' | 'success' | 'error'
|
|
50
51
|
*/
|
|
51
|
-
variant?: string
|
|
52
|
+
variant?: string;
|
|
52
53
|
|
|
53
54
|
/**
|
|
54
55
|
* Size variant for styling via data-size attribute
|
|
55
56
|
* @example 'sm' | 'md' | 'lg'
|
|
56
57
|
*/
|
|
57
|
-
size?: string
|
|
58
|
+
size?: string;
|
|
58
59
|
|
|
59
60
|
/**
|
|
60
61
|
* Additional data attributes for custom styling
|
|
61
62
|
* @example { 'data-highlighted': true, 'data-category': 'premium' }
|
|
62
63
|
*/
|
|
63
|
-
dataAttributes?: Record<string, string | boolean | number
|
|
64
|
+
dataAttributes?: Record<string, string | boolean | number>;
|
|
64
65
|
}
|
|
65
66
|
|
|
66
67
|
/**
|
|
@@ -88,7 +89,10 @@ export interface OptionProps extends Omit<React.ComponentPropsWithoutRef<'option
|
|
|
88
89
|
* @param {OptionProps} props - Component props
|
|
89
90
|
* @returns {JSX.Element} Option element
|
|
90
91
|
*/
|
|
91
|
-
export const Option = React.forwardRef<
|
|
92
|
+
export const Option = React.forwardRef<
|
|
93
|
+
HTMLOptionElement,
|
|
94
|
+
OptionProps & Partial<SelectOptionsProps>
|
|
95
|
+
>(
|
|
92
96
|
(
|
|
93
97
|
{
|
|
94
98
|
value,
|
|
@@ -105,18 +109,18 @@ export const Option = React.forwardRef<HTMLOptionElement, OptionProps & Partial<
|
|
|
105
109
|
selectLabel,
|
|
106
110
|
...props
|
|
107
111
|
},
|
|
108
|
-
ref
|
|
112
|
+
ref,
|
|
109
113
|
) => {
|
|
110
114
|
// Map legacy props to new props
|
|
111
|
-
const optionValue = value ?? selectValue
|
|
112
|
-
const optionLabel = label ?? selectLabel
|
|
115
|
+
const optionValue = value ?? selectValue;
|
|
116
|
+
const optionLabel = label ?? selectLabel;
|
|
113
117
|
|
|
114
118
|
// Build data attributes object for styling
|
|
115
119
|
const combinedDataAttrs = {
|
|
116
|
-
...(variant && {
|
|
117
|
-
...(size && {
|
|
120
|
+
...(variant && { "data-option": variant }),
|
|
121
|
+
...(size && { "data-size": size }),
|
|
118
122
|
...dataAttributes,
|
|
119
|
-
}
|
|
123
|
+
};
|
|
120
124
|
|
|
121
125
|
return (
|
|
122
126
|
<UI
|
|
@@ -131,17 +135,17 @@ export const Option = React.forwardRef<HTMLOptionElement, OptionProps & Partial<
|
|
|
131
135
|
>
|
|
132
136
|
{children || optionLabel || optionValue}
|
|
133
137
|
</UI>
|
|
134
|
-
)
|
|
135
|
-
}
|
|
136
|
-
)
|
|
138
|
+
);
|
|
139
|
+
},
|
|
140
|
+
);
|
|
137
141
|
|
|
138
|
-
Option.displayName =
|
|
142
|
+
Option.displayName = "Select.Option";
|
|
139
143
|
|
|
140
144
|
// Legacy type export for backwards compatibility
|
|
141
|
-
export type SelectOptionsProps = Omit<OptionProps,
|
|
142
|
-
selectValue: string | number
|
|
143
|
-
selectLabel?: string
|
|
144
|
-
}
|
|
145
|
+
export type SelectOptionsProps = Omit<OptionProps, "classes" | "styles"> & {
|
|
146
|
+
selectValue: string | number;
|
|
147
|
+
selectLabel?: string;
|
|
148
|
+
};
|
|
145
149
|
|
|
146
150
|
/**
|
|
147
151
|
* Select component - Accessible dropdown selection input with validation support
|
|
@@ -187,7 +191,7 @@ export const Select = React.forwardRef<HTMLSelectElement, SelectProps>(
|
|
|
187
191
|
children,
|
|
188
192
|
required,
|
|
189
193
|
selected,
|
|
190
|
-
validationState =
|
|
194
|
+
validationState = "none",
|
|
191
195
|
errorMessage,
|
|
192
196
|
hintText,
|
|
193
197
|
onBlur,
|
|
@@ -197,7 +201,7 @@ export const Select = React.forwardRef<HTMLSelectElement, SelectProps>(
|
|
|
197
201
|
onEnter,
|
|
198
202
|
...props
|
|
199
203
|
},
|
|
200
|
-
ref
|
|
204
|
+
ref,
|
|
201
205
|
) => {
|
|
202
206
|
// Use the disabled state hook with enhanced API for automatic className merging
|
|
203
207
|
const { disabledProps, handlers } = useDisabledState<HTMLSelectElement>(
|
|
@@ -210,33 +214,33 @@ export const Select = React.forwardRef<HTMLSelectElement, SelectProps>(
|
|
|
210
214
|
onKeyDown: (e: React.KeyboardEvent<HTMLSelectElement>) => {
|
|
211
215
|
// Handle Enter key press for accessibility
|
|
212
216
|
// Enables keyboard-only users to trigger actions after selection
|
|
213
|
-
if (e.key ===
|
|
214
|
-
onEnter(e)
|
|
217
|
+
if (e.key === "Enter" && onEnter) {
|
|
218
|
+
onEnter(e);
|
|
215
219
|
}
|
|
216
220
|
// Always call consumer's onKeyDown if provided
|
|
217
221
|
if (onKeyDown) {
|
|
218
|
-
onKeyDown(e)
|
|
222
|
+
onKeyDown(e);
|
|
219
223
|
}
|
|
220
224
|
},
|
|
221
225
|
},
|
|
222
226
|
// Automatic className merging - hook combines disabled class with user classes
|
|
223
227
|
className: classes,
|
|
224
|
-
}
|
|
225
|
-
)
|
|
228
|
+
},
|
|
229
|
+
);
|
|
226
230
|
|
|
227
231
|
// Determine aria-invalid based on validation state
|
|
228
|
-
const isInvalid = validationState ===
|
|
232
|
+
const isInvalid = validationState === "invalid";
|
|
229
233
|
|
|
230
234
|
// Generate describedby IDs for error and hint text
|
|
231
|
-
const describedByIds: string[] = []
|
|
235
|
+
const describedByIds: string[] = [];
|
|
232
236
|
if (errorMessage && id) {
|
|
233
|
-
describedByIds.push(`${id}-error`)
|
|
237
|
+
describedByIds.push(`${id}-error`);
|
|
234
238
|
}
|
|
235
239
|
if (hintText && id) {
|
|
236
|
-
describedByIds.push(`${id}-hint`)
|
|
240
|
+
describedByIds.push(`${id}-hint`);
|
|
237
241
|
}
|
|
238
242
|
const ariaDescribedBy =
|
|
239
|
-
describedByIds.length > 0 ? describedByIds.join(
|
|
243
|
+
describedByIds.length > 0 ? describedByIds.join(" ") : undefined;
|
|
240
244
|
|
|
241
245
|
return (
|
|
242
246
|
<UI
|
|
@@ -249,7 +253,7 @@ export const Select = React.forwardRef<HTMLSelectElement, SelectProps>(
|
|
|
249
253
|
{...handlers}
|
|
250
254
|
required={required}
|
|
251
255
|
aria-required={required}
|
|
252
|
-
aria-disabled={disabledProps[
|
|
256
|
+
aria-disabled={disabledProps["aria-disabled"]}
|
|
253
257
|
aria-invalid={isInvalid}
|
|
254
258
|
aria-describedby={ariaDescribedBy}
|
|
255
259
|
style={styles}
|
|
@@ -257,19 +261,19 @@ export const Select = React.forwardRef<HTMLSelectElement, SelectProps>(
|
|
|
257
261
|
>
|
|
258
262
|
{children || <option value="" />}
|
|
259
263
|
</UI>
|
|
260
|
-
)
|
|
261
|
-
}
|
|
262
|
-
)
|
|
264
|
+
);
|
|
265
|
+
},
|
|
266
|
+
);
|
|
263
267
|
|
|
264
|
-
Select.displayName =
|
|
268
|
+
Select.displayName = "Select";
|
|
265
269
|
|
|
266
270
|
// Create a compound component with proper typing
|
|
267
271
|
type SelectComponent = typeof Select & {
|
|
268
|
-
Option: typeof Option
|
|
269
|
-
}
|
|
272
|
+
Option: typeof Option;
|
|
273
|
+
};
|
|
270
274
|
|
|
271
275
|
// Type assertion to allow adding static property to ForwardRefExoticComponent
|
|
272
276
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
273
|
-
|
|
277
|
+
(Select as any).Option = Option;
|
|
274
278
|
|
|
275
|
-
export default Select as SelectComponent
|
|
279
|
+
export default Select as SelectComponent;
|
|
@@ -98,7 +98,7 @@ a[href] {
|
|
|
98
98
|
font-size: var(--link-fs);
|
|
99
99
|
padding-inline: var(--link-fs);
|
|
100
100
|
padding-block: calc(var(--link-fs) - 0.4rem);
|
|
101
|
-
border-radius: var(--link-radius,
|
|
101
|
+
border-radius: var(--link-radius, 100vw);
|
|
102
102
|
display: inline-flex;
|
|
103
103
|
align-items: center;
|
|
104
104
|
justify-content: center;
|
|
@@ -126,7 +126,7 @@ a[href] {
|
|
|
126
126
|
// Pill variant (rounded corners)
|
|
127
127
|
&[data-link~="pill"],
|
|
128
128
|
&:has(> i) {
|
|
129
|
-
--link-radius:
|
|
129
|
+
--link-radius: 100vw;
|
|
130
130
|
--link-decoration: none;
|
|
131
131
|
font-style: normal;
|
|
132
132
|
|