@g9tm/lynxcontrols 1.4.5 → 1.4.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (167) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/base/index.d.ts +1 -1
  3. package/dist/base/index.d.ts.map +1 -1
  4. package/dist/base/index.jsx +1 -1
  5. package/dist/base/pressable.d.ts.map +1 -1
  6. package/dist/base/pressable.jsx +2 -1
  7. package/dist/base/pressable.jsx.map +1 -1
  8. package/dist/base/selection-item.d.ts +9 -1
  9. package/dist/base/selection-item.d.ts.map +1 -1
  10. package/dist/base/selection-item.jsx +10 -1
  11. package/dist/base/selection-item.jsx.map +1 -1
  12. package/dist/button/button.css +20 -0
  13. package/dist/button/button.css.map +1 -1
  14. package/dist/button/header-action-button.d.ts +5 -0
  15. package/dist/button/header-action-button.d.ts.map +1 -1
  16. package/dist/button/header-action-button.jsx +6 -1
  17. package/dist/button/header-action-button.jsx.map +1 -1
  18. package/dist/button/visuals.d.ts.map +1 -1
  19. package/dist/button/visuals.jsx +1 -1
  20. package/dist/button/visuals.jsx.map +1 -1
  21. package/dist/cascade/cascade-panel.d.ts.map +1 -1
  22. package/dist/cascade/cascade-panel.jsx +2 -2
  23. package/dist/cascade/cascade-panel.jsx.map +1 -1
  24. package/dist/edge-panel/edge-panel.jsx +5 -5
  25. package/dist/edge-panel/edge-panel.jsx.map +1 -1
  26. package/dist/expander/expander.d.ts.map +1 -1
  27. package/dist/expander/expander.jsx +2 -1
  28. package/dist/expander/expander.jsx.map +1 -1
  29. package/dist/fields/editor.d.ts.map +1 -1
  30. package/dist/fields/editor.jsx +2 -2
  31. package/dist/fields/editor.jsx.map +1 -1
  32. package/dist/fields/fields.css +21 -0
  33. package/dist/fields/fields.css.map +1 -1
  34. package/dist/fields/index.d.ts +1 -1
  35. package/dist/fields/index.d.ts.map +1 -1
  36. package/dist/fields/index.jsx +1 -1
  37. package/dist/fields/outlined-field.d.ts +27 -1
  38. package/dist/fields/outlined-field.d.ts.map +1 -1
  39. package/dist/fields/outlined-field.jsx +29 -2
  40. package/dist/fields/outlined-field.jsx.map +1 -1
  41. package/dist/fields/text-entry.d.ts.map +1 -1
  42. package/dist/fields/text-entry.jsx +2 -2
  43. package/dist/fields/text-entry.jsx.map +1 -1
  44. package/dist/host/host.css.map +1 -1
  45. package/dist/host/host.d.ts +3 -2
  46. package/dist/host/host.d.ts.map +1 -1
  47. package/dist/host/host.jsx +2 -2
  48. package/dist/host/host.jsx.map +1 -1
  49. package/dist/pickers/combo-box.d.ts +8 -0
  50. package/dist/pickers/combo-box.d.ts.map +1 -1
  51. package/dist/pickers/combo-box.jsx +51 -9
  52. package/dist/pickers/combo-box.jsx.map +1 -1
  53. package/dist/pickers/date-time-picker.d.ts +2 -2
  54. package/dist/pickers/date-time-picker.d.ts.map +1 -1
  55. package/dist/pickers/date-time-picker.jsx +4 -3
  56. package/dist/pickers/date-time-picker.jsx.map +1 -1
  57. package/dist/pickers/date-time.d.ts +5 -2
  58. package/dist/pickers/date-time.d.ts.map +1 -1
  59. package/dist/pickers/date-time.jsx +1 -1
  60. package/dist/pickers/date-time.jsx.map +1 -1
  61. package/dist/pickers/picker-sheet.d.ts +6 -2
  62. package/dist/pickers/picker-sheet.d.ts.map +1 -1
  63. package/dist/pickers/picker-sheet.jsx +2 -3
  64. package/dist/pickers/picker-sheet.jsx.map +1 -1
  65. package/dist/pickers/picker.d.ts.map +1 -1
  66. package/dist/pickers/picker.jsx +3 -2
  67. package/dist/pickers/picker.jsx.map +1 -1
  68. package/dist/pickers/pickers.css +27 -0
  69. package/dist/pickers/pickers.css.map +1 -1
  70. package/dist/pickers/timespan-picker.d.ts.map +1 -1
  71. package/dist/pickers/timespan-picker.jsx +3 -2
  72. package/dist/pickers/timespan-picker.jsx.map +1 -1
  73. package/dist/pickers/trigger.d.ts +3 -1
  74. package/dist/pickers/trigger.d.ts.map +1 -1
  75. package/dist/pickers/trigger.jsx +6 -1
  76. package/dist/pickers/trigger.jsx.map +1 -1
  77. package/dist/plus-button/model.d.ts.map +1 -1
  78. package/dist/plus-button/model.jsx +5 -1
  79. package/dist/plus-button/model.jsx.map +1 -1
  80. package/dist/popup/frame.jsx +2 -2
  81. package/dist/popup/frame.jsx.map +1 -1
  82. package/dist/popup/service.d.ts.map +1 -1
  83. package/dist/popup/service.jsx +2 -2
  84. package/dist/popup/service.jsx.map +1 -1
  85. package/dist/provider/provider.css +4 -0
  86. package/dist/provider/provider.css.map +1 -1
  87. package/dist/provider/provider.d.ts.map +1 -1
  88. package/dist/provider/provider.jsx +4 -2
  89. package/dist/provider/provider.jsx.map +1 -1
  90. package/dist/provider/settings.d.ts +12 -0
  91. package/dist/provider/settings.d.ts.map +1 -1
  92. package/dist/provider/settings.jsx +6 -3
  93. package/dist/provider/settings.jsx.map +1 -1
  94. package/dist/provider/theme.css +4 -0
  95. package/dist/provider/theme.css.map +1 -1
  96. package/dist/range-slider/math.d.ts +14 -4
  97. package/dist/range-slider/math.d.ts.map +1 -1
  98. package/dist/range-slider/math.jsx +16 -4
  99. package/dist/range-slider/math.jsx.map +1 -1
  100. package/dist/range-slider/range-slider.css +17 -0
  101. package/dist/range-slider/range-slider.css.map +1 -1
  102. package/dist/range-slider/range-slider.d.ts +11 -0
  103. package/dist/range-slider/range-slider.d.ts.map +1 -1
  104. package/dist/range-slider/range-slider.jsx +35 -13
  105. package/dist/range-slider/range-slider.jsx.map +1 -1
  106. package/dist/selection/index.d.ts +2 -1
  107. package/dist/selection/index.d.ts.map +1 -1
  108. package/dist/selection/index.jsx +2 -1
  109. package/dist/selection/selection-sheet.d.ts +8 -1
  110. package/dist/selection/selection-sheet.d.ts.map +1 -1
  111. package/dist/selection/selection-sheet.jsx +64 -11
  112. package/dist/selection/selection-sheet.jsx.map +1 -1
  113. package/dist/selection/selection.css +7 -0
  114. package/dist/selection/selection.css.map +1 -1
  115. package/dist/selection/window.d.ts +29 -0
  116. package/dist/selection/window.d.ts.map +1 -0
  117. package/dist/selection/window.jsx +24 -0
  118. package/dist/selection/window.jsx.map +1 -0
  119. package/dist/sheet/frame.d.ts.map +1 -1
  120. package/dist/sheet/frame.jsx +35 -9
  121. package/dist/sheet/frame.jsx.map +1 -1
  122. package/dist/sheet/header.d.ts.map +1 -1
  123. package/dist/sheet/header.jsx +3 -1
  124. package/dist/sheet/header.jsx.map +1 -1
  125. package/dist/sheet/index.d.ts +2 -1
  126. package/dist/sheet/index.d.ts.map +1 -1
  127. package/dist/sheet/index.jsx +2 -1
  128. package/dist/sheet/motion.d.ts.map +1 -1
  129. package/dist/sheet/motion.jsx +14 -0
  130. package/dist/sheet/motion.jsx.map +1 -1
  131. package/dist/sheet/options.d.ts +26 -0
  132. package/dist/sheet/options.d.ts.map +1 -1
  133. package/dist/sheet/options.jsx +2 -1
  134. package/dist/sheet/options.jsx.map +1 -1
  135. package/dist/sheet/scroll-indicator.d.ts +33 -0
  136. package/dist/sheet/scroll-indicator.d.ts.map +1 -0
  137. package/dist/sheet/scroll-indicator.jsx +84 -0
  138. package/dist/sheet/scroll-indicator.jsx.map +1 -0
  139. package/dist/sheet/service.d.ts +8 -0
  140. package/dist/sheet/service.d.ts.map +1 -1
  141. package/dist/sheet/service.jsx +15 -4
  142. package/dist/sheet/service.jsx.map +1 -1
  143. package/dist/sheet/sheet.css +14 -0
  144. package/dist/sheet/sheet.css.map +1 -1
  145. package/dist/sheet/sizing.d.ts +2 -0
  146. package/dist/sheet/sizing.d.ts.map +1 -1
  147. package/dist/sheet/sizing.jsx +2 -1
  148. package/dist/sheet/sizing.jsx.map +1 -1
  149. package/dist/tab-bar/tab-bar.d.ts.map +1 -1
  150. package/dist/tab-bar/tab-bar.jsx +11 -6
  151. package/dist/tab-bar/tab-bar.jsx.map +1 -1
  152. package/dist/toast/service.jsx +3 -3
  153. package/dist/toast/service.jsx.map +1 -1
  154. package/dist/toast/store.d.ts.map +1 -1
  155. package/dist/toast/store.jsx +3 -2
  156. package/dist/toast/store.jsx.map +1 -1
  157. package/dist/toggle/chip-group.d.ts +9 -1
  158. package/dist/toggle/chip-group.d.ts.map +1 -1
  159. package/dist/toggle/chip-group.jsx +51 -12
  160. package/dist/toggle/chip-group.jsx.map +1 -1
  161. package/dist/toggle/switch.d.ts +1 -1
  162. package/dist/toggle/switch.d.ts.map +1 -1
  163. package/dist/toggle/switch.jsx +3 -2
  164. package/dist/toggle/switch.jsx.map +1 -1
  165. package/dist/toggle/toggle.css +20 -0
  166. package/dist/toggle/toggle.css.map +1 -1
  167. package/package.json +3 -3
