@symbiote-native/slider 0.1.0

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 (109) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +90 -0
  3. package/build/angular/index.d.ts +3 -0
  4. package/build/angular/index.js +2 -0
  5. package/build/angular/slider/index.android.d.ts +9 -0
  6. package/build/angular/slider/index.android.js +71 -0
  7. package/build/angular/slider/index.d.ts +2 -0
  8. package/build/angular/slider/index.ios.d.ts +11 -0
  9. package/build/angular/slider/index.ios.js +72 -0
  10. package/build/angular/slider/index.js +3 -0
  11. package/build/angular/slider/shared.d.ts +84 -0
  12. package/build/angular/slider/shared.js +648 -0
  13. package/build/core/constants.d.ts +20 -0
  14. package/build/core/constants.js +40 -0
  15. package/build/core/index.d.ts +7 -0
  16. package/build/core/index.js +11 -0
  17. package/build/core/render-slider.d.ts +11 -0
  18. package/build/core/render-slider.js +66 -0
  19. package/build/core/render-steps-indicator.d.ts +28 -0
  20. package/build/core/render-steps-indicator.js +91 -0
  21. package/build/core/slider-props.d.ts +52 -0
  22. package/build/core/slider-props.js +6 -0
  23. package/build/core/slider-state.d.ts +15 -0
  24. package/build/core/slider-state.js +73 -0
  25. package/build/react/index.d.ts +4 -0
  26. package/build/react/index.js +7 -0
  27. package/build/react/slider/index.android.d.ts +1 -0
  28. package/build/react/slider/index.android.js +10 -0
  29. package/build/react/slider/index.d.ts +1 -0
  30. package/build/react/slider/index.ios.d.ts +1 -0
  31. package/build/react/slider/index.ios.js +11 -0
  32. package/build/react/slider/index.js +3 -0
  33. package/build/react/slider/shared.d.ts +10 -0
  34. package/build/react/slider/shared.js +175 -0
  35. package/build/register.d.ts +1 -0
  36. package/build/register.js +48 -0
  37. package/build/vue/index.d.ts +3 -0
  38. package/build/vue/index.js +8 -0
  39. package/build/vue/slider/index.android.d.ts +18 -0
  40. package/build/vue/slider/index.android.js +10 -0
  41. package/build/vue/slider/index.d.ts +2 -0
  42. package/build/vue/slider/index.ios.d.ts +18 -0
  43. package/build/vue/slider/index.ios.js +11 -0
  44. package/build/vue/slider/index.js +3 -0
  45. package/build/vue/slider/shared.d.ts +26 -0
  46. package/build/vue/slider/shared.js +254 -0
  47. package/build-ngc/angular/index.d.ts +3 -0
  48. package/build-ngc/angular/index.js +3 -0
  49. package/build-ngc/angular/index.js.map +1 -0
  50. package/build-ngc/angular/slider/index.android.d.ts +12 -0
  51. package/build-ngc/angular/slider/index.android.js +28 -0
  52. package/build-ngc/angular/slider/index.android.js.map +1 -0
  53. package/build-ngc/angular/slider/index.d.ts +2 -0
  54. package/build-ngc/angular/slider/index.ios.d.ts +14 -0
  55. package/build-ngc/angular/slider/index.ios.js +29 -0
  56. package/build-ngc/angular/slider/index.ios.js.map +1 -0
  57. package/build-ngc/angular/slider/index.js +4 -0
  58. package/build-ngc/angular/slider/index.js.map +1 -0
  59. package/build-ngc/angular/slider/shared.d.ts +87 -0
  60. package/build-ngc/angular/slider/shared.js +427 -0
  61. package/build-ngc/angular/slider/shared.js.map +1 -0
  62. package/build-ngc/core/constants.d.ts +20 -0
  63. package/build-ngc/core/constants.js +41 -0
  64. package/build-ngc/core/constants.js.map +1 -0
  65. package/build-ngc/core/index.d.ts +7 -0
  66. package/build-ngc/core/index.js +12 -0
  67. package/build-ngc/core/index.js.map +1 -0
  68. package/build-ngc/core/render-slider.d.ts +11 -0
  69. package/build-ngc/core/render-slider.js +67 -0
  70. package/build-ngc/core/render-slider.js.map +1 -0
  71. package/build-ngc/core/render-steps-indicator.d.ts +28 -0
  72. package/build-ngc/core/render-steps-indicator.js +92 -0
  73. package/build-ngc/core/render-steps-indicator.js.map +1 -0
  74. package/build-ngc/core/slider-props.d.ts +52 -0
  75. package/build-ngc/core/slider-props.js +7 -0
  76. package/build-ngc/core/slider-props.js.map +1 -0
  77. package/build-ngc/core/slider-state.d.ts +15 -0
  78. package/build-ngc/core/slider-state.js +74 -0
  79. package/build-ngc/core/slider-state.js.map +1 -0
  80. package/build-ngc/register.d.ts +1 -0
  81. package/build-ngc/register.js +49 -0
  82. package/build-ngc/register.js.map +1 -0
  83. package/package.json +116 -0
  84. package/src/angular/index.ts +4 -0
  85. package/src/angular/slider/index.android.ts +25 -0
  86. package/src/angular/slider/index.ios.ts +26 -0
  87. package/src/angular/slider/index.ts +5 -0
  88. package/src/angular/slider/shared.ts +364 -0
  89. package/src/angular/slider/slider.test.ts +260 -0
  90. package/src/core/constants.ts +47 -0
  91. package/src/core/index.ts +46 -0
  92. package/src/core/render-slider.ts +89 -0
  93. package/src/core/render-steps-indicator.ts +154 -0
  94. package/src/core/slider-props.ts +83 -0
  95. package/src/core/slider-state.ts +112 -0
  96. package/src/react/index.ts +11 -0
  97. package/src/react/slider/index.android.ts +13 -0
  98. package/src/react/slider/index.ios.ts +14 -0
  99. package/src/react/slider/index.ts +4 -0
  100. package/src/react/slider/shared.ts +332 -0
  101. package/src/react/slider/slider.test.tsx +203 -0
  102. package/src/register.test.tsx +89 -0
  103. package/src/register.ts +59 -0
  104. package/src/vue/index.ts +11 -0
  105. package/src/vue/slider/index.android.ts +13 -0
  106. package/src/vue/slider/index.ios.ts +14 -0
  107. package/src/vue/slider/index.ts +5 -0
  108. package/src/vue/slider/shared.ts +383 -0
  109. package/src/vue/slider/slider.test.ts +184 -0
