@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
@@ -33,6 +33,17 @@ export interface G9RangeSliderProps {
33
33
  readonly showLabels?: boolean;
34
34
  /** .NET-style number format of labels and tooltip (`"0"`, `"0.0"`, `"0°"`). Default `"0"`. */
35
35
  readonly valueFormat?: string | null;
36
+ /**
37
+ * A LOGARITHMIC track (MAUI 1.4.9): equal distances are equal ratios, so a range over orders of magnitude (site areas
38
+ * 787 to 56,475 ha, AgriPad's site filter) is usable at both ends. Needs `minimum > 0` (else linear); the value then
39
+ * snaps to two significant figures instead of `step`. Default false.
40
+ */
41
+ readonly logarithmic?: boolean;
42
+ /**
43
+ * Each thumb's value drawn ABOVE it at all times, following it (MAUI 1.4.9, the design's «مساحت (هکتار)» readout); the
44
+ * min / max edge labels and the drag tooltip are then not drawn. Needs `showLabels` (it uses their room). Default false.
45
+ */
46
+ readonly showThumbValues?: boolean;
36
47
  readonly disabled?: boolean;
37
48
  /** After the user changed a value: the single value, or the range end (MAUI `ValueChanged`). */
38
49
  readonly onValueChanged?: (value: number) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"range-slider.d.ts","sourceRoot":"","sources":["../../src/range-slider/range-slider.tsx"],"names":[],"mappings":"AAAA,OAAO,oBAAoB,CAAC;AAC5B,OAAO,EAAe,iBAAiB,EAAW,MAAM,+BAA+B,CAAC;AAExF,OAAO,EAAE,KAAK,SAAS,EAAoB,MAAM,gBAAgB,CAAC;AAYlE,gDAAgD;AAChD,eAAO,MAAM,eAAe;;;;;;EAM1B,CAAC;AAEH,sCAAsC;AACtC,MAAM,WAAW,kBAAkB;IACjC,iBAAiB;IACjB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,mBAAmB;IACnB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,6GAA6G;IAC7G,QAAQ,CAAC,IAAI,CAAC,EAAE,iBAAiB,CAAC;IAClC,wCAAwC;IACxC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,wDAAwD;IACxD,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9D,gDAAgD;IAChD,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,sFAAsF;IACtF,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAC9B,8FAA8F;IAC9F,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,gGAAgG;IAChG,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClD,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IACrC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,iGAAiG;AACjG,wBAAgB,aAAa,CAC3B,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,OAAO,GACX,MAAM,GAAG,IAAI,CAUf;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,SAAS,CAqHlE"}
1
+ {"version":3,"file":"range-slider.d.ts","sourceRoot":"","sources":["../../src/range-slider/range-slider.tsx"],"names":[],"mappings":"AAAA,OAAO,oBAAoB,CAAC;AAC5B,OAAO,EAAe,iBAAiB,EAAW,MAAM,+BAA+B,CAAC;AAExF,OAAO,EAAE,KAAK,SAAS,EAAoB,MAAM,gBAAgB,CAAC;AAclE,gDAAgD;AAChD,eAAO,MAAM,eAAe;;;;;;EAM1B,CAAC;AAEH,sCAAsC;AACtC,MAAM,WAAW,kBAAkB;IACjC,iBAAiB;IACjB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,mBAAmB;IACnB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,6GAA6G;IAC7G,QAAQ,CAAC,IAAI,CAAC,EAAE,iBAAiB,CAAC;IAClC,wCAAwC;IACxC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,wDAAwD;IACxD,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9D,gDAAgD;IAChD,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,sFAAsF;IACtF,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAC9B,8FAA8F;IAC9F,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC;;;;OAIG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B;;;OAGG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;IACnC,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,gGAAgG;IAChG,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClD,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IACrC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,iGAAiG;AACjG,wBAAgB,aAAa,CAC3B,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,OAAO,GACX,MAAM,GAAG,IAAI,CAUf;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,SAAS,CAoIlE"}
@@ -4,7 +4,7 @@ import { SliderIndicator, SliderRoot, SliderThumb, SliderTrack } from "@lynx-js/
4
4
  import { useRef, useState } from "@lynx-js/react";
5
5
  import { useControllableState } from "../base/use-controllable-state.jsx";
6
6
  import { useG9Culture, useG9Direction, useG9Theme } from "../provider/hooks.jsx";
