@purestack/ts-components 1.1.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 (106) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +10 -0
  3. package/dist/ts-components.d.mts +1662 -0
  4. package/dist/ts-components.d.mts.map +1 -0
  5. package/dist/ts-components.mjs +9200 -0
  6. package/dist/ts-components.mjs.map +1 -0
  7. package/package.json +130 -0
  8. package/src/defineComponents.ts +87 -0
  9. package/src/index.ts +270 -0
  10. package/src/registerStyles.ts +63 -0
  11. package/src/standard/alertBox/alertBox.ts +64 -0
  12. package/src/standard/autoId.ts +25 -0
  13. package/src/standard/badge/badge.ts +41 -0
  14. package/src/standard/badge/badgeStyle.ts +21 -0
  15. package/src/standard/barChart/barChart.ts +338 -0
  16. package/src/standard/barChart/barChartStyle.ts +81 -0
  17. package/src/standard/btn/btn.ts +191 -0
  18. package/src/standard/btn/btnStyle.ts +59 -0
  19. package/src/standard/btnGroup/btnGroup.ts +208 -0
  20. package/src/standard/btnGroup/btnGroupStyle.ts +85 -0
  21. package/src/standard/chart/cartesianChart.ts +99 -0
  22. package/src/standard/chart/chartDefaults.ts +25 -0
  23. package/src/standard/chart/chartUtils.ts +84 -0
  24. package/src/standard/classicLogo/classicLogo.ts +429 -0
  25. package/src/standard/classicLogo/classicLogoStyle.ts +292 -0
  26. package/src/standard/componentVariant.ts +153 -0
  27. package/src/standard/composer/composer.ts +1035 -0
  28. package/src/standard/composer/composerCanvasInitialStyle.ts +225 -0
  29. package/src/standard/composer/composerCanvasRevertStyle.ts +14 -0
  30. package/src/standard/composer/composerCanvasSharedStyle.ts +60 -0
  31. package/src/standard/composer/composerCanvasStyleTypes.ts +8 -0
  32. package/src/standard/composer/composerCanvasThemeStyle.ts +53 -0
  33. package/src/standard/composer/composerStyle.ts +156 -0
  34. package/src/standard/composer/emailHtmlPolicy.ts +474 -0
  35. package/src/standard/consent/consent.ts +173 -0
  36. package/src/standard/consent/consentStyle.ts +44 -0
  37. package/src/standard/contactForm/contactForm.ts +135 -0
  38. package/src/standard/contactForm/contactFormStyle.ts +116 -0
  39. package/src/standard/doughnutChart/doughnutChart.ts +527 -0
  40. package/src/standard/doughnutChart/doughnutChartStyle.ts +64 -0
  41. package/src/standard/dropFiles/dropFiles.ts +480 -0
  42. package/src/standard/dropFiles/dropFilesStyle.ts +171 -0
  43. package/src/standard/expandablePanel/expandablePanel.ts +106 -0
  44. package/src/standard/expandablePanel/expandablePanelStyle.ts +56 -0
  45. package/src/standard/flex/flex.ts +269 -0
  46. package/src/standard/flex/flexStyle.ts +556 -0
  47. package/src/standard/footer/footer.ts +93 -0
  48. package/src/standard/footer/footerStyle.ts +39 -0
  49. package/src/standard/form/autoCompleteInput.ts +567 -0
  50. package/src/standard/form/form.ts +205 -0
  51. package/src/standard/form/formCheck.ts +96 -0
  52. package/src/standard/form/formInputField.ts +184 -0
  53. package/src/standard/form/formSelectField.ts +152 -0
  54. package/src/standard/form/formStyle.ts +585 -0
  55. package/src/standard/form/multiAutoCompleteInput.ts +880 -0
  56. package/src/standard/grid/grid.ts +177 -0
  57. package/src/standard/grid/gridStyle.ts +56 -0
  58. package/src/standard/icon/icon.ts +96 -0
  59. package/src/standard/icon/iconStyle.ts +50 -0
  60. package/src/standard/landing/codeShowcase.ts +54 -0
  61. package/src/standard/landing/comparisonColumn.ts +30 -0
  62. package/src/standard/landing/comparisonFeature.ts +22 -0
  63. package/src/standard/landing/comparisonTable.ts +38 -0
  64. package/src/standard/landing/ctaSection.ts +59 -0
  65. package/src/standard/landing/featureCard.ts +41 -0
  66. package/src/standard/landing/landing.ts +52 -0
  67. package/src/standard/landing/landingBand.ts +217 -0
  68. package/src/standard/landing/landingSection.ts +43 -0
  69. package/src/standard/landing/landingTypes.ts +141 -0
  70. package/src/standard/landing/metricItem.ts +25 -0
  71. package/src/standard/landing/metricStrip.ts +20 -0
  72. package/src/standard/lineChart/lineChart.ts +462 -0
  73. package/src/standard/lineChart/lineChartStyle.ts +91 -0
  74. package/src/standard/logo/logo.ts +192 -0
  75. package/src/standard/logo/logoStyle.ts +164 -0
  76. package/src/standard/modal/modal.ts +171 -0
  77. package/src/standard/modal/modalStore.ts +154 -0
  78. package/src/standard/modal/modalStyle.ts +190 -0
  79. package/src/standard/navMenu/navMenu.ts +278 -0
  80. package/src/standard/navMenu/navMenuStyle.ts +323 -0
  81. package/src/standard/pageLinks/pageLinks.ts +90 -0
  82. package/src/standard/pageScript/pageScript.ts +155 -0
  83. package/src/standard/pageToc/pageToc.ts +154 -0
  84. package/src/standard/pageToc/pageTocStyle.ts +372 -0
  85. package/src/standard/panel/panel.ts +55 -0
  86. package/src/standard/panel/panelStyle.ts +15 -0
  87. package/src/standard/pricing/pricing.ts +146 -0
  88. package/src/standard/searchBox/searchBox.ts +54 -0
  89. package/src/standard/searchBox/searchBoxStyle.ts +180 -0
  90. package/src/standard/sectionHeader/sectionHeader.ts +99 -0
  91. package/src/standard/signIn/signIn.ts +167 -0
  92. package/src/standard/signIn/signInStyle.ts +70 -0
  93. package/src/standard/tabs/tabs.ts +193 -0
  94. package/src/standard/tabs/tabsStyle.ts +231 -0
  95. package/src/standard/themeToggle/themeToggle.ts +33 -0
  96. package/src/standard/themeToggle/themeToggleStyle.ts +88 -0
  97. package/src/standard/toast/toastHost.ts +42 -0
  98. package/src/standard/toast/toastStore.ts +50 -0
  99. package/src/standard/topBar/topBar.ts +101 -0
  100. package/src/standard/topBar/topBarStyle.ts +169 -0
  101. package/src/standard/virtualList/variableVirtualTable.ts +371 -0
  102. package/src/standard/virtualList/virtualList.ts +423 -0
  103. package/src/standard/virtualList/virtualListStyle.ts +34 -0
  104. package/src/standard/virtualList/virtualTable.ts +179 -0
  105. package/src/standard/virtualList/virtualTableStyle.ts +24 -0
  106. package/tsconfig.json +23 -0
