@flamingo-stack/openframe-frontend-core 0.0.734 → 0.0.735
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/build/export-map.json +1 -1
- package/dist/{chunk-4V672TEI.cjs → chunk-36CCUJOE.cjs} +406 -353
- package/dist/{chunk-2OHBH6PS.cjs → chunk-3FZZPR76.cjs} +42 -42
- package/dist/{chunk-JRC3KXKV.cjs → chunk-3JP2OVH3.cjs} +30 -30
- package/dist/{chunk-4Q34V7MD.cjs → chunk-3X4N3IT7.cjs} +18 -18
- package/dist/{chunk-R65UD6BH.cjs → chunk-4F7V2MAC.cjs} +12 -12
- package/dist/{chunk-AOTOOGNX.cjs → chunk-6TTAILSV.cjs} +3 -3
- package/dist/{chunk-OV7QQHLG.cjs → chunk-7HT3VHLJ.cjs} +17 -17
- package/dist/{chunk-3NANWZO3.cjs → chunk-EQ7OOK4B.cjs} +11 -11
- package/dist/{chunk-CMUEFHM3.cjs → chunk-EQH7BUNS.cjs} +4 -4
- package/dist/{chunk-EMBH2EJO.cjs → chunk-F7STMHT7.cjs} +65 -65
- package/dist/{chunk-D34BLEIR.cjs → chunk-HLBFTDUL.cjs} +2 -2
- package/dist/{chunk-HAWQA5FI.cjs → chunk-JDXQ6T5P.cjs} +128 -112
- package/dist/{chunk-73ZW3265.cjs → chunk-MRVZ56GT.cjs} +79 -79
- package/dist/{chunk-5DDFSGCE.cjs → chunk-NVCSVGNI.cjs} +33 -33
- package/dist/{chunk-DHIISS4W.cjs → chunk-RH3AKULV.cjs} +6 -6
- package/dist/{chunk-TLQQP2EL.cjs → chunk-SHQZN5LF.cjs} +6 -6
- package/dist/{chunk-L7WJBJU7.cjs → chunk-SZRZBCWC.cjs} +67 -67
- package/dist/{chunk-FA5SMA7L.cjs → chunk-T323E2Y6.cjs} +4 -4
- package/dist/{chunk-5OGT7H2S.cjs → chunk-TUMUT7CV.cjs} +15 -15
- package/dist/{chunk-BP6R5WDW.cjs → chunk-VA7OMDZO.cjs} +41 -23
- package/dist/{chunk-KSXZABGH.cjs → chunk-W6E7XCBI.cjs} +38 -38
- package/dist/{cloud-tenants-HU7YZD33.cjs → cloud-tenants-H5D57P4U.cjs} +7 -7
- package/dist/components/case-studies/index.cjs +19 -19
- package/dist/components/chat/entity-cards/program-card.d.ts.map +1 -1
- package/dist/components/chat/entity-cards/program-card.js +6 -6
- package/dist/components/chat/index.cjs +5 -5
- package/dist/components/contact/index.cjs +8 -8
- package/dist/components/docs/index.cjs +11 -11
- package/dist/components/embeds/index.cjs +8 -8
- package/dist/components/faq/index.cjs +8 -8
- package/dist/components/features/cards-strip.d.ts.map +1 -1
- package/dist/components/features/cards-strip.js +6 -2
- package/dist/components/features/index.cjs +7 -7
- package/dist/components/features/video-bites-strip.d.ts +6 -1
- package/dist/components/features/video-bites-strip.d.ts.map +1 -1
- package/dist/components/features/video-bites-strip.js +15 -3
- package/dist/components/help-center-pages/index.cjs +106 -106
- package/dist/components/index.cjs +61 -55
- package/dist/components/meeting-scheduler/index.cjs +29 -29
- package/dist/components/navigation/index.cjs +10 -10
- package/dist/components/onboarding-guides/index.cjs +10 -10
- package/dist/components/product-demo/index.cjs +6 -6
- package/dist/components/related-content/index.cjs +4 -4
- package/dist/components/tickets/index.cjs +11 -11
- package/dist/components/ui/fade-preview.d.ts +5 -1
- package/dist/components/ui/fade-preview.d.ts.map +1 -1
- package/dist/components/ui/fade-preview.js +18 -1
- package/dist/components/ui/index.cjs +13 -7
- package/dist/components/ui/index.d.ts +1 -0
- package/dist/components/ui/index.d.ts.map +1 -1
- package/dist/components/ui/index.js +1 -0
- package/dist/components/ui/layout-hold.d.ts +31 -0
- package/dist/components/ui/layout-hold.d.ts.map +1 -0
- package/dist/components/ui/layout-hold.js +25 -0
- package/dist/components/ui/snap-carousel.d.ts.map +1 -1
- package/dist/components/ui/snap-carousel.js +28 -15
- package/dist/{devices-CKLN7BHY.cjs → devices-SQTEXY2H.cjs} +8 -8
- package/dist/{embeddable-chat-FTAX4SVV.cjs → embeddable-chat-S5ODWE3L.cjs} +71 -71
- package/dist/hooks/index.cjs +4 -2
- package/dist/hooks/ui/index.d.ts +1 -0
- package/dist/hooks/ui/index.d.ts.map +1 -1
- package/dist/hooks/ui/index.js +1 -0
- package/dist/hooks/ui/use-resumable-timeout.d.ts +22 -0
- package/dist/hooks/ui/use-resumable-timeout.d.ts.map +1 -0
- package/dist/hooks/ui/use-resumable-timeout.js +26 -0
- package/dist/hooks/use-scenario-player.d.ts +4 -3
- package/dist/hooks/use-scenario-player.d.ts.map +1 -1
- package/dist/hooks/use-scenario-player.js +17 -23
- package/dist/index.cjs +19 -11
- package/dist/{knowledge-NRLHSCC5.cjs → knowledge-FO3TPLFO.cjs} +8 -8
- package/dist/{logs-BR6SLYAF.cjs → logs-Y4WQB2YR.cjs} +15 -15
- package/dist/{policies-MQRXBYG2.cjs → policies-D6VY2ODF.cjs} +11 -11
- package/dist/{software-update-RUGIQP7N.cjs → software-update-7XN6U7HC.cjs} +10 -10
- package/package.json +1 -1
- package/src/components/chat/entity-cards/program-card.tsx +9 -8
- package/src/components/features/cards-strip.tsx +11 -2
- package/src/components/features/video-bites-strip.tsx +22 -3
- package/src/components/ui/fade-preview.tsx +30 -1
- package/src/components/ui/index.ts +1 -0
- package/src/components/ui/layout-hold.tsx +55 -0
- package/src/components/ui/snap-carousel.tsx +36 -20
- package/src/hooks/ui/index.ts +1 -0
- package/src/hooks/ui/use-resumable-timeout.ts +55 -0
- package/src/hooks/use-scenario-player.ts +28 -32
|
@@ -8,23 +8,23 @@ var _chunkII4QMH26cjs = require('./chunk-II4QMH26.cjs');
|
|
|
8
8
|
var _chunkKHXZFLINcjs = require('./chunk-KHXZFLIN.cjs');
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
var
|
|
11
|
+
var _chunk36CCUJOEcjs = require('./chunk-36CCUJOE.cjs');
|
|
12
12
|
require('./chunk-ZJNYWNCB.cjs');
|
|
13
13
|
require('./chunk-3HPB4H4C.cjs');
|
|
14
14
|
require('./chunk-L4ZNR5V7.cjs');
|
|
15
15
|
require('./chunk-HQQE74RO.cjs');
|
|
16
16
|
require('./chunk-DEY6XXGO.cjs');
|
|
17
|
-
require('./chunk-
|
|
17
|
+
require('./chunk-VA7OMDZO.cjs');
|
|
18
18
|
require('./chunk-AAFW4STC.cjs');
|
|
19
19
|
require('./chunk-24I6RFVU.cjs');
|
|
20
20
|
require('./chunk-A6P6DHEZ.cjs');
|
|
21
21
|
require('./chunk-MZ4KBSH7.cjs');
|
|
22
22
|
require('./chunk-OXJ57643.cjs');
|
|
23
23
|
require('./chunk-YUMFVQIN.cjs');
|
|
24
|
-
require('./chunk-
|
|
24
|
+
require('./chunk-F7STMHT7.cjs');
|
|
25
25
|
|
|
26
26
|
|
|
27
|
-
var
|
|
27
|
+
var _chunkJDXQ6T5Pcjs = require('./chunk-JDXQ6T5P.cjs');
|
|
28
28
|
require('./chunk-ZRYKDN2J.cjs');
|
|
29
29
|
require('./chunk-HZJRERJW.cjs');
|
|
30
30
|
require('./chunk-DUXLZPMJ.cjs');
|
|
@@ -1825,8 +1825,8 @@ require('./chunk-7DNL734S.cjs');
|
|
|
1825
1825
|
require('./chunk-WWUSFOJ7.cjs');
|
|
1826
1826
|
require('./chunk-SKI6NKOE.cjs');
|
|
1827
1827
|
require('./chunk-EWPR7662.cjs');
|
|
1828
|
-
require('./chunk-
|
|
1829
|
-
require('./chunk-
|
|
1828
|
+
require('./chunk-SHQZN5LF.cjs');
|
|
1829
|
+
require('./chunk-RH3AKULV.cjs');
|
|
1830
1830
|
require('./chunk-FCGLSWKR.cjs');
|
|
1831
1831
|
require('./chunk-YADG5Q7C.cjs');
|
|
1832
1832
|
require('./chunk-MYBTNOS6.cjs');
|
|
@@ -1905,10 +1905,10 @@ function KnowledgeScreen(_props) {
|
|
|
1905
1905
|
const cast = _chunkII4QMH26cjs.useProductDemoCast.call(void 0, );
|
|
1906
1906
|
const fixture = _react.useMemo.call(void 0, () => buildKnowledgeFixture(cast), [cast]);
|
|
1907
1907
|
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-full bg-ods-bg", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1908
|
-
|
|
1908
|
+
_chunk36CCUJOEcjs.KnowledgeBaseArticleView,
|
|
1909
1909
|
{
|
|
1910
1910
|
...fixture.article,
|
|
1911
|
-
content: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1911
|
+
content: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkJDXQ6T5Pcjs.SimpleMarkdownRenderer, { content: fixture.content, textSize: "compact" })
|
|
1912
1912
|
}
|
|
1913
1913
|
) });
|
|
1914
1914
|
}
|
|
@@ -16,13 +16,13 @@ var _chunkKHXZFLINcjs = require('./chunk-KHXZFLIN.cjs');
|
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
|
|
19
|
-
var
|
|
19
|
+
var _chunk36CCUJOEcjs = require('./chunk-36CCUJOE.cjs');
|
|
20
20
|
require('./chunk-ZJNYWNCB.cjs');
|
|
21
21
|
require('./chunk-3HPB4H4C.cjs');
|
|
22
22
|
require('./chunk-L4ZNR5V7.cjs');
|
|
23
23
|
require('./chunk-HQQE74RO.cjs');
|
|
24
24
|
require('./chunk-DEY6XXGO.cjs');
|
|
25
|
-
require('./chunk-
|
|
25
|
+
require('./chunk-VA7OMDZO.cjs');
|
|
26
26
|
require('./chunk-AAFW4STC.cjs');
|
|
27
27
|
require('./chunk-24I6RFVU.cjs');
|
|
28
28
|
require('./chunk-A6P6DHEZ.cjs');
|
|
@@ -31,8 +31,8 @@ require('./chunk-OXJ57643.cjs');
|
|
|
31
31
|
require('./chunk-YUMFVQIN.cjs');
|
|
32
32
|
|
|
33
33
|
|
|
34
|
-
var
|
|
35
|
-
require('./chunk-
|
|
34
|
+
var _chunkF7STMHT7cjs = require('./chunk-F7STMHT7.cjs');
|
|
35
|
+
require('./chunk-JDXQ6T5P.cjs');
|
|
36
36
|
require('./chunk-ZRYKDN2J.cjs');
|
|
37
37
|
require('./chunk-HZJRERJW.cjs');
|
|
38
38
|
require('./chunk-DUXLZPMJ.cjs');
|
|
@@ -1833,8 +1833,8 @@ require('./chunk-7DNL734S.cjs');
|
|
|
1833
1833
|
require('./chunk-WWUSFOJ7.cjs');
|
|
1834
1834
|
require('./chunk-SKI6NKOE.cjs');
|
|
1835
1835
|
require('./chunk-EWPR7662.cjs');
|
|
1836
|
-
require('./chunk-
|
|
1837
|
-
require('./chunk-
|
|
1836
|
+
require('./chunk-SHQZN5LF.cjs');
|
|
1837
|
+
require('./chunk-RH3AKULV.cjs');
|
|
1838
1838
|
require('./chunk-FCGLSWKR.cjs');
|
|
1839
1839
|
require('./chunk-YADG5Q7C.cjs');
|
|
1840
1840
|
require('./chunk-MYBTNOS6.cjs');
|
|
@@ -1886,7 +1886,7 @@ function entry(logId, minutesAgo, severity, toolType, device2, summary) {
|
|
|
1886
1886
|
id: logId,
|
|
1887
1887
|
logId,
|
|
1888
1888
|
timestamp: displayTime(_chunkKHXZFLINcjs.demoMinutesAgo.call(void 0, minutesAgo)),
|
|
1889
|
-
status: { label: severity, variant:
|
|
1889
|
+
status: { label: severity, variant: _chunk36CCUJOEcjs.logSeverityVariant.call(void 0, severity) },
|
|
1890
1890
|
source: { name: toolType, toolType },
|
|
1891
1891
|
device: device2,
|
|
1892
1892
|
description: { title: summary }
|
|
@@ -1958,13 +1958,13 @@ var NO_FILTERS = {};
|
|
|
1958
1958
|
var ACTION_COLUMNS = ["copy", "quickView", "open"];
|
|
1959
1959
|
var BESIDE_DRAWER_HIDDEN = [...ACTION_COLUMNS, "tool", "source"];
|
|
1960
1960
|
var logHref = () => "#";
|
|
1961
|
-
var copyAction = () => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1961
|
+
var copyAction = () => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk36CCUJOEcjs.LogCopyIconButton, {});
|
|
1962
1962
|
function LogsScreen({ compact = false }) {
|
|
1963
1963
|
const [dock, setDock] = _react.useState.call(void 0, null);
|
|
1964
1964
|
const selected = LOGS_FIXTURE_SELECTED;
|
|
1965
1965
|
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex h-full bg-ods-bg", children: [
|
|
1966
1966
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "min-w-0 flex-1 overflow-clip", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1967
|
-
|
|
1967
|
+
_chunk36CCUJOEcjs.LogsPageView,
|
|
1968
1968
|
{
|
|
1969
1969
|
showHeader: false,
|
|
1970
1970
|
className: "p-[var(--spacing-system-l)]",
|
|
@@ -1972,7 +1972,7 @@ function LogsScreen({ compact = false }) {
|
|
|
1972
1972
|
onSearchChange: noop,
|
|
1973
1973
|
onOpenFilters: noop,
|
|
1974
1974
|
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1975
|
-
|
|
1975
|
+
_chunk36CCUJOEcjs.LogsTableView,
|
|
1976
1976
|
{
|
|
1977
1977
|
logs: LOGS_FIXTURE_ENTRIES,
|
|
1978
1978
|
facets: LOGS_FIXTURE_FACETS,
|
|
@@ -1986,8 +1986,8 @@ function LogsScreen({ compact = false }) {
|
|
|
1986
1986
|
)
|
|
1987
1987
|
}
|
|
1988
1988
|
) }),
|
|
1989
|
-
!compact && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { ref: setDock, className: "relative w-[calc(400px+var(--spacing-system-m))] shrink-0", children: dock && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1990
|
-
|
|
1989
|
+
!compact && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { ref: setDock, className: "relative w-[calc(400px+var(--spacing-system-m))] shrink-0", children: dock && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk36CCUJOEcjs.AppLayoutDrawerContainerContext.Provider, { value: dock, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1990
|
+
_chunk36CCUJOEcjs.LogDrawer,
|
|
1991
1991
|
{
|
|
1992
1992
|
docked: true,
|
|
1993
1993
|
isOpen: true,
|
|
@@ -1999,12 +1999,12 @@ function LogsScreen({ compact = false }) {
|
|
|
1999
1999
|
{ label: "Log ID", value: selected.logId },
|
|
2000
2000
|
{
|
|
2001
2001
|
label: "Source",
|
|
2002
|
-
value: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2002
|
+
value: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk36CCUJOEcjs.ToolBadge, { toolType: _chunkF7STMHT7cjs.normalizeToolTypeWithFallback.call(void 0, selected.source.toolType) })
|
|
2003
2003
|
},
|
|
2004
|
-
{ label: "Device", value:
|
|
2004
|
+
{ label: "Device", value: _chunk36CCUJOEcjs.logSourceLabels.call(void 0, selected.device).deviceName }
|
|
2005
2005
|
],
|
|
2006
2006
|
deviceCard: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2007
|
-
|
|
2007
|
+
_chunk36CCUJOEcjs.DeviceCard,
|
|
2008
2008
|
{
|
|
2009
2009
|
...LOGS_FIXTURE_DEVICE,
|
|
2010
2010
|
actions: {
|
|
@@ -10,21 +10,21 @@ var _chunkKHXZFLINcjs = require('./chunk-KHXZFLIN.cjs');
|
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
var
|
|
13
|
+
var _chunk36CCUJOEcjs = require('./chunk-36CCUJOE.cjs');
|
|
14
14
|
require('./chunk-ZJNYWNCB.cjs');
|
|
15
15
|
require('./chunk-3HPB4H4C.cjs');
|
|
16
16
|
require('./chunk-L4ZNR5V7.cjs');
|
|
17
17
|
require('./chunk-HQQE74RO.cjs');
|
|
18
18
|
require('./chunk-DEY6XXGO.cjs');
|
|
19
|
-
require('./chunk-
|
|
19
|
+
require('./chunk-VA7OMDZO.cjs');
|
|
20
20
|
require('./chunk-AAFW4STC.cjs');
|
|
21
21
|
require('./chunk-24I6RFVU.cjs');
|
|
22
22
|
require('./chunk-A6P6DHEZ.cjs');
|
|
23
23
|
require('./chunk-MZ4KBSH7.cjs');
|
|
24
24
|
require('./chunk-OXJ57643.cjs');
|
|
25
25
|
require('./chunk-YUMFVQIN.cjs');
|
|
26
|
-
require('./chunk-
|
|
27
|
-
require('./chunk-
|
|
26
|
+
require('./chunk-F7STMHT7.cjs');
|
|
27
|
+
require('./chunk-JDXQ6T5P.cjs');
|
|
28
28
|
require('./chunk-ZRYKDN2J.cjs');
|
|
29
29
|
require('./chunk-HZJRERJW.cjs');
|
|
30
30
|
require('./chunk-DUXLZPMJ.cjs');
|
|
@@ -1825,8 +1825,8 @@ require('./chunk-7DNL734S.cjs');
|
|
|
1825
1825
|
require('./chunk-WWUSFOJ7.cjs');
|
|
1826
1826
|
require('./chunk-SKI6NKOE.cjs');
|
|
1827
1827
|
require('./chunk-EWPR7662.cjs');
|
|
1828
|
-
require('./chunk-
|
|
1829
|
-
require('./chunk-
|
|
1828
|
+
require('./chunk-SHQZN5LF.cjs');
|
|
1829
|
+
require('./chunk-RH3AKULV.cjs');
|
|
1830
1830
|
require('./chunk-FCGLSWKR.cjs');
|
|
1831
1831
|
require('./chunk-YADG5Q7C.cjs');
|
|
1832
1832
|
require('./chunk-MYBTNOS6.cjs');
|
|
@@ -1891,14 +1891,14 @@ var POLICIES = [
|
|
|
1891
1891
|
policy("policy-local-admins", "No local admins", "No everyday account is a local administrator.", false, 0)
|
|
1892
1892
|
];
|
|
1893
1893
|
var POLICIES_FIXTURE = {
|
|
1894
|
-
summary:
|
|
1894
|
+
summary: _chunk36CCUJOEcjs.computePolicySummary.call(void 0, POLICIES),
|
|
1895
1895
|
rows: POLICIES.map((item) => ({
|
|
1896
1896
|
id: item.id,
|
|
1897
1897
|
name: item.name,
|
|
1898
1898
|
description: item.description,
|
|
1899
1899
|
critical: item.critical,
|
|
1900
1900
|
severityLabel: item.critical ? "Critical" : "Low",
|
|
1901
|
-
status:
|
|
1901
|
+
status: _chunk36CCUJOEcjs.getPolicyTableStatus.call(void 0, item),
|
|
1902
1902
|
actions: [
|
|
1903
1903
|
{ label: "Policy Details", onClick: noop },
|
|
1904
1904
|
{ label: "Delete Policy", onClick: noop }
|
|
@@ -1912,16 +1912,16 @@ var POLICIES_FIXTURE = {
|
|
|
1912
1912
|
var _jsxruntime = require('react/jsx-runtime');
|
|
1913
1913
|
function PoliciesScreen({ compact = false }) {
|
|
1914
1914
|
const table = /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1915
|
-
|
|
1915
|
+
_chunk36CCUJOEcjs.PoliciesTable,
|
|
1916
1916
|
{
|
|
1917
1917
|
rows: POLICIES_FIXTURE.rows,
|
|
1918
1918
|
rowAsLink: true,
|
|
1919
|
-
rightSlot: compact ? void 0 : /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1919
|
+
rightSlot: compact ? void 0 : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk36CCUJOEcjs.DataTable.RowCount, {}),
|
|
1920
1920
|
emptyMessage: "No policies found."
|
|
1921
1921
|
}
|
|
1922
1922
|
);
|
|
1923
1923
|
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex h-full flex-col gap-[var(--spacing-system-l)] bg-ods-bg p-[var(--spacing-system-l)]", children: [
|
|
1924
|
-
!compact && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1924
|
+
!compact && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk36CCUJOEcjs.PolicySummaryCards, { summary: POLICIES_FIXTURE.summary, now: POLICIES_FIXTURE.now }),
|
|
1925
1925
|
table
|
|
1926
1926
|
] });
|
|
1927
1927
|
}
|
|
@@ -15,7 +15,7 @@ var _chunkKHXZFLINcjs = require('./chunk-KHXZFLIN.cjs');
|
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
|
|
18
|
-
var
|
|
18
|
+
var _chunk36CCUJOEcjs = require('./chunk-36CCUJOE.cjs');
|
|
19
19
|
require('./chunk-ZJNYWNCB.cjs');
|
|
20
20
|
require('./chunk-3HPB4H4C.cjs');
|
|
21
21
|
|
|
@@ -23,15 +23,15 @@ require('./chunk-3HPB4H4C.cjs');
|
|
|
23
23
|
var _chunkL4ZNR5V7cjs = require('./chunk-L4ZNR5V7.cjs');
|
|
24
24
|
require('./chunk-HQQE74RO.cjs');
|
|
25
25
|
require('./chunk-DEY6XXGO.cjs');
|
|
26
|
-
require('./chunk-
|
|
26
|
+
require('./chunk-VA7OMDZO.cjs');
|
|
27
27
|
require('./chunk-AAFW4STC.cjs');
|
|
28
28
|
require('./chunk-24I6RFVU.cjs');
|
|
29
29
|
require('./chunk-A6P6DHEZ.cjs');
|
|
30
30
|
require('./chunk-MZ4KBSH7.cjs');
|
|
31
31
|
require('./chunk-OXJ57643.cjs');
|
|
32
32
|
require('./chunk-YUMFVQIN.cjs');
|
|
33
|
-
require('./chunk-
|
|
34
|
-
require('./chunk-
|
|
33
|
+
require('./chunk-F7STMHT7.cjs');
|
|
34
|
+
require('./chunk-JDXQ6T5P.cjs');
|
|
35
35
|
require('./chunk-ZRYKDN2J.cjs');
|
|
36
36
|
require('./chunk-HZJRERJW.cjs');
|
|
37
37
|
require('./chunk-DUXLZPMJ.cjs');
|
|
@@ -1832,8 +1832,8 @@ require('./chunk-7DNL734S.cjs');
|
|
|
1832
1832
|
require('./chunk-WWUSFOJ7.cjs');
|
|
1833
1833
|
require('./chunk-SKI6NKOE.cjs');
|
|
1834
1834
|
require('./chunk-EWPR7662.cjs');
|
|
1835
|
-
require('./chunk-
|
|
1836
|
-
require('./chunk-
|
|
1835
|
+
require('./chunk-SHQZN5LF.cjs');
|
|
1836
|
+
require('./chunk-RH3AKULV.cjs');
|
|
1837
1837
|
require('./chunk-FCGLSWKR.cjs');
|
|
1838
1838
|
require('./chunk-YADG5Q7C.cjs');
|
|
1839
1839
|
require('./chunk-MYBTNOS6.cjs');
|
|
@@ -1926,12 +1926,12 @@ function StaticPackageField({ value }) {
|
|
|
1926
1926
|
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1927
1927
|
_chunkL4ZNR5V7cjs.Autocomplete,
|
|
1928
1928
|
{
|
|
1929
|
-
label:
|
|
1929
|
+
label: _chunk36CCUJOEcjs.PACKAGE_SEARCH_LABEL,
|
|
1930
1930
|
labelVariant: "large",
|
|
1931
1931
|
options: value ? [{ value: value.id, label: value.name, description: _nullishCoalesce(value.description, () => ( void 0)) }] : [],
|
|
1932
1932
|
value: _nullishCoalesce(_optionalChain([value, 'optionalAccess', _ => _.id]), () => ( null)),
|
|
1933
1933
|
onChange: noop,
|
|
1934
|
-
placeholder:
|
|
1934
|
+
placeholder: _chunk36CCUJOEcjs.PACKAGE_SEARCH_PLACEHOLDER
|
|
1935
1935
|
}
|
|
1936
1936
|
);
|
|
1937
1937
|
}
|
|
@@ -1945,7 +1945,7 @@ function SoftwareUpdateScreen({ compact = false }) {
|
|
|
1945
1945
|
[fixture.devices, fixture.selectedIds]
|
|
1946
1946
|
);
|
|
1947
1947
|
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-full bg-ods-bg pt-[var(--spacing-system-l)]", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-full", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1948
|
-
|
|
1948
|
+
_chunk36CCUJOEcjs.SoftwareActionForm,
|
|
1949
1949
|
{
|
|
1950
1950
|
action: fixture.action,
|
|
1951
1951
|
showHeader: false,
|
|
@@ -1957,7 +1957,7 @@ function SoftwareUpdateScreen({ compact = false }) {
|
|
|
1957
1957
|
initialValues: fixture.initialValues,
|
|
1958
1958
|
renderPackageSearch,
|
|
1959
1959
|
renderDevicePicker: () => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1960
|
-
|
|
1960
|
+
_chunk36CCUJOEcjs.DeviceSelector,
|
|
1961
1961
|
{
|
|
1962
1962
|
devices: selected,
|
|
1963
1963
|
loading: false,
|
package/package.json
CHANGED
|
@@ -83,8 +83,8 @@ const EDITORIAL_META_ROW =
|
|
|
83
83
|
const EDITORIAL_PERSON_ROW = 'flex h-8 min-w-0 items-center gap-[var(--spacing-system-s)]';
|
|
84
84
|
|
|
85
85
|
// The default card's boxes, shared by the card and its skeleton: a large SQUARE cover
|
|
86
|
-
// (the picture fills it), a display title, the date and meta row (stacked
|
|
87
|
-
// one line
|
|
86
|
+
// (the picture fills it), a two-line display title, the date and meta row (stacked up to
|
|
87
|
+
// lg, where the text column is wide enough for one line), a three-line description, a tag row, the gallery and the action,
|
|
88
88
|
// so a card is one height whatever its copy and cover.
|
|
89
89
|
const DEFAULT_BODY =
|
|
90
90
|
'flex flex-col gap-[var(--spacing-system-lf)] p-[var(--spacing-system-lf)] md:p-[var(--spacing-system-xlf)]';
|
|
@@ -92,9 +92,9 @@ const DEFAULT_HEADER = 'flex flex-col gap-[var(--spacing-system-lf)] md:flex-row
|
|
|
92
92
|
const DEFAULT_COVER_FRAME =
|
|
93
93
|
'relative aspect-square w-full flex-shrink-0 overflow-hidden rounded-lg md:w-[240px] lg:w-[320px] xl:w-[400px]';
|
|
94
94
|
const DEFAULT_TEXT = 'flex min-w-0 flex-1 flex-col gap-[var(--spacing-system-mf)]';
|
|
95
|
-
const DEFAULT_TITLE = 'line-clamp-2 text-ods-text-primary text-h1';
|
|
95
|
+
const DEFAULT_TITLE = 'line-clamp-2 min-h-[2lh] text-ods-text-primary text-h1';
|
|
96
96
|
const DEFAULT_META_ROW =
|
|
97
|
-
'flex min-h-[calc(2lh+0.5rem)] flex-col gap-2 text-h4
|
|
97
|
+
'flex min-h-[calc(2lh+0.5rem)] flex-col gap-2 text-h4 lg:min-h-[1lh] lg:flex-row lg:items-center lg:gap-4';
|
|
98
98
|
const DEFAULT_DESCRIPTION = 'line-clamp-3 min-h-[3lh] text-ods-text-secondary text-h4';
|
|
99
99
|
const DEFAULT_TAG_ROW = 'flex flex-wrap gap-[var(--spacing-system-xsf)]';
|
|
100
100
|
const DEFAULT_GALLERY_ROW = 'flex gap-[var(--spacing-system-mf)]';
|
|
@@ -177,7 +177,7 @@ export function ProgramCardSkeleton({
|
|
|
177
177
|
<div className={`${DEFAULT_COVER_FRAME} bg-ods-border`} />
|
|
178
178
|
<div className={DEFAULT_TEXT}>
|
|
179
179
|
<div className={DEFAULT_TITLE}>
|
|
180
|
-
<span className="block h-[
|
|
180
|
+
<span className="block h-[2lh] w-3/4 rounded bg-ods-border" />
|
|
181
181
|
</div>
|
|
182
182
|
<div className={DEFAULT_META_ROW}>
|
|
183
183
|
<span className="block h-[1lh] w-32 rounded bg-ods-border" />
|
|
@@ -202,7 +202,8 @@ export function ProgramCardSkeleton({
|
|
|
202
202
|
</div>
|
|
203
203
|
)}
|
|
204
204
|
<div className={DEFAULT_FOOTER}>
|
|
205
|
-
|
|
205
|
+
{/* The action button's own height (44px, 48px from md). */}
|
|
206
|
+
<div className="h-11 w-40 rounded bg-ods-border md:h-12" />
|
|
206
207
|
</div>
|
|
207
208
|
</div>
|
|
208
209
|
);
|
|
@@ -632,13 +633,13 @@ export function ProgramCard<T extends BaseProgramItem>({
|
|
|
632
633
|
<span style={{ color: accentColor }}>{dateLabel}</span>
|
|
633
634
|
{renderMeta ? (
|
|
634
635
|
<>
|
|
635
|
-
<span className="hidden text-ods-text-secondary
|
|
636
|
+
<span className="hidden text-ods-text-secondary lg:inline">•</span>
|
|
636
637
|
{renderMeta(item)}
|
|
637
638
|
</>
|
|
638
639
|
) : (
|
|
639
640
|
defaultRenderMeta() && (
|
|
640
641
|
<>
|
|
641
|
-
<span className="hidden text-ods-text-secondary
|
|
642
|
+
<span className="hidden text-ods-text-secondary lg:inline">•</span>
|
|
642
643
|
<div className="flex items-center gap-2">{defaultRenderMeta()}</div>
|
|
643
644
|
</>
|
|
644
645
|
)
|
|
@@ -259,8 +259,17 @@ function ManagedCell({
|
|
|
259
259
|
const cloneRef = useSuppressCloneFocus(ctx.isClone);
|
|
260
260
|
return (
|
|
261
261
|
<div
|
|
262
|
-
|
|
263
|
-
|
|
262
|
+
// The width is CSS's (the engine's own 767px line), never a script's: the
|
|
263
|
+
// first paint is the cell's final width, so a phone's strip never resizes
|
|
264
|
+
// when the page hydrates.
|
|
265
|
+
className="w-[var(--strip-cell-mobile)] shrink-0 self-stretch min-[768px]:w-[var(--strip-cell-desktop)]"
|
|
266
|
+
style={
|
|
267
|
+
{
|
|
268
|
+
'--strip-cell-mobile': `${cardWidthMobile}px`,
|
|
269
|
+
'--strip-cell-desktop': `${desktopWidth}px`,
|
|
270
|
+
maxWidth: STRIP_CELL_MAX_WIDTH,
|
|
271
|
+
} as React.CSSProperties
|
|
272
|
+
}
|
|
264
273
|
data-strip-card-key={ctx.cardKey}
|
|
265
274
|
onPointerEnter={ctx.isTouch ? undefined : () => ctx.onActivate(ctx.cardKey)}
|
|
266
275
|
onPointerLeave={ctx.isTouch ? undefined : () => ctx.onDeactivate(ctx.cardKey)}
|
|
@@ -147,7 +147,8 @@ export function VideoBitesStrip({
|
|
|
147
147
|
cardKey={ctx.cardKey}
|
|
148
148
|
isClone={ctx.isClone}
|
|
149
149
|
isTouch={ctx.isTouch}
|
|
150
|
-
height={
|
|
150
|
+
height={cardHeightDesktop}
|
|
151
|
+
heightMobile={cardHeightMobile}
|
|
151
152
|
active={ctx.active}
|
|
152
153
|
onActivate={ctx.onActivate}
|
|
153
154
|
onDeactivate={ctx.onDeactivate}
|
|
@@ -178,6 +179,11 @@ export interface VideoBiteCardProps {
|
|
|
178
179
|
/** Fixed card height (strip). Omit → width-driven: card fills its grid
|
|
179
180
|
* cell and the aspect-ratio derives the height (editor grids). */
|
|
180
181
|
height?: number;
|
|
182
|
+
/** With `height`: the height under the strip's 768px line. The switch is CSS's,
|
|
183
|
+
* so the first paint is the card's final size on a phone too. OPTIONAL and
|
|
184
|
+
* additive: omitted, `height` applies at every width, exactly as before this
|
|
185
|
+
* prop existed (a caller that resolves the height itself keeps working). */
|
|
186
|
+
heightMobile?: number;
|
|
181
187
|
/** Controlled hover-activation (strip). Omit → the card manages its own
|
|
182
188
|
* hover/focus state. */
|
|
183
189
|
active?: boolean;
|
|
@@ -211,6 +217,7 @@ export function VideoBiteCard({
|
|
|
211
217
|
sectionHref,
|
|
212
218
|
onBiteNavigate,
|
|
213
219
|
height,
|
|
220
|
+
heightMobile,
|
|
214
221
|
active,
|
|
215
222
|
onActivate,
|
|
216
223
|
onDeactivate,
|
|
@@ -356,10 +363,22 @@ export function VideoBiteCard({
|
|
|
356
363
|
|
|
357
364
|
const media = (
|
|
358
365
|
<div
|
|
359
|
-
className=
|
|
366
|
+
className={cn(
|
|
367
|
+
'relative w-full',
|
|
368
|
+
height !== undefined && 'h-[var(--bite-height-mobile)] min-[768px]:h-[var(--bite-height)]',
|
|
369
|
+
)}
|
|
360
370
|
// Strip mode: fixed height + aspect drive the width (capped at 90vw,
|
|
361
371
|
// same as the old single-box layout). Editor mode: width-driven.
|
|
362
|
-
style={{
|
|
372
|
+
style={{
|
|
373
|
+
aspectRatio: cssAspect,
|
|
374
|
+
...(height !== undefined
|
|
375
|
+
? {
|
|
376
|
+
'--bite-height': `${height}px`,
|
|
377
|
+
'--bite-height-mobile': `${heightMobile ?? height}px`,
|
|
378
|
+
maxWidth: STRIP_CELL_MAX_WIDTH,
|
|
379
|
+
}
|
|
380
|
+
: {}),
|
|
381
|
+
}}
|
|
363
382
|
>
|
|
364
383
|
{/* THE shared hover-preview media zone (poster → facade → badge →
|
|
365
384
|
controlled hover playback + near-viewport mount gate). The bite strip
|
|
@@ -56,7 +56,9 @@ export interface FadePreviewProps {
|
|
|
56
56
|
* MEASURED to the bottom of item N (at every width). Implies `fixedHeight`, so
|
|
57
57
|
* the block keeps that height loading or loaded, and "Show N more" counts the
|
|
58
58
|
* items past N unless `hiddenCount` says otherwise. Until the list holds N
|
|
59
|
-
* items, `collapsedHeight` (or the height last measured) is kept.
|
|
59
|
+
* items, `collapsedHeight` (or the height last measured) is kept. The first
|
|
60
|
+
* paint (before any measure) is held for N up to 12; add rows to
|
|
61
|
+
* `UNMEASURED_ITEMS_CLASSES` for a longer preview.
|
|
60
62
|
*/
|
|
61
63
|
visibleItems?: number;
|
|
62
64
|
/**
|
|
@@ -80,6 +82,32 @@ const FILL_CLASSES: Record<string, string> = {
|
|
|
80
82
|
lg: 'lg:absolute lg:inset-0',
|
|
81
83
|
};
|
|
82
84
|
|
|
85
|
+
/**
|
|
86
|
+
* Item mode before the first measure (the server's markup, and the page until it
|
|
87
|
+
* hydrates): the items past the first N are hidden by CSS, so the block is its
|
|
88
|
+
* collapsed height in the very first paint. Without it the whole list showed and
|
|
89
|
+
* the measure then cut it, which moved everything under it. Spelled out per N
|
|
90
|
+
* (Tailwind only emits classes it can read, and a `<style>` element is not
|
|
91
|
+
* allowed here: each rewrite relayouts the document), so it covers N up to
|
|
92
|
+
* `FADE_PREVIEW_MAX_UNMEASURED_ITEMS`; a larger N is clipped at the measure, as before.
|
|
93
|
+
*/
|
|
94
|
+
const UNMEASURED_ITEMS_CLASSES: Record<number, string> = {
|
|
95
|
+
1: '[&>*>*:nth-child(n+2)]:hidden',
|
|
96
|
+
2: '[&>*>*:nth-child(n+3)]:hidden',
|
|
97
|
+
3: '[&>*>*:nth-child(n+4)]:hidden',
|
|
98
|
+
4: '[&>*>*:nth-child(n+5)]:hidden',
|
|
99
|
+
5: '[&>*>*:nth-child(n+6)]:hidden',
|
|
100
|
+
6: '[&>*>*:nth-child(n+7)]:hidden',
|
|
101
|
+
7: '[&>*>*:nth-child(n+8)]:hidden',
|
|
102
|
+
8: '[&>*>*:nth-child(n+9)]:hidden',
|
|
103
|
+
9: '[&>*>*:nth-child(n+10)]:hidden',
|
|
104
|
+
10: '[&>*>*:nth-child(n+11)]:hidden',
|
|
105
|
+
11: '[&>*>*:nth-child(n+12)]:hidden',
|
|
106
|
+
12: '[&>*>*:nth-child(n+13)]:hidden',
|
|
107
|
+
};
|
|
108
|
+
/** The largest `visibleItems` the first paint is held for (the table above). */
|
|
109
|
+
export const FADE_PREVIEW_MAX_UNMEASURED_ITEMS = 12;
|
|
110
|
+
|
|
83
111
|
const cssLength = (value: number | string) => (typeof value === 'number' ? `${value}px` : value);
|
|
84
112
|
|
|
85
113
|
export function FadePreview({
|
|
@@ -198,6 +226,7 @@ export function FadePreview({
|
|
|
198
226
|
className={cn(
|
|
199
227
|
'overflow-hidden transition-[max-height,height] duration-500',
|
|
200
228
|
fill && FILL_CLASSES[String(fill)],
|
|
229
|
+
itemMode && itemsHeight == null && !expanded && UNMEASURED_ITEMS_CLASSES[visible],
|
|
201
230
|
)}
|
|
202
231
|
style={{
|
|
203
232
|
transitionTimingFunction: 'cubic-bezier(0.33, 1, 0.68, 1)',
|
|
@@ -64,6 +64,7 @@ export * from './alert';
|
|
|
64
64
|
export * from './badge';
|
|
65
65
|
export * from './ai-generated-badge';
|
|
66
66
|
export * from './fade-preview';
|
|
67
|
+
export * from './layout-hold';
|
|
67
68
|
export * from './progress';
|
|
68
69
|
export * from './release-changelog-section';
|
|
69
70
|
export * from './stacked-rows-panel';
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import { cn } from '../../utils/cn';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Holding a layout while its content is read, the two ways that are right at
|
|
6
|
+
* EVERY width. A placeholder of a guessed size (a `w-40` bar, a `h-[120px]`
|
|
7
|
+
* box) is only right at the widths it was tuned at: text wraps where the words
|
|
8
|
+
* make it wrap, so the placeholder has to be made of the words, or of the real
|
|
9
|
+
* layout, to wrap where the content will.
|
|
10
|
+
*
|
|
11
|
+
* - `TextHold`: an inline stand-in exactly as wide as the words it is given
|
|
12
|
+
* (same font, same letter spacing, because it IS those words, not shown).
|
|
13
|
+
* `bar` draws it as a pulsing grey bar; `blank` only keeps its space.
|
|
14
|
+
* - `LayoutHold`: a block as tall as the real layout rendered inside it, kept
|
|
15
|
+
* invisible and inert: the layout's own height, at any width.
|
|
16
|
+
*
|
|
17
|
+
* Neither is shown or read out; both are removed for assistive technology.
|
|
18
|
+
*/
|
|
19
|
+
export interface TextHoldProps {
|
|
20
|
+
/** The words whose width is held (the content's own, or a stand-in of its length). */
|
|
21
|
+
children: ReactNode;
|
|
22
|
+
/** `bar`: a pulsing grey bar of that width. `blank`: the width only. */
|
|
23
|
+
variant?: 'bar' | 'blank';
|
|
24
|
+
className?: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function TextHold({ children, variant = 'bar', className }: TextHoldProps) {
|
|
28
|
+
return (
|
|
29
|
+
<span
|
|
30
|
+
aria-hidden
|
|
31
|
+
className={cn(
|
|
32
|
+
variant === 'bar' ? 'animate-pulse rounded bg-ods-border text-transparent' : 'invisible',
|
|
33
|
+
// A hold is never selectable or clickable, whatever it wraps.
|
|
34
|
+
'pointer-events-none select-none',
|
|
35
|
+
className,
|
|
36
|
+
)}
|
|
37
|
+
>
|
|
38
|
+
{children}
|
|
39
|
+
</span>
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export interface LayoutHoldProps {
|
|
44
|
+
/** The real layout, rendered with the data at hand. */
|
|
45
|
+
children: ReactNode;
|
|
46
|
+
className?: string;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function LayoutHold({ children, className }: LayoutHoldProps) {
|
|
50
|
+
return (
|
|
51
|
+
<div aria-hidden inert className={cn('invisible', className)}>
|
|
52
|
+
{children}
|
|
53
|
+
</div>
|
|
54
|
+
);
|
|
55
|
+
}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import { type ReactNode, useCallback, useEffect, useRef, useState } from 'react';
|
|
4
4
|
import { useAutoplay } from '../../hooks/ui/use-autoplay';
|
|
5
5
|
import { useInView } from '../../hooks/ui/use-in-view';
|
|
6
|
+
import { useResumableTimeout } from '../../hooks/ui/use-resumable-timeout';
|
|
6
7
|
import { cn } from '../../utils/cn';
|
|
7
8
|
import { Chevron02LeftIcon } from '../icons-v2-generated/arrows/chevron-02-left-icon';
|
|
8
9
|
import { Chevron02RightIcon } from '../icons-v2-generated/arrows/chevron-02-right-icon';
|
|
@@ -39,20 +40,31 @@ export interface SnapCarouselProps<T> {
|
|
|
39
40
|
const GAP_PX = 12;
|
|
40
41
|
|
|
41
42
|
/**
|
|
42
|
-
* The active dot
|
|
43
|
-
*
|
|
44
|
-
*
|
|
43
|
+
* The active dot's fill: how much of the slide's wait has been run. It starts
|
|
44
|
+
* from where the wait stands (`ranMs`, nothing for a new slide) and runs to
|
|
45
|
+
* full over what is LEFT of it. While the carousel is not advancing it stands
|
|
46
|
+
* still at that point; it never empties because the carousel left the screen.
|
|
45
47
|
*/
|
|
46
|
-
function DotFill({ durationMs }: { durationMs: number }) {
|
|
47
|
-
|
|
48
|
+
function DotFill({ durationMs, ranMs, running }: { durationMs: number; ranMs: number; running: boolean }) {
|
|
49
|
+
// One frame at the starting point, so the browser has it to run from.
|
|
50
|
+
const [going, setGoing] = useState(false);
|
|
48
51
|
useEffect(() => {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
+
if (!running) return undefined;
|
|
53
|
+
const frame = requestAnimationFrame(() => setGoing(true));
|
|
54
|
+
return () => {
|
|
55
|
+
cancelAnimationFrame(frame);
|
|
56
|
+
setGoing(false);
|
|
57
|
+
};
|
|
58
|
+
}, [running]);
|
|
59
|
+
const moving = running && going;
|
|
52
60
|
return (
|
|
53
61
|
<span
|
|
54
|
-
className="absolute inset-0 origin-left bg-ods-text-primary
|
|
55
|
-
style={{
|
|
62
|
+
className="absolute inset-0 origin-left bg-ods-text-primary ease-linear"
|
|
63
|
+
style={{
|
|
64
|
+
transform: `scaleX(${moving ? 1 : durationMs > 0 ? ranMs / durationMs : 0})`,
|
|
65
|
+
transitionProperty: moving ? 'transform' : 'none',
|
|
66
|
+
transitionDuration: `${Math.max(0, durationMs - ranMs)}ms`,
|
|
67
|
+
}}
|
|
56
68
|
/>
|
|
57
69
|
);
|
|
58
70
|
}
|
|
@@ -122,12 +134,15 @@ export function SnapCarousel<T>({
|
|
|
122
134
|
const canAutoAdvance = autoAdvanceMs > 0 && count > 1;
|
|
123
135
|
const playing = auto.playing && canAutoAdvance;
|
|
124
136
|
|
|
125
|
-
//
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
137
|
+
// A new slide starts a whole interval (a swipe or an arrow is followed by a
|
|
138
|
+
// full one); an interruption (off screen, a hold, another tab) only pauses it.
|
|
139
|
+
const ranMs = useResumableTimeout({
|
|
140
|
+
running: playing,
|
|
141
|
+
durationMs: autoAdvanceMs,
|
|
142
|
+
resetKey: index,
|
|
143
|
+
onElapsed: () => goTo(index >= count - 1 ? 0 : index + 1),
|
|
144
|
+
});
|
|
145
|
+
const showsWait = canAutoAdvance && !auto.reducedMotion;
|
|
131
146
|
|
|
132
147
|
const setRefs = useCallback(
|
|
133
148
|
(node: HTMLDivElement | null) => {
|
|
@@ -172,12 +187,13 @@ export function SnapCarousel<T>({
|
|
|
172
187
|
className={cn(
|
|
173
188
|
'relative h-1.5 overflow-hidden rounded-full transition-[width] duration-200 motion-reduce:transition-none',
|
|
174
189
|
dotIndex === index ? 'w-6' : 'w-1.5',
|
|
175
|
-
|
|
190
|
+
// A carousel that never advances by itself marks its slide with a whole dot.
|
|
191
|
+
dotIndex === index && !showsWait ? 'bg-ods-text-primary' : 'bg-ods-border',
|
|
176
192
|
)}
|
|
177
193
|
>
|
|
178
|
-
{dotIndex === index &&
|
|
179
|
-
// Re-keyed per slide so
|
|
180
|
-
<DotFill key={index} durationMs={autoAdvanceMs} />
|
|
194
|
+
{dotIndex === index && showsWait && (
|
|
195
|
+
// Re-keyed per slide so a NEW slide starts from empty; a pause keeps its place.
|
|
196
|
+
<DotFill key={index} durationMs={autoAdvanceMs} ranMs={ranMs} running={playing} />
|
|
181
197
|
)}
|
|
182
198
|
</span>
|
|
183
199
|
))}
|