@@ -0,0 +1,203 @@
1
+ // Co-located React-driven test (ADR 0025) for the @symbiote-native/slider React wrapper. Mirrors the Vue
2
+ // wrapper test against the SAME injected codegen-shaped ViewConfig, proving the shared core drives
3
+ // React identically: the native RNCSlider leaf paints inside the centering View, value/disabled/
4
+ // limits fold faithfully to the library, tints process, and the native value/sliding events map
5
+ // onto onValueChange / onSlidingStart / onSlidingComplete. Slider is imported from '.' (NOT the
6
+ // package barrel) so the third-party native-spec side-effect (../register) never loads headless.
7
+
8
+ import { createElement } from 'react';
9
+ import { afterEach, beforeEach, describe, expect, it } from 'vitest';
10
+ import { mount, unmount, setNativeViewConfigSource } from '@symbiote-native/react';
11
+ import { installFabric, type IFakeNode } from '@symbiote-native/test-utils';
12
+ import { Slider } from '.';
13
+
14
+ const ROOT_TAG = 312;
15
+ const SLIDER_VIEW = 'RNCSlider';
16
+
17
+ const fakeColor = (value: unknown): string => `processed(${value})`;
18
+
19
+ const RNC_SLIDER_VIEW_CONFIG = {
20
+ bubblingEventTypes: {
21
+ topChange: { phasedRegistrationNames: { bubbled: 'onChange', captured: 'onChangeCapture' } },
22
+ topRNCSliderValueChange: {
23
+ phasedRegistrationNames: {
24
+ bubbled: 'onRNCSliderValueChange',
25
+ captured: 'onRNCSliderValueChangeCapture',
26
+ },
27
+ },
28
+ },
29
+ directEventTypes: {
30
+ topRNCSliderSlidingStart: { registrationName: 'onRNCSliderSlidingStart' },
31
+ topRNCSliderSlidingComplete: { registrationName: 'onRNCSliderSlidingComplete' },
32
+ topRNCSliderAccessibilityAction: { registrationName: 'onRNCSliderAccessibilityAction' },
33
+ },
34
+ validAttributes: {
35
+ value: true,
36
+ minimumValue: true,
37
+ maximumValue: true,
38
+ step: true,
39
+ lowerLimit: true,
40
+ upperLimit: true,
41
+ inverted: true,
42
+ disabled: true,
43
+ minimumTrackTintColor: { process: fakeColor },
44
+ maximumTrackTintColor: { process: fakeColor },
45
+ thumbTintColor: { process: fakeColor },
46
+ },
47
+ };
48
+
49
+ const fabric = installFabric();
50
+ setNativeViewConfigSource(name => (name === SLIDER_VIEW ? RNC_SLIDER_VIEW_CONFIG : undefined));
51
+
52
+ beforeEach(() => fabric.reset());
53
+ afterEach(() => unmount(ROOT_TAG));
54
+
55
+ const tick = (): Promise<void> => new Promise(resolve => setTimeout(resolve, 0));
56
+
57
+ function findInTree(
58
+ predicate: (node: IFakeNode) => boolean,
59
+ nodes = fabric.committed,
60
+ ): IFakeNode | undefined {
61
+ for (const node of nodes) {
62
+ if (predicate(node)) return node;
63
+ const child = findInTree(predicate, node.children);
64
+ if (child) return child;
65
+ }
66
+ return undefined;
67
+ }
68
+
69
+ function sliderNode(): IFakeNode {
70
+ const node = fabric.find(n => n.viewName === SLIDER_VIEW);
71
+ if (!node) throw new Error(`no ${SLIDER_VIEW} was created`);
72
+ return node;
73
+ }
74
+
75
+ function currentSliderNode(): IFakeNode {
76
+ const node = findInTree(n => n.viewName === SLIDER_VIEW);
77
+ if (!node) throw new Error(`no committed ${SLIDER_VIEW} exists`);
78
+ return node;
79
+ }
80
+
81
+ function sliderWrapperNode(): IFakeNode {
82
+ const node = findInTree(
83
+ n => n.viewName === 'RCTView' && n.children.some(child => child.viewName === SLIDER_VIEW),
84
+ );
85
+ if (!node) throw new Error('no committed Slider wrapper exists');
86
+ return node;
87
+ }
88
+
89
+ describe('React Slider wrapper', () => {
90
+ it('paints the raw RNCSlider leaf inside a centering wrapper View', () => {
91
+ mount(
92
+ ROOT_TAG,
93
+ createElement(Slider, { value: 0.5, minimumValue: 0, maximumValue: 1, step: 0.1 }),
94
+ );
95
+ const props = sliderNode().props;
96
+ expect(props.value).toBe(0.5);
97
+ expect(props.minimumValue).toBe(0);
98
+ expect(props.maximumValue).toBe(1);
99
+ expect(props.step).toBe(0.1);
100
+ expect(fabric.find(n => n.viewName === 'RCTView')).toBeDefined();
101
+ });
102
+
103
+ it('defaults range + limits the way the library wrapper does', () => {
104
+ mount(ROOT_TAG, createElement(Slider, { value: 0.3 }));
105
+ const props = sliderNode().props;
106
+ expect(props.minimumValue).toBe(0);
107
+ expect(props.maximumValue).toBe(1);
108
+ expect(props.step).toBe(0);
109
+ expect(props.lowerLimit).toBe(Number.MIN_SAFE_INTEGER);
110
+ expect(props.upperLimit).toBe(Number.MAX_SAFE_INTEGER);
111
+ expect(props.inverted).toBe(false);
112
+ expect(props.disabled).toBe(false);
113
+ });
114
+
115
+ it('sanitizes a falsy/NaN value to undefined (library passedValue quirk)', () => {
116
+ mount(ROOT_TAG, createElement(Slider, { value: 0 }));
117
+ expect(sliderNode().props.value).toBeUndefined();
118
+ unmount(ROOT_TAG);
119
+ fabric.reset();
120
+ mount(ROOT_TAG, createElement(Slider, { value: Number.NaN }));
121
+ expect(sliderNode().props.value).toBeUndefined();
122
+ });
123
+
124
+ it('measures the wrapper and pins the native slider width in the common non-steps path', async () => {
125
+ mount(ROOT_TAG, createElement(Slider, { value: 0.5 }));
126
+ fabric.fireEvent(sliderWrapperNode().instanceHandle, 'topLayout', {
127
+ layout: { x: 0, y: 0, width: 240, height: 40 },
128
+ });
129
+ await tick();
130
+ expect(currentSliderNode().props.width).toBe(240);
131
+ });
132
+
133
+ it('forwards tint props and runs them through the derived processor', () => {
134
+ mount(
135
+ ROOT_TAG,
136
+ createElement(Slider, {
137
+ value: 0.2,
138
+ minimumTrackTintColor: '#ff0000',
139
+ maximumTrackTintColor: '#00ff00',
140
+ thumbTintColor: '#0000ff',
141
+ }),
142
+ );
143
+ const props = sliderNode().props;
144
+ expect(props.minimumTrackTintColor).toBe('processed(#ff0000)');
145
+ expect(props.maximumTrackTintColor).toBe('processed(#00ff00)');
146
+ expect(props.thumbTintColor).toBe('processed(#0000ff)');
147
+ });
148
+
149
+ it('maps both native value rails onto onValueChange(value)', () => {
150
+ let changed: number | undefined;
151
+ mount(
152
+ ROOT_TAG,
153
+ createElement(Slider, { value: 0.2, onValueChange: (v: number) => (changed = v) }),
154
+ );
155
+ const node = sliderNode();
156
+ fabric.fireEvent(node.instanceHandle, 'topChange', { value: 0.7 });
157
+ expect(changed).toBe(0.7);
158
+ fabric.fireEvent(node.instanceHandle, 'topRNCSliderValueChange', { value: 0.42 });
159
+ expect(changed).toBe(0.42);
160
+ });
161
+
162
+ it('maps the direct sliding events onto their callbacks', () => {
163
+ let startedAt: number | undefined;
164
+ let completedAt: number | undefined;
165
+ mount(
166
+ ROOT_TAG,
167
+ createElement(Slider, {
168
+ value: 0.2,
169
+ onSlidingStart: (v: number) => (startedAt = v),
170
+ onSlidingComplete: (v: number) => (completedAt = v),
171
+ }),
172
+ );
173
+ const node = sliderNode();
174
+ fabric.fireEvent(node.instanceHandle, 'topRNCSliderSlidingStart', { value: 0.1 });
175
+ fabric.fireEvent(node.instanceHandle, 'topRNCSliderSlidingComplete', { value: 0.9 });
176
+ expect(startedAt).toBe(0.1);
177
+ expect(completedAt).toBe(0.9);
178
+ });
179
+
180
+ it('resolves disabled from accessibilityState when no explicit boolean', () => {
181
+ mount(ROOT_TAG, createElement(Slider, { value: 0.2, accessibilityState: { disabled: true } }));
182
+ expect(sliderNode().props.disabled).toBe(true);
183
+ });
184
+
185
+ it('renders the step indicator when renderStepNumber is set', () => {
186
+ mount(
187
+ ROOT_TAG,
188
+ createElement(Slider, {
189
+ value: 0.5,
190
+ minimumValue: 0,
191
+ maximumValue: 1,
192
+ step: 0.5,
193
+ renderStepNumber: true,
194
+ }),
195
+ );
196
+ expect(fabric.find(n => n.props.testID === 'StepsIndicator-Container')).toBeDefined();
197
+ });
198
+
199
+ it('does NOT leak the JS onValueChange callback to the native node as a prop', () => {
200
+ mount(ROOT_TAG, createElement(Slider, { value: 0.2, onValueChange: () => undefined }));
201
+ expect(typeof sliderNode().props.onValueChange).not.toBe('function');
202
+ });
203
+ });
@@ -0,0 +1,89 @@
1
+ // Regression test for the package-level RNCSlider fallback registration. The app/examples still
2
+ // inject RN's ReactNativeViewConfigRegistry when available, but @symbiote-native/slider must be self-
3
+ // contained: importing this package registers RNCSlider's events + tint processors even when the
4
+ // registry lookup misses on a real host.
5
+
6
+ import { createElement } from 'react';
7
+ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
8
+ import { mount, unmount, setNativeViewConfigSource } from '@symbiote-native/react';
9
+ import { setColorProcessor, type ISymbioteEvent } from '@symbiote-native/engine';
10
+ import { installFabric, type IFakeNode } from '@symbiote-native/test-utils';
11
+ import './register';
12
+
13
+ vi.mock('@react-native-community/slider/dist/RNCSliderNativeComponent', () => ({}));
14
+
15
+ const ROOT_TAG = 313;
16
+ const SLIDER_VIEW = 'RNCSlider';
17
+
18
+ const fabric = installFabric();
19
+
20
+ function sliderNode(): IFakeNode {
21
+ const node = fabric.find(n => n.viewName === SLIDER_VIEW);
22
+ if (!node) throw new Error(`no ${SLIDER_VIEW} was created`);
23
+ return node;
24
+ }
25
+
26
+ function numberFromEvent(event: ISymbioteEvent): number | undefined {
27
+ const value = event.nativeEvent.value;
28
+ return typeof value === 'number' ? value : undefined;
29
+ }
30
+
31
+ beforeEach(() => {
32
+ fabric.reset();
33
+ setNativeViewConfigSource(() => undefined);
34
+ setColorProcessor(value => `processed(${String(value)})`);
35
+ });
36
+
37
+ afterEach(() => {
38
+ unmount(ROOT_TAG);
39
+ setColorProcessor(value => value);
40
+ });
41
+
42
+ describe('RNCSlider package registration', () => {
43
+ it('processes slider tint colors without RN ViewConfig registry metadata', () => {
44
+ mount(
45
+ ROOT_TAG,
46
+ createElement('RNCSlider', {
47
+ minimumTrackTintColor: '#ff0000',
48
+ maximumTrackTintColor: '#00ff00',
49
+ thumbTintColor: '#0000ff',
50
+ }),
51
+ );
52
+
53
+ const props = sliderNode().props;
54
+ expect(props.minimumTrackTintColor).toBe('processed(#ff0000)');
55
+ expect(props.maximumTrackTintColor).toBe('processed(#00ff00)');
56
+ expect(props.thumbTintColor).toBe('processed(#0000ff)');
57
+ });
58
+
59
+ it('routes slider native value events without RN ViewConfig registry metadata', () => {
60
+ let changed: number | undefined;
61
+ const onChange = (event: ISymbioteEvent): void => {
62
+ changed = numberFromEvent(event);
63
+ };
64
+
65
+ mount(ROOT_TAG, createElement('RNCSlider', { onChange, onRNCSliderValueChange: onChange }));
66
+
67
+ const node = sliderNode();
68
+ fabric.fireEvent(node.instanceHandle, 'topChange', { value: 0.25 });
69
+ expect(changed).toBe(0.25);
70
+ fabric.fireEvent(node.instanceHandle, 'topRNCSliderValueChange', { value: 0.75 });
71
+ expect(changed).toBe(0.75);
72
+ });
73
+
74
+ it('routes slider direct events without RN ViewConfig registry metadata', () => {
75
+ let completedAt: number | undefined;
76
+
77
+ mount(
78
+ ROOT_TAG,
79
+ createElement('RNCSlider', {
80
+ onRNCSliderSlidingComplete: (event: ISymbioteEvent): void => {
81
+ completedAt = numberFromEvent(event);
82
+ },
83
+ }),
84
+ );
85
+
86
+ fabric.fireEvent(sliderNode().instanceHandle, 'topRNCSliderSlidingComplete', { value: 0.5 });
87
+ expect(completedAt).toBe(0.5);
88
+ });
89
+ });
@@ -0,0 +1,59 @@
1
+ // Side-effect: register RNCSlider's ViewConfig in RN's ReactNativeViewConfigRegistry. Evaluating
2
+ // the codegen native-component spec (codegenNativeComponent('RNCSlider', …)) registers the
3
+ // ViewConfig getter the engine reads via setNativeViewConfigSource, so the engine can derive
4
+ // RNCSlider's events and color/image processors on first commit. We pull the codegen SPEC, never
5
+ // the library's default export (Slider.tsx, a React component using hooks) — this module has no
6
+ // hooks, so it is framework-agnostic and shared by every adapter entry (vue / react). Each adapter
7
+ // barrel imports it; the component modules and their headless tests stay free of the spec. See
8
+ // CLAUDE.md <third_party_rn_packages_are_react_only> and ADR 0027.
9
+
10
+ import '@react-native-community/slider/dist/RNCSliderNativeComponent';
11
+ import { processColor, registerComponent, type IColorValue } from '@symbiote-native/engine';
12
+ import {
13
+ RNC_SLIDER_VIEW_NAME,
14
+ SLIDER_ON_CHANGE,
15
+ SLIDER_ON_VALUE_CHANGE,
16
+ SLIDER_ON_SLIDING_START,
17
+ SLIDER_ON_SLIDING_COMPLETE,
18
+ SLIDER_ON_ACCESSIBILITY_ACTION,
19
+ } from './core';
20
+
21
+ function listenerName(prop: string): string {
22
+ return prop.charAt(2).toLowerCase() + prop.slice(3);
23
+ }
24
+
25
+ function processSliderColor(value: unknown): unknown {
26
+ return processColor(value as IColorValue);
27
+ }
28
+
29
+ // Fallback metadata for the native slider. RN's codegen module above normally registers the same
30
+ // ViewConfig into ReactNativeViewConfigRegistry, but relying only on that side effect is brittle on
31
+ // Metro/RN version boundaries: if the registry lookup misses, the slider still mounts, but tint
32
+ // props stay raw and native value events never route back to JS. Keep the explicit fallback here,
33
+ // in the wrapper package that owns RNCSlider, so React/Vue/Angular all inherit the same behavior.
34
+ registerComponent(RNC_SLIDER_VIEW_NAME, {
35
+ events: [
36
+ { raw: 'topChange', listener: listenerName(SLIDER_ON_CHANGE) },
37
+ { raw: 'topRNCSliderValueChange', listener: listenerName(SLIDER_ON_VALUE_CHANGE) },
38
+ {
39
+ raw: 'topRNCSliderSlidingStart',
40
+ listener: listenerName(SLIDER_ON_SLIDING_START),
41
+ direct: true,
42
+ },
43
+ {
44
+ raw: 'topRNCSliderSlidingComplete',
45
+ listener: listenerName(SLIDER_ON_SLIDING_COMPLETE),
46
+ direct: true,
47
+ },
48
+ {
49
+ raw: 'topRNCSliderAccessibilityAction',
50
+ listener: listenerName(SLIDER_ON_ACCESSIBILITY_ACTION),
51
+ direct: true,
52
+ },
53
+ ],
54
+ processors: {
55
+ minimumTrackTintColor: processSliderColor,
56
+ maximumTrackTintColor: processSliderColor,
57
+ thumbTintColor: processSliderColor,
58
+ },
59
+ });
@@ -0,0 +1,11 @@
1
+ // @symbiote-native/slider/vue: the Vue wrapper over the @react-native-community/slider native view.
2
+ // Importing this barrel first registers the native view's ViewConfig (./register, a side-effect
3
+ // import of the codegen spec — never the library's React component), then exposes the platform-
4
+ // split Slider. The public prop type is the agnostic core ISliderProps plus a Vue-only `class`
5
+ // field (see slider/shared.ts); the custom StepMarker is a Vue scoped slot, not a prop. See
6
+ // ADR 0027.
7
+
8
+ import '../register';
9
+
10
+ export { Slider } from './slider';
11
+ export type { ISliderProps } from './slider/shared';
@@ -0,0 +1,13 @@
1
+ // Slider on Android: the native view sizes itself (no default height), lays out implicit steps at
2
+ // 128-point resolution, and keeps the step row at the top. Mirrors the library's Android branches.
3
+
4
+ import { createSlider } from './shared';
5
+ import { SLIDER_STEP_RESOLUTION_ANDROID } from '../../core';
6
+
7
+ const ANDROID_STEPS_CONTAINER_TOP = 0;
8
+
9
+ export const Slider = createSlider({
10
+ defaultStyle: {},
11
+ stepResolution: SLIDER_STEP_RESOLUTION_ANDROID,
12
+ stepsContainerTop: ANDROID_STEPS_CONTAINER_TOP,
13
+ });
@@ -0,0 +1,14 @@
1
+ // Slider on iOS: the native view has an intrinsic 40pt height (the wrapper applies it as the
2
+ // default), lays out implicit steps at 1000-point resolution, and nudges the step row down 10pt.
3
+ // Also the base (./index re-exports it) for headless. Mirrors the library's iOS branches.
4
+
5
+ import { createSlider } from './shared';
6
+ import { SLIDER_IOS_DEFAULT_HEIGHT, SLIDER_STEP_RESOLUTION_IOS } from '../../core';
7
+
8
+ const IOS_STEPS_CONTAINER_TOP = 10;
9
+
10
+ export const Slider = createSlider({
11
+ defaultStyle: { height: SLIDER_IOS_DEFAULT_HEIGHT },
12
+ stepResolution: SLIDER_STEP_RESOLUTION_IOS,
13
+ stepsContainerTop: IOS_STEPS_CONTAINER_TOP,
14
+ });
@@ -0,0 +1,5 @@
1
+ // Base entry for headless / tsc: re-exports the iOS variant (Metro picks index.ios / index.android
2
+ // per platform via filename selection; this no-suffix file is what tsx/vitest resolve). ADR 0026.
3
+
4
+ export { Slider } from './index.ios';
5
+ export type { ISliderProps } from './shared';