@pieai/swimmer-ui-kit 2.5.0 → 2.6.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/CHANGELOG.md CHANGED
@@ -3,6 +3,65 @@
3
3
  All notable changes to `@pieai/swimmer-ui-kit`.
4
4
  Format: [Keep a Changelog](https://keepachangelog.com); versioning: semver.
5
5
 
6
+ ## 2.6.0 — 2026-09-12
7
+
8
+ Minor: new optional material selection and native controls. Existing root
9
+ exports and export-map paths remain; omitted options retain prior defaults.
10
+
11
+ ### Added
12
+
13
+ - `LiquidFinish` and optional `liquidFinish="matte" | "glossy"` across
14
+ LiquidGroup/LiquidSurface, GameButton, GameIconButton, GameToggle,
15
+ GameSegmentedControl, GameProgress and GameSelect. Both finishes reuse the
16
+ existing renderer; matte removes the specular pass, not motion or shadows.
17
+ Explicit LiquidGroup `gloss` remains the advanced override.
18
+ - Liquid icon buttons and switch thumbs; GameSelect uses a real native select
19
+ with optional liquid closed-field decoration, form/reset/ref/optgroup support,
20
+ invalid semantics and ordinary disabled/multiple/list modes. The popup remains
21
+ platform-native; this is not a searchable combobox or custom liquid listbox.
22
+ - Optional flat, filter-free progress and segmented surfaces. Slider forwards
23
+ native step, disabled, name and id.
24
+ - A beginner catalog at the site root: 12 shared recipe groups, 6 liquid control
25
+ categories, matte/glossy comparison, theme/state selection, actual interaction,
26
+ complete copyable/typechecked React examples and shareable configuration URLs.
27
+ Storybook uses the same recipes. The old reference remains at `/?view=reference`
28
+ and old `#game-ui-preview-*` links still open it.
29
+
30
+ ### Fixed and intentionally changed
31
+
32
+ - Press decoration ignores secondary pointer buttons and key repeat, clears on
33
+ lost capture/cancellation/blur, resets through disabled, and honors `static`.
34
+ Native content and hit targets never inherit the squash transform.
35
+ - The liquid button's native element no longer picks up the ordinary button's
36
+ independent CSS `scale` on press or hover lift; only the silhouette moves.
37
+ - Pointer feedback survives macOS WebKit's native pointerdown-then-blur ordering;
38
+ a true window deactivation still cancels the gesture. No focus is forced onto
39
+ the native control to hide this platform difference.
40
+ - Progress ARIA values now agree with the clamped visible value, including invalid
41
+ maxima and non-finite input. Forced-colors decoration falls back to system UI.
42
+ - `GameInput` and `GameTextArea` now expose `invalid` through `aria-invalid`,
43
+ like the new select; an explicit ARIA value still wins.
44
+ - Select decoration is a sibling of the persistent native field. Disabling,
45
+ changing material or switching single/list presentation must not remount the
46
+ select and lose an uncontrolled choice or replace its forwarded DOM ref.
47
+ Catalog material/state adjustments likewise preserve the current example's
48
+ entered values instead of silently resetting the recipe.
49
+ - Disabled icon buttons, switches and segmented options now have a quiet,
50
+ non-hovering treatment. Disabled segmented controls retain the selected option
51
+ on a flat surface instead of reserving animated liquid groups.
52
+ Inherited native fieldset disabling also hides button/icon/switch/select decoration.
53
+ - The liquid form page selects experiments instead of mounting every form, size,
54
+ tone and state simultaneously. At most two liquid groups are mounted; the shared
55
+ budget was not increased and the twelve forms were not removed or retuned.
56
+
57
+ ### Consumer action
58
+
59
+ Pin the new version and run your own product gates. New materials/controls are
60
+ opt-in; University was not modified. Do not remove its destination/route transition
61
+ when adopting kit buttons. See the upgrade playbook for adoption and rollback.
62
+ No new runtime dependency, ambient clock, donor observer, image optimization or
63
+ commercial donor preset is introduced by this release.
64
+
6
65
  ## 2.5.0 — 2026-09-12
7
66
 
8
67
  ### Find the right component before reading the whole API
package/README.md CHANGED
@@ -17,14 +17,18 @@ assets may not be extracted, modified, or redistributed as a standalone pack.
17
17
  [Usage and upgrade playbook](docs/reference/usage-and-upgrade-playbook.md)
18
18
  - Exhaustive reference (not the starting point):
19
19
  [Generated public API inventory](docs/reference/public-api-inventory.md)
20
- - Live catalog: `pnpm dev` (preview page) and `pnpm storybook`
20
+ - [Interactive catalog](https://swimmer-ui-kit.pieaistudio.com/): real controls,
21
+ matte/glossy comparison, theme/state selectors and copyable React examples.
22
+ - [Full reference](https://swimmer-ui-kit.pieaistudio.com/?view=reference) and
23
+ [liquid form laboratory](https://swimmer-ui-kit.pieaistudio.com/liquid.html).
24
+ Local: `pnpm dev` and `pnpm storybook`.
21
25
 
22
26
  ## Install
23
27
 
24
28
  ```json
25
29
  {
26
30
  "dependencies": {
27
- "@pieai/swimmer-ui-kit": "2.5.0"
31
+ "@pieai/swimmer-ui-kit": "2.6.0"
28
32
  }
29
33
  }
30
34
  ```
package/dist/index.d.ts CHANGED
@@ -5,6 +5,7 @@ import { HTMLAttributes } from 'react';
5
5
  import { InputHTMLAttributes } from 'react';
6
6
  import { ReactNode } from 'react';
7
7
  import { RefAttributes } from 'react';
8
+ import { SelectHTMLAttributes } from 'react';
8
9
  import { TextareaHTMLAttributes } from 'react';
9
10
 
10
11
  /** Opt in to placeholders on purpose, and stop being told about it. */
@@ -1376,12 +1377,14 @@ export declare interface GameBuildLibraryProps {
1376
1377
  'data-testid'?: string | undefined;
1377
1378
  }
1378
1379
 
1379
- export declare function GameButton({ children, className, fullWidth, onClick, sound, static: isStatic, surface, type, variant, ...props }: GameButtonProps): ReactNode;
1380
+ export declare function GameButton({ children, className, fullWidth, liquidFinish, onClick, sound, static: isStatic, surface, type, variant, ...props }: GameButtonProps): ReactNode;
1380
1381
 
1381
1382
  export declare interface GameButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
1382
1383
  children: ReactNode;
1383
1384
  /** Fill the available row, including the liquid silhouette and hit target. */
1384
1385
  fullWidth?: boolean;
1386
+ /** Named liquid material. Only used with surface="liquid"; omitted keeps the current look. */
1387
+ liquidFinish?: LiquidFinish;
1385
1388
  sound?: GameInteractionSoundOptions | false;
1386
1389
  /** Disable the scale-on-press feedback where the motion would distract. */
1387
1390
  static?: boolean;
@@ -1727,11 +1730,13 @@ export declare interface GameHudProps {
1727
1730
  label: string;
1728
1731
  }
1729
1732
 
1730
- export declare function GameIconButton({ children, className, label, type, ...props }: GameIconButtonProps): ReactNode;
1733
+ export declare function GameIconButton({ children, className, label, surface, liquidFinish, type, ...props }: GameIconButtonProps): ReactNode;
1731
1734
 
1732
1735
  export declare interface GameIconButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
1733
1736
  children: ReactNode;
1734
1737
  label: string;
1738
+ surface?: GameButtonSurface;
1739
+ liquidFinish?: LiquidFinish;
1735
1740
  }
1736
1741
 
1737
1742
  export declare const GameInput: ForwardRefExoticComponent<GameInputProps & RefAttributes<HTMLInputElement>>;
@@ -1912,9 +1917,12 @@ export declare interface GamePlacementToolbarProps {
1912
1917
  title: string;
1913
1918
  }
1914
1919
 
1915
- export declare function GameProgress({ className, label, max, showValue, tone, value, valueLabel, }: GameProgressProps): ReactNode;
1920
+ export declare function GameProgress({ className, label, max, showValue, tone, value, valueLabel, surface, liquidFinish, }: GameProgressProps): ReactNode;
1916
1921
 
1917
1922
  export declare interface GameProgressProps {
1923
+ /** Defaults to the existing liquid leading edge. Flat adds no SVG filter. */
1924
+ surface?: GameButtonSurface;
1925
+ liquidFinish?: LiquidFinish;
1918
1926
  /** Current value, between 0 and `max`. */
1919
1927
  value: number;
1920
1928
  max?: number;
@@ -1980,13 +1988,17 @@ export declare const GameSceneHudLayout: typeof GameShell;
1980
1988
 
1981
1989
  export declare type GameSceneHudLayoutProps = GameShellProps;
1982
1990
 
1983
- export declare function GameSegmentedControl({ activeId, label, onSelect, options, }: GameSegmentedControlProps): ReactNode;
1991
+ export declare function GameSegmentedControl({ activeId, label, onSelect, options, surface, liquidFinish, disabled, }: GameSegmentedControlProps): ReactNode;
1984
1992
 
1985
1993
  export declare interface GameSegmentedControlProps {
1986
1994
  activeId: string;
1987
1995
  label: string;
1988
1996
  onSelect?: (id: string) => void;
1989
1997
  options: readonly GameSegmentedOption[];
1998
+ /** Existing default is liquid. Flat provides a quiet, filter-free option. */
1999
+ surface?: GameButtonSurface;
2000
+ liquidFinish?: LiquidFinish;
2001
+ disabled?: boolean;
1990
2002
  }
1991
2003
 
1992
2004
  declare interface GameSegmentedOption {
@@ -1994,6 +2006,20 @@ declare interface GameSegmentedOption {
1994
2006
  label: string;
1995
2007
  }
1996
2008
 
2009
+ /**
2010
+ * Native select, not a custom listbox state machine. Options/optgroups, form
2011
+ * submission, reset, keyboard and the mobile picker remain browser-owned.
2012
+ * Liquid paints only the closed single-select field. Disabled/multiple/list
2013
+ * modes use the ordinary surface; we do not pretend to animate an OS popup.
2014
+ */
2015
+ export declare const GameSelect: ForwardRefExoticComponent<GameSelectProps & RefAttributes<HTMLSelectElement>>;
2016
+
2017
+ export declare interface GameSelectProps extends SelectHTMLAttributes<HTMLSelectElement> {
2018
+ invalid?: boolean;
2019
+ surface?: GameButtonSurface;
2020
+ liquidFinish?: LiquidFinish;
2021
+ }
2022
+
1997
2023
  export declare function GameShell({ assetLibrary, bottomBar, children, className, density, hud, layout, movementPad, overlay, sidePanel, title, }: GameShellProps): ReactNode;
1998
2024
 
1999
2025
  export declare interface GameShellProps {
@@ -2018,9 +2044,9 @@ export declare interface GameShellProps {
2018
2044
  title: string;
2019
2045
  }
2020
2046
 
2021
- export declare function GameSlider({ label, max, min, onChange, value }: GameSliderProps): ReactNode;
2047
+ export declare function GameSlider({ label, max, min, step, disabled, name, id, onChange, value, }: GameSliderProps): ReactNode;
2022
2048
 
2023
- export declare interface GameSliderProps extends Pick<InputHTMLAttributes<HTMLInputElement>, 'max' | 'min' | 'value'> {
2049
+ export declare interface GameSliderProps extends Pick<InputHTMLAttributes<HTMLInputElement>, 'max' | 'min' | 'value' | 'step' | 'disabled' | 'name' | 'id'> {
2024
2050
  label: string;
2025
2051
  onChange?: (value: number) => void;
2026
2052
  }
@@ -2200,11 +2226,13 @@ export declare interface GameToastProps {
2200
2226
  tone?: 'info' | 'success' | 'danger';
2201
2227
  }
2202
2228
 
2203
- export declare function GameToggle({ checked, disabled, label, onClick }: GameToggleProps): ReactNode;
2229
+ export declare function GameToggle({ checked, disabled, label, onClick, surface, liquidFinish, }: GameToggleProps): ReactNode;
2204
2230
 
2205
2231
  export declare interface GameToggleProps extends Pick<ButtonHTMLAttributes<HTMLButtonElement>, 'disabled' | 'onClick'> {
2206
2232
  checked: boolean;
2207
2233
  label: string;
2234
+ surface?: GameButtonSurface;
2235
+ liquidFinish?: LiquidFinish;
2208
2236
  }
2209
2237
 
2210
2238
  export declare function GameTooltip({ children, label }: GameTooltipProps): ReactNode;
@@ -2354,6 +2382,9 @@ export declare const LIQUID_FORMS: Readonly<Record<LiquidForm, LiquidFormSpec>>;
2354
2382
  */
2355
2383
  export declare const LIQUID_GOOEY_WAVINESS_MAX_FRACTION = 0.3;
2356
2384
 
2385
+ /** Material is independent of a widget's meaning and a form's motion. */
2386
+ export declare type LiquidFinish = 'matte' | 'glossy';
2387
+
2357
2388
  /**
2358
2389
  * The named looks.
2359
2390
  *
@@ -2532,6 +2563,8 @@ export declare interface LiquidGroupProps extends Omit<HTMLAttributes<HTMLDivEle
2532
2563
  * curved surface so it reads as a material rather than as a silhouette.
2533
2564
  */
2534
2565
  gloss?: number;
2566
+ /** Optional named finish. An explicit raw gloss wins; omitted preserves the old rendering. */
2567
+ liquidFinish?: LiquidFinish;
2535
2568
  /** Surface fill. Defaults to the kit's theme surface token. */
2536
2569
  fill?: string;
2537
2570
  /** Extra filter-region slack in px for the silhouette's painted edges. */
@@ -2624,10 +2657,12 @@ export declare interface LiquidMetalButtonProps extends ButtonHTMLAttributes<HTM
2624
2657
 
2625
2658
  export declare type LiquidMetalRendererMode = 'auto' | 'css' | 'webgl';
2626
2659
 
2627
- export declare function LiquidSurface({ children, form, active, fill, stroke, shadow: shadowOverride, radius, className, style, }: LiquidSurfaceProps): ReactNode;
2660
+ export declare function LiquidSurface({ children, liquidFinish, form, active, fill, stroke, shadow: shadowOverride, radius, className, style, }: LiquidSurfaceProps): ReactNode;
2628
2661
 
2629
2662
  export declare interface LiquidSurfaceProps {
2630
2663
  children: ReactNode;
2664
+ /** Omitted keeps the form's existing lighting; matte and glossy share the same motion. */
2665
+ liquidFinish?: LiquidFinish;
2631
2666
  /** Which named look. Defaults to the press form, the one a control wants. */
2632
2667
  form?: LiquidForm;
2633
2668
  /**