@cloudgrid-io/ui 0.14.0 → 0.15.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.
@@ -0,0 +1,16 @@
1
+ export interface CelebrationProps {
2
+ /**
3
+ * Called once, when the burst has finished and the overlay is gone. Under
4
+ * reduced motion it is called immediately instead.
5
+ */
6
+ onDone?: () => void;
7
+ /** Milliseconds. Read once at mount, clamped. */
8
+ duration?: number;
9
+ /** Read once at mount, clamped. */
10
+ particleCount?: number;
11
+ /** Applied to the overlay canvas. */
12
+ className?: string;
13
+ }
14
+ declare function Celebration({ onDone, duration, particleCount, className }: CelebrationProps): null;
15
+ export { Celebration };
16
+ //# sourceMappingURL=celebration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"celebration.d.ts","sourceRoot":"","sources":["../../src/blocks/celebration.tsx"],"names":[],"mappings":"AAgIA,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,IAAI,CAAA;IACnB,iDAAiD;IACjD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,mCAAmC;IACnC,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,qCAAqC;IACrC,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAwCD,iBAAS,WAAW,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,EAAE,SAAS,EAAE,EAAE,gBAAgB,QAqJpF;AAED,OAAO,EAAE,WAAW,EAAE,CAAA"}
@@ -0,0 +1,259 @@
1
+ "use client";
2
+ import * as React from "react";
3
+ /**
4
+ * One burst of confetti, and then it is gone.
5
+ *
6
+ * ## Why this exists (#160)
7
+ *
8
+ * The onboarding welcome screen wanted a celebration. Written inline in the
9
+ * console it would be a canvas animation carrying its own hardcoded palette,
10
+ * living beside the screen that happens to use it first, and a second screen
11
+ * that wanted one would get a second copy. So it is a component, and its colours
12
+ * come out of the token layer like everything else here.
13
+ *
14
+ * ## What it does
15
+ *
16
+ * Mounts, paints a single burst over the viewport, removes itself, and calls
17
+ * `onDone`. It never loops, never fires twice, and never restarts because its
18
+ * parent re-rendered or handed it a new prop. Mount it to celebrate; unmount is
19
+ * not required, since it takes its own overlay away when the burst is over.
20
+ *
21
+ * ```tsx
22
+ * {justPlugged ? <Celebration onDone={() => setJustPlugged(false)} /> : null}
23
+ * ```
24
+ *
25
+ * ## Reduced motion
26
+ *
27
+ * `prefers-reduced-motion: reduce` renders nothing at all — no canvas is
28
+ * created — and `onDone` fires immediately, on the same tick as the mount. That
29
+ * second half is the important one: a caller may gate a screen transition on
30
+ * `onDone`, and it must not sit for 1.8s waiting for an animation that is never
31
+ * going to run. The celebration is decoration; the screen is the message.
32
+ *
33
+ * A **static accent** — the same burst painted once and held, rather than
34
+ * animated — is the obvious future alternative, and it would slot in here with
35
+ * no API change: same mount, same `onDone`, one `drawFrame` call instead of a
36
+ * loop. It is deliberately not shipped yet, because an accent that only
37
+ * reduced-motion users ever see is a second design and nobody has drawn it.
38
+ *
39
+ * ## Colour
40
+ *
41
+ * `--cg-primary`, `--cg-secondary` and `--cg-tertiary`, resolved off the
42
+ * document root once at mount. Canvas takes colour strings rather than CSS
43
+ * variables, so the read has to happen somewhere; doing it at mount keeps it off
44
+ * the per-frame path and means a re-theme moves the confetti with everything
45
+ * else. The ROOT is read deliberately, not the nearest surface: this overlay
46
+ * belongs to the viewport, not to whichever panel mounted it.
47
+ *
48
+ * If none of the three resolve — a consumer who never imported `tokens.css` —
49
+ * the fallback is the overlay's own inherited text colour. Never a hardcoded
50
+ * one: a brand effect that invents a brand is exactly what the token layer
51
+ * exists to prevent.
52
+ *
53
+ * ## What it costs
54
+ *
55
+ * Nothing at import time, no dependency beyond React, and no node in the
56
+ * caller's tree — the component renders `null` and the overlay hangs off
57
+ * `document.body`. That last part is not a shortcut. A `position: fixed`
58
+ * element is positioned against the nearest ancestor carrying a `transform`,
59
+ * `filter` or `will-change`, and an onboarding screen is exactly the kind of
60
+ * surface that animates its own container, so an overlay rendered in place
61
+ * would cover the viewport everywhere it was tested and cover a card where it
62
+ * shipped.
63
+ *
64
+ * ## Props
65
+ *
66
+ * - `onDone` — called once, when the burst is over. Not called if the component
67
+ * is unmounted mid-burst: the caller who unmounted it already knows.
68
+ * - `duration` — milliseconds, default {@link DEFAULT_DURATION_MS}, clamped to
69
+ * {@link MIN_DURATION_MS}–{@link MAX_DURATION_MS}. A celebration is a moment,
70
+ * not a state.
71
+ * - `particleCount` — default {@link DEFAULT_PARTICLE_COUNT}, capped at
72
+ * {@link MAX_PARTICLE_COUNT}.
73
+ * - `className` — lands on the overlay canvas. Its position, inset,
74
+ * pointer-events and stacking are inline and win over a utility, because those
75
+ * four are the contract rather than a default.
76
+ *
77
+ * `duration` and `particleCount` are read ONCE, at mount. Changing them later
78
+ * does nothing, deliberately: a burst that restarted when its parent re-rendered
79
+ * with a new number is the "repeats on re-render" defect wearing a plausible
80
+ * face. `onDone` is the exception and is always the current one.
81
+ */
82
+ /** A celebration is a moment. Long enough to register, short enough to leave. */
83
+ const DEFAULT_DURATION_MS = 1800;
84
+ const MIN_DURATION_MS = 300;
85
+ const MAX_DURATION_MS = 8000;
86
+ /** Conservative on purpose: this runs on the first screen a new person sees. */
87
+ const DEFAULT_PARTICLE_COUNT = 90;
88
+ const MAX_PARTICLE_COUNT = 400;
89
+ /** The brand ramp, in the order the burst cycles it. */
90
+ const RAMP = ["--cg-primary", "--cg-secondary", "--cg-tertiary"];
91
+ /**
92
+ * Above application chrome, below a browser's own UI. Inline rather than a
93
+ * token because it is a stacking decision, not a brand one.
94
+ */
95
+ const OVERLAY_Z_INDEX = 9999;
96
+ /** Per frame at 60fps, which is what `dt` normalises to. */
97
+ const GRAVITY = 0.4;
98
+ const DRAG = 0.99;
99
+ /** The share of the burst that plays at full opacity before it fades out. */
100
+ const FADE_FROM = 0.7;
101
+ /** Retina is worth paying for; a 3x phone is not, for 90 rectangles. */
102
+ const MAX_PIXEL_RATIO = 2;
103
+ const clamp = (value, low, high) => Math.min(high, Math.max(low, value));
104
+ /**
105
+ * A cone of scraps thrown up from a little above the middle of the screen.
106
+ *
107
+ * Minted once per burst and kept, so a React strict-mode remount resumes the
108
+ * same confetti rather than throwing a second handful. See the effect.
109
+ */
110
+ function mint(count, width, height, palette) {
111
+ const originX = width / 2;
112
+ const originY = height * 0.45;
113
+ const particles = [];
114
+ for (let i = 0; i < count; i++) {
115
+ // Straight up, give or take a radian either way. Wide enough to read as a
116
+ // burst, narrow enough that most of it stays on the screen it decorates.
117
+ const angle = -Math.PI / 2 + (Math.random() - 0.5) * 2;
118
+ const speed = 6 + Math.random() * 8;
119
+ particles.push({
120
+ x: originX + (Math.random() - 0.5) * width * 0.1,
121
+ y: originY + (Math.random() - 0.5) * 20,
122
+ vx: Math.cos(angle) * speed,
123
+ vy: Math.sin(angle) * speed,
124
+ rot: Math.random() * Math.PI * 2,
125
+ spin: (Math.random() - 0.5) * 0.3,
126
+ w: 6 + Math.random() * 6,
127
+ h: 9 + Math.random() * 7,
128
+ wobble: Math.random() * Math.PI * 2,
129
+ wobbleRate: 0.08 + Math.random() * 0.1,
130
+ colour: palette[i % palette.length],
131
+ });
132
+ }
133
+ return particles;
134
+ }
135
+ function Celebration({ onDone, duration, particleCount, className }) {
136
+ // The callback is kept fresh; the numbers are not. See the props note above.
137
+ const onDoneRef = React.useRef(onDone);
138
+ React.useEffect(() => {
139
+ onDoneRef.current = onDone;
140
+ });
141
+ // useRef keeps its FIRST argument for the life of the component, which is
142
+ // exactly "read once at mount" without a second hook to say so.
143
+ const settings = React.useRef({ duration, particleCount, className });
144
+ /**
145
+ * The burst's own state, on a ref so it survives what React does to effects.
146
+ *
147
+ * Strict mode runs an effect, cleans it up, and runs it again. The naive guard
148
+ * — a boolean that makes the second run a no-op — is worse than none: the
149
+ * first run's cleanup has already cancelled the frame and removed the canvas,
150
+ * so it produces a component that animates nothing in development and
151
+ * correctly in production.
152
+ *
153
+ * One burst means one CLOCK, not one effect run. `startedAt` and `particles`
154
+ * are minted on the first run only, so a second run re-creates the canvas and
155
+ * resumes the same confetti at the elapsed time the clock says. `finished`
156
+ * short-circuits everything after, so `onDone` cannot fire twice.
157
+ */
158
+ const run = React.useRef({ startedAt: null, particles: null, finished: false });
159
+ React.useEffect(() => {
160
+ const state = run.current;
161
+ if (state.finished)
162
+ return;
163
+ const finish = () => {
164
+ if (state.finished)
165
+ return;
166
+ state.finished = true;
167
+ onDoneRef.current?.();
168
+ };
169
+ const reduced = typeof window.matchMedia === "function" &&
170
+ window.matchMedia("(prefers-reduced-motion: reduce)").matches;
171
+ if (reduced) {
172
+ finish();
173
+ return;
174
+ }
175
+ const durationMs = clamp(settings.current.duration ?? DEFAULT_DURATION_MS, MIN_DURATION_MS, MAX_DURATION_MS);
176
+ const count = Math.round(clamp(settings.current.particleCount ?? DEFAULT_PARTICLE_COUNT, 0, MAX_PARTICLE_COUNT));
177
+ const canvas = document.createElement("canvas");
178
+ canvas.dataset.slot = "celebration";
179
+ canvas.setAttribute("aria-hidden", "true");
180
+ if (settings.current.className)
181
+ canvas.className = settings.current.className;
182
+ // width/height are not redundant beside inset: a <canvas> is a REPLACED
183
+ // element, and an absolutely positioned replaced box with auto width keeps
184
+ // its INTRINSIC size rather than stretching to its offsets.
185
+ canvas.style.cssText =
186
+ "position:fixed;inset:0;width:100%;height:100%;" +
187
+ `pointer-events:none;z-index:${OVERLAY_Z_INDEX}`;
188
+ document.body.appendChild(canvas);
189
+ const ctx = canvas.getContext("2d");
190
+ if (!ctx) {
191
+ canvas.remove();
192
+ finish();
193
+ return;
194
+ }
195
+ const width = window.innerWidth;
196
+ const height = window.innerHeight;
197
+ const ratio = Math.min(window.devicePixelRatio || 1, MAX_PIXEL_RATIO);
198
+ canvas.width = Math.round(width * ratio);
199
+ canvas.height = Math.round(height * ratio);
200
+ ctx.scale(ratio, ratio);
201
+ const rootStyle = getComputedStyle(document.documentElement);
202
+ const palette = RAMP.map((name) => rootStyle.getPropertyValue(name).trim()).filter(Boolean);
203
+ if (palette.length === 0)
204
+ palette.push(getComputedStyle(canvas).color);
205
+ if (state.particles === null)
206
+ state.particles = mint(count, width, height, palette);
207
+ if (state.startedAt === null)
208
+ state.startedAt = performance.now();
209
+ const particles = state.particles;
210
+ const startedAt = state.startedAt;
211
+ let last = performance.now();
212
+ let frame = 0;
213
+ const step = (now) => {
214
+ const progress = (now - startedAt) / durationMs;
215
+ if (progress >= 1) {
216
+ canvas.remove();
217
+ finish();
218
+ return;
219
+ }
220
+ // Normalised to a 60fps frame and capped, so a backgrounded tab resumes
221
+ // rather than teleporting every scrap off the bottom of the screen.
222
+ const dt = Math.min(now - last, 64) / (1000 / 60);
223
+ last = now;
224
+ ctx.clearRect(0, 0, width, height);
225
+ ctx.globalAlpha =
226
+ progress < FADE_FROM ? 1 : 1 - (progress - FADE_FROM) / (1 - FADE_FROM);
227
+ for (const p of particles) {
228
+ p.vy += GRAVITY * dt;
229
+ p.vx *= DRAG ** dt;
230
+ p.vy *= DRAG ** dt;
231
+ p.x += p.vx * dt;
232
+ p.y += p.vy * dt;
233
+ p.rot += p.spin * dt;
234
+ p.wobble += p.wobbleRate * dt;
235
+ ctx.save();
236
+ ctx.translate(p.x, p.y);
237
+ ctx.rotate(p.rot);
238
+ ctx.scale(1, Math.cos(p.wobble));
239
+ ctx.fillStyle = p.colour;
240
+ ctx.fillRect(-p.w / 2, -p.h / 2, p.w, p.h);
241
+ ctx.restore();
242
+ }
243
+ frame = requestAnimationFrame(step);
244
+ };
245
+ frame = requestAnimationFrame(step);
246
+ return () => {
247
+ cancelAnimationFrame(frame);
248
+ canvas.remove();
249
+ };
250
+ // Mount only. Every prop this effect reads is read through a ref, precisely
251
+ // so that a changed prop cannot re-run it and start a second burst.
252
+ // eslint-disable-next-line react-hooks/exhaustive-deps
253
+ }, []);
254
+ // Nothing in the caller's tree, on the server or on the client. The overlay is
255
+ // the effect's, and it lives on document.body.
256
+ return null;
257
+ }
258
+ export { Celebration };
259
+ //# sourceMappingURL=celebration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"celebration.js","sourceRoot":"","sources":["../../src/blocks/celebration.tsx"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -23,6 +23,7 @@ export * from "./ui/textarea.js";
23
23
  export * from "./ui/tooltip.js";
