@q1travel/design-system 0.6.0 → 0.7.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/contracts/button-api-compatibility.md +11 -1
- package/dist-pkg/design-system.d.ts +48 -12
- package/dist-pkg/design-system.js +1830 -1585
- package/dist-pkg/style.css +242 -1
- package/package.json +1 -1
|
@@ -20,7 +20,13 @@ New recommended code examples and product migrations use only the canonical API.
|
|
|
20
20
|
|
|
21
21
|
When a canonical prop and its deprecated alias are both defined, the canonical prop wins. Resolution uses nullish precedence, so `svgOnly={false}` still overrides `iconOnly={true}`, and a defined `aria-label` still overrides `ariaLabel`.
|
|
22
22
|
|
|
23
|
-
IconButton requires either `aria-label` or the deprecated `ariaLabel` at the TypeScript boundary. Its
|
|
23
|
+
IconButton requires either `aria-label` or the deprecated `ariaLabel` at the TypeScript boundary. Its built-package runtime warning evaluates the resolved accessible name so JavaScript consumers retain the same guard after package build.
|
|
24
|
+
|
|
25
|
+
## Native Button Props
|
|
26
|
+
|
|
27
|
+
Button and IconButton accept native button props, ARIA attributes, `data-*` attributes, and DOM event handlers. `data-*` values accept React-renderable scalar metadata (`string`, `number`, `boolean`, `null`, or `undefined`); `null` and `undefined` omit the attribute. They forward those props to the real `<button>` instead of a wrapper so menu semantics, roving focus, hover, and pointer-down behavior remain attached to the interactive element.
|
|
28
|
+
|
|
29
|
+
Package-owned semantics are applied after native props. `type`, `className`, `disabled`, loading `aria-disabled`/`tabIndex`, the resolved accessible name, `ref`, and the loading click guard therefore keep their documented behavior. Outside loading, a consumer-provided `tabIndex` or `aria-disabled` remains intact. The canonical native `aria-keyshortcuts` value wins over the compatibility `ariaKeyshortcuts` field by nullish precedence.
|
|
24
30
|
|
|
25
31
|
## Component-Owned Semantics
|
|
26
32
|
|
|
@@ -43,6 +49,9 @@ The scan covers the current local checkouts named below; it is not evidence abou
|
|
|
43
49
|
|
|
44
50
|
- `npm run check` verifies the documentation build, source contracts, and real-browser behavior.
|
|
45
51
|
- `npm run build:pkg` builds the package and verifies emitted declarations, consumer type compatibility, and package runtime behavior.
|
|
52
|
+
- The package API gate renders the built package, not source modules, so it proves native-prop passthrough and the JavaScript accessible-name warning survive publication build transforms.
|
|
53
|
+
- The clean-tarball consumer gate installs the generated tarball in an isolated consumer, imports Button and IconButton from that installed package, and executes loading/native-prop and JavaScript accessible-name contracts against the installed runtime.
|
|
54
|
+
- The browser menu-ARIA passthrough proof uses a hidden, non-navigation fixture rendered by the real components. Public specimens must not claim popup semantics without implementing the corresponding interaction.
|
|
46
55
|
- Both gates are required for this migration. Neither gate publishes a package.
|
|
47
56
|
|
|
48
57
|
## Removal Conditions
|
|
@@ -61,3 +70,4 @@ Until then, the aliases remain tested public compatibility contracts.
|
|
|
61
70
|
- This contract does not migrate `q1travel-web`.
|
|
62
71
|
- This contract does not choose a package version, publish a package, or remove an alias.
|
|
63
72
|
- This contract does not change Button size, loading, variant, route, or styling contracts beyond the decorative slot boundary described above.
|
|
73
|
+
- This contract does not move button semantics or event handlers to a wrapper.
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { AnchorHTMLAttributes } from 'react';
|
|
2
2
|
import { ButtonHTMLAttributes } from 'react';
|
|
3
|
+
import { ComponentPropsWithoutRef } from 'react';
|
|
3
4
|
import { FocusEventHandler } from 'react';
|
|
4
5
|
import { HTMLAttributes } from 'react';
|
|
5
6
|
import { InputHTMLAttributes } from 'react';
|
|
@@ -240,11 +241,8 @@ export declare type ButtonLinkProps = Omit<ButtonBaseProps, 'type'> & {
|
|
|
240
241
|
ref?: Ref<HTMLAnchorElement>;
|
|
241
242
|
};
|
|
242
243
|
|
|
243
|
-
declare type ButtonProps = ButtonBaseProps & {
|
|
244
|
-
|
|
245
|
-
onFocus?: FocusEventHandler<HTMLButtonElement>;
|
|
246
|
-
onBlur?: FocusEventHandler<HTMLButtonElement>;
|
|
247
|
-
onKeyDown?: KeyboardEventHandler<HTMLButtonElement>;
|
|
244
|
+
declare type ButtonProps = ButtonBaseProps & Omit<ComponentPropsWithoutRef<'button'>, keyof ButtonBaseProps> & {
|
|
245
|
+
[dataAttribute: `data-${string}`]: string | number | boolean | null | undefined;
|
|
248
246
|
/** 供 focus 管理、测量、浮层定位等场景使用。 */
|
|
249
247
|
ref?: Ref<HTMLButtonElement>;
|
|
250
248
|
};
|
|
@@ -756,7 +754,7 @@ declare type IconButtonAccessibleName = {
|
|
|
756
754
|
ariaLabel: string;
|
|
757
755
|
};
|
|
758
756
|
|
|
759
|
-
|
|
757
|
+
declare type IconButtonBaseProps = {
|
|
760
758
|
variant?: ButtonVariant;
|
|
761
759
|
size?: ButtonSize;
|
|
762
760
|
circle?: boolean;
|
|
@@ -766,11 +764,10 @@ export declare type IconButtonProps = IconButtonAccessibleName & {
|
|
|
766
764
|
type?: 'button' | 'submit' | 'reset';
|
|
767
765
|
className?: string;
|
|
768
766
|
children?: ReactNode;
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
onKeyDown?: KeyboardEventHandler<HTMLButtonElement>;
|
|
767
|
+
};
|
|
768
|
+
|
|
769
|
+
export declare type IconButtonProps = IconButtonAccessibleName & IconButtonBaseProps & Omit<ComponentPropsWithoutRef<'button'>, keyof IconButtonBaseProps | 'aria-label'> & {
|
|
770
|
+
[dataAttribute: `data-${string}`]: string | number | boolean | null | undefined;
|
|
774
771
|
ref?: Ref<HTMLButtonElement>;
|
|
775
772
|
};
|
|
776
773
|
|
|
@@ -889,7 +886,7 @@ declare type NativeInputProps = Omit<InputHTMLAttributes<HTMLInputElement>, 'id'
|
|
|
889
886
|
|
|
890
887
|
declare type NativeInputProps_2 = Omit<InputHTMLAttributes<HTMLInputElement>, 'type'>;
|
|
891
888
|
|
|
892
|
-
export declare function Navigation({ className, ...props }: NavigationProps): JSX.Element;
|
|
889
|
+
export declare function Navigation({ className, orientation, ...props }: NavigationProps): JSX.Element;
|
|
893
890
|
|
|
894
891
|
export declare function NavigationGroup({ label, icon, expanded, defaultExpanded, onExpandedChange, children, }: NavigationGroupProps): JSX.Element;
|
|
895
892
|
|
|
@@ -927,6 +924,7 @@ export declare type NavigationItemProps = NavigationItemAsLink | NavigationItemA
|
|
|
927
924
|
|
|
928
925
|
export declare type NavigationProps = HTMLAttributes<HTMLElement> & {
|
|
929
926
|
'aria-label': string;
|
|
927
|
+
orientation?: 'vertical' | 'horizontal';
|
|
930
928
|
};
|
|
931
929
|
|
|
932
930
|
export declare function NavigationSection({ label, action, children, className, ...props }: NavigationSectionProps): JSX.Element;
|
|
@@ -1081,6 +1079,44 @@ export declare function ScrollerWithButtons({ axis, contentName, label, children
|
|
|
1081
1079
|
children: ReactNode;
|
|
1082
1080
|
}): JSX.Element;
|
|
1083
1081
|
|
|
1082
|
+
export declare function SearchDialog({ open, onOpenChange, query, onQueryChange, sections, onSelect, renderTrigger, label, placeholder, emptyTitle, clearQueryLabel, }: SearchDialogProps): JSX.Element;
|
|
1083
|
+
|
|
1084
|
+
export declare type SearchDialogItem = {
|
|
1085
|
+
id: string;
|
|
1086
|
+
label: string;
|
|
1087
|
+
description?: string;
|
|
1088
|
+
disabled?: boolean;
|
|
1089
|
+
};
|
|
1090
|
+
|
|
1091
|
+
export declare type SearchDialogProps = {
|
|
1092
|
+
open: boolean;
|
|
1093
|
+
onOpenChange: (open: boolean) => void;
|
|
1094
|
+
query: string;
|
|
1095
|
+
onQueryChange: (query: string) => void;
|
|
1096
|
+
sections: SearchDialogSection[];
|
|
1097
|
+
onSelect: (item: SearchDialogItem) => void;
|
|
1098
|
+
renderTrigger: (props: SearchDialogTriggerProps) => ReactNode;
|
|
1099
|
+
label: string;
|
|
1100
|
+
placeholder?: string;
|
|
1101
|
+
emptyTitle?: string;
|
|
1102
|
+
clearQueryLabel?: string;
|
|
1103
|
+
};
|
|
1104
|
+
|
|
1105
|
+
export declare type SearchDialogSection = {
|
|
1106
|
+
id: string;
|
|
1107
|
+
heading?: string;
|
|
1108
|
+
items: SearchDialogItem[];
|
|
1109
|
+
};
|
|
1110
|
+
|
|
1111
|
+
export declare type SearchDialogTriggerProps = {
|
|
1112
|
+
ref: (node: HTMLButtonElement | null) => void;
|
|
1113
|
+
type: 'button';
|
|
1114
|
+
onClick: () => void;
|
|
1115
|
+
'aria-haspopup': 'dialog';
|
|
1116
|
+
'aria-expanded': boolean;
|
|
1117
|
+
'aria-controls': string;
|
|
1118
|
+
};
|
|
1119
|
+
|
|
1084
1120
|
export declare function SearchInput({ id, ariaLabel, placeholder, defaultValue, disabled, loading, kbdHint, icon, }: {
|
|
1085
1121
|
id: string;
|
|
1086
1122
|
ariaLabel: string;
|