@g9tm/lynxcontrols 1.4.2 → 1.4.4

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 (66) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/button/button.css +1 -0
  3. package/dist/button/button.css.map +1 -1
  4. package/dist/button/button.d.ts +2 -0
  5. package/dist/button/button.d.ts.map +1 -1
  6. package/dist/button/button.jsx +3 -2
  7. package/dist/button/button.jsx.map +1 -1
  8. package/dist/fields/outlined-field.d.ts +1 -1
  9. package/dist/fields/outlined-field.d.ts.map +1 -1
  10. package/dist/fields/outlined-field.jsx +13 -3
  11. package/dist/fields/outlined-field.jsx.map +1 -1
  12. package/dist/fields/use-text-input.d.ts.map +1 -1
  13. package/dist/fields/use-text-input.jsx +2 -2
  14. package/dist/fields/use-text-input.jsx.map +1 -1
  15. package/dist/pickers/date-time-picker.d.ts.map +1 -1
  16. package/dist/pickers/date-time-picker.jsx +13 -4
  17. package/dist/pickers/date-time-picker.jsx.map +1 -1
  18. package/dist/pickers/picker-sheet.d.ts +5 -1
  19. package/dist/pickers/picker-sheet.d.ts.map +1 -1
  20. package/dist/pickers/picker-sheet.jsx +3 -17
  21. package/dist/pickers/picker-sheet.jsx.map +1 -1
  22. package/dist/pickers/pickers.css +32 -43
  23. package/dist/pickers/pickers.css.map +1 -1
  24. package/dist/pickers/wheel-column.d.ts +3 -1
  25. package/dist/pickers/wheel-column.d.ts.map +1 -1
  26. package/dist/pickers/wheel-column.jsx +17 -3
  27. package/dist/pickers/wheel-column.jsx.map +1 -1
  28. package/dist/popup/frame.d.ts +6 -0
  29. package/dist/popup/frame.d.ts.map +1 -1
  30. package/dist/popup/frame.jsx +8 -6
  31. package/dist/popup/frame.jsx.map +1 -1
  32. package/dist/popup/popup.css +23 -16
  33. package/dist/popup/popup.css.map +1 -1
  34. package/dist/popup/service.d.ts.map +1 -1
  35. package/dist/popup/service.jsx +3 -2
  36. package/dist/popup/service.jsx.map +1 -1
  37. package/dist/range-slider/range-slider.css +5 -0
  38. package/dist/range-slider/range-slider.css.map +1 -1
  39. package/dist/range-slider/range-slider.jsx +1 -1
  40. package/dist/range-slider/range-slider.jsx.map +1 -1
  41. package/dist/selection/selection-sheet.d.ts.map +1 -1
  42. package/dist/selection/selection-sheet.jsx +4 -2
  43. package/dist/selection/selection-sheet.jsx.map +1 -1
  44. package/dist/selection/selection.css +15 -0
  45. package/dist/selection/selection.css.map +1 -1
  46. package/dist/sheet/frame.d.ts.map +1 -1
  47. package/dist/sheet/frame.jsx +28 -21
  48. package/dist/sheet/frame.jsx.map +1 -1
  49. package/dist/sheet/sheet.css +10 -0
  50. package/dist/sheet/sheet.css.map +1 -1
  51. package/dist/sheet/sizing.d.ts +6 -0
  52. package/dist/sheet/sizing.d.ts.map +1 -1
  53. package/dist/sheet/sizing.jsx +4 -2
  54. package/dist/sheet/sizing.jsx.map +1 -1
  55. package/dist/tabs/model.d.ts +1 -1
  56. package/dist/tabs/model.d.ts.map +1 -1
  57. package/dist/tabs/model.jsx.map +1 -1
  58. package/dist/tabs/tab-view.jsx +1 -1
  59. package/dist/tabs/tab-view.jsx.map +1 -1
  60. package/dist/toggle/chip-group.jsx +8 -2
  61. package/dist/toggle/chip-group.jsx.map +1 -1
  62. package/dist/toggle/switch.jsx +2 -1
  63. package/dist/toggle/switch.jsx.map +1 -1
  64. package/dist/toggle/toggle.css +5 -2
  65. package/dist/toggle/toggle.css.map +1 -1
  66. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"button.d.ts","sourceRoot":"","sources":["../../src/button/button.tsx"],"names":[],"mappings":"AAAA,OAAO,cAAc,CAAC;AACtB,OAAO,EAAE,KAAK,eAAe,EAAE,KAAK,aAAa,EAAE,KAAK,aAAa,EAAa,MAAM,+BAA+B,CAAC;AACxH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,KAAK,kBAAkB,EAA4B,MAAM,iBAAiB,CAAC;AAGpF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGhD,OAAO,EAAyC,KAAK,gBAAgB,EAAsB,MAAM,WAAW,CAAC;AAE7G,mDAAmD;AACnD,MAAM,WAAW,aAAc,SAAQ,kBAAkB;IACvD,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,4EAA4E;IAC5E,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,0CAA0C;IAC1C,QAAQ,CAAC,OAAO,CAAC,EAAE,eAAe,CAAC;IACnC,gEAAgE;IAChE,QAAQ,CAAC,IAAI,CAAC,EAAE,aAAa,CAAC;IAC9B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,QAAQ,CAAC,WAAW,CAAC,EAAE,WAAW,CAAC;IACnC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1C,QAAQ,CAAC,YAAY,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IAC7C,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,QAAQ,CAAC,YAAY,CAAC,EAAE,WAAW,CAAC;IACpC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3C,QAAQ,CAAC,aAAa,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IAC9C,4FAA4F;IAC5F,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAC7B,0GAA0G;IAC1G,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;IAClC,8CAA8C;IAC9C,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,0DAA0D;IAC1D,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,wBAAwB;IACxB,QAAQ,CAAC,cAAc,CAAC,EAAE,gBAAgB,CAAC;IAC3C,wEAAwE;IACxE,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7C,mDAAmD;IACnD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,qGAAqG;IACrG,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IAC9B,sGAAsG;IACtG,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,wGAAwG;IACxG,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,SAAS,CAqFxD"}