7
- import { coerceSliderRange, formatSliderValue, sliderBounds, sliderRatio, sliderValueAt, snapSliderValue } from "./math.jsx";
7
+ import { coerceSliderRange, formatSliderValue, isLogTrack, sliderBounds, sliderRatio, sliderValueAt, snapLogValue, snapSliderValue } from "./math.jsx";
8
8
  const g9SliderMetrics = Object.freeze({
9
9
  height: 104,
10
10
  heightCompact: 36,
@@ -35,6 +35,17 @@ function G9RangeSlider(props) {
35
35
  const single = props.mode === G9RangeSliderMode.Single;
36
36
  const labels = false !== props.showLabels;
37
37
  const bounds = sliderBounds(min, max);
38
+ const log = isLogTrack(props.logarithmic, bounds.min, bounds.max);
39
+ const thumbValues = labels && true === props.showThumbValues;
40
+ const snap = (v)=>log && step > 0 ? snapLogValue(v, min, max) : snapSliderValue(v, min, max, step);
41
+ const ordered = (a, b)=>a <= b ? [
42
+ a,
43
+ b
44
+ ] : [
45
+ b,
46
+ a
47
+ ];
48
+ const ratioOf = (v)=>sliderRatio(v, min, max, log);
38
49
  const [value, setValue] = useControllableState({
39
50
  value: props.value,
40
51
  defaultValue: null != (_props_defaultValue = props.defaultValue) ? _props_defaultValue : 0,
@@ -58,8 +69,8 @@ function G9RangeSlider(props) {
58
69
  equals: (a, b)=>a[0] === b[0] && a[1] === b[1]
59
70
  });
60
71
  const [dragging, setDragging] = useState(null);
61
- const shown = single ? snapSliderValue(value, min, max, step) : null;
62
- const shownRange = coerceSliderRange(range[0], range[1], min, max, step);
72
+ const shown = single ? snap(value) : null;
73
+ const shownRange = log ? ordered(snap(range[0]), snap(range[1])) : coerceSliderRange(range[0], range[1], min, max, step);
63
74
  const latest = useRef({
64
75
  props,
65
76
  shownRange,
@@ -94,8 +105,8 @@ function G9RangeSlider(props) {
94
105
  };
95
106
  const onValueChange = (v, source)=>{
96
107
  if ('drag' !== source || props.disabled) return;
97
- if ('number' == typeof v) applySingle(snapSliderValue(sliderValueAt(v, min, max), min, max, step));
98
- else applyRange(coerceSliderRange(sliderValueAt(v[0], min, max), sliderValueAt(v[1], min, max), min, max, step));
108
+ if ('number' == typeof v) applySingle(snap(sliderValueAt(v, min, max, log)));
109
+ else applyRange(ordered(snap(sliderValueAt(v[0], min, max, log)), snap(sliderValueAt(v[1], min, max, log))));
99
110
  };
100
111
  const onDragging = ()=>setDragging((d)=>d ? null : {
101
112
  index: 1
@@ -118,24 +129,35 @@ function G9RangeSlider(props) {
118
129
  Math.max(s, next)
119
130
  ]);
120
131
  };
121
- const sliderValue = single ? sliderRatio(shown, min, max) : [
122
- sliderRatio(shownRange[0], min, max),
123
- sliderRatio(shownRange[1], min, max)
132
+ const sliderValue = single ? ratioOf(shown) : [
133
+ ratioOf(shownRange[0]),
134
+ ratioOf(shownRange[1])
124
135
  ];
125
136
  const tooltipValue = single ? shown : shownRange[null != (_ref = null == dragging ? void 0 : dragging.index) ? _ref : 1];
126
- const tooltipRatio = sliderRatio(tooltipValue, min, max);
137
+ const tooltipRatio = ratioOf(tooltipValue);
138
+ const at = (ratio)=>`${(rtl ? 1 - ratio : ratio) * 100}%`;
127
139
  const thumb = (index)=><SliderThumb key={index} index={index} className="g9-slider__thumb">
128
140
  <view className={`g9-slider__thumb-dot${dragging && dragging.index === index ? ' g9-slider__thumb-dot--active' : ''}`}/>
129
141
  </SliderThumb>;
130
142
  return <view className={`g9-slider${labels ? ' g9-slider--labels' : ' g9-slider--compact'}${props.disabled ? ' g9-slider--disabled' : ''}${props.className ? ` ${props.className}` : ''}`} style={{
131
143
  height: `${labels ? g9SliderMetrics.height : g9SliderMetrics.heightCompact}px`
132
144
  }} accessibility-element={true} accessibility-label={null != (_props_accessibilityLabel = props.accessibilityLabel) ? _props_accessibilityLabel : ''} accessibility-value={single ? fmt(shown) : `${fmt(shownRange[0])} – ${fmt(shownRange[1])}`} bindkeydown={onKey}>
133
- {labels && dragging ? <view className="g9-slider__tooltip" style={{
134
- left: `${(rtl ? 1 - tooltipRatio : tooltipRatio) * 100}%`
145
+ {labels && dragging && !thumbValues ? <view className="g9-slider__tooltip" style={{
146
+ left: at(tooltipRatio)
135
147
  }}>
136
148
  <text className="g9-slider__tooltip-text">{fmt(tooltipValue)}</text>
137
149
  </view> : null}
138
- <SliderRoot className="g9-slider__root" value={sliderValue} {...step > 0 ? {
150
+ {thumbValues ? (single ? [
151
+ shown
152
+ ] : [
153
+ shownRange[0],
154
+ shownRange[1]
155
+ ]).map((v, i)=><view key={`v${i}`} className="g9-slider__thumb-value" style={{
156
+ left: at(ratioOf(v))
157
+ }}>
158
+ <text className="g9-slider__thumb-value-text">{fmt(v)}</text>
159
+ </view>) : null}
160
+ <SliderRoot className="g9-slider__root" value={sliderValue} {...step > 0 && !log ? {
139
161
  step: step / (bounds.max - bounds.min)
140
162
  } : {}} disabled={true === props.disabled} enableRTL={rtl} onValueChange={onValueChange} onDragging={onDragging} onValueCommit={onCommit}>
141
163
  <SliderTrack className="g9-slider__track">
@@ -148,7 +170,7 @@ function G9RangeSlider(props) {
148
170
  ]}
149
171
  </SliderTrack>
150
172
  </SliderRoot>
151
- {labels ? <view className="g9-slider__labels">
173
+ {labels && !thumbValues ? <view className="g9-slider__labels">
152
174
  <text className="g9-slider__label">{fmt(rtl ? bounds.max : bounds.min)}</text>
153
175
  <text className="g9-slider__label">{fmt(rtl ? bounds.min : bounds.max)}</text>
154
176
  </view> : null}
@@ -1 +1 @@
1
- {"version":3,"file":"range-slider/range-slider.jsx","sources":["../../src/range-slider/range-slider.tsx"],"sourcesContent":["import './range-slider.css';\nimport { formatColor, G9RangeSliderMode, lighten } from '@g9tm/lynxcontrols-foundation';\nimport { SliderIndicator, SliderRoot, SliderThumb, SliderTrack } from '@lynx-js/lynx-ui-slider';\nimport { type ReactNode, useRef, useState } from '@lynx-js/react';\nimport { useControllableState } from '../base/use-controllable-state';\nimport { useG9Culture, useG9Direction, useG9Theme } from '../provider/hooks';\nimport {\n coerceSliderRange,\n formatSliderValue,\n sliderBounds,\n sliderRatio,\n sliderValueAt,\n snapSliderValue,\n} from './math';\n\n/** Layout tokens (MAUI `G9Metrics.Slider*`). */\nexport const g9SliderMetrics = Object.freeze({\n height: 104,\n heightCompact: 36,\n trackHeight: 8,\n thumbRadius: 14,\n horizontalInset: 16,\n});\n\n/** Props of {@link G9RangeSlider}. */\nexport interface G9RangeSliderProps {\n /** Default 0. */\n readonly minimum?: number;\n /** Default 100. */\n readonly maximum?: number;\n /** `'single'` (one thumb, `value`) or `'range'` (two thumbs, `rangeStart`/`rangeEnd`). Default `'range'`. */\n readonly mode?: G9RangeSliderMode;\n /** Single mode value (MAUI `Value`). */\n readonly value?: number;\n readonly defaultValue?: number;\n readonly onValueChange?: (value: number) => void;\n /** Range mode thumbs (MAUI `RangeStart`/`RangeEnd`). */\n readonly rangeStart?: number;\n readonly rangeEnd?: number;\n readonly defaultRangeStart?: number;\n readonly defaultRangeEnd?: number;\n readonly onRangeChange?: (start: number, end: number) => void;\n /** Snap interval; 0 = continuous. Default 1. */\n readonly step?: number;\n /** Min/max edge labels and the drag tooltip (false = compact 36 px). Default true. */\n readonly showLabels?: boolean;\n /** .NET-style number format of labels and tooltip (`\"0\"`, `\"0.0\"`, `\"0°\"`). Default `\"0\"`. */\n readonly valueFormat?: string | null;\n readonly disabled?: boolean;\n /** After the user changed a value: the single value, or the range end (MAUI `ValueChanged`). */\n readonly onValueChanged?: (value: number) => void;\n readonly accessibilityLabel?: string;\n readonly className?: string;\n}\n\n/** Arrow/Home/End handling of the desktop keyboard: the new value, or `null` for another key. */\nexport function sliderKeyStep(\n key: string,\n value: number,\n min: number,\n max: number,\n step: number,\n rtl: boolean,\n): number | null {\n const b = sliderBounds(min, max);\n const delta = step > 0 ? step : (b.max - b.min) / 100;\n const forward = rtl ? 'ArrowLeft' : 'ArrowRight';\n const back = rtl ? 'ArrowRight' : 'ArrowLeft';\n if (key === forward || key === 'ArrowUp') return snapSliderValue(value + delta, min, max, step);\n if (key === back || key === 'ArrowDown') return snapSliderValue(value - delta, min, max, step);\n if (key === 'Home') return b.min;\n if (key === 'End') return b.max;\n return null;\n}\n\n/**\n * One- or two-thumb slider (MAUI `G9RangeSlider`) on lynx-ui `SliderRoot`: lynx-ui owns the gesture (main-thread\n * drag, thumbs that meet but never cross); G9 maps minimum/maximum/step onto its normalized value, snaps with the\n * MAUI formula, keeps the stored values as given until the user moves them (display is always coerced; MAUI's\n * deferred write-back), paints the fill between the thumbs, shows min/max labels (swapped in RTL) and a tooltip\n * while dragging, and moves with the arrow keys on desktop.\n */\nexport function G9RangeSlider(props: G9RangeSliderProps): ReactNode {\n const culture = useG9Culture();\n const rtl = useG9Direction() === 'rtl';\n const primary = useG9Theme().palette.Primary;\n // MAUI G9RangeSliderDrawable: saturated at the minimum end, 22 % lighter towards the value, in reading direction.\n const fill = `linear-gradient(to ${rtl ? 'left' : 'right'}, ${formatColor(primary)}, ${formatColor(lighten(primary, 0.22))})`;\n const min = props.minimum ?? 0;\n const max = props.maximum ?? 100;\n const step = props.step ?? 1;\n const single = props.mode === G9RangeSliderMode.Single;\n const labels = props.showLabels !== false;\n const bounds = sliderBounds(min, max);\n const [value, setValue] = useControllableState<number>({\n value: props.value,\n defaultValue: props.defaultValue ?? 0,\n onChange: props.onValueChange,\n name: 'G9RangeSlider.value',\n });\n const [range, setRange] = useControllableState<readonly [number, number], []>({\n value:\n props.rangeStart !== undefined && props.rangeEnd !== undefined ? [props.rangeStart, props.rangeEnd] : undefined,\n defaultValue: [props.defaultRangeStart ?? 0, props.defaultRangeEnd ?? 100],\n onChange: (r) => props.onRangeChange?.(r[0], r[1]),\n name: 'G9RangeSlider.range',\n equals: (a, b) => a[0] === b[0] && a[1] === b[1],\n });\n const [dragging, setDragging] = useState<{ index: 0 | 1 } | null>(null);\n const shown = single ? snapSliderValue(value, min, max, step) : null;\n const shownRange = coerceSliderRange(range[0], range[1], min, max, step);\n const latest = useRef({ props, shownRange, shown });\n latest.current = { props, shownRange, shown };\n const fmt = (v: number) => formatSliderValue(v, props.valueFormat ?? '0', culture);\n\n const applySingle = (next: number) => {\n if (next === latest.current.shown) return;\n setValue(next);\n latest.current.props.onValueChanged?.(next);\n };\n const applyRange = (next: readonly [number, number]) => {\n const [s, e] = latest.current.shownRange;\n if (next[0] === s && next[1] === e) return;\n if (next[0] !== s) setDragging((d) => (d ? { index: 0 } : d));\n else setDragging((d) => (d ? { index: 1 } : d));\n setRange(next);\n latest.current.props.onValueChanged?.(next[1]);\n };\n const onValueChange = (v: number | readonly [number, number], source: 'external' | 'drag') => {\n if (source !== 'drag' || props.disabled) return;\n if (typeof v === 'number') applySingle(snapSliderValue(sliderValueAt(v, min, max), min, max, step));\n else applyRange(coerceSliderRange(sliderValueAt(v[0], min, max), sliderValueAt(v[1], min, max), min, max, step));\n };\n // lynx-ui reports the drag start and end through `onDragging`; the commit closes it for sure.\n const onDragging = () => setDragging((d) => (d ? null : { index: 1 }));\n const onCommit = () => setDragging(null);\n const onKey = (e: { detail?: { key?: string } }) => {\n if (props.disabled) return;\n const key = e.detail?.key ?? '';\n if (single) {\n const next = sliderKeyStep(key, shown as number, min, max, step, rtl);\n if (next !== null) applySingle(next);\n return;\n }\n // Keys move the end thumb, never past the start (and vice versa with Shift-less Home).\n const [s, end] = shownRange;\n const next = sliderKeyStep(key, end, min, max, step, rtl);\n if (next !== null) applyRange([Math.min(s, next), Math.max(s, next)]);\n };\n\n const sliderValue = single\n ? sliderRatio(shown as number, min, max)\n : ([sliderRatio(shownRange[0], min, max), sliderRatio(shownRange[1], min, max)] as const);\n const tooltipValue = single ? (shown as number) : shownRange[dragging?.index ?? 1];\n const tooltipRatio = sliderRatio(tooltipValue, min, max);\n const thumb = (index: 0 | 1) => (\n <SliderThumb key={index} index={index} className=\"g9-slider__thumb\">\n <view\n className={`g9-slider__thumb-dot${dragging && dragging.index === index ? ' g9-slider__thumb-dot--active' : ''}`}\n />\n </SliderThumb>\n );\n return (\n <view\n className={`g9-slider${labels ? ' g9-slider--labels' : ' g9-slider--compact'}${props.disabled ? ' g9-slider--disabled' : ''}${props.className ? ` ${props.className}` : ''}`}\n style={{ height: `${labels ? g9SliderMetrics.height : g9SliderMetrics.heightCompact}px` }}\n accessibility-element={true}\n accessibility-label={props.accessibilityLabel ?? ''}\n accessibility-value={single ? fmt(shown as number) : `${fmt(shownRange[0])} – ${fmt(shownRange[1])}`}\n bindkeydown={onKey}\n >\n {labels && dragging ? (\n <view className=\"g9-slider__tooltip\" style={{ left: `${(rtl ? 1 - tooltipRatio : tooltipRatio) * 100}%` }}>\n <text className=\"g9-slider__tooltip-text\">{fmt(tooltipValue)}</text>\n </view>\n ) : null}\n <SliderRoot\n className=\"g9-slider__root\"\n value={sliderValue as number}\n {...(step > 0 ? { step: step / (bounds.max - bounds.min) } : {})}\n disabled={props.disabled === true}\n enableRTL={rtl}\n onValueChange={onValueChange as (v: number, s: 'external' | 'drag') => void}\n onDragging={onDragging}\n onValueCommit={onCommit}\n >\n <SliderTrack className=\"g9-slider__track\">\n <SliderIndicator className=\"g9-slider__fill\" style={{ background: fill }} />\n {single ? thumb(0) : [thumb(0), thumb(1)]}\n </SliderTrack>\n </SliderRoot>\n {labels ? (\n <view className=\"g9-slider__labels\">\n <text className=\"g9-slider__label\">{fmt(rtl ? bounds.max : bounds.min)}</text>\n <text className=\"g9-slider__label\">{fmt(rtl ? bounds.min : bounds.max)}</text>\n </view>\n ) : null}\n </view>\n );\n}\n"],"names":["g9SliderMetrics","Object","sliderKeyStep","key","value","min","max","step","rtl","b","sliderBounds","delta","forward","back","snapSliderValue","G9RangeSlider","props","_props_minimum","_props_maximum","_props_step","_props_defaultValue","_props_defaultRangeStart","_props_defaultRangeEnd","_props_accessibilityLabel","culture","useG9Culture","useG9Direction","primary","useG9Theme","fill","formatColor","lighten","single","G9RangeSliderMode","labels","bounds","setValue","useControllableState","range","setRange","undefined","r","a","dragging","setDragging","useState","shown","shownRange","coerceSliderRange","latest","useRef","fmt","v","_props_valueFormat","formatSliderValue","applySingle","next","_latest_current_props","applyRange","s","e","d","onValueChange","source","sliderValueAt","onDragging","onCommit","onKey","_e_detail","end","Math","sliderValue","sliderRatio","tooltipValue","tooltipRatio","thumb","index","SliderThumb","view","text","SliderRoot","SliderTrack","SliderIndicator"],"mappings":"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"}
1
+ {"version":3,"file":"range-slider/range-slider.jsx","sources":["../../src/range-slider/range-slider.tsx"],"sourcesContent":["import './range-slider.css';\nimport { formatColor, G9RangeSliderMode, lighten } from '@g9tm/lynxcontrols-foundation';\nimport { SliderIndicator, SliderRoot, SliderThumb, SliderTrack } from '@lynx-js/lynx-ui-slider';\nimport { type ReactNode, useRef, useState } from '@lynx-js/react';\nimport { useControllableState } from '../base/use-controllable-state';\nimport { useG9Culture, useG9Direction, useG9Theme } from '../provider/hooks';\nimport {\n coerceSliderRange,\n formatSliderValue,\n isLogTrack,\n sliderBounds,\n sliderRatio,\n sliderValueAt,\n snapLogValue,\n snapSliderValue,\n} from './math';\n\n/** Layout tokens (MAUI `G9Metrics.Slider*`). */\nexport const g9SliderMetrics = Object.freeze({\n height: 104,\n heightCompact: 36,\n trackHeight: 8,\n thumbRadius: 14,\n horizontalInset: 16,\n});\n\n/** Props of {@link G9RangeSlider}. */\nexport interface G9RangeSliderProps {\n /** Default 0. */\n readonly minimum?: number;\n /** Default 100. */\n readonly maximum?: number;\n /** `'single'` (one thumb, `value`) or `'range'` (two thumbs, `rangeStart`/`rangeEnd`). Default `'range'`. */\n readonly mode?: G9RangeSliderMode;\n /** Single mode value (MAUI `Value`). */\n readonly value?: number;\n readonly defaultValue?: number;\n readonly onValueChange?: (value: number) => void;\n /** Range mode thumbs (MAUI `RangeStart`/`RangeEnd`). */\n readonly rangeStart?: number;\n readonly rangeEnd?: number;\n readonly defaultRangeStart?: number;\n readonly defaultRangeEnd?: number;\n readonly onRangeChange?: (start: number, end: number) => void;\n /** Snap interval; 0 = continuous. Default 1. */\n readonly step?: number;\n /** Min/max edge labels and the drag tooltip (false = compact 36 px). Default true. */\n readonly showLabels?: boolean;\n /** .NET-style number format of labels and tooltip (`\"0\"`, `\"0.0\"`, `\"0°\"`). Default `\"0\"`. */\n readonly valueFormat?: string | null;\n /**\n * A LOGARITHMIC track (MAUI 1.4.9): equal distances are equal ratios, so a range over orders of magnitude (site areas\n * 787 to 56,475 ha, AgriPad's site filter) is usable at both ends. Needs `minimum > 0` (else linear); the value then\n * snaps to two significant figures instead of `step`. Default false.\n */\n readonly logarithmic?: boolean;\n /**\n * Each thumb's value drawn ABOVE it at all times, following it (MAUI 1.4.9, the design's «مساحت (هکتار)» readout); the\n * min / max edge labels and the drag tooltip are then not drawn. Needs `showLabels` (it uses their room). Default false.\n */\n readonly showThumbValues?: boolean;\n readonly disabled?: boolean;\n /** After the user changed a value: the single value, or the range end (MAUI `ValueChanged`). */\n readonly onValueChanged?: (value: number) => void;\n readonly accessibilityLabel?: string;\n readonly className?: string;\n}\n\n/** Arrow/Home/End handling of the desktop keyboard: the new value, or `null` for another key. */\nexport function sliderKeyStep(\n key: string,\n value: number,\n min: number,\n max: number,\n step: number,\n rtl: boolean,\n): number | null {\n const b = sliderBounds(min, max);\n const delta = step > 0 ? step : (b.max - b.min) / 100;\n const forward = rtl ? 'ArrowLeft' : 'ArrowRight';\n const back = rtl ? 'ArrowRight' : 'ArrowLeft';\n if (key === forward || key === 'ArrowUp') return snapSliderValue(value + delta, min, max, step);\n if (key === back || key === 'ArrowDown') return snapSliderValue(value - delta, min, max, step);\n if (key === 'Home') return b.min;\n if (key === 'End') return b.max;\n return null;\n}\n\n/**\n * One- or two-thumb slider (MAUI `G9RangeSlider`) on lynx-ui `SliderRoot`: lynx-ui owns the gesture (main-thread\n * drag, thumbs that meet but never cross); G9 maps minimum/maximum/step onto its normalized value, snaps with the\n * MAUI formula, keeps the stored values as given until the user moves them (display is always coerced; MAUI's\n * deferred write-back), paints the fill between the thumbs, shows min/max labels (swapped in RTL) and a tooltip\n * while dragging, and moves with the arrow keys on desktop.\n */\nexport function G9RangeSlider(props: G9RangeSliderProps): ReactNode {\n const culture = useG9Culture();\n const rtl = useG9Direction() === 'rtl';\n const primary = useG9Theme().palette.Primary;\n // MAUI G9RangeSliderDrawable: saturated at the minimum end, 22 % lighter towards the value, in reading direction.\n const fill = `linear-gradient(to ${rtl ? 'left' : 'right'}, ${formatColor(primary)}, ${formatColor(lighten(primary, 0.22))})`;\n const min = props.minimum ?? 0;\n const max = props.maximum ?? 100;\n const step = props.step ?? 1;\n const single = props.mode === G9RangeSliderMode.Single;\n const labels = props.showLabels !== false;\n const bounds = sliderBounds(min, max);\n const log = isLogTrack(props.logarithmic, bounds.min, bounds.max);\n const thumbValues = labels && props.showThumbValues === true;\n // MAUI Snap: a logarithmic track with a step snaps to two significant figures, a linear one to `step`; `step <= 0` is\n // continuous on both (clamped only).\n const snap = (v: number) => (log && step > 0 ? snapLogValue(v, min, max) : snapSliderValue(v, min, max, step));\n const ordered = (a: number, b: number): readonly [number, number] => (a <= b ? [a, b] : [b, a]);\n const ratioOf = (v: number) => sliderRatio(v, min, max, log);\n const [value, setValue] = useControllableState<number>({\n value: props.value,\n defaultValue: props.defaultValue ?? 0,\n onChange: props.onValueChange,\n name: 'G9RangeSlider.value',\n });\n const [range, setRange] = useControllableState<readonly [number, number], []>({\n value:\n props.rangeStart !== undefined && props.rangeEnd !== undefined ? [props.rangeStart, props.rangeEnd] : undefined,\n defaultValue: [props.defaultRangeStart ?? 0, props.defaultRangeEnd ?? 100],\n onChange: (r) => props.onRangeChange?.(r[0], r[1]),\n name: 'G9RangeSlider.range',\n equals: (a, b) => a[0] === b[0] && a[1] === b[1],\n });\n const [dragging, setDragging] = useState<{ index: 0 | 1 } | null>(null);\n const shown = single ? snap(value) : null;\n const shownRange = log\n ? ordered(snap(range[0]), snap(range[1]))\n : coerceSliderRange(range[0], range[1], min, max, step);\n const latest = useRef({ props, shownRange, shown });\n latest.current = { props, shownRange, shown };\n const fmt = (v: number) => formatSliderValue(v, props.valueFormat ?? '0', culture);\n\n const applySingle = (next: number) => {\n if (next === latest.current.shown) return;\n setValue(next);\n latest.current.props.onValueChanged?.(next);\n };\n const applyRange = (next: readonly [number, number]) => {\n const [s, e] = latest.current.shownRange;\n if (next[0] === s && next[1] === e) return;\n if (next[0] !== s) setDragging((d) => (d ? { index: 0 } : d));\n else setDragging((d) => (d ? { index: 1 } : d));\n setRange(next);\n latest.current.props.onValueChanged?.(next[1]);\n };\n const onValueChange = (v: number | readonly [number, number], source: 'external' | 'drag') => {\n if (source !== 'drag' || props.disabled) return;\n if (typeof v === 'number') applySingle(snap(sliderValueAt(v, min, max, log)));\n else applyRange(ordered(snap(sliderValueAt(v[0], min, max, log)), snap(sliderValueAt(v[1], min, max, log))));\n };\n // lynx-ui reports the drag start and end through `onDragging`; the commit closes it for sure.\n const onDragging = () => setDragging((d) => (d ? null : { index: 1 }));\n const onCommit = () => setDragging(null);\n const onKey = (e: { detail?: { key?: string } }) => {\n if (props.disabled) return;\n const key = e.detail?.key ?? '';\n if (single) {\n const next = sliderKeyStep(key, shown as number, min, max, step, rtl);\n if (next !== null) applySingle(next);\n return;\n }\n // Keys move the end thumb, never past the start (and vice versa with Shift-less Home).\n const [s, end] = shownRange;\n const next = sliderKeyStep(key, end, min, max, step, rtl);\n if (next !== null) applyRange([Math.min(s, next), Math.max(s, next)]);\n };\n\n const sliderValue = single ? ratioOf(shown as number) : ([ratioOf(shownRange[0]), ratioOf(shownRange[1])] as const);\n const tooltipValue = single ? (shown as number) : shownRange[dragging?.index ?? 1];\n const tooltipRatio = ratioOf(tooltipValue);\n const at = (ratio: number) => `${(rtl ? 1 - ratio : ratio) * 100}%`;\n const thumb = (index: 0 | 1) => (\n <SliderThumb key={index} index={index} className=\"g9-slider__thumb\">\n <view\n className={`g9-slider__thumb-dot${dragging && dragging.index === index ? ' g9-slider__thumb-dot--active' : ''}`}\n />\n </SliderThumb>\n );\n return (\n <view\n className={`g9-slider${labels ? ' g9-slider--labels' : ' g9-slider--compact'}${props.disabled ? ' g9-slider--disabled' : ''}${props.className ? ` ${props.className}` : ''}`}\n style={{ height: `${labels ? g9SliderMetrics.height : g9SliderMetrics.heightCompact}px` }}\n accessibility-element={true}\n accessibility-label={props.accessibilityLabel ?? ''}\n accessibility-value={single ? fmt(shown as number) : `${fmt(shownRange[0])} – ${fmt(shownRange[1])}`}\n bindkeydown={onKey}\n >\n {labels && dragging && !thumbValues ? (\n <view className=\"g9-slider__tooltip\" style={{ left: at(tooltipRatio) }}>\n <text className=\"g9-slider__tooltip-text\">{fmt(tooltipValue)}</text>\n </view>\n ) : null}\n {thumbValues\n ? (single ? [shown as number] : [shownRange[0], shownRange[1]]).map((v, i) => (\n <view key={`v${i}`} className=\"g9-slider__thumb-value\" style={{ left: at(ratioOf(v)) }}>\n <text className=\"g9-slider__thumb-value-text\">{fmt(v)}</text>\n </view>\n ))\n : null}\n <SliderRoot\n className=\"g9-slider__root\"\n value={sliderValue as number}\n {...(step > 0 && !log ? { step: step / (bounds.max - bounds.min) } : {})}\n disabled={props.disabled === true}\n enableRTL={rtl}\n onValueChange={onValueChange as (v: number, s: 'external' | 'drag') => void}\n onDragging={onDragging}\n onValueCommit={onCommit}\n >\n <SliderTrack className=\"g9-slider__track\">\n <SliderIndicator className=\"g9-slider__fill\" style={{ background: fill }} />\n {single ? thumb(0) : [thumb(0), thumb(1)]}\n </SliderTrack>\n </SliderRoot>\n {labels && !thumbValues ? (\n <view className=\"g9-slider__labels\">\n <text className=\"g9-slider__label\">{fmt(rtl ? bounds.max : bounds.min)}</text>\n <text className=\"g9-slider__label\">{fmt(rtl ? bounds.min : bounds.max)}</text>\n </view>\n ) : null}\n </view>\n );\n}\n"],"names":["g9SliderMetrics","Object","sliderKeyStep","key","value","min","max","step","rtl","b","sliderBounds","delta","forward","back","snapSliderValue","G9RangeSlider","props","_props_minimum","_props_maximum","_props_step","_props_defaultValue","_props_defaultRangeStart","_props_defaultRangeEnd","_props_accessibilityLabel","culture","useG9Culture","useG9Direction","primary","useG9Theme","fill","formatColor","lighten","single","G9RangeSliderMode","labels","bounds","log","isLogTrack","thumbValues","snap","v","snapLogValue","ordered","a","ratioOf","sliderRatio","setValue","useControllableState","range","setRange","undefined","r","dragging","setDragging","useState","shown","shownRange","coerceSliderRange","latest","useRef","fmt","_props_valueFormat","formatSliderValue","applySingle","next","_latest_current_props","applyRange","s","e","d","onValueChange","source","sliderValueAt","onDragging","onCommit","onKey","_e_detail","end","Math","sliderValue","tooltipValue","tooltipRatio","at","ratio","thumb","index","SliderThumb","view","text","i","SliderRoot","SliderTrack","SliderIndicator"],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  export type { G9SelectionItem } from '../base/selection-item.js';
2
2
  export { createSelectionModel, foldSearchText, type G9SelectionMode, type G9SelectionModel, type G9SelectionModelOptions, } from './model.js';
3
- export { estimateSelectionHeight, type G9ListSheetRequest, type G9SelectionSheetRequest, type G9SelectionSheetResult, g9SelectionCloseDelayMs, g9SelectionEagerBuildItemLimit, g9SelectionRowHeight, g9SelectionSearchDebounceMs, selectionIdentities, showListSheet, showSelectionSheet, } from './selection-sheet.js';
3
+ export { estimateSelectionHeight, type G9ListSheetRequest, type G9SelectionSheetRequest, type G9SelectionSheetResult, g9SelectionCloseDelayMs, g9SelectionEagerBuildItemLimit, g9SelectionRowHeight, g9SelectionSearchDebounceMs, g9SelectionSkeletonRowCap, selectionIdentities, showListSheet, showSelectionSheet, } from './selection-sheet.js';
4
4
  export { type G9SelectionModelHookOptions, useSelectionModel } from './use-selection-model.js';
5
+ export { computeSelectionWindow, type G9SelectionWindow, g9SelectionGrowThreshold, g9SelectionMaxRenderedRows, g9SelectionRowPageSize, nextSelectionLimit, } from './window.js';
5
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/selection/index.ts"],"names":[],"mappings":"AAEA,YAAY,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EACL,oBAAoB,EACpB,cAAc,EACd,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,uBAAuB,GAC7B,MAAM,SAAS,CAAC;AACjB,OAAO,EACL,uBAAuB,EACvB,KAAK,kBAAkB,EACvB,KAAK,uBAAuB,EAC5B,KAAK,sBAAsB,EAC3B,uBAAuB,EACvB,8BAA8B,EAC9B,oBAAoB,EACpB,2BAA2B,EAC3B,mBAAmB,EACnB,aAAa,EACb,kBAAkB,GACnB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,KAAK,2BAA2B,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/selection/index.ts"],"names":[],"mappings":"AAEA,YAAY,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EACL,oBAAoB,EACpB,cAAc,EACd,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,uBAAuB,GAC7B,MAAM,SAAS,CAAC;AACjB,OAAO,EACL,uBAAuB,EACvB,KAAK,kBAAkB,EACvB,KAAK,uBAAuB,EAC5B,KAAK,sBAAsB,EAC3B,uBAAuB,EACvB,8BAA8B,EAC9B,oBAAoB,EACpB,2BAA2B,EAC3B,yBAAyB,EACzB,mBAAmB,EACnB,aAAa,EACb,kBAAkB,GACnB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,KAAK,2BAA2B,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC5F,OAAO,EACL,sBAAsB,EACtB,KAAK,iBAAiB,EACtB,wBAAwB,EACxB,0BAA0B,EAC1B,sBAAsB,EACtB,kBAAkB,GACnB,MAAM,UAAU,CAAC"}
@@ -1,3 +1,4 @@
1
1
  export { createSelectionModel, foldSearchText } from "./model.jsx";
2
- export { estimateSelectionHeight, g9SelectionCloseDelayMs, g9SelectionEagerBuildItemLimit, g9SelectionRowHeight, g9SelectionSearchDebounceMs, selectionIdentities, showListSheet, showSelectionSheet } from "./selection-sheet.jsx";
2
+ export { estimateSelectionHeight, g9SelectionCloseDelayMs, g9SelectionEagerBuildItemLimit, g9SelectionRowHeight, g9SelectionSearchDebounceMs, g9SelectionSkeletonRowCap, selectionIdentities, showListSheet, showSelectionSheet } from "./selection-sheet.jsx";
3
3
  export { useSelectionModel } from "./use-selection-model.jsx";
4
+ export { computeSelectionWindow, g9SelectionGrowThreshold, g9SelectionMaxRenderedRows, g9SelectionRowPageSize, nextSelectionLimit } from "./window.jsx";
@@ -1,6 +1,6 @@
1
1
  import './selection.css';
2
2
  import { type G9TextInputDirection } from '@g9tm/lynxcontrols-foundation';
3
- import type { G9SelectionItem } from '../base/selection-item.js';
3
+ import { type G9SelectionItem } from '../base/selection-item.js';
4
4
  import { type G9SheetOptions } from '../sheet/options.js';
5
5
  import type { G9SheetService } from '../sheet/service.js';
6
6
  /** MAUI `G9SelectionSheet.EagerBuildItemLimit`: lists up to 40 items are built at once; longer lists defer. */
@@ -45,9 +45,16 @@ export interface G9SelectionSheetRequest<T extends G9SelectionItem> {
45
45
  readonly resetSelection?: ReadonlyArray<T> | null;
46
46
  /** Count pill label (multi). Default `"{n} {selected}"`. */
47
47
  readonly countLabel?: (count: number) => string;
48
+ /**
49
+ * Multi: Done stays disabled until at least this many items are ticked (MAUI `minimumSelected`, G9MAUIControls 1.4.7) —
50
+ * the sheet never closes on an answer the caller would refuse and reopen. Default 0.
51
+ */
52
+ readonly minimumSelected?: number;
48
53
  /** Extra sheet options (merged over the defaults). */
49
54
  readonly options?: G9SheetOptions;
50
55
  }
56
+ /** Placeholder rows: no more than the tallest selection sheet can show (MAUI 1.4.8 `SkeletonRowCap`). */
57
+ export declare const g9SelectionSkeletonRowCap: number;
51
58
  /**
52
59
  * Shows the selection sheet (MAUI `G9SelectionSheet.ShowForResultAsync`): a fit sheet with a header (title near the
53
60
  * close button), optional search (150 ms debounce, text match, hidden selected rows stay selected), rows with icon or
@@ -1 +1 @@
1
- {"version":3,"file":"selection-sheet.d.ts","sourceRoot":"","sources":["../../src/selection/selection-sheet.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"selection-sheet.d.ts","sourceRoot":"","sources":["../../src/selection/selection-sheet.tsx"],"names":[],"mappings":"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"}
@@ -1,8 +1,9 @@
1
1
  import "./selection.css";
2
- import { G9StringKey, formatColor, withAlpha } from "@g9tm/lynxcontrols-foundation";
2
+ import { G9Metrics, G9StringKey, formatColor, withAlpha } from "@g9tm/lynxcontrols-foundation";
3
3
  import { useEffect, useRef, useState, useSyncExternalStore } from "@lynx-js/react";
4
4
  import { g9ChildId, g9RowStyle, g9TextStart } from "../base/control.jsx";
5
5
  import { useG9Press } from "../base/press.jsx";
6
+ import { isAvatarImage } from "../base/selection-item.jsx";
6
7
  import { startTimer, stopTimer } from "../base/timers.jsx";
7
8
  import { G9Button } from "../button/button.jsx";
8
9
  import { G9SearchEntry } from "../fields/search-entry.jsx";
@@ -12,6 +13,7 @@ import { G9Swatch } from "../icon/swatch.jsx";
12
13
  import { useG9Direction, useG9Settings, useG9Strings, useG9Theme } from "../provider/hooks.jsx";
13
14
  import { fitToContentSheetOptions, fullScreenWithoutHandleSheetOptions } from "../sheet/options.jsx";
14
15
  import { createSelectionModel } from "./model.jsx";
16
+ import { computeSelectionWindow, g9SelectionGrowThreshold, g9SelectionRowPageSize, nextSelectionLimit } from "./window.jsx";
15
17
  const g9SelectionEagerBuildItemLimit = 40;
16
18
  const g9SelectionRowHeight = 52;
17
19
  const g9SelectionSearchDebounceMs = 150;
@@ -31,6 +33,7 @@ function estimateSelectionHeight(count, showSearch) {
31
33
  const chrome = (showSearch ? 64 : 0) + 18;
32
34
  return Math.min(520, Math.max(2 * g9SelectionRowHeight + chrome, count * g9SelectionRowHeight + chrome));
33
35
  }
36
+ const g9SelectionSkeletonRowCap = Math.ceil(G9Metrics.SelectionMaxHeight / G9Metrics.SelectionRowHeight) + 1;
34
37
  function SelectionRow(props) {
35
38
  var _item_iconTintColor;
36
39
  var _item_swatchFirstColor, _item_swatchSecondColor;
@@ -49,6 +52,8 @@ function SelectionRow(props) {
49
52
  image: item.iconImage
50
53
  };
51
54
  const iconColor = null != (_item_iconTintColor = item.iconTintColor) ? _item_iconTintColor : selected ? palette.Primary : palette.TextSecondary;
55
+ const avatar = isAvatarImage(item);
56
+ const iconSize = avatar ? G9Metrics.SelectionAvatarSize : G9Metrics.SelectionIconSize;
52
57
  return <view {...props.elementId ? {
53
58
  id: props.elementId
54
59
  } : {}} className={`g9-selection-row${selected ? ' g9-selection-row--selected' : ''}`} style={selected ? {
@@ -62,7 +67,9 @@ function SelectionRow(props) {
62
67
  opacity: 0.45
63
68
  } : {}
64
69
  }}>
65
- {hasIconSlot(icon) ? <G9IconSlot {...icon} size={18} color={iconColor}/> : (null == (_item_swatchFirstColor = item.swatchFirstColor) ? void 0 : _item_swatchFirstColor.trim()) || (null == (_item_swatchSecondColor = item.swatchSecondColor) ? void 0 : _item_swatchSecondColor.trim()) ? <G9Swatch first={item.swatchFirstColor} second={item.swatchSecondColor} direction={props.direction}/> : <view className="g9-selection-row__icon-gap"/>}
70
+ {hasIconSlot(icon) ? <G9IconSlot {...icon} size={iconSize} color={iconColor} {...avatar ? {
71
+ imageCornerRadius: iconSize / 2
72
+ } : {}}/> : (null == (_item_swatchFirstColor = item.swatchFirstColor) ? void 0 : _item_swatchFirstColor.trim()) || (null == (_item_swatchSecondColor = item.swatchSecondColor) ? void 0 : _item_swatchSecondColor.trim()) ? <G9Swatch first={item.swatchFirstColor} second={item.swatchSecondColor} direction={props.direction}/> : <view className="g9-selection-row__icon-gap"/>}
66
73
  <text className="g9-selection-row__text" text-maxline="1" style={{
67
74
  color: selected ? palette.Primary : palette.TextPrimary,
68
75
  fontWeight: selected ? 'bold' : 'normal',
@@ -93,6 +100,32 @@ function SelectionBody(props) {
93
100
  }, []);
94
101
  const visible = request.showSearch ? model.withItems(request.items).filter(applied) : request.items;
95
102
  const visibleIds = new Set(visible.map((item)=>ids[request.items.indexOf(item)]));
103
+ const [grown, setGrown] = useState({
104
+ query: applied,
105
+ limit: g9SelectionRowPageSize
106
+ });
107
+ const limit = grown.query === applied ? grown.limit : g9SelectionRowPageSize;
108
+ const shown = computeSelectionWindow(request.items.length, (i)=>visibleIds.has(ids[i]), (i)=>model.isSelected(ids[i]), limit);
109
+ const latest = useRef({
110
+ applied,
111
+ limit,
112
+ hidden: shown.hidden
113
+ });
114
+ latest.current = {
115
+ applied,
116
+ limit,
117
+ hidden: shown.hidden
118
+ };
119
+ useEffect(()=>props.scrolledToEnd.subscribe(()=>{
120
+ const now = latest.current;
121
+ const next = nextSelectionLimit(now.limit, now.hidden);
122
+ if (next !== now.limit) setGrown({
123
+ query: now.applied,
124
+ limit: next
125
+ });
126
+ }), [
127
+ props.scrolledToEnd
128
+ ]);
96
129
  const dir = 'leftToRight' === request.itemTextDirection ? 'ltr' : 'rightToLeft' === request.itemTextDirection ? 'rtl' : parentDir;
97
130
  const multiple = true === request.allowMultiple;
98
131
  const onQuery = (value)=>{
@@ -116,15 +149,16 @@ function SelectionBody(props) {
116
149
  {request.showSearch ? <view className="g9-selection__search">
117
150
  <G9TextEntry placeholder={strings.get(G9StringKey.Search)} leadingIcon="search" value={query} onValueChange={onQuery}/>
118
151
  </view> : null}
119
- {visible.length > 0 ? <view className="g9-selection__items">
120
- {request.items.map((item, i)=>{
152
+ {shown.indices.length > 0 ? <view className="g9-selection__items">
153
+ {shown.indices.map((i)=>{
121
154
  var _item_key;
122
155
  var _request_options;
123
156
  const id = ids[i];
124
- if (!visibleIds.has(id)) return null;
157
+ const item = request.items[i];
125
158
  return <SelectionRow key={id} item={item} elementId={g9ChildId(null == (_request_options = request.options) ? void 0 : _request_options.automationId, `Item_${null != (_item_key = item.key) ? _item_key : i}`)} selected={model.isSelected(id)} direction={dir} onTap={()=>tap(id)}/>;
126
159
  })}
127
160
  </view> : null}
161
+ {shown.hidden > 0 ? <text className="g9-selection__more">{strings.format(G9StringKey.MoreResultsFormat, shown.hidden)}</text> : null}
128
162
  {0 === visible.length ? <text className="g9-selection__empty">{null != (_request_emptyText = request.emptyText) ? _request_emptyText : strings.get(G9StringKey.NoResults)}</text> : null}
129
163
  </view>;
130
164
  }
@@ -152,6 +186,7 @@ function showSelectionSheet(sheets, request) {
152
186
  isEnabled: (item)=>false !== item.isEnabled
153
187
  });
154
188
  return new Promise((resolve)=>{
189
+ var _request_minimumSelected;
155
190
  let draft = initial;
156
191
  const draftListeners = new Set();
157
192
  const draftStore = {
@@ -193,7 +228,16 @@ function showSelectionSheet(sheets, request) {
193
228
  null == handle || handle.close();
194
229
  };
195
230
  const reset = request.resetSelection && request.resetSelection.length > 0 ? request.resetSelection : null;
196
- const body = ()=><SelectionBody request={request} ids={ids} initial={initial} done={done} onDraft={(m)=>{
231
+ const endListeners = new Set();
232
+ const scrolledToEnd = {
233
+ subscribe: (l)=>{
234
+ endListeners.add(l);
235
+ return ()=>{
236
+ endListeners.delete(l);
237
+ };
238
+ }
239
+ };
240
+ const body = ()=><SelectionBody request={request} ids={ids} initial={initial} done={done} scrolledToEnd={scrolledToEnd} onDraft={(m)=>{
197
241
  draft = m;
198
242
  for (const l of [
199
243
  ...draftListeners
@@ -204,16 +248,25 @@ function showSelectionSheet(sheets, request) {
204
248
  deferContent: items.length > g9SelectionEagerBuildItemLimit,
205
249
  deferredLoadingPlaceholderHeight: estimateSelectionHeight(items.length, true === request.showSearch),
206
250
  loadingSkeleton: 'listRows',
207
- loadingSkeletonRowCount: items.length,
251
+ loadingSkeletonRowCount: Math.min(items.length, g9SelectionSkeletonRowCap),
252
+ onScrollToEnd: ()=>{
253
+ for (const l of [
254
+ ...endListeners
255
+ ])l();
256
+ },
257
+ scrollToEndThreshold: g9SelectionGrowThreshold,
208
258
  backgroundColor: 'var(--g9-surface)',
209
259
  showToolbar: true,
210
260
  showCloseButton: true,
211
261
  title: request.title,
212
262
  headerTitlePlacement: 'nearBack',
213
263
  ...multiple || reset ? {
214
- headerTrailingView: <SelectionHeaderActions multiple={multiple} draft={draftStore} {...request.countLabel ? {
264
+ headerTrailingView: <SelectionHeaderActions multiple={multiple} draft={draftStore} minimum={Math.max(0, null != (_request_minimumSelected = request.minimumSelected) ? _request_minimumSelected : 0)} {...request.countLabel ? {
215
265
  countLabel: request.countLabel
216
- } : {}} onDone={()=>complete(draft.selectedKeys, true)} {...reset ? {
266
+ } : {}} onDone={()=>{
267
+ var _request_minimumSelected;
268
+ if (draft.selectedKeys.length >= Math.max(0, null != (_request_minimumSelected = request.minimumSelected) ? _request_minimumSelected : 0)) complete(draft.selectedKeys, true);
269
+ }} {...reset ? {
217
270
  onReset: ()=>{
218
271
  settle([], true, reset);
219
272
  null == handle || handle.close();
@@ -242,7 +295,7 @@ function SelectionHeaderActions(props) {
242
295
  {props.countLabel ? props.countLabel(n) : `${n} ${strings.get(G9StringKey.Selected)}`}
243
296
  </text>
244
297
  </view> : null}
245
- {props.multiple ? <G9Button text={strings.get(G9StringKey.Done)} variant="text" size="small" onPress={props.onDone}/> : null}
298
+ {props.multiple ? <G9Button text={strings.get(G9StringKey.Done)} variant="text" size="small" disabled={n < props.minimum} onPress={props.onDone}/> : null}
246
299
  </view>;
247
300
  }
248
301
  function showListSheet(sheets, request) {
@@ -363,6 +416,6 @@ function ListPickerRow(props) {
363
416
  </text>
364
417
  </view>;
365
418
  }
366
- export { estimateSelectionHeight, g9SelectionCloseDelayMs, g9SelectionEagerBuildItemLimit, g9SelectionRowHeight, g9SelectionSearchDebounceMs, selectionIdentities, showListSheet, showSelectionSheet };
419
+ export { estimateSelectionHeight, g9SelectionCloseDelayMs, g9SelectionEagerBuildItemLimit, g9SelectionRowHeight, g9SelectionSearchDebounceMs, g9SelectionSkeletonRowCap, selectionIdentities, showListSheet, showSelectionSheet };
367
420
 
368
421
  //# sourceMappingURL=selection-sheet.jsx.map