24
24
  export * from "./blocks/agent-prompt.js";
25
25
  export * from "./blocks/card-grid.js";
26
+ export * from "./blocks/celebration.js";
26
27
  export * from "./blocks/compare-table.js";
27
28
  export * from "./blocks/creation-tile.js";
28
29
  export * from "./blocks/cta-banner.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAiBA,cAAc,mBAAmB,CAAA;AACjC,cAAc,eAAe,CAAA;AAC7B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,cAAc,CAAA;AAC5B,cAAc,kBAAkB,CAAA;AAChC,cAAc,kBAAkB,CAAA;AAChC,cAAc,oBAAoB,CAAA;AAClC,cAAc,kBAAkB,CAAA;AAChC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,uBAAuB,CAAA;AACrC,cAAc,qBAAqB,CAAA;AACnC,cAAc,eAAe,CAAA;AAC7B,cAAc,sBAAsB,CAAA;AACpC,cAAc,eAAe,CAAA;AAC7B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,mBAAmB,CAAA;AACjC,cAAc,kBAAkB,CAAA;AAChC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,eAAe,CAAA;AAC7B,cAAc,cAAc,CAAA;AAC5B,cAAc,kBAAkB,CAAA;AAChC,cAAc,iBAAiB,CAAA;AAG/B,cAAc,0BAA0B,CAAA;AACxC,cAAc,uBAAuB,CAAA;AACrC,cAAc,2BAA2B,CAAA;AACzC,cAAc,2BAA2B,CAAA;AACzC,cAAc,wBAAwB,CAAA;AACtC,cAAc,uBAAuB,CAAA;AACrC,cAAc,yBAAyB,CAAA;AACvC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,2BAA2B,CAAA;AACzC,cAAc,2BAA2B,CAAA;AACzC,cAAc,uBAAuB,CAAA;AACrC,cAAc,kBAAkB,CAAA;AAChC,cAAc,iCAAiC,CAAA;AAC/C,cAAc,yBAAyB,CAAA;AACvC,cAAc,0BAA0B,CAAA;AACxC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,yBAAyB,CAAA;AACvC,cAAc,gCAAgC,CAAA;AAC9C,cAAc,2BAA2B,CAAA;AACzC,cAAc,mBAAmB,CAAA;AACjC,cAAc,uBAAuB,CAAA;AACrC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,yBAAyB,CAAA;AACvC,cAAc,uBAAuB,CAAA;AACrC,cAAc,uBAAuB,CAAA;AACrC,cAAc,wBAAwB,CAAA;AACtC,cAAc,wBAAwB,CAAA;AAGtC,cAAc,uBAAuB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAiBA,cAAc,mBAAmB,CAAA;AACjC,cAAc,eAAe,CAAA;AAC7B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,cAAc,CAAA;AAC5B,cAAc,kBAAkB,CAAA;AAChC,cAAc,kBAAkB,CAAA;AAChC,cAAc,oBAAoB,CAAA;AAClC,cAAc,kBAAkB,CAAA;AAChC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,uBAAuB,CAAA;AACrC,cAAc,qBAAqB,CAAA;AACnC,cAAc,eAAe,CAAA;AAC7B,cAAc,sBAAsB,CAAA;AACpC,cAAc,eAAe,CAAA;AAC7B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,mBAAmB,CAAA;AACjC,cAAc,kBAAkB,CAAA;AAChC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,eAAe,CAAA;AAC7B,cAAc,cAAc,CAAA;AAC5B,cAAc,kBAAkB,CAAA;AAChC,cAAc,iBAAiB,CAAA;AAG/B,cAAc,0BAA0B,CAAA;AACxC,cAAc,uBAAuB,CAAA;AACrC,cAAc,yBAAyB,CAAA;AACvC,cAAc,2BAA2B,CAAA;AACzC,cAAc,2BAA2B,CAAA;AACzC,cAAc,wBAAwB,CAAA;AACtC,cAAc,uBAAuB,CAAA;AACrC,cAAc,yBAAyB,CAAA;AACvC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,2BAA2B,CAAA;AACzC,cAAc,2BAA2B,CAAA;AACzC,cAAc,uBAAuB,CAAA;AACrC,cAAc,kBAAkB,CAAA;AAChC,cAAc,iCAAiC,CAAA;AAC/C,cAAc,yBAAyB,CAAA;AACvC,cAAc,0BAA0B,CAAA;AACxC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,yBAAyB,CAAA;AACvC,cAAc,gCAAgC,CAAA;AAC9C,cAAc,2BAA2B,CAAA;AACzC,cAAc,mBAAmB,CAAA;AACjC,cAAc,uBAAuB,CAAA;AACrC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,yBAAyB,CAAA;AACvC,cAAc,uBAAuB,CAAA;AACrC,cAAc,uBAAuB,CAAA;AACrC,cAAc,wBAAwB,CAAA;AACtC,cAAc,wBAAwB,CAAA;AAGtC,cAAc,uBAAuB,CAAA"}