@@ -0,0 +1,177 @@
1
+ import {
2
+ type ComputedRef,
3
+ computed,
4
+ defineComponent,
5
+ html,
6
+ type RefOrValue,
7
+ unref,
8
+ } from 'regor'
9
+
10
+ export type GridAlignItems = 'stretch' | 'start' | 'center' | 'end'
11
+ export type GridJustifyItems = 'stretch' | 'start' | 'center' | 'end'
12
+
13
+ export interface Grid {
14
+ container?: RefOrValue<string>
15
+ columns?: RefOrValue<number | string>
16
+ columnsSm?: RefOrValue<number | string>
17
+ columnsMd?: RefOrValue<number | string>
18
+ columnsLg?: RefOrValue<number | string>
19
+ columnsXl?: RefOrValue<number | string>
20
+ alignItems?: RefOrValue<GridAlignItems>
21
+ justifyItems?: RefOrValue<GridJustifyItems>
22
+ dense?: RefOrValue<boolean | string>
23
+ classes?: ComputedRef<string>
24
+ gridStyle?: ComputedRef<Record<string, string>>
25
+ }
26
+
27
+ const gridTemplate = html`<div :is="container ?? 'div'" class="grid" :class="classes" :style="gridStyle">
28
+ <slot></slot>
29
+ </div>`
30
+
31
+ function defineGridComponent() {
32
+ return defineComponent<Grid>(gridTemplate, {
33
+ props: [
34
+ 'container',
35
+ 'columns',
36
+ 'columnsSm',
37
+ 'columnsMd',
38
+ 'columnsLg',
39
+ 'columnsXl',
40
+ 'alignItems',
41
+ 'justifyItems',
42
+ 'dense',
43
+ ],
44
+ context: (head) => resolveGrid(head.props),
45
+ })
46
+ }
47
+
48
+ export function defineGridComponents() {
49
+ return {
50
+ grid: defineGridComponent(),
51
+ }
52
+ }
53
+
54
+ function resolveGrid(props: Grid): Grid {
55
+ const classes = computed(() => {
56
+ return [
57
+ resolveAlignClass(props.alignItems),
58
+ resolveJustifyClass(props.justifyItems),
59
+ resolveDenseClass(props.dense),
60
+ ]
61
+ .filter(Boolean)
62
+ .join(' ')
63
+ })
64
+ const gridStyle = computed(() => {
65
+ const resolvedColumns = resolveResponsiveGridTemplateColumns(props)
66
+
67
+ return {
68
+ '--grid-template-columns': resolvedColumns.base,
69
+ '--grid-template-columns-sm': resolvedColumns.sm,
70
+ '--grid-template-columns-md': resolvedColumns.md,
71
+ '--grid-template-columns-lg': resolvedColumns.lg,
72
+ '--grid-template-columns-xl': resolvedColumns.xl,
73
+ } as Record<string, string>
74
+ })
75
+
76
+ return {
77
+ ...props,
78
+ classes,
79
+ gridStyle,
80
+ }
81
+ }
82
+
83
+ type ResolvedGridTemplateColumns = {
84
+ base: string
85
+ sm: string
86
+ md: string
87
+ lg: string
88
+ xl: string
89
+ }
90
+
91
+ function resolveResponsiveGridTemplateColumns(
92
+ props: Grid,
93
+ ): ResolvedGridTemplateColumns {
94
+ const base =
95
+ resolveGridTemplateColumnsValue(props.columns) ?? toRepeatTemplate(1)
96
+ const sm = resolveGridTemplateColumnsValue(props.columnsSm) ?? base
97
+ const md = resolveGridTemplateColumnsValue(props.columnsMd) ?? sm
98
+ const lg = resolveGridTemplateColumnsValue(props.columnsLg) ?? md
99
+ const xl = resolveGridTemplateColumnsValue(props.columnsXl) ?? lg
100
+
101
+ return { base, sm, md, lg, xl }
102
+ }
103
+
104
+ function resolveGridTemplateColumnsValue(
105
+ value?: RefOrValue<number | string>,
106
+ ): string | undefined {
107
+ const resolvedValue = unref(value)
108
+
109
+ if (typeof resolvedValue === 'number' && Number.isInteger(resolvedValue)) {
110
+ return toRepeatTemplate(clampColumns(resolvedValue))
111
+ }
112
+
113
+ if (typeof resolvedValue !== 'string') return undefined
114
+
115
+ const normalized = resolvedValue.trim()
116
+ if (!normalized) return undefined
117
+
118
+ const columnCount = tryParseColumnCount(normalized)
119
+ if (columnCount !== undefined) return toRepeatTemplate(columnCount)
120
+
121
+ return normalized
122
+ }
123
+
124
+ function tryParseColumnCount(value: string): number | undefined {
125
+ if (!/^\d+$/.test(value)) return undefined
126
+
127
+ const parsed = Number.parseInt(value, 10)
128
+ if (!Number.isInteger(parsed)) return undefined
129
+
130
+ return clampColumns(parsed)
131
+ }
132
+
133
+ function toRepeatTemplate(columns: number) {
134
+ return `repeat(${columns}, minmax(0, 1fr))`
135
+ }
136
+
137
+ function clampColumns(value: number) {
138
+ if (value < 1) return 1
139
+ if (value > 12) return 12
140
+ return value
141
+ }
142
+
143
+ function resolveAlignClass(value?: RefOrValue<GridAlignItems>) {
144
+ if (!value) return ''
145
+ const normalized = unref(value).toLowerCase()
146
+ if (
147
+ normalized === 'stretch' ||
148
+ normalized === 'start' ||
149
+ normalized === 'center' ||
150
+ normalized === 'end'
151
+ ) {
152
+ return `align-${normalized}`
153
+ }
154
+ return ''
155
+ }
156
+
157
+ function resolveJustifyClass(value?: RefOrValue<GridJustifyItems>) {
158
+ if (!value) return ''
159
+ const normalized = unref(value).toLowerCase()
160
+ if (
161
+ normalized === 'stretch' ||
162
+ normalized === 'start' ||
163
+ normalized === 'center' ||
164
+ normalized === 'end'
165
+ ) {
166
+ return `justify-items-${normalized}`
167
+ }
168
+ return ''
169
+ }
170
+
171
+ function resolveDenseClass(value?: RefOrValue<boolean | string>) {
172
+ if (!value) return ''
173
+ const normalized = unref(value)
174
+ if (normalized === true || normalized === 'true') return 'grid-dense'
175
+
176
+ return ''
177
+ }
@@ -0,0 +1,56 @@
1
+ import {
2
+ BREAKPOINTS,
3
+ mediaMin,
4
+ styleBuilder,
5
+ themes,
6
+ } from '@purestack/ts-style'
7
+
8
+ export function registerGridStyles() {
9
+ themes.forEach((theme, _palette) => {
10
+ styleBuilder
11
+ .select('.grid', theme)
12
+ .display('grid')
13
+ .minWidth('0')
14
+ .gap('0.75rem')
15
+ .gridTemplateColumns('var(--grid-template-columns)')
16
+
17
+ styleBuilder.select('.grid > *', theme).minWidth('0')
18
+
19
+ styleBuilder.select('.align-stretch', theme).alignItems('stretch')
20
+ styleBuilder.select('.align-start', theme).alignItems('start')
21
+ styleBuilder.select('.align-center', theme).alignItems('center')
22
+ styleBuilder.select('.align-end', theme).alignItems('end')
23
+
24
+ styleBuilder.select('.justify-items-stretch', theme).justifyItems('stretch')
25
+ styleBuilder.select('.justify-items-start', theme).justifyItems('start')
26
+ styleBuilder.select('.justify-items-center', theme).justifyItems('center')
27
+ styleBuilder.select('.justify-items-end', theme).justifyItems('end')
28
+
29
+ styleBuilder.select('.justify-self-stretch', theme).justifySelf('stretch')
30
+ styleBuilder.select('.justify-self-start', theme).justifySelf('start')
31
+ styleBuilder.select('.justify-self-center', theme).justifySelf('center')
32
+ styleBuilder.select('.justify-self-end', theme).justifySelf('end')
33
+
34
+ styleBuilder.select('.grid-dense', theme).gridAutoFlow('row dense')
35
+
36
+ styleBuilder
37
+ .select('.grid', theme)
38
+ .media(mediaMin(BREAKPOINTS.sm))
39
+ .gridTemplateColumns('var(--grid-template-columns-sm)')
40
+
41
+ styleBuilder
42
+ .select('.grid', theme)
43
+ .media(mediaMin(BREAKPOINTS.md))
44
+ .gridTemplateColumns('var(--grid-template-columns-md)')
45
+
46
+ styleBuilder
47
+ .select('.grid', theme)
48
+ .media(mediaMin(BREAKPOINTS.lg))
49
+ .gridTemplateColumns('var(--grid-template-columns-lg)')
50
+
51
+ styleBuilder
52
+ .select('.grid', theme)
53
+ .media(mediaMin(BREAKPOINTS.xl))
54
+ .gridTemplateColumns('var(--grid-template-columns-xl)')
55
+ })
56
+ }
@@ -0,0 +1,96 @@
1
+ import type { SemanticTone } from '@purestack/ts-style'
2
+ import {
3
+ type ComputedRef,
4
+ computed,
5
+ defineComponent,
6
+ html,
7
+ type RefOrValue,
8
+ unref,
9
+ } from 'regor'
10
+ import {
11
+ type ComponentVariant,
12
+ type ComponentVariantMode,
13
+ resolveComponentClasses,
14
+ } from '../componentVariant'
15
+
16
+ export type GetSvgIcon = (name: string) => string
17
+ export type IconFrameSize = 'sm' | 'md' | 'lg'
18
+
19
+ export interface Icon {
20
+ name?: RefOrValue<string>
21
+ svg?: ComputedRef<string>
22
+ }
23
+
24
+ export interface IconFrame {
25
+ name?: RefOrValue<string>
26
+ tone?: RefOrValue<SemanticTone>
27
+ size?: RefOrValue<IconFrameSize>
28
+ variant?: RefOrValue<ComponentVariant>
29
+ variantMode?: RefOrValue<ComponentVariantMode>
30
+ classes?: ComputedRef<string>
31
+ hasIcon?: ComputedRef<boolean>
32
+ }
33
+
34
+ const DEFAULT_ICON_FRAME_VARIANT: ComponentVariant = 'solid'
35
+ const DEFAULT_ICON_FRAME_VARIANT_MODE: ComponentVariantMode = 'stateless'
36
+
37
+ const iconTemplate = html`<span class="icon" r-if="svg" r-html="svg"></span>`
38
+
39
+ const iconFrameTemplate = html`<span class="icon-frame" :class="classes" r-if="hasIcon">
40
+ <Icon :name="name"/>
41
+ </span>`
42
+
43
+ function defineIconComponent(getSvgIcon: GetSvgIcon) {
44
+ return defineComponent<Icon>(iconTemplate, {
45
+ props: ['name'],
46
+ context: (head) => resolveIcon(head.props, getSvgIcon),
47
+ })
48
+ }
49
+
50
+ function defineIconFrameComponent() {
51
+ return defineComponent<IconFrame>(iconFrameTemplate, {
52
+ props: ['name', 'tone', 'size', 'variant', 'variantMode'],
53
+ context: (head) => resolveIconFrame(head.props),
54
+ })
55
+ }
56
+
57
+ export function defineIconComponents(getSvgIcon: GetSvgIcon) {
58
+ return {
59
+ icon: defineIconComponent(getSvgIcon),
60
+ iconFrame: defineIconFrameComponent(),
61
+ }
62
+ }
63
+
64
+ function resolveIcon(props: Icon, getSvgIcon: GetSvgIcon): Icon {
65
+ const svg = computed(() => {
66
+ const name = unref(props.name)
67
+ return name ? getSvgIcon(name) : ''
68
+ })
69
+
70
+ return {
71
+ ...props,
72
+ svg,
73
+ }
74
+ }
75
+
76
+ function resolveIconFrame(props: IconFrame): IconFrame {
77
+ return {
78
+ ...props,
79
+ hasIcon: computed(() => Boolean(unref(props.name))),
80
+ classes: computed(() =>
81
+ resolveComponentClasses(props, {
82
+ defaultVariant: DEFAULT_ICON_FRAME_VARIANT,
83
+ defaultVariantMode: DEFAULT_ICON_FRAME_VARIANT_MODE,
84
+ classes: [resolveIconFrameSizeClass(props.size)],
85
+ }),
86
+ ),
87
+ }
88
+ }
89
+
90
+ function resolveIconFrameSizeClass(size?: RefOrValue<IconFrameSize>) {
91
+ const resolvedSize = unref(size)
92
+ if (resolvedSize === 'sm' || resolvedSize === 'lg') {
93
+ return `icon-frame--${resolvedSize}`
94
+ }
95
+ return ''
96
+ }
@@ -0,0 +1,50 @@
1
+ import type { ThemePalette } from '@purestack/ts-style'
2
+ import { styleBuilder, themes } from '@purestack/ts-style'
3
+
4
+ export function registerIconStyles() {
5
+ themes.forEach((theme, palette) => {
6
+ registerIconBaseStyles(theme, palette)
7
+ })
8
+ }
9
+
10
+ function registerIconBaseStyles(theme: string, palette: ThemePalette) {
11
+ styleBuilder
12
+ .select('.icon', theme)
13
+ .display('inline-flex')
14
+ .alignItems('center')
15
+ .justifyContent('center')
16
+ .width('1.7em')
17
+ .height('1.7em')
18
+ .lineHeight('0')
19
+ .verticalAlign('middle')
20
+ .flexShrink('0')
21
+ .alignSelf('center')
22
+
23
+ styleBuilder
24
+ .select('.icon svg', theme)
25
+ .display('block')
26
+ .width('100%')
27
+ .height('100%')
28
+
29
+ styleBuilder
30
+ .select('.icon-frame', theme)
31
+ .padding('0.25em')
32
+ .display('inline-flex')
33
+ .alignItems('center')
34
+ .justifyContent('center')
35
+ .lineHeight('0')
36
+ .flexShrink('0')
37
+ .borderRadius(palette.radii.md)
38
+
39
+ styleBuilder
40
+ .select('.icon-frame--sm', theme)
41
+ .borderRadius(palette.radii.sm)
42
+ .padding('0.5em')
43
+ .fontSize('0.6em')
44
+
45
+ styleBuilder
46
+ .select('.icon-frame--lg', theme)
47
+ .borderRadius('0.75rem')
48
+ .padding('0.5em')
49
+ .fontSize('1.5em')
50
+ }
@@ -0,0 +1,54 @@
1
+ import { defineComponent, html } from 'regor'
2
+ import type { CodeShowcase } from './landingTypes'
3
+
4
+ export function defineCodeShowcaseComponent() {
5
+ const codeShowcaseTemplate = html`<Panel :tone="tone" :variant="variant || 'surface'">
6
+ <Flex direction="column">
7
+ <Flex align="start" justify="between" wrap="true">
8
+ <SectionHeader
9
+ :eyebrow="eyebrow"
10
+ :title="title"
11
+ :subtitle="summary"
12
+ titleTag="h3"
13
+ titleClass="fs-h4 mb-1"
14
+ subtitleClass="mb-0"/>
15
+ <Badge r-if="language" :tone="tone">{{ language }}</Badge>
16
+ </Flex>
17
+ <Panel
18
+ variant="outline"
19
+ tone="neutral"
20
+ class="box-shadow-none"
21
+ bodyClass="overflow-x-auto"
22
+ >
23
+ <slot></slot>
24
+ </Panel>
25
+ <Panel
26
+ r-if="resultTitle || resultMeta"
27
+ :tone="tone"
28
+ variant="outline"
29
+ class="box-shadow-none"
30
+ >
31
+ <Flex align="center" justify="between" wrap="true" class="mb-2">
32
+ <strong r-if="resultTitle">{{ resultTitle }}</strong>
33
+ <Badge r-if="resultMeta" :tone="tone">{{ resultMeta }}</Badge>
34
+ </Flex>
35
+ <slot name="result"></slot>
36
+ </Panel>
37
+ </Flex>
38
+ </Panel>`
39
+
40
+ return {
41
+ codeShowcase: defineComponent<CodeShowcase>(codeShowcaseTemplate, {
42
+ props: [
43
+ 'eyebrow',
44
+ 'title',
45
+ 'summary',
46
+ 'language',
47
+ 'resultTitle',
48
+ 'resultMeta',
49
+ 'tone',
50
+ 'variant',
51
+ ],
52
+ }),
53
+ }
54
+ }
@@ -0,0 +1,30 @@
1
+ import { defineComponent, html } from 'regor'
2
+ import type { ComparisonColumn } from './landingTypes'
3
+
4
+ export function defineComparisonColumnComponent() {
5
+ const comparisonColumnTemplate = html`<Panel :tone="tone" :variant="variant || 'surface'">
6
+ <Flex direction="column" align="start">
7
+ <Flex align="center" justify="between" class="w-full" r-if="icon || badge">
8
+ <IconFrame
9
+ r-if="icon"
10
+ :name="icon"
11
+ :tone="tone"
12
+ :variant="variant"
13
+ size="lg"/>
14
+ <Badge r-if="badge" :tone="tone">{{ badge }}</Badge>
15
+ </Flex>
16
+ <h3 class="fs-h4 fw-700 my-0" r-if="title">{{ title }}</h3>
17
+ <p class="text-tagline mb-0" r-if="summary">{{ summary }}</p>
18
+ <slot></slot>
19
+ </Flex>
20
+ </Panel>`
21
+
22
+ return {
23
+ comparisonColumn: defineComponent<ComparisonColumn>(
24
+ comparisonColumnTemplate,
25
+ {
26
+ props: ['title', 'summary', 'badge', 'icon', 'tone', 'variant'],
27
+ },
28
+ ),
29
+ }
30
+ }
@@ -0,0 +1,22 @@
1
+ import { defineComponent, html } from 'regor'
2
+ import type { ComparisonFeature } from './landingTypes'
3
+
4
+ export function defineComparisonFeatureComponent() {
5
+ const comparisonFeatureTemplate = html`<Flex container="li" align="start">
6
+ <IconFrame
7
+ :name="icon || 'lucide:check'"
8
+ :tone="tone"
9
+ variant="surface"
10
+ size="sm"/>
11
+ <slot></slot>
12
+ </Flex>`
13
+
14
+ return {
15
+ comparisonFeature: defineComponent<ComparisonFeature>(
16
+ comparisonFeatureTemplate,
17
+ {
18
+ props: ['icon', 'tone'],
19
+ },
20
+ ),
21
+ }
22
+ }
@@ -0,0 +1,38 @@
1
+ import { defineComponent, html } from 'regor'
2
+ import type { ComparisonTable } from './landingTypes'
3
+
4
+ export function defineComparisonTableComponent() {
5
+ const comparisonTableTemplate = html`<Panel :tone="tone" :variant="variant || 'surface'" class="mb-6">
6
+ <Flex direction="column" align="start" class="w-full">
7
+ <SectionHeader
8
+ r-if="eyebrow || title || subtitle"
9
+ :eyebrow="eyebrow"
10
+ :title="title"
11
+ :subtitle="subtitle"
12
+ titleTag="h2"
13
+ subtitleClass="mb-0"/>
14
+ <Grid
15
+ :columns="columns || 1"
16
+ :columnsLg="columnsLg || 3"
17
+ alignItems="stretch"
18
+ class="w-full"
19
+ >
20
+ <slot></slot>
21
+ </Grid>
22
+ </Flex>
23
+ </Panel>`
24
+
25
+ return {
26
+ comparisonTable: defineComponent<ComparisonTable>(comparisonTableTemplate, {
27
+ props: [
28
+ 'eyebrow',
29
+ 'title',
30
+ 'subtitle',
31
+ 'tone',
32
+ 'variant',
33
+ 'columns',
34
+ 'columnsLg',
35
+ ],
36
+ }),
37
+ }
38
+ }
@@ -0,0 +1,59 @@
1
+ import { defineComponent, html } from 'regor'
2
+ import type { CtaSection } from './landingTypes'
3
+
4
+ export function defineCtaSectionComponent() {
5
+ const ctaSectionTemplate = html`<Panel :tone="tone" :variant="variant || 'surface'">
6
+ <Grid columns="1" columnsLg="minmax(0, 1fr) auto" alignItems="center">
7
+ <SectionHeader
8
+ :eyebrow="eyebrow"
9
+ :title="title"
10
+ :subtitle="subtitle"
11
+ titleTag="h2"
12
+ titleClass="fs-h2 mb-2"
13
+ subtitleClass="mb-0"/>
14
+ <Flex align="center" justify="end" wrap="true">
15
+ <BtnLink
16
+ r-if="primaryLabel && primaryHref"
17
+ :href="primaryHref"
18
+ :icon="primaryIcon"
19
+ iconPosition="end"
20
+ :tone="tone || 'accent'"
21
+ size="lg"
22
+ >
23
+ {{ primaryLabel }}
24
+ </BtnLink>
25
+ <BtnLink
26
+ r-if="secondaryLabel && secondaryHref"
27
+ :href="secondaryHref"
28
+ :icon="secondaryIcon"
29
+ :tone="tone || 'ghost'"
30
+ variant="outline"
31
+ size="lg"
32
+ >
33
+ {{ secondaryLabel }}
34
+ </BtnLink>
35
+ <slot name="actions"></slot>
36
+ </Flex>
37
+ <p class="prose-meta mb-0" r-if="meta">{{ meta }}</p>
38
+ </Grid>
39
+ </Panel>`
40
+
41
+ return {
42
+ ctaSection: defineComponent<CtaSection>(ctaSectionTemplate, {
43
+ props: [
44
+ 'eyebrow',
45
+ 'title',
46
+ 'subtitle',
47
+ 'primaryLabel',
48
+ 'primaryHref',
49
+ 'primaryIcon',
50
+ 'secondaryLabel',
51
+ 'secondaryHref',
52
+ 'secondaryIcon',
53
+ 'meta',
54
+ 'tone',
55
+ 'variant',
56
+ ],
57
+ }),
58
+ }
59
+ }
@@ -0,0 +1,41 @@
1
+ import { defineComponent, html } from 'regor'
2
+ import type { FeatureCard } from './landingTypes'
3
+
4
+ export function defineFeatureCardComponent() {
5
+ const featureCardTemplate = html`<Panel :tone="tone" :variant="variant || 'surface'">
6
+ <Flex direction="column" align="start" justify="center">
7
+ <Flex align="center" justify="center" class="w-full" r-if="icon || badge">
8
+ <IconFrame
9
+ r-if="icon"
10
+ :name="icon"
11
+ :tone="tone"
12
+ :variant="variant"
13
+ size="lg"/>
14
+ <Badge r-if="badge" :tone="tone">{{ badge }}</Badge>
15
+ </Flex>
16
+ <Flex direction="column" align="center" class="text-justify">
17
+ <p class="text-eyebrow" r-if="eyebrow">{{ eyebrow }}</p>
18
+ <h3 class="fs-h4 fw-700 my-0" r-if="title">{{ title }}</h3>
19
+ <p class="text-tagline mb-0" r-if="summary">{{ summary }}</p>
20
+ <slot></slot>
21
+ </Flex>
22
+ <Flex wrap="true" class="mt-auto">
23
+ <slot name="actions"></slot>
24
+ </Flex>
25
+ </Flex>
26
+ </Panel>`
27
+
28
+ return {
29
+ featureCard: defineComponent<FeatureCard>(featureCardTemplate, {
30
+ props: [
31
+ 'eyebrow',
32
+ 'title',
33
+ 'summary',
34
+ 'badge',
35
+ 'icon',
36
+ 'tone',
37
+ 'variant',
38
+ ],
39
+ }),
40
+ }
41
+ }
@@ -0,0 +1,52 @@
1
+ export type {
2
+ CodeShowcase,
3
+ ComparisonColumn,
4
+ ComparisonFeature,
5
+ ComparisonTable,
6
+ CtaSection,
7
+ FeatureCard,
8
+ LandingBand,
9
+ LandingBandEdge,
10
+ LandingBandImageFit,
11
+ LandingSection,
12
+ LandingTitleTag,
13
+ MetricItem,
14
+ MetricStrip,
15
+ } from './landingTypes'
16
+
17
+ import { defineCodeShowcaseComponent } from './codeShowcase'
18
+ import { defineComparisonColumnComponent } from './comparisonColumn'
19
+ import { defineComparisonFeatureComponent } from './comparisonFeature'
20
+ import { defineComparisonTableComponent } from './comparisonTable'
21
+ import { defineCtaSectionComponent } from './ctaSection'
22
+ import { defineFeatureCardComponent } from './featureCard'
23
+ import { defineLandingBandComponent } from './landingBand'
24
+ import { defineLandingSectionComponent } from './landingSection'
25
+ import { defineMetricItemComponent } from './metricItem'
26
+ import { defineMetricStripComponent } from './metricStrip'
27
+
28
+ export { defineCodeShowcaseComponent } from './codeShowcase'
29
+ export { defineComparisonColumnComponent } from './comparisonColumn'
30
+ export { defineComparisonFeatureComponent } from './comparisonFeature'
31
+ export { defineComparisonTableComponent } from './comparisonTable'
32
+ export { defineCtaSectionComponent } from './ctaSection'
33
+ export { defineFeatureCardComponent } from './featureCard'
34
+ export { defineLandingBandComponent } from './landingBand'
35
+ export { defineLandingSectionComponent } from './landingSection'
36
+ export { defineMetricItemComponent } from './metricItem'
37
+ export { defineMetricStripComponent } from './metricStrip'
38
+
39
+ export function defineLandingComponents() {
40
+ return {
41
+ ...defineLandingBandComponent(),
42
+ ...defineLandingSectionComponent(),
43
+ ...defineFeatureCardComponent(),
44
+ ...defineMetricStripComponent(),
45
+ ...defineMetricItemComponent(),
46
+ ...defineCodeShowcaseComponent(),
47
+ ...defineComparisonTableComponent(),
48
+ ...defineComparisonColumnComponent(),
49
+ ...defineComparisonFeatureComponent(),
50
+ ...defineCtaSectionComponent(),
51
+ }
52
+ }