@xenide-io/the-old-ui-theme 0.2.9 → 0.3.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/README.md +1 -1
- package/dist/{chunk-SHF57J7U.mjs → chunk-FDMD3IIN.mjs} +1573 -652
- package/dist/index-D1RTT2Ap.d.mts +1044 -0
- package/dist/index-D1RTT2Ap.d.ts +1044 -0
- package/dist/index.d.mts +10 -7
- package/dist/index.d.ts +10 -7
- package/dist/index.js +1705 -744
- package/dist/index.mjs +61 -1
- package/dist/tailwind-preset.js +7 -0
- package/dist/tailwind-preset.mjs +7 -0
- package/dist/ui.d.mts +3 -2
- package/dist/ui.d.ts +3 -2
- package/dist/ui.js +1584 -666
- package/dist/ui.mjs +31 -1
- package/package.json +18 -4
- package/src/app/globals.css +1005 -227
- package/src/components/icons/IconBase.tsx +20 -12
- package/src/components/icons/createIconBase.tsx +12 -7
- package/src/components/icons/icons.tsx +208 -18
- package/src/components/sections/AlertShowcase.tsx +2 -1
- package/src/components/sections/BadgeShowcase.tsx +1 -1
- package/src/components/sections/ButtonShowcase.tsx +6 -10
- package/src/components/sections/CardShowcase.tsx +22 -6
- package/src/components/sections/DropdownShowcase.tsx +4 -6
- package/src/components/sections/FilterChipsShowcase.tsx +74 -26
- package/src/components/sections/FormShowcase.tsx +2 -1
- package/src/components/sections/IconShowcase.tsx +86 -206
- package/src/components/sections/KbdShowcase.tsx +47 -21
- package/src/components/sections/ModalShowcase.tsx +7 -6
- package/src/components/sections/ProductLayoutsShowcase.tsx +138 -0
- package/src/components/sections/ProgressShowcase.tsx +50 -53
- package/src/components/sections/SwapShowcase.tsx +13 -5
- package/src/components/ui/Alert.tsx +28 -19
- package/src/components/ui/AuthLayout.tsx +58 -0
- package/src/components/ui/Badge.tsx +10 -5
- package/src/components/ui/Button.tsx +22 -12
- package/src/components/ui/ButtonChrome.tsx +1 -1
- package/src/components/ui/Calendar.tsx +6 -7
- package/src/components/ui/Card.tsx +21 -11
- package/src/components/ui/CollapsibleSection.tsx +11 -11
- package/src/components/ui/DropdownMenu.tsx +189 -65
- package/src/components/ui/FilterBar.tsx +165 -0
- package/src/components/ui/FilterChips.tsx +65 -35
- package/src/components/ui/FilterControls.tsx +30 -0
- package/src/components/ui/FormField.tsx +69 -0
- package/src/components/ui/Input.tsx +166 -140
- package/src/components/ui/Kbd.tsx +88 -13
- package/src/components/ui/Loader.tsx +96 -0
- package/src/components/ui/Modal.tsx +66 -36
- package/src/components/ui/SettingsLayout.tsx +94 -0
- package/src/components/ui/ShowcaseWrapper.tsx +4 -16
- package/src/components/ui/Stepper.tsx +5 -6
- package/src/components/ui/first-slice.test.tsx +98 -0
- package/src/components/ui/index.ts +62 -3
- package/src/components/ui/interaction-primitives.test.tsx +77 -0
- package/src/components/ui/kbd-icons.test.tsx +90 -0
- package/src/components/ui/product-patterns.test.tsx +77 -0
- package/src/styles/themes.css +411 -1
- package/tailwind-preset.ts +7 -0
- package/dist/index-CmS6hcUk.d.mts +0 -753
- package/dist/index-CmS6hcUk.d.ts +0 -753
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { forwardRef, type SVGAttributes } from "react";
|
|
2
2
|
import { cn } from "@/lib/cn";
|
|
3
3
|
|
|
4
4
|
export interface IconProps extends SVGAttributes<SVGSVGElement> {
|
|
5
|
-
/** Pixel size or CSS length
|
|
5
|
+
/** Pixel size or CSS length; defaults to `1em`. */
|
|
6
6
|
size?: number | string;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
/**
|
|
10
|
-
export function IconBase({
|
|
9
|
+
/** Shared SVG wrapper with predictable sizing and accessible-name behavior. */
|
|
10
|
+
export const IconBase = forwardRef<SVGSVGElement, IconProps>(function IconBase({
|
|
11
11
|
className,
|
|
12
12
|
size,
|
|
13
13
|
children,
|
|
@@ -15,25 +15,33 @@ export function IconBase({
|
|
|
15
15
|
fill = "none",
|
|
16
16
|
xmlns = "http://www.w3.org/2000/svg",
|
|
17
17
|
focusable = "false",
|
|
18
|
+
style,
|
|
19
|
+
role,
|
|
20
|
+
"aria-hidden": ariaHidden,
|
|
21
|
+
"aria-label": ariaLabel,
|
|
22
|
+
"aria-labelledby": ariaLabelledBy,
|
|
18
23
|
...props
|
|
19
|
-
}
|
|
20
|
-
const
|
|
21
|
-
size != null
|
|
22
|
-
? { width: size, height: size }
|
|
23
|
-
: {};
|
|
24
|
+
}, ref) {
|
|
25
|
+
const hasAccessibleName = Boolean(ariaLabel || ariaLabelledBy);
|
|
24
26
|
|
|
25
27
|
return (
|
|
26
28
|
<svg
|
|
29
|
+
ref={ref}
|
|
27
30
|
className={cn("ph-icon", className)}
|
|
28
|
-
{...dimensionProps}
|
|
29
31
|
viewBox={viewBox}
|
|
30
32
|
fill={fill}
|
|
31
33
|
xmlns={xmlns}
|
|
32
34
|
focusable={focusable}
|
|
33
|
-
|
|
35
|
+
role={role ?? (hasAccessibleName ? "img" : undefined)}
|
|
36
|
+
aria-hidden={ariaHidden ?? (hasAccessibleName ? undefined : true)}
|
|
37
|
+
aria-label={ariaLabel}
|
|
38
|
+
aria-labelledby={ariaLabelledBy}
|
|
39
|
+
style={{ width: size, height: size, ...style }}
|
|
34
40
|
{...props}
|
|
35
41
|
>
|
|
36
42
|
{children}
|
|
37
43
|
</svg>
|
|
38
44
|
);
|
|
39
|
-
}
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
IconBase.displayName = "IconBase";
|
|
@@ -1,26 +1,31 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { forwardRef, type ReactNode } from "react";
|
|
2
2
|
import type { IconProps } from "@/components/icons/IconBase";
|
|
3
3
|
import { IconBase } from "@/components/icons/IconBase";
|
|
4
4
|
|
|
5
5
|
interface IconBaseDefinition {
|
|
6
|
+
name?: string;
|
|
6
7
|
viewBox?: string;
|
|
7
8
|
paths: ReactNode;
|
|
8
9
|
}
|
|
9
10
|
|
|
10
|
-
/** Factory for filled Lemon-style glyphs
|
|
11
|
-
export function createIconBase({ viewBox = "0 0 24 24", paths }: IconBaseDefinition) {
|
|
12
|
-
|
|
11
|
+
/** Factory for filled Old UI, Lemon, and Material-style glyphs. */
|
|
12
|
+
export function createIconBase({ name = "IconGlyph", viewBox = "0 0 24 24", paths }: IconBaseDefinition) {
|
|
13
|
+
const IconGlyph = forwardRef<SVGSVGElement, IconProps>(function IconGlyph(props, ref) {
|
|
13
14
|
return (
|
|
14
|
-
<IconBase viewBox={viewBox} {...props}>
|
|
15
|
+
<IconBase ref={ref} viewBox={viewBox} {...props}>
|
|
15
16
|
{paths}
|
|
16
17
|
</IconBase>
|
|
17
18
|
);
|
|
18
|
-
};
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
IconGlyph.displayName = name;
|
|
22
|
+
return IconGlyph;
|
|
19
23
|
}
|
|
20
24
|
|
|
21
25
|
/** Shorthand for single-path filled icons. */
|
|
22
|
-
export function createIconBasePath(d: string, viewBox = "0 0 24 24") {
|
|
26
|
+
export function createIconBasePath(d: string, viewBox = "0 0 24 24", name?: string) {
|
|
23
27
|
return createIconBase({
|
|
28
|
+
name,
|
|
24
29
|
viewBox,
|
|
25
30
|
paths: <path d={d} fill="currentColor" />,
|
|
26
31
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* (`frontend/src/lib/lemon-ui/icons/icons.tsx`) and Material Design where noted.
|
|
2
|
+
* Filled product glyphs from PostHog/Material sources plus clearly labeled Old UI originals.
|
|
4
3
|
*/
|
|
4
|
+
import { forwardRef } from "react";
|
|
5
5
|
import type { IconProps } from "@/components/icons/IconBase";
|
|
6
6
|
import { createIconBase, createIconBasePath } from "@/components/icons/createIconBase";
|
|
7
7
|
import { cn } from "@/lib/cn";
|
|
@@ -141,6 +141,13 @@ export const IconErrorOutline = createIconBase({
|
|
|
141
141
|
),
|
|
142
142
|
});
|
|
143
143
|
|
|
144
|
+
export const IconInfo = createIconBase({
|
|
145
|
+
name: "IconInfo",
|
|
146
|
+
paths: fill(
|
|
147
|
+
"M11 10h2v7h-2v-7zm0-3h2v2h-2V7zm1-5C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z",
|
|
148
|
+
),
|
|
149
|
+
});
|
|
150
|
+
|
|
144
151
|
export const IconCancel = createIconBase({
|
|
145
152
|
paths: fill(
|
|
146
153
|
"m12 2c-5.53 0-10 4.47-10 10s4.47 10 10 10 10-4.47 10-10-4.47-10-10-10zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm3.59-13-3.59 3.59-3.59-3.59-1.41 1.41 3.59 3.59-3.59 3.59 1.41 1.41 3.59-3.59 3.59 3.59 1.41-1.41-3.59-3.59 3.59-3.59z",
|
|
@@ -272,7 +279,152 @@ export const IconRocket = createIconBasePath(
|
|
|
272
279
|
"M9.19 6.35c-2.04 2.29-3.44 5.58-3.57 5.89L2 10.69l4.05-4.05c.47-.47 1.15-.68 1.81-.55l1.33 1.26zm5.45 8.67l-1.33-1.26c-.66-.13-1.34.08-1.81.55L2 18.31l3.62 3.57c.31-.13 3.6-1.53 5.89-3.57 1.53-1.72 2.52-3.76 2.87-5.02zM12 2c-1.1 0-2 .9-2 2v1.09c2.84.48 5 2.94 5 5.91 0 2.97-2.16 5.43-5 5.91V20c0 1.1.9 2 2 2s2-.9 2-2v-1.09c-2.84-.48-5-2.94-5-5.91 0-2.97 2.16-5.43 5-5.91V4c0-1.1-.9-2-2-2z",
|
|
273
280
|
);
|
|
274
281
|
|
|
275
|
-
export const IconTerminal =
|
|
282
|
+
export const IconTerminal = createIconBase({
|
|
283
|
+
name: "IconTerminal",
|
|
284
|
+
paths: (
|
|
285
|
+
<path
|
|
286
|
+
d="M3 4v16h18V4H3zm2 2h14v12H5V6zm2 2.2L10.8 12 7 15.8 8.4 17.2l5.2-5.2-5.2-5.2L7 8.2zM13 17h5v-2h-5v2z"
|
|
287
|
+
fill="currentColor"
|
|
288
|
+
fillRule="evenodd"
|
|
289
|
+
clipRule="evenodd"
|
|
290
|
+
/>
|
|
291
|
+
),
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
// —— Old UI originals: authored for this library's tactile product language ——
|
|
295
|
+
export const IconOldWindow = createIconBase({
|
|
296
|
+
name: "IconOldWindow",
|
|
297
|
+
paths: (
|
|
298
|
+
<path
|
|
299
|
+
d="M3 3v18h18V3H3zm2 7v9h14v-9H5zm1-4h2v1H6V6zm3 0h2v1H9V6z"
|
|
300
|
+
fill="currentColor"
|
|
301
|
+
fillRule="evenodd"
|
|
302
|
+
clipRule="evenodd"
|
|
303
|
+
/>
|
|
304
|
+
),
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
export const IconCommandCursor = createIconBase({
|
|
308
|
+
name: "IconCommandCursor",
|
|
309
|
+
paths: (
|
|
310
|
+
<path
|
|
311
|
+
d="M4 3v18h16V3H4zm2 2h12v14H6V5zm1.5 3.5L11 12l-3.5 3.5L9 17l5-5-5-5-1.5 1.5zM13 17h4v-2h-4v2z"
|
|
312
|
+
fill="currentColor"
|
|
313
|
+
fillRule="evenodd"
|
|
314
|
+
clipRule="evenodd"
|
|
315
|
+
/>
|
|
316
|
+
),
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
export const IconDataReel = createIconBase({
|
|
320
|
+
name: "IconDataReel",
|
|
321
|
+
paths: (
|
|
322
|
+
<path
|
|
323
|
+
d="M3 5v14h18V5H3zm2 2h14v10H5V7zm3 1a3 3 0 1 0 0 6 3 3 0 0 0 0-6zm8 0a3 3 0 1 0 0 6 3 3 0 0 0 0-6zM10 11h4v1.5h-4V11z"
|
|
324
|
+
fill="currentColor"
|
|
325
|
+
fillRule="evenodd"
|
|
326
|
+
clipRule="evenodd"
|
|
327
|
+
/>
|
|
328
|
+
),
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
export const IconCodePreview = createIconBase({
|
|
332
|
+
name: "IconCodePreview",
|
|
333
|
+
paths: (
|
|
334
|
+
<path
|
|
335
|
+
d="M3 3v15h18V3H3zm2 2h14v11H5V5zm3.5 2L5 10.5 8.5 14l1.4-1.4-2.1-2.1 2.1-2.1L8.5 7zm7 0-1.4 1.4 2.1 2.1-2.1 2.1 1.4 1.4 3.5-3.5L15.5 7zM9 20h6v2H9v-2z"
|
|
336
|
+
fill="currentColor"
|
|
337
|
+
fillRule="evenodd"
|
|
338
|
+
clipRule="evenodd"
|
|
339
|
+
/>
|
|
340
|
+
),
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
export const IconInsightBoard = createIconBase({
|
|
344
|
+
name: "IconInsightBoard",
|
|
345
|
+
paths: (
|
|
346
|
+
<path
|
|
347
|
+
d="M3 3v18h18V3H3zm2 2h14v3H5V5zm0 5h6v9H5v-9zm8 0h6v4h-6v-4zm0 6h6v3h-6v-3zM6 6h2v1H6V6zm3 0h2v1H9V6z"
|
|
348
|
+
fill="currentColor"
|
|
349
|
+
fillRule="evenodd"
|
|
350
|
+
clipRule="evenodd"
|
|
351
|
+
/>
|
|
352
|
+
),
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
export const IconEventStream = createIconBase({
|
|
356
|
+
name: "IconEventStream",
|
|
357
|
+
paths: (
|
|
358
|
+
<>
|
|
359
|
+
<path d="M5 4h2v16H5V4z" fill="currentColor" opacity="0.45" />
|
|
360
|
+
{fill("M6 3a3 3 0 1 0 0 6 3 3 0 0 0 0-6zm0 8a3 3 0 1 0 0 6 3 3 0 0 0 0-6zm5-6h10v2H11V5zm0 8h7v2h-7v-2zm0 5h10v2H11v-2z")}
|
|
361
|
+
</>
|
|
362
|
+
),
|
|
363
|
+
});
|
|
364
|
+
|
|
365
|
+
export const IconFeatureGate = createIconBase({
|
|
366
|
+
name: "IconFeatureGate",
|
|
367
|
+
paths: (
|
|
368
|
+
<path
|
|
369
|
+
d="M4 3h2v18H4V3zm3 2h12l-3 4 3 4H7V5zm4 1-2.2 4H12l-1 4 4.2-5H12l1-3h-2z"
|
|
370
|
+
fill="currentColor"
|
|
371
|
+
fillRule="evenodd"
|
|
372
|
+
clipRule="evenodd"
|
|
373
|
+
/>
|
|
374
|
+
),
|
|
375
|
+
});
|
|
376
|
+
|
|
377
|
+
export const IconReplayFrame = createIconBase({
|
|
378
|
+
name: "IconReplayFrame",
|
|
379
|
+
paths: (
|
|
380
|
+
<path
|
|
381
|
+
d="M3 3v18h18V3H3zm2 2h14v11H5V5zm5 2v7l6-3.5L10 7zm-5 11h9v1H5v-1zm11 0h3v1h-3v-1z"
|
|
382
|
+
fill="currentColor"
|
|
383
|
+
fillRule="evenodd"
|
|
384
|
+
clipRule="evenodd"
|
|
385
|
+
/>
|
|
386
|
+
),
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
export const IconQueryStack = createIconBase({
|
|
390
|
+
name: "IconQueryStack",
|
|
391
|
+
paths: fill(
|
|
392
|
+
"M4 5c0-1.66 3.58-3 8-3s8 1.34 8 3-3.58 3-8 3-8-1.34-8-3zm0 3v3c0 1.66 3.58 3 8 3 .7 0 1.38-.04 2-.12V11.8c-.64.13-1.31.2-2 .2-4.42 0-8-1.34-8-3zm0 6v3c0 1.66 3.58 3 8 3 .7 0 1.38-.04 2-.12v-2.08c-.64.13-1.31.2-2 .2-4.42 0-8-1.34-8-3zm12-1 5 4-5 4v-3h-4v-2h4v-3z",
|
|
393
|
+
),
|
|
394
|
+
});
|
|
395
|
+
|
|
396
|
+
export const IconExperimentSplit = createIconBase({
|
|
397
|
+
name: "IconExperimentSplit",
|
|
398
|
+
paths: fill(
|
|
399
|
+
"M5 3a3 3 0 1 0 0 6 3 3 0 0 0 0-6zm14 0a3 3 0 1 0 0 6 3 3 0 0 0 0-6zM5 15a3 3 0 1 0 0 6 3 3 0 0 0 0-6zm1-6h2c0 2.2 1.8 4 4 4h2.17A3 3 0 0 1 19 11v2a3 3 0 0 1-4.83-2H12a6 6 0 0 1-6-6v4zm0 4a6 6 0 0 0 6-6h2a8 8 0 0 1-8 8v-2z",
|
|
400
|
+
),
|
|
401
|
+
});
|
|
402
|
+
|
|
403
|
+
export const IconSurveyCard = createIconBase({
|
|
404
|
+
name: "IconSurveyCard",
|
|
405
|
+
paths: (
|
|
406
|
+
<path
|
|
407
|
+
d="M3 3v18h18V3H3zm2 2h14v14H5V5zm2 2h7v2H7V7zm0 4h4v2H7v-2zm7-.4-2.5 2.5-1-1-1.4 1.4 2.4 2.4 3.9-3.9-1.4-1.4zM7 16h10v1H7v-1z"
|
|
408
|
+
fill="currentColor"
|
|
409
|
+
fillRule="evenodd"
|
|
410
|
+
clipRule="evenodd"
|
|
411
|
+
/>
|
|
412
|
+
),
|
|
413
|
+
});
|
|
414
|
+
|
|
415
|
+
export const OLD_UI_ICONS = {
|
|
416
|
+
oldWindow: IconOldWindow,
|
|
417
|
+
commandCursor: IconCommandCursor,
|
|
418
|
+
dataReel: IconDataReel,
|
|
419
|
+
codePreview: IconCodePreview,
|
|
420
|
+
insightBoard: IconInsightBoard,
|
|
421
|
+
eventStream: IconEventStream,
|
|
422
|
+
featureGate: IconFeatureGate,
|
|
423
|
+
replayFrame: IconReplayFrame,
|
|
424
|
+
queryStack: IconQueryStack,
|
|
425
|
+
experimentSplit: IconExperimentSplit,
|
|
426
|
+
surveyCard: IconSurveyCard,
|
|
427
|
+
} as const;
|
|
276
428
|
|
|
277
429
|
export const IconActivity = createIconBasePath(
|
|
278
430
|
"M22 12h-4l-3 9L9 3l-3 9H2v2h6.76l2.24-6.72L15 15l2.24-6.72L19 14h3v-2z",
|
|
@@ -283,12 +435,14 @@ export const IconFlask = createIconBasePath(
|
|
|
283
435
|
);
|
|
284
436
|
|
|
285
437
|
/** Busy-state spinner — PostHog `IconSync` with spin animation. */
|
|
286
|
-
export function IconSpinner({ className, ...props }
|
|
287
|
-
return <IconSync className={cn("ph-icon-spin", className)} {...props} />;
|
|
288
|
-
}
|
|
438
|
+
export const IconSpinner = forwardRef<SVGSVGElement, IconProps>(function IconSpinner({ className, ...props }, ref) {
|
|
439
|
+
return <IconSync ref={ref} className={cn("ph-icon-spin", className)} {...props} />;
|
|
440
|
+
});
|
|
289
441
|
|
|
290
|
-
|
|
291
|
-
|
|
442
|
+
IconSpinner.displayName = "IconSpinner";
|
|
443
|
+
|
|
444
|
+
/** Canonical names power documentation and new dynamic-icon usage. */
|
|
445
|
+
export const CANONICAL_ICONS = {
|
|
292
446
|
activity: IconActivity,
|
|
293
447
|
areaChart: IconAreaChart,
|
|
294
448
|
arrowDown: IconArrowDown,
|
|
@@ -303,65 +457,101 @@ export const PH_ICONS = {
|
|
|
303
457
|
chevronDown: IconChevronDown,
|
|
304
458
|
chevronLeft: IconChevronLeft,
|
|
305
459
|
chevronRight: IconChevronRight,
|
|
306
|
-
|
|
460
|
+
clipboardEdit: IconClipboardEdit,
|
|
307
461
|
close: IconClose,
|
|
462
|
+
codePreview: IconCodePreview,
|
|
308
463
|
cohort: IconCohort,
|
|
464
|
+
commandCursor: IconCommandCursor,
|
|
309
465
|
copy: IconCopy,
|
|
310
466
|
cumulativeChart: IconCumulativeChart,
|
|
467
|
+
dataReel: IconDataReel,
|
|
311
468
|
database: IconDatabase,
|
|
312
469
|
download: IconDownload,
|
|
313
470
|
edit: IconEdit,
|
|
314
471
|
errorOutline: IconErrorOutline,
|
|
472
|
+
eventStream: IconEventStream,
|
|
315
473
|
exclamation: IconExclamation,
|
|
474
|
+
experimentSplit: IconExperimentSplit,
|
|
475
|
+
featureGate: IconFeatureGate,
|
|
316
476
|
flag: IconFlag,
|
|
317
477
|
flare: IconFlare,
|
|
318
478
|
flask: IconFlask,
|
|
319
479
|
gift: IconGift,
|
|
320
|
-
|
|
480
|
+
gridView: IconGridView,
|
|
321
481
|
handClick: IconHandClick,
|
|
322
482
|
home: IconHome,
|
|
323
|
-
info:
|
|
483
|
+
info: IconInfo,
|
|
484
|
+
insightBoard: IconInsightBoard,
|
|
324
485
|
layers: IconLayers,
|
|
325
|
-
|
|
486
|
+
listView: IconListView,
|
|
326
487
|
logout: IconLogout,
|
|
327
488
|
mail: IconMail,
|
|
328
489
|
moon: IconMoon,
|
|
490
|
+
oldWindow: IconOldWindow,
|
|
329
491
|
panelRight: IconPanelRight,
|
|
330
492
|
person: IconPerson,
|
|
331
|
-
|
|
493
|
+
playCircle: IconPlayCircle,
|
|
332
494
|
plus: IconPlus,
|
|
333
495
|
premium: IconPremium,
|
|
334
496
|
queryEditor: IconQueryEditor,
|
|
497
|
+
queryStack: IconQueryStack,
|
|
335
498
|
radar: IconRadar,
|
|
336
499
|
recording: IconRecording,
|
|
500
|
+
replayFrame: IconReplayFrame,
|
|
337
501
|
robot: IconRobot,
|
|
338
502
|
rocket: IconRocket,
|
|
339
503
|
save: IconSave,
|
|
340
504
|
search: IconSearch,
|
|
341
505
|
selectEvents: IconSelectEvents,
|
|
342
|
-
settings: IconTuning,
|
|
343
506
|
shoppingCart: IconShoppingCart,
|
|
344
507
|
spinner: IconSpinner,
|
|
345
508
|
star: IconStar,
|
|
346
509
|
subArrowRight: IconSubArrowRight,
|
|
347
510
|
sun: IconSun,
|
|
511
|
+
surveyCard: IconSurveyCard,
|
|
348
512
|
surveys: IconSurveys,
|
|
349
513
|
sync: IconSync,
|
|
350
514
|
tableChart: IconTableChart,
|
|
351
515
|
terminal: IconTerminal,
|
|
352
516
|
toggle: IconToggle,
|
|
353
517
|
trash: IconTrash,
|
|
354
|
-
|
|
518
|
+
tuning: IconTuning,
|
|
355
519
|
upload: IconUpload,
|
|
356
520
|
volume: IconVolume,
|
|
357
521
|
volumeOff: IconVolumeOff,
|
|
522
|
+
} as const;
|
|
523
|
+
|
|
524
|
+
/** Compatibility names remain runtime-identical to their canonical glyphs. */
|
|
525
|
+
export const PH_ICON_ALIASES = {
|
|
526
|
+
clipboard: IconClipboardEdit,
|
|
527
|
+
grid: IconGridView,
|
|
528
|
+
list: IconListView,
|
|
529
|
+
play: IconPlayCircle,
|
|
530
|
+
settings: IconTuning,
|
|
531
|
+
trendingUp: IconArrowUp,
|
|
358
532
|
warning: IconExclamation,
|
|
359
533
|
xCircle: IconCancel,
|
|
360
534
|
} as const;
|
|
361
535
|
|
|
536
|
+
export const PH_ICONS = {
|
|
537
|
+
...CANONICAL_ICONS,
|
|
538
|
+
...PH_ICON_ALIASES,
|
|
539
|
+
} as const;
|
|
540
|
+
|
|
541
|
+
for (const [name, Icon] of Object.entries(CANONICAL_ICONS)) {
|
|
542
|
+
const namedIcon = Icon as typeof Icon & { displayName?: string };
|
|
543
|
+
if (!namedIcon.displayName || namedIcon.displayName === "IconGlyph") {
|
|
544
|
+
namedIcon.displayName = `Icon${name[0].toUpperCase()}${name.slice(1)}`;
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
export type CanonicalIconName = keyof typeof CANONICAL_ICONS;
|
|
549
|
+
export type IconAliasName = keyof typeof PH_ICON_ALIASES;
|
|
362
550
|
export type IconName = keyof typeof PH_ICONS;
|
|
363
551
|
|
|
364
|
-
export
|
|
552
|
+
export const IconByName = forwardRef<SVGSVGElement, IconProps & { name: IconName }>(function IconByName({ name, ...props }, ref) {
|
|
365
553
|
const Icon = PH_ICONS[name];
|
|
366
|
-
return <Icon {...props} />;
|
|
367
|
-
}
|
|
554
|
+
return <Icon ref={ref} {...props} />;
|
|
555
|
+
});
|
|
556
|
+
|
|
557
|
+
IconByName.displayName = "IconByName";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Alert, ComponentDocs, ShowcaseWrapper } from "@/components/ui";
|
|
2
2
|
|
|
3
3
|
export default function AlertShowcase() {
|
|
4
|
-
const code = `import { Alert } from "the-old-ui";
|
|
4
|
+
const code = `import { Alert } from "@xenide-io/the-old-ui-theme";
|
|
5
5
|
|
|
6
6
|
<div className="space-y-4">
|
|
7
7
|
<Alert status="info" title="Pipeline delay" description="Events are flowing; warehouse sync may lag by ~2 minutes." />
|
|
@@ -24,6 +24,7 @@ export default function AlertShowcase() {
|
|
|
24
24
|
{ name: "description", type: "string", description: "Supporting message copy." },
|
|
25
25
|
{ name: "onDismiss", type: "() => void", description: "Shows a close button when provided." },
|
|
26
26
|
{ name: "icon", type: "ReactNode", description: "Optional custom icon override." },
|
|
27
|
+
{ name: "live", type: "off | polite | assertive", description: "Opt into live-region announcements for content that appears dynamically." },
|
|
27
28
|
]}
|
|
28
29
|
/>
|
|
29
30
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Badge, ComponentDocs, ShowcaseWrapper } from "@/components/ui";
|
|
2
2
|
|
|
3
3
|
export default function BadgeShowcase() {
|
|
4
|
-
const code = `import { Badge } from "the-old-ui";
|
|
4
|
+
const code = `import { Badge } from "@xenide-io/the-old-ui-theme";
|
|
5
5
|
|
|
6
6
|
<div className="ph-panel space-y-6">
|
|
7
7
|
<div>
|
|
@@ -3,7 +3,6 @@ import {
|
|
|
3
3
|
IconPlayCircle,
|
|
4
4
|
IconPlus,
|
|
5
5
|
IconSave,
|
|
6
|
-
IconSpinner,
|
|
7
6
|
IconSubArrowRight,
|
|
8
7
|
IconTrash,
|
|
9
8
|
IconUpload,
|
|
@@ -11,8 +10,7 @@ import {
|
|
|
11
10
|
import { Button, ComponentDocs, DropdownButton, DropdownItem, Panel, ShowcaseWrapper } from "@/components/ui";
|
|
12
11
|
|
|
13
12
|
export default function ButtonShowcase() {
|
|
14
|
-
const code = `import { IconDownload, IconPlayCircle, IconPlus, IconSave,
|
|
15
|
-
import { Button, DropdownButton, DropdownItem, Panel } from "the-old-ui";
|
|
13
|
+
const code = `import { Button, DropdownButton, DropdownItem, IconDownload, IconPlayCircle, IconPlus, IconSave, IconSubArrowRight, IconTrash, IconUpload, Panel } from "@xenide-io/the-old-ui-theme";
|
|
16
14
|
|
|
17
15
|
<div className="space-y-8">
|
|
18
16
|
<Panel className="space-y-4">
|
|
@@ -144,9 +142,7 @@ import { Button, DropdownButton, DropdownItem, Panel } from "the-old-ui";
|
|
|
144
142
|
<Button variant="primary" disabled>
|
|
145
143
|
Disabled
|
|
146
144
|
</Button>
|
|
147
|
-
<Button variant="primary"
|
|
148
|
-
Loading
|
|
149
|
-
</Button>
|
|
145
|
+
<Button variant="primary" loading>Loading</Button>
|
|
150
146
|
</div>
|
|
151
147
|
</Panel>
|
|
152
148
|
</div>`;
|
|
@@ -154,7 +150,7 @@ import { Button, DropdownButton, DropdownItem, Panel } from "the-old-ui";
|
|
|
154
150
|
return (
|
|
155
151
|
<ShowcaseWrapper
|
|
156
152
|
title="Buttons"
|
|
157
|
-
description="
|
|
153
|
+
description="Every filled variant shares the same bordered face, lower frame, hover lift, and pressed depth. Ghost and link actions stay flat."
|
|
158
154
|
code={code}
|
|
159
155
|
filename="ButtonExample.tsx"
|
|
160
156
|
docs={
|
|
@@ -167,6 +163,8 @@ import { Button, DropdownButton, DropdownItem, Panel } from "the-old-ui";
|
|
|
167
163
|
{ name: "icon", type: "ReactNode", description: "Leading icon slot." },
|
|
168
164
|
{ name: "sideIcon", type: "ReactNode", description: "Trailing icon slot." },
|
|
169
165
|
{ name: "split", type: "boolean", defaultValue: "false", description: "Adds split divider before the trailing slot." },
|
|
166
|
+
{ name: "loading", type: "boolean", defaultValue: "false", description: "Disables the action, exposes aria-busy, and replaces the leading icon with a spinner." },
|
|
167
|
+
{ name: "loadingLabel", type: "ReactNode", description: "Optional label shown while loading; the normal label stays in place by default." },
|
|
170
168
|
]}
|
|
171
169
|
/>
|
|
172
170
|
}
|
|
@@ -301,9 +299,7 @@ import { Button, DropdownButton, DropdownItem, Panel } from "the-old-ui";
|
|
|
301
299
|
<Button variant="primary" disabled>
|
|
302
300
|
Disabled
|
|
303
301
|
</Button>
|
|
304
|
-
<Button variant="primary"
|
|
305
|
-
Loading
|
|
306
|
-
</Button>
|
|
302
|
+
<Button variant="primary" loading>Loading</Button>
|
|
307
303
|
</div>
|
|
308
304
|
</Panel>
|
|
309
305
|
</div>
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { Badge, Button, Card, ComponentDocs, ShowcaseWrapper } from "@/components/ui";
|
|
2
2
|
|
|
3
3
|
export default function CardShowcase() {
|
|
4
|
-
const code = `import { Badge, Button, Card } from "the-old-ui";
|
|
4
|
+
const code = `import { Badge, Button, Card } from "@xenide-io/the-old-ui-theme";
|
|
5
5
|
|
|
6
6
|
<div className="grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3">
|
|
7
7
|
<Card
|
|
8
8
|
title="Insight saved"
|
|
9
|
-
description="
|
|
9
|
+
description="A quiet, static surface. Depth is reserved for interactive or elevated content."
|
|
10
10
|
actions={
|
|
11
11
|
<>
|
|
12
12
|
<Button variant="secondary" outline>
|
|
@@ -19,7 +19,7 @@ export default function CardShowcase() {
|
|
|
19
19
|
|
|
20
20
|
<Card
|
|
21
21
|
title="With visual"
|
|
22
|
-
description="
|
|
22
|
+
description="Media sits flush to the card edge with a semantic divider."
|
|
23
23
|
media={<div className="flex h-40 items-center justify-center bg-gradient-to-br from-orange-400 via-ph-brand to-ph-blue text-lg font-bold text-white">Hero stripe</div>}
|
|
24
24
|
actions={
|
|
25
25
|
<Button variant="primary" size="sm">
|
|
@@ -60,12 +60,19 @@ export default function CardShowcase() {
|
|
|
60
60
|
description="Grey trays on canvas — mirrors secondary surfaces in-app."
|
|
61
61
|
actions={<Button variant="primary" outline>Inspect</Button>}
|
|
62
62
|
/>
|
|
63
|
+
|
|
64
|
+
<Card
|
|
65
|
+
interactive
|
|
66
|
+
title="Interactive surface"
|
|
67
|
+
description="Hover depth is opt-in for cards containing an action."
|
|
68
|
+
actions={<Button variant="tertiary">Review</Button>}
|
|
69
|
+
/>
|
|
63
70
|
</div>`;
|
|
64
71
|
|
|
65
72
|
return (
|
|
66
73
|
<ShowcaseWrapper
|
|
67
74
|
title="Cards"
|
|
68
|
-
description="
|
|
75
|
+
description="Static by default, with explicit elevated, highlighted, and interactive treatments."
|
|
69
76
|
code={code}
|
|
70
77
|
filename="CardExample.tsx"
|
|
71
78
|
docs={
|
|
@@ -76,6 +83,8 @@ export default function CardShowcase() {
|
|
|
76
83
|
{ name: "description", type: "ReactNode", description: "Optional supporting copy." },
|
|
77
84
|
{ name: "actions", type: "ReactNode", description: "Button row rendered with card action spacing." },
|
|
78
85
|
{ name: "media", type: "ReactNode", description: "Optional visual block rendered above the card body." },
|
|
86
|
+
{ name: "interactive", type: "boolean", defaultValue: "false", description: "Adds hover and focus-within depth for a card containing an action." },
|
|
87
|
+
{ name: "titleAs", type: "h2 | h3 | h4", defaultValue: "h3", description: "Selects the semantic heading level without changing the card style." },
|
|
79
88
|
]}
|
|
80
89
|
/>
|
|
81
90
|
}
|
|
@@ -83,7 +92,7 @@ export default function CardShowcase() {
|
|
|
83
92
|
<div className="grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3">
|
|
84
93
|
<Card
|
|
85
94
|
title="Insight saved"
|
|
86
|
-
description="
|
|
95
|
+
description="A quiet, static surface. Depth is reserved for interactive or elevated content."
|
|
87
96
|
actions={
|
|
88
97
|
<>
|
|
89
98
|
<Button variant="secondary" outline>
|
|
@@ -96,7 +105,7 @@ export default function CardShowcase() {
|
|
|
96
105
|
|
|
97
106
|
<Card
|
|
98
107
|
title="With visual"
|
|
99
|
-
description="
|
|
108
|
+
description="Media sits flush to the card edge with a semantic divider."
|
|
100
109
|
media={<div className="flex h-40 items-center justify-center bg-gradient-to-br from-orange-400 via-ph-brand to-ph-blue text-lg font-bold text-white">Hero stripe</div>}
|
|
101
110
|
actions={
|
|
102
111
|
<Button variant="primary" size="sm">
|
|
@@ -137,6 +146,13 @@ export default function CardShowcase() {
|
|
|
137
146
|
description="Grey trays on canvas — mirrors secondary surfaces in-app."
|
|
138
147
|
actions={<Button variant="primary" outline>Inspect</Button>}
|
|
139
148
|
/>
|
|
149
|
+
|
|
150
|
+
<Card
|
|
151
|
+
interactive
|
|
152
|
+
title="Interactive surface"
|
|
153
|
+
description="Hover depth is opt-in for cards containing an action."
|
|
154
|
+
actions={<Button variant="tertiary">Review</Button>}
|
|
155
|
+
/>
|
|
140
156
|
</div>
|
|
141
157
|
</ShowcaseWrapper>
|
|
142
158
|
);
|
|
@@ -4,8 +4,8 @@ import { IconCopy, IconEdit, IconLogout, IconPerson, IconTrash, IconTuning } fro
|
|
|
4
4
|
import { DropdownButton, DropdownItem, ShowcaseWrapper } from "@/components/ui";
|
|
5
5
|
|
|
6
6
|
export default function DropdownShowcase() {
|
|
7
|
-
const code = `import { IconCopy, IconEdit, IconLogout, IconPerson, IconTrash, IconTuning } from "the-old-ui";
|
|
8
|
-
import { DropdownButton, DropdownItem } from "the-old-ui";
|
|
7
|
+
const code = `import { IconCopy, IconEdit, IconLogout, IconPerson, IconTrash, IconTuning } from "@xenide-io/the-old-ui-theme";
|
|
8
|
+
import { DropdownButton, DropdownItem } from "@xenide-io/the-old-ui-theme";
|
|
9
9
|
|
|
10
10
|
<div className="ph-panel space-y-6">
|
|
11
11
|
<p className="text-sm text-ph-subtle">
|
|
@@ -51,15 +51,13 @@ import { DropdownButton, DropdownItem } from "the-old-ui";
|
|
|
51
51
|
return (
|
|
52
52
|
<ShowcaseWrapper
|
|
53
53
|
title="Dropdowns"
|
|
54
|
-
description="
|
|
54
|
+
description="Accessible menu buttons with keyboard navigation and automatic viewport-aware side flipping and alignment shifting."
|
|
55
55
|
code={code}
|
|
56
56
|
filename="DropdownExample.tsx"
|
|
57
57
|
>
|
|
58
58
|
<div className="ph-panel space-y-6">
|
|
59
59
|
<p className="text-sm text-ph-subtle">
|
|
60
|
-
|
|
61
|
-
<code className="ph-kbd">the-old-ui</code> — labelled Lemon triggers +{" "}
|
|
62
|
-
<code className="ph-kbd">DropdownItem</code> menu rows.
|
|
60
|
+
Menus prefer the requested side, then flip above or sideways and shift start/end alignment to remain visible.
|
|
63
61
|
</p>
|
|
64
62
|
|
|
65
63
|
<div className="flex flex-wrap items-start gap-6">
|