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
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"source.d.ts","sourceRoot":"","sources":["../../../src/core/source.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEtC,uEAAuE;AACvE,wBAAgB,SAAS,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAKzF"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.hasSource = hasSource;
|
|
4
|
+
/** Match source identity by kind and id, ignoring display metadata. */
|
|
5
|
+
function hasSource(sources, source) {
|
|
6
|
+
return (source !== undefined &&
|
|
7
|
+
sources.some((item) => item.kind === source.kind && item.id === source.id));
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=source.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"source.js","sourceRoot":"","sources":["../../../src/core/source.ts"],"names":[],"mappings":";;;AAEA,uEAAuE;AACvE,mBAA0B,OAA0B,EAAE,MAA0B;IAC9E,OAAO,CACL,MAAM,KAAK,SAAS;QACpB,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,MAAM,CAAC,IAAI,IAAI,IAAI,CAAC,EAAE,KAAK,MAAM,CAAC,EAAE,CAAC,CAC3E,CAAC;AACJ,CAAC"}
|
package/dist/src/index.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
export type { GapInput, IntervalInput } from './components/layers/layers.types';
|
|
2
2
|
export { RosterGap } from './components/layers/parts/gap';
|
|
3
3
|
export { RosterInterval } from './components/layers/parts/interval';
|
|
4
|
+
export { Portal, PortalHost } from './components/primitives/portal';
|
|
4
5
|
export { Roster } from './components/roster';
|
|
6
|
+
export { RosterBodyLayout } from './components/roster/body-layout';
|
|
5
7
|
export { RosterLaneLabel } from './components/roster/lanes/parts/lane-label';
|
|
6
8
|
export { RosterBody } from './components/roster/parts/body';
|
|
7
9
|
export { RosterCorner } from './components/roster/parts/corner';
|
|
@@ -10,7 +12,10 @@ export { RosterGrid } from './components/roster/parts/grid';
|
|
|
10
12
|
export { RosterHeader } from './components/roster/parts/header';
|
|
11
13
|
export { RosterHeaderCell } from './components/roster/parts/header-cell';
|
|
12
14
|
export { RosterLaneLabelColumn } from './components/roster/parts/lane-label-column';
|
|
13
|
-
export
|
|
15
|
+
export { RosterLaneList } from './components/roster/parts/lane-list';
|
|
16
|
+
export type { BodyInput, GridInput, HeaderCellInput, HeaderInput, IntervalDetailInput, LabelColumnInput, LaneLabelInput, RosterInput, RosterModel, RosterProjection, RosterProps, RosterScroll, RosterStyleProps, RosterTick, } from './components/roster/roster.types';
|
|
17
|
+
export { RosterSelectionPopover } from './components/roster/selection/selection-layout';
|
|
18
|
+
export type { SelectionLayoutProps } from './components/roster/selection/selection-layout.types';
|
|
14
19
|
export { useRoster } from './components/roster/use-roster';
|
|
15
20
|
export { Schedule } from './components/schedule';
|
|
16
21
|
export { ScheduleColumn } from './components/schedule/days/parts/column';
|
package/dist/src/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AAChF,OAAO,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACpE,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,4CAA4C,CAAC;AAC7E,OAAO,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uCAAuC,CAAC;AACzE,OAAO,EAAE,qBAAqB,EAAE,MAAM,6CAA6C,CAAC;AACpF,YAAY,EACV,SAAS,EACT,SAAS,EACT,WAAW,EACX,gBAAgB,EAChB,cAAc,EACd,WAAW,EACX,WAAW,EACX,gBAAgB,EAChB,WAAW,EACX,YAAY,EACZ,gBAAgB,EAChB,UAAU,GACX,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,gCAAgC,CAAC;AAC3D,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,EAAE,iBAAiB,EAAE,MAAM,6CAA6C,CAAC;AAChF,OAAO,EAAE,YAAY,EAAE,MAAM,uCAAuC,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,2CAA2C,CAAC;AAC5E,OAAO,EAAE,mBAAmB,EAAE,MAAM,+CAA+C,CAAC;AACpF,OAAO,EAAE,kBAAkB,EAAE,MAAM,6CAA6C,CAAC;AACjF,OAAO,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACpE,OAAO,EAAE,kBAAkB,EAAE,MAAM,wCAAwC,CAAC;AAC5E,YAAY,EACV,mBAAmB,EACnB,kBAAkB,EAClB,aAAa,EACb,aAAa,EACb,kBAAkB,EAClB,aAAa,EACb,kBAAkB,EAClB,uBAAuB,EACvB,kBAAkB,GACnB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,oCAAoC,CAAC;AACjE,cAAc,QAAQ,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AAChF,OAAO,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACpE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,eAAe,EAAE,MAAM,4CAA4C,CAAC;AAC7E,OAAO,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uCAAuC,CAAC;AACzE,OAAO,EAAE,qBAAqB,EAAE,MAAM,6CAA6C,CAAC;AACpF,OAAO,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAC;AACrE,YAAY,EACV,SAAS,EACT,SAAS,EACT,eAAe,EACf,WAAW,EACX,mBAAmB,EACnB,gBAAgB,EAChB,cAAc,EACd,WAAW,EACX,WAAW,EACX,gBAAgB,EAChB,WAAW,EACX,YAAY,EACZ,gBAAgB,EAChB,UAAU,GACX,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,sBAAsB,EAAE,MAAM,gDAAgD,CAAC;AACxF,YAAY,EAAE,oBAAoB,EAAE,MAAM,sDAAsD,CAAC;AACjG,OAAO,EAAE,SAAS,EAAE,MAAM,gCAAgC,CAAC;AAC3D,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,EAAE,iBAAiB,EAAE,MAAM,6CAA6C,CAAC;AAChF,OAAO,EAAE,YAAY,EAAE,MAAM,uCAAuC,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,2CAA2C,CAAC;AAC5E,OAAO,EAAE,mBAAmB,EAAE,MAAM,+CAA+C,CAAC;AACpF,OAAO,EAAE,kBAAkB,EAAE,MAAM,6CAA6C,CAAC;AACjF,OAAO,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACpE,OAAO,EAAE,kBAAkB,EAAE,MAAM,wCAAwC,CAAC;AAC5E,YAAY,EACV,mBAAmB,EACnB,kBAAkB,EAClB,aAAa,EACb,aAAa,EACb,kBAAkB,EAClB,aAAa,EACb,kBAAkB,EAClB,uBAAuB,EACvB,kBAAkB,GACnB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,oCAAoC,CAAC;AACjE,cAAc,QAAQ,CAAC"}
|
package/dist/src/index.js
CHANGED
|
@@ -14,13 +14,18 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.useSchedule = exports.ScheduleIncomplete = exports.ScheduleGutter = exports.ScheduleTransition = exports.ScheduleSkippedDate = exports.ScheduleNowLine = exports.ScheduleGrid = exports.ScheduleDayHeader = exports.ScheduleColumn = exports.Schedule = exports.useRoster = exports.RosterLaneLabelColumn = exports.RosterHeaderCell = exports.RosterHeader = exports.RosterGrid = exports.RosterEmpty = exports.RosterCorner = exports.RosterBody = exports.RosterLaneLabel = exports.Roster = exports.RosterInterval = exports.RosterGap = void 0;
|
|
17
|
+
exports.useSchedule = exports.ScheduleIncomplete = exports.ScheduleGutter = exports.ScheduleTransition = exports.ScheduleSkippedDate = exports.ScheduleNowLine = exports.ScheduleGrid = exports.ScheduleDayHeader = exports.ScheduleColumn = exports.Schedule = exports.useRoster = exports.RosterSelectionPopover = exports.RosterLaneList = exports.RosterLaneLabelColumn = exports.RosterHeaderCell = exports.RosterHeader = exports.RosterGrid = exports.RosterEmpty = exports.RosterCorner = exports.RosterBody = exports.RosterLaneLabel = exports.RosterBodyLayout = exports.Roster = exports.PortalHost = exports.Portal = exports.RosterInterval = exports.RosterGap = void 0;
|
|
18
18
|
var gap_1 = require("./components/layers/parts/gap");
|
|
19
19
|
Object.defineProperty(exports, "RosterGap", { enumerable: true, get: function () { return gap_1.RosterGap; } });
|
|
20
20
|
var interval_1 = require("./components/layers/parts/interval");
|
|
21
21
|
Object.defineProperty(exports, "RosterInterval", { enumerable: true, get: function () { return interval_1.RosterInterval; } });
|
|
22
|
+
var portal_1 = require("./components/primitives/portal");
|
|
23
|
+
Object.defineProperty(exports, "Portal", { enumerable: true, get: function () { return portal_1.Portal; } });
|
|
24
|
+
Object.defineProperty(exports, "PortalHost", { enumerable: true, get: function () { return portal_1.PortalHost; } });
|
|
22
25
|
var roster_1 = require("./components/roster");
|
|
23
26
|
Object.defineProperty(exports, "Roster", { enumerable: true, get: function () { return roster_1.Roster; } });
|
|
27
|
+
var body_layout_1 = require("./components/roster/body-layout");
|
|
28
|
+
Object.defineProperty(exports, "RosterBodyLayout", { enumerable: true, get: function () { return body_layout_1.RosterBodyLayout; } });
|
|
24
29
|
var lane_label_1 = require("./components/roster/lanes/parts/lane-label");
|
|
25
30
|
Object.defineProperty(exports, "RosterLaneLabel", { enumerable: true, get: function () { return lane_label_1.RosterLaneLabel; } });
|
|
26
31
|
var body_1 = require("./components/roster/parts/body");
|
|
@@ -37,6 +42,10 @@ var header_cell_1 = require("./components/roster/parts/header-cell");
|
|
|
37
42
|
Object.defineProperty(exports, "RosterHeaderCell", { enumerable: true, get: function () { return header_cell_1.RosterHeaderCell; } });
|
|
38
43
|
var lane_label_column_1 = require("./components/roster/parts/lane-label-column");
|
|
39
44
|
Object.defineProperty(exports, "RosterLaneLabelColumn", { enumerable: true, get: function () { return lane_label_column_1.RosterLaneLabelColumn; } });
|
|
45
|
+
var lane_list_1 = require("./components/roster/parts/lane-list");
|
|
46
|
+
Object.defineProperty(exports, "RosterLaneList", { enumerable: true, get: function () { return lane_list_1.RosterLaneList; } });
|
|
47
|
+
var selection_layout_1 = require("./components/roster/selection/selection-layout");
|
|
48
|
+
Object.defineProperty(exports, "RosterSelectionPopover", { enumerable: true, get: function () { return selection_layout_1.RosterSelectionPopover; } });
|
|
40
49
|
var use_roster_1 = require("./components/roster/use-roster");
|
|
41
50
|
Object.defineProperty(exports, "useRoster", { enumerable: true, get: function () { return use_roster_1.useRoster; } });
|
|
42
51
|
var schedule_1 = require("./components/schedule");
|
package/dist/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AACA,qDAA0D;AAAjD,gGAAA,SAAS,OAAA;AAClB,+DAAoE;AAA3D,0GAAA,cAAc,OAAA;AACvB,8CAA6C;AAApC,gGAAA,MAAM,OAAA;AACf,yEAA6E;AAApE,6GAAA,eAAe,OAAA;AACxB,uDAA4D;AAAnD,kGAAA,UAAU,OAAA;AACnB,2DAAgE;AAAvD,sGAAA,YAAY,OAAA;AACrB,yDAA8D;AAArD,oGAAA,WAAW,OAAA;AACpB,uDAA4D;AAAnD,kGAAA,UAAU,OAAA;AACnB,2DAAgE;AAAvD,sGAAA,YAAY,OAAA;AACrB,qEAAyE;AAAhE,+GAAA,gBAAgB,OAAA;AACzB,iFAAoF;AAA3E,0HAAA,qBAAqB,OAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AACA,qDAA0D;AAAjD,gGAAA,SAAS,OAAA;AAClB,+DAAoE;AAA3D,0GAAA,cAAc,OAAA;AACvB,yDAAoE;AAA3D,gGAAA,MAAM,OAAA;AAAE,oGAAA,UAAU,OAAA;AAC3B,8CAA6C;AAApC,gGAAA,MAAM,OAAA;AACf,+DAAmE;AAA1D,+GAAA,gBAAgB,OAAA;AACzB,yEAA6E;AAApE,6GAAA,eAAe,OAAA;AACxB,uDAA4D;AAAnD,kGAAA,UAAU,OAAA;AACnB,2DAAgE;AAAvD,sGAAA,YAAY,OAAA;AACrB,yDAA8D;AAArD,oGAAA,WAAW,OAAA;AACpB,uDAA4D;AAAnD,kGAAA,UAAU,OAAA;AACnB,2DAAgE;AAAvD,sGAAA,YAAY,OAAA;AACrB,qEAAyE;AAAhE,+GAAA,gBAAgB,OAAA;AACzB,iFAAoF;AAA3E,0HAAA,qBAAqB,OAAA;AAC9B,iEAAqE;AAA5D,2GAAA,cAAc,OAAA;AAiBvB,mFAAwF;AAA/E,0HAAA,sBAAsB,OAAA;AAE/B,6DAA2D;AAAlD,uGAAA,SAAS,OAAA;AAClB,kDAAiD;AAAxC,oGAAA,QAAQ,OAAA;AACjB,kEAAyE;AAAhE,wGAAA,cAAc,OAAA;AACvB,0EAAgF;AAAvE,+GAAA,iBAAiB,OAAA;AAC1B,8DAAqE;AAA5D,oGAAA,YAAY,OAAA;AACrB,sEAA4E;AAAnE,2GAAA,eAAe,OAAA;AACxB,8EAAoF;AAA3E,mHAAA,mBAAmB,OAAA;AAC5B,0EAAiF;AAAxE,gHAAA,kBAAkB,OAAA;AAC3B,6DAAoE;AAA3D,wGAAA,cAAc,OAAA;AACvB,qEAA4E;AAAnE,gHAAA,kBAAkB,OAAA;AAY3B,mEAAiE;AAAxD,2GAAA,WAAW,OAAA;AACpB,yCAAuB"}
|
|
@@ -8,21 +8,22 @@ type Mapping<T> = {
|
|
|
8
8
|
/** Each class prop resolves into the style prop of the same chrome region. */
|
|
9
9
|
export declare const rosterClassNames: Mapping<RosterStyleProps>;
|
|
10
10
|
export declare const scheduleClassNames: Mapping<ScheduleStyleProps>;
|
|
11
|
-
export declare const Roster: import("react").ComponentType<import("../components/roster/roster.types").RosterInput & RosterStyleProps & {
|
|
11
|
+
export declare const Roster: import("react").ComponentType<Omit<import("../components/roster/roster.types").RosterInput, "selectable"> & RosterStyleProps & {
|
|
12
|
+
intervalDetailComponent?: import("react").ComponentType<import("../components/roster/roster.types").IntervalDetailInput>;
|
|
13
|
+
selectionLayout?: import("react").ComponentType<import("..").SelectionLayoutProps>;
|
|
14
|
+
portalHost?: string;
|
|
12
15
|
incompleteLabel?: string;
|
|
13
16
|
neverSetLabel?: string;
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
laneLabelColumnZone?: (input: import("../components/roster/roster.types").LabelColumnInput) => import("react").ReactNode;
|
|
25
|
-
bodyZone?: (input: import("../components/roster/roster.types").BodyInput) => import("react").ReactNode;
|
|
17
|
+
laneLabelComponent?: import("react").ComponentType<import("../components/roster/roster.types").LaneLabelInput>;
|
|
18
|
+
headerCellComponent?: import("react").ComponentType<import("../components/roster/roster.types").HeaderCellInput>;
|
|
19
|
+
intervalComponent?: import("react").ComponentType<import("..").IntervalInput>;
|
|
20
|
+
gapComponent?: import("react").ComponentType<import("..").GapInput>;
|
|
21
|
+
gridComponent?: import("react").ComponentType<import("../components/roster/roster.types").GridInput>;
|
|
22
|
+
emptyZone?: import("react").ReactNode;
|
|
23
|
+
cornerZone?: import("react").ReactNode;
|
|
24
|
+
headerComponent?: import("react").ComponentType<import("../components/roster/roster.types").HeaderInput>;
|
|
25
|
+
laneLabelColumnComponent?: import("react").ComponentType<import("../components/roster/roster.types").LabelColumnInput>;
|
|
26
|
+
bodyComponent?: import("react").ComponentType<import("../components/roster/roster.types").BodyInput>;
|
|
26
27
|
} & {
|
|
27
28
|
bodyClassName?: string | undefined;
|
|
28
29
|
className?: string | undefined;
|
|
@@ -31,26 +32,26 @@ export declare const Roster: import("react").ComponentType<import("../components
|
|
|
31
32
|
}>;
|
|
32
33
|
export declare const Schedule: import("react").ComponentType<import("../components/schedule/schedule.types").ScheduleInput & ScheduleStyleProps & {
|
|
33
34
|
incompleteLabel?: string;
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
gutterComponent?: import("react").ComponentType<import("../components/schedule/schedule.types").ScheduleHoursInput>;
|
|
36
|
+
gridComponent?: import("react").ComponentType<import("../components/schedule/schedule.types").ScheduleHoursInput>;
|
|
37
|
+
dayHeaderComponent?: import("react").ComponentType<{
|
|
37
38
|
day: import("..").DayColumn;
|
|
38
|
-
}
|
|
39
|
-
|
|
39
|
+
}>;
|
|
40
|
+
skippedDateComponent?: import("react").ComponentType<{
|
|
40
41
|
localDate: string;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
}>;
|
|
43
|
+
columnComponent?: import("react").ComponentType<import("../components/schedule/schedule.types").ScheduleColumnInput>;
|
|
44
|
+
transitionComponent?: import("react").ComponentType<import("../components/schedule/schedule.types").ScheduleTransitionInput>;
|
|
45
|
+
nowLineComponent?: import("react").ComponentType<{
|
|
45
46
|
y: number;
|
|
46
47
|
column: number;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
48
|
+
}>;
|
|
49
|
+
intervalComponent?: import("react").ComponentType<import("..").IntervalInput>;
|
|
50
|
+
gapComponent?: import("react").ComponentType<import("..").GapInput>;
|
|
51
|
+
incompleteComponent?: import("react").ComponentType<{
|
|
51
52
|
lane: import("..").Lane;
|
|
52
53
|
label: string;
|
|
53
|
-
}
|
|
54
|
+
}>;
|
|
54
55
|
} & {
|
|
55
56
|
className?: string | undefined;
|
|
56
57
|
daysClassName?: string | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/nativewind/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAE1E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAEhF,KAAK,aAAa,CAAC,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,EAAE,GAAG,MAAM,WAAW,GAAG,GAAG,MAAM,WAAW,CAAC,CAAC;AACtF,KAAK,WAAW,CAAC,CAAC,SAAS,MAAM,IAAI,CAAC,SAAS,GAAG,MAAM,MAAM,WAAW,GACrE,GAAG,MAAM,OAAO,GAChB,OAAO,CAAC;AACZ,KAAK,OAAO,CAAC,CAAC,IAAI;KAAG,CAAC,IAAI,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC;CAAE,CAAC;AAEhE,8EAA8E;AAC9E,eAAO,MAAM,gBAAgB,EAAE,OAAO,CAAC,gBAAgB,CAKtD,CAAC;AACF,eAAO,MAAM,kBAAkB,EAAE,OAAO,CAAC,kBAAkB,CAK1D,CAAC;AAIF,eAAO,MAAM,MAAM
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/nativewind/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAE1E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAEhF,KAAK,aAAa,CAAC,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,EAAE,GAAG,MAAM,WAAW,GAAG,GAAG,MAAM,WAAW,CAAC,CAAC;AACtF,KAAK,WAAW,CAAC,CAAC,SAAS,MAAM,IAAI,CAAC,SAAS,GAAG,MAAM,MAAM,WAAW,GACrE,GAAG,MAAM,OAAO,GAChB,OAAO,CAAC;AACZ,KAAK,OAAO,CAAC,CAAC,IAAI;KAAG,CAAC,IAAI,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC;CAAE,CAAC;AAEhE,8EAA8E;AAC9E,eAAO,MAAM,gBAAgB,EAAE,OAAO,CAAC,gBAAgB,CAKtD,CAAC;AACF,eAAO,MAAM,kBAAkB,EAAE,OAAO,CAAC,kBAAkB,CAK1D,CAAC;AAIF,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;EAA2C,CAAC;AAC/D,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;EAA+C,CAAC"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Migrations
|
|
2
|
+
|
|
3
|
+
Changes to public props that need consumer edits, by the version that ships them.
|
|
4
|
+
The changelog lists every change; this page carries only the ones with a
|
|
5
|
+
migration step.
|
|
6
|
+
|
|
7
|
+
## 0.1.0: slot components replace render functions
|
|
8
|
+
|
|
9
|
+
Every Roster and Schedule prop that used to take a render function now takes a
|
|
10
|
+
component type or a node. Props ending in `Component` accept
|
|
11
|
+
`ComponentType<Input>` and are mounted by React with the same input as props.
|
|
12
|
+
Props ending in `Zone` accept `ReactNode`. Press callbacks (`onIntervalPress`,
|
|
13
|
+
`onGapPress`, `onCellPress`, `onIntervalHover`, `onNavigate`) are unchanged.
|
|
14
|
+
|
|
15
|
+
| Before (0.0.x) | After (0.1.0) | Input |
|
|
16
|
+
| --- | --- | --- |
|
|
17
|
+
| `emptyZone={() => <Empty />}` | `emptyZone={<Empty />}` | none |
|
|
18
|
+
| `cornerZone={() => <Corner />}` | `cornerZone={<Corner />}` | none |
|
|
19
|
+
| `headerZone={(input) => ...}` | `headerComponent={Header}` | `HeaderInput` |
|
|
20
|
+
| `laneLabelColumnZone={(input) => ...}` | `laneLabelColumnComponent={LabelColumn}` | `LabelColumnInput` |
|
|
21
|
+
| `bodyZone={(input) => ...}` | `bodyComponent={Body}` | `BodyInput` |
|
|
22
|
+
| `headerCellZone={({ tick }) => ...}` | `headerCellComponent={HeaderCell}` | `HeaderCellInput` |
|
|
23
|
+
| `laneLabelZone={(input) => ...}` | `laneLabelComponent={LaneLabel}` | `LaneLabelInput` |
|
|
24
|
+
| `intervalZone={(input) => ...}` | `intervalComponent={Interval}` | `IntervalInput` |
|
|
25
|
+
| `gapZone={(input) => ...}` | `gapComponent={Gap}` | `GapInput` |
|
|
26
|
+
| `gridZone={(input) => ...}` | `gridComponent={Grid}` | `GridInput` |
|
|
27
|
+
|
|
28
|
+
Schedule follows the same rule: `gutterZone`, `gridZone`, `dayHeaderZone`,
|
|
29
|
+
`skippedDateZone`, `columnZone`, `transitionZone`, `nowLineZone`, `intervalZone`,
|
|
30
|
+
`gapZone`, and `incompleteZone` become the matching `Component` props with the
|
|
31
|
+
same inputs.
|
|
32
|
+
|
|
33
|
+
Nested contracts renamed with them: `HeaderInput.headerCellZone` is now
|
|
34
|
+
`headerCellComponent`, `LabelColumnInput.laneLabelZone` is now
|
|
35
|
+
`laneLabelComponent`, and `BodyInput` carries `intervalComponent`,
|
|
36
|
+
`gapComponent`, and `gridComponent`.
|
|
37
|
+
|
|
38
|
+
Mechanical rewrite for a render function that was already a plain function of
|
|
39
|
+
its input:
|
|
40
|
+
|
|
41
|
+
```tsx
|
|
42
|
+
// Before
|
|
43
|
+
<Roster intervalZone={({ rect, layer }) => <Bar rect={rect} layer={layer} />} />
|
|
44
|
+
|
|
45
|
+
// After: the same function, declared once at module scope and passed as a type
|
|
46
|
+
function Interval({ rect, layer }: IntervalInput) {
|
|
47
|
+
return <Bar rect={rect} layer={layer} />;
|
|
48
|
+
}
|
|
49
|
+
<Roster intervalComponent={Interval} />
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Declare slot components at module scope. An inline arrow creates a new
|
|
53
|
+
component type every render, which remounts every interval and defeats the
|
|
54
|
+
body's content key.
|
|
55
|
+
|
|
56
|
+
The default parts are exported under their existing names (`RosterInterval`,
|
|
57
|
+
`RosterGap`, `RosterLaneLabel`, `RosterHeaderCell`, `RosterGrid`, `RosterHeader`,
|
|
58
|
+
`RosterLaneLabelColumn`, `RosterBody`, `RosterEmpty`, `RosterCorner`) and can be
|
|
59
|
+
composed inside a replacement. `RosterBody` is now built from `RosterBodyLayout`
|
|
60
|
+
(arranges `gridZone` and `listZone`) and `RosterLaneList` (owns the virtualized
|
|
61
|
+
lane list); both are exported for consumers that replace the body.
|
package/llms.txt
CHANGED
|
@@ -144,12 +144,12 @@ show the incompleteLabel; do not describe incomplete empty time as definitive.
|
|
|
144
144
|
|
|
145
145
|
| Import | Runtime exports and purpose |
|
|
146
146
|
| --- | --- |
|
|
147
|
-
| react-native-roster | Roster, Schedule,
|
|
147
|
+
| react-native-roster | Roster, Schedule, hooks, default slot components, RosterSelectionPopover, PortalHost, Portal, and core re-exports. |
|
|
148
148
|
| react-native-roster/core | layoutLane, coverageFor, flagFor, windowFor, prev, next, today, dayColumnsFor, timeAtX, timeAtY, snapToStep, byLabel, byCoverage, and core counters/caches. |
|
|
149
149
|
| react-native-roster/rrule | expandRuleSet, envelopeFor, expandStats, resetExpandStats, clearExpandCache; RuleSet, RosterRule, RosterDate, ExpandOptions, ExpandResult, and ExpandStats types. |
|
|
150
150
|
| react-native-roster/nativewind | Side-effect registration of Roster and Schedule with NativeWind's cssInterop, plus the registered Roster and Schedule and the rosterClassNames/scheduleClassNames mappings. Imports the optional nativewind peer. |
|
|
151
151
|
|
|
152
|
-
No default exports. Root exports renderer inputs/models/
|
|
152
|
+
No default exports. Root exports renderer inputs/models/slot input types as well as
|
|
153
153
|
core types. Core imports standard JS and Intl only. Only /rrule imports
|
|
154
154
|
rrule-temporal 1.6.0 and @js-temporal/polyfill 0.5.1. Those are installed runtime
|
|
155
155
|
dependencies but cannot enter root/core bundles through library imports.
|
|
@@ -160,6 +160,14 @@ from dist/src; declarations use the types condition. Build before Node export
|
|
|
160
160
|
tests. Root needs a native renderer or web bundler; direct Node use of root is
|
|
161
161
|
not a substitute for a React Native app. Core and /rrule work in Node/Bun.
|
|
162
162
|
|
|
163
|
+
## 0.1.0 slot prop rename
|
|
164
|
+
|
|
165
|
+
0.1.0 renamed every input-bearing render-function Zone prop to a Component prop;
|
|
166
|
+
use the current names below instead of the 0.0.x props. Singleton emptyZone and
|
|
167
|
+
cornerZone keep their names and now take nodes. See [docs/migrations.md](./docs/migrations.md).
|
|
168
|
+
Zone props are ReactNode.
|
|
169
|
+
Component props are ComponentType<Input>.
|
|
170
|
+
|
|
163
171
|
## Renderer contracts
|
|
164
172
|
|
|
165
173
|
Roster required props: lanes: Lane[], windowSpec: WindowSpec.
|
|
@@ -178,7 +186,7 @@ outside React state.
|
|
|
178
186
|
|
|
179
187
|
useRoster returns window, projection, orderedLanes, coverage, laneState,
|
|
180
188
|
geometryFor(lane), scroll, press(lane,x,y), ticks, contentWidth, viewport,
|
|
181
|
-
onLayout, navigate, and status ('empty' or 'ready'). There is no visibleRange
|
|
189
|
+
onLayout, navigate, selection, dismissSelection, and status ('empty' or 'ready'). There is no visibleRange
|
|
182
190
|
field in the shipped public model. Custom layouts must wire onLayout. Custom
|
|
183
191
|
bodies compute geometry only for mounted lanes, preserving virtualization.
|
|
184
192
|
A zero-duration window has contentWidth=0 and renders no Roster body. Positive
|
|
@@ -198,44 +206,118 @@ The chassis measures width, reserves a 48 px gutter, and fits all actual day
|
|
|
198
206
|
columns without horizontal scrolling; the body scrolls vertically. now updates
|
|
199
207
|
every minute and is null outside the selected window.
|
|
200
208
|
|
|
201
|
-
|
|
202
|
-
|
|
209
|
+
Props ending in Component accept ComponentType<Input>, mounted as React elements.
|
|
210
|
+
Props ending in Zone accept ReactNode; pass null to suppress a singleton default.
|
|
211
|
+
Define component types at module scope; hooks and class components work normally.
|
|
212
|
+
Use exported defaults inside replacements to preserve geometry, scrolling, and
|
|
213
|
+
interaction. Input types, including HeaderCellInput, are exported from root.
|
|
214
|
+
Mount a React context provider above Roster for extra consumer data, and read it with useContext in a module-scope slot component.
|
|
215
|
+
Avoid inline closures or memoized factories returning a new component per render; new interval types remount every interval and defeat the body's content key.
|
|
216
|
+
|
|
217
|
+
RosterBody composes the exported RosterBodyLayout (gridZone/listZone nodes with
|
|
218
|
+
scroll wiring) and RosterLaneList (LegendList, geometryFor, and LaneRow mounting).
|
|
219
|
+
Keep its viewport gate and measured estimatedListSize in custom compositions.
|
|
203
220
|
|
|
204
221
|
## Roster zones
|
|
205
222
|
|
|
206
|
-
|
|
|
223
|
+
| Slot | Component inputs or node | Default and behavior |
|
|
207
224
|
| --- | --- | --- |
|
|
208
|
-
| `emptyZone` |
|
|
209
|
-
| `
|
|
210
|
-
| `
|
|
211
|
-
| `
|
|
212
|
-
| `
|
|
213
|
-
| `
|
|
214
|
-
| `cornerZone` |
|
|
215
|
-
| `
|
|
216
|
-
| `
|
|
217
|
-
| `
|
|
225
|
+
| `emptyZone` | `ReactNode` | `RosterEmpty`: No lanes. |
|
|
226
|
+
| `laneLabelComponent` | `lane`, `flag`, `complete`, `viewTimezone`, localized labels | `RosterLaneLabel`: label, differing IANA zone badge, and notices. |
|
|
227
|
+
| `headerCellComponent` | `HeaderCellInput` (`tick`) | `RosterHeaderCell`: tick label. |
|
|
228
|
+
| `intervalComponent` | `rect`, `layer`, `lane`, `highlighted` | `RosterInterval`: positioned colored rect, with final inset bounds. |
|
|
229
|
+
| `gapComponent` | `rect`, `layer`, `lane` | `RosterGap`: no visible content; the row supplies pressable bounds. |
|
|
230
|
+
| `gridComponent` | `ticks`, `contentWidth` | `RosterGrid`: one hairline per tick behind every lane. |
|
|
231
|
+
| `cornerZone` | `ReactNode` | `RosterCorner`: nothing; the cell above the labels, laneLabelWidth wide. |
|
|
232
|
+
| `headerComponent` | `ticks`, `projection`, `scroll`, `contentWidth`, `headerCellComponent` | `RosterHeader`: frozen header following horizontal offset. |
|
|
233
|
+
| `laneLabelColumnComponent` | `labels: LaneLabelInput[]`, `projection`, `scroll`, `laneLabelComponent` | `RosterLaneLabelColumn`: frozen labels following vertical offset. |
|
|
234
|
+
| `bodyComponent` | Ordered `lanes`, `window`, `geometryFor`, `projection`, `scroll`, `press`, `ticks`, `viewport`, `contentWidth`, highlight/hover, incomplete label, and rect components | `RosterBody`: virtualized lanes. |
|
|
235
|
+
|
|
236
|
+
## Selection
|
|
237
|
+
|
|
238
|
+
Roster only; Schedule does not yet support selection and will gain it in a later change.
|
|
239
|
+
intervalDetailComponent?: ComponentType<IntervalDetailInput> enables selection on interval
|
|
240
|
+
press while preserving onIntervalPress. Absent content retains no selection.
|
|
241
|
+
Pressing the selected interval again dismisses it; pressing another interval
|
|
242
|
+
switches selection. Cell and gap presses dismiss selection while still firing
|
|
243
|
+
`onCellPress` and `onGapPress`. These rules live in the hook and apply on native
|
|
244
|
+
and web; web outside press and Escape still dismiss.
|
|
245
|
+
IntervalDetailInput is IntervalInput plus absolute start and end and viewTimezone.
|
|
246
|
+
useRoster owns selection: {rect,layer,lane,start,end}|null and dismissSelection(). It resolves
|
|
247
|
+
current lane/layer/rect references and clears removed lane or absolute rect bounds.
|
|
248
|
+
Resizing and sorting retain valid selection with current geometry; reconciliation
|
|
249
|
+
uses the private reconcileSelection helper to match source identity sets and choose
|
|
250
|
+
nearest bounds with a total difference of at most 1 ms for projection roundoff.
|
|
251
|
+
selectable?: boolean belongs only to the hook input, RosterInput, and defaults to false.
|
|
252
|
+
It is excluded from RosterProps; hook consumers pass
|
|
253
|
+
selectable: true to retain selection. intervalDetailComponent, selectionLayout, and
|
|
254
|
+
portalHost belong to RosterProps because the chassis mounts content and the layout.
|
|
255
|
+
The chassis passes selectable: Boolean(intervalDetailComponent) to useRoster.
|
|
256
|
+
Custom chassis mount their content and layout using the returned model.
|
|
257
|
+
|
|
258
|
+
selectionLayout?: ComponentType<SelectionLayoutProps> defaults to the root-exported
|
|
259
|
+
RosterSelectionPopover. It is the explicit naming exception to the Component suffix.
|
|
260
|
+
The chassis mounts the strategy once around the body node, then passes that node
|
|
261
|
+
to RosterLayout.bodyZone. SelectionLayoutProps is exported: anchorZone and contentZone
|
|
262
|
+
are ReactNode; targetBounds is {x,y,width,height}|null in body-content coordinates, including
|
|
263
|
+
the lane offset and interval inset; open is
|
|
264
|
+
boolean; onDismiss is () => void; portalHost is string; scroll is Pick<RosterScroll, 'x' | 'y' | 'headerStyle' | 'labelStyle'>.
|
|
265
|
+
Layouts receive no lane, layer, or rect. Render anchorZone once and arrange contentZone
|
|
266
|
+
above or beside it. The interval-detail fixture demonstrates a runtime inspector toggle.
|
|
267
|
+
|
|
268
|
+
Native selection-layout.tsx uses the root-exported PortalHost and Portal from
|
|
269
|
+
components/primitives/portal.tsx, a module-level Map store with useSyncExternalStore.
|
|
270
|
+
The default layout owns a host named from the roster's useId; portalHost overrides
|
|
271
|
+
that name. Use distinct names for independent rosters and never mount the same host
|
|
272
|
+
twice. Custom layouts may target an ancestor host they own. Caller context does not
|
|
273
|
+
cross a store portal; provide context above the host or inside the portaled node.
|
|
274
|
+
Native hardware back dismisses details. The detail card flips above
|
|
275
|
+
when that fits, or uses the top edge when neither vertical placement fits. It clamps
|
|
276
|
+
left using measured viewport and content widths. Shared x/y values position the
|
|
277
|
+
overlay in viewport coordinates, never React scroll state. Selection identity
|
|
278
|
+
must not enter the body content key or cause mounted rows to render. The stable press
|
|
279
|
+
ref lives in use-roster-press.ts so React Compiler can retain derived body inputs in useRoster.
|
|
280
|
+
|
|
281
|
+
Native has no intercepting dismissal overlay; body presses reach the hook, and the detail
|
|
282
|
+
card captures its own presses. Web excludes the body wrapper from Radix outside
|
|
283
|
+
dismissal, leaving body presses to the hook while preserving true outside presses and Escape.
|
|
284
|
+
The hook toggles the selected interval closed, switches to another interval, and dismisses
|
|
285
|
+
on cell or gap presses while preserving their callbacks. The body restores horizontal
|
|
286
|
+
and vertical offsets from shared values on remount when selectionLayout changes.
|
|
287
|
+
A mount effect calls the horizontal ScrollView ref's scrollTo without animation;
|
|
288
|
+
native also retains contentOffset. LegendList restores initialScrollOffset through
|
|
289
|
+
its own web mount effect and native initial offset.
|
|
290
|
+
|
|
291
|
+
selection-layout.web.tsx uses @radix-ui/react-popover, required by the web root entry
|
|
292
|
+
but an optional peer for native/core-only consumers. Source web bundlers (Vite,
|
|
293
|
+
Storybook, or Metro web) require it even with selection disabled because the web
|
|
294
|
+
layout is in the module graph. Install with Bun. The emitted
|
|
295
|
+
browser remap must travel with the shared selection-layout.types.ts contract, just
|
|
296
|
+
like press-point and interval-hover. Its zero-size, pointer-transparent anchor follows
|
|
297
|
+
the shared translation; Radix's portal follows anchor movement and owns outside press,
|
|
298
|
+
Escape, and collisions. The layout returns focus to the previously focused element
|
|
299
|
+
only after Escape.
|
|
218
300
|
|
|
219
301
|
## Schedule zones
|
|
220
302
|
|
|
221
|
-
|
|
|
303
|
+
| Slot | Component inputs or node | Default and behavior |
|
|
222
304
|
| --- | --- | --- |
|
|
223
|
-
| `
|
|
224
|
-
| `
|
|
225
|
-
| `
|
|
226
|
-
| `
|
|
227
|
-
| `
|
|
228
|
-
| `
|
|
229
|
-
| `
|
|
230
|
-
| `
|
|
231
|
-
| `
|
|
305
|
+
| `gutterComponent` | `hours`, `pxPerHour` | `ScheduleGutter`: 24 frozen hour labels. |
|
|
306
|
+
| `gridComponent` | `hours`, `pxPerHour` | `ScheduleGrid`: 24 bordered hour bands behind each day's rects. |
|
|
307
|
+
| `dayHeaderComponent` | `day` | `ScheduleDayHeader`: weekday, localDate, and transition badge. |
|
|
308
|
+
| `skippedDateComponent` | `localDate` | `ScheduleSkippedDate`: zero-width header marker for a wholly skipped date. |
|
|
309
|
+
| `columnComponent` | `day`, `rects`, `gapRects`, `lane`, `highlightSource`, `press`, interval/gap components | `ScheduleColumn`: final rect bounds in layer order. |
|
|
310
|
+
| `transitionComponent` | `day`, `transition`, `y`, `dividerY`, `height`, `width` | `ScheduleTransition`: skipped-time hatch, or repeat divider and again label. |
|
|
311
|
+
| `nowLineComponent` | `y`, `column` | `ScheduleNowLine`: line in the current day's column, updated each minute. |
|
|
312
|
+
| `intervalComponent`, `gapComponent` | Same inputs as Roster | Shared `RosterInterval` and `RosterGap`. |
|
|
313
|
+
| `incompleteComponent` | `lane`, `label` | `ScheduleIncomplete`: notice in reserved space above the grid when incomplete. |
|
|
232
314
|
|
|
233
315
|
Position custom interval content at rect.x/y with width/height/z and
|
|
234
316
|
pointerEvents="none". Gap content already sits in a positioned pressable.
|
|
235
317
|
Column x coordinates are local; select the column through rect.column.
|
|
236
|
-
|
|
318
|
+
Slot components are plain React Native views; under NativeWind they take className
|
|
237
319
|
directly. The default RosterLaneLabel owns its row's bottom border, so a custom
|
|
238
|
-
|
|
320
|
+
laneLabelComponent draws its own separators.
|
|
239
321
|
|
|
240
322
|
## Navigation and zones
|
|
241
323
|
|
|
@@ -255,7 +337,7 @@ Schedule always uses 24 equal wall-hour bands. Positive deltaMinutes means a
|
|
|
255
337
|
skipped empty region; negative means two half-height repeat regions. Rects split
|
|
256
338
|
at column edges, source changes, and every scale boundary. For repeat at T with
|
|
257
339
|
magnitude d, boundaries are T-d, T, and T+d. A wholly skipped date produces no
|
|
258
|
-
column;
|
|
340
|
+
column; skippedDateComponent labels the header gap (Apia 2011-12-30).
|
|
259
341
|
Each column spans the first instant of its date to the first instant of the next.
|
|
260
342
|
Skipped wall spans belong to the date they interrupt. Its transitions include a
|
|
261
343
|
skip at the exclusive end when it empties that date's final wall bands (Nuuk
|
|
@@ -457,7 +539,7 @@ W: seed 1318, 200 lanes, week, two layers, 24-lane layout batch, 15-minute ticks
|
|
|
457
539
|
Bun 1.4.0, 2026-09-08T05:18:00Z, commit
|
|
458
540
|
1c4ac0e8580b1d46c043f946aa7ebc1ee316d0fa. Median of 11 target-cold samples after
|
|
459
541
|
five runtime warmups. Each timing must stay below 16 ms; CI also enforces <=1.5x
|
|
460
|
-
its baseline. Size gates: core <15 kB, root <
|
|
542
|
+
its baseline. Size gates: core <15 kB, root <44 kB minified/uncompressed, peers
|
|
461
543
|
external. Phone fps and cold-layout numbers are not yet captured; the paired
|
|
462
544
|
react-big-scheduler comparison is not yet measured. Do not claim relative speed.
|
|
463
545
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-roster",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Layered intervals with provenance across lanes and a shared time axis for React Native.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react-native",
|
|
@@ -31,7 +31,8 @@
|
|
|
31
31
|
"types": "./dist/src/index.d.ts",
|
|
32
32
|
"browser": {
|
|
33
33
|
"./dist/src/components/primitives/press-point.js": "./dist/src/components/primitives/press-point.web.js",
|
|
34
|
-
"./dist/src/components/roster/lanes/interval-hover.js": "./dist/src/components/roster/lanes/interval-hover.web.js"
|
|
34
|
+
"./dist/src/components/roster/lanes/interval-hover.js": "./dist/src/components/roster/lanes/interval-hover.web.js",
|
|
35
|
+
"./dist/src/components/roster/selection/selection-layout.js": "./dist/src/components/roster/selection/selection-layout.web.js"
|
|
35
36
|
},
|
|
36
37
|
"exports": {
|
|
37
38
|
".": {
|
|
@@ -66,7 +67,8 @@
|
|
|
66
67
|
"README.md",
|
|
67
68
|
"LICENSE",
|
|
68
69
|
"NOTICE.md",
|
|
69
|
-
"llms.txt"
|
|
70
|
+
"llms.txt",
|
|
71
|
+
"docs/migrations.md"
|
|
70
72
|
],
|
|
71
73
|
"scripts": {
|
|
72
74
|
"clean": "rm -rf dist",
|
|
@@ -100,7 +102,8 @@
|
|
|
100
102
|
"nativewind": ">=4.1.0",
|
|
101
103
|
"react": ">=18.2.0",
|
|
102
104
|
"react-native": ">=0.74.0",
|
|
103
|
-
"react-native-reanimated": ">=3.19.0"
|
|
105
|
+
"react-native-reanimated": ">=3.19.0",
|
|
106
|
+
"@radix-ui/react-popover": "^1.1.23"
|
|
104
107
|
},
|
|
105
108
|
"peerDependenciesMeta": {
|
|
106
109
|
"expo": {
|
|
@@ -111,6 +114,9 @@
|
|
|
111
114
|
},
|
|
112
115
|
"react-native-reanimated": {
|
|
113
116
|
"optional": true
|
|
117
|
+
},
|
|
118
|
+
"@radix-ui/react-popover": {
|
|
119
|
+
"optional": true
|
|
114
120
|
}
|
|
115
121
|
},
|
|
116
122
|
"dependencies": {
|
|
@@ -149,7 +155,8 @@
|
|
|
149
155
|
"semantic-release": "^25.0.3",
|
|
150
156
|
"semver": "^7.7.0",
|
|
151
157
|
"size-limit": "^13.0.3",
|
|
152
|
-
"temporal-spec": "1.0.1"
|
|
158
|
+
"temporal-spec": "1.0.1",
|
|
159
|
+
"@radix-ui/react-popover": "1.1.23"
|
|
153
160
|
},
|
|
154
161
|
"publishConfig": {
|
|
155
162
|
"access": "public",
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
# layers
|
|
2
2
|
|
|
3
3
|
This area is about a layer; its children are intervals and gaps. Both
|
|
4
|
-
projections draw the same
|
|
4
|
+
projections draw the same components, so they live above Roster and Schedule.
|
|
5
5
|
|
|
6
6
|
- Root entry exports: `RosterInterval`, `RosterGap`, `IntervalInput`, `GapInput`
|
|
7
|
-
- `layers.types.ts`: the
|
|
8
|
-
- `parts/interval.tsx`, `parts/gap.tsx`: the default
|
|
7
|
+
- `layers.types.ts`: the component input contract both projections pass
|
|
8
|
+
- `parts/interval.tsx`, `parts/gap.tsx`: the default components
|
|
9
9
|
- `utils/styles.ts`: content-keyed style objects per layer
|
|
10
10
|
|
|
11
11
|
Imports core only. Tests: `test/components/layers`.
|
|
12
|
+
|
|
13
|
+
Both projections accept intervalComponent and gapComponent as ComponentType inputs.
|
|
14
|
+
Their data-owning lane or column mounts the component with the final rect, layer,
|
|
15
|
+
and lane; interval inputs also carry highlighted. No renderer calls a slot function.
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
# primitives
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
public export.
|
|
3
|
+
Building blocks shared by the projections, plus the native portal store for Roster selection.
|
|
5
4
|
|
|
6
5
|
- `press-point.tsx`, `press-point.web.tsx`, `press-point.types.ts`: pointer
|
|
7
6
|
coordinates relative to the pressed surface; the web file is selected by the
|
|
@@ -10,3 +9,15 @@ public export.
|
|
|
10
9
|
default paint when the override carries a NativeWind class entry
|
|
11
10
|
|
|
12
11
|
Tests: `test/components/primitives`.
|
|
12
|
+
|
|
13
|
+
- `portal.tsx`: root-exported `PortalHost({name})` and
|
|
14
|
+
`Portal({hostName,name,children})`; a module-level Map of hosts to portal nodes,
|
|
15
|
+
subscribed through useSyncExternalStore, registered and removed through lifecycle effects
|
|
16
|
+
|
|
17
|
+
Mount one host per destination name. The default Roster selection layout owns its
|
|
18
|
+
per-instance host; custom layouts can target an ancestor host they own. Caller
|
|
19
|
+
context does not cross the store; provide it above the host or inside the node.
|
|
20
|
+
Schedule does not yet support selection.
|
|
21
|
+
|
|
22
|
+
As a primitive, `Portal` takes `children` rather than a named zone; named zones belong
|
|
23
|
+
to the machine and feature tiers.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Fragment, type ReactNode, useEffect, useSyncExternalStore } from 'react';
|
|
2
|
+
|
|
3
|
+
const hosts = new Map<string, Map<string, ReactNode>>();
|
|
4
|
+
const listeners = new Set<() => void>();
|
|
5
|
+
const empty = new Map<string, ReactNode>();
|
|
6
|
+
|
|
7
|
+
function subscribe(listener: () => void) {
|
|
8
|
+
listeners.add(listener);
|
|
9
|
+
return () => listeners.delete(listener);
|
|
10
|
+
}
|
|
11
|
+
function publish(hostName: string, nodes: Map<string, ReactNode>) {
|
|
12
|
+
if (nodes.size) hosts.set(hostName, nodes);
|
|
13
|
+
else hosts.delete(hostName);
|
|
14
|
+
for (const listener of listeners) listener();
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** Mount once at the destination for a named native portal. */
|
|
18
|
+
export function PortalHost({ name }: { name: string }) {
|
|
19
|
+
const nodes = useSyncExternalStore(
|
|
20
|
+
subscribe,
|
|
21
|
+
() => hosts.get(name) ?? empty,
|
|
22
|
+
() => empty,
|
|
23
|
+
);
|
|
24
|
+
return Array.from(nodes, ([key, node]) => <Fragment key={key}>{node}</Fragment>);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** Register content at a named native host; caller context does not cross the store. */
|
|
28
|
+
export function Portal({
|
|
29
|
+
hostName,
|
|
30
|
+
name,
|
|
31
|
+
children,
|
|
32
|
+
}: {
|
|
33
|
+
hostName: string;
|
|
34
|
+
name: string;
|
|
35
|
+
children: ReactNode;
|
|
36
|
+
}) {
|
|
37
|
+
useEffect(() => {
|
|
38
|
+
const nodes = new Map(hosts.get(hostName));
|
|
39
|
+
nodes.set(name, children);
|
|
40
|
+
publish(hostName, nodes);
|
|
41
|
+
return () => {
|
|
42
|
+
const nodes = new Map(hosts.get(hostName));
|
|
43
|
+
nodes.delete(name);
|
|
44
|
+
publish(hostName, nodes);
|
|
45
|
+
};
|
|
46
|
+
}, [hostName, name, children]);
|
|
47
|
+
return null;
|
|
48
|
+
}
|