1
+ {"version":3,"file":"button.d.ts","sourceRoot":"","sources":["../../src/button/button.tsx"],"names":[],"mappings":"AAAA,OAAO,cAAc,CAAC;AACtB,OAAO,EAAE,KAAK,eAAe,EAAE,KAAK,aAAa,EAAE,KAAK,aAAa,EAAa,MAAM,+BAA+B,CAAC;AACxH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,KAAK,kBAAkB,EAA4B,MAAM,iBAAiB,CAAC;AAGpF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGhD,OAAO,EAAyC,KAAK,gBAAgB,EAAsB,MAAM,WAAW,CAAC;AAE7G,mDAAmD;AACnD,MAAM,WAAW,aAAc,SAAQ,kBAAkB;IACvD,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,4EAA4E;IAC5E,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,0CAA0C;IAC1C,QAAQ,CAAC,OAAO,CAAC,EAAE,eAAe,CAAC;IACnC,gEAAgE;IAChE,QAAQ,CAAC,IAAI,CAAC,EAAE,aAAa,CAAC;IAC9B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,QAAQ,CAAC,WAAW,CAAC,EAAE,WAAW,CAAC;IACnC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1C,QAAQ,CAAC,YAAY,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IAC7C,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,QAAQ,CAAC,YAAY,CAAC,EAAE,WAAW,CAAC;IACpC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3C,QAAQ,CAAC,aAAa,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IAC9C,4FAA4F;IAC5F,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAC7B,0GAA0G;IAC1G,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;IAClC,8CAA8C;IAC9C,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,0DAA0D;IAC1D,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,wBAAwB;IACxB,QAAQ,CAAC,cAAc,CAAC,EAAE,gBAAgB,CAAC;IAC3C,wEAAwE;IACxE,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7C,mDAAmD;IACnD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,qGAAqG;IACrG,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IAC9B,sGAAsG;IACtG,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,wGAAwG;IACxG,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B,4GAA4G;IAC5G,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;CACjC;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,SAAS,CAsFxD"}
@@ -13,6 +13,7 @@ function G9Button(props) {
13
13
  const loading = true === props.isLoading;
14
14
  const enabled = !control.disabled && true !== props.blocked;
15
15
  const preset = buttonSizePreset(null != (_props_size = props.size) ? _props_size : 'medium');
16
+ const height = props.heightRequest && props.heightRequest > 0 ? props.heightRequest : preset.height;
16
17
  const paint = resolveButtonPaint({
17
18
  variant: null != (_props_variant = props.variant) ? _props_variant : 'primary',
18
19
  palette: theme.palette,
@@ -52,8 +53,8 @@ function G9Button(props) {
52
53
  'accessibility-label': null != (_ref = null != (_props_accessibilityLabel1 = props.accessibilityLabel) ? _props_accessibilityLabel1 : props.text) ? _ref : ''
53
54
  } : {}} style={{
54
55
  ...g9RowStyle(control.direction),
55
- minHeight: `${preset.height}px`,
56
- height: `${preset.height}px`,
56
+ minHeight: `${height}px`,
57
+ height: `${height}px`,
57
58
  background: paint.background,
58
59
  borderColor: paint.stroke,
59
60
  borderWidth: `${paint.strokeWidth}px`,
@@ -1 +1 @@
1
- {"version":3,"file":"button/button.jsx","sources":["../../src/button/button.tsx"],"sourcesContent":["import './button.css';\nimport { type G9ButtonVariant, type G9ControlSize, type G9ImageSource, G9Metrics } from '@g9tm/lynxcontrols-foundation';\nimport type { ReactNode } from '@lynx-js/react';\nimport { type G9ControlBaseProps, g9RowStyle, useG9Control } from '../base/control';\nimport { useG9Press, usePressVisual } from '../base/press';\nimport { G9ActivityIndicator } from '../display/activity-indicator';\nimport type { G9IconInput } from '../icon/icon';\nimport { G9IconSlot, hasIconSlot } from '../icon/slot';\nimport { useG9Theme } from '../provider/hooks';\nimport { buttonSizePreset, fontAttributesStyle, type G9FontAttributes, resolveButtonPaint } from './visuals';\n\n/** Props of {@link G9Button} (MAUI `G9Button`). */\nexport interface G9ButtonProps extends G9ControlBaseProps {\n readonly text?: string | null;\n /** Text next to the spinner while loading; empty shows the spinner only. */\n readonly loadingText?: string | null;\n /** Colour recipe. Default `'primary'`. */\n readonly variant?: G9ButtonVariant;\n /** Height, padding and font preset. Default `'medium'` (44). */\n readonly size?: G9ControlSize;\n readonly leadingEmoji?: string | null;\n readonly leadingIcon?: G9IconInput;\n readonly leadingImagePath?: string | null;\n readonly leadingImage?: G9ImageSource | null;\n readonly trailingEmoji?: string | null;\n readonly trailingIcon?: G9IconInput;\n readonly trailingImagePath?: string | null;\n readonly trailingImage?: G9ImageSource | null;\n /** Spinner instead of the icons, presses blocked, opacity 0.7, flat fill. Default false. */\n readonly isLoading?: boolean;\n /** One line with a tail ellipsis; false keeps the text on one line at its natural width. Default true. */\n readonly textTruncation?: boolean;\n /** Icon slot and spinner size. Default 20. */\n readonly iconSize?: number;\n /** Font size; default the size preset's (12/14/15/16). */\n readonly fontSize?: number;\n /** Default `'bold'`. */\n readonly fontAttributes?: G9FontAttributes;\n /** Overrides the variant fill (transparent → no fill and no border). */\n readonly baseBackgroundColor?: string | null;\n /** Overrides the text, icon and spinner colour. */\n readonly textColor?: string | null;\n /** The press (MAUI `Clicked` + `Command`): exactly once per tap, never while disabled or loading. */\n readonly onPress?: () => void;\n /** Spinner colour; default the text colour (MAUI `G9SafeButton.SpinnerColor`, which MAUI ignored). */\n readonly spinnerColor?: string;\n /** Blocks presses like `disabled` (dims to 0.38) without being `disabled` (safe buttons while busy). */\n readonly blocked?: boolean;\n}\n\n/**\n * Text button (MAUI `G9Button`): variant fill (gradient for the solid variants), 12 px corners, no shadow, optional\n * leading/trailing icons, loading state with a spinner. One press handler on the root: a tap on the icon or the label\n * fires `onPress` once (MAUI \"press must fire\"); a second tap within 300 ms is dropped; a throwing handler is\n * reported to diagnostics. Press feedback: scale 0.96 (80 ms) → 1 (150 ms) on the main thread.\n */\nexport function G9Button(props: G9ButtonProps): ReactNode {\n const control = useG9Control(props, 'g9-button');\n const theme = useG9Theme();\n const loading = props.isLoading === true;\n const enabled = !control.disabled && props.blocked !== true;\n const preset = buttonSizePreset(props.size ?? 'medium');\n const paint = resolveButtonPaint({\n variant: props.variant ?? 'primary',\n palette: theme.palette,\n enabled,\n loading,\n baseBackgroundColor: props.baseBackgroundColor,\n textColor: props.textColor,\n kind: 'button',\n });\n const iconSize = props.iconSize && props.iconSize > 0 ? props.iconSize : G9Metrics.InputIconSize;\n const press = useG9Press(props.onPress, { blocked: !enabled || loading, source: 'G9Button' });\n const visual = usePressVisual(\n { property: 'scale', rest: 1, pressed: 0.96, inMs: 80, outMs: 150 },\n !enabled || loading,\n );\n const leading = {\n emoji: props.leadingEmoji,\n icon: props.leadingIcon,\n imagePath: props.leadingImagePath,\n image: props.leadingImage,\n };\n const trailing = {\n emoji: props.trailingEmoji,\n icon: props.trailingIcon,\n imagePath: props.trailingImagePath,\n image: props.trailingImage,\n };\n const label = loading ? (props.loadingText ?? '') : (props.text ?? '');\n const truncate = props.textTruncation !== false;\n return (\n <view\n className={`${control.className}${preset.fill ? ' g9-button--fill' : ''}`}\n {...control.idProps}\n accessibility-element={true}\n accessibility-traits=\"button\"\n {...((props.accessibilityLabel ?? props.text)\n ? { 'accessibility-label': props.accessibilityLabel ?? props.text ?? '' }\n : {})}\n style={{\n ...g9RowStyle(control.direction),\n // MAUI ApplySize: HeightRequest = the preset (52 hero, 44 medium…), the padding a margin around the row — the\n // button never grows with its label (a min-height let hero buttons grow to ~57 dp from the 16 px padding).\n minHeight: `${preset.height}px`,\n height: `${preset.height}px`,\n background: paint.background,\n borderColor: paint.stroke,\n borderWidth: `${paint.strokeWidth}px`,\n borderRadius: `${G9Metrics.RadiusMd}px`,\n opacity: paint.opacity,\n paddingLeft: `${preset.paddingHorizontal}px`,\n paddingRight: `${preset.paddingHorizontal}px`,\n paddingTop: '0px',\n paddingBottom: '0px',\n }}\n bindtap={press}\n {...visual}\n >\n {loading ? (\n <G9ActivityIndicator running size={iconSize} color={props.spinnerColor ?? paint.text} />\n ) : hasIconSlot(leading) ? (\n <G9IconSlot {...leading} size={iconSize} color={paint.text} />\n ) : null}\n {label.trim() !== '' ? (\n <text\n className=\"g9-button__label\"\n {...(truncate ? { 'text-maxline': '1' } : {})}\n style={{\n color: paint.text,\n fontSize: `${props.fontSize && props.fontSize > 0 ? props.fontSize : preset.fontSize}px`,\n ...fontAttributesStyle(props.fontAttributes ?? 'bold'),\n ...(truncate ? { textOverflow: 'ellipsis', overflow: 'hidden' } : { whiteSpace: 'nowrap' }),\n }}\n >\n {label}\n </text>\n ) : null}\n {!loading && hasIconSlot(trailing) ? <G9IconSlot {...trailing} size={iconSize} color={paint.text} /> : null}\n </view>\n );\n}\n"],"names":["G9Button","props","_props_size","_props_variant","_props_loadingText","_props_text","_props_accessibilityLabel","_ref","_props_spinnerColor","_props_fontAttributes","control","useG9Control","theme","useG9Theme","loading","enabled","preset","buttonSizePreset","paint","resolveButtonPaint","iconSize","G9Metrics","press","useG9Press","visual","usePressVisual","leading","trailing","label","truncate","view","g9RowStyle","G9ActivityIndicator","hasIconSlot","G9IconSlot","text","fontAttributesStyle"],"mappings":"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"}
1
+ {"version":3,"file":"button/button.jsx","sources":["../../src/button/button.tsx"],"sourcesContent":["import './button.css';\nimport { type G9ButtonVariant, type G9ControlSize, type G9ImageSource, G9Metrics } from '@g9tm/lynxcontrols-foundation';\nimport type { ReactNode } from '@lynx-js/react';\nimport { type G9ControlBaseProps, g9RowStyle, useG9Control } from '../base/control';\nimport { useG9Press, usePressVisual } from '../base/press';\nimport { G9ActivityIndicator } from '../display/activity-indicator';\nimport type { G9IconInput } from '../icon/icon';\nimport { G9IconSlot, hasIconSlot } from '../icon/slot';\nimport { useG9Theme } from '../provider/hooks';\nimport { buttonSizePreset, fontAttributesStyle, type G9FontAttributes, resolveButtonPaint } from './visuals';\n\n/** Props of {@link G9Button} (MAUI `G9Button`). */\nexport interface G9ButtonProps extends G9ControlBaseProps {\n readonly text?: string | null;\n /** Text next to the spinner while loading; empty shows the spinner only. */\n readonly loadingText?: string | null;\n /** Colour recipe. Default `'primary'`. */\n readonly variant?: G9ButtonVariant;\n /** Height, padding and font preset. Default `'medium'` (44). */\n readonly size?: G9ControlSize;\n readonly leadingEmoji?: string | null;\n readonly leadingIcon?: G9IconInput;\n readonly leadingImagePath?: string | null;\n readonly leadingImage?: G9ImageSource | null;\n readonly trailingEmoji?: string | null;\n readonly trailingIcon?: G9IconInput;\n readonly trailingImagePath?: string | null;\n readonly trailingImage?: G9ImageSource | null;\n /** Spinner instead of the icons, presses blocked, opacity 0.7, flat fill. Default false. */\n readonly isLoading?: boolean;\n /** One line with a tail ellipsis; false keeps the text on one line at its natural width. Default true. */\n readonly textTruncation?: boolean;\n /** Icon slot and spinner size. Default 20. */\n readonly iconSize?: number;\n /** Font size; default the size preset's (12/14/15/16). */\n readonly fontSize?: number;\n /** Default `'bold'`. */\n readonly fontAttributes?: G9FontAttributes;\n /** Overrides the variant fill (transparent → no fill and no border). */\n readonly baseBackgroundColor?: string | null;\n /** Overrides the text, icon and spinner colour. */\n readonly textColor?: string | null;\n /** The press (MAUI `Clicked` + `Command`): exactly once per tap, never while disabled or loading. */\n readonly onPress?: () => void;\n /** Spinner colour; default the text colour (MAUI `G9SafeButton.SpinnerColor`, which MAUI ignored). */\n readonly spinnerColor?: string;\n /** Blocks presses like `disabled` (dims to 0.38) without being `disabled` (safe buttons while busy). */\n readonly blocked?: boolean;\n /** Height in dp instead of the size preset's (MAUI `HeightRequest` set after the preset, e.g. 46 or 50). */\n readonly heightRequest?: number;\n}\n\n/**\n * Text button (MAUI `G9Button`): variant fill (gradient for the solid variants), 12 px corners, no shadow, optional\n * leading/trailing icons, loading state with a spinner. One press handler on the root: a tap on the icon or the label\n * fires `onPress` once (MAUI \"press must fire\"); a second tap within 300 ms is dropped; a throwing handler is\n * reported to diagnostics. Press feedback: scale 0.96 (80 ms) → 1 (150 ms) on the main thread.\n */\nexport function G9Button(props: G9ButtonProps): ReactNode {\n const control = useG9Control(props, 'g9-button');\n const theme = useG9Theme();\n const loading = props.isLoading === true;\n const enabled = !control.disabled && props.blocked !== true;\n const preset = buttonSizePreset(props.size ?? 'medium');\n const height = props.heightRequest && props.heightRequest > 0 ? props.heightRequest : preset.height;\n const paint = resolveButtonPaint({\n variant: props.variant ?? 'primary',\n palette: theme.palette,\n enabled,\n loading,\n baseBackgroundColor: props.baseBackgroundColor,\n textColor: props.textColor,\n kind: 'button',\n });\n const iconSize = props.iconSize && props.iconSize > 0 ? props.iconSize : G9Metrics.InputIconSize;\n const press = useG9Press(props.onPress, { blocked: !enabled || loading, source: 'G9Button' });\n const visual = usePressVisual(\n { property: 'scale', rest: 1, pressed: 0.96, inMs: 80, outMs: 150 },\n !enabled || loading,\n );\n const leading = {\n emoji: props.leadingEmoji,\n icon: props.leadingIcon,\n imagePath: props.leadingImagePath,\n image: props.leadingImage,\n };\n const trailing = {\n emoji: props.trailingEmoji,\n icon: props.trailingIcon,\n imagePath: props.trailingImagePath,\n image: props.trailingImage,\n };\n const label = loading ? (props.loadingText ?? '') : (props.text ?? '');\n const truncate = props.textTruncation !== false;\n return (\n <view\n className={`${control.className}${preset.fill ? ' g9-button--fill' : ''}`}\n {...control.idProps}\n accessibility-element={true}\n accessibility-traits=\"button\"\n {...((props.accessibilityLabel ?? props.text)\n ? { 'accessibility-label': props.accessibilityLabel ?? props.text ?? '' }\n : {})}\n style={{\n ...g9RowStyle(control.direction),\n // MAUI ApplySize: HeightRequest = the preset (52 hero, 44 medium…), the padding a margin around the row — the\n // button never grows with its label (a min-height let hero buttons grow to ~57 dp from the 16 px padding).\n minHeight: `${height}px`,\n height: `${height}px`,\n background: paint.background,\n borderColor: paint.stroke,\n borderWidth: `${paint.strokeWidth}px`,\n borderRadius: `${G9Metrics.RadiusMd}px`,\n opacity: paint.opacity,\n paddingLeft: `${preset.paddingHorizontal}px`,\n paddingRight: `${preset.paddingHorizontal}px`,\n paddingTop: '0px',\n paddingBottom: '0px',\n }}\n bindtap={press}\n {...visual}\n >\n {loading ? (\n <G9ActivityIndicator running size={iconSize} color={props.spinnerColor ?? paint.text} />\n ) : hasIconSlot(leading) ? (\n <G9IconSlot {...leading} size={iconSize} color={paint.text} />\n ) : null}\n {label.trim() !== '' ? (\n <text\n className=\"g9-button__label\"\n {...(truncate ? { 'text-maxline': '1' } : {})}\n style={{\n color: paint.text,\n fontSize: `${props.fontSize && props.fontSize > 0 ? props.fontSize : preset.fontSize}px`,\n ...fontAttributesStyle(props.fontAttributes ?? 'bold'),\n ...(truncate ? { textOverflow: 'ellipsis', overflow: 'hidden' } : { whiteSpace: 'nowrap' }),\n }}\n >\n {label}\n </text>\n ) : null}\n {!loading && hasIconSlot(trailing) ? <G9IconSlot {...trailing} size={iconSize} color={paint.text} /> : null}\n </view>\n );\n}\n"],"names":["G9Button","props","_props_size","_props_variant","_props_loadingText","_props_text","_props_accessibilityLabel","_ref","_props_spinnerColor","_props_fontAttributes","control","useG9Control","theme","useG9Theme","loading","enabled","preset","buttonSizePreset","height","paint","resolveButtonPaint","iconSize","G9Metrics","press","useG9Press","visual","usePressVisual","leading","trailing","label","truncate","view","g9RowStyle","G9ActivityIndicator","hasIconSlot","G9IconSlot","text","fontAttributesStyle"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import './fields.css';
2
2
  import { G9FilledValueHighlight, type G9ImageSource } from '@g9tm/lynxcontrols-foundation';
3
- import type { ReactNode } from '@lynx-js/react';
3
+ import { type ReactNode } from '@lynx-js/react';
4
4
  import type { G9IconInput } from '../icon/icon.js';
5
5
  import { type G9PhysicalPadding } from './slot-layout.js';
6
6
  /** Props every outlined field shares (the public members of MAUI `G9OutlinedFieldBase`). */
@@ -1 +1 @@
1
- {"version":3,"file":"outlined-field.d.ts","sourceRoot":"","sources":["../../src/fields/outlined-field.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"outlined-field.d.ts","sourceRoot":"","sources":["../../src/fields/outlined-field.tsx"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import "./fields.css";
2
2
  import { G9FilledValueHighlight, G9Metrics } from "@g9tm/lynxcontrols-foundation";
3
+ import { useState } from "@lynx-js/react";
3
4
  import { g9IdProps, g9RowStyle } from "../base/control.jsx";
4
5
  import { g9KeyboardTargetProps } from "../host/keyboard.jsx";
5
6
  import { G9IconSlot, hasIconSlot } from "../icon/slot.jsx";
@@ -113,7 +114,8 @@ function G9OutlinedField(props) {
113
114
  };
114
115
  const multiline = true === props.multiline;
115
116
  const labelHeight = G9Metrics.FloatingLabelHeight;
116
- const restTop = multiline ? (G9Metrics.ControlHeight - labelHeight) / 2 : (state.fieldHeight - labelHeight) / 2;
117
+ const [boxHeight, setBoxHeight] = useState(0);
118
+ const restTop = ((multiline && boxHeight > 8 ? boxHeight : multiline ? G9Metrics.ControlHeight : state.fieldHeight) - labelHeight) / 2;
117
119
  const labelX = slot.labelRestX + (state.floated ? slot.labelFloatedX : 0);
118
120
  const labelAnchor = isRtl ? 'right' : 'left';
119
121
  const iconSize = G9Metrics.InputIconSize;
@@ -137,7 +139,14 @@ function G9OutlinedField(props) {
137
139
  height: multiline ? void 0 : `${state.fieldHeight}px`,
138
140
  minHeight: multiline ? `${state.fieldHeight}px` : void 0,
139
141
  marginTop: props.reserveFloatingLabelClearance ? `${G9Metrics.FloatingLabelClearance}px` : '0px'
140
- }} bindtap={onBoxTap}>
142
+ }} bindtap={onBoxTap} {...multiline ? {
143
+ bindlayoutchange: (e)=>{
144
+ var _ref;
145
+ var _e_detail;
146
+ const h = null != (_ref = null == (_e_detail = e.detail) ? void 0 : _e_detail.height) ? _ref : 0;
147
+ if (Math.abs(h - boxHeight) > 0.5) setBoxHeight(h);
148
+ }
149
+ } : {}}>
141
150
  {}
142
151
  <view className="g9-field__outline" style={{
143
152
  borderColor: state.stateColor,
@@ -190,7 +199,8 @@ function G9OutlinedField(props) {
190
199
  }}>
191
200
  {state.helperText}
192
201
  </text> : <view className="g9-field__helper"/>}
193
- {state.counterText ? <text className="g9-field__counter">{state.counterText}</text> : null}
202
+ {}
203
+ {state.counterText ? <text className="g9-field__counter">{`${isRtl ? '\u200F' : ''}${state.counterText}`}</text> : null}
194
204
  </view> : null}
195
205
  </view>;
196
206
  }
@@ -1 +1 @@
1
- {"version":3,"file":"fields/outlined-field.jsx","sources":["../../src/fields/outlined-field.tsx"],"sourcesContent":["import './fields.css';\nimport { G9FilledValueHighlight, type G9ImageSource, G9Metrics } from '@g9tm/lynxcontrols-foundation';\nimport type { ReactNode } from '@lynx-js/react';\nimport { g9IdProps, g9RowStyle } from '../base/control';\nimport { g9KeyboardTargetProps } from '../host/keyboard';\nimport type { G9IconInput } from '../icon/icon';\nimport { G9IconSlot, hasIconSlot } from '../icon/slot';\nimport { useG9Direction, useG9Settings } from '../provider/hooks';\nimport { type G9PhysicalPadding, resolveFieldSlotLayout } from './slot-layout';\n\n// MAUI `G9OutlinedFieldBase` (Controls/Shared/G9OutlinedFieldBase.cs) as composition (plan/specs/03 §5): the\n// props every outlined input shares, a pure state resolver, `useOutlinedField`, and the `<G9OutlinedField>` frame the\n// inputs put their element into.\n\n/** Props every outlined field shares (the public members of MAUI `G9OutlinedFieldBase`). */\nexport interface G9OutlinedFieldProps {\n /**\n * Element `id` of the field root (MAUI `AutomationId`; automation taps its bounds to focus it). Used verbatim: keep\n * it to `[A-Za-z0-9_-]`.\n */\n readonly id?: string;\n /** Floating label. Without it the placeholder is the label (MAUI `Label ?? Placeholder`). */\n readonly label?: string | null;\n /** Placeholder; shown as the label when `label` is not set. */\n readonly placeholder?: string | null;\n /** Helper line under the field; replaced by `errorText` while the field has an error. */\n readonly helperText?: string | null;\n /** Error message, shown (in the error colour) while `hasError`. */\n readonly errorText?: string | null;\n /** Error state: error outline, label and helper colour. Validation can also set it (`validate()`). Default false. */\n readonly hasError?: boolean;\n /** Keep the label floated even when empty and unfocused. Default false. */\n readonly alwaysFloat?: boolean;\n /** Value visible and selectable but not editable (MAUI `IsReadOnly`). Default false. */\n readonly readOnly?: boolean;\n /** Not interactive and dimmed (MAUI `IsEnabled = false`). Default false. */\n readonly disabled?: boolean;\n /** Maximum characters; `-1` (default) or `0` means unlimited. */\n readonly maxLength?: number;\n /** Show the `n / max` counter (only when `maxLength > 0`). Default false. */\n readonly showCharacterCounter?: boolean;\n /** Status colour (any CSS colour or `g9Token(...)`); used while `useStatusColor`. Default the primary colour. */\n readonly statusColor?: string | null;\n /** Draw the outline in `statusColor` (emphasised) whatever the focus. Default false. */\n readonly useStatusColor?: boolean;\n /** Soft inner halo while focused (no error, no status colour). Default false. */\n readonly showFocusHalo?: boolean;\n /** Filled-value accent of this field; `'inherit'` (default) takes `settings.fields.highlightFilledValue`. */\n readonly filledValueHighlight?: G9FilledValueHighlight;\n readonly leadingEmoji?: string | null;\n readonly leadingIcon?: G9IconInput;\n readonly leadingImagePath?: string | null;\n readonly leadingImage?: G9ImageSource | null;\n readonly trailingEmoji?: string | null;\n readonly trailingIcon?: G9IconInput;\n readonly trailingImagePath?: string | null;\n readonly trailingImage?: G9ImageSource | null;\n /** Spinner in the trailing slot (wins over every trailing icon). Default false. */\n readonly isTrailingBusy?: boolean;\n /** Keep the trailing icon on the physical right in RTL too. Default false. */\n readonly forceTrailingIconRight?: boolean;\n /** Keep the leading icon on the physical left in RTL too. Default false. */\n readonly forceLeadingIconLeft?: boolean;\n /** Box height; `0` (default) uses `G9Metrics.ControlHeight` (52). */\n readonly fieldHeight?: number;\n /** Reserve the floated label's overhang above the box (MAUI `FloatingLabelClearance`, 6). Default false. */\n readonly reserveFloatingLabelClearance?: boolean;\n /** Leading icon tap (MAUI `LeadingCommand` + `CommandParameter`). Makes the icon actionable. */\n readonly onLeadingPress?: () => void;\n /** Trailing icon tap when no built-in affordance claims it (MAUI `TrailingCommand`). */\n readonly onTrailingPress?: () => void;\n /** Extra padding of the inner content (MAUI `InnerContentPadding`), physical sides. */\n readonly innerContentPadding?: Partial<G9PhysicalPadding>;\n /** Class of the root element. */\n readonly className?: string;\n}\n\n/** What {@link resolveOutlinedFieldState} needs besides the props. */\nexport interface G9OutlinedFieldStateInput {\n readonly focused: boolean;\n readonly hasValue: boolean;\n /** A value the field shows without text (a picker's selection): floats the label like a value. */\n readonly valueFloated?: boolean;\n /** App-wide filled-value accent (`settings.fields.highlightFilledValue`). */\n readonly highlightFilledValue: boolean;\n /** Characters of the value, for the counter. */\n readonly textLength: number;\n /** Resting chrome tone: `'outline'` (default) or `'placeholder'` (search). */\n readonly restingTone?: 'outline' | 'placeholder';\n}\n\n/** The resolved look of an outlined field (colours are CSS colour values). */\nexport interface G9OutlinedFieldState {\n readonly floated: boolean;\n /** Outline, floated label and trailing icon colour. */\n readonly stateColor: string;\n readonly labelColor: string;\n /** Leading icon and resting label colour. */\n readonly restingContentColor: string;\n readonly labelText: string;\n /** Helper line text (`errorText` while in error), `''` when hidden. */\n readonly helperText: string;\n readonly helperColor: string;\n /** Counter text (`'n / max'`), `''` when hidden. */\n readonly counterText: string;\n readonly footerVisible: boolean;\n readonly strokeWidth: number;\n /** Focus halo thickness, 0 when off. */\n readonly haloWidth: number;\n readonly fieldHeight: number;\n}\n\nconst v = (token: string): string => `var(--g9-${token})`;\n\n/**\n * Resolves the field's state colours and footer (MAUI `ResolveStateColor`, `ResolveFloatingLabelColor`, the footer\n * part of `Refresh`). Precedence: error > status colour > focus > accented filled value > resting.\n */\nexport function resolveOutlinedFieldState(\n props: G9OutlinedFieldProps,\n input: G9OutlinedFieldStateInput,\n): G9OutlinedFieldState {\n const hasError = props.hasError === true;\n const useStatus = props.useStatusColor === true;\n const filled = input.hasValue || input.valueFloated === true;\n const highlight = props.filledValueHighlight ?? G9FilledValueHighlight.Inherit;\n const accentFilled =\n highlight === G9FilledValueHighlight.Accent\n ? true\n : highlight === G9FilledValueHighlight.Neutral\n ? false\n : input.highlightFilledValue;\n const placeholderTone = input.restingTone === 'placeholder';\n const restingOutline = placeholderTone ? v('input-placeholder') : v('outline');\n const restingContentColor = placeholderTone ? v('input-placeholder') : v('text-tertiary');\n let stateColor: string;\n if (hasError) stateColor = v('error');\n else if (useStatus) stateColor = props.statusColor ?? v('primary');\n else if (input.focused) stateColor = v('primary');\n else stateColor = filled && accentFilled ? v('primary') : restingOutline;\n\n const floated = props.alwaysFloat === true || input.valueFloated === true || input.focused || input.hasValue;\n const neutralFilledRest = filled && !input.focused && !hasError && !useStatus && !accentFilled;\n const labelColor = floated && !neutralFilledRest ? stateColor : restingContentColor;\n\n const helperRaw = hasError ? (props.errorText ?? '') : (props.helperText ?? '');\n const helperText = helperRaw.trim() === '' ? '' : helperRaw;\n const maxLength = props.maxLength ?? -1;\n const counterText = props.showCharacterCounter === true && maxLength > 0 ? `${input.textLength} / ${maxLength}` : '';\n const emphasis = input.focused || hasError || useStatus;\n const halo = props.showFocusHalo === true && input.focused && !hasError && !useStatus;\n const labelRaw = props.label ?? props.placeholder ?? '';\n return {\n floated,\n stateColor,\n labelColor,\n restingContentColor,\n labelText: labelRaw.trim() === '' ? '' : labelRaw,\n helperText,\n helperColor: hasError ? v('error') : v('text-tertiary'),\n counterText,\n footerVisible: helperText !== '' || counterText !== '',\n strokeWidth: emphasis ? G9Metrics.OutlinedFieldEmphasisStrokeThickness : G9Metrics.OutlinedFieldStrokeThickness,\n haloWidth: halo ? G9Metrics.OutlinedFieldFocusHaloThickness : 0,\n fieldHeight: props.fieldHeight && props.fieldHeight > 0 ? props.fieldHeight : G9Metrics.ControlHeight,\n };\n}\n\n/** {@link resolveOutlinedFieldState} with the app-wide settings read from the provider. */\nexport function useOutlinedField(\n props: G9OutlinedFieldProps,\n input: Omit<G9OutlinedFieldStateInput, 'highlightFilledValue'>,\n): G9OutlinedFieldState {\n const settings = useG9Settings();\n return resolveOutlinedFieldState(props, { ...input, highlightFilledValue: settings.fields.highlightFilledValue });\n}\n\n/** A built-in trailing affordance an input puts in the trailing slot (password eye, microphone, clear). */\nexport interface G9TrailingAffordance {\n /** What it shows. */\n readonly icon: G9IconInput;\n /** Icon colour; default the state colour. */\n readonly color?: string;\n /** Accessibility label. */\n readonly label?: string;\n /** Stable key (MAUI `ResolveTrailingIconSignature`): the slot is rebuilt only when it changes. */\n readonly signature: string;\n readonly onPress: () => void;\n}\n\n/** Props of {@link G9OutlinedField}: the shared props plus what the composing input supplies. */\nexport interface G9OutlinedFieldFrameProps extends G9OutlinedFieldProps {\n readonly focused: boolean;\n readonly hasValue: boolean;\n readonly valueFloated?: boolean;\n readonly textLength?: number;\n /** The input element (or any content) inside the box. */\n readonly children?: ReactNode;\n /** A built-in trailing affordance; replaces the trailing icon props (busy still wins). */\n readonly trailingAffordance?: G9TrailingAffordance | null;\n /** Tapping the box (outside the icons) focuses the content (MAUI `FocusTarget`). */\n readonly onFocusRequest?: () => void;\n /** Resting tone (`'placeholder'` for search, MAUI `ResolveRestingOutlineColor` override). */\n readonly restingTone?: 'outline' | 'placeholder';\n /** Vertical placement of the icons and the resting label: centred (entries) or top/bottom (editor). */\n readonly multiline?: boolean;\n /** Accessibility label of the box (defaults to the label text). */\n readonly accessibilityLabel?: string;\n}\n\nfunction physicalSide(column: 0 | 2): 'left' | 'right' {\n return column === 0 ? 'left' : 'right';\n}\n\n/**\n * The outlined field frame (MAUI `G9OutlinedFieldBase`): outline with a notched floating label, leading and\n * trailing icon slots, helper/error line and counter. Inputs (`G9TextEntry`, `G9Editor`, `G9SearchEntry`, the pickers)\n * put their element in `children`. Direction is set on the root from the culture (labels, icons, helper follow it;\n * the input decides its own text direction). A tap on an icon never focuses the content; a tap elsewhere on the box\n * calls `onFocusRequest`.\n *\n * Look: colours come from the theme variables (`--g9-primary`, `--g9-outline`, `--g9-error`, …). The floated label\n * sits on the outline with the background `--g9-field-notch-background` (default `--g9-background`; set it on a\n * container of another colour with `g9FieldNotchStyle`, G9 sheets and popups do), which hides the\n * outline under it.\n */\nexport function G9OutlinedField(props: G9OutlinedFieldFrameProps): ReactNode {\n const direction = useG9Direction();\n const isRtl = direction === 'rtl';\n const state = useOutlinedField(props, {\n focused: props.focused,\n hasValue: props.hasValue,\n valueFloated: props.valueFloated ?? false,\n textLength: props.textLength ?? 0,\n restingTone: props.restingTone ?? 'outline',\n });\n const leading = {\n emoji: props.leadingEmoji ?? null,\n icon: props.leadingIcon,\n imagePath: props.leadingImagePath ?? null,\n image: props.leadingImage ?? null,\n };\n const trailing = {\n emoji: props.trailingEmoji ?? null,\n icon: props.trailingIcon,\n imagePath: props.trailingImagePath ?? null,\n image: props.trailingImage ?? null,\n };\n const busy = props.isTrailingBusy === true;\n const affordance = props.trailingAffordance ?? null;\n const hasLeading = hasIconSlot(leading);\n const hasTrailing = busy || affordance !== null || hasIconSlot(trailing);\n const pad = props.innerContentPadding ?? {};\n const slot = resolveFieldSlotLayout(\n {\n hasLeadingIcon: hasLeading,\n hasTrailingIcon: hasTrailing,\n isRtl,\n forceTrailingIconRight: props.forceTrailingIconRight === true,\n forceLeadingIconLeft: props.forceLeadingIconLeft === true,\n },\n { left: pad.left ?? 0, top: pad.top ?? 0, right: pad.right ?? 0, bottom: pad.bottom ?? 0 },\n );\n const disabled = props.disabled === true;\n const leadingActionable = props.onLeadingPress !== undefined;\n const trailingActionable = affordance !== null || props.onTrailingPress !== undefined;\n const onLeadingTap = () => {\n if (disabled || !leadingActionable) return;\n props.onLeadingPress?.();\n };\n const onTrailingTap = () => {\n if (disabled || busy || !trailingActionable) return;\n if (affordance) affordance.onPress();\n else props.onTrailingPress?.();\n };\n const onBoxTap = () => {\n if (!disabled) props.onFocusRequest?.();\n };\n\n const multiline = props.multiline === true;\n const labelHeight = G9Metrics.FloatingLabelHeight;\n const restTop = multiline ? (G9Metrics.ControlHeight - labelHeight) / 2 : (state.fieldHeight - labelHeight) / 2;\n const labelX = slot.labelRestX + (state.floated ? slot.labelFloatedX : 0);\n const labelAnchor = isRtl ? 'right' : 'left';\n const iconSize = G9Metrics.InputIconSize;\n const slotStyle = (column: 0 | 2, width: number, bottomAligned: boolean) => ({\n [physicalSide(column)]: '0px',\n width: `${width}px`,\n ...(bottomAligned\n ? { bottom: '0px', height: `${G9Metrics.EditorTrailingSlotHeight}px` }\n : { top: '0px', bottom: '0px' }),\n });\n\n const trailingContent = busy ? (\n <view className=\"g9-field__busy\" style={{ borderColor: state.stateColor, borderTopColor: 'transparent' }} />\n ) : affordance ? (\n <G9IconSlot icon={affordance.icon} color={affordance.color ?? state.stateColor} size={iconSize} />\n ) : (\n <G9IconSlot {...trailing} color={state.stateColor} size={iconSize} />\n );\n\n return (\n <view\n className={`g9-field g9-dir-${direction}${disabled ? ' g9-field--disabled' : ''}${props.className ? ` ${props.className}` : ''}`}\n {...g9IdProps(props.id)}\n >\n <view\n {...g9KeyboardTargetProps}\n className={`g9-field__box${state.floated ? ' g9-field__box--floated' : ''}${props.focused ? ' g9-field__box--focused' : ''}`}\n accessibility-element={false}\n style={{\n height: multiline ? undefined : `${state.fieldHeight}px`,\n minHeight: multiline ? `${state.fieldHeight}px` : undefined,\n marginTop: props.reserveFloatingLabelClearance ? `${G9Metrics.FloatingLabelClearance}px` : '0px',\n }}\n bindtap={onBoxTap}\n >\n {/* The outline is its own view (MAUI paints it on a canvas): a stroke change never moves the content, and a\n disabled field dims it without an opacity layer on the box, which clipped the floated label on Android. */}\n <view\n className=\"g9-field__outline\"\n style={{\n borderColor: state.stateColor,\n borderWidth: `${state.strokeWidth}px`,\n borderRadius: `${G9Metrics.RadiusMd}px`,\n }}\n />\n {state.haloWidth > 0 ? (\n <view\n className=\"g9-field__halo\"\n style={{\n borderColor: state.stateColor,\n borderWidth: `${state.haloWidth}px`,\n opacity: G9Metrics.FocusRingOpacity,\n borderRadius: `${G9Metrics.RadiusMd}px`,\n }}\n />\n ) : null}\n <view\n className=\"g9-field__content\"\n style={{\n paddingLeft: `${slot.innerPadding.left + (hasLeading && slot.leadingColumn === 0 ? G9Metrics.LeadingIconSlotWidth : 0) + (hasTrailing && slot.trailingColumn === 0 ? G9Metrics.TrailingIconSlotWidth : 0)}px`,\n paddingRight: `${slot.innerPadding.right + (hasLeading && slot.leadingColumn === 2 ? G9Metrics.LeadingIconSlotWidth : 0) + (hasTrailing && slot.trailingColumn === 2 ? G9Metrics.TrailingIconSlotWidth : 0)}px`,\n paddingTop: `${slot.innerPadding.top}px`,\n paddingBottom: `${slot.innerPadding.bottom}px`,\n }}\n >\n {props.children}\n </view>\n {hasLeading ? (\n <view\n className=\"g9-field__slot g9-field__slot--leading\"\n style={slotStyle(slot.leadingColumn, G9Metrics.LeadingIconSlotWidth, false)}\n catchtap={onLeadingTap}\n {...(leadingActionable ? { 'accessibility-element': true, 'accessibility-traits': 'button' } : {})}\n >\n <G9IconSlot {...leading} color={state.restingContentColor} size={iconSize} />\n </view>\n ) : null}\n {hasTrailing ? (\n <view\n key={busy ? 'busy' : affordance ? affordance.signature : 'icon'}\n className=\"g9-field__slot g9-field__slot--trailing\"\n style={slotStyle(slot.trailingColumn, G9Metrics.TrailingIconSlotWidth, multiline && !busy)}\n catchtap={onTrailingTap}\n {...(trailingActionable\n ? {\n 'accessibility-element': true,\n 'accessibility-traits': 'button',\n ...(affordance?.label ? { 'accessibility-label': affordance.label } : {}),\n }\n : {})}\n >\n {trailingContent}\n </view>\n ) : null}\n {state.labelText ? (\n <text\n className={`g9-field__label${state.floated ? ' g9-field__label--floated' : ''}`}\n style={{\n [labelAnchor]: `${G9Metrics.InputHorizontalPadding}px`,\n top: `${state.floated ? G9Metrics.FloatingLabelFloatedY : restTop}px`,\n fontSize: `${state.floated ? G9Metrics.FloatingLabelFontSizeFloat : G9Metrics.FloatingLabelFontSizeRest}px`,\n color: disabled ? 'var(--g9-text-disabled)' : state.labelColor,\n transform: `translateX(${labelX}px)`,\n }}\n >\n {state.labelText}\n </text>\n ) : null}\n </view>\n {state.footerVisible ? (\n <view className=\"g9-field__footer\" style={g9RowStyle(direction)}>\n {state.helperText ? (\n <text\n className=\"g9-field__helper\"\n style={{ color: state.helperColor, textAlign: isRtl ? 'right' : 'left' }}\n >\n {state.helperText}\n </text>\n ) : (\n <view className=\"g9-field__helper\" />\n )}\n {state.counterText ? <text className=\"g9-field__counter\">{state.counterText}</text> : null}\n </view>\n ) : null}\n </view>\n );\n}\n"],"names":["v","token","resolveOutlinedFieldState","props","input","_props_filledValueHighlight","_props_statusColor","_props_errorText","_props_helperText","_props_maxLength","_ref","hasError","useStatus","filled","highlight","G9FilledValueHighlight","accentFilled","placeholderTone","restingOutline","restingContentColor","stateColor","floated","neutralFilledRest","labelColor","helperRaw","helperText","maxLength","counterText","emphasis","halo","labelRaw","G9Metrics","useOutlinedField","settings","useG9Settings","physicalSide","column","G9OutlinedField","_props_valueFloated","_props_textLength","_props_restingTone","_props_leadingEmoji","_props_leadingImagePath","_props_leadingImage","_props_trailingEmoji","_props_trailingImagePath","_props_trailingImage","_props_trailingAffordance","_props_innerContentPadding","_pad_left","_pad_top","_pad_right","_pad_bottom","_affordance_color","direction","useG9Direction","isRtl","state","leading","trailing","busy","affordance","hasLeading","hasIconSlot","hasTrailing","pad","slot","resolveFieldSlotLayout","disabled","leadingActionable","undefined","trailingActionable","onLeadingTap","onTrailingTap","onBoxTap","multiline","labelHeight","restTop","labelX","labelAnchor","iconSize","slotStyle","width","bottomAligned","trailingContent","view","G9IconSlot","g9IdProps","g9KeyboardTargetProps","text","g9RowStyle"],"mappings":"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"}
1
+ {"version":3,"file":"fields/outlined-field.jsx","sources":["../../src/fields/outlined-field.tsx"],"sourcesContent":["import './fields.css';\nimport { G9FilledValueHighlight, type G9ImageSource, G9Metrics } from '@g9tm/lynxcontrols-foundation';\nimport { type ReactNode, useState } from '@lynx-js/react';\nimport { g9IdProps, g9RowStyle } from '../base/control';\nimport { g9KeyboardTargetProps } from '../host/keyboard';\nimport type { G9IconInput } from '../icon/icon';\nimport { G9IconSlot, hasIconSlot } from '../icon/slot';\nimport { useG9Direction, useG9Settings } from '../provider/hooks';\nimport { type G9PhysicalPadding, resolveFieldSlotLayout } from './slot-layout';\n\n// MAUI `G9OutlinedFieldBase` (Controls/Shared/G9OutlinedFieldBase.cs) as composition (plan/specs/03 §5): the\n// props every outlined input shares, a pure state resolver, `useOutlinedField`, and the `<G9OutlinedField>` frame the\n// inputs put their element into.\n\n/** Props every outlined field shares (the public members of MAUI `G9OutlinedFieldBase`). */\nexport interface G9OutlinedFieldProps {\n /**\n * Element `id` of the field root (MAUI `AutomationId`; automation taps its bounds to focus it). Used verbatim: keep\n * it to `[A-Za-z0-9_-]`.\n */\n readonly id?: string;\n /** Floating label. Without it the placeholder is the label (MAUI `Label ?? Placeholder`). */\n readonly label?: string | null;\n /** Placeholder; shown as the label when `label` is not set. */\n readonly placeholder?: string | null;\n /** Helper line under the field; replaced by `errorText` while the field has an error. */\n readonly helperText?: string | null;\n /** Error message, shown (in the error colour) while `hasError`. */\n readonly errorText?: string | null;\n /** Error state: error outline, label and helper colour. Validation can also set it (`validate()`). Default false. */\n readonly hasError?: boolean;\n /** Keep the label floated even when empty and unfocused. Default false. */\n readonly alwaysFloat?: boolean;\n /** Value visible and selectable but not editable (MAUI `IsReadOnly`). Default false. */\n readonly readOnly?: boolean;\n /** Not interactive and dimmed (MAUI `IsEnabled = false`). Default false. */\n readonly disabled?: boolean;\n /** Maximum characters; `-1` (default) or `0` means unlimited. */\n readonly maxLength?: number;\n /** Show the `n / max` counter (only when `maxLength > 0`). Default false. */\n readonly showCharacterCounter?: boolean;\n /** Status colour (any CSS colour or `g9Token(...)`); used while `useStatusColor`. Default the primary colour. */\n readonly statusColor?: string | null;\n /** Draw the outline in `statusColor` (emphasised) whatever the focus. Default false. */\n readonly useStatusColor?: boolean;\n /** Soft inner halo while focused (no error, no status colour). Default false. */\n readonly showFocusHalo?: boolean;\n /** Filled-value accent of this field; `'inherit'` (default) takes `settings.fields.highlightFilledValue`. */\n readonly filledValueHighlight?: G9FilledValueHighlight;\n readonly leadingEmoji?: string | null;\n readonly leadingIcon?: G9IconInput;\n readonly leadingImagePath?: string | null;\n readonly leadingImage?: G9ImageSource | null;\n readonly trailingEmoji?: string | null;\n readonly trailingIcon?: G9IconInput;\n readonly trailingImagePath?: string | null;\n readonly trailingImage?: G9ImageSource | null;\n /** Spinner in the trailing slot (wins over every trailing icon). Default false. */\n readonly isTrailingBusy?: boolean;\n /** Keep the trailing icon on the physical right in RTL too. Default false. */\n readonly forceTrailingIconRight?: boolean;\n /** Keep the leading icon on the physical left in RTL too. Default false. */\n readonly forceLeadingIconLeft?: boolean;\n /** Box height; `0` (default) uses `G9Metrics.ControlHeight` (52). */\n readonly fieldHeight?: number;\n /** Reserve the floated label's overhang above the box (MAUI `FloatingLabelClearance`, 6). Default false. */\n readonly reserveFloatingLabelClearance?: boolean;\n /** Leading icon tap (MAUI `LeadingCommand` + `CommandParameter`). Makes the icon actionable. */\n readonly onLeadingPress?: () => void;\n /** Trailing icon tap when no built-in affordance claims it (MAUI `TrailingCommand`). */\n readonly onTrailingPress?: () => void;\n /** Extra padding of the inner content (MAUI `InnerContentPadding`), physical sides. */\n readonly innerContentPadding?: Partial<G9PhysicalPadding>;\n /** Class of the root element. */\n readonly className?: string;\n}\n\n/** What {@link resolveOutlinedFieldState} needs besides the props. */\nexport interface G9OutlinedFieldStateInput {\n readonly focused: boolean;\n readonly hasValue: boolean;\n /** A value the field shows without text (a picker's selection): floats the label like a value. */\n readonly valueFloated?: boolean;\n /** App-wide filled-value accent (`settings.fields.highlightFilledValue`). */\n readonly highlightFilledValue: boolean;\n /** Characters of the value, for the counter. */\n readonly textLength: number;\n /** Resting chrome tone: `'outline'` (default) or `'placeholder'` (search). */\n readonly restingTone?: 'outline' | 'placeholder';\n}\n\n/** The resolved look of an outlined field (colours are CSS colour values). */\nexport interface G9OutlinedFieldState {\n readonly floated: boolean;\n /** Outline, floated label and trailing icon colour. */\n readonly stateColor: string;\n readonly labelColor: string;\n /** Leading icon and resting label colour. */\n readonly restingContentColor: string;\n readonly labelText: string;\n /** Helper line text (`errorText` while in error), `''` when hidden. */\n readonly helperText: string;\n readonly helperColor: string;\n /** Counter text (`'n / max'`), `''` when hidden. */\n readonly counterText: string;\n readonly footerVisible: boolean;\n readonly strokeWidth: number;\n /** Focus halo thickness, 0 when off. */\n readonly haloWidth: number;\n readonly fieldHeight: number;\n}\n\nconst v = (token: string): string => `var(--g9-${token})`;\n\n/**\n * Resolves the field's state colours and footer (MAUI `ResolveStateColor`, `ResolveFloatingLabelColor`, the footer\n * part of `Refresh`). Precedence: error > status colour > focus > accented filled value > resting.\n */\nexport function resolveOutlinedFieldState(\n props: G9OutlinedFieldProps,\n input: G9OutlinedFieldStateInput,\n): G9OutlinedFieldState {\n const hasError = props.hasError === true;\n const useStatus = props.useStatusColor === true;\n const filled = input.hasValue || input.valueFloated === true;\n const highlight = props.filledValueHighlight ?? G9FilledValueHighlight.Inherit;\n const accentFilled =\n highlight === G9FilledValueHighlight.Accent\n ? true\n : highlight === G9FilledValueHighlight.Neutral\n ? false\n : input.highlightFilledValue;\n const placeholderTone = input.restingTone === 'placeholder';\n const restingOutline = placeholderTone ? v('input-placeholder') : v('outline');\n const restingContentColor = placeholderTone ? v('input-placeholder') : v('text-tertiary');\n let stateColor: string;\n if (hasError) stateColor = v('error');\n else if (useStatus) stateColor = props.statusColor ?? v('primary');\n else if (input.focused) stateColor = v('primary');\n else stateColor = filled && accentFilled ? v('primary') : restingOutline;\n\n const floated = props.alwaysFloat === true || input.valueFloated === true || input.focused || input.hasValue;\n const neutralFilledRest = filled && !input.focused && !hasError && !useStatus && !accentFilled;\n const labelColor = floated && !neutralFilledRest ? stateColor : restingContentColor;\n\n const helperRaw = hasError ? (props.errorText ?? '') : (props.helperText ?? '');\n const helperText = helperRaw.trim() === '' ? '' : helperRaw;\n const maxLength = props.maxLength ?? -1;\n const counterText = props.showCharacterCounter === true && maxLength > 0 ? `${input.textLength} / ${maxLength}` : '';\n const emphasis = input.focused || hasError || useStatus;\n const halo = props.showFocusHalo === true && input.focused && !hasError && !useStatus;\n const labelRaw = props.label ?? props.placeholder ?? '';\n return {\n floated,\n stateColor,\n labelColor,\n restingContentColor,\n labelText: labelRaw.trim() === '' ? '' : labelRaw,\n helperText,\n helperColor: hasError ? v('error') : v('text-tertiary'),\n counterText,\n footerVisible: helperText !== '' || counterText !== '',\n strokeWidth: emphasis ? G9Metrics.OutlinedFieldEmphasisStrokeThickness : G9Metrics.OutlinedFieldStrokeThickness,\n haloWidth: halo ? G9Metrics.OutlinedFieldFocusHaloThickness : 0,\n fieldHeight: props.fieldHeight && props.fieldHeight > 0 ? props.fieldHeight : G9Metrics.ControlHeight,\n };\n}\n\n/** {@link resolveOutlinedFieldState} with the app-wide settings read from the provider. */\nexport function useOutlinedField(\n props: G9OutlinedFieldProps,\n input: Omit<G9OutlinedFieldStateInput, 'highlightFilledValue'>,\n): G9OutlinedFieldState {\n const settings = useG9Settings();\n return resolveOutlinedFieldState(props, { ...input, highlightFilledValue: settings.fields.highlightFilledValue });\n}\n\n/** A built-in trailing affordance an input puts in the trailing slot (password eye, microphone, clear). */\nexport interface G9TrailingAffordance {\n /** What it shows. */\n readonly icon: G9IconInput;\n /** Icon colour; default the state colour. */\n readonly color?: string;\n /** Accessibility label. */\n readonly label?: string;\n /** Stable key (MAUI `ResolveTrailingIconSignature`): the slot is rebuilt only when it changes. */\n readonly signature: string;\n readonly onPress: () => void;\n}\n\n/** Props of {@link G9OutlinedField}: the shared props plus what the composing input supplies. */\nexport interface G9OutlinedFieldFrameProps extends G9OutlinedFieldProps {\n readonly focused: boolean;\n readonly hasValue: boolean;\n readonly valueFloated?: boolean;\n readonly textLength?: number;\n /** The input element (or any content) inside the box. */\n readonly children?: ReactNode;\n /** A built-in trailing affordance; replaces the trailing icon props (busy still wins). */\n readonly trailingAffordance?: G9TrailingAffordance | null;\n /** Tapping the box (outside the icons) focuses the content (MAUI `FocusTarget`). */\n readonly onFocusRequest?: () => void;\n /** Resting tone (`'placeholder'` for search, MAUI `ResolveRestingOutlineColor` override). */\n readonly restingTone?: 'outline' | 'placeholder';\n /** Vertical placement of the icons and the resting label: centred (entries) or top/bottom (editor). */\n readonly multiline?: boolean;\n /** Accessibility label of the box (defaults to the label text). */\n readonly accessibilityLabel?: string;\n}\n\nfunction physicalSide(column: 0 | 2): 'left' | 'right' {\n return column === 0 ? 'left' : 'right';\n}\n\n/**\n * The outlined field frame (MAUI `G9OutlinedFieldBase`): outline with a notched floating label, leading and\n * trailing icon slots, helper/error line and counter. Inputs (`G9TextEntry`, `G9Editor`, `G9SearchEntry`, the pickers)\n * put their element in `children`. Direction is set on the root from the culture (labels, icons, helper follow it;\n * the input decides its own text direction). A tap on an icon never focuses the content; a tap elsewhere on the box\n * calls `onFocusRequest`.\n *\n * Look: colours come from the theme variables (`--g9-primary`, `--g9-outline`, `--g9-error`, …). The floated label\n * sits on the outline with the background `--g9-field-notch-background` (default `--g9-background`; set it on a\n * container of another colour with `g9FieldNotchStyle`, G9 sheets and popups do), which hides the\n * outline under it.\n */\nexport function G9OutlinedField(props: G9OutlinedFieldFrameProps): ReactNode {\n const direction = useG9Direction();\n const isRtl = direction === 'rtl';\n const state = useOutlinedField(props, {\n focused: props.focused,\n hasValue: props.hasValue,\n valueFloated: props.valueFloated ?? false,\n textLength: props.textLength ?? 0,\n restingTone: props.restingTone ?? 'outline',\n });\n const leading = {\n emoji: props.leadingEmoji ?? null,\n icon: props.leadingIcon,\n imagePath: props.leadingImagePath ?? null,\n image: props.leadingImage ?? null,\n };\n const trailing = {\n emoji: props.trailingEmoji ?? null,\n icon: props.trailingIcon,\n imagePath: props.trailingImagePath ?? null,\n image: props.trailingImage ?? null,\n };\n const busy = props.isTrailingBusy === true;\n const affordance = props.trailingAffordance ?? null;\n const hasLeading = hasIconSlot(leading);\n const hasTrailing = busy || affordance !== null || hasIconSlot(trailing);\n const pad = props.innerContentPadding ?? {};\n const slot = resolveFieldSlotLayout(\n {\n hasLeadingIcon: hasLeading,\n hasTrailingIcon: hasTrailing,\n isRtl,\n forceTrailingIconRight: props.forceTrailingIconRight === true,\n forceLeadingIconLeft: props.forceLeadingIconLeft === true,\n },\n { left: pad.left ?? 0, top: pad.top ?? 0, right: pad.right ?? 0, bottom: pad.bottom ?? 0 },\n );\n const disabled = props.disabled === true;\n const leadingActionable = props.onLeadingPress !== undefined;\n const trailingActionable = affordance !== null || props.onTrailingPress !== undefined;\n const onLeadingTap = () => {\n if (disabled || !leadingActionable) return;\n props.onLeadingPress?.();\n };\n const onTrailingTap = () => {\n if (disabled || busy || !trailingActionable) return;\n if (affordance) affordance.onPress();\n else props.onTrailingPress?.();\n };\n const onBoxTap = () => {\n if (!disabled) props.onFocusRequest?.();\n };\n\n const multiline = props.multiline === true;\n const labelHeight = G9Metrics.FloatingLabelHeight;\n // MAUI rests the label in the middle of the box's MEASURED height (ResolveFieldHeight → _box.Height): an empty\n // editor of 110 dp shows «شرح» halfway down it, not on its first line. Before the first layout: the control height.\n const [boxHeight, setBoxHeight] = useState(0);\n const restTop =\n ((multiline && boxHeight > 8 ? boxHeight : multiline ? G9Metrics.ControlHeight : state.fieldHeight) - labelHeight) /\n 2;\n const labelX = slot.labelRestX + (state.floated ? slot.labelFloatedX : 0);\n const labelAnchor = isRtl ? 'right' : 'left';\n const iconSize = G9Metrics.InputIconSize;\n const slotStyle = (column: 0 | 2, width: number, bottomAligned: boolean) => ({\n [physicalSide(column)]: '0px',\n width: `${width}px`,\n ...(bottomAligned\n ? { bottom: '0px', height: `${G9Metrics.EditorTrailingSlotHeight}px` }\n : { top: '0px', bottom: '0px' }),\n });\n\n const trailingContent = busy ? (\n <view className=\"g9-field__busy\" style={{ borderColor: state.stateColor, borderTopColor: 'transparent' }} />\n ) : affordance ? (\n <G9IconSlot icon={affordance.icon} color={affordance.color ?? state.stateColor} size={iconSize} />\n ) : (\n <G9IconSlot {...trailing} color={state.stateColor} size={iconSize} />\n );\n\n return (\n <view\n className={`g9-field g9-dir-${direction}${disabled ? ' g9-field--disabled' : ''}${props.className ? ` ${props.className}` : ''}`}\n {...g9IdProps(props.id)}\n >\n <view\n {...g9KeyboardTargetProps}\n className={`g9-field__box${state.floated ? ' g9-field__box--floated' : ''}${props.focused ? ' g9-field__box--focused' : ''}`}\n accessibility-element={false}\n style={{\n height: multiline ? undefined : `${state.fieldHeight}px`,\n minHeight: multiline ? `${state.fieldHeight}px` : undefined,\n marginTop: props.reserveFloatingLabelClearance ? `${G9Metrics.FloatingLabelClearance}px` : '0px',\n }}\n bindtap={onBoxTap}\n {...(multiline\n ? {\n bindlayoutchange: (e: { detail?: { height?: number } }) => {\n const h = e.detail?.height ?? 0;\n if (Math.abs(h - boxHeight) > 0.5) setBoxHeight(h);\n },\n }\n : {})}\n >\n {/* The outline is its own view (MAUI paints it on a canvas): a stroke change never moves the content, and a\n disabled field dims it without an opacity layer on the box, which clipped the floated label on Android. */}\n <view\n className=\"g9-field__outline\"\n style={{\n borderColor: state.stateColor,\n borderWidth: `${state.strokeWidth}px`,\n borderRadius: `${G9Metrics.RadiusMd}px`,\n }}\n />\n {state.haloWidth > 0 ? (\n <view\n className=\"g9-field__halo\"\n style={{\n borderColor: state.stateColor,\n borderWidth: `${state.haloWidth}px`,\n opacity: G9Metrics.FocusRingOpacity,\n borderRadius: `${G9Metrics.RadiusMd}px`,\n }}\n />\n ) : null}\n <view\n className=\"g9-field__content\"\n style={{\n paddingLeft: `${slot.innerPadding.left + (hasLeading && slot.leadingColumn === 0 ? G9Metrics.LeadingIconSlotWidth : 0) + (hasTrailing && slot.trailingColumn === 0 ? G9Metrics.TrailingIconSlotWidth : 0)}px`,\n paddingRight: `${slot.innerPadding.right + (hasLeading && slot.leadingColumn === 2 ? G9Metrics.LeadingIconSlotWidth : 0) + (hasTrailing && slot.trailingColumn === 2 ? G9Metrics.TrailingIconSlotWidth : 0)}px`,\n paddingTop: `${slot.innerPadding.top}px`,\n paddingBottom: `${slot.innerPadding.bottom}px`,\n }}\n >\n {props.children}\n </view>\n {hasLeading ? (\n <view\n className=\"g9-field__slot g9-field__slot--leading\"\n style={slotStyle(slot.leadingColumn, G9Metrics.LeadingIconSlotWidth, false)}\n catchtap={onLeadingTap}\n {...(leadingActionable ? { 'accessibility-element': true, 'accessibility-traits': 'button' } : {})}\n >\n <G9IconSlot {...leading} color={state.restingContentColor} size={iconSize} />\n </view>\n ) : null}\n {hasTrailing ? (\n <view\n key={busy ? 'busy' : affordance ? affordance.signature : 'icon'}\n className=\"g9-field__slot g9-field__slot--trailing\"\n style={slotStyle(slot.trailingColumn, G9Metrics.TrailingIconSlotWidth, multiline && !busy)}\n catchtap={onTrailingTap}\n {...(trailingActionable\n ? {\n 'accessibility-element': true,\n 'accessibility-traits': 'button',\n ...(affordance?.label ? { 'accessibility-label': affordance.label } : {}),\n }\n : {})}\n >\n {trailingContent}\n </view>\n ) : null}\n {state.labelText ? (\n <text\n className={`g9-field__label${state.floated ? ' g9-field__label--floated' : ''}`}\n style={{\n [labelAnchor]: `${G9Metrics.InputHorizontalPadding}px`,\n top: `${state.floated ? G9Metrics.FloatingLabelFloatedY : restTop}px`,\n fontSize: `${state.floated ? G9Metrics.FloatingLabelFontSizeFloat : G9Metrics.FloatingLabelFontSizeRest}px`,\n color: disabled ? 'var(--g9-text-disabled)' : state.labelColor,\n transform: `translateX(${labelX}px)`,\n }}\n >\n {state.labelText}\n </text>\n ) : null}\n </view>\n {state.footerVisible ? (\n <view className=\"g9-field__footer\" style={g9RowStyle(direction)}>\n {state.helperText ? (\n <text\n className=\"g9-field__helper\"\n style={{ color: state.helperColor, textAlign: isRtl ? 'right' : 'left' }}\n >\n {state.helperText}\n </text>\n ) : (\n <view className=\"g9-field__helper\" />\n )}\n {/* RLM first in a right-to-left field: «0 / 4000» has no strong letter, so it would lay out left-to-right; MAUI's\n label inherits the RTL flow and reads «۴۰۰۰ / ۰». */}\n {state.counterText ? (\n <text className=\"g9-field__counter\">{`${isRtl ? '\\u200F' : ''}${state.counterText}`}</text>\n ) : null}\n </view>\n ) : null}\n </view>\n );\n}\n"],"names":["v","token","resolveOutlinedFieldState","props","input","_props_filledValueHighlight","_props_statusColor","_props_errorText","_props_helperText","_props_maxLength","_ref","hasError","useStatus","filled","highlight","G9FilledValueHighlight","accentFilled","placeholderTone","restingOutline","restingContentColor","stateColor","floated","neutralFilledRest","labelColor","helperRaw","helperText","maxLength","counterText","emphasis","halo","labelRaw","G9Metrics","useOutlinedField","settings","useG9Settings","physicalSide","column","G9OutlinedField","_props_valueFloated","_props_textLength","_props_restingTone","_props_leadingEmoji","_props_leadingImagePath","_props_leadingImage","_props_trailingEmoji","_props_trailingImagePath","_props_trailingImage","_props_trailingAffordance","_props_innerContentPadding","_pad_left","_pad_top","_pad_right","_pad_bottom","_affordance_color","direction","useG9Direction","isRtl","state","leading","trailing","busy","affordance","hasLeading","hasIconSlot","hasTrailing","pad","slot","resolveFieldSlotLayout","disabled","leadingActionable","undefined","trailingActionable","onLeadingTap","onTrailingTap","onBoxTap","multiline","labelHeight","boxHeight","setBoxHeight","useState","restTop","labelX","labelAnchor","iconSize","slotStyle","width","bottomAligned","trailingContent","view","G9IconSlot","g9IdProps","g9KeyboardTargetProps","e","_e_detail","h","Math","text","g9RowStyle"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"use-text-input.d.ts","sourceRoot":"","sources":["../../src/fields/use-text-input.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"use-text-input.d.ts","sourceRoot":"","sources":["../../src/fields/use-text-input.ts"],"names":[],"mappings":"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"}
@@ -5,7 +5,7 @@ import { startTimer } from "../base/timers.jsx";
5
5
  import { useControllableState } from "../base/use-controllable-state.jsx";
6
6
  import { g9KeyboardTargetProps } from "../host/keyboard.jsx";
7
7
  import { useG9Culture, useG9Strings } from "../provider/hooks.jsx";
8
- import { decimalSeparatorFor, inputTypeHasValidationRule, inputTypePrefersLeftToRight, sanitizeInputText, validateInputText } from "./input-policy.jsx";
8
+ import { inputTypeHasValidationRule, inputTypePrefersLeftToRight, sanitizeInputText, validateInputText } from "./input-policy.jsx";
9
9
  import { useDictation } from "./use-dictation.jsx";
10
10
  import { runTextValidator } from "./validator.jsx";
11
11
  function resolveInputTextDirection(inputTextDirection, inputType, isPassword, cultureDirection) {
@@ -41,7 +41,7 @@ function useTextInput(props, options) {
41
41
  const strings = useG9Strings();
42
42
  const keyboardAware = useContext(KeyboardAwareTriggerContext);
43
43
  const inputType = null != (_props_inputType = props.inputType) ? _props_inputType : G9InputType.Default;
44
- const separator = decimalSeparatorFor(culture.numberingSystem);
44
+ const separator = '.';
45
45
  const sanitize = (raw)=>sanitizeInputText(inputType, raw, props.allowedCharsPattern, separator);
46
46
  const [text, setText] = useControllableState({
47
47
  value: props.value,
@@ -1 +1 @@
1
- {"version":3,"file":"fields/use-text-input.jsx","sources":["../../src/fields/use-text-input.ts"],"sourcesContent":["import { G9InputType, type G9KeyboardType, G9TextInputDirection } from '@g9tm/lynxcontrols-foundation';\nimport { KeyboardAwareTriggerContext } from '@lynx-js/lynx-ui-input';\nimport { useContext, useEffect, useRef, useState } from '@lynx-js/react';\nimport type { NodesRef } from '@lynx-js/types';\nimport { startTimer } from '../base/timers';\nimport { useControllableState } from '../base/use-controllable-state';\nimport { g9KeyboardTargetProps } from '../host/keyboard';\nimport { useG9Culture, useG9Strings } from '../provider/hooks';\nimport {\n decimalSeparatorFor,\n inputTypeHasValidationRule,\n inputTypePrefersLeftToRight,\n sanitizeInputText,\n validateInputText,\n} from './input-policy';\nimport type { G9OutlinedFieldProps } from './outlined-field';\nimport { useDictation } from './use-dictation';\nimport { type G9TextValidator, runTextValidator } from './validator';\n\n/** Where a value change came from (plan/specs/03 §3). */\nexport type G9ValueChangeSource = 'user' | 'dictation' | 'clear' | 'programmatic';\n\n/** Payload of `onValueChange`. */\nexport interface G9ValueChangeDetails {\n readonly source: G9ValueChangeSource;\n}\n\n/** Props the text inputs (`G9TextEntry`, `G9Editor`, `G9SearchEntry`) share on top of the outlined-field props. */\nexport interface G9TextInputProps extends G9OutlinedFieldProps {\n /** The text (controlled; MAUI `Text`). Present, the caller owns it and must apply `onValueChange`. */\n readonly value?: string;\n /** Initial text while uncontrolled. Default `''`. */\n readonly defaultValue?: string;\n /**\n * Once per change of the field's value, with where it came from: `'user'` (typing, paste), `'dictation'`,\n * `'clear'` (the clear button) or `'programmatic'` (the field re-filtered a value it was given, e.g. after an\n * `inputType` change). Never for a value the parent pushed in that needed no filtering.\n */\n readonly onValueChange?: (value: string, details: G9ValueChangeDetails) => void;\n /** On-screen keyboard; used when `inputType` is `'default'` (any other type picks its own). Default `'default'`. */\n readonly keyboardType?: G9KeyboardType;\n /** Semantic input type: keyboard, live filter and blur validation. Default `'default'`. */\n readonly inputType?: G9InputType;\n /** Per-character filter regex (a single character class) for `inputType: 'custom'`. */\n readonly allowedCharsPattern?: string | null;\n /** Blur validation regex for `inputType: 'custom'`. An invalid pattern fails closed. */\n readonly validationPattern?: string | null;\n /** Message for a failed type validation; default the culture's `invalidEmail` / `invalidUrl` / `invalidValue`. */\n readonly validationErrorText?: string | null;\n /** Direction of the entered text; `'matchParent'` (default) pins numbers, phone, email, URL and passwords LTR. */\n readonly inputTextDirection?: G9TextInputDirection;\n /** Font family of the entered text; default the culture's font. */\n readonly customFont?: string | null;\n /** Offer dictation through `services.speech` (hidden without the service or recogniser). Default false. */\n readonly voiceEnabled?: boolean;\n /** Locale to recognise (MAUI `VoiceCulture`); default the active culture. */\n readonly voiceLocale?: string | null;\n readonly onVoiceListeningStarted?: () => void;\n readonly onVoiceListeningEnded?: () => void;\n /** Dictation could not run or finish; a localized message for a toast. */\n readonly onVoiceFailed?: (message: string) => void;\n /** Validation ran (blur, `validateOnTextChanged` or `validate()`): the message, or `null` when valid. */\n readonly onValidationChange?: (message: string | null) => void;\n readonly onFocus?: () => void;\n readonly onBlur?: () => void;\n /** The keyboard's confirm key was pressed. */\n readonly onConfirm?: (value: string) => void;\n /** Element id of the inner `<input>`/`<textarea>`. */\n readonly inputId?: string;\n}\n\n/** Imperative handle of the text inputs (MAUI public methods). */\nexport interface G9TextInputHandle {\n /** Focuses the inner element (raises the keyboard). */\n focus(): void;\n /** Removes focus (hides the keyboard). */\n blur(): void;\n /** Runs the validator and the type rule now; sets or clears the error; `true` when valid (MAUI `Validate`). */\n validate(): boolean;\n /** `true` while dictating (MAUI `IsListening`). */\n readonly isListening: boolean;\n /** MAUI `ToggleVoiceAsync`. */\n toggleVoice(): Promise<void>;\n /** MAUI `StartVoiceAsync`. */\n startVoice(): Promise<void>;\n /** MAUI `StopVoiceAsync`; safe when nothing runs. */\n stopVoice(): Promise<void>;\n /** The inner element's node ref (MAUI `InnerEntry` / `InnerEditor`), for `invoke` calls G9 does not wrap. */\n readonly element: G9NodeRef | null;\n}\n\n/** The Lynx node ref of a field's inner element. */\nexport type G9NodeRef = NodesRef;\n\n/** Lynx input event detail. */\ninterface InputDetail {\n readonly value?: string;\n readonly isComposing?: boolean;\n}\n\n/** Resolves the entered text's direction (MAUI `ResolveInputFlowDirection`). */\nexport function resolveInputTextDirection(\n inputTextDirection: G9TextInputDirection,\n inputType: G9InputType,\n isPassword: boolean,\n cultureDirection: 'ltr' | 'rtl',\n): 'ltr' | 'rtl' {\n if (inputTextDirection === G9TextInputDirection.LeftToRight) return 'ltr';\n if (inputTextDirection === G9TextInputDirection.RightToLeft) return 'rtl';\n if (inputTypePrefersLeftToRight(inputType) || isPassword) return 'ltr';\n return cultureDirection;\n}\n\n/** Calls a UI method on a node; a missing node or a failing call is ignored (the element is gone). */\nexport function invokeNode(\n ref: { current: G9NodeRef | null },\n method: string,\n params?: Record<string, unknown>,\n): boolean {\n const node = ref.current;\n if (!node) return false;\n try {\n node\n .invoke({\n method,\n ...(params ? { params } : {}),\n success: () => {},\n fail: () => {},\n })\n .exec();\n } catch {\n // The element was unmounted between the call and its execution.\n return false;\n }\n return true;\n}\n\n/**\n * {@link invokeNode}, retried on the next ticks (up to `attempts` times) while the element is not created natively\n * yet, e.g. a focus requested during the first commit.\n */\nexport function invokeNodeWhenReady(\n ref: { current: G9NodeRef | null },\n method: string,\n params?: Record<string, unknown>,\n attempts = 5,\n): void {\n if (invokeNode(ref, method, params) || attempts <= 0) return;\n startTimer(() => invokeNodeWhenReady(ref, method, params, attempts - 1), 0);\n}\n\ninterface ValidationResult {\n readonly message: string | null;\n // The external error props this result overrides; new props from the parent win again.\n readonly hasError: boolean | undefined;\n readonly errorText: string | null | undefined;\n}\n\n/** Options of {@link useTextInput}. */\nexport interface G9TextInputCoreOptions {\n /** Name for the controlled/uncontrolled diagnostic, e.g. `'G9TextEntry.value'`. */\n readonly name: string;\n /** Whether the microphone is shown, given the dictation and value state. */\n readonly showMic: (state: { available: boolean; listening: boolean; hasValue: boolean }) => boolean;\n /** Extra validator (`G9TextEntry.validator`; the editor has none). */\n readonly validator?: G9TextValidator | null;\n /** Validate on every change (`G9TextEntry.validateOnTextChanged`). */\n readonly validateOnTextChanged?: boolean;\n /** A password field (its text is pinned LTR). */\n readonly isPassword?: boolean;\n}\n\n/**\n * The state machine behind the text inputs: value ownership, the live filter, the native element sync, focus,\n * validation and dictation. Returns what the input element and the outlined frame need.\n */\nexport function useTextInput(props: G9TextInputProps, options: G9TextInputCoreOptions) {\n const culture = useG9Culture();\n const strings = useG9Strings();\n const keyboardAware = useContext(KeyboardAwareTriggerContext);\n const inputType = props.inputType ?? G9InputType.Default;\n const separator = decimalSeparatorFor(culture.numberingSystem);\n const sanitize = (raw: string) => sanitizeInputText(inputType, raw, props.allowedCharsPattern, separator);\n\n const [text, setText] = useControllableState<string, [G9ValueChangeDetails]>({\n value: props.value,\n defaultValue: props.defaultValue ?? '',\n onChange: props.onValueChange,\n name: options.name,\n });\n const display = sanitize(text);\n const latestText = useRef(display);\n latestText.current = display;\n\n const elementRef = useRef<NodesRef | null>(null);\n const native = useRef('');\n /** The last native input event was an IME composition (its commit may repeat the composed text). */\n const composingRef = useRef(false);\n const [focused, setFocused] = useState(false);\n const focusedRef = useRef(false);\n const [passwordVisible, setPasswordVisible] = useState(false);\n const [, bump] = useState(0);\n const [validation, setValidation] = useState<ValidationResult | null>(null);\n const hasValue = display !== '';\n\n const runValidation = (value: string): boolean => {\n const message =\n runTextValidator(options.validator, value) ??\n validateInputText(inputType, value, props.validationPattern, props.validationErrorText, strings);\n setValidation({ message, hasError: props.hasError, errorText: props.errorText });\n props.onValidationChange?.(message);\n return message === null;\n };\n const hasRule = options.validator != null || inputTypeHasValidationRule(inputType, props.validationPattern);\n\n const dictation = useDictation({\n enabled: props.voiceEnabled === true,\n locale: props.voiceLocale ?? null,\n readText: () => latestText.current,\n writeText: (value) => {\n setText(sanitize(value), { source: 'dictation' });\n },\n ...(props.onVoiceListeningStarted ? { onListeningStarted: props.onVoiceListeningStarted } : {}),\n ...(props.onVoiceListeningEnded ? { onListeningEnded: props.onVoiceListeningEnded } : {}),\n ...(props.onVoiceFailed ? { onFailed: props.onVoiceFailed } : {}),\n });\n\n // A value the field was given that its filter rejects is replaced once (MAUI OnTextChanged writes it back).\n const refiltered = useRef<string | null>(null);\n useEffect(() => {\n if (display !== text && refiltered.current !== text) {\n refiltered.current = text;\n setText(display, { source: 'programmatic' });\n }\n });\n\n // Keep the native element showing the field's value (lynx-ui pattern: `invoke('setValue')`). The node ref can\n // attach after the first effect, so attaching syncs too.\n const retries = useRef(0);\n const sync = () => {\n const value = latestText.current;\n if (native.current === value) return;\n if (invokeNode(elementRef, 'setValue', { value })) {\n native.current = value;\n retries.current = 0;\n } else if (elementRef.current && retries.current < 5) {\n // The element is not created natively yet (first commit): try again on the next tick.\n retries.current += 1;\n startTimer(() => syncRef.current(), 0);\n }\n };\n const syncRef = useRef(sync);\n syncRef.current = sync;\n const attach = useRef((node: NodesRef | null) => {\n elementRef.current = node;\n if (node) syncRef.current();\n }).current;\n useEffect(() => {\n sync();\n });\n\n // Clearing the value re-masks a revealed password (MAUI OnTextChanged).\n useEffect(() => {\n if (!hasValue && passwordVisible) setPasswordVisible(false);\n }, [hasValue, passwordVisible]);\n\n // New external error props win over an earlier validation result.\n const validationCurrent =\n validation !== null && validation.hasError === props.hasError && validation.errorText === props.errorText;\n const hasError = validationCurrent ? validation.message !== null : props.hasError === true;\n const errorText = validationCurrent && validation.message !== null ? validation.message : props.errorText;\n\n const onInput = (event: { detail?: InputDetail }) => {\n const raw = event.detail?.value ?? '';\n // Not an edit: the native element reports what it already holds (Android emits an empty `input` when a read-only\n // field is created, before `setValue` lands), or the user cannot type here at all. Forwarding it would wipe a\n // controlled value (a barcode field opened on an existing code came up empty).\n if (props.readOnly === true) {\n // Nobody types here: the native element drifted (Android clears a read-only input it just created) — show the\n // field's value again.\n native.current = raw;\n if (raw !== latestText.current) syncRef.current();\n return;\n }\n const composing = event.detail?.isComposing === true;\n const echo = !composing && !composingRef.current && raw === native.current;\n composingRef.current = composing;\n if (echo) return;\n native.current = raw;\n // IME composition is never interrupted: the composed text is filtered when it is committed.\n if (composing) return;\n const clean = sanitize(raw);\n latestText.current = clean;\n setText(clean, { source: 'user' });\n if (options.validateOnTextChanged) runValidation(clean);\n bump((n) => n + 1);\n };\n const onFocus = () => {\n focusedRef.current = true;\n setFocused(true);\n keyboardAware.onInputFocused?.();\n // Tapping the field while dictating means typing: end the session (ADR-0024).\n if (dictation.listening) void dictation.stop();\n props.onFocus?.();\n };\n const onBlur = () => {\n focusedRef.current = false;\n setFocused(false);\n keyboardAware.onInputBlurred?.();\n // Only fields with a rule validate on blur, so an externally set error survives.\n if (hasRule && latestText.current !== '') runValidation(latestText.current);\n props.onBlur?.();\n };\n const onConfirm = () => props.onConfirm?.(latestText.current);\n\n const focus = () => {\n if (props.disabled) return;\n invokeNode(elementRef, 'focus');\n };\n const blur = () => invokeNode(elementRef, 'blur');\n\n const showMic = options.showMic({ available: dictation.available, listening: dictation.listening, hasValue });\n const pressMic = () => {\n // The microphone never focuses the field, and starting takes the keyboard down (ADR-0024).\n if (!dictation.listening && focusedRef.current) blur();\n void dictation.toggle();\n };\n\n const direction = resolveInputTextDirection(\n props.inputTextDirection ?? G9TextInputDirection.MatchParent,\n inputType,\n options.isPassword === true,\n culture.direction,\n );\n const font =\n props.customFont && props.customFont.trim() !== ''\n ? props.customFont\n : culture.direction === 'rtl'\n ? culture.rtlFontFamily\n : culture.ltrFontFamily;\n\n const handle: G9TextInputHandle = {\n focus,\n blur,\n validate: () => runValidation(latestText.current),\n get isListening() {\n return dictation.listening;\n },\n toggleVoice: () => dictation.toggle(),\n startVoice: () => dictation.start(),\n stopVoice: () => dictation.stop(),\n get element() {\n return elementRef.current;\n },\n };\n\n return {\n text: display,\n setText,\n hasValue,\n focused,\n hasError,\n errorText,\n passwordVisible,\n setPasswordVisible,\n dictation,\n showMic,\n pressMic,\n focus,\n blur,\n handle,\n inputType,\n /** Element attributes and handlers shared by `<input>` and `<textarea>`. */\n elementProps: {\n ...g9KeyboardTargetProps,\n ref: attach,\n ...(props.inputId ? { id: props.inputId } : {}),\n 'ignore-focus': true,\n readonly: props.readOnly === true,\n disabled: props.disabled === true,\n maxlength: props.maxLength !== undefined && props.maxLength > 0 ? props.maxLength : 2147483647,\n bindinput: onInput,\n bindfocus: onFocus,\n bindblur: onBlur,\n bindconfirm: onConfirm,\n },\n textDirection: direction,\n font,\n };\n}\n"],"names":["resolveInputTextDirection","inputTextDirection","inputType","isPassword","cultureDirection","G9TextInputDirection","inputTypePrefersLeftToRight","invokeNode","ref","method","params","node","invokeNodeWhenReady","attempts","startTimer","useTextInput","props","options","_props_inputType","_props_defaultValue","_props_voiceLocale","_props_inputTextDirection","culture","useG9Culture","strings","useG9Strings","keyboardAware","useContext","KeyboardAwareTriggerContext","G9InputType","separator","decimalSeparatorFor","sanitize","raw","sanitizeInputText","text","setText","useControllableState","display","latestText","useRef","elementRef","native","composingRef","focused","setFocused","useState","focusedRef","passwordVisible","setPasswordVisible","bump","validation","setValidation","hasValue","runValidation","value","_runTextValidator","message","validateInputText","hasRule","inputTypeHasValidationRule","dictation","useDictation","refiltered","useEffect","retries","sync","syncRef","attach","validationCurrent","hasError","errorText","onInput","event","_event_detail","_event_detail1","composing","echo","clean","n","onFocus","onBlur","onConfirm","focus","blur","showMic","pressMic","direction","font","handle","g9KeyboardTargetProps","undefined"],"mappings":"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"}
1
+ {"version":3,"file":"fields/use-text-input.jsx","sources":["../../src/fields/use-text-input.ts"],"sourcesContent":["import { G9InputType, type G9KeyboardType, G9TextInputDirection } from '@g9tm/lynxcontrols-foundation';\nimport { KeyboardAwareTriggerContext } from '@lynx-js/lynx-ui-input';\nimport { useContext, useEffect, useRef, useState } from '@lynx-js/react';\nimport type { NodesRef } from '@lynx-js/types';\nimport { startTimer } from '../base/timers';\nimport { useControllableState } from '../base/use-controllable-state';\nimport { g9KeyboardTargetProps } from '../host/keyboard';\nimport { useG9Culture, useG9Strings } from '../provider/hooks';\nimport {\n inputTypeHasValidationRule,\n inputTypePrefersLeftToRight,\n sanitizeInputText,\n validateInputText,\n} from './input-policy';\nimport type { G9OutlinedFieldProps } from './outlined-field';\nimport { useDictation } from './use-dictation';\nimport { type G9TextValidator, runTextValidator } from './validator';\n\n/** Where a value change came from (plan/specs/03 §3). */\nexport type G9ValueChangeSource = 'user' | 'dictation' | 'clear' | 'programmatic';\n\n/** Payload of `onValueChange`. */\nexport interface G9ValueChangeDetails {\n readonly source: G9ValueChangeSource;\n}\n\n/** Props the text inputs (`G9TextEntry`, `G9Editor`, `G9SearchEntry`) share on top of the outlined-field props. */\nexport interface G9TextInputProps extends G9OutlinedFieldProps {\n /** The text (controlled; MAUI `Text`). Present, the caller owns it and must apply `onValueChange`. */\n readonly value?: string;\n /** Initial text while uncontrolled. Default `''`. */\n readonly defaultValue?: string;\n /**\n * Once per change of the field's value, with where it came from: `'user'` (typing, paste), `'dictation'`,\n * `'clear'` (the clear button) or `'programmatic'` (the field re-filtered a value it was given, e.g. after an\n * `inputType` change). Never for a value the parent pushed in that needed no filtering.\n */\n readonly onValueChange?: (value: string, details: G9ValueChangeDetails) => void;\n /** On-screen keyboard; used when `inputType` is `'default'` (any other type picks its own). Default `'default'`. */\n readonly keyboardType?: G9KeyboardType;\n /** Semantic input type: keyboard, live filter and blur validation. Default `'default'`. */\n readonly inputType?: G9InputType;\n /** Per-character filter regex (a single character class) for `inputType: 'custom'`. */\n readonly allowedCharsPattern?: string | null;\n /** Blur validation regex for `inputType: 'custom'`. An invalid pattern fails closed. */\n readonly validationPattern?: string | null;\n /** Message for a failed type validation; default the culture's `invalidEmail` / `invalidUrl` / `invalidValue`. */\n readonly validationErrorText?: string | null;\n /** Direction of the entered text; `'matchParent'` (default) pins numbers, phone, email, URL and passwords LTR. */\n readonly inputTextDirection?: G9TextInputDirection;\n /** Font family of the entered text; default the culture's font. */\n readonly customFont?: string | null;\n /** Offer dictation through `services.speech` (hidden without the service or recogniser). Default false. */\n readonly voiceEnabled?: boolean;\n /** Locale to recognise (MAUI `VoiceCulture`); default the active culture. */\n readonly voiceLocale?: string | null;\n readonly onVoiceListeningStarted?: () => void;\n readonly onVoiceListeningEnded?: () => void;\n /** Dictation could not run or finish; a localized message for a toast. */\n readonly onVoiceFailed?: (message: string) => void;\n /** Validation ran (blur, `validateOnTextChanged` or `validate()`): the message, or `null` when valid. */\n readonly onValidationChange?: (message: string | null) => void;\n readonly onFocus?: () => void;\n readonly onBlur?: () => void;\n /** The keyboard's confirm key was pressed. */\n readonly onConfirm?: (value: string) => void;\n /** Element id of the inner `<input>`/`<textarea>`. */\n readonly inputId?: string;\n}\n\n/** Imperative handle of the text inputs (MAUI public methods). */\nexport interface G9TextInputHandle {\n /** Focuses the inner element (raises the keyboard). */\n focus(): void;\n /** Removes focus (hides the keyboard). */\n blur(): void;\n /** Runs the validator and the type rule now; sets or clears the error; `true` when valid (MAUI `Validate`). */\n validate(): boolean;\n /** `true` while dictating (MAUI `IsListening`). */\n readonly isListening: boolean;\n /** MAUI `ToggleVoiceAsync`. */\n toggleVoice(): Promise<void>;\n /** MAUI `StartVoiceAsync`. */\n startVoice(): Promise<void>;\n /** MAUI `StopVoiceAsync`; safe when nothing runs. */\n stopVoice(): Promise<void>;\n /** The inner element's node ref (MAUI `InnerEntry` / `InnerEditor`), for `invoke` calls G9 does not wrap. */\n readonly element: G9NodeRef | null;\n}\n\n/** The Lynx node ref of a field's inner element. */\nexport type G9NodeRef = NodesRef;\n\n/** Lynx input event detail. */\ninterface InputDetail {\n readonly value?: string;\n readonly isComposing?: boolean;\n}\n\n/** Resolves the entered text's direction (MAUI `ResolveInputFlowDirection`). */\nexport function resolveInputTextDirection(\n inputTextDirection: G9TextInputDirection,\n inputType: G9InputType,\n isPassword: boolean,\n cultureDirection: 'ltr' | 'rtl',\n): 'ltr' | 'rtl' {\n if (inputTextDirection === G9TextInputDirection.LeftToRight) return 'ltr';\n if (inputTextDirection === G9TextInputDirection.RightToLeft) return 'rtl';\n if (inputTypePrefersLeftToRight(inputType) || isPassword) return 'ltr';\n return cultureDirection;\n}\n\n/** Calls a UI method on a node; a missing node or a failing call is ignored (the element is gone). */\nexport function invokeNode(\n ref: { current: G9NodeRef | null },\n method: string,\n params?: Record<string, unknown>,\n): boolean {\n const node = ref.current;\n if (!node) return false;\n try {\n node\n .invoke({\n method,\n ...(params ? { params } : {}),\n success: () => {},\n fail: () => {},\n })\n .exec();\n } catch {\n // The element was unmounted between the call and its execution.\n return false;\n }\n return true;\n}\n\n/**\n * {@link invokeNode}, retried on the next ticks (up to `attempts` times) while the element is not created natively\n * yet, e.g. a focus requested during the first commit.\n */\nexport function invokeNodeWhenReady(\n ref: { current: G9NodeRef | null },\n method: string,\n params?: Record<string, unknown>,\n attempts = 5,\n): void {\n if (invokeNode(ref, method, params) || attempts <= 0) return;\n startTimer(() => invokeNodeWhenReady(ref, method, params, attempts - 1), 0);\n}\n\ninterface ValidationResult {\n readonly message: string | null;\n // The external error props this result overrides; new props from the parent win again.\n readonly hasError: boolean | undefined;\n readonly errorText: string | null | undefined;\n}\n\n/** Options of {@link useTextInput}. */\nexport interface G9TextInputCoreOptions {\n /** Name for the controlled/uncontrolled diagnostic, e.g. `'G9TextEntry.value'`. */\n readonly name: string;\n /** Whether the microphone is shown, given the dictation and value state. */\n readonly showMic: (state: { available: boolean; listening: boolean; hasValue: boolean }) => boolean;\n /** Extra validator (`G9TextEntry.validator`; the editor has none). */\n readonly validator?: G9TextValidator | null;\n /** Validate on every change (`G9TextEntry.validateOnTextChanged`). */\n readonly validateOnTextChanged?: boolean;\n /** A password field (its text is pinned LTR). */\n readonly isPassword?: boolean;\n}\n\n/**\n * The state machine behind the text inputs: value ownership, the live filter, the native element sync, focus,\n * validation and dictation. Returns what the input element and the outlined frame need.\n */\nexport function useTextInput(props: G9TextInputProps, options: G9TextInputCoreOptions) {\n const culture = useG9Culture();\n const strings = useG9Strings();\n const keyboardAware = useContext(KeyboardAwareTriggerContext);\n const inputType = props.inputType ?? G9InputType.Default;\n // The decimal separator the FIELD holds is always the ASCII '.', whatever the culture: Lynx's native `digit` input\n // accepts only ASCII digits and '.', and silently dropped the Persian '٫' — 1.6 showed (and would be edited) as 16\n // (AgriPad's harvest weights, 2026-11-02). A typed '٫' still normalises to '.' (filterDecimal); the digits themselves\n // are drawn Persian by the app's font. decimalSeparatorFor stays for callers that format text for display.\n const separator = '.';\n const sanitize = (raw: string) => sanitizeInputText(inputType, raw, props.allowedCharsPattern, separator);\n\n const [text, setText] = useControllableState<string, [G9ValueChangeDetails]>({\n value: props.value,\n defaultValue: props.defaultValue ?? '',\n onChange: props.onValueChange,\n name: options.name,\n });\n const display = sanitize(text);\n const latestText = useRef(display);\n latestText.current = display;\n\n const elementRef = useRef<NodesRef | null>(null);\n const native = useRef('');\n /** The last native input event was an IME composition (its commit may repeat the composed text). */\n const composingRef = useRef(false);\n const [focused, setFocused] = useState(false);\n const focusedRef = useRef(false);\n const [passwordVisible, setPasswordVisible] = useState(false);\n const [, bump] = useState(0);\n const [validation, setValidation] = useState<ValidationResult | null>(null);\n const hasValue = display !== '';\n\n const runValidation = (value: string): boolean => {\n const message =\n runTextValidator(options.validator, value) ??\n validateInputText(inputType, value, props.validationPattern, props.validationErrorText, strings);\n setValidation({ message, hasError: props.hasError, errorText: props.errorText });\n props.onValidationChange?.(message);\n return message === null;\n };\n const hasRule = options.validator != null || inputTypeHasValidationRule(inputType, props.validationPattern);\n\n const dictation = useDictation({\n enabled: props.voiceEnabled === true,\n locale: props.voiceLocale ?? null,\n readText: () => latestText.current,\n writeText: (value) => {\n setText(sanitize(value), { source: 'dictation' });\n },\n ...(props.onVoiceListeningStarted ? { onListeningStarted: props.onVoiceListeningStarted } : {}),\n ...(props.onVoiceListeningEnded ? { onListeningEnded: props.onVoiceListeningEnded } : {}),\n ...(props.onVoiceFailed ? { onFailed: props.onVoiceFailed } : {}),\n });\n\n // A value the field was given that its filter rejects is replaced once (MAUI OnTextChanged writes it back).\n const refiltered = useRef<string | null>(null);\n useEffect(() => {\n if (display !== text && refiltered.current !== text) {\n refiltered.current = text;\n setText(display, { source: 'programmatic' });\n }\n });\n\n // Keep the native element showing the field's value (lynx-ui pattern: `invoke('setValue')`). The node ref can\n // attach after the first effect, so attaching syncs too.\n const retries = useRef(0);\n const sync = () => {\n const value = latestText.current;\n if (native.current === value) return;\n if (invokeNode(elementRef, 'setValue', { value })) {\n native.current = value;\n retries.current = 0;\n } else if (elementRef.current && retries.current < 5) {\n // The element is not created natively yet (first commit): try again on the next tick.\n retries.current += 1;\n startTimer(() => syncRef.current(), 0);\n }\n };\n const syncRef = useRef(sync);\n syncRef.current = sync;\n const attach = useRef((node: NodesRef | null) => {\n elementRef.current = node;\n if (node) syncRef.current();\n }).current;\n useEffect(() => {\n sync();\n });\n\n // Clearing the value re-masks a revealed password (MAUI OnTextChanged).\n useEffect(() => {\n if (!hasValue && passwordVisible) setPasswordVisible(false);\n }, [hasValue, passwordVisible]);\n\n // New external error props win over an earlier validation result.\n const validationCurrent =\n validation !== null && validation.hasError === props.hasError && validation.errorText === props.errorText;\n const hasError = validationCurrent ? validation.message !== null : props.hasError === true;\n const errorText = validationCurrent && validation.message !== null ? validation.message : props.errorText;\n\n const onInput = (event: { detail?: InputDetail }) => {\n const raw = event.detail?.value ?? '';\n // Not an edit: the native element reports what it already holds (Android emits an empty `input` when a read-only\n // field is created, before `setValue` lands), or the user cannot type here at all. Forwarding it would wipe a\n // controlled value (a barcode field opened on an existing code came up empty).\n if (props.readOnly === true) {\n // Nobody types here: the native element drifted (Android clears a read-only input it just created) — show the\n // field's value again.\n native.current = raw;\n if (raw !== latestText.current) syncRef.current();\n return;\n }\n const composing = event.detail?.isComposing === true;\n const echo = !composing && !composingRef.current && raw === native.current;\n composingRef.current = composing;\n if (echo) return;\n native.current = raw;\n // IME composition is never interrupted: the composed text is filtered when it is committed.\n if (composing) return;\n const clean = sanitize(raw);\n latestText.current = clean;\n setText(clean, { source: 'user' });\n if (options.validateOnTextChanged) runValidation(clean);\n bump((n) => n + 1);\n };\n const onFocus = () => {\n focusedRef.current = true;\n setFocused(true);\n keyboardAware.onInputFocused?.();\n // Tapping the field while dictating means typing: end the session (ADR-0024).\n if (dictation.listening) void dictation.stop();\n props.onFocus?.();\n };\n const onBlur = () => {\n focusedRef.current = false;\n setFocused(false);\n keyboardAware.onInputBlurred?.();\n // Only fields with a rule validate on blur, so an externally set error survives.\n if (hasRule && latestText.current !== '') runValidation(latestText.current);\n props.onBlur?.();\n };\n const onConfirm = () => props.onConfirm?.(latestText.current);\n\n const focus = () => {\n if (props.disabled) return;\n invokeNode(elementRef, 'focus');\n };\n const blur = () => invokeNode(elementRef, 'blur');\n\n const showMic = options.showMic({ available: dictation.available, listening: dictation.listening, hasValue });\n const pressMic = () => {\n // The microphone never focuses the field, and starting takes the keyboard down (ADR-0024).\n if (!dictation.listening && focusedRef.current) blur();\n void dictation.toggle();\n };\n\n const direction = resolveInputTextDirection(\n props.inputTextDirection ?? G9TextInputDirection.MatchParent,\n inputType,\n options.isPassword === true,\n culture.direction,\n );\n const font =\n props.customFont && props.customFont.trim() !== ''\n ? props.customFont\n : culture.direction === 'rtl'\n ? culture.rtlFontFamily\n : culture.ltrFontFamily;\n\n const handle: G9TextInputHandle = {\n focus,\n blur,\n validate: () => runValidation(latestText.current),\n get isListening() {\n return dictation.listening;\n },\n toggleVoice: () => dictation.toggle(),\n startVoice: () => dictation.start(),\n stopVoice: () => dictation.stop(),\n get element() {\n return elementRef.current;\n },\n };\n\n return {\n text: display,\n setText,\n hasValue,\n focused,\n hasError,\n errorText,\n passwordVisible,\n setPasswordVisible,\n dictation,\n showMic,\n pressMic,\n focus,\n blur,\n handle,\n inputType,\n /** Element attributes and handlers shared by `<input>` and `<textarea>`. */\n elementProps: {\n ...g9KeyboardTargetProps,\n ref: attach,\n ...(props.inputId ? { id: props.inputId } : {}),\n 'ignore-focus': true,\n readonly: props.readOnly === true,\n disabled: props.disabled === true,\n maxlength: props.maxLength !== undefined && props.maxLength > 0 ? props.maxLength : 2147483647,\n bindinput: onInput,\n bindfocus: onFocus,\n bindblur: onBlur,\n bindconfirm: onConfirm,\n },\n textDirection: direction,\n font,\n };\n}\n"],"names":["resolveInputTextDirection","inputTextDirection","inputType","isPassword","cultureDirection","G9TextInputDirection","inputTypePrefersLeftToRight","invokeNode","ref","method","params","node","invokeNodeWhenReady","attempts","startTimer","useTextInput","props","options","_props_inputType","_props_defaultValue","_props_voiceLocale","_props_inputTextDirection","culture","useG9Culture","strings","useG9Strings","keyboardAware","useContext","KeyboardAwareTriggerContext","G9InputType","separator","sanitize","raw","sanitizeInputText","text","setText","useControllableState","display","latestText","useRef","elementRef","native","composingRef","focused","setFocused","useState","focusedRef","passwordVisible","setPasswordVisible","bump","validation","setValidation","hasValue","runValidation","value","_runTextValidator","message","validateInputText","hasRule","inputTypeHasValidationRule","dictation","useDictation","refiltered","useEffect","retries","sync","syncRef","attach","validationCurrent","hasError","errorText","onInput","event","_event_detail","_event_detail1","composing","echo","clean","n","onFocus","onBlur","onConfirm","focus","blur","showMic","pressMic","direction","font","handle","g9KeyboardTargetProps","undefined"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"date-time-picker.d.ts","sourceRoot":"","sources":["../../src/pickers/date-time-picker.tsx"],"names":[],"mappings":"AAAA,OAAO,eAAe,CAAC;AACvB,OAAO,EAEL,KAAK,gBAAgB,EACrB,KAAK,SAAS,EACd,uBAAuB,EACvB,oBAAoB,EACpB,KAAK,WAAW,EAChB,KAAK,eAAe,EAGrB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,KAAK,SAAS,EAAoB,MAAM,gBAAgB,CAAC;AAqBlE,OAAO,EAAE,KAAK,kBAAkB,EAA8B,MAAM,WAAW,CAAC;AAGhF,yEAAyE;AACzE,eAAO,MAAM,gBAAgB,KAAK,CAAC;AAEnC,yCAAyC;AACzC,MAAM,WAAW,qBAAsB,SAAQ,kBAAkB;IAC/D,6GAA6G;IAC7G,QAAQ,CAAC,KAAK,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;IACxC,QAAQ,CAAC,YAAY,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;IAC/C,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,KAAK,IAAI,CAAC;IACjE,wBAAwB;IACxB,QAAQ,CAAC,IAAI,CAAC,EAAE,oBAAoB,CAAC;IACrC,6BAA6B;IAC7B,QAAQ,CAAC,aAAa,CAAC,EAAE,uBAAuB,CAAC;IACjD,mEAAmE;IACnE,QAAQ,CAAC,oBAAoB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9C,QAAQ,CAAC,OAAO,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IACtC,QAAQ,CAAC,OAAO,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IACtC,0DAA0D;IAC1D,QAAQ,CAAC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IACzC;;;OAGG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;IACnC,0CAA0C;IAC1C,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;IACnC,6GAA6G;IAC7G,QAAQ,CAAC,QAAQ,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAC5C,wDAAwD;IACxD,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,CAAC;CAChE;AAED,UAAU,cAAc;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC;IAClC,QAAQ,CAAC,GAAG,EAAE,MAAM,eAAe,CAAC;IACpC,QAAQ,CAAC,IAAI,EAAE,oBAAoB,CAAC;IACpC,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAC;IACpC,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE;QAAE,GAAG,EAAE,eAAe,GAAG,IAAI,CAAC;QAAC,GAAG,EAAE,eAAe,GAAG,IAAI,CAAA;KAAE,CAAC;IAC9E,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IACjC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,MAAM,CAAC;IACpD,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,CAAC;IAChD,QAAQ,CAAC,MAAM,EAAE,MAAM,IAAI,CAAC;CAC7B;AAED,4GAA4G;AAC5G,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,cAAc,GAAG,SAAS,CAmGlE;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,GAAG,SAAS,CA6ExE"}
1
+ {"version":3,"file":"date-time-picker.d.ts","sourceRoot":"","sources":["../../src/pickers/date-time-picker.tsx"],"names":[],"mappings":"AAAA,OAAO,eAAe,CAAC;AACvB,OAAO,EAGL,KAAK,gBAAgB,EACrB,KAAK,SAAS,EACd,uBAAuB,EACvB,oBAAoB,EACpB,KAAK,WAAW,EAChB,KAAK,eAAe,EAIrB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,KAAK,SAAS,EAAoB,MAAM,gBAAgB,CAAC;AAuBlE,OAAO,EAAE,KAAK,kBAAkB,EAA8B,MAAM,WAAW,CAAC;AAGhF,yEAAyE;AACzE,eAAO,MAAM,gBAAgB,KAAK,CAAC;AAEnC,yCAAyC;AACzC,MAAM,WAAW,qBAAsB,SAAQ,kBAAkB;IAC/D,6GAA6G;IAC7G,QAAQ,CAAC,KAAK,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;IACxC,QAAQ,CAAC,YAAY,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;IAC/C,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,KAAK,IAAI,CAAC;IACjE,wBAAwB;IACxB,QAAQ,CAAC,IAAI,CAAC,EAAE,oBAAoB,CAAC;IACrC,6BAA6B;IAC7B,QAAQ,CAAC,aAAa,CAAC,EAAE,uBAAuB,CAAC;IACjD,mEAAmE;IACnE,QAAQ,CAAC,oBAAoB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9C,QAAQ,CAAC,OAAO,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IACtC,QAAQ,CAAC,OAAO,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IACtC,0DAA0D;IAC1D,QAAQ,CAAC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IACzC;;;OAGG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;IACnC,0CAA0C;IAC1C,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;IACnC,6GAA6G;IAC7G,QAAQ,CAAC,QAAQ,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAC5C,wDAAwD;IACxD,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,CAAC;CAChE;AAED,UAAU,cAAc;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC;IAClC,QAAQ,CAAC,GAAG,EAAE,MAAM,eAAe,CAAC;IACpC,QAAQ,CAAC,IAAI,EAAE,oBAAoB,CAAC;IACpC,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAC;IACpC,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE;QAAE,GAAG,EAAE,eAAe,GAAG,IAAI,CAAC;QAAC,GAAG,EAAE,eAAe,GAAG,IAAI,CAAA;KAAE,CAAC;IAC9E,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IACjC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,MAAM,CAAC;IACpD,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,CAAC;IAChD,QAAQ,CAAC,MAAM,EAAE,MAAM,IAAI,CAAC;CAC7B;AAED,4GAA4G;AAC5G,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,cAAc,GAAG,SAAS,CA8GlE;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,GAAG,SAAS,CA6ExE"}
@@ -1,9 +1,11 @@
1
1
  import "./pickers.css";
2
- import { G9DateTimeDisplayFormat, G9DateTimePickerMode, G9StringKey, daysInMonth, localDateTimeFromDate } from "@g9tm/lynxcontrols-foundation";
2
+ import { G9DateTimeDisplayFormat, G9DateTimePickerMode, G9StringKey, daysInMonth, formatColor, localDateTimeFromDate, withAlpha } from "@g9tm/lynxcontrols-foundation";
3
3
  import { useRef, useState } from "@lynx-js/react";
4
+ import { g9RowStyle } from "../base/control.jsx";
4
5
  import { useG9Press } from "../base/press.jsx";
5
6
  import { useControllableState } from "../base/use-controllable-state.jsx";
6
- import { useG9Culture, useG9Service, useG9Settings, useG9Strings } from "../provider/hooks.jsx";
7
+ import { G9IconSlot } from "../icon/slot.jsx";
8
+ import { useG9Culture, useG9Service, useG9Settings, useG9Strings, useG9Theme } from "../provider/hooks.jsx";
7
9
  import { useG9Sheets } from "../sheet/service.jsx";
8
10
  import { asDateTime, clampPickerValue, composePickerValue, dayWheelItems, formatPickerValue, hourWheelItems, minuteWheelItems, monthWheelItems, normalizePickerBounds, pickerParts, resolvePickerCalendar, yearWheelItems, yearWindow } from "./date-time.jsx";
9
11
  import { PickerSheetHeader, showPickerSheet } from "./picker-sheet.jsx";
@@ -12,6 +14,8 @@ import { G9WheelColumn } from "./wheel-column.jsx";
12
14
  const g9YearWindowStep = 25;
13
15
  function DateTimeSheetBody(props) {
14
16
  const strings = useG9Strings();
17
+ const palette = useG9Theme().palette;
18
+ const glyphs = useG9Settings().glyphs;
15
19
  const { calendar, culture, bounds, mode } = props;
16
20
  const [value, setValueState] = useState(()=>clampPickerValue(props.initial, bounds, calendar));
17
21
  const latest = useRef(value);
@@ -54,7 +58,12 @@ function DateTimeSheetBody(props) {
54
58
  <text className="g9-picker-sheet__preview" text-maxline="1">
55
59
  {props.format(value)}
56
60
  </text>
57
- {props.showToday ? <view className="g9-picker-sheet__today" accessibility-element={true} accessibility-traits="button" bindtap={today}>
61
+ {props.showToday ? <view className="g9-picker-sheet__today" accessibility-element={true} accessibility-traits="button" bindtap={today} style={{
62
+ ...g9RowStyle(culture.direction),
63
+ backgroundColor: formatColor(withAlpha(palette.Primary, 0.08)),
64
+ borderColor: formatColor(withAlpha(palette.Primary, 0.3))
65
+ }}>
66
+ <G9IconSlot icon={glyphs.calendarToday} size={14} color={palette.Primary}/>
58
67
  <text className="g9-picker-sheet__today-text">
59
68
  {strings.get(mode === G9DateTimePickerMode.Time ? G9StringKey.Now : G9StringKey.Today)}
60
69
  </text>
@@ -63,7 +72,7 @@ function DateTimeSheetBody(props) {
63
72
  {showDate ? <G9WheelColumn label={strings.get(G9StringKey.Day)} items={dayWheelItems(daysInMonth(calendar, parts.year, parts.month), culture)} value={parts.day} onValueChange={(day)=>change({
64
73
  day
65
74
  })}/> : null}
66
- {showDate ? <G9WheelColumn label={strings.get(G9StringKey.Month)} items={monthWheelItems(calendar, culture)} value={parts.month} onValueChange={(month)=>change({
75
+ {showDate ? <G9WheelColumn label={strings.get(G9StringKey.Month)} weight={1.7} items={monthWheelItems(calendar, culture)} value={parts.month} onValueChange={(month)=>change({
67
76
  month
68
77
  })}/> : null}
69
78
  {showDate ? <G9WheelColumn label={strings.get(G9StringKey.Year)} items={yearWheelItems(window_.from, window_.to, culture)} value={parts.year} onValueChange={(year)=>change({