@cloudgrid-io/ui 0.18.0 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/blocks/compare-table.d.ts.map +1 -1
- package/dist/blocks/compare-table.js +10 -8
- package/dist/blocks/compare-table.js.map +1 -1
- package/dist/blocks/drop-zone.js +2 -2
- package/dist/blocks/drop-zone.js.map +1 -1
- package/dist/blocks/entity-card.d.ts +102 -12
- package/dist/blocks/entity-card.d.ts.map +1 -1
- package/dist/blocks/entity-card.js +66 -11
- package/dist/blocks/entity-card.js.map +1 -1
- package/dist/blocks/eyebrow.d.ts +43 -0
- package/dist/blocks/eyebrow.d.ts.map +1 -0
- package/dist/blocks/eyebrow.js +53 -0
- package/dist/blocks/eyebrow.js.map +1 -0
- package/dist/blocks/feature-cells.d.ts +12 -7
- package/dist/blocks/feature-cells.d.ts.map +1 -1
- package/dist/blocks/feature-cells.js +11 -11
- package/dist/blocks/feature-cells.js.map +1 -1
- package/dist/blocks/icons.d.ts +68 -10
- package/dist/blocks/icons.d.ts.map +1 -1
- package/dist/blocks/icons.js +68 -10
- package/dist/blocks/icons.js.map +1 -1
- package/dist/blocks/onboarding-question.js +2 -2
- package/dist/blocks/onboarding-question.js.map +1 -1
- package/dist/blocks/page-heading.d.ts +5 -0
- package/dist/blocks/page-heading.d.ts.map +1 -1
- package/dist/blocks/page-heading.js +7 -1
- package/dist/blocks/page-heading.js.map +1 -1
- package/dist/blocks/phosphor-marks.d.ts +99 -22
- package/dist/blocks/phosphor-marks.d.ts.map +1 -1
- package/dist/blocks/phosphor-marks.js +155 -25
- package/dist/blocks/phosphor-marks.js.map +1 -1
- package/dist/blocks/pricing-tier-cards.d.ts +6 -3
- package/dist/blocks/pricing-tier-cards.d.ts.map +1 -1
- package/dist/blocks/pricing-tier-cards.js +2 -2
- package/dist/blocks/pricing-tier-cards.js.map +1 -1
- package/dist/blocks/token-specimen.d.ts +59 -0
- package/dist/blocks/token-specimen.d.ts.map +1 -0
- package/dist/blocks/token-specimen.js +61 -0
- package/dist/blocks/token-specimen.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/ui/accordion.d.ts.map +1 -1
- package/dist/ui/accordion.js +2 -2
- package/dist/ui/accordion.js.map +1 -1
- package/dist/ui/badge.d.ts +1 -1
- package/dist/ui/button.d.ts +1 -1
- package/dist/ui/checkbox.d.ts.map +1 -1
- package/dist/ui/checkbox.js +2 -2
- package/dist/ui/checkbox.js.map +1 -1
- package/dist/ui/code-block.js +1 -1
- package/dist/ui/code-block.js.map +1 -1
- package/dist/ui/combobox.js +3 -3
- package/dist/ui/combobox.js.map +1 -1
- package/dist/ui/dialog.d.ts.map +1 -1
- package/dist/ui/dialog.js +2 -2
- package/dist/ui/dialog.js.map +1 -1
- package/dist/ui/dropdown-menu.d.ts.map +1 -1
- package/dist/ui/dropdown-menu.js +1 -1
- package/dist/ui/dropdown-menu.js.map +1 -1
- package/dist/ui/number-field.js +1 -1
- package/dist/ui/number-field.js.map +1 -1
- package/dist/ui/select.d.ts.map +1 -1
- package/dist/ui/select.js +1 -1
- package/dist/ui/select.js.map +1 -1
- package/dist/ui/sonner.js +5 -5
- package/dist/ui/sonner.js.map +1 -1
- package/package.json +1 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compare-table.d.ts","sourceRoot":"","sources":["../../src/blocks/compare-table.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"compare-table.d.ts","sourceRoot":"","sources":["../../src/blocks/compare-table.tsx"],"names":[],"mappings":"AAuCA,KAAK,UAAU,GAAG;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAAA;AAY1C,iBAAS,YAAY,CAAC,EACpB,KAAK,EACL,SAAS,EACT,IAAI,EACJ,SAAS,EACT,GAAG,KAAK,EACT,EAAE,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,GAAG;IAC5C,KAAK,EAAE,MAAM,CAAA;IACb,iEAAiE;IACjE,SAAS,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAC3B,IAAI,EAAE,UAAU,EAAE,CAAA;CACnB,+BA+DA;AAED,OAAO,EAAE,YAAY,EAAE,CAAA;AACvB,YAAY,EAAE,UAAU,EAAE,CAAA"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
2
|
+
import { IncludedIcon, NotIncludedIcon } from "./icons.js";
|
|
3
3
|
import { Logo } from "./logo.js";
|
|
4
4
|
import { cn } from "../lib/cloudgrid-cn.js";
|
|
5
5
|
/**
|
|
@@ -25,17 +25,19 @@ import { cn } from "../lib/cloudgrid-cn.js";
|
|
|
25
25
|
* represents a rival is the caller's call, not this component's. Pass a
|
|
26
26
|
* `rivalLogo` if you have one. Without it the name alone reads fine.
|
|
27
27
|
*
|
|
28
|
-
* ## Marks are
|
|
28
|
+
* ## Marks are the library's, and they carry text
|
|
29
29
|
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
30
|
+
* `IncludedIcon` / `NotIncludedIcon` from `@/registry/ui/icons` — Phosphor
|
|
31
|
+
* `check-circle` and `x-circle`, which is what v0's inlined SVG strings were
|
|
32
|
+
* before they were transcribed (#167). The marks set `aria-hidden` themselves
|
|
33
|
+
* and each cell carries visually-hidden "Included" or "Not included", so a
|
|
34
|
+
* screen reader hears the claim rather than nothing, and so does anything
|
|
35
|
+
* reading the markup.
|
|
34
36
|
*/
|
|
35
37
|
const VALID = ["both", "us", "them", "neither"];
|
|
36
38
|
function Mark({ yes }) {
|
|
37
|
-
const Icon = yes ?
|
|
38
|
-
return (_jsxs(_Fragment, { children: [_jsx(Icon, {
|
|
39
|
+
const Icon = yes ? IncludedIcon : NotIncludedIcon;
|
|
40
|
+
return (_jsxs(_Fragment, { children: [_jsx(Icon, { className: cn("inline-block size-[22px]", yes ? "text-brand" : "text-faint") }), _jsx("span", { className: "sr-only", children: yes ? "Included" : "Not included" })] }));
|
|
39
41
|
}
|
|
40
42
|
function CompareTable({ rival, rivalLogo, rows, className, ...props }) {
|
|
41
43
|
const parsed = rows.map((pair) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compare-table.js","sourceRoot":"","sources":["../../src/blocks/compare-table.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"compare-table.js","sourceRoot":"","sources":["../../src/blocks/compare-table.tsx"],"names":[],"mappings":"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"}
|
package/dist/blocks/drop-zone.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import * as React from "react";
|
|
4
|
-
import { ArrowDownIcon,
|
|
4
|
+
import { ArrowDownIcon, WarningIcon } from "./icons.js";
|
|
5
5
|
import { cn } from "../lib/cloudgrid-cn.js";
|
|
6
6
|
/**
|
|
7
7
|
* `accept` on the input governs the PICKER only. A drag and drop hands over
|
|
@@ -109,7 +109,7 @@ function DropZone({ onDrop, onReject, accept, multiple = false, disabled = false
|
|
|
109
109
|
// utility for `--cg-text-accent`. `text-ring` resolves to the same value
|
|
110
110
|
// through the bridge and was used here first, but one spelling per
|
|
111
111
|
// concept is worth more than saving eight characters.
|
|
112
|
-
bad ? "text-destructive" : "text-(--cg-text-accent)"), children: bad ? _jsx(
|
|
112
|
+
bad ? "text-destructive" : "text-(--cg-text-accent)"), children: bad ? _jsx(WarningIcon, { className: "size-5" }) : _jsx(ArrowDownIcon, { className: "size-5" }) }), _jsx("span", { id: `${base}-prompt`, className: "text-body-sm text-muted-foreground", children: prompt })] }), _jsx("span", { id: `${base}-status`, role: bad ? "alert" : undefined, "aria-live": "polite", className: cn("text-caption", bad ? "text-destructive" : "text-faint"), children: taken.length === 1
|
|
113
113
|
? taken[0].name
|
|
114
114
|
: taken.length > 1
|
|
115
115
|
? `${taken.length} ready`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"drop-zone.js","sourceRoot":"","sources":["../../src/blocks/drop-zone.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAE,aAAa,EAAE,
|
|
1
|
+
{"version":3,"file":"drop-zone.js","sourceRoot":"","sources":["../../src/blocks/drop-zone.tsx"],"names":[],"mappings":"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"}
|
|
@@ -66,10 +66,23 @@
|
|
|
66
66
|
* ## The hover reveal, and the rule it supersedes
|
|
67
67
|
*
|
|
68
68
|
* `reveal` puts a panel over the preview carrying the title, one line of
|
|
69
|
-
* description, the creator, the status and two real links: Open and
|
|
69
|
+
* description, the creator, the status and two real links: Open and Dashboard.
|
|
70
70
|
* It shows on hover and on `:focus-within`, and it respects
|
|
71
71
|
* `prefers-reduced-motion` by arriving without the fade rather than not at all.
|
|
72
72
|
*
|
|
73
|
+
* **The second action is Dashboard, and it is not a gear.** Founder direction
|
|
74
|
+
* 2026-09-08 (#182). The door it opens is the entity's page in the console,
|
|
75
|
+
* which shows analytics and what runs under the hood — so what it promises is
|
|
76
|
+
* "look inside", and a gear promises "change how this is configured". Those are
|
|
77
|
+
* different pages and a reader who takes one for the other has been misled by
|
|
78
|
+
* the icon rather than by the label. The mark is `EntityDashboardIcon`
|
|
79
|
+
* (Phosphor `gauge`); `SettingsIcon` is still exported for the surfaces that
|
|
80
|
+
* really are settings.
|
|
81
|
+
*
|
|
82
|
+
* The prop is `dashboardHref`. `settingsHref` is kept as a deprecated alias for
|
|
83
|
+
* this minor and maps straight to it, so no caller breaks on the rename — see
|
|
84
|
+
* the note on the prop.
|
|
85
|
+
*
|
|
73
86
|
* **This supersedes the "cards are visually static" rule of the console's
|
|
74
87
|
* 2026-08-16 card spec, for the media variant only.** Founder direction
|
|
75
88
|
* 2026-09-08 (#165). The rest of that rule stands and is unchanged: no lift, no
|
|
@@ -84,22 +97,22 @@
|
|
|
84
97
|
* browsers repair it by closing the outer one — which silently unlinks the card
|
|
85
98
|
* and leaves the actions where the parser decides to put them. The panel is the
|
|
86
99
|
* link surface instead: Open stretches across the whole panel with an
|
|
87
|
-
* `::after`, so a click anywhere on the thumbnail opens the entity, and
|
|
88
|
-
* sits above it. Every existing caller is unaffected — `reveal`
|
|
89
|
-
* the wrapper behaves exactly as it did.
|
|
100
|
+
* `::after`, so a click anywhere on the thumbnail opens the entity, and
|
|
101
|
+
* Dashboard sits above it. Every existing caller is unaffected — `reveal`
|
|
102
|
+
* defaults off and the wrapper behaves exactly as it did.
|
|
90
103
|
*
|
|
91
|
-
* **The panel stays clickable while it is invisible — except
|
|
104
|
+
* **The panel stays clickable while it is invisible — except Dashboard.**
|
|
92
105
|
* `opacity-0` is a paint state, not a pointer state, so a touch user with no
|
|
93
106
|
* hover at all still gets Open by tapping the thumbnail. Gating Open's pointer
|
|
94
107
|
* events on hover would make the card do nothing on a phone.
|
|
95
108
|
*
|
|
96
|
-
*
|
|
109
|
+
* Dashboard is the one exception, and it has to be. It is `relative`, so it
|
|
97
110
|
* stacks above Open's stretched hit area; live at rest, that made a pill-sized
|
|
98
|
-
* region of an invisible panel go to
|
|
111
|
+
* region of an invisible panel go to that link on a tap — different from every
|
|
99
112
|
* pixel around it, and impossible to see (#171). So it carries
|
|
100
113
|
* `pointer-events-none` until the panel is revealed by hover or focus-within,
|
|
101
114
|
* which is the reasoning the kind mark beside it already carried. Open's
|
|
102
|
-
* overlay is untouched, so a tap anywhere on the thumbnail —
|
|
115
|
+
* overlay is untouched, so a tap anywhere on the thumbnail — the second pill
|
|
103
116
|
* included — opens the entity, and the touch fallback is exactly as it was.
|
|
104
117
|
*
|
|
105
118
|
* **It is an ink surface, declared.** The panel carries
|
|
@@ -122,6 +135,51 @@
|
|
|
122
135
|
* is product knowledge. The console maps its wire status through its own table
|
|
123
136
|
* and drops the result in here.
|
|
124
137
|
*
|
|
138
|
+
* ## `headerActions` is the OTHER slot, and the difference is where it renders
|
|
139
|
+
*
|
|
140
|
+
* `status` is one node rendered in TWO places: the header row and the reveal
|
|
141
|
+
* panel. That is right for a state chip — what an entity currently is stays true
|
|
142
|
+
* while you hover it — and wrong for everything else, because a slot rendered
|
|
143
|
+
* twice can only carry something that belongs in both.
|
|
144
|
+
*
|
|
145
|
+
* The console found the edge (#176, cloudgrid-console#654). Its cards carry a
|
|
146
|
+
* save toggle and an overflow menu at the header's right, which is exactly where
|
|
147
|
+
* `status` sits. Putting them in that slot duplicates two interactive controls
|
|
148
|
+
* into an invisible hover panel: two menu triggers with the same accessible name
|
|
149
|
+
* on every card, two save buttons, and a kebab whose dropdown opens inside a
|
|
150
|
+
* panel that disappears when the pointer leaves. So the console moved them to
|
|
151
|
+
* its footer instead — nothing lost, nothing duplicated, and the controls a row
|
|
152
|
+
* below where the design puts them for a library reason rather than a design
|
|
153
|
+
* one.
|
|
154
|
+
*
|
|
155
|
+
* `headerActions` is that slot. It renders **once**, in the header row, to the
|
|
156
|
+
* right of `status`, and never in the reveal panel. Nothing else about the card
|
|
157
|
+
* changes and no existing caller is affected.
|
|
158
|
+
*
|
|
159
|
+
* Three things about it:
|
|
160
|
+
*
|
|
161
|
+
* **The panel deliberately has no equivalent.** The reveal already carries the
|
|
162
|
+
* two actions it can carry — Open, and Dashboard — and its own hit model is one
|
|
163
|
+
* stretched anchor with a single exception lifted above it. A third control in
|
|
164
|
+
* there would need the same `pointer-events` gating Dashboard carries, for the
|
|
165
|
+
* same reason (#171), and would be invisible on a phone. The panel's actions are
|
|
166
|
+
* a fixed pair by design; the header's are the caller's.
|
|
167
|
+
*
|
|
168
|
+
* **Interactive controls inside a whole-card link are the caller's problem, and
|
|
169
|
+
* they are a real one.** With `href` set and `reveal` off, this card is wrapped
|
|
170
|
+
* in an `<a>`. A `<button>` inside an anchor is invalid HTML, and even where a
|
|
171
|
+
* browser tolerates it a click on the button also activates the link. This card
|
|
172
|
+
* cannot fix that for you: stopping the event needs a handler, a handler needs
|
|
173
|
+
* `"use client"`, and that would put a client boundary on a card that is
|
|
174
|
+
* otherwise entirely static — on every listing that renders it, for a slot most
|
|
175
|
+
* callers never pass. So a caller passing controls here either composes its own
|
|
176
|
+
* wrapper (which is what the console does, for `next/link`) or drops the
|
|
177
|
+
* whole-card `href` and gives the title its own link.
|
|
178
|
+
*
|
|
179
|
+
* **It does not render when `children` replaces the body.** Same as `status`:
|
|
180
|
+
* both live in the default body, and a caller supplying its own body owns its
|
|
181
|
+
* own header row.
|
|
182
|
+
*
|
|
125
183
|
* ## Surfaces
|
|
126
184
|
*
|
|
127
185
|
* The chrome flips: ground, hairlines, title, body text and the stat rule all
|
|
@@ -177,22 +235,42 @@ declare function EntityKindBadge({ kind, size, className, ...props }: Omit<React
|
|
|
177
235
|
kind: EntityKind;
|
|
178
236
|
size?: "sm" | "md";
|
|
179
237
|
}): import("react").JSX.Element;
|
|
180
|
-
declare function EntityCard({ title, slug, description, titleLines, descriptionLines, status, stats, seed, previewUrl, kind, reveal, settingsHref, creator, href, ariaLabel, meta, footer, className, children, ...props }: Omit<React.ComponentProps<"div">, "ref" | "title"> & {
|
|
238
|
+
declare function EntityCard({ title, slug, description, titleLines, descriptionLines, status, headerActions, stats, seed, previewUrl, kind, reveal, dashboardHref, settingsHref, creator, href, ariaLabel, meta, footer, className, children, ...props }: Omit<React.ComponentProps<"div">, "ref" | "title"> & {
|
|
181
239
|
title: string;
|
|
182
240
|
/** The entity's address, in the mono utility face. */
|
|
183
241
|
slug?: string;
|
|
184
242
|
description?: string;
|
|
185
243
|
titleLines?: 1 | 2;
|
|
186
244
|
descriptionLines?: 1 | 2;
|
|
187
|
-
/**
|
|
245
|
+
/**
|
|
246
|
+
* Top right of the header row, and ALSO inside the reveal panel. One node,
|
|
247
|
+
* two places, so it can only carry something true in both: drop an
|
|
248
|
+
* `EntityStatus` in. Row controls go in `headerActions`.
|
|
249
|
+
*/
|
|
188
250
|
status?: React.ReactNode;
|
|
251
|
+
/**
|
|
252
|
+
* The header row's own controls — a save toggle, an overflow menu — to the
|
|
253
|
+
* right of `status`. Rendered **once**, in the header, never in the reveal
|
|
254
|
+
* panel (#176).
|
|
255
|
+
*
|
|
256
|
+
* Read the note above before passing an interactive control together with
|
|
257
|
+
* `href`: this card wraps itself in an anchor, and it cannot intercept the
|
|
258
|
+
* click for you without becoming a client component.
|
|
259
|
+
*/
|
|
260
|
+
headerActions?: React.ReactNode;
|
|
189
261
|
stats?: EntityCardStat[];
|
|
190
262
|
/**
|
|
191
263
|
* The entity's stable id. Its presence is what turns the preview region on,
|
|
192
264
|
* and its value is what picks the identity look. Pass the id, not the title.
|
|
193
265
|
*/
|
|
194
266
|
seed?: string;
|
|
195
|
-
/**
|
|
267
|
+
/**
|
|
268
|
+
* A real capture, painted over the identity tile. A miss falls back to it.
|
|
269
|
+
*
|
|
270
|
+
* Pass it ready to request. The card does not encode it — a data URI, a signed
|
|
271
|
+
* storage URL carrying `%2F`, an already-escaped filename all go out as given
|
|
272
|
+
* (ui#178).
|
|
273
|
+
*/
|
|
196
274
|
previewUrl?: string;
|
|
197
275
|
/**
|
|
198
276
|
* What the entity IS. Paints the badge on the preview's top-right corner, or
|
|
@@ -207,7 +285,19 @@ declare function EntityCard({ title, slug, description, titleLines, descriptionL
|
|
|
207
285
|
* and an anchor inside an anchor is invalid HTML. See the note above.
|
|
208
286
|
*/
|
|
209
287
|
reveal?: boolean;
|
|
210
|
-
/**
|
|
288
|
+
/**
|
|
289
|
+
* The Dashboard action's target: the entity's page in the console, where the
|
|
290
|
+
* analytics and what runs under the hood live. Only read when `reveal` is on.
|
|
291
|
+
*/
|
|
292
|
+
dashboardHref?: string;
|
|
293
|
+
/**
|
|
294
|
+
* @deprecated Renamed to `dashboardHref` in #182 — the action is Dashboard,
|
|
295
|
+
* not Settings, because that is what the page it opens actually is.
|
|
296
|
+
*
|
|
297
|
+
* Kept for this minor and mapped straight through, so no caller breaks on the
|
|
298
|
+
* rename. `dashboardHref` wins if both are given. It will be removed in the
|
|
299
|
+
* next major; the fix is one word at each call site.
|
|
300
|
+
*/
|
|
211
301
|
settingsHref?: string;
|
|
212
302
|
/**
|
|
213
303
|
* Who made it, shown on the reveal panel. `avatar` is a node so a consumer can
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entity-card.d.ts","sourceRoot":"","sources":["../../src/blocks/entity-card.tsx"],"names":[],"mappings":"AAWA
|
|
1
|
+
{"version":3,"file":"entity-card.d.ts","sourceRoot":"","sources":["../../src/blocks/entity-card.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { Card } from "../ui/card.js";
|
|
3
3
|
import { EntityIdentity } from "./entity-identity.js";
|
|
4
|
-
import { KindAgentIcon, KindAppIcon, KindInspirationIcon, OpenLiveIcon,
|
|
4
|
+
import { EntityDashboardIcon, KindAgentIcon, KindAppIcon, KindInspirationIcon, OpenLiveIcon, } from "./icons.js";
|
|
5
5
|
import { cn } from "../lib/cloudgrid-cn.js";
|
|
6
6
|
/**
|
|
7
7
|
* What an entity IS. Three kinds, and they are the product's, not this file's:
|
|
@@ -34,6 +34,47 @@ export const ENTITY_KIND_LABEL = {
|
|
|
34
34
|
inspiration: "Inspiration",
|
|
35
35
|
app: "App",
|
|
36
36
|
};
|
|
37
|
+
/**
|
|
38
|
+
* Make a caller's URL safe to sit inside a CSS `url("…")` string — and nothing
|
|
39
|
+
* more than that.
|
|
40
|
+
*
|
|
41
|
+
* **The caller owns encoding.** A `previewUrl` arrives ready to request: a
|
|
42
|
+
* platform thumbnail path, a signed storage URL whose credential scope is full
|
|
43
|
+
* of `%2F`, a data URI whose payload is already percent-escaped. This function's
|
|
44
|
+
* only job is the transport into a CSS string; it must not have an opinion about
|
|
45
|
+
* the URL itself.
|
|
46
|
+
*
|
|
47
|
+
* That is the correction in ui#178. This used to be `encodeURI(previewUrl)`,
|
|
48
|
+
* which is not idempotent — it percent-encodes `%` — so an already-encoded URL
|
|
49
|
+
* came out double-encoded (`%3C` → `%253C`), the browser requested something
|
|
50
|
+
* nobody serves, and the identity tile below showed through. That is the
|
|
51
|
+
* DESIGNED response to a 404, so the card looked fine while showing the wrong
|
|
52
|
+
* tier, and nothing failed loudly.
|
|
53
|
+
*
|
|
54
|
+
* So: escape what a CSS string token cannot carry, and only that.
|
|
55
|
+
*
|
|
56
|
+
* - `\` and `"` become CSS escapes. The quote is the one character that could
|
|
57
|
+
* otherwise close the string and let the rest of the URL be parsed as CSS.
|
|
58
|
+
* - The newline family becomes a CSS hex escape (`\a `). A raw newline is
|
|
59
|
+
* invalid inside a CSS string and would end the declaration.
|
|
60
|
+
* - Everything else — `%`, a space, `<`, `(`, `)` — passes through untouched.
|
|
61
|
+
* Parentheses only terminate an UNQUOTED `url(…)` token; inside the quoted
|
|
62
|
+
* form they are ordinary characters, and rewriting one would corrupt a
|
|
63
|
+
* perfectly good filename.
|
|
64
|
+
*
|
|
65
|
+
* Percent-encoding is never the answer here: it changes the URL, which is the
|
|
66
|
+
* caller's, not ours.
|
|
67
|
+
*/
|
|
68
|
+
function cssUrlString(url) {
|
|
69
|
+
return url.replace(/[\\"\n\r\f]/g, (c) => {
|
|
70
|
+
if (c === "\\")
|
|
71
|
+
return "\\\\";
|
|
72
|
+
if (c === '"')
|
|
73
|
+
return '\\"';
|
|
74
|
+
// Hex escape, trailing space included: it is what terminates the escape.
|
|
75
|
+
return `\\${c.charCodeAt(0).toString(16)} `;
|
|
76
|
+
});
|
|
77
|
+
}
|
|
37
78
|
/**
|
|
38
79
|
* The kind badge on its own, exported because a listing header, a detail page or
|
|
39
80
|
* a row may want the same mark without a card around it.
|
|
@@ -54,15 +95,27 @@ function EntityKindBadge({ kind, size = "md", className, ...props }) {
|
|
|
54
95
|
border: "1px solid color-mix(in srgb, var(--cg-ink) 12%, transparent)",
|
|
55
96
|
}, ...props, children: [_jsx(Icon, { className: size === "md" ? "size-4" : "size-3.5" }), _jsx("span", { className: "sr-only", children: ENTITY_KIND_LABEL[kind] })] }));
|
|
56
97
|
}
|
|
57
|
-
function EntityCard({ title, slug, description, titleLines = 2, descriptionLines = 1, status, stats, seed, previewUrl, kind, reveal = false, settingsHref, creator, href, ariaLabel, meta, footer, className, children, ...props }) {
|
|
98
|
+
function EntityCard({ title, slug, description, titleLines = 2, descriptionLines = 1, status, headerActions, stats, seed, previewUrl, kind, reveal = false, dashboardHref, settingsHref, creator, href, ariaLabel, meta, footer, className, children, ...props }) {
|
|
58
99
|
// The reveal owns the preview and spends the `href`, so it only exists when
|
|
59
100
|
// both are there. Asked for without a `seed` it would be a panel over nothing;
|
|
60
101
|
// asked for without an `href` its Open action would be an anchor with no
|
|
61
102
|
// target, which renders as a link, is not focusable, and does nothing when
|
|
62
103
|
// clicked. Silently off in both cases rather than half-built.
|
|
63
104
|
const revealed = reveal && Boolean(seed) && Boolean(href);
|
|
105
|
+
// One target, two prop names, for one minor. `settingsHref` is the old name
|
|
106
|
+
// (#182 renamed the action to Dashboard, because the console page it opens is
|
|
107
|
+
// a dashboard and not a settings screen), and it is resolved here rather than
|
|
108
|
+
// at the render site so there is exactly one place the alias exists and one
|
|
109
|
+
// place to delete when it goes. `??`, not `||`: an empty string is a caller
|
|
110
|
+
// saying "no target", and coalescing it to the deprecated name would resurrect
|
|
111
|
+
// a link the caller had switched off.
|
|
112
|
+
const dashboardTarget = dashboardHref ?? settingsHref;
|
|
64
113
|
const body = children ??
|
|
65
|
-
(_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex items-start justify-between gap-3", children: [_jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("span", { dir: "auto", "data-slot": "entity-card-title", title: title, className: cn("block text-body-sm font-medium break-words text-ink", titleLines === 1 ? "truncate" : "line-clamp-2"), children: [kind && !seed ? (_jsx(EntityKindBadge, { kind: kind, size: "sm", className: "mr-1.5 align-[-0.2em]" })) : null, title] }), slug ? (_jsx("span", { dir: "auto", "data-slot": "entity-card-slug", title: slug, className: "mt-0.5 block truncate font-mono text-caption text-faint", children: slug })) : null] }), status ? _jsx("div", { className: "shrink-0", children: status }) : null
|
|
114
|
+
(_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex items-start justify-between gap-3", children: [_jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("span", { dir: "auto", "data-slot": "entity-card-title", title: title, className: cn("block text-body-sm font-medium break-words text-ink", titleLines === 1 ? "truncate" : "line-clamp-2"), children: [kind && !seed ? (_jsx(EntityKindBadge, { kind: kind, size: "sm", className: "mr-1.5 align-[-0.2em]" })) : null, title] }), slug ? (_jsx("span", { dir: "auto", "data-slot": "entity-card-slug", title: slug, className: "mt-0.5 block truncate font-mono text-caption text-faint", children: slug })) : null] }), status ? _jsx("div", { className: "shrink-0", children: status }) : null, headerActions ? (_jsx("div", { "data-slot": "entity-card-actions",
|
|
115
|
+
// items-center against the title's first line, and -mt-1 to pull an
|
|
116
|
+
// icon button's own padding back so the glyph optically lines up
|
|
117
|
+
// with the title rather than sitting a couple of pixels low.
|
|
118
|
+
className: "-mt-1 flex shrink-0 items-center gap-1", children: headerActions })) : null] }), description ? (_jsx("p", { dir: "auto", "data-slot": "entity-card-description", title: description, className: cn("m-0 text-body-sm text-body", descriptionLines === 1 ? "truncate" : "line-clamp-2"), children: description })) : null, meta, _jsx("div", { "aria-hidden": "true", className: "grow" }), stats && stats.length > 0 ? (_jsx("div", { "data-slot": "entity-card-stats", className: "flex flex-wrap items-center gap-4 border-t border-hairline pt-3 text-caption text-body", children: stats.map((stat) => (_jsxs("span", { className: "inline-flex items-center gap-1.5", children: [stat.icon ? (_jsx("span", { "aria-hidden": "true", className: "inline-flex [&>svg]:size-4", children: stat.icon })) : null, stat.value, _jsx("span", { className: "sr-only", children: stat.label })] }, stat.label))) })) : null, footer] }));
|
|
66
119
|
const card = (_jsxs(Card, { "data-slot": "entity-card",
|
|
67
120
|
// gap-0 py-0: `Card` pads itself for a header/content/footer stack, and
|
|
68
121
|
// this card's preview is full bleed to the top edge. The padding moves
|
|
@@ -85,9 +138,11 @@ function EntityCard({ title, slug, description, titleLines = 2, descriptionLines
|
|
|
85
138
|
className: "relative shrink-0 overflow-hidden rounded-t-xl border-b border-hairline", children: [_jsx(EntityIdentity, { seed: seed, name: title }), previewUrl ? (_jsx("div", { "data-slot": "entity-card-capture", "aria-hidden": "true", className: "absolute inset-0 bg-cover bg-center",
|
|
86
139
|
// A background image, not an <img>: a URL that 404s paints
|
|
87
140
|
// nothing and the identity tile below shows through, with no
|
|
88
|
-
// state and no client boundary.
|
|
89
|
-
//
|
|
90
|
-
|
|
141
|
+
// state and no client boundary. The URL goes out exactly as the
|
|
142
|
+
// caller wrote it — `cssUrlString` escapes only the quote and
|
|
143
|
+
// backslash that would break out of url("..."), and never
|
|
144
|
+
// re-encodes an already-encoded URL (ui#178).
|
|
145
|
+
style: { backgroundImage: `url("${cssUrlString(previewUrl)}")` } })) : null, revealed ? (_jsxs("div", { "data-slot": "entity-card-reveal", "data-cg-surface": "ink", className: cn("absolute inset-0 flex flex-col justify-end gap-1.5 bg-scrim-strong p-3 text-ink",
|
|
91
146
|
// opacity-0, not hidden: the panel is in the tab order at all
|
|
92
147
|
// times, so tabbing into Open is what reveals it, and a touch
|
|
93
148
|
// user with no hover still has a live tap target.
|
|
@@ -105,23 +160,23 @@ function EntityCard({ title, slug, description, titleLines = 2, descriptionLines
|
|
|
105
160
|
// anywhere on the thumbnail opens the entity. The anchor
|
|
106
161
|
// itself must NOT be positioned or the stretched layer sizes
|
|
107
162
|
// to the anchor instead of to the panel — the panel is already
|
|
108
|
-
// absolute, so it is the containing block.
|
|
163
|
+
// absolute, so it is the containing block. Dashboard comes
|
|
109
164
|
// later in the DOM and IS positioned, so it stacks above the
|
|
110
165
|
// stretched layer rather than under it.
|
|
111
|
-
className: "inline-flex items-center gap-1 rounded-pill border border-hairline px-2 py-1 text-caption no-underline after:absolute after:inset-0 after:content-[''] focus-visible:ring-3 focus-visible:ring-ring focus-visible:outline-none", children: [_jsx(OpenLiveIcon, { className: "size-3.5" }), "Open"] }),
|
|
166
|
+
className: "inline-flex items-center gap-1 rounded-pill border border-hairline px-2 py-1 text-caption no-underline after:absolute after:inset-0 after:content-[''] focus-visible:ring-3 focus-visible:ring-ring focus-visible:outline-none", children: [_jsx(OpenLiveIcon, { className: "size-3.5" }), "Open"] }), dashboardTarget ? (_jsxs("a", { href: dashboardTarget, "data-slot": "entity-card-dashboard",
|
|
112
167
|
// relative, and that is load-bearing: it lifts this link
|
|
113
168
|
// above Open's stretched ::after, which otherwise covers the
|
|
114
169
|
// whole panel and would swallow every click meant for here.
|
|
115
170
|
//
|
|
116
171
|
// And because it is lifted, it must not be live while the
|
|
117
172
|
// panel is invisible: opacity-0 is a paint state, so at rest
|
|
118
|
-
// this pill was a region of the thumbnail that went
|
|
119
|
-
//
|
|
173
|
+
// this pill was a region of the thumbnail that went here on
|
|
174
|
+
// a tap instead of opening the entity (#171).
|
|
120
175
|
// pointer-events-none until the panel is actually revealed —
|
|
121
176
|
// the same reasoning the kind mark carries. Open keeps its
|
|
122
177
|
// stretched hit area at all times, so the touch fallback is
|
|
123
178
|
// untouched.
|
|
124
|
-
className: "pointer-events-none relative inline-flex items-center gap-1 rounded-pill border border-hairline px-2 py-1 text-caption no-underline group-hover/card:pointer-events-auto group-focus-within/card:pointer-events-auto focus-visible:ring-3 focus-visible:ring-ring focus-visible:outline-none", children: [_jsx(
|
|
179
|
+
className: "pointer-events-none relative inline-flex items-center gap-1 rounded-pill border border-hairline px-2 py-1 text-caption no-underline group-hover/card:pointer-events-auto group-focus-within/card:pointer-events-auto focus-visible:ring-3 focus-visible:ring-ring focus-visible:outline-none", children: [_jsx(EntityDashboardIcon, { className: "size-3.5" }), "Dashboard"] })) : null] })] })) : null, kind ? (_jsx(EntityKindBadge, { kind: kind, className: "pointer-events-none absolute top-2 right-2" })) : null] })) : null, _jsx("div", { className: "flex min-h-0 flex-1 flex-col gap-3 p-(--card-spacing)", children: body })] }));
|
|
125
180
|
// A revealed card is never wrapped: the panel's Open action is already an
|
|
126
181
|
// anchor, and an anchor inside an anchor is invalid HTML that browsers repair
|
|
127
182
|
// by closing the outer one.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entity-card.js","sourceRoot":"","sources":["../../src/blocks/entity-card.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAA;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAA;AAC9D,OAAO,EACL,aAAa,EACb,WAAW,EACX,mBAAmB,EACnB,YAAY,
|
|
1
|
+
{"version":3,"file":"entity-card.js","sourceRoot":"","sources":["../../src/blocks/entity-card.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The small label that sits above something and names the part of the page it
|
|
3
|
+
* belongs to. A section label, a specimen caption, the word over a lockup.
|
|
4
|
+
*
|
|
5
|
+
* ## Why it exists as its own thing (#176)
|
|
6
|
+
*
|
|
7
|
+
* The recipe was already in this library — `text-label font-medium text-faint`,
|
|
8
|
+
* written inline inside `PageHeading` and reachable only by rendering a whole
|
|
9
|
+
* page lockup. So a surface that wanted the label and not the display heading
|
|
10
|
+
* had two options, and both are wrong in the same way: hand-build the three
|
|
11
|
+
* classes, or borrow the nearest primitive that is not this one.
|
|
12
|
+
*
|
|
13
|
+
* The console's styleguide did the second. Its section labels render as
|
|
14
|
+
* `Badge variant="outline"`, which is a pill — the right colour, the wrong
|
|
15
|
+
* shape, and a reference page for a design system teaching its reader that
|
|
16
|
+
* building your own furniture is normal. That is what cloudgrid-console#654
|
|
17
|
+
* filed and what this answers.
|
|
18
|
+
*
|
|
19
|
+
* `PageHeading` renders this rather than repeating the classes, so there is one
|
|
20
|
+
* definition of what an eyebrow looks like and retuning it is one edit here.
|
|
21
|
+
*
|
|
22
|
+
* ## What it is not
|
|
23
|
+
*
|
|
24
|
+
* Not a heading. It is a `<p>`, and it takes no `level`: an eyebrow is a label
|
|
25
|
+
* for the thing under it, so promoting it to `<h2>` would put a second entry in
|
|
26
|
+
* the document outline for one section and announce the label instead of the
|
|
27
|
+
* title. When the eyebrow and a heading belong together, put both in a
|
|
28
|
+
* `PageHeading`, which stacks them and keeps the heading the heading.
|
|
29
|
+
*
|
|
30
|
+
* Not uppercase. `--cg-label-size` carries its own weight and leading through
|
|
31
|
+
* `text-label`, and the brand's uppercase treatment belongs to the display face
|
|
32
|
+
* — the heading — rather than to the small print above it. A caller who wants
|
|
33
|
+
* caps has `className`.
|
|
34
|
+
*
|
|
35
|
+
* ## Type
|
|
36
|
+
*
|
|
37
|
+
* `text-label` rather than `text-caption`, deliberately: the label step exists
|
|
38
|
+
* on the brand ramp with its own weight companion (`--cg-label-weight`), and a
|
|
39
|
+
* caption is body copy set small. They render close and mean different things.
|
|
40
|
+
*/
|
|
41
|
+
declare function Eyebrow({ className, ...props }: React.ComponentProps<"p">): import("react").JSX.Element;
|
|
42
|
+
export { Eyebrow };
|
|
43
|
+
//# sourceMappingURL=eyebrow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eyebrow.d.ts","sourceRoot":"","sources":["../../src/blocks/eyebrow.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,iBAAS,OAAO,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,+BAalE;AAED,OAAO,EAAE,OAAO,EAAE,CAAA"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from "../lib/cloudgrid-cn.js";
|
|
3
|
+
/**
|
|
4
|
+
* The small label that sits above something and names the part of the page it
|
|
5
|
+
* belongs to. A section label, a specimen caption, the word over a lockup.
|
|
6
|
+
*
|
|
7
|
+
* ## Why it exists as its own thing (#176)
|
|
8
|
+
*
|
|
9
|
+
* The recipe was already in this library — `text-label font-medium text-faint`,
|
|
10
|
+
* written inline inside `PageHeading` and reachable only by rendering a whole
|
|
11
|
+
* page lockup. So a surface that wanted the label and not the display heading
|
|
12
|
+
* had two options, and both are wrong in the same way: hand-build the three
|
|
13
|
+
* classes, or borrow the nearest primitive that is not this one.
|
|
14
|
+
*
|
|
15
|
+
* The console's styleguide did the second. Its section labels render as
|
|
16
|
+
* `Badge variant="outline"`, which is a pill — the right colour, the wrong
|
|
17
|
+
* shape, and a reference page for a design system teaching its reader that
|
|
18
|
+
* building your own furniture is normal. That is what cloudgrid-console#654
|
|
19
|
+
* filed and what this answers.
|
|
20
|
+
*
|
|
21
|
+
* `PageHeading` renders this rather than repeating the classes, so there is one
|
|
22
|
+
* definition of what an eyebrow looks like and retuning it is one edit here.
|
|
23
|
+
*
|
|
24
|
+
* ## What it is not
|
|
25
|
+
*
|
|
26
|
+
* Not a heading. It is a `<p>`, and it takes no `level`: an eyebrow is a label
|
|
27
|
+
* for the thing under it, so promoting it to `<h2>` would put a second entry in
|
|
28
|
+
* the document outline for one section and announce the label instead of the
|
|
29
|
+
* title. When the eyebrow and a heading belong together, put both in a
|
|
30
|
+
* `PageHeading`, which stacks them and keeps the heading the heading.
|
|
31
|
+
*
|
|
32
|
+
* Not uppercase. `--cg-label-size` carries its own weight and leading through
|
|
33
|
+
* `text-label`, and the brand's uppercase treatment belongs to the display face
|
|
34
|
+
* — the heading — rather than to the small print above it. A caller who wants
|
|
35
|
+
* caps has `className`.
|
|
36
|
+
*
|
|
37
|
+
* ## Type
|
|
38
|
+
*
|
|
39
|
+
* `text-label` rather than `text-caption`, deliberately: the label step exists
|
|
40
|
+
* on the brand ramp with its own weight companion (`--cg-label-weight`), and a
|
|
41
|
+
* caption is body copy set small. They render close and mean different things.
|
|
42
|
+
*/
|
|
43
|
+
function Eyebrow({ className, ...props }) {
|
|
44
|
+
return (_jsx("p", { "data-slot": "eyebrow",
|
|
45
|
+
// m-0 because a consumer without Tailwind's preflight — a prose block, an
|
|
46
|
+
// Astro page with its own base sheet — inherits a paragraph margin and the
|
|
47
|
+
// label drifts away from the thing it labels. This library's own pages are
|
|
48
|
+
// preflighted, so the margin is invisible here and only ever wrong
|
|
49
|
+
// downstream, which is the failure worth carrying three characters for.
|
|
50
|
+
className: cn("m-0 text-label font-medium text-faint", className), ...props }));
|
|
51
|
+
}
|
|
52
|
+
export { Eyebrow };
|
|
53
|
+
//# sourceMappingURL=eyebrow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eyebrow.js","sourceRoot":"","sources":["../../src/blocks/eyebrow.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,oBAAoB,CAAA;AAEvC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,SAAS,OAAO,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAA6B;IACjE,OAAO,CACL,yBACY,SAAS;QACnB,0EAA0E;QAC1E,2EAA2E;QAC3E,2EAA2E;QAC3E,mEAAmE;QACnE,wEAAwE;QACxE,SAAS,EAAE,EAAE,CAAC,uCAAuC,EAAE,SAAS,CAAC,KAC7D,KAAK,GACT,CACH,CAAA;AACH,CAAC;AAED,OAAO,EAAE,OAAO,EAAE,CAAA"}
|
|
@@ -7,16 +7,21 @@
|
|
|
7
7
|
* structure, because the copy reads as a sequence of commitments rather than a
|
|
8
8
|
* feature race.
|
|
9
9
|
*
|
|
10
|
-
* ##
|
|
10
|
+
* ## The glyphs are Phosphor, through the library's own names
|
|
11
11
|
*
|
|
12
12
|
* v0 inlined ten Phosphor SVGs as raw strings, because Astro can import SVG via
|
|
13
13
|
* Vite's `?raw` and React bundlers cannot, and rendered them with
|
|
14
|
-
* `dangerouslySetInnerHTML`.
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* `
|
|
18
|
-
*
|
|
19
|
-
*
|
|
14
|
+
* `dangerouslySetInnerHTML`. This renders the same family, without either
|
|
15
|
+
* problem: `scripts/generate-phosphor-marks.mjs` reads the path data out of
|
|
16
|
+
* `@phosphor-icons/core` and inlines it as components, and this file names roles
|
|
17
|
+
* — `AiIcon`, `MemoryIcon`, `ScheduleIcon` — rather than glyphs, so a repick is
|
|
18
|
+
* one slug in the generator and no edit here (#167).
|
|
19
|
+
*
|
|
20
|
+
* The interim between the two was lucide, chosen when this registry declared
|
|
21
|
+
* `iconLibrary: lucide`. It no longer does: Phosphor is the only icon library,
|
|
22
|
+
* every equivalent was an approximation of a mark the designer had already
|
|
23
|
+
* picked, and `dangerouslySetInnerHTML` for decoration remains a sharp tool used
|
|
24
|
+
* for nothing.
|
|
20
25
|
*
|
|
21
26
|
* ## The matcher, and its escape hatch
|
|
22
27
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"feature-cells.d.ts","sourceRoot":"","sources":["../../src/blocks/feature-cells.tsx"],"names":[],"mappings":"AAeA
|
|
1
|
+
{"version":3,"file":"feature-cells.d.ts","sourceRoot":"","sources":["../../src/blocks/feature-cells.tsx"],"names":[],"mappings":"AAeA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,KAAK,gBAAgB,GAAG;IACtB,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;IACT,mDAAmD;IACnD,IAAI,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CACnD,CAAA;AA+BD,iBAAS,YAAY,CAAC,EACpB,KAAK,EACL,OAAiB,EACjB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,GAAG;IAC3C,KAAK,EAAE,gBAAgB,EAAE,CAAA;IACzB,OAAO,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAA;CAC7B,+BA4DA;AAED,OAAO,EAAE,YAAY,EAAE,CAAA;AACvB,YAAY,EAAE,gBAAgB,EAAE,CAAA"}
|