@12-apps/ui 6.87.0 → 6.88.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/components-catalog.md +1 -1
- package/dist/_internal/components/data-display/DayRuler/DayRuler.js +2 -2
- package/dist/_internal/components/data-display/ScheduleGrid/ScheduleGrid.js +6 -6
- package/dist/_internal/components/data-display/ScheduleGrid/ScheduleGrid.keyboard.js +2 -2
- package/dist/_internal/components/data-display/ScheduleGrid/ScheduleGrid.parts.js +3 -3
- package/dist/_internal/components/data-display/ScheduleGrid/ScheduleGrid.styles.js +1 -1
- package/dist/_internal/components/data-display/ScheduleGrid/schedule-grid-model.js +1 -1
- package/dist/_internal/components/data-display/ScheduleGrid/useGridDrag.js +2 -2
- package/dist/_internal/components/data-display/index.js +7 -7
- package/dist/_internal/components/index.js +7 -7
- package/dist/{chunk-I7CVC2DW.js → chunk-ARPOWDEO.js} +34 -14
- package/dist/chunk-ARPOWDEO.js.map +1 -0
- package/dist/{chunk-MQVYJVKV.js → chunk-E6UMTR2G.js} +2 -2
- package/dist/chunk-E6UMTR2G.js.map +1 -0
- package/dist/{chunk-D6JKCCRQ.js → chunk-MLIBJWQZ.js} +2 -2
- package/dist/{chunk-QQFFE3CQ.js → chunk-MPUOLKFT.js} +2 -2
- package/dist/{chunk-WCETCAZO.js → chunk-UIJU5X26.js} +5 -5
- package/dist/{chunk-B3SL5FP2.js → chunk-WBMLMLXP.js} +2 -2
- package/dist/{chunk-YSUJCKEE.js → chunk-WMTW4JXT.js} +7 -3
- package/dist/chunk-WMTW4JXT.js.map +1 -0
- package/dist/data-display/DayRuler.js +2 -2
- package/dist/data-display/ScheduleGrid.js +6 -6
- package/dist/types/components/data-display/ScheduleGrid/ScheduleGrid.parts.d.ts.map +1 -1
- package/dist/types/components/data-display/ScheduleGrid/ScheduleGrid.styles.d.ts +4 -1
- package/dist/types/components/data-display/ScheduleGrid/ScheduleGrid.styles.d.ts.map +1 -1
- package/dist/types/components/data-display/ScheduleGrid/ScheduleGrid.types.d.ts +23 -3
- package/dist/types/components/data-display/ScheduleGrid/ScheduleGrid.types.d.ts.map +1 -1
- package/dist/types/components/data-display/ScheduleGrid/schedule-grid-model.d.ts +1 -1
- package/dist/types/components/data-display/ScheduleGrid/schedule-grid-model.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/data-display/ScheduleGrid/ScheduleGrid.md +35 -5
- package/src/components/data-display/ScheduleGrid/ScheduleGrid.parts.tsx +33 -8
- package/src/components/data-display/ScheduleGrid/ScheduleGrid.styles.ts +9 -2
- package/src/components/data-display/ScheduleGrid/ScheduleGrid.types.ts +23 -3
- package/src/components/data-display/ScheduleGrid/schedule-grid-model.ts +2 -2
- package/dist/chunk-I7CVC2DW.js.map +0 -1
- package/dist/chunk-MQVYJVKV.js.map +0 -1
- package/dist/chunk-YSUJCKEE.js.map +0 -1
- /package/dist/{chunk-D6JKCCRQ.js.map → chunk-MLIBJWQZ.js.map} +0 -0
- /package/dist/{chunk-QQFFE3CQ.js.map → chunk-MPUOLKFT.js.map} +0 -0
- /package/dist/{chunk-WCETCAZO.js.map → chunk-UIJU5X26.js.map} +0 -0
- /package/dist/{chunk-B3SL5FP2.js.map → chunk-WBMLMLXP.js.map} +0 -0
package/components-catalog.md
CHANGED
|
@@ -234,7 +234,7 @@ Components for displaying data, visualizations, and information to users.
|
|
|
234
234
|
### ScheduleGrid
|
|
235
235
|
**Purpose**: A week grid of people (or resources) × days with blocks that have a start and an end
|
|
236
236
|
**Use Cases**: Staff schedules (turnos), rosters, resource booking by day
|
|
237
|
-
**Features**: Click an empty cell to create, drag across a row to create on each day, drag a block's edge grip to copy it along the row, drag its middle to move it, click to open; blocked (hatched) days refuse drops; a block's break drawn as a hatched gap; a name adornment and a chips slot per row; five tones that each carry their note text; sticky header row; keyboard twins (Shift+←/→ copy, Alt+←/→ move, arrows move focus) with a live region; touch never drags; read-only, loading, error, empty; container queries
|
|
237
|
+
**Features**: Click an empty cell to create, drag across a row to create on each day, drag a block's edge grip to copy it along the row, drag its middle to move it, click to open; blocked (hatched) days refuse drops; closed (gone) days offer no "+", refuse a create or a drop, draw no fill and carry a screen-reader-only label; past day headers in the secondary ink; a block's break drawn as a hatched gap; a name adornment and a chips slot per row; five tones that each carry their note text; sticky header row; keyboard twins (Shift+←/→ copy, Alt+←/→ move, arrows move focus) with a live region; touch never drags; read-only, loading, error, empty; container queries
|
|
238
238
|
**Location**: `src/components/data-display/ScheduleGrid`
|
|
239
239
|
**Docs**: `src/components/data-display/ScheduleGrid/ScheduleGrid.md`
|
|
240
240
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import {
|
|
3
3
|
DayRuler
|
|
4
|
-
} from "../../../../chunk-
|
|
4
|
+
} from "../../../../chunk-MLIBJWQZ.js";
|
|
5
5
|
import "../../../../chunk-MAYAJXO6.js";
|
|
6
6
|
import "../../../../chunk-IP424VZD.js";
|
|
7
7
|
import "../../../../chunk-EEK2NK4W.js";
|
|
@@ -11,7 +11,7 @@ import "../../../../chunk-7ZQ3KQ7J.js";
|
|
|
11
11
|
import "../../../../chunk-YMYJO2CZ.js";
|
|
12
12
|
import "../../../../chunk-AC7K7IJE.js";
|
|
13
13
|
import "../../../../chunk-6HZYRKOB.js";
|
|
14
|
-
import "../../../../chunk-
|
|
14
|
+
import "../../../../chunk-WMTW4JXT.js";
|
|
15
15
|
import "../../../../chunk-3R6BR22L.js";
|
|
16
16
|
import "../../../../chunk-YE44HUFF.js";
|
|
17
17
|
import "../../../../chunk-35HMJQLO.js";
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import {
|
|
3
3
|
ScheduleGrid
|
|
4
|
-
} from "../../../../chunk-
|
|
5
|
-
import "../../../../chunk-
|
|
6
|
-
import "../../../../chunk-
|
|
4
|
+
} from "../../../../chunk-UIJU5X26.js";
|
|
5
|
+
import "../../../../chunk-MPUOLKFT.js";
|
|
6
|
+
import "../../../../chunk-ARPOWDEO.js";
|
|
7
7
|
import "../../../../chunk-GONPUJIE.js";
|
|
8
|
-
import "../../../../chunk-
|
|
9
|
-
import "../../../../chunk-
|
|
8
|
+
import "../../../../chunk-WBMLMLXP.js";
|
|
9
|
+
import "../../../../chunk-E6UMTR2G.js";
|
|
10
10
|
import "../../../../chunk-AC7K7IJE.js";
|
|
11
11
|
import "../../../../chunk-6HZYRKOB.js";
|
|
12
|
-
import "../../../../chunk-
|
|
12
|
+
import "../../../../chunk-WMTW4JXT.js";
|
|
13
13
|
import "../../../../chunk-3R6BR22L.js";
|
|
14
14
|
import "../../../../chunk-YE44HUFF.js";
|
|
15
15
|
import "../../../../chunk-35HMJQLO.js";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
focusables,
|
|
3
3
|
handleGridKey
|
|
4
|
-
} from "../../../../chunk-
|
|
5
|
-
import "../../../../chunk-
|
|
4
|
+
} from "../../../../chunk-MPUOLKFT.js";
|
|
5
|
+
import "../../../../chunk-E6UMTR2G.js";
|
|
6
6
|
import "../../../../chunk-PZ5AY32C.js";
|
|
7
7
|
export {
|
|
8
8
|
focusables,
|
|
@@ -2,11 +2,11 @@ import {
|
|
|
2
2
|
GridBody,
|
|
3
3
|
GridCell,
|
|
4
4
|
GridHeader
|
|
5
|
-
} from "../../../../chunk-
|
|
6
|
-
import "../../../../chunk-
|
|
5
|
+
} from "../../../../chunk-ARPOWDEO.js";
|
|
6
|
+
import "../../../../chunk-E6UMTR2G.js";
|
|
7
7
|
import "../../../../chunk-AC7K7IJE.js";
|
|
8
8
|
import "../../../../chunk-6HZYRKOB.js";
|
|
9
|
-
import "../../../../chunk-
|
|
9
|
+
import "../../../../chunk-WMTW4JXT.js";
|
|
10
10
|
import "../../../../chunk-3R6BR22L.js";
|
|
11
11
|
import "../../../../chunk-4HK4FVMV.js";
|
|
12
12
|
import "../../../../chunk-TZ23DNKY.js";
|
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
skeletonCellSx,
|
|
22
22
|
totalCellSx,
|
|
23
23
|
totalHeaderSx
|
|
24
|
-
} from "../../../../chunk-
|
|
24
|
+
} from "../../../../chunk-WMTW4JXT.js";
|
|
25
25
|
import "../../../../chunk-3R6BR22L.js";
|
|
26
26
|
import "../../../../chunk-4HK4FVMV.js";
|
|
27
27
|
import "../../../../chunk-TZ23DNKY.js";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
useGridDrag
|
|
3
|
-
} from "../../../../chunk-
|
|
4
|
-
import "../../../../chunk-
|
|
3
|
+
} from "../../../../chunk-WBMLMLXP.js";
|
|
4
|
+
import "../../../../chunk-E6UMTR2G.js";
|
|
5
5
|
import "../../../../chunk-YE44HUFF.js";
|
|
6
6
|
import "../../../../chunk-PZ5AY32C.js";
|
|
7
7
|
export {
|
|
@@ -134,12 +134,12 @@ import "../../../chunk-PUFA7FQ7.js";
|
|
|
134
134
|
import "../../../chunk-7RXL4ONS.js";
|
|
135
135
|
import {
|
|
136
136
|
ScheduleGrid
|
|
137
|
-
} from "../../../chunk-
|
|
138
|
-
import "../../../chunk-
|
|
139
|
-
import "../../../chunk-
|
|
137
|
+
} from "../../../chunk-UIJU5X26.js";
|
|
138
|
+
import "../../../chunk-MPUOLKFT.js";
|
|
139
|
+
import "../../../chunk-ARPOWDEO.js";
|
|
140
140
|
import "../../../chunk-GONPUJIE.js";
|
|
141
|
-
import "../../../chunk-
|
|
142
|
-
import "../../../chunk-
|
|
141
|
+
import "../../../chunk-WBMLMLXP.js";
|
|
142
|
+
import "../../../chunk-E6UMTR2G.js";
|
|
143
143
|
import {
|
|
144
144
|
SectionOnboarding
|
|
145
145
|
} from "../../../chunk-AD6GRJFV.js";
|
|
@@ -208,7 +208,7 @@ import "../../../chunk-G3E66C6J.js";
|
|
|
208
208
|
import "../../../chunk-TTRWOI6Z.js";
|
|
209
209
|
import {
|
|
210
210
|
DayRuler
|
|
211
|
-
} from "../../../chunk-
|
|
211
|
+
} from "../../../chunk-MLIBJWQZ.js";
|
|
212
212
|
import "../../../chunk-MAYAJXO6.js";
|
|
213
213
|
import "../../../chunk-IP424VZD.js";
|
|
214
214
|
import "../../../chunk-EEK2NK4W.js";
|
|
@@ -218,7 +218,7 @@ import "../../../chunk-7ZQ3KQ7J.js";
|
|
|
218
218
|
import "../../../chunk-YMYJO2CZ.js";
|
|
219
219
|
import "../../../chunk-AC7K7IJE.js";
|
|
220
220
|
import "../../../chunk-6HZYRKOB.js";
|
|
221
|
-
import "../../../chunk-
|
|
221
|
+
import "../../../chunk-WMTW4JXT.js";
|
|
222
222
|
import "../../../chunk-3R6BR22L.js";
|
|
223
223
|
import "../../../chunk-YE44HUFF.js";
|
|
224
224
|
import "../../../chunk-35HMJQLO.js";
|
|
@@ -590,12 +590,12 @@ import "../../chunk-PUFA7FQ7.js";
|
|
|
590
590
|
import "../../chunk-7RXL4ONS.js";
|
|
591
591
|
import {
|
|
592
592
|
ScheduleGrid
|
|
593
|
-
} from "../../chunk-
|
|
594
|
-
import "../../chunk-
|
|
595
|
-
import "../../chunk-
|
|
593
|
+
} from "../../chunk-UIJU5X26.js";
|
|
594
|
+
import "../../chunk-MPUOLKFT.js";
|
|
595
|
+
import "../../chunk-ARPOWDEO.js";
|
|
596
596
|
import "../../chunk-GONPUJIE.js";
|
|
597
|
-
import "../../chunk-
|
|
598
|
-
import "../../chunk-
|
|
597
|
+
import "../../chunk-WBMLMLXP.js";
|
|
598
|
+
import "../../chunk-E6UMTR2G.js";
|
|
599
599
|
import {
|
|
600
600
|
SectionOnboarding
|
|
601
601
|
} from "../../chunk-AD6GRJFV.js";
|
|
@@ -797,7 +797,7 @@ import "../../chunk-G3E66C6J.js";
|
|
|
797
797
|
import "../../chunk-TTRWOI6Z.js";
|
|
798
798
|
import {
|
|
799
799
|
DayRuler
|
|
800
|
-
} from "../../chunk-
|
|
800
|
+
} from "../../chunk-MLIBJWQZ.js";
|
|
801
801
|
import "../../chunk-MAYAJXO6.js";
|
|
802
802
|
import "../../chunk-IP424VZD.js";
|
|
803
803
|
import "../../chunk-EEK2NK4W.js";
|
|
@@ -807,7 +807,7 @@ import "../../chunk-7ZQ3KQ7J.js";
|
|
|
807
807
|
import "../../chunk-YMYJO2CZ.js";
|
|
808
808
|
import "../../chunk-AC7K7IJE.js";
|
|
809
809
|
import "../../chunk-6HZYRKOB.js";
|
|
810
|
-
import "../../chunk-
|
|
810
|
+
import "../../chunk-WMTW4JXT.js";
|
|
811
811
|
import "../../chunk-3R6BR22L.js";
|
|
812
812
|
import "../../chunk-YE44HUFF.js";
|
|
813
813
|
import "../../chunk-35HMJQLO.js";
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
daysBetween,
|
|
3
3
|
isOpen
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-E6UMTR2G.js";
|
|
5
5
|
import {
|
|
6
6
|
ScheduleNameCell
|
|
7
7
|
} from "./chunk-AC7K7IJE.js";
|
|
8
8
|
import {
|
|
9
|
+
SR_ONLY_SX,
|
|
9
10
|
blockSx,
|
|
10
11
|
blockedLabelSx,
|
|
11
12
|
breakSx,
|
|
@@ -22,7 +23,7 @@ import {
|
|
|
22
23
|
skeletonCellSx,
|
|
23
24
|
totalCellSx,
|
|
24
25
|
totalHeaderSx
|
|
25
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-WMTW4JXT.js";
|
|
26
27
|
import {
|
|
27
28
|
SCHEDULE_GRID_METRICS
|
|
28
29
|
} from "./chunk-3R6BR22L.js";
|
|
@@ -117,17 +118,26 @@ function CellFill({ props, ghost }) {
|
|
|
117
118
|
if (!cell.blocked || cell.blocks.length > 0 || !cell.blockedLabel) return null;
|
|
118
119
|
return /* @__PURE__ */ jsx(Box, { component: "span", sx: blockedLabelSx, "aria-hidden": true, title: cell.blockedLabel, children: cell.blockedLabel });
|
|
119
120
|
}
|
|
120
|
-
function
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
121
|
+
function ClosedWords({ cell }) {
|
|
122
|
+
if (!cell.closed || cell.blocked || !cell.closedLabel) return null;
|
|
123
|
+
return /* @__PURE__ */ jsx(Box, { component: "span", sx: SR_ONLY_SX, children: cell.closedLabel });
|
|
124
|
+
}
|
|
125
|
+
function lookOf(props, ghost) {
|
|
126
|
+
const { row, day, column, cell, drag, can } = props;
|
|
127
|
+
return {
|
|
125
128
|
today: Boolean(column.today),
|
|
126
|
-
blocked,
|
|
129
|
+
blocked: Boolean(cell.blocked),
|
|
130
|
+
closed: Boolean(cell.closed),
|
|
127
131
|
target: ghost !== null,
|
|
128
132
|
over: drag?.mode === "move" && drag.moved && drag.rowId === row.id && drag.day === day,
|
|
129
133
|
interactive: can.create && isOpen(cell)
|
|
130
134
|
};
|
|
135
|
+
}
|
|
136
|
+
function GridCell(props) {
|
|
137
|
+
const { row, day, column, cell, can, labels, testId } = props;
|
|
138
|
+
const ghost = ghostFor(props);
|
|
139
|
+
const look = lookOf(props, ghost);
|
|
140
|
+
const blocked = look.blocked;
|
|
131
141
|
const closedName = blocked && cell.blocks.length === 0 ? cell.blockedLabel ?? labels.blockedCell(row.label, column.label) : void 0;
|
|
132
142
|
return /* @__PURE__ */ jsxs(
|
|
133
143
|
Box,
|
|
@@ -153,7 +163,8 @@ function GridCell(props) {
|
|
|
153
163
|
},
|
|
154
164
|
block.id
|
|
155
165
|
)),
|
|
156
|
-
/* @__PURE__ */ jsx(CellFill, { props, ghost })
|
|
166
|
+
/* @__PURE__ */ jsx(CellFill, { props, ghost }),
|
|
167
|
+
/* @__PURE__ */ jsx(ClosedWords, { cell })
|
|
157
168
|
]
|
|
158
169
|
}
|
|
159
170
|
);
|
|
@@ -168,10 +179,19 @@ function keepDatesWhole(label) {
|
|
|
168
179
|
function GridHeader({ columns, totalLabel, rowSx, testId }) {
|
|
169
180
|
return /* @__PURE__ */ jsxs(Box, { role: "row", sx: [rowSx, headerRowSx], "data-testid": `${testId}-header`, children: [
|
|
170
181
|
/* @__PURE__ */ jsx("span", { role: "cell", "data-sg-corner": "" }),
|
|
171
|
-
columns.map((column, day) => /* @__PURE__ */ jsxs(
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
182
|
+
columns.map((column, day) => /* @__PURE__ */ jsxs(
|
|
183
|
+
Box,
|
|
184
|
+
{
|
|
185
|
+
role: "columnheader",
|
|
186
|
+
sx: headerCellSx(Boolean(column.today), Boolean(column.past)),
|
|
187
|
+
"data-sg-past": column.past ? "" : void 0,
|
|
188
|
+
children: [
|
|
189
|
+
/* @__PURE__ */ jsx("span", { "data-sg-col": "full", title: column.label, children: keepDatesWhole(column.label) }),
|
|
190
|
+
column.sublabel ? /* @__PURE__ */ jsx(Box, { component: "span", sx: headerSublabelSx, "data-sg-col": "sub", children: column.sublabel }) : null
|
|
191
|
+
]
|
|
192
|
+
},
|
|
193
|
+
`${day}-${column.label}`
|
|
194
|
+
)),
|
|
175
195
|
totalLabel !== void 0 ? /* @__PURE__ */ jsx(Box, { role: "columnheader", sx: totalHeaderSx, children: totalLabel }) : null
|
|
176
196
|
] });
|
|
177
197
|
}
|
|
@@ -226,4 +246,4 @@ export {
|
|
|
226
246
|
GridHeader,
|
|
227
247
|
GridBody
|
|
228
248
|
};
|
|
229
|
-
//# sourceMappingURL=chunk-
|
|
249
|
+
//# sourceMappingURL=chunk-ARPOWDEO.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/data-display/ScheduleGrid/ScheduleGrid.parts.tsx"],"sourcesContent":["import AddIcon from '@mui/icons-material/Add';\nimport Box from '@mui/material/Box/index.js';\nimport type { CSSObject, Theme } from '@mui/material/styles/index.js';\nimport type * as React from 'react';\n\nimport type { ScheduleGridLabels } from '../../../copy/labels';\nimport { daysBetween, isOpen } from './schedule-grid-model';\nimport { SCHEDULE_GRID_METRICS } from './ScheduleGrid.metrics';\nimport {\n blockedLabelSx,\n blockSx,\n breakSx,\n cellSx,\n ghostSx,\n gripSx,\n groupTitleSx,\n headerCellSx,\n headerSublabelSx,\n headerRowSx,\n nameCellSx,\n personRowSx,\n plusButtonSx,\n skeletonCellSx,\n SR_ONLY_SX,\n totalCellSx,\n totalHeaderSx,\n} from './ScheduleGrid.styles';\nimport type { CellLook } from './ScheduleGrid.styles';\nimport type {\n ScheduleGridBlock,\n ScheduleGridCell,\n ScheduleGridColumn,\n ScheduleGridProps,\n ScheduleGridRow,\n} from './ScheduleGrid.types';\nimport { ScheduleNameCell } from './ScheduleNameCell';\nimport type { GridDrag, GridDragApi } from './useGridDrag';\n\n/** What the grid lets a cell do, resolved once per render. */\nexport interface CellAbilities {\n create: boolean;\n copy: boolean;\n move: boolean;\n}\n\n/** A row's shared columns, as an `sx` part. */\ntype RowSx = (theme: Theme) => CSSObject;\n\ninterface CellProps {\n row: ScheduleGridRow;\n day: number;\n column: ScheduleGridColumn;\n cell: ScheduleGridCell;\n drag: GridDrag | null;\n dragApi: GridDragApi;\n can: CellAbilities;\n createPreview?: (rowId: string) => string;\n onCreate?: (rowId: string, days: number[]) => void;\n onBlockClick?: (blockId: string) => void;\n labels: ScheduleGridLabels;\n testId: string;\n}\n\n/** The ghost text this cell shows during a create or copy, or `null` when the gesture does not land here. */\nfunction ghostFor(props: CellProps): string | null {\n const { drag, row, day, cell, createPreview } = props;\n if (!drag || drag.mode === 'move' || drag.rowId !== row.id || !isOpen(cell)) return null;\n if (!daysBetween(drag.anchor, drag.day).includes(day)) return null;\n if (drag.mode === 'copy') return day === drag.anchor ? null : drag.preview;\n return createPreview?.(row.id) ?? '';\n}\n\n/** The keys a block answers to, for `aria-keyshortcuts`. */\nfunction shortcutsOf(movable: boolean, copyable: boolean): string | undefined {\n const keys = [movable ? 'Alt+ArrowLeft Alt+ArrowRight' : '', copyable ? 'Shift+ArrowLeft Shift+ArrowRight' : ''];\n return keys.filter(Boolean).join(' ') || undefined;\n}\n\nconst titleOf = (block: ScheduleGridBlock): string => block.title ?? [block.label, block.note].filter(Boolean).join(' · ');\n\ninterface BlockProps {\n block: ScheduleGridBlock;\n row: ScheduleGridRow;\n day: number;\n can: CellAbilities;\n dragApi: GridDragApi;\n onBlockClick?: (blockId: string) => void;\n testId: string;\n}\n\nfunction Grip({ side, onPointerDown, testId }: { side: 'l' | 'r'; onPointerDown: (event: React.PointerEvent) => void; testId: string }) {\n return <Box component=\"span\" aria-hidden sx={gripSx(side)} onPointerDown={onPointerDown} data-sg-grip=\"\" data-testid={testId} />;\n}\n\n/** The block's break, kept inside it whatever the host sent. */\nfunction BreakBand({ span, testId }: { span: { start: number; end: number }; testId: string }): React.JSX.Element | null {\n const start = Math.min(1, Math.max(0, span.start));\n const end = Math.min(1, Math.max(0, span.end));\n if (!(end > start)) return null;\n return <Box component=\"span\" aria-hidden sx={breakSx({ start, end })} data-sg-break=\"\" data-testid={testId} />;\n}\n\nfunction BlockButton({ block, row, day, can, dragApi, onBlockClick, testId }: BlockProps): React.JSX.Element {\n const movable = can.move && Boolean(block.movable);\n const copyable = can.copy && Boolean(block.copyable);\n const startCopy = (event: React.PointerEvent): void => dragApi.startCopy(event, block.id, row.id, day, block.label);\n const startMove = (event: React.PointerEvent): void => dragApi.startMove(event, block.id, row.id, day);\n return (\n <Box\n component=\"button\"\n type=\"button\"\n sx={blockSx(block.tone, { selected: Boolean(block.selected), movable })}\n title={titleOf(block)}\n aria-keyshortcuts={shortcutsOf(movable, copyable)}\n aria-current={block.selected ? 'true' : undefined}\n data-sg-focus=\"\"\n data-sg-row={row.id}\n data-sg-day={day}\n data-sg-block={block.id}\n data-tone={block.tone}\n data-testid={`${testId}-block-${block.id}`}\n onPointerDown={movable ? startMove : undefined}\n onClick={() => {\n if (!dragApi.takeClick()) onBlockClick?.(block.id);\n }}\n >\n {block.breakSpan ? <BreakBand span={block.breakSpan} testId={`${testId}-break-${block.id}`} /> : null}\n {copyable ? <Grip side=\"l\" onPointerDown={startCopy} testId={`${testId}-grip-l-${block.id}`} /> : null}\n <span data-sg-line=\"label\">{block.label}</span>\n {block.note ? <span data-sg-line=\"note\">{block.note}</span> : null}\n {copyable ? <Grip side=\"r\" onPointerDown={startCopy} testId={`${testId}-grip-r-${block.id}`} /> : null}\n </Box>\n );\n}\n\n/**\n * The empty cell's \"+\". It stays mounted while a drag shows the ghost in it, so\n * a press and release in place is still its click.\n */\nfunction PlusButton({ props, ghost }: { props: CellProps; ghost: string | null }): React.JSX.Element {\n const { row, day, column, dragApi, onCreate, labels } = props;\n return (\n <Box\n component=\"button\"\n type=\"button\"\n sx={plusButtonSx}\n aria-label={labels.createCell(row.label, column.label)}\n data-ghost={ghost === null ? undefined : ''}\n data-sg-focus=\"\"\n data-sg-row={row.id}\n data-sg-day={day}\n onPointerDown={(event: React.PointerEvent) => dragApi.startCreate(event, row.id, day)}\n onClick={() => {\n if (!dragApi.takeClick()) onCreate?.(row.id, [day]);\n }}\n >\n {ghost === null ? <AddIcon aria-hidden /> : <Ghost text={ghost} />}\n </Box>\n );\n}\n\nfunction Ghost({ text }: { text: string }): React.JSX.Element {\n return (\n <Box component=\"span\" sx={ghostSx} aria-hidden>\n {text}\n </Box>\n );\n}\n\n/** What fills a cell after its blocks: the \"+\" (or the ghost in it), a lone ghost, or a closed day's label. */\nfunction CellFill({ props, ghost }: { props: CellProps; ghost: string | null }): React.JSX.Element | null {\n const { cell, can } = props;\n if (can.create && isOpen(cell)) return <PlusButton props={props} ghost={ghost} />;\n if (ghost !== null) return <Ghost text={ghost} />;\n if (!cell.blocked || cell.blocks.length > 0 || !cell.blockedLabel) return null;\n return (\n <Box component=\"span\" sx={blockedLabelSx} aria-hidden title={cell.blockedLabel}>\n {cell.blockedLabel}\n </Box>\n );\n}\n\n/** A gone day's words for a screen reader (\"Já passou\"): visually hidden, and only when the host gives them. */\nfunction ClosedWords({ cell }: { cell: ScheduleGridCell }): React.JSX.Element | null {\n if (!cell.closed || cell.blocked || !cell.closedLabel) return null;\n return (\n <Box component=\"span\" sx={SR_ONLY_SX}>\n {cell.closedLabel}\n </Box>\n );\n}\n\n/** How the cell is drawn right now. */\nfunction lookOf(props: CellProps, ghost: string | null): CellLook {\n const { row, day, column, cell, drag, can } = props;\n return {\n today: Boolean(column.today),\n blocked: Boolean(cell.blocked),\n closed: Boolean(cell.closed),\n target: ghost !== null,\n over: drag?.mode === 'move' && drag.moved && drag.rowId === row.id && drag.day === day,\n interactive: can.create && isOpen(cell),\n };\n}\n\n/** One day of one row: its blocks, a \"+\" when it is empty, the hatch when it is closed. */\nexport function GridCell(props: CellProps): React.JSX.Element {\n const { row, day, column, cell, can, labels, testId } = props;\n const ghost = ghostFor(props);\n const look = lookOf(props, ghost);\n const blocked = look.blocked;\n const closedName = blocked && cell.blocks.length === 0 ? (cell.blockedLabel ?? labels.blockedCell(row.label, column.label)) : undefined;\n return (\n <Box\n role=\"cell\"\n sx={cellSx(look)}\n data-sg-cell=\"\"\n data-sg-row={row.id}\n data-sg-day={day}\n data-testid={`${testId}-cell-${row.id}-${day}`}\n aria-label={closedName}\n >\n {cell.blocks.map((block) => (\n <BlockButton\n key={block.id}\n block={block}\n row={row}\n day={day}\n can={can}\n dragApi={props.dragApi}\n onBlockClick={props.onBlockClick}\n testId={testId}\n />\n ))}\n <CellFill props={props} ghost={ghost} />\n <ClosedWords cell={cell} />\n </Box>\n );\n}\n\n/** The first column: the person, as both views draw it. */\nfunction NameCell({ row }: { row: ScheduleGridRow }): React.JSX.Element {\n const sizes = { name: SCHEDULE_GRID_METRICS.rowName, meta: SCHEDULE_GRID_METRICS.rowMeta, chipsTop: 0.5 };\n return <ScheduleNameCell row={row} role=\"rowheader\" sx={nameCellSx} sizes={sizes} />;\n}\n\ninterface HeaderProps {\n columns: readonly ScheduleGridColumn[];\n /** Present when the grid has a last column. */\n totalLabel?: string;\n rowSx: RowSx;\n testId: string;\n}\n\n/** The days, their counts and the total column's header — pinned while the grid scrolls. */\n\n/** A label wraps between words, never inside \"Seg 19/10\": the space before a number holds. */\nfunction keepDatesWhole(label: string): string {\n return label.replace(/ (?=\\d)/g, '\\u00a0');\n}\n\nexport function GridHeader({ columns, totalLabel, rowSx, testId }: HeaderProps): React.JSX.Element {\n return (\n <Box role=\"row\" sx={[rowSx, headerRowSx]} data-testid={`${testId}-header`}>\n {/* Above the names: a cell of the header row, with nothing to head. */}\n <span role=\"cell\" data-sg-corner=\"\" />\n {columns.map((column, day) => (\n <Box\n role=\"columnheader\"\n key={`${day}-${column.label}`}\n sx={headerCellSx(Boolean(column.today), Boolean(column.past))}\n data-sg-past={column.past ? '' : undefined}\n >\n <span data-sg-col=\"full\" title={column.label}>\n {keepDatesWhole(column.label)}\n </span>\n {column.sublabel ? (\n <Box component=\"span\" sx={headerSublabelSx} data-sg-col=\"sub\">\n {column.sublabel}\n </Box>\n ) : null}\n </Box>\n ))}\n {totalLabel !== undefined ? (\n <Box role=\"columnheader\" sx={totalHeaderSx}>\n {totalLabel}\n </Box>\n ) : null}\n </Box>\n );\n}\n\ninterface BodyProps {\n grid: ScheduleGridProps;\n rows: readonly ScheduleGridRow[];\n rowSx: RowSx;\n hasTotal: boolean;\n can: CellAbilities;\n dragApi: GridDragApi;\n labels: ScheduleGridLabels;\n testId: string;\n}\n\nfunction SkeletonRows({ grid, rowSx, testId }: Pick<BodyProps, 'grid' | 'rowSx' | 'testId'>): React.JSX.Element {\n return (\n <>\n {Array.from({ length: SCHEDULE_GRID_METRICS.skeletonRows }, (_, index) => (\n <Box key={index} sx={[rowSx, personRowSx]} aria-hidden data-testid={`${testId}-loading`}>\n <Box sx={skeletonCellSx} />\n {grid.columns.map((column, day) => (\n <Box key={`${day}-${column.label}`} sx={skeletonCellSx} />\n ))}\n </Box>\n ))}\n </>\n );\n}\n\nfunction PersonRow({ row, body }: { row: ScheduleGridRow; body: BodyProps }): React.JSX.Element {\n const { grid, rowSx, hasTotal, can, dragApi, labels, testId } = body;\n return (\n <Box role=\"row\" sx={[rowSx, personRowSx]} data-testid={`${testId}-row-${row.id}`}>\n <NameCell row={row} />\n {grid.columns.map((column, day) => (\n <GridCell\n key={`${day}-${column.label}`}\n row={row}\n day={day}\n column={column}\n cell={grid.cell(row.id, day)}\n drag={dragApi.drag}\n dragApi={dragApi}\n can={can}\n createPreview={grid.createPreview}\n onCreate={grid.onCreate}\n onBlockClick={grid.onBlockClick}\n labels={labels}\n testId={testId}\n />\n ))}\n {hasTotal ? (\n <Box role=\"cell\" sx={totalCellSx}>\n {row.total}\n </Box>\n ) : null}\n </Box>\n );\n}\n\n/** The host's error or empty node, as the table's one full-width row (a table holds rows only). */\nfunction MessageRow({ children, testId }: { children: React.ReactNode; testId: string }): React.JSX.Element | null {\n if (children === null || children === undefined || children === false) return null;\n return (\n <Box role=\"row\" data-testid={`${testId}-message`}>\n <Box role=\"cell\">{children}</Box>\n </Box>\n );\n}\n\n/** The groups and their rows — or the skeleton, the host's error, or the host's empty state. */\nexport function GridBody(body: BodyProps): React.JSX.Element | null {\n const { grid, rows } = body;\n if (grid.error) return <MessageRow testId={body.testId}>{grid.error}</MessageRow>;\n if (grid.loading) return <SkeletonRows grid={grid} rowSx={body.rowSx} testId={body.testId} />;\n if (rows.length === 0) return <MessageRow testId={body.testId}>{grid.empty}</MessageRow>;\n return (\n <>\n {grid.groups.map((group, index) => (\n <Box role=\"rowgroup\" key={`${index}-${group.title ?? ''}`} aria-label={group.title}>\n {group.title ? (\n <Box component=\"p\" sx={groupTitleSx} aria-hidden data-sg-group-title=\"\">\n {group.title}\n </Box>\n ) : null}\n {group.rows.map((row) => (\n <PersonRow key={row.id} row={row} body={body} />\n ))}\n </Box>\n ))}\n </>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// src/components/data-display/ScheduleGrid/schedule-grid-model.ts
|
|
2
2
|
function isOpen(cell) {
|
|
3
|
-
return !cell.blocked && cell.blocks.length === 0;
|
|
3
|
+
return !cell.blocked && !cell.closed && cell.blocks.length === 0;
|
|
4
4
|
}
|
|
5
5
|
function daysBetween(a, b) {
|
|
6
6
|
const from = Math.min(a, b);
|
|
@@ -29,4 +29,4 @@ export {
|
|
|
29
29
|
canDrop,
|
|
30
30
|
stepDay
|
|
31
31
|
};
|
|
32
|
-
//# sourceMappingURL=chunk-
|
|
32
|
+
//# sourceMappingURL=chunk-E6UMTR2G.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/data-display/ScheduleGrid/schedule-grid-model.ts"],"sourcesContent":["import type { ScheduleGridCell } from './ScheduleGrid.types';\n\n/**\n * THE GRID'S RULES, as pure functions (FUT-3825): which days a gesture lands\n * on. The host decides everything else — hours, limits, refusals.\n */\n\n/** A cell that can take a new turno: nothing in it, not closed to the row (`blocked`) and not gone (`closed`). */\nexport function isOpen(cell: ScheduleGridCell): boolean {\n return !cell.blocked && !cell.closed && cell.blocks.length === 0;\n}\n\n/** Every day from `a` to `b` inclusive, in order, whichever is larger. */\nexport function daysBetween(a: number, b: number): number[] {\n const from = Math.min(a, b);\n const to = Math.max(a, b);\n return Array.from({ length: to - from + 1 }, (_, index) => from + index);\n}\n\n/** A create across `anchor…current` of one row: the crossed days that are open (G-R1). */\nexport function createTargets(cellOf: (day: number) => ScheduleGridCell, anchor: number, current: number): number[] {\n return daysBetween(anchor, current).filter((day) => isOpen(cellOf(day)));\n}\n\n/** A copy of the block on `source` across `source…current`: never its own day, never a taken or closed one (G-R2). */\nexport function copyTargets(cellOf: (day: number) => ScheduleGridCell, source: number, current: number): number[] {\n return daysBetween(source, current).filter((day) => day !== source && isOpen(cellOf(day)));\n}\n\n/** A move may land on an open cell that is not its own (G-R3). */\nexport function canDrop(target: ScheduleGridCell, sameCell: boolean): boolean {\n return !sameCell && isOpen(target);\n}\n\n/** The day one step left (-1) or right (+1) of `day`, or `undefined` past either end. */\nexport function stepDay(day: number, direction: -1 | 1, dayCount: number): number | undefined {\n const next = day + direction;\n return next >= 0 && next < dayCount ? next : undefined;\n}\n"],"mappings":";AAQO,SAAS,OAAO,MAAiC;AACtD,SAAO,CAAC,KAAK,WAAW,CAAC,KAAK,UAAU,KAAK,OAAO,WAAW;AACjE;AAGO,SAAS,YAAY,GAAW,GAAqB;AAC1D,QAAM,OAAO,KAAK,IAAI,GAAG,CAAC;AAC1B,QAAM,KAAK,KAAK,IAAI,GAAG,CAAC;AACxB,SAAO,MAAM,KAAK,EAAE,QAAQ,KAAK,OAAO,EAAE,GAAG,CAAC,GAAG,UAAU,OAAO,KAAK;AACzE;AAGO,SAAS,cAAc,QAA2C,QAAgB,SAA2B;AAClH,SAAO,YAAY,QAAQ,OAAO,EAAE,OAAO,CAAC,QAAQ,OAAO,OAAO,GAAG,CAAC,CAAC;AACzE;AAGO,SAAS,YAAY,QAA2C,QAAgB,SAA2B;AAChH,SAAO,YAAY,QAAQ,OAAO,EAAE,OAAO,CAAC,QAAQ,QAAQ,UAAU,OAAO,OAAO,GAAG,CAAC,CAAC;AAC3F;AAGO,SAAS,QAAQ,QAA0B,UAA4B;AAC5E,SAAO,CAAC,YAAY,OAAO,MAAM;AACnC;AAGO,SAAS,QAAQ,KAAa,WAAmB,UAAsC;AAC5F,QAAM,OAAO,MAAM;AACnB,SAAO,QAAQ,KAAK,OAAO,WAAW,OAAO;AAC/C;","names":[]}
|
|
@@ -22,7 +22,7 @@ import {
|
|
|
22
22
|
} from "./chunk-7ZQ3KQ7J.js";
|
|
23
23
|
import {
|
|
24
24
|
SR_ONLY_SX
|
|
25
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-WMTW4JXT.js";
|
|
26
26
|
import {
|
|
27
27
|
useAnnouncer
|
|
28
28
|
} from "./chunk-35HMJQLO.js";
|
|
@@ -117,4 +117,4 @@ function DayRuler(props) {
|
|
|
117
117
|
export {
|
|
118
118
|
DayRuler
|
|
119
119
|
};
|
|
120
|
-
//# sourceMappingURL=chunk-
|
|
120
|
+
//# sourceMappingURL=chunk-MLIBJWQZ.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
isOpen,
|
|
3
3
|
stepDay
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-E6UMTR2G.js";
|
|
5
5
|
|
|
6
6
|
// src/components/data-display/ScheduleGrid/ScheduleGrid.keyboard.ts
|
|
7
7
|
function focusables(root) {
|
|
@@ -87,4 +87,4 @@ export {
|
|
|
87
87
|
focusables,
|
|
88
88
|
handleGridKey
|
|
89
89
|
};
|
|
90
|
-
//# sourceMappingURL=chunk-
|
|
90
|
+
//# sourceMappingURL=chunk-MPUOLKFT.js.map
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
2
|
focusables,
|
|
3
3
|
handleGridKey
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-MPUOLKFT.js";
|
|
5
5
|
import {
|
|
6
6
|
GridBody,
|
|
7
7
|
GridHeader
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-ARPOWDEO.js";
|
|
9
9
|
import {
|
|
10
10
|
useSidewaysScroll
|
|
11
11
|
} from "./chunk-GONPUJIE.js";
|
|
12
12
|
import {
|
|
13
13
|
useGridDrag
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-WBMLMLXP.js";
|
|
15
15
|
import {
|
|
16
16
|
SR_ONLY_SX,
|
|
17
17
|
frameSx,
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
rootSx,
|
|
20
20
|
rowGridSx,
|
|
21
21
|
scrollSx
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-WMTW4JXT.js";
|
|
23
23
|
import {
|
|
24
24
|
useAnnouncer
|
|
25
25
|
} from "./chunk-35HMJQLO.js";
|
|
@@ -137,4 +137,4 @@ function ScheduleGrid(props) {
|
|
|
137
137
|
export {
|
|
138
138
|
ScheduleGrid
|
|
139
139
|
};
|
|
140
|
-
//# sourceMappingURL=chunk-
|
|
140
|
+
//# sourceMappingURL=chunk-UIJU5X26.js.map
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
canDrop,
|
|
3
3
|
copyTargets,
|
|
4
4
|
createTargets
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-E6UMTR2G.js";
|
|
6
6
|
import {
|
|
7
7
|
useDragWindow,
|
|
8
8
|
useTrailingClick
|
|
@@ -91,4 +91,4 @@ function useGridDrag(rootRef, handlers) {
|
|
|
91
91
|
export {
|
|
92
92
|
useGridDrag
|
|
93
93
|
};
|
|
94
|
-
//# sourceMappingURL=chunk-
|
|
94
|
+
//# sourceMappingURL=chunk-WBMLMLXP.js.map
|
|
@@ -105,11 +105,14 @@ var headerRowSx = (theme) => ({
|
|
|
105
105
|
paddingTop: theme.spacing(0.75),
|
|
106
106
|
paddingBottom: theme.spacing(0.75)
|
|
107
107
|
});
|
|
108
|
-
function headerCellSx(today) {
|
|
108
|
+
function headerCellSx(today, past = false) {
|
|
109
|
+
let color = "text.primary";
|
|
110
|
+
if (past) color = "text.secondary";
|
|
111
|
+
if (today) color = "primary.main";
|
|
109
112
|
return {
|
|
110
113
|
fontSize: sxRem(SCHEDULE_GRID_METRICS.headerLabel),
|
|
111
114
|
fontWeight: 500,
|
|
112
|
-
color
|
|
115
|
+
color,
|
|
113
116
|
p: 0.5,
|
|
114
117
|
minWidth: 0,
|
|
115
118
|
// A long label ("Hoje · Seg 19/10") wraps to a second line, as the prototype's: never cut.
|
|
@@ -180,6 +183,7 @@ function cellSx(look) {
|
|
|
180
183
|
if (look.blocked) {
|
|
181
184
|
return { ...base, background: hatch(theme), borderColor: theme.palette.divider, cursor: "not-allowed" };
|
|
182
185
|
}
|
|
186
|
+
if (look.closed) return { ...base, backgroundColor: "transparent", borderColor: theme.palette.divider };
|
|
183
187
|
if (look.target) {
|
|
184
188
|
return {
|
|
185
189
|
...base,
|
|
@@ -338,4 +342,4 @@ export {
|
|
|
338
342
|
skeletonCellSx,
|
|
339
343
|
SR_ONLY_SX
|
|
340
344
|
};
|
|
341
|
-
//# sourceMappingURL=chunk-
|
|
345
|
+
//# sourceMappingURL=chunk-WMTW4JXT.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/data-display/ScheduleGrid/ScheduleGrid.styles.ts"],"sourcesContent":["import type { SxProps, Theme } from '@mui/material/styles/index.js';\nimport type { CSSObject } from '@mui/material/styles/index.js';\n\nimport { rem, sxRem } from '../../../tokens/relative';\nimport { SCHEDULE_GRID_METRICS as M } from './ScheduleGrid.metrics';\nimport { blockToneStyles, breakHatch } from './schedule-tones';\nimport type { ScheduleBlockTone } from './ScheduleGrid.types';\n\n/**\n * The grid's root: the container the column widths answer to (container\n * queries, never media queries — the grid may sit in a narrow pane).\n */\nexport const rootSx: SxProps<Theme> = { containerType: 'inline-size', minWidth: 0, width: '100%' };\n\n/** The columns a row has: the name, the days, the total (when there is one). */\nfunction trackCount(dayCount: number, hasTotal: boolean): number {\n return 1 + dayCount + (hasTotal ? 1 : 0);\n}\n\n/**\n * The narrowest container a layout fits in, in px: its name column, its days\n * at their minimum, its total, and the gaps between them — for THIS grid's\n * day count, so a fortnight scrolls where a week still fits.\n */\nfunction fitsFrom(dayCount: number, hasTotal: boolean, name: number, day: number, total: number): number {\n return name + dayCount * day + (hasTotal ? total : 0) + (trackCount(dayCount, hasTotal) - 1) * M.gap;\n}\n\n/** `@container (width < px)`: every bound is \"from px up\" (ranges are exclusive below, inclusive above). */\nfunction below(theme: Theme, px: number): string {\n return `@container (width < ${rem(theme, px)})`;\n}\n\n/**\n * The column widths, as variables every row reads, by the container's width:\n * - from `wide` up: 200px names, days of at least 104px with their grips;\n * - from `compact` up: 140px names, 40px total, days of at least 98px — still\n * unscrolled, grips kept, the header row sticking to the page;\n * - below `compact`: days of at least 152px, grips kept; the body scrolls\n * sideways under the pinned names and the header row follows it sideways\n * while it still sticks to the page (`useSidewaysScroll` sets its scroll);\n * - below 600px: 120px names, 136px days, no grips.\n * The `wide` and `compact` bounds come from this grid's own day count\n * (`fitsFrom`). Container queries, never media queries.\n */\nexport function frameSx(dayCount: number, hasTotal: boolean): SxProps<Theme> {\n return (theme: Theme) => {\n const terms = ['var(--sg-name)', `${dayCount} * var(--sg-day)`, `${trackCount(dayCount, hasTotal) - 1} * ${rem(theme, M.gap)}`];\n if (hasTotal) terms.push('var(--sg-total)');\n const wide = fitsFrom(dayCount, hasTotal, M.nameColumn.wide, M.dayMin.wide, M.totalColumn.wide);\n const compact = fitsFrom(dayCount, hasTotal, M.nameColumn.compact, M.dayMin.compact, M.totalColumn.compact);\n return {\n '--sg-name': rem(theme, M.nameColumn.wide),\n '--sg-total': rem(theme, M.totalColumn.wide),\n '--sg-day': rem(theme, M.dayMin.wide),\n // What every row is at least: its own columns at their minimums.\n '--sg-min': `calc(${terms.join(' + ')})`,\n [below(theme, wide)]: {\n '--sg-name': rem(theme, M.nameColumn.compact),\n '--sg-total': rem(theme, M.totalColumn.compact),\n '--sg-day': rem(theme, M.dayMin.compact),\n '& [data-sg-block]': { paddingLeft: rem(theme, M.blockPadding.tight), paddingRight: rem(theme, M.blockPadding.tight) },\n },\n [below(theme, compact)]: {\n '--sg-day': rem(theme, M.dayMin.scrolled),\n '& [data-sg-block]': {\n paddingLeft: rem(theme, M.blockPadding.start),\n paddingRight: rem(theme, M.blockPadding.end),\n },\n // A cell the keyboard reaches is brought out beside the pinned names, never under them.\n '& > [data-sg-scroll]': {\n overflowX: 'auto',\n overscrollBehaviorX: 'contain',\n scrollPaddingInlineStart: `calc(var(--sg-name) + ${rem(theme, M.gap)})`,\n },\n // The header row follows the days sideways (the grid sets its scroll). It is no scroller of\n // its own: a scroller with nothing focusable inside is a tab stop of its own.\n // `contain` still holds on a hidden overflow: a sideways swipe over the header is never the\n // browser's back / forward gesture.\n '& > [data-sg-head]': { overflowX: 'hidden', overscrollBehaviorX: 'contain' },\n // The pinned column: the names (and the cell above them, and the group\n // titles) stay while the days scroll under them.\n '& [role=\"rowheader\"], & [data-sg-corner]': {\n position: 'sticky',\n left: 0,\n zIndex: 2,\n backgroundColor: theme.palette.background.default,\n // Covers the gap after it too, so nothing scrolling shows between the name and the days.\n boxShadow: `${rem(theme, M.gap)} 0 0 ${theme.palette.background.default}`,\n },\n '& [data-sg-group-title]': { position: 'sticky', left: 0, width: 'fit-content' },\n },\n [below(theme, M.narrowBelow)]: {\n '--sg-name': rem(theme, M.nameColumn.narrow),\n '--sg-day': rem(theme, M.dayMin.narrow),\n // A phone-sized pane is read and tapped, not dragged (a phone renders\n // DayRuler per day): the grips would eat the block (Shift+arrows still copy).\n '& [data-sg-grip]': { display: 'none' },\n '& [data-sg-block]': { paddingLeft: rem(theme, M.cellPadding), paddingRight: rem(theme, M.cellPadding) },\n },\n display: 'flex',\n flexDirection: 'column',\n minWidth: 0,\n userSelect: 'none',\n };\n };\n}\n\n/** The body: scrolls sideways (under the compact bound) when the days' minimums do not fit. */\nexport const scrollSx: SxProps<Theme> = { minWidth: 0 };\n\n/** One line of the grid — the header or a person — as the shared columns. */\n/** A style that may sit in an `sx` array next to another. */\ntype SxPart = (theme: Theme) => CSSObject;\n\nexport function rowGridSx(dayCount: number, hasTotal: boolean): SxPart {\n return (theme: Theme) => ({\n display: 'grid',\n gridTemplateColumns: `var(--sg-name) repeat(${dayCount}, minmax(var(--sg-day), 1fr))${hasTotal ? ' var(--sg-total)' : ''}`,\n gap: rem(theme, M.gap),\n alignItems: 'stretch',\n minWidth: 'var(--sg-min)',\n });\n}\n\n/**\n * Around the header row: opaque, pinned to the top of the PAGE (or whatever\n * scrolls the grid vertically) — it is not inside the sideways scroller, so\n * it sticks at every width; while the days scroll it follows them sideways.\n */\nexport function headerSx(stickyTop: number): SxPart {\n return (theme: Theme) => ({\n position: 'sticky',\n top: rem(theme, stickyTop),\n zIndex: 3,\n backgroundColor: theme.palette.background.default,\n });\n}\n\n/** The header row itself, inside its sticky frame. */\nexport const headerRowSx: SxPart = (theme: Theme) => ({\n paddingTop: theme.spacing(0.75),\n paddingBottom: theme.spacing(0.75),\n});\n\n/** A day's header: today's label in the primary colour, a gone day's in the secondary ink (today wins). */\nexport function headerCellSx(today: boolean, past = false): SxProps<Theme> {\n let color = 'text.primary';\n if (past) color = 'text.secondary';\n if (today) color = 'primary.main';\n return {\n fontSize: sxRem(M.headerLabel),\n fontWeight: 500,\n color,\n p: 0.5,\n minWidth: 0,\n // A long label (\"Hoje · Seg 19/10\") wraps to a second line, as the prototype's: never cut.\n '& > *': { display: 'block', overflowWrap: 'anywhere' },\n };\n}\n\nexport const headerSublabelSx: SxProps<Theme> = {\n fontSize: sxRem(M.headerSublabel),\n fontWeight: 400,\n color: 'text.secondary',\n};\n\nexport const totalHeaderSx: SxProps<Theme> = {\n fontSize: sxRem(M.total),\n color: 'text.secondary',\n textAlign: 'right',\n alignSelf: 'end',\n p: 0.5,\n pr: 0,\n};\n\nexport const groupTitleSx: SxProps<Theme> = {\n fontSize: sxRem(M.groupTitle),\n letterSpacing: '0.05em',\n textTransform: 'uppercase',\n color: 'text.secondary',\n fontWeight: 500,\n pt: 1.5,\n pb: 0.5,\n m: 0,\n};\n\n/** A person's line: one grid row, then the gap below it. */\nexport const personRowSx: SxPart = (theme: Theme) => ({ marginBottom: rem(theme, M.gap) });\n\nexport const nameCellSx: SxProps<Theme> = {\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'center',\n pr: 0.5,\n minWidth: 0,\n};\n\nexport const totalCellSx: SxProps<Theme> = {\n fontSize: sxRem(M.total),\n color: 'text.secondary',\n textAlign: 'right',\n alignSelf: 'center',\n whiteSpace: 'nowrap',\n};\n\n/** What a cell is drawing right now. */\nexport interface CellLook {\n today: boolean;\n blocked: boolean;\n /** The day has gone (`closed`): no fill, the divider border; never a drop target. */\n closed: boolean;\n /** A create or copy will land here: dashed, with the hours as ghost text. */\n target: boolean;\n /** The pointer is over it while a block moves. */\n over: boolean;\n /** The cell's own \"+\" button may be pressed. */\n interactive: boolean;\n}\n\nfunction hatch(theme: Theme): string {\n const a = theme.palette.action.hover;\n const b = theme.palette.action.selected;\n const w = rem(theme, M.hatch);\n const w2 = rem(theme, M.hatch * 2);\n return `repeating-linear-gradient(135deg, ${a} 0, ${a} ${w}, ${b} ${w}, ${b} ${w2})`;\n}\n\nexport function cellSx(look: CellLook): SxProps<Theme> {\n return (theme: Theme): CSSObject => {\n const base: CSSObject = {\n position: 'relative',\n minHeight: rem(theme, M.cellMinHeight),\n borderRadius: rem(theme, M.cellRadius),\n backgroundColor: theme.palette.action.hover,\n border: `1px solid ${look.today ? theme.palette.primary.main : theme.palette.divider}`,\n padding: rem(theme, M.cellPadding),\n display: 'flex',\n flexDirection: 'column',\n gap: rem(theme, M.blockGap),\n boxSizing: 'border-box',\n minWidth: 0,\n cursor: look.interactive ? 'cell' : 'default',\n };\n if (look.blocked) {\n return { ...base, background: hatch(theme), borderColor: theme.palette.divider, cursor: 'not-allowed' };\n }\n if (look.closed) return { ...base, backgroundColor: 'transparent', borderColor: theme.palette.divider };\n if (look.target) {\n return {\n ...base,\n border: `${rem(theme, M.targetBorder)} dashed ${theme.palette.primary.main}`,\n backgroundColor: theme.palette.action.selected,\n };\n }\n if (look.over) return { ...base, borderColor: theme.palette.primary.main, backgroundColor: theme.palette.action.selected };\n return base;\n };\n}\n\n/** The empty cell's button: the whole cell, a quiet \"+\" in its middle. */\nexport const plusButtonSx: SxProps<Theme> = (theme: Theme) => ({\n flex: '1 1 auto',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n font: 'inherit',\n background: 'transparent',\n border: 0,\n p: 0,\n m: 0,\n color: theme.palette.text.disabled,\n cursor: 'inherit',\n borderRadius: rem(theme, M.cellRadius - M.cellPadding),\n '& svg': { fontSize: rem(theme, M.plusIcon) },\n // The \"+\" is swapped for the ghost on pointer down: were it the press's\n // target, the browser would drop the click once it left the DOM.\n '& > *': { pointerEvents: 'none' },\n '&:hover': { color: theme.palette.text.secondary },\n '&:focus-visible': { outline: `${rem(theme, M.ring)} solid ${theme.palette.primary.main}`, outlineOffset: 0 },\n // A drag's ghost text sits where the prototype writes it: top left.\n '&[data-ghost]': { justifyContent: 'flex-start', alignItems: 'flex-start' },\n});\n\n/** The ghost text of a cell a create or copy will land on. */\nexport const ghostSx: SxProps<Theme> = (theme: Theme) => ({\n fontSize: rem(theme, M.blockFont),\n fontWeight: 500,\n color: theme.palette.primary.main,\n px: 0.75,\n py: 0.5,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n});\n\n/** A closed day's word (\"Afastamento\"): one line inside its cell, cut with an ellipsis (the full word in `title`). */\nexport const blockedLabelSx: SxProps<Theme> = (theme: Theme) => ({\n display: 'block',\n fontSize: rem(theme, M.blockFont),\n color: theme.palette.text.secondary,\n px: 0.75,\n py: 0.5,\n lineHeight: 1.3,\n minWidth: 0,\n maxWidth: '100%',\n boxSizing: 'border-box',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n});\n\nexport function blockSx(tone: ScheduleBlockTone, opts: { selected: boolean; movable: boolean }): SxProps<Theme> {\n return (theme: Theme): CSSObject => ({\n ...blockToneStyles(theme, tone),\n position: 'relative',\n display: 'block',\n width: '100%',\n minWidth: 0,\n maxWidth: '100%',\n boxSizing: 'border-box',\n textAlign: 'left',\n font: 'inherit',\n fontSize: rem(theme, M.blockFont),\n fontWeight: 500,\n lineHeight: 1.35,\n borderRadius: rem(theme, M.blockRadius),\n padding: `${rem(theme, M.blockPadding.y)} ${rem(theme, M.blockPadding.end)} ${rem(theme, M.blockPadding.y)} ${rem(theme, M.blockPadding.start)}`,\n cursor: opts.movable ? 'grab' : 'pointer',\n margin: 0,\n boxShadow: opts.selected ? `0 0 0 ${rem(theme, M.ring)} ${theme.palette.primary.main}` : 'none',\n '&:focus-visible': { outline: `${rem(theme, M.ring)} solid ${theme.palette.primary.main}`, outlineOffset: rem(theme, M.ringOffset) },\n // The hours stay on one line; the note wraps (the block grows), as the prototype's\n // \"↻ a cada 2 / semanas\": a note is never cut, so a break keeps its end.\n '& > [data-sg-line]': { position: 'relative', display: 'block' },\n '& > [data-sg-line=\"label\"]': { overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' },\n '& > [data-sg-line=\"note\"]': { fontWeight: 400, overflowWrap: 'anywhere' },\n });\n}\n\n/** A break inside a block: a hatched band across its height, under its text. */\nexport function breakSx(span: { start: number; end: number }): SxProps<Theme> {\n return (theme: Theme) => ({\n position: 'absolute',\n top: 0,\n bottom: 0,\n left: `${span.start * 100}%`,\n width: `${(span.end - span.start) * 100}%`,\n background: breakHatch(theme, rem(theme, M.breakStripe.ink), rem(theme, M.breakStripe.ink + M.breakStripe.gap)),\n pointerEvents: 'none',\n });\n}\n\nexport function gripSx(side: 'l' | 'r'): SxProps<Theme> {\n return (theme: Theme) => ({\n position: 'absolute',\n top: 0,\n bottom: 0,\n [side === 'l' ? 'left' : 'right']: 0,\n width: rem(theme, M.grip.width),\n cursor: 'ew-resize',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n '&::before': {\n content: '\"\"',\n display: 'block',\n width: rem(theme, M.grip.barWidth),\n height: rem(theme, M.grip.barHeight),\n borderRadius: rem(theme, M.grip.barRadius),\n backgroundColor: 'currentColor',\n opacity: 0.5,\n },\n });\n}\n\nexport const skeletonCellSx: SxProps<Theme> = (theme: Theme) => ({\n minHeight: rem(theme, M.cellMinHeight),\n borderRadius: rem(theme, M.cellRadius),\n backgroundColor: theme.palette.action.hover,\n});\n\nexport const SR_ONLY_SX: SxProps<Theme> = {\n position: 'absolute',\n width: sxRem(1),\n height: sxRem(1),\n padding: 0,\n margin: sxRem(-1),\n overflow: 'hidden',\n clip: 'rect(0, 0, 0, 0)',\n whiteSpace: 'nowrap',\n border: 0,\n};\n"],"mappings":"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","names":[]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import "../chunk-TTRWOI6Z.js";
|
|
2
2
|
import {
|
|
3
3
|
DayRuler
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-MLIBJWQZ.js";
|
|
5
5
|
import "../chunk-MAYAJXO6.js";
|
|
6
6
|
import "../chunk-IP424VZD.js";
|
|
7
7
|
import "../chunk-EEK2NK4W.js";
|
|
@@ -11,7 +11,7 @@ import "../chunk-7ZQ3KQ7J.js";
|
|
|
11
11
|
import "../chunk-YMYJO2CZ.js";
|
|
12
12
|
import "../chunk-AC7K7IJE.js";
|
|
13
13
|
import "../chunk-6HZYRKOB.js";
|
|
14
|
-
import "../chunk-
|
|
14
|
+
import "../chunk-WMTW4JXT.js";
|
|
15
15
|
import "../chunk-3R6BR22L.js";
|
|
16
16
|
import "../chunk-YE44HUFF.js";
|
|
17
17
|
import "../chunk-35HMJQLO.js";
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import "../chunk-7RXL4ONS.js";
|
|
2
2
|
import {
|
|
3
3
|
ScheduleGrid
|
|
4
|
-
} from "../chunk-
|
|
5
|
-
import "../chunk-
|
|
6
|
-
import "../chunk-
|
|
4
|
+
} from "../chunk-UIJU5X26.js";
|
|
5
|
+
import "../chunk-MPUOLKFT.js";
|
|
6
|
+
import "../chunk-ARPOWDEO.js";
|
|
7
7
|
import "../chunk-GONPUJIE.js";
|
|
8
|
-
import "../chunk-
|
|
9
|
-
import "../chunk-
|
|
8
|
+
import "../chunk-WBMLMLXP.js";
|
|
9
|
+
import "../chunk-E6UMTR2G.js";
|
|
10
10
|
import "../chunk-AC7K7IJE.js";
|
|
11
11
|
import "../chunk-6HZYRKOB.js";
|
|
12
|
-
import "../chunk-
|
|
12
|
+
import "../chunk-WMTW4JXT.js";
|
|
13
13
|
import "../chunk-3R6BR22L.js";
|
|
14
14
|
import "../chunk-YE44HUFF.js";
|
|
15
15
|
import "../chunk-35HMJQLO.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ScheduleGrid.parts.d.ts","sourceRoot":"","sources":["../../../../../src/components/data-display/ScheduleGrid/ScheduleGrid.parts.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AAEpC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"ScheduleGrid.parts.d.ts","sourceRoot":"","sources":["../../../../../src/components/data-display/ScheduleGrid/ScheduleGrid.parts.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AAEpC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAuB/D,OAAO,KAAK,EAEV,gBAAgB,EAChB,kBAAkB,EAClB,iBAAiB,EACjB,eAAe,EAChB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE3D,8DAA8D;AAC9D,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,OAAO,CAAC;CACf;AAED,+CAA+C;AAC/C,KAAK,KAAK,GAAG,CAAC,KAAK,EAAE,KAAK,KAAK,SAAS,CAAC;AAEzC,UAAU,SAAS;IACjB,GAAG,EAAE,eAAe,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,kBAAkB,CAAC;IAC3B,IAAI,EAAE,gBAAgB,CAAC;IACvB,IAAI,EAAE,QAAQ,GAAG,IAAI,CAAC;IACtB,OAAO,EAAE,WAAW,CAAC;IACrB,GAAG,EAAE,aAAa,CAAC;IACnB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IAC1C,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACnD,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,MAAM,EAAE,kBAAkB,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;CAChB;AAgJD,2FAA2F;AAC3F,wBAAgB,QAAQ,CAAC,KAAK,EAAE,SAAS,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAgC5D;AAQD,UAAU,WAAW;IACnB,OAAO,EAAE,SAAS,kBAAkB,EAAE,CAAC;IACvC,+CAA+C;IAC/C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,KAAK,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AASD,wBAAgB,UAAU,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,WAAW,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CA6BjG;AAED,UAAU,SAAS;IACjB,IAAI,EAAE,iBAAiB,CAAC;IACxB,IAAI,EAAE,SAAS,eAAe,EAAE,CAAC;IACjC,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;IAClB,GAAG,EAAE,aAAa,CAAC;IACnB,OAAO,EAAE,WAAW,CAAC;IACrB,MAAM,EAAE,kBAAkB,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;CAChB;AA0DD,gGAAgG;AAChG,wBAAgB,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,GAAG,IAAI,CAqBlE"}
|
|
@@ -33,7 +33,8 @@ export declare function rowGridSx(dayCount: number, hasTotal: boolean): SxPart;
|
|
|
33
33
|
export declare function headerSx(stickyTop: number): SxPart;
|
|
34
34
|
/** The header row itself, inside its sticky frame. */
|
|
35
35
|
export declare const headerRowSx: SxPart;
|
|
36
|
-
|
|
36
|
+
/** A day's header: today's label in the primary colour, a gone day's in the secondary ink (today wins). */
|
|
37
|
+
export declare function headerCellSx(today: boolean, past?: boolean): SxProps<Theme>;
|
|
37
38
|
export declare const headerSublabelSx: SxProps<Theme>;
|
|
38
39
|
export declare const totalHeaderSx: SxProps<Theme>;
|
|
39
40
|
export declare const groupTitleSx: SxProps<Theme>;
|
|
@@ -45,6 +46,8 @@ export declare const totalCellSx: SxProps<Theme>;
|
|
|
45
46
|
export interface CellLook {
|
|
46
47
|
today: boolean;
|
|
47
48
|
blocked: boolean;
|
|
49
|
+
/** The day has gone (`closed`): no fill, the divider border; never a drop target. */
|
|
50
|
+
closed: boolean;
|
|
48
51
|
/** A create or copy will land here: dashed, with the hours as ghost text. */
|
|
49
52
|
target: boolean;
|
|
50
53
|
/** The pointer is over it while a block moves. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ScheduleGrid.styles.d.ts","sourceRoot":"","sources":["../../../../../src/components/data-display/ScheduleGrid/ScheduleGrid.styles.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAK/D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAE9D;;;GAGG;AACH,eAAO,MAAM,MAAM,EAAE,OAAO,CAAC,KAAK,CAAgE,CAAC;AAqBnG;;;;;;;;;;;GAWG;AACH,wBAAgB,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CA6D3E;AAED,+FAA+F;AAC/F,eAAO,MAAM,QAAQ,EAAE,OAAO,CAAC,KAAK,CAAmB,CAAC;AAExD,6EAA6E;AAC7E,6DAA6D;AAC7D,KAAK,MAAM,GAAG,CAAC,KAAK,EAAE,KAAK,KAAK,SAAS,CAAC;AAE1C,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,MAAM,CAQrE;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAOlD;AAED,sDAAsD;AACtD,eAAO,MAAM,WAAW,EAAE,MAGxB,CAAC;AAEH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,
|
|
1
|
+
{"version":3,"file":"ScheduleGrid.styles.d.ts","sourceRoot":"","sources":["../../../../../src/components/data-display/ScheduleGrid/ScheduleGrid.styles.ts"],"names":[],"mappings":"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"}
|
|
@@ -18,6 +18,12 @@ export interface ScheduleGridColumn {
|
|
|
18
18
|
sublabel?: string;
|
|
19
19
|
/** Today's column: its label in the primary colour and its cells framed. */
|
|
20
20
|
today?: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* The day has gone: its label in the secondary ink (`today` wins). The
|
|
23
|
+
* header only — the cells that can take no new turno say so themselves
|
|
24
|
+
* (`ScheduleGridCell.closed`).
|
|
25
|
+
*/
|
|
26
|
+
past?: boolean;
|
|
21
27
|
}
|
|
22
28
|
/** A row: one person (or resource) across the days. */
|
|
23
29
|
export interface ScheduleGridRow {
|
|
@@ -87,6 +93,20 @@ export interface ScheduleGridCell {
|
|
|
87
93
|
blocked?: boolean;
|
|
88
94
|
/** Written in a blocked cell with no blocks ("Afastamento"). */
|
|
89
95
|
blockedLabel?: string;
|
|
96
|
+
/**
|
|
97
|
+
* The day can take no new turno (it has gone). No "+", the empty cell is no
|
|
98
|
+
* focus stop, a create or copy drag skips it and a move or keyboard
|
|
99
|
+
* copy/move onto it is refused — as on a `blocked` day — but with no hatch
|
|
100
|
+
* and no label: the cell just looks empty. Blocks already there still show
|
|
101
|
+
* and still open. Drawn with no fill, only the divider border.
|
|
102
|
+
*/
|
|
103
|
+
closed?: boolean;
|
|
104
|
+
/**
|
|
105
|
+
* A closed cell's words for a screen reader ("Já passou"), visually hidden;
|
|
106
|
+
* nothing on screen. Without it the cell stays unnamed. Ignored on a
|
|
107
|
+
* `blocked` cell, which has its own name.
|
|
108
|
+
*/
|
|
109
|
+
closedLabel?: string;
|
|
90
110
|
}
|
|
91
111
|
export interface ScheduleGridProps {
|
|
92
112
|
/** The day columns, in order (seven for a week). A day is its index here. */
|
|
@@ -103,12 +123,12 @@ export interface ScheduleGridProps {
|
|
|
103
123
|
readOnly?: boolean;
|
|
104
124
|
/**
|
|
105
125
|
* A click on an empty cell (one day), or a drag across empty cells of one
|
|
106
|
-
* row (every crossed day that is empty and not
|
|
126
|
+
* row (every crossed day that is empty, not blocked and not closed).
|
|
107
127
|
*/
|
|
108
128
|
onCreate?: (rowId: string, days: number[]) => void;
|
|
109
|
-
/** A block's edge grip dragged along its row: the crossed days that are empty and not
|
|
129
|
+
/** A block's edge grip dragged along its row: the crossed days that are empty, not blocked and not closed. */
|
|
110
130
|
onCopy?: (blockId: string, days: number[]) => void;
|
|
111
|
-
/** A block's middle dropped on an empty, open cell of any row. */
|
|
131
|
+
/** A block's middle dropped on an empty, open cell of any row (never a blocked or closed one). */
|
|
112
132
|
onMove?: (blockId: string, toRowId: string, toDay: number) => void;
|
|
113
133
|
/** A block clicked, tapped or Entered. */
|
|
114
134
|
onBlockClick?: (blockId: string) => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ScheduleGrid.types.d.ts","sourceRoot":"","sources":["../../../../../src/components/data-display/ScheduleGrid/ScheduleGrid.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AAEpC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE/D;;;;;;;;GAQG;AACH,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,WAAW,GAAG,QAAQ,CAAC;AAElF,kCAAkC;AAClC,MAAM,WAAW,kBAAkB;IACjC,iDAAiD;IACjD,KAAK,EAAE,MAAM,CAAC;IACd,+CAA+C;IAC/C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4EAA4E;IAC5E,KAAK,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"ScheduleGrid.types.d.ts","sourceRoot":"","sources":["../../../../../src/components/data-display/ScheduleGrid/ScheduleGrid.types.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,7 +3,7 @@ import type { ScheduleGridCell } from './ScheduleGrid.types';
|
|
|
3
3
|
* THE GRID'S RULES, as pure functions (FUT-3825): which days a gesture lands
|
|
4
4
|
* on. The host decides everything else — hours, limits, refusals.
|
|
5
5
|
*/
|
|
6
|
-
/** A cell that can take a new turno: nothing in it
|
|
6
|
+
/** A cell that can take a new turno: nothing in it, not closed to the row (`blocked`) and not gone (`closed`). */
|
|
7
7
|
export declare function isOpen(cell: ScheduleGridCell): boolean;
|
|
8
8
|
/** Every day from `a` to `b` inclusive, in order, whichever is larger. */
|
|
9
9
|
export declare function daysBetween(a: number, b: number): number[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schedule-grid-model.d.ts","sourceRoot":"","sources":["../../../../../src/components/data-display/ScheduleGrid/schedule-grid-model.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAE7D;;;GAGG;AAEH,
|
|
1
|
+
{"version":3,"file":"schedule-grid-model.d.ts","sourceRoot":"","sources":["../../../../../src/components/data-display/ScheduleGrid/schedule-grid-model.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAE7D;;;GAGG;AAEH,kHAAkH;AAClH,wBAAgB,MAAM,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAEtD;AAED,0EAA0E;AAC1E,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAI1D;AAED,0FAA0F;AAC1F,wBAAgB,aAAa,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,gBAAgB,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAElH;AAED,sHAAsH;AACtH,wBAAgB,WAAW,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,gBAAgB,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAEhH;AAED,kEAAkE;AAClE,wBAAgB,OAAO,CAAC,MAAM,EAAE,gBAAgB,EAAE,QAAQ,EAAE,OAAO,GAAG,OAAO,CAE5E;AAED,yFAAyF;AACzF,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAG5F"}
|
package/package.json
CHANGED
|
@@ -23,8 +23,8 @@ lists events on one axis). For one day by the hour, or for a phone, use `DayRule
|
|
|
23
23
|
| gesture | pointer (mouse, pen) | keyboard | reports |
|
|
24
24
|
|---|---|---|---|
|
|
25
25
|
| create one day | click an empty cell | Enter on its "+" | `onCreate(rowId, [day])` |
|
|
26
|
-
| create several | drag across cells of ONE row | — | `onCreate(rowId, days)` — the crossed days that are empty and not
|
|
27
|
-
| copy | drag a block's left or right edge grip along its row | Shift+← / Shift+→ | `onCopy(blockId, days)` — never its own day, a taken or a
|
|
26
|
+
| create several | drag across cells of ONE row | — | `onCreate(rowId, days)` — the crossed days that are empty, not blocked and not closed |
|
|
27
|
+
| copy | drag a block's left or right edge grip along its row | Shift+← / Shift+→ | `onCopy(blockId, days)` — never its own day, a taken, a blocked or a closed one |
|
|
28
28
|
| move | drag a block's middle to another cell (any row) | Alt+← / Alt+→ | `onMove(blockId, toRowId, toDay)` — only onto an empty, open cell |
|
|
29
29
|
| open | click a block | Enter | `onBlockClick(blockId)` |
|
|
30
30
|
| focus | — | ← → ↑ ↓ to the nearest cell with something to focus | — |
|
|
@@ -48,9 +48,9 @@ lists events on one axis). For one day by the hour, or for a phone, use `DayRule
|
|
|
48
48
|
|
|
49
49
|
| Prop | Type | Description |
|
|
50
50
|
|---|---|---|
|
|
51
|
-
| `columns` | `ScheduleGridColumn[]` | `label` (wraps to a second line when its column is short, never cut, and never between a word and the number after it: "Seg 19/10" stays whole; also in `title`), `sublabel?`, `today?` (label in the primary colour, cells framed). A day is its index here. |
|
|
51
|
+
| `columns` | `ScheduleGridColumn[]` | `label` (wraps to a second line when its column is short, never cut, and never between a word and the number after it: "Seg 19/10" stays whole; also in `title`), `sublabel?`, `today?` (label in the primary colour, cells framed), `past?` (the day has gone: label in `text.secondary`, see [Closed days](#closed-days)). A day is its index here. |
|
|
52
52
|
| `groups` | `ScheduleGridGroup[]` | `title?` (upper-case heading, names the row group), `rows`: `id`, `label`, `meta?`, `metaTone?` (`'warning'` for "acima de 40h"), `total?`, `onLabelClick?` (makes the name a button), `labelAccessible?`, `nameAdornment?` (node beside the name — a "Freela" tag; it moves under the name when the column has no room for both), `chips?` (node under the meta — "2 regras ›"; one line, a chip that does not fit shrinks and cuts its label). |
|
|
53
|
-
| `cell` | `(rowId, day) => ScheduleGridCell` | `blocks` (`id`, `label`, `note?`, `tone`, `movable?`, `copyable?`, `selected?`, `title?`, `breakSpan?` — `{ start, end }` as fractions 0…1 of the block, a meal break drawn as a hatched gap; its words go in `note`), `blocked?` (hatched, refuses create and drop), `blockedLabel
|
|
53
|
+
| `cell` | `(rowId, day) => ScheduleGridCell` | `blocks` (`id`, `label`, `note?`, `tone`, `movable?`, `copyable?`, `selected?`, `title?`, `breakSpan?` — `{ start, end }` as fractions 0…1 of the block, a meal break drawn as a hatched gap; its words go in `note`), `blocked?` (hatched, refuses create and drop), `blockedLabel?`, `closed?` (the day can take no new turno — it has gone: no fill, no "+", see [Closed days](#closed-days)), `closedLabel?` (a closed cell's visually hidden words, "Já passou"). Called for every cell on each render: keep it cheap. |
|
|
54
54
|
| `totalLabel` | `string?` | The last column's header ("horas"). |
|
|
55
55
|
| `readOnly` | `boolean?` | No "+", no grips, no drag; empty cells are not focusable. Block clicks still reach `onBlockClick`. |
|
|
56
56
|
| `onCreate` / `onCopy` / `onMove` / `onBlockClick` | see Gestures | Each gesture is offered only when its handler is given. |
|
|
@@ -82,6 +82,36 @@ block's height, under its text, so the block reads as cut there in every tone; i
|
|
|
82
82
|
`nameAdornment` and `chips` are the host's nodes (an `@12-apps/ui` `Chip` fits): the grid only
|
|
83
83
|
places them.
|
|
84
84
|
|
|
85
|
+
## Closed days
|
|
86
|
+
|
|
87
|
+
A week runs Monday to Sunday, so the one shown often holds days already gone, and the server
|
|
88
|
+
refuses a turno on them. The host marks such a cell `closed: true`, and the grid offers nothing
|
|
89
|
+
there that could never work:
|
|
90
|
+
|
|
91
|
+
- no "+": the empty cell is not a focus stop (Tab and the arrows pass over it);
|
|
92
|
+
- a create or copy drag across it skips it, and a move or a keyboard copy/move onto it is
|
|
93
|
+
refused (read aloud as for a taken day) — the same rules as a `blocked` day; a move passing
|
|
94
|
+
over it does not highlight it;
|
|
95
|
+
- the blocks already there still show, still open (`onBlockClick`), and still copy and move
|
|
96
|
+
OUT of the day — only the day a turno lands on must be open;
|
|
97
|
+
- no fill: a transparent ground inside the `divider` border, so a run of gone days (a phone's
|
|
98
|
+
first screen can hold nothing else) reads as quiet, not as broken cells. No hatch and no
|
|
99
|
+
visible text;
|
|
100
|
+
- `closedLabel` ("Já passou") is the cell's words for a screen reader, in a visually hidden
|
|
101
|
+
span; without it the cell stays unnamed. It is ignored on a `blocked` cell, which has its own
|
|
102
|
+
name.
|
|
103
|
+
|
|
104
|
+
The day's header says it too: a column with `past: true` draws its label in `text.secondary`
|
|
105
|
+
(`today` wins). **`past` is on the column, not derived from the cells**, because the two say
|
|
106
|
+
different things: `past` is a fact of the DAY, the same for every row, while `closed` is a
|
|
107
|
+
per-row decision the host makes (a back office may still open a gone day to one person, or a
|
|
108
|
+
gone day may hold only blocks). Deriving the header from the cells would make it ask every row
|
|
109
|
+
on each render and pick a rule for a day closed to some rows only. A host showing a gone day
|
|
110
|
+
normally sets both: `past` on its column and `closed` on its cells.
|
|
111
|
+
|
|
112
|
+
`blocked` is the other closed cell: an afastamento, hatched and named. A cell may be both; the
|
|
113
|
+
hatch wins.
|
|
114
|
+
|
|
85
115
|
## Layout
|
|
86
116
|
|
|
87
117
|
- Name column 200px · the day columns share the rest equally (`minmax(0, 1fr)`) · total 56px;
|
|
@@ -119,7 +149,7 @@ places them.
|
|
|
119
149
|
rows only, so the host's `error` and `empty` nodes sit in one full-width row's cell. Every empty
|
|
120
150
|
cell's "+" and every block is a native `<button>` (Tab, Enter, Space); blocks declare their
|
|
121
151
|
shortcuts in `aria-keyshortcuts`, and the `selected` block is `aria-current="true"`. A blocked
|
|
122
|
-
cell is named by `blockedLabel` (or `labels.blockedCell`). The live region is `role="status"`,
|
|
152
|
+
cell is named by `blockedLabel` (or `labels.blockedCell`); a closed one carries its `closedLabel`, when given, as visually hidden text. The live region is `role="status"`,
|
|
123
153
|
polite, and stays mounted: each sentence clears it and is written on the next frame, so the
|
|
124
154
|
same sentence twice is read twice.
|
|
125
155
|
|
|
@@ -21,9 +21,11 @@ import {
|
|
|
21
21
|
personRowSx,
|
|
22
22
|
plusButtonSx,
|
|
23
23
|
skeletonCellSx,
|
|
24
|
+
SR_ONLY_SX,
|
|
24
25
|
totalCellSx,
|
|
25
26
|
totalHeaderSx,
|
|
26
27
|
} from './ScheduleGrid.styles';
|
|
28
|
+
import type { CellLook } from './ScheduleGrid.styles';
|
|
27
29
|
import type {
|
|
28
30
|
ScheduleGridBlock,
|
|
29
31
|
ScheduleGridCell,
|
|
@@ -178,18 +180,35 @@ function CellFill({ props, ghost }: { props: CellProps; ghost: string | null }):
|
|
|
178
180
|
);
|
|
179
181
|
}
|
|
180
182
|
|
|
181
|
-
/**
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
183
|
+
/** A gone day's words for a screen reader ("Já passou"): visually hidden, and only when the host gives them. */
|
|
184
|
+
function ClosedWords({ cell }: { cell: ScheduleGridCell }): React.JSX.Element | null {
|
|
185
|
+
if (!cell.closed || cell.blocked || !cell.closedLabel) return null;
|
|
186
|
+
return (
|
|
187
|
+
<Box component="span" sx={SR_ONLY_SX}>
|
|
188
|
+
{cell.closedLabel}
|
|
189
|
+
</Box>
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/** How the cell is drawn right now. */
|
|
194
|
+
function lookOf(props: CellProps, ghost: string | null): CellLook {
|
|
195
|
+
const { row, day, column, cell, drag, can } = props;
|
|
196
|
+
return {
|
|
187
197
|
today: Boolean(column.today),
|
|
188
|
-
blocked,
|
|
198
|
+
blocked: Boolean(cell.blocked),
|
|
199
|
+
closed: Boolean(cell.closed),
|
|
189
200
|
target: ghost !== null,
|
|
190
201
|
over: drag?.mode === 'move' && drag.moved && drag.rowId === row.id && drag.day === day,
|
|
191
202
|
interactive: can.create && isOpen(cell),
|
|
192
203
|
};
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/** One day of one row: its blocks, a "+" when it is empty, the hatch when it is closed. */
|
|
207
|
+
export function GridCell(props: CellProps): React.JSX.Element {
|
|
208
|
+
const { row, day, column, cell, can, labels, testId } = props;
|
|
209
|
+
const ghost = ghostFor(props);
|
|
210
|
+
const look = lookOf(props, ghost);
|
|
211
|
+
const blocked = look.blocked;
|
|
193
212
|
const closedName = blocked && cell.blocks.length === 0 ? (cell.blockedLabel ?? labels.blockedCell(row.label, column.label)) : undefined;
|
|
194
213
|
return (
|
|
195
214
|
<Box
|
|
@@ -214,6 +233,7 @@ export function GridCell(props: CellProps): React.JSX.Element {
|
|
|
214
233
|
/>
|
|
215
234
|
))}
|
|
216
235
|
<CellFill props={props} ghost={ghost} />
|
|
236
|
+
<ClosedWords cell={cell} />
|
|
217
237
|
</Box>
|
|
218
238
|
);
|
|
219
239
|
}
|
|
@@ -245,7 +265,12 @@ export function GridHeader({ columns, totalLabel, rowSx, testId }: HeaderProps):
|
|
|
245
265
|
{/* Above the names: a cell of the header row, with nothing to head. */}
|
|
246
266
|
<span role="cell" data-sg-corner="" />
|
|
247
267
|
{columns.map((column, day) => (
|
|
248
|
-
<Box
|
|
268
|
+
<Box
|
|
269
|
+
role="columnheader"
|
|
270
|
+
key={`${day}-${column.label}`}
|
|
271
|
+
sx={headerCellSx(Boolean(column.today), Boolean(column.past))}
|
|
272
|
+
data-sg-past={column.past ? '' : undefined}
|
|
273
|
+
>
|
|
249
274
|
<span data-sg-col="full" title={column.label}>
|
|
250
275
|
{keepDatesWhole(column.label)}
|
|
251
276
|
</span>
|
|
@@ -143,11 +143,15 @@ export const headerRowSx: SxPart = (theme: Theme) => ({
|
|
|
143
143
|
paddingBottom: theme.spacing(0.75),
|
|
144
144
|
});
|
|
145
145
|
|
|
146
|
-
|
|
146
|
+
/** A day's header: today's label in the primary colour, a gone day's in the secondary ink (today wins). */
|
|
147
|
+
export function headerCellSx(today: boolean, past = false): SxProps<Theme> {
|
|
148
|
+
let color = 'text.primary';
|
|
149
|
+
if (past) color = 'text.secondary';
|
|
150
|
+
if (today) color = 'primary.main';
|
|
147
151
|
return {
|
|
148
152
|
fontSize: sxRem(M.headerLabel),
|
|
149
153
|
fontWeight: 500,
|
|
150
|
-
color
|
|
154
|
+
color,
|
|
151
155
|
p: 0.5,
|
|
152
156
|
minWidth: 0,
|
|
153
157
|
// A long label ("Hoje · Seg 19/10") wraps to a second line, as the prototype's: never cut.
|
|
@@ -204,6 +208,8 @@ export const totalCellSx: SxProps<Theme> = {
|
|
|
204
208
|
export interface CellLook {
|
|
205
209
|
today: boolean;
|
|
206
210
|
blocked: boolean;
|
|
211
|
+
/** The day has gone (`closed`): no fill, the divider border; never a drop target. */
|
|
212
|
+
closed: boolean;
|
|
207
213
|
/** A create or copy will land here: dashed, with the hours as ghost text. */
|
|
208
214
|
target: boolean;
|
|
209
215
|
/** The pointer is over it while a block moves. */
|
|
@@ -239,6 +245,7 @@ export function cellSx(look: CellLook): SxProps<Theme> {
|
|
|
239
245
|
if (look.blocked) {
|
|
240
246
|
return { ...base, background: hatch(theme), borderColor: theme.palette.divider, cursor: 'not-allowed' };
|
|
241
247
|
}
|
|
248
|
+
if (look.closed) return { ...base, backgroundColor: 'transparent', borderColor: theme.palette.divider };
|
|
242
249
|
if (look.target) {
|
|
243
250
|
return {
|
|
244
251
|
...base,
|
|
@@ -21,6 +21,12 @@ export interface ScheduleGridColumn {
|
|
|
21
21
|
sublabel?: string;
|
|
22
22
|
/** Today's column: its label in the primary colour and its cells framed. */
|
|
23
23
|
today?: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* The day has gone: its label in the secondary ink (`today` wins). The
|
|
26
|
+
* header only — the cells that can take no new turno say so themselves
|
|
27
|
+
* (`ScheduleGridCell.closed`).
|
|
28
|
+
*/
|
|
29
|
+
past?: boolean;
|
|
24
30
|
}
|
|
25
31
|
|
|
26
32
|
/** A row: one person (or resource) across the days. */
|
|
@@ -95,6 +101,20 @@ export interface ScheduleGridCell {
|
|
|
95
101
|
blocked?: boolean;
|
|
96
102
|
/** Written in a blocked cell with no blocks ("Afastamento"). */
|
|
97
103
|
blockedLabel?: string;
|
|
104
|
+
/**
|
|
105
|
+
* The day can take no new turno (it has gone). No "+", the empty cell is no
|
|
106
|
+
* focus stop, a create or copy drag skips it and a move or keyboard
|
|
107
|
+
* copy/move onto it is refused — as on a `blocked` day — but with no hatch
|
|
108
|
+
* and no label: the cell just looks empty. Blocks already there still show
|
|
109
|
+
* and still open. Drawn with no fill, only the divider border.
|
|
110
|
+
*/
|
|
111
|
+
closed?: boolean;
|
|
112
|
+
/**
|
|
113
|
+
* A closed cell's words for a screen reader ("Já passou"), visually hidden;
|
|
114
|
+
* nothing on screen. Without it the cell stays unnamed. Ignored on a
|
|
115
|
+
* `blocked` cell, which has its own name.
|
|
116
|
+
*/
|
|
117
|
+
closedLabel?: string;
|
|
98
118
|
}
|
|
99
119
|
|
|
100
120
|
export interface ScheduleGridProps {
|
|
@@ -112,12 +132,12 @@ export interface ScheduleGridProps {
|
|
|
112
132
|
readOnly?: boolean;
|
|
113
133
|
/**
|
|
114
134
|
* A click on an empty cell (one day), or a drag across empty cells of one
|
|
115
|
-
* row (every crossed day that is empty and not
|
|
135
|
+
* row (every crossed day that is empty, not blocked and not closed).
|
|
116
136
|
*/
|
|
117
137
|
onCreate?: (rowId: string, days: number[]) => void;
|
|
118
|
-
/** A block's edge grip dragged along its row: the crossed days that are empty and not
|
|
138
|
+
/** A block's edge grip dragged along its row: the crossed days that are empty, not blocked and not closed. */
|
|
119
139
|
onCopy?: (blockId: string, days: number[]) => void;
|
|
120
|
-
/** A block's middle dropped on an empty, open cell of any row. */
|
|
140
|
+
/** A block's middle dropped on an empty, open cell of any row (never a blocked or closed one). */
|
|
121
141
|
onMove?: (blockId: string, toRowId: string, toDay: number) => void;
|
|
122
142
|
/** A block clicked, tapped or Entered. */
|
|
123
143
|
onBlockClick?: (blockId: string) => void;
|
|
@@ -5,9 +5,9 @@ import type { ScheduleGridCell } from './ScheduleGrid.types';
|
|
|
5
5
|
* on. The host decides everything else — hours, limits, refusals.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
/** A cell that can take a new turno: nothing in it
|
|
8
|
+
/** A cell that can take a new turno: nothing in it, not closed to the row (`blocked`) and not gone (`closed`). */
|
|
9
9
|
export function isOpen(cell: ScheduleGridCell): boolean {
|
|
10
|
-
return !cell.blocked && cell.blocks.length === 0;
|
|
10
|
+
return !cell.blocked && !cell.closed && cell.blocks.length === 0;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
/** Every day from `a` to `b` inclusive, in order, whichever is larger. */
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/data-display/ScheduleGrid/ScheduleGrid.parts.tsx"],"sourcesContent":["import AddIcon from '@mui/icons-material/Add';\nimport Box from '@mui/material/Box/index.js';\nimport type { CSSObject, Theme } from '@mui/material/styles/index.js';\nimport type * as React from 'react';\n\nimport type { ScheduleGridLabels } from '../../../copy/labels';\nimport { daysBetween, isOpen } from './schedule-grid-model';\nimport { SCHEDULE_GRID_METRICS } from './ScheduleGrid.metrics';\nimport {\n blockedLabelSx,\n blockSx,\n breakSx,\n cellSx,\n ghostSx,\n gripSx,\n groupTitleSx,\n headerCellSx,\n headerSublabelSx,\n headerRowSx,\n nameCellSx,\n personRowSx,\n plusButtonSx,\n skeletonCellSx,\n totalCellSx,\n totalHeaderSx,\n} from './ScheduleGrid.styles';\nimport type {\n ScheduleGridBlock,\n ScheduleGridCell,\n ScheduleGridColumn,\n ScheduleGridProps,\n ScheduleGridRow,\n} from './ScheduleGrid.types';\nimport { ScheduleNameCell } from './ScheduleNameCell';\nimport type { GridDrag, GridDragApi } from './useGridDrag';\n\n/** What the grid lets a cell do, resolved once per render. */\nexport interface CellAbilities {\n create: boolean;\n copy: boolean;\n move: boolean;\n}\n\n/** A row's shared columns, as an `sx` part. */\ntype RowSx = (theme: Theme) => CSSObject;\n\ninterface CellProps {\n row: ScheduleGridRow;\n day: number;\n column: ScheduleGridColumn;\n cell: ScheduleGridCell;\n drag: GridDrag | null;\n dragApi: GridDragApi;\n can: CellAbilities;\n createPreview?: (rowId: string) => string;\n onCreate?: (rowId: string, days: number[]) => void;\n onBlockClick?: (blockId: string) => void;\n labels: ScheduleGridLabels;\n testId: string;\n}\n\n/** The ghost text this cell shows during a create or copy, or `null` when the gesture does not land here. */\nfunction ghostFor(props: CellProps): string | null {\n const { drag, row, day, cell, createPreview } = props;\n if (!drag || drag.mode === 'move' || drag.rowId !== row.id || !isOpen(cell)) return null;\n if (!daysBetween(drag.anchor, drag.day).includes(day)) return null;\n if (drag.mode === 'copy') return day === drag.anchor ? null : drag.preview;\n return createPreview?.(row.id) ?? '';\n}\n\n/** The keys a block answers to, for `aria-keyshortcuts`. */\nfunction shortcutsOf(movable: boolean, copyable: boolean): string | undefined {\n const keys = [movable ? 'Alt+ArrowLeft Alt+ArrowRight' : '', copyable ? 'Shift+ArrowLeft Shift+ArrowRight' : ''];\n return keys.filter(Boolean).join(' ') || undefined;\n}\n\nconst titleOf = (block: ScheduleGridBlock): string => block.title ?? [block.label, block.note].filter(Boolean).join(' · ');\n\ninterface BlockProps {\n block: ScheduleGridBlock;\n row: ScheduleGridRow;\n day: number;\n can: CellAbilities;\n dragApi: GridDragApi;\n onBlockClick?: (blockId: string) => void;\n testId: string;\n}\n\nfunction Grip({ side, onPointerDown, testId }: { side: 'l' | 'r'; onPointerDown: (event: React.PointerEvent) => void; testId: string }) {\n return <Box component=\"span\" aria-hidden sx={gripSx(side)} onPointerDown={onPointerDown} data-sg-grip=\"\" data-testid={testId} />;\n}\n\n/** The block's break, kept inside it whatever the host sent. */\nfunction BreakBand({ span, testId }: { span: { start: number; end: number }; testId: string }): React.JSX.Element | null {\n const start = Math.min(1, Math.max(0, span.start));\n const end = Math.min(1, Math.max(0, span.end));\n if (!(end > start)) return null;\n return <Box component=\"span\" aria-hidden sx={breakSx({ start, end })} data-sg-break=\"\" data-testid={testId} />;\n}\n\nfunction BlockButton({ block, row, day, can, dragApi, onBlockClick, testId }: BlockProps): React.JSX.Element {\n const movable = can.move && Boolean(block.movable);\n const copyable = can.copy && Boolean(block.copyable);\n const startCopy = (event: React.PointerEvent): void => dragApi.startCopy(event, block.id, row.id, day, block.label);\n const startMove = (event: React.PointerEvent): void => dragApi.startMove(event, block.id, row.id, day);\n return (\n <Box\n component=\"button\"\n type=\"button\"\n sx={blockSx(block.tone, { selected: Boolean(block.selected), movable })}\n title={titleOf(block)}\n aria-keyshortcuts={shortcutsOf(movable, copyable)}\n aria-current={block.selected ? 'true' : undefined}\n data-sg-focus=\"\"\n data-sg-row={row.id}\n data-sg-day={day}\n data-sg-block={block.id}\n data-tone={block.tone}\n data-testid={`${testId}-block-${block.id}`}\n onPointerDown={movable ? startMove : undefined}\n onClick={() => {\n if (!dragApi.takeClick()) onBlockClick?.(block.id);\n }}\n >\n {block.breakSpan ? <BreakBand span={block.breakSpan} testId={`${testId}-break-${block.id}`} /> : null}\n {copyable ? <Grip side=\"l\" onPointerDown={startCopy} testId={`${testId}-grip-l-${block.id}`} /> : null}\n <span data-sg-line=\"label\">{block.label}</span>\n {block.note ? <span data-sg-line=\"note\">{block.note}</span> : null}\n {copyable ? <Grip side=\"r\" onPointerDown={startCopy} testId={`${testId}-grip-r-${block.id}`} /> : null}\n </Box>\n );\n}\n\n/**\n * The empty cell's \"+\". It stays mounted while a drag shows the ghost in it, so\n * a press and release in place is still its click.\n */\nfunction PlusButton({ props, ghost }: { props: CellProps; ghost: string | null }): React.JSX.Element {\n const { row, day, column, dragApi, onCreate, labels } = props;\n return (\n <Box\n component=\"button\"\n type=\"button\"\n sx={plusButtonSx}\n aria-label={labels.createCell(row.label, column.label)}\n data-ghost={ghost === null ? undefined : ''}\n data-sg-focus=\"\"\n data-sg-row={row.id}\n data-sg-day={day}\n onPointerDown={(event: React.PointerEvent) => dragApi.startCreate(event, row.id, day)}\n onClick={() => {\n if (!dragApi.takeClick()) onCreate?.(row.id, [day]);\n }}\n >\n {ghost === null ? <AddIcon aria-hidden /> : <Ghost text={ghost} />}\n </Box>\n );\n}\n\nfunction Ghost({ text }: { text: string }): React.JSX.Element {\n return (\n <Box component=\"span\" sx={ghostSx} aria-hidden>\n {text}\n </Box>\n );\n}\n\n/** What fills a cell after its blocks: the \"+\" (or the ghost in it), a lone ghost, or a closed day's label. */\nfunction CellFill({ props, ghost }: { props: CellProps; ghost: string | null }): React.JSX.Element | null {\n const { cell, can } = props;\n if (can.create && isOpen(cell)) return <PlusButton props={props} ghost={ghost} />;\n if (ghost !== null) return <Ghost text={ghost} />;\n if (!cell.blocked || cell.blocks.length > 0 || !cell.blockedLabel) return null;\n return (\n <Box component=\"span\" sx={blockedLabelSx} aria-hidden title={cell.blockedLabel}>\n {cell.blockedLabel}\n </Box>\n );\n}\n\n/** One day of one row: its blocks, a \"+\" when it is empty, the hatch when it is closed. */\nexport function GridCell(props: CellProps): React.JSX.Element {\n const { row, day, column, cell, drag, can, labels, testId } = props;\n const ghost = ghostFor(props);\n const blocked = Boolean(cell.blocked);\n const look = {\n today: Boolean(column.today),\n blocked,\n target: ghost !== null,\n over: drag?.mode === 'move' && drag.moved && drag.rowId === row.id && drag.day === day,\n interactive: can.create && isOpen(cell),\n };\n const closedName = blocked && cell.blocks.length === 0 ? (cell.blockedLabel ?? labels.blockedCell(row.label, column.label)) : undefined;\n return (\n <Box\n role=\"cell\"\n sx={cellSx(look)}\n data-sg-cell=\"\"\n data-sg-row={row.id}\n data-sg-day={day}\n data-testid={`${testId}-cell-${row.id}-${day}`}\n aria-label={closedName}\n >\n {cell.blocks.map((block) => (\n <BlockButton\n key={block.id}\n block={block}\n row={row}\n day={day}\n can={can}\n dragApi={props.dragApi}\n onBlockClick={props.onBlockClick}\n testId={testId}\n />\n ))}\n <CellFill props={props} ghost={ghost} />\n </Box>\n );\n}\n\n/** The first column: the person, as both views draw it. */\nfunction NameCell({ row }: { row: ScheduleGridRow }): React.JSX.Element {\n const sizes = { name: SCHEDULE_GRID_METRICS.rowName, meta: SCHEDULE_GRID_METRICS.rowMeta, chipsTop: 0.5 };\n return <ScheduleNameCell row={row} role=\"rowheader\" sx={nameCellSx} sizes={sizes} />;\n}\n\ninterface HeaderProps {\n columns: readonly ScheduleGridColumn[];\n /** Present when the grid has a last column. */\n totalLabel?: string;\n rowSx: RowSx;\n testId: string;\n}\n\n/** The days, their counts and the total column's header — pinned while the grid scrolls. */\n\n/** A label wraps between words, never inside \"Seg 19/10\": the space before a number holds. */\nfunction keepDatesWhole(label: string): string {\n return label.replace(/ (?=\\d)/g, '\\u00a0');\n}\n\nexport function GridHeader({ columns, totalLabel, rowSx, testId }: HeaderProps): React.JSX.Element {\n return (\n <Box role=\"row\" sx={[rowSx, headerRowSx]} data-testid={`${testId}-header`}>\n {/* Above the names: a cell of the header row, with nothing to head. */}\n <span role=\"cell\" data-sg-corner=\"\" />\n {columns.map((column, day) => (\n <Box role=\"columnheader\" key={`${day}-${column.label}`} sx={headerCellSx(Boolean(column.today))}>\n <span data-sg-col=\"full\" title={column.label}>\n {keepDatesWhole(column.label)}\n </span>\n {column.sublabel ? (\n <Box component=\"span\" sx={headerSublabelSx} data-sg-col=\"sub\">\n {column.sublabel}\n </Box>\n ) : null}\n </Box>\n ))}\n {totalLabel !== undefined ? (\n <Box role=\"columnheader\" sx={totalHeaderSx}>\n {totalLabel}\n </Box>\n ) : null}\n </Box>\n );\n}\n\ninterface BodyProps {\n grid: ScheduleGridProps;\n rows: readonly ScheduleGridRow[];\n rowSx: RowSx;\n hasTotal: boolean;\n can: CellAbilities;\n dragApi: GridDragApi;\n labels: ScheduleGridLabels;\n testId: string;\n}\n\nfunction SkeletonRows({ grid, rowSx, testId }: Pick<BodyProps, 'grid' | 'rowSx' | 'testId'>): React.JSX.Element {\n return (\n <>\n {Array.from({ length: SCHEDULE_GRID_METRICS.skeletonRows }, (_, index) => (\n <Box key={index} sx={[rowSx, personRowSx]} aria-hidden data-testid={`${testId}-loading`}>\n <Box sx={skeletonCellSx} />\n {grid.columns.map((column, day) => (\n <Box key={`${day}-${column.label}`} sx={skeletonCellSx} />\n ))}\n </Box>\n ))}\n </>\n );\n}\n\nfunction PersonRow({ row, body }: { row: ScheduleGridRow; body: BodyProps }): React.JSX.Element {\n const { grid, rowSx, hasTotal, can, dragApi, labels, testId } = body;\n return (\n <Box role=\"row\" sx={[rowSx, personRowSx]} data-testid={`${testId}-row-${row.id}`}>\n <NameCell row={row} />\n {grid.columns.map((column, day) => (\n <GridCell\n key={`${day}-${column.label}`}\n row={row}\n day={day}\n column={column}\n cell={grid.cell(row.id, day)}\n drag={dragApi.drag}\n dragApi={dragApi}\n can={can}\n createPreview={grid.createPreview}\n onCreate={grid.onCreate}\n onBlockClick={grid.onBlockClick}\n labels={labels}\n testId={testId}\n />\n ))}\n {hasTotal ? (\n <Box role=\"cell\" sx={totalCellSx}>\n {row.total}\n </Box>\n ) : null}\n </Box>\n );\n}\n\n/** The host's error or empty node, as the table's one full-width row (a table holds rows only). */\nfunction MessageRow({ children, testId }: { children: React.ReactNode; testId: string }): React.JSX.Element | null {\n if (children === null || children === undefined || children === false) return null;\n return (\n <Box role=\"row\" data-testid={`${testId}-message`}>\n <Box role=\"cell\">{children}</Box>\n </Box>\n );\n}\n\n/** The groups and their rows — or the skeleton, the host's error, or the host's empty state. */\nexport function GridBody(body: BodyProps): React.JSX.Element | null {\n const { grid, rows } = body;\n if (grid.error) return <MessageRow testId={body.testId}>{grid.error}</MessageRow>;\n if (grid.loading) return <SkeletonRows grid={grid} rowSx={body.rowSx} testId={body.testId} />;\n if (rows.length === 0) return <MessageRow testId={body.testId}>{grid.empty}</MessageRow>;\n return (\n <>\n {grid.groups.map((group, index) => (\n <Box role=\"rowgroup\" key={`${index}-${group.title ?? ''}`} aria-label={group.title}>\n {group.title ? (\n <Box component=\"p\" sx={groupTitleSx} aria-hidden data-sg-group-title=\"\">\n {group.title}\n </Box>\n ) : null}\n {group.rows.map((row) => (\n <PersonRow key={row.id} row={row} body={body} />\n ))}\n </Box>\n ))}\n </>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/data-display/ScheduleGrid/schedule-grid-model.ts"],"sourcesContent":["import type { ScheduleGridCell } from './ScheduleGrid.types';\n\n/**\n * THE GRID'S RULES, as pure functions (FUT-3825): which days a gesture lands\n * on. The host decides everything else — hours, limits, refusals.\n */\n\n/** A cell that can take a new turno: nothing in it and not closed to the row. */\nexport function isOpen(cell: ScheduleGridCell): boolean {\n return !cell.blocked && cell.blocks.length === 0;\n}\n\n/** Every day from `a` to `b` inclusive, in order, whichever is larger. */\nexport function daysBetween(a: number, b: number): number[] {\n const from = Math.min(a, b);\n const to = Math.max(a, b);\n return Array.from({ length: to - from + 1 }, (_, index) => from + index);\n}\n\n/** A create across `anchor…current` of one row: the crossed days that are open (G-R1). */\nexport function createTargets(cellOf: (day: number) => ScheduleGridCell, anchor: number, current: number): number[] {\n return daysBetween(anchor, current).filter((day) => isOpen(cellOf(day)));\n}\n\n/** A copy of the block on `source` across `source…current`: never its own day, never a taken or closed one (G-R2). */\nexport function copyTargets(cellOf: (day: number) => ScheduleGridCell, source: number, current: number): number[] {\n return daysBetween(source, current).filter((day) => day !== source && isOpen(cellOf(day)));\n}\n\n/** A move may land on an open cell that is not its own (G-R3). */\nexport function canDrop(target: ScheduleGridCell, sameCell: boolean): boolean {\n return !sameCell && isOpen(target);\n}\n\n/** The day one step left (-1) or right (+1) of `day`, or `undefined` past either end. */\nexport function stepDay(day: number, direction: -1 | 1, dayCount: number): number | undefined {\n const next = day + direction;\n return next >= 0 && next < dayCount ? next : undefined;\n}\n"],"mappings":";AAQO,SAAS,OAAO,MAAiC;AACtD,SAAO,CAAC,KAAK,WAAW,KAAK,OAAO,WAAW;AACjD;AAGO,SAAS,YAAY,GAAW,GAAqB;AAC1D,QAAM,OAAO,KAAK,IAAI,GAAG,CAAC;AAC1B,QAAM,KAAK,KAAK,IAAI,GAAG,CAAC;AACxB,SAAO,MAAM,KAAK,EAAE,QAAQ,KAAK,OAAO,EAAE,GAAG,CAAC,GAAG,UAAU,OAAO,KAAK;AACzE;AAGO,SAAS,cAAc,QAA2C,QAAgB,SAA2B;AAClH,SAAO,YAAY,QAAQ,OAAO,EAAE,OAAO,CAAC,QAAQ,OAAO,OAAO,GAAG,CAAC,CAAC;AACzE;AAGO,SAAS,YAAY,QAA2C,QAAgB,SAA2B;AAChH,SAAO,YAAY,QAAQ,OAAO,EAAE,OAAO,CAAC,QAAQ,QAAQ,UAAU,OAAO,OAAO,GAAG,CAAC,CAAC;AAC3F;AAGO,SAAS,QAAQ,QAA0B,UAA4B;AAC5E,SAAO,CAAC,YAAY,OAAO,MAAM;AACnC;AAGO,SAAS,QAAQ,KAAa,WAAmB,UAAsC;AAC5F,QAAM,OAAO,MAAM;AACnB,SAAO,QAAQ,KAAK,OAAO,WAAW,OAAO;AAC/C;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/data-display/ScheduleGrid/ScheduleGrid.styles.ts"],"sourcesContent":["import type { SxProps, Theme } from '@mui/material/styles/index.js';\nimport type { CSSObject } from '@mui/material/styles/index.js';\n\nimport { rem, sxRem } from '../../../tokens/relative';\nimport { SCHEDULE_GRID_METRICS as M } from './ScheduleGrid.metrics';\nimport { blockToneStyles, breakHatch } from './schedule-tones';\nimport type { ScheduleBlockTone } from './ScheduleGrid.types';\n\n/**\n * The grid's root: the container the column widths answer to (container\n * queries, never media queries — the grid may sit in a narrow pane).\n */\nexport const rootSx: SxProps<Theme> = { containerType: 'inline-size', minWidth: 0, width: '100%' };\n\n/** The columns a row has: the name, the days, the total (when there is one). */\nfunction trackCount(dayCount: number, hasTotal: boolean): number {\n return 1 + dayCount + (hasTotal ? 1 : 0);\n}\n\n/**\n * The narrowest container a layout fits in, in px: its name column, its days\n * at their minimum, its total, and the gaps between them — for THIS grid's\n * day count, so a fortnight scrolls where a week still fits.\n */\nfunction fitsFrom(dayCount: number, hasTotal: boolean, name: number, day: number, total: number): number {\n return name + dayCount * day + (hasTotal ? total : 0) + (trackCount(dayCount, hasTotal) - 1) * M.gap;\n}\n\n/** `@container (width < px)`: every bound is \"from px up\" (ranges are exclusive below, inclusive above). */\nfunction below(theme: Theme, px: number): string {\n return `@container (width < ${rem(theme, px)})`;\n}\n\n/**\n * The column widths, as variables every row reads, by the container's width:\n * - from `wide` up: 200px names, days of at least 104px with their grips;\n * - from `compact` up: 140px names, 40px total, days of at least 98px — still\n * unscrolled, grips kept, the header row sticking to the page;\n * - below `compact`: days of at least 152px, grips kept; the body scrolls\n * sideways under the pinned names and the header row follows it sideways\n * while it still sticks to the page (`useSidewaysScroll` sets its scroll);\n * - below 600px: 120px names, 136px days, no grips.\n * The `wide` and `compact` bounds come from this grid's own day count\n * (`fitsFrom`). Container queries, never media queries.\n */\nexport function frameSx(dayCount: number, hasTotal: boolean): SxProps<Theme> {\n return (theme: Theme) => {\n const terms = ['var(--sg-name)', `${dayCount} * var(--sg-day)`, `${trackCount(dayCount, hasTotal) - 1} * ${rem(theme, M.gap)}`];\n if (hasTotal) terms.push('var(--sg-total)');\n const wide = fitsFrom(dayCount, hasTotal, M.nameColumn.wide, M.dayMin.wide, M.totalColumn.wide);\n const compact = fitsFrom(dayCount, hasTotal, M.nameColumn.compact, M.dayMin.compact, M.totalColumn.compact);\n return {\n '--sg-name': rem(theme, M.nameColumn.wide),\n '--sg-total': rem(theme, M.totalColumn.wide),\n '--sg-day': rem(theme, M.dayMin.wide),\n // What every row is at least: its own columns at their minimums.\n '--sg-min': `calc(${terms.join(' + ')})`,\n [below(theme, wide)]: {\n '--sg-name': rem(theme, M.nameColumn.compact),\n '--sg-total': rem(theme, M.totalColumn.compact),\n '--sg-day': rem(theme, M.dayMin.compact),\n '& [data-sg-block]': { paddingLeft: rem(theme, M.blockPadding.tight), paddingRight: rem(theme, M.blockPadding.tight) },\n },\n [below(theme, compact)]: {\n '--sg-day': rem(theme, M.dayMin.scrolled),\n '& [data-sg-block]': {\n paddingLeft: rem(theme, M.blockPadding.start),\n paddingRight: rem(theme, M.blockPadding.end),\n },\n // A cell the keyboard reaches is brought out beside the pinned names, never under them.\n '& > [data-sg-scroll]': {\n overflowX: 'auto',\n overscrollBehaviorX: 'contain',\n scrollPaddingInlineStart: `calc(var(--sg-name) + ${rem(theme, M.gap)})`,\n },\n // The header row follows the days sideways (the grid sets its scroll). It is no scroller of\n // its own: a scroller with nothing focusable inside is a tab stop of its own.\n // `contain` still holds on a hidden overflow: a sideways swipe over the header is never the\n // browser's back / forward gesture.\n '& > [data-sg-head]': { overflowX: 'hidden', overscrollBehaviorX: 'contain' },\n // The pinned column: the names (and the cell above them, and the group\n // titles) stay while the days scroll under them.\n '& [role=\"rowheader\"], & [data-sg-corner]': {\n position: 'sticky',\n left: 0,\n zIndex: 2,\n backgroundColor: theme.palette.background.default,\n // Covers the gap after it too, so nothing scrolling shows between the name and the days.\n boxShadow: `${rem(theme, M.gap)} 0 0 ${theme.palette.background.default}`,\n },\n '& [data-sg-group-title]': { position: 'sticky', left: 0, width: 'fit-content' },\n },\n [below(theme, M.narrowBelow)]: {\n '--sg-name': rem(theme, M.nameColumn.narrow),\n '--sg-day': rem(theme, M.dayMin.narrow),\n // A phone-sized pane is read and tapped, not dragged (a phone renders\n // DayRuler per day): the grips would eat the block (Shift+arrows still copy).\n '& [data-sg-grip]': { display: 'none' },\n '& [data-sg-block]': { paddingLeft: rem(theme, M.cellPadding), paddingRight: rem(theme, M.cellPadding) },\n },\n display: 'flex',\n flexDirection: 'column',\n minWidth: 0,\n userSelect: 'none',\n };\n };\n}\n\n/** The body: scrolls sideways (under the compact bound) when the days' minimums do not fit. */\nexport const scrollSx: SxProps<Theme> = { minWidth: 0 };\n\n/** One line of the grid — the header or a person — as the shared columns. */\n/** A style that may sit in an `sx` array next to another. */\ntype SxPart = (theme: Theme) => CSSObject;\n\nexport function rowGridSx(dayCount: number, hasTotal: boolean): SxPart {\n return (theme: Theme) => ({\n display: 'grid',\n gridTemplateColumns: `var(--sg-name) repeat(${dayCount}, minmax(var(--sg-day), 1fr))${hasTotal ? ' var(--sg-total)' : ''}`,\n gap: rem(theme, M.gap),\n alignItems: 'stretch',\n minWidth: 'var(--sg-min)',\n });\n}\n\n/**\n * Around the header row: opaque, pinned to the top of the PAGE (or whatever\n * scrolls the grid vertically) — it is not inside the sideways scroller, so\n * it sticks at every width; while the days scroll it follows them sideways.\n */\nexport function headerSx(stickyTop: number): SxPart {\n return (theme: Theme) => ({\n position: 'sticky',\n top: rem(theme, stickyTop),\n zIndex: 3,\n backgroundColor: theme.palette.background.default,\n });\n}\n\n/** The header row itself, inside its sticky frame. */\nexport const headerRowSx: SxPart = (theme: Theme) => ({\n paddingTop: theme.spacing(0.75),\n paddingBottom: theme.spacing(0.75),\n});\n\nexport function headerCellSx(today: boolean): SxProps<Theme> {\n return {\n fontSize: sxRem(M.headerLabel),\n fontWeight: 500,\n color: today ? 'primary.main' : 'text.primary',\n p: 0.5,\n minWidth: 0,\n // A long label (\"Hoje · Seg 19/10\") wraps to a second line, as the prototype's: never cut.\n '& > *': { display: 'block', overflowWrap: 'anywhere' },\n };\n}\n\nexport const headerSublabelSx: SxProps<Theme> = {\n fontSize: sxRem(M.headerSublabel),\n fontWeight: 400,\n color: 'text.secondary',\n};\n\nexport const totalHeaderSx: SxProps<Theme> = {\n fontSize: sxRem(M.total),\n color: 'text.secondary',\n textAlign: 'right',\n alignSelf: 'end',\n p: 0.5,\n pr: 0,\n};\n\nexport const groupTitleSx: SxProps<Theme> = {\n fontSize: sxRem(M.groupTitle),\n letterSpacing: '0.05em',\n textTransform: 'uppercase',\n color: 'text.secondary',\n fontWeight: 500,\n pt: 1.5,\n pb: 0.5,\n m: 0,\n};\n\n/** A person's line: one grid row, then the gap below it. */\nexport const personRowSx: SxPart = (theme: Theme) => ({ marginBottom: rem(theme, M.gap) });\n\nexport const nameCellSx: SxProps<Theme> = {\n display: 'flex',\n flexDirection: 'column',\n justifyContent: 'center',\n pr: 0.5,\n minWidth: 0,\n};\n\nexport const totalCellSx: SxProps<Theme> = {\n fontSize: sxRem(M.total),\n color: 'text.secondary',\n textAlign: 'right',\n alignSelf: 'center',\n whiteSpace: 'nowrap',\n};\n\n/** What a cell is drawing right now. */\nexport interface CellLook {\n today: boolean;\n blocked: boolean;\n /** A create or copy will land here: dashed, with the hours as ghost text. */\n target: boolean;\n /** The pointer is over it while a block moves. */\n over: boolean;\n /** The cell's own \"+\" button may be pressed. */\n interactive: boolean;\n}\n\nfunction hatch(theme: Theme): string {\n const a = theme.palette.action.hover;\n const b = theme.palette.action.selected;\n const w = rem(theme, M.hatch);\n const w2 = rem(theme, M.hatch * 2);\n return `repeating-linear-gradient(135deg, ${a} 0, ${a} ${w}, ${b} ${w}, ${b} ${w2})`;\n}\n\nexport function cellSx(look: CellLook): SxProps<Theme> {\n return (theme: Theme): CSSObject => {\n const base: CSSObject = {\n position: 'relative',\n minHeight: rem(theme, M.cellMinHeight),\n borderRadius: rem(theme, M.cellRadius),\n backgroundColor: theme.palette.action.hover,\n border: `1px solid ${look.today ? theme.palette.primary.main : theme.palette.divider}`,\n padding: rem(theme, M.cellPadding),\n display: 'flex',\n flexDirection: 'column',\n gap: rem(theme, M.blockGap),\n boxSizing: 'border-box',\n minWidth: 0,\n cursor: look.interactive ? 'cell' : 'default',\n };\n if (look.blocked) {\n return { ...base, background: hatch(theme), borderColor: theme.palette.divider, cursor: 'not-allowed' };\n }\n if (look.target) {\n return {\n ...base,\n border: `${rem(theme, M.targetBorder)} dashed ${theme.palette.primary.main}`,\n backgroundColor: theme.palette.action.selected,\n };\n }\n if (look.over) return { ...base, borderColor: theme.palette.primary.main, backgroundColor: theme.palette.action.selected };\n return base;\n };\n}\n\n/** The empty cell's button: the whole cell, a quiet \"+\" in its middle. */\nexport const plusButtonSx: SxProps<Theme> = (theme: Theme) => ({\n flex: '1 1 auto',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n font: 'inherit',\n background: 'transparent',\n border: 0,\n p: 0,\n m: 0,\n color: theme.palette.text.disabled,\n cursor: 'inherit',\n borderRadius: rem(theme, M.cellRadius - M.cellPadding),\n '& svg': { fontSize: rem(theme, M.plusIcon) },\n // The \"+\" is swapped for the ghost on pointer down: were it the press's\n // target, the browser would drop the click once it left the DOM.\n '& > *': { pointerEvents: 'none' },\n '&:hover': { color: theme.palette.text.secondary },\n '&:focus-visible': { outline: `${rem(theme, M.ring)} solid ${theme.palette.primary.main}`, outlineOffset: 0 },\n // A drag's ghost text sits where the prototype writes it: top left.\n '&[data-ghost]': { justifyContent: 'flex-start', alignItems: 'flex-start' },\n});\n\n/** The ghost text of a cell a create or copy will land on. */\nexport const ghostSx: SxProps<Theme> = (theme: Theme) => ({\n fontSize: rem(theme, M.blockFont),\n fontWeight: 500,\n color: theme.palette.primary.main,\n px: 0.75,\n py: 0.5,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n});\n\n/** A closed day's word (\"Afastamento\"): one line inside its cell, cut with an ellipsis (the full word in `title`). */\nexport const blockedLabelSx: SxProps<Theme> = (theme: Theme) => ({\n display: 'block',\n fontSize: rem(theme, M.blockFont),\n color: theme.palette.text.secondary,\n px: 0.75,\n py: 0.5,\n lineHeight: 1.3,\n minWidth: 0,\n maxWidth: '100%',\n boxSizing: 'border-box',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n});\n\nexport function blockSx(tone: ScheduleBlockTone, opts: { selected: boolean; movable: boolean }): SxProps<Theme> {\n return (theme: Theme): CSSObject => ({\n ...blockToneStyles(theme, tone),\n position: 'relative',\n display: 'block',\n width: '100%',\n minWidth: 0,\n maxWidth: '100%',\n boxSizing: 'border-box',\n textAlign: 'left',\n font: 'inherit',\n fontSize: rem(theme, M.blockFont),\n fontWeight: 500,\n lineHeight: 1.35,\n borderRadius: rem(theme, M.blockRadius),\n padding: `${rem(theme, M.blockPadding.y)} ${rem(theme, M.blockPadding.end)} ${rem(theme, M.blockPadding.y)} ${rem(theme, M.blockPadding.start)}`,\n cursor: opts.movable ? 'grab' : 'pointer',\n margin: 0,\n boxShadow: opts.selected ? `0 0 0 ${rem(theme, M.ring)} ${theme.palette.primary.main}` : 'none',\n '&:focus-visible': { outline: `${rem(theme, M.ring)} solid ${theme.palette.primary.main}`, outlineOffset: rem(theme, M.ringOffset) },\n // The hours stay on one line; the note wraps (the block grows), as the prototype's\n // \"↻ a cada 2 / semanas\": a note is never cut, so a break keeps its end.\n '& > [data-sg-line]': { position: 'relative', display: 'block' },\n '& > [data-sg-line=\"label\"]': { overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' },\n '& > [data-sg-line=\"note\"]': { fontWeight: 400, overflowWrap: 'anywhere' },\n });\n}\n\n/** A break inside a block: a hatched band across its height, under its text. */\nexport function breakSx(span: { start: number; end: number }): SxProps<Theme> {\n return (theme: Theme) => ({\n position: 'absolute',\n top: 0,\n bottom: 0,\n left: `${span.start * 100}%`,\n width: `${(span.end - span.start) * 100}%`,\n background: breakHatch(theme, rem(theme, M.breakStripe.ink), rem(theme, M.breakStripe.ink + M.breakStripe.gap)),\n pointerEvents: 'none',\n });\n}\n\nexport function gripSx(side: 'l' | 'r'): SxProps<Theme> {\n return (theme: Theme) => ({\n position: 'absolute',\n top: 0,\n bottom: 0,\n [side === 'l' ? 'left' : 'right']: 0,\n width: rem(theme, M.grip.width),\n cursor: 'ew-resize',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n '&::before': {\n content: '\"\"',\n display: 'block',\n width: rem(theme, M.grip.barWidth),\n height: rem(theme, M.grip.barHeight),\n borderRadius: rem(theme, M.grip.barRadius),\n backgroundColor: 'currentColor',\n opacity: 0.5,\n },\n });\n}\n\nexport const skeletonCellSx: SxProps<Theme> = (theme: Theme) => ({\n minHeight: rem(theme, M.cellMinHeight),\n borderRadius: rem(theme, M.cellRadius),\n backgroundColor: theme.palette.action.hover,\n});\n\nexport const SR_ONLY_SX: SxProps<Theme> = {\n position: 'absolute',\n width: sxRem(1),\n height: sxRem(1),\n padding: 0,\n margin: sxRem(-1),\n overflow: 'hidden',\n clip: 'rect(0, 0, 0, 0)',\n whiteSpace: 'nowrap',\n border: 0,\n};\n"],"mappings":"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","names":[]}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|