react-native-roster 0.0.1 → 0.2.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 +209 -32
- package/dist/src/components/primitives/portal.d.ts +12 -0
- package/dist/src/components/primitives/portal.d.ts.map +1 -0
- package/dist/src/components/primitives/portal.js +41 -0
- package/dist/src/components/primitives/portal.js.map +1 -0
- package/dist/src/components/roster/body-layout.d.ts +9 -0
- package/dist/src/components/roster/body-layout.d.ts.map +1 -0
- package/dist/src/components/roster/body-layout.js +15 -0
- package/dist/src/components/roster/body-layout.js.map +1 -0
- package/dist/src/components/roster/index.d.ts +2 -1
- package/dist/src/components/roster/index.d.ts.map +1 -1
- package/dist/src/components/roster/index.js +34 -27
- package/dist/src/components/roster/index.js.map +1 -1
- package/dist/src/components/roster/lanes/lane.d.ts +2 -2
- package/dist/src/components/roster/lanes/lane.d.ts.map +1 -1
- package/dist/src/components/roster/lanes/lane.js +4 -8
- package/dist/src/components/roster/lanes/lane.js.map +1 -1
- package/dist/src/components/roster/parts/body.d.ts +3 -3
- package/dist/src/components/roster/parts/body.d.ts.map +1 -1
- package/dist/src/components/roster/parts/body.js +5 -20
- package/dist/src/components/roster/parts/body.js.map +1 -1
- package/dist/src/components/roster/parts/header-cell.d.ts +2 -4
- package/dist/src/components/roster/parts/header-cell.d.ts.map +1 -1
- package/dist/src/components/roster/parts/header-cell.js.map +1 -1
- package/dist/src/components/roster/parts/header.d.ts +1 -1
- package/dist/src/components/roster/parts/header.d.ts.map +1 -1
- package/dist/src/components/roster/parts/header.js +2 -2
- package/dist/src/components/roster/parts/header.js.map +1 -1
- package/dist/src/components/roster/parts/lane-label-column.d.ts +1 -1
- package/dist/src/components/roster/parts/lane-label-column.d.ts.map +1 -1
- package/dist/src/components/roster/parts/lane-label-column.js +2 -2
- package/dist/src/components/roster/parts/lane-label-column.js.map +1 -1
- package/dist/src/components/roster/parts/lane-list.d.ts +7 -0
- package/dist/src/components/roster/parts/lane-list.d.ts.map +1 -0
- package/dist/src/components/roster/parts/lane-list.js +26 -0
- package/dist/src/components/roster/parts/lane-list.js.map +1 -0
- package/dist/src/components/roster/roster.types.d.ts +48 -21
- package/dist/src/components/roster/roster.types.d.ts.map +1 -1
- package/dist/src/components/roster/selection/selection-layout.d.ts +4 -0
- package/dist/src/components/roster/selection/selection-layout.d.ts.map +1 -0
- package/dist/src/components/roster/selection/selection-layout.js +82 -0
- package/dist/src/components/roster/selection/selection-layout.js.map +1 -0
- package/dist/src/components/roster/selection/selection-layout.types.d.ts +25 -0
- package/dist/src/components/roster/selection/selection-layout.types.d.ts.map +1 -0
- package/dist/src/components/roster/selection/selection-layout.types.js +3 -0
- package/dist/src/components/roster/selection/selection-layout.types.js.map +1 -0
- package/dist/src/components/roster/selection/selection-layout.web.d.ts +4 -0
- package/dist/src/components/roster/selection/selection-layout.web.d.ts.map +1 -0
- package/dist/src/components/roster/selection/selection-layout.web.js +52 -0
- package/dist/src/components/roster/selection/selection-layout.web.js.map +1 -0
- package/dist/src/components/roster/use-roster-press.d.ts +6 -0
- package/dist/src/components/roster/use-roster-press.d.ts.map +1 -0
- package/dist/src/components/roster/use-roster-press.js +61 -0
- package/dist/src/components/roster/use-roster-press.js.map +1 -0
- package/dist/src/components/roster/use-roster.d.ts.map +1 -1
- package/dist/src/components/roster/use-roster.js +40 -30
- package/dist/src/components/roster/use-roster.js.map +1 -1
- package/dist/src/components/roster/utils/body-content-key.d.ts +1 -1
- package/dist/src/components/roster/utils/body-content-key.d.ts.map +1 -1
- package/dist/src/components/roster/utils/body-content-key.js +10 -10
- package/dist/src/components/roster/utils/body-content-key.js.map +1 -1
- package/dist/src/components/schedule/days/day.d.ts +2 -2
- package/dist/src/components/schedule/days/day.d.ts.map +1 -1
- package/dist/src/components/schedule/days/day.js +2 -11
- package/dist/src/components/schedule/days/day.js.map +1 -1
- package/dist/src/components/schedule/days/header-layout.d.ts +1 -1
- package/dist/src/components/schedule/days/header-layout.d.ts.map +1 -1
- package/dist/src/components/schedule/days/parts/column.d.ts +1 -1
- package/dist/src/components/schedule/days/parts/column.d.ts.map +1 -1
- package/dist/src/components/schedule/days/parts/column.js +4 -8
- package/dist/src/components/schedule/days/parts/column.js.map +1 -1
- package/dist/src/components/schedule/index.d.ts.map +1 -1
- package/dist/src/components/schedule/index.js +7 -8
- package/dist/src/components/schedule/index.js.map +1 -1
- package/dist/src/components/schedule/schedule.types.d.ts +17 -17
- package/dist/src/components/schedule/schedule.types.d.ts.map +1 -1
- package/dist/src/core/index.d.ts +1 -0
- package/dist/src/core/index.d.ts.map +1 -1
- package/dist/src/core/index.js +3 -1
- package/dist/src/core/index.js.map +1 -1
- package/dist/src/core/source.d.ts +4 -0
- package/dist/src/core/source.d.ts.map +1 -0
- package/dist/src/core/source.js +9 -0
- package/dist/src/core/source.js.map +1 -0
- package/dist/src/index.d.ts +6 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +10 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/nativewind/index.d.ts +28 -27
- package/dist/src/nativewind/index.d.ts.map +1 -1
- package/docs/migrations.md +61 -0
- package/llms.txt +112 -30
- package/package.json +12 -5
- package/src/components/layers/README.md +7 -3
- package/src/components/primitives/README.md +13 -2
- package/src/components/primitives/portal.tsx +48 -0
- package/src/components/roster/README.md +62 -5
- package/src/components/roster/body-layout.tsx +38 -0
- package/src/components/roster/index.tsx +109 -46
- package/src/components/roster/lanes/lane.tsx +16 -13
- package/src/components/roster/parts/body.tsx +17 -84
- package/src/components/roster/parts/header-cell.tsx +2 -2
- package/src/components/roster/parts/header.tsx +7 -2
- package/src/components/roster/parts/lane-label-column.tsx +2 -2
- package/src/components/roster/parts/lane-list.tsx +76 -0
- package/src/components/roster/roster.types.ts +47 -17
- package/src/components/roster/selection/selection-layout.tsx +90 -0
- package/src/components/roster/selection/selection-layout.types.ts +20 -0
- package/src/components/roster/selection/selection-layout.web.tsx +88 -0
- package/src/components/roster/use-roster-press.ts +74 -0
- package/src/components/roster/use-roster.ts +57 -44
- package/src/components/roster/utils/body-content-key.ts +13 -13
- package/src/components/schedule/README.md +8 -3
- package/src/components/schedule/days/day.tsx +31 -18
- package/src/components/schedule/days/header-layout.tsx +1 -1
- package/src/components/schedule/days/parts/column.tsx +10 -12
- package/src/components/schedule/index.tsx +20 -21
- package/src/components/schedule/schedule.types.ts +13 -13
- package/src/core/README.md +4 -0
- package/src/core/index.ts +1 -0
- package/src/core/source.ts +9 -0
- package/src/index.ts +7 -0
package/README.md
CHANGED
|
@@ -34,7 +34,7 @@ hundred people without lying about time zones, this is the one.
|
|
|
34
34
|
z-order; coverage math unions availability, subtracts bookings, and sorts.
|
|
35
35
|
- **Recurrence adapter.** Weekly, daily, and monthly rules with exclusions,
|
|
36
36
|
caps, and content-keyed caches, kept out of the core.
|
|
37
|
-
- **Zones everywhere.**
|
|
37
|
+
- **Zones everywhere.** Input-bearing regions accept component types, singletons accept nodes, and
|
|
38
38
|
every chrome region takes `style` plus a NativeWind `className` twin.
|
|
39
39
|
- **Virtualized and measured.** Geometry runs only for mounted lanes; CI gates
|
|
40
40
|
layout, coverage, bundle size, and browser action budgets.
|
|
@@ -130,7 +130,7 @@ export function RecurringExample() {
|
|
|
130
130
|
|
|
131
131
|
Tuesday is a gap carrying the dated exclusion; the other weekdays carry the
|
|
132
132
|
include rule. Expand once per `windowFor(spec)` in your screen's hook, never
|
|
133
|
-
inside a
|
|
133
|
+
inside a slot component; content-keyed caches reuse unchanged occurrences. The
|
|
134
134
|
[adapter guide](./docs/adapters.md) covers validation, caps, cache lifetime,
|
|
135
135
|
and mapping tables or feeds without a recurrence dependency;
|
|
136
136
|
[recurrence semantics](./docs/recurrence.md) records the exact anchor, UNTIL,
|
|
@@ -167,12 +167,13 @@ and "Availability may be incomplete"; both are localizable props.
|
|
|
167
167
|
|
|
168
168
|
| Import | Shipped surface |
|
|
169
169
|
| --- | --- |
|
|
170
|
-
| `react-native-roster` | `Roster`, `Schedule`, `
|
|
170
|
+
| `react-native-roster` | `Roster`, `Schedule`, hooks, slot components, `RosterSelectionPopover`, `PortalHost`, `Portal`, and all core exports. |
|
|
171
171
|
| `react-native-roster/core` | Types, `layoutLane`, `coverageFor`, `flagFor`, axis helpers, comparators, and counters. Standard JavaScript and `Intl` only. |
|
|
172
172
|
| `react-native-roster/rrule` | `expandRuleSet`, `envelopeFor`, types, and expansion counters and caches. Uses pinned `rrule-temporal` and `@js-temporal/polyfill`. |
|
|
173
173
|
| `react-native-roster/nativewind` | Registers `Roster` and `Schedule` with NativeWind so their `className` props resolve; re-exports the registered components. |
|
|
174
174
|
|
|
175
|
-
Root and core never import recurrence dependencies.
|
|
175
|
+
Root and core never import recurrence dependencies. Public entry aliases retain the
|
|
176
|
+
implementation function identities while keeping CommonJS export overhead within the size gates. Metro selects TypeScript
|
|
176
177
|
source through the `react-native` export condition; other bundlers select
|
|
177
178
|
emitted CommonJS with declarations in `dist/src`. The emit is CommonJS, so
|
|
178
179
|
importing one function from the root costs the whole root bundle; import from
|
|
@@ -203,23 +204,44 @@ to `byLabel`; `byCoverage({ measure })` sorts by coverage descending.
|
|
|
203
204
|
|
|
204
205
|
## Roster zones
|
|
205
206
|
|
|
206
|
-
|
|
207
|
-
|
|
207
|
+
Props ending in `Component` accept `ComponentType<Input>` and are mounted by React.
|
|
208
|
+
Props ending in `Zone` accept `ReactNode`. Define components at module scope so
|
|
209
|
+
state survives rerenders; hooks and class components are supported. Compose the
|
|
210
|
+
exported default components inside replacements to retain scrolling, geometry,
|
|
211
|
+
or press behavior. Pass `null` to a node slot to suppress its default.
|
|
208
212
|
|
|
209
|
-
|
|
|
213
|
+
| Slot | Component inputs or node | Default and behavior |
|
|
210
214
|
| --- | --- | --- |
|
|
211
|
-
| `emptyZone` |
|
|
212
|
-
| `cornerZone` |
|
|
213
|
-
| `
|
|
214
|
-
| `
|
|
215
|
-
| `
|
|
216
|
-
| `
|
|
217
|
-
| `
|
|
218
|
-
| `
|
|
219
|
-
| `
|
|
220
|
-
| `
|
|
221
|
-
|
|
222
|
-
|
|
215
|
+
| `emptyZone` | `ReactNode` | `RosterEmpty`: No lanes. |
|
|
216
|
+
| `cornerZone` | `ReactNode` | `RosterCorner`: nothing; the cell above the labels, `laneLabelWidth` wide. |
|
|
217
|
+
| `laneLabelComponent` | `lane`, `flag`, `complete`, `viewTimezone`, localized labels | `RosterLaneLabel`: label, differing IANA zone badge, and notices. |
|
|
218
|
+
| `headerCellComponent` | `HeaderCellInput` (`tick`) | `RosterHeaderCell`: tick label. |
|
|
219
|
+
| `intervalComponent` | `rect`, `layer`, `lane`, `highlighted` | `RosterInterval`: positioned colored rect, with final inset bounds. |
|
|
220
|
+
| `intervalDetailComponent` | `rect`, `layer`, `lane`, `highlighted`, absolute `start` and `end`, `viewTimezone` | Absent by default; enables selection and fills its details. |
|
|
221
|
+
| `selectionLayout` | `SelectionLayoutProps`: nodes, targetBounds, open, dismissal, host, and shared scroll | `RosterSelectionPopover`: native portal or Radix web popover; replace at runtime. |
|
|
222
|
+
| `gapComponent` | `rect`, `layer`, `lane` | `RosterGap`: no visible content; the row supplies pressable bounds. |
|
|
223
|
+
| `gridComponent` | `ticks`, `contentWidth` | `RosterGrid`: one hairline per tick behind every lane. |
|
|
224
|
+
| `headerComponent` | `ticks`, `projection`, `scroll`, `contentWidth`, `headerCellComponent` | `RosterHeader`: frozen header following horizontal offset. |
|
|
225
|
+
| `laneLabelColumnComponent` | `labels`, `projection`, `scroll`, `laneLabelComponent` | `RosterLaneLabelColumn`: frozen labels following vertical offset. |
|
|
226
|
+
| `bodyComponent` | Ordered `lanes`, `window`, `geometryFor`, `projection`, `scroll`, `press`, `ticks`, `viewport`, `contentWidth`, highlight and hover, incomplete label, and rect components | `RosterBody`: virtualized lanes. |
|
|
227
|
+
|
|
228
|
+
`RosterBody` composes `RosterBodyLayout`, which arranges `gridZone` and `listZone`
|
|
229
|
+
nodes with scroll wiring, and `RosterLaneList`, which owns LegendList and its
|
|
230
|
+
per-lane callback. The body waits for viewport measurement before mounting the list.
|
|
231
|
+
|
|
232
|
+
```tsx
|
|
233
|
+
import type { LaneLabelInput } from 'react-native-roster';
|
|
234
|
+
import { Text } from 'react-native';
|
|
235
|
+
|
|
236
|
+
function LaneLabel({ lane }: LaneLabelInput) {
|
|
237
|
+
return <Text>{lane.label}</Text>;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
<Roster lanes={lanes} windowSpec={windowSpec}
|
|
241
|
+
laneLabelComponent={LaneLabel} cornerZone={<Text>People</Text>} />
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
A custom interval component positions at `rect.x/y`, uses `rect.width/height/z`,
|
|
223
245
|
and sets `pointerEvents="none"` so the parent hit-test walk owns presses. Gap
|
|
224
246
|
fillers are already inside positioned pressables. `useRoster` exposes ordered
|
|
225
247
|
lanes, coverage, lane state, ticks, `geometryFor`, shared scrolling, `press`,
|
|
@@ -230,6 +252,160 @@ holding the corner and ticks), `laneLabelColumnStyle`, and `bodyStyle`.
|
|
|
230
252
|
`laneLabelWidth` sizes the corner and label column, default 180. Each style
|
|
231
253
|
prop has a `className` twin; see [NativeWind](#nativewind).
|
|
232
254
|
|
|
255
|
+
### Selection
|
|
256
|
+
|
|
257
|
+
Add `intervalDetailComponent` to enable pressed-interval details. The press still
|
|
258
|
+
fires `onIntervalPress`; without the component, presses retain no selection.
|
|
259
|
+
`useRoster` owns `selection` and `dismissSelection`.
|
|
260
|
+
Pressing the selected interval again dismisses it; pressing another interval
|
|
261
|
+
switches selection. Cell and gap presses dismiss selection while still firing
|
|
262
|
+
`onCellPress` and `onGapPress`. These rules live in the hook and apply on native
|
|
263
|
+
and web; web outside press and Escape still dismiss.
|
|
264
|
+
Removing the selected lane, layer, or interval bounds clears selection. The private
|
|
265
|
+
reconcileSelection helper matches source identity sets and chooses nearest bounds with
|
|
266
|
+
a total difference of at most 1 ms for projection roundoff.
|
|
267
|
+
|
|
268
|
+
Native has no intercepting dismissal overlay; body presses reach the hook, and the detail
|
|
269
|
+
card captures its own presses. Web excludes the body wrapper from Radix outside
|
|
270
|
+
dismissal, leaving body presses to the hook while preserving true outside presses and Escape.
|
|
271
|
+
The hook toggles the selected interval closed, switches to another interval, and dismisses
|
|
272
|
+
on cell or gap presses while preserving their callbacks. The body restores horizontal
|
|
273
|
+
and vertical offsets from shared values on remount when selectionLayout changes.
|
|
274
|
+
A mount effect calls the horizontal ScrollView ref's scrollTo without animation;
|
|
275
|
+
native also retains contentOffset. LegendList restores initialScrollOffset through
|
|
276
|
+
its own web mount effect and native initial offset.
|
|
277
|
+
|
|
278
|
+
Current data and geometry replace old references, including after resizing or sorting. Reconciliation matches the layer id and
|
|
279
|
+
order-insensitive source identities, then chooses the nearest absolute bounds. The sum
|
|
280
|
+
of bound differences must be at most 1 ms. Stored bounds remain the display values.
|
|
281
|
+
|
|
282
|
+
`selectable?: boolean` belongs only to the hook input, `RosterInput`, and defaults to false.
|
|
283
|
+
It is excluded from `RosterProps`. Hook consumers
|
|
284
|
+
pass `selectable: true` to `useRoster` to retain selection. `intervalDetailComponent`,
|
|
285
|
+
`selectionLayout`, and `portalHost` live on `RosterProps` because the chassis mounts
|
|
286
|
+
the content and layout. The chassis enables selection with
|
|
287
|
+
`selectable: Boolean(intervalDetailComponent)`. Custom chassis mount their layout
|
|
288
|
+
with the returned selection, dismissal, and scroll inputs.
|
|
289
|
+
|
|
290
|
+
```tsx
|
|
291
|
+
import { Text, View } from 'react-native';
|
|
292
|
+
import { Roster } from 'react-native-roster';
|
|
293
|
+
import type { IntervalDetailInput, Lane } from 'react-native-roster';
|
|
294
|
+
|
|
295
|
+
function IntervalDetails({ lane, layer, rect, start, end, viewTimezone }: IntervalDetailInput) {
|
|
296
|
+
const format = new Intl.DateTimeFormat('en-US', { timeZone: viewTimezone, timeStyle: 'short' });
|
|
297
|
+
return <View style={{ padding: 16, backgroundColor: 'white' }}>
|
|
298
|
+
<Text>{lane.label}: {layer.label ?? layer.id}</Text>
|
|
299
|
+
<Text>{format.format(start)} to {format.format(end)}</Text>
|
|
300
|
+
{rect.sources.map((source) =>
|
|
301
|
+
<Text key={JSON.stringify([source.kind, source.id])}>
|
|
302
|
+
{source.label ?? source.id}
|
|
303
|
+
</Text>)}
|
|
304
|
+
</View>;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
export function SelectionExample({ lanes }: { lanes: Lane[] }) {
|
|
308
|
+
return <Roster lanes={lanes}
|
|
309
|
+
windowSpec={{ span: 'day', anchorDate: '2024-01-01', timezone: 'UTC' }}
|
|
310
|
+
style={{ height: 480, flex: undefined }}
|
|
311
|
+
intervalDetailComponent={IntervalDetails} />;
|
|
312
|
+
}
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
Web consumers install `bun add @radix-ui/react-popover`. It is an optional peer
|
|
316
|
+
for native and core-only consumers, and required by the web root entry. Consumers
|
|
317
|
+
resolving the library from source with a web bundler (Vite, Storybook, or Metro web)
|
|
318
|
+
must install it even without enabling selection because `selection-layout.web.tsx`
|
|
319
|
+
is in the module graph. Native and core-only consumers do not need it.
|
|
320
|
+
`RosterSelectionPopover` selects native or web through platform resolution.
|
|
321
|
+
Native mounts a local `PortalHost` and registers `Portal` content; web uses Radix
|
|
322
|
+
for portal placement, outside press, Escape, and collisions. The layout returns focus
|
|
323
|
+
to the previously focused element only after Escape.
|
|
324
|
+
The overlay tracks both scroll offsets with Reanimated shared values, without
|
|
325
|
+
React scroll state. Native clamps details horizontally to the measured viewport,
|
|
326
|
+
flips above when that fits, and uses the top edge when neither vertical placement
|
|
327
|
+
fits. The default native popover waits for viewport measurement and scrolls oversized
|
|
328
|
+
content on both axes within a maximum size of the viewport minus 8 px on each axis.
|
|
329
|
+
Consumers wanting a different presentation supply `selectionLayout`.
|
|
330
|
+
Native also dismisses on hardware back.
|
|
331
|
+
|
|
332
|
+
`selectionLayout?: ComponentType<SelectionLayoutProps>` is the layout strategy
|
|
333
|
+
naming exception to the `Component` suffix. The chassis mounts it with `anchorZone`
|
|
334
|
+
(the body), `contentZone` (details or null), `targetBounds` (body-content bounds), `open`,
|
|
335
|
+
`onDismiss`, `portalHost`, and `scroll`. The target bounds include the lane offset and
|
|
336
|
+
interval inset. Layout scroll inputs are limited to `x`, `y`, `headerStyle`, and
|
|
337
|
+
`labelStyle`. Render each node once. A consumer inspector
|
|
338
|
+
can arrange the nodes in columns and call `onDismiss` from its close button.
|
|
339
|
+
The [interval-detail gallery route](./demo/app/gallery/interval-detail.tsx)
|
|
340
|
+
switches presentations at runtime.
|
|
341
|
+
|
|
342
|
+
`portalHost` overrides the native destination name, whose default uses a unique
|
|
343
|
+
per-roster `useId`. Give separate rosters separate override names. The default
|
|
344
|
+
layout owns its host; do not also mount that name at an ancestor. Custom layouts
|
|
345
|
+
can instead target their own ancestor host, using the exported `PortalHost` and
|
|
346
|
+
`Portal`. A store-based portal does not preserve context from the registration
|
|
347
|
+
site; place required providers above the host or re-provide them in the content.
|
|
348
|
+
Selection never enters the lane list's body content key.
|
|
349
|
+
|
|
350
|
+
Schedule does not yet support selection; it is a later change.
|
|
351
|
+
|
|
352
|
+
### Consumer data in slot components
|
|
353
|
+
|
|
354
|
+
For consumer data beyond a slot's Input, mount a React context provider above
|
|
355
|
+
`Roster` and read it with `useContext` in a module-scope slot component. This
|
|
356
|
+
example supplies density and locale while keeping the header cell type stable:
|
|
357
|
+
|
|
358
|
+
```tsx
|
|
359
|
+
import { createContext, useContext } from 'react';
|
|
360
|
+
import { Text } from 'react-native';
|
|
361
|
+
import type { HeaderCellInput, RosterProps } from 'react-native-roster';
|
|
362
|
+
import { Roster } from 'react-native-roster';
|
|
363
|
+
|
|
364
|
+
type SlotPreferences = {
|
|
365
|
+
density: 'compact' | 'comfortable';
|
|
366
|
+
locale: string;
|
|
367
|
+
};
|
|
368
|
+
|
|
369
|
+
const SlotPreferencesContext = createContext<SlotPreferences>({
|
|
370
|
+
density: 'comfortable',
|
|
371
|
+
locale: 'en-US',
|
|
372
|
+
});
|
|
373
|
+
|
|
374
|
+
function LocalizedHeaderCell({ tick }: HeaderCellInput) {
|
|
375
|
+
const { density, locale } = useContext(SlotPreferencesContext);
|
|
376
|
+
const label = new Intl.DateTimeFormat(locale, {
|
|
377
|
+
timeZone: 'UTC',
|
|
378
|
+
...(tick.kind === 'day'
|
|
379
|
+
? { month: 'short', day: 'numeric' }
|
|
380
|
+
: { hour: 'numeric', minute: '2-digit' }),
|
|
381
|
+
}).format(tick.time);
|
|
382
|
+
|
|
383
|
+
return (
|
|
384
|
+
<Text numberOfLines={1} style={{ padding: density === 'compact' ? 2 : 6 }}>
|
|
385
|
+
{label}
|
|
386
|
+
</Text>
|
|
387
|
+
);
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
export function ConsumerRoster({ lanes }: Pick<RosterProps, 'lanes'>) {
|
|
391
|
+
return (
|
|
392
|
+
<SlotPreferencesContext.Provider value={{ density: 'compact', locale: 'en-GB' }}>
|
|
393
|
+
<Roster
|
|
394
|
+
lanes={lanes}
|
|
395
|
+
windowSpec={{ span: 'week', anchorDate: '2024-01-01', timezone: 'UTC' }}
|
|
396
|
+
style={{ height: 480, flex: undefined }}
|
|
397
|
+
headerCellComponent={LocalizedHeaderCell}
|
|
398
|
+
/>
|
|
399
|
+
</SlotPreferencesContext.Provider>
|
|
400
|
+
);
|
|
401
|
+
}
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
An inline closure or a memoized factory that returns a new component per render
|
|
405
|
+
is not the recommended path. A new interval component type remounts every interval
|
|
406
|
+
and defeats the body's content key. Context supplies changing consumer data while
|
|
407
|
+
preserving the module-scope component type.
|
|
408
|
+
|
|
233
409
|
## Schedule and its zones
|
|
234
410
|
|
|
235
411
|
```tsx
|
|
@@ -249,17 +425,17 @@ reserves a 48 px gutter, and fits the day columns without horizontal scrolling.
|
|
|
249
425
|
`pxPerHour` defaults to 48. Chrome takes `style`, `headerStyle`, `gutterStyle`,
|
|
250
426
|
and `daysStyle`, each with a `className` twin.
|
|
251
427
|
|
|
252
|
-
|
|
|
428
|
+
| Slot | Component inputs or node | Default and behavior |
|
|
253
429
|
| --- | --- | --- |
|
|
254
|
-
| `
|
|
255
|
-
| `
|
|
256
|
-
| `
|
|
257
|
-
| `
|
|
258
|
-
| `
|
|
259
|
-
| `
|
|
260
|
-
| `
|
|
261
|
-
| `
|
|
262
|
-
| `
|
|
430
|
+
| `gutterComponent` | `hours`, `pxPerHour` | `ScheduleGutter`: 24 frozen hour labels. |
|
|
431
|
+
| `gridComponent` | `hours`, `pxPerHour` | `ScheduleGrid`: 24 bordered hour bands behind each day's rects. |
|
|
432
|
+
| `dayHeaderComponent` | `day` | `ScheduleDayHeader`: weekday, localDate, and transition badge. |
|
|
433
|
+
| `skippedDateComponent` | `localDate` | `ScheduleSkippedDate`: zero-width header marker for a wholly skipped date. |
|
|
434
|
+
| `columnComponent` | `day`, `rects`, `gapRects`, `lane`, `highlightSource`, `press`, interval and gap components | `ScheduleColumn`: final rect bounds in layer order. |
|
|
435
|
+
| `transitionComponent` | `day`, `transition`, `y`, `dividerY`, `height`, `width` | `ScheduleTransition`: skipped-time hatch, or repeat divider and again label. |
|
|
436
|
+
| `nowLineComponent` | `y`, `column` | `ScheduleNowLine`: line in the current day's column, updated each minute. |
|
|
437
|
+
| `intervalComponent`, `gapComponent` | Same inputs as Roster | Shared `RosterInterval` and `RosterGap`. |
|
|
438
|
+
| `incompleteComponent` | `lane`, `label` | `ScheduleIncomplete`: notice above the grid when the lane is incomplete. |
|
|
263
439
|
|
|
264
440
|
## NativeWind
|
|
265
441
|
|
|
@@ -297,8 +473,8 @@ import { Roster } from 'react-native-roster';
|
|
|
297
473
|
/>
|
|
298
474
|
```
|
|
299
475
|
|
|
300
|
-
|
|
301
|
-
`
|
|
476
|
+
Slot components are ordinary React Native views, so a custom `laneLabelComponent` or
|
|
477
|
+
`intervalComponent` uses `className` on `View` and `Text` directly. Without the
|
|
302
478
|
entry point, class props are ignored and style props still work. The entry
|
|
303
479
|
point is the package's only module with side effects and is listed in
|
|
304
480
|
`sideEffects`. The [showcase route](./demo/app/showcase.tsx) styles every region
|
|
@@ -321,7 +497,7 @@ network). The home page lists every fixture route:
|
|
|
321
497
|
- The showcase at `/showcase`: twelve generated people across seven zones,
|
|
322
498
|
weekly hours and exclusions from the recurrence adapter, booked events, day
|
|
323
499
|
and week spans, sorting, filtering, and a per-person Schedule, styled with
|
|
324
|
-
NativeWind class props and
|
|
500
|
+
NativeWind class props and slot components, with a sun and moon theme toggle.
|
|
325
501
|
Names, titles, and the organization come from `@faker-js/faker` with a fixed
|
|
326
502
|
seed; any resemblance to real people is coincidental.
|
|
327
503
|
|
|
@@ -362,6 +538,7 @@ bun run check
|
|
|
362
538
|
the library build, the static web export, tests with coverage, knip, strict
|
|
363
539
|
publint, size-limit, and Playwright.
|
|
364
540
|
|
|
541
|
+
- [Migrations](https://github.com/simiancraft/react-native-roster/blob/main/docs/migrations.md) lists prop renames by version with before-and-after examples.
|
|
365
542
|
- [Adapter guide](./docs/adapters.md), [recurrence semantics](./docs/recurrence.md),
|
|
366
543
|
[timezones](./docs/timezones.md), [caches](./docs/caches.md), and the
|
|
367
544
|
[performance guide](./docs/performance.md).
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
/** Mount once at the destination for a named native portal. */
|
|
3
|
+
export declare function PortalHost({ name }: {
|
|
4
|
+
name: string;
|
|
5
|
+
}): import("react/jsx-runtime").JSX.Element[];
|
|
6
|
+
/** Register content at a named native host; caller context does not cross the store. */
|
|
7
|
+
export declare function Portal({ hostName, name, children, }: {
|
|
8
|
+
hostName: string;
|
|
9
|
+
name: string;
|
|
10
|
+
children: ReactNode;
|
|
11
|
+
}): null;
|
|
12
|
+
//# sourceMappingURL=portal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"portal.d.ts","sourceRoot":"","sources":["../../../../src/components/primitives/portal.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,SAAS,EAAmC,MAAM,OAAO,CAAC;AAgBlF,+DAA+D;AAC/D,wBAAgB,UAAU,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,6CAOpD;AAED,wFAAwF;AACxF,wBAAgB,MAAM,CAAC,EACrB,QAAQ,EACR,IAAI,EACJ,QAAQ,GACT,EAAE;IACD,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,SAAS,CAAC;CACrB,QAYA"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PortalHost = PortalHost;
|
|
4
|
+
exports.Portal = Portal;
|
|
5
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
6
|
+
const react_1 = require("react");
|
|
7
|
+
const hosts = new Map();
|
|
8
|
+
const listeners = new Set();
|
|
9
|
+
const empty = new Map();
|
|
10
|
+
function subscribe(listener) {
|
|
11
|
+
listeners.add(listener);
|
|
12
|
+
return () => listeners.delete(listener);
|
|
13
|
+
}
|
|
14
|
+
function publish(hostName, nodes) {
|
|
15
|
+
if (nodes.size)
|
|
16
|
+
hosts.set(hostName, nodes);
|
|
17
|
+
else
|
|
18
|
+
hosts.delete(hostName);
|
|
19
|
+
for (const listener of listeners)
|
|
20
|
+
listener();
|
|
21
|
+
}
|
|
22
|
+
/** Mount once at the destination for a named native portal. */
|
|
23
|
+
function PortalHost({ name }) {
|
|
24
|
+
const nodes = (0, react_1.useSyncExternalStore)(subscribe, () => hosts.get(name) ?? empty, () => empty);
|
|
25
|
+
return Array.from(nodes, ([key, node]) => (0, jsx_runtime_1.jsx)(react_1.Fragment, { children: node }, key));
|
|
26
|
+
}
|
|
27
|
+
/** Register content at a named native host; caller context does not cross the store. */
|
|
28
|
+
function Portal({ hostName, name, children, }) {
|
|
29
|
+
(0, react_1.useEffect)(() => {
|
|
30
|
+
const nodes = new Map(hosts.get(hostName));
|
|
31
|
+
nodes.set(name, children);
|
|
32
|
+
publish(hostName, nodes);
|
|
33
|
+
return () => {
|
|
34
|
+
const nodes = new Map(hosts.get(hostName));
|
|
35
|
+
nodes.delete(name);
|
|
36
|
+
publish(hostName, nodes);
|
|
37
|
+
};
|
|
38
|
+
}, [hostName, name, children]);
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=portal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"portal.js","sourceRoot":"","sources":["../../../../src/components/primitives/portal.tsx"],"names":[],"mappings":";;;;;AAAA,iCAAkF;AAElF,MAAM,KAAK,GAAG,IAAI,GAAG,EAAkC,CAAC;AACxD,MAAM,SAAS,GAAG,IAAI,GAAG,EAAc,CAAC;AACxC,MAAM,KAAK,GAAG,IAAI,GAAG,EAAqB,CAAC;AAE3C,SAAS,SAAS,CAAC,QAAoB;IACrC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACxB,OAAO,GAAG,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;AAC1C,CAAC;AACD,SAAS,OAAO,CAAC,QAAgB,EAAE,KAA6B;IAC9D,IAAI,KAAK,CAAC,IAAI;QAAE,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;;QACtC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC5B,KAAK,MAAM,QAAQ,IAAI,SAAS;QAAE,QAAQ,EAAE,CAAC;AAC/C,CAAC;AAED,+DAA+D;AAC/D,oBAA2B,EAAE,IAAI,EAAoB;IACnD,MAAM,KAAK,GAAG,IAAA,4BAAoB,EAChC,SAAS,EACT,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,KAAK,EAC9B,GAAG,EAAE,CAAC,KAAK,CACZ,CAAC;IACF,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,uBAAC,gBAAQ,cAAY,IAAI,IAAV,GAAG,CAAmB,CAAC,CAAC;AACnF,CAAC;AAED,wFAAwF;AACxF,gBAAuB,EACrB,QAAQ,EACR,IAAI,EACJ,QAAQ,GAKT;IACC,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC3C,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAC1B,OAAO,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;QACzB,OAAO,GAAG,EAAE;YACV,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC;YAC3C,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YACnB,OAAO,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;QAC3B,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,QAAQ,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC/B,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import type { BodyInput } from './roster.types';
|
|
3
|
+
export declare function RosterBodyLayout({ scroll, contentWidth, viewport, gridZone, listZone, }: Pick<BodyInput, 'scroll' | 'contentWidth' | 'viewport'> & {
|
|
4
|
+
/** Noninteractive grid behind the lane list. */
|
|
5
|
+
gridZone: ReactNode;
|
|
6
|
+
/** Virtualized lane collection within the measured viewport. */
|
|
7
|
+
listZone: ReactNode;
|
|
8
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
//# sourceMappingURL=body-layout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"body-layout.d.ts","sourceRoot":"","sources":["../../../../src/components/roster/body-layout.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAuB,MAAM,OAAO,CAAC;AAE5D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD,wBAAgB,gBAAgB,CAAC,EAC/B,MAAM,EACN,YAAY,EACZ,QAAQ,EACR,QAAQ,EACR,QAAQ,GACT,EAAE,IAAI,CAAC,SAAS,EAAE,QAAQ,GAAG,cAAc,GAAG,UAAU,CAAC,GAAG;IAC3D,gDAAgD;IAChD,QAAQ,EAAE,SAAS,CAAC;IACpB,gEAAgE;IAChE,QAAQ,EAAE,SAAS,CAAC;CACrB,2CAsBA"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RosterBodyLayout = RosterBodyLayout;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const react_1 = require("react");
|
|
6
|
+
const react_native_1 = require("react-native");
|
|
7
|
+
function RosterBodyLayout({ scroll, contentWidth, viewport, gridZone, listZone, }) {
|
|
8
|
+
const [contentOffset] = (0, react_1.useState)(() => ({ x: scroll.x.get(), y: 0 }));
|
|
9
|
+
const bodyRef = scroll.bodyRef;
|
|
10
|
+
(0, react_1.useEffect)(() => {
|
|
11
|
+
bodyRef.current?.scrollTo({ x: contentOffset.x, animated: false });
|
|
12
|
+
}, [bodyRef, contentOffset]);
|
|
13
|
+
return ((0, jsx_runtime_1.jsx)(react_native_1.ScrollView, { testID: "roster-horizontal-scroll", ref: scroll.bodyRef, contentOffset: contentOffset, horizontal: true, onScroll: scroll.onBodyScroll, scrollEventThrottle: 16, style: { flex: 1 }, children: (0, jsx_runtime_1.jsxs)(react_native_1.View, { style: { width: contentWidth, height: viewport.height }, children: [gridZone, listZone] }) }));
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=body-layout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"body-layout.js","sourceRoot":"","sources":["../../../../src/components/roster/body-layout.tsx"],"names":[],"mappings":";;;;AAAA,iCAA4D;AAC5D,+CAAgD;AAGhD,0BAAiC,EAC/B,MAAM,EACN,YAAY,EACZ,QAAQ,EACR,QAAQ,EACR,QAAQ,GAMT;IACC,MAAM,CAAC,aAAa,CAAC,GAAG,IAAA,gBAAQ,EAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IACtE,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;IAC/B,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE,CAAC,EAAE,aAAa,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;IACrE,CAAC,EAAE,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC;IAC7B,OAAO,CACL,uBAAC,yBAAU,IACT,MAAM,EAAC,0BAA0B,EACjC,GAAG,EAAE,MAAM,CAAC,OAAO,EACnB,aAAa,EAAE,aAAa,EAC5B,UAAU,QACV,QAAQ,EAAE,MAAM,CAAC,YAAY,EAC7B,mBAAmB,EAAE,EAAE,EACvB,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,YAElB,wBAAC,mBAAI,IAAC,KAAK,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,aAC1D,QAAQ,EACR,QAAQ,IACJ,GACI,CACd,CAAC;AACJ,CAAC"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
1
2
|
import type { RosterProps } from './roster.types';
|
|
2
|
-
export declare function Roster(props: RosterProps): string | number | bigint | boolean | import("react/jsx-runtime").JSX.Element | Iterable<
|
|
3
|
+
export declare function Roster(props: RosterProps): string | number | bigint | boolean | import("react/jsx-runtime").JSX.Element | Iterable<ReactNode> | Promise<string | number | bigint | boolean | Iterable<ReactNode> | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | import("react").ReactPortal | null | undefined> | null;
|
|
3
4
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/roster/index.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/roster/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAS,MAAM,OAAO,CAAC;AAa9C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAQlD,wBAAgB,MAAM,CAAC,KAAK,EAAE,WAAW,+TAmIxC"}
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Roster = Roster;
|
|
4
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const react_1 = require("react");
|
|
6
|
+
const core_1 = require("../../core");
|
|
5
7
|
const gap_1 = require("../layers/parts/gap");
|
|
6
8
|
const interval_1 = require("../layers/parts/interval");
|
|
7
9
|
const lane_label_1 = require("./lanes/parts/lane-label");
|
|
@@ -13,17 +15,37 @@ const grid_1 = require("./parts/grid");
|
|
|
13
15
|
const header_1 = require("./parts/header");
|
|
14
16
|
const header_cell_1 = require("./parts/header-cell");
|
|
15
17
|
const lane_label_column_1 = require("./parts/lane-label-column");
|
|
18
|
+
const selection_layout_1 = require("./selection/selection-layout");
|
|
16
19
|
const use_roster_1 = require("./use-roster");
|
|
20
|
+
const defaultEmptyZone = (0, jsx_runtime_1.jsx)(empty_1.RosterEmpty, {});
|
|
21
|
+
const defaultCornerZone = (0, jsx_runtime_1.jsx)(corner_1.RosterCorner, {});
|
|
17
22
|
function Roster(props) {
|
|
18
|
-
const { status, orderedLanes, laneState, window, geometryFor, projection, scroll, press, ticks, contentWidth, viewport, onLayout, } = (0, use_roster_1.useRoster)(props);
|
|
19
|
-
const {
|
|
23
|
+
const { selection, dismissSelection, status, orderedLanes, laneState, window, geometryFor, projection, scroll, press, ticks, contentWidth, viewport, onLayout, } = (0, use_roster_1.useRoster)({ ...props, selectable: Boolean(props.intervalDetailComponent) });
|
|
24
|
+
const { intervalDetailComponent: IntervalDetailComponent, selectionLayout: SelectionLayout = selection_layout_1.RosterSelectionPopover, emptyZone = defaultEmptyZone, cornerZone = defaultCornerZone, headerComponent: HeaderComponent = header_1.RosterHeader, laneLabelColumnComponent: LaneLabelColumnComponent = lane_label_column_1.RosterLaneLabelColumn, bodyComponent: BodyComponent = body_1.RosterBody, headerCellComponent = header_cell_1.RosterHeaderCell, laneLabelComponent = lane_label_1.RosterLaneLabel, intervalComponent = interval_1.RosterInterval, gapComponent = gap_1.RosterGap, gridComponent = grid_1.RosterGrid, incompleteLabel = 'Availability may be incomplete', neverSetLabel = 'No availability set', } = props;
|
|
25
|
+
const hostId = (0, react_1.useId)();
|
|
20
26
|
if (status === 'empty')
|
|
21
|
-
return emptyZone
|
|
27
|
+
return emptyZone;
|
|
22
28
|
if (window.start === window.end)
|
|
23
29
|
return null;
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
30
|
+
let targetBounds = null;
|
|
31
|
+
if (selection) {
|
|
32
|
+
targetBounds = {
|
|
33
|
+
x: selection.rect.x,
|
|
34
|
+
y: orderedLanes.findIndex((lane) => lane.id === selection.lane.id) * projection.rowHeight +
|
|
35
|
+
selection.rect.y,
|
|
36
|
+
width: selection.rect.width,
|
|
37
|
+
height: selection.rect.height,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
let contentZone = null;
|
|
41
|
+
if (selection && IntervalDetailComponent) {
|
|
42
|
+
contentZone = ((0, jsx_runtime_1.jsx)(IntervalDetailComponent, { ...selection, viewTimezone: projection.viewTimezone, highlighted: (0, core_1.hasSource)(selection.rect.sources, props.highlightSource) }));
|
|
43
|
+
}
|
|
44
|
+
return ((0, jsx_runtime_1.jsx)(layout_1.RosterLayout, { style: props.style, headerStyle: props.headerStyle, laneLabelColumnStyle: props.laneLabelColumnStyle, bodyStyle: props.bodyStyle, laneLabelWidth: props.laneLabelWidth, onLayout: onLayout, cornerZone: cornerZone, headerZone: (0, jsx_runtime_1.jsx)(HeaderComponent, { ticks: ticks, projection: projection, scroll: scroll, contentWidth: contentWidth, headerCellComponent: headerCellComponent }), laneLabelColumnZone: (0, jsx_runtime_1.jsx)(LaneLabelColumnComponent, { labels: orderedLanes.map((lane) => {
|
|
45
|
+
const state = laneState.get(lane.id) ?? {
|
|
46
|
+
flag: 'none',
|
|
47
|
+
complete: true,
|
|
48
|
+
};
|
|
27
49
|
return {
|
|
28
50
|
lane,
|
|
29
51
|
...state,
|
|
@@ -31,26 +53,11 @@ function Roster(props) {
|
|
|
31
53
|
incompleteLabel,
|
|
32
54
|
neverSetLabel,
|
|
33
55
|
};
|
|
34
|
-
}),
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
lanes: orderedLanes,
|
|
40
|
-
window,
|
|
41
|
-
geometryFor,
|
|
42
|
-
projection,
|
|
43
|
-
scroll,
|
|
44
|
-
press,
|
|
45
|
-
ticks,
|
|
46
|
-
contentWidth,
|
|
47
|
-
viewport,
|
|
48
|
-
intervalZone,
|
|
49
|
-
gapZone,
|
|
50
|
-
gridZone,
|
|
51
|
-
highlightSource: props.highlightSource,
|
|
52
|
-
onIntervalHover: props.onIntervalHover,
|
|
53
|
-
incompleteLabel,
|
|
54
|
-
}) }));
|
|
56
|
+
}), projection: projection, scroll: scroll, laneLabelComponent: laneLabelComponent }), bodyZone: (0, jsx_runtime_1.jsx)(SelectionLayout, { portalHost: props.portalHost ?? `roster-${hostId}`, open: selection !== null, onDismiss: dismissSelection, scroll: {
|
|
57
|
+
x: scroll.x,
|
|
58
|
+
y: scroll.y,
|
|
59
|
+
headerStyle: scroll.headerStyle,
|
|
60
|
+
labelStyle: scroll.labelStyle,
|
|
61
|
+
}, targetBounds: targetBounds, contentZone: contentZone, anchorZone: (0, jsx_runtime_1.jsx)(BodyComponent, { lanes: orderedLanes, window: window, geometryFor: geometryFor, projection: projection, scroll: scroll, press: press, ticks: ticks, contentWidth: contentWidth, viewport: viewport, intervalComponent: intervalComponent, gapComponent: gapComponent, gridComponent: gridComponent, highlightSource: props.highlightSource, onIntervalHover: props.onIntervalHover, incompleteLabel: incompleteLabel }) }) }));
|
|
55
62
|
}
|
|
56
63
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/components/roster/index.tsx"],"names":[],"mappings":";;;;AAAA,6CAAgD;AAChD,uDAA0D;AAC1D,yDAA2D;AAC3D,qCAAwC;AACxC,uCAA0C;AAC1C,2CAA8C;AAC9C,yCAA4C;AAC5C,uCAA0C;AAC1C,2CAA8C;AAC9C,qDAAuD;AACvD,iEAAkE;AAElE,6CAAyC;AAEzC,gBAAuB,KAAkB;IACvC,MAAM,EACJ,MAAM,EACN,YAAY,EACZ,SAAS,EACT,MAAM,EACN,WAAW,EACX,UAAU,EACV,MAAM,EACN,KAAK,EACL,KAAK,EACL,YAAY,EACZ,QAAQ,EACR,QAAQ,GACT,GAAG,IAAA,sBAAS,EAAC,KAAK,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/components/roster/index.tsx"],"names":[],"mappings":";;;;AAAA,iCAA8C;AAC9C,qCAAuC;AACvC,6CAAgD;AAChD,uDAA0D;AAC1D,yDAA2D;AAC3D,qCAAwC;AACxC,uCAA0C;AAC1C,2CAA8C;AAC9C,yCAA4C;AAC5C,uCAA0C;AAC1C,2CAA8C;AAC9C,qDAAuD;AACvD,iEAAkE;AAElE,mEAAsE;AAEtE,6CAAyC;AAEzC,MAAM,gBAAgB,GAAG,uBAAC,mBAAW,KAAG,CAAC;AACzC,MAAM,iBAAiB,GAAG,uBAAC,qBAAY,KAAG,CAAC;AAE3C,gBAAuB,KAAkB;IACvC,MAAM,EACJ,SAAS,EACT,gBAAgB,EAChB,MAAM,EACN,YAAY,EACZ,SAAS,EACT,MAAM,EACN,WAAW,EACX,UAAU,EACV,MAAM,EACN,KAAK,EACL,KAAK,EACL,YAAY,EACZ,QAAQ,EACR,QAAQ,GACT,GAAG,IAAA,sBAAS,EAAC,EAAE,GAAG,KAAK,EAAE,UAAU,EAAE,OAAO,CAAC,KAAK,CAAC,uBAAuB,CAAC,EAAE,CAAC,CAAC;IAChF,MAAM,EACJ,uBAAuB,EAAE,uBAAuB,EAChD,eAAe,EAAE,eAAe,GAAG,yCAAsB,EACzD,SAAS,GAAG,gBAAgB,EAC5B,UAAU,GAAG,iBAAiB,EAC9B,eAAe,EAAE,eAAe,GAAG,qBAAY,EAC/C,wBAAwB,EAAE,wBAAwB,GAAG,yCAAqB,EAC1E,aAAa,EAAE,aAAa,GAAG,iBAAU,EACzC,mBAAmB,GAAG,8BAAgB,EACtC,kBAAkB,GAAG,4BAAe,EACpC,iBAAiB,GAAG,yBAAc,EAClC,YAAY,GAAG,eAAS,EACxB,aAAa,GAAG,iBAAU,EAC1B,eAAe,GAAG,gCAAgC,EAClD,aAAa,GAAG,qBAAqB,GACtC,GAAG,KAAK,CAAC;IACV,MAAM,MAAM,GAAG,IAAA,aAAK,GAAE,CAAC;IACvB,IAAI,MAAM,KAAK,OAAO;QAAE,OAAO,SAAS,CAAC;IACzC,IAAI,MAAM,CAAC,KAAK,KAAK,MAAM,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IAC7C,IAAI,YAAY,GAAyC,IAAI,CAAC;IAC9D,IAAI,SAAS,EAAE,CAAC;QACd,YAAY,GAAG;YACb,CAAC,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;YACnB,CAAC,EACC,YAAY,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,SAAS;gBACtF,SAAS,CAAC,IAAI,CAAC,CAAC;YAClB,KAAK,EAAE,SAAS,CAAC,IAAI,CAAC,KAAK;YAC3B,MAAM,EAAE,SAAS,CAAC,IAAI,CAAC,MAAM;SAC9B,CAAC;IACJ,CAAC;IACD,IAAI,WAAW,GAAc,IAAI,CAAC;IAClC,IAAI,SAAS,IAAI,uBAAuB,EAAE,CAAC;QACzC,WAAW,GAAG,CACZ,uBAAC,uBAAuB,OAClB,SAAS,EACb,YAAY,EAAE,UAAU,CAAC,YAAY,EACrC,WAAW,EAAE,IAAA,gBAAS,EAAC,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,eAAe,CAAC,GACrE,CACH,CAAC;IACJ,CAAC;IACD,OAAO,CACL,uBAAC,qBAAY,IACX,KAAK,EAAE,KAAK,CAAC,KAAK,EAClB,WAAW,EAAE,KAAK,CAAC,WAAW,EAC9B,oBAAoB,EAAE,KAAK,CAAC,oBAAoB,EAChD,SAAS,EAAE,KAAK,CAAC,SAAS,EAC1B,cAAc,EAAE,KAAK,CAAC,cAAc,EACpC,QAAQ,EAAE,QAAQ,EAClB,UAAU,EAAE,UAAU,EACtB,UAAU,EACR,uBAAC,eAAe,IACd,KAAK,EAAE,KAAK,EACZ,UAAU,EAAE,UAAU,EACtB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,YAAY,EAC1B,mBAAmB,EAAE,mBAAmB,GACxC,EAEJ,mBAAmB,EACjB,uBAAC,wBAAwB,IACvB,MAAM,EAAE,YAAY,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;gBAChC,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI;oBACtC,IAAI,EAAE,MAAM;oBACZ,QAAQ,EAAE,IAAI;iBACf,CAAC;gBACF,OAAO;oBACL,IAAI;oBACJ,GAAG,KAAK;oBACR,YAAY,EAAE,UAAU,CAAC,YAAY;oBACrC,eAAe;oBACf,aAAa;iBACd,CAAC;YACJ,CAAC,CAAC,EACF,UAAU,EAAE,UAAU,EACtB,MAAM,EAAE,MAAM,EACd,kBAAkB,EAAE,kBAAkB,GACtC,EAEJ,QAAQ,EACN,uBAAC,eAAe,IACd,UAAU,EAAE,KAAK,CAAC,UAAU,IAAI,UAAU,MAAM,EAAE,EAClD,IAAI,EAAE,SAAS,KAAK,IAAI,EACxB,SAAS,EAAE,gBAAgB,EAC3B,MAAM,EAAE;gBACN,CAAC,EAAE,MAAM,CAAC,CAAC;gBACX,CAAC,EAAE,MAAM,CAAC,CAAC;gBACX,WAAW,EAAE,MAAM,CAAC,WAAW;gBAC/B,UAAU,EAAE,MAAM,CAAC,UAAU;aAC9B,EACD,YAAY,EAAE,YAAY,EAC1B,WAAW,EAAE,WAAW,EACxB,UAAU,EACR,uBAAC,aAAa,IACZ,KAAK,EAAE,YAAY,EACnB,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,WAAW,EACxB,UAAU,EAAE,UAAU,EACtB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,KAAK,EACZ,YAAY,EAAE,YAAY,EAC1B,QAAQ,EAAE,QAAQ,EAClB,iBAAiB,EAAE,iBAAiB,EACpC,YAAY,EAAE,YAAY,EAC1B,aAAa,EAAE,aAAa,EAC5B,eAAe,EAAE,KAAK,CAAC,eAAe,EACtC,eAAe,EAAE,KAAK,CAAC,eAAe,EACtC,eAAe,EAAE,eAAe,GAChC,GAEJ,GAEJ,CACH,CAAC;AACJ,CAAC"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import type { Lane, LaneGeometry } from '../../../core';
|
|
2
2
|
import type { BodyInput } from '../roster.types';
|
|
3
|
-
export type LaneRowProps = Pick<BodyInput, 'press' | '
|
|
3
|
+
export type LaneRowProps = Pick<BodyInput, 'press' | 'intervalComponent' | 'gapComponent' | 'highlightSource' | 'onIntervalHover' | 'incompleteLabel'> & {
|
|
4
4
|
lane: Lane;
|
|
5
5
|
geometry: LaneGeometry;
|
|
6
6
|
width: number;
|
|
7
7
|
rowHeight: number;
|
|
8
8
|
};
|
|
9
|
-
export declare function LaneRow({ lane, geometry, width, rowHeight, press,
|
|
9
|
+
export declare function LaneRow({ lane, geometry, width, rowHeight, press, intervalComponent: IntervalComponent, gapComponent: GapComponent, highlightSource, onIntervalHover, incompleteLabel, }: LaneRowProps): import("react/jsx-runtime").JSX.Element;
|
|
10
10
|
//# sourceMappingURL=lane.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lane.d.ts","sourceRoot":"","sources":["../../../../../src/components/roster/lanes/lane.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"lane.d.ts","sourceRoot":"","sources":["../../../../../src/components/roster/lanes/lane.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAGxD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAIjD,MAAM,MAAM,YAAY,GAAG,IAAI,CAC7B,SAAS,EACP,OAAO,GACP,mBAAmB,GACnB,cAAc,GACd,iBAAiB,GACjB,iBAAiB,GACjB,iBAAiB,CACpB,GAAG;IACF,IAAI,EAAE,IAAI,CAAC;IACX,QAAQ,EAAE,YAAY,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,wBAAgB,OAAO,CAAC,EACtB,IAAI,EACJ,QAAQ,EACR,KAAK,EACL,SAAS,EACT,KAAK,EACL,iBAAiB,EAAE,iBAAiB,EACpC,YAAY,EAAE,YAAY,EAC1B,eAAe,EACf,eAAe,EACf,eAAkD,GACnD,EAAE,YAAY,2CAuDd"}
|
|
@@ -4,22 +4,18 @@ exports.LaneRow = LaneRow;
|
|
|
4
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
5
|
const react_1 = require("react");
|
|
6
6
|
const react_native_1 = require("react-native");
|
|
7
|
+
const core_1 = require("../../../core");
|
|
7
8
|
const press_point_1 = require("../../primitives/press-point");
|
|
8
9
|
const interval_hover_1 = require("./interval-hover");
|
|
9
10
|
const incomplete_1 = require("./parts/incomplete");
|
|
10
|
-
function LaneRow({ lane, geometry, width, rowHeight, press,
|
|
11
|
+
function LaneRow({ lane, geometry, width, rowHeight, press, intervalComponent: IntervalComponent, gapComponent: GapComponent, highlightSource, onIntervalHover, incompleteLabel = 'Availability may be incomplete', }) {
|
|
11
12
|
const layers = [...lane.layers].sort((a, b) => a.z - b.z);
|
|
12
13
|
return ((0, jsx_runtime_1.jsxs)(react_native_1.Pressable, { ...(0, interval_hover_1.intervalHoverProps)({ lane, geometry, onIntervalHover }), testID: `roster-lane-${lane.id}`, accessibilityLabel: lane.label, onPress: (input) => {
|
|
13
14
|
const point = (0, press_point_1.pressPoint)(input);
|
|
14
15
|
press(lane, point.x, point.y);
|
|
15
16
|
}, style: { width, height: rowHeight }, children: [(0, jsx_runtime_1.jsx)(incomplete_1.RosterIncomplete, { lane: lane, geometry: geometry, width: width, label: incompleteLabel }), layers.map((layer) => ((0, jsx_runtime_1.jsxs)(react_1.Fragment, { children: [geometry.rects
|
|
16
17
|
.filter((rect) => rect.layerId === layer.id)
|
|
17
|
-
.map((rect) => ((0, jsx_runtime_1.jsx)(react_1.Fragment, { children:
|
|
18
|
-
rect,
|
|
19
|
-
layer,
|
|
20
|
-
lane,
|
|
21
|
-
highlighted: rect.sources.some((source) => source.kind === highlightSource?.kind && source.id === highlightSource.id),
|
|
22
|
-
}) }, `interval-${rect.x}:${rect.width}`))), geometry.gapRects
|
|
18
|
+
.map((rect) => ((0, jsx_runtime_1.jsx)(react_1.Fragment, { children: (0, jsx_runtime_1.jsx)(IntervalComponent, { rect: rect, layer: layer, lane: lane, highlighted: (0, core_1.hasSource)(rect.sources, highlightSource) }) }, `interval-${rect.x}:${rect.width}`))), geometry.gapRects
|
|
23
19
|
.filter((rect) => rect.layerId === layer.id)
|
|
24
20
|
.map((rect) => ((0, jsx_runtime_1.jsx)(react_native_1.Pressable, { accessibilityLabel: `${lane.label}: removed time`, onPress: (input) => {
|
|
25
21
|
input.stopPropagation();
|
|
@@ -32,6 +28,6 @@ function LaneRow({ lane, geometry, width, rowHeight, press, intervalZone, gapZon
|
|
|
32
28
|
width: rect.width,
|
|
33
29
|
height: rect.height,
|
|
34
30
|
zIndex: rect.z,
|
|
35
|
-
}, children:
|
|
31
|
+
}, children: (0, jsx_runtime_1.jsx)(GapComponent, { rect: rect, layer: layer, lane: lane }) }, `gap-${rect.x}:${rect.width}`)))] }, layer.id)))] }));
|
|
36
32
|
}
|
|
37
33
|
//# sourceMappingURL=lane.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lane.js","sourceRoot":"","sources":["../../../../../src/components/roster/lanes/lane.tsx"],"names":[],"mappings":";;;;AAAA,iCAAiC;AACjC,+CAAyC;AAEzC,8DAA0D;AAE1D,qDAAsD;AACtD,mDAAsD;
|
|
1
|
+
{"version":3,"file":"lane.js","sourceRoot":"","sources":["../../../../../src/components/roster/lanes/lane.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { ProfilerOnRenderCallback } from 'react';
|
|
2
2
|
import type { BodyInput } from '../roster.types';
|
|
3
|
-
export declare function RosterBody(
|
|
4
|
-
/**
|
|
3
|
+
export declare function RosterBody(props: BodyInput & {
|
|
4
|
+
/** Development-only Profiler hook used by the gallery; not a supported customization point. */
|
|
5
5
|
onRowRender?: ProfilerOnRenderCallback;
|
|
6
6
|
}): import("react/jsx-runtime").JSX.Element | null;
|
|
7
7
|
//# sourceMappingURL=body.d.ts.map
|