tempest-react-sdk 0.56.0 → 0.57.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/dist/components/AppBar/AppBar.module.cjs.map +1 -1
- package/dist/components/AppBar/AppBar.module.js.map +1 -1
- package/dist/components/Scheduler/Scheduler.module.cjs.map +1 -1
- package/dist/components/Scheduler/Scheduler.module.js.map +1 -1
- package/dist/hooks/use-push-to-talk.cjs +1 -1
- package/dist/hooks/use-push-to-talk.cjs.map +1 -1
- package/dist/hooks/use-push-to-talk.js +2 -2
- package/dist/hooks/use-push-to-talk.js.map +1 -1
- package/dist/styles/AppBar.css +1 -1
- package/dist/styles/Scheduler.css +2 -2
- package/dist/styles/core.css +1 -1
- package/dist/styles/layout.css +2 -2
- package/dist/styles/navigation.css +1 -1
- package/dist/styles.css +1 -1
- package/dist/tempest-react-sdk.cjs +1 -1
- package/dist/tempest-react-sdk.d.ts +175 -12
- package/dist/tempest-react-sdk.js +33 -33
- package/dist/webrtc/link-stats.cjs +1 -1
- package/dist/webrtc/link-stats.cjs.map +1 -1
- package/dist/webrtc/link-stats.js +134 -44
- package/dist/webrtc/link-stats.js.map +1 -1
- package/dist/webrtc/mesh-quality.cjs +1 -1
- package/dist/webrtc/mesh-quality.cjs.map +1 -1
- package/dist/webrtc/mesh-quality.js +8 -2
- package/dist/webrtc/mesh-quality.js.map +1 -1
- package/dist/webrtc/peer-mesh.cjs +1 -1
- package/dist/webrtc/peer-mesh.cjs.map +1 -1
- package/dist/webrtc/peer-mesh.js +85 -63
- package/dist/webrtc/peer-mesh.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AppBar.module.cjs","names":[],"sources":["../../../src/components/AppBar/AppBar.module.css"],"sourcesContent":[".bar {\n display: grid;\n grid-template-columns: auto 1fr auto;\n align-items: center;\n gap: var(--tempest-space-2);\n width: 100%;\n min-height: 56px;\n padding: var(--tempest-space-3) var(--tempest-space-4);\n font-family: var(--tempest-font-sans);\n}\n\n/* Symmetric side columns so the title is truly centered. */\n.bar.centered {\n grid-template-columns: 1fr auto 1fr;\n}\n\n.bar.surface {\n background: var(--tempest-surface);\n color: var(--tempest-text);\n}\n\n.bar.primary {\n background: var(--tempest-primary);\n color: var(--tempest-
|
|
1
|
+
{"version":3,"file":"AppBar.module.cjs","names":[],"sources":["../../../src/components/AppBar/AppBar.module.css"],"sourcesContent":[".bar {\n display: grid;\n grid-template-columns: auto 1fr auto;\n align-items: center;\n gap: var(--tempest-space-2);\n width: 100%;\n min-height: 56px;\n padding: var(--tempest-space-3) var(--tempest-space-4);\n font-family: var(--tempest-font-sans);\n}\n\n/* Symmetric side columns so the title is truly centered. */\n.bar.centered {\n grid-template-columns: 1fr auto 1fr;\n}\n\n.bar.surface {\n background: var(--tempest-surface);\n color: var(--tempest-text);\n}\n\n.bar.primary {\n background: var(--tempest-primary);\n color: var(--tempest-primary-foreground);\n}\n\n.bar.transparent {\n background: transparent;\n color: inherit;\n}\n\n.bar.bordered {\n border-bottom: 1px solid var(--tempest-border);\n}\n\n.bar.sticky {\n position: sticky;\n top: 0;\n z-index: 30;\n}\n\n.bar.safeArea {\n padding-top: max(var(--tempest-space-3), env(safe-area-inset-top, 0px));\n}\n\n.leading {\n display: flex;\n align-items: center;\n gap: var(--tempest-space-2);\n min-width: 0;\n}\n\n.actions {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: var(--tempest-space-1);\n min-width: 0;\n}\n\n.title {\n margin: 0;\n min-width: 0;\n font-size: var(--tempest-text-xl);\n font-weight: var(--tempest-weight-bold);\n line-height: 1.2;\n text-align: left;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.bar.centered .title {\n text-align: center;\n}\n\n.brand {\n font-size: var(--tempest-text-lg);\n font-weight: var(--tempest-weight-bold);\n color: inherit;\n white-space: nowrap;\n}\n\n.iconBtn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: 0 0 auto;\n width: 36px;\n height: 36px;\n padding: 0;\n border: none;\n border-radius: var(--tempest-radius-full);\n background: transparent;\n color: inherit;\n cursor: pointer;\n}\n\n.iconBtn:hover {\n background: var(--tempest-surface-2);\n}\n\n.iconBtn:focus-visible {\n outline: var(--tempest-focus-ring-width) solid var(--tempest-focus-ring-color);\n outline-offset: var(--tempest-focus-ring-offset);\n}\n"],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AppBar.module.js","names":[],"sources":["../../../src/components/AppBar/AppBar.module.css"],"sourcesContent":[".bar {\n display: grid;\n grid-template-columns: auto 1fr auto;\n align-items: center;\n gap: var(--tempest-space-2);\n width: 100%;\n min-height: 56px;\n padding: var(--tempest-space-3) var(--tempest-space-4);\n font-family: var(--tempest-font-sans);\n}\n\n/* Symmetric side columns so the title is truly centered. */\n.bar.centered {\n grid-template-columns: 1fr auto 1fr;\n}\n\n.bar.surface {\n background: var(--tempest-surface);\n color: var(--tempest-text);\n}\n\n.bar.primary {\n background: var(--tempest-primary);\n color: var(--tempest-
|
|
1
|
+
{"version":3,"file":"AppBar.module.js","names":[],"sources":["../../../src/components/AppBar/AppBar.module.css"],"sourcesContent":[".bar {\n display: grid;\n grid-template-columns: auto 1fr auto;\n align-items: center;\n gap: var(--tempest-space-2);\n width: 100%;\n min-height: 56px;\n padding: var(--tempest-space-3) var(--tempest-space-4);\n font-family: var(--tempest-font-sans);\n}\n\n/* Symmetric side columns so the title is truly centered. */\n.bar.centered {\n grid-template-columns: 1fr auto 1fr;\n}\n\n.bar.surface {\n background: var(--tempest-surface);\n color: var(--tempest-text);\n}\n\n.bar.primary {\n background: var(--tempest-primary);\n color: var(--tempest-primary-foreground);\n}\n\n.bar.transparent {\n background: transparent;\n color: inherit;\n}\n\n.bar.bordered {\n border-bottom: 1px solid var(--tempest-border);\n}\n\n.bar.sticky {\n position: sticky;\n top: 0;\n z-index: 30;\n}\n\n.bar.safeArea {\n padding-top: max(var(--tempest-space-3), env(safe-area-inset-top, 0px));\n}\n\n.leading {\n display: flex;\n align-items: center;\n gap: var(--tempest-space-2);\n min-width: 0;\n}\n\n.actions {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: var(--tempest-space-1);\n min-width: 0;\n}\n\n.title {\n margin: 0;\n min-width: 0;\n font-size: var(--tempest-text-xl);\n font-weight: var(--tempest-weight-bold);\n line-height: 1.2;\n text-align: left;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.bar.centered .title {\n text-align: center;\n}\n\n.brand {\n font-size: var(--tempest-text-lg);\n font-weight: var(--tempest-weight-bold);\n color: inherit;\n white-space: nowrap;\n}\n\n.iconBtn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: 0 0 auto;\n width: 36px;\n height: 36px;\n padding: 0;\n border: none;\n border-radius: var(--tempest-radius-full);\n background: transparent;\n color: inherit;\n cursor: pointer;\n}\n\n.iconBtn:hover {\n background: var(--tempest-surface-2);\n}\n\n.iconBtn:focus-visible {\n outline: var(--tempest-focus-ring-width) solid var(--tempest-focus-ring-color);\n outline-offset: var(--tempest-focus-ring-offset);\n}\n"],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Scheduler.module.cjs","names":[],"sources":["../../../src/components/Scheduler/Scheduler.module.css"],"sourcesContent":[".wrapper {\n /*\n * Column widths are declared once here and reused by the header, the all-day\n * lane and the grid — three separate grids that have to line up exactly, and\n * would drift the moment any of them computed its own tracks.\n */\n --tempest-scheduler-gutter: 3.5rem;\n --tempest-scheduler-height: 32rem;\n\n display: flex;\n flex-direction: column;\n width: 100%;\n border: 1px solid var(--tempest-border);\n border-radius: var(--tempest-radius-lg);\n background-color: var(--tempest-bg);\n font-family: var(--tempest-font-sans);\n overflow: hidden;\n}\n\n.head,\n.allDayLane {\n display: grid;\n grid-template-columns: var(--tempest-scheduler-gutter) repeat(\n var(--tempest-scheduler-days),\n minmax(0, 1fr)\n );\n border-bottom: 1px solid var(--tempest-border);\n background-color: var(--tempest-surface);\n}\n\n.dayHead {\n padding: var(--tempest-space-2);\n text-align: center;\n color: var(--tempest-text-muted);\n font-size: var(--tempest-text-xs);\n font-weight: var(--tempest-weight-semibold);\n letter-spacing: var(--tempest-tracking-wide);\n text-transform: capitalize;\n border-left: 1px solid var(--tempest-border);\n}\n\n.dayHead.today {\n color: var(--tempest-primary);\n}\n\n.gutterHead {\n padding: var(--tempest-space-2);\n color: var(--tempest-text-muted);\n font-size: 0.625rem;\n text-align: right;\n}\n\n.allDayTrack {\n display: grid;\n grid-template-columns: repeat(var(--tempest-scheduler-days), minmax(0, 1fr));\n grid-column: 2 / -1;\n gap: 2px;\n padding: 2px;\n}\n\n.allDayEvent {\n overflow: hidden;\n padding: 0 var(--tempest-space-2);\n border: none;\n border-radius: var(--tempest-radius-sm);\n background-color: var(--tempest-primary);\n color: var(--tempest-primary-
|
|
1
|
+
{"version":3,"file":"Scheduler.module.cjs","names":[],"sources":["../../../src/components/Scheduler/Scheduler.module.css"],"sourcesContent":[".wrapper {\n /*\n * Column widths are declared once here and reused by the header, the all-day\n * lane and the grid — three separate grids that have to line up exactly, and\n * would drift the moment any of them computed its own tracks.\n */\n --tempest-scheduler-gutter: 3.5rem;\n --tempest-scheduler-height: 32rem;\n\n display: flex;\n flex-direction: column;\n width: 100%;\n border: 1px solid var(--tempest-border);\n border-radius: var(--tempest-radius-lg);\n background-color: var(--tempest-bg);\n font-family: var(--tempest-font-sans);\n overflow: hidden;\n}\n\n.head,\n.allDayLane {\n display: grid;\n grid-template-columns: var(--tempest-scheduler-gutter) repeat(\n var(--tempest-scheduler-days),\n minmax(0, 1fr)\n );\n border-bottom: 1px solid var(--tempest-border);\n background-color: var(--tempest-surface);\n}\n\n.dayHead {\n padding: var(--tempest-space-2);\n text-align: center;\n color: var(--tempest-text-muted);\n font-size: var(--tempest-text-xs);\n font-weight: var(--tempest-weight-semibold);\n letter-spacing: var(--tempest-tracking-wide);\n text-transform: capitalize;\n border-left: 1px solid var(--tempest-border);\n}\n\n.dayHead.today {\n color: var(--tempest-primary);\n}\n\n.gutterHead {\n padding: var(--tempest-space-2);\n color: var(--tempest-text-muted);\n font-size: 0.625rem;\n text-align: right;\n}\n\n.allDayTrack {\n display: grid;\n grid-template-columns: repeat(var(--tempest-scheduler-days), minmax(0, 1fr));\n grid-column: 2 / -1;\n gap: 2px;\n padding: 2px;\n}\n\n.allDayEvent {\n overflow: hidden;\n padding: 0 var(--tempest-space-2);\n border: none;\n border-radius: var(--tempest-radius-sm);\n background-color: var(--tempest-primary);\n color: var(--tempest-primary-foreground);\n font: inherit;\n font-size: var(--tempest-text-xs);\n line-height: 1.5rem;\n text-align: left;\n text-overflow: ellipsis;\n white-space: nowrap;\n cursor: pointer;\n}\n\n.allDayEvent:disabled {\n cursor: default;\n}\n\n.body {\n display: grid;\n grid-template-columns: var(--tempest-scheduler-gutter) 1fr;\n height: var(--tempest-scheduler-height);\n overflow-y: auto;\n}\n\n.gutter {\n position: relative;\n border-right: 1px solid var(--tempest-border);\n}\n\n.hourLabel {\n position: absolute;\n right: var(--tempest-space-1);\n /*\n * Nudged up by half a line so the label reads as sitting *on* its hour line\n * rather than hanging below it.\n */\n transform: translateY(-50%);\n color: var(--tempest-text-muted);\n font-size: 0.625rem;\n font-variant-numeric: tabular-nums;\n}\n\n.grid {\n position: relative;\n display: grid;\n grid-template-columns: repeat(var(--tempest-scheduler-days), minmax(0, 1fr));\n}\n\n.dayColumn {\n position: relative;\n grid-row: 1;\n border-left: 1px solid var(--tempest-border);\n}\n\n.dayColumn:first-child {\n border-left: none;\n}\n\n.todayColumn {\n background-color: var(--tempest-surface);\n}\n\n.hourLine {\n position: absolute;\n left: 0;\n right: 0;\n border-top: 1px solid var(--tempest-border);\n pointer-events: none;\n}\n\n/*\n * Events live in the same grid as the day columns, one row deep, positioned inside\n * their column by percentage. Being siblings of the columns rather than children is\n * what lets an event overlay the hour lines without clipping.\n */\n/*\n * Absolutely positioned, so the inline `grid-column` it is placed with must name\n * BOTH lines. For an abspos child of a grid container an `auto` side does not\n * mean \"span 1\" — CSS Grid §9.2 resolves it to the container's padding edge, so\n * a bare `grid-column: 3` runs from column 3 to the end of the week and every\n * event covers the whole view. A one-day scheduler hides it: there, \"column 1 to\n * the edge\" happens to be one column. Hence `N / span 1` in Scheduler.tsx.\n */\n.event {\n position: absolute;\n grid-row: 1;\n display: flex;\n flex-direction: column;\n gap: 1px;\n overflow: hidden;\n padding: 2px var(--tempest-space-1);\n border: 1px solid var(--tempest-bg);\n border-radius: var(--tempest-radius-sm);\n background-color: var(--tempest-primary);\n color: var(--tempest-primary-foreground);\n font: inherit;\n text-align: left;\n cursor: pointer;\n}\n\n.event:disabled {\n cursor: default;\n}\n\n.event:focus-visible {\n outline: 2px solid var(--tempest-text);\n outline-offset: -2px;\n}\n\n/*\n * No `opacity` here, deliberately. Dimming the time to signal it as secondary drops\n * it below the AA contrast threshold against the event fill — the browser `axe` sweep\n * caught exactly that (jsdom cannot, since it does not paint). The hierarchy comes\n * from size and weight instead, which cost nothing in contrast.\n */\n.eventTime {\n font-size: 0.625rem;\n font-variant-numeric: tabular-nums;\n}\n\n.eventTitle {\n font-size: var(--tempest-text-xs);\n font-weight: var(--tempest-weight-medium);\n line-height: var(--tempest-leading-snug);\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.nowLine {\n position: absolute;\n left: 0;\n right: 0;\n grid-row: 1;\n grid-column: 1 / -1;\n height: 0;\n border-top: 2px solid var(--tempest-danger, #dc2626);\n pointer-events: none;\n z-index: 1;\n}\n\n@media (max-width: 640px) {\n .wrapper {\n --tempest-scheduler-gutter: 2.75rem;\n }\n\n .dayHead {\n font-size: 0.625rem;\n padding: var(--tempest-space-1);\n }\n}\n"],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Scheduler.module.js","names":[],"sources":["../../../src/components/Scheduler/Scheduler.module.css"],"sourcesContent":[".wrapper {\n /*\n * Column widths are declared once here and reused by the header, the all-day\n * lane and the grid — three separate grids that have to line up exactly, and\n * would drift the moment any of them computed its own tracks.\n */\n --tempest-scheduler-gutter: 3.5rem;\n --tempest-scheduler-height: 32rem;\n\n display: flex;\n flex-direction: column;\n width: 100%;\n border: 1px solid var(--tempest-border);\n border-radius: var(--tempest-radius-lg);\n background-color: var(--tempest-bg);\n font-family: var(--tempest-font-sans);\n overflow: hidden;\n}\n\n.head,\n.allDayLane {\n display: grid;\n grid-template-columns: var(--tempest-scheduler-gutter) repeat(\n var(--tempest-scheduler-days),\n minmax(0, 1fr)\n );\n border-bottom: 1px solid var(--tempest-border);\n background-color: var(--tempest-surface);\n}\n\n.dayHead {\n padding: var(--tempest-space-2);\n text-align: center;\n color: var(--tempest-text-muted);\n font-size: var(--tempest-text-xs);\n font-weight: var(--tempest-weight-semibold);\n letter-spacing: var(--tempest-tracking-wide);\n text-transform: capitalize;\n border-left: 1px solid var(--tempest-border);\n}\n\n.dayHead.today {\n color: var(--tempest-primary);\n}\n\n.gutterHead {\n padding: var(--tempest-space-2);\n color: var(--tempest-text-muted);\n font-size: 0.625rem;\n text-align: right;\n}\n\n.allDayTrack {\n display: grid;\n grid-template-columns: repeat(var(--tempest-scheduler-days), minmax(0, 1fr));\n grid-column: 2 / -1;\n gap: 2px;\n padding: 2px;\n}\n\n.allDayEvent {\n overflow: hidden;\n padding: 0 var(--tempest-space-2);\n border: none;\n border-radius: var(--tempest-radius-sm);\n background-color: var(--tempest-primary);\n color: var(--tempest-primary-
|
|
1
|
+
{"version":3,"file":"Scheduler.module.js","names":[],"sources":["../../../src/components/Scheduler/Scheduler.module.css"],"sourcesContent":[".wrapper {\n /*\n * Column widths are declared once here and reused by the header, the all-day\n * lane and the grid — three separate grids that have to line up exactly, and\n * would drift the moment any of them computed its own tracks.\n */\n --tempest-scheduler-gutter: 3.5rem;\n --tempest-scheduler-height: 32rem;\n\n display: flex;\n flex-direction: column;\n width: 100%;\n border: 1px solid var(--tempest-border);\n border-radius: var(--tempest-radius-lg);\n background-color: var(--tempest-bg);\n font-family: var(--tempest-font-sans);\n overflow: hidden;\n}\n\n.head,\n.allDayLane {\n display: grid;\n grid-template-columns: var(--tempest-scheduler-gutter) repeat(\n var(--tempest-scheduler-days),\n minmax(0, 1fr)\n );\n border-bottom: 1px solid var(--tempest-border);\n background-color: var(--tempest-surface);\n}\n\n.dayHead {\n padding: var(--tempest-space-2);\n text-align: center;\n color: var(--tempest-text-muted);\n font-size: var(--tempest-text-xs);\n font-weight: var(--tempest-weight-semibold);\n letter-spacing: var(--tempest-tracking-wide);\n text-transform: capitalize;\n border-left: 1px solid var(--tempest-border);\n}\n\n.dayHead.today {\n color: var(--tempest-primary);\n}\n\n.gutterHead {\n padding: var(--tempest-space-2);\n color: var(--tempest-text-muted);\n font-size: 0.625rem;\n text-align: right;\n}\n\n.allDayTrack {\n display: grid;\n grid-template-columns: repeat(var(--tempest-scheduler-days), minmax(0, 1fr));\n grid-column: 2 / -1;\n gap: 2px;\n padding: 2px;\n}\n\n.allDayEvent {\n overflow: hidden;\n padding: 0 var(--tempest-space-2);\n border: none;\n border-radius: var(--tempest-radius-sm);\n background-color: var(--tempest-primary);\n color: var(--tempest-primary-foreground);\n font: inherit;\n font-size: var(--tempest-text-xs);\n line-height: 1.5rem;\n text-align: left;\n text-overflow: ellipsis;\n white-space: nowrap;\n cursor: pointer;\n}\n\n.allDayEvent:disabled {\n cursor: default;\n}\n\n.body {\n display: grid;\n grid-template-columns: var(--tempest-scheduler-gutter) 1fr;\n height: var(--tempest-scheduler-height);\n overflow-y: auto;\n}\n\n.gutter {\n position: relative;\n border-right: 1px solid var(--tempest-border);\n}\n\n.hourLabel {\n position: absolute;\n right: var(--tempest-space-1);\n /*\n * Nudged up by half a line so the label reads as sitting *on* its hour line\n * rather than hanging below it.\n */\n transform: translateY(-50%);\n color: var(--tempest-text-muted);\n font-size: 0.625rem;\n font-variant-numeric: tabular-nums;\n}\n\n.grid {\n position: relative;\n display: grid;\n grid-template-columns: repeat(var(--tempest-scheduler-days), minmax(0, 1fr));\n}\n\n.dayColumn {\n position: relative;\n grid-row: 1;\n border-left: 1px solid var(--tempest-border);\n}\n\n.dayColumn:first-child {\n border-left: none;\n}\n\n.todayColumn {\n background-color: var(--tempest-surface);\n}\n\n.hourLine {\n position: absolute;\n left: 0;\n right: 0;\n border-top: 1px solid var(--tempest-border);\n pointer-events: none;\n}\n\n/*\n * Events live in the same grid as the day columns, one row deep, positioned inside\n * their column by percentage. Being siblings of the columns rather than children is\n * what lets an event overlay the hour lines without clipping.\n */\n/*\n * Absolutely positioned, so the inline `grid-column` it is placed with must name\n * BOTH lines. For an abspos child of a grid container an `auto` side does not\n * mean \"span 1\" — CSS Grid §9.2 resolves it to the container's padding edge, so\n * a bare `grid-column: 3` runs from column 3 to the end of the week and every\n * event covers the whole view. A one-day scheduler hides it: there, \"column 1 to\n * the edge\" happens to be one column. Hence `N / span 1` in Scheduler.tsx.\n */\n.event {\n position: absolute;\n grid-row: 1;\n display: flex;\n flex-direction: column;\n gap: 1px;\n overflow: hidden;\n padding: 2px var(--tempest-space-1);\n border: 1px solid var(--tempest-bg);\n border-radius: var(--tempest-radius-sm);\n background-color: var(--tempest-primary);\n color: var(--tempest-primary-foreground);\n font: inherit;\n text-align: left;\n cursor: pointer;\n}\n\n.event:disabled {\n cursor: default;\n}\n\n.event:focus-visible {\n outline: 2px solid var(--tempest-text);\n outline-offset: -2px;\n}\n\n/*\n * No `opacity` here, deliberately. Dimming the time to signal it as secondary drops\n * it below the AA contrast threshold against the event fill — the browser `axe` sweep\n * caught exactly that (jsdom cannot, since it does not paint). The hierarchy comes\n * from size and weight instead, which cost nothing in contrast.\n */\n.eventTime {\n font-size: 0.625rem;\n font-variant-numeric: tabular-nums;\n}\n\n.eventTitle {\n font-size: var(--tempest-text-xs);\n font-weight: var(--tempest-weight-medium);\n line-height: var(--tempest-leading-snug);\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.nowLine {\n position: absolute;\n left: 0;\n right: 0;\n grid-row: 1;\n grid-column: 1 / -1;\n height: 0;\n border-top: 2px solid var(--tempest-danger, #dc2626);\n pointer-events: none;\n z-index: 1;\n}\n\n@media (max-width: 640px) {\n .wrapper {\n --tempest-scheduler-gutter: 2.75rem;\n }\n\n .dayHead {\n font-size: 0.625rem;\n padding: var(--tempest-space-1);\n }\n}\n"],"mappings":""}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
let e=require("react");var t=[{code:`Space`,label:`Espaço`},{code:`ControlLeft`,label:`Ctrl esquerdo`},{code:`AltLeft`,label:`Alt esquerdo`},{code:`ShiftLeft`,label:`Shift esquerdo`},{code:`Backquote`,label:"Crase (`)"}],n=`Space`;function r(e){return t.find(t=>t.code===e)?.label??e}function i(e){if(!(e instanceof HTMLElement))return!1;if(e.isContentEditable)return!0;let t=e.tagName;return t===`INPUT`||t===`TEXTAREA`||t===`SELECT`}function a({code:t=n,onDown:r,onUp:a,enabled:o=!0}){let s=(0,e.useRef)({onDown:r,onUp:a});(0,e.useEffect)(()=>{s.current={onDown:r,onUp:a}}),(0,e.useEffect)(()=>{if(!o||typeof window>`u`)return;let e=!1,n=()=>{e&&(e=!1,s.current.onUp())},r=n=>{n.code!==t||n.repeat||i(n.target)||(n.preventDefault(),!e&&(e=!0,s.current.onDown()))},a=
|
|
1
|
+
let e=require("react");var t=[{code:`Space`,label:`Espaço`},{code:`ControlLeft`,label:`Ctrl esquerdo`},{code:`AltLeft`,label:`Alt esquerdo`},{code:`ShiftLeft`,label:`Shift esquerdo`},{code:`Backquote`,label:"Crase (`)"}],n=`Space`;function r(e){return t.find(t=>t.code===e)?.label??e}function i(e){if(!(e instanceof HTMLElement))return!1;if(e.isContentEditable)return!0;let t=e.tagName;return t===`INPUT`||t===`TEXTAREA`||t===`SELECT`}function a({code:t=n,onDown:r,onUp:a,enabled:o=!0}){let s=(0,e.useRef)({onDown:r,onUp:a});(0,e.useEffect)(()=>{s.current={onDown:r,onUp:a}}),(0,e.useEffect)(()=>{if(!o||typeof window>`u`)return;let e=!1,n=()=>{e&&(e=!1,s.current.onUp())},r=n=>{n.code!==t||n.repeat||i(n.target)||(n.preventDefault(),!e&&(e=!0,s.current.onDown()))},a=r=>{r.code!==t||!e||(r.preventDefault(),n())};return window.addEventListener(`keydown`,r),window.addEventListener(`keyup`,a),window.addEventListener(`blur`,n),()=>{window.removeEventListener(`keydown`,r),window.removeEventListener(`keyup`,a),window.removeEventListener(`blur`,n),n()}},[t,o])}exports.DEFAULT_PUSH_TO_TALK_KEY=n,exports.PUSH_TO_TALK_KEYS=t,exports.pushToTalkKeyLabel=r,exports.usePushToTalk=a;
|
|
2
2
|
//# sourceMappingURL=use-push-to-talk.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-push-to-talk.cjs","names":[],"sources":["../../src/hooks/use-push-to-talk.ts"],"sourcesContent":["import { useEffect, useRef } from \"react\";\n\n/** A key offered for push-to-talk, with the label a settings screen shows. */\nexport interface PushToTalkKey {\n /** `KeyboardEvent.code`, which is layout-independent. */\n code: string;\n /** What to show a person. `code` itself is not a label. */\n label: string;\n}\n\n/**\n * The keys worth offering for push-to-talk.\n *\n * Identified by `code` rather than `key` so a binding survives a layout change:\n * on an ABNT2 keyboard the `key` reported for the backquote position is not what\n * a US layout reports, while `Backquote` is the same physical key everywhere.\n *\n * Left-hand modifiers only. The right-hand ones sit under the hand that is\n * usually on the mouse, and a modifier that is also a shortcut prefix\n * (`ControlLeft` with a browser shortcut) is a deliberate trade the caller makes\n * by choosing it.\n */\nexport const PUSH_TO_TALK_KEYS: readonly PushToTalkKey[] = [\n { code: \"Space\", label: \"Espaço\" },\n { code: \"ControlLeft\", label: \"Ctrl esquerdo\" },\n { code: \"AltLeft\", label: \"Alt esquerdo\" },\n { code: \"ShiftLeft\", label: \"Shift esquerdo\" },\n { code: \"Backquote\", label: \"Crase (`)\" },\n];\n\n/** The key a caller gets when it does not choose one. */\nexport const DEFAULT_PUSH_TO_TALK_KEY = \"Space\";\n\n/**\n * The label to show for a `KeyboardEvent.code`.\n *\n * @param code - The bound key's code.\n * @returns Its label, or the code itself for a key this list does not name —\n * showing `\"F13\"` beats showing nothing.\n */\nexport function pushToTalkKeyLabel(code: string): string {\n return PUSH_TO_TALK_KEYS.find((key) => key.code === code)?.label ?? code;\n}\n\n/**\n * Whether a keystroke is meant for something the person is typing into.\n *\n * Without this a push-to-talk key bound to Space opens the microphone every time\n * somebody writes a message — and the space never reaches the text field,\n * because the handler preventDefault'd it.\n *\n * @param target - The event's target.\n * @returns `true` when the keystroke belongs to a field, not to the app.\n */\nfunction isTypingTarget(target: EventTarget | null): boolean {\n if (!(target instanceof HTMLElement)) return false;\n if (target.isContentEditable) return true;\n const tag = target.tagName;\n return tag === \"INPUT\" || tag === \"TEXTAREA\" || tag === \"SELECT\";\n}\n\n/** Options for {@link usePushToTalk}. */\nexport interface UsePushToTalkOptions {\n /** `KeyboardEvent.code` to hold. Default {@link DEFAULT_PUSH_TO_TALK_KEY}. */\n code?: string;\n /** Called once when the key goes down. */\n onDown: () => void;\n /** Called when the key comes up, the window blurs, or the hook unmounts. */\n onUp: () => void;\n /**\n * Whether the binding is live. Default `true`.\n *\n * Turning it off releases first, so flipping a call from push-to-talk to an\n * open microphone while the key is held does not leave `onUp` unfired.\n */\n enabled?: boolean;\n}\n\n/**\n * Hold a key to transmit; release it to go silent again.\n *\n * Looks like `keydown`/`keyup` and is not, because three things go wrong:\n *\n * 1. **`blur` has to release.** Alt-tabbing away while holding the key means the\n * browser never sees the `keyup`, and the microphone stays open for as long as\n * the person is looking at another window — exactly what push-to-talk exists\n * to prevent.\n * 2. **Auto-repeat has to be ignored.** A held key repeats at the keyboard's rate,\n * and without the `repeat` check `onDown` fires on every one of them.\n * 3. **A text field has to win.** Space bound to push-to-talk with the focus in an\n * `<input>` means the space never reaches the message being written.\n *\n * Unmounting releases too, for the same reason `blur` does: the callback that\n * stops transmitting has to run even when the component holding it goes away\n * mid-press.\n *\n * The callbacks are read through a ref that a commit-time effect refreshes, so\n * passing inline arrows neither tears the listeners down on every render nor\n * writes to the ref during one — a render React discards would leave the ref\n * pointing at callbacks that never became the UI.\n *\n * @param options - See {@link UsePushToTalkOptions}.\n *\n * @example\n * usePushToTalk({\n * code: \"Space\",\n * onDown: () => setMicEnabled(true),\n * onUp: () => setMicEnabled(false),\n * });\n */\nexport function usePushToTalk({\n code = DEFAULT_PUSH_TO_TALK_KEY,\n onDown,\n onUp,\n enabled = true,\n}: UsePushToTalkOptions): void {\n const callbacks = useRef({ onDown, onUp });\n useEffect(() => {\n callbacks.current = { onDown, onUp };\n });\n\n useEffect(() => {\n if (!enabled || typeof window === \"undefined\") return;\n let held = false;\n\n const release = (): void => {\n if (!held) return;\n held = false;\n callbacks.current.onUp();\n };\n\n const handleKeyDown = (event: KeyboardEvent): void => {\n if (event.code !== code || event.repeat) return;\n if (isTypingTarget(event.target)) return;\n event.preventDefault();\n if (held) return;\n held = true;\n callbacks.current.onDown();\n };\n\n const handleKeyUp = (event: KeyboardEvent): void => {\n if (event.code !== code
|
|
1
|
+
{"version":3,"file":"use-push-to-talk.cjs","names":[],"sources":["../../src/hooks/use-push-to-talk.ts"],"sourcesContent":["import { useEffect, useRef } from \"react\";\n\n/** A key offered for push-to-talk, with the label a settings screen shows. */\nexport interface PushToTalkKey {\n /** `KeyboardEvent.code`, which is layout-independent. */\n code: string;\n /** What to show a person. `code` itself is not a label. */\n label: string;\n}\n\n/**\n * The keys worth offering for push-to-talk.\n *\n * Identified by `code` rather than `key` so a binding survives a layout change:\n * on an ABNT2 keyboard the `key` reported for the backquote position is not what\n * a US layout reports, while `Backquote` is the same physical key everywhere.\n *\n * Left-hand modifiers only. The right-hand ones sit under the hand that is\n * usually on the mouse, and a modifier that is also a shortcut prefix\n * (`ControlLeft` with a browser shortcut) is a deliberate trade the caller makes\n * by choosing it.\n */\nexport const PUSH_TO_TALK_KEYS: readonly PushToTalkKey[] = [\n { code: \"Space\", label: \"Espaço\" },\n { code: \"ControlLeft\", label: \"Ctrl esquerdo\" },\n { code: \"AltLeft\", label: \"Alt esquerdo\" },\n { code: \"ShiftLeft\", label: \"Shift esquerdo\" },\n { code: \"Backquote\", label: \"Crase (`)\" },\n];\n\n/** The key a caller gets when it does not choose one. */\nexport const DEFAULT_PUSH_TO_TALK_KEY = \"Space\";\n\n/**\n * The label to show for a `KeyboardEvent.code`.\n *\n * @param code - The bound key's code.\n * @returns Its label, or the code itself for a key this list does not name —\n * showing `\"F13\"` beats showing nothing.\n */\nexport function pushToTalkKeyLabel(code: string): string {\n return PUSH_TO_TALK_KEYS.find((key) => key.code === code)?.label ?? code;\n}\n\n/**\n * Whether a keystroke is meant for something the person is typing into.\n *\n * Without this a push-to-talk key bound to Space opens the microphone every time\n * somebody writes a message — and the space never reaches the text field,\n * because the handler preventDefault'd it.\n *\n * @param target - The event's target.\n * @returns `true` when the keystroke belongs to a field, not to the app.\n */\nfunction isTypingTarget(target: EventTarget | null): boolean {\n if (!(target instanceof HTMLElement)) return false;\n if (target.isContentEditable) return true;\n const tag = target.tagName;\n return tag === \"INPUT\" || tag === \"TEXTAREA\" || tag === \"SELECT\";\n}\n\n/** Options for {@link usePushToTalk}. */\nexport interface UsePushToTalkOptions {\n /** `KeyboardEvent.code` to hold. Default {@link DEFAULT_PUSH_TO_TALK_KEY}. */\n code?: string;\n /** Called once when the key goes down. */\n onDown: () => void;\n /** Called when the key comes up, the window blurs, or the hook unmounts. */\n onUp: () => void;\n /**\n * Whether the binding is live. Default `true`.\n *\n * Turning it off releases first, so flipping a call from push-to-talk to an\n * open microphone while the key is held does not leave `onUp` unfired.\n */\n enabled?: boolean;\n}\n\n/**\n * Hold a key to transmit; release it to go silent again.\n *\n * Looks like `keydown`/`keyup` and is not, because three things go wrong:\n *\n * 1. **`blur` has to release.** Alt-tabbing away while holding the key means the\n * browser never sees the `keyup`, and the microphone stays open for as long as\n * the person is looking at another window — exactly what push-to-talk exists\n * to prevent.\n * 2. **Auto-repeat has to be ignored.** A held key repeats at the keyboard's rate,\n * and without the `repeat` check `onDown` fires on every one of them.\n * 3. **A text field has to win.** Space bound to push-to-talk with the focus in an\n * `<input>` means the space never reaches the message being written.\n *\n * Unmounting releases too, for the same reason `blur` does: the callback that\n * stops transmitting has to run even when the component holding it goes away\n * mid-press.\n *\n * The callbacks are read through a ref that a commit-time effect refreshes, so\n * passing inline arrows neither tears the listeners down on every render nor\n * writes to the ref during one — a render React discards would leave the ref\n * pointing at callbacks that never became the UI.\n *\n * @param options - See {@link UsePushToTalkOptions}.\n *\n * @example\n * usePushToTalk({\n * code: \"Space\",\n * onDown: () => setMicEnabled(true),\n * onUp: () => setMicEnabled(false),\n * });\n */\nexport function usePushToTalk({\n code = DEFAULT_PUSH_TO_TALK_KEY,\n onDown,\n onUp,\n enabled = true,\n}: UsePushToTalkOptions): void {\n const callbacks = useRef({ onDown, onUp });\n useEffect(() => {\n callbacks.current = { onDown, onUp };\n });\n\n useEffect(() => {\n if (!enabled || typeof window === \"undefined\") return;\n let held = false;\n\n const release = (): void => {\n if (!held) return;\n held = false;\n callbacks.current.onUp();\n };\n\n const handleKeyDown = (event: KeyboardEvent): void => {\n if (event.code !== code || event.repeat) return;\n if (isTypingTarget(event.target)) return;\n event.preventDefault();\n if (held) return;\n held = true;\n callbacks.current.onDown();\n };\n\n /**\n * Release on the way up, and never mind where the keystroke landed.\n *\n * The field guard belongs on the way **down** — it is what stops a\n * push-to-talk bound to Space from opening the microphone every time\n * somebody writes a message. On the way up it did the opposite of its\n * job: `keyup` is delivered to whatever is focused when the key rises,\n * not to what was focused when it fell, so clicking into an input while\n * still holding sent the release into the guard and left `held` true.\n * The microphone stayed open until the window blurred.\n *\n * `held` is the guard this needs. If we never opened the microphone\n * there is nothing to close, and `release()` already returns on that —\n * so the only thing left to decide is `preventDefault`, which is\n * honest only for a keystroke we actually acted on.\n */\n const handleKeyUp = (event: KeyboardEvent): void => {\n if (event.code !== code || !held) return;\n event.preventDefault();\n release();\n };\n\n window.addEventListener(\"keydown\", handleKeyDown);\n window.addEventListener(\"keyup\", handleKeyUp);\n window.addEventListener(\"blur\", release);\n\n return () => {\n window.removeEventListener(\"keydown\", handleKeyDown);\n window.removeEventListener(\"keyup\", handleKeyUp);\n window.removeEventListener(\"blur\", release);\n release();\n };\n }, [code, enabled]);\n}\n"],"mappings":"uBAsBA,IAAa,EAA8C,CACvD,CAAE,KAAM,QAAS,MAAO,QAAS,EACjC,CAAE,KAAM,cAAe,MAAO,eAAgB,EAC9C,CAAE,KAAM,UAAW,MAAO,cAAe,EACzC,CAAE,KAAM,YAAa,MAAO,gBAAiB,EAC7C,CAAE,KAAM,YAAa,MAAO,WAAY,CAC5C,EAGa,EAA2B,QASxC,SAAgB,EAAmB,EAAsB,CACrD,OAAO,EAAkB,KAAM,GAAQ,EAAI,OAAS,CAAI,CAAC,EAAE,OAAS,CACxE,CAYA,SAAS,EAAe,EAAqC,CACzD,GAAI,EAAE,aAAkB,aAAc,MAAO,GAC7C,GAAI,EAAO,kBAAmB,MAAO,GACrC,IAAM,EAAM,EAAO,QACnB,OAAO,IAAQ,SAAW,IAAQ,YAAc,IAAQ,QAC5D,CAmDA,SAAgB,EAAc,CAC1B,OAAO,EACP,SACA,OACA,UAAU,IACiB,CAC3B,IAAM,GAAA,EAAY,EAAA,OAAA,CAAO,CAAE,SAAQ,MAAK,CAAC,GACzC,EAAA,EAAA,UAAA,KAAgB,CACZ,EAAU,QAAU,CAAE,SAAQ,MAAK,CACvC,CAAC,GAED,EAAA,EAAA,UAAA,KAAgB,CACZ,GAAI,CAAC,GAAW,OAAO,OAAW,IAAa,OAC/C,IAAI,EAAO,GAEL,MAAsB,CACnB,IACL,EAAO,GACP,EAAU,QAAQ,KAAK,EAC3B,EAEM,EAAiB,GAA+B,CAC9C,EAAM,OAAS,GAAQ,EAAM,QAC7B,EAAe,EAAM,MAAM,IAC/B,EAAM,eAAe,EACjB,KACJ,EAAO,GACP,EAAU,QAAQ,OAAO,GAC7B,EAkBM,EAAe,GAA+B,CAC5C,EAAM,OAAS,GAAQ,CAAC,IAC5B,EAAM,eAAe,EACrB,EAAQ,EACZ,EAMA,OAJA,OAAO,iBAAiB,UAAW,CAAa,EAChD,OAAO,iBAAiB,QAAS,CAAW,EAC5C,OAAO,iBAAiB,OAAQ,CAAO,MAE1B,CACT,OAAO,oBAAoB,UAAW,CAAa,EACnD,OAAO,oBAAoB,QAAS,CAAW,EAC/C,OAAO,oBAAoB,OAAQ,CAAO,EAC1C,EAAQ,CACZ,CACJ,EAAG,CAAC,EAAM,CAAO,CAAC,CACtB"}
|
|
@@ -47,8 +47,8 @@ function o({ code: n = r, onDown: i, onUp: o, enabled: s = !0 }) {
|
|
|
47
47
|
e && (e = !1, c.current.onUp());
|
|
48
48
|
}, r = (t) => {
|
|
49
49
|
t.code !== n || t.repeat || a(t.target) || (t.preventDefault(), !e && (e = !0, c.current.onDown()));
|
|
50
|
-
}, i = (
|
|
51
|
-
|
|
50
|
+
}, i = (r) => {
|
|
51
|
+
r.code !== n || !e || (r.preventDefault(), t());
|
|
52
52
|
};
|
|
53
53
|
return window.addEventListener("keydown", r), window.addEventListener("keyup", i), window.addEventListener("blur", t), () => {
|
|
54
54
|
window.removeEventListener("keydown", r), window.removeEventListener("keyup", i), window.removeEventListener("blur", t), t();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-push-to-talk.js","names":[],"sources":["../../src/hooks/use-push-to-talk.ts"],"sourcesContent":["import { useEffect, useRef } from \"react\";\n\n/** A key offered for push-to-talk, with the label a settings screen shows. */\nexport interface PushToTalkKey {\n /** `KeyboardEvent.code`, which is layout-independent. */\n code: string;\n /** What to show a person. `code` itself is not a label. */\n label: string;\n}\n\n/**\n * The keys worth offering for push-to-talk.\n *\n * Identified by `code` rather than `key` so a binding survives a layout change:\n * on an ABNT2 keyboard the `key` reported for the backquote position is not what\n * a US layout reports, while `Backquote` is the same physical key everywhere.\n *\n * Left-hand modifiers only. The right-hand ones sit under the hand that is\n * usually on the mouse, and a modifier that is also a shortcut prefix\n * (`ControlLeft` with a browser shortcut) is a deliberate trade the caller makes\n * by choosing it.\n */\nexport const PUSH_TO_TALK_KEYS: readonly PushToTalkKey[] = [\n { code: \"Space\", label: \"Espaço\" },\n { code: \"ControlLeft\", label: \"Ctrl esquerdo\" },\n { code: \"AltLeft\", label: \"Alt esquerdo\" },\n { code: \"ShiftLeft\", label: \"Shift esquerdo\" },\n { code: \"Backquote\", label: \"Crase (`)\" },\n];\n\n/** The key a caller gets when it does not choose one. */\nexport const DEFAULT_PUSH_TO_TALK_KEY = \"Space\";\n\n/**\n * The label to show for a `KeyboardEvent.code`.\n *\n * @param code - The bound key's code.\n * @returns Its label, or the code itself for a key this list does not name —\n * showing `\"F13\"` beats showing nothing.\n */\nexport function pushToTalkKeyLabel(code: string): string {\n return PUSH_TO_TALK_KEYS.find((key) => key.code === code)?.label ?? code;\n}\n\n/**\n * Whether a keystroke is meant for something the person is typing into.\n *\n * Without this a push-to-talk key bound to Space opens the microphone every time\n * somebody writes a message — and the space never reaches the text field,\n * because the handler preventDefault'd it.\n *\n * @param target - The event's target.\n * @returns `true` when the keystroke belongs to a field, not to the app.\n */\nfunction isTypingTarget(target: EventTarget | null): boolean {\n if (!(target instanceof HTMLElement)) return false;\n if (target.isContentEditable) return true;\n const tag = target.tagName;\n return tag === \"INPUT\" || tag === \"TEXTAREA\" || tag === \"SELECT\";\n}\n\n/** Options for {@link usePushToTalk}. */\nexport interface UsePushToTalkOptions {\n /** `KeyboardEvent.code` to hold. Default {@link DEFAULT_PUSH_TO_TALK_KEY}. */\n code?: string;\n /** Called once when the key goes down. */\n onDown: () => void;\n /** Called when the key comes up, the window blurs, or the hook unmounts. */\n onUp: () => void;\n /**\n * Whether the binding is live. Default `true`.\n *\n * Turning it off releases first, so flipping a call from push-to-talk to an\n * open microphone while the key is held does not leave `onUp` unfired.\n */\n enabled?: boolean;\n}\n\n/**\n * Hold a key to transmit; release it to go silent again.\n *\n * Looks like `keydown`/`keyup` and is not, because three things go wrong:\n *\n * 1. **`blur` has to release.** Alt-tabbing away while holding the key means the\n * browser never sees the `keyup`, and the microphone stays open for as long as\n * the person is looking at another window — exactly what push-to-talk exists\n * to prevent.\n * 2. **Auto-repeat has to be ignored.** A held key repeats at the keyboard's rate,\n * and without the `repeat` check `onDown` fires on every one of them.\n * 3. **A text field has to win.** Space bound to push-to-talk with the focus in an\n * `<input>` means the space never reaches the message being written.\n *\n * Unmounting releases too, for the same reason `blur` does: the callback that\n * stops transmitting has to run even when the component holding it goes away\n * mid-press.\n *\n * The callbacks are read through a ref that a commit-time effect refreshes, so\n * passing inline arrows neither tears the listeners down on every render nor\n * writes to the ref during one — a render React discards would leave the ref\n * pointing at callbacks that never became the UI.\n *\n * @param options - See {@link UsePushToTalkOptions}.\n *\n * @example\n * usePushToTalk({\n * code: \"Space\",\n * onDown: () => setMicEnabled(true),\n * onUp: () => setMicEnabled(false),\n * });\n */\nexport function usePushToTalk({\n code = DEFAULT_PUSH_TO_TALK_KEY,\n onDown,\n onUp,\n enabled = true,\n}: UsePushToTalkOptions): void {\n const callbacks = useRef({ onDown, onUp });\n useEffect(() => {\n callbacks.current = { onDown, onUp };\n });\n\n useEffect(() => {\n if (!enabled || typeof window === \"undefined\") return;\n let held = false;\n\n const release = (): void => {\n if (!held) return;\n held = false;\n callbacks.current.onUp();\n };\n\n const handleKeyDown = (event: KeyboardEvent): void => {\n if (event.code !== code || event.repeat) return;\n if (isTypingTarget(event.target)) return;\n event.preventDefault();\n if (held) return;\n held = true;\n callbacks.current.onDown();\n };\n\n const handleKeyUp = (event: KeyboardEvent): void => {\n if (event.code !== code
|
|
1
|
+
{"version":3,"file":"use-push-to-talk.js","names":[],"sources":["../../src/hooks/use-push-to-talk.ts"],"sourcesContent":["import { useEffect, useRef } from \"react\";\n\n/** A key offered for push-to-talk, with the label a settings screen shows. */\nexport interface PushToTalkKey {\n /** `KeyboardEvent.code`, which is layout-independent. */\n code: string;\n /** What to show a person. `code` itself is not a label. */\n label: string;\n}\n\n/**\n * The keys worth offering for push-to-talk.\n *\n * Identified by `code` rather than `key` so a binding survives a layout change:\n * on an ABNT2 keyboard the `key` reported for the backquote position is not what\n * a US layout reports, while `Backquote` is the same physical key everywhere.\n *\n * Left-hand modifiers only. The right-hand ones sit under the hand that is\n * usually on the mouse, and a modifier that is also a shortcut prefix\n * (`ControlLeft` with a browser shortcut) is a deliberate trade the caller makes\n * by choosing it.\n */\nexport const PUSH_TO_TALK_KEYS: readonly PushToTalkKey[] = [\n { code: \"Space\", label: \"Espaço\" },\n { code: \"ControlLeft\", label: \"Ctrl esquerdo\" },\n { code: \"AltLeft\", label: \"Alt esquerdo\" },\n { code: \"ShiftLeft\", label: \"Shift esquerdo\" },\n { code: \"Backquote\", label: \"Crase (`)\" },\n];\n\n/** The key a caller gets when it does not choose one. */\nexport const DEFAULT_PUSH_TO_TALK_KEY = \"Space\";\n\n/**\n * The label to show for a `KeyboardEvent.code`.\n *\n * @param code - The bound key's code.\n * @returns Its label, or the code itself for a key this list does not name —\n * showing `\"F13\"` beats showing nothing.\n */\nexport function pushToTalkKeyLabel(code: string): string {\n return PUSH_TO_TALK_KEYS.find((key) => key.code === code)?.label ?? code;\n}\n\n/**\n * Whether a keystroke is meant for something the person is typing into.\n *\n * Without this a push-to-talk key bound to Space opens the microphone every time\n * somebody writes a message — and the space never reaches the text field,\n * because the handler preventDefault'd it.\n *\n * @param target - The event's target.\n * @returns `true` when the keystroke belongs to a field, not to the app.\n */\nfunction isTypingTarget(target: EventTarget | null): boolean {\n if (!(target instanceof HTMLElement)) return false;\n if (target.isContentEditable) return true;\n const tag = target.tagName;\n return tag === \"INPUT\" || tag === \"TEXTAREA\" || tag === \"SELECT\";\n}\n\n/** Options for {@link usePushToTalk}. */\nexport interface UsePushToTalkOptions {\n /** `KeyboardEvent.code` to hold. Default {@link DEFAULT_PUSH_TO_TALK_KEY}. */\n code?: string;\n /** Called once when the key goes down. */\n onDown: () => void;\n /** Called when the key comes up, the window blurs, or the hook unmounts. */\n onUp: () => void;\n /**\n * Whether the binding is live. Default `true`.\n *\n * Turning it off releases first, so flipping a call from push-to-talk to an\n * open microphone while the key is held does not leave `onUp` unfired.\n */\n enabled?: boolean;\n}\n\n/**\n * Hold a key to transmit; release it to go silent again.\n *\n * Looks like `keydown`/`keyup` and is not, because three things go wrong:\n *\n * 1. **`blur` has to release.** Alt-tabbing away while holding the key means the\n * browser never sees the `keyup`, and the microphone stays open for as long as\n * the person is looking at another window — exactly what push-to-talk exists\n * to prevent.\n * 2. **Auto-repeat has to be ignored.** A held key repeats at the keyboard's rate,\n * and without the `repeat` check `onDown` fires on every one of them.\n * 3. **A text field has to win.** Space bound to push-to-talk with the focus in an\n * `<input>` means the space never reaches the message being written.\n *\n * Unmounting releases too, for the same reason `blur` does: the callback that\n * stops transmitting has to run even when the component holding it goes away\n * mid-press.\n *\n * The callbacks are read through a ref that a commit-time effect refreshes, so\n * passing inline arrows neither tears the listeners down on every render nor\n * writes to the ref during one — a render React discards would leave the ref\n * pointing at callbacks that never became the UI.\n *\n * @param options - See {@link UsePushToTalkOptions}.\n *\n * @example\n * usePushToTalk({\n * code: \"Space\",\n * onDown: () => setMicEnabled(true),\n * onUp: () => setMicEnabled(false),\n * });\n */\nexport function usePushToTalk({\n code = DEFAULT_PUSH_TO_TALK_KEY,\n onDown,\n onUp,\n enabled = true,\n}: UsePushToTalkOptions): void {\n const callbacks = useRef({ onDown, onUp });\n useEffect(() => {\n callbacks.current = { onDown, onUp };\n });\n\n useEffect(() => {\n if (!enabled || typeof window === \"undefined\") return;\n let held = false;\n\n const release = (): void => {\n if (!held) return;\n held = false;\n callbacks.current.onUp();\n };\n\n const handleKeyDown = (event: KeyboardEvent): void => {\n if (event.code !== code || event.repeat) return;\n if (isTypingTarget(event.target)) return;\n event.preventDefault();\n if (held) return;\n held = true;\n callbacks.current.onDown();\n };\n\n /**\n * Release on the way up, and never mind where the keystroke landed.\n *\n * The field guard belongs on the way **down** — it is what stops a\n * push-to-talk bound to Space from opening the microphone every time\n * somebody writes a message. On the way up it did the opposite of its\n * job: `keyup` is delivered to whatever is focused when the key rises,\n * not to what was focused when it fell, so clicking into an input while\n * still holding sent the release into the guard and left `held` true.\n * The microphone stayed open until the window blurred.\n *\n * `held` is the guard this needs. If we never opened the microphone\n * there is nothing to close, and `release()` already returns on that —\n * so the only thing left to decide is `preventDefault`, which is\n * honest only for a keystroke we actually acted on.\n */\n const handleKeyUp = (event: KeyboardEvent): void => {\n if (event.code !== code || !held) return;\n event.preventDefault();\n release();\n };\n\n window.addEventListener(\"keydown\", handleKeyDown);\n window.addEventListener(\"keyup\", handleKeyUp);\n window.addEventListener(\"blur\", release);\n\n return () => {\n window.removeEventListener(\"keydown\", handleKeyDown);\n window.removeEventListener(\"keyup\", handleKeyUp);\n window.removeEventListener(\"blur\", release);\n release();\n };\n }, [code, enabled]);\n}\n"],"mappings":";;AAsBA,IAAa,IAA8C;CACvD;EAAE,MAAM;EAAS,OAAO;CAAS;CACjC;EAAE,MAAM;EAAe,OAAO;CAAgB;CAC9C;EAAE,MAAM;EAAW,OAAO;CAAe;CACzC;EAAE,MAAM;EAAa,OAAO;CAAiB;CAC7C;EAAE,MAAM;EAAa,OAAO;CAAY;AAC5C,GAGa,IAA2B;AASxC,SAAgB,EAAmB,GAAsB;CACrD,OAAO,EAAkB,MAAM,MAAQ,EAAI,SAAS,CAAI,CAAC,EAAE,SAAS;AACxE;AAYA,SAAS,EAAe,GAAqC;CACzD,IAAI,EAAE,aAAkB,cAAc,OAAO;CAC7C,IAAI,EAAO,mBAAmB,OAAO;CACrC,IAAM,IAAM,EAAO;CACnB,OAAO,MAAQ,WAAW,MAAQ,cAAc,MAAQ;AAC5D;AAmDA,SAAgB,EAAc,EAC1B,UAAO,GACP,WACA,SACA,aAAU,MACiB;CAC3B,IAAM,IAAY,EAAO;EAAE;EAAQ;CAAK,CAAC;CAKzC,AAJA,QAAgB;EACZ,EAAU,UAAU;GAAE;GAAQ;EAAK;CACvC,CAAC,GAED,QAAgB;EACZ,IAAI,CAAC,KAAW,OAAO,SAAW,KAAa;EAC/C,IAAI,IAAO,IAEL,UAAsB;GACnB,MACL,IAAO,IACP,EAAU,QAAQ,KAAK;EAC3B,GAEM,KAAiB,MAA+B;GAC9C,EAAM,SAAS,KAAQ,EAAM,UAC7B,EAAe,EAAM,MAAM,MAC/B,EAAM,eAAe,GACjB,OACJ,IAAO,IACP,EAAU,QAAQ,OAAO;EAC7B,GAkBM,KAAe,MAA+B;GAC5C,EAAM,SAAS,KAAQ,CAAC,MAC5B,EAAM,eAAe,GACrB,EAAQ;EACZ;EAMA,OAJA,OAAO,iBAAiB,WAAW,CAAa,GAChD,OAAO,iBAAiB,SAAS,CAAW,GAC5C,OAAO,iBAAiB,QAAQ,CAAO,SAE1B;GAIT,AAHA,OAAO,oBAAoB,WAAW,CAAa,GACnD,OAAO,oBAAoB,SAAS,CAAW,GAC/C,OAAO,oBAAoB,QAAQ,CAAO,GAC1C,EAAQ;EACZ;CACJ,GAAG,CAAC,GAAM,CAAO,CAAC;AACtB"}
|
package/dist/styles/AppBar.css
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
.tempest_bar_SHqWS{align-items:center;gap:var(--tempest-space-2);width:100%;min-height:56px;padding:var(--tempest-space-3) var(--tempest-space-4);font-family:var(--tempest-font-sans);grid-template-columns:auto 1fr auto;display:grid}
|
|
3
3
|
.tempest_bar_SHqWS.tempest_centered_S0CCw{grid-template-columns:1fr auto 1fr}
|
|
4
4
|
.tempest_bar_SHqWS.tempest_surface_fusKb{background:var(--tempest-surface);color:var(--tempest-text)}
|
|
5
|
-
.tempest_bar_SHqWS.tempest_primary_QcCyN{background:var(--tempest-primary);color:var(--tempest-
|
|
5
|
+
.tempest_bar_SHqWS.tempest_primary_QcCyN{background:var(--tempest-primary);color:var(--tempest-primary-foreground)}
|
|
6
6
|
.tempest_bar_SHqWS.tempest_transparent_uGrsu{color:inherit;background:0 0}
|
|
7
7
|
.tempest_bar_SHqWS.tempest_bordered_5M9FZ{border-bottom:1px solid var(--tempest-border)}
|
|
8
8
|
.tempest_bar_SHqWS.tempest_sticky_DStUO{z-index:30;position:sticky;top:0}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
.tempest_dayHead_qxQ-f.tempest_today_rs9C1{color:var(--tempest-primary)}
|
|
6
6
|
.tempest_gutterHead_eSRW-{padding:var(--tempest-space-2);color:var(--tempest-text-muted);text-align:right;font-size:.625rem}
|
|
7
7
|
.tempest_allDayTrack_aOePR{grid-template-columns:repeat(var(--tempest-scheduler-days), minmax(0, 1fr));grid-column:2/-1;gap:2px;padding:2px;display:grid}
|
|
8
|
-
.tempest_allDayEvent_oESg4{padding:0 var(--tempest-space-2);border-radius:var(--tempest-radius-sm);background-color:var(--tempest-primary);color:var(--tempest-primary-
|
|
8
|
+
.tempest_allDayEvent_oESg4{padding:0 var(--tempest-space-2);border-radius:var(--tempest-radius-sm);background-color:var(--tempest-primary);color:var(--tempest-primary-foreground);font:inherit;font-size:var(--tempest-text-xs);text-align:left;text-overflow:ellipsis;white-space:nowrap;cursor:pointer;border:none;line-height:1.5rem;overflow:hidden}
|
|
9
9
|
.tempest_allDayEvent_oESg4:disabled{cursor:default}
|
|
10
10
|
.tempest_body_GkK47{grid-template-columns:var(--tempest-scheduler-gutter) 1fr;height:var(--tempest-scheduler-height);display:grid;overflow-y:auto}
|
|
11
11
|
.tempest_gutter_BHgLa{border-right:1px solid var(--tempest-border);position:relative}
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
.tempest_dayColumn_r3HZQ:first-child{border-left:none}
|
|
16
16
|
.tempest_todayColumn_NdkQu{background-color:var(--tempest-surface)}
|
|
17
17
|
.tempest_hourLine_Wch54{border-top:1px solid var(--tempest-border);pointer-events:none;position:absolute;left:0;right:0}
|
|
18
|
-
.tempest_event_R6dCw{padding:2px var(--tempest-space-1);border:1px solid var(--tempest-bg);border-radius:var(--tempest-radius-sm);background-color:var(--tempest-primary);color:var(--tempest-primary-
|
|
18
|
+
.tempest_event_R6dCw{padding:2px var(--tempest-space-1);border:1px solid var(--tempest-bg);border-radius:var(--tempest-radius-sm);background-color:var(--tempest-primary);color:var(--tempest-primary-foreground);font:inherit;text-align:left;cursor:pointer;flex-direction:column;grid-row:1;gap:1px;display:flex;position:absolute;overflow:hidden}
|
|
19
19
|
.tempest_event_R6dCw:disabled{cursor:default}
|
|
20
20
|
.tempest_event_R6dCw:focus-visible{outline:2px solid var(--tempest-text);outline-offset:-2px}
|
|
21
21
|
.tempest_eventTime_HsFmy{font-variant-numeric:tabular-nums;font-size:.625rem}
|
package/dist/styles/core.css
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* Generated by scripts/split-css.mjs — do not edit. */
|
|
2
2
|
:root{--tempest-primary-50:#eef4ff;--tempest-primary-100:#d9e6ff;--tempest-primary-200:#b3ccff;--tempest-primary-300:#80aaff;--tempest-primary-400:#4d85ff;--tempest-primary-500:#06f;--tempest-primary-600:#0052cc;--tempest-primary-700:#003d99;--tempest-primary-800:#002e75;--tempest-primary-900:#001f4d;--tempest-primary:var(--tempest-primary-500);--tempest-primary-hover:var(--tempest-primary-600);--tempest-primary-active:var(--tempest-primary-700);--tempest-primary-soft:var(--tempest-primary-50);--tempest-primary-soft-hover:var(--tempest-primary-100);--tempest-primary-foreground:#fff;--tempest-danger-on-solid:#fff;--tempest-info-on-solid:#fff;--tempest-success-on-solid:#1f0606;--tempest-warning-on-solid:#1f0606;--tempest-primary-on-soft:var(--tempest-primary-600);--tempest-gray-50:#f8f9fb;--tempest-gray-100:#f1f3f6;--tempest-gray-200:#e4e7ec;--tempest-gray-300:#d0d5dd;--tempest-gray-400:#98a2b3;--tempest-gray-500:#667085;--tempest-gray-600:#475467;--tempest-gray-700:#344054;--tempest-gray-800:#1d2939;--tempest-gray-900:#101828;--tempest-bg:#fff;--tempest-surface:var(--tempest-gray-50);--tempest-surface-2:var(--tempest-gray-100);--tempest-surface-3:var(--tempest-gray-200);--tempest-border:var(--tempest-gray-200);--tempest-border-strong:var(--tempest-gray-300);--tempest-text:var(--tempest-gray-900);--tempest-text-muted:var(--tempest-gray-600);--tempest-text-subtle:var(--tempest-gray-500);--tempest-text-on-primary:#fff;--tempest-success:#15803d;--tempest-success-fg:#14532d;--tempest-success-bg:#dcfce7;--tempest-success-border:#86efac;--tempest-success-solid:#16a34a;--tempest-warning:#b45309;--tempest-warning-fg:#78350f;--tempest-warning-bg:#fef3c7;--tempest-warning-border:#fcd34d;--tempest-warning-solid:#d97706;--tempest-danger:#b91c1c;--tempest-danger-fg:#7f1d1d;--tempest-danger-bg:#fee2e2;--tempest-danger-border:#fca5a5;--tempest-danger-solid:#dc2626;--tempest-danger-hover:#991b1b;--tempest-info:#1d4ed8;--tempest-info-fg:#1e3a8a;--tempest-info-bg:#dbeafe;--tempest-info-border:#93c5fd;--tempest-info-solid:#2563eb;--tempest-focus-ring-color:#0066ff59;--tempest-focus-ring-width:3px;--tempest-focus-ring-offset:2px;--tempest-radius-xs:2px;--tempest-radius-sm:4px;--tempest-radius-md:8px;--tempest-radius-lg:12px;--tempest-radius-xl:16px;--tempest-radius-2xl:24px;--tempest-radius-full:9999px;--tempest-shadow-xs:0 1px 2px #0f172a0a;--tempest-shadow-sm:0 1px 3px #0f172a14, 0 1px 2px #0f172a0a;--tempest-shadow-md:0 4px 12px #0f172a14, 0 2px 4px #0f172a0a;--tempest-shadow-lg:0 12px 32px #0f172a1f, 0 4px 8px #0f172a0f;--tempest-shadow-xl:0 24px 48px #0f172a2e, 0 8px 16px #0f172a14;--tempest-shadow-inner:inset 0 2px 4px #0f172a0f;--tempest-space-0:0px;--tempest-space-1:4px;--tempest-space-2:8px;--tempest-space-3:12px;--tempest-space-4:16px;--tempest-space-5:20px;--tempest-space-6:24px;--tempest-space-7:28px;--tempest-space-8:32px;--tempest-space-10:40px;--tempest-space-12:48px;--tempest-space-16:64px;--tempest-space-20:80px;--tempest-space-24:96px;--tempest-font-sans:-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Apple Color Emoji", "Segoe UI Emoji", sans-serif;--tempest-font-mono:ui-monospace, SFMono-Regular, "SF Mono", "Cascadia Code", Menlo, Consolas, "Liberation Mono", monospace;--tempest-font-display:var(--tempest-font-sans);--tempest-z-base:0;--tempest-z-raised:10;--tempest-z-dropdown:1000;--tempest-z-sticky:1020;--tempest-z-overlay:1050;--tempest-z-modal:1100;--tempest-z-popover:1150;--tempest-z-toast:1200;--tempest-z-tooltip:1300;--tempest-bp-xs:480px;--tempest-bp-sm:640px;--tempest-bp-md:768px;--tempest-bp-lg:1024px;--tempest-bp-xl:1280px;--tempest-bp-2xl:1536px;--tempest-chart-1:#2563eb;--tempest-chart-2:#16a34a;--tempest-chart-3:#f59e0b;--tempest-chart-4:#7c3aed;--tempest-chart-5:#ec4899;--tempest-chart-6:#06b6d4;--tempest-chart-7:#ea580c;--tempest-chart-8:#0f766e;--tempest-chart-sequential-1:#dde8fe;--tempest-chart-sequential-2:#acc8fe;--tempest-chart-sequential-3:#7aa7ff;--tempest-chart-sequential-4:#4983fc;--tempest-chart-sequential-5:#3667ce;--tempest-chart-sequential-6:#2b4e96;--tempest-chart-sequential-7:#25375a;--tempest-chart-diverging-1:#0f3ca1;--tempest-chart-diverging-2:#416eca;--tempest-chart-diverging-3:#7ba0e7;--tempest-chart-diverging-4:#bdd2f9;--tempest-chart-diverging-5:#e4e7ec;--tempest-chart-diverging-6:#f6c3bc;--tempest-chart-diverging-7:#de847a;--tempest-chart-diverging-8:#ba473f;--tempest-chart-diverging-9:#870f11;--tempest-chart-grid:var(--tempest-gray-200);--tempest-chart-axis:var(--tempest-gray-500);--tempest-code-comment:#5f666e;--tempest-code-punctuation:#5d6671;--tempest-code-string:#327243;--tempest-code-number:#9d5035;--tempest-code-keyword:#625baf;--tempest-code-literal:#9f4c4f;--tempest-code-function:#1a6c94;--tempest-code-tag:#974d72;--tempest-code-attribute:#127171;--tempest-code-property:#127171;--tempest-safe-area-top:env(safe-area-inset-top,0px);--tempest-safe-area-right:env(safe-area-inset-right,0px);--tempest-safe-area-bottom:env(safe-area-inset-bottom,0px);--tempest-safe-area-left:env(safe-area-inset-left,0px)}
|
|
3
|
-
[data-tempest-theme=dark]{--tempest-primary-50:#0a1730;--tempest-primary-100:#0f2245;--tempest-primary-200:#133066;--tempest-primary-300:#1a4399;--tempest-primary-400:#2563eb;--tempest-primary-500:#3b82f6;--tempest-primary-600:#60a5fa;--tempest-primary-700:#93c5fd;--tempest-primary-800:#bfdbfe;--tempest-primary-900:#dbeafe;--tempest-primary:var(--tempest-primary-500);--tempest-primary-hover:var(--tempest-primary-600);--tempest-primary-active:var(--tempest-primary-700);--tempest-primary-soft:var(--tempest-primary-100);--tempest-primary-soft-hover:var(--tempest-primary-200);--tempest-primary-on-soft:var(--tempest-primary-700);--tempest-bg:#0b0d12;--tempest-surface:#14171f;--tempest-surface-2:#1d2230;--tempest-surface-3:#262d3f;--tempest-border:#2a3142;--tempest-border-strong:#3a4258;--tempest-text:#f1f3f8;--tempest-text-muted:#aab2c0;--tempest-text-subtle:#
|
|
3
|
+
[data-tempest-theme=dark]{--tempest-primary-50:#0a1730;--tempest-primary-100:#0f2245;--tempest-primary-200:#133066;--tempest-primary-300:#1a4399;--tempest-primary-400:#2563eb;--tempest-primary-500:#3b82f6;--tempest-primary-600:#60a5fa;--tempest-primary-700:#93c5fd;--tempest-primary-800:#bfdbfe;--tempest-primary-900:#dbeafe;--tempest-primary:var(--tempest-primary-500);--tempest-primary-hover:var(--tempest-primary-600);--tempest-primary-active:var(--tempest-primary-700);--tempest-primary-soft:var(--tempest-primary-100);--tempest-primary-soft-hover:var(--tempest-primary-200);--tempest-primary-on-soft:var(--tempest-primary-700);--tempest-bg:#0b0d12;--tempest-surface:#14171f;--tempest-surface-2:#1d2230;--tempest-surface-3:#262d3f;--tempest-border:#2a3142;--tempest-border-strong:#3a4258;--tempest-text:#f1f3f8;--tempest-text-muted:#aab2c0;--tempest-text-subtle:#7b849a;--tempest-primary-foreground:#1f0606;--tempest-text-on-primary:var(--tempest-primary-foreground);--tempest-danger-on-solid:#1f0606;--tempest-info-on-solid:#1f0606;--tempest-success-on-solid:#1f0606;--tempest-warning-on-solid:#1f0606;--tempest-success-fg:#4ade80;--tempest-success-bg:#052e16;--tempest-success-border:#166534;--tempest-success-solid:#22c55e;--tempest-success:#4ade80;--tempest-warning-fg:#fbbf24;--tempest-warning-bg:#2c1c05;--tempest-warning-border:#78350f;--tempest-warning-solid:#f59e0b;--tempest-warning:#fbbf24;--tempest-danger-fg:#f87171;--tempest-danger-bg:#2c0a0a;--tempest-danger-border:#7f1d1d;--tempest-danger-solid:#ef4444;--tempest-danger:#f87171;--tempest-danger-hover:#f87171;--tempest-info-fg:#60a5fa;--tempest-info-bg:#0a1730;--tempest-info-border:#1e3a8a;--tempest-info-solid:#3b82f6;--tempest-info:#60a5fa;--tempest-focus-ring-color:#60a5fa73;--tempest-shadow-xs:0 1px 2px #0000004d;--tempest-shadow-sm:0 1px 3px #0006, 0 1px 2px #0003;--tempest-shadow-md:0 4px 12px #0006, 0 2px 4px #0003;--tempest-shadow-lg:0 12px 32px #00000080, 0 4px 8px #0000004d;--tempest-shadow-xl:0 24px 48px #0009, 0 8px 16px #0000004d;--tempest-chart-1:#60a5fa;--tempest-chart-2:#4ade80;--tempest-chart-3:#fbbf24;--tempest-chart-4:#a78bfa;--tempest-chart-5:#f472b6;--tempest-chart-6:#22d3ee;--tempest-chart-7:#fb923c;--tempest-chart-8:#2dd4bf;--tempest-chart-sequential-1:#172849;--tempest-chart-sequential-2:#1b3c83;--tempest-chart-sequential-3:#2453b9;--tempest-chart-sequential-4:#376fe5;--tempest-chart-sequential-5:#5b90fb;--tempest-chart-sequential-6:#8cb2fa;--tempest-chart-sequential-7:#bad2fe;--tempest-chart-diverging-1:#1543a8;--tempest-chart-diverging-2:#416eca;--tempest-chart-diverging-3:#7599e0;--tempest-chart-diverging-4:#b0c5ec;--tempest-chart-diverging-5:#262d3f;--tempest-chart-diverging-6:#e8b6af;--tempest-chart-diverging-7:#d77e74;--tempest-chart-diverging-8:#ba473f;--tempest-chart-diverging-9:#94020c;--tempest-chart-grid:var(--tempest-gray-300);--tempest-chart-axis:var(--tempest-gray-600);--tempest-code-comment:#838b93;--tempest-code-punctuation:#818b95;--tempest-code-string:#589866;--tempest-code-number:#c57558;--tempest-code-keyword:#8580d8;--tempest-code-literal:#c87172;--tempest-code-function:#2893c6;--tempest-code-tag:#c07197;--tempest-code-attribute:#349897;--tempest-code-property:#349897}
|
|
4
4
|
:root{--tempest-text-2xs:10px;--tempest-text-xs:12px;--tempest-text-sm:13px;--tempest-text-base:14px;--tempest-text-md:15px;--tempest-text-lg:16px;--tempest-text-xl:18px;--tempest-text-2xl:20px;--tempest-text-3xl:24px;--tempest-text-4xl:30px;--tempest-text-5xl:36px;--tempest-text-6xl:48px;--tempest-leading-none:1;--tempest-leading-tight:1.2;--tempest-leading-snug:1.35;--tempest-leading-normal:1.5;--tempest-leading-relaxed:1.65;--tempest-leading-loose:1.9;--tempest-weight-regular:400;--tempest-weight-medium:500;--tempest-weight-semibold:600;--tempest-weight-bold:700;--tempest-weight-extrabold:800;--tempest-tracking-tight:-.02em;--tempest-tracking-normal:0;--tempest-tracking-wide:.025em;--tempest-tracking-wider:.05em;--tempest-tracking-widest:.1em;--tempest-text-fluid-sm:clamp(13px, 12px + .2vw, 15px);--tempest-text-fluid-base:clamp(14px, 13px + .3vw, 16px);--tempest-text-fluid-lg:clamp(16px, 14px + .5vw, 20px);--tempest-text-fluid-xl:clamp(18px, 15px + .8vw, 24px);--tempest-text-fluid-2xl:clamp(20px, 16px + 1.2vw, 30px);--tempest-text-fluid-3xl:clamp(24px, 18px + 2vw, 40px);--tempest-text-fluid-4xl:clamp(28px, 20px + 3vw, 56px);--tempest-text-fluid-5xl:clamp(32px, 24px + 4vw, 72px);--tempest-text-fluid-6xl:clamp(40px, 28px + 5vw, 96px);--tempest-duration-instant:0s;--tempest-duration-fast:.12s;--tempest-duration-base:.18s;--tempest-duration-slow:.28s;--tempest-duration-slower:.42s;--tempest-ease-linear:linear;--tempest-ease-in:cubic-bezier(.4, 0, 1, 1);--tempest-ease-out:cubic-bezier(0, 0, .2, 1);--tempest-ease-in-out:cubic-bezier(.4, 0, .2, 1);--tempest-ease-emphasized:cubic-bezier(.2, 0, 0, 1);--tempest-ease-bounce:cubic-bezier(.34, 1.56, .64, 1);--tempest-transition-color:color var(--tempest-duration-fast) var(--tempest-ease-out), background-color var(--tempest-duration-fast) var(--tempest-ease-out), border-color var(--tempest-duration-fast) var(--tempest-ease-out);--tempest-transition-shadow:box-shadow var(--tempest-duration-base) var(--tempest-ease-out);--tempest-transition-transform:transform var(--tempest-duration-fast) var(--tempest-ease-out);--tempest-transition-base:color var(--tempest-duration-fast) var(--tempest-ease-out), background-color var(--tempest-duration-fast) var(--tempest-ease-out), border-color var(--tempest-duration-fast) var(--tempest-ease-out), box-shadow var(--tempest-duration-base) var(--tempest-ease-out), transform var(--tempest-duration-fast) var(--tempest-ease-out), opacity var(--tempest-duration-fast) var(--tempest-ease-out)}
|
|
5
5
|
@media (prefers-reduced-motion:reduce){:root{--tempest-duration-fast:.01ms;--tempest-duration-base:.01ms;--tempest-duration-slow:.01ms;--tempest-duration-slower:.01ms}}
|
|
6
6
|
:root,[data-tempest-density=comfortable]{--tempest-control-height-xs:24px;--tempest-control-height-sm:32px;--tempest-control-height-md:40px;--tempest-control-height-lg:48px;--tempest-control-height-xl:56px;--tempest-control-padding-xs:var(--tempest-space-2);--tempest-control-padding-sm:var(--tempest-space-3);--tempest-control-padding-md:var(--tempest-space-4);--tempest-control-padding-lg:var(--tempest-space-5);--tempest-control-padding-xl:var(--tempest-space-6);--tempest-control-font-xs:var(--tempest-text-xs);--tempest-control-font-sm:var(--tempest-text-sm);--tempest-control-font-md:var(--tempest-text-base);--tempest-control-font-lg:var(--tempest-text-lg);--tempest-control-font-xl:var(--tempest-text-xl);--tempest-control-radius:var(--tempest-radius-md);--tempest-control-gap:var(--tempest-space-2)}
|
package/dist/styles/layout.css
CHANGED
|
@@ -94,7 +94,7 @@
|
|
|
94
94
|
.tempest_dayHead_qxQ-f.tempest_today_rs9C1{color:var(--tempest-primary)}
|
|
95
95
|
.tempest_gutterHead_eSRW-{padding:var(--tempest-space-2);color:var(--tempest-text-muted);text-align:right;font-size:.625rem}
|
|
96
96
|
.tempest_allDayTrack_aOePR{grid-template-columns:repeat(var(--tempest-scheduler-days), minmax(0, 1fr));grid-column:2/-1;gap:2px;padding:2px;display:grid}
|
|
97
|
-
.tempest_allDayEvent_oESg4{padding:0 var(--tempest-space-2);border-radius:var(--tempest-radius-sm);background-color:var(--tempest-primary);color:var(--tempest-primary-
|
|
97
|
+
.tempest_allDayEvent_oESg4{padding:0 var(--tempest-space-2);border-radius:var(--tempest-radius-sm);background-color:var(--tempest-primary);color:var(--tempest-primary-foreground);font:inherit;font-size:var(--tempest-text-xs);text-align:left;text-overflow:ellipsis;white-space:nowrap;cursor:pointer;border:none;line-height:1.5rem;overflow:hidden}
|
|
98
98
|
.tempest_allDayEvent_oESg4:disabled{cursor:default}
|
|
99
99
|
.tempest_body_GkK47{grid-template-columns:var(--tempest-scheduler-gutter) 1fr;height:var(--tempest-scheduler-height);display:grid;overflow-y:auto}
|
|
100
100
|
.tempest_gutter_BHgLa{border-right:1px solid var(--tempest-border);position:relative}
|
|
@@ -104,7 +104,7 @@
|
|
|
104
104
|
.tempest_dayColumn_r3HZQ:first-child{border-left:none}
|
|
105
105
|
.tempest_todayColumn_NdkQu{background-color:var(--tempest-surface)}
|
|
106
106
|
.tempest_hourLine_Wch54{border-top:1px solid var(--tempest-border);pointer-events:none;position:absolute;left:0;right:0}
|
|
107
|
-
.tempest_event_R6dCw{padding:2px var(--tempest-space-1);border:1px solid var(--tempest-bg);border-radius:var(--tempest-radius-sm);background-color:var(--tempest-primary);color:var(--tempest-primary-
|
|
107
|
+
.tempest_event_R6dCw{padding:2px var(--tempest-space-1);border:1px solid var(--tempest-bg);border-radius:var(--tempest-radius-sm);background-color:var(--tempest-primary);color:var(--tempest-primary-foreground);font:inherit;text-align:left;cursor:pointer;flex-direction:column;grid-row:1;gap:1px;display:flex;position:absolute;overflow:hidden}
|
|
108
108
|
.tempest_event_R6dCw:disabled{cursor:default}
|
|
109
109
|
.tempest_event_R6dCw:focus-visible{outline:2px solid var(--tempest-text);outline-offset:-2px}
|
|
110
110
|
.tempest_eventTime_HsFmy{font-variant-numeric:tabular-nums;font-size:.625rem}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
.tempest_bar_SHqWS{align-items:center;gap:var(--tempest-space-2);width:100%;min-height:56px;padding:var(--tempest-space-3) var(--tempest-space-4);font-family:var(--tempest-font-sans);grid-template-columns:auto 1fr auto;display:grid}
|
|
3
3
|
.tempest_bar_SHqWS.tempest_centered_S0CCw{grid-template-columns:1fr auto 1fr}
|
|
4
4
|
.tempest_bar_SHqWS.tempest_surface_fusKb{background:var(--tempest-surface);color:var(--tempest-text)}
|
|
5
|
-
.tempest_bar_SHqWS.tempest_primary_QcCyN{background:var(--tempest-primary);color:var(--tempest-
|
|
5
|
+
.tempest_bar_SHqWS.tempest_primary_QcCyN{background:var(--tempest-primary);color:var(--tempest-primary-foreground)}
|
|
6
6
|
.tempest_bar_SHqWS.tempest_transparent_uGrsu{color:inherit;background:0 0}
|
|
7
7
|
.tempest_bar_SHqWS.tempest_bordered_5M9FZ{border-bottom:1px solid var(--tempest-border)}
|
|
8
8
|
.tempest_bar_SHqWS.tempest_sticky_DStUO{z-index:30;position:sticky;top:0}
|