@heliosgraphics/fx 0.0.1-alpha.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.
Files changed (67) hide show
  1. package/components/LiveComponents/LiveComponents.tsx +116 -0
  2. package/components/LiveComponents/LiveComponents.types.ts +9 -0
  3. package/components/LiveComponents/LiveComponents.utils.ts +1 -0
  4. package/components/LiveComponents/_components/GridBackground/GridBackground.module.css +14 -0
  5. package/components/LiveComponents/_components/GridBackground/GridBackground.tsx +18 -0
  6. package/components/LiveComponents/_components/GridBackground/GridBackground.types.ts +5 -0
  7. package/components/LiveComponents/_components/GridBackground/index.ts +1 -0
  8. package/components/LiveComponents/_components/LiveComponent/LiveComponent.module.css +45 -0
  9. package/components/LiveComponents/_components/LiveComponent/LiveComponent.tsx +63 -0
  10. package/components/LiveComponents/_components/LiveComponent/LiveComponent.types.ts +4 -0
  11. package/components/LiveComponents/_components/LiveComponent/index.ts +1 -0
  12. package/components/LiveComponents/_components/PermutationsGrid/PermutationsGrid.module.css +28 -0
  13. package/components/LiveComponents/_components/PermutationsGrid/PermutationsGrid.tsx +117 -0
  14. package/components/LiveComponents/_components/PermutationsGrid/PermutationsGrid.types.ts +8 -0
  15. package/components/LiveComponents/_components/PermutationsGrid/PermutationsGrid.utils.ts +24 -0
  16. package/components/LiveComponents/_components/PermutationsGrid/index.ts +2 -0
  17. package/components/LiveComponents/index.ts +2 -0
  18. package/components/Page/Page.tsx +52 -0
  19. package/components/Page/Page.types.ts +13 -0
  20. package/components/Page/index.ts +2 -0
  21. package/components/PageBlock/PageBlock.tsx +16 -0
  22. package/components/PageBlock/PageBlock.types.ts +6 -0
  23. package/components/PageBlock/index.ts +2 -0
  24. package/components/PropsTable/PropsTable.tsx +84 -0
  25. package/components/PropsTable/PropsTable.types.ts +7 -0
  26. package/components/PropsTable/PropsTable.utils.tsx +81 -0
  27. package/components/PropsTable/_components/BooleanEditor/BooleanEditor.tsx +23 -0
  28. package/components/PropsTable/_components/BooleanEditor/BooleanEditor.types.ts +6 -0
  29. package/components/PropsTable/_components/BooleanEditor/index.ts +2 -0
  30. package/components/PropsTable/_components/EnumEditor/EnumEditor.tsx +64 -0
  31. package/components/PropsTable/_components/EnumEditor/EnumEditor.types.ts +9 -0
  32. package/components/PropsTable/_components/EnumEditor/index.ts +2 -0
  33. package/components/PropsTable/_components/NumberEditor/NumberEditor.tsx +26 -0
  34. package/components/PropsTable/_components/NumberEditor/NumberEditor.types.ts +9 -0
  35. package/components/PropsTable/_components/NumberEditor/index.ts +2 -0
  36. package/components/PropsTable/_components/StringEditor/StringEditor.tsx +22 -0
  37. package/components/PropsTable/_components/StringEditor/StringEditor.types.ts +6 -0
  38. package/components/PropsTable/_components/StringEditor/index.ts +2 -0
  39. package/components/PropsTable/index.ts +2 -0
  40. package/components/WorkshopAside/WorkshopAside.tsx +103 -0
  41. package/components/WorkshopAside/WorkshopAside.types.ts +6 -0
  42. package/components/WorkshopAside/index.ts +2 -0
  43. package/components/WorkshopNavigation/WorkshopNavigation.tsx +36 -0
  44. package/components/WorkshopNavigation/WorkshopNavigation.types.ts +1 -0
  45. package/components/WorkshopNavigation/index.ts +2 -0
  46. package/components/index.ts +17 -0
  47. package/config/index.ts +24 -0
  48. package/contexts/LayoutProvider/LayoutProvider.tsx +28 -0
  49. package/contexts/LayoutProvider/LayoutProvider.types.ts +8 -0
  50. package/contexts/LayoutProvider/index.ts +2 -0
  51. package/contexts/WorkshopProvider/WorkshopProvider.tsx +57 -0
  52. package/contexts/WorkshopProvider/WorkshopProvider.types.ts +11 -0
  53. package/contexts/WorkshopProvider/index.ts +2 -0
  54. package/contexts/index.ts +5 -0
  55. package/index.ts +17 -0
  56. package/package.json +41 -0
  57. package/pages/ComponentPage/ComponentPage.tsx +26 -0
  58. package/pages/ComponentPage/ComponentPage.types.ts +10 -0
  59. package/pages/ComponentPage/index.ts +2 -0
  60. package/pages/DashboardPage/DashboardPage.tsx +88 -0
  61. package/pages/DashboardPage/DashboardPage.types.ts +9 -0
  62. package/pages/DashboardPage/DashboardPage.utils.ts +33 -0
  63. package/pages/DashboardPage/index.ts +2 -0
  64. package/pages/index.ts +5 -0
  65. package/types/config.ts +18 -0
  66. package/types/knobs.ts +13 -0
  67. package/types/meta.ts +28 -0
