@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":"toast/store.jsx","sources":["../../src/toast/store.ts"],"sourcesContent":["import type { G9IconInput } from '../icon/icon';\n\n// Toast state (MAUI `G9ToastHelper`): typed toasts in per-position stacks, the reference-counted full-screen loader,\n// the compact loading toast and the progress toast, as a pure store. The view renders `getSnapshot()`; timers come\n// from the caller so tests drive time.\n\n/** Toast kind (MAUI `G9ToastType`). */\nexport const G9ToastType = {\n Information: 'information',\n Success: 'success',\n Warning: 'warning',\n Error: 'error',\n} as const;\nexport type G9ToastType = (typeof G9ToastType)[keyof typeof G9ToastType];\n\n/** Nine anchors (MAUI `G9ToastPosition`). */\nexport const G9ToastPosition = {\n TopLeft: 'topLeft',\n TopCenter: 'topCenter',\n TopRight: 'topRight',\n MiddleLeft: 'middleLeft',\n MiddleCenter: 'middleCenter',\n MiddleRight: 'middleRight',\n BottomLeft: 'bottomLeft',\n BottomCenter: 'bottomCenter',\n BottomRight: 'bottomRight',\n} as const;\nexport type G9ToastPosition = (typeof G9ToastPosition)[keyof typeof G9ToastPosition];\n\n/** Options of one toast (MAUI `G9ToastOptions`). */\nexport interface G9ToastOptions {\n /** Default: bottom right (LTR) / bottom left (RTL). */\n readonly position?: G9ToastPosition | null;\n /** Auto-dismiss after this many ms. Default 3000. */\n readonly durationMs?: number;\n /** Icon override; default the type's glyph. */\n readonly icon?: G9IconInput;\n /** Action button text (e.g. \"Undo\"); with `action`. */\n readonly actionText?: string | null;\n /** Runs once when the action button is tapped (through the provider's safe executor). */\n readonly action?: (() => unknown) | null;\n}\n\n/** Default toast options (MAUI `G9ToastOptions.Default`). */\nexport const g9DefaultToastOptions: Readonly<Required<Pick<G9ToastOptions, 'durationMs'>>> = Object.freeze({\n durationMs: 3000,\n});\n\n/** Timings (MAUI toast guide). */\nexport const g9ToastTimings = Object.freeze({\n enterMs: 250,\n exitMs: 200,\n loaderFadeInMs: 200,\n loaderFadeOutMs: 180,\n reanchorMs: 220,\n});\n/** Most toasts per stack (MAUI `MaxToastsPerStack`). */\nexport const g9MaxToastsPerStack = 4;\n\n/** One live toast. */\nexport interface G9ToastEntry {\n readonly id: number;\n readonly message: string;\n readonly type: G9ToastType;\n readonly position: G9ToastPosition;\n readonly icon: G9IconInput;\n readonly actionText: string | null;\n readonly hasAction: boolean;\n readonly status: 'entering' | 'shown' | 'leaving';\n /** Bumped when an identical toast collapsed into this one (its lifetime restarted). */\n readonly refreshes: number;\n /** Its lifetime (the countdown fill runs over it; 0 or less = sticky, no fill). */\n readonly durationMs: number;\n}\n\n/** The full-screen loader (visible while at least one hold is open). */\nexport interface G9LoaderState {\n readonly text: string;\n readonly status: 'entering' | 'shown' | 'leaving';\n}\n\n/** The compact loading toast. */\nexport interface G9LoadingToastState {\n readonly text: string;\n readonly position: G9ToastPosition;\n}\n\n/** The progress toast. */\nexport interface G9ProgressToastState {\n readonly title: string;\n readonly detail: string | null;\n /** 0…1. */\n readonly progress: number;\n readonly position: G9ToastPosition;\n}\n\n/** What the view renders. */\nexport interface G9ToastSnapshot {\n readonly toasts: ReadonlyArray<G9ToastEntry>;\n readonly loader: G9LoaderState | null;\n readonly loadingToast: G9LoadingToastState | null;\n readonly progress: G9ProgressToastState | null;\n /** Bumped by `refreshBottomInsets`; `reanchorAnimated` says whether the move glides. */\n readonly insetVersion: number;\n readonly reanchorAnimated: boolean;\n /** Heights of bottom-anchored overlays the bottom stacks sit above (MAUI `IG9BottomAnchoredOverlay`). */\n readonly bottomOverlayHeight: number;\n}\n\n/** A hold on the full-screen loader (MAUI `BeginLoadingAsync` lease); disposing twice is harmless. */\nexport interface G9LoadingLease {\n dispose(): void;\n}\n\n/** A shown toast. */\nexport interface G9ToastHandle {\n readonly id: number;\n dismiss(): void;\n /** Settles when the toast left the screen. */\n readonly closed: Promise<void>;\n}\n\n/** Timing and action plumbing of the store. */\nexport interface G9ToastStoreConfig {\n setTimer(callback: () => void, ms: number): unknown;\n clearTimer(handle: unknown): void;\n /** Runs a toast action (once per tap is the store's job; errors are the runner's). */\n runAction(action: () => unknown): void;\n /** Where a toast without a position goes (bottom right in LTR, bottom left in RTL). */\n defaultPosition(): G9ToastPosition;\n}\n\ninterface ToastRecord {\n entry: G9ToastEntry;\n action: (() => unknown) | null;\n durationMs: number;\n timer: unknown;\n actionRan: boolean;\n closed: () => void;\n}\n\ninterface Hold {\n readonly token: number;\n readonly text: string;\n readonly lease: boolean;\n}\n\nconst isPlain = (r: ToastRecord) => !r.entry.hasAction;\n\n/** The toast store. */\nexport class G9ToastStore {\n private records: ToastRecord[] = [];\n private holds: Hold[] = [];\n private loaderStatus: G9LoaderState['status'] | null = null;\n private loaderText = '';\n private loaderTimer: unknown = null;\n private loadingToast: G9LoadingToastState | null = null;\n private progress: G9ProgressToastState | null = null;\n private insetVersion = 0;\n private reanchorAnimated = true;\n private readonly overlays = new Map<string, number>();\n private nextId = 1;\n private readonly listeners = new Set<() => void>();\n private snapshot: G9ToastSnapshot;\n private disposed = false;\n\n constructor(private readonly config: G9ToastStoreConfig) {\n this.snapshot = this.build();\n }\n\n getSnapshot(): G9ToastSnapshot {\n return this.snapshot;\n }\n\n subscribe(listener: () => void): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n /**\n * Shows a toast (MAUI `ShowToastAsync`). An identical newest toast of the same stack (same message and type, no\n * action on either) is refreshed instead (lifetime restarted). Past four per stack the oldest leaves.\n */\n show(message: string, type: G9ToastType = 'information', options: G9ToastOptions = {}): G9ToastHandle {\n const position = options.position ?? this.config.defaultPosition();\n const hasAction = !!options.actionText && !!options.action;\n const duration = options.durationMs ?? g9DefaultToastOptions.durationMs;\n const stack = this.records.filter((r) => r.entry.position === position && r.entry.status !== 'leaving');\n const newest = stack[stack.length - 1];\n if (\n !this.disposed &&\n newest &&\n !hasAction &&\n isPlain(newest) &&\n newest.entry.message === message &&\n newest.entry.type === type\n ) {\n newest.entry = { ...newest.entry, refreshes: newest.entry.refreshes + 1, durationMs: duration };\n newest.durationMs = duration;\n this.arm(newest);\n this.emit();\n return this.handle(newest);\n }\n let closed!: () => void;\n const done = new Promise<void>((r) => (closed = r));\n const record: ToastRecord = {\n entry: {\n id: this.nextId++,\n message,\n type,\n position,\n icon: options.icon,\n actionText: hasAction ? (options.actionText as string) : null,\n hasAction,\n status: 'entering',\n refreshes: 0,\n durationMs: duration,\n },\n action: hasAction ? (options.action as () => unknown) : null,\n durationMs: duration,\n timer: null,\n actionRan: false,\n closed,\n };\n if (this.disposed) {\n closed();\n return { id: record.entry.id, dismiss: () => {}, closed: done };\n }\n this.records.push(record);\n for (const extra of stack.slice(0, Math.max(0, stack.length + 1 - g9MaxToastsPerStack))) this.leave(extra);\n this.later(() => {\n if (record.entry.status === 'entering') {\n record.entry = { ...record.entry, status: 'shown' };\n this.emit();\n }\n }, g9ToastTimings.enterMs);\n this.arm(record);\n this.emit();\n return { ...this.handle(record), closed: done };\n }\n\n /** Dismisses one toast, or every typed toast (MAUI `DismissToastAsync`). */\n dismissToast(id?: number): void {\n for (const r of [...this.records]) if (id === undefined || r.entry.id === id) this.leave(r);\n }\n\n /** The action button: runs the action once (a second tap during the exit does nothing) and dismisses. */\n pressAction(id: number): void {\n const r = this.records.find((x) => x.entry.id === id);\n if (!r || r.actionRan || !r.action) return;\n r.actionRan = true;\n this.config.runAction(r.action);\n this.leave(r);\n }\n\n /** Raises the full-screen loader (reference-counted; the newest text wins) (MAUI `ShowLoadingAsync`). */\n showLoading(text = ''): void {\n this.hold({ token: this.nextId++, text, lease: false });\n }\n\n /** A lease on the loader (MAUI `BeginLoadingAsync`). */\n beginLoading(text = ''): G9LoadingLease {\n const hold = { token: this.nextId++, text, lease: true };\n this.hold(hold);\n let released = false;\n return {\n dispose: () => {\n if (released) return;\n released = true;\n this.release(hold.token);\n },\n };\n }\n\n /** Releases the newest anonymous hold; a lease's hold is never released here (MAUI `DismissLoadingAsync`). */\n dismissLoading(): void {\n const anonymous = [...this.holds].reverse().find((h) => !h.lease);\n if (anonymous) this.release(anonymous.token);\n }\n\n /** Shows (or relabels) the compact loading toast (MAUI `ShowLoadingToastAsync`); it never auto-dismisses. */\n showLoadingToast(text = '', position: G9ToastPosition | null = null): void {\n this.loadingToast = { text, position: position ?? this.config.defaultPosition() };\n this.emit();\n }\n\n dismissLoadingToast(): void {\n if (!this.loadingToast) return;\n this.loadingToast = null;\n this.emit();\n }\n\n /** Shows the progress toast, replacing an active one (MAUI `ShowProgressToastAsync`). */\n showProgress(\n title: string,\n detail: string | null = null,\n progress = 0,\n position: G9ToastPosition | null = null,\n ): void {\n this.progress = { title, detail, progress: clamp01(progress), position: position ?? this.config.defaultPosition() };\n this.emit();\n }\n\n /** Updates the progress toast; omitted parts stay (MAUI `UpdateProgressToastAsync`). No-op without one. */\n updateProgress(title?: string | null, detail?: string | null, progress?: number | null): void {\n if (!this.progress) return;\n this.progress = {\n ...this.progress,\n ...(title != null ? { title } : {}),\n ...(detail !== undefined && detail !== null ? { detail } : {}),\n ...(progress != null ? { progress: clamp01(progress) } : {}),\n };\n this.emit();\n }\n\n dismissProgress(): void {\n if (!this.progress) return;\n this.progress = null;\n this.emit();\n }\n\n /** Re-anchors every live toast to the current insets; `animate` glides (220 ms) (MAUI `RefreshBottomInsetsAsync`). */\n refreshBottomInsets(animate = true): void {\n this.insetVersion += 1;\n this.reanchorAnimated = animate;\n this.emit();\n }\n\n /** Registers (or clears with `null`) a bottom-anchored overlay the bottom stacks must sit above. */\n setBottomOverlay(key: string, heightPx: number | null): void {\n if (heightPx === null || heightPx <= 0) this.overlays.delete(key);\n else this.overlays.set(key, heightPx);\n this.emit();\n }\n\n /** Clears everything, the loader regardless of its count (MAUI `DismissAllAsync`). */\n dismissAll(): void {\n this.dismissToast();\n this.holds = [];\n this.updateLoader();\n this.loadingToast = null;\n this.progress = null;\n this.emit();\n }\n\n /** The host unmounted. */\n dispose(): void {\n this.disposed = true;\n for (const r of this.records) {\n if (r.timer !== null) this.config.clearTimer(r.timer);\n r.closed();\n }\n this.records = [];\n if (this.loaderTimer !== null) this.config.clearTimer(this.loaderTimer);\n this.holds = [];\n this.loaderStatus = null;\n this.emit();\n }\n\n private handle(record: ToastRecord): G9ToastHandle {\n return {\n id: record.entry.id,\n dismiss: () => this.leave(record),\n closed: Promise.resolve(),\n };\n }\n\n private arm(record: ToastRecord): void {\n if (record.timer !== null) this.config.clearTimer(record.timer);\n record.timer = this.config.setTimer(() => {\n record.timer = null;\n this.leave(record);\n }, record.durationMs);\n }\n\n private leave(record: ToastRecord): void {\n if (record.entry.status === 'leaving' || !this.records.includes(record)) return;\n if (record.timer !== null) this.config.clearTimer(record.timer);\n record.timer = null;\n record.entry = { ...record.entry, status: 'leaving' };\n this.emit();\n this.later(() => {\n this.records = this.records.filter((r) => r !== record);\n record.closed();\n this.emit();\n }, g9ToastTimings.exitMs);\n }\n\n private hold(hold: Hold): void {\n this.holds.push(hold);\n this.updateLoader();\n this.emit();\n }\n\n private release(token: number): void {\n this.holds = this.holds.filter((h) => h.token !== token);\n this.updateLoader();\n this.emit();\n }\n\n private updateLoader(): void {\n const top = this.holds[this.holds.length - 1];\n if (top) {\n this.loaderText = top.text;\n if (this.loaderStatus === null || this.loaderStatus === 'leaving') {\n if (this.loaderTimer !== null) this.config.clearTimer(this.loaderTimer);\n this.loaderStatus = 'entering';\n this.loaderTimer = this.config.setTimer(() => {\n this.loaderTimer = null;\n this.loaderStatus = 'shown';\n this.emit();\n }, g9ToastTimings.loaderFadeInMs);\n }\n return;\n }\n if (this.loaderStatus === null || this.loaderStatus === 'leaving') return;\n if (this.loaderTimer !== null) this.config.clearTimer(this.loaderTimer);\n this.loaderStatus = 'leaving';\n this.loaderTimer = this.config.setTimer(() => {\n this.loaderTimer = null;\n this.loaderStatus = null;\n this.emit();\n }, g9ToastTimings.loaderFadeOutMs);\n }\n\n private later(callback: () => void, ms: number): void {\n this.config.setTimer(() => {\n if (!this.disposed) callback();\n }, ms);\n }\n\n private build(): G9ToastSnapshot {\n return {\n toasts: this.records.map((r) => r.entry),\n loader: this.loaderStatus ? { text: this.loaderText, status: this.loaderStatus } : null,\n loadingToast: this.loadingToast,\n progress: this.progress,\n insetVersion: this.insetVersion,\n reanchorAnimated: this.reanchorAnimated,\n bottomOverlayHeight: [...this.overlays.values()].reduce((a, b) => a + b, 0),\n };\n }\n\n private emit(): void {\n this.snapshot = this.build();\n for (const l of this.listeners) l();\n }\n}\n\nfunction clamp01(v: number): number {\n return Number.isFinite(v) ? Math.min(1, Math.max(0, v)) : 0;\n}\n\n/** The culture default position: bottom right in LTR, bottom left in RTL. */\nexport function resolveToastPosition(position: G9ToastPosition | null | undefined, rtl: boolean): G9ToastPosition {\n return position ?? (rtl ? 'bottomLeft' : 'bottomRight');\n}\n"],"names":["G9ToastType","G9ToastPosition","g9DefaultToastOptions","Object","g9ToastTimings","g9MaxToastsPerStack","isPlain","r","G9ToastStore","listener","message","type","options","_options_position","_options_durationMs","position","hasAction","duration","stack","newest","closed","done","Promise","record","extra","Math","id","undefined","x","text","hold","released","anonymous","h","title","detail","progress","clamp01","animate","key","heightPx","token","top","callback","ms","a","b","l","config","Map","Set","v","Number","resolveToastPosition","rtl"],"mappings":"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"}
1
+ {"version":3,"file":"toast/store.jsx","sources":["../../src/toast/store.ts"],"sourcesContent":["import { g9Ms } from '@g9tm/lynxcontrols-foundation';\nimport type { G9IconInput } from '../icon/icon';\n\n// Toast state (MAUI `G9ToastHelper`): typed toasts in per-position stacks, the reference-counted full-screen loader,\n// the compact loading toast and the progress toast, as a pure store. The view renders `getSnapshot()`; timers come\n// from the caller so tests drive time.\n\n/** Toast kind (MAUI `G9ToastType`). */\nexport const G9ToastType = {\n Information: 'information',\n Success: 'success',\n Warning: 'warning',\n Error: 'error',\n} as const;\nexport type G9ToastType = (typeof G9ToastType)[keyof typeof G9ToastType];\n\n/** Nine anchors (MAUI `G9ToastPosition`). */\nexport const G9ToastPosition = {\n TopLeft: 'topLeft',\n TopCenter: 'topCenter',\n TopRight: 'topRight',\n MiddleLeft: 'middleLeft',\n MiddleCenter: 'middleCenter',\n MiddleRight: 'middleRight',\n BottomLeft: 'bottomLeft',\n BottomCenter: 'bottomCenter',\n BottomRight: 'bottomRight',\n} as const;\nexport type G9ToastPosition = (typeof G9ToastPosition)[keyof typeof G9ToastPosition];\n\n/** Options of one toast (MAUI `G9ToastOptions`). */\nexport interface G9ToastOptions {\n /** Default: bottom right (LTR) / bottom left (RTL). */\n readonly position?: G9ToastPosition | null;\n /** Auto-dismiss after this many ms. Default 3000. */\n readonly durationMs?: number;\n /** Icon override; default the type's glyph. */\n readonly icon?: G9IconInput;\n /** Action button text (e.g. \"Undo\"); with `action`. */\n readonly actionText?: string | null;\n /** Runs once when the action button is tapped (through the provider's safe executor). */\n readonly action?: (() => unknown) | null;\n}\n\n/** Default toast options (MAUI `G9ToastOptions.Default`). */\nexport const g9DefaultToastOptions: Readonly<Required<Pick<G9ToastOptions, 'durationMs'>>> = Object.freeze({\n durationMs: 3000,\n});\n\n/** Timings (MAUI toast guide). */\nexport const g9ToastTimings = Object.freeze({\n enterMs: 250,\n exitMs: 200,\n loaderFadeInMs: 200,\n loaderFadeOutMs: 180,\n reanchorMs: 220,\n});\n/** Most toasts per stack (MAUI `MaxToastsPerStack`). */\nexport const g9MaxToastsPerStack = 4;\n\n/** One live toast. */\nexport interface G9ToastEntry {\n readonly id: number;\n readonly message: string;\n readonly type: G9ToastType;\n readonly position: G9ToastPosition;\n readonly icon: G9IconInput;\n readonly actionText: string | null;\n readonly hasAction: boolean;\n readonly status: 'entering' | 'shown' | 'leaving';\n /** Bumped when an identical toast collapsed into this one (its lifetime restarted). */\n readonly refreshes: number;\n /** Its lifetime (the countdown fill runs over it; 0 or less = sticky, no fill). */\n readonly durationMs: number;\n}\n\n/** The full-screen loader (visible while at least one hold is open). */\nexport interface G9LoaderState {\n readonly text: string;\n readonly status: 'entering' | 'shown' | 'leaving';\n}\n\n/** The compact loading toast. */\nexport interface G9LoadingToastState {\n readonly text: string;\n readonly position: G9ToastPosition;\n}\n\n/** The progress toast. */\nexport interface G9ProgressToastState {\n readonly title: string;\n readonly detail: string | null;\n /** 0…1. */\n readonly progress: number;\n readonly position: G9ToastPosition;\n}\n\n/** What the view renders. */\nexport interface G9ToastSnapshot {\n readonly toasts: ReadonlyArray<G9ToastEntry>;\n readonly loader: G9LoaderState | null;\n readonly loadingToast: G9LoadingToastState | null;\n readonly progress: G9ProgressToastState | null;\n /** Bumped by `refreshBottomInsets`; `reanchorAnimated` says whether the move glides. */\n readonly insetVersion: number;\n readonly reanchorAnimated: boolean;\n /** Heights of bottom-anchored overlays the bottom stacks sit above (MAUI `IG9BottomAnchoredOverlay`). */\n readonly bottomOverlayHeight: number;\n}\n\n/** A hold on the full-screen loader (MAUI `BeginLoadingAsync` lease); disposing twice is harmless. */\nexport interface G9LoadingLease {\n dispose(): void;\n}\n\n/** A shown toast. */\nexport interface G9ToastHandle {\n readonly id: number;\n dismiss(): void;\n /** Settles when the toast left the screen. */\n readonly closed: Promise<void>;\n}\n\n/** Timing and action plumbing of the store. */\nexport interface G9ToastStoreConfig {\n setTimer(callback: () => void, ms: number): unknown;\n clearTimer(handle: unknown): void;\n /** Runs a toast action (once per tap is the store's job; errors are the runner's). */\n runAction(action: () => unknown): void;\n /** Where a toast without a position goes (bottom right in LTR, bottom left in RTL). */\n defaultPosition(): G9ToastPosition;\n}\n\ninterface ToastRecord {\n entry: G9ToastEntry;\n action: (() => unknown) | null;\n durationMs: number;\n timer: unknown;\n actionRan: boolean;\n closed: () => void;\n}\n\ninterface Hold {\n readonly token: number;\n readonly text: string;\n readonly lease: boolean;\n}\n\nconst isPlain = (r: ToastRecord) => !r.entry.hasAction;\n\n/** The toast store. */\nexport class G9ToastStore {\n private records: ToastRecord[] = [];\n private holds: Hold[] = [];\n private loaderStatus: G9LoaderState['status'] | null = null;\n private loaderText = '';\n private loaderTimer: unknown = null;\n private loadingToast: G9LoadingToastState | null = null;\n private progress: G9ProgressToastState | null = null;\n private insetVersion = 0;\n private reanchorAnimated = true;\n private readonly overlays = new Map<string, number>();\n private nextId = 1;\n private readonly listeners = new Set<() => void>();\n private snapshot: G9ToastSnapshot;\n private disposed = false;\n\n constructor(private readonly config: G9ToastStoreConfig) {\n this.snapshot = this.build();\n }\n\n getSnapshot(): G9ToastSnapshot {\n return this.snapshot;\n }\n\n subscribe(listener: () => void): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n /**\n * Shows a toast (MAUI `ShowToastAsync`). An identical newest toast of the same stack (same message and type, no\n * action on either) is refreshed instead (lifetime restarted). Past four per stack the oldest leaves.\n */\n show(message: string, type: G9ToastType = 'information', options: G9ToastOptions = {}): G9ToastHandle {\n const position = options.position ?? this.config.defaultPosition();\n const hasAction = !!options.actionText && !!options.action;\n const duration = options.durationMs ?? g9DefaultToastOptions.durationMs;\n const stack = this.records.filter((r) => r.entry.position === position && r.entry.status !== 'leaving');\n const newest = stack[stack.length - 1];\n if (\n !this.disposed &&\n newest &&\n !hasAction &&\n isPlain(newest) &&\n newest.entry.message === message &&\n newest.entry.type === type\n ) {\n newest.entry = { ...newest.entry, refreshes: newest.entry.refreshes + 1, durationMs: duration };\n newest.durationMs = duration;\n this.arm(newest);\n this.emit();\n return this.handle(newest);\n }\n let closed!: () => void;\n const done = new Promise<void>((r) => (closed = r));\n const record: ToastRecord = {\n entry: {\n id: this.nextId++,\n message,\n type,\n position,\n icon: options.icon,\n actionText: hasAction ? (options.actionText as string) : null,\n hasAction,\n status: 'entering',\n refreshes: 0,\n durationMs: duration,\n },\n action: hasAction ? (options.action as () => unknown) : null,\n durationMs: duration,\n timer: null,\n actionRan: false,\n closed,\n };\n if (this.disposed) {\n closed();\n return { id: record.entry.id, dismiss: () => {}, closed: done };\n }\n this.records.push(record);\n for (const extra of stack.slice(0, Math.max(0, stack.length + 1 - g9MaxToastsPerStack))) this.leave(extra);\n this.later(() => {\n if (record.entry.status === 'entering') {\n record.entry = { ...record.entry, status: 'shown' };\n this.emit();\n }\n }, g9Ms(g9ToastTimings.enterMs));\n this.arm(record);\n this.emit();\n return { ...this.handle(record), closed: done };\n }\n\n /** Dismisses one toast, or every typed toast (MAUI `DismissToastAsync`). */\n dismissToast(id?: number): void {\n for (const r of [...this.records]) if (id === undefined || r.entry.id === id) this.leave(r);\n }\n\n /** The action button: runs the action once (a second tap during the exit does nothing) and dismisses. */\n pressAction(id: number): void {\n const r = this.records.find((x) => x.entry.id === id);\n if (!r || r.actionRan || !r.action) return;\n r.actionRan = true;\n this.config.runAction(r.action);\n this.leave(r);\n }\n\n /** Raises the full-screen loader (reference-counted; the newest text wins) (MAUI `ShowLoadingAsync`). */\n showLoading(text = ''): void {\n this.hold({ token: this.nextId++, text, lease: false });\n }\n\n /** A lease on the loader (MAUI `BeginLoadingAsync`). */\n beginLoading(text = ''): G9LoadingLease {\n const hold = { token: this.nextId++, text, lease: true };\n this.hold(hold);\n let released = false;\n return {\n dispose: () => {\n if (released) return;\n released = true;\n this.release(hold.token);\n },\n };\n }\n\n /** Releases the newest anonymous hold; a lease's hold is never released here (MAUI `DismissLoadingAsync`). */\n dismissLoading(): void {\n const anonymous = [...this.holds].reverse().find((h) => !h.lease);\n if (anonymous) this.release(anonymous.token);\n }\n\n /** Shows (or relabels) the compact loading toast (MAUI `ShowLoadingToastAsync`); it never auto-dismisses. */\n showLoadingToast(text = '', position: G9ToastPosition | null = null): void {\n this.loadingToast = { text, position: position ?? this.config.defaultPosition() };\n this.emit();\n }\n\n dismissLoadingToast(): void {\n if (!this.loadingToast) return;\n this.loadingToast = null;\n this.emit();\n }\n\n /** Shows the progress toast, replacing an active one (MAUI `ShowProgressToastAsync`). */\n showProgress(\n title: string,\n detail: string | null = null,\n progress = 0,\n position: G9ToastPosition | null = null,\n ): void {\n this.progress = { title, detail, progress: clamp01(progress), position: position ?? this.config.defaultPosition() };\n this.emit();\n }\n\n /** Updates the progress toast; omitted parts stay (MAUI `UpdateProgressToastAsync`). No-op without one. */\n updateProgress(title?: string | null, detail?: string | null, progress?: number | null): void {\n if (!this.progress) return;\n this.progress = {\n ...this.progress,\n ...(title != null ? { title } : {}),\n ...(detail !== undefined && detail !== null ? { detail } : {}),\n ...(progress != null ? { progress: clamp01(progress) } : {}),\n };\n this.emit();\n }\n\n dismissProgress(): void {\n if (!this.progress) return;\n this.progress = null;\n this.emit();\n }\n\n /** Re-anchors every live toast to the current insets; `animate` glides (220 ms) (MAUI `RefreshBottomInsetsAsync`). */\n refreshBottomInsets(animate = true): void {\n this.insetVersion += 1;\n this.reanchorAnimated = animate;\n this.emit();\n }\n\n /** Registers (or clears with `null`) a bottom-anchored overlay the bottom stacks must sit above. */\n setBottomOverlay(key: string, heightPx: number | null): void {\n if (heightPx === null || heightPx <= 0) this.overlays.delete(key);\n else this.overlays.set(key, heightPx);\n this.emit();\n }\n\n /** Clears everything, the loader regardless of its count (MAUI `DismissAllAsync`). */\n dismissAll(): void {\n this.dismissToast();\n this.holds = [];\n this.updateLoader();\n this.loadingToast = null;\n this.progress = null;\n this.emit();\n }\n\n /** The host unmounted. */\n dispose(): void {\n this.disposed = true;\n for (const r of this.records) {\n if (r.timer !== null) this.config.clearTimer(r.timer);\n r.closed();\n }\n this.records = [];\n if (this.loaderTimer !== null) this.config.clearTimer(this.loaderTimer);\n this.holds = [];\n this.loaderStatus = null;\n this.emit();\n }\n\n private handle(record: ToastRecord): G9ToastHandle {\n return {\n id: record.entry.id,\n dismiss: () => this.leave(record),\n closed: Promise.resolve(),\n };\n }\n\n private arm(record: ToastRecord): void {\n if (record.timer !== null) this.config.clearTimer(record.timer);\n record.timer = this.config.setTimer(() => {\n record.timer = null;\n this.leave(record);\n }, record.durationMs);\n }\n\n private leave(record: ToastRecord): void {\n if (record.entry.status === 'leaving' || !this.records.includes(record)) return;\n if (record.timer !== null) this.config.clearTimer(record.timer);\n record.timer = null;\n record.entry = { ...record.entry, status: 'leaving' };\n this.emit();\n this.later(() => {\n this.records = this.records.filter((r) => r !== record);\n record.closed();\n this.emit();\n }, g9Ms(g9ToastTimings.exitMs));\n }\n\n private hold(hold: Hold): void {\n this.holds.push(hold);\n this.updateLoader();\n this.emit();\n }\n\n private release(token: number): void {\n this.holds = this.holds.filter((h) => h.token !== token);\n this.updateLoader();\n this.emit();\n }\n\n private updateLoader(): void {\n const top = this.holds[this.holds.length - 1];\n if (top) {\n this.loaderText = top.text;\n if (this.loaderStatus === null || this.loaderStatus === 'leaving') {\n if (this.loaderTimer !== null) this.config.clearTimer(this.loaderTimer);\n this.loaderStatus = 'entering';\n this.loaderTimer = this.config.setTimer(() => {\n this.loaderTimer = null;\n this.loaderStatus = 'shown';\n this.emit();\n }, g9ToastTimings.loaderFadeInMs);\n }\n return;\n }\n if (this.loaderStatus === null || this.loaderStatus === 'leaving') return;\n if (this.loaderTimer !== null) this.config.clearTimer(this.loaderTimer);\n this.loaderStatus = 'leaving';\n this.loaderTimer = this.config.setTimer(() => {\n this.loaderTimer = null;\n this.loaderStatus = null;\n this.emit();\n }, g9ToastTimings.loaderFadeOutMs);\n }\n\n private later(callback: () => void, ms: number): void {\n this.config.setTimer(() => {\n if (!this.disposed) callback();\n }, ms);\n }\n\n private build(): G9ToastSnapshot {\n return {\n toasts: this.records.map((r) => r.entry),\n loader: this.loaderStatus ? { text: this.loaderText, status: this.loaderStatus } : null,\n loadingToast: this.loadingToast,\n progress: this.progress,\n insetVersion: this.insetVersion,\n reanchorAnimated: this.reanchorAnimated,\n bottomOverlayHeight: [...this.overlays.values()].reduce((a, b) => a + b, 0),\n };\n }\n\n private emit(): void {\n this.snapshot = this.build();\n for (const l of this.listeners) l();\n }\n}\n\nfunction clamp01(v: number): number {\n return Number.isFinite(v) ? Math.min(1, Math.max(0, v)) : 0;\n}\n\n/** The culture default position: bottom right in LTR, bottom left in RTL. */\nexport function resolveToastPosition(position: G9ToastPosition | null | undefined, rtl: boolean): G9ToastPosition {\n return position ?? (rtl ? 'bottomLeft' : 'bottomRight');\n}\n"],"names":["G9ToastType","G9ToastPosition","g9DefaultToastOptions","Object","g9ToastTimings","g9MaxToastsPerStack","isPlain","r","G9ToastStore","listener","message","type","options","_options_position","_options_durationMs","position","hasAction","duration","stack","newest","closed","done","Promise","record","extra","Math","g9Ms","id","undefined","x","text","hold","released","anonymous","h","title","detail","progress","clamp01","animate","key","heightPx","token","top","callback","ms","a","b","l","config","Map","Set","v","Number","resolveToastPosition","rtl"],"mappings":"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"}
@@ -29,8 +29,16 @@ export interface G9ChipGroupProps extends G9ControlBaseProps {
29
29
  readonly selectedBackground?: string | null;
30
30
  /** Group-wide selected text colour. Default on-primary. */
31
31
  readonly selectedTextColor?: string | null;
32
- /** `'wrap'` (default) or one horizontally scrolling line. */
32
+ /**
33
+ * `'wrap'` (default), one horizontally scrolling line, or (MAUI 1.4.9) `'segmented'`: equal flat cells that share each
34
+ * row — AgriPad's design for short exclusive choices.
35
+ */
33
36
  readonly layoutMode?: G9ChipGroupLayoutMode;
37
+ /**
38
+ * `'segmented'` only: how many equal cells one row holds; more items wrap onto the next row in the same columns (the
39
+ * design's «مرتب‌سازی بر اساس», three a row). `0` (default) = every item on one row.
40
+ */
41
+ readonly segmentColumns?: number;
34
42
  /** Default 9 (`G9LayoutMetrics.ControlCornerRadius`). */
35
43
  readonly chipCornerRadius?: number;
36
44
  /** Check mark at the trailing edge of selected chips. Default true. */
@@ -1 +1 @@
1
- {"version":3,"file":"chip-group.d.ts","sourceRoot":"","sources":["../../src/toggle/chip-group.tsx"],"names":[],"mappings":"AAAA,OAAO,cAAc,CAAC;AACtB,OAAO,EAIL,KAAK,qBAAqB,EAC1B,KAAK,wBAAwB,EAI9B,MAAM,+BAA+B,CAAC;AACvC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,KAAK,kBAAkB,EAAkD,MAAM,iBAAiB,CAAC;AAE1G,OAAO,EAAE,KAAK,eAAe,EAAgB,MAAM,wBAAwB,CAAC;AAK5E,yDAAyD;AACzD,MAAM,WAAW,gBAAiB,SAAQ,kBAAkB;IAC1D,iHAAiH;IACjH,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC;IAC/C,kCAAkC;IAClC,QAAQ,CAAC,aAAa,CAAC,EAAE,wBAAwB,CAAC;IAClD,mEAAmE;IACnE,QAAQ,CAAC,YAAY,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAC9C,QAAQ,CAAC,mBAAmB,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACrD,QAAQ,CAAC,oBAAoB,CAAC,EAAE,CAAC,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC;IACtE,iFAAiF;IACjF,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5C,QAAQ,CAAC,mBAAmB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,EAAE,eAAe,GAAG,IAAI,KAAK,IAAI,CAAC;IAC1F,kFAAkF;IAClF,QAAQ,CAAC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IACtC,oCAAoC;IACpC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,kBAAkB;IAClB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,qCAAqC;IACrC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,kFAAkF;IAClF,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5C,2DAA2D;IAC3D,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3C,6DAA6D;IAC7D,QAAQ,CAAC,UAAU,CAAC,EAAE,qBAAqB,CAAC;IAC5C,yDAAyD;IACzD,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,uEAAuE;IACvE,QAAQ,CAAC,sBAAsB,CAAC,EAAE,OAAO,CAAC;IAC1C;;;OAGG;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,CAAC,eAAe,CAAC,KAAK,IAAI,CAAC;CAC9E;AAID;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,SAAS,CAyF9D"}
1
+ {"version":3,"file":"chip-group.d.ts","sourceRoot":"","sources":["../../src/toggle/chip-group.tsx"],"names":[],"mappings":"AAAA,OAAO,cAAc,CAAC;AACtB,OAAO,EAIL,KAAK,qBAAqB,EAC1B,KAAK,wBAAwB,EAK9B,MAAM,+BAA+B,CAAC;AACvC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,KAAK,kBAAkB,EAAkD,MAAM,iBAAiB,CAAC;AAE1G,OAAO,EAAE,KAAK,eAAe,EAAgB,MAAM,wBAAwB,CAAC;AAK5E,yDAAyD;AACzD,MAAM,WAAW,gBAAiB,SAAQ,kBAAkB;IAC1D,iHAAiH;IACjH,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC;IAC/C,kCAAkC;IAClC,QAAQ,CAAC,aAAa,CAAC,EAAE,wBAAwB,CAAC;IAClD,mEAAmE;IACnE,QAAQ,CAAC,YAAY,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAC9C,QAAQ,CAAC,mBAAmB,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACrD,QAAQ,CAAC,oBAAoB,CAAC,EAAE,CAAC,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC;IACtE,iFAAiF;IACjF,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5C,QAAQ,CAAC,mBAAmB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,EAAE,eAAe,GAAG,IAAI,KAAK,IAAI,CAAC;IAC1F,kFAAkF;IAClF,QAAQ,CAAC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IACtC,oCAAoC;IACpC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,kBAAkB;IAClB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,qCAAqC;IACrC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,kFAAkF;IAClF,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5C,2DAA2D;IAC3D,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3C;;;OAGG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,qBAAqB,CAAC;IAC5C;;;OAGG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,yDAAyD;IACzD,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,uEAAuE;IACvE,QAAQ,CAAC,sBAAsB,CAAC,EAAE,OAAO,CAAC;IAC1C;;;OAGG;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,CAAC,eAAe,CAAC,KAAK,IAAI,CAAC;CAC9E;AAID;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,SAAS,CA+I9D"}
@@ -1,5 +1,5 @@
1
1
  import "./toggle.css";
2
- import { G9Metrics, G9StringKey, buildSolidOrGradient, fillToCss, formatColor, tryParseColor } from "@g9tm/lynxcontrols-foundation";
2
+ import { G9Metrics, G9StringKey, buildSolidOrGradient, fillToCss, formatColor, mix, tryParseColor } from "@g9tm/lynxcontrols-foundation";
3
3
  import { g9ChildId, g9IdProps, g9RowStyle, useG9Control } from "../base/control.jsx";
4
4
  import { useG9Press } from "../base/press.jsx";
5
5
  import { selectionKey } from "../base/selection-item.jsx";
@@ -52,16 +52,49 @@ function G9ChipGroup(props) {
52
52
  const iconSize = null != (_props_iconSize = props.iconSize) ? _props_iconSize : G9Metrics.ChipIconSize;
53
53
  const radius = null != (_props_chipCornerRadius = props.chipCornerRadius) ? _props_chipCornerRadius : 9;
54
54
  const checkmark = false !== props.showSelectionCheckmark;
55
+ const segmented = 'segmented' === props.layoutMode;
55
56
  const chips = props.items.map((item)=>{
56
- var _ref, _item_selectedColor, _ref1, _item_selectedTextColor;
57
57
  const selected = isSelected(item);
58
- const bg = null != (_ref = null != (_item_selectedColor = item.selectedColor) ? _item_selectedColor : props.selectedBackground) ? _ref : palette.Primary;
59
- const fg = null != (_ref1 = null != (_item_selectedTextColor = item.selectedTextColor) ? _item_selectedTextColor : props.selectedTextColor) ? _ref1 : palette.OnPrimary;
60
- const parsed = tryParseColor(bg);
61
- const background = selected ? parsed ? fillToCss(buildSolidOrGradient(parsed, true)) : bg : palette.Surface;
62
- const color = selected ? fg : palette.TextSecondary;
63
- return <Chip key={selectionKey(item)} direction={control.direction} item={item} selected={selected} background={background} stroke={selected ? parsed ? formatColor(parsed) : bg : palette.OutlineVariant} color={color} height={height} spacing={spacing} iconSize={iconSize} radius={radius} checkmark={checkmark} checkIcon={glyphs.check} groupDisabled={control.disabled} selectedLabel={strings.get(G9StringKey.Selected)} onTap={tap} id={g9ChildId(props.id, selectionKey(item))}/>;
58
+ let background;
59
+ let stroke;
60
+ let color;
61
+ if (segmented) {
62
+ var _ref, _item_selectedColor, _ref1, _item_selectedTextColor;
63
+ const accent = null != (_ref = null != (_item_selectedColor = item.selectedColor) ? _item_selectedColor : props.selectedBackground) ? _ref : palette.Primary;
64
+ const parsedAccent = tryParseColor(accent);
65
+ background = selected ? parsedAccent ? formatColor(mix(palette.Surface, parsedAccent, 0.08)) : accent : palette.SurfaceContainer;
66
+ stroke = selected ? parsedAccent ? formatColor(parsedAccent) : accent : palette.OutlineVariant;
67
+ color = selected ? null != (_ref1 = null != (_item_selectedTextColor = item.selectedTextColor) ? _item_selectedTextColor : props.selectedTextColor) ? _ref1 : palette.TextPrimary : palette.TextSecondary;
68
+ } else {
69
+ var _ref2, _item_selectedColor1, _ref3, _item_selectedTextColor1;
70
+ const bg = null != (_ref2 = null != (_item_selectedColor1 = item.selectedColor) ? _item_selectedColor1 : props.selectedBackground) ? _ref2 : palette.Primary;
71
+ const fg = null != (_ref3 = null != (_item_selectedTextColor1 = item.selectedTextColor) ? _item_selectedTextColor1 : props.selectedTextColor) ? _ref3 : palette.OnPrimary;
72
+ const parsed = tryParseColor(bg);
73
+ background = selected ? parsed ? fillToCss(buildSolidOrGradient(parsed, true)) : bg : palette.Surface;
74
+ stroke = selected ? parsed ? formatColor(parsed) : bg : palette.OutlineVariant;
75
+ color = selected ? fg : palette.TextSecondary;
76
+ }
77
+ return <Chip key={selectionKey(item)} direction={control.direction} item={item} selected={selected} background={background} stroke={stroke} color={color} height={segmented ? Math.max(height, G9Metrics.SegmentHeight) : height} spacing={spacing} iconSize={iconSize} radius={segmented ? G9Metrics.SegmentCornerRadius : radius} checkmark={checkmark && !segmented} segment={segmented} checkIcon={glyphs.check} groupDisabled={control.disabled} selectedLabel={strings.get(G9StringKey.Selected)} onTap={tap} id={g9ChildId(props.id, selectionKey(item))}/>;
64
78
  });
79
+ if (segmented) {
80
+ const columns = props.segmentColumns && props.segmentColumns > 0 ? Math.min(props.segmentColumns, Math.max(1, chips.length)) : Math.max(1, chips.length);
81
+ const rows = [];
82
+ for(let start = 0; start < chips.length; start += columns){
83
+ const cells = chips.slice(start, start + columns);
84
+ while(cells.length < columns)cells.push(<view key={`fill-${cells.length}`} className="g9-chip-group__segment-fill"/>);
85
+ rows.push(<view key={`row-${start}`} className="g9-chip-group__segment-row" style={{
86
+ ...g9RowStyle(control.direction),
87
+ columnGap: `${spacing}px`
88
+ }}>
89
+ {cells}
90
+ </view>);
91
+ }
92
+ return <view className={`${control.className} g9-chip-group--segmented`} {...control.idProps} style={{
93
+ rowGap: `${spacing}px`
94
+ }}>
95
+ {rows}
96
+ </view>;
97
+ }
65
98
  const scroll = 'singleLineScroll' === props.layoutMode;
66
99
  return scroll ? <scroll-view className={`${control.className} g9-chip-group--scroll`} {...control.idProps} scroll-orientation="horizontal">
67
100
  <view className="g9-chip-group__line" style={g9RowStyle(control.direction)}>
@@ -79,12 +112,14 @@ function Chip(props) {
79
112
  source: 'G9ChipGroup',
80
113
  guardMs: 0
81
114
  });
82
- return <view className={`g9-chip${props.selected ? ' g9-chip--selected' : ''}${false === item.isEnabled ? ' g9-chip--disabled' : ''}`} {...g9IdProps(props.id)} style={{
115
+ return <view className={`g9-chip${props.segment ? ' g9-chip--segment' : ''}${props.selected ? ' g9-chip--selected' : ''}${false === item.isEnabled ? ' g9-chip--disabled' : ''}`} {...g9IdProps(props.id)} style={{
83
116
  ...g9RowStyle(props.direction),
84
117
  height: `${props.height}px`,
85
118
  minHeight: `${props.height}px`,
86
- ['rtl' === props.direction ? 'marginLeft' : 'marginRight']: `${props.spacing}px`,
87
- marginBottom: `${props.spacing}px`,
119
+ ...props.segment ? {} : {
120
+ ['rtl' === props.direction ? 'marginLeft' : 'marginRight']: `${props.spacing}px`,
121
+ marginBottom: `${props.spacing}px`
122
+ },
88
123
  borderRadius: `${props.radius}px`,
89
124
  background: props.background,
90
125
  borderColor: props.stroke
@@ -99,7 +134,11 @@ function Chip(props) {
99
134
  image: item.iconImage
100
135
  }) ? <G9IconSlot emoji={item.emoji} icon={item.icon} imagePath={item.iconPath} image={item.iconImage} size={props.iconSize} color={props.color}/> : null}
101
136
  <text className="g9-chip__text" style={{
102
- color: props.color
137
+ color: props.color,
138
+ ...props.segment ? {
139
+ fontSize: `${G9Metrics.SegmentFontSize}px`,
140
+ fontWeight: props.selected ? 'bold' : 'normal'
141
+ } : {}
103
142
  }}>
104
143
  {item.text}
105
144
  </text>
@@ -1 +1 @@
1
- {"version":3,"file":"toggle/chip-group.jsx","sources":["../../src/toggle/chip-group.tsx"],"sourcesContent":["import './toggle.css';\nimport {\n buildSolidOrGradient,\n fillToCss,\n formatColor,\n type G9ChipGroupLayoutMode,\n type G9ChipGroupSelectionMode,\n G9Metrics,\n G9StringKey,\n tryParseColor,\n} from '@g9tm/lynxcontrols-foundation';\nimport type { ReactNode } from '@lynx-js/react';\nimport { type G9ControlBaseProps, g9ChildId, g9IdProps, g9RowStyle, useG9Control } from '../base/control';\nimport { useG9Press } from '../base/press';\nimport { type G9SelectionItem, selectionKey } from '../base/selection-item';\nimport { useControllableState } from '../base/use-controllable-state';\nimport { G9IconSlot, hasIconSlot } from '../icon/slot';\nimport { useG9Settings, useG9Strings, useG9Theme } from '../provider/hooks';\n\n/** Props of {@link G9ChipGroup} (MAUI `G9ChipGroup`). */\nexport interface G9ChipGroupProps extends G9ControlBaseProps {\n /** One chip per item (MAUI `ItemsSource`). Selection is by `selectionKey(item)`, so replaced objects keep it. */\n readonly items: ReadonlyArray<G9SelectionItem>;\n /** Default `'multiSelection'`. */\n readonly selectionMode?: G9ChipGroupSelectionMode;\n /** Multi mode: controlled selected keys (MAUI `SelectedItems`). */\n readonly selectedKeys?: ReadonlyArray<string>;\n readonly defaultSelectedKeys?: ReadonlyArray<string>;\n readonly onSelectedKeysChange?: (keys: ReadonlyArray<string>) => void;\n /** Single mode: controlled selected key (MAUI `SelectedItem`); `null` = none. */\n readonly selectedKey?: string | null;\n readonly defaultSelectedKey?: string | null;\n readonly onSelectedKeyChange?: (key: string | null, item: G9SelectionItem | null) => void;\n /** Single mode: tapping the selected chip clears the selection. Default false. */\n readonly allowNullSelection?: boolean;\n /** Gap between chips. Default 6. */\n readonly itemSpacing?: number;\n /** Default 36. */\n readonly chipHeight?: number;\n /** Leading icon size. Default 16. */\n readonly iconSize?: number;\n /** Group-wide selected fill (an item's `selectedColor` wins). Default primary. */\n readonly selectedBackground?: string | null;\n /** Group-wide selected text colour. Default on-primary. */\n readonly selectedTextColor?: string | null;\n /** `'wrap'` (default) or one horizontally scrolling line. */\n readonly layoutMode?: G9ChipGroupLayoutMode;\n /** Default 9 (`G9LayoutMetrics.ControlCornerRadius`). */\n readonly chipCornerRadius?: number;\n /** Check mark at the trailing edge of selected chips. Default true. */\n readonly showSelectionCheckmark?: boolean;\n /**\n * After every user tap (MAUI `SelectionChanged`): single mode `[item]` or `[]` (also when the tap changed nothing),\n * multi mode the selected items.\n */\n readonly onSelectionChange?: (items: ReadonlyArray<G9SelectionItem>) => void;\n}\n\nconst EMPTY: ReadonlyArray<string> = [];\n\n/**\n * Chip group (MAUI `G9ChipGroup`): single or multi selection by item identity, wrap or single-line scroll, colour\n * transition (140 ms) and check mark (120 ms) in CSS, press pulse 0.94 on the main thread. Disabled items are dimmed\n * and ignore taps.\n */\nexport function G9ChipGroup(props: G9ChipGroupProps): ReactNode {\n const control = useG9Control(props, 'g9-chip-group');\n const palette = useG9Theme().palette;\n const glyphs = useG9Settings().glyphs;\n const strings = useG9Strings();\n const single = props.selectionMode === 'singleSelection';\n const [keys, setKeys] = useControllableState<ReadonlyArray<string>>({\n value: props.selectedKeys,\n defaultValue: props.defaultSelectedKeys ?? EMPTY,\n onChange: props.onSelectedKeysChange,\n name: 'G9ChipGroup.selectedKeys',\n });\n const [key, setKey] = useControllableState<string | null, [G9SelectionItem | null]>({\n value: props.selectedKey,\n defaultValue: props.defaultSelectedKey ?? null,\n onChange: props.onSelectedKeyChange,\n name: 'G9ChipGroup.selectedKey',\n });\n const isSelected = (item: G9SelectionItem) =>\n single ? key === selectionKey(item) : keys.includes(selectionKey(item));\n\n const tap = (item: G9SelectionItem) => {\n if (control.disabled || item.isEnabled === false) return;\n const k = selectionKey(item);\n if (single) {\n const next = key === k ? (props.allowNullSelection ? null : k) : k;\n setKey(next, next === null ? null : item);\n props.onSelectionChange?.(next === null ? [] : [item]);\n return;\n }\n const next = keys.includes(k) ? keys.filter((x) => x !== k) : [...keys, k];\n setKeys(next);\n props.onSelectionChange?.(props.items.filter((i) => next.includes(selectionKey(i))));\n };\n\n const height = props.chipHeight ?? G9Metrics.ChipHeight;\n const spacing = props.itemSpacing ?? G9Metrics.ChipSpacing;\n const iconSize = props.iconSize ?? G9Metrics.ChipIconSize;\n const radius = props.chipCornerRadius ?? 9;\n const checkmark = props.showSelectionCheckmark !== false;\n const chips = props.items.map((item) => {\n const selected = isSelected(item);\n const bg = item.selectedColor ?? props.selectedBackground ?? palette.Primary;\n const fg = item.selectedTextColor ?? props.selectedTextColor ?? palette.OnPrimary;\n const parsed = tryParseColor(bg);\n const background = selected ? (parsed ? fillToCss(buildSolidOrGradient(parsed, true)) : bg) : palette.Surface;\n const color = selected ? fg : palette.TextSecondary;\n return (\n <Chip\n key={selectionKey(item)}\n direction={control.direction}\n item={item}\n selected={selected}\n background={background}\n stroke={selected ? (parsed ? formatColor(parsed) : bg) : palette.OutlineVariant}\n color={color}\n height={height}\n spacing={spacing}\n iconSize={iconSize}\n radius={radius}\n checkmark={checkmark}\n checkIcon={glyphs.check}\n groupDisabled={control.disabled}\n selectedLabel={strings.get(G9StringKey.Selected)}\n onTap={tap}\n id={g9ChildId(props.id, selectionKey(item))}\n />\n );\n });\n const scroll = props.layoutMode === 'singleLineScroll';\n return scroll ? (\n <scroll-view\n className={`${control.className} g9-chip-group--scroll`}\n {...control.idProps}\n scroll-orientation=\"horizontal\"\n >\n <view className=\"g9-chip-group__line\" style={g9RowStyle(control.direction)}>\n {chips}\n </view>\n </scroll-view>\n ) : (\n <view\n className={`${control.className} g9-chip-group--wrap`}\n {...control.idProps}\n style={g9RowStyle(control.direction)}\n >\n {chips}\n </view>\n );\n}\n\ninterface ChipProps {\n readonly item: G9SelectionItem;\n readonly selected: boolean;\n readonly background: string;\n readonly stroke: string;\n readonly color: string;\n readonly height: number;\n readonly spacing: number;\n readonly iconSize: number;\n readonly radius: number;\n readonly checkmark: boolean;\n readonly checkIcon: Parameters<typeof G9IconSlot>[0]['icon'];\n readonly groupDisabled: boolean;\n readonly selectedLabel: string;\n readonly onTap: (item: G9SelectionItem) => void;\n readonly direction: 'ltr' | 'rtl';\n /** The chip's automation id (`${groupId}_${key}`). */\n readonly id: string | undefined;\n}\n\nfunction Chip(props: ChipProps): ReactNode {\n const { item } = props;\n const disabled = props.groupDisabled || item.isEnabled === false;\n const press = useG9Press(() => props.onTap(item), { blocked: disabled, source: 'G9ChipGroup', guardMs: 0 });\n return (\n <view\n className={`g9-chip${props.selected ? ' g9-chip--selected' : ''}${item.isEnabled === false ? ' g9-chip--disabled' : ''}`}\n {...g9IdProps(props.id)}\n style={{\n ...g9RowStyle(props.direction),\n height: `${props.height}px`,\n minHeight: `${props.height}px`,\n [props.direction === 'rtl' ? 'marginLeft' : 'marginRight']: `${props.spacing}px`,\n marginBottom: `${props.spacing}px`,\n borderRadius: `${props.radius}px`,\n background: props.background,\n borderColor: props.stroke,\n }}\n accessibility-element={true}\n accessibility-traits=\"button\"\n accessibility-label={item.text}\n {...(props.selected ? { 'accessibility-value': props.selectedLabel } : {})}\n bindtap={press}\n >\n {/* Only when the item has one (MAUI adds the icon view only then): an empty slot still took the row's 6 dp gap,\n and every icon-less chip came out 6 dp wider than MAUI's. */}\n {hasIconSlot({ emoji: item.emoji, icon: item.icon, imagePath: item.iconPath, image: item.iconImage }) ? (\n <G9IconSlot\n emoji={item.emoji}\n icon={item.icon}\n imagePath={item.iconPath}\n image={item.iconImage}\n size={props.iconSize}\n color={props.color}\n />\n ) : null}\n <text className=\"g9-chip__text\" style={{ color: props.color }}>\n {item.text}\n </text>\n {props.checkmark ? (\n <view className={`g9-chip__check${props.selected ? ' g9-chip__check--on' : ''}`}>\n <G9IconSlot icon={props.checkIcon} size={G9Metrics.ChipIconSize} color={props.color} />\n </view>\n ) : null}\n </view>\n );\n}\n"],"names":["EMPTY","G9ChipGroup","props","_props_defaultSelectedKeys","_props_defaultSelectedKey","_props_chipHeight","_props_itemSpacing","_props_iconSize","_props_chipCornerRadius","control","useG9Control","palette","useG9Theme","glyphs","useG9Settings","strings","useG9Strings","single","keys","setKeys","useControllableState","key","setKey","isSelected","item","selectionKey","tap","k","next","x","i","height","G9Metrics","spacing","iconSize","radius","checkmark","chips","_ref","_ref1","selected","bg","fg","parsed","tryParseColor","background","fillToCss","buildSolidOrGradient","color","Chip","formatColor","G9StringKey","g9ChildId","scroll","scroll-view","view","g9RowStyle","disabled","press","useG9Press","g9IdProps","hasIconSlot","G9IconSlot","text"],"mappings":"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"}
1
+ {"version":3,"file":"toggle/chip-group.jsx","sources":["../../src/toggle/chip-group.tsx"],"sourcesContent":["import './toggle.css';\nimport {\n buildSolidOrGradient,\n fillToCss,\n formatColor,\n type G9ChipGroupLayoutMode,\n type G9ChipGroupSelectionMode,\n G9Metrics,\n G9StringKey,\n mix,\n tryParseColor,\n} from '@g9tm/lynxcontrols-foundation';\nimport type { ReactNode } from '@lynx-js/react';\nimport { type G9ControlBaseProps, g9ChildId, g9IdProps, g9RowStyle, useG9Control } from '../base/control';\nimport { useG9Press } from '../base/press';\nimport { type G9SelectionItem, selectionKey } from '../base/selection-item';\nimport { useControllableState } from '../base/use-controllable-state';\nimport { G9IconSlot, hasIconSlot } from '../icon/slot';\nimport { useG9Settings, useG9Strings, useG9Theme } from '../provider/hooks';\n\n/** Props of {@link G9ChipGroup} (MAUI `G9ChipGroup`). */\nexport interface G9ChipGroupProps extends G9ControlBaseProps {\n /** One chip per item (MAUI `ItemsSource`). Selection is by `selectionKey(item)`, so replaced objects keep it. */\n readonly items: ReadonlyArray<G9SelectionItem>;\n /** Default `'multiSelection'`. */\n readonly selectionMode?: G9ChipGroupSelectionMode;\n /** Multi mode: controlled selected keys (MAUI `SelectedItems`). */\n readonly selectedKeys?: ReadonlyArray<string>;\n readonly defaultSelectedKeys?: ReadonlyArray<string>;\n readonly onSelectedKeysChange?: (keys: ReadonlyArray<string>) => void;\n /** Single mode: controlled selected key (MAUI `SelectedItem`); `null` = none. */\n readonly selectedKey?: string | null;\n readonly defaultSelectedKey?: string | null;\n readonly onSelectedKeyChange?: (key: string | null, item: G9SelectionItem | null) => void;\n /** Single mode: tapping the selected chip clears the selection. Default false. */\n readonly allowNullSelection?: boolean;\n /** Gap between chips. Default 6. */\n readonly itemSpacing?: number;\n /** Default 36. */\n readonly chipHeight?: number;\n /** Leading icon size. Default 16. */\n readonly iconSize?: number;\n /** Group-wide selected fill (an item's `selectedColor` wins). Default primary. */\n readonly selectedBackground?: string | null;\n /** Group-wide selected text colour. Default on-primary. */\n readonly selectedTextColor?: string | null;\n /**\n * `'wrap'` (default), one horizontally scrolling line, or (MAUI 1.4.9) `'segmented'`: equal flat cells that share each\n * row — AgriPad's design for short exclusive choices.\n */\n readonly layoutMode?: G9ChipGroupLayoutMode;\n /**\n * `'segmented'` only: how many equal cells one row holds; more items wrap onto the next row in the same columns (the\n * design's «مرتب‌سازی بر اساس», three a row). `0` (default) = every item on one row.\n */\n readonly segmentColumns?: number;\n /** Default 9 (`G9LayoutMetrics.ControlCornerRadius`). */\n readonly chipCornerRadius?: number;\n /** Check mark at the trailing edge of selected chips. Default true. */\n readonly showSelectionCheckmark?: boolean;\n /**\n * After every user tap (MAUI `SelectionChanged`): single mode `[item]` or `[]` (also when the tap changed nothing),\n * multi mode the selected items.\n */\n readonly onSelectionChange?: (items: ReadonlyArray<G9SelectionItem>) => void;\n}\n\nconst EMPTY: ReadonlyArray<string> = [];\n\n/**\n * Chip group (MAUI `G9ChipGroup`): single or multi selection by item identity, wrap or single-line scroll, colour\n * transition (140 ms) and check mark (120 ms) in CSS, press pulse 0.94 on the main thread. Disabled items are dimmed\n * and ignore taps.\n */\nexport function G9ChipGroup(props: G9ChipGroupProps): ReactNode {\n const control = useG9Control(props, 'g9-chip-group');\n const palette = useG9Theme().palette;\n const glyphs = useG9Settings().glyphs;\n const strings = useG9Strings();\n const single = props.selectionMode === 'singleSelection';\n const [keys, setKeys] = useControllableState<ReadonlyArray<string>>({\n value: props.selectedKeys,\n defaultValue: props.defaultSelectedKeys ?? EMPTY,\n onChange: props.onSelectedKeysChange,\n name: 'G9ChipGroup.selectedKeys',\n });\n const [key, setKey] = useControllableState<string | null, [G9SelectionItem | null]>({\n value: props.selectedKey,\n defaultValue: props.defaultSelectedKey ?? null,\n onChange: props.onSelectedKeyChange,\n name: 'G9ChipGroup.selectedKey',\n });\n const isSelected = (item: G9SelectionItem) =>\n single ? key === selectionKey(item) : keys.includes(selectionKey(item));\n\n const tap = (item: G9SelectionItem) => {\n if (control.disabled || item.isEnabled === false) return;\n const k = selectionKey(item);\n if (single) {\n const next = key === k ? (props.allowNullSelection ? null : k) : k;\n setKey(next, next === null ? null : item);\n props.onSelectionChange?.(next === null ? [] : [item]);\n return;\n }\n const next = keys.includes(k) ? keys.filter((x) => x !== k) : [...keys, k];\n setKeys(next);\n props.onSelectionChange?.(props.items.filter((i) => next.includes(selectionKey(i))));\n };\n\n const height = props.chipHeight ?? G9Metrics.ChipHeight;\n const spacing = props.itemSpacing ?? G9Metrics.ChipSpacing;\n const iconSize = props.iconSize ?? G9Metrics.ChipIconSize;\n const radius = props.chipCornerRadius ?? 9;\n const checkmark = props.showSelectionCheckmark !== false;\n const segmented = props.layoutMode === 'segmented';\n const chips = props.items.map((item) => {\n const selected = isSelected(item);\n let background: string;\n let stroke: string;\n let color: string;\n if (segmented) {\n // MAUI 1.4.9 segment: resting = a grey cell on a hairline; chosen = a faint accent tint (8 % over Surface), the\n // accent as the outline, the text in the strong text colour and bold. Flat — no gradient.\n const accent = item.selectedColor ?? props.selectedBackground ?? palette.Primary;\n const parsedAccent = tryParseColor(accent);\n background = selected\n ? parsedAccent\n ? formatColor(mix(palette.Surface, parsedAccent, 0.08))\n : accent\n : palette.SurfaceContainer;\n stroke = selected ? (parsedAccent ? formatColor(parsedAccent) : accent) : palette.OutlineVariant;\n color = selected\n ? (item.selectedTextColor ?? props.selectedTextColor ?? palette.TextPrimary)\n : palette.TextSecondary;\n } else {\n const bg = item.selectedColor ?? props.selectedBackground ?? palette.Primary;\n const fg = item.selectedTextColor ?? props.selectedTextColor ?? palette.OnPrimary;\n const parsed = tryParseColor(bg);\n background = selected ? (parsed ? fillToCss(buildSolidOrGradient(parsed, true)) : bg) : palette.Surface;\n stroke = selected ? (parsed ? formatColor(parsed) : bg) : palette.OutlineVariant;\n color = selected ? fg : palette.TextSecondary;\n }\n return (\n <Chip\n key={selectionKey(item)}\n direction={control.direction}\n item={item}\n selected={selected}\n background={background}\n stroke={stroke}\n color={color}\n height={segmented ? Math.max(height, G9Metrics.SegmentHeight) : height}\n spacing={spacing}\n iconSize={iconSize}\n radius={segmented ? G9Metrics.SegmentCornerRadius : radius}\n checkmark={checkmark && !segmented}\n segment={segmented}\n checkIcon={glyphs.check}\n groupDisabled={control.disabled}\n selectedLabel={strings.get(G9StringKey.Selected)}\n onTap={tap}\n id={g9ChildId(props.id, selectionKey(item))}\n />\n );\n });\n if (segmented) {\n // One row per `columns` items, every cell the same width (MAUI's star columns): a short last row keeps the column\n // width with empty fillers instead of stretching its cells.\n const columns =\n props.segmentColumns && props.segmentColumns > 0\n ? Math.min(props.segmentColumns, Math.max(1, chips.length))\n : Math.max(1, chips.length);\n const rows: ReactNode[] = [];\n for (let start = 0; start < chips.length; start += columns) {\n const cells: ReactNode[] = chips.slice(start, start + columns);\n while (cells.length < columns)\n cells.push(<view key={`fill-${cells.length}`} className=\"g9-chip-group__segment-fill\" />);\n rows.push(\n <view\n key={`row-${start}`}\n className=\"g9-chip-group__segment-row\"\n style={{ ...g9RowStyle(control.direction), columnGap: `${spacing}px` }}\n >\n {cells}\n </view>,\n );\n }\n return (\n <view\n className={`${control.className} g9-chip-group--segmented`}\n {...control.idProps}\n style={{ rowGap: `${spacing}px` }}\n >\n {rows}\n </view>\n );\n }\n const scroll = props.layoutMode === 'singleLineScroll';\n return scroll ? (\n <scroll-view\n className={`${control.className} g9-chip-group--scroll`}\n {...control.idProps}\n scroll-orientation=\"horizontal\"\n >\n <view className=\"g9-chip-group__line\" style={g9RowStyle(control.direction)}>\n {chips}\n </view>\n </scroll-view>\n ) : (\n <view\n className={`${control.className} g9-chip-group--wrap`}\n {...control.idProps}\n style={g9RowStyle(control.direction)}\n >\n {chips}\n </view>\n );\n}\n\ninterface ChipProps {\n readonly item: G9SelectionItem;\n readonly selected: boolean;\n readonly background: string;\n readonly stroke: string;\n readonly color: string;\n readonly height: number;\n readonly spacing: number;\n readonly iconSize: number;\n readonly radius: number;\n readonly checkmark: boolean;\n readonly checkIcon: Parameters<typeof G9IconSlot>[0]['icon'];\n readonly groupDisabled: boolean;\n readonly selectedLabel: string;\n readonly onTap: (item: G9SelectionItem) => void;\n readonly direction: 'ltr' | 'rtl';\n /** A segmented cell: fills its column, no margin (the row's gap is the spacing), 14 px text bold only when chosen. */\n readonly segment?: boolean;\n /** The chip's automation id (`${groupId}_${key}`). */\n readonly id: string | undefined;\n}\n\nfunction Chip(props: ChipProps): ReactNode {\n const { item } = props;\n const disabled = props.groupDisabled || item.isEnabled === false;\n const press = useG9Press(() => props.onTap(item), { blocked: disabled, source: 'G9ChipGroup', guardMs: 0 });\n return (\n <view\n className={`g9-chip${props.segment ? ' g9-chip--segment' : ''}${props.selected ? ' g9-chip--selected' : ''}${item.isEnabled === false ? ' g9-chip--disabled' : ''}`}\n {...g9IdProps(props.id)}\n style={{\n ...g9RowStyle(props.direction),\n height: `${props.height}px`,\n minHeight: `${props.height}px`,\n ...(props.segment\n ? {}\n : {\n [props.direction === 'rtl' ? 'marginLeft' : 'marginRight']: `${props.spacing}px`,\n marginBottom: `${props.spacing}px`,\n }),\n borderRadius: `${props.radius}px`,\n background: props.background,\n borderColor: props.stroke,\n }}\n accessibility-element={true}\n accessibility-traits=\"button\"\n accessibility-label={item.text}\n {...(props.selected ? { 'accessibility-value': props.selectedLabel } : {})}\n bindtap={press}\n >\n {/* Only when the item has one (MAUI adds the icon view only then): an empty slot still took the row's 6 dp gap,\n and every icon-less chip came out 6 dp wider than MAUI's. */}\n {hasIconSlot({ emoji: item.emoji, icon: item.icon, imagePath: item.iconPath, image: item.iconImage }) ? (\n <G9IconSlot\n emoji={item.emoji}\n icon={item.icon}\n imagePath={item.iconPath}\n image={item.iconImage}\n size={props.iconSize}\n color={props.color}\n />\n ) : null}\n <text\n className=\"g9-chip__text\"\n style={{\n color: props.color,\n ...(props.segment\n ? { fontSize: `${G9Metrics.SegmentFontSize}px`, fontWeight: props.selected ? 'bold' : 'normal' }\n : {}),\n }}\n >\n {item.text}\n </text>\n {props.checkmark ? (\n <view className={`g9-chip__check${props.selected ? ' g9-chip__check--on' : ''}`}>\n <G9IconSlot icon={props.checkIcon} size={G9Metrics.ChipIconSize} color={props.color} />\n </view>\n ) : null}\n </view>\n );\n}\n"],"names":["EMPTY","G9ChipGroup","props","_props_defaultSelectedKeys","_props_defaultSelectedKey","_props_chipHeight","_props_itemSpacing","_props_iconSize","_props_chipCornerRadius","control","useG9Control","palette","useG9Theme","glyphs","useG9Settings","strings","useG9Strings","single","keys","setKeys","useControllableState","key","setKey","isSelected","item","selectionKey","tap","k","next","x","i","height","G9Metrics","spacing","iconSize","radius","checkmark","segmented","chips","selected","background","stroke","color","_ref","_ref1","accent","parsedAccent","tryParseColor","formatColor","mix","_ref2","_ref3","bg","fg","parsed","fillToCss","buildSolidOrGradient","Chip","Math","G9StringKey","g9ChildId","columns","rows","start","cells","view","g9RowStyle","scroll","scroll-view","disabled","press","useG9Press","g9IdProps","hasIconSlot","G9IconSlot","text"],"mappings":"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"}
@@ -45,7 +45,7 @@ export interface G9SwitchHandle {
45
45
  }
46
46
  /**
47
47
  * Switch (MAUI `G9Switch`): 56 × 32 track, 24 px thumb that stretches while travelling, 240 ms spring-like CSS
48
- * transition, tick/dot track mark; RTL moves the "on" side to the left. A blocked tap (required, or the last active
48
+ * transition, tick/dot track mark; RTL moves the "on" side to the left unless `toggles.switchMirrorInRtl` is false. A blocked tap (required, or the last active
49
49
  * switch of a `minOneActive` group) shakes instead of toggling. Disabled: opacity 0.45.
50
50
  */
51
51
  export declare const G9Switch: import("react").ForwardRefExoticComponent<G9SwitchProps & import("react").RefAttributes<G9SwitchHandle>>;
@@ -1 +1 @@
1
- {"version":3,"file":"switch.d.ts","sourceRoot":"","sources":["../../src/toggle/switch.tsx"],"names":[],"mappings":"AAAA,OAAO,cAAc,CAAC;AAUtB,OAAO,EAGL,KAAK,SAAS,EAMf,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,KAAK,kBAAkB,EAAyC,MAAM,iBAAiB,CAAC;AAuCjG,6DAA6D;AAC7D,MAAM,WAAW,kBAAmB,SAAQ,kBAAkB;IAC5D,4FAA4F;IAC5F,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC;IAChC,4GAA4G;IAC5G,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;IAClC,kFAAkF;IAClF,QAAQ,CAAC,mBAAmB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACvE,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,CAAC;CAC/B;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,SAAS,CAuDlE;AAID,mDAAmD;AACnD,MAAM,WAAW,aAAc,SAAQ,kBAAkB;IACvD,sCAAsC;IACtC,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;IAClC;;;OAGG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACtD,2EAA2E;IAC3E,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAC9B,yGAAyG;IACzG,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,4FAA4F;IAC5F,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B,6DAA6D;IAC7D,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,yDAAyD;IACzD,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACtC;AAED,6CAA6C;AAC7C,MAAM,WAAW,cAAc;IAC7B,qBAAqB;IACrB,MAAM,IAAI,IAAI,CAAC;CAChB;AAID;;;;GAIG;AACH,eAAO,MAAM,QAAQ,0GAuHnB,CAAC"}
1
+ {"version":3,"file":"switch.d.ts","sourceRoot":"","sources":["../../src/toggle/switch.tsx"],"names":[],"mappings":"AAAA,OAAO,cAAc,CAAC;AAUtB,OAAO,EAGL,KAAK,SAAS,EAMf,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,KAAK,kBAAkB,EAAyC,MAAM,iBAAiB,CAAC;AAuCjG,6DAA6D;AAC7D,MAAM,WAAW,kBAAmB,SAAQ,kBAAkB;IAC5D,4FAA4F;IAC5F,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC;IAChC,4GAA4G;IAC5G,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;IAClC,kFAAkF;IAClF,QAAQ,CAAC,mBAAmB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACvE,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,CAAC;CAC/B;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,SAAS,CAuDlE;AAID,mDAAmD;AACnD,MAAM,WAAW,aAAc,SAAQ,kBAAkB;IACvD,sCAAsC;IACtC,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;IAClC;;;OAGG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACtD,2EAA2E;IAC3E,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAC9B,yGAAyG;IACzG,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,4FAA4F;IAC5F,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B,6DAA6D;IAC7D,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,yDAAyD;IACzD,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACtC;AAED,6CAA6C;AAC7C,MAAM,WAAW,cAAc;IAC7B,qBAAqB;IACrB,MAAM,IAAI,IAAI,CAAC;CAChB;AAID;;;;GAIG;AACH,eAAO,MAAM,QAAQ,0GAyHnB,CAAC"}
@@ -5,7 +5,7 @@ import { g9RowStyle, g9TextStart, useG9Control } from "../base/control.jsx";
5
5
  import { useG9Press } from "../base/press.jsx";
6
6
  import { useControllableState } from "../base/use-controllable-state.jsx";
7
7
  import { G9CoreContext } from "../provider/contexts.jsx";
8
- import { useG9Strings, useG9Theme } from "../provider/hooks.jsx";
8
+ import { useG9Settings, useG9Strings, useG9Theme } from "../provider/hooks.jsx";
9
9
  const registries = new WeakMap();
10
10
  const globalScope = {};
11
11
  function groupSet(scope, group) {
@@ -79,6 +79,7 @@ const switch_G9Switch = forwardRef(function(props, ref) {
79
79
  const control = useG9Control(props, 'g9-switch');
80
80
  const theme = useG9Theme();
81
81
  const strings = useG9Strings();
82
+ const settings = useG9Settings();
82
83
  const core = useContext(G9CoreContext);
83
84
  const group = useContext(SwitchGroupContext);
84
85
  const [checked, setChecked] = useControllableState({
@@ -144,7 +145,7 @@ const switch_G9Switch = forwardRef(function(props, ref) {
144
145
  source: 'G9Switch',
145
146
  guardMs: 0
146
147
  });
147
- const rtl = 'rtl' === control.direction;
148
+ const rtl = 'rtl' === control.direction && settings.toggles.switchMirrorInRtl;
148
149
  const width = G9Metrics.SwitchWidth;
149
150
  const thumb = G9Metrics.SwitchThumb;
150
151
  const travel = width - 4 - thumb - 4;
@@ -1 +1 @@
1
- {"version":3,"file":"toggle/switch.jsx","sources":["../../src/toggle/switch.tsx"],"sourcesContent":["import './toggle.css';\nimport {\n formatColor,\n G9Metrics,\n G9StringKey,\n switchOffTrack,\n switchOnTrack,\n switchThumbOff,\n switchThumbOn,\n} from '@g9tm/lynxcontrols-foundation';\nimport {\n createContext,\n forwardRef,\n type ReactNode,\n useContext,\n useEffect,\n useImperativeHandle,\n useRef,\n useState,\n} from '@lynx-js/react';\nimport { type G9ControlBaseProps, g9RowStyle, g9TextStart, useG9Control } from '../base/control';\nimport { useG9Press } from '../base/press';\nimport { useControllableState } from '../base/use-controllable-state';\nimport { G9CoreContext } from '../provider/contexts';\nimport { useG9Strings, useG9Theme } from '../provider/hooks';\n\n// ---- selection groups (MAUI `SelectionGroup`: radio-style, scoped to the provider) -------------------------------\n\ninterface GroupMember {\n turnOff(): void;\n}\n\nconst registries = new WeakMap<object, Map<string, Set<GroupMember>>>();\nconst globalScope = {};\n\nfunction groupSet(scope: object, group: string): Set<GroupMember> {\n let groups = registries.get(scope);\n if (!groups) {\n groups = new Map();\n registries.set(scope, groups);\n }\n let set = groups.get(group);\n if (!set) {\n set = new Set();\n groups.set(group, set);\n }\n return set;\n}\n\n// ---- G9SwitchGroup ---------------------------------------------------------------------------------------------\n\ninterface SwitchGroupContextValue {\n readonly minOneActive: boolean;\n activeCount(): number;\n report(id: number, on: boolean | null): void;\n}\n\nconst SwitchGroupContext = createContext<SwitchGroupContextValue | null>(null);\n\n/** Props of {@link G9SwitchGroup} (MAUI `G9SwitchGroup`). */\nexport interface G9SwitchGroupProps extends G9ControlBaseProps {\n /** A tap cannot turn off the last active switch of the group (it shakes). Default false. */\n readonly minOneActive?: boolean;\n /** Shows `active / total` under the switches (warning colour at ≤ 1 with `minOneActive`). Default false. */\n readonly showLiveStatus?: boolean;\n /** Told when the number of active switches changes (MAUI `ActiveSwitchCount`). */\n readonly onActiveCountChange?: (active: number, total: number) => void;\n readonly children?: ReactNode;\n}\n\n/**\n * A vertical group of switches (MAUI `G9SwitchGroup`): counts its switches (nearest group only, as MAUI's direct\n * children), optionally keeps one on and shows a live `active / total` status. It does not make switches exclusive:\n * use `selectionGroup` for radio behaviour.\n */\nexport function G9SwitchGroup(props: G9SwitchGroupProps): ReactNode {\n const control = useG9Control(props, 'g9-switch-group');\n const [states, setStates] = useState<ReadonlyMap<number, boolean>>(() => new Map());\n const latest = useRef(states);\n latest.current = states;\n const minOneActive = props.minOneActive === true;\n const minRef = useRef(minOneActive);\n minRef.current = minOneActive;\n // One context object for the group's life: switches key their effects on it.\n const value = useRef<SwitchGroupContextValue | null>(null);\n if (value.current === null) {\n value.current = {\n get minOneActive() {\n return minRef.current;\n },\n activeCount: () => {\n let n = 0;\n for (const on of latest.current.values()) if (on) n++;\n return n;\n },\n report: (id, on) =>\n setStates((current) => {\n if (on === null ? !current.has(id) : current.get(id) === on) return current;\n const next = new Map(current);\n if (on === null) next.delete(id);\n else next.set(id, on);\n latest.current = next;\n return next;\n }),\n };\n }\n let active = 0;\n for (const on of states.values()) if (on) active++;\n const total = states.size;\n const notify = useRef(props.onActiveCountChange);\n notify.current = props.onActiveCountChange;\n useEffect(() => {\n notify.current?.(active, total);\n }, [active, total]);\n const warn = minOneActive && active <= 1;\n return (\n <SwitchGroupContext.Provider value={value.current}>\n <view className={control.className} {...control.idProps}>\n {props.children}\n {props.showLiveStatus ? (\n <text\n className=\"g9-switch-group__status\"\n style={{ color: warn ? 'var(--g9-warning)' : 'var(--g9-text-tertiary)' }}\n >\n {`${active} / ${total}`}\n </text>\n ) : null}\n </view>\n </SwitchGroupContext.Provider>\n );\n}\n\n// ---- G9Switch ----------------------------------------------------------------------------------------------------\n\n/** Props of {@link G9Switch} (MAUI `G9Switch`). */\nexport interface G9SwitchProps extends G9ControlBaseProps {\n /** Controlled state (MAUI `IsOn`). */\n readonly checked?: boolean;\n readonly defaultChecked?: boolean;\n /**\n * Once per change made by the switch: a tap, `toggle()`, or being turned off by its selection group (MAUI\n * `Toggled`). Never for a value the parent pushed in.\n */\n readonly onCheckedChange?: (checked: boolean) => void;\n /** A tap cannot turn it off (it shakes); code still can. Default false. */\n readonly isRequired?: boolean;\n /** Radio group name: turning this on turns off the others with the same name under the same provider. */\n readonly selectionGroup?: string | null;\n /** Form row: title/description fill the start, switch at the end, padded. Default false. */\n readonly isInFormRow?: boolean;\n /** Bold 14 title (form row only); the accessibility name. */\n readonly title?: string | null;\n /** 12 px description under the title (form row only). */\n readonly description?: string | null;\n}\n\n/** Imperative handle of {@link G9Switch}. */\nexport interface G9SwitchHandle {\n /** Same as a tap. */\n toggle(): void;\n}\n\nlet switchIds = 0;\n\n/**\n * Switch (MAUI `G9Switch`): 56 × 32 track, 24 px thumb that stretches while travelling, 240 ms spring-like CSS\n * transition, tick/dot track mark; RTL moves the \"on\" side to the left. A blocked tap (required, or the last active\n * switch of a `minOneActive` group) shakes instead of toggling. Disabled: opacity 0.45.\n */\nexport const G9Switch = forwardRef<G9SwitchHandle, G9SwitchProps>(function G9Switch(props, ref): ReactNode {\n const control = useG9Control(props, 'g9-switch');\n const theme = useG9Theme();\n const strings = useG9Strings();\n const core = useContext(G9CoreContext);\n const group = useContext(SwitchGroupContext);\n const [checked, setChecked] = useControllableState<boolean>({\n value: props.checked,\n defaultValue: props.defaultChecked ?? false,\n onChange: props.onCheckedChange,\n name: 'G9Switch.checked',\n });\n const [shake, setShake] = useState(0);\n const id = useRef(0);\n if (id.current === 0) id.current = ++switchIds;\n const latestChecked = useRef(checked);\n latestChecked.current = checked;\n const setRef = useRef(setChecked);\n setRef.current = setChecked;\n\n // Report to the group.\n useEffect(() => {\n group?.report(id.current, checked);\n }, [group, checked]);\n useEffect(() => () => group?.report(id.current, null), [group]);\n\n // Selection group registration (while mounted and named).\n const groupName = props.selectionGroup && props.selectionGroup.trim() !== '' ? props.selectionGroup : null;\n const scope: object = core ?? globalScope;\n const memberRef = useRef<GroupMember | null>(null);\n useEffect(() => {\n if (!groupName) return;\n const member: GroupMember = { turnOff: () => setRef.current(false) };\n const set = groupSet(scope, groupName);\n set.add(member);\n memberRef.current = member;\n return () => {\n set.delete(member);\n memberRef.current = null;\n };\n }, [groupName, scope]);\n useEffect(() => {\n if (!checked || !groupName) return;\n for (const other of groupSet(scope, groupName)) if (other !== memberRef.current) other.turnOff();\n }, [checked, groupName, scope]);\n\n const toggle = () => {\n if (control.disabled) return;\n const on = latestChecked.current;\n if (on && (props.isRequired || (group?.minOneActive && group.activeCount() <= 1))) {\n setShake((n) => n + 1);\n return;\n }\n setChecked(!on);\n };\n useImperativeHandle(ref, () => ({ toggle }));\n const press = useG9Press(toggle, { blocked: control.disabled, source: 'G9Switch', guardMs: 0 });\n\n const rtl = control.direction === 'rtl';\n const width = G9Metrics.SwitchWidth;\n const thumb = G9Metrics.SwitchThumb;\n const travel = width - 4 - thumb - 4;\n const x = (checked ? travel : 0) * (rtl ? -1 : 1);\n const track = formatColor(checked ? switchOnTrack(theme) : switchOffTrack(theme));\n const thumbColor = formatColor(checked ? switchThumbOn(theme) : switchThumbOff(theme));\n const form = props.isInFormRow === true;\n const title = props.title && props.title.trim() !== '' ? props.title : null;\n const description = props.description && props.description.trim() !== '' ? props.description : null;\n return (\n <view\n className={`${control.className}${form ? ' g9-switch--row' : ''}`}\n {...control.idProps}\n style={g9RowStyle(control.direction)}\n accessibility-element={true}\n accessibility-traits=\"button\"\n {...(checked ? { 'accessibility-value': strings.get(G9StringKey.Selected) } : {})}\n {...((props.accessibilityLabel ?? title)\n ? { 'accessibility-label': props.accessibilityLabel ?? title ?? '' }\n : {})}\n bindtap={press}\n >\n {form ? (\n <view className=\"g9-switch__text\">\n {title ? (\n <text className=\"g9-switch__title\" style={g9TextStart(control.direction)}>\n {title}\n </text>\n ) : null}\n {description ? (\n <text className=\"g9-switch__description\" style={g9TextStart(control.direction)}>\n {description}\n </text>\n ) : null}\n </view>\n ) : null}\n <view\n key={`shake-${shake}`}\n className={`g9-switch__track${shake > 0 ? ' g9-switch__track--shake' : ''}`}\n style={{ width: `${width}px`, height: `${G9Metrics.SwitchHeight}px`, backgroundColor: track }}\n >\n {/* MAUI G9SwitchDrawable.DrawTrackMark: the mark is ALWAYS 15 dp from the track's start edge — on, the thumb has\n travelled to the end and the tick shows beside it; off, the thumb covers the dot. (Centring the tick at\n the end put it under the thumb: no tick was ever visible.) */}\n <view className=\"g9-switch__mark\" style={{ [rtl ? 'right' : 'left']: checked ? '9px' : '12px' }}>\n {checked ? <text className=\"g9-switch__tick\">✓</text> : <view className=\"g9-switch__dot\" />}\n </view>\n <view\n className=\"g9-switch__thumb\"\n style={{\n [rtl ? 'right' : 'left']: '4px',\n width: `${thumb}px`,\n height: `${thumb}px`,\n backgroundColor: thumbColor,\n transform: `translateX(${x}px)`,\n }}\n />\n </view>\n </view>\n );\n});\n"],"names":["registries","WeakMap","globalScope","groupSet","scope","group","groups","Map","set","Set","SwitchGroupContext","createContext","G9SwitchGroup","props","control","useG9Control","states","setStates","useState","latest","useRef","minOneActive","minRef","value","n","on","id","current","next","active","total","notify","useEffect","warn","view","text","switchIds","G9Switch","forwardRef","ref","_props_defaultChecked","_props_accessibilityLabel","_ref","theme","useG9Theme","strings","useG9Strings","core","useContext","G9CoreContext","checked","setChecked","useControllableState","shake","setShake","latestChecked","setRef","groupName","memberRef","member","other","toggle","useImperativeHandle","press","useG9Press","rtl","width","G9Metrics","thumb","travel","x","track","formatColor","switchOnTrack","switchOffTrack","thumbColor","switchThumbOn","switchThumbOff","form","title","description","g9RowStyle","G9StringKey","g9TextStart"],"mappings":"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"}
1
+ {"version":3,"file":"toggle/switch.jsx","sources":["../../src/toggle/switch.tsx"],"sourcesContent":["import './toggle.css';\nimport {\n formatColor,\n G9Metrics,\n G9StringKey,\n switchOffTrack,\n switchOnTrack,\n switchThumbOff,\n switchThumbOn,\n} from '@g9tm/lynxcontrols-foundation';\nimport {\n createContext,\n forwardRef,\n type ReactNode,\n useContext,\n useEffect,\n useImperativeHandle,\n useRef,\n useState,\n} from '@lynx-js/react';\nimport { type G9ControlBaseProps, g9RowStyle, g9TextStart, useG9Control } from '../base/control';\nimport { useG9Press } from '../base/press';\nimport { useControllableState } from '../base/use-controllable-state';\nimport { G9CoreContext } from '../provider/contexts';\nimport { useG9Settings, useG9Strings, useG9Theme } from '../provider/hooks';\n\n// ---- selection groups (MAUI `SelectionGroup`: radio-style, scoped to the provider) -------------------------------\n\ninterface GroupMember {\n turnOff(): void;\n}\n\nconst registries = new WeakMap<object, Map<string, Set<GroupMember>>>();\nconst globalScope = {};\n\nfunction groupSet(scope: object, group: string): Set<GroupMember> {\n let groups = registries.get(scope);\n if (!groups) {\n groups = new Map();\n registries.set(scope, groups);\n }\n let set = groups.get(group);\n if (!set) {\n set = new Set();\n groups.set(group, set);\n }\n return set;\n}\n\n// ---- G9SwitchGroup ---------------------------------------------------------------------------------------------\n\ninterface SwitchGroupContextValue {\n readonly minOneActive: boolean;\n activeCount(): number;\n report(id: number, on: boolean | null): void;\n}\n\nconst SwitchGroupContext = createContext<SwitchGroupContextValue | null>(null);\n\n/** Props of {@link G9SwitchGroup} (MAUI `G9SwitchGroup`). */\nexport interface G9SwitchGroupProps extends G9ControlBaseProps {\n /** A tap cannot turn off the last active switch of the group (it shakes). Default false. */\n readonly minOneActive?: boolean;\n /** Shows `active / total` under the switches (warning colour at ≤ 1 with `minOneActive`). Default false. */\n readonly showLiveStatus?: boolean;\n /** Told when the number of active switches changes (MAUI `ActiveSwitchCount`). */\n readonly onActiveCountChange?: (active: number, total: number) => void;\n readonly children?: ReactNode;\n}\n\n/**\n * A vertical group of switches (MAUI `G9SwitchGroup`): counts its switches (nearest group only, as MAUI's direct\n * children), optionally keeps one on and shows a live `active / total` status. It does not make switches exclusive:\n * use `selectionGroup` for radio behaviour.\n */\nexport function G9SwitchGroup(props: G9SwitchGroupProps): ReactNode {\n const control = useG9Control(props, 'g9-switch-group');\n const [states, setStates] = useState<ReadonlyMap<number, boolean>>(() => new Map());\n const latest = useRef(states);\n latest.current = states;\n const minOneActive = props.minOneActive === true;\n const minRef = useRef(minOneActive);\n minRef.current = minOneActive;\n // One context object for the group's life: switches key their effects on it.\n const value = useRef<SwitchGroupContextValue | null>(null);\n if (value.current === null) {\n value.current = {\n get minOneActive() {\n return minRef.current;\n },\n activeCount: () => {\n let n = 0;\n for (const on of latest.current.values()) if (on) n++;\n return n;\n },\n report: (id, on) =>\n setStates((current) => {\n if (on === null ? !current.has(id) : current.get(id) === on) return current;\n const next = new Map(current);\n if (on === null) next.delete(id);\n else next.set(id, on);\n latest.current = next;\n return next;\n }),\n };\n }\n let active = 0;\n for (const on of states.values()) if (on) active++;\n const total = states.size;\n const notify = useRef(props.onActiveCountChange);\n notify.current = props.onActiveCountChange;\n useEffect(() => {\n notify.current?.(active, total);\n }, [active, total]);\n const warn = minOneActive && active <= 1;\n return (\n <SwitchGroupContext.Provider value={value.current}>\n <view className={control.className} {...control.idProps}>\n {props.children}\n {props.showLiveStatus ? (\n <text\n className=\"g9-switch-group__status\"\n style={{ color: warn ? 'var(--g9-warning)' : 'var(--g9-text-tertiary)' }}\n >\n {`${active} / ${total}`}\n </text>\n ) : null}\n </view>\n </SwitchGroupContext.Provider>\n );\n}\n\n// ---- G9Switch ----------------------------------------------------------------------------------------------------\n\n/** Props of {@link G9Switch} (MAUI `G9Switch`). */\nexport interface G9SwitchProps extends G9ControlBaseProps {\n /** Controlled state (MAUI `IsOn`). */\n readonly checked?: boolean;\n readonly defaultChecked?: boolean;\n /**\n * Once per change made by the switch: a tap, `toggle()`, or being turned off by its selection group (MAUI\n * `Toggled`). Never for a value the parent pushed in.\n */\n readonly onCheckedChange?: (checked: boolean) => void;\n /** A tap cannot turn it off (it shakes); code still can. Default false. */\n readonly isRequired?: boolean;\n /** Radio group name: turning this on turns off the others with the same name under the same provider. */\n readonly selectionGroup?: string | null;\n /** Form row: title/description fill the start, switch at the end, padded. Default false. */\n readonly isInFormRow?: boolean;\n /** Bold 14 title (form row only); the accessibility name. */\n readonly title?: string | null;\n /** 12 px description under the title (form row only). */\n readonly description?: string | null;\n}\n\n/** Imperative handle of {@link G9Switch}. */\nexport interface G9SwitchHandle {\n /** Same as a tap. */\n toggle(): void;\n}\n\nlet switchIds = 0;\n\n/**\n * Switch (MAUI `G9Switch`): 56 × 32 track, 24 px thumb that stretches while travelling, 240 ms spring-like CSS\n * transition, tick/dot track mark; RTL moves the \"on\" side to the left unless `toggles.switchMirrorInRtl` is false. A blocked tap (required, or the last active\n * switch of a `minOneActive` group) shakes instead of toggling. Disabled: opacity 0.45.\n */\nexport const G9Switch = forwardRef<G9SwitchHandle, G9SwitchProps>(function G9Switch(props, ref): ReactNode {\n const control = useG9Control(props, 'g9-switch');\n const theme = useG9Theme();\n const strings = useG9Strings();\n const settings = useG9Settings();\n const core = useContext(G9CoreContext);\n const group = useContext(SwitchGroupContext);\n const [checked, setChecked] = useControllableState<boolean>({\n value: props.checked,\n defaultValue: props.defaultChecked ?? false,\n onChange: props.onCheckedChange,\n name: 'G9Switch.checked',\n });\n const [shake, setShake] = useState(0);\n const id = useRef(0);\n if (id.current === 0) id.current = ++switchIds;\n const latestChecked = useRef(checked);\n latestChecked.current = checked;\n const setRef = useRef(setChecked);\n setRef.current = setChecked;\n\n // Report to the group.\n useEffect(() => {\n group?.report(id.current, checked);\n }, [group, checked]);\n useEffect(() => () => group?.report(id.current, null), [group]);\n\n // Selection group registration (while mounted and named).\n const groupName = props.selectionGroup && props.selectionGroup.trim() !== '' ? props.selectionGroup : null;\n const scope: object = core ?? globalScope;\n const memberRef = useRef<GroupMember | null>(null);\n useEffect(() => {\n if (!groupName) return;\n const member: GroupMember = { turnOff: () => setRef.current(false) };\n const set = groupSet(scope, groupName);\n set.add(member);\n memberRef.current = member;\n return () => {\n set.delete(member);\n memberRef.current = null;\n };\n }, [groupName, scope]);\n useEffect(() => {\n if (!checked || !groupName) return;\n for (const other of groupSet(scope, groupName)) if (other !== memberRef.current) other.turnOff();\n }, [checked, groupName, scope]);\n\n const toggle = () => {\n if (control.disabled) return;\n const on = latestChecked.current;\n if (on && (props.isRequired || (group?.minOneActive && group.activeCount() <= 1))) {\n setShake((n) => n + 1);\n return;\n }\n setChecked(!on);\n };\n useImperativeHandle(ref, () => ({ toggle }));\n const press = useG9Press(toggle, { blocked: control.disabled, source: 'G9Switch', guardMs: 0 });\n\n // The row flows with the language; the toggle mirrors only while the app lets it (MAUI 1.4.10 MirrorInRtl).\n const rtl = control.direction === 'rtl' && settings.toggles.switchMirrorInRtl;\n const width = G9Metrics.SwitchWidth;\n const thumb = G9Metrics.SwitchThumb;\n const travel = width - 4 - thumb - 4;\n const x = (checked ? travel : 0) * (rtl ? -1 : 1);\n const track = formatColor(checked ? switchOnTrack(theme) : switchOffTrack(theme));\n const thumbColor = formatColor(checked ? switchThumbOn(theme) : switchThumbOff(theme));\n const form = props.isInFormRow === true;\n const title = props.title && props.title.trim() !== '' ? props.title : null;\n const description = props.description && props.description.trim() !== '' ? props.description : null;\n return (\n <view\n className={`${control.className}${form ? ' g9-switch--row' : ''}`}\n {...control.idProps}\n style={g9RowStyle(control.direction)}\n accessibility-element={true}\n accessibility-traits=\"button\"\n {...(checked ? { 'accessibility-value': strings.get(G9StringKey.Selected) } : {})}\n {...((props.accessibilityLabel ?? title)\n ? { 'accessibility-label': props.accessibilityLabel ?? title ?? '' }\n : {})}\n bindtap={press}\n >\n {form ? (\n <view className=\"g9-switch__text\">\n {title ? (\n <text className=\"g9-switch__title\" style={g9TextStart(control.direction)}>\n {title}\n </text>\n ) : null}\n {description ? (\n <text className=\"g9-switch__description\" style={g9TextStart(control.direction)}>\n {description}\n </text>\n ) : null}\n </view>\n ) : null}\n <view\n key={`shake-${shake}`}\n className={`g9-switch__track${shake > 0 ? ' g9-switch__track--shake' : ''}`}\n style={{ width: `${width}px`, height: `${G9Metrics.SwitchHeight}px`, backgroundColor: track }}\n >\n {/* MAUI G9SwitchDrawable.DrawTrackMark: the mark is ALWAYS 15 dp from the track's start edge — on, the thumb has\n travelled to the end and the tick shows beside it; off, the thumb covers the dot. (Centring the tick at\n the end put it under the thumb: no tick was ever visible.) */}\n <view className=\"g9-switch__mark\" style={{ [rtl ? 'right' : 'left']: checked ? '9px' : '12px' }}>\n {checked ? <text className=\"g9-switch__tick\">✓</text> : <view className=\"g9-switch__dot\" />}\n </view>\n <view\n className=\"g9-switch__thumb\"\n style={{\n [rtl ? 'right' : 'left']: '4px',\n width: `${thumb}px`,\n height: `${thumb}px`,\n backgroundColor: thumbColor,\n transform: `translateX(${x}px)`,\n }}\n />\n </view>\n </view>\n );\n});\n"],"names":["registries","WeakMap","globalScope","groupSet","scope","group","groups","Map","set","Set","SwitchGroupContext","createContext","G9SwitchGroup","props","control","useG9Control","states","setStates","useState","latest","useRef","minOneActive","minRef","value","n","on","id","current","next","active","total","notify","useEffect","warn","view","text","switchIds","G9Switch","forwardRef","ref","_props_defaultChecked","_props_accessibilityLabel","_ref","theme","useG9Theme","strings","useG9Strings","settings","useG9Settings","core","useContext","G9CoreContext","checked","setChecked","useControllableState","shake","setShake","latestChecked","setRef","groupName","memberRef","member","other","toggle","useImperativeHandle","press","useG9Press","rtl","width","G9Metrics","thumb","travel","x","track","formatColor","switchOnTrack","switchOffTrack","thumbColor","switchThumbOn","switchThumbOff","form","title","description","g9RowStyle","G9StringKey","g9TextStart"],"mappings":";;;;;;;;AAgCA,MAAMA,aAAa,IAAIC;AACvB,MAAMC,cAAc,CAAC;AAErB,SAASC,SAASC,KAAa,EAAEC,KAAa;IAC5C,IAAIC,SAASN,WAAW,GAAG,CAACI;IAC5B,IAAI,CAACE,QAAQ;QACXA,SAAS,IAAIC;QACbP,WAAW,GAAG,CAACI,OAAOE;IACxB;IACA,IAAIE,MAAMF,OAAO,GAAG,CAACD;IACrB,IAAI,CAACG,KAAK;QACRA,MAAM,IAAIC;QACVH,OAAO,GAAG,CAACD,OAAOG;IACpB;IACA,OAAOA;AACT;AAUA,MAAME,qBAAqBC,cAA8C;AAkBlE,SAASC,cAAcC,KAAyB;IACrD,MAAMC,UAAUC,aAAaF,OAAO;IACpC,MAAM,CAACG,QAAQC,UAAU,GAAGC,SAAuC,IAAM,IAAIX;IAC7E,MAAMY,SAASC,OAAOJ;IACtBG,OAAO,OAAO,GAAGH;IACjB,MAAMK,eAAeR,AAAuB,SAAvBA,MAAM,YAAY;IACvC,MAAMS,SAASF,OAAOC;IACtBC,OAAO,OAAO,GAAGD;IAEjB,MAAME,QAAQH,OAAuC;IACrD,IAAIG,AAAkB,SAAlBA,MAAM,OAAO,EACfA,MAAM,OAAO,GAAG;QACd,IAAI;YACF,OAAOD,OAAO,OAAO;QACvB;QACA,aAAa;YACX,IAAIE,IAAI;YACR,KAAK,MAAMC,MAAMN,OAAO,OAAO,CAAC,MAAM,GAAI,IAAIM,IAAID;YAClD,OAAOA;QACT;QACA,QAAQ,CAACE,IAAID,KACXR,UAAU,CAACU;gBACT,IAAIF,AAAO,SAAPA,KAAc,CAACE,QAAQ,GAAG,CAACD,MAAMC,QAAQ,GAAG,CAACD,QAAQD,IAAI,OAAOE;gBACpE,MAAMC,OAAO,IAAIrB,IAAIoB;gBACrB,IAAIF,AAAO,SAAPA,IAAaG,KAAK,MAAM,CAACF;qBACxBE,KAAK,GAAG,CAACF,IAAID;gBAClBN,OAAO,OAAO,GAAGS;gBACjB,OAAOA;YACT;IACJ;IAEF,IAAIC,SAAS;IACb,KAAK,MAAMJ,MAAMT,OAAO,MAAM,GAAI,IAAIS,IAAII;IAC1C,MAAMC,QAAQd,OAAO,IAAI;IACzB,MAAMe,SAASX,OAAOP,MAAM,mBAAmB;IAC/CkB,OAAO,OAAO,GAAGlB,MAAM,mBAAmB;IAC1CmB,UAAU;YACRD;gBAAAA,CAAAA,kBAAAA,OAAO,OAAO,AAAD,KAAbA,gBAAAA,IAAAA,CAAAA,QAAiBF,QAAQC;IAC3B,GAAG;QAACD;QAAQC;KAAM;IAClB,MAAMG,OAAOZ,gBAAgBQ,UAAU;IACvC,QACGnB,mBAAmB,SAAS,OAAOa,MAAM,OAAO,EAAE;MACjD,CAACW,KAAK,WAAWpB,QAAQ,SAAS,GAAG,GAAGA,QAAQ,OAAO,EAAE;QACvD,CAACD,MAAM,QAAQ,CAAC;QAChB,CAACA,MAAM,cAAc,IAClBsB,KACC,UAAU,0BACV,OAAO;QAAE,OAAOF,OAAO,sBAAsB;IAA0B,GACxE;YACC,CAAC,GAAGJ,OAAO,GAAG,EAAEC,OAAO,CAAC;UAC1B,EAAEK,QACA,KAAK;MACX,EAAED,KAAK;IACT,EAAExB,mBAAmB;AAEzB;AAgCA,IAAI0B,YAAY;AAOT,MAAMC,kBAAWC,WAA0C,SAAkBzB,KAAK,EAAE0B,GAAG;QAS5EC,uBAqENC,2BACuBC,MAAAA;IA9EjC,MAAM5B,UAAUC,aAAaF,OAAO;IACpC,MAAM8B,QAAQC;IACd,MAAMC,UAAUC;IAChB,MAAMC,WAAWC;IACjB,MAAMC,OAAOC,WAAWC;IACxB,MAAM9C,QAAQ6C,WAAWxC;IACzB,MAAM,CAAC0C,SAASC,WAAW,GAAGC,qBAA8B;QAC1D,OAAOzC,MAAM,OAAO;QACpB,cAAc,QAAA2B,CAAAA,wBAAAA,MAAM,cAAc,AAAD,IAAnBA,wBAAwB;QACtC,UAAU3B,MAAM,eAAe;QAC/B,MAAM;IACR;IACA,MAAM,CAAC0C,OAAOC,SAAS,GAAGtC,SAAS;IACnC,MAAMQ,KAAKN,OAAO;IAClB,IAAIM,AAAe,MAAfA,GAAG,OAAO,EAAQA,GAAG,OAAO,GAAG,EAAEU;IACrC,MAAMqB,gBAAgBrC,OAAOgC;IAC7BK,cAAc,OAAO,GAAGL;IACxB,MAAMM,SAAStC,OAAOiC;IACtBK,OAAO,OAAO,GAAGL;IAGjBrB,UAAU;QACR3B,QAAAA,SAAAA,MAAO,MAAM,CAACqB,GAAG,OAAO,EAAE0B;IAC5B,GAAG;QAAC/C;QAAO+C;KAAQ;IACnBpB,UAAU,IAAM,IAAM3B,QAAAA,QAAAA,KAAAA,IAAAA,MAAO,MAAM,CAACqB,GAAG,OAAO,EAAE,OAAO;QAACrB;KAAM;IAG9D,MAAMsD,YAAY9C,MAAM,cAAc,IAAIA,AAAgC,OAAhCA,MAAM,cAAc,CAAC,IAAI,KAAYA,MAAM,cAAc,GAAG;IACtG,MAAMT,QAAgB6C,QAAAA,OAAAA,OAAQ/C;IAC9B,MAAM0D,YAAYxC,OAA2B;IAC7CY,UAAU;QACR,IAAI,CAAC2B,WAAW;QAChB,MAAME,SAAsB;YAAE,SAAS,IAAMH,OAAO,OAAO,CAAC;QAAO;QACnE,MAAMlD,MAAML,SAASC,OAAOuD;QAC5BnD,IAAI,GAAG,CAACqD;QACRD,UAAU,OAAO,GAAGC;QACpB,OAAO;YACLrD,IAAI,MAAM,CAACqD;YACXD,UAAU,OAAO,GAAG;QACtB;IACF,GAAG;QAACD;QAAWvD;KAAM;IACrB4B,UAAU;QACR,IAAI,CAACoB,WAAW,CAACO,WAAW;QAC5B,KAAK,MAAMG,SAAS3D,SAASC,OAAOuD,WAAY,IAAIG,UAAUF,UAAU,OAAO,EAAEE,MAAM,OAAO;IAChG,GAAG;QAACV;QAASO;QAAWvD;KAAM;IAE9B,MAAM2D,SAAS;QACb,IAAIjD,QAAQ,QAAQ,EAAE;QACtB,MAAMW,KAAKgC,cAAc,OAAO;QAChC,IAAIhC,MAAOZ,CAAAA,MAAM,UAAU,IAAKR,AAAAA,CAAAA,QAAAA,QAAAA,KAAAA,IAAAA,MAAO,YAAY,AAAD,KAAKA,MAAM,WAAW,MAAM,IAAK,YACjFmD,SAAS,CAAChC,IAAMA,IAAI;QAGtB6B,WAAW,CAAC5B;IACd;IACAuC,oBAAoBzB,KAAK,IAAO;YAAEwB;QAAO;IACzC,MAAME,QAAQC,WAAWH,QAAQ;QAAE,SAASjD,QAAQ,QAAQ;QAAE,QAAQ;QAAY,SAAS;IAAE;IAG7F,MAAMqD,MAAMrD,AAAsB,UAAtBA,QAAQ,SAAS,IAAciC,SAAS,OAAO,CAAC,iBAAiB;IAC7E,MAAMqB,QAAQC,UAAU,WAAW;IACnC,MAAMC,QAAQD,UAAU,WAAW;IACnC,MAAME,SAASH,QAAQ,IAAIE,QAAQ;IACnC,MAAME,IAAKpB,AAAAA,CAAAA,UAAUmB,SAAS,KAAMJ,CAAAA,MAAM,KAAK;IAC/C,MAAMM,QAAQC,YAAYtB,UAAUuB,cAAchC,SAASiC,eAAejC;IAC1E,MAAMkC,aAAaH,YAAYtB,UAAU0B,cAAcnC,SAASoC,eAAepC;IAC/E,MAAMqC,OAAOnE,AAAsB,SAAtBA,MAAM,WAAW;IAC9B,MAAMoE,QAAQpE,MAAM,KAAK,IAAIA,AAAuB,OAAvBA,MAAM,KAAK,CAAC,IAAI,KAAYA,MAAM,KAAK,GAAG;IACvE,MAAMqE,cAAcrE,MAAM,WAAW,IAAIA,AAA6B,OAA7BA,MAAM,WAAW,CAAC,IAAI,KAAYA,MAAM,WAAW,GAAG;IAC/F,QACGqB,KACC,WAAW,GAAGpB,QAAQ,SAAS,GAAGkE,OAAO,oBAAoB,IAAI,GAChE,GAAGlE,QAAQ,OAAO,EACnB,OAAOqE,WAAWrE,QAAQ,SAAS,GACnC,uBAAuB,MACvB,qBAAqB,UACpB,GAAIsC,UAAU;QAAE,uBAAuBP,QAAQ,GAAG,CAACuC,YAAY,QAAQ;IAAE,IAAI,CAAC,CAAC,GAC/E,GAAI,AAAC,SAAA3C,CAAAA,4BAAAA,MAAM,kBAAkB,AAAD,IAAvBA,4BAA4BwC,KAAI,IAClC;QAAE,uBAAuB,QAAAvC,CAAAA,OAAAA,QAAAA,CAAAA,6BAAAA,MAAM,kBAAkB,AAAD,IAAvBA,6BAA4BuC,KAAI,IAAhCvC,OAAqC;IAAG,IACjE,CAAC,CAAC,EACN,SAASuB,OACV;MACC,CAACe,QACE9C,KAAK,UAAU,kBAAkB;UAChC,CAAC+C,SACE9C,KAAK,UAAU,mBAAmB,OAAOkD,YAAYvE,QAAQ,SAAS,GAAG;cACxE,CAACmE,MAAM;YACT,EAAE9C,QACA,KAAK;UACT,CAAC+C,eACE/C,KAAK,UAAU,yBAAyB,OAAOkD,YAAYvE,QAAQ,SAAS,GAAG;cAC9E,CAACoE,YAAY;YACf,EAAE/C,QACA,KAAK;QACX,EAAED,QACA,KAAK;MACT,CAACA,KACC,KAAK,CAAC,MAAM,EAAEqB,OAAO,EACrB,WAAW,CAAC,gBAAgB,EAAEA,QAAQ,IAAI,6BAA6B,IAAI,EAC3E,OAAO;QAAE,OAAO,GAAGa,MAAM,EAAE,CAAC;QAAE,QAAQ,GAAGC,UAAU,YAAY,CAAC,EAAE,CAAC;QAAE,iBAAiBI;IAAM,GAC7F;QACC,EAEkE;QAClE,CAACvC,KAAK,UAAU,kBAAkB,OAAO;QAAE,CAACiC,MAAM,UAAU,OAAO,EAAEf,UAAU,QAAQ;IAAO,GAAG;UAC/F,CAACA,WAAWjB,KAAK,UAAU,kBAAkB,CAAC,EAAEA,SAASD,KAAK,UAAU,mBAAoB;QAC9F,EAAEA,KAAK;QACP,CAACA,KACC,UAAU,mBACV,OAAO;QACL,CAACiC,MAAM,UAAU,OAAO,EAAE;QAC1B,OAAO,GAAGG,MAAM,EAAE,CAAC;QACnB,QAAQ,GAAGA,MAAM,EAAE,CAAC;QACpB,iBAAiBO;QACjB,WAAW,CAAC,WAAW,EAAEL,EAAE,GAAG,CAAC;IACjC,IACA;MACJ,EAAEtC,KAAK;IACT,EAAEA;AAEN"}
@@ -167,6 +167,26 @@
167
167
  opacity: .45;
168
168
  }
169
169
 
170
+ .g9-chip-group--segmented {
171
+ flex-direction: column;
172
+ display: flex;
173
+ }
174
+
175
+ .g9-chip-group__segment-row {
176
+ flex-direction: row;
177
+ display: flex;
178
+ }
179
+
180
+ .g9-chip-group__segment-fill {
181
+ flex: 1;
182
+ }
183
+
184
+ .g9-chip--segment {
185
+ border-width: 1px;
186
+ flex: 1;
187
+ justify-content: center;
188
+ }
189
+
170
190
  .g9-chip__text {
171
191
  white-space: nowrap;
172
192
  font-size: 13px;
@@ -1 +1 @@
1
- {"version":3,"sources":["webpack://./src/toggle/toggle.css"],"names":[],"mappings":"AACA;EAAE,mBAAmB;EACnB,sBAAsB;EACtB,uBAAuB;EACvB,aAAa;AACf;;AAGA;EAAE,mBAAmB;EACnB,eAAe;AACjB;;AAGA;EAAE,uBAAuB;EACvB,mBAAmB;EACnB,aAAa;AACf;;AAKA;EAFE,YAAY;AACd;;AAKA;EAFE,WAAW;EACX,YAAY;AACd;;AAOA;EAJE,OAAO;EACP,kBAAkB;EAClB,eAAe;AACjB;;AAOA;EAJE,mBAAmB;EACnB,uBAAuB;EACvB,mBAAmB;EACnB,aAAa;AACf;;AAOA;EAJE,8BAA8B;EAC9B,mBAAmB;EACnB,gBAAgB;EAChB,kBAAkB;AACpB;;AAOA;EAJE,sBAAsB;EACtB,OAAO;EACP,YAAY;EACZ,aAAa;AACf;;AAOA;EAJE,6BAA6B;EAC7B,eAAe;EACf,iBAAiB;AACnB;;AAOA;EAJE,8BAA8B;EAC9B,eAAe;AACjB;;AAOA;EAJE,mBAAmB;EACnB,0CAA0C;EAC1C,kBAAkB;AACpB;;AAOA;EAJE,2CAA2C;AAC7C;;AAOA;EAJE;IACE,wBAAwB;EAC1B;;EAEA;IACE,2BAA2B;EAC7B;;EAEA;IACE,0BAA0B;EAC5B;;EAEA;IACE,2BAA2B;EAC7B;;EAEA;IACE,0BAA0B;EAC5B;;EAEA;IACE,wBAAwB;EAC1B;AACF;;AAEA;EACE,mBAAmB;EACnB,0FAA0F;EAC1F,kBAAkB;EAClB,QAAQ;AACV;;AAIA;EADE,kBAAkB;EAClB,QAAQ;AACV;;AAKA;EAFE,gBAAgB;EAChB,gBAAgB;EAChB,eAAe;EACf,iBAAiB;EACjB,iBAAiB;AACnB;;AAKA;EAFE,2BAA2B;EAC3B,kBAAkB;EAClB,UAAU;EACV,WAAW;EACX,eAAe;AACjB;;AAKA;EAFE,YAAY;AACd;;AAKA;EAFE,sBAAsB;EACtB,aAAa;AACf;;AAKA;EAFE,iBAAiB;EACjB,eAAe;AACjB;;AAOA;EAJE,eAAe;EACf,2BAA2B;EAC3B,aAAa;AACf;;AAQA;EALE,mBAAmB;EACnB,aAAa;AACf;;AAQA;EALE,mBAAmB;EACnB,mBAAmB;EACnB,mBAAmB;EACnB,mBAAmB;EACnB,eAAe;EACf,eAAe;EACf,4EAA4E;EAC5E,aAAa;AACf;;AAUA;EAPE,YAAY;AACd;;AAUA;EAPE,mBAAmB;EACnB,eAAe;EACf,iBAAiB;AACnB;;AAUA;EAPE,UAAU;EACV,QAAQ;EACR,wFAAwF;EACxF,gBAAgB;EAChB,oBAAoB;AACtB;;AAaA;EAVE,UAAU;EACV,WAAW;EACX,mBAAmB;AACrB","sourcesContent":["/* Toggles (MAUI G9CheckBox, G9Switch, G9SwitchGroup, G9ChipGroup). */\n.g9-checkbox {\n display: flex;\n flex-direction: row;\n align-items: flex-start;\n align-self: flex-start;\n}\n\n.g9-checkbox--labelled {\n align-self: stretch;\n column-gap: 2px;\n}\n\n.g9-checkbox__slot {\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n/* MAUI G9CheckBox: the 20 px box is centred in a 48 × 48 slot (both axes). The slot used to put it at the start edge\n and 7 px low (row direction + padding), 28 px from its label on Android. */\n.g9-checkbox__slot--reserve {\n height: 48px;\n}\n\n.g9-checkbox__box {\n width: 20px;\n height: 20px;\n}\n\n/* One line centres on the slot (MAUI: label centred in the 48 px row); a wrapping label grows the row and the box\n stays level with its first line. */\n.g9-checkbox__text {\n flex: 1;\n align-self: center;\n font-size: 14px;\n}\n\n.g9-switch {\n display: flex;\n flex-direction: row;\n align-items: center;\n justify-content: center;\n}\n\n.g9-switch--row {\n justify-content: space-between;\n column-gap: 12px;\n padding: 12px 16px;\n align-self: stretch;\n}\n\n.g9-switch__text {\n display: flex;\n flex-direction: column;\n flex: 1;\n row-gap: 2px;\n}\n\n.g9-switch__title {\n font-size: 14px;\n font-weight: bold;\n color: var(--g9-text-primary);\n}\n\n.g9-switch__description {\n font-size: 12px;\n color: var(--g9-text-tertiary);\n}\n\n.g9-switch__track {\n position: relative;\n border-radius: 16px;\n transition: background-color 240ms ease-out;\n}\n\n.g9-switch__track--shake {\n animation: g9-switch-shake 310ms ease-in-out;\n}\n\n@keyframes g9-switch-shake {\n 0% {\n transform: translateX(0px);\n }\n 19% {\n transform: translateX(-4px);\n }\n 39% {\n transform: translateX(4px);\n }\n 58% {\n transform: translateX(-3px);\n }\n 77% {\n transform: translateX(3px);\n }\n 100% {\n transform: translateX(0px);\n }\n}\n\n.g9-switch__thumb {\n position: absolute;\n top: 4px;\n border-radius: 12px;\n transition:\n transform 240ms cubic-bezier(0.34, 1.56, 0.64, 1),\n background-color 240ms ease-out;\n}\n\n.g9-switch__mark {\n position: absolute;\n top: 9px;\n}\n\n/* MAUI draws the tick with 2.5 dp round strokes, 11 × 9 dp: a bold 15 dp glyph is that weight and size. */\n.g9-switch__tick {\n font-size: 15px;\n font-weight: bold;\n line-height: 15px;\n margin-top: -2px;\n color: rgba(255, 255, 255, 0.75);\n}\n\n.g9-switch__dot {\n width: 6px;\n height: 6px;\n margin-top: 4px;\n border-radius: 3px;\n background-color: rgba(0, 0, 0, 0.22);\n}\n\n.g9-disabled {\n opacity: 0.45;\n}\n\n.g9-switch-group {\n display: flex;\n flex-direction: column;\n}\n\n.g9-switch-group__status {\n font-size: 11px;\n margin: 6px 2px 0px 2px;\n}\n\n/* MAUI G9ChipGroup: a FlexLayout of Wrap and JustifyContent Start — the chips run from the reading start (the row is\n reversed in RTL, so flex-start is the right edge there), never centred. */\n.g9-chip-group--wrap {\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n justify-content: flex-start;\n}\n\n.g9-chip-group__line {\n display: flex;\n flex-direction: row;\n}\n\n.g9-chip {\n display: flex;\n flex-direction: row;\n align-items: center;\n column-gap: 6px;\n padding: 0px 14px;\n border-style: solid;\n border-width: 1.5px;\n transition:\n background-color 140ms ease-in-out,\n border-color 140ms ease-in-out;\n}\n\n.g9-chip--disabled {\n opacity: 0.45;\n}\n\n.g9-chip__text {\n font-size: 13px;\n font-weight: bold;\n white-space: nowrap;\n}\n\n.g9-chip__check {\n width: 0px;\n opacity: 0;\n transform: scale(0.5);\n overflow: hidden;\n transition:\n width 120ms ease-in-out,\n opacity 120ms ease-in-out,\n transform 120ms ease-in-out;\n}\n\n.g9-chip__check--on {\n width: 16px;\n opacity: 1;\n transform: scale(1);\n}\n"],"sourceRoot":""}
1
+ {"version":3,"sources":["webpack://./src/toggle/toggle.css"],"names":[],"mappings":"AACA;EAAE,mBAAmB;EACnB,sBAAsB;EACtB,uBAAuB;EACvB,aAAa;AACf;;AAGA;EAAE,mBAAmB;EACnB,eAAe;AACjB;;AAGA;EAAE,uBAAuB;EACvB,mBAAmB;EACnB,aAAa;AACf;;AAKA;EAFE,YAAY;AACd;;AAKA;EAFE,WAAW;EACX,YAAY;AACd;;AAOA;EAJE,OAAO;EACP,kBAAkB;EAClB,eAAe;AACjB;;AAOA;EAJE,mBAAmB;EACnB,uBAAuB;EACvB,mBAAmB;EACnB,aAAa;AACf;;AAOA;EAJE,8BAA8B;EAC9B,mBAAmB;EACnB,gBAAgB;EAChB,kBAAkB;AACpB;;AAOA;EAJE,sBAAsB;EACtB,OAAO;EACP,YAAY;EACZ,aAAa;AACf;;AAOA;EAJE,6BAA6B;EAC7B,eAAe;EACf,iBAAiB;AACnB;;AAOA;EAJE,8BAA8B;EAC9B,eAAe;AACjB;;AAOA;EAJE,mBAAmB;EACnB,0CAA0C;EAC1C,kBAAkB;AACpB;;AAOA;EAJE,2CAA2C;AAC7C;;AAOA;EAJE;IACE,wBAAwB;EAC1B;;EAEA;IACE,2BAA2B;EAC7B;;EAEA;IACE,0BAA0B;EAC5B;;EAEA;IACE,2BAA2B;EAC7B;;EAEA;IACE,0BAA0B;EAC5B;;EAEA;IACE,wBAAwB;EAC1B;AACF;;AAEA;EACE,mBAAmB;EACnB,0FAA0F;EAC1F,kBAAkB;EAClB,QAAQ;AACV;;AAIA;EADE,kBAAkB;EAClB,QAAQ;AACV;;AAKA;EAFE,gBAAgB;EAChB,gBAAgB;EAChB,eAAe;EACf,iBAAiB;EACjB,iBAAiB;AACnB;;AAKA;EAFE,2BAA2B;EAC3B,kBAAkB;EAClB,UAAU;EACV,WAAW;EACX,eAAe;AACjB;;AAKA;EAFE,YAAY;AACd;;AAKA;EAFE,sBAAsB;EACtB,aAAa;AACf;;AAKA;EAFE,iBAAiB;EACjB,eAAe;AACjB;;AAOA;EAJE,eAAe;EACf,2BAA2B;EAC3B,aAAa;AACf;;AAQA;EALE,mBAAmB;EACnB,aAAa;AACf;;AAQA;EALE,mBAAmB;EACnB,mBAAmB;EACnB,mBAAmB;EACnB,mBAAmB;EACnB,eAAe;EACf,eAAe;EACf,4EAA4E;EAC5E,aAAa;AACf;;AAUA;EAPE,YAAY;AACd;;AAWA;EARE,sBAAsB;EACtB,aAAa;AACf;;AAWA;EARE,mBAAmB;EACnB,aAAa;AACf;;AAWA;EARE,OAAO;AACT;;AAYA;EATE,iBAAiB;EACjB,OAAO;EACP,uBAAuB;AACzB;;AAYA;EATE,mBAAmB;EACnB,eAAe;EACf,iBAAiB;AACnB;;AAYA;EATE,UAAU;EACV,QAAQ;EACR,wFAAwF;EACxF,gBAAgB;EAChB,oBAAoB;AACtB;;AAeA;EAZE,UAAU;EACV,WAAW;EACX,mBAAmB;AACrB","sourcesContent":["/* Toggles (MAUI G9CheckBox, G9Switch, G9SwitchGroup, G9ChipGroup). */\n.g9-checkbox {\n display: flex;\n flex-direction: row;\n align-items: flex-start;\n align-self: flex-start;\n}\n\n.g9-checkbox--labelled {\n align-self: stretch;\n column-gap: 2px;\n}\n\n.g9-checkbox__slot {\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n/* MAUI G9CheckBox: the 20 px box is centred in a 48 × 48 slot (both axes). The slot used to put it at the start edge\n and 7 px low (row direction + padding), 28 px from its label on Android. */\n.g9-checkbox__slot--reserve {\n height: 48px;\n}\n\n.g9-checkbox__box {\n width: 20px;\n height: 20px;\n}\n\n/* One line centres on the slot (MAUI: label centred in the 48 px row); a wrapping label grows the row and the box\n stays level with its first line. */\n.g9-checkbox__text {\n flex: 1;\n align-self: center;\n font-size: 14px;\n}\n\n.g9-switch {\n display: flex;\n flex-direction: row;\n align-items: center;\n justify-content: center;\n}\n\n.g9-switch--row {\n justify-content: space-between;\n column-gap: 12px;\n padding: 12px 16px;\n align-self: stretch;\n}\n\n.g9-switch__text {\n display: flex;\n flex-direction: column;\n flex: 1;\n row-gap: 2px;\n}\n\n.g9-switch__title {\n font-size: 14px;\n font-weight: bold;\n color: var(--g9-text-primary);\n}\n\n.g9-switch__description {\n font-size: 12px;\n color: var(--g9-text-tertiary);\n}\n\n.g9-switch__track {\n position: relative;\n border-radius: 16px;\n transition: background-color 240ms ease-out;\n}\n\n.g9-switch__track--shake {\n animation: g9-switch-shake 310ms ease-in-out;\n}\n\n@keyframes g9-switch-shake {\n 0% {\n transform: translateX(0px);\n }\n 19% {\n transform: translateX(-4px);\n }\n 39% {\n transform: translateX(4px);\n }\n 58% {\n transform: translateX(-3px);\n }\n 77% {\n transform: translateX(3px);\n }\n 100% {\n transform: translateX(0px);\n }\n}\n\n.g9-switch__thumb {\n position: absolute;\n top: 4px;\n border-radius: 12px;\n transition:\n transform 240ms cubic-bezier(0.34, 1.56, 0.64, 1),\n background-color 240ms ease-out;\n}\n\n.g9-switch__mark {\n position: absolute;\n top: 9px;\n}\n\n/* MAUI draws the tick with 2.5 dp round strokes, 11 × 9 dp: a bold 15 dp glyph is that weight and size. */\n.g9-switch__tick {\n font-size: 15px;\n font-weight: bold;\n line-height: 15px;\n margin-top: -2px;\n color: rgba(255, 255, 255, 0.75);\n}\n\n.g9-switch__dot {\n width: 6px;\n height: 6px;\n margin-top: 4px;\n border-radius: 3px;\n background-color: rgba(0, 0, 0, 0.22);\n}\n\n.g9-disabled {\n opacity: 0.45;\n}\n\n.g9-switch-group {\n display: flex;\n flex-direction: column;\n}\n\n.g9-switch-group__status {\n font-size: 11px;\n margin: 6px 2px 0px 2px;\n}\n\n/* MAUI G9ChipGroup: a FlexLayout of Wrap and JustifyContent Start — the chips run from the reading start (the row is\n reversed in RTL, so flex-start is the right edge there), never centred. */\n.g9-chip-group--wrap {\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n justify-content: flex-start;\n}\n\n.g9-chip-group__line {\n display: flex;\n flex-direction: row;\n}\n\n.g9-chip {\n display: flex;\n flex-direction: row;\n align-items: center;\n column-gap: 6px;\n padding: 0px 14px;\n border-style: solid;\n border-width: 1.5px;\n transition:\n background-color 140ms ease-in-out,\n border-color 140ms ease-in-out;\n}\n\n.g9-chip--disabled {\n opacity: 0.45;\n}\n\n/* MAUI 1.4.9 Segmented: rows of equal cells (star columns); a short last row keeps the width with empty fillers. */\n.g9-chip-group--segmented {\n display: flex;\n flex-direction: column;\n}\n\n.g9-chip-group__segment-row {\n display: flex;\n flex-direction: row;\n}\n\n.g9-chip-group__segment-fill {\n flex: 1;\n}\n\n/* A segment: fills its column, centred text, a 1 px hairline (a chip's is 1.5). */\n.g9-chip--segment {\n flex: 1;\n justify-content: center;\n border-width: 1px;\n}\n\n.g9-chip__text {\n font-size: 13px;\n font-weight: bold;\n white-space: nowrap;\n}\n\n.g9-chip__check {\n width: 0px;\n opacity: 0;\n transform: scale(0.5);\n overflow: hidden;\n transition:\n width 120ms ease-in-out,\n opacity 120ms ease-in-out,\n transform 120ms ease-in-out;\n}\n\n.g9-chip__check--on {\n width: 16px;\n opacity: 1;\n transform: scale(1);\n}\n"],"sourceRoot":""}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@g9tm/lynxcontrols",
3
- "version": "1.4.5",
3
+ "version": "1.4.11",
4
4
  "description": "ReactLynx controls and overlay infrastructure: provider/host, sheets, popups, toasts, fields, buttons, pickers, tab view, tab bar, edge panel, swipe rows.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -137,7 +137,7 @@
137
137
  "build": "rslib build"
138
138
  },
139
139
  "dependencies": {
140
- "@g9tm/lynxcontrols-foundation": "1.4.5",
140
+ "@g9tm/lynxcontrols-foundation": "1.4.11",
141
141
  "@lynx-js/lynx-ui-common": "3.139.0",
142
142
  "@lynx-js/lynx-ui-deferred-component": "3.139.0",
143
143
  "@lynx-js/lynx-ui-draggable": "3.139.0",
@@ -152,6 +152,6 @@
152
152
  "@lynx-js/lynx-ui-view-pager": "3.139.0"
153
153
  },
154
154
  "peerDependencies": {
155
- "@lynx-js/react": ">=0.126.2 <0.127.0"
155
+ "@lynx-js/react": ">=0.129.1 <0.130.0"
156
156
  }
157
157
  }