@g9tm/lynxcontrols 1.4.5 → 1.4.11

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.
Files changed (167) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/base/index.d.ts +1 -1
  3. package/dist/base/index.d.ts.map +1 -1
  4. package/dist/base/index.jsx +1 -1
  5. package/dist/base/pressable.d.ts.map +1 -1
  6. package/dist/base/pressable.jsx +2 -1
  7. package/dist/base/pressable.jsx.map +1 -1
  8. package/dist/base/selection-item.d.ts +9 -1
  9. package/dist/base/selection-item.d.ts.map +1 -1
  10. package/dist/base/selection-item.jsx +10 -1
  11. package/dist/base/selection-item.jsx.map +1 -1
  12. package/dist/button/button.css +20 -0
  13. package/dist/button/button.css.map +1 -1
  14. package/dist/button/header-action-button.d.ts +5 -0
  15. package/dist/button/header-action-button.d.ts.map +1 -1
  16. package/dist/button/header-action-button.jsx +6 -1
  17. package/dist/button/header-action-button.jsx.map +1 -1
  18. package/dist/button/visuals.d.ts.map +1 -1
  19. package/dist/button/visuals.jsx +1 -1
  20. package/dist/button/visuals.jsx.map +1 -1
  21. package/dist/cascade/cascade-panel.d.ts.map +1 -1
  22. package/dist/cascade/cascade-panel.jsx +2 -2
  23. package/dist/cascade/cascade-panel.jsx.map +1 -1
  24. package/dist/edge-panel/edge-panel.jsx +5 -5
  25. package/dist/edge-panel/edge-panel.jsx.map +1 -1
  26. package/dist/expander/expander.d.ts.map +1 -1
  27. package/dist/expander/expander.jsx +2 -1
  28. package/dist/expander/expander.jsx.map +1 -1
  29. package/dist/fields/editor.d.ts.map +1 -1
  30. package/dist/fields/editor.jsx +2 -2
  31. package/dist/fields/editor.jsx.map +1 -1
  32. package/dist/fields/fields.css +21 -0
  33. package/dist/fields/fields.css.map +1 -1
  34. package/dist/fields/index.d.ts +1 -1
  35. package/dist/fields/index.d.ts.map +1 -1
  36. package/dist/fields/index.jsx +1 -1
  37. package/dist/fields/outlined-field.d.ts +27 -1
  38. package/dist/fields/outlined-field.d.ts.map +1 -1
  39. package/dist/fields/outlined-field.jsx +29 -2
  40. package/dist/fields/outlined-field.jsx.map +1 -1
  41. package/dist/fields/text-entry.d.ts.map +1 -1
  42. package/dist/fields/text-entry.jsx +2 -2
  43. package/dist/fields/text-entry.jsx.map +1 -1
  44. package/dist/host/host.css.map +1 -1
  45. package/dist/host/host.d.ts +3 -2
  46. package/dist/host/host.d.ts.map +1 -1
  47. package/dist/host/host.jsx +2 -2
  48. package/dist/host/host.jsx.map +1 -1
  49. package/dist/pickers/combo-box.d.ts +8 -0
  50. package/dist/pickers/combo-box.d.ts.map +1 -1
  51. package/dist/pickers/combo-box.jsx +51 -9
  52. package/dist/pickers/combo-box.jsx.map +1 -1
  53. package/dist/pickers/date-time-picker.d.ts +2 -2
  54. package/dist/pickers/date-time-picker.d.ts.map +1 -1
  55. package/dist/pickers/date-time-picker.jsx +4 -3
  56. package/dist/pickers/date-time-picker.jsx.map +1 -1
  57. package/dist/pickers/date-time.d.ts +5 -2
  58. package/dist/pickers/date-time.d.ts.map +1 -1
  59. package/dist/pickers/date-time.jsx +1 -1
  60. package/dist/pickers/date-time.jsx.map +1 -1
  61. package/dist/pickers/picker-sheet.d.ts +6 -2
  62. package/dist/pickers/picker-sheet.d.ts.map +1 -1
  63. package/dist/pickers/picker-sheet.jsx +2 -3
  64. package/dist/pickers/picker-sheet.jsx.map +1 -1
  65. package/dist/pickers/picker.d.ts.map +1 -1
  66. package/dist/pickers/picker.jsx +3 -2
  67. package/dist/pickers/picker.jsx.map +1 -1
  68. package/dist/pickers/pickers.css +27 -0
  69. package/dist/pickers/pickers.css.map +1 -1
  70. package/dist/pickers/timespan-picker.d.ts.map +1 -1
  71. package/dist/pickers/timespan-picker.jsx +3 -2
  72. package/dist/pickers/timespan-picker.jsx.map +1 -1
  73. package/dist/pickers/trigger.d.ts +3 -1
  74. package/dist/pickers/trigger.d.ts.map +1 -1
  75. package/dist/pickers/trigger.jsx +6 -1
  76. package/dist/pickers/trigger.jsx.map +1 -1
  77. package/dist/plus-button/model.d.ts.map +1 -1
  78. package/dist/plus-button/model.jsx +5 -1
  79. package/dist/plus-button/model.jsx.map +1 -1
  80. package/dist/popup/frame.jsx +2 -2
  81. package/dist/popup/frame.jsx.map +1 -1
  82. package/dist/popup/service.d.ts.map +1 -1
  83. package/dist/popup/service.jsx +2 -2
  84. package/dist/popup/service.jsx.map +1 -1
  85. package/dist/provider/provider.css +4 -0
  86. package/dist/provider/provider.css.map +1 -1
  87. package/dist/provider/provider.d.ts.map +1 -1
  88. package/dist/provider/provider.jsx +4 -2
  89. package/dist/provider/provider.jsx.map +1 -1
  90. package/dist/provider/settings.d.ts +12 -0
  91. package/dist/provider/settings.d.ts.map +1 -1
  92. package/dist/provider/settings.jsx +6 -3
  93. package/dist/provider/settings.jsx.map +1 -1
  94. package/dist/provider/theme.css +4 -0
  95. package/dist/provider/theme.css.map +1 -1
  96. package/dist/range-slider/math.d.ts +14 -4
  97. package/dist/range-slider/math.d.ts.map +1 -1
  98. package/dist/range-slider/math.jsx +16 -4
  99. package/dist/range-slider/math.jsx.map +1 -1
  100. package/dist/range-slider/range-slider.css +17 -0
  101. package/dist/range-slider/range-slider.css.map +1 -1
  102. package/dist/range-slider/range-slider.d.ts +11 -0
  103. package/dist/range-slider/range-slider.d.ts.map +1 -1
  104. package/dist/range-slider/range-slider.jsx +35 -13
  105. package/dist/range-slider/range-slider.jsx.map +1 -1
  106. package/dist/selection/index.d.ts +2 -1
  107. package/dist/selection/index.d.ts.map +1 -1
  108. package/dist/selection/index.jsx +2 -1
  109. package/dist/selection/selection-sheet.d.ts +8 -1
  110. package/dist/selection/selection-sheet.d.ts.map +1 -1
  111. package/dist/selection/selection-sheet.jsx +64 -11
  112. package/dist/selection/selection-sheet.jsx.map +1 -1
  113. package/dist/selection/selection.css +7 -0
  114. package/dist/selection/selection.css.map +1 -1
  115. package/dist/selection/window.d.ts +29 -0
  116. package/dist/selection/window.d.ts.map +1 -0
  117. package/dist/selection/window.jsx +24 -0
  118. package/dist/selection/window.jsx.map +1 -0
  119. package/dist/sheet/frame.d.ts.map +1 -1
  120. package/dist/sheet/frame.jsx +35 -9
  121. package/dist/sheet/frame.jsx.map +1 -1
  122. package/dist/sheet/header.d.ts.map +1 -1
  123. package/dist/sheet/header.jsx +3 -1
  124. package/dist/sheet/header.jsx.map +1 -1
  125. package/dist/sheet/index.d.ts +2 -1
  126. package/dist/sheet/index.d.ts.map +1 -1
  127. package/dist/sheet/index.jsx +2 -1
  128. package/dist/sheet/motion.d.ts.map +1 -1
  129. package/dist/sheet/motion.jsx +14 -0
  130. package/dist/sheet/motion.jsx.map +1 -1
  131. package/dist/sheet/options.d.ts +26 -0
  132. package/dist/sheet/options.d.ts.map +1 -1
  133. package/dist/sheet/options.jsx +2 -1
  134. package/dist/sheet/options.jsx.map +1 -1
  135. package/dist/sheet/scroll-indicator.d.ts +33 -0
  136. package/dist/sheet/scroll-indicator.d.ts.map +1 -0
  137. package/dist/sheet/scroll-indicator.jsx +84 -0
  138. package/dist/sheet/scroll-indicator.jsx.map +1 -0
  139. package/dist/sheet/service.d.ts +8 -0
  140. package/dist/sheet/service.d.ts.map +1 -1
  141. package/dist/sheet/service.jsx +15 -4
  142. package/dist/sheet/service.jsx.map +1 -1
  143. package/dist/sheet/sheet.css +14 -0
  144. package/dist/sheet/sheet.css.map +1 -1
  145. package/dist/sheet/sizing.d.ts +2 -0
  146. package/dist/sheet/sizing.d.ts.map +1 -1
  147. package/dist/sheet/sizing.jsx +2 -1
  148. package/dist/sheet/sizing.jsx.map +1 -1
  149. package/dist/tab-bar/tab-bar.d.ts.map +1 -1
  150. package/dist/tab-bar/tab-bar.jsx +11 -6
  151. package/dist/tab-bar/tab-bar.jsx.map +1 -1
  152. package/dist/toast/service.jsx +3 -3
  153. package/dist/toast/service.jsx.map +1 -1
  154. package/dist/toast/store.d.ts.map +1 -1
  155. package/dist/toast/store.jsx +3 -2
  156. package/dist/toast/store.jsx.map +1 -1
  157. package/dist/toggle/chip-group.d.ts +9 -1
  158. package/dist/toggle/chip-group.d.ts.map +1 -1
  159. package/dist/toggle/chip-group.jsx +51 -12
  160. package/dist/toggle/chip-group.jsx.map +1 -1
  161. package/dist/toggle/switch.d.ts +1 -1
  162. package/dist/toggle/switch.d.ts.map +1 -1
  163. package/dist/toggle/switch.jsx +3 -2
  164. package/dist/toggle/switch.jsx.map +1 -1
  165. package/dist/toggle/toggle.css +20 -0
  166. package/dist/toggle/toggle.css.map +1 -1
  167. package/package.json +3 -3
@@ -1,3 +1,4 @@
1
+ import { g9Ms } from "@g9tm/lynxcontrols-foundation";
1
2
  import { useG9Control } from "./control.jsx";
2
3
  import { useG9Press, usePressVisual } from "./press.jsx";
