@g9tm/lynxcontrols 1.4.0 → 1.4.3
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.
- package/README.md +7 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/base/control.d.ts +24 -0
- package/dist/base/control.d.ts.map +1 -1
- package/dist/base/control.jsx +14 -2
- package/dist/base/control.jsx.map +1 -1
- package/dist/base/index.d.ts +1 -1
- package/dist/base/index.d.ts.map +1 -1
- package/dist/base/index.jsx +1 -1
- package/dist/base/pressable.d.ts.map +1 -1
- package/dist/base/pressable.jsx +1 -1
- package/dist/base/pressable.jsx.map +1 -1
- package/dist/button/button.d.ts.map +1 -1
- package/dist/button/button.jsx +4 -3
- package/dist/button/button.jsx.map +1 -1
- package/dist/button/header-action-button.d.ts.map +1 -1
- package/dist/button/header-action-button.jsx +1 -1
- package/dist/button/header-action-button.jsx.map +1 -1
- package/dist/button/icon-button.d.ts.map +1 -1
- package/dist/button/icon-button.jsx +1 -1
- package/dist/button/icon-button.jsx.map +1 -1
- package/dist/button/nav-card.d.ts.map +1 -1
- package/dist/button/nav-card.jsx +6 -5
- package/dist/button/nav-card.jsx.map +1 -1
- package/dist/button/vertical-icon-text-button.d.ts.map +1 -1
- package/dist/button/vertical-icon-text-button.jsx +1 -1
- package/dist/button/vertical-icon-text-button.jsx.map +1 -1
- package/dist/display/culture-date-time-label.d.ts.map +1 -1
- package/dist/display/culture-date-time-label.jsx +3 -1
- package/dist/display/culture-date-time-label.jsx.map +1 -1
- package/dist/display/progress-bar.jsx +1 -1
- package/dist/display/progress-bar.jsx.map +1 -1
- package/dist/display/separator.jsx +2 -2
- package/dist/display/separator.jsx.map +1 -1
- package/dist/display/title-with-line.jsx +1 -1
- package/dist/display/title-with-line.jsx.map +1 -1
- package/dist/expander/expander.d.ts.map +1 -1
- package/dist/expander/expander.jsx +6 -4
- package/dist/expander/expander.jsx.map +1 -1
- package/dist/fields/fields.css +12 -4
- package/dist/fields/fields.css.map +1 -1
- package/dist/fields/index.d.ts +1 -0
- package/dist/fields/index.d.ts.map +1 -1
- package/dist/fields/index.jsx +1 -0
- package/dist/fields/notch.d.ts +10 -0
- package/dist/fields/notch.d.ts.map +1 -0
- package/dist/fields/notch.jsx +9 -0
- package/dist/fields/notch.jsx.map +1 -0
- package/dist/fields/outlined-field.d.ts +7 -1
- package/dist/fields/outlined-field.d.ts.map +1 -1
- package/dist/fields/outlined-field.jsx +8 -5
- package/dist/fields/outlined-field.jsx.map +1 -1
- package/dist/fields/pin-entry.d.ts +2 -0
- package/dist/fields/pin-entry.d.ts.map +1 -1
- package/dist/fields/pin-entry.jsx +2 -1
- package/dist/fields/pin-entry.jsx.map +1 -1
- package/dist/fields/text-entry.d.ts.map +1 -1
- package/dist/fields/text-entry.jsx +12 -2
- package/dist/fields/text-entry.jsx.map +1 -1
- package/dist/fields/use-text-input.d.ts.map +1 -1
- package/dist/fields/use-text-input.jsx +11 -1
- package/dist/fields/use-text-input.jsx.map +1 -1
- package/dist/host/hooks.d.ts +5 -0
- package/dist/host/hooks.d.ts.map +1 -1
- package/dist/host/hooks.jsx +4 -1
- package/dist/host/hooks.jsx.map +1 -1
- package/dist/host/index.d.ts +1 -1
- package/dist/host/index.d.ts.map +1 -1
- package/dist/host/index.jsx +1 -1
- package/dist/popup/frame.d.ts.map +1 -1
- package/dist/popup/frame.jsx +11 -3
- package/dist/popup/frame.jsx.map +1 -1
- package/dist/popup/index.d.ts +1 -1
- package/dist/popup/index.d.ts.map +1 -1
- package/dist/popup/popup.css +1 -1
- package/dist/popup/popup.css.map +1 -1
- package/dist/popup/service.d.ts.map +1 -1
- package/dist/popup/service.jsx +12 -4
- package/dist/popup/service.jsx.map +1 -1
- package/dist/popup/types.d.ts +11 -0
- package/dist/popup/types.d.ts.map +1 -1
- package/dist/popup/types.jsx.map +1 -1
- package/dist/selection/selection-sheet.d.ts.map +1 -1
- package/dist/selection/selection-sheet.jsx +7 -3
- package/dist/selection/selection-sheet.jsx.map +1 -1
- package/dist/selection/selection.css +1 -0
- package/dist/selection/selection.css.map +1 -1
- package/dist/sheet/frame.d.ts +2 -0
- package/dist/sheet/frame.d.ts.map +1 -1
- package/dist/sheet/frame.jsx +134 -69
- package/dist/sheet/frame.jsx.map +1 -1
- package/dist/sheet/gesture.d.ts +51 -0
- package/dist/sheet/gesture.d.ts.map +1 -0
- package/dist/sheet/gesture.jsx +107 -0
- package/dist/sheet/gesture.jsx.map +1 -0
- package/dist/sheet/handoff.d.ts +32 -0
- package/dist/sheet/handoff.d.ts.map +1 -0
- package/dist/sheet/handoff.jsx +33 -0
- package/dist/sheet/handoff.jsx.map +1 -0
- package/dist/sheet/header.d.ts +12 -1
- package/dist/sheet/header.d.ts.map +1 -1
- package/dist/sheet/header.jsx +42 -29
- package/dist/sheet/header.jsx.map +1 -1
- package/dist/sheet/index.d.ts +3 -2
- package/dist/sheet/index.d.ts.map +1 -1
- package/dist/sheet/index.jsx +3 -2
- package/dist/sheet/motion.d.ts +59 -0
- package/dist/sheet/motion.d.ts.map +1 -0
- package/dist/sheet/motion.jsx +59 -0
- package/dist/sheet/motion.jsx.map +1 -0
- package/dist/sheet/options.d.ts +34 -2
- package/dist/sheet/options.d.ts.map +1 -1
- package/dist/sheet/options.jsx +2 -1
- package/dist/sheet/options.jsx.map +1 -1
- package/dist/sheet/service.d.ts.map +1 -1
- package/dist/sheet/service.jsx +1 -1
- package/dist/sheet/service.jsx.map +1 -1
- package/dist/sheet/sheet.css +52 -1
- package/dist/sheet/sheet.css.map +1 -1
- package/dist/sheet/sizing.d.ts +27 -3
- package/dist/sheet/sizing.d.ts.map +1 -1
- package/dist/sheet/sizing.jsx +19 -4
- package/dist/sheet/sizing.jsx.map +1 -1
- package/dist/tab-bar/tab-bar.d.ts +5 -0
- package/dist/tab-bar/tab-bar.d.ts.map +1 -1
- package/dist/tab-bar/tab-bar.jsx +5 -2
- package/dist/tab-bar/tab-bar.jsx.map +1 -1
- package/dist/toast/service.d.ts.map +1 -1
- package/dist/toast/service.jsx +58 -21
- package/dist/toast/service.jsx.map +1 -1
- package/dist/toast/store.d.ts +2 -0
- package/dist/toast/store.d.ts.map +1 -1
- package/dist/toast/store.jsx +4 -2
- package/dist/toast/store.jsx.map +1 -1
- package/dist/toast/toast.css +20 -13
- package/dist/toast/toast.css.map +1 -1
- package/dist/toggle/checkbox.d.ts.map +1 -1
- package/dist/toggle/checkbox.jsx +1 -1
- package/dist/toggle/checkbox.jsx.map +1 -1
- package/dist/toggle/chip-group.d.ts.map +1 -1
- package/dist/toggle/chip-group.jsx +5 -5
- package/dist/toggle/chip-group.jsx.map +1 -1
- package/dist/toggle/switch.d.ts.map +1 -1
- package/dist/toggle/switch.jsx +2 -2
- package/dist/toggle/switch.jsx.map +1 -1
- package/dist/toggle/toggle.css +1 -2
- package/dist/toggle/toggle.css.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toggle/checkbox.jsx","sources":["../../src/toggle/checkbox.tsx"],"sourcesContent":["import './toggle.css';\nimport { formatColor, type G9PaletteValues, G9StringKey, withAlpha } from '@g9tm/lynxcontrols-foundation';\nimport { forwardRef, type ReactNode, useEffect, useImperativeHandle, useRef } from '@lynx-js/react';\nimport type { NodesRef } from '@lynx-js/types';\nimport { type G9ControlBaseProps, g9RowStyle, g9TextStart, useG9Control } from '../base/control';\nimport { useG9Press } from '../base/press';\nimport { type G9TimerHandle, startTimer, stopTimer } from '../base/timers';\nimport { useControllableState } from '../base/use-controllable-state';\nimport { useG9Strings, useG9Theme } from '../provider/hooks';\nimport { checkMarkPath, fillAmount, nextOnTap, targetMorph, targetProgress } from './checkbox-math';\n\n/** Box size, corner and stroke (MAUI `G9Metrics` check-box values, ADR-0028). */\nexport const g9CheckBoxMetrics = Object.freeze({\n box: 20,\n corner: 6,\n stroke: 2,\n touchTarget: 48,\n progressMs: 200,\n morphMs: 150,\n});\n\n/** Colours the box is drawn with. */\nexport interface G9CheckBoxColors {\n readonly outline: string;\n readonly fill: string;\n readonly mark: string;\n}\n\n/** The palette colours of a check box (outline, fill, mark; disabled variants). */\nexport function checkBoxColors(palette: G9PaletteValues, disabled: boolean): G9CheckBoxColors {\n return {\n outline: palette.Outline,\n fill: disabled ? palette.TextDisabled : palette.Primary,\n mark: disabled ? palette.Surface : palette.OnPrimary,\n };\n}\n\n/**\n * The SVG of the box at an animation state (MAUI `G9CheckBoxDrawable`): the outline fades with `1 − fill`\n * (× 0.55 disabled), the fill grows from 78 % to 100 % with its alpha, the mark (tick → dash by `morph`) is trimmed by\n * the golden phase functions. Never mirrored in RTL.\n */\nexport function checkBoxSvg(progress: number, morph: number, colors: G9CheckBoxColors, disabled: boolean): string {\n const m = g9CheckBoxMetrics;\n const fill = fillAmount(progress);\n const outlineAlpha = (1 - fill) * (disabled ? 0.55 : 1);\n const scale = 0.78 + 0.22 * fill;\n const side = m.box * scale;\n const offset = (m.box - side) / 2;\n const r = (n: number) => Math.round(n * 1000) / 1000;\n const parts = [\n `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${m.box}\" height=\"${m.box}\" viewBox=\"0 0 ${m.box} ${m.box}\">`,\n ];\n if (outlineAlpha > 0.001) {\n parts.push(\n `<rect x=\"1\" y=\"1\" width=\"${m.box - 2}\" height=\"${m.box - 2}\" rx=\"${m.corner - 1}\" fill=\"none\" stroke=\"${formatColor(withAlpha(colors.outline, outlineAlpha))}\" stroke-width=\"${m.stroke}\"/>`,\n );\n }\n if (fill > 0.001) {\n parts.push(\n `<rect x=\"${r(offset)}\" y=\"${r(offset)}\" width=\"${r(side)}\" height=\"${r(side)}\" rx=\"${r(m.corner * scale)}\" fill=\"${formatColor(withAlpha(colors.fill, fill))}\"/>`,\n );\n }\n const path = checkMarkPath(progress, morph, m.box);\n if (path) {\n parts.push(\n `<path d=\"${path}\" fill=\"none\" stroke=\"${formatColor(colors.mark)}\" stroke-width=\"${m.stroke}\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>`,\n );\n }\n parts.push('</svg>');\n return parts.join('');\n}\n\n/** Props of {@link G9CheckBox} (MAUI `G9CheckBox`). */\nexport interface G9CheckBoxProps extends G9ControlBaseProps {\n /** Controlled checked state (MAUI `IsChecked`). */\n readonly checked?: boolean;\n readonly defaultChecked?: boolean;\n /** Once per change of `checked` caused by the control (MAUI `CheckedChanged`); never for pushed values. */\n readonly onCheckedChange?: (checked: boolean) => void;\n /** Controlled third state (MAUI `IsIndeterminate`); a tap clears it. */\n readonly indeterminate?: boolean;\n readonly defaultIndeterminate?: boolean;\n readonly onIndeterminateChange?: (indeterminate: boolean) => void;\n /** Label at the end side; also the accessibility name. */\n readonly text?: string | null;\n /** After every user toggle, with the new state (MAUI `Command`). */\n readonly onPress?: (checked: boolean) => void;\n /** 48 px touch slot with the box at the top; false: a 20 px slot, box centred. Default true. */\n readonly reserveTouchTarget?: boolean;\n}\n\n/** Imperative handle of {@link G9CheckBox}. */\nexport interface G9CheckBoxHandle {\n /** Same as a tap (MAUI `Toggle`); ignored while disabled. */\n toggle(): void;\n}\n\n/**\n * Tri-state check box (MAUI `G9CheckBox`, ADR-0028): tap toggles, indeterminate → checked, never into\n * indeterminate. The box animates (200 ms fill/tick, 150 ms tick↔dash) by updating the SVG attribute directly\n * (`setNativeProps`), never by re-rendering per frame; the first render does not animate.\n */\nexport const G9CheckBox = forwardRef<G9CheckBoxHandle, G9CheckBoxProps>(function G9CheckBox(props, ref): ReactNode {\n const control = useG9Control(props, 'g9-checkbox');\n const palette = useG9Theme().palette;\n const strings = useG9Strings();\n const [checked, setChecked] = useControllableState<boolean>({\n value: props.checked,\n defaultValue: props.defaultChecked ?? false,\n onChange: props.onCheckedChange,\n name: 'G9CheckBox.checked',\n });\n const [indeterminate, setIndeterminate] = useControllableState<boolean>({\n value: props.indeterminate,\n defaultValue: props.defaultIndeterminate ?? false,\n onChange: props.onIndeterminateChange,\n name: 'G9CheckBox.indeterminate',\n });\n const colors = checkBoxColors(palette, control.disabled);\n const progressTarget = targetProgress(checked, indeterminate);\n const morphTarget = targetMorph(indeterminate);\n\n // Animation state lives outside React: the drawn progress/morph and the frame timer.\n const svgRef = useRef<NodesRef | null>(null);\n const drawn = useRef({ progress: progressTarget, morph: morphTarget });\n const frame = useRef<G9TimerHandle | null>(null);\n const latest = useRef({ colors, disabled: control.disabled });\n latest.current = { colors, disabled: control.disabled };\n useEffect(() => {\n const from = { ...drawn.current };\n if (from.progress === progressTarget && from.morph === morphTarget) return;\n // Unchecked → indeterminate draws the dash directly; a fade-out keeps the current mark shape.\n const morphFrom = from.progress < 0.01 ? morphTarget : from.morph;\n const morphTo = progressTarget === 0 ? morphFrom : morphTarget;\n const started = Date.now();\n const step = () => {\n const t = Date.now() - started;\n const p = Math.min(1, t / g9CheckBoxMetrics.progressMs);\n const q = Math.min(1, t / g9CheckBoxMetrics.morphMs);\n const easeOut = 1 - (1 - p) ** 3;\n const easeInOut = q < 0.5 ? 4 * q * q * q : 1 - (-2 * q + 2) ** 3 / 2;\n drawn.current = {\n progress: from.progress + (progressTarget - from.progress) * easeOut,\n morph: morphFrom + (morphTo - morphFrom) * easeInOut,\n };\n try {\n svgRef.current\n ?.setNativeProps({\n content: checkBoxSvg(\n drawn.current.progress,\n drawn.current.morph,\n latest.current.colors,\n latest.current.disabled,\n ),\n })\n .exec();\n } catch {\n // Unmounted between frames.\n }\n frame.current = p < 1 || q < 1 ? startTimer(step, 16) : null;\n };\n if (frame.current !== null) stopTimer(frame.current);\n step();\n return () => {\n if (frame.current !== null) stopTimer(frame.current);\n frame.current = null;\n };\n }, [progressTarget, morphTarget]);\n\n const toggle = () => {\n if (control.disabled) return;\n const next = nextOnTap(checked, indeterminate);\n setIndeterminate(next.indeterminate);\n setChecked(next.checked);\n props.onPress?.(next.checked);\n };\n useImperativeHandle(ref, () => ({ toggle }));\n const press = useG9Press(toggle, { blocked: control.disabled, source: 'G9CheckBox', guardMs: 0 });\n\n const reserve = props.reserveTouchTarget !== false;\n const text = props.text && props.text.trim() !== '' ? props.text : null;\n const state = indeterminate\n ? strings.get(G9StringKey.PartiallyChecked)\n : checked\n ? strings.get(G9StringKey.Checked)\n : strings.get(G9StringKey.NotChecked);\n return (\n <view\n className={`${control.className}${text ? ' g9-checkbox--labelled' : ''}`}\n style={g9RowStyle(control.direction)}\n accessibility-element={true}\n accessibility-traits=\"button\"\n accessibility-value={state}\n {...((props.accessibilityLabel ?? text) ? { 'accessibility-label': props.accessibilityLabel ?? text ?? '' } : {})}\n bindtap={press}\n >\n <view\n className={`g9-checkbox__slot${reserve ? ' g9-checkbox__slot--reserve' : ''}`}\n style={{ width: `${reserve ? g9CheckBoxMetrics.touchTarget : g9CheckBoxMetrics.box}px` }}\n >\n <svg\n ref={svgRef}\n className=\"g9-checkbox__box\"\n content={checkBoxSvg(drawn.current.progress, drawn.current.morph, colors, control.disabled)}\n />\n </view>\n {text ? (\n <text\n className=\"g9-checkbox__text\"\n style={{\n ...g9TextStart(control.direction),\n color: control.disabled ? 'var(--g9-text-disabled)' : 'var(--g9-text-primary)',\n paddingTop: reserve ? '12px' : '0px',\n paddingBottom: reserve ? '12px' : '0px',\n }}\n >\n {text}\n </text>\n ) : null}\n </view>\n );\n});\n"],"names":["g9CheckBoxMetrics","Object","checkBoxColors","palette","disabled","checkBoxSvg","progress","morph","colors","m","fill","fillAmount","outlineAlpha","scale","side","offset","r","n","Math","parts","formatColor","withAlpha","path","checkMarkPath","G9CheckBox","forwardRef","props","ref","_props_defaultChecked","_props_defaultIndeterminate","_props_accessibilityLabel","_ref","control","useG9Control","useG9Theme","strings","useG9Strings","checked","setChecked","useControllableState","indeterminate","setIndeterminate","progressTarget","targetProgress","morphTarget","targetMorph","svgRef","useRef","drawn","frame","latest","useEffect","from","morphFrom","morphTo","started","Date","step","t","p","q","easeOut","easeInOut","_svgRef_current","startTimer","stopTimer","toggle","next","nextOnTap","useImperativeHandle","press","useG9Press","reserve","text1","state","G9StringKey","view","g9RowStyle","svg","text","g9TextStart"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"toggle/checkbox.jsx","sources":["../../src/toggle/checkbox.tsx"],"sourcesContent":["import './toggle.css';\nimport { formatColor, type G9PaletteValues, G9StringKey, withAlpha } from '@g9tm/lynxcontrols-foundation';\nimport { forwardRef, type ReactNode, useEffect, useImperativeHandle, useRef } from '@lynx-js/react';\nimport type { NodesRef } from '@lynx-js/types';\nimport { type G9ControlBaseProps, g9RowStyle, g9TextStart, useG9Control } from '../base/control';\nimport { useG9Press } from '../base/press';\nimport { type G9TimerHandle, startTimer, stopTimer } from '../base/timers';\nimport { useControllableState } from '../base/use-controllable-state';\nimport { useG9Strings, useG9Theme } from '../provider/hooks';\nimport { checkMarkPath, fillAmount, nextOnTap, targetMorph, targetProgress } from './checkbox-math';\n\n/** Box size, corner and stroke (MAUI `G9Metrics` check-box values, ADR-0028). */\nexport const g9CheckBoxMetrics = Object.freeze({\n box: 20,\n corner: 6,\n stroke: 2,\n touchTarget: 48,\n progressMs: 200,\n morphMs: 150,\n});\n\n/** Colours the box is drawn with. */\nexport interface G9CheckBoxColors {\n readonly outline: string;\n readonly fill: string;\n readonly mark: string;\n}\n\n/** The palette colours of a check box (outline, fill, mark; disabled variants). */\nexport function checkBoxColors(palette: G9PaletteValues, disabled: boolean): G9CheckBoxColors {\n return {\n outline: palette.Outline,\n fill: disabled ? palette.TextDisabled : palette.Primary,\n mark: disabled ? palette.Surface : palette.OnPrimary,\n };\n}\n\n/**\n * The SVG of the box at an animation state (MAUI `G9CheckBoxDrawable`): the outline fades with `1 − fill`\n * (× 0.55 disabled), the fill grows from 78 % to 100 % with its alpha, the mark (tick → dash by `morph`) is trimmed by\n * the golden phase functions. Never mirrored in RTL.\n */\nexport function checkBoxSvg(progress: number, morph: number, colors: G9CheckBoxColors, disabled: boolean): string {\n const m = g9CheckBoxMetrics;\n const fill = fillAmount(progress);\n const outlineAlpha = (1 - fill) * (disabled ? 0.55 : 1);\n const scale = 0.78 + 0.22 * fill;\n const side = m.box * scale;\n const offset = (m.box - side) / 2;\n const r = (n: number) => Math.round(n * 1000) / 1000;\n const parts = [\n `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${m.box}\" height=\"${m.box}\" viewBox=\"0 0 ${m.box} ${m.box}\">`,\n ];\n if (outlineAlpha > 0.001) {\n parts.push(\n `<rect x=\"1\" y=\"1\" width=\"${m.box - 2}\" height=\"${m.box - 2}\" rx=\"${m.corner - 1}\" fill=\"none\" stroke=\"${formatColor(withAlpha(colors.outline, outlineAlpha))}\" stroke-width=\"${m.stroke}\"/>`,\n );\n }\n if (fill > 0.001) {\n parts.push(\n `<rect x=\"${r(offset)}\" y=\"${r(offset)}\" width=\"${r(side)}\" height=\"${r(side)}\" rx=\"${r(m.corner * scale)}\" fill=\"${formatColor(withAlpha(colors.fill, fill))}\"/>`,\n );\n }\n const path = checkMarkPath(progress, morph, m.box);\n if (path) {\n parts.push(\n `<path d=\"${path}\" fill=\"none\" stroke=\"${formatColor(colors.mark)}\" stroke-width=\"${m.stroke}\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>`,\n );\n }\n parts.push('</svg>');\n return parts.join('');\n}\n\n/** Props of {@link G9CheckBox} (MAUI `G9CheckBox`). */\nexport interface G9CheckBoxProps extends G9ControlBaseProps {\n /** Controlled checked state (MAUI `IsChecked`). */\n readonly checked?: boolean;\n readonly defaultChecked?: boolean;\n /** Once per change of `checked` caused by the control (MAUI `CheckedChanged`); never for pushed values. */\n readonly onCheckedChange?: (checked: boolean) => void;\n /** Controlled third state (MAUI `IsIndeterminate`); a tap clears it. */\n readonly indeterminate?: boolean;\n readonly defaultIndeterminate?: boolean;\n readonly onIndeterminateChange?: (indeterminate: boolean) => void;\n /** Label at the end side; also the accessibility name. */\n readonly text?: string | null;\n /** After every user toggle, with the new state (MAUI `Command`). */\n readonly onPress?: (checked: boolean) => void;\n /** 48 px touch slot with the box at the top; false: a 20 px slot, box centred. Default true. */\n readonly reserveTouchTarget?: boolean;\n}\n\n/** Imperative handle of {@link G9CheckBox}. */\nexport interface G9CheckBoxHandle {\n /** Same as a tap (MAUI `Toggle`); ignored while disabled. */\n toggle(): void;\n}\n\n/**\n * Tri-state check box (MAUI `G9CheckBox`, ADR-0028): tap toggles, indeterminate → checked, never into\n * indeterminate. The box animates (200 ms fill/tick, 150 ms tick↔dash) by updating the SVG attribute directly\n * (`setNativeProps`), never by re-rendering per frame; the first render does not animate.\n */\nexport const G9CheckBox = forwardRef<G9CheckBoxHandle, G9CheckBoxProps>(function G9CheckBox(props, ref): ReactNode {\n const control = useG9Control(props, 'g9-checkbox');\n const palette = useG9Theme().palette;\n const strings = useG9Strings();\n const [checked, setChecked] = useControllableState<boolean>({\n value: props.checked,\n defaultValue: props.defaultChecked ?? false,\n onChange: props.onCheckedChange,\n name: 'G9CheckBox.checked',\n });\n const [indeterminate, setIndeterminate] = useControllableState<boolean>({\n value: props.indeterminate,\n defaultValue: props.defaultIndeterminate ?? false,\n onChange: props.onIndeterminateChange,\n name: 'G9CheckBox.indeterminate',\n });\n const colors = checkBoxColors(palette, control.disabled);\n const progressTarget = targetProgress(checked, indeterminate);\n const morphTarget = targetMorph(indeterminate);\n\n // Animation state lives outside React: the drawn progress/morph and the frame timer.\n const svgRef = useRef<NodesRef | null>(null);\n const drawn = useRef({ progress: progressTarget, morph: morphTarget });\n const frame = useRef<G9TimerHandle | null>(null);\n const latest = useRef({ colors, disabled: control.disabled });\n latest.current = { colors, disabled: control.disabled };\n useEffect(() => {\n const from = { ...drawn.current };\n if (from.progress === progressTarget && from.morph === morphTarget) return;\n // Unchecked → indeterminate draws the dash directly; a fade-out keeps the current mark shape.\n const morphFrom = from.progress < 0.01 ? morphTarget : from.morph;\n const morphTo = progressTarget === 0 ? morphFrom : morphTarget;\n const started = Date.now();\n const step = () => {\n const t = Date.now() - started;\n const p = Math.min(1, t / g9CheckBoxMetrics.progressMs);\n const q = Math.min(1, t / g9CheckBoxMetrics.morphMs);\n const easeOut = 1 - (1 - p) ** 3;\n const easeInOut = q < 0.5 ? 4 * q * q * q : 1 - (-2 * q + 2) ** 3 / 2;\n drawn.current = {\n progress: from.progress + (progressTarget - from.progress) * easeOut,\n morph: morphFrom + (morphTo - morphFrom) * easeInOut,\n };\n try {\n svgRef.current\n ?.setNativeProps({\n content: checkBoxSvg(\n drawn.current.progress,\n drawn.current.morph,\n latest.current.colors,\n latest.current.disabled,\n ),\n })\n .exec();\n } catch {\n // Unmounted between frames.\n }\n frame.current = p < 1 || q < 1 ? startTimer(step, 16) : null;\n };\n if (frame.current !== null) stopTimer(frame.current);\n step();\n return () => {\n if (frame.current !== null) stopTimer(frame.current);\n frame.current = null;\n };\n }, [progressTarget, morphTarget]);\n\n const toggle = () => {\n if (control.disabled) return;\n const next = nextOnTap(checked, indeterminate);\n setIndeterminate(next.indeterminate);\n setChecked(next.checked);\n props.onPress?.(next.checked);\n };\n useImperativeHandle(ref, () => ({ toggle }));\n const press = useG9Press(toggle, { blocked: control.disabled, source: 'G9CheckBox', guardMs: 0 });\n\n const reserve = props.reserveTouchTarget !== false;\n const text = props.text && props.text.trim() !== '' ? props.text : null;\n const state = indeterminate\n ? strings.get(G9StringKey.PartiallyChecked)\n : checked\n ? strings.get(G9StringKey.Checked)\n : strings.get(G9StringKey.NotChecked);\n return (\n <view\n className={`${control.className}${text ? ' g9-checkbox--labelled' : ''}`}\n {...control.idProps}\n style={g9RowStyle(control.direction)}\n accessibility-element={true}\n accessibility-traits=\"button\"\n accessibility-value={state}\n {...((props.accessibilityLabel ?? text) ? { 'accessibility-label': props.accessibilityLabel ?? text ?? '' } : {})}\n bindtap={press}\n >\n <view\n className={`g9-checkbox__slot${reserve ? ' g9-checkbox__slot--reserve' : ''}`}\n style={{ width: `${reserve ? g9CheckBoxMetrics.touchTarget : g9CheckBoxMetrics.box}px` }}\n >\n <svg\n ref={svgRef}\n className=\"g9-checkbox__box\"\n content={checkBoxSvg(drawn.current.progress, drawn.current.morph, colors, control.disabled)}\n />\n </view>\n {text ? (\n <text\n className=\"g9-checkbox__text\"\n style={{\n ...g9TextStart(control.direction),\n color: control.disabled ? 'var(--g9-text-disabled)' : 'var(--g9-text-primary)',\n paddingTop: reserve ? '12px' : '0px',\n paddingBottom: reserve ? '12px' : '0px',\n }}\n >\n {text}\n </text>\n ) : null}\n </view>\n );\n});\n"],"names":["g9CheckBoxMetrics","Object","checkBoxColors","palette","disabled","checkBoxSvg","progress","morph","colors","m","fill","fillAmount","outlineAlpha","scale","side","offset","r","n","Math","parts","formatColor","withAlpha","path","checkMarkPath","G9CheckBox","forwardRef","props","ref","_props_defaultChecked","_props_defaultIndeterminate","_props_accessibilityLabel","_ref","control","useG9Control","useG9Theme","strings","useG9Strings","checked","setChecked","useControllableState","indeterminate","setIndeterminate","progressTarget","targetProgress","morphTarget","targetMorph","svgRef","useRef","drawn","frame","latest","useEffect","from","morphFrom","morphTo","started","Date","step","t","p","q","easeOut","easeInOut","_svgRef_current","startTimer","stopTimer","toggle","next","nextOnTap","useImperativeHandle","press","useG9Press","reserve","text1","state","G9StringKey","view","g9RowStyle","svg","text","g9TextStart"],"mappings":"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"}
|
|
@@ -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,
|
|
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,6 +1,6 @@
|
|
|
1
1
|
import "./toggle.css";
|
|
2
2
|
import { G9Metrics, G9StringKey, buildSolidOrGradient, fillToCss, formatColor, tryParseColor } from "@g9tm/lynxcontrols-foundation";
|
|
3
|
-
import { g9RowStyle, useG9Control } from "../base/control.jsx";
|
|
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";
|
|
6
6
|
import { useControllableState } from "../base/use-controllable-state.jsx";
|
|
@@ -60,14 +60,14 @@ function G9ChipGroup(props) {
|
|
|
60
60
|
const parsed = tryParseColor(bg);
|
|
61
61
|
const background = selected ? parsed ? fillToCss(buildSolidOrGradient(parsed, true)) : bg : palette.Surface;
|
|
62
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}/>;
|
|
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))}/>;
|
|
64
64
|
});
|
|
65
65
|
const scroll = 'singleLineScroll' === props.layoutMode;
|
|
66
|
-
return scroll ? <scroll-view className={`${control.className} g9-chip-group--scroll`} scroll-orientation="horizontal">
|
|
66
|
+
return scroll ? <scroll-view className={`${control.className} g9-chip-group--scroll`} {...control.idProps} scroll-orientation="horizontal">
|
|
67
67
|
<view className="g9-chip-group__line" style={g9RowStyle(control.direction)}>
|
|
68
68
|
{chips}
|
|
69
69
|
</view>
|
|
70
|
-
</scroll-view> : <view className={`${control.className} g9-chip-group--wrap`} style={g9RowStyle(control.direction)}>
|
|
70
|
+
</scroll-view> : <view className={`${control.className} g9-chip-group--wrap`} {...control.idProps} style={g9RowStyle(control.direction)}>
|
|
71
71
|
{chips}
|
|
72
72
|
</view>;
|
|
73
73
|
}
|
|
@@ -79,7 +79,7 @@ function Chip(props) {
|
|
|
79
79
|
source: 'G9ChipGroup',
|
|
80
80
|
guardMs: 0
|
|
81
81
|
});
|
|
82
|
-
return <view className={`g9-chip${props.selected ? ' g9-chip--selected' : ''}${false === item.isEnabled ? ' g9-chip--disabled' : ''}`} style={{
|
|
82
|
+
return <view className={`g9-chip${props.selected ? ' g9-chip--selected' : ''}${false === item.isEnabled ? ' g9-chip--disabled' : ''}`} {...g9IdProps(props.id)} style={{
|
|
83
83
|
...g9RowStyle(props.direction),
|
|
84
84
|
height: `${props.height}px`,
|
|
85
85
|
minHeight: `${props.height}px`,
|
|
@@ -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, 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 } 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 />\n );\n });\n const scroll = props.layoutMode === 'singleLineScroll';\n return scroll ? (\n <scroll-view className={`${control.className} g9-chip-group--scroll`} scroll-orientation=\"horizontal\">\n <view className=\"g9-chip-group__line\" style={g9RowStyle(control.direction)}>\n {chips}\n </view>\n </scroll-view>\n ) : (\n <view className={`${control.className} g9-chip-group--wrap`} style={g9RowStyle(control.direction)}>\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}\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 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 <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 <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","scroll","scroll-view","view","g9RowStyle","disabled","press","useG9Press","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 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 } 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 <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 <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","G9IconSlot","text"],"mappings":"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"}
|
|
@@ -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,
|
|
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"}
|
package/dist/toggle/switch.jsx
CHANGED
|
@@ -63,7 +63,7 @@ function G9SwitchGroup(props) {
|
|
|
63
63
|
]);
|
|
64
64
|
const warn = minOneActive && active <= 1;
|
|
65
65
|
return <SwitchGroupContext.Provider value={value.current}>
|
|
66
|
-
<view className={control.className}>
|
|
66
|
+
<view className={control.className} {...control.idProps}>
|
|
67
67
|
{props.children}
|
|
68
68
|
{props.showLiveStatus ? <text className="g9-switch-group__status" style={{
|
|
69
69
|
color: warn ? 'var(--g9-warning)' : 'var(--g9-text-tertiary)'
|
|
@@ -154,7 +154,7 @@ const switch_G9Switch = forwardRef(function(props, ref) {
|
|
|
154
154
|
const form = true === props.isInFormRow;
|
|
155
155
|
const title = props.title && '' !== props.title.trim() ? props.title : null;
|
|
156
156
|
const description = props.description && '' !== props.description.trim() ? props.description : null;
|
|
157
|
-
return <view className={`${control.className}${form ? ' g9-switch--row' : ''}`} style={g9RowStyle(control.direction)} accessibility-element={true} accessibility-traits="button" {...checked ? {
|
|
157
|
+
return <view className={`${control.className}${form ? ' g9-switch--row' : ''}`} {...control.idProps} style={g9RowStyle(control.direction)} accessibility-element={true} accessibility-traits="button" {...checked ? {
|
|
158
158
|
'accessibility-value': strings.get(G9StringKey.Selected)
|
|
159
159
|
} : {}} {...(null != (_props_accessibilityLabel = props.accessibilityLabel) ? _props_accessibilityLabel : title) ? {
|
|
160
160
|
'accessibility-label': null != (_ref = null != (_props_accessibilityLabel1 = props.accessibilityLabel) ? _props_accessibilityLabel1 : title) ? _ref : ''
|
|
@@ -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}>\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 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 <view\n className=\"g9-switch__mark\"\n style={{ [rtl ? 'right' : 'left']: checked ? `${width - 15 - 6}px` : '12px' }}\n >\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 { 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 <view\n className=\"g9-switch__mark\"\n style={{ [rtl ? 'right' : 'left']: checked ? `${width - 15 - 6}px` : '12px' }}\n >\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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"}
|
package/dist/toggle/toggle.css
CHANGED
|
@@ -17,9 +17,7 @@
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
.g9-checkbox__slot--reserve {
|
|
20
|
-
justify-content: flex-start;
|
|
21
20
|
height: 48px;
|
|
22
|
-
padding-top: 14px;
|
|
23
21
|
}
|
|
24
22
|
|
|
25
23
|
.g9-checkbox__box {
|
|
@@ -29,6 +27,7 @@
|
|
|
29
27
|
|
|
30
28
|
.g9-checkbox__text {
|
|
31
29
|
flex: 1;
|
|
30
|
+
align-self: center;
|
|
32
31
|
font-size: 14px;
|
|
33
32
|
}
|
|
34
33
|
|
|
@@ -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;;
|
|
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;;AAIA;EADE,gBAAgB;EAChB,eAAe;AACjB;;AAIA;EADE,2BAA2B;EAC3B,kBAAkB;EAClB,UAAU;EACV,WAAW;EACX,eAAe;AACjB;;AAIA;EADE,YAAY;AACd;;AAIA;EADE,sBAAsB;EACtB,aAAa;AACf;;AAIA;EADE,iBAAiB;EACjB,eAAe;AACjB;;AAIA;EADE,eAAe;EACf,uBAAuB;EACvB,aAAa;AACf;;AAKA;EAFE,mBAAmB;EACnB,aAAa;AACf;;AAKA;EAFE,mBAAmB;EACnB,mBAAmB;EACnB,mBAAmB;EACnB,mBAAmB;EACnB,eAAe;EACf,eAAe;EACf,4EAA4E;EAC5E,aAAa;AACf;;AAOA;EAJE,YAAY;AACd;;AAOA;EAJE,mBAAmB;EACnB,eAAe;EACf,iBAAiB;AACnB;;AAOA;EAJE,UAAU;EACV,QAAQ;EACR,wFAAwF;EACxF,gBAAgB;EAChB,oBAAoB;AACtB;;AAUA;EAPE,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.g9-switch__tick {\n font-size: 12px;\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.g9-chip-group--wrap {\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n justify-content: center;\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":""}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@g9tm/lynxcontrols",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.3",
|
|
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.
|
|
140
|
+
"@g9tm/lynxcontrols-foundation": "1.4.3",
|
|
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",
|