react-native-roster 0.0.0 → 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.
- package/NOTICE.md +29 -0
- package/README.md +455 -2
- package/dist/src/adapters/rrule/cache.d.ts +15 -0
- package/dist/src/adapters/rrule/cache.d.ts.map +1 -0
- package/dist/src/adapters/rrule/cache.js +53 -0
- package/dist/src/adapters/rrule/cache.js.map +1 -0
- package/dist/src/adapters/rrule/envelope.d.ts +3 -0
- package/dist/src/adapters/rrule/envelope.d.ts.map +1 -0
- package/dist/src/adapters/rrule/envelope.js +9 -0
- package/dist/src/adapters/rrule/envelope.js.map +1 -0
- package/dist/src/adapters/rrule/expand.d.ts +4 -0
- package/dist/src/adapters/rrule/expand.d.ts.map +1 -0
- package/dist/src/adapters/rrule/expand.js +92 -0
- package/dist/src/adapters/rrule/expand.js.map +1 -0
- package/dist/src/adapters/rrule/hash.d.ts +3 -0
- package/dist/src/adapters/rrule/hash.d.ts.map +1 -0
- package/dist/src/adapters/rrule/hash.js +15 -0
- package/dist/src/adapters/rrule/hash.js.map +1 -0
- package/dist/src/adapters/rrule/index.d.ts +5 -0
- package/dist/src/adapters/rrule/index.d.ts.map +1 -0
- package/dist/src/adapters/rrule/index.js +12 -0
- package/dist/src/adapters/rrule/index.js.map +1 -0
- package/dist/src/adapters/rrule/net.d.ts +6 -0
- package/dist/src/adapters/rrule/net.d.ts.map +1 -0
- package/dist/src/adapters/rrule/net.js +31 -0
- package/dist/src/adapters/rrule/net.js.map +1 -0
- package/dist/src/adapters/rrule/occurrences.d.ts +6 -0
- package/dist/src/adapters/rrule/occurrences.d.ts.map +1 -0
- package/dist/src/adapters/rrule/occurrences.js +252 -0
- package/dist/src/adapters/rrule/occurrences.js.map +1 -0
- package/dist/src/adapters/rrule/types.d.ts +62 -0
- package/dist/src/adapters/rrule/types.d.ts.map +1 -0
- package/dist/src/adapters/rrule/types.js +3 -0
- package/dist/src/adapters/rrule/types.js.map +1 -0
- package/dist/src/adapters/rrule/validate.d.ts +6 -0
- package/dist/src/adapters/rrule/validate.d.ts.map +1 -0
- package/dist/src/adapters/rrule/validate.js +64 -0
- package/dist/src/adapters/rrule/validate.js.map +1 -0
- package/dist/src/components/layers/layers.types.d.ts +15 -0
- package/dist/src/components/layers/layers.types.d.ts.map +1 -0
- package/dist/src/components/layers/layers.types.js +3 -0
- package/dist/src/components/layers/layers.types.js.map +1 -0
- package/dist/src/components/layers/parts/gap.d.ts +3 -0
- package/dist/src/components/layers/parts/gap.d.ts.map +1 -0
- package/dist/src/components/layers/parts/gap.js +7 -0
- package/dist/src/components/layers/parts/gap.js.map +1 -0
- package/dist/src/components/layers/parts/interval.d.ts +3 -0
- package/dist/src/components/layers/parts/interval.d.ts.map +1 -0
- package/dist/src/components/layers/parts/interval.js +22 -0
- package/dist/src/components/layers/parts/interval.js.map +1 -0
- package/dist/src/components/layers/utils/styles.d.ts +7 -0
- package/dist/src/components/layers/utils/styles.d.ts.map +1 -0
- package/dist/src/components/layers/utils/styles.js +24 -0
- package/dist/src/components/layers/utils/styles.js.map +1 -0
- package/dist/src/components/primitives/press-point.d.ts +3 -0
- package/dist/src/components/primitives/press-point.d.ts.map +1 -0
- package/dist/src/components/primitives/press-point.js +7 -0
- package/dist/src/components/primitives/press-point.js.map +1 -0
- package/dist/src/components/primitives/press-point.types.d.ts +14 -0
- package/dist/src/components/primitives/press-point.types.d.ts.map +1 -0
- package/dist/src/components/primitives/press-point.types.js +3 -0
- package/dist/src/components/primitives/press-point.types.js.map +1 -0
- package/dist/src/components/primitives/press-point.web.d.ts +3 -0
- package/dist/src/components/primitives/press-point.web.d.ts.map +1 -0
- package/dist/src/components/primitives/press-point.web.js +17 -0
- package/dist/src/components/primitives/press-point.web.js.map +1 -0
- package/dist/src/components/primitives/region-style.d.ts +9 -0
- package/dist/src/components/primitives/region-style.d.ts.map +1 -0
- package/dist/src/components/primitives/region-style.js +20 -0
- package/dist/src/components/primitives/region-style.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 +9 -0
- package/dist/src/components/roster/body-layout.js.map +1 -0
- package/dist/src/components/roster/index.d.ts +3 -0
- package/dist/src/components/roster/index.d.ts.map +1 -0
- package/dist/src/components/roster/index.js +40 -0
- package/dist/src/components/roster/index.js.map +1 -0
- package/dist/src/components/roster/lanes/interval-hover.d.ts +3 -0
- package/dist/src/components/roster/lanes/interval-hover.d.ts.map +1 -0
- package/dist/src/components/roster/lanes/interval-hover.js +7 -0
- package/dist/src/components/roster/lanes/interval-hover.js.map +1 -0
- package/dist/src/components/roster/lanes/interval-hover.types.d.ts +15 -0
- package/dist/src/components/roster/lanes/interval-hover.types.d.ts.map +1 -0
- package/dist/src/components/roster/lanes/interval-hover.types.js +3 -0
- package/dist/src/components/roster/lanes/interval-hover.types.js.map +1 -0
- package/dist/src/components/roster/lanes/interval-hover.web.d.ts +3 -0
- package/dist/src/components/roster/lanes/interval-hover.web.d.ts.map +1 -0
- package/dist/src/components/roster/lanes/interval-hover.web.js +20 -0
- package/dist/src/components/roster/lanes/interval-hover.web.js.map +1 -0
- package/dist/src/components/roster/lanes/lane.d.ts +10 -0
- package/dist/src/components/roster/lanes/lane.d.ts.map +1 -0
- package/dist/src/components/roster/lanes/lane.js +32 -0
- package/dist/src/components/roster/lanes/lane.js.map +1 -0
- package/dist/src/components/roster/lanes/parts/incomplete.d.ts +8 -0
- package/dist/src/components/roster/lanes/parts/incomplete.d.ts.map +1 -0
- package/dist/src/components/roster/lanes/parts/incomplete.js +30 -0
- package/dist/src/components/roster/lanes/parts/incomplete.js.map +1 -0
- package/dist/src/components/roster/lanes/parts/lane-label.d.ts +3 -0
- package/dist/src/components/roster/lanes/parts/lane-label.d.ts.map +1 -0
- package/dist/src/components/roster/lanes/parts/lane-label.js +18 -0
- package/dist/src/components/roster/lanes/parts/lane-label.js.map +1 -0
- package/dist/src/components/roster/layout.d.ts +17 -0
- package/dist/src/components/roster/layout.d.ts.map +1 -0
- package/dist/src/components/roster/layout.js +24 -0
- package/dist/src/components/roster/layout.js.map +1 -0
- package/dist/src/components/roster/parts/body.d.ts +7 -0
- package/dist/src/components/roster/parts/body.d.ts.map +1 -0
- package/dist/src/components/roster/parts/body.js +14 -0
- package/dist/src/components/roster/parts/body.js.map +1 -0
- package/dist/src/components/roster/parts/corner.d.ts +2 -0
- package/dist/src/components/roster/parts/corner.d.ts.map +1 -0
- package/dist/src/components/roster/parts/corner.js +7 -0
- package/dist/src/components/roster/parts/corner.js.map +1 -0
- package/dist/src/components/roster/parts/empty.d.ts +2 -0
- package/dist/src/components/roster/parts/empty.d.ts.map +1 -0
- package/dist/src/components/roster/parts/empty.js +9 -0
- package/dist/src/components/roster/parts/empty.js.map +1 -0
- package/dist/src/components/roster/parts/grid.d.ts +3 -0
- package/dist/src/components/roster/parts/grid.d.ts.map +1 -0
- package/dist/src/components/roster/parts/grid.js +16 -0
- package/dist/src/components/roster/parts/grid.js.map +1 -0
- package/dist/src/components/roster/parts/header-cell.d.ts +3 -0
- package/dist/src/components/roster/parts/header-cell.d.ts.map +1 -0
- package/dist/src/components/roster/parts/header-cell.js +9 -0
- package/dist/src/components/roster/parts/header-cell.js.map +1 -0
- package/dist/src/components/roster/parts/header.d.ts +3 -0
- package/dist/src/components/roster/parts/header.d.ts.map +1 -0
- package/dist/src/components/roster/parts/header.js +13 -0
- package/dist/src/components/roster/parts/header.js.map +1 -0
- package/dist/src/components/roster/parts/lane-label-column.d.ts +3 -0
- package/dist/src/components/roster/parts/lane-label-column.d.ts.map +1 -0
- package/dist/src/components/roster/parts/lane-label-column.js +18 -0
- package/dist/src/components/roster/parts/lane-label-column.js.map +1 -0
- 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 +25 -0
- package/dist/src/components/roster/parts/lane-list.js.map +1 -0
- package/dist/src/components/roster/roster.types.d.ts +145 -0
- package/dist/src/components/roster/roster.types.d.ts.map +1 -0
- package/dist/src/components/roster/roster.types.js +3 -0
- package/dist/src/components/roster/roster.types.js.map +1 -0
- package/dist/src/components/roster/use-roster.d.ts +3 -0
- package/dist/src/components/roster/use-roster.d.ts.map +1 -0
- package/dist/src/components/roster/use-roster.js +106 -0
- package/dist/src/components/roster/use-roster.js.map +1 -0
- package/dist/src/components/roster/utils/body-content-key.d.ts +3 -0
- package/dist/src/components/roster/utils/body-content-key.d.ts.map +1 -0
- package/dist/src/components/roster/utils/body-content-key.js +29 -0
- package/dist/src/components/roster/utils/body-content-key.js.map +1 -0
- package/dist/src/components/roster/utils/ticks.d.ts +4 -0
- package/dist/src/components/roster/utils/ticks.d.ts.map +1 -0
- package/dist/src/components/roster/utils/ticks.js +60 -0
- package/dist/src/components/roster/utils/ticks.js.map +1 -0
- package/dist/src/components/schedule/days/day.d.ts +20 -0
- package/dist/src/components/schedule/days/day.d.ts.map +1 -0
- package/dist/src/components/schedule/days/day.js +17 -0
- package/dist/src/components/schedule/days/day.js.map +1 -0
- package/dist/src/components/schedule/days/header-layout.d.ts +9 -0
- package/dist/src/components/schedule/days/header-layout.d.ts.map +1 -0
- package/dist/src/components/schedule/days/header-layout.js +9 -0
- package/dist/src/components/schedule/days/header-layout.js.map +1 -0
- package/dist/src/components/schedule/days/layout.d.ts +18 -0
- package/dist/src/components/schedule/days/layout.d.ts.map +1 -0
- package/dist/src/components/schedule/days/layout.js +9 -0
- package/dist/src/components/schedule/days/layout.js.map +1 -0
- package/dist/src/components/schedule/days/parts/column.d.ts +3 -0
- package/dist/src/components/schedule/days/parts/column.d.ts.map +1 -0
- package/dist/src/components/schedule/days/parts/column.js +28 -0
- package/dist/src/components/schedule/days/parts/column.js.map +1 -0
- package/dist/src/components/schedule/days/parts/day-header.d.ts +5 -0
- package/dist/src/components/schedule/days/parts/day-header.d.ts.map +1 -0
- package/dist/src/components/schedule/days/parts/day-header.js +10 -0
- package/dist/src/components/schedule/days/parts/day-header.js.map +1 -0
- package/dist/src/components/schedule/days/parts/grid.d.ts +3 -0
- package/dist/src/components/schedule/days/parts/grid.d.ts.map +1 -0
- package/dist/src/components/schedule/days/parts/grid.js +14 -0
- package/dist/src/components/schedule/days/parts/grid.js.map +1 -0
- package/dist/src/components/schedule/days/parts/now-line.d.ts +5 -0
- package/dist/src/components/schedule/days/parts/now-line.d.ts.map +1 -0
- package/dist/src/components/schedule/days/parts/now-line.js +9 -0
- package/dist/src/components/schedule/days/parts/now-line.js.map +1 -0
- package/dist/src/components/schedule/days/parts/skipped-date.d.ts +4 -0
- package/dist/src/components/schedule/days/parts/skipped-date.d.ts.map +1 -0
- package/dist/src/components/schedule/days/parts/skipped-date.js +17 -0
- package/dist/src/components/schedule/days/parts/skipped-date.js.map +1 -0
- package/dist/src/components/schedule/days/parts/transition.d.ts +3 -0
- package/dist/src/components/schedule/days/parts/transition.d.ts.map +1 -0
- package/dist/src/components/schedule/days/parts/transition.js +42 -0
- package/dist/src/components/schedule/days/parts/transition.js.map +1 -0
- package/dist/src/components/schedule/index.d.ts +3 -0
- package/dist/src/components/schedule/index.d.ts.map +1 -0
- package/dist/src/components/schedule/index.js +44 -0
- package/dist/src/components/schedule/index.js.map +1 -0
- package/dist/src/components/schedule/layout.d.ts +15 -0
- package/dist/src/components/schedule/layout.d.ts.map +1 -0
- package/dist/src/components/schedule/layout.js +10 -0
- package/dist/src/components/schedule/layout.js.map +1 -0
- package/dist/src/components/schedule/parts/gutter.d.ts +3 -0
- package/dist/src/components/schedule/parts/gutter.d.ts.map +1 -0
- package/dist/src/components/schedule/parts/gutter.js +9 -0
- package/dist/src/components/schedule/parts/gutter.js.map +1 -0
- package/dist/src/components/schedule/parts/incomplete.d.ts +6 -0
- package/dist/src/components/schedule/parts/incomplete.d.ts.map +1 -0
- package/dist/src/components/schedule/parts/incomplete.js +9 -0
- package/dist/src/components/schedule/parts/incomplete.js.map +1 -0
- package/dist/src/components/schedule/schedule.types.d.ts +109 -0
- package/dist/src/components/schedule/schedule.types.d.ts.map +1 -0
- package/dist/src/components/schedule/schedule.types.js +3 -0
- package/dist/src/components/schedule/schedule.types.js.map +1 -0
- package/dist/src/components/schedule/use-schedule-viewport.d.ts +7 -0
- package/dist/src/components/schedule/use-schedule-viewport.d.ts.map +1 -0
- package/dist/src/components/schedule/use-schedule-viewport.js +15 -0
- package/dist/src/components/schedule/use-schedule-viewport.js.map +1 -0
- package/dist/src/components/schedule/use-schedule.d.ts +3 -0
- package/dist/src/components/schedule/use-schedule.d.ts.map +1 -0
- package/dist/src/components/schedule/use-schedule.js +71 -0
- package/dist/src/components/schedule/use-schedule.js.map +1 -0
- package/dist/src/components/schedule/utils/days.d.ts +17 -0
- package/dist/src/components/schedule/utils/days.d.ts.map +1 -0
- package/dist/src/components/schedule/utils/days.js +49 -0
- package/dist/src/components/schedule/utils/days.js.map +1 -0
- package/dist/src/core/axis.d.ts +18 -0
- package/dist/src/core/axis.d.ts.map +1 -0
- package/dist/src/core/axis.js +58 -0
- package/dist/src/core/axis.js.map +1 -0
- package/dist/src/core/cache.d.ts +29 -0
- package/dist/src/core/cache.d.ts.map +1 -0
- package/dist/src/core/cache.js +33 -0
- package/dist/src/core/cache.js.map +1 -0
- package/dist/src/core/columns.d.ts +3 -0
- package/dist/src/core/columns.d.ts.map +1 -0
- package/dist/src/core/columns.js +45 -0
- package/dist/src/core/columns.js.map +1 -0
- package/dist/src/core/coverage.d.ts +3 -0
- package/dist/src/core/coverage.d.ts.map +1 -0
- package/dist/src/core/coverage.js +60 -0
- package/dist/src/core/coverage.js.map +1 -0
- package/dist/src/core/flag.d.ts +3 -0
- package/dist/src/core/flag.d.ts.map +1 -0
- package/dist/src/core/flag.js +17 -0
- package/dist/src/core/flag.js.map +1 -0
- package/dist/src/core/hash.d.ts +5 -0
- package/dist/src/core/hash.d.ts.map +1 -0
- package/dist/src/core/hash.js +29 -0
- package/dist/src/core/hash.js.map +1 -0
- package/dist/src/core/hit-test.d.ts +6 -0
- package/dist/src/core/hit-test.d.ts.map +1 -0
- package/dist/src/core/hit-test.js +23 -0
- package/dist/src/core/hit-test.js.map +1 -0
- package/dist/src/core/index.d.ts +12 -0
- package/dist/src/core/index.d.ts.map +1 -0
- package/dist/src/core/index.js +30 -0
- package/dist/src/core/index.js.map +1 -0
- package/dist/src/core/layout.d.ts +3 -0
- package/dist/src/core/layout.d.ts.map +1 -0
- package/dist/src/core/layout.js +96 -0
- package/dist/src/core/layout.js.map +1 -0
- package/dist/src/core/order.d.ts +7 -0
- package/dist/src/core/order.d.ts.map +1 -0
- package/dist/src/core/order.js +12 -0
- package/dist/src/core/order.js.map +1 -0
- package/dist/src/core/scale.d.ts +9 -0
- package/dist/src/core/scale.d.ts.map +1 -0
- package/dist/src/core/scale.js +41 -0
- package/dist/src/core/scale.js.map +1 -0
- package/dist/src/core/snap.d.ts +10 -0
- package/dist/src/core/snap.d.ts.map +1 -0
- package/dist/src/core/snap.js +43 -0
- package/dist/src/core/snap.js.map +1 -0
- package/dist/src/core/spans.d.ts +3 -0
- package/dist/src/core/spans.d.ts.map +1 -0
- package/dist/src/core/spans.js +60 -0
- package/dist/src/core/spans.js.map +1 -0
- package/dist/src/core/types.d.ts +104 -0
- package/dist/src/core/types.d.ts.map +1 -0
- package/dist/src/core/types.js +3 -0
- package/dist/src/core/types.js.map +1 -0
- package/dist/src/core/zone.d.ts +10 -0
- package/dist/src/core/zone.d.ts.map +1 -0
- package/dist/src/core/zone.js +103 -0
- package/dist/src/core/zone.js.map +1 -0
- package/dist/src/index.d.ts +29 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +67 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/nativewind/index.d.ts +59 -0
- package/dist/src/nativewind/index.d.ts.map +1 -0
- package/dist/src/nativewind/index.js +24 -0
- package/dist/src/nativewind/index.js.map +1 -0
- package/docs/migrations.md +61 -0
- package/llms.txt +498 -0
- package/package.json +155 -8
- package/src/adapters/rrule/README.md +41 -0
- package/src/adapters/rrule/cache.ts +50 -0
- package/src/adapters/rrule/envelope.ts +7 -0
- package/src/adapters/rrule/expand.ts +105 -0
- package/src/adapters/rrule/hash.ts +13 -0
- package/src/adapters/rrule/index.ts +11 -0
- package/src/adapters/rrule/net.ts +30 -0
- package/src/adapters/rrule/occurrences.ts +288 -0
- package/src/adapters/rrule/types.ts +52 -0
- package/src/adapters/rrule/validate.ts +78 -0
- package/src/components/layers/README.md +15 -0
- package/src/components/layers/layers.types.ts +6 -0
- package/src/components/layers/parts/gap.tsx +5 -0
- package/src/components/layers/parts/interval.tsx +24 -0
- package/src/components/layers/utils/styles.ts +24 -0
- package/src/components/primitives/README.md +12 -0
- package/src/components/primitives/press-point.tsx +5 -0
- package/src/components/primitives/press-point.types.ts +5 -0
- package/src/components/primitives/press-point.web.tsx +19 -0
- package/src/components/primitives/region-style.ts +21 -0
- package/src/components/roster/README.md +29 -0
- package/src/components/roster/body-layout.tsx +32 -0
- package/src/components/roster/index.tsx +108 -0
- package/src/components/roster/lanes/interval-hover.tsx +5 -0
- package/src/components/roster/lanes/interval-hover.types.ts +11 -0
- package/src/components/roster/lanes/interval-hover.web.tsx +19 -0
- package/src/components/roster/lanes/lane.tsx +93 -0
- package/src/components/roster/lanes/parts/incomplete.tsx +44 -0
- package/src/components/roster/lanes/parts/lane-label.tsx +41 -0
- package/src/components/roster/layout.tsx +68 -0
- package/src/components/roster/parts/body.tsx +24 -0
- package/src/components/roster/parts/corner.tsx +3 -0
- package/src/components/roster/parts/empty.tsx +5 -0
- package/src/components/roster/parts/grid.tsx +26 -0
- package/src/components/roster/parts/header-cell.tsx +10 -0
- package/src/components/roster/parts/header.tsx +23 -0
- package/src/components/roster/parts/lane-label-column.tsx +31 -0
- package/src/components/roster/parts/lane-list.tsx +74 -0
- package/src/components/roster/roster.types.ts +156 -0
- package/src/components/roster/use-roster.ts +133 -0
- package/src/components/roster/utils/body-content-key.ts +46 -0
- package/src/components/roster/utils/ticks.ts +62 -0
- package/src/components/schedule/README.md +23 -0
- package/src/components/schedule/days/day.tsx +89 -0
- package/src/components/schedule/days/header-layout.tsx +12 -0
- package/src/components/schedule/days/layout.tsx +38 -0
- package/src/components/schedule/days/parts/column.tsx +59 -0
- package/src/components/schedule/days/parts/day-header.tsx +18 -0
- package/src/components/schedule/days/parts/grid.tsx +21 -0
- package/src/components/schedule/days/parts/now-line.tsx +11 -0
- package/src/components/schedule/days/parts/skipped-date.tsx +22 -0
- package/src/components/schedule/days/parts/transition.tsx +70 -0
- package/src/components/schedule/index.tsx +108 -0
- package/src/components/schedule/layout.tsx +42 -0
- package/src/components/schedule/parts/gutter.tsx +16 -0
- package/src/components/schedule/parts/incomplete.tsx +13 -0
- package/src/components/schedule/schedule.types.ts +103 -0
- package/src/components/schedule/use-schedule-viewport.ts +13 -0
- package/src/components/schedule/use-schedule.ts +75 -0
- package/src/components/schedule/utils/days.ts +54 -0
- package/src/core/README.md +25 -0
- package/src/core/axis.ts +58 -0
- package/src/core/cache.ts +38 -0
- package/src/core/columns.ts +49 -0
- package/src/core/coverage.ts +56 -0
- package/src/core/flag.ts +14 -0
- package/src/core/hash.ts +28 -0
- package/src/core/hit-test.ts +27 -0
- package/src/core/index.ts +34 -0
- package/src/core/layout.ts +101 -0
- package/src/core/order.ts +18 -0
- package/src/core/scale.ts +45 -0
- package/src/core/snap.ts +52 -0
- package/src/core/spans.ts +58 -0
- package/src/core/types.ts +92 -0
- package/src/core/zone.ts +100 -0
- package/src/index.ts +52 -0
- package/src/nativewind/README.md +14 -0
- package/src/nativewind/index.ts +30 -0
- package/index.js +0 -4
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { RosterGap } from '../layers/parts/gap';
|
|
2
|
+
import { RosterInterval } from '../layers/parts/interval';
|
|
3
|
+
import { RosterLaneLabel } from './lanes/parts/lane-label';
|
|
4
|
+
import { RosterLayout } from './layout';
|
|
5
|
+
import { RosterBody } from './parts/body';
|
|
6
|
+
import { RosterCorner } from './parts/corner';
|
|
7
|
+
import { RosterEmpty } from './parts/empty';
|
|
8
|
+
import { RosterGrid } from './parts/grid';
|
|
9
|
+
import { RosterHeader } from './parts/header';
|
|
10
|
+
import { RosterHeaderCell } from './parts/header-cell';
|
|
11
|
+
import { RosterLaneLabelColumn } from './parts/lane-label-column';
|
|
12
|
+
import type { RosterProps } from './roster.types';
|
|
13
|
+
import { useRoster } from './use-roster';
|
|
14
|
+
|
|
15
|
+
const defaultEmptyZone = <RosterEmpty />;
|
|
16
|
+
const defaultCornerZone = <RosterCorner />;
|
|
17
|
+
|
|
18
|
+
export function Roster(props: RosterProps) {
|
|
19
|
+
const {
|
|
20
|
+
status,
|
|
21
|
+
orderedLanes,
|
|
22
|
+
laneState,
|
|
23
|
+
window,
|
|
24
|
+
geometryFor,
|
|
25
|
+
projection,
|
|
26
|
+
scroll,
|
|
27
|
+
press,
|
|
28
|
+
ticks,
|
|
29
|
+
contentWidth,
|
|
30
|
+
viewport,
|
|
31
|
+
onLayout,
|
|
32
|
+
} = useRoster(props);
|
|
33
|
+
const {
|
|
34
|
+
emptyZone = defaultEmptyZone,
|
|
35
|
+
cornerZone = defaultCornerZone,
|
|
36
|
+
headerComponent: HeaderComponent = RosterHeader,
|
|
37
|
+
laneLabelColumnComponent: LaneLabelColumnComponent = RosterLaneLabelColumn,
|
|
38
|
+
bodyComponent: BodyComponent = RosterBody,
|
|
39
|
+
headerCellComponent = RosterHeaderCell,
|
|
40
|
+
laneLabelComponent = RosterLaneLabel,
|
|
41
|
+
intervalComponent = RosterInterval,
|
|
42
|
+
gapComponent = RosterGap,
|
|
43
|
+
gridComponent = RosterGrid,
|
|
44
|
+
incompleteLabel = 'Availability may be incomplete',
|
|
45
|
+
neverSetLabel = 'No availability set',
|
|
46
|
+
} = props;
|
|
47
|
+
if (status === 'empty') return emptyZone;
|
|
48
|
+
if (window.start === window.end) return null;
|
|
49
|
+
return (
|
|
50
|
+
<RosterLayout
|
|
51
|
+
style={props.style}
|
|
52
|
+
headerStyle={props.headerStyle}
|
|
53
|
+
laneLabelColumnStyle={props.laneLabelColumnStyle}
|
|
54
|
+
bodyStyle={props.bodyStyle}
|
|
55
|
+
laneLabelWidth={props.laneLabelWidth}
|
|
56
|
+
onLayout={onLayout}
|
|
57
|
+
cornerZone={cornerZone}
|
|
58
|
+
headerZone={
|
|
59
|
+
<HeaderComponent
|
|
60
|
+
ticks={ticks}
|
|
61
|
+
projection={projection}
|
|
62
|
+
scroll={scroll}
|
|
63
|
+
contentWidth={contentWidth}
|
|
64
|
+
headerCellComponent={headerCellComponent}
|
|
65
|
+
/>
|
|
66
|
+
}
|
|
67
|
+
laneLabelColumnZone={
|
|
68
|
+
<LaneLabelColumnComponent
|
|
69
|
+
labels={orderedLanes.map((lane) => {
|
|
70
|
+
const state = laneState.get(lane.id) ?? {
|
|
71
|
+
flag: 'none',
|
|
72
|
+
complete: true,
|
|
73
|
+
};
|
|
74
|
+
return {
|
|
75
|
+
lane,
|
|
76
|
+
...state,
|
|
77
|
+
viewTimezone: projection.viewTimezone,
|
|
78
|
+
incompleteLabel,
|
|
79
|
+
neverSetLabel,
|
|
80
|
+
};
|
|
81
|
+
})}
|
|
82
|
+
projection={projection}
|
|
83
|
+
scroll={scroll}
|
|
84
|
+
laneLabelComponent={laneLabelComponent}
|
|
85
|
+
/>
|
|
86
|
+
}
|
|
87
|
+
bodyZone={
|
|
88
|
+
<BodyComponent
|
|
89
|
+
lanes={orderedLanes}
|
|
90
|
+
window={window}
|
|
91
|
+
geometryFor={geometryFor}
|
|
92
|
+
projection={projection}
|
|
93
|
+
scroll={scroll}
|
|
94
|
+
press={press}
|
|
95
|
+
ticks={ticks}
|
|
96
|
+
contentWidth={contentWidth}
|
|
97
|
+
viewport={viewport}
|
|
98
|
+
intervalComponent={intervalComponent}
|
|
99
|
+
gapComponent={gapComponent}
|
|
100
|
+
gridComponent={gridComponent}
|
|
101
|
+
highlightSource={props.highlightSource}
|
|
102
|
+
onIntervalHover={props.onIntervalHover}
|
|
103
|
+
incompleteLabel={incompleteLabel}
|
|
104
|
+
/>
|
|
105
|
+
}
|
|
106
|
+
/>
|
|
107
|
+
);
|
|
108
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Lane, LaneGeometry, Rect } from '../../../core';
|
|
2
|
+
import type { PressPointInput } from '../../primitives/press-point.types';
|
|
3
|
+
|
|
4
|
+
export type IntervalHoverInput = {
|
|
5
|
+
lane: Lane;
|
|
6
|
+
geometry: LaneGeometry;
|
|
7
|
+
onIntervalHover?: (rect: Rect, lane: Lane) => void;
|
|
8
|
+
};
|
|
9
|
+
export type IntervalHoverProps = {
|
|
10
|
+
onPointerMove?: (input: PressPointInput & { nativeEvent: { pointerType?: string } }) => void;
|
|
11
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { hitTest } from '../../../core/hit-test';
|
|
2
|
+
import { pressPoint } from '../../primitives/press-point.web';
|
|
3
|
+
import type { IntervalHoverInput, IntervalHoverProps } from './interval-hover.types';
|
|
4
|
+
|
|
5
|
+
export function intervalHoverProps({
|
|
6
|
+
lane,
|
|
7
|
+
geometry,
|
|
8
|
+
onIntervalHover,
|
|
9
|
+
}: IntervalHoverInput): IntervalHoverProps {
|
|
10
|
+
if (!onIntervalHover) return {};
|
|
11
|
+
return {
|
|
12
|
+
onPointerMove(input) {
|
|
13
|
+
if (input.nativeEvent.pointerType === 'touch') return;
|
|
14
|
+
const { x, y } = pressPoint(input);
|
|
15
|
+
const hit = hitTest(lane, geometry, x, y);
|
|
16
|
+
if (hit?.kind === 'interval') onIntervalHover(hit.rect, lane);
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { Fragment } from 'react';
|
|
2
|
+
import { Pressable } from 'react-native';
|
|
3
|
+
import type { Lane, LaneGeometry } from '../../../core';
|
|
4
|
+
import { pressPoint } from '../../primitives/press-point';
|
|
5
|
+
import type { BodyInput } from '../roster.types';
|
|
6
|
+
import { intervalHoverProps } from './interval-hover';
|
|
7
|
+
import { RosterIncomplete } from './parts/incomplete';
|
|
8
|
+
|
|
9
|
+
export type LaneRowProps = Pick<
|
|
10
|
+
BodyInput,
|
|
11
|
+
| 'press'
|
|
12
|
+
| 'intervalComponent'
|
|
13
|
+
| 'gapComponent'
|
|
14
|
+
| 'highlightSource'
|
|
15
|
+
| 'onIntervalHover'
|
|
16
|
+
| 'incompleteLabel'
|
|
17
|
+
> & {
|
|
18
|
+
lane: Lane;
|
|
19
|
+
geometry: LaneGeometry;
|
|
20
|
+
width: number;
|
|
21
|
+
rowHeight: number;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export function LaneRow({
|
|
25
|
+
lane,
|
|
26
|
+
geometry,
|
|
27
|
+
width,
|
|
28
|
+
rowHeight,
|
|
29
|
+
press,
|
|
30
|
+
intervalComponent: IntervalComponent,
|
|
31
|
+
gapComponent: GapComponent,
|
|
32
|
+
highlightSource,
|
|
33
|
+
onIntervalHover,
|
|
34
|
+
incompleteLabel = 'Availability may be incomplete',
|
|
35
|
+
}: LaneRowProps) {
|
|
36
|
+
const layers = [...lane.layers].sort((a, b) => a.z - b.z);
|
|
37
|
+
return (
|
|
38
|
+
<Pressable
|
|
39
|
+
{...intervalHoverProps({ lane, geometry, onIntervalHover })}
|
|
40
|
+
testID={`roster-lane-${lane.id}`}
|
|
41
|
+
accessibilityLabel={lane.label}
|
|
42
|
+
onPress={(input) => {
|
|
43
|
+
const point = pressPoint(input);
|
|
44
|
+
press(lane, point.x, point.y);
|
|
45
|
+
}}
|
|
46
|
+
style={{ width, height: rowHeight }}
|
|
47
|
+
>
|
|
48
|
+
<RosterIncomplete lane={lane} geometry={geometry} width={width} label={incompleteLabel} />
|
|
49
|
+
{layers.map((layer) => (
|
|
50
|
+
<Fragment key={layer.id}>
|
|
51
|
+
{geometry.rects
|
|
52
|
+
.filter((rect) => rect.layerId === layer.id)
|
|
53
|
+
.map((rect) => (
|
|
54
|
+
<Fragment key={`interval-${rect.x}:${rect.width}`}>
|
|
55
|
+
<IntervalComponent
|
|
56
|
+
rect={rect}
|
|
57
|
+
layer={layer}
|
|
58
|
+
lane={lane}
|
|
59
|
+
highlighted={rect.sources.some(
|
|
60
|
+
(source) =>
|
|
61
|
+
source.kind === highlightSource?.kind && source.id === highlightSource.id,
|
|
62
|
+
)}
|
|
63
|
+
/>
|
|
64
|
+
</Fragment>
|
|
65
|
+
))}
|
|
66
|
+
{geometry.gapRects
|
|
67
|
+
.filter((rect) => rect.layerId === layer.id)
|
|
68
|
+
.map((rect) => (
|
|
69
|
+
<Pressable
|
|
70
|
+
key={`gap-${rect.x}:${rect.width}`}
|
|
71
|
+
accessibilityLabel={`${lane.label}: removed time`}
|
|
72
|
+
onPress={(input) => {
|
|
73
|
+
input.stopPropagation();
|
|
74
|
+
const point = pressPoint(input);
|
|
75
|
+
press(lane, rect.x + point.x, rect.y + point.y);
|
|
76
|
+
}}
|
|
77
|
+
style={{
|
|
78
|
+
position: 'absolute',
|
|
79
|
+
left: rect.x,
|
|
80
|
+
top: rect.y,
|
|
81
|
+
width: rect.width,
|
|
82
|
+
height: rect.height,
|
|
83
|
+
zIndex: rect.z,
|
|
84
|
+
}}
|
|
85
|
+
>
|
|
86
|
+
<GapComponent rect={rect} layer={layer} lane={lane} />
|
|
87
|
+
</Pressable>
|
|
88
|
+
))}
|
|
89
|
+
</Fragment>
|
|
90
|
+
))}
|
|
91
|
+
</Pressable>
|
|
92
|
+
);
|
|
93
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Text } from 'react-native';
|
|
2
|
+
import type { Lane, LaneGeometry } from '../../../../core';
|
|
3
|
+
|
|
4
|
+
export function RosterIncomplete({
|
|
5
|
+
lane,
|
|
6
|
+
geometry,
|
|
7
|
+
width,
|
|
8
|
+
label,
|
|
9
|
+
}: {
|
|
10
|
+
lane: Lane;
|
|
11
|
+
geometry: LaneGeometry;
|
|
12
|
+
width: number;
|
|
13
|
+
label: string;
|
|
14
|
+
}) {
|
|
15
|
+
if (lane.complete !== false) return null;
|
|
16
|
+
// Choose the first empty span; the notice never covers an interval.
|
|
17
|
+
let left = 0;
|
|
18
|
+
let right = width;
|
|
19
|
+
for (const rect of [...geometry.rects].sort((a, b) => a.x - b.x)) {
|
|
20
|
+
if (rect.x > left) {
|
|
21
|
+
right = rect.x;
|
|
22
|
+
break;
|
|
23
|
+
}
|
|
24
|
+
left = Math.max(left, rect.x + rect.width);
|
|
25
|
+
}
|
|
26
|
+
if (left >= right) return null;
|
|
27
|
+
return (
|
|
28
|
+
<Text
|
|
29
|
+
testID={`roster-incomplete-${lane.id}`}
|
|
30
|
+
pointerEvents="none"
|
|
31
|
+
numberOfLines={1}
|
|
32
|
+
style={{
|
|
33
|
+
position: 'absolute',
|
|
34
|
+
left,
|
|
35
|
+
width: right - left,
|
|
36
|
+
top: 4,
|
|
37
|
+
color: '#64748b',
|
|
38
|
+
fontSize: 12,
|
|
39
|
+
}}
|
|
40
|
+
>
|
|
41
|
+
{label}
|
|
42
|
+
</Text>
|
|
43
|
+
);
|
|
44
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Text, View } from 'react-native';
|
|
2
|
+
import type { LaneLabelInput } from '../../roster.types';
|
|
3
|
+
|
|
4
|
+
export function RosterLaneLabel({
|
|
5
|
+
lane,
|
|
6
|
+
flag,
|
|
7
|
+
complete,
|
|
8
|
+
viewTimezone,
|
|
9
|
+
incompleteLabel,
|
|
10
|
+
neverSetLabel,
|
|
11
|
+
}: LaneLabelInput) {
|
|
12
|
+
const zone =
|
|
13
|
+
lane.timezone && lane.timezone !== viewTimezone ? (
|
|
14
|
+
<Text style={{ fontSize: 10, color: '#64748b' }}>{lane.timezone}</Text>
|
|
15
|
+
) : null;
|
|
16
|
+
const flagText =
|
|
17
|
+
flag === 'never-set' ? (
|
|
18
|
+
<Text style={{ fontSize: 10, color: '#9a3412' }}>{neverSetLabel}</Text>
|
|
19
|
+
) : null;
|
|
20
|
+
const completeness = complete ? null : (
|
|
21
|
+
<Text style={{ fontSize: 10, color: '#9a3412' }}>{incompleteLabel}</Text>
|
|
22
|
+
);
|
|
23
|
+
return (
|
|
24
|
+
<View
|
|
25
|
+
style={{
|
|
26
|
+
flex: 1,
|
|
27
|
+
justifyContent: 'center',
|
|
28
|
+
paddingHorizontal: 8,
|
|
29
|
+
borderBottomWidth: 1,
|
|
30
|
+
borderBottomColor: '#e2e8f0',
|
|
31
|
+
}}
|
|
32
|
+
>
|
|
33
|
+
<Text numberOfLines={1} style={{ color: '#0f172a', fontSize: 12 }}>
|
|
34
|
+
{lane.label}
|
|
35
|
+
</Text>
|
|
36
|
+
{zone}
|
|
37
|
+
{flagText}
|
|
38
|
+
{completeness}
|
|
39
|
+
</View>
|
|
40
|
+
);
|
|
41
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import type { LayoutChangeEvent } from 'react-native';
|
|
3
|
+
import { View } from 'react-native';
|
|
4
|
+
import { regionStyle } from '../primitives/region-style';
|
|
5
|
+
import type { RosterStyleProps } from './roster.types';
|
|
6
|
+
|
|
7
|
+
type RosterLayoutProps = Omit<RosterStyleProps, `${string}ClassName` | 'className'> & {
|
|
8
|
+
/** Cell above the lane labels, beside the header. */
|
|
9
|
+
cornerZone: ReactNode;
|
|
10
|
+
/** Frozen tick row; the layout clips translated header content. */
|
|
11
|
+
headerZone: ReactNode;
|
|
12
|
+
/** Frozen lane labels; the layout supplies the label column and clips vertical translation. */
|
|
13
|
+
laneLabelColumnZone: ReactNode;
|
|
14
|
+
/** Virtualized body with its horizontal scroller; fills the measured viewport. */
|
|
15
|
+
bodyZone: ReactNode;
|
|
16
|
+
onLayout: (input: LayoutChangeEvent) => void;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export function RosterLayout({
|
|
20
|
+
cornerZone,
|
|
21
|
+
headerZone,
|
|
22
|
+
laneLabelColumnZone,
|
|
23
|
+
bodyZone,
|
|
24
|
+
onLayout,
|
|
25
|
+
style,
|
|
26
|
+
headerStyle,
|
|
27
|
+
laneLabelColumnStyle,
|
|
28
|
+
bodyStyle,
|
|
29
|
+
laneLabelWidth = 180,
|
|
30
|
+
}: RosterLayoutProps) {
|
|
31
|
+
return (
|
|
32
|
+
<View style={regionStyle(structure.root, paint.root, style)}>
|
|
33
|
+
<View style={regionStyle(structure.header, paint.header, headerStyle)}>
|
|
34
|
+
<View style={{ width: laneLabelWidth }}>{cornerZone}</View>
|
|
35
|
+
<View style={structure.headerStrip}>{headerZone}</View>
|
|
36
|
+
</View>
|
|
37
|
+
<View style={structure.content}>
|
|
38
|
+
<View
|
|
39
|
+
style={regionStyle(
|
|
40
|
+
{ ...structure.labels, width: laneLabelWidth },
|
|
41
|
+
paint.labels,
|
|
42
|
+
laneLabelColumnStyle,
|
|
43
|
+
)}
|
|
44
|
+
>
|
|
45
|
+
{laneLabelColumnZone}
|
|
46
|
+
</View>
|
|
47
|
+
<View onLayout={onLayout} style={regionStyle(structure.body, {}, bodyStyle)}>
|
|
48
|
+
{bodyZone}
|
|
49
|
+
</View>
|
|
50
|
+
</View>
|
|
51
|
+
</View>
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const structure = {
|
|
56
|
+
root: { flex: 1, minHeight: 0, overflow: 'hidden' },
|
|
57
|
+
header: { flexDirection: 'row', height: 40, overflow: 'hidden' },
|
|
58
|
+
headerStrip: { flex: 1, minWidth: 0, overflow: 'hidden' },
|
|
59
|
+
content: { flex: 1, minHeight: 0, flexDirection: 'row' },
|
|
60
|
+
labels: { overflow: 'hidden' },
|
|
61
|
+
body: { flex: 1, minWidth: 0, overflow: 'hidden' },
|
|
62
|
+
} as const;
|
|
63
|
+
// Paint is what a class replaces; see regionStyle.
|
|
64
|
+
const paint = {
|
|
65
|
+
root: { backgroundColor: '#fff' },
|
|
66
|
+
header: { borderBottomWidth: 1, borderBottomColor: '#cbd5e1' },
|
|
67
|
+
labels: { borderRightWidth: 1, borderRightColor: '#cbd5e1' },
|
|
68
|
+
} as const;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { ProfilerOnRenderCallback } from 'react';
|
|
2
|
+
import { RosterBodyLayout } from '../body-layout';
|
|
3
|
+
import type { BodyInput } from '../roster.types';
|
|
4
|
+
import { RosterLaneList } from './lane-list';
|
|
5
|
+
|
|
6
|
+
export function RosterBody(
|
|
7
|
+
props: BodyInput & {
|
|
8
|
+
/** Development-only Profiler hook used by the gallery; not a supported customization point. */
|
|
9
|
+
onRowRender?: ProfilerOnRenderCallback;
|
|
10
|
+
},
|
|
11
|
+
) {
|
|
12
|
+
const { viewport, scroll, contentWidth, ticks, gridComponent: GridComponent } = props;
|
|
13
|
+
// LegendList requires a measured viewport and does not support static rendering.
|
|
14
|
+
if (viewport.width <= 0 || viewport.height <= 0) return null;
|
|
15
|
+
return (
|
|
16
|
+
<RosterBodyLayout
|
|
17
|
+
scroll={scroll}
|
|
18
|
+
contentWidth={contentWidth}
|
|
19
|
+
viewport={viewport}
|
|
20
|
+
gridZone={<GridComponent ticks={ticks} contentWidth={contentWidth} />}
|
|
21
|
+
listZone={<RosterLaneList {...props} />}
|
|
22
|
+
/>
|
|
23
|
+
);
|
|
24
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { View } from 'react-native';
|
|
2
|
+
import type { GridInput } from '../roster.types';
|
|
3
|
+
|
|
4
|
+
export function RosterGrid({ ticks, contentWidth }: GridInput) {
|
|
5
|
+
return (
|
|
6
|
+
<View
|
|
7
|
+
testID="roster-grid"
|
|
8
|
+
pointerEvents="none"
|
|
9
|
+
style={{ position: 'absolute', width: contentWidth, height: '100%' }}
|
|
10
|
+
>
|
|
11
|
+
{ticks.map((tick) => (
|
|
12
|
+
<View
|
|
13
|
+
key={tick.time}
|
|
14
|
+
style={{
|
|
15
|
+
position: 'absolute',
|
|
16
|
+
left: tick.x,
|
|
17
|
+
top: 0,
|
|
18
|
+
bottom: 0,
|
|
19
|
+
width: 1,
|
|
20
|
+
backgroundColor: '#e2e8f0',
|
|
21
|
+
}}
|
|
22
|
+
/>
|
|
23
|
+
))}
|
|
24
|
+
</View>
|
|
25
|
+
);
|
|
26
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Text } from 'react-native';
|
|
2
|
+
import type { HeaderCellInput } from '../roster.types';
|
|
3
|
+
|
|
4
|
+
export function RosterHeaderCell({ tick }: HeaderCellInput) {
|
|
5
|
+
return (
|
|
6
|
+
<Text numberOfLines={1} style={{ color: '#475569', fontSize: 11, padding: 4 }}>
|
|
7
|
+
{tick.label}
|
|
8
|
+
</Text>
|
|
9
|
+
);
|
|
10
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { View } from 'react-native';
|
|
2
|
+
import Animated from 'react-native-reanimated';
|
|
3
|
+
import type { HeaderInput } from '../roster.types';
|
|
4
|
+
|
|
5
|
+
export function RosterHeader({
|
|
6
|
+
ticks,
|
|
7
|
+
contentWidth,
|
|
8
|
+
scroll,
|
|
9
|
+
headerCellComponent: HeaderCellComponent,
|
|
10
|
+
}: HeaderInput) {
|
|
11
|
+
return (
|
|
12
|
+
<Animated.View
|
|
13
|
+
testID="roster-header"
|
|
14
|
+
style={[{ width: contentWidth, height: 40 }, scroll.headerStyle]}
|
|
15
|
+
>
|
|
16
|
+
{ticks.map((tick) => (
|
|
17
|
+
<View key={tick.time} style={{ position: 'absolute', left: tick.x, top: 0 }}>
|
|
18
|
+
<HeaderCellComponent tick={tick} />
|
|
19
|
+
</View>
|
|
20
|
+
))}
|
|
21
|
+
</Animated.View>
|
|
22
|
+
);
|
|
23
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { View } from 'react-native';
|
|
2
|
+
import Animated from 'react-native-reanimated';
|
|
3
|
+
import type { LabelColumnInput } from '../roster.types';
|
|
4
|
+
|
|
5
|
+
export function RosterLaneLabelColumn({
|
|
6
|
+
labels,
|
|
7
|
+
projection,
|
|
8
|
+
scroll,
|
|
9
|
+
laneLabelComponent: LaneLabelComponent,
|
|
10
|
+
}: LabelColumnInput) {
|
|
11
|
+
return (
|
|
12
|
+
<Animated.View
|
|
13
|
+
testID="roster-labels"
|
|
14
|
+
style={[{ height: labels.length * projection.rowHeight }, scroll.labelStyle]}
|
|
15
|
+
>
|
|
16
|
+
{labels.map((label, index) => (
|
|
17
|
+
<View
|
|
18
|
+
key={label.lane.id}
|
|
19
|
+
style={{
|
|
20
|
+
position: 'absolute',
|
|
21
|
+
top: index * projection.rowHeight,
|
|
22
|
+
height: projection.rowHeight,
|
|
23
|
+
width: '100%',
|
|
24
|
+
}}
|
|
25
|
+
>
|
|
26
|
+
<LaneLabelComponent {...label} />
|
|
27
|
+
</View>
|
|
28
|
+
))}
|
|
29
|
+
</Animated.View>
|
|
30
|
+
);
|
|
31
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { LegendList } from '@legendapp/list';
|
|
2
|
+
import { Profiler, type ProfilerOnRenderCallback } from 'react';
|
|
3
|
+
import { LaneRow } from '../lanes/lane';
|
|
4
|
+
import type { BodyInput } from '../roster.types';
|
|
5
|
+
import { bodyContentKey } from '../utils/body-content-key';
|
|
6
|
+
|
|
7
|
+
export function RosterLaneList({
|
|
8
|
+
lanes,
|
|
9
|
+
geometryFor,
|
|
10
|
+
projection,
|
|
11
|
+
scroll,
|
|
12
|
+
press,
|
|
13
|
+
contentWidth,
|
|
14
|
+
viewport,
|
|
15
|
+
window,
|
|
16
|
+
intervalComponent,
|
|
17
|
+
gapComponent,
|
|
18
|
+
highlightSource,
|
|
19
|
+
onIntervalHover,
|
|
20
|
+
incompleteLabel,
|
|
21
|
+
onRowRender,
|
|
22
|
+
}: Omit<BodyInput, 'ticks' | 'gridComponent'> & {
|
|
23
|
+
/** Development-only Profiler hook used by the gallery; not a supported customization point. */
|
|
24
|
+
onRowRender?: ProfilerOnRenderCallback;
|
|
25
|
+
}) {
|
|
26
|
+
return (
|
|
27
|
+
<LegendList
|
|
28
|
+
testID="roster-vertical-scroll"
|
|
29
|
+
data={lanes}
|
|
30
|
+
extraData={bodyContentKey({
|
|
31
|
+
window,
|
|
32
|
+
projection,
|
|
33
|
+
highlightSource,
|
|
34
|
+
intervalComponent,
|
|
35
|
+
gapComponent,
|
|
36
|
+
onIntervalHover,
|
|
37
|
+
incompleteLabel,
|
|
38
|
+
})}
|
|
39
|
+
keyExtractor={(lane) => lane.id}
|
|
40
|
+
estimatedListSize={{ width: contentWidth, height: viewport.height }}
|
|
41
|
+
estimatedItemSize={projection.rowHeight}
|
|
42
|
+
getFixedItemSize={() => projection.rowHeight}
|
|
43
|
+
drawDistance={0}
|
|
44
|
+
recycleItems={false}
|
|
45
|
+
maintainVisibleContentPosition={false}
|
|
46
|
+
onScroll={scroll.onVerticalScroll}
|
|
47
|
+
scrollEventThrottle={16}
|
|
48
|
+
style={{ flex: 1 }}
|
|
49
|
+
renderItem={({ item }) => {
|
|
50
|
+
const row = (
|
|
51
|
+
<LaneRow
|
|
52
|
+
lane={item}
|
|
53
|
+
geometry={geometryFor(item)}
|
|
54
|
+
width={contentWidth}
|
|
55
|
+
rowHeight={projection.rowHeight}
|
|
56
|
+
press={press}
|
|
57
|
+
intervalComponent={intervalComponent}
|
|
58
|
+
gapComponent={gapComponent}
|
|
59
|
+
highlightSource={highlightSource}
|
|
60
|
+
onIntervalHover={onIntervalHover}
|
|
61
|
+
incompleteLabel={incompleteLabel}
|
|
62
|
+
/>
|
|
63
|
+
);
|
|
64
|
+
if (onRowRender)
|
|
65
|
+
return (
|
|
66
|
+
<Profiler id={item.id} onRender={onRowRender}>
|
|
67
|
+
{row}
|
|
68
|
+
</Profiler>
|
|
69
|
+
);
|
|
70
|
+
return row;
|
|
71
|
+
}}
|
|
72
|
+
/>
|
|
73
|
+
);
|
|
74
|
+
}
|