package/dist/index.js CHANGED
@@ -40,6 +40,7 @@ export * from "./ui/tooltip.js";
40
40
  // Composed blocks.
41
41
  export * from "./blocks/agent-prompt.js";
42
42
  export * from "./blocks/card-grid.js";
43
+ export * from "./blocks/celebration.js";
43
44
  export * from "./blocks/compare-table.js";
44
45
  export * from "./blocks/creation-tile.js";
45
46
  export * from "./blocks/cta-banner.js";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,0CAA0C;AAC1C,EAAE;AACF,gFAAgF;AAChF,8EAA8E;AAC9E,oEAAoE;AACpE,EAAE;AACF,gFAAgF;AAChF,+EAA+E;AAC/E,yEAAyE;AACzE,gFAAgF;AAChF,4EAA4E;AAC5E,EAAE;AACF,kEAAkE;AAClE,8EAA8E;AAC9E,uEAAuE;AAEvE,cAAc;AACd,cAAc,mBAAmB,CAAA;AACjC,cAAc,eAAe,CAAA;AAC7B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,cAAc,CAAA;AAC5B,cAAc,kBAAkB,CAAA;AAChC,cAAc,kBAAkB,CAAA;AAChC,cAAc,oBAAoB,CAAA;AAClC,cAAc,kBAAkB,CAAA;AAChC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,uBAAuB,CAAA;AACrC,cAAc,qBAAqB,CAAA;AACnC,cAAc,eAAe,CAAA;AAC7B,cAAc,sBAAsB,CAAA;AACpC,cAAc,eAAe,CAAA;AAC7B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,mBAAmB,CAAA;AACjC,cAAc,kBAAkB,CAAA;AAChC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,eAAe,CAAA;AAC7B,cAAc,cAAc,CAAA;AAC5B,cAAc,kBAAkB,CAAA;AAChC,cAAc,iBAAiB,CAAA;AAE/B,mBAAmB;AACnB,cAAc,0BAA0B,CAAA;AACxC,cAAc,uBAAuB,CAAA;AACrC,cAAc,2BAA2B,CAAA;AACzC,cAAc,2BAA2B,CAAA;AACzC,cAAc,wBAAwB,CAAA;AACtC,cAAc,uBAAuB,CAAA;AACrC,cAAc,yBAAyB,CAAA;AACvC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,2BAA2B,CAAA;AACzC,cAAc,2BAA2B,CAAA;AACzC,cAAc,uBAAuB,CAAA;AACrC,cAAc,kBAAkB,CAAA;AAChC,cAAc,iCAAiC,CAAA;AAC/C,cAAc,yBAAyB,CAAA;AACvC,cAAc,0BAA0B,CAAA;AACxC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,yBAAyB,CAAA;AACvC,cAAc,gCAAgC,CAAA;AAC9C,cAAc,2BAA2B,CAAA;AACzC,cAAc,mBAAmB,CAAA;AACjC,cAAc,uBAAuB,CAAA;AACrC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,yBAAyB,CAAA;AACvC,cAAc,uBAAuB,CAAA;AACrC,cAAc,uBAAuB,CAAA;AACrC,cAAc,wBAAwB,CAAA;AACtC,cAAc,wBAAwB,CAAA;AAEtC,0EAA0E;AAC1E,cAAc,uBAAuB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,0CAA0C;AAC1C,EAAE;AACF,gFAAgF;AAChF,8EAA8E;AAC9E,oEAAoE;AACpE,EAAE;AACF,gFAAgF;AAChF,+EAA+E;AAC/E,yEAAyE;AACzE,gFAAgF;AAChF,4EAA4E;AAC5E,EAAE;AACF,kEAAkE;AAClE,8EAA8E;AAC9E,uEAAuE;AAEvE,cAAc;AACd,cAAc,mBAAmB,CAAA;AACjC,cAAc,eAAe,CAAA;AAC7B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,cAAc,CAAA;AAC5B,cAAc,kBAAkB,CAAA;AAChC,cAAc,kBAAkB,CAAA;AAChC,cAAc,oBAAoB,CAAA;AAClC,cAAc,kBAAkB,CAAA;AAChC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,uBAAuB,CAAA;AACrC,cAAc,qBAAqB,CAAA;AACnC,cAAc,eAAe,CAAA;AAC7B,cAAc,sBAAsB,CAAA;AACpC,cAAc,eAAe,CAAA;AAC7B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,mBAAmB,CAAA;AACjC,cAAc,kBAAkB,CAAA;AAChC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,eAAe,CAAA;AAC7B,cAAc,cAAc,CAAA;AAC5B,cAAc,kBAAkB,CAAA;AAChC,cAAc,iBAAiB,CAAA;AAE/B,mBAAmB;AACnB,cAAc,0BAA0B,CAAA;AACxC,cAAc,uBAAuB,CAAA;AACrC,cAAc,yBAAyB,CAAA;AACvC,cAAc,2BAA2B,CAAA;AACzC,cAAc,2BAA2B,CAAA;AACzC,cAAc,wBAAwB,CAAA;AACtC,cAAc,uBAAuB,CAAA;AACrC,cAAc,yBAAyB,CAAA;AACvC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,2BAA2B,CAAA;AACzC,cAAc,2BAA2B,CAAA;AACzC,cAAc,uBAAuB,CAAA;AACrC,cAAc,kBAAkB,CAAA;AAChC,cAAc,iCAAiC,CAAA;AAC/C,cAAc,yBAAyB,CAAA;AACvC,cAAc,0BAA0B,CAAA;AACxC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,yBAAyB,CAAA;AACvC,cAAc,gCAAgC,CAAA;AAC9C,cAAc,2BAA2B,CAAA;AACzC,cAAc,mBAAmB,CAAA;AACjC,cAAc,uBAAuB,CAAA;AACrC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,yBAAyB,CAAA;AACvC,cAAc,uBAAuB,CAAA;AACrC,cAAc,uBAAuB,CAAA;AACrC,cAAc,wBAAwB,CAAA;AACtC,cAAc,wBAAwB,CAAA;AAEtC,0EAA0E;AAC1E,cAAc,uBAAuB,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloudgrid-io/ui",
3
- "version": "0.14.0",
3
+ "version": "0.15.0",
4
4
  "description": "CloudGrid design system: React components, brand design tokens, Tailwind theme, self-hosted fonts.",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/",