@@ -1 +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, 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
+ {"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 /**\n * Keep the label floated even when empty and unfocused. Default false. With a `label` AND a `placeholder` the\n * placeholder is then drawn inside the empty box under the floated label (MAUI 1.4.9: «عنوان» floated with «عنوان کار\n * را وارد کنید» inside).\n */\n readonly alwaysFloat?: boolean;\n /**\n * The `placeholder` is the box's own hint (MAUI 1.4.9 `PlaceholderInside`): inside while the field is empty, gone with\n * a value, never lifted into the notch as a label — a chat composer's «یادداشت خود را بنویسید...». A `label`, if set,\n * still floats as usual. Default false: without a label the placeholder is the floating label's text.\n */\n readonly placeholderInside?: 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})`;\nconst blank = (s: string | null | undefined): boolean => s == null || s.trim() === '';\n\n/**\n * The hint a field draws INSIDE its box while it is empty, or `null` (MAUI 1.4.9 `RestingPlaceholder`). Without a `label`\n * (or with `placeholderInside`) it is the `placeholder`. With a label it is drawn only when `alwaysFloat` keeps the label\n * up in the notch — otherwise the resting label sits where the hint would be — and never when it repeats the label.\n */\nexport function resolveRestingPlaceholder(\n props: Pick<G9OutlinedFieldProps, 'label' | 'placeholder' | 'alwaysFloat' | 'placeholderInside'>,\n): string | null {\n if (blank(props.placeholder)) return null;\n const placeholder = props.placeholder as string;\n if (props.placeholderInside === true || blank(props.label)) return placeholder;\n return props.alwaysFloat === true && props.label !== placeholder ? placeholder : null;\n}\n\n/**\n * The hint a TEXT input draws itself (MAUI 1.4.9 `G9TextEntry` / `G9Editor`): only while the field owns it — a label is\n * set, or `placeholderInside` — since without a label the floating label already is the placeholder.\n */\nexport function resolveInnerHint(\n props: Pick<G9OutlinedFieldProps, 'label' | 'placeholder' | 'alwaysFloat' | 'placeholderInside'>,\n): string | null {\n const owns = props.placeholderInside === true || !blank(props.label);\n return owns ? resolveRestingPlaceholder(props) : null;\n}\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 // MAUI 1.4.9: `Label ?? (PlaceholderInside ? null : Placeholder)` — a placeholder inside the box never floats.\n const labelRaw = props.label ?? (props.placeholderInside === true ? null : 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 * A hint the frame draws over the content while the field is empty (`resolveInnerHint`, MAUI 1.4.9): text inputs pass\n * it; the pickers draw their own value text. TextTertiary, the input's 15 px, never taking a touch.\n */\n readonly hint?: string | null;\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 {props.hint && !props.hasValue && props.valueFloated !== true ? (\n <view\n className={`g9-field__hint${multiline ? ' g9-field__hint--multiline' : ''}`}\n user-interaction-enabled={false}\n style={{\n left: `${slot.innerPadding.left + (hasLeading && slot.leadingColumn === 0 ? G9Metrics.LeadingIconSlotWidth : 0) + (hasTrailing && slot.trailingColumn === 0 ? G9Metrics.TrailingIconSlotWidth : 0)}px`,\n right: `${slot.innerPadding.right + (hasLeading && slot.leadingColumn === 2 ? G9Metrics.LeadingIconSlotWidth : 0) + (hasTrailing && slot.trailingColumn === 2 ? G9Metrics.TrailingIconSlotWidth : 0)}px`,\n ...(multiline ? { top: `${slot.innerPadding.top}px` } : {}),\n }}\n >\n <text\n className=\"g9-field__hint-text\"\n {...(multiline ? {} : { 'text-maxline': '1' })}\n style={{\n textAlign: isRtl ? 'right' : 'left',\n color: disabled ? 'var(--g9-text-disabled)' : 'var(--g9-text-tertiary)',\n }}\n >\n {props.hint}\n </text>\n </view>\n ) : null}\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","blank","s","resolveRestingPlaceholder","props","placeholder","resolveInnerHint","owns","resolveOutlinedFieldState","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":"text-entry.d.ts","sourceRoot":"","sources":["../../src/fields/text-entry.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,iBAAiB,EAAE,KAAK,gBAAgB,EAAgB,MAAM,kBAAkB,CAAC;AAC/F,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD,yDAAyD;AACzD,MAAM,WAAW,gBAAiB,SAAQ,gBAAgB;IACxD,2GAA2G;IAC3G,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;IAClC,wFAAwF;IACxF,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAC9B,mFAAmF;IACnF,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B,yGAAyG;IACzG,QAAQ,CAAC,SAAS,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;IAC5C,iEAAiE;IACjE,QAAQ,CAAC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IACzC,8CAA8C;IAC9C,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,GAAG,MAAM,GAAG,MAAM,CAAC;IAClE,sFAAsF;IACtF,QAAQ,CAAC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IACvC,wEAAwE;IACxE,QAAQ,CAAC,uBAAuB,CAAC,EAAE,OAAO,CAAC;CAC5C;AAED,gDAAgD;AAChD,MAAM,MAAM,iBAAiB,GAAG,iBAAiB,CAAC;AAElD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE;IACxC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;CAClC,GAAG,OAAO,CAEV;AAED,4DAA4D;AAC5D,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,GAAG,aAAa,CAAC;IACjD,QAAQ,CAAC,WAAW,CAAC,EAAE,gBAAgB,CAAC,aAAa,CAAC,CAAC;IACvD,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9C;AAED,UAAU,SAAU,SAAQ,gBAAgB;IAC1C,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;CAClC;AAED;;;GAGG;AACH,eAAO,MAAM,aAAa,yGAyFzB,CAAC;AAIF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,WAAW,gHAEtB,CAAC"}
1
+ {"version":3,"file":"text-entry.d.ts","sourceRoot":"","sources":["../../src/fields/text-entry.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,iBAAiB,EAAE,KAAK,gBAAgB,EAAgB,MAAM,kBAAkB,CAAC;AAC/F,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD,yDAAyD;AACzD,MAAM,WAAW,gBAAiB,SAAQ,gBAAgB;IACxD,2GAA2G;IAC3G,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;IAClC,wFAAwF;IACxF,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAC9B,mFAAmF;IACnF,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B,yGAAyG;IACzG,QAAQ,CAAC,SAAS,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;IAC5C,iEAAiE;IACjE,QAAQ,CAAC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IACzC,8CAA8C;IAC9C,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,GAAG,MAAM,GAAG,MAAM,CAAC;IAClE,sFAAsF;IACtF,QAAQ,CAAC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IACvC,wEAAwE;IACxE,QAAQ,CAAC,uBAAuB,CAAC,EAAE,OAAO,CAAC;CAC5C;AAED,gDAAgD;AAChD,MAAM,MAAM,iBAAiB,GAAG,iBAAiB,CAAC;AAElD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE;IACxC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;CAClC,GAAG,OAAO,CAEV;AAED,4DAA4D;AAC5D,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,GAAG,aAAa,CAAC;IACjD,QAAQ,CAAC,WAAW,CAAC,EAAE,gBAAgB,CAAC,aAAa,CAAC,CAAC;IACvD,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9C;AAED,UAAU,SAAU,SAAQ,gBAAgB;IAC1C,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;CAClC;AAED;;;GAGG;AACH,eAAO,MAAM,aAAa,yGA0FzB,CAAC;AAIF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,WAAW,gHAEtB,CAAC"}
@@ -2,7 +2,7 @@ import { G9KeyboardType, G9StringKey } from "@g9tm/lynxcontrols-foundation";
2
2
  import { forwardRef, useImperativeHandle } from "@lynx-js/react";
3
3
  import { useG9Settings, useG9Strings } from "../provider/hooks.jsx";
4
4
  import { resolveEffectiveKeyboard, resolveInputElementType } from "./input-policy.jsx";
5
- import { G9OutlinedField } from "./outlined-field.jsx";
5
+ import { G9OutlinedField, resolveInnerHint } from "./outlined-field.jsx";
6
6
  import { useTextInput } from "./use-text-input.jsx";
7
7
  function shouldShowEntryMic(state) {
8
8
  return state.available && !(state.passwordToggle && state.hasValue) && (state.listening || !state.hasValue);
@@ -50,7 +50,7 @@ const TextEntryBody = forwardRef(function(props, ref) {
50
50
  };
51
51
  const masked = true === props.isPassword && !core.passwordVisible;
52
52
  const keyboard = resolveEffectiveKeyboard(core.inputType, null != (_props_keyboardType = props.keyboardType) ? _props_keyboardType : G9KeyboardType.Default);
53
- return <G9OutlinedField {...props} hasError={core.hasError} errorText={null != (_core_errorText = core.errorText) ? _core_errorText : null} forceTrailingIconRight={true === props.forceTrailingIconRight || passwordToggle} focused={core.focused} hasValue={core.hasValue} textLength={core.text.length} trailingAffordance={affordance} restingTone={null != (_props_variant_restingTone = props.variant.restingTone) ? _props_variant_restingTone : 'outline'} onFocusRequest={core.focus}>
53
+ return <G9OutlinedField {...props} hint={resolveInnerHint(props)} hasError={core.hasError} errorText={null != (_core_errorText = core.errorText) ? _core_errorText : null} forceTrailingIconRight={true === props.forceTrailingIconRight || passwordToggle} focused={core.focused} hasValue={core.hasValue} textLength={core.text.length} trailingAffordance={affordance} restingTone={null != (_props_variant_restingTone = props.variant.restingTone) ? _props_variant_restingTone : 'outline'} onFocusRequest={core.focus}>
54
54
  {}
55
55
  {true === props.readOnly && !masked ? <text className="g9-field__input g9-field__input--readonly" text-maxline="1" style={{
56
56
  direction: core.textDirection,
@@ -1 +1 @@
1
- {"version":3,"file":"fields/text-entry.jsx","sources":["../../src/fields/text-entry.tsx"],"sourcesContent":["import { G9KeyboardType, G9StringKey } from '@g9tm/lynxcontrols-foundation';\nimport { forwardRef, type ReactNode, useImperativeHandle } from '@lynx-js/react';\nimport { useG9Settings, useG9Strings } from '../provider/hooks';\nimport { resolveEffectiveKeyboard, resolveInputElementType } from './input-policy';\nimport { G9OutlinedField, type G9TrailingAffordance } from './outlined-field';\nimport { type G9TextInputHandle, type G9TextInputProps, useTextInput } from './use-text-input';\nimport type { G9TextValidator } from './validator';\n\n/** Props of {@link G9TextEntry} (MAUI `G9TextEntry`). */\nexport interface G9TextEntryProps extends G9TextInputProps {\n /** Eye toggle in the trailing slot while there is a value; pins the trailing icon right. Default false. */\n readonly passwordToggle?: boolean;\n /** Mask the value (until the eye reveals it); the text is pinned LTR. Default false. */\n readonly isPassword?: boolean;\n /** Clear (×) button in the trailing slot while there is a value. Default false. */\n readonly clearButton?: boolean;\n /** Extra validation, run before the input-type rule (on blur, `validateOnTextChanged`, `validate()`). */\n readonly validator?: G9TextValidator | null;\n /** Validate on every change, not only on blur. Default false. */\n readonly validateOnTextChanged?: boolean;\n /** Keyboard confirm key. Default `'done'`. */\n readonly confirmType?: 'send' | 'search' | 'go' | 'done' | 'next';\n /** iOS spell checking (`ios-spell-check`; Android has no attribute). Default true. */\n readonly isSpellCheckEnabled?: boolean;\n /** iOS auto-correct / prediction (`ios-auto-correct`). Default true. */\n readonly isTextPredictionEnabled?: boolean;\n}\n\n/** Imperative handle of {@link G9TextEntry}. */\nexport type G9TextEntryHandle = G9TextInputHandle;\n\n/**\n * Whether the trailing slot shows the microphone (MAUI `ShouldShowVoiceMic`): dictation available, not while the\n * password eye owns the slot, and only on an empty field or during a session (the clear button owns a filled field).\n */\nexport function shouldShowEntryMic(state: {\n readonly available: boolean;\n readonly listening: boolean;\n readonly hasValue: boolean;\n readonly passwordToggle: boolean;\n}): boolean {\n return state.available && !(state.passwordToggle && state.hasValue) && (state.listening || !state.hasValue);\n}\n\n/** What `G9SearchEntry` changes in the entry (internal). */\nexport interface G9EntryVariant {\n readonly name: string;\n readonly restingTone?: 'outline' | 'placeholder';\n readonly confirmType?: G9TextEntryProps['confirmType'];\n readonly onConfirm?: (value: string) => void;\n}\n\ninterface BodyProps extends G9TextEntryProps {\n readonly variant: G9EntryVariant;\n}\n\n/**\n * The entry body shared by `G9TextEntry` and `G9SearchEntry` (internal). The inner name must differ from the binding\n * (E20, scripts/check-dist-jsx.mjs): `G9TextEntry` renders it in this module.\n */\nexport const TextEntryBody = forwardRef<G9TextEntryHandle, BodyProps>(\n function TextEntryBodyRender(props, ref): ReactNode {\n const glyphs = useG9Settings().glyphs;\n const strings = useG9Strings();\n const passwordToggle = props.passwordToggle === true;\n const core = useTextInput(\n { ...props, ...(props.variant.onConfirm ? { onConfirm: props.variant.onConfirm } : {}) },\n {\n name: props.variant.name,\n validator: props.validator ?? null,\n validateOnTextChanged: props.validateOnTextChanged === true,\n isPassword: props.isPassword === true,\n showMic: (s) => shouldShowEntryMic({ ...s, passwordToggle }),\n },\n );\n useImperativeHandle(ref, () => core.handle);\n\n let affordance: G9TrailingAffordance | null = null;\n if (passwordToggle && core.hasValue) {\n affordance = {\n icon: core.passwordVisible ? glyphs.eyeClosed : glyphs.eyeOpen,\n signature: core.passwordVisible ? 'eye-closed' : 'eye-open',\n onPress: () => core.setPasswordVisible(!core.passwordVisible),\n };\n } else if (core.showMic) {\n affordance = {\n icon: core.dictation.listening ? glyphs.micOff : glyphs.mic,\n color: core.dictation.listening ? 'var(--g9-error)' : 'var(--g9-primary)',\n signature: 'voice',\n onPress: core.pressMic,\n };\n } else if (props.clearButton === true && core.hasValue) {\n affordance = {\n icon: glyphs.clear,\n label: strings.get(G9StringKey.Clear),\n signature: 'clear',\n onPress: () => core.setText('', { source: 'clear' }),\n };\n }\n\n const masked = props.isPassword === true && !core.passwordVisible;\n const keyboard = resolveEffectiveKeyboard(core.inputType, props.keyboardType ?? G9KeyboardType.Default);\n return (\n <G9OutlinedField\n {...props}\n hasError={core.hasError}\n errorText={core.errorText ?? null}\n forceTrailingIconRight={props.forceTrailingIconRight === true || passwordToggle}\n focused={core.focused}\n hasValue={core.hasValue}\n textLength={core.text.length}\n trailingAffordance={affordance}\n restingTone={props.variant.restingTone ?? 'outline'}\n onFocusRequest={core.focus}\n >\n {/* A read-only (unmasked) field shows its value as text: nobody types into it, and a native read-only\n EditText ignored the value pushed into it (a scan-only barcode field stayed blank). */}\n {props.readOnly === true && !masked ? (\n <text\n className=\"g9-field__input g9-field__input--readonly\"\n text-maxline=\"1\"\n style={{\n direction: core.textDirection,\n textAlign: core.textDirection === 'rtl' ? 'right' : 'left',\n ...(core.font ? { fontFamily: core.font } : {}),\n color: props.disabled ? 'var(--g9-text-disabled)' : 'var(--g9-text-primary)',\n }}\n >\n {core.text}\n </text>\n ) : (\n <input\n {...core.elementProps}\n className=\"g9-field__input\"\n type={resolveInputElementType(core.inputType, keyboard, masked)}\n confirm-type={props.variant.confirmType ?? props.confirmType ?? 'done'}\n ios-spell-check={props.isSpellCheckEnabled !== false}\n ios-auto-correct={props.isTextPredictionEnabled !== false}\n style={{\n direction: core.textDirection,\n textAlign: core.textDirection === 'rtl' ? 'right' : 'left',\n ...(core.font ? { fontFamily: core.font } : {}),\n color: props.disabled ? 'var(--g9-text-disabled)' : 'var(--g9-text-primary)',\n }}\n />\n )}\n </G9OutlinedField>\n );\n },\n);\n\nconst entryVariant: G9EntryVariant = { name: 'G9TextEntry.value' };\n\n/**\n * Single-line outlined text field (MAUI `G9TextEntry`): floating label, input-type keyboard/filter/validation,\n * password eye, clear button, optional dictation (`voiceEnabled` + `services.speech`).\n *\n * - Value: `value`/`defaultValue`/`onValueChange(value, { source })`; one call per change.\n * - Validation: on blur when there is a rule (`validator`, email/url, custom pattern), on every change with\n * `validateOnTextChanged`, or through the handle's `validate()`. An error set through `hasError`/`errorText`\n * survives blur on a field without a rule.\n * - Requires the host's `xelement-input` registration (plan/specs/02 §2). Keyboard avoidance: put the form inside\n * lynx-ui `KeyboardAwareRoot`/`KeyboardAwareResponder`; the field reports focus to it.\n */\nexport const G9TextEntry = forwardRef<G9TextEntryHandle, G9TextEntryProps>(function G9TextEntry(props, ref) {\n return <TextEntryBody {...props} variant={entryVariant} ref={ref} />;\n});\n"],"names":["shouldShowEntryMic","state","TextEntryBody","forwardRef","props","ref","_props_validator","_props_keyboardType","_core_errorText","_props_variant_restingTone","_ref","glyphs","useG9Settings","strings","useG9Strings","passwordToggle","core","useTextInput","s","useImperativeHandle","affordance","G9StringKey","masked","keyboard","resolveEffectiveKeyboard","G9KeyboardType","G9OutlinedField","text","input","resolveInputElementType","entryVariant","G9TextEntry"],"mappings":"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"}
1
+ {"version":3,"file":"fields/text-entry.jsx","sources":["../../src/fields/text-entry.tsx"],"sourcesContent":["import { G9KeyboardType, G9StringKey } from '@g9tm/lynxcontrols-foundation';\nimport { forwardRef, type ReactNode, useImperativeHandle } from '@lynx-js/react';\nimport { useG9Settings, useG9Strings } from '../provider/hooks';\nimport { resolveEffectiveKeyboard, resolveInputElementType } from './input-policy';\nimport { G9OutlinedField, type G9TrailingAffordance, resolveInnerHint } from './outlined-field';\nimport { type G9TextInputHandle, type G9TextInputProps, useTextInput } from './use-text-input';\nimport type { G9TextValidator } from './validator';\n\n/** Props of {@link G9TextEntry} (MAUI `G9TextEntry`). */\nexport interface G9TextEntryProps extends G9TextInputProps {\n /** Eye toggle in the trailing slot while there is a value; pins the trailing icon right. Default false. */\n readonly passwordToggle?: boolean;\n /** Mask the value (until the eye reveals it); the text is pinned LTR. Default false. */\n readonly isPassword?: boolean;\n /** Clear (×) button in the trailing slot while there is a value. Default false. */\n readonly clearButton?: boolean;\n /** Extra validation, run before the input-type rule (on blur, `validateOnTextChanged`, `validate()`). */\n readonly validator?: G9TextValidator | null;\n /** Validate on every change, not only on blur. Default false. */\n readonly validateOnTextChanged?: boolean;\n /** Keyboard confirm key. Default `'done'`. */\n readonly confirmType?: 'send' | 'search' | 'go' | 'done' | 'next';\n /** iOS spell checking (`ios-spell-check`; Android has no attribute). Default true. */\n readonly isSpellCheckEnabled?: boolean;\n /** iOS auto-correct / prediction (`ios-auto-correct`). Default true. */\n readonly isTextPredictionEnabled?: boolean;\n}\n\n/** Imperative handle of {@link G9TextEntry}. */\nexport type G9TextEntryHandle = G9TextInputHandle;\n\n/**\n * Whether the trailing slot shows the microphone (MAUI `ShouldShowVoiceMic`): dictation available, not while the\n * password eye owns the slot, and only on an empty field or during a session (the clear button owns a filled field).\n */\nexport function shouldShowEntryMic(state: {\n readonly available: boolean;\n readonly listening: boolean;\n readonly hasValue: boolean;\n readonly passwordToggle: boolean;\n}): boolean {\n return state.available && !(state.passwordToggle && state.hasValue) && (state.listening || !state.hasValue);\n}\n\n/** What `G9SearchEntry` changes in the entry (internal). */\nexport interface G9EntryVariant {\n readonly name: string;\n readonly restingTone?: 'outline' | 'placeholder';\n readonly confirmType?: G9TextEntryProps['confirmType'];\n readonly onConfirm?: (value: string) => void;\n}\n\ninterface BodyProps extends G9TextEntryProps {\n readonly variant: G9EntryVariant;\n}\n\n/**\n * The entry body shared by `G9TextEntry` and `G9SearchEntry` (internal). The inner name must differ from the binding\n * (E20, scripts/check-dist-jsx.mjs): `G9TextEntry` renders it in this module.\n */\nexport const TextEntryBody = forwardRef<G9TextEntryHandle, BodyProps>(\n function TextEntryBodyRender(props, ref): ReactNode {\n const glyphs = useG9Settings().glyphs;\n const strings = useG9Strings();\n const passwordToggle = props.passwordToggle === true;\n const core = useTextInput(\n { ...props, ...(props.variant.onConfirm ? { onConfirm: props.variant.onConfirm } : {}) },\n {\n name: props.variant.name,\n validator: props.validator ?? null,\n validateOnTextChanged: props.validateOnTextChanged === true,\n isPassword: props.isPassword === true,\n showMic: (s) => shouldShowEntryMic({ ...s, passwordToggle }),\n },\n );\n useImperativeHandle(ref, () => core.handle);\n\n let affordance: G9TrailingAffordance | null = null;\n if (passwordToggle && core.hasValue) {\n affordance = {\n icon: core.passwordVisible ? glyphs.eyeClosed : glyphs.eyeOpen,\n signature: core.passwordVisible ? 'eye-closed' : 'eye-open',\n onPress: () => core.setPasswordVisible(!core.passwordVisible),\n };\n } else if (core.showMic) {\n affordance = {\n icon: core.dictation.listening ? glyphs.micOff : glyphs.mic,\n color: core.dictation.listening ? 'var(--g9-error)' : 'var(--g9-primary)',\n signature: 'voice',\n onPress: core.pressMic,\n };\n } else if (props.clearButton === true && core.hasValue) {\n affordance = {\n icon: glyphs.clear,\n label: strings.get(G9StringKey.Clear),\n signature: 'clear',\n onPress: () => core.setText('', { source: 'clear' }),\n };\n }\n\n const masked = props.isPassword === true && !core.passwordVisible;\n const keyboard = resolveEffectiveKeyboard(core.inputType, props.keyboardType ?? G9KeyboardType.Default);\n return (\n <G9OutlinedField\n {...props}\n hint={resolveInnerHint(props)}\n hasError={core.hasError}\n errorText={core.errorText ?? null}\n forceTrailingIconRight={props.forceTrailingIconRight === true || passwordToggle}\n focused={core.focused}\n hasValue={core.hasValue}\n textLength={core.text.length}\n trailingAffordance={affordance}\n restingTone={props.variant.restingTone ?? 'outline'}\n onFocusRequest={core.focus}\n >\n {/* A read-only (unmasked) field shows its value as text: nobody types into it, and a native read-only\n EditText ignored the value pushed into it (a scan-only barcode field stayed blank). */}\n {props.readOnly === true && !masked ? (\n <text\n className=\"g9-field__input g9-field__input--readonly\"\n text-maxline=\"1\"\n style={{\n direction: core.textDirection,\n textAlign: core.textDirection === 'rtl' ? 'right' : 'left',\n ...(core.font ? { fontFamily: core.font } : {}),\n color: props.disabled ? 'var(--g9-text-disabled)' : 'var(--g9-text-primary)',\n }}\n >\n {core.text}\n </text>\n ) : (\n <input\n {...core.elementProps}\n className=\"g9-field__input\"\n type={resolveInputElementType(core.inputType, keyboard, masked)}\n confirm-type={props.variant.confirmType ?? props.confirmType ?? 'done'}\n ios-spell-check={props.isSpellCheckEnabled !== false}\n ios-auto-correct={props.isTextPredictionEnabled !== false}\n style={{\n direction: core.textDirection,\n textAlign: core.textDirection === 'rtl' ? 'right' : 'left',\n ...(core.font ? { fontFamily: core.font } : {}),\n color: props.disabled ? 'var(--g9-text-disabled)' : 'var(--g9-text-primary)',\n }}\n />\n )}\n </G9OutlinedField>\n );\n },\n);\n\nconst entryVariant: G9EntryVariant = { name: 'G9TextEntry.value' };\n\n/**\n * Single-line outlined text field (MAUI `G9TextEntry`): floating label, input-type keyboard/filter/validation,\n * password eye, clear button, optional dictation (`voiceEnabled` + `services.speech`).\n *\n * - Value: `value`/`defaultValue`/`onValueChange(value, { source })`; one call per change.\n * - Validation: on blur when there is a rule (`validator`, email/url, custom pattern), on every change with\n * `validateOnTextChanged`, or through the handle's `validate()`. An error set through `hasError`/`errorText`\n * survives blur on a field without a rule.\n * - Requires the host's `xelement-input` registration (plan/specs/02 §2). Keyboard avoidance: put the form inside\n * lynx-ui `KeyboardAwareRoot`/`KeyboardAwareResponder`; the field reports focus to it.\n */\nexport const G9TextEntry = forwardRef<G9TextEntryHandle, G9TextEntryProps>(function G9TextEntry(props, ref) {\n return <TextEntryBody {...props} variant={entryVariant} ref={ref} />;\n});\n"],"names":["shouldShowEntryMic","state","TextEntryBody","forwardRef","props","ref","_props_validator","_props_keyboardType","_core_errorText","_props_variant_restingTone","_ref","glyphs","useG9Settings","strings","useG9Strings","passwordToggle","core","useTextInput","s","useImperativeHandle","affordance","G9StringKey","masked","keyboard","resolveEffectiveKeyboard","G9KeyboardType","G9OutlinedField","resolveInnerHint","text","input","resolveInputElementType","entryVariant","G9TextEntry"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"sources":["webpack://./src/host/host.css"],"names":[],"mappings":"AACA;EAAE,sBAAsB;EACtB,OAAO;EACP,WAAW;EACX,YAAY;EACZ,aAAa;EACb,kBAAkB;EAClB,gBAAgB;AAClB;;AAIA;EADE,oBAAoB;EACpB,kBAAkB;EAClB,MAAM;EACN,SAAS;EACT,OAAO;EACP,QAAQ;AACV;;AAIA;EADE,sBAAsB;EACtB,aAAa;EACb,kBAAkB;EAClB,MAAM;EACN,SAAS;EACT,OAAO;EACP,QAAQ;AACV;;AAKA;EAFE,oBAAoB;EACpB,kBAAkB;EAClB,MAAM;EACN,SAAS;EACT,OAAO;EACP,QAAQ;AACV;;AAMA;EAHE,UAAU;EACV,uBAAuB;EACvB,mBAAmB;EACnB,uCAAuC;EACvC,wBAAwB;EACxB,8DAA8D;EAC9D,aAAa;EACb,kBAAkB;EAClB,MAAM;EACN,SAAS;EACT,OAAO;EACP,QAAQ;EACR,mBAAmB;AACrB;;AAMA;EAHE,UAAU;EACV,oBAAoB;AACtB;;AAMA;EAHE,mBAAmB;EACnB,iBAAiB;EACjB,uBAAuB;EACvB,mBAAmB;EACnB,WAAW;EACX,YAAY;EACZ,sCAAsC;AACxC;;AAMA;EAHE;IACE,oBAAoB;EACtB;;EAEA;IACE,yBAAyB;EAC3B;AACF","sourcesContent":["/* G9Host: one page frame. Sibling order below is the z-order (MAUI G9PageTemplate.xaml); nothing uses z-index. */\n.g9-host {\n display: flex;\n flex-direction: column;\n position: relative;\n flex: 1;\n width: 100%;\n height: 100%;\n overflow: hidden;\n}\n\n/* MAUI BackdropHost: behind the content, input-transparent, visible only when a sheet recedes the page. */\n.g9-host__backdrop {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n pointer-events: none;\n}\n\n.g9-host__content {\n display: flex;\n flex-direction: column;\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n}\n\n/* Overlay layers: full-size and input-transparent; items opt back in (pointer-events does not inherit). */\n.g9-host__layer {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n pointer-events: none;\n}\n\n/* The page-loading cover: topmost, input-opaque, centred spinner. */\n.g9-page-loading {\n display: flex;\n align-items: center;\n justify-content: center;\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n opacity: 1;\n transform: scale(1);\n transition-property: opacity, transform;\n transition-duration: 200ms;\n transition-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);\n}\n\n.g9-page-loading--exiting {\n opacity: 0;\n transform: scale(0.9);\n}\n\n.g9-page-loading__spinner {\n width: 48px;\n height: 48px;\n border-width: 4px;\n border-style: solid;\n border-radius: 24px;\n border-top-color: transparent;\n animation: g9-spin 900ms linear infinite;\n}\n\n@keyframes g9-spin {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n}\n"],"sourceRoot":""}
1
+ {"version":3,"sources":["webpack://./src/host/host.css"],"names":[],"mappings":"AACA;EAAE,sBAAsB;EACtB,OAAO;EACP,WAAW;EACX,YAAY;EACZ,aAAa;EACb,kBAAkB;EAClB,gBAAgB;AAClB;;AAIA;EADE,oBAAoB;EACpB,kBAAkB;EAClB,MAAM;EACN,SAAS;EACT,OAAO;EACP,QAAQ;AACV;;AAIA;EADE,sBAAsB;EACtB,aAAa;EACb,kBAAkB;EAClB,MAAM;EACN,SAAS;EACT,OAAO;EACP,QAAQ;AACV;;AAOA;EAJE,oBAAoB;EACpB,kBAAkB;EAClB,MAAM;EACN,SAAS;EACT,OAAO;EACP,QAAQ;AACV;;AAQA;EALE,UAAU;EACV,uBAAuB;EACvB,mBAAmB;EACnB,uCAAuC;EACvC,wBAAwB;EACxB,8DAA8D;EAC9D,aAAa;EACb,kBAAkB;EAClB,MAAM;EACN,SAAS;EACT,OAAO;EACP,QAAQ;EACR,mBAAmB;AACrB;;AAQA;EALE,UAAU;EACV,oBAAoB;AACtB;;AAQA;EALE,mBAAmB;EACnB,iBAAiB;EACjB,uBAAuB;EACvB,mBAAmB;EACnB,WAAW;EACX,YAAY;EACZ,sCAAsC;AACxC;;AAQA;EALE;IACE,oBAAoB;EACtB;;EAEA;IACE,yBAAyB;EAC3B;AACF","sourcesContent":["/* G9Host: one page frame. Sibling order below is the z-order (MAUI G9PageTemplate.xaml); nothing uses z-index. */\n.g9-host {\n display: flex;\n flex-direction: column;\n position: relative;\n flex: 1;\n width: 100%;\n height: 100%;\n overflow: hidden;\n}\n\n/* MAUI BackdropHost: behind the content, input-transparent, visible only when a sheet recedes the page. */\n.g9-host__backdrop {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n pointer-events: none;\n}\n\n.g9-host__content {\n display: flex;\n flex-direction: column;\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n}\n\n/* Overlay layers: full-size and input-transparent. Every item MUST opt back in with `pointer-events: auto` on its root:\n Lynx INHERITS pointer-events from the parent element, so an item without it is transparent too — its handlers never\n run and the touch reaches what is under the layer (AgriPad's Initialize cover let a tap open a tab, 2026-11-03). */\n.g9-host__layer {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n pointer-events: none;\n}\n\n/* The page-loading cover: topmost, input-opaque, centred spinner. */\n.g9-page-loading {\n display: flex;\n align-items: center;\n justify-content: center;\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n opacity: 1;\n transform: scale(1);\n transition-property: opacity, transform;\n transition-duration: 200ms;\n transition-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);\n}\n\n.g9-page-loading--exiting {\n opacity: 0;\n transform: scale(0.9);\n}\n\n.g9-page-loading__spinner {\n width: 48px;\n height: 48px;\n border-width: 4px;\n border-style: solid;\n border-radius: 24px;\n border-top-color: transparent;\n animation: g9-spin 900ms linear infinite;\n}\n\n@keyframes g9-spin {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n}\n"],"sourceRoot":""}
@@ -63,8 +63,9 @@ export declare const G9HostReadinessContext: import("react").Context<G9HostReadi
63
63
  * stack, readiness and loading cover, safe-area insets, tap-outside keyboard dismissal, and its registration in
64
64
  * `g9Hosts` for code outside the tree. One per page; hosts may nest. Must be inside `G9Provider`.
65
65
  *
66
- * Layers are input-transparent (`pointer-events: none`), so empty areas pass touches to the layers below while each
67
- * item receives its own touches; an empty layer renders nothing.
66
+ * Layers are input-transparent (`pointer-events: none`), so empty areas pass touches to the layers below; each item
67
+ * receives its own touches only when its root sets `pointer-events: auto` — Lynx inherits pointer-events, so an item
68
+ * without it is transparent as well. An empty layer renders nothing.
68
69
  */
69
70
  export declare function G9Host(props: G9HostProps): ReactNode;
70
71
  //# sourceMappingURL=host.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../../src/host/host.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAW,MAAM,+BAA+B,CAAC;AAE5E,OAAO,EAIL,KAAK,SAAS,EAOf,MAAM,gBAAgB,CAAC;AAIxB,OAAO,EAAmB,KAAK,YAAY,EAAE,MAAM,QAAQ,CAAC;AAE5D,OAAO,EAAuC,KAAK,cAAc,EAAgB,MAAM,UAAU,CAAC;AAElG,OAAO,EAAuB,KAAK,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAClF,OAAO,EAA4B,KAAK,YAAY,EAAE,KAAK,YAAY,EAAgB,MAAM,YAAY,CAAC;AAC1G,OAAO,YAAY,CAAC;AAEpB,oHAAoH;AACpH,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,SAAS,CAAC;AAElD,+BAA+B;AAC/B,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,CAAC;IAC9B;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B,sGAAsG;IACtG,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB;;;;OAIG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAA;KAAE,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7F,mGAAmG;IACnG,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,2FAA2F;IAC3F,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,YAAY,GAAG,OAAO,CAAC;IAC/C,oHAAoH;IACpH,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;IAClC,oHAAoH;IACpH,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC;IAChC,iHAAiH;IACjH,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IACjC,uHAAuH;IACvH,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,wHAAwH;IACxH,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,2HAA2H;IAC3H,QAAQ,CAAC,2BAA2B,CAAC,EAAE,OAAO,CAAC;IAC/C,iHAAiH;IACjH,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,cAAc,EAAE,gBAAgB,CAAC,CAAC,CAAC;IAC7E,gHAAgH;IAChH,QAAQ,CAAC,+BAA+B,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,MAAM,CAAC;IAC3E,0FAA0F;IAC1F,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,+GAA+G;IAC/G,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,mCAAmC;AACnC,eAAO,MAAM,aAAa,8CAA2C,CAAC;AACtE,iCAAiC;AACjC,eAAO,MAAM,mBAAmB,8CAA2C,CAAC;AAC5E,+CAA+C;AAC/C,eAAO,MAAM,sBAAsB,2DAAwD,CAAC;AA+B5F;;;;;;;;GAQG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE,WAAW,GAAG,SAAS,CAmNpD"}
1
+ {"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../../src/host/host.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAiB,MAAM,+BAA+B,CAAC;AAElF,OAAO,EAIL,KAAK,SAAS,EAOf,MAAM,gBAAgB,CAAC;AAIxB,OAAO,EAAmB,KAAK,YAAY,EAAE,MAAM,QAAQ,CAAC;AAE5D,OAAO,EAAuC,KAAK,cAAc,EAAgB,MAAM,UAAU,CAAC;AAElG,OAAO,EAAuB,KAAK,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAClF,OAAO,EAA4B,KAAK,YAAY,EAAE,KAAK,YAAY,EAAgB,MAAM,YAAY,CAAC;AAC1G,OAAO,YAAY,CAAC;AAEpB,oHAAoH;AACpH,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,SAAS,CAAC;AAElD,+BAA+B;AAC/B,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,CAAC;IAC9B;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B,sGAAsG;IACtG,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB;;;;OAIG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAA;KAAE,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7F,mGAAmG;IACnG,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,2FAA2F;IAC3F,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,YAAY,GAAG,OAAO,CAAC;IAC/C,oHAAoH;IACpH,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;IAClC,oHAAoH;IACpH,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC;IAChC,iHAAiH;IACjH,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IACjC,uHAAuH;IACvH,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,wHAAwH;IACxH,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,2HAA2H;IAC3H,QAAQ,CAAC,2BAA2B,CAAC,EAAE,OAAO,CAAC;IAC/C,iHAAiH;IACjH,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,cAAc,EAAE,gBAAgB,CAAC,CAAC,CAAC;IAC7E,gHAAgH;IAChH,QAAQ,CAAC,+BAA+B,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,MAAM,CAAC;IAC3E,0FAA0F;IAC1F,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,+GAA+G;IAC/G,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,mCAAmC;AACnC,eAAO,MAAM,aAAa,8CAA2C,CAAC;AACtE,iCAAiC;AACjC,eAAO,MAAM,mBAAmB,8CAA2C,CAAC;AAC5E,+CAA+C;AAC/C,eAAO,MAAM,sBAAsB,2DAAwD,CAAC;AA+B5F;;;;;;;;;GASG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE,WAAW,GAAG,SAAS,CAmNpD"}
@@ -1,4 +1,4 @@
1
- import { G9Error } from "@g9tm/lynxcontrols-foundation";
1
+ import { G9Error, g9Ms } from "@g9tm/lynxcontrols-foundation";
2
2
  import { OverlayView } from "@lynx-js/lynx-ui-overlay";
3
3
  import { Fragment, createContext, memo, useContext, useEffect, useMemo, useRef, useState, useSyncExternalStore } from "@lynx-js/react";
4
4
  import { useStableCallback } from "../base/use-stable-callback.jsx";
@@ -210,7 +210,7 @@ function G9Host(props) {
210
210
  <view className="g9-host__content" style={{
211
211
  backgroundColor: null != (_props_background = props.background) ? _props_background : 'var(--g9-background)',
212
212
  transform: effect ? `translateY(${effect.translateY}px) scale(${effect.scale})` : 'translateY(0px) scale(1)',
213
- transition: `transform ${null != (_ref2 = null == effect ? void 0 : effect.durationMs) ? _ref2 : 300}ms ease-out`
213
+ transition: `transform ${g9Ms(null != (_ref2 = null == effect ? void 0 : effect.durationMs) ? _ref2 : 300)}ms ease-out`
214
214
  }}>
215
215
  {props.children}
216
216
  </view>
@@ -1 +1 @@
1
- {"version":3,"file":"host/host.jsx","sources":["../../src/host/host.tsx"],"sourcesContent":["import { type G9AbortSignal, G9Error } from '@g9tm/lynxcontrols-foundation';\nimport { OverlayView } from '@lynx-js/lynx-ui-overlay';\nimport {\n createContext,\n Fragment,\n memo,\n type ReactNode,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n useSyncExternalStore,\n} from '@lynx-js/react';\nimport { useStableCallback } from '../base/use-stable-callback';\nimport { G9KeyboardContext } from '../provider/contexts';\nimport { useG9Core, useG9SafeInsets, useG9Settings } from '../provider/hooks';\nimport { createBackStack, type G9BackResult } from './back';\nimport { isKeyboardTarget } from './keyboard';\nimport { createLayerStore, type G9LayerStore, type G9OverlayLayer, g9LayerOrder } from './layers';\nimport { G9PageLoadingOverlay } from './page-loading-overlay';\nimport { createHostReadiness, type G9HostReadinessController } from './readiness';\nimport { type G9HostContentEffect, type G9HostHandle, type G9HostInsets, hostRegistry } from './registry';\nimport './host.css';\n\n/** How a layer is mounted: in the page tree (default) or in a Lynx `<overlay>` above native views (maps, video). */\nexport type G9LayerContainer = 'tree' | 'overlay';\n\n/** Props of {@link G9Host}. */\nexport interface G9HostProps {\n readonly children?: ReactNode;\n /**\n * Whether the page is on screen (MAUI `Loaded`/`Unloaded`, tab activation). Default `true`. An inactive host stays\n * registered and becomes active again when set back to `true`; see `g9Hosts` for the resolution rule.\n */\n readonly active?: boolean;\n /** Names the page in diagnostics (the cover's busy activity is `page:<name>`). Default `'G9Host'`. */\n readonly name?: string;\n /**\n * The page's appearing work (MAUI `OnAppearingAfterParentAsync`), run through the provider's safe executor each time\n * the host becomes active; `signal` aborts when it stops being active or unmounts. On the first appearance the\n * loading cover waits for it (unless `manualRelease`).\n */\n readonly onAppearing?: (context: { readonly signal: G9AbortSignal }) => void | Promise<void>;\n /** Runs each time the host stops being active (MAUI `OnDisappearingAfterParentAsync`), guarded. */\n readonly onDisappearing?: () => void | Promise<void>;\n /** The page's own back handling (MAUI `TryHandleInAppBack`), asked after every overlay. */\n readonly onBack?: () => G9BackResult | boolean;\n /** Swallow every system back press before anything else runs (MAUI `IsHardwareBackSuppressed`). Default `false`. */\n readonly backSuppressed?: boolean;\n /** Show the page-loading cover until the page is ready (MAUI `G9PageLoadingOverlay`, always on). Default `true`. */\n readonly loadingCover?: boolean;\n /** The page releases the cover itself through `useG9HostReady().release()` (MAUI `PageLoadingManualRelease`). */\n readonly manualRelease?: boolean;\n /** Extra delay after ready (MAUI `PageLoadingDismissDelayMs`). Default `settings.pageLoading.dismissDelayMs` (369). */\n readonly dismissDelayMs?: number;\n /** Hard cap on the cover (MAUI `PageLoadingSafetyTimeoutMs`). Default `settings.pageLoading.safetyTimeoutMs` (5000). */\n readonly safetyTimeoutMs?: number;\n /** Dismiss the soft keyboard on a tap outside any keyboard target (MAUI `TapOutsideKeyboardDismisser`). Default `true`. */\n readonly dismissKeyboardOnTapOutside?: boolean;\n /** Per-layer container; a layer over a native view (map, video) needs `'overlay'`. Default `'tree'` for each. */\n readonly layerContainers?: Partial<Record<G9OverlayLayer, G9LayerContainer>>;\n /** MAUI `ComputeBottomSafeAreaWithTabBar`: the bottom inset plus the page's own tab bar. Default: the inset. */\n readonly computeBottomSafeAreaWithTabBar?: (bottomInset: number) => number;\n /** The page background (MAUI `ApplyThemedBackground`). Default `var(--g9-background)`. */\n readonly background?: string;\n /** The colour behind the content, shown when a sheet recedes the page (MAUI `BackdropHost`). Default black. */\n readonly backdropColor?: string;\n readonly className?: string;\n}\n\n/** The nearest host, for hooks. */\nexport const G9HostContext = createContext<G9HostHandle | null>(null);\n/** The nearest host's insets. */\nexport const G9HostInsetsContext = createContext<G9HostInsets | null>(null);\n/** The nearest host's readiness controller. */\nexport const G9HostReadinessContext = createContext<G9HostReadinessController | null>(null);\n\nconst OVERLAY_LAYERS = g9LayerOrder.filter((layer): layer is G9OverlayLayer => layer !== 'content');\nlet hostSequence = 0;\n\n// The inner name must differ from the binding: rslib renames `const X = memo(function X…)` with a module prefix and the\n// in-module `<X>` then compiles as an unknown intrinsic element (E20; scripts/check-dist-jsx.mjs).\nconst HostLayer = memo(function HostLayerRender(props: {\n readonly hostId: string;\n readonly store: G9LayerStore;\n readonly layer: G9OverlayLayer;\n readonly container: G9LayerContainer;\n}): ReactNode {\n const { hostId, store, layer, container } = props;\n const entries = useSyncExternalStore(\n (listener) => store.subscribe(layer, listener),\n () => store.getSnapshot(layer),\n );\n if (entries.length === 0) return null;\n const className = `g9-host__layer g9-host__layer--${layer}`;\n const items = entries.map((entry) => <Fragment key={entry.key}>{entry.element}</Fragment>);\n if (container === 'overlay') {\n return (\n <OverlayView container=\"window\" className={className} id={`${hostId}-${layer}`}>\n {items}\n </OverlayView>\n );\n }\n return <view className={className}>{items}</view>;\n});\n\n/**\n * The page frame (MAUI `G9PageBase` + `G9PageTemplate`): the content and the overlay layers in a fixed z-order\n * (`content` → `edgePanel` → `sheets` → `popups` → `feedback` → `floating`, then the loading cover), the page's back\n * stack, readiness and loading cover, safe-area insets, tap-outside keyboard dismissal, and its registration in\n * `g9Hosts` for code outside the tree. One per page; hosts may nest. Must be inside `G9Provider`.\n *\n * Layers are input-transparent (`pointer-events: none`), so empty areas pass touches to the layers below while each\n * item receives its own touches; an empty layer renders nothing.\n */\nexport function G9Host(props: G9HostProps): ReactNode {\n const core = useG9Core();\n const settings = useG9Settings();\n const parent = useContext(G9HostContext);\n const keyboard = useContext(G9KeyboardContext);\n const providerInsets = useG9SafeInsets();\n const active = props.active ?? true;\n const name = props.name ?? 'G9Host';\n\n const latest = useRef(props);\n latest.current = props;\n\n const bottomWithTabBar = props.computeBottomSafeAreaWithTabBar\n ? props.computeBottomSafeAreaWithTabBar(providerInsets.bottom)\n : providerInsets.bottom;\n const insets = useMemo<G9HostInsets>(\n () => Object.freeze({ ...providerInsets, bottomWithTabBar }),\n [providerInsets, bottomWithTabBar],\n );\n const insetsRef = useRef(insets);\n insetsRef.current = insets;\n\n const [state] = useState(() => {\n hostSequence += 1;\n const id = `g9-host-${hostSequence}`;\n const layers = createLayerStore();\n const back = createBackStack({\n isSuppressed: () => latest.current.backSuppressed === true,\n onHandlerError: (error) =>\n core.diagnostics.log({ level: 'error', message: 'A back handler threw.', source: name, error }),\n });\n const features = new Map<string, unknown>();\n let released = false;\n let contentEffect: G9HostContentEffect | null = null;\n const effectListeners = new Set<() => void>();\n const readiness = createHostReadiness({\n cover: props.loadingCover ?? true,\n manualRelease: props.manualRelease ?? false,\n dismissDelayMs: props.dismissDelayMs ?? settings.pageLoading.dismissDelayMs,\n safetyTimeoutMs: props.safetyTimeoutMs ?? settings.pageLoading.safetyTimeoutMs,\n startActivity: () => {\n const scope = core.diagnostics.activity(`page:${name}`);\n return () => scope.dispose();\n },\n runAppearing: async (signal) => {\n const onAppearing = latest.current.onAppearing;\n if (!onAppearing) return;\n await core.executor.run((context) => onAppearing({ signal: context.signal }), {\n source: name,\n throttleKey: `${id}.onAppearing`,\n enableThrottle: false,\n preventConcurrentExecution: false,\n signal,\n });\n },\n });\n const handle: G9HostHandle = {\n id,\n parent,\n services: core.services,\n layers,\n registerLayerItem(layer, item) {\n if (released) return () => {};\n return layers.register(layer, item);\n },\n removeLayerItem: (layer, key) => layers.remove(layer, key),\n back,\n getInsets: () => insetsRef.current,\n readiness,\n attachFeature(key, value) {\n if (features.has(key)) throw new G9Error('host-feature', `Host feature '${String(key)}' is already attached.`);\n features.set(key, value);\n return () => {\n if (features.get(key) === value) features.delete(key);\n };\n },\n getFeature: (key) => features.get(key) as never,\n get released() {\n return released;\n },\n setContentEffect(effect) {\n if (released || contentEffect === effect) return;\n contentEffect = effect;\n for (const listener of [...effectListeners]) listener();\n },\n getContentEffect: () => contentEffect,\n };\n const effectStore = {\n subscribe(listener: () => void) {\n effectListeners.add(listener);\n return () => {\n effectListeners.delete(listener);\n };\n },\n getSnapshot: () => contentEffect,\n };\n return {\n handle,\n readiness,\n effectStore,\n release() {\n released = true;\n features.clear();\n },\n };\n });\n const { handle, readiness, effectStore } = state;\n\n // Unmount: synchronous unregistration and release of everything the host owns.\n useEffect(\n () => () => {\n hostRegistry.remove(handle);\n readiness.dispose();\n handle.layers.clear();\n handle.back.clear();\n state.release();\n },\n [handle, readiness, state],\n );\n\n // Visibility drives the registry and the appearing/disappearing lifecycle.\n const wasActive = useRef<boolean | null>(null);\n useEffect(() => {\n const previous = wasActive.current;\n wasActive.current = active;\n if (active) {\n hostRegistry.activate(handle);\n readiness.appear();\n return;\n }\n if (previous === null) {\n hostRegistry.register(handle);\n return;\n }\n hostRegistry.markOffScreen(handle);\n readiness.disappear();\n const onDisappearing = latest.current.onDisappearing;\n if (onDisappearing) {\n core.executor.runSafe(() => onDisappearing(), {\n source: name,\n throttleKey: `${handle.id}.onDisappearing`,\n enableThrottle: false,\n preventConcurrentExecution: false,\n });\n }\n }, [active, handle, readiness, core, name]);\n\n // The page's own back handling sits in the content layer, below every overlay.\n const hasOnBack = props.onBack !== undefined;\n useEffect(\n () => (hasOnBack ? handle.back.push(() => latest.current.onBack?.() ?? 'pass') : undefined),\n [hasOnBack, handle],\n );\n\n const keyboardVisible = useRef(false);\n keyboardVisible.current = keyboard?.visible === true;\n const onCaptureTap = useStableCallback((event: { target?: { dataset?: Record<string, unknown> } }) => {\n if (!keyboardVisible.current || isKeyboardTarget(event.target)) return;\n core.services.host.hideKeyboard();\n });\n\n const cover = useSyncExternalStore(readiness.subscribe, readiness.getSnapshot).cover;\n const effect = useSyncExternalStore(effectStore.subscribe, effectStore.getSnapshot);\n const containers = props.layerContainers ?? {};\n const tapOutside = props.dismissKeyboardOnTapOutside ?? true;\n\n return (\n <G9HostContext.Provider value={handle}>\n <G9HostInsetsContext.Provider value={insets}>\n <G9HostReadinessContext.Provider value={readiness}>\n <view\n className={`g9-host${props.className ? ` ${props.className}` : ''}`}\n {...(tapOutside ? { 'capture-bindtap': onCaptureTap } : {})}\n >\n <view\n className=\"g9-host__backdrop\"\n style={{ backgroundColor: effect?.backdropColor ?? props.backdropColor ?? '#000000' }}\n />\n <view\n className=\"g9-host__content\"\n style={{\n backgroundColor: props.background ?? 'var(--g9-background)',\n transform: effect\n ? `translateY(${effect.translateY}px) scale(${effect.scale})`\n : 'translateY(0px) scale(1)',\n transition: `transform ${effect?.durationMs ?? 300}ms ease-out`,\n }}\n >\n {props.children}\n </view>\n {OVERLAY_LAYERS.map((layer) => (\n <HostLayer\n key={layer}\n hostId={handle.id}\n store={handle.layers}\n layer={layer}\n container={containers[layer] ?? 'tree'}\n />\n ))}\n {cover === 'hidden' ? null : (\n <G9PageLoadingOverlay\n exiting={cover === 'exiting'}\n backgroundColor={settings.pageLoading.backgroundColor}\n spinnerColor={settings.pageLoading.spinnerColor}\n />\n )}\n </view>\n </G9HostReadinessContext.Provider>\n </G9HostInsetsContext.Provider>\n </G9HostContext.Provider>\n );\n}\n"],"names":["G9HostContext","createContext","G9HostInsetsContext","G9HostReadinessContext","OVERLAY_LAYERS","g9LayerOrder","layer","hostSequence","HostLayer","memo","props","hostId","store","container","entries","useSyncExternalStore","listener","className","items","entry","Fragment","OverlayView","view","G9Host","_props_active","_props_name","_props_layerContainers","_props_dismissKeyboardOnTapOutside","_ref","_props_background","core","useG9Core","settings","useG9Settings","parent","useContext","keyboard","G9KeyboardContext","providerInsets","useG9SafeInsets","active","name","latest","useRef","bottomWithTabBar","insets","useMemo","Object","insetsRef","state","useState","_props_loadingCover","_props_manualRelease","_props_dismissDelayMs","_props_safetyTimeoutMs","id","layers","createLayerStore","back","createBackStack","error","features","Map","released","contentEffect","effectListeners","Set","readiness","createHostReadiness","scope","signal","onAppearing","context","handle","item","key","value","G9Error","String","effect","effectStore","useEffect","hostRegistry","wasActive","previous","onDisappearing","hasOnBack","undefined","_latest_current","keyboardVisible","onCaptureTap","useStableCallback","event","isKeyboardTarget","cover","containers","tapOutside","_containers_layer","G9PageLoadingOverlay"],"mappings":"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"}
1
+ {"version":3,"file":"host/host.jsx","sources":["../../src/host/host.tsx"],"sourcesContent":["import { type G9AbortSignal, G9Error, g9Ms } from '@g9tm/lynxcontrols-foundation';\nimport { OverlayView } from '@lynx-js/lynx-ui-overlay';\nimport {\n createContext,\n Fragment,\n memo,\n type ReactNode,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n useSyncExternalStore,\n} from '@lynx-js/react';\nimport { useStableCallback } from '../base/use-stable-callback';\nimport { G9KeyboardContext } from '../provider/contexts';\nimport { useG9Core, useG9SafeInsets, useG9Settings } from '../provider/hooks';\nimport { createBackStack, type G9BackResult } from './back';\nimport { isKeyboardTarget } from './keyboard';\nimport { createLayerStore, type G9LayerStore, type G9OverlayLayer, g9LayerOrder } from './layers';\nimport { G9PageLoadingOverlay } from './page-loading-overlay';\nimport { createHostReadiness, type G9HostReadinessController } from './readiness';\nimport { type G9HostContentEffect, type G9HostHandle, type G9HostInsets, hostRegistry } from './registry';\nimport './host.css';\n\n/** How a layer is mounted: in the page tree (default) or in a Lynx `<overlay>` above native views (maps, video). */\nexport type G9LayerContainer = 'tree' | 'overlay';\n\n/** Props of {@link G9Host}. */\nexport interface G9HostProps {\n readonly children?: ReactNode;\n /**\n * Whether the page is on screen (MAUI `Loaded`/`Unloaded`, tab activation). Default `true`. An inactive host stays\n * registered and becomes active again when set back to `true`; see `g9Hosts` for the resolution rule.\n */\n readonly active?: boolean;\n /** Names the page in diagnostics (the cover's busy activity is `page:<name>`). Default `'G9Host'`. */\n readonly name?: string;\n /**\n * The page's appearing work (MAUI `OnAppearingAfterParentAsync`), run through the provider's safe executor each time\n * the host becomes active; `signal` aborts when it stops being active or unmounts. On the first appearance the\n * loading cover waits for it (unless `manualRelease`).\n */\n readonly onAppearing?: (context: { readonly signal: G9AbortSignal }) => void | Promise<void>;\n /** Runs each time the host stops being active (MAUI `OnDisappearingAfterParentAsync`), guarded. */\n readonly onDisappearing?: () => void | Promise<void>;\n /** The page's own back handling (MAUI `TryHandleInAppBack`), asked after every overlay. */\n readonly onBack?: () => G9BackResult | boolean;\n /** Swallow every system back press before anything else runs (MAUI `IsHardwareBackSuppressed`). Default `false`. */\n readonly backSuppressed?: boolean;\n /** Show the page-loading cover until the page is ready (MAUI `G9PageLoadingOverlay`, always on). Default `true`. */\n readonly loadingCover?: boolean;\n /** The page releases the cover itself through `useG9HostReady().release()` (MAUI `PageLoadingManualRelease`). */\n readonly manualRelease?: boolean;\n /** Extra delay after ready (MAUI `PageLoadingDismissDelayMs`). Default `settings.pageLoading.dismissDelayMs` (369). */\n readonly dismissDelayMs?: number;\n /** Hard cap on the cover (MAUI `PageLoadingSafetyTimeoutMs`). Default `settings.pageLoading.safetyTimeoutMs` (5000). */\n readonly safetyTimeoutMs?: number;\n /** Dismiss the soft keyboard on a tap outside any keyboard target (MAUI `TapOutsideKeyboardDismisser`). Default `true`. */\n readonly dismissKeyboardOnTapOutside?: boolean;\n /** Per-layer container; a layer over a native view (map, video) needs `'overlay'`. Default `'tree'` for each. */\n readonly layerContainers?: Partial<Record<G9OverlayLayer, G9LayerContainer>>;\n /** MAUI `ComputeBottomSafeAreaWithTabBar`: the bottom inset plus the page's own tab bar. Default: the inset. */\n readonly computeBottomSafeAreaWithTabBar?: (bottomInset: number) => number;\n /** The page background (MAUI `ApplyThemedBackground`). Default `var(--g9-background)`. */\n readonly background?: string;\n /** The colour behind the content, shown when a sheet recedes the page (MAUI `BackdropHost`). Default black. */\n readonly backdropColor?: string;\n readonly className?: string;\n}\n\n/** The nearest host, for hooks. */\nexport const G9HostContext = createContext<G9HostHandle | null>(null);\n/** The nearest host's insets. */\nexport const G9HostInsetsContext = createContext<G9HostInsets | null>(null);\n/** The nearest host's readiness controller. */\nexport const G9HostReadinessContext = createContext<G9HostReadinessController | null>(null);\n\nconst OVERLAY_LAYERS = g9LayerOrder.filter((layer): layer is G9OverlayLayer => layer !== 'content');\nlet hostSequence = 0;\n\n// The inner name must differ from the binding: rslib renames `const X = memo(function X…)` with a module prefix and the\n// in-module `<X>` then compiles as an unknown intrinsic element (E20; scripts/check-dist-jsx.mjs).\nconst HostLayer = memo(function HostLayerRender(props: {\n readonly hostId: string;\n readonly store: G9LayerStore;\n readonly layer: G9OverlayLayer;\n readonly container: G9LayerContainer;\n}): ReactNode {\n const { hostId, store, layer, container } = props;\n const entries = useSyncExternalStore(\n (listener) => store.subscribe(layer, listener),\n () => store.getSnapshot(layer),\n );\n if (entries.length === 0) return null;\n const className = `g9-host__layer g9-host__layer--${layer}`;\n const items = entries.map((entry) => <Fragment key={entry.key}>{entry.element}</Fragment>);\n if (container === 'overlay') {\n return (\n <OverlayView container=\"window\" className={className} id={`${hostId}-${layer}`}>\n {items}\n </OverlayView>\n );\n }\n return <view className={className}>{items}</view>;\n});\n\n/**\n * The page frame (MAUI `G9PageBase` + `G9PageTemplate`): the content and the overlay layers in a fixed z-order\n * (`content` → `edgePanel` → `sheets` → `popups` → `feedback` → `floating`, then the loading cover), the page's back\n * stack, readiness and loading cover, safe-area insets, tap-outside keyboard dismissal, and its registration in\n * `g9Hosts` for code outside the tree. One per page; hosts may nest. Must be inside `G9Provider`.\n *\n * Layers are input-transparent (`pointer-events: none`), so empty areas pass touches to the layers below; each item\n * receives its own touches only when its root sets `pointer-events: auto` — Lynx inherits pointer-events, so an item\n * without it is transparent as well. An empty layer renders nothing.\n */\nexport function G9Host(props: G9HostProps): ReactNode {\n const core = useG9Core();\n const settings = useG9Settings();\n const parent = useContext(G9HostContext);\n const keyboard = useContext(G9KeyboardContext);\n const providerInsets = useG9SafeInsets();\n const active = props.active ?? true;\n const name = props.name ?? 'G9Host';\n\n const latest = useRef(props);\n latest.current = props;\n\n const bottomWithTabBar = props.computeBottomSafeAreaWithTabBar\n ? props.computeBottomSafeAreaWithTabBar(providerInsets.bottom)\n : providerInsets.bottom;\n const insets = useMemo<G9HostInsets>(\n () => Object.freeze({ ...providerInsets, bottomWithTabBar }),\n [providerInsets, bottomWithTabBar],\n );\n const insetsRef = useRef(insets);\n insetsRef.current = insets;\n\n const [state] = useState(() => {\n hostSequence += 1;\n const id = `g9-host-${hostSequence}`;\n const layers = createLayerStore();\n const back = createBackStack({\n isSuppressed: () => latest.current.backSuppressed === true,\n onHandlerError: (error) =>\n core.diagnostics.log({ level: 'error', message: 'A back handler threw.', source: name, error }),\n });\n const features = new Map<string, unknown>();\n let released = false;\n let contentEffect: G9HostContentEffect | null = null;\n const effectListeners = new Set<() => void>();\n const readiness = createHostReadiness({\n cover: props.loadingCover ?? true,\n manualRelease: props.manualRelease ?? false,\n dismissDelayMs: props.dismissDelayMs ?? settings.pageLoading.dismissDelayMs,\n safetyTimeoutMs: props.safetyTimeoutMs ?? settings.pageLoading.safetyTimeoutMs,\n startActivity: () => {\n const scope = core.diagnostics.activity(`page:${name}`);\n return () => scope.dispose();\n },\n runAppearing: async (signal) => {\n const onAppearing = latest.current.onAppearing;\n if (!onAppearing) return;\n await core.executor.run((context) => onAppearing({ signal: context.signal }), {\n source: name,\n throttleKey: `${id}.onAppearing`,\n enableThrottle: false,\n preventConcurrentExecution: false,\n signal,\n });\n },\n });\n const handle: G9HostHandle = {\n id,\n parent,\n services: core.services,\n layers,\n registerLayerItem(layer, item) {\n if (released) return () => {};\n return layers.register(layer, item);\n },\n removeLayerItem: (layer, key) => layers.remove(layer, key),\n back,\n getInsets: () => insetsRef.current,\n readiness,\n attachFeature(key, value) {\n if (features.has(key)) throw new G9Error('host-feature', `Host feature '${String(key)}' is already attached.`);\n features.set(key, value);\n return () => {\n if (features.get(key) === value) features.delete(key);\n };\n },\n getFeature: (key) => features.get(key) as never,\n get released() {\n return released;\n },\n setContentEffect(effect) {\n if (released || contentEffect === effect) return;\n contentEffect = effect;\n for (const listener of [...effectListeners]) listener();\n },\n getContentEffect: () => contentEffect,\n };\n const effectStore = {\n subscribe(listener: () => void) {\n effectListeners.add(listener);\n return () => {\n effectListeners.delete(listener);\n };\n },\n getSnapshot: () => contentEffect,\n };\n return {\n handle,\n readiness,\n effectStore,\n release() {\n released = true;\n features.clear();\n },\n };\n });\n const { handle, readiness, effectStore } = state;\n\n // Unmount: synchronous unregistration and release of everything the host owns.\n useEffect(\n () => () => {\n hostRegistry.remove(handle);\n readiness.dispose();\n handle.layers.clear();\n handle.back.clear();\n state.release();\n },\n [handle, readiness, state],\n );\n\n // Visibility drives the registry and the appearing/disappearing lifecycle.\n const wasActive = useRef<boolean | null>(null);\n useEffect(() => {\n const previous = wasActive.current;\n wasActive.current = active;\n if (active) {\n hostRegistry.activate(handle);\n readiness.appear();\n return;\n }\n if (previous === null) {\n hostRegistry.register(handle);\n return;\n }\n hostRegistry.markOffScreen(handle);\n readiness.disappear();\n const onDisappearing = latest.current.onDisappearing;\n if (onDisappearing) {\n core.executor.runSafe(() => onDisappearing(), {\n source: name,\n throttleKey: `${handle.id}.onDisappearing`,\n enableThrottle: false,\n preventConcurrentExecution: false,\n });\n }\n }, [active, handle, readiness, core, name]);\n\n // The page's own back handling sits in the content layer, below every overlay.\n const hasOnBack = props.onBack !== undefined;\n useEffect(\n () => (hasOnBack ? handle.back.push(() => latest.current.onBack?.() ?? 'pass') : undefined),\n [hasOnBack, handle],\n );\n\n const keyboardVisible = useRef(false);\n keyboardVisible.current = keyboard?.visible === true;\n const onCaptureTap = useStableCallback((event: { target?: { dataset?: Record<string, unknown> } }) => {\n if (!keyboardVisible.current || isKeyboardTarget(event.target)) return;\n core.services.host.hideKeyboard();\n });\n\n const cover = useSyncExternalStore(readiness.subscribe, readiness.getSnapshot).cover;\n const effect = useSyncExternalStore(effectStore.subscribe, effectStore.getSnapshot);\n const containers = props.layerContainers ?? {};\n const tapOutside = props.dismissKeyboardOnTapOutside ?? true;\n\n return (\n <G9HostContext.Provider value={handle}>\n <G9HostInsetsContext.Provider value={insets}>\n <G9HostReadinessContext.Provider value={readiness}>\n <view\n className={`g9-host${props.className ? ` ${props.className}` : ''}`}\n {...(tapOutside ? { 'capture-bindtap': onCaptureTap } : {})}\n >\n <view\n className=\"g9-host__backdrop\"\n style={{ backgroundColor: effect?.backdropColor ?? props.backdropColor ?? '#000000' }}\n />\n <view\n className=\"g9-host__content\"\n style={{\n backgroundColor: props.background ?? 'var(--g9-background)',\n transform: effect\n ? `translateY(${effect.translateY}px) scale(${effect.scale})`\n : 'translateY(0px) scale(1)',\n transition: `transform ${g9Ms(effect?.durationMs ?? 300)}ms ease-out`,\n }}\n >\n {props.children}\n </view>\n {OVERLAY_LAYERS.map((layer) => (\n <HostLayer\n key={layer}\n hostId={handle.id}\n store={handle.layers}\n layer={layer}\n container={containers[layer] ?? 'tree'}\n />\n ))}\n {cover === 'hidden' ? null : (\n <G9PageLoadingOverlay\n exiting={cover === 'exiting'}\n backgroundColor={settings.pageLoading.backgroundColor}\n spinnerColor={settings.pageLoading.spinnerColor}\n />\n )}\n </view>\n </G9HostReadinessContext.Provider>\n </G9HostInsetsContext.Provider>\n </G9HostContext.Provider>\n );\n}\n"],"names":["G9HostContext","createContext","G9HostInsetsContext","G9HostReadinessContext","OVERLAY_LAYERS","g9LayerOrder","layer","hostSequence","HostLayer","memo","props","hostId","store","container","entries","useSyncExternalStore","listener","className","items","entry","Fragment","OverlayView","view","G9Host","_props_active","_props_name","_props_layerContainers","_props_dismissKeyboardOnTapOutside","_ref","_props_background","core","useG9Core","settings","useG9Settings","parent","useContext","keyboard","G9KeyboardContext","providerInsets","useG9SafeInsets","active","name","latest","useRef","bottomWithTabBar","insets","useMemo","Object","insetsRef","state","useState","_props_loadingCover","_props_manualRelease","_props_dismissDelayMs","_props_safetyTimeoutMs","id","layers","createLayerStore","back","createBackStack","error","features","Map","released","contentEffect","effectListeners","Set","readiness","createHostReadiness","scope","signal","onAppearing","context","handle","item","key","value","G9Error","String","effect","effectStore","useEffect","hostRegistry","wasActive","previous","onDisappearing","hasOnBack","undefined","_latest_current","keyboardVisible","onCaptureTap","useStableCallback","event","isKeyboardTarget","cover","containers","tapOutside","g9Ms","_containers_layer","G9PageLoadingOverlay"],"mappings":"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"}
@@ -27,7 +27,15 @@ export interface G9ComboBoxProps<T extends G9SelectionItem = G9SelectionItem> ex
27
27
  readonly clearButton?: boolean;
28
28
  /** Direction of the value/chips and the sheet rows (MAUI `ValueTextDirection`). Default follows the culture. */
29
29
  readonly valueTextDirection?: G9TextInputDirection;
30
+ /**
31
+ * How a multi-select field draws its chosen items (MAUI 1.4.10 `ChipStyle`): `'filled'` (default — primary chips) or
32
+ * `'tonal'` — light pills (SurfaceContainerLow, an OutlineVariant hairline, TextPrimary 14) each with its own «×» that
33
+ * removes that one item without opening the sheet. Pair with `clearButton={false}` to keep the trailing glyph (AgriPad).
34
+ */
35
+ readonly chipStyle?: G9ComboBoxChipStyle;
30
36
  }
37
+ /** MAUI `G9ComboBoxChipStyle`. */
38
+ export type G9ComboBoxChipStyle = 'filled' | 'tonal';
31
39
  /** Two key lists hold the same keys in the same order. */
32
40
  export declare function sameSelectionKeys(a: ReadonlyArray<string>, b: ReadonlyArray<string>): boolean;
33
41
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"combo-box.d.ts","sourceRoot":"","sources":["../../src/pickers/combo-box.tsx"],"names":[],"mappings":"AAAA,OAAO,eAAe,CAAC;AACvB,OAAO,EAAgD,KAAK,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACxH,OAAO,EAAE,KAAK,SAAS,EAAU,MAAM,gBAAgB,CAAC;AAExD,OAAO,EAAE,KAAK,eAAe,EAAgB,MAAM,wBAAwB,CAAC;AAK5E,OAAO,EACL,KAAK,kBAAkB,EAMxB,MAAM,WAAW,CAAC;AAEnB,yEAAyE;AACzE,eAAO,MAAM,eAAe,IAAI,CAAC;AAEjC,mCAAmC;AACnC,MAAM,WAAW,eAAe,CAAC,CAAC,SAAS,eAAe,GAAG,eAAe,CAAE,SAAQ,kBAAkB;IACtG,sGAAsG;IACtG,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC;IACjC,iHAAiH;IACjH,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IACjC,2DAA2D;IAC3D,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,EAAE,CAAC,GAAG,IAAI,KAAK,IAAI,CAAC;IACtE,2EAA2E;IAC3E,QAAQ,CAAC,MAAM,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACxC,QAAQ,CAAC,aAAa,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAC/C,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;IACzF,4DAA4D;IAC5D,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,kGAAkG;IAClG,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,2GAA2G;IAC3G,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B,gHAAgH;IAChH,QAAQ,CAAC,kBAAkB,CAAC,EAAE,oBAAoB,CAAC;CACpD;AAED,0DAA0D;AAC1D,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,OAAO,CAE7F;AAGD;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS,eAAe,GAAG,eAAe,EAAE,KAAK,EAAE,eAAe,CAAC,CAAC,CAAC,GAAG,SAAS,CAqH5G"}
1
+ {"version":3,"file":"combo-box.d.ts","sourceRoot":"","sources":["../../src/pickers/combo-box.tsx"],"names":[],"mappings":"AACA,OAAO,eAAe,CAAC;AACvB,OAAO,EAAgD,KAAK,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACxH,OAAO,EAAE,KAAK,SAAS,EAAU,MAAM,gBAAgB,CAAC;AAExD,OAAO,EAAE,KAAK,eAAe,EAA+B,MAAM,wBAAwB,CAAC;AAM3F,OAAO,EACL,KAAK,kBAAkB,EAMxB,MAAM,WAAW,CAAC;AAEnB,yEAAyE;AACzE,eAAO,MAAM,eAAe,IAAI,CAAC;AAEjC,mCAAmC;AACnC,MAAM,WAAW,eAAe,CAAC,CAAC,SAAS,eAAe,GAAG,eAAe,CAAE,SAAQ,kBAAkB;IACtG,sGAAsG;IACtG,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC;IACjC,iHAAiH;IACjH,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IACjC,2DAA2D;IAC3D,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,EAAE,CAAC,GAAG,IAAI,KAAK,IAAI,CAAC;IACtE,2EAA2E;IAC3E,QAAQ,CAAC,MAAM,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACxC,QAAQ,CAAC,aAAa,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAC/C,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;IACzF,4DAA4D;IAC5D,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,kGAAkG;IAClG,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,2GAA2G;IAC3G,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B,gHAAgH;IAChH,QAAQ,CAAC,kBAAkB,CAAC,EAAE,oBAAoB,CAAC;IACnD;;;;OAIG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,mBAAmB,CAAC;CAC1C;AAED,kCAAkC;AAClC,MAAM,MAAM,mBAAmB,GAAG,QAAQ,GAAG,OAAO,CAAC;AAErD,0DAA0D;AAC1D,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,OAAO,CAE7F;AAGD;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS,eAAe,GAAG,eAAe,EAAE,KAAK,EAAE,eAAe,CAAC,CAAC,CAAC,GAAG,SAAS,CAwI5G"}
@@ -1,9 +1,11 @@
1
+ import { resolveRestingPlaceholder } from "../fields/outlined-field.jsx";
1
2
  import "./pickers.css";
2
3
  import { G9StringKey, buildSolidOrGradient, fillToCss } from "@g9tm/lynxcontrols-foundation";
3
4
  import { useRef } from "@lynx-js/react";
4
5
  import { g9RowStyle } from "../base/control.jsx";
5
- import { selectionKey } from "../base/selection-item.jsx";
6
+ import { isAvatarImage, selectionKey } from "../base/selection-item.jsx";
6
7
  import { useControllableState } from "../base/use-controllable-state.jsx";
8
+ import { G9IconSlot, hasIconSlot } from "../icon/slot.jsx";
7
9
  import { useG9Direction, useG9Settings, useG9Strings, useG9Theme } from "../provider/hooks.jsx";
8
10
  import { showSelectionSheet } from "../selection/selection-sheet.jsx";
9
11
  import { useG9Sheets } from "../sheet/service.jsx";
@@ -14,7 +16,7 @@ function sameSelectionKeys(a, b) {
14
16
  }
15
17
  const sameKeys = sameSelectionKeys;
16
18
  function G9ComboBox(props) {
17
- var _props_defaultValue, _props_defaultValues, _props_placeholder;
19
+ var _props_defaultValue, _props_defaultValues, _resolveRestingPlaceholder;
18
20
  const sheets = useG9Sheets();
19
21
  const glyphs = useG9Settings().glyphs;
20
22
  const strings = useG9Strings();
@@ -55,6 +57,13 @@ function G9ComboBox(props) {
55
57
  if (multiple) setKeys([], []);
56
58
  else setKey(null, null);
57
59
  };
60
+ const removeOne = (item)=>{
61
+ if (blocked) return;
62
+ const k = selectionKey(item);
63
+ const next = latest.current.keys.filter((x)=>x !== k);
64
+ if (next.length !== latest.current.keys.length) setKeys(next, byKey(next));
65
+ };
66
+ const tonal = 'tonal' === props.chipStyle;
58
67
  const onOpen = ()=>open(async (isCurrent)=>{
59
68
  var _ref, _p_label, _p_emptyStateText;
60
69
  var _p_sheetTitle;
@@ -103,27 +112,60 @@ function G9ComboBox(props) {
103
112
  } : null}>
104
113
  <view className={`g9-combo__value ${dir}`} style={row}>
105
114
  {multiple && hasValue ? <view className="g9-combo__chips" style={row}>
106
- {selected.slice(0, g9ComboMaxChips).map((item)=><view key={selectionKey(item)} className="g9-combo__chip" style={{
115
+ {selected.slice(0, g9ComboMaxChips).map((item)=>tonal ? <TonalChip key={selectionKey(item)} item={item} row={row} rtl={'rtl' === valueDirection(props.valueTextDirection, culture)} removable={!blocked} onRemove={()=>removeOne(item)}/> : <view key={selectionKey(item)} className="g9-combo__chip" style={{
107
116
  ...row,
108
117
  background: fillToCss(buildSolidOrGradient(primary, true))
109
118
  }}>
110
- <SelectionValueIcon item={item} color="var(--g9-on-primary)"/>
111
- <text className="g9-combo__chip-text" text-maxline="1">
112
- {item.text}
113
- </text>
114
- </view>)}
119
+ <SelectionValueIcon item={item} color="var(--g9-on-primary)" inChip/>
120
+ <text className="g9-combo__chip-text" text-maxline="1">
121
+ {item.text}
122
+ </text>
123
+ </view>)}
115
124
  {selected.length > g9ComboMaxChips ? <view className="g9-combo__chip g9-combo__chip--more">
116
125
  <text className="g9-combo__chip-text">{`+${selected.length - g9ComboMaxChips}`}</text>
117
126
  </view> : null}
118
127
  </view> : [
119
128
  hasValue ? <SelectionValueIcon key="i" item={selected[0]}/> : null,
120
129
  <text key="t" className={`g9-picker__text${hasValue ? '' : ' g9-picker__text--placeholder'}`} text-maxline="1">
121
- {hasValue ? selected[0].text : props.label ? '' : null != (_props_placeholder = props.placeholder) ? _props_placeholder : ''}
130
+ {hasValue ? selected[0].text : null != (_resolveRestingPlaceholder = resolveRestingPlaceholder(props)) ? _resolveRestingPlaceholder : ''}
122
131
  </text>
123
132
  ]}
124
133
  </view>
125
134
  </PickerField>;
126
135
  }
136
+ function TonalChip(props) {
137
+ var _item_emoji, _item_iconPath, _item_iconImage, _item_iconTintColor;
138
+ const glyphs = useG9Settings().glyphs;
139
+ const { item } = props;
140
+ const icon = {
141
+ emoji: null != (_item_emoji = item.emoji) ? _item_emoji : null,
142
+ icon: item.icon,
143
+ imagePath: null != (_item_iconPath = item.iconPath) ? _item_iconPath : null,
144
+ image: null != (_item_iconImage = item.iconImage) ? _item_iconImage : null
145
+ };
146
+ return <view className="g9-combo__tonal" style={{
147
+ ...props.row,
148
+ ...props.rtl ? {
149
+ paddingRight: '10px',
150
+ paddingLeft: '6px',
151
+ marginLeft: '4px'
152
+ } : {
153
+ paddingLeft: '10px',
154
+ paddingRight: '6px',
155
+ marginRight: '4px'
156
+ }
157
+ }}>
158
+ {!isAvatarImage(item) && hasIconSlot(icon) ? <G9IconSlot {...icon} size={14} color={null != (_item_iconTintColor = item.iconTintColor) ? _item_iconTintColor : 'var(--g9-on-surface-variant)'}/> : null}
159
+ <text className="g9-combo__tonal-text" text-maxline="1">
160
+ {item.text}
161
+ </text>
162
+ <view className="g9-combo__tonal-close" accessibility-element={true} accessibility-traits="button" accessibility-label={item.text} {...props.removable ? {
163
+ catchtap: props.onRemove
164
+ } : {}}>
165
+ <G9IconSlot icon={glyphs.clear} size={16} color="var(--g9-text-tertiary)"/>
166
+ </view>
167
+ </view>;
168
+ }
127
169
  export { G9ComboBox, g9ComboMaxChips, sameSelectionKeys };
128
170
 
129
171
  //# sourceMappingURL=combo-box.jsx.map