@q1travel/design-system 0.6.0 → 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.
@@ -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 development warning evaluates the resolved accessible name.
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
- onClick?: MouseEventHandler<HTMLButtonElement>;
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
- export declare type IconButtonProps = IconButtonAccessibleName & {
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
- onClick?: MouseEventHandler<HTMLButtonElement>;
770
- 'aria-describedby'?: string;
771
- onFocus?: FocusEventHandler<HTMLButtonElement>;
772
- onBlur?: FocusEventHandler<HTMLButtonElement>;
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