@@ -0,0 +1,26 @@
1
+ import { Breadcrumb, type BreadcrumbItem } from "@heliosgraphics/ui"
2
+ import { notFound } from "next/navigation"
3
+ import { Page } from "../../components/Page"
4
+ import { PropsTable } from "../../components/PropsTable"
5
+ import { LiveComponents } from "../../components/LiveComponents"
6
+ import type { FC } from "react"
7
+ import type { ComponentPageProps } from "./ComponentPage.types"
8
+
9
+ export const ComponentPage: FC<ComponentPageProps> = async ({ params, components, knobs, demoComponents }) => {
10
+ const { component } = await params
11
+ const demoMeta = components[component]
12
+
13
+ if (!component || !demoMeta) notFound()
14
+
15
+ const BREADCRUMB_ITEMS: Array<BreadcrumbItem> = [
16
+ { name: "Components", href: "/" },
17
+ { name: component, href: `/components/${component}`, isActive: true },
18
+ ]
19
+
20
+ return (
21
+ <Page title={component} breadcrumb={<Breadcrumb items={BREADCRUMB_ITEMS} />} disabledPadding={true}>
22
+ <LiveComponents demoComponent={demoComponents?.[component] ?? null} demoMeta={demoMeta} knobs={knobs} />
23
+ <PropsTable meta={demoMeta} knobs={knobs} />
24
+ </Page>
25
+ )
26
+ }
@@ -0,0 +1,10 @@
1
+ import type { ReactNode } from "react"
2
+ import type { WorkshopComponentRegistry } from "../../types/meta"
3
+ import type { KnobRegistry } from "../../types/knobs"
4
+
5
+ export interface ComponentPageProps {
6
+ params: Promise<{ component: string }>
7
+ components: WorkshopComponentRegistry
8
+ knobs: KnobRegistry
9
+ demoComponents?: Record<string, ReactNode>
10
+ }
@@ -0,0 +1,2 @@
1
+ export { ComponentPage } from "./ComponentPage"
2
+ export type { ComponentPageProps } from "./ComponentPage.types"
@@ -0,0 +1,88 @@
1
+ "use client"
2
+
3
+ import { Flex, Heading, Text, Separator, Pill } from "@heliosgraphics/ui"
4
+ import { getComponentStats } from "./DashboardPage.utils"
5
+ import type { FC } from "react"
6
+ import type { DashboardPageProps } from "./DashboardPage.types"
7
+ import type { WorkshopComponentStatus } from "../../types/meta"
8
+ import type { HeliosColorType } from "@heliosgraphics/ui"
9
+
10
+ const STATUS_INTENT_MAP: Record<WorkshopComponentStatus, HeliosColorType> = {
11
+ stable: "green",
12
+ nominal: "blue",
13
+ experimental: "orange",
14
+ internal: "gray",
15
+ }
16
+
17
+ export const DashboardPage: FC<DashboardPageProps> = ({ name, description, components, children }) => {
18
+ const stats = getComponentStats(components)
19
+
20
+ return (
21
+ <Flex isColumn={true} gap={16} padding={[8, 16, 24]}>
22
+ <Flex isColumn={true} gap={4}>
23
+ <Heading level={1} fontWeight="semibold">
24
+ {name}
25
+ </Heading>
26
+ {description && (
27
+ <Text type="paragraph" emphasis="secondary">
28
+ {description}
29
+ </Text>
30
+ )}
31
+ </Flex>
32
+ <Separator emphasis="secondary" />
33
+ <Flex gap={16}>
34
+ <Flex isColumn={true} gap={2}>
35
+ <Text type="small" emphasis="secondary">
36
+ Components
37
+ </Text>
38
+ <Heading level={3}>{stats.total}</Heading>
39
+ </Flex>
40
+ <Flex isColumn={true} gap={2}>
41
+ <Text type="small" emphasis="secondary">
42
+ Categories
43
+ </Text>
44
+ <Heading level={3}>{stats.categoryCount}</Heading>
45
+ </Flex>
46
+ </Flex>
47
+ <Separator emphasis="secondary" />
48
+ <Flex gap={32}>
49
+ <Flex isColumn={true} gap={8}>
50
+ <Text type="small" emphasis="secondary">
51
+ By Category
52
+ </Text>
53
+ <Flex isColumn={true} gap={4}>
54
+ {stats.categories.map(({ name: categoryName, count }) => (
55
+ <Flex key={categoryName} isBetween={true} isYCentered={true} gap={12}>
56
+ <Text type="paragraph">{categoryName}</Text>
57
+ <Text type="small" emphasis="secondary">
58
+ {count}
59
+ </Text>
60
+ </Flex>
61
+ ))}
62
+ </Flex>
63
+ </Flex>
64
+ <Flex isColumn={true} gap={8}>
65
+ <Text type="small" emphasis="secondary">
66
+ By Status
67
+ </Text>
68
+ <Flex isColumn={true} gap={4}>
69
+ {stats.statuses.map(({ name: statusName, count }) => (
70
+ <Flex key={statusName} isYCentered={true} gap={8}>
71
+ <Pill label={statusName} color={STATUS_INTENT_MAP[statusName]} size="small" />
72
+ <Text type="small" emphasis="secondary">
73
+ {count}
74
+ </Text>
75
+ </Flex>
76
+ ))}
77
+ </Flex>
78
+ </Flex>
79
+ </Flex>
80
+ {children && (
81
+ <>
82
+ <Separator emphasis="secondary" />
83
+ {children}
84
+ </>
85
+ )}
86
+ </Flex>
87
+ )
88
+ }
@@ -0,0 +1,9 @@
1
+ import type { ReactNode } from "react"
2
+ import type { WorkshopComponentRegistry } from "../../types/meta"
3
+
4
+ export interface DashboardPageProps {
5
+ name: string
6
+ description?: string
7
+ components: WorkshopComponentRegistry
8
+ children?: ReactNode
9
+ }
@@ -0,0 +1,33 @@
1
+ import type { WorkshopComponentRegistry, WorkshopComponentStatus } from "../../types/meta"
2
+
3
+ interface ComponentStats {
4
+ total: number
5
+ categoryCount: number
6
+ categories: Array<{ name: string; count: number }>
7
+ statuses: Array<{ name: WorkshopComponentStatus; count: number }>
8
+ }
9
+
10
+ const STATUS_ORDER: Array<WorkshopComponentStatus> = ["stable", "nominal", "experimental", "internal"]
11
+
12
+ export const getComponentStats = (components: WorkshopComponentRegistry): ComponentStats => {
13
+ const entries = Object.values(components)
14
+ const total: number = entries.length
15
+
16
+ const categoryMap = new Map<string, number>()
17
+ const statusMap = new Map<WorkshopComponentStatus, number>()
18
+
19
+ for (const entry of entries) {
20
+ const category: string = entry._category ?? "uncategorized"
21
+ const status: WorkshopComponentStatus = entry._status ?? "experimental"
22
+ categoryMap.set(category, (categoryMap.get(category) ?? 0) + 1)
23
+ statusMap.set(status, (statusMap.get(status) ?? 0) + 1)
24
+ }
25
+
26
+ const categories = Array.from(categoryMap.entries())
27
+ .map(([name, count]) => ({ name, count }))
28
+ .sort((a, b) => b.count - a.count)
29
+
30
+ const statuses = STATUS_ORDER.filter((s) => statusMap.has(s)).map((name) => ({ name, count: statusMap.get(name)! }))
31
+
32
+ return { total, categoryCount: categoryMap.size, categories, statuses }
33
+ }
@@ -0,0 +1,2 @@
1
+ export { DashboardPage } from "./DashboardPage"
2
+ export type { DashboardPageProps } from "./DashboardPage.types"
package/pages/index.ts ADDED
@@ -0,0 +1,5 @@
1
+ export { ComponentPage } from "./ComponentPage"
2
+ export type { ComponentPageProps } from "./ComponentPage"
3
+
4
+ export { DashboardPage } from "./DashboardPage"
5
+ export type { DashboardPageProps } from "./DashboardPage"
@@ -0,0 +1,18 @@
1
+ import type { KnobRegistry } from "./knobs"
2
+ import type { WorkshopComponentStatus } from "./meta"
3
+ import type { HeliosIconType } from "@heliosgraphics/ui"
4
+
5
+ export interface WorkshopPageConfig {
6
+ title: string
7
+ href: string
8
+ icon?: HeliosIconType
9
+ }
10
+
11
+ export interface WorkshopConfig {
12
+ name: string
13
+ transpilePackages?: Array<string>
14
+ baseUrl?: string
15
+ knobs: KnobRegistry
16
+ visibleStatuses?: Array<WorkshopComponentStatus>
17
+ pages?: Array<WorkshopPageConfig>
18
+ }
package/types/knobs.ts ADDED
@@ -0,0 +1,13 @@
1
+ export interface KnobDefinition {
2
+ label: string
3
+ values: Array<string | number | boolean>
4
+ defaultValue: string | number | boolean
5
+ isInternal?: boolean
6
+ editor?: string
7
+ }
8
+
9
+ export type KnobRegistry = Record<string, KnobDefinition>
10
+
11
+ export type KnobValues = Record<string, string | number | boolean>
12
+
13
+ export type KnobSetters = Record<string, (value: string | number | boolean) => void>
package/types/meta.ts ADDED
@@ -0,0 +1,28 @@
1
+ export interface WorkshopAttributeItem<T> {
2
+ alias?: keyof T
3
+ default?: number | string
4
+ description?: string
5
+ isOptional?: boolean
6
+ type: string
7
+ knob?: string
8
+ }
9
+
10
+ export interface WorkshopPattern {
11
+ id: string
12
+ description: string
13
+ content: string
14
+ }
15
+
16
+ export type WorkshopComponentStatus = "stable" | "nominal" | "internal" | "experimental"
17
+
18
+ export type WorkshopComponentCategory = string
19
+
20
+ export type WorkshopAttributeMeta<T> = Record<keyof T, WorkshopAttributeItem<T>> & {
21
+ _category: WorkshopComponentCategory
22
+ _extends?: Array<string>
23
+ _patterns: Array<WorkshopPattern>
24
+ _status: WorkshopComponentStatus
25
+ _type?: "composite" | "hoc"
26
+ }
27
+
28
+ export type WorkshopComponentRegistry = Record<string, WorkshopAttributeMeta<unknown>>