3
4
  const g9PressFeedbackDefaults = Object.freeze({
@@ -15,7 +16,7 @@ function G9Pressable(props) {
15
16
  blocked: control.disabled,
16
17
  source: 'G9Pressable'
17
18
  });
18
- const ms = null != (_props_animationDurationMs = props.animationDurationMs) ? _props_animationDurationMs : g9PressFeedbackDefaults.inMs;
19
+ const ms = g9Ms(null != (_props_animationDurationMs = props.animationDurationMs) ? _props_animationDurationMs : g9PressFeedbackDefaults.inMs);
19
20
  const visual = usePressVisual({
20
21
  property: 'opacity',
21
22
  rest: null != (_props_restOpacity = props.restOpacity) ? _props_restOpacity : g9PressFeedbackDefaults.rest,
@@ -1 +1 @@
1
- {"version":3,"file":"base/pressable.jsx","sources":["../../src/base/pressable.tsx"],"sourcesContent":["import type { ReactNode } from '@lynx-js/react';\nimport { type G9ControlBaseProps, useG9Control } from './control';\nimport { type G9PressVisual, useG9Press, usePressVisual } from './press';\n\n/** The standard press feedback curve (MAUI `G9PressFeedbackBehavior` defaults: 1 / 0.86 / 0.78 over 110 ms). */\nexport const g9PressFeedbackDefaults: G9PressVisual = Object.freeze({\n property: 'opacity',\n rest: 1,\n hovered: 0.86,\n pressed: 0.78,\n inMs: 110,\n outMs: 110,\n});\n\n/** Props of {@link G9Pressable}. */\nexport interface G9PressableProps extends G9ControlBaseProps {\n /** The press (MAUI `Command` + `CommandParameter`); one handler on the root, children never take the touch. */\n readonly onPress?: () => void;\n /** Opacity at rest. Default 1. */\n readonly restOpacity?: number;\n /** Opacity under a desktop pointer. Default 0.86. */\n readonly hoveredOpacity?: number;\n /** Opacity while pressed. Default 0.78. */\n readonly pressedOpacity?: number;\n /** Each tween's length. Default 110 ms. */\n readonly animationDurationMs?: number;\n readonly children?: ReactNode;\n}\n\n/**\n * Opacity press feedback around any content (MAUI `G9PressFeedbackBehavior` attached to a view; `.For(command)` is\n * `<G9Pressable onPress={…}>`). The feedback runs on the main thread; the press goes through `useG9Press`.\n */\nexport function G9Pressable(props: G9PressableProps): ReactNode {\n const control = useG9Control(props, 'g9-pressable');\n const press = useG9Press(props.onPress, { blocked: control.disabled, source: 'G9Pressable' });\n const ms = props.animationDurationMs ?? g9PressFeedbackDefaults.inMs;\n const visual = usePressVisual(\n {\n property: 'opacity',\n rest: props.restOpacity ?? g9PressFeedbackDefaults.rest,\n hovered: props.hoveredOpacity ?? (g9PressFeedbackDefaults.hovered as number),\n pressed: props.pressedOpacity ?? g9PressFeedbackDefaults.pressed,\n inMs: ms,\n outMs: ms,\n },\n control.disabled,\n );\n return (\n <view\n className={control.className}\n {...control.idProps}\n style={{ opacity: props.restOpacity ?? 1 }}\n {...(props.accessibilityLabel\n ? { 'accessibility-element': true, 'accessibility-label': props.accessibilityLabel }\n : {})}\n bindtap={press}\n {...visual}\n >\n {props.children}\n </view>\n );\n}\n"],"names":["g9PressFeedbackDefaults","Object","G9Pressable","props","_props_animationDurationMs","_props_restOpacity","_props_hoveredOpacity","_props_pressedOpacity","_props_restOpacity1","control","useG9Control","press","useG9Press","ms","visual","usePressVisual","view"],"mappings":";;AAKO,MAAMA,0BAAyCC,OAAO,MAAM,CAAC;IAClE,UAAU;IACV,MAAM;IACN,SAAS;IACT,SAAS;IACT,MAAM;IACN,OAAO;AACT;AAqBO,SAASC,YAAYC,KAAuB;QAGtCC,4BAIDC,oBACGC,uBACAC,uBAUSC;IAlBtB,MAAMC,UAAUC,aAAaP,OAAO;IACpC,MAAMQ,QAAQC,WAAWT,MAAM,OAAO,EAAE;QAAE,SAASM,QAAQ,QAAQ;QAAE,QAAQ;IAAc;IAC3F,MAAMI,KAAK,QAAAT,CAAAA,6BAAAA,MAAM,mBAAmB,AAAD,IAAxBA,6BAA6BJ,wBAAwB,IAAI;IACpE,MAAMc,SAASC,eACb;QACE,UAAU;QACV,MAAM,QAAAV,CAAAA,qBAAAA,MAAM,WAAW,AAAD,IAAhBA,qBAAqBL,wBAAwB,IAAI;QACvD,SAAS,QAAAM,CAAAA,wBAAAA,MAAM,cAAc,AAAD,IAAnBA,wBAAyBN,wBAAwB,OAAO;QACjE,SAAS,QAAAO,CAAAA,wBAAAA,MAAM,cAAc,AAAD,IAAnBA,wBAAwBP,wBAAwB,OAAO;QAChE,MAAMa;QACN,OAAOA;IACT,GACAJ,QAAQ,QAAQ;IAElB,QACGO,KACC,WAAWP,QAAQ,SAAS,GAC3B,GAAGA,QAAQ,OAAO,EACnB,OAAO;QAAE,SAAS,QAAAD,CAAAA,sBAAAA,MAAM,WAAW,AAAD,IAAhBA,sBAAqB;IAAE,IACxC,GAAIL,MAAM,kBAAkB,GACzB;QAAE,yBAAyB;QAAM,uBAAuBA,MAAM,kBAAkB;IAAC,IACjF,CAAC,CAAC,EACN,SAASQ,QACR,GAAGG,MAAM,EACX;MACC,CAACX,MAAM,QAAQ,CAAC;IAClB,EAAEa;AAEN"}
1
+ {"version":3,"file":"base/pressable.jsx","sources":["../../src/base/pressable.tsx"],"sourcesContent":["import { g9Ms } from '@g9tm/lynxcontrols-foundation';\nimport type { ReactNode } from '@lynx-js/react';\nimport { type G9ControlBaseProps, useG9Control } from './control';\nimport { type G9PressVisual, useG9Press, usePressVisual } from './press';\n\n/** The standard press feedback curve (MAUI `G9PressFeedbackBehavior` defaults: 1 / 0.86 / 0.78 over 110 ms). */\nexport const g9PressFeedbackDefaults: G9PressVisual = Object.freeze({\n property: 'opacity',\n rest: 1,\n hovered: 0.86,\n pressed: 0.78,\n inMs: 110,\n outMs: 110,\n});\n\n/** Props of {@link G9Pressable}. */\nexport interface G9PressableProps extends G9ControlBaseProps {\n /** The press (MAUI `Command` + `CommandParameter`); one handler on the root, children never take the touch. */\n readonly onPress?: () => void;\n /** Opacity at rest. Default 1. */\n readonly restOpacity?: number;\n /** Opacity under a desktop pointer. Default 0.86. */\n readonly hoveredOpacity?: number;\n /** Opacity while pressed. Default 0.78. */\n readonly pressedOpacity?: number;\n /** Each tween's length. Default 110 ms. */\n readonly animationDurationMs?: number;\n readonly children?: ReactNode;\n}\n\n/**\n * Opacity press feedback around any content (MAUI `G9PressFeedbackBehavior` attached to a view; `.For(command)` is\n * `<G9Pressable onPress={…}>`). The feedback runs on the main thread; the press goes through `useG9Press`.\n */\nexport function G9Pressable(props: G9PressableProps): ReactNode {\n const control = useG9Control(props, 'g9-pressable');\n const press = useG9Press(props.onPress, { blocked: control.disabled, source: 'G9Pressable' });\n const ms = g9Ms(props.animationDurationMs ?? g9PressFeedbackDefaults.inMs);\n const visual = usePressVisual(\n {\n property: 'opacity',\n rest: props.restOpacity ?? g9PressFeedbackDefaults.rest,\n hovered: props.hoveredOpacity ?? (g9PressFeedbackDefaults.hovered as number),\n pressed: props.pressedOpacity ?? g9PressFeedbackDefaults.pressed,\n inMs: ms,\n outMs: ms,\n },\n control.disabled,\n );\n return (\n <view\n className={control.className}\n {...control.idProps}\n style={{ opacity: props.restOpacity ?? 1 }}\n {...(props.accessibilityLabel\n ? { 'accessibility-element': true, 'accessibility-label': props.accessibilityLabel }\n : {})}\n bindtap={press}\n {...visual}\n >\n {props.children}\n </view>\n );\n}\n"],"names":["g9PressFeedbackDefaults","Object","G9Pressable","props","_props_animationDurationMs","_props_restOpacity","_props_hoveredOpacity","_props_pressedOpacity","_props_restOpacity1","control","useG9Control","press","useG9Press","ms","g9Ms","visual","usePressVisual","view"],"mappings":";;;AAMO,MAAMA,0BAAyCC,OAAO,MAAM,CAAC;IAClE,UAAU;IACV,MAAM;IACN,SAAS;IACT,SAAS;IACT,MAAM;IACN,OAAO;AACT;AAqBO,SAASC,YAAYC,KAAuB;QAGjCC,4BAINC,oBACGC,uBACAC,uBAUSC;IAlBtB,MAAMC,UAAUC,aAAaP,OAAO;IACpC,MAAMQ,QAAQC,WAAWT,MAAM,OAAO,EAAE;QAAE,SAASM,QAAQ,QAAQ;QAAE,QAAQ;IAAc;IAC3F,MAAMI,KAAKC,KAAK,QAAAV,CAAAA,6BAAAA,MAAM,mBAAmB,AAAD,IAAxBA,6BAA6BJ,wBAAwB,IAAI;IACzE,MAAMe,SAASC,eACb;QACE,UAAU;QACV,MAAM,QAAAX,CAAAA,qBAAAA,MAAM,WAAW,AAAD,IAAhBA,qBAAqBL,wBAAwB,IAAI;QACvD,SAAS,QAAAM,CAAAA,wBAAAA,MAAM,cAAc,AAAD,IAAnBA,wBAAyBN,wBAAwB,OAAO;QACjE,SAAS,QAAAO,CAAAA,wBAAAA,MAAM,cAAc,AAAD,IAAnBA,wBAAwBP,wBAAwB,OAAO;QAChE,MAAMa;QACN,OAAOA;IACT,GACAJ,QAAQ,QAAQ;IAElB,QACGQ,KACC,WAAWR,QAAQ,SAAS,GAC3B,GAAGA,QAAQ,OAAO,EACnB,OAAO;QAAE,SAAS,QAAAD,CAAAA,sBAAAA,MAAM,WAAW,AAAD,IAAhBA,sBAAqB;IAAE,IACxC,GAAIL,MAAM,kBAAkB,GACzB;QAAE,yBAAyB;QAAM,uBAAuBA,MAAM,kBAAkB;IAAC,IACjF,CAAC,CAAC,EACN,SAASQ,QACR,GAAGI,MAAM,EACX;MACC,CAACZ,MAAM,QAAQ,CAAC;IAClB,EAAEc;AAEN"}
@@ -1,4 +1,4 @@
1
- import type { G9ImageSource } from '@g9tm/lynxcontrols-foundation';
1
+ import { type G9ImageSource } from '@g9tm/lynxcontrols-foundation';
2
2
  import type { G9IconInput } from '../icon/icon.js';
3
3
  /**
4
4
  * One selectable item (MAUI `G9SelectionItem`), shared by the chip group (WP04), the selection sheet and the pickers
@@ -23,7 +23,15 @@ export interface G9SelectionItem<TValue = unknown> {
23
23
  /** Selected fill override (wins over the group's). */
24
24
  readonly selectedColor?: string | null | undefined;
25
25
  readonly selectedTextColor?: string | null | undefined;
26
+ /**
27
+ * The image (`iconPath` / `iconImage`) is a person's picture (MAUI 1.4.10 `IsAvatar`): drawn ROUND, at
28
+ * `G9Metrics.SelectionAvatarSize` (28) in the selection sheet's rows and round at the icon size as a single combo-box
29
+ * value; multi-select chips show the name only. Ignored for an emoji or a glyph.
30
+ */
31
+ readonly isAvatar?: boolean | undefined;
26
32
  }
33
+ /** The item's icon is a person's picture: `isAvatar` on an image, not an emoji or a glyph (MAUI `IsAvatarImage`). */
34
+ export declare function isAvatarImage(item: G9SelectionItem): boolean;
27
35
  /** The identity of an item: `key` unless blank, else `text` (MAUI `G9SelectionItem.SelectionIdentity`). */
28
36
  export declare function selectionKey(item: Pick<G9SelectionItem, 'key' | 'text'>): string;
29
37
  //# sourceMappingURL=selection-item.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"selection-item.d.ts","sourceRoot":"","sources":["../../src/base/selection-item.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD;;;GAGG;AACH,MAAM,WAAW,eAAe,CAAC,MAAM,GAAG,OAAO;IAC/C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,sFAAsF;IACtF,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACzC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC3C,QAAQ,CAAC,IAAI,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;IACxC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC9C,QAAQ,CAAC,SAAS,CAAC,EAAE,aAAa,GAAG,IAAI,GAAG,SAAS,CAAC;IACtD,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACnD,+DAA+D;IAC/D,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACtD,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACvD,+CAA+C;IAC/C,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,oBAAoB;IACpB,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACzC,sDAAsD;IACtD,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACnD,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;CACxD;AAED,2GAA2G;AAC3G,wBAAgB,YAAY,CAAC,IAAI,EAAE,IAAI,CAAC,eAAe,EAAE,KAAK,GAAG,MAAM,CAAC,GAAG,MAAM,CAEhF"}
1
+ {"version":3,"file":"selection-item.d.ts","sourceRoot":"","sources":["../../src/base/selection-item.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAe,MAAM,+BAA+B,CAAC;AAChF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD;;;GAGG;AACH,MAAM,WAAW,eAAe,CAAC,MAAM,GAAG,OAAO;IAC/C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,sFAAsF;IACtF,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACzC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC3C,QAAQ,CAAC,IAAI,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;IACxC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC9C,QAAQ,CAAC,SAAS,CAAC,EAAE,aAAa,GAAG,IAAI,GAAG,SAAS,CAAC;IACtD,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACnD,+DAA+D;IAC/D,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACtD,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACvD,+CAA+C;IAC/C,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,oBAAoB;IACpB,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACzC,sDAAsD;IACtD,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACnD,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACvD;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CACzC;AAED,qHAAqH;AACrH,wBAAgB,aAAa,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAQ5D;AAED,2GAA2G;AAC3G,wBAAgB,YAAY,CAAC,IAAI,EAAE,IAAI,CAAC,eAAe,EAAE,KAAK,GAAG,MAAM,CAAC,GAAG,MAAM,CAEhF"}
@@ -1,6 +1,15 @@
1
+ import { isIconEmpty } from "@g9tm/lynxcontrols-foundation";
2
+ function isAvatarImage(item) {
3
+ if (true !== item.isAvatar) return false;
4
+ if (null != item.emoji && '' !== item.emoji.trim()) return false;
5
+ const icon = item.icon;
6
+ const glyph = void 0 !== icon && ('string' == typeof icon ? '' !== icon.trim() && 'none' !== icon : !isIconEmpty(icon));
7
+ if (glyph) return false;
8
+ return null != item.iconPath && '' !== item.iconPath.trim() || null != item.iconImage;
9
+ }
1
10
  function selectionKey(item) {
2
11
  return null != item.key && '' !== item.key.trim() ? item.key : item.text;
3
12
  }
4
- export { selectionKey };
13
+ export { isAvatarImage, selectionKey };
5
14
 
6
15
  //# sourceMappingURL=selection-item.jsx.map
@@ -1 +1 @@
1
- {"version":3,"file":"base/selection-item.jsx","sources":["../../src/base/selection-item.ts"],"sourcesContent":["import type { G9ImageSource } from '@g9tm/lynxcontrols-foundation';\nimport type { G9IconInput } from '../icon/icon';\n\n/**\n * One selectable item (MAUI `G9SelectionItem`), shared by the chip group (WP04), the selection sheet and the pickers\n * (WP05/WP06). Plain data: create it inline or map your own objects to it.\n */\nexport interface G9SelectionItem<TValue = unknown> {\n readonly text: string;\n /** Stable identity; when blank, `text` is the identity (MAUI `SelectionIdentity`). */\n readonly key?: string | null | undefined;\n readonly emoji?: string | null | undefined;\n readonly icon?: G9IconInput | undefined;\n readonly iconPath?: string | null | undefined;\n readonly iconImage?: G9ImageSource | null | undefined;\n readonly iconTintColor?: string | null | undefined;\n /** Colour swatch (one colour = circle, two = split circle). */\n readonly swatchFirstColor?: string | null | undefined;\n readonly swatchSecondColor?: string | null | undefined;\n /** App payload, never read by the controls. */\n readonly value?: TValue | undefined;\n /** Default true. */\n readonly isEnabled?: boolean | undefined;\n /** Selected fill override (wins over the group's). */\n readonly selectedColor?: string | null | undefined;\n readonly selectedTextColor?: string | null | undefined;\n}\n\n/** The identity of an item: `key` unless blank, else `text` (MAUI `G9SelectionItem.SelectionIdentity`). */\nexport function selectionKey(item: Pick<G9SelectionItem, 'key' | 'text'>): string {\n return item.key != null && item.key.trim() !== '' ? item.key : item.text;\n}\n"],"names":["selectionKey","item"],"mappings":"AA6BO,SAASA,aAAaC,IAA2C;IACtE,OAAOA,AAAY,QAAZA,KAAK,GAAG,IAAYA,AAAoB,OAApBA,KAAK,GAAG,CAAC,IAAI,KAAYA,KAAK,GAAG,GAAGA,KAAK,IAAI;AAC1E"}
1
+ {"version":3,"file":"base/selection-item.jsx","sources":["../../src/base/selection-item.ts"],"sourcesContent":["import { type G9ImageSource, isIconEmpty } from '@g9tm/lynxcontrols-foundation';\nimport type { G9IconInput } from '../icon/icon';\n\n/**\n * One selectable item (MAUI `G9SelectionItem`), shared by the chip group (WP04), the selection sheet and the pickers\n * (WP05/WP06). Plain data: create it inline or map your own objects to it.\n */\nexport interface G9SelectionItem<TValue = unknown> {\n readonly text: string;\n /** Stable identity; when blank, `text` is the identity (MAUI `SelectionIdentity`). */\n readonly key?: string | null | undefined;\n readonly emoji?: string | null | undefined;\n readonly icon?: G9IconInput | undefined;\n readonly iconPath?: string | null | undefined;\n readonly iconImage?: G9ImageSource | null | undefined;\n readonly iconTintColor?: string | null | undefined;\n /** Colour swatch (one colour = circle, two = split circle). */\n readonly swatchFirstColor?: string | null | undefined;\n readonly swatchSecondColor?: string | null | undefined;\n /** App payload, never read by the controls. */\n readonly value?: TValue | undefined;\n /** Default true. */\n readonly isEnabled?: boolean | undefined;\n /** Selected fill override (wins over the group's). */\n readonly selectedColor?: string | null | undefined;\n readonly selectedTextColor?: string | null | undefined;\n /**\n * The image (`iconPath` / `iconImage`) is a person's picture (MAUI 1.4.10 `IsAvatar`): drawn ROUND, at\n * `G9Metrics.SelectionAvatarSize` (28) in the selection sheet's rows and round at the icon size as a single combo-box\n * value; multi-select chips show the name only. Ignored for an emoji or a glyph.\n */\n readonly isAvatar?: boolean | undefined;\n}\n\n/** The item's icon is a person's picture: `isAvatar` on an image, not an emoji or a glyph (MAUI `IsAvatarImage`). */\nexport function isAvatarImage(item: G9SelectionItem): boolean {\n if (item.isAvatar !== true) return false;\n if (item.emoji != null && item.emoji.trim() !== '') return false;\n const icon = item.icon;\n const glyph =\n icon !== undefined && (typeof icon === 'string' ? icon.trim() !== '' && icon !== 'none' : !isIconEmpty(icon));\n if (glyph) return false;\n return (item.iconPath != null && item.iconPath.trim() !== '') || item.iconImage != null;\n}\n\n/** The identity of an item: `key` unless blank, else `text` (MAUI `G9SelectionItem.SelectionIdentity`). */\nexport function selectionKey(item: Pick<G9SelectionItem, 'key' | 'text'>): string {\n return item.key != null && item.key.trim() !== '' ? item.key : item.text;\n}\n"],"names":["isAvatarImage","item","icon","glyph","undefined","isIconEmpty","selectionKey"],"mappings":";AAmCO,SAASA,cAAcC,IAAqB;IACjD,IAAIA,AAAkB,SAAlBA,KAAK,QAAQ,EAAW,OAAO;IACnC,IAAIA,AAAc,QAAdA,KAAK,KAAK,IAAYA,AAAsB,OAAtBA,KAAK,KAAK,CAAC,IAAI,IAAW,OAAO;IAC3D,MAAMC,OAAOD,KAAK,IAAI;IACtB,MAAME,QACJD,AAASE,WAATF,QAAuB,CAAgB,YAAhB,OAAOA,OAAoBA,AAAgB,OAAhBA,KAAK,IAAI,MAAaA,AAAS,WAATA,OAAkB,CAACG,YAAYH,KAAI;IAC7G,IAAIC,OAAO,OAAO;IAClB,OAAQF,AAAiB,QAAjBA,KAAK,QAAQ,IAAYA,AAAyB,OAAzBA,KAAK,QAAQ,CAAC,IAAI,MAAcA,AAAkB,QAAlBA,KAAK,SAAS;AACjF;AAGO,SAASK,aAAaL,IAA2C;IACtE,OAAOA,AAAY,QAAZA,KAAK,GAAG,IAAYA,AAAoB,OAApBA,KAAK,GAAG,CAAC,IAAI,KAAYA,KAAK,GAAG,GAAGA,KAAK,IAAI;AAC1E"}
@@ -60,6 +60,26 @@
60
60
  top: 6px;
61
61
  }
62
62
 
63
+ .g9-header-action__count {
64
+ background-color: var(--g9-primary);
65
+ border-radius: 8px;
66
+ justify-content: center;
67
+ align-items: center;
68
+ min-width: 16px;
69
+ height: 16px;
70
+ padding: 0 4px;
71
+ display: flex;
72
+ position: absolute;
73
+ top: 2px;
74
+ }
75
+
76
+ .g9-header-action__count-text {
77
+ text-align: center;
78
+ color: var(--g9-on-primary);
79
+ font-size: 10px;
80
+ font-weight: bold;
81
+ }
82
+
63
83
  .g9-vertical-button {
64
84
  border-style: solid;
65
85
  border-width: 1px;
@@ -1 +1 @@
1
- {"version":3,"sources":["webpack://./src/button/button.css"],"names":[],"mappings":"AACA;EAAE,mBAAmB;EACnB,mBAAmB;EACnB,uBAAuB;EACvB,mBAAmB;EACnB,eAAe;EACf,aAAa;EACb,gBAAgB;AAClB;;AAGA;EAAE,mBAAmB;AACrB;;AAGA;EAAE,kBAAkB;AACpB;;AAGA;EAAE,uBAAuB;EACvB,mBAAmB;EACnB,aAAa;AACf;;AAGA;EAAE,kBAAkB;AACpB;;AAGA;EAAE,mBAAmB;EACnB,uBAAuB;EACvB,mBAAmB;EACnB,aAAa;AACf;;AAGA;EAAE,mBAAmB;EACnB,iBAAiB;EACjB,mCAAmC;EACnC,oDAAoD;EACpD,kBAAkB;EAClB,uBAAuB;EACvB,mBAAmB;EACnB,aAAa;EACb,kBAAkB;AACpB;;AAGA;EAAE,mCAAmC;EACnC,eAAe;EACf,iBAAiB;AACnB;;AAGA;EAAE,mCAAmC;EACnC,kBAAkB;EAClB,UAAU;EACV,WAAW;EACX,kBAAkB;EAClB,QAAQ;AACV;;AAGA;EAAE,mBAAmB;EACnB,iBAAiB;EACjB,iDAAiD;EACjD,6CAA6C;EAC7C,kBAAkB;EAClB,sBAAsB;EACtB,mBAAmB;EACnB,YAAY;EACZ,aAAa;AACf;;AAGA;EAAE,kBAAkB;EAClB,0BAA0B;AAC5B;;AAGA;EAAE,mBAAmB;EACnB,iBAAiB;EACjB,uCAAuC;EACvC,mBAAmB;EACnB,mBAAmB;EACnB,mBAAmB;EACnB,gBAAgB;EAChB,kBAAkB;EAClB,aAAa;AACf;;AAGA;EAAE,mBAAmB;EACnB,uBAAuB;EACvB,mBAAmB;EACnB,WAAW;EACX,YAAY;EACZ,aAAa;EACb,kBAAkB;AACpB;;AAGA;EAAE,sBAAsB;EACtB,OAAO;EACP,YAAY;EACZ,aAAa;AACf;;AAGA;EAAE,uBAAuB;EACvB,eAAe;EACf,iBAAiB;AACnB;;AAIA;EADE,mBAAmB;EACnB,eAAe;EACf,aAAa;AACf;;AAIA;EADE,cAAc;EACd,YAAY;AACd;;AAIA;EADE,cAAc;EACd,mBAAmB;EACnB,aAAa;AACf;;AAKA;EAFE,uBAAuB;EACvB,8BAA8B;EAC9B,iBAAiB;AACnB;;AAKA;EAFE,mBAAmB;EACnB,mBAAmB;EACnB,eAAe;EACf,aAAa;AACf;;AAKA;EAFE,eAAe;EACf,iBAAiB;AACnB;;AAKA;EAFE,2CAA2C;EAC3C,mBAAmB;EACnB,kBAAkB;AACpB;;AAKA;EAFE,sBAAsB;EACtB,eAAe;EACf,iBAAiB;AACnB","sourcesContent":["/* Buttons (MAUI G9Button, G9IconButton, G9HeaderActionButton, G9VerticalIconTextButton, G9NavCard). No shadows. */\n.g9-button {\n display: flex;\n flex-direction: row;\n align-items: center;\n justify-content: center;\n border-style: solid;\n overflow: hidden;\n column-gap: 8px;\n}\n\n.g9-button--fill {\n align-self: stretch;\n}\n\n.g9-button__label {\n text-align: center;\n}\n\n.g9-icon-button {\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.g9-icon-button__host {\n position: relative;\n}\n\n.g9-icon-button__frame {\n display: flex;\n align-items: center;\n justify-content: center;\n border-style: solid;\n}\n\n.g9-header-action {\n display: flex;\n position: relative;\n align-items: center;\n justify-content: center;\n border-style: solid;\n border-width: 1px;\n border-radius: 9px;\n border-color: var(--g9-card-border);\n background-color: var(--g9-surface-container-lowest);\n}\n\n.g9-header-action__text {\n font-size: 13px;\n font-weight: bold;\n color: var(--g9-on-surface-variant);\n}\n\n.g9-header-action__badge {\n position: absolute;\n top: 6px;\n width: 8px;\n height: 8px;\n border-radius: 4px;\n background-color: var(--g9-primary);\n}\n\n.g9-vertical-button {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 5px;\n border-style: solid;\n border-width: 1px;\n border-radius: 9px;\n border-color: var(--g9-surface-container-highest);\n background-color: var(--g9-surface-container);\n}\n\n.g9-vertical-button__text {\n text-align: center;\n color: var(--g9-secondary);\n}\n\n.g9-nav-card {\n display: flex;\n flex-direction: row;\n align-items: center;\n column-gap: 12px;\n padding: 12px 14px;\n border-style: solid;\n border-width: 1px;\n border-radius: 16px;\n border-color: var(--g9-outline-variant);\n}\n\n.g9-nav-card__tile {\n display: flex;\n position: relative;\n align-items: center;\n justify-content: center;\n width: 38px;\n height: 38px;\n border-radius: 12px;\n}\n\n.g9-nav-card__text {\n display: flex;\n flex-direction: column;\n flex: 1;\n row-gap: 2px;\n}\n\n.g9-nav-card__title {\n font-size: 14px;\n font-weight: bold;\n text-overflow: ellipsis;\n}\n\n/* Only while a titleAccessory is set: the title shrinks (and truncates), the accessory keeps its size. */\n.g9-nav-card__title-row {\n display: flex;\n align-items: center;\n column-gap: 8px;\n}\n\n.g9-nav-card__title-row .g9-nav-card__title {\n flex-shrink: 1;\n min-width: 0;\n}\n\n.g9-nav-card__title-accessory {\n display: flex;\n flex-shrink: 0;\n align-items: center;\n}\n\n/* One line with an ellipsis (MAUI MaxLines 1, TailTruncation): text-maxline alone let a long subtitle wrap. */\n.g9-nav-card__subtitle {\n text-overflow: ellipsis;\n font-size: 11.5px;\n color: var(--g9-text-tertiary);\n}\n\n.g9-nav-card__trailing {\n display: flex;\n flex-direction: row;\n align-items: center;\n column-gap: 8px;\n}\n\n.g9-nav-card__value {\n font-size: 13px;\n font-weight: bold;\n}\n\n.g9-nav-card__soon {\n padding: 3.5px 7px;\n border-radius: 11px;\n background-color: var(--g9-error-container);\n}\n\n.g9-nav-card__soon-text {\n font-size: 10px;\n font-weight: bold;\n color: var(--g9-error);\n}\n"],"sourceRoot":""}
1
+ {"version":3,"sources":["webpack://./src/button/button.css"],"names":[],"mappings":"AACA;EAAE,mBAAmB;EACnB,mBAAmB;EACnB,uBAAuB;EACvB,mBAAmB;EACnB,eAAe;EACf,aAAa;EACb,gBAAgB;AAClB;;AAGA;EAAE,mBAAmB;AACrB;;AAGA;EAAE,kBAAkB;AACpB;;AAGA;EAAE,uBAAuB;EACvB,mBAAmB;EACnB,aAAa;AACf;;AAGA;EAAE,kBAAkB;AACpB;;AAGA;EAAE,mBAAmB;EACnB,uBAAuB;EACvB,mBAAmB;EACnB,aAAa;AACf;;AAGA;EAAE,mBAAmB;EACnB,iBAAiB;EACjB,mCAAmC;EACnC,oDAAoD;EACpD,kBAAkB;EAClB,uBAAuB;EACvB,mBAAmB;EACnB,aAAa;EACb,kBAAkB;AACpB;;AAGA;EAAE,mCAAmC;EACnC,eAAe;EACf,iBAAiB;AACnB;;AAGA;EAAE,mCAAmC;EACnC,kBAAkB;EAClB,UAAU;EACV,WAAW;EACX,kBAAkB;EAClB,QAAQ;AACV;;AAIA;EADE,mCAAmC;EACnC,kBAAkB;EAClB,uBAAuB;EACvB,mBAAmB;EACnB,eAAe;EACf,YAAY;EACZ,cAAc;EACd,aAAa;EACb,kBAAkB;EAClB,QAAQ;AACV;;AAIA;EADE,kBAAkB;EAClB,2BAA2B;EAC3B,eAAe;EACf,iBAAiB;AACnB;;AAIA;EADE,mBAAmB;EACnB,iBAAiB;EACjB,iDAAiD;EACjD,6CAA6C;EAC7C,kBAAkB;EAClB,sBAAsB;EACtB,mBAAmB;EACnB,YAAY;EACZ,aAAa;AACf;;AAIA;EADE,kBAAkB;EAClB,0BAA0B;AAC5B;;AAIA;EADE,mBAAmB;EACnB,iBAAiB;EACjB,uCAAuC;EACvC,mBAAmB;EACnB,mBAAmB;EACnB,mBAAmB;EACnB,gBAAgB;EAChB,kBAAkB;EAClB,aAAa;AACf;;AAIA;EADE,mBAAmB;EACnB,uBAAuB;EACvB,mBAAmB;EACnB,WAAW;EACX,YAAY;EACZ,aAAa;EACb,kBAAkB;AACpB;;AAIA;EADE,sBAAsB;EACtB,OAAO;EACP,YAAY;EACZ,aAAa;AACf;;AAIA;EADE,uBAAuB;EACvB,eAAe;EACf,iBAAiB;AACnB;;AAKA;EAFE,mBAAmB;EACnB,eAAe;EACf,aAAa;AACf;;AAKA;EAFE,cAAc;EACd,YAAY;AACd;;AAKA;EAFE,cAAc;EACd,mBAAmB;EACnB,aAAa;AACf;;AAMA;EAHE,uBAAuB;EACvB,8BAA8B;EAC9B,iBAAiB;AACnB;;AAMA;EAHE,mBAAmB;EACnB,mBAAmB;EACnB,eAAe;EACf,aAAa;AACf;;AAMA;EAHE,eAAe;EACf,iBAAiB;AACnB;;AAMA;EAHE,2CAA2C;EAC3C,mBAAmB;EACnB,kBAAkB;AACpB;;AAMA;EAHE,sBAAsB;EACtB,eAAe;EACf,iBAAiB;AACnB","sourcesContent":["/* Buttons (MAUI G9Button, G9IconButton, G9HeaderActionButton, G9VerticalIconTextButton, G9NavCard). No shadows. */\n.g9-button {\n display: flex;\n flex-direction: row;\n align-items: center;\n justify-content: center;\n border-style: solid;\n overflow: hidden;\n column-gap: 8px;\n}\n\n.g9-button--fill {\n align-self: stretch;\n}\n\n.g9-button__label {\n text-align: center;\n}\n\n.g9-icon-button {\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.g9-icon-button__host {\n position: relative;\n}\n\n.g9-icon-button__frame {\n display: flex;\n align-items: center;\n justify-content: center;\n border-style: solid;\n}\n\n.g9-header-action {\n display: flex;\n position: relative;\n align-items: center;\n justify-content: center;\n border-style: solid;\n border-width: 1px;\n border-radius: 9px;\n border-color: var(--g9-card-border);\n background-color: var(--g9-surface-container-lowest);\n}\n\n.g9-header-action__text {\n font-size: 13px;\n font-weight: bold;\n color: var(--g9-on-surface-variant);\n}\n\n.g9-header-action__badge {\n position: absolute;\n top: 6px;\n width: 8px;\n height: 8px;\n border-radius: 4px;\n background-color: var(--g9-primary);\n}\n\n/* MAUI 1.4.9 CountBadge: a 16 px pill (min width 16, 4 px side padding, corner 8) over the top end corner, 2 px in. */\n.g9-header-action__count {\n position: absolute;\n top: 2px;\n display: flex;\n align-items: center;\n justify-content: center;\n min-width: 16px;\n height: 16px;\n padding: 0 4px;\n border-radius: 8px;\n background-color: var(--g9-primary);\n}\n\n.g9-header-action__count-text {\n font-size: 10px;\n font-weight: bold;\n text-align: center;\n color: var(--g9-on-primary);\n}\n\n.g9-vertical-button {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 5px;\n border-style: solid;\n border-width: 1px;\n border-radius: 9px;\n border-color: var(--g9-surface-container-highest);\n background-color: var(--g9-surface-container);\n}\n\n.g9-vertical-button__text {\n text-align: center;\n color: var(--g9-secondary);\n}\n\n.g9-nav-card {\n display: flex;\n flex-direction: row;\n align-items: center;\n column-gap: 12px;\n padding: 12px 14px;\n border-style: solid;\n border-width: 1px;\n border-radius: 16px;\n border-color: var(--g9-outline-variant);\n}\n\n.g9-nav-card__tile {\n display: flex;\n position: relative;\n align-items: center;\n justify-content: center;\n width: 38px;\n height: 38px;\n border-radius: 12px;\n}\n\n.g9-nav-card__text {\n display: flex;\n flex-direction: column;\n flex: 1;\n row-gap: 2px;\n}\n\n.g9-nav-card__title {\n font-size: 14px;\n font-weight: bold;\n text-overflow: ellipsis;\n}\n\n/* Only while a titleAccessory is set: the title shrinks (and truncates), the accessory keeps its size. */\n.g9-nav-card__title-row {\n display: flex;\n align-items: center;\n column-gap: 8px;\n}\n\n.g9-nav-card__title-row .g9-nav-card__title {\n flex-shrink: 1;\n min-width: 0;\n}\n\n.g9-nav-card__title-accessory {\n display: flex;\n flex-shrink: 0;\n align-items: center;\n}\n\n/* One line with an ellipsis (MAUI MaxLines 1, TailTruncation): text-maxline alone let a long subtitle wrap. */\n.g9-nav-card__subtitle {\n text-overflow: ellipsis;\n font-size: 11.5px;\n color: var(--g9-text-tertiary);\n}\n\n.g9-nav-card__trailing {\n display: flex;\n flex-direction: row;\n align-items: center;\n column-gap: 8px;\n}\n\n.g9-nav-card__value {\n font-size: 13px;\n font-weight: bold;\n}\n\n.g9-nav-card__soon {\n padding: 3.5px 7px;\n border-radius: 11px;\n background-color: var(--g9-error-container);\n}\n\n.g9-nav-card__soon-text {\n font-size: 10px;\n font-weight: bold;\n color: var(--g9-error);\n}\n"],"sourceRoot":""}
@@ -21,6 +21,11 @@ export interface G9HeaderActionButtonProps extends G9ControlBaseProps {
21
21
  readonly isActive?: boolean;
22
22
  /** The 8 px dot while active. Default true. */
23
23
  readonly showActiveBadge?: boolean;
24
+ /**
25
+ * A COUNT on the action (MAUI 1.4.9 `BadgeText`, AgriPad's «۲» active filters): a 16 px Primary pill with this text
26
+ * over the icon's top end corner, shown whenever it is set — the active dot gives way to it. Null / empty: the dot rules.
27
+ */
28
+ readonly badgeText?: string | null;
24
29
  /** Scale 0.92 (70 ms) → 1 (90 ms) on press. Default true. */
25
30
  readonly animatePress?: boolean;
26
31
  /** Default 24. */
@@ -1 +1 @@
1
- {"version":3,"file":"header-action-button.d.ts","sourceRoot":"","sources":["../../src/button/header-action-button.tsx"],"names":[],"mappings":"AAAA,OAAO,cAAc,CAAC;AACtB,OAAO,EAAwB,KAAK,aAAa,EAAa,MAAM,+BAA+B,CAAC;AACpG,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,KAAK,kBAAkB,EAAgB,MAAM,iBAAiB,CAAC;AAGxE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAIhD,oEAAoE;AACpE,eAAO,MAAM,iBAAiB,KAAK,CAAC;AACpC,gGAAgG;AAChG,eAAO,MAAM,mBAAmB,KAAK,CAAC;AAEtC,2EAA2E;AAC3E,MAAM,WAAW,yBAA0B,SAAQ,kBAAkB;IACnE,8EAA8E;IAC9E,QAAQ,CAAC,IAAI,CAAC,EAAE,WAAW,CAAC;IAC5B,uCAAuC;IACvC,QAAQ,CAAC,SAAS,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IAC1C,2CAA2C;IAC3C,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,sEAAsE;IACtE,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B,0CAA0C;IAC1C,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,+CAA+C;IAC/C,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;IACnC,6DAA6D;IAC7D,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC;IAChC,kBAAkB;IAClB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,mEAAmE;IACnE,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CAC/B;AAED,8GAA8G;AAC9G,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,yBAAyB,GAAG,SAAS,CA+ChF"}
1
+ {"version":3,"file":"header-action-button.d.ts","sourceRoot":"","sources":["../../src/button/header-action-button.tsx"],"names":[],"mappings":"AAAA,OAAO,cAAc,CAAC;AACtB,OAAO,EAAwB,KAAK,aAAa,EAAa,MAAM,+BAA+B,CAAC;AACpG,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,KAAK,kBAAkB,EAAgB,MAAM,iBAAiB,CAAC;AAGxE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAIhD,oEAAoE;AACpE,eAAO,MAAM,iBAAiB,KAAK,CAAC;AACpC,gGAAgG;AAChG,eAAO,MAAM,mBAAmB,KAAK,CAAC;AAEtC,2EAA2E;AAC3E,MAAM,WAAW,yBAA0B,SAAQ,kBAAkB;IACnE,8EAA8E;IAC9E,QAAQ,CAAC,IAAI,CAAC,EAAE,WAAW,CAAC;IAC5B,uCAAuC;IACvC,QAAQ,CAAC,SAAS,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IAC1C,2CAA2C;IAC3C,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,sEAAsE;IACtE,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B,0CAA0C;IAC1C,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,+CAA+C;IAC/C,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;IACnC;;;OAGG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,6DAA6D;IAC7D,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC;IAChC,kBAAkB;IAClB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,mEAAmE;IACnE,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CAC/B;AAED,8GAA8G;AAC9G,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,yBAAyB,GAAG,SAAS,CAwDhF"}
@@ -27,6 +27,7 @@ function G9HeaderActionButton(props) {
27
27
  outMs: 90
28
28
  }, control.disabled || busy || false === props.animatePress);
29
29
  const text1 = null != (_props_buttonText = props.buttonText) ? _props_buttonText : '';
30
+ const badge = null != props.badgeText && '' !== props.badgeText ? props.badgeText : null;
30
31
  let content;
31
32
  content = busy ? <G9ActivityIndicator running size={20} color="var(--g9-on-surface-variant)"/> : props.iconImage ? <G9IconSlot image={props.iconImage} size={iconSize}/> : '' !== text1.trim() ? <text className="g9-header-action__text">{text1}</text> : <G9IconSlot icon={null != (_props_icon = props.icon) ? _props_icon : G9Glyph.Menu} size={iconSize} color="var(--g9-on-surface-variant)"/>;
32
33
  return <view className={control.className} {...control.idProps} style={{
@@ -41,7 +42,11 @@ function G9HeaderActionButton(props) {
41
42
  'accessibility-label': null != (_props_accessibilityLabel1 = props.accessibilityLabel) ? _props_accessibilityLabel1 : text1
42
43
  } : {}} bindtap={press} {...visual}>
43
44
  {content}
44
- {active && false !== props.showActiveBadge ? <view className="g9-header-action__badge" style={{
45
+ {badge ? <view className="g9-header-action__count" user-interaction-enabled={false} style={{
46
+ ['rtl' === control.direction ? 'left' : 'right']: '2px'
47
+ }}>
48
+ <text className="g9-header-action__count-text">{badge}</text>
49
+ </view> : active && false !== props.showActiveBadge ? <view className="g9-header-action__badge" style={{
45
50
  ['rtl' === control.direction ? 'left' : 'right']: '6px'
46
51
  }}/> : null}
47
52
  </view>;
@@ -1 +1 @@
1
- {"version":3,"file":"button/header-action-button.jsx","sources":["../../src/button/header-action-button.tsx"],"sourcesContent":["import './button.css';\nimport { formatColor, G9Glyph, type G9ImageSource, withAlpha } from '@g9tm/lynxcontrols-foundation';\nimport type { ReactNode } from '@lynx-js/react';\nimport { type G9ControlBaseProps, useG9Control } from '../base/control';\nimport { useG9Press, usePressVisual } from '../base/press';\nimport { G9ActivityIndicator } from '../display/activity-indicator';\nimport type { G9IconInput } from '../icon/icon';\nimport { G9IconSlot } from '../icon/slot';\nimport { useG9Theme } from '../provider/hooks';\n\n/** MAUI `G9LayoutMetrics.ToolbarIconSize` / `ToolbarButtonSize`. */\nexport const g9ToolbarIconSize = 24;\n/** Touch box of a toolbar / header action button (MAUI `G9LayoutMetrics.ToolbarButtonSize`). */\nexport const g9ToolbarButtonSize = 42;\n\n/** Props of {@link G9HeaderActionButton} (MAUI `G9HeaderActionButton`). */\nexport interface G9HeaderActionButtonProps extends G9ControlBaseProps {\n /** Glyph shown when there is no image and no text. Default `G9Glyph.Menu`. */\n readonly icon?: G9IconInput;\n /** Image; wins over text and glyph. */\n readonly iconImage?: G9ImageSource | null;\n /** Bold 13 label (wins over the glyph). */\n readonly buttonText?: string | null;\n /** Spinner instead of the content; presses blocked. Default false. */\n readonly isBusy?: boolean;\n /** Tinted active state. Default false. */\n readonly isActive?: boolean;\n /** The 8 px dot while active. Default true. */\n readonly showActiveBadge?: boolean;\n /** Scale 0.92 (70 ms) → 1 (90 ms) on press. Default true. */\n readonly animatePress?: boolean;\n /** Default 24. */\n readonly iconSize?: number;\n /** Square size; ≤ 0 → 42 (MAUI `ToolbarButtonSize`). Default 0. */\n readonly buttonSize?: number;\n readonly onPress?: () => void;\n}\n\n/** Toolbar/header action (MAUI `G9HeaderActionButton`): bordered square with a glyph, image or short text. */\nexport function G9HeaderActionButton(props: G9HeaderActionButtonProps): ReactNode {\n const control = useG9Control(props, 'g9-header-action');\n const palette = useG9Theme().palette;\n const busy = props.isBusy === true;\n const active = props.isActive === true;\n const size = props.buttonSize && props.buttonSize > 0 ? props.buttonSize : g9ToolbarButtonSize;\n const iconSize = props.iconSize ?? g9ToolbarIconSize;\n const press = useG9Press(props.onPress, { blocked: control.disabled || busy, source: 'G9HeaderActionButton' });\n const visual = usePressVisual(\n { property: 'scale', rest: 1, pressed: 0.92, inMs: 70, outMs: 90 },\n control.disabled || busy || props.animatePress === false,\n );\n const text = props.buttonText ?? '';\n let content: ReactNode;\n if (busy) content = <G9ActivityIndicator running size={20} color=\"var(--g9-on-surface-variant)\" />;\n else if (props.iconImage) content = <G9IconSlot image={props.iconImage} size={iconSize} />;\n else if (text.trim() !== '') content = <text className=\"g9-header-action__text\">{text}</text>;\n else content = <G9IconSlot icon={props.icon ?? G9Glyph.Menu} size={iconSize} color=\"var(--g9-on-surface-variant)\" />;\n return (\n <view\n className={control.className}\n {...control.idProps}\n style={{\n width: `${size}px`,\n height: `${size}px`,\n opacity: control.disabled || busy ? 0.5 : 1,\n ...(active\n ? {\n backgroundColor: formatColor(withAlpha(palette.Primary, 0.12)),\n borderColor: formatColor(withAlpha(palette.Primary, 0.38)),\n }\n : {}),\n }}\n accessibility-element={true}\n accessibility-traits=\"button\"\n {...((props.accessibilityLabel ?? (text || undefined))\n ? { 'accessibility-label': props.accessibilityLabel ?? text }\n : {})}\n bindtap={press}\n {...visual}\n >\n {content}\n {active && props.showActiveBadge !== false ? (\n <view className=\"g9-header-action__badge\" style={{ [control.direction === 'rtl' ? 'left' : 'right']: '6px' }} />\n ) : null}\n </view>\n );\n}\n"],"names":["g9ToolbarIconSize","g9ToolbarButtonSize","G9HeaderActionButton","props","_props_iconSize","_props_buttonText","_props_icon","_props_accessibilityLabel","_props_accessibilityLabel1","control","useG9Control","palette","useG9Theme","busy","active","size","iconSize","press","useG9Press","visual","usePressVisual","text1","content","G9ActivityIndicator","G9IconSlot","text","G9Glyph","view","formatColor","withAlpha","undefined"],"mappings":";;;;;;;AAWO,MAAMA,oBAAoB;AAE1B,MAAMC,sBAAsB;AA0B5B,SAASC,qBAAqBC,KAAgC;QAMlDC,iBAMJC,mBAKoBC,aAkBvBC,2BACuBC;IAnCjC,MAAMC,UAAUC,aAAaP,OAAO;IACpC,MAAMQ,UAAUC,aAAa,OAAO;IACpC,MAAMC,OAAOV,AAAiB,SAAjBA,MAAM,MAAM;IACzB,MAAMW,SAASX,AAAmB,SAAnBA,MAAM,QAAQ;IAC7B,MAAMY,OAAOZ,MAAM,UAAU,IAAIA,MAAM,UAAU,GAAG,IAAIA,MAAM,UAAU,GAAGF;IAC3E,MAAMe,WAAW,QAAAZ,CAAAA,kBAAAA,MAAM,QAAQ,AAAD,IAAbA,kBAAkBJ;IACnC,MAAMiB,QAAQC,WAAWf,MAAM,OAAO,EAAE;QAAE,SAASM,QAAQ,QAAQ,IAAII;QAAM,QAAQ;IAAuB;IAC5G,MAAMM,SAASC,eACb;QAAE,UAAU;QAAS,MAAM;QAAG,SAAS;QAAM,MAAM;QAAI,OAAO;IAAG,GACjEX,QAAQ,QAAQ,IAAII,QAAQV,AAAuB,UAAvBA,MAAM,YAAY;IAEhD,MAAMkB,QAAAA,QAAOhB,CAAAA,oBAAAA,MAAM,UAAU,AAAD,IAAfA,oBAAoB;IACjC,IAAIiB;IACMA,UAANT,QAAiBU,oBAAoB,QAAQ,MAAM,IAAI,MAAM,mCACxDpB,MAAM,SAAS,IAAaqB,WAAW,OAAOrB,MAAM,SAAS,EAAE,MAAMa,cACrEK,AAAgB,OAAhBA,MAAK,IAAI,MAAsBI,KAAK,UAAU,0BAA0BJ,QAAOI,SACxED,WAAW,MAAM,QAAAlB,CAAAA,cAAAA,MAAM,IAAI,AAAD,IAATA,cAAcoB,QAAQ,IAAI,EAAE,MAAMV,UAAU,MAAM;IACnF,QACGW,KACC,WAAWlB,QAAQ,SAAS,GAC3B,GAAGA,QAAQ,OAAO,EACnB,OAAO;QACL,OAAO,GAAGM,KAAK,EAAE,CAAC;QAClB,QAAQ,GAAGA,KAAK,EAAE,CAAC;QACnB,SAASN,QAAQ,QAAQ,IAAII,OAAO,MAAM;QAC1C,GAAIC,SACA;YACE,iBAAiBc,YAAYC,UAAUlB,QAAQ,OAAO,EAAE;YACxD,aAAaiB,YAAYC,UAAUlB,QAAQ,OAAO,EAAE;QACtD,IACA,CAAC,CAAC;IACR,GACA,uBAAuB,MACvB,qBAAqB,UACpB,GAAI,AAAC,SAAAJ,CAAAA,4BAAAA,MAAM,kBAAkB,AAAD,IAAvBA,4BAA6Bc,SAAQS,MAAQ,IAC/C;QAAE,uBAAuB,QAAAtB,CAAAA,6BAAAA,MAAM,kBAAkB,AAAD,IAAvBA,6BAA4Ba;IAAK,IAC1D,CAAC,CAAC,EACN,SAASJ,QACR,GAAGE,MAAM,EACX;MACC,CAACG,QAAQ;MACT,CAACR,UAAUX,AAA0B,UAA1BA,MAAM,eAAe,IAC7BwB,KAAK,UAAU,0BAA0B,OAAO;QAAE,CAAClB,AAAsB,UAAtBA,QAAQ,SAAS,GAAa,SAAS,QAAQ,EAAE;IAAM,OACzG,KAAK;IACX,EAAEkB;AAEN"}
1
+ {"version":3,"file":"button/header-action-button.jsx","sources":["../../src/button/header-action-button.tsx"],"sourcesContent":["import './button.css';\nimport { formatColor, G9Glyph, type G9ImageSource, withAlpha } from '@g9tm/lynxcontrols-foundation';\nimport type { ReactNode } from '@lynx-js/react';\nimport { type G9ControlBaseProps, useG9Control } from '../base/control';\nimport { useG9Press, usePressVisual } from '../base/press';\nimport { G9ActivityIndicator } from '../display/activity-indicator';\nimport type { G9IconInput } from '../icon/icon';\nimport { G9IconSlot } from '../icon/slot';\nimport { useG9Theme } from '../provider/hooks';\n\n/** MAUI `G9LayoutMetrics.ToolbarIconSize` / `ToolbarButtonSize`. */\nexport const g9ToolbarIconSize = 24;\n/** Touch box of a toolbar / header action button (MAUI `G9LayoutMetrics.ToolbarButtonSize`). */\nexport const g9ToolbarButtonSize = 42;\n\n/** Props of {@link G9HeaderActionButton} (MAUI `G9HeaderActionButton`). */\nexport interface G9HeaderActionButtonProps extends G9ControlBaseProps {\n /** Glyph shown when there is no image and no text. Default `G9Glyph.Menu`. */\n readonly icon?: G9IconInput;\n /** Image; wins over text and glyph. */\n readonly iconImage?: G9ImageSource | null;\n /** Bold 13 label (wins over the glyph). */\n readonly buttonText?: string | null;\n /** Spinner instead of the content; presses blocked. Default false. */\n readonly isBusy?: boolean;\n /** Tinted active state. Default false. */\n readonly isActive?: boolean;\n /** The 8 px dot while active. Default true. */\n readonly showActiveBadge?: boolean;\n /**\n * A COUNT on the action (MAUI 1.4.9 `BadgeText`, AgriPad's «۲» active filters): a 16 px Primary pill with this text\n * over the icon's top end corner, shown whenever it is set — the active dot gives way to it. Null / empty: the dot rules.\n */\n readonly badgeText?: string | null;\n /** Scale 0.92 (70 ms) → 1 (90 ms) on press. Default true. */\n readonly animatePress?: boolean;\n /** Default 24. */\n readonly iconSize?: number;\n /** Square size; ≤ 0 → 42 (MAUI `ToolbarButtonSize`). Default 0. */\n readonly buttonSize?: number;\n readonly onPress?: () => void;\n}\n\n/** Toolbar/header action (MAUI `G9HeaderActionButton`): bordered square with a glyph, image or short text. */\nexport function G9HeaderActionButton(props: G9HeaderActionButtonProps): ReactNode {\n const control = useG9Control(props, 'g9-header-action');\n const palette = useG9Theme().palette;\n const busy = props.isBusy === true;\n const active = props.isActive === true;\n const size = props.buttonSize && props.buttonSize > 0 ? props.buttonSize : g9ToolbarButtonSize;\n const iconSize = props.iconSize ?? g9ToolbarIconSize;\n const press = useG9Press(props.onPress, { blocked: control.disabled || busy, source: 'G9HeaderActionButton' });\n const visual = usePressVisual(\n { property: 'scale', rest: 1, pressed: 0.92, inMs: 70, outMs: 90 },\n control.disabled || busy || props.animatePress === false,\n );\n const text = props.buttonText ?? '';\n const badge = props.badgeText != null && props.badgeText !== '' ? props.badgeText : null;\n let content: ReactNode;\n if (busy) content = <G9ActivityIndicator running size={20} color=\"var(--g9-on-surface-variant)\" />;\n else if (props.iconImage) content = <G9IconSlot image={props.iconImage} size={iconSize} />;\n else if (text.trim() !== '') content = <text className=\"g9-header-action__text\">{text}</text>;\n else content = <G9IconSlot icon={props.icon ?? G9Glyph.Menu} size={iconSize} color=\"var(--g9-on-surface-variant)\" />;\n return (\n <view\n className={control.className}\n {...control.idProps}\n style={{\n width: `${size}px`,\n height: `${size}px`,\n opacity: control.disabled || busy ? 0.5 : 1,\n ...(active\n ? {\n backgroundColor: formatColor(withAlpha(palette.Primary, 0.12)),\n borderColor: formatColor(withAlpha(palette.Primary, 0.38)),\n }\n : {}),\n }}\n accessibility-element={true}\n accessibility-traits=\"button\"\n {...((props.accessibilityLabel ?? (text || undefined))\n ? { 'accessibility-label': props.accessibilityLabel ?? text }\n : {})}\n bindtap={press}\n {...visual}\n >\n {content}\n {badge ? (\n <view\n className=\"g9-header-action__count\"\n user-interaction-enabled={false}\n style={{ [control.direction === 'rtl' ? 'left' : 'right']: '2px' }}\n >\n <text className=\"g9-header-action__count-text\">{badge}</text>\n </view>\n ) : active && props.showActiveBadge !== false ? (\n <view className=\"g9-header-action__badge\" style={{ [control.direction === 'rtl' ? 'left' : 'right']: '6px' }} />\n ) : null}\n </view>\n );\n}\n"],"names":["g9ToolbarIconSize","g9ToolbarButtonSize","G9HeaderActionButton","props","_props_iconSize","_props_buttonText","_props_icon","_props_accessibilityLabel","_props_accessibilityLabel1","control","useG9Control","palette","useG9Theme","busy","active","size","iconSize","press","useG9Press","visual","usePressVisual","text1","badge","content","G9ActivityIndicator","G9IconSlot","text","G9Glyph","view","formatColor","withAlpha","undefined"],"mappings":";;;;;;;AAWO,MAAMA,oBAAoB;AAE1B,MAAMC,sBAAsB;AA+B5B,SAASC,qBAAqBC,KAAgC;QAMlDC,iBAMJC,mBAMoBC,aAkBvBC,2BACuBC;IApCjC,MAAMC,UAAUC,aAAaP,OAAO;IACpC,MAAMQ,UAAUC,aAAa,OAAO;IACpC,MAAMC,OAAOV,AAAiB,SAAjBA,MAAM,MAAM;IACzB,MAAMW,SAASX,AAAmB,SAAnBA,MAAM,QAAQ;IAC7B,MAAMY,OAAOZ,MAAM,UAAU,IAAIA,MAAM,UAAU,GAAG,IAAIA,MAAM,UAAU,GAAGF;IAC3E,MAAMe,WAAW,QAAAZ,CAAAA,kBAAAA,MAAM,QAAQ,AAAD,IAAbA,kBAAkBJ;IACnC,MAAMiB,QAAQC,WAAWf,MAAM,OAAO,EAAE;QAAE,SAASM,QAAQ,QAAQ,IAAII;QAAM,QAAQ;IAAuB;IAC5G,MAAMM,SAASC,eACb;QAAE,UAAU;QAAS,MAAM;QAAG,SAAS;QAAM,MAAM;QAAI,OAAO;IAAG,GACjEX,QAAQ,QAAQ,IAAII,QAAQV,AAAuB,UAAvBA,MAAM,YAAY;IAEhD,MAAMkB,QAAAA,QAAOhB,CAAAA,oBAAAA,MAAM,UAAU,AAAD,IAAfA,oBAAoB;IACjC,MAAMiB,QAAQnB,AAAmB,QAAnBA,MAAM,SAAS,IAAYA,AAAoB,OAApBA,MAAM,SAAS,GAAUA,MAAM,SAAS,GAAG;IACpF,IAAIoB;IACMA,UAANV,QAAiBW,oBAAoB,QAAQ,MAAM,IAAI,MAAM,mCACxDrB,MAAM,SAAS,IAAasB,WAAW,OAAOtB,MAAM,SAAS,EAAE,MAAMa,cACrEK,AAAgB,OAAhBA,MAAK,IAAI,MAAsBK,KAAK,UAAU,0BAA0BL,QAAOK,SACxED,WAAW,MAAM,QAAAnB,CAAAA,cAAAA,MAAM,IAAI,AAAD,IAATA,cAAcqB,QAAQ,IAAI,EAAE,MAAMX,UAAU,MAAM;IACnF,QACGY,KACC,WAAWnB,QAAQ,SAAS,GAC3B,GAAGA,QAAQ,OAAO,EACnB,OAAO;QACL,OAAO,GAAGM,KAAK,EAAE,CAAC;QAClB,QAAQ,GAAGA,KAAK,EAAE,CAAC;QACnB,SAASN,QAAQ,QAAQ,IAAII,OAAO,MAAM;QAC1C,GAAIC,SACA;YACE,iBAAiBe,YAAYC,UAAUnB,QAAQ,OAAO,EAAE;YACxD,aAAakB,YAAYC,UAAUnB,QAAQ,OAAO,EAAE;QACtD,IACA,CAAC,CAAC;IACR,GACA,uBAAuB,MACvB,qBAAqB,UACpB,GAAI,AAAC,SAAAJ,CAAAA,4BAAAA,MAAM,kBAAkB,AAAD,IAAvBA,4BAA6Bc,SAAQU,MAAQ,IAC/C;QAAE,uBAAuB,QAAAvB,CAAAA,6BAAAA,MAAM,kBAAkB,AAAD,IAAvBA,6BAA4Ba;IAAK,IAC1D,CAAC,CAAC,EACN,SAASJ,QACR,GAAGE,MAAM,EACX;MACC,CAACI,QAAQ;MACT,CAACD,SACEM,KACC,UAAU,0BACV,0BAA0B,OAC1B,OAAO;QAAE,CAACnB,AAAsB,UAAtBA,QAAQ,SAAS,GAAa,SAAS,QAAQ,EAAE;IAAM,GAClE;UACC,CAACiB,KAAK,UAAU,gCAAgCJ,QAAQI,KAAK;QAC/D,EAAEE,QACAd,UAAUX,AAA0B,UAA1BA,MAAM,eAAe,IAChCyB,KAAK,UAAU,0BAA0B,OAAO;QAAE,CAACnB,AAAsB,UAAtBA,QAAQ,SAAS,GAAa,SAAS,QAAQ,EAAE;IAAM,OACzG,KAAK;IACX,EAAEmB;AAEN"}
@@ -1 +1 @@
1
- {"version":3,"file":"visuals.d.ts","sourceRoot":"","sources":["../../src/button/visuals.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,eAAe,EACpB,KAAK,aAAa,EAElB,KAAK,eAAe,EAKrB,MAAM,+BAA+B,CAAC;AAEvC,sHAAsH;AACtH,MAAM,WAAW,aAAa;IAC5B,0DAA0D;IAC1D,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,qEAAqE;IACrE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,4CAA4C;AAC5C,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC;IAClC,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC;IAClC,+BAA+B;IAC/B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACzD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC/C,8FAA8F;IAC9F,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAAC;CAClC;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,kBAAkB,GAAG,aAAa,CA4C3E;AAED,0DAA0D;AAC1D,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,mCAAmC;IACnC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;CACxB;AAED,6EAA6E;AAC7E,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,aAAa,GAAG,kBAAkB,CAmCxE;AAED,6BAA6B;AAC7B,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,YAAY,CAAC;AAEzE,wCAAwC;AACxC,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,gBAAgB,GAAG;IACjE,UAAU,EAAE,MAAM,GAAG,QAAQ,CAAC;IAC9B,SAAS,EAAE,QAAQ,GAAG,QAAQ,CAAC;CAChC,CAKA"}
1
+ {"version":3,"file":"visuals.d.ts","sourceRoot":"","sources":["../../src/button/visuals.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,eAAe,EACpB,KAAK,aAAa,EAElB,KAAK,eAAe,EAKrB,MAAM,+BAA+B,CAAC;AAEvC,sHAAsH;AACtH,MAAM,WAAW,aAAa;IAC5B,0DAA0D;IAC1D,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,qEAAqE;IACrE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,4CAA4C;AAC5C,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC;IAClC,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC;IAClC,+BAA+B;IAC/B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACzD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC/C,8FAA8F;IAC9F,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAAC;CAClC;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,kBAAkB,GAAG,aAAa,CA4C3E;AAED,0DAA0D;AAC1D,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,mCAAmC;IACnC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;CACxB;AAED,6EAA6E;AAC7E,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,aAAa,GAAG,kBAAkB,CAqCxE;AAED,6BAA6B;AAC7B,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,YAAY,CAAC;AAEzE,wCAAwC;AACxC,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,gBAAgB,GAAG;IACjE,UAAU,EAAE,MAAM,GAAG,QAAQ,CAAC;IAC9B,SAAS,EAAE,QAAQ,GAAG,QAAQ,CAAC;CAChC,CAKA"}
@@ -67,7 +67,7 @@ function buttonSizePreset(size) {
67
67
  return {
68
68
  height: G9Metrics.ButtonHeightHero,
69
69
  paddingHorizontal: 16,
70
- paddingVertical: 16,
70
+ paddingVertical: 12,
71
71
  fontSize: G9Metrics.ButtonFontHero,
72
72
  fill: true
73
73
  };
@@ -1 +1 @@
1
- {"version":3,"file":"button/visuals.jsx","sources":["../../src/button/visuals.ts"],"sourcesContent":["import {\n buildSolidOrGradient,\n createBorderColor,\n fillToCss,\n formatColor,\n type G9ButtonVariant,\n type G9ControlSize,\n G9Metrics,\n type G9PaletteValues,\n getContrastingTextColor,\n resolveButtonVariant,\n toRgba,\n tryParseColor,\n} from '@g9tm/lynxcontrols-foundation';\n\n/** What a button paints (MAUI `G9Visuals.ButtonVisualResult` + the stroke/opacity rules of G9Button/G9IconButton). */\nexport interface G9ButtonPaint {\n /** CSS `background` (a colour or a vertical gradient). */\n readonly background: string;\n readonly text: string;\n readonly stroke: string;\n readonly strokeWidth: number;\n /** 0.38 when not effectively enabled, 0.70 while loading, else 1. */\n readonly opacity: number;\n}\n\n/** Inputs of {@link resolveButtonPaint}. */\nexport interface G9ButtonPaintInput {\n readonly variant: G9ButtonVariant;\n readonly palette: G9PaletteValues;\n /** `IsEnabled && !blocked`. */\n readonly enabled: boolean;\n readonly loading: boolean;\n readonly baseBackgroundColor?: string | null | undefined;\n readonly textColor?: string | null | undefined;\n /** `'button'`: tonal has a 1.5 stroke; `'icon'`: only outline/text do (MAUI G9IconButton). */\n readonly kind: 'button' | 'icon';\n}\n\n/**\n * Resolves the paint of a button (MAUI `G9Button.OnApplyVisuals` / `G9IconButton.OnApplyVisuals`):\n * - variant colours from `resolveButtonVariant`; the gradient only while enabled and not loading;\n * - `baseBackgroundColor`: fully transparent → no fill, no border; otherwise a flat fill, contrasting text and a\n * darkened border (stroke 1 when visible);\n * - `textColor` always wins for text/icon/spinner;\n * - stroke 1.5 for outline/text (and tonal on `G9Button`), else 0.\n * A colour that is not a parseable literal (e.g. a `var(--…)` token) is used as given: flat fill, the variant's text\n * colour unless `textColor` is set, and no derived border.\n */\nexport function resolveButtonPaint(input: G9ButtonPaintInput): G9ButtonPaint {\n const variant = resolveButtonVariant(input.variant, input.palette);\n const opacity = !input.enabled ? 0.38 : input.loading ? 0.7 : 1;\n const base = input.baseBackgroundColor;\n if (base != null) {\n const parsed = tryParseColor(base);\n if (parsed && parsed.a === 0) {\n return {\n background: 'transparent',\n text: input.textColor ?? variant.text,\n stroke: 'transparent',\n strokeWidth: 0,\n opacity,\n };\n }\n if (!parsed) {\n return {\n background: base,\n text: input.textColor ?? variant.text,\n stroke: 'transparent',\n strokeWidth: 0,\n opacity,\n };\n }\n const stroke = createBorderColor(parsed);\n return {\n background: formatColor(parsed),\n text: input.textColor ?? formatColor(getContrastingTextColor(parsed)),\n stroke: formatColor(stroke),\n strokeWidth: toRgba(stroke).a > 0 ? 1 : 0,\n opacity,\n };\n }\n const outlined =\n input.variant === 'outline' || input.variant === 'text' || (input.kind === 'button' && input.variant === 'tonal');\n return {\n background: fillToCss(\n buildSolidOrGradient(variant.background, variant.usesGradient && input.enabled && !input.loading),\n ),\n text: input.textColor ?? variant.text,\n stroke: variant.stroke,\n strokeWidth: outlined ? 1.5 : 0,\n opacity,\n };\n}\n\n/** Size preset of `G9Button` (MAUI `ApplySizePreset`). */\nexport interface G9ButtonSizePreset {\n readonly height: number;\n readonly paddingHorizontal: number;\n readonly paddingVertical: number;\n readonly fontSize: number;\n /** Hero buttons fill the width. */\n readonly fill: boolean;\n}\n\n/** MAUI G9Button size presets: small 36 / medium 44 / large 48 / hero 52. */\nexport function buttonSizePreset(size: G9ControlSize): G9ButtonSizePreset {\n switch (size) {\n case 'small':\n return {\n height: G9Metrics.ButtonHeightSmall,\n paddingHorizontal: 12,\n paddingVertical: 8,\n fontSize: G9Metrics.ButtonFontSmall,\n fill: false,\n };\n case 'large':\n return {\n height: G9Metrics.ButtonHeightLarge,\n paddingHorizontal: 20,\n paddingVertical: 14,\n fontSize: G9Metrics.ButtonFontLarge,\n fill: false,\n };\n case 'hero':\n return {\n height: G9Metrics.ButtonHeightHero,\n paddingHorizontal: 16,\n paddingVertical: 16,\n fontSize: G9Metrics.ButtonFontHero,\n fill: true,\n };\n default:\n return {\n height: G9Metrics.ButtonHeightMedium,\n paddingHorizontal: 16,\n paddingVertical: 12,\n fontSize: G9Metrics.ButtonFontMedium,\n fill: false,\n };\n }\n}\n\n/** MAUI `FontAttributes`. */\nexport type G9FontAttributes = 'none' | 'bold' | 'italic' | 'boldItalic';\n\n/** CSS for {@link G9FontAttributes}. */\nexport function fontAttributesStyle(attributes: G9FontAttributes): {\n fontWeight: 'bold' | 'normal';\n fontStyle: 'italic' | 'normal';\n} {\n return {\n fontWeight: attributes === 'bold' || attributes === 'boldItalic' ? 'bold' : 'normal',\n fontStyle: attributes === 'italic' || attributes === 'boldItalic' ? 'italic' : 'normal',\n };\n}\n"],"names":["resolveButtonPaint","input","_input_textColor","variant","resolveButtonVariant","opacity","base","_input_textColor1","parsed","tryParseColor","_input_textColor2","_input_textColor3","stroke","createBorderColor","formatColor","getContrastingTextColor","toRgba","outlined","fillToCss","buildSolidOrGradient","buttonSizePreset","size","G9Metrics","fontAttributesStyle","attributes"],"mappings":";AAiDO,SAASA,mBAAmBC,KAAyB;QAuClDC;IAtCR,MAAMC,UAAUC,qBAAqBH,MAAM,OAAO,EAAEA,MAAM,OAAO;IACjE,MAAMI,UAAU,AAACJ,MAAM,OAAO,GAAUA,MAAM,OAAO,GAAG,MAAM,IAA7B;IACjC,MAAMK,OAAOL,MAAM,mBAAmB;IACtC,IAAIK,AAAQ,QAARA,MAAc;YAuBRC;QAtBR,MAAMC,SAASC,cAAcH;QAC7B,IAAIE,UAAUA,AAAa,MAAbA,OAAO,CAAC,EAAQ;gBAGpBE;YAFR,OAAO;gBACL,YAAY;gBACZ,MAAM,QAAAA,CAAAA,oBAAAA,MAAM,SAAS,AAAD,IAAdA,oBAAmBP,QAAQ,IAAI;gBACrC,QAAQ;gBACR,aAAa;gBACbE;YACF;QACF;QACA,IAAI,CAACG,QAAQ;gBAGHG;YAFR,OAAO;gBACL,YAAYL;gBACZ,MAAM,QAAAK,CAAAA,oBAAAA,MAAM,SAAS,AAAD,IAAdA,oBAAmBR,QAAQ,IAAI;gBACrC,QAAQ;gBACR,aAAa;gBACbE;YACF;QACF;QACA,MAAMO,SAASC,kBAAkBL;QACjC,OAAO;YACL,YAAYM,YAAYN;YACxB,MAAM,QAAAD,CAAAA,oBAAAA,MAAM,SAAS,AAAD,IAAdA,oBAAmBO,YAAYC,wBAAwBP;YAC7D,QAAQM,YAAYF;YACpB,aAAaI,OAAOJ,QAAQ,CAAC,GAAG,IAAI,IAAI;YACxCP;QACF;IACF;IACA,MAAMY,WACJhB,AAAkB,cAAlBA,MAAM,OAAO,IAAkBA,AAAkB,WAAlBA,MAAM,OAAO,IAAgBA,AAAe,aAAfA,MAAM,IAAI,IAAiBA,AAAkB,YAAlBA,MAAM,OAAO;IACtG,OAAO;QACL,YAAYiB,UACVC,qBAAqBhB,QAAQ,UAAU,EAAEA,QAAQ,YAAY,IAAIF,MAAM,OAAO,IAAI,CAACA,MAAM,OAAO;QAElG,MAAM,QAAAC,CAAAA,mBAAAA,MAAM,SAAS,AAAD,IAAdA,mBAAmBC,QAAQ,IAAI;QACrC,QAAQA,QAAQ,MAAM;QACtB,aAAac,WAAW,MAAM;QAC9BZ;IACF;AACF;AAaO,SAASe,iBAAiBC,IAAmB;IAClD,OAAQA;QACN,KAAK;YACH,OAAO;gBACL,QAAQC,UAAU,iBAAiB;gBACnC,mBAAmB;gBACnB,iBAAiB;gBACjB,UAAUA,UAAU,eAAe;gBACnC,MAAM;YACR;QACF,KAAK;YACH,OAAO;gBACL,QAAQA,UAAU,iBAAiB;gBACnC,mBAAmB;gBACnB,iBAAiB;gBACjB,UAAUA,UAAU,eAAe;gBACnC,MAAM;YACR;QACF,KAAK;YACH,OAAO;gBACL,QAAQA,UAAU,gBAAgB;gBAClC,mBAAmB;gBACnB,iBAAiB;gBACjB,UAAUA,UAAU,cAAc;gBAClC,MAAM;YACR;QACF;YACE,OAAO;gBACL,QAAQA,UAAU,kBAAkB;gBACpC,mBAAmB;gBACnB,iBAAiB;gBACjB,UAAUA,UAAU,gBAAgB;gBACpC,MAAM;YACR;IACJ;AACF;AAMO,SAASC,oBAAoBC,UAA4B;IAI9D,OAAO;QACL,YAAYA,AAAe,WAAfA,cAAyBA,AAAe,iBAAfA,aAA8B,SAAS;QAC5E,WAAWA,AAAe,aAAfA,cAA2BA,AAAe,iBAAfA,aAA8B,WAAW;IACjF;AACF"}
1
+ {"version":3,"file":"button/visuals.jsx","sources":["../../src/button/visuals.ts"],"sourcesContent":["import {\n buildSolidOrGradient,\n createBorderColor,\n fillToCss,\n formatColor,\n type G9ButtonVariant,\n type G9ControlSize,\n G9Metrics,\n type G9PaletteValues,\n getContrastingTextColor,\n resolveButtonVariant,\n toRgba,\n tryParseColor,\n} from '@g9tm/lynxcontrols-foundation';\n\n/** What a button paints (MAUI `G9Visuals.ButtonVisualResult` + the stroke/opacity rules of G9Button/G9IconButton). */\nexport interface G9ButtonPaint {\n /** CSS `background` (a colour or a vertical gradient). */\n readonly background: string;\n readonly text: string;\n readonly stroke: string;\n readonly strokeWidth: number;\n /** 0.38 when not effectively enabled, 0.70 while loading, else 1. */\n readonly opacity: number;\n}\n\n/** Inputs of {@link resolveButtonPaint}. */\nexport interface G9ButtonPaintInput {\n readonly variant: G9ButtonVariant;\n readonly palette: G9PaletteValues;\n /** `IsEnabled && !blocked`. */\n readonly enabled: boolean;\n readonly loading: boolean;\n readonly baseBackgroundColor?: string | null | undefined;\n readonly textColor?: string | null | undefined;\n /** `'button'`: tonal has a 1.5 stroke; `'icon'`: only outline/text do (MAUI G9IconButton). */\n readonly kind: 'button' | 'icon';\n}\n\n/**\n * Resolves the paint of a button (MAUI `G9Button.OnApplyVisuals` / `G9IconButton.OnApplyVisuals`):\n * - variant colours from `resolveButtonVariant`; the gradient only while enabled and not loading;\n * - `baseBackgroundColor`: fully transparent → no fill, no border; otherwise a flat fill, contrasting text and a\n * darkened border (stroke 1 when visible);\n * - `textColor` always wins for text/icon/spinner;\n * - stroke 1.5 for outline/text (and tonal on `G9Button`), else 0.\n * A colour that is not a parseable literal (e.g. a `var(--…)` token) is used as given: flat fill, the variant's text\n * colour unless `textColor` is set, and no derived border.\n */\nexport function resolveButtonPaint(input: G9ButtonPaintInput): G9ButtonPaint {\n const variant = resolveButtonVariant(input.variant, input.palette);\n const opacity = !input.enabled ? 0.38 : input.loading ? 0.7 : 1;\n const base = input.baseBackgroundColor;\n if (base != null) {\n const parsed = tryParseColor(base);\n if (parsed && parsed.a === 0) {\n return {\n background: 'transparent',\n text: input.textColor ?? variant.text,\n stroke: 'transparent',\n strokeWidth: 0,\n opacity,\n };\n }\n if (!parsed) {\n return {\n background: base,\n text: input.textColor ?? variant.text,\n stroke: 'transparent',\n strokeWidth: 0,\n opacity,\n };\n }\n const stroke = createBorderColor(parsed);\n return {\n background: formatColor(parsed),\n text: input.textColor ?? formatColor(getContrastingTextColor(parsed)),\n stroke: formatColor(stroke),\n strokeWidth: toRgba(stroke).a > 0 ? 1 : 0,\n opacity,\n };\n }\n const outlined =\n input.variant === 'outline' || input.variant === 'text' || (input.kind === 'button' && input.variant === 'tonal');\n return {\n background: fillToCss(\n buildSolidOrGradient(variant.background, variant.usesGradient && input.enabled && !input.loading),\n ),\n text: input.textColor ?? variant.text,\n stroke: variant.stroke,\n strokeWidth: outlined ? 1.5 : 0,\n opacity,\n };\n}\n\n/** Size preset of `G9Button` (MAUI `ApplySizePreset`). */\nexport interface G9ButtonSizePreset {\n readonly height: number;\n readonly paddingHorizontal: number;\n readonly paddingVertical: number;\n readonly fontSize: number;\n /** Hero buttons fill the width. */\n readonly fill: boolean;\n}\n\n/** MAUI G9Button size presets: small 36 / medium 44 / large 48 / hero 52. */\nexport function buttonSizePreset(size: G9ControlSize): G9ButtonSizePreset {\n switch (size) {\n case 'small':\n return {\n height: G9Metrics.ButtonHeightSmall,\n paddingHorizontal: 12,\n paddingVertical: 8,\n fontSize: G9Metrics.ButtonFontSmall,\n fill: false,\n };\n case 'large':\n return {\n height: G9Metrics.ButtonHeightLarge,\n paddingHorizontal: 20,\n paddingVertical: 14,\n fontSize: G9Metrics.ButtonFontLarge,\n fill: false,\n };\n case 'hero':\n // 52 tall with 12 above and below the text row, not 16 (MAUI 1.4.11): 16 left a 16 px label 20 px of height and cut\n // a Persian descender off («ج» of «خروج» on AgriPad's sign-out button, TR-0035).\n return {\n height: G9Metrics.ButtonHeightHero,\n paddingHorizontal: 16,\n paddingVertical: 12,\n fontSize: G9Metrics.ButtonFontHero,\n fill: true,\n };\n default:\n return {\n height: G9Metrics.ButtonHeightMedium,\n paddingHorizontal: 16,\n paddingVertical: 12,\n fontSize: G9Metrics.ButtonFontMedium,\n fill: false,\n };\n }\n}\n\n/** MAUI `FontAttributes`. */\nexport type G9FontAttributes = 'none' | 'bold' | 'italic' | 'boldItalic';\n\n/** CSS for {@link G9FontAttributes}. */\nexport function fontAttributesStyle(attributes: G9FontAttributes): {\n fontWeight: 'bold' | 'normal';\n fontStyle: 'italic' | 'normal';\n} {\n return {\n fontWeight: attributes === 'bold' || attributes === 'boldItalic' ? 'bold' : 'normal',\n fontStyle: attributes === 'italic' || attributes === 'boldItalic' ? 'italic' : 'normal',\n };\n}\n"],"names":["resolveButtonPaint","input","_input_textColor","variant","resolveButtonVariant","opacity","base","_input_textColor1","parsed","tryParseColor","_input_textColor2","_input_textColor3","stroke","createBorderColor","formatColor","getContrastingTextColor","toRgba","outlined","fillToCss","buildSolidOrGradient","buttonSizePreset","size","G9Metrics","fontAttributesStyle","attributes"],"mappings":";AAiDO,SAASA,mBAAmBC,KAAyB;QAuClDC;IAtCR,MAAMC,UAAUC,qBAAqBH,MAAM,OAAO,EAAEA,MAAM,OAAO;IACjE,MAAMI,UAAU,AAACJ,MAAM,OAAO,GAAUA,MAAM,OAAO,GAAG,MAAM,IAA7B;IACjC,MAAMK,OAAOL,MAAM,mBAAmB;IACtC,IAAIK,AAAQ,QAARA,MAAc;YAuBRC;QAtBR,MAAMC,SAASC,cAAcH;QAC7B,IAAIE,UAAUA,AAAa,MAAbA,OAAO,CAAC,EAAQ;gBAGpBE;YAFR,OAAO;gBACL,YAAY;gBACZ,MAAM,QAAAA,CAAAA,oBAAAA,MAAM,SAAS,AAAD,IAAdA,oBAAmBP,QAAQ,IAAI;gBACrC,QAAQ;gBACR,aAAa;gBACbE;YACF;QACF;QACA,IAAI,CAACG,QAAQ;gBAGHG;YAFR,OAAO;gBACL,YAAYL;gBACZ,MAAM,QAAAK,CAAAA,oBAAAA,MAAM,SAAS,AAAD,IAAdA,oBAAmBR,QAAQ,IAAI;gBACrC,QAAQ;gBACR,aAAa;gBACbE;YACF;QACF;QACA,MAAMO,SAASC,kBAAkBL;QACjC,OAAO;YACL,YAAYM,YAAYN;YACxB,MAAM,QAAAD,CAAAA,oBAAAA,MAAM,SAAS,AAAD,IAAdA,oBAAmBO,YAAYC,wBAAwBP;YAC7D,QAAQM,YAAYF;YACpB,aAAaI,OAAOJ,QAAQ,CAAC,GAAG,IAAI,IAAI;YACxCP;QACF;IACF;IACA,MAAMY,WACJhB,AAAkB,cAAlBA,MAAM,OAAO,IAAkBA,AAAkB,WAAlBA,MAAM,OAAO,IAAgBA,AAAe,aAAfA,MAAM,IAAI,IAAiBA,AAAkB,YAAlBA,MAAM,OAAO;IACtG,OAAO;QACL,YAAYiB,UACVC,qBAAqBhB,QAAQ,UAAU,EAAEA,QAAQ,YAAY,IAAIF,MAAM,OAAO,IAAI,CAACA,MAAM,OAAO;QAElG,MAAM,QAAAC,CAAAA,mBAAAA,MAAM,SAAS,AAAD,IAAdA,mBAAmBC,QAAQ,IAAI;QACrC,QAAQA,QAAQ,MAAM;QACtB,aAAac,WAAW,MAAM;QAC9BZ;IACF;AACF;AAaO,SAASe,iBAAiBC,IAAmB;IAClD,OAAQA;QACN,KAAK;YACH,OAAO;gBACL,QAAQC,UAAU,iBAAiB;gBACnC,mBAAmB;gBACnB,iBAAiB;gBACjB,UAAUA,UAAU,eAAe;gBACnC,MAAM;YACR;QACF,KAAK;YACH,OAAO;gBACL,QAAQA,UAAU,iBAAiB;gBACnC,mBAAmB;gBACnB,iBAAiB;gBACjB,UAAUA,UAAU,eAAe;gBACnC,MAAM;YACR;QACF,KAAK;YAGH,OAAO;gBACL,QAAQA,UAAU,gBAAgB;gBAClC,mBAAmB;gBACnB,iBAAiB;gBACjB,UAAUA,UAAU,cAAc;gBAClC,MAAM;YACR;QACF;YACE,OAAO;gBACL,QAAQA,UAAU,kBAAkB;gBACpC,mBAAmB;gBACnB,iBAAiB;gBACjB,UAAUA,UAAU,gBAAgB;gBACpC,MAAM;YACR;IACJ;AACF;AAMO,SAASC,oBAAoBC,UAA4B;IAI9D,OAAO;QACL,YAAYA,AAAe,WAAfA,cAAyBA,AAAe,iBAAfA,aAA8B,SAAS;QAC5E,WAAWA,AAAe,aAAfA,cAA2BA,AAAe,iBAAfA,aAA8B,WAAW;IACjF;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"cascade-panel.d.ts","sourceRoot":"","sources":["../../src/cascade/cascade-panel.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cascade-panel.d.ts","sourceRoot":"","sources":["../../src/cascade/cascade-panel.tsx"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import "./cascade.css";
2
- import { G9CascadeDirection, G9CascadeTransition, G9StringKey } from "@g9tm/lynxcontrols-foundation";
2
+ import { G9CascadeDirection, G9CascadeTransition, G9StringKey, g9Ms } from "@g9tm/lynxcontrols-foundation";
3
3
  import { useEffect, useRef, useState, useSyncExternalStore } from "@lynx-js/react";
4
4
  import { useG9Press } from "../base/press.jsx";
5
5
  import { startTimer, stopTimer } from "../base/timers.jsx";
@@ -98,7 +98,7 @@ function G9CascadePanel(props) {
98
98
  var _props_controller, _props_animationDurationMs, _props_transition, _ref, _props_rootContent, _props_cornerRadius, _props_rootTitle;
99
99
  const own = useCascadePanel();
100
100
  const controller = null != (_props_controller = props.controller) ? _props_controller : own;
101
- const duration = null != (_props_animationDurationMs = props.animationDurationMs) ? _props_animationDurationMs : g9CascadeAnimationMs;
101
+ const duration = g9Ms(null != (_props_animationDurationMs = props.animationDurationMs) ? _props_animationDurationMs : g9CascadeAnimationMs);
102
102
  controller.state.durationMs = duration;
103
103
  controller.state.onPushed = props.onPanelPushed;
104
104
  controller.state.onPopped = props.onPanelPopped;
@@ -1 +1 @@
1
- {"version":3,"file":"cascade/cascade-panel.jsx","sources":["../../src/cascade/cascade-panel.tsx"],"sourcesContent":["import './cascade.css';\nimport { G9CascadeDirection, G9CascadeTransition, G9StringKey } from '@g9tm/lynxcontrols-foundation';\nimport { type ReactNode, useEffect, useRef, useState, useSyncExternalStore } from '@lynx-js/react';\nimport { useG9Press } from '../base/press';\nimport { startTimer, stopTimer } from '../base/timers';\nimport { G9ActivityIndicator } from '../display/activity-indicator';\nimport { G9IconSlot } from '../icon/slot';\nimport { useG9Direction, useG9Settings, useG9Strings } from '../provider/hooks';\nimport { type G9CascadeContent, type G9CascadePanelEntry, type G9CascadePushOptions, G9CascadeStack } from './model';\n\n/** Slide duration (MAUI `G9Metrics.CascadePanelAnimationMs`). */\nexport const g9CascadeAnimationMs = 280;\n/** How far a covered panel parallaxes (share of the slide) and how much it dims, in `overlay` mode. */\nexport const g9CascadeParallax = Object.freeze({ shift: 0.3, dim: 0.12 });\n\n/** Imperative API of a cascade panel (MAUI `G9CascadePanel` methods), from {@link useCascadePanel}. */\nexport interface G9CascadeController {\n /** Push a built view, or a factory built after the slide (spinner meanwhile). Resolves when it slid in. */\n push(content: G9CascadeContent, options?: G9CascadePushOptions): Promise<boolean>;\n /** Pop the top panel (no-op at the root). Resolves when it slid out. */\n pop(): Promise<boolean>;\n /** Pop every panel back to the root (after a slide in flight). */\n popToRoot(): Promise<boolean>;\n /** Current nesting depth; 0 = only the root. */\n readonly depth: number;\n /** @internal the stack the panel renders */\n readonly stack: G9CascadeStack;\n}\n\ninterface ControllerState {\n durationMs: number;\n onPushed?: ((depth: number) => void) | undefined;\n onPopped?: ((depth: number) => void) | undefined;\n}\n\n/** Creates a cascade controller outside React (tests, view models). */\nexport function createCascadeController(): G9CascadeController & { readonly state: ControllerState } {\n const state: ControllerState = { durationMs: g9CascadeAnimationMs };\n const stack = new G9CascadeStack({\n setTimer: (cb, ms) => startTimer(cb, ms),\n clearTimer: (h) => stopTimer(h as never),\n durationMs: () => state.durationMs,\n onPushed: (d) => state.onPushed?.(d),\n onPopped: (d) => state.onPopped?.(d),\n });\n return {\n state,\n stack,\n push: (content, options) => stack.push(content, options),\n pop: () => stack.pop(),\n popToRoot: () => stack.popToRoot(),\n get depth() {\n return stack.depth;\n },\n };\n}\n\n/** A stable controller for a `G9CascadePanel` (pass it as `controller`). */\nexport function useCascadePanel(): G9CascadeController {\n const ref = useRef<G9CascadeController | null>(null);\n if (ref.current === null) ref.current = createCascadeController();\n return ref.current;\n}\n\n/** Props of {@link G9CascadePanel}. */\nexport interface G9CascadePanelProps {\n readonly controller?: G9CascadeController;\n /** The view at depth 0; swapping it replaces the root without touching the nested stack. */\n readonly rootContent?: ReactNode;\n /** Lazy root (used when `rootContent` is absent): spinner, then built one tick after mount. */\n readonly rootContentFactory?: (() => ReactNode) | null;\n readonly rootTitle?: string | null;\n /** Default entry direction; `'auto'` follows the reading direction (L→R in LTR, R→L in RTL). */\n readonly direction?: G9CascadeDirection;\n /** `'overlay'` (default) slides over a stationary base; `'push'` slides the base out. */\n readonly transition?: G9CascadeTransition;\n /** Fade the root in on first appearance. Default false. */\n readonly animateRoot?: boolean;\n /** Back + title header on nested panels. Default true. */\n readonly showHeader?: boolean;\n /** A (back-less) header on the root too. Default false. */\n readonly showRootHeader?: boolean;\n /** Default 280. */\n readonly animationDurationMs?: number;\n /** Overlay mode: the covered panel parallaxes and dims. Default true. */\n readonly enableParallax?: boolean;\n /** Default 16 (MAUI `RadiusLg`). */\n readonly cornerRadius?: number;\n /** After a panel slid in, with the new depth (MAUI `PanelPushed`). */\n readonly onPanelPushed?: (depth: number) => void;\n /** After a panel slid out, with the new depth (MAUI `PanelPopped`). */\n readonly onPanelPopped?: (depth: number) => void;\n readonly className?: string;\n}\n\ntype Physical = 'leftToRight' | 'rightToLeft' | 'topToBottom' | 'bottomToTop';\n\n/** Resolves `'auto'` to the reading direction. */\nexport function resolveCascadeDirection(direction: G9CascadeDirection | null | undefined, rtl: boolean): Physical {\n if (!direction || direction === G9CascadeDirection.Auto) return rtl ? 'rightToLeft' : 'leftToRight';\n return direction;\n}\n\n/** The transform of a panel `amount` (0…1) of the way off-screen against its entry direction. */\nexport function cascadeOffset(direction: Physical, amount: number): string {\n const pct = `${Math.round(amount * 1000) / 10}%`;\n const neg = `-${pct}`;\n switch (direction) {\n case 'leftToRight':\n return `translateX(${amount === 0 ? '0%' : neg})`;\n case 'rightToLeft':\n return `translateX(${pct})`;\n case 'topToBottom':\n return `translateY(${amount === 0 ? '0%' : neg})`;\n default:\n return `translateY(${pct})`;\n }\n}\n\nfunction Header(props: { readonly title: string | null; readonly onBack: (() => void) | null }): ReactNode {\n const rtl = useG9Direction() === 'rtl';\n const glyphs = useG9Settings().glyphs;\n const strings = useG9Strings();\n const back = useG9Press(() => props.onBack?.(), { source: 'G9CascadePanel', guardMs: 0 });\n return (\n <view className={`g9-cascade__header g9-dir-${rtl ? 'rtl' : 'ltr'}`}>\n {props.onBack ? (\n <view\n className=\"g9-cascade__back\"\n accessibility-element={true}\n accessibility-traits=\"button\"\n accessibility-label={strings.get(G9StringKey.Back)}\n bindtap={back}\n >\n <G9IconSlot icon={rtl ? glyphs.chevronForward : glyphs.chevronBack} size={24} color=\"var(--g9-on-surface)\" />\n </view>\n ) : null}\n <text className=\"g9-cascade__title\" text-maxline=\"1\">\n {props.title ?? ''}\n </text>\n </view>\n );\n}\n\nfunction Body(props: {\n readonly content: G9CascadeContent;\n readonly wrap: boolean;\n readonly ready: boolean;\n}): ReactNode {\n const lazy = typeof props.content === 'function';\n const node = lazy ? (props.ready ? (props.content as () => ReactNode)() : null) : (props.content as ReactNode);\n const inner =\n lazy && !props.ready ? (\n <view className=\"g9-cascade__loading\">\n <G9ActivityIndicator running size={32} />\n </view>\n ) : (\n node\n );\n return props.wrap ? (\n <scroll-view className=\"g9-cascade__body\" scroll-orientation=\"vertical\">\n {inner}\n </scroll-view>\n ) : (\n <view className=\"g9-cascade__body\">{inner}</view>\n );\n}\n\n/**\n * In-place drill-down navigation (MAUI `G9CascadePanel`): `controller.push(view, { title })` slides a panel in over\n * the current one from any edge, `pop()` slides it back; panels stack to any depth inside whatever container holds the\n * panel (clipped to its bounds, opaque `Surface` panels). `overlay` keeps the base still (parallax + dim with\n * `enableParallax`); `push` slides it out. Lazy panels show a spinner and build after the slide. One slide runs at a\n * time: same-kind repeats are dropped, the other kind waits (see `G9CascadeStack`).\n */\nexport function G9CascadePanel(props: G9CascadePanelProps): ReactNode {\n const own = useCascadePanel();\n const controller = (props.controller ?? own) as ReturnType<typeof createCascadeController>;\n const duration = props.animationDurationMs ?? g9CascadeAnimationMs;\n controller.state.durationMs = duration;\n controller.state.onPushed = props.onPanelPushed;\n controller.state.onPopped = props.onPanelPopped;\n const stack = controller.stack;\n const panels = useSyncExternalStore(\n (l) => stack.subscribe(l),\n () => stack.getSnapshot(),\n );\n const rtl = useG9Direction() === 'rtl';\n const overlay = (props.transition ?? G9CascadeTransition.Overlay) === G9CascadeTransition.Overlay;\n const parallax = props.enableParallax !== false;\n useEffect(() => () => stack.dispose(), [stack]);\n\n // Lazy root: built one tick after mount. Root fade: visible after the first frame.\n const [rootReady, setRootReady] = useState(false);\n const [rootShown, setRootShown] = useState(props.animateRoot !== true);\n useEffect(() => {\n const t = startTimer(() => {\n setRootReady(true);\n setRootShown(true);\n }, 16);\n return () => stopTimer(t);\n }, []);\n\n const topIndex = (id: number | 'root') => (id === 'root' ? 0 : panels.findIndex((p) => p.id === id) + 1);\n // The panel that covers a given level, if any, and how far it is in.\n const coverOf = (level: number): { entry: G9CascadePanelEntry; amount: number } | null => {\n const above = panels[level];\n if (!above) return null;\n const amount = above.status === 'entering' || above.status === 'shown' ? 1 : 0;\n return { entry: above, amount };\n };\n const style = (level: number, entry: G9CascadePanelEntry | null) => {\n const own = entry ? resolveCascadeDirection(entry.direction ?? props.direction, rtl) : null;\n // Own slide: off-screen while staged/leaving, in place otherwise.\n const out = entry && (entry.status === 'staged' || entry.status === 'leaving');\n let transform = own && out ? cascadeOffset(own, 1) : 'translateX(0%)';\n let dim = 0;\n const cover = coverOf(level);\n if (cover && !out) {\n const dir = resolveCascadeDirection(cover.entry.direction ?? props.direction, rtl);\n // A covered level moves the other way: by the parallax share (overlay) or all the way (push).\n const opposite: Record<Physical, Physical> = {\n leftToRight: 'rightToLeft',\n rightToLeft: 'leftToRight',\n topToBottom: 'bottomToTop',\n bottomToTop: 'topToBottom',\n };\n const amount = cover.amount * (overlay ? (parallax ? g9CascadeParallax.shift : 0) : 1);\n transform = cascadeOffset(opposite[dir], amount);\n dim = overlay && parallax ? cover.amount * g9CascadeParallax.dim : 0;\n }\n return {\n transform,\n transition: entry?.status === 'staged' ? 'none' : `transform ${duration}ms ease-out, opacity ${duration}ms`,\n zIndex: level,\n ...(dim > 0 ? { opacity: 1 - dim } : { opacity: level === 0 && !rootShown ? 0 : 1 }),\n };\n };\n\n const rootContent = props.rootContent ?? props.rootContentFactory ?? null;\n return (\n <view\n className={`g9-cascade${props.className ? ` ${props.className}` : ''}`}\n style={{ borderRadius: `${props.cornerRadius ?? 16}px` }}\n >\n <view className=\"g9-cascade__panel\" style={style(0, null)}>\n {props.showRootHeader ? <Header title={props.rootTitle ?? null} onBack={null} /> : null}\n <Body content={rootContent} wrap ready={rootReady} />\n </view>\n {panels.map((entry) => (\n <view\n key={entry.id}\n className={`g9-cascade__panel g9-cascade__panel--${entry.status}`}\n style={style(topIndex(entry.id), entry)}\n >\n {props.showHeader !== false ? <Header title={entry.title} onBack={() => void stack.pop()} /> : null}\n <Body\n content={entry.content}\n wrap={entry.wrap}\n ready={entry.status === 'shown' || entry.status === 'leaving'}\n />\n </view>\n ))}\n </view>\n );\n}\n"],"names":["g9CascadeAnimationMs","g9CascadeParallax","Object","createCascadeController","state","stack","G9CascadeStack","cb","ms","startTimer","h","stopTimer","d","content","options","useCascadePanel","ref","useRef","resolveCascadeDirection","direction","rtl","G9CascadeDirection","cascadeOffset","amount","pct","Math","neg","Header","props","_props_title","useG9Direction","glyphs","useG9Settings","strings","useG9Strings","back","useG9Press","view","G9StringKey","G9IconSlot","text","Body","lazy","node","inner","G9ActivityIndicator","scroll-view","G9CascadePanel","_props_controller","_props_animationDurationMs","_props_transition","_ref","_props_cornerRadius","_props_rootTitle","own","controller","duration","panels","useSyncExternalStore","l","overlay","G9CascadeTransition","parallax","useEffect","rootReady","setRootReady","useState","rootShown","setRootShown","t","topIndex","id","p","coverOf","level","above","style","entry","_entry_direction","out","transform","dim","cover","_cover_entry_direction","dir","opposite","rootContent"],"mappings":"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"}
1
+ {"version":3,"file":"cascade/cascade-panel.jsx","sources":["../../src/cascade/cascade-panel.tsx"],"sourcesContent":["import './cascade.css';\nimport { G9CascadeDirection, G9CascadeTransition, G9StringKey, g9Ms } from '@g9tm/lynxcontrols-foundation';\nimport { type ReactNode, useEffect, useRef, useState, useSyncExternalStore } from '@lynx-js/react';\nimport { useG9Press } from '../base/press';\nimport { startTimer, stopTimer } from '../base/timers';\nimport { G9ActivityIndicator } from '../display/activity-indicator';\nimport { G9IconSlot } from '../icon/slot';\nimport { useG9Direction, useG9Settings, useG9Strings } from '../provider/hooks';\nimport { type G9CascadeContent, type G9CascadePanelEntry, type G9CascadePushOptions, G9CascadeStack } from './model';\n\n/** Slide duration (MAUI `G9Metrics.CascadePanelAnimationMs`). */\nexport const g9CascadeAnimationMs = 280;\n/** How far a covered panel parallaxes (share of the slide) and how much it dims, in `overlay` mode. */\nexport const g9CascadeParallax = Object.freeze({ shift: 0.3, dim: 0.12 });\n\n/** Imperative API of a cascade panel (MAUI `G9CascadePanel` methods), from {@link useCascadePanel}. */\nexport interface G9CascadeController {\n /** Push a built view, or a factory built after the slide (spinner meanwhile). Resolves when it slid in. */\n push(content: G9CascadeContent, options?: G9CascadePushOptions): Promise<boolean>;\n /** Pop the top panel (no-op at the root). Resolves when it slid out. */\n pop(): Promise<boolean>;\n /** Pop every panel back to the root (after a slide in flight). */\n popToRoot(): Promise<boolean>;\n /** Current nesting depth; 0 = only the root. */\n readonly depth: number;\n /** @internal the stack the panel renders */\n readonly stack: G9CascadeStack;\n}\n\ninterface ControllerState {\n durationMs: number;\n onPushed?: ((depth: number) => void) | undefined;\n onPopped?: ((depth: number) => void) | undefined;\n}\n\n/** Creates a cascade controller outside React (tests, view models). */\nexport function createCascadeController(): G9CascadeController & { readonly state: ControllerState } {\n const state: ControllerState = { durationMs: g9CascadeAnimationMs };\n const stack = new G9CascadeStack({\n setTimer: (cb, ms) => startTimer(cb, ms),\n clearTimer: (h) => stopTimer(h as never),\n durationMs: () => state.durationMs,\n onPushed: (d) => state.onPushed?.(d),\n onPopped: (d) => state.onPopped?.(d),\n });\n return {\n state,\n stack,\n push: (content, options) => stack.push(content, options),\n pop: () => stack.pop(),\n popToRoot: () => stack.popToRoot(),\n get depth() {\n return stack.depth;\n },\n };\n}\n\n/** A stable controller for a `G9CascadePanel` (pass it as `controller`). */\nexport function useCascadePanel(): G9CascadeController {\n const ref = useRef<G9CascadeController | null>(null);\n if (ref.current === null) ref.current = createCascadeController();\n return ref.current;\n}\n\n/** Props of {@link G9CascadePanel}. */\nexport interface G9CascadePanelProps {\n readonly controller?: G9CascadeController;\n /** The view at depth 0; swapping it replaces the root without touching the nested stack. */\n readonly rootContent?: ReactNode;\n /** Lazy root (used when `rootContent` is absent): spinner, then built one tick after mount. */\n readonly rootContentFactory?: (() => ReactNode) | null;\n readonly rootTitle?: string | null;\n /** Default entry direction; `'auto'` follows the reading direction (L→R in LTR, R→L in RTL). */\n readonly direction?: G9CascadeDirection;\n /** `'overlay'` (default) slides over a stationary base; `'push'` slides the base out. */\n readonly transition?: G9CascadeTransition;\n /** Fade the root in on first appearance. Default false. */\n readonly animateRoot?: boolean;\n /** Back + title header on nested panels. Default true. */\n readonly showHeader?: boolean;\n /** A (back-less) header on the root too. Default false. */\n readonly showRootHeader?: boolean;\n /** Default 280. */\n readonly animationDurationMs?: number;\n /** Overlay mode: the covered panel parallaxes and dims. Default true. */\n readonly enableParallax?: boolean;\n /** Default 16 (MAUI `RadiusLg`). */\n readonly cornerRadius?: number;\n /** After a panel slid in, with the new depth (MAUI `PanelPushed`). */\n readonly onPanelPushed?: (depth: number) => void;\n /** After a panel slid out, with the new depth (MAUI `PanelPopped`). */\n readonly onPanelPopped?: (depth: number) => void;\n readonly className?: string;\n}\n\ntype Physical = 'leftToRight' | 'rightToLeft' | 'topToBottom' | 'bottomToTop';\n\n/** Resolves `'auto'` to the reading direction. */\nexport function resolveCascadeDirection(direction: G9CascadeDirection | null | undefined, rtl: boolean): Physical {\n if (!direction || direction === G9CascadeDirection.Auto) return rtl ? 'rightToLeft' : 'leftToRight';\n return direction;\n}\n\n/** The transform of a panel `amount` (0…1) of the way off-screen against its entry direction. */\nexport function cascadeOffset(direction: Physical, amount: number): string {\n const pct = `${Math.round(amount * 1000) / 10}%`;\n const neg = `-${pct}`;\n switch (direction) {\n case 'leftToRight':\n return `translateX(${amount === 0 ? '0%' : neg})`;\n case 'rightToLeft':\n return `translateX(${pct})`;\n case 'topToBottom':\n return `translateY(${amount === 0 ? '0%' : neg})`;\n default:\n return `translateY(${pct})`;\n }\n}\n\nfunction Header(props: { readonly title: string | null; readonly onBack: (() => void) | null }): ReactNode {\n const rtl = useG9Direction() === 'rtl';\n const glyphs = useG9Settings().glyphs;\n const strings = useG9Strings();\n const back = useG9Press(() => props.onBack?.(), { source: 'G9CascadePanel', guardMs: 0 });\n return (\n <view className={`g9-cascade__header g9-dir-${rtl ? 'rtl' : 'ltr'}`}>\n {props.onBack ? (\n <view\n className=\"g9-cascade__back\"\n accessibility-element={true}\n accessibility-traits=\"button\"\n accessibility-label={strings.get(G9StringKey.Back)}\n bindtap={back}\n >\n <G9IconSlot icon={rtl ? glyphs.chevronForward : glyphs.chevronBack} size={24} color=\"var(--g9-on-surface)\" />\n </view>\n ) : null}\n <text className=\"g9-cascade__title\" text-maxline=\"1\">\n {props.title ?? ''}\n </text>\n </view>\n );\n}\n\nfunction Body(props: {\n readonly content: G9CascadeContent;\n readonly wrap: boolean;\n readonly ready: boolean;\n}): ReactNode {\n const lazy = typeof props.content === 'function';\n const node = lazy ? (props.ready ? (props.content as () => ReactNode)() : null) : (props.content as ReactNode);\n const inner =\n lazy && !props.ready ? (\n <view className=\"g9-cascade__loading\">\n <G9ActivityIndicator running size={32} />\n </view>\n ) : (\n node\n );\n return props.wrap ? (\n <scroll-view className=\"g9-cascade__body\" scroll-orientation=\"vertical\">\n {inner}\n </scroll-view>\n ) : (\n <view className=\"g9-cascade__body\">{inner}</view>\n );\n}\n\n/**\n * In-place drill-down navigation (MAUI `G9CascadePanel`): `controller.push(view, { title })` slides a panel in over\n * the current one from any edge, `pop()` slides it back; panels stack to any depth inside whatever container holds the\n * panel (clipped to its bounds, opaque `Surface` panels). `overlay` keeps the base still (parallax + dim with\n * `enableParallax`); `push` slides it out. Lazy panels show a spinner and build after the slide. One slide runs at a\n * time: same-kind repeats are dropped, the other kind waits (see `G9CascadeStack`).\n */\nexport function G9CascadePanel(props: G9CascadePanelProps): ReactNode {\n const own = useCascadePanel();\n const controller = (props.controller ?? own) as ReturnType<typeof createCascadeController>;\n const duration = g9Ms(props.animationDurationMs ?? g9CascadeAnimationMs);\n controller.state.durationMs = duration;\n controller.state.onPushed = props.onPanelPushed;\n controller.state.onPopped = props.onPanelPopped;\n const stack = controller.stack;\n const panels = useSyncExternalStore(\n (l) => stack.subscribe(l),\n () => stack.getSnapshot(),\n );\n const rtl = useG9Direction() === 'rtl';\n const overlay = (props.transition ?? G9CascadeTransition.Overlay) === G9CascadeTransition.Overlay;\n const parallax = props.enableParallax !== false;\n useEffect(() => () => stack.dispose(), [stack]);\n\n // Lazy root: built one tick after mount. Root fade: visible after the first frame.\n const [rootReady, setRootReady] = useState(false);\n const [rootShown, setRootShown] = useState(props.animateRoot !== true);\n useEffect(() => {\n const t = startTimer(() => {\n setRootReady(true);\n setRootShown(true);\n }, 16);\n return () => stopTimer(t);\n }, []);\n\n const topIndex = (id: number | 'root') => (id === 'root' ? 0 : panels.findIndex((p) => p.id === id) + 1);\n // The panel that covers a given level, if any, and how far it is in.\n const coverOf = (level: number): { entry: G9CascadePanelEntry; amount: number } | null => {\n const above = panels[level];\n if (!above) return null;\n const amount = above.status === 'entering' || above.status === 'shown' ? 1 : 0;\n return { entry: above, amount };\n };\n const style = (level: number, entry: G9CascadePanelEntry | null) => {\n const own = entry ? resolveCascadeDirection(entry.direction ?? props.direction, rtl) : null;\n // Own slide: off-screen while staged/leaving, in place otherwise.\n const out = entry && (entry.status === 'staged' || entry.status === 'leaving');\n let transform = own && out ? cascadeOffset(own, 1) : 'translateX(0%)';\n let dim = 0;\n const cover = coverOf(level);\n if (cover && !out) {\n const dir = resolveCascadeDirection(cover.entry.direction ?? props.direction, rtl);\n // A covered level moves the other way: by the parallax share (overlay) or all the way (push).\n const opposite: Record<Physical, Physical> = {\n leftToRight: 'rightToLeft',\n rightToLeft: 'leftToRight',\n topToBottom: 'bottomToTop',\n bottomToTop: 'topToBottom',\n };\n const amount = cover.amount * (overlay ? (parallax ? g9CascadeParallax.shift : 0) : 1);\n transform = cascadeOffset(opposite[dir], amount);\n dim = overlay && parallax ? cover.amount * g9CascadeParallax.dim : 0;\n }\n return {\n transform,\n transition: entry?.status === 'staged' ? 'none' : `transform ${duration}ms ease-out, opacity ${duration}ms`,\n zIndex: level,\n ...(dim > 0 ? { opacity: 1 - dim } : { opacity: level === 0 && !rootShown ? 0 : 1 }),\n };\n };\n\n const rootContent = props.rootContent ?? props.rootContentFactory ?? null;\n return (\n <view\n className={`g9-cascade${props.className ? ` ${props.className}` : ''}`}\n style={{ borderRadius: `${props.cornerRadius ?? 16}px` }}\n >\n <view className=\"g9-cascade__panel\" style={style(0, null)}>\n {props.showRootHeader ? <Header title={props.rootTitle ?? null} onBack={null} /> : null}\n <Body content={rootContent} wrap ready={rootReady} />\n </view>\n {panels.map((entry) => (\n <view\n key={entry.id}\n className={`g9-cascade__panel g9-cascade__panel--${entry.status}`}\n style={style(topIndex(entry.id), entry)}\n >\n {props.showHeader !== false ? <Header title={entry.title} onBack={() => void stack.pop()} /> : null}\n <Body\n content={entry.content}\n wrap={entry.wrap}\n ready={entry.status === 'shown' || entry.status === 'leaving'}\n />\n </view>\n ))}\n </view>\n );\n}\n"],"names":["g9CascadeAnimationMs","g9CascadeParallax","Object","createCascadeController","state","stack","G9CascadeStack","cb","ms","startTimer","h","stopTimer","d","content","options","useCascadePanel","ref","useRef","resolveCascadeDirection","direction","rtl","G9CascadeDirection","cascadeOffset","amount","pct","Math","neg","Header","props","_props_title","useG9Direction","glyphs","useG9Settings","strings","useG9Strings","back","useG9Press","view","G9StringKey","G9IconSlot","text","Body","lazy","node","inner","G9ActivityIndicator","scroll-view","G9CascadePanel","_props_controller","_props_animationDurationMs","_props_transition","_ref","_props_cornerRadius","_props_rootTitle","own","controller","duration","g9Ms","panels","useSyncExternalStore","l","overlay","G9CascadeTransition","parallax","useEffect","rootReady","setRootReady","useState","rootShown","setRootShown","t","topIndex","id","p","coverOf","level","above","style","entry","_entry_direction","out","transform","dim","cover","_cover_entry_direction","dir","opposite","rootContent"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import "./edge-panel.css";
2
- import { G9StringKey } from "@g9tm/lynxcontrols-foundation";
2
+ import { G9StringKey, g9Ms } from "@g9tm/lynxcontrols-foundation";
3
3
  import { useEffect, useMemo, useRef, useState } from "@lynx-js/react";
4
4
  import { g9RowStyle, g9TextStart } from "../base/control.jsx";
5
5
  import { startTimer, stopTimer } from "../base/timers.jsx";
@@ -68,8 +68,8 @@ function G9EdgePanel(props) {
68
68
  onChange: props.onOpenChange,
69
69
  name: 'G9EdgePanel.open'
70
70
  });
71
- const openMs = null != (_ref = null != (_props_openAnimationDuration = props.openAnimationDuration) ? _props_openAnimationDuration : props.animationDuration) ? _ref : g9EdgePanelMetrics.defaultOpenAnimationDurationMs;
72
- const closeMs = null != (_ref1 = null != (_props_closeAnimationDuration = props.closeAnimationDuration) ? _props_closeAnimationDuration : props.animationDuration) ? _ref1 : g9EdgePanelMetrics.defaultCloseAnimationDurationMs;
71
+ const openMs = g9Ms(null != (_ref = null != (_props_openAnimationDuration = props.openAnimationDuration) ? _props_openAnimationDuration : props.animationDuration) ? _ref : g9EdgePanelMetrics.defaultOpenAnimationDurationMs);
72
+ const closeMs = g9Ms(null != (_ref1 = null != (_props_closeAnimationDuration = props.closeAnimationDuration) ? _props_closeAnimationDuration : props.animationDuration) ? _ref1 : g9EdgePanelMetrics.defaultCloseAnimationDurationMs);
73
73
  const [phase, setPhase] = useState(isOpen ? 'entering' : 'closed');
74
74
  const latest = useRef(props);
75
75
  latest.current = props;
@@ -201,7 +201,7 @@ function EdgePanelOverlay(o) {
201
201
  {cardRendered ? <view className={`g9-edge-panel__close g9-edge-panel__close--${placement}`} style={{
202
202
  ...closeStyle,
203
203
  opacity: shown ? 1 : 0,
204
- transition: `opacity ${g9EdgePanelMetrics.tabEntranceDurationMs}ms ease-out`,
204
+ transition: `opacity ${g9Ms(g9EdgePanelMetrics.tabEntranceDurationMs)}ms ease-out`,
205
205
  backgroundColor: null != (_p_tabBackgroundColor = p.tabBackgroundColor) ? _p_tabBackgroundColor : 'var(--g9-surface-container-highest)'
206
206
  }} accessibility-element accessibility-traits="button" bindtap={o.onTab}>
207
207
  <G9IconSlot icon={glyphs.clear} size={g9EdgePanelMetrics.tabIconSize} color="var(--g9-on-surface)"/>
@@ -274,7 +274,7 @@ function PanelBody(props) {
274
274
  const content = null != p.panelContent ? p.panelContent : frame ? <view key={`level-${version}`} className="g9-edge-panel__menu" style={{
275
275
  transform: `translateX(${entered ? 0 : 24 * sign}px)`,
276
276
  opacity: entered ? 1 : 0,
277
- transition: entered ? `transform ${g9EdgePanelMetrics.menuTransitionDurationMs}ms ease-out, opacity ${g9EdgePanelMetrics.menuTransitionDurationMs}ms ease-out` : 'none'
277
+ transition: entered ? `transform ${g9Ms(g9EdgePanelMetrics.menuTransitionDurationMs)}ms ease-out, opacity ${g9Ms(g9EdgePanelMetrics.menuTransitionDurationMs)}ms ease-out` : 'none'
278
278
  }}>
279
279
  {nav.isRoot ? null : <view className="g9-edge-panel__back" style={g9RowStyle(contentRtl ? 'rtl' : 'ltr')} accessibility-element accessibility-traits="button" bindtap={()=>{
280
280
  nav.back();