@q1travel/design-system 0.5.1 → 0.6.1
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 +145 -11
- package/dist-pkg/design-system.js +1586 -1206
- package/dist-pkg/style.css +432 -0
- package/dist-pkg/tokens.css +2 -0
- 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,4 +1,6 @@
|
|
|
1
1
|
import { AnchorHTMLAttributes } from 'react';
|
|
2
|
+
import { ButtonHTMLAttributes } from 'react';
|
|
3
|
+
import { ComponentPropsWithoutRef } from 'react';
|
|
2
4
|
import { FocusEventHandler } from 'react';
|
|
3
5
|
import { HTMLAttributes } from 'react';
|
|
4
6
|
import { InputHTMLAttributes } from 'react';
|
|
@@ -239,11 +241,8 @@ export declare type ButtonLinkProps = Omit<ButtonBaseProps, 'type'> & {
|
|
|
239
241
|
ref?: Ref<HTMLAnchorElement>;
|
|
240
242
|
};
|
|
241
243
|
|
|
242
|
-
declare type ButtonProps = ButtonBaseProps & {
|
|
243
|
-
|
|
244
|
-
onFocus?: FocusEventHandler<HTMLButtonElement>;
|
|
245
|
-
onBlur?: FocusEventHandler<HTMLButtonElement>;
|
|
246
|
-
onKeyDown?: KeyboardEventHandler<HTMLButtonElement>;
|
|
244
|
+
declare type ButtonProps = ButtonBaseProps & Omit<ComponentPropsWithoutRef<'button'>, keyof ButtonBaseProps> & {
|
|
245
|
+
[dataAttribute: `data-${string}`]: string | number | boolean | null | undefined;
|
|
247
246
|
/** 供 focus 管理、测量、浮层定位等场景使用。 */
|
|
248
247
|
ref?: Ref<HTMLButtonElement>;
|
|
249
248
|
};
|
|
@@ -521,6 +520,54 @@ export declare type ContextMenuEntry = {
|
|
|
521
520
|
type: 'separator';
|
|
522
521
|
};
|
|
523
522
|
|
|
523
|
+
export declare function ContextSwitcher({ currentContext, groups, open, defaultOpen, onOpenChange, onSelect, pendingId, errorMessage, footerActions, onFooterAction, label, }: ContextSwitcherProps): JSX.Element;
|
|
524
|
+
|
|
525
|
+
export declare type ContextSwitcherAction = {
|
|
526
|
+
id: string;
|
|
527
|
+
label: ReactNode;
|
|
528
|
+
textValue: string;
|
|
529
|
+
icon?: ReactNode;
|
|
530
|
+
disabled?: boolean;
|
|
531
|
+
};
|
|
532
|
+
|
|
533
|
+
export declare type ContextSwitcherCurrent = {
|
|
534
|
+
label: ReactNode;
|
|
535
|
+
description?: ReactNode;
|
|
536
|
+
avatar?: ReactNode;
|
|
537
|
+
textValue: string;
|
|
538
|
+
};
|
|
539
|
+
|
|
540
|
+
export declare type ContextSwitcherGroup = {
|
|
541
|
+
id: string;
|
|
542
|
+
label: ReactNode;
|
|
543
|
+
textValue: string;
|
|
544
|
+
selectedId?: string;
|
|
545
|
+
items: ContextSwitcherItem[];
|
|
546
|
+
};
|
|
547
|
+
|
|
548
|
+
export declare type ContextSwitcherItem = {
|
|
549
|
+
id: string;
|
|
550
|
+
label: ReactNode;
|
|
551
|
+
textValue: string;
|
|
552
|
+
description?: ReactNode;
|
|
553
|
+
avatar?: ReactNode;
|
|
554
|
+
disabled?: boolean;
|
|
555
|
+
};
|
|
556
|
+
|
|
557
|
+
export declare type ContextSwitcherProps = {
|
|
558
|
+
currentContext: ContextSwitcherCurrent;
|
|
559
|
+
groups: ContextSwitcherGroup[];
|
|
560
|
+
open?: boolean;
|
|
561
|
+
defaultOpen?: boolean;
|
|
562
|
+
onOpenChange?: (open: boolean) => void;
|
|
563
|
+
onSelect: (item: ContextSwitcherItem) => void;
|
|
564
|
+
pendingId?: string;
|
|
565
|
+
errorMessage?: ReactNode;
|
|
566
|
+
footerActions?: ContextSwitcherAction[];
|
|
567
|
+
onFooterAction?: (action: ContextSwitcherAction) => void;
|
|
568
|
+
label?: string;
|
|
569
|
+
};
|
|
570
|
+
|
|
524
571
|
export declare function ControlOption({ id, label, description, error, indeterminate, ref, type, ...rest }: ControlOptionOwnProps & (FieldShellProps | FieldBareProps) & CheckboxOnlyProps & {
|
|
525
572
|
type: 'checkbox' | 'radio';
|
|
526
573
|
} & NativeInputProps): JSX.Element;
|
|
@@ -707,7 +754,7 @@ declare type IconButtonAccessibleName = {
|
|
|
707
754
|
ariaLabel: string;
|
|
708
755
|
};
|
|
709
756
|
|
|
710
|
-
|
|
757
|
+
declare type IconButtonBaseProps = {
|
|
711
758
|
variant?: ButtonVariant;
|
|
712
759
|
size?: ButtonSize;
|
|
713
760
|
circle?: boolean;
|
|
@@ -717,11 +764,10 @@ export declare type IconButtonProps = IconButtonAccessibleName & {
|
|
|
717
764
|
type?: 'button' | 'submit' | 'reset';
|
|
718
765
|
className?: string;
|
|
719
766
|
children?: ReactNode;
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
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;
|
|
725
771
|
ref?: Ref<HTMLButtonElement>;
|
|
726
772
|
};
|
|
727
773
|
|
|
@@ -840,6 +886,74 @@ declare type NativeInputProps = Omit<InputHTMLAttributes<HTMLInputElement>, 'id'
|
|
|
840
886
|
|
|
841
887
|
declare type NativeInputProps_2 = Omit<InputHTMLAttributes<HTMLInputElement>, 'type'>;
|
|
842
888
|
|
|
889
|
+
export declare function Navigation({ className, ...props }: NavigationProps): JSX.Element;
|
|
890
|
+
|
|
891
|
+
export declare function NavigationGroup({ label, icon, expanded, defaultExpanded, onExpandedChange, children, }: NavigationGroupProps): JSX.Element;
|
|
892
|
+
|
|
893
|
+
export declare type NavigationGroupProps = {
|
|
894
|
+
label: ReactNode;
|
|
895
|
+
icon?: ReactNode;
|
|
896
|
+
expanded?: boolean;
|
|
897
|
+
defaultExpanded?: boolean;
|
|
898
|
+
onExpandedChange?: (expanded: boolean) => void;
|
|
899
|
+
children: ReactNode;
|
|
900
|
+
};
|
|
901
|
+
|
|
902
|
+
export declare function NavigationItem(props: NavigationItemProps): JSX.Element;
|
|
903
|
+
|
|
904
|
+
export declare type NavigationItemAsButton = NavigationItemOwnProps & {
|
|
905
|
+
href?: undefined;
|
|
906
|
+
} & Omit<ButtonHTMLAttributes<HTMLButtonElement>, keyof NavigationItemOwnProps>;
|
|
907
|
+
|
|
908
|
+
export declare type NavigationItemAsLink = NavigationItemOwnProps & {
|
|
909
|
+
href: string;
|
|
910
|
+
} & Omit<AnchorHTMLAttributes<HTMLAnchorElement>, keyof NavigationItemOwnProps | 'href'>;
|
|
911
|
+
|
|
912
|
+
declare type NavigationItemOwnProps = {
|
|
913
|
+
active?: boolean;
|
|
914
|
+
disabled?: boolean;
|
|
915
|
+
icon?: ReactNode;
|
|
916
|
+
badge?: ReactNode;
|
|
917
|
+
description?: ReactNode;
|
|
918
|
+
action?: ReactNode;
|
|
919
|
+
children: ReactNode;
|
|
920
|
+
className?: string;
|
|
921
|
+
};
|
|
922
|
+
|
|
923
|
+
export declare type NavigationItemProps = NavigationItemAsLink | NavigationItemAsButton;
|
|
924
|
+
|
|
925
|
+
export declare type NavigationProps = HTMLAttributes<HTMLElement> & {
|
|
926
|
+
'aria-label': string;
|
|
927
|
+
};
|
|
928
|
+
|
|
929
|
+
export declare function NavigationSection({ label, action, children, className, ...props }: NavigationSectionProps): JSX.Element;
|
|
930
|
+
|
|
931
|
+
declare type NavigationSectionLabel = Exclude<ReactNode, boolean | null | undefined>;
|
|
932
|
+
|
|
933
|
+
declare type NavigationSectionNativeProps = Omit<HTMLAttributes<HTMLElement>, keyof NavigationSectionOwnProps>;
|
|
934
|
+
|
|
935
|
+
declare type NavigationSectionOwnProps = {
|
|
936
|
+
label?: ReactNode;
|
|
937
|
+
action?: ReactNode;
|
|
938
|
+
children: ReactNode;
|
|
939
|
+
className?: string;
|
|
940
|
+
};
|
|
941
|
+
|
|
942
|
+
export declare type NavigationSectionProps = NavigationSectionWithLabel | NavigationSectionWithAccessibleName;
|
|
943
|
+
|
|
944
|
+
declare type NavigationSectionWithAccessibleName = NavigationSectionNativeProps & Omit<NavigationSectionOwnProps, 'action'> & {
|
|
945
|
+
label?: undefined;
|
|
946
|
+
action?: never;
|
|
947
|
+
} & ({
|
|
948
|
+
'aria-label': string;
|
|
949
|
+
} | {
|
|
950
|
+
'aria-labelledby': string;
|
|
951
|
+
});
|
|
952
|
+
|
|
953
|
+
declare type NavigationSectionWithLabel = NavigationSectionNativeProps & Omit<NavigationSectionOwnProps, 'label'> & {
|
|
954
|
+
label: NavigationSectionLabel;
|
|
955
|
+
};
|
|
956
|
+
|
|
843
957
|
export declare function Note({ tone, size, filled, disabled, label, action, children, }: {
|
|
844
958
|
tone?: NoteTone;
|
|
845
959
|
size?: NoteSize;
|
|
@@ -1015,6 +1129,26 @@ export declare function ShowMore({ items, initial, noBorder, initialExpanded, }:
|
|
|
1015
1129
|
initialExpanded?: boolean;
|
|
1016
1130
|
}): JSX.Element;
|
|
1017
1131
|
|
|
1132
|
+
export declare const Sidebar: typeof SidebarRoot & {
|
|
1133
|
+
Header: typeof SidebarHeader;
|
|
1134
|
+
Content: typeof SidebarContent;
|
|
1135
|
+
Footer: typeof SidebarFooter;
|
|
1136
|
+
};
|
|
1137
|
+
|
|
1138
|
+
declare function SidebarContent({ className, ...props }: SidebarSlotProps): JSX.Element;
|
|
1139
|
+
|
|
1140
|
+
declare function SidebarFooter({ className, ...props }: SidebarSlotProps): JSX.Element;
|
|
1141
|
+
|
|
1142
|
+
declare function SidebarHeader({ className, ...props }: SidebarSlotProps): JSX.Element;
|
|
1143
|
+
|
|
1144
|
+
export declare type SidebarProps = HTMLAttributes<HTMLElement> & {
|
|
1145
|
+
'aria-label': string;
|
|
1146
|
+
};
|
|
1147
|
+
|
|
1148
|
+
declare function SidebarRoot({ className, ...props }: SidebarProps): JSX.Element;
|
|
1149
|
+
|
|
1150
|
+
export declare type SidebarSlotProps = HTMLAttributes<HTMLDivElement>;
|
|
1151
|
+
|
|
1018
1152
|
export declare function Skeleton({ shape, animated, show, className, children, }: {
|
|
1019
1153
|
shape?: SkeletonShape;
|
|
1020
1154
|
animated?: boolean;
|