panelui-native 0.54.0 → 0.56.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.
- package/README.md +1 -0
- package/lib/module/components/combobox/index.js +61 -7
- package/lib/module/components/combobox/index.js.map +1 -1
- package/lib/module/components/hex-chart/index.js +765 -0
- package/lib/module/components/hex-chart/index.js.map +1 -0
- package/lib/module/components/sortable/index.js +74 -12
- package/lib/module/components/sortable/index.js.map +1 -1
- package/lib/module/components/steps/index.js +95 -12
- package/lib/module/components/steps/index.js.map +1 -1
- package/lib/module/components/tag-input/index.js +435 -0
- package/lib/module/components/tag-input/index.js.map +1 -0
- package/lib/module/components/tour/index.js +661 -0
- package/lib/module/components/tour/index.js.map +1 -0
- package/lib/module/index.js +3 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/utils/chart.js +209 -0
- package/lib/module/utils/chart.js.map +1 -1
- package/lib/typescript/src/components/combobox/index.d.ts.map +1 -1
- package/lib/typescript/src/components/hex-chart/index.d.ts +277 -0
- package/lib/typescript/src/components/hex-chart/index.d.ts.map +1 -0
- package/lib/typescript/src/components/sortable/index.d.ts.map +1 -1
- package/lib/typescript/src/components/steps/index.d.ts +19 -0
- package/lib/typescript/src/components/steps/index.d.ts.map +1 -1
- package/lib/typescript/src/components/tag-input/index.d.ts +240 -0
- package/lib/typescript/src/components/tag-input/index.d.ts.map +1 -0
- package/lib/typescript/src/components/tour/index.d.ts +168 -0
- package/lib/typescript/src/components/tour/index.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +3 -0
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/utils/chart.d.ts +98 -0
- package/lib/typescript/src/utils/chart.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/hex-chart/index.tsx +1009 -0
- package/src/components/steps/index.tsx +103 -8
- package/src/components/tour/index.tsx +933 -0
- package/src/index.ts +22 -0
- package/src/utils/chart.ts +236 -0
|
@@ -14,10 +14,24 @@
|
|
|
14
14
|
* Steps does not own your flow: it reflects whatever step your app says is
|
|
15
15
|
* active. Pass `value` to control it, or `defaultValue` to let it manage
|
|
16
16
|
* its own.
|
|
17
|
+
*
|
|
18
|
+
* The connectors are the component's job, not yours. The root counts the items
|
|
19
|
+
* it holds and each one draws the connector to the next, so a stepper is just
|
|
20
|
+
* its steps — there is no separator to forget, mis-order, or leave dangling
|
|
21
|
+
* past the last stop. An item that contains its own `Steps.Separator` keeps it
|
|
22
|
+
* and gets no second one, so hand-placed connectors still work; `separators`
|
|
23
|
+
* turns the automatic ones off wholesale.
|
|
24
|
+
*
|
|
25
|
+
* Knowing the count is also what lets a step say where it sits. A screen reader
|
|
26
|
+
* reaching the middle of a wizard hears "Payment, step 2 of 3, completed" —
|
|
27
|
+
* the position and the state, which are the two things the circle and its fill
|
|
28
|
+
* convey to everyone else.
|
|
17
29
|
*/
|
|
18
30
|
import {
|
|
31
|
+
Children,
|
|
19
32
|
createContext,
|
|
20
33
|
forwardRef,
|
|
34
|
+
isValidElement,
|
|
21
35
|
useCallback,
|
|
22
36
|
useContext,
|
|
23
37
|
useMemo,
|
|
@@ -91,6 +105,7 @@ interface StepsContextValue {
|
|
|
91
105
|
activeStep: number;
|
|
92
106
|
setActiveStep: (step: number) => void;
|
|
93
107
|
orientation: StepsOrientation;
|
|
108
|
+
separators: boolean;
|
|
94
109
|
}
|
|
95
110
|
|
|
96
111
|
interface StepItemContextValue {
|
|
@@ -100,8 +115,23 @@ interface StepItemContextValue {
|
|
|
100
115
|
isLoading: boolean;
|
|
101
116
|
}
|
|
102
117
|
|
|
118
|
+
/**
|
|
119
|
+
* Where an item sits among its siblings, published by the root.
|
|
120
|
+
*
|
|
121
|
+
* Deliberately not the item's own `step` prop: that is the author's numbering
|
|
122
|
+
* of the flow and may skip, repeat or start anywhere, while the connector and
|
|
123
|
+
* the "2 of 3" announcement both need the position in the row as rendered.
|
|
124
|
+
* Absent when an item is used outside a root that maps its children, which is
|
|
125
|
+
* why every reader of it has a fallback.
|
|
126
|
+
*/
|
|
127
|
+
interface StepPositionContextValue {
|
|
128
|
+
position: number;
|
|
129
|
+
total: number;
|
|
130
|
+
}
|
|
131
|
+
|
|
103
132
|
const StepsContext = createContext<StepsContextValue | null>(null);
|
|
104
133
|
const StepItemContext = createContext<StepItemContextValue | null>(null);
|
|
134
|
+
const StepPositionContext = createContext<StepPositionContextValue | null>(null);
|
|
105
135
|
|
|
106
136
|
function useSteps(component: string): StepsContextValue {
|
|
107
137
|
const context = useContext(StepsContext);
|
|
@@ -127,6 +157,13 @@ export interface StepsProps extends ViewProps {
|
|
|
127
157
|
value?: number;
|
|
128
158
|
onValueChange?: (value: number) => void;
|
|
129
159
|
orientation?: StepsOrientation;
|
|
160
|
+
/**
|
|
161
|
+
* Draw the connector between one item and the next. On by default — an item
|
|
162
|
+
* that holds its own `Steps.Separator` is left alone either way, so this is
|
|
163
|
+
* for a stepper that wants no connectors at all rather than for one that
|
|
164
|
+
* places them by hand.
|
|
165
|
+
*/
|
|
166
|
+
separators?: boolean;
|
|
130
167
|
children?: ReactNode;
|
|
131
168
|
}
|
|
132
169
|
|
|
@@ -138,6 +175,7 @@ const StepsRoot = forwardRef<View, StepsProps>(
|
|
|
138
175
|
value,
|
|
139
176
|
onValueChange,
|
|
140
177
|
orientation = 'horizontal',
|
|
178
|
+
separators = true,
|
|
141
179
|
children,
|
|
142
180
|
...props
|
|
143
181
|
},
|
|
@@ -156,16 +194,37 @@ const StepsRoot = forwardRef<View, StepsProps>(
|
|
|
156
194
|
);
|
|
157
195
|
|
|
158
196
|
const context = useMemo(
|
|
159
|
-
() => ({ activeStep, setActiveStep, orientation }),
|
|
160
|
-
[activeStep, setActiveStep, orientation]
|
|
197
|
+
() => ({ activeStep, setActiveStep, orientation, separators }),
|
|
198
|
+
[activeStep, setActiveStep, orientation, separators]
|
|
161
199
|
);
|
|
162
200
|
|
|
163
201
|
const { root } = stepsVariants({ orientation });
|
|
164
202
|
|
|
203
|
+
/*
|
|
204
|
+
* Items are counted here rather than registered by each one on mount,
|
|
205
|
+
* because the count has to be right on the first frame: a connector that
|
|
206
|
+
* appears after the last item and disappears once the registrations land
|
|
207
|
+
* is a visible flicker on every mount. Reading the children gives the whole
|
|
208
|
+
* row at once, and a Provider adds no host view, so wrapping an item in one
|
|
209
|
+
* leaves the flex layout exactly as it was.
|
|
210
|
+
*/
|
|
211
|
+
const nodes = Children.toArray(textChildren(children));
|
|
212
|
+
const total = nodes.filter((node) => isValidElement(node) && node.type === StepsItem).length;
|
|
213
|
+
let position = -1;
|
|
214
|
+
|
|
165
215
|
return (
|
|
166
216
|
<StepsContext.Provider value={context}>
|
|
167
217
|
<View ref={ref} className={root({ className })} {...props}>
|
|
168
|
-
{
|
|
218
|
+
{nodes.map((node) => {
|
|
219
|
+
if (!isValidElement(node) || node.type !== StepsItem) return node;
|
|
220
|
+
position += 1;
|
|
221
|
+
const placement = { position, total };
|
|
222
|
+
return (
|
|
223
|
+
<StepPositionContext.Provider key={node.key ?? position} value={placement}>
|
|
224
|
+
{node}
|
|
225
|
+
</StepPositionContext.Provider>
|
|
226
|
+
);
|
|
227
|
+
})}
|
|
169
228
|
</View>
|
|
170
229
|
</StepsContext.Provider>
|
|
171
230
|
);
|
|
@@ -190,7 +249,8 @@ const StepsItem = forwardRef<View, StepsItemProps>(
|
|
|
190
249
|
{ className, step, completed = false, disabled = false, loading = false, children, ...props },
|
|
191
250
|
ref
|
|
192
251
|
) => {
|
|
193
|
-
const { activeStep, orientation } = useSteps('Steps.Item');
|
|
252
|
+
const { activeStep, orientation, separators } = useSteps('Steps.Item');
|
|
253
|
+
const placement = useContext(StepPositionContext);
|
|
194
254
|
|
|
195
255
|
const isLoading = loading && step === activeStep;
|
|
196
256
|
const state: StepState =
|
|
@@ -209,10 +269,23 @@ const StepsItem = forwardRef<View, StepsItemProps>(
|
|
|
209
269
|
|
|
210
270
|
const { item } = stepsVariants({ orientation, state });
|
|
211
271
|
|
|
272
|
+
/*
|
|
273
|
+
* The last item has nothing to connect to, and one placed by hand is the
|
|
274
|
+
* author's — adding a second beside it would double the line rather than
|
|
275
|
+
* replace it. Only the top level is inspected, which is where a connector
|
|
276
|
+
* has to be anyway: it is a sibling of the trigger, not something buried
|
|
277
|
+
* inside it.
|
|
278
|
+
*/
|
|
279
|
+
const isLast = placement ? placement.position === placement.total - 1 : true;
|
|
280
|
+
const hasOwnSeparator = Children.toArray(children).some(
|
|
281
|
+
(child) => isValidElement(child) && child.type === StepsSeparator
|
|
282
|
+
);
|
|
283
|
+
|
|
212
284
|
return (
|
|
213
285
|
<StepItemContext.Provider value={context}>
|
|
214
286
|
<View ref={ref} className={item({ className })} {...props}>
|
|
215
287
|
{textChildren(children)}
|
|
288
|
+
{separators && !isLast && !hasOwnSeparator ? <StepsSeparator /> : null}
|
|
216
289
|
</View>
|
|
217
290
|
</StepItemContext.Provider>
|
|
218
291
|
);
|
|
@@ -225,18 +298,38 @@ export interface StepsTriggerProps extends ViewProps {
|
|
|
225
298
|
children?: ReactNode;
|
|
226
299
|
}
|
|
227
300
|
|
|
301
|
+
/** What each state is called when a screen reader reaches the step. */
|
|
302
|
+
const STATE_WORDS: Record<StepState, string> = {
|
|
303
|
+
completed: 'completed',
|
|
304
|
+
active: 'current step',
|
|
305
|
+
loading: 'in progress',
|
|
306
|
+
inactive: 'not started',
|
|
307
|
+
};
|
|
308
|
+
|
|
228
309
|
/** Makes its item selectable. Omit it for a read-only stepper. */
|
|
229
310
|
const StepsTrigger = forwardRef<View, StepsTriggerProps>(
|
|
230
311
|
({ className, children, ...props }, ref) => {
|
|
231
312
|
const { setActiveStep, orientation } = useSteps('Steps.Trigger');
|
|
232
313
|
const { step, state, isDisabled } = useStepItem('Steps.Trigger');
|
|
314
|
+
const placement = useContext(StepPositionContext);
|
|
233
315
|
const { trigger } = stepsVariants({ orientation, state, isDisabled });
|
|
234
316
|
|
|
317
|
+
/*
|
|
318
|
+
* Said as a value rather than a label, because the label is the step's own
|
|
319
|
+
* title and the circle beside it — text the trigger already merges. An
|
|
320
|
+
* `accessibilityLabel` here would replace all of that with the position,
|
|
321
|
+
* trading the name of the step for its number; a value is read after it.
|
|
322
|
+
*/
|
|
323
|
+
const position = placement
|
|
324
|
+
? `step ${placement.position + 1} of ${placement.total}, ${STATE_WORDS[state]}`
|
|
325
|
+
: STATE_WORDS[state];
|
|
326
|
+
|
|
235
327
|
return (
|
|
236
328
|
<Pressable
|
|
237
329
|
ref={ref}
|
|
238
330
|
accessibilityRole="button"
|
|
239
331
|
accessibilityState={{ disabled: isDisabled, selected: state === 'active' }}
|
|
332
|
+
accessibilityValue={{ text: position }}
|
|
240
333
|
disabled={isDisabled}
|
|
241
334
|
onPress={() => setActiveStep(step)}
|
|
242
335
|
className={trigger({ className })}
|
|
@@ -310,11 +403,13 @@ export interface StepsSeparatorProps extends ViewProps {
|
|
|
310
403
|
}
|
|
311
404
|
|
|
312
405
|
/**
|
|
313
|
-
* The connector between two steps. Fills with the primary colour once the
|
|
314
|
-
*
|
|
406
|
+
* The connector between two steps. Fills with the primary colour once the step
|
|
407
|
+
* before it is complete.
|
|
315
408
|
*
|
|
316
|
-
*
|
|
317
|
-
*
|
|
409
|
+
* Every item draws one automatically, so this is only worth writing to dress a
|
|
410
|
+
* particular connector — an item that holds its own keeps it and gets no
|
|
411
|
+
* second. It belongs inside a `Steps.Item` either way, so it can read that
|
|
412
|
+
* item's state: the connector after step 1 goes solid when step 1 is done.
|
|
318
413
|
*/
|
|
319
414
|
const StepsSeparator = forwardRef<View, StepsSeparatorProps>(
|
|
320
415
|
({ className, ...props }, ref) => {
|