@intility/bifrost-experimental 0.0.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +17 -0
- package/README.md +57 -0
- package/dist/bifrost-experimental.css +132 -0
- package/dist/components/Backdrop/Backdrop.d.ts +31 -0
- package/dist/components/Backdrop/Backdrop.js +53 -0
- package/dist/components/Backdrop/index.d.ts +2 -0
- package/dist/components/Backdrop/index.js +1 -0
- package/dist/components/FrontpageHeader/FrontpageHeader.d.ts +33 -0
- package/dist/components/FrontpageHeader/FrontpageHeader.js +84 -0
- package/dist/components/FrontpageHeader/index.d.ts +2 -0
- package/dist/components/FrontpageHeader/index.js +1 -0
- package/dist/components/TwinkleBackground/TwinkleBackground.d.ts +36 -0
- package/dist/components/TwinkleBackground/TwinkleBackground.js +389 -0
- package/dist/components/TwinkleBackground/index.d.ts +2 -0
- package/dist/components/TwinkleBackground/index.js +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/package.json +56 -6
- package/index.js +0 -1
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# @intility/bifrost-experimental
|
|
2
|
+
|
|
3
|
+
## 0.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- d272c33: `TwinkleBackground` has a new `fill` prop for using it inside a `Box` or a card. The dots then cover the whole container, evenly, with no fade. The dot grid is now also centered with a margin to the edges, so the edge of the container no longer cuts a dot in half.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- 75f2bf7: `Backdrop` no longer uses `filter: blur()` for its soft edges. Safari on some Macs drew a dark or light halo around the shade when switching between light and dark mode. The edges now fade with a gradient mask instead.
|
|
12
|
+
|
|
13
|
+
## 0.1.0 - 2026-10-27
|
|
14
|
+
|
|
15
|
+
### First release
|
|
16
|
+
|
|
17
|
+
- 2b88573: New package for experimental, AI-generated components. Adds `TwinkleBackground`, an animated dot-grid background in the Bifrost theme color, `Backdrop`, a soft shaded area that keeps text readable on a busy background, and `FrontpageHeader`, a logo, title and subtitle for the front page of a Platform Manager module. #998
|
package/README.md
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# @intility/bifrost-experimental
|
|
2
|
+
|
|
3
|
+
Experimental, AI-generated React components for Intility's design system,
|
|
4
|
+
Bifrost. See [Experimental](https://bifrost.intility.com/react/experimental)
|
|
5
|
+
in the style guide.
|
|
6
|
+
|
|
7
|
+
## What experimental means
|
|
8
|
+
|
|
9
|
+
The components are built with AI and aren't reviewed line by line. They are
|
|
10
|
+
front end only: they depend on nothing but React and Bifrost, and make no
|
|
11
|
+
network calls. Lint rules and tests catch common mistakes, but they aren't a
|
|
12
|
+
guarantee. Use the components in your apps, but expect them to change more
|
|
13
|
+
often than the Bifrost packages.
|
|
14
|
+
|
|
15
|
+
## Install
|
|
16
|
+
|
|
17
|
+
```shell
|
|
18
|
+
npm install @intility/bifrost-experimental
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
It needs `react`, `react-dom` and `@intility/bifrost-react`. Import the CSS
|
|
22
|
+
once, after the Bifrost CSS:
|
|
23
|
+
|
|
24
|
+
```tsx
|
|
25
|
+
import "@intility/bifrost-react/bifrost-app.css";
|
|
26
|
+
import "@intility/bifrost-experimental/bifrost-experimental.css";
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Import each component from its own path:
|
|
30
|
+
|
|
31
|
+
```tsx
|
|
32
|
+
import TwinkleBackground from "@intility/bifrost-experimental/TwinkleBackground";
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Components
|
|
36
|
+
|
|
37
|
+
- [`Backdrop`](https://bifrost.intility.com/react/experimental/backdrop):
|
|
38
|
+
a soft shaded area that keeps text readable on a busy background
|
|
39
|
+
- [`FrontpageHeader`](https://bifrost.intility.com/react/experimental/frontpage-header):
|
|
40
|
+
logo, title and subtitle for the front page of a Platform Manager module
|
|
41
|
+
- [`TwinkleBackground`](https://bifrost.intility.com/react/experimental/twinkle-background):
|
|
42
|
+
an animated dot grid in the theme color, for the front page of a Platform
|
|
43
|
+
Manager module
|
|
44
|
+
|
|
45
|
+
## Contributing
|
|
46
|
+
|
|
47
|
+
See
|
|
48
|
+
[AGENTS.md](https://github.com/intility/bifrost/blob/main/packages/bifrost-experimental/AGENTS.md)
|
|
49
|
+
for the rules and commands, whether you write the component yourself or with
|
|
50
|
+
an AI agent.
|
|
51
|
+
|
|
52
|
+
Members of the `bifrost-experimenters` team in the `intility` GitHub
|
|
53
|
+
organization can approve changes to the components, their docs pages
|
|
54
|
+
(`docs/app/react/experimental/`) and the Experimental sidebar group
|
|
55
|
+
(`docs/utils/experimentalNavigation.ts`). Changes to the package configs, the
|
|
56
|
+
guardrails and the rest of the docs need a Bifrost developer, as
|
|
57
|
+
[CODEOWNERS](https://github.com/intility/bifrost/blob/main/CODEOWNERS) defines.
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/* No z-index or isolation: the shade has to join the stacking context around
|
|
2
|
+
it, so it sits above what is behind it but below all the text */
|
|
3
|
+
.bfx-backdrop {
|
|
4
|
+
display: block;
|
|
5
|
+
position: relative;
|
|
6
|
+
width: fit-content;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/* The wrapper only takes the text color from its bfc-*-bg class. The type
|
|
10
|
+
selector outranks the class, whatever order the stylesheets load in. */
|
|
11
|
+
span.bfx-backdrop {
|
|
12
|
+
background-color: transparent;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.bfx-backdrop-shade {
|
|
16
|
+
position: absolute;
|
|
17
|
+
z-index: -1;
|
|
18
|
+
pointer-events: none;
|
|
19
|
+
|
|
20
|
+
/* How far the shade reaches past the content, which is also the width of its
|
|
21
|
+
fade. The horizontal reach is no wider than the page padding, so the shade
|
|
22
|
+
can't reach past the screen edge on small screens. */
|
|
23
|
+
--bfx-backdrop-x: min(var(--bfs32), var(--bfl-page-padding));
|
|
24
|
+
--bfx-backdrop-y: var(--bfs24);
|
|
25
|
+
|
|
26
|
+
/* Larger than the content without changing the layout */
|
|
27
|
+
inset: calc(-1 * var(--bfx-backdrop-y)) calc(-1 * var(--bfx-backdrop-x));
|
|
28
|
+
opacity: 0.7;
|
|
29
|
+
|
|
30
|
+
/* Soft edges, so it doesn't look like a box. Each edge eases out over the
|
|
31
|
+
reach, like the tail of a blur, and the two masks are multiplied so the
|
|
32
|
+
corners fade too. A mask rather than filter: blur(), which Safari renders
|
|
33
|
+
with a dark or light halo on some Macs. */
|
|
34
|
+
mask-image:
|
|
35
|
+
linear-gradient(
|
|
36
|
+
to bottom,
|
|
37
|
+
transparent,
|
|
38
|
+
rgba(0, 0, 0, 0.1) calc(var(--bfx-backdrop-y) * 0.25),
|
|
39
|
+
rgba(0, 0, 0, 0.5) calc(var(--bfx-backdrop-y) * 0.5),
|
|
40
|
+
rgba(0, 0, 0, 0.9) calc(var(--bfx-backdrop-y) * 0.75),
|
|
41
|
+
#000 var(--bfx-backdrop-y),
|
|
42
|
+
#000 calc(100% - var(--bfx-backdrop-y)),
|
|
43
|
+
rgba(0, 0, 0, 0.9) calc(100% - var(--bfx-backdrop-y) * 0.75),
|
|
44
|
+
rgba(0, 0, 0, 0.5) calc(100% - var(--bfx-backdrop-y) * 0.5),
|
|
45
|
+
rgba(0, 0, 0, 0.1) calc(100% - var(--bfx-backdrop-y) * 0.25),
|
|
46
|
+
transparent
|
|
47
|
+
),
|
|
48
|
+
linear-gradient(
|
|
49
|
+
to right,
|
|
50
|
+
transparent,
|
|
51
|
+
rgba(0, 0, 0, 0.1) calc(var(--bfx-backdrop-x) * 0.25),
|
|
52
|
+
rgba(0, 0, 0, 0.5) calc(var(--bfx-backdrop-x) * 0.5),
|
|
53
|
+
rgba(0, 0, 0, 0.9) calc(var(--bfx-backdrop-x) * 0.75),
|
|
54
|
+
#000 var(--bfx-backdrop-x),
|
|
55
|
+
#000 calc(100% - var(--bfx-backdrop-x)),
|
|
56
|
+
rgba(0, 0, 0, 0.9) calc(100% - var(--bfx-backdrop-x) * 0.75),
|
|
57
|
+
rgba(0, 0, 0, 0.5) calc(100% - var(--bfx-backdrop-x) * 0.5),
|
|
58
|
+
rgba(0, 0, 0, 0.1) calc(100% - var(--bfx-backdrop-x) * 0.25),
|
|
59
|
+
transparent
|
|
60
|
+
);
|
|
61
|
+
mask-composite: intersect;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/* A stacking context, so the title's and subtitle's backdrops sit behind both
|
|
65
|
+
lines and neither covers the other line */
|
|
66
|
+
.bfx-frontpage-header {
|
|
67
|
+
display: flex;
|
|
68
|
+
align-items: center;
|
|
69
|
+
gap: var(--bfs16);
|
|
70
|
+
isolation: isolate;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.bfx-frontpage-header-logo {
|
|
74
|
+
display: flex;
|
|
75
|
+
flex-shrink: 0;
|
|
76
|
+
height: 72px;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/* Stretching from the slot isn't enough in Safari, which sizes the slot from
|
|
80
|
+
the image's own width. An SVG with only a viewBox has none, so the logo would
|
|
81
|
+
overlap the title. */
|
|
82
|
+
.bfx-frontpage-header-logo > * {
|
|
83
|
+
height: 100%;
|
|
84
|
+
width: auto;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/* flex-start keeps each line only as wide as its text */
|
|
88
|
+
.bfx-frontpage-header-text {
|
|
89
|
+
display: flex;
|
|
90
|
+
flex-direction: column;
|
|
91
|
+
align-items: flex-start;
|
|
92
|
+
gap: var(--bfs8);
|
|
93
|
+
}
|
|
94
|
+
.bfx-twinkle-background {
|
|
95
|
+
position: absolute;
|
|
96
|
+
inset: 0 0 auto;
|
|
97
|
+
|
|
98
|
+
/* A canvas is a replaced element, so inset alone doesn't stretch it */
|
|
99
|
+
width: 100%;
|
|
100
|
+
height: 40%;
|
|
101
|
+
z-index: -1;
|
|
102
|
+
pointer-events: none;
|
|
103
|
+
|
|
104
|
+
/* The component reads this color back for the canvas. Light mode cuts the
|
|
105
|
+
chroma to a quarter, so the dots are only a hint of color. Browsers without
|
|
106
|
+
relative colors fall back to the text color. */
|
|
107
|
+
color: light-dark(
|
|
108
|
+
oklch(from var(--bfc-theme) l calc(c * 0.25) h),
|
|
109
|
+
var(--bfc-theme)
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
.bfx-twinkle-background-fill {
|
|
114
|
+
height: 100%;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/* Red and green aren't themes. The theme colors have a lightness of 46% to
|
|
118
|
+
55% in light mode and 71% to 90% in dark mode, so the lightness is moved
|
|
119
|
+
into that range where alert (55% dark) and success (85% light) are far off. */
|
|
120
|
+
.bfx-twinkle-background-red {
|
|
121
|
+
color: light-dark(
|
|
122
|
+
oklch(from var(--bfc-alert) l calc(c * 0.25) h),
|
|
123
|
+
oklch(from var(--bfc-alert) 66% c h)
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
.bfx-twinkle-background-green {
|
|
128
|
+
color: light-dark(
|
|
129
|
+
oklch(from var(--bfc-success) 52% calc(c * 0.25) h),
|
|
130
|
+
var(--bfc-success)
|
|
131
|
+
);
|
|
132
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { BoxProps } from "@intility/bifrost-react/Box";
|
|
2
|
+
import type { ReactNode } from "react";
|
|
3
|
+
export type BackdropProps = {
|
|
4
|
+
children: ReactNode;
|
|
5
|
+
/**
|
|
6
|
+
* The background the backdrop sits on, which is the color it fades out to.
|
|
7
|
+
* Takes the same values as the `background` prop of Bifrost's Box, and also
|
|
8
|
+
* sets the matching text color.
|
|
9
|
+
* @example
|
|
10
|
+
* `"base"` is the page background, and the default.
|
|
11
|
+
* `true` and `"base-3"` match `.bfc-base-3-bg`.
|
|
12
|
+
* `"theme-fade"` matches `.bfc-theme-fade-bg`.
|
|
13
|
+
*/
|
|
14
|
+
background?: BoxProps["background"];
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Soft shaded area behind one line of text or one see-through control, so it
|
|
18
|
+
* stays readable on a busy background like the twinkle background. Wrap each
|
|
19
|
+
* line on its own, not a group of lines. Experimental: AI-generated, not
|
|
20
|
+
* reviewed line by line.
|
|
21
|
+
*
|
|
22
|
+
* @see https://bifrost.intility.com/react/experimental/backdrop
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* <h1 className="bf-h1">
|
|
26
|
+
* <Backdrop>Platform Manager</Backdrop>
|
|
27
|
+
* </h1>
|
|
28
|
+
* <Backdrop background="base-3">On a base-3 background</Backdrop>
|
|
29
|
+
*/
|
|
30
|
+
declare const Backdrop: ({ children, background }: BackdropProps) => import("react").JSX.Element;
|
|
31
|
+
export default Backdrop;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { c as _c } from "react-compiler-runtime";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
/**
|
|
4
|
+
* Soft shaded area behind one line of text or one see-through control, so it
|
|
5
|
+
* stays readable on a busy background like the twinkle background. Wrap each
|
|
6
|
+
* line on its own, not a group of lines. Experimental: AI-generated, not
|
|
7
|
+
* reviewed line by line.
|
|
8
|
+
*
|
|
9
|
+
* @see https://bifrost.intility.com/react/experimental/backdrop
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* <h1 className="bf-h1">
|
|
13
|
+
* <Backdrop>Platform Manager</Backdrop>
|
|
14
|
+
* </h1>
|
|
15
|
+
* <Backdrop background="base-3">On a base-3 background</Backdrop>
|
|
16
|
+
*/
|
|
17
|
+
const Backdrop = t0 => {
|
|
18
|
+
const $ = _c(6);
|
|
19
|
+
const {
|
|
20
|
+
children,
|
|
21
|
+
background: t1
|
|
22
|
+
} = t0;
|
|
23
|
+
const background = t1 === undefined ? "base" : t1;
|
|
24
|
+
const bg = `bfc-${background === true ? "base-3" : background || "base"}-bg`;
|
|
25
|
+
const t2 = `bfx-backdrop ${bg}`;
|
|
26
|
+
const t3 = `bfx-backdrop-shade ${bg}`;
|
|
27
|
+
let t4;
|
|
28
|
+
if ($[0] !== t3) {
|
|
29
|
+
t4 = /*#__PURE__*/_jsx("span", {
|
|
30
|
+
"aria-hidden": true,
|
|
31
|
+
className: t3
|
|
32
|
+
});
|
|
33
|
+
$[0] = t3;
|
|
34
|
+
$[1] = t4;
|
|
35
|
+
} else {
|
|
36
|
+
t4 = $[1];
|
|
37
|
+
}
|
|
38
|
+
let t5;
|
|
39
|
+
if ($[2] !== children || $[3] !== t2 || $[4] !== t4) {
|
|
40
|
+
t5 = /*#__PURE__*/_jsxs("span", {
|
|
41
|
+
className: t2,
|
|
42
|
+
children: [t4, children]
|
|
43
|
+
});
|
|
44
|
+
$[2] = children;
|
|
45
|
+
$[3] = t2;
|
|
46
|
+
$[4] = t4;
|
|
47
|
+
$[5] = t5;
|
|
48
|
+
} else {
|
|
49
|
+
t5 = $[5];
|
|
50
|
+
}
|
|
51
|
+
return t5;
|
|
52
|
+
};
|
|
53
|
+
export default Backdrop;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from "./Backdrop.js";
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
export type FrontpageHeaderProps = {
|
|
3
|
+
/**
|
|
4
|
+
* The name of the app or module. Rendered as the page's `h1`, so use the
|
|
5
|
+
* component once per page.
|
|
6
|
+
*/
|
|
7
|
+
title: ReactNode;
|
|
8
|
+
/** One line under the title */
|
|
9
|
+
subtitle?: ReactNode;
|
|
10
|
+
/**
|
|
11
|
+
* Image shown to the left of the title, like `<img src="/logo.svg" alt="" />`.
|
|
12
|
+
* It is shown 72px high and hidden on small screens. Use an empty `alt` when
|
|
13
|
+
* the title already names the app.
|
|
14
|
+
*/
|
|
15
|
+
logo?: ReactNode;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Header for the front page of a Platform Manager module: logo, title and
|
|
19
|
+
* subtitle. The title is the page's `h1`. To keep the title and subtitle
|
|
20
|
+
* readable on the twinkle background, wrap each in a `Backdrop`.
|
|
21
|
+
* Experimental: AI-generated, not reviewed line by line.
|
|
22
|
+
*
|
|
23
|
+
* @see https://bifrost.intility.com/react/experimental/frontpage-header
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* <FrontpageHeader
|
|
27
|
+
* logo={<img src="/logo.svg" alt="" />}
|
|
28
|
+
* title={<Backdrop>Platform Manager</Backdrop>}
|
|
29
|
+
* subtitle={<Backdrop>An operational control plane</Backdrop>}
|
|
30
|
+
* />
|
|
31
|
+
*/
|
|
32
|
+
declare const FrontpageHeader: ({ title, subtitle, logo }: FrontpageHeaderProps) => import("react").JSX.Element;
|
|
33
|
+
export default FrontpageHeader;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { c as _c } from "react-compiler-runtime";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
/**
|
|
4
|
+
* Header for the front page of a Platform Manager module: logo, title and
|
|
5
|
+
* subtitle. The title is the page's `h1`. To keep the title and subtitle
|
|
6
|
+
* readable on the twinkle background, wrap each in a `Backdrop`.
|
|
7
|
+
* Experimental: AI-generated, not reviewed line by line.
|
|
8
|
+
*
|
|
9
|
+
* @see https://bifrost.intility.com/react/experimental/frontpage-header
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* <FrontpageHeader
|
|
13
|
+
* logo={<img src="/logo.svg" alt="" />}
|
|
14
|
+
* title={<Backdrop>Platform Manager</Backdrop>}
|
|
15
|
+
* subtitle={<Backdrop>An operational control plane</Backdrop>}
|
|
16
|
+
* />
|
|
17
|
+
*/
|
|
18
|
+
const FrontpageHeader = t0 => {
|
|
19
|
+
const $ = _c(12);
|
|
20
|
+
const {
|
|
21
|
+
title,
|
|
22
|
+
subtitle,
|
|
23
|
+
logo
|
|
24
|
+
} = t0;
|
|
25
|
+
let t1;
|
|
26
|
+
if ($[0] !== logo) {
|
|
27
|
+
t1 = logo && /*#__PURE__*/_jsx("span", {
|
|
28
|
+
className: "bfx-frontpage-header-logo from-small",
|
|
29
|
+
children: logo
|
|
30
|
+
});
|
|
31
|
+
$[0] = logo;
|
|
32
|
+
$[1] = t1;
|
|
33
|
+
} else {
|
|
34
|
+
t1 = $[1];
|
|
35
|
+
}
|
|
36
|
+
let t2;
|
|
37
|
+
if ($[2] !== title) {
|
|
38
|
+
t2 = /*#__PURE__*/_jsx("h1", {
|
|
39
|
+
className: "bf-h1",
|
|
40
|
+
children: title
|
|
41
|
+
});
|
|
42
|
+
$[2] = title;
|
|
43
|
+
$[3] = t2;
|
|
44
|
+
} else {
|
|
45
|
+
t2 = $[3];
|
|
46
|
+
}
|
|
47
|
+
let t3;
|
|
48
|
+
if ($[4] !== subtitle) {
|
|
49
|
+
t3 = subtitle && /*#__PURE__*/_jsx("div", {
|
|
50
|
+
className: "bf-large",
|
|
51
|
+
children: subtitle
|
|
52
|
+
});
|
|
53
|
+
$[4] = subtitle;
|
|
54
|
+
$[5] = t3;
|
|
55
|
+
} else {
|
|
56
|
+
t3 = $[5];
|
|
57
|
+
}
|
|
58
|
+
let t4;
|
|
59
|
+
if ($[6] !== t2 || $[7] !== t3) {
|
|
60
|
+
t4 = /*#__PURE__*/_jsxs("div", {
|
|
61
|
+
className: "bfx-frontpage-header-text",
|
|
62
|
+
children: [t2, t3]
|
|
63
|
+
});
|
|
64
|
+
$[6] = t2;
|
|
65
|
+
$[7] = t3;
|
|
66
|
+
$[8] = t4;
|
|
67
|
+
} else {
|
|
68
|
+
t4 = $[8];
|
|
69
|
+
}
|
|
70
|
+
let t5;
|
|
71
|
+
if ($[9] !== t1 || $[10] !== t4) {
|
|
72
|
+
t5 = /*#__PURE__*/_jsxs("div", {
|
|
73
|
+
className: "bfx-frontpage-header",
|
|
74
|
+
children: [t1, t4]
|
|
75
|
+
});
|
|
76
|
+
$[9] = t1;
|
|
77
|
+
$[10] = t4;
|
|
78
|
+
$[11] = t5;
|
|
79
|
+
} else {
|
|
80
|
+
t5 = $[11];
|
|
81
|
+
}
|
|
82
|
+
return t5;
|
|
83
|
+
};
|
|
84
|
+
export default FrontpageHeader;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from "./FrontpageHeader.js";
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export type TwinkleBackgroundProps = {
|
|
2
|
+
/**
|
|
3
|
+
* The color of the dots. `"theme"` follows the Bifrost theme of the app, and
|
|
4
|
+
* the other values override it.
|
|
5
|
+
* @default "theme"
|
|
6
|
+
*/
|
|
7
|
+
color?: "theme" | "teal" | "purple" | "pink" | "yellow" | "red" | "green";
|
|
8
|
+
/**
|
|
9
|
+
* Fills the whole container with evenly spread dots, with no fade, for a
|
|
10
|
+
* background inside a card or a `Box`. By default the dots cover the top 40%
|
|
11
|
+
* of the container and fade out down the page.
|
|
12
|
+
* @default false
|
|
13
|
+
*/
|
|
14
|
+
fill?: boolean;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Animated dot grid in the Bifrost theme color, for the front page of a
|
|
18
|
+
* Platform Manager module. It fades out down the page and reacts to hover and
|
|
19
|
+
* clicks. Render it as the first child of a container with
|
|
20
|
+
* `position: relative` and `isolation: isolate`; it fills the top 40% of that
|
|
21
|
+
* container, behind its content, or all of it with `fill`. No dot is cut off
|
|
22
|
+
* by the edge of the container. Experimental: AI-generated, not reviewed line
|
|
23
|
+
* by line.
|
|
24
|
+
*
|
|
25
|
+
* @see https://bifrost.intility.com/react/experimental/twinkle-background
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* <div style={{ position: "relative", isolation: "isolate" }}>
|
|
29
|
+
* <TwinkleBackground />
|
|
30
|
+
* <Backdrop>
|
|
31
|
+
* <h1 className="bf-h1">Platform Manager</h1>
|
|
32
|
+
* </Backdrop>
|
|
33
|
+
* </div>
|
|
34
|
+
*/
|
|
35
|
+
declare const TwinkleBackground: ({ color, fill, }: TwinkleBackgroundProps) => import("react").JSX.Element;
|
|
36
|
+
export default TwinkleBackground;
|
|
@@ -0,0 +1,389 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { c as _c } from "react-compiler-runtime";
|
|
4
|
+
import { useEffect, useRef, useSyncExternalStore } from "react";
|
|
5
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
6
|
+
// Not props, so every front page looks the same
|
|
7
|
+
const SPACING = 16;
|
|
8
|
+
// Opacity at the dimmest point of a twinkle
|
|
9
|
+
const MIN_ALPHA = 0.2;
|
|
10
|
+
// Hover glow reach in CSS pixels, ripple speed in CSS pixels per second and
|
|
11
|
+
// ripple life in seconds
|
|
12
|
+
const RADIUS = 240;
|
|
13
|
+
const RIPPLE_SPEED = 620;
|
|
14
|
+
const RIPPLE_LIFE = 1.8;
|
|
15
|
+
const CLICK_STRENGTH = 0.5;
|
|
16
|
+
// Resting opacity. Hover and ripples lift dots above it, up to fully opaque.
|
|
17
|
+
const OPACITY = {
|
|
18
|
+
light: 0.4,
|
|
19
|
+
dark: 0.8
|
|
20
|
+
};
|
|
21
|
+
// Dots are filled in batches of equal opacity, one path per batch instead of
|
|
22
|
+
// one per dot. The steps are too small to see.
|
|
23
|
+
const ALPHA_STEPS = 48;
|
|
24
|
+
// Reading the computed color forces a style recalculation, so not every frame
|
|
25
|
+
const STYLE_INTERVAL = 250;
|
|
26
|
+
// Caps the animation at about 60fps on high refresh rate screens
|
|
27
|
+
const FRAME_INTERVAL = 1000 / 60 - 2;
|
|
28
|
+
// Clicks on these don't start a ripple. tabindex="-1" is often set on a whole
|
|
29
|
+
// container like <main>, so it doesn't count.
|
|
30
|
+
const INTERACTIVE = 'a, button, input, select, textarea, label, summary, [tabindex]:not([tabindex="-1"]), [contenteditable],' + "[role=button], [role=link], [role=tab], [role=checkbox], [role=radio], [role=switch]," + "[role=menuitem], [role=option], [role=combobox], [role=slider]";
|
|
31
|
+
const TAU = Math.PI * 2;
|
|
32
|
+
|
|
33
|
+
// Reduced motion is the only way to stop the twinkle (WCAG 2.2.2), so it is
|
|
34
|
+
// followed live
|
|
35
|
+
const REDUCED_MOTION = "(prefers-reduced-motion: reduce)";
|
|
36
|
+
const subscribeReducedMotion = onChange => {
|
|
37
|
+
const query = window.matchMedia(REDUCED_MOTION);
|
|
38
|
+
query.addEventListener("change", onChange);
|
|
39
|
+
return () => query.removeEventListener("change", onChange);
|
|
40
|
+
};
|
|
41
|
+
const useReducedMotion = () => {
|
|
42
|
+
return useSyncExternalStore(subscribeReducedMotion, _temp, _temp2);
|
|
43
|
+
};
|
|
44
|
+
const within = (rect, x, y) => x >= 0 && x <= rect.width && y >= 0 && y <= rect.height;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Animated dot grid in the Bifrost theme color, for the front page of a
|
|
48
|
+
* Platform Manager module. It fades out down the page and reacts to hover and
|
|
49
|
+
* clicks. Render it as the first child of a container with
|
|
50
|
+
* `position: relative` and `isolation: isolate`; it fills the top 40% of that
|
|
51
|
+
* container, behind its content, or all of it with `fill`. No dot is cut off
|
|
52
|
+
* by the edge of the container. Experimental: AI-generated, not reviewed line
|
|
53
|
+
* by line.
|
|
54
|
+
*
|
|
55
|
+
* @see https://bifrost.intility.com/react/experimental/twinkle-background
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* <div style={{ position: "relative", isolation: "isolate" }}>
|
|
59
|
+
* <TwinkleBackground />
|
|
60
|
+
* <Backdrop>
|
|
61
|
+
* <h1 className="bf-h1">Platform Manager</h1>
|
|
62
|
+
* </Backdrop>
|
|
63
|
+
* </div>
|
|
64
|
+
*/
|
|
65
|
+
const TwinkleBackground = t0 => {
|
|
66
|
+
const $ = _c(6);
|
|
67
|
+
const {
|
|
68
|
+
color: t1,
|
|
69
|
+
fill: t2
|
|
70
|
+
} = t0;
|
|
71
|
+
const color = t1 === undefined ? "theme" : t1;
|
|
72
|
+
const fill = t2 === undefined ? false : t2;
|
|
73
|
+
const canvasRef = useRef(null);
|
|
74
|
+
const still = useReducedMotion();
|
|
75
|
+
const colorClass = color === "red" || color === "green" ? ` bfx-twinkle-background-${color}` : color === "theme" ? "" : ` bf-theme-${color}`;
|
|
76
|
+
let t3;
|
|
77
|
+
let t4;
|
|
78
|
+
if ($[0] !== fill || $[1] !== still) {
|
|
79
|
+
t3 = () => {
|
|
80
|
+
const canvas = canvasRef.current;
|
|
81
|
+
const ctx = canvas?.getContext("2d");
|
|
82
|
+
if (!canvas || !ctx) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
const forcedColors = window.matchMedia("(forced-colors: active)");
|
|
86
|
+
const pointer = {
|
|
87
|
+
x: 0,
|
|
88
|
+
y: 0,
|
|
89
|
+
on: 0
|
|
90
|
+
};
|
|
91
|
+
const cursor = {
|
|
92
|
+
x: 0,
|
|
93
|
+
y: 0,
|
|
94
|
+
over: false
|
|
95
|
+
};
|
|
96
|
+
const clicks = [];
|
|
97
|
+
let w = 0;
|
|
98
|
+
let h = 0;
|
|
99
|
+
let cols = 1;
|
|
100
|
+
let offsetX = 0;
|
|
101
|
+
let offsetY = 0;
|
|
102
|
+
let span = 0;
|
|
103
|
+
let rand = new Float32Array(0);
|
|
104
|
+
const seed = Math.random() * 4294967296 | 0;
|
|
105
|
+
const noise = (col, row, k) => {
|
|
106
|
+
let n = Math.imul(col + 1, 2654435761) ^ Math.imul(row + 1, 2246822507) ^ Math.imul(k + 1, 3266489909) ^ seed;
|
|
107
|
+
n = Math.imul(n ^ n >>> 15, 739982445);
|
|
108
|
+
n = Math.imul(n ^ n >>> 12, 695872825);
|
|
109
|
+
return ((n ^ n >>> 15) >>> 0) / 4294967296;
|
|
110
|
+
};
|
|
111
|
+
let clock = 0;
|
|
112
|
+
let last = 0;
|
|
113
|
+
let raf = 0;
|
|
114
|
+
let visible = false;
|
|
115
|
+
let dotColor = "";
|
|
116
|
+
let base = OPACITY.light;
|
|
117
|
+
let styleAt = -Infinity;
|
|
118
|
+
const readStyle = () => {
|
|
119
|
+
const style = getComputedStyle(canvas);
|
|
120
|
+
dotColor = style.color;
|
|
121
|
+
base = style.colorScheme.includes("dark") ? OPACITY.dark : OPACITY.light;
|
|
122
|
+
};
|
|
123
|
+
const batches = Array.from({
|
|
124
|
+
length: ALPHA_STEPS
|
|
125
|
+
}, _temp3);
|
|
126
|
+
const draw = () => {
|
|
127
|
+
ctx.clearRect(0, 0, w, h);
|
|
128
|
+
if (forcedColors.matches || h <= 0) {
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
ctx.fillStyle = dotColor;
|
|
132
|
+
for (let i = 0; i < rand.length; i = i + 2, i) {
|
|
133
|
+
const r1 = rand[i];
|
|
134
|
+
const r2 = rand[i + 1];
|
|
135
|
+
const x = offsetX + i / 2 % cols * SPACING;
|
|
136
|
+
const y = offsetY + Math.floor(i / 2 / cols) * SPACING;
|
|
137
|
+
const tw = 0.5 + 0.5 * Math.sin(clock * 0.48 * (1 + r1 * 3) + r2 * TAU);
|
|
138
|
+
let alpha = MIN_ALPHA + (1 - MIN_ALPHA) * tw * tw;
|
|
139
|
+
let size = 1.4 * (1 - 0.3 * r2) * (0.8 + 0.4 * tw);
|
|
140
|
+
if (pointer.on > 0.001) {
|
|
141
|
+
const d = Math.hypot(x - pointer.x, y - pointer.y);
|
|
142
|
+
const near = d < RADIUS ? 1 - d / RADIUS : 0;
|
|
143
|
+
alpha = alpha * (1 - 0.3 * pointer.on + near * near * 1.8 * pointer.on);
|
|
144
|
+
}
|
|
145
|
+
for (const c of clicks) {
|
|
146
|
+
const age = clock - c.t;
|
|
147
|
+
const life = 1 - age / RIPPLE_LIFE;
|
|
148
|
+
const d_0 = Math.hypot(x - c.x, y - c.y);
|
|
149
|
+
const ring = Math.exp(-((d_0 - age * RIPPLE_SPEED) ** 2) / 4232) * life * life * CLICK_STRENGTH;
|
|
150
|
+
alpha = alpha + ring * 2.6;
|
|
151
|
+
size = size + ring * 1.4;
|
|
152
|
+
}
|
|
153
|
+
const fade = fill || span <= 0 ? 0 : (y - offsetY) / span;
|
|
154
|
+
alpha = alpha * (1 - fade * fade) * base;
|
|
155
|
+
const step = Math.round(Math.min(1, alpha) * ALPHA_STEPS);
|
|
156
|
+
if (step < 1) {
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
batches[step - 1].push(x, y, size);
|
|
160
|
+
}
|
|
161
|
+
batches.forEach((dots, i_0) => {
|
|
162
|
+
if (!dots.length) {
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
ctx.globalAlpha = (i_0 + 1) / ALPHA_STEPS;
|
|
166
|
+
ctx.beginPath();
|
|
167
|
+
for (let j = 0; j < dots.length; j = j + 3, j) {
|
|
168
|
+
ctx.moveTo(dots[j] + dots[j + 2], dots[j + 1]);
|
|
169
|
+
ctx.arc(dots[j], dots[j + 1], dots[j + 2], 0, TAU);
|
|
170
|
+
}
|
|
171
|
+
ctx.fill();
|
|
172
|
+
dots.length = 0;
|
|
173
|
+
});
|
|
174
|
+
};
|
|
175
|
+
const redraw = () => {
|
|
176
|
+
if (h <= 0) {
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
readStyle();
|
|
180
|
+
draw();
|
|
181
|
+
};
|
|
182
|
+
const tick = now => {
|
|
183
|
+
if (forcedColors.matches) {
|
|
184
|
+
ctx.clearRect(0, 0, w, h);
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
raf = requestAnimationFrame(tick);
|
|
188
|
+
if (last && now - last < FRAME_INTERVAL) {
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
if (now - styleAt > STYLE_INTERVAL) {
|
|
192
|
+
readStyle();
|
|
193
|
+
styleAt = now;
|
|
194
|
+
}
|
|
195
|
+
clock = clock + (last ? Math.min(0.05, (now - last) / 1000) : 0);
|
|
196
|
+
clock;
|
|
197
|
+
last = now;
|
|
198
|
+
while (clicks.length && clock - clicks[0].t > RIPPLE_LIFE) {
|
|
199
|
+
clicks.shift();
|
|
200
|
+
}
|
|
201
|
+
let inside = false;
|
|
202
|
+
if (cursor.over) {
|
|
203
|
+
const rect = canvas.getBoundingClientRect();
|
|
204
|
+
const x_0 = cursor.x - rect.left;
|
|
205
|
+
const y_0 = cursor.y - rect.top;
|
|
206
|
+
inside = within(rect, x_0, y_0);
|
|
207
|
+
if (pointer.on < 0.01) {
|
|
208
|
+
pointer.x = x_0;
|
|
209
|
+
pointer.y = y_0;
|
|
210
|
+
}
|
|
211
|
+
pointer.x = pointer.x + (x_0 - pointer.x) * 0.18;
|
|
212
|
+
pointer.y = pointer.y + (y_0 - pointer.y) * 0.18;
|
|
213
|
+
}
|
|
214
|
+
pointer.on = pointer.on + ((inside ? 1 : 0) - pointer.on) * 0.08;
|
|
215
|
+
draw();
|
|
216
|
+
};
|
|
217
|
+
const play = () => {
|
|
218
|
+
cancelAnimationFrame(raf);
|
|
219
|
+
last = 0;
|
|
220
|
+
raf = requestAnimationFrame(tick);
|
|
221
|
+
};
|
|
222
|
+
const resize = () => {
|
|
223
|
+
const rect_0 = canvas.getBoundingClientRect();
|
|
224
|
+
const dpr = window.devicePixelRatio || 1;
|
|
225
|
+
w = rect_0.width;
|
|
226
|
+
h = rect_0.height;
|
|
227
|
+
canvas.width = Math.round(w * dpr);
|
|
228
|
+
canvas.height = Math.round(h * dpr);
|
|
229
|
+
ctx.setTransform(w ? canvas.width / w : 1, 0, 0, h ? canvas.height / h : 1, 0, 0);
|
|
230
|
+
cols = Math.max(1, Math.floor(w / SPACING));
|
|
231
|
+
const rows = Math.max(1, Math.floor(h / SPACING));
|
|
232
|
+
span = (rows - 1) * SPACING;
|
|
233
|
+
offsetX = (w - (cols - 1) * SPACING) / 2;
|
|
234
|
+
offsetY = (h - span) / 2;
|
|
235
|
+
rand = Float32Array.from({
|
|
236
|
+
length: cols * rows * 2
|
|
237
|
+
}, (_, i_1) => noise((i_1 >> 1) % cols, Math.floor(i_1 / 2 / cols), i_1 & 1));
|
|
238
|
+
redraw();
|
|
239
|
+
};
|
|
240
|
+
let unwatchDensity = _temp4;
|
|
241
|
+
const watchDensity = () => {
|
|
242
|
+
const query = window.matchMedia(`(resolution: ${window.devicePixelRatio}dppx)`);
|
|
243
|
+
const onChange = () => {
|
|
244
|
+
resize();
|
|
245
|
+
watchDensity();
|
|
246
|
+
};
|
|
247
|
+
query.addEventListener("change", onChange, {
|
|
248
|
+
once: true
|
|
249
|
+
});
|
|
250
|
+
unwatchDensity = () => query.removeEventListener("change", onChange);
|
|
251
|
+
};
|
|
252
|
+
const onMove = e => {
|
|
253
|
+
cursor.x = e.clientX;
|
|
254
|
+
cursor.y = e.clientY;
|
|
255
|
+
cursor.over = true;
|
|
256
|
+
};
|
|
257
|
+
const onLeave = () => {
|
|
258
|
+
cursor.over = false;
|
|
259
|
+
};
|
|
260
|
+
const onRelease = e_0 => {
|
|
261
|
+
if (e_0.pointerType !== "mouse") {
|
|
262
|
+
onLeave();
|
|
263
|
+
}
|
|
264
|
+
};
|
|
265
|
+
const onDown = e_1 => {
|
|
266
|
+
const el = e_1.target;
|
|
267
|
+
if (e_1.button !== 0 || !(el instanceof Element)) {
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
if (!canvas.parentElement?.contains(el) || el.closest(INTERACTIVE)) {
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
const rect_1 = canvas.getBoundingClientRect();
|
|
274
|
+
const x_1 = e_1.clientX - rect_1.left;
|
|
275
|
+
const y_1 = e_1.clientY - rect_1.top;
|
|
276
|
+
if (!within(rect_1, x_1, y_1)) {
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
if (clicks.length >= 8) {
|
|
280
|
+
clicks.shift();
|
|
281
|
+
}
|
|
282
|
+
clicks.push({
|
|
283
|
+
x: x_1,
|
|
284
|
+
y: y_1,
|
|
285
|
+
t: clock
|
|
286
|
+
});
|
|
287
|
+
};
|
|
288
|
+
const resizeObserver = new ResizeObserver(resize);
|
|
289
|
+
resizeObserver.observe(canvas);
|
|
290
|
+
watchDensity();
|
|
291
|
+
const systemMode = window.matchMedia("(prefers-color-scheme: dark)");
|
|
292
|
+
const attributes = new MutationObserver(redraw);
|
|
293
|
+
const onForcedColors = () => {
|
|
294
|
+
if (still) {
|
|
295
|
+
redraw();
|
|
296
|
+
} else {
|
|
297
|
+
if (visible) {
|
|
298
|
+
play();
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
};
|
|
302
|
+
forcedColors.addEventListener("change", onForcedColors);
|
|
303
|
+
if (still) {
|
|
304
|
+
systemMode.addEventListener("change", redraw);
|
|
305
|
+
for (let el_0 = canvas; el_0; el_0 = el_0.parentElement) {
|
|
306
|
+
attributes.observe(el_0, {
|
|
307
|
+
attributes: true,
|
|
308
|
+
attributeFilter: ["class", "style", "data-bf-color-mode"]
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
const visibility = new IntersectionObserver(t5 => {
|
|
313
|
+
const [entry] = t5;
|
|
314
|
+
visible = entry.isIntersecting;
|
|
315
|
+
if (visible) {
|
|
316
|
+
play();
|
|
317
|
+
} else {
|
|
318
|
+
cancelAnimationFrame(raf);
|
|
319
|
+
}
|
|
320
|
+
});
|
|
321
|
+
if (!still) {
|
|
322
|
+
visibility.observe(canvas);
|
|
323
|
+
window.addEventListener("pointermove", onMove, {
|
|
324
|
+
passive: true
|
|
325
|
+
});
|
|
326
|
+
window.addEventListener("pointerdown", onDown, {
|
|
327
|
+
passive: true
|
|
328
|
+
});
|
|
329
|
+
window.addEventListener("pointerup", onRelease, {
|
|
330
|
+
passive: true
|
|
331
|
+
});
|
|
332
|
+
window.addEventListener("pointercancel", onLeave, {
|
|
333
|
+
passive: true
|
|
334
|
+
});
|
|
335
|
+
document.addEventListener("mouseleave", onLeave);
|
|
336
|
+
window.addEventListener("blur", onLeave);
|
|
337
|
+
}
|
|
338
|
+
return () => {
|
|
339
|
+
cancelAnimationFrame(raf);
|
|
340
|
+
resizeObserver.disconnect();
|
|
341
|
+
unwatchDensity();
|
|
342
|
+
systemMode.removeEventListener("change", redraw);
|
|
343
|
+
forcedColors.removeEventListener("change", onForcedColors);
|
|
344
|
+
attributes.disconnect();
|
|
345
|
+
visibility.disconnect();
|
|
346
|
+
window.removeEventListener("pointermove", onMove);
|
|
347
|
+
window.removeEventListener("pointerdown", onDown);
|
|
348
|
+
window.removeEventListener("pointerup", onRelease);
|
|
349
|
+
window.removeEventListener("pointercancel", onLeave);
|
|
350
|
+
document.removeEventListener("mouseleave", onLeave);
|
|
351
|
+
window.removeEventListener("blur", onLeave);
|
|
352
|
+
};
|
|
353
|
+
};
|
|
354
|
+
t4 = [still, fill];
|
|
355
|
+
$[0] = fill;
|
|
356
|
+
$[1] = still;
|
|
357
|
+
$[2] = t3;
|
|
358
|
+
$[3] = t4;
|
|
359
|
+
} else {
|
|
360
|
+
t3 = $[2];
|
|
361
|
+
t4 = $[3];
|
|
362
|
+
}
|
|
363
|
+
useEffect(t3, t4);
|
|
364
|
+
const t5 = `bfx-twinkle-background${fill ? " bfx-twinkle-background-fill" : ""}${colorClass}`;
|
|
365
|
+
let t6;
|
|
366
|
+
if ($[4] !== t5) {
|
|
367
|
+
t6 = /*#__PURE__*/_jsx("canvas", {
|
|
368
|
+
ref: canvasRef,
|
|
369
|
+
"aria-hidden": true,
|
|
370
|
+
className: t5
|
|
371
|
+
});
|
|
372
|
+
$[4] = t5;
|
|
373
|
+
$[5] = t6;
|
|
374
|
+
} else {
|
|
375
|
+
t6 = $[5];
|
|
376
|
+
}
|
|
377
|
+
return t6;
|
|
378
|
+
};
|
|
379
|
+
export default TwinkleBackground;
|
|
380
|
+
function _temp() {
|
|
381
|
+
return window.matchMedia(REDUCED_MOTION).matches;
|
|
382
|
+
}
|
|
383
|
+
function _temp2() {
|
|
384
|
+
return false;
|
|
385
|
+
}
|
|
386
|
+
function _temp3() {
|
|
387
|
+
return [];
|
|
388
|
+
}
|
|
389
|
+
function _temp4() {}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from "./TwinkleBackground.js";
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
package/package.json
CHANGED
|
@@ -1,11 +1,61 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@intility/bifrost-experimental",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "",
|
|
5
|
-
"license": "MIT",
|
|
6
|
-
"author": "Intility AS",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Experimental, AI-generated React components for Intility's design system, Bifrost.",
|
|
7
5
|
"type": "module",
|
|
8
|
-
"main": "index.js",
|
|
6
|
+
"main": "dist/index.js",
|
|
9
7
|
"scripts": {
|
|
10
|
-
|
|
8
|
+
"build:css": "postcss src/bifrost-experimental.css --dir dist --use postcss-import --no-map",
|
|
9
|
+
"build:module": "babel ./src -d dist --extensions .ts,.tsx --ignore '**/*.test.*,**/*.d.ts' --root-mode upward",
|
|
10
|
+
"build:types": "tsc --project tsconfig.build.json",
|
|
11
|
+
"watch:css": "npm run build:css -- --watch",
|
|
12
|
+
"watch:module": "npm run build:module -- --watch",
|
|
13
|
+
"watch:types": "npm run build:types -- --watch --preserveWatchOutput",
|
|
14
|
+
"clean": "rimraf dist",
|
|
15
|
+
"lint": "eslint \"./src/**/*.{ts,tsx}\" && stylelint \"src/**/*.css\"",
|
|
16
|
+
"typecheck": "tsc --noEmit"
|
|
17
|
+
},
|
|
18
|
+
"exports": {
|
|
19
|
+
"./package.json": "./package.json",
|
|
20
|
+
"./bifrost-experimental.css": "./dist/bifrost-experimental.css",
|
|
21
|
+
".": "./dist/index.js",
|
|
22
|
+
"./*": "./dist/components/*/index.js"
|
|
23
|
+
},
|
|
24
|
+
"homepage": "https://bifrost.intility.com/react/experimental",
|
|
25
|
+
"keywords": [
|
|
26
|
+
"react",
|
|
27
|
+
"typescript",
|
|
28
|
+
"intility",
|
|
29
|
+
"design system",
|
|
30
|
+
"bifrost",
|
|
31
|
+
"experimental"
|
|
32
|
+
],
|
|
33
|
+
"author": "Intility AS",
|
|
34
|
+
"license": "MIT",
|
|
35
|
+
"repository": {
|
|
36
|
+
"type": "git",
|
|
37
|
+
"url": "git+https://github.com/intility/bifrost.git",
|
|
38
|
+
"directory": "packages/bifrost-experimental"
|
|
39
|
+
},
|
|
40
|
+
"publishConfig": {
|
|
41
|
+
"registry": "https://registry.npmjs.org/",
|
|
42
|
+
"access": "public"
|
|
43
|
+
},
|
|
44
|
+
"peerDependencies": {
|
|
45
|
+
"@intility/bifrost-react": "^6",
|
|
46
|
+
"react": "^17 || ^18 || ^19",
|
|
47
|
+
"react-dom": "^17 || ^18 || ^19"
|
|
48
|
+
},
|
|
49
|
+
"devDependencies": {
|
|
50
|
+
"@intility/bifrost-react": "^6.23.0"
|
|
51
|
+
},
|
|
52
|
+
"dependencies": {
|
|
53
|
+
"react-compiler-runtime": "^1.0.0"
|
|
54
|
+
},
|
|
55
|
+
"files": [
|
|
56
|
+
"CHANGELOG.md",
|
|
57
|
+
"README.md",
|
|
58
|
+
"dist/**/*",
|
|
59
|
+
"!dist/**/*.test.*"
|
|
60
|
+
]
|
|
11
61
|
}
|
package/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
console.log("hey there");
|