@alphacifer/slidev-addon-theme 0.0.6 → 0.0.7

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 CHANGED
@@ -148,6 +148,42 @@ addons:
148
148
  </ArcCompare>
149
149
  ```
150
150
 
151
+ ## Comparison table
152
+
153
+ - Components: `ComparisonTable`, `ComparisonTableCols`, `ComparisonTableCol`, `ComparisonTableRows`, `ComparisonTableRow`, `ComparisonTableCell`
154
+
155
+ ```vue
156
+ <!-- Self-contained mockup default (5 columns x 6 rows) -->
157
+ <ComparisonTable />
158
+
159
+ <!-- Custom compound comparison structure -->
160
+ <ComparisonTable>
161
+ <ComparisonTableCols>
162
+ <ComparisonTableCol color="#ff0000">
163
+ Column 1
164
+ </ComparisonTableCol>
165
+ <ComparisonTableCol color="#00ff00">
166
+ Column 2
167
+ </ComparisonTableCol>
168
+ <ComparisonTableCol color="#0000ff">
169
+ Column 3
170
+ </ComparisonTableCol>
171
+ </ComparisonTableCols>
172
+ <ComparisonTableRows>
173
+ <ComparisonTableRow title="Row 1">
174
+ <ComparisonTableCell>Row 1, Cell 1</ComparisonTableCell>
175
+ <ComparisonTableCell>Row 1, Cell 2</ComparisonTableCell>
176
+ <ComparisonTableCell>Row 1, Cell 3</ComparisonTableCell>
177
+ </ComparisonTableRow>
178
+ <ComparisonTableRow title="Row 2">
179
+ <ComparisonTableCell>Row 2, Cell 1</ComparisonTableCell>
180
+ <ComparisonTableCell>Row 2, Cell 2</ComparisonTableCell>
181
+ <ComparisonTableCell>Row 2, Cell 3</ComparisonTableCell>
182
+ </ComparisonTableRow>
183
+ </ComparisonTableRows>
184
+ </ComparisonTable>
185
+ ```
186
+
151
187
  ## Preview
152
188
 
153
189
  ```bash
@@ -0,0 +1,244 @@
1
+ <script setup lang="ts">
2
+ import {
3
+ type ComputedRef,
4
+ computed,
5
+ Fragment,
6
+ inject,
7
+ provide,
8
+ useSlots,
9
+ type VNode,
10
+ } from 'vue';
11
+
12
+ import {
13
+ COMPARISON_TABLE_KEY,
14
+ DEFAULT_BORDER_RADIUS,
15
+ DEFAULT_CELL_BG,
16
+ DEFAULT_CELL_COLOR,
17
+ DEFAULT_COL_HEADER_TEXT_COLOR,
18
+ DEFAULT_MOCKUP_COLS,
19
+ DEFAULT_MOCKUP_ROWS,
20
+ DEFAULT_ROW_HEADER_COLOR,
21
+ DEFAULT_ROW_HEADER_TEXT_COLOR,
22
+ DEFAULT_ROW_HEADER_WIDTH,
23
+ DEFAULT_SPACING,
24
+ type IComparisonTableContext,
25
+ resolveDimension,
26
+ } from '../../utils/comparisonTable';
27
+ import { useMergedUnoAttrs } from '../../utils/useMergedUnoAttrs';
28
+ import ComparisonTableCell from './ComparisonTableCell.vue';
29
+ import ComparisonTableCol from './ComparisonTableCol.vue';
30
+ import ComparisonTableCols from './ComparisonTableCols.vue';
31
+ import ComparisonTableRow from './ComparisonTableRow.vue';
32
+ import ComparisonTableRows from './ComparisonTableRows.vue';
33
+
34
+ defineOptions({
35
+ inheritAttrs: false,
36
+ name: 'ComparisonTable',
37
+ });
38
+
39
+ export interface IComparisonTableProps {
40
+ readonly cellBg?: string;
41
+ readonly cellColor?: string;
42
+ readonly rowHeaderColor?: string;
43
+ readonly rowHeaderTextColor?: string;
44
+ readonly colHeaderTextColor?: string;
45
+ readonly borderRadius?: number | string;
46
+ readonly rowHeaderWidth?: number | string;
47
+ readonly spacing?: number | string;
48
+ readonly tableLayout?: 'fixed' | 'auto';
49
+ readonly dense?: boolean;
50
+ readonly animation?: boolean;
51
+ readonly active?: boolean;
52
+ readonly width?: number | string;
53
+ readonly height?: number | string;
54
+ }
55
+
56
+ const props = withDefaults(defineProps<IComparisonTableProps>(), {
57
+ cellBg: DEFAULT_CELL_BG,
58
+ cellColor: DEFAULT_CELL_COLOR,
59
+ rowHeaderColor: DEFAULT_ROW_HEADER_COLOR,
60
+ rowHeaderTextColor: DEFAULT_ROW_HEADER_TEXT_COLOR,
61
+ colHeaderTextColor: DEFAULT_COL_HEADER_TEXT_COLOR,
62
+ borderRadius: DEFAULT_BORDER_RADIUS,
63
+ rowHeaderWidth: DEFAULT_ROW_HEADER_WIDTH,
64
+ spacing: DEFAULT_SPACING,
65
+ tableLayout: 'fixed',
66
+ dense: false,
67
+ animation: true,
68
+ active: undefined,
69
+ width: '100%',
70
+ height: undefined,
71
+ });
72
+
73
+ const slots = useSlots();
74
+
75
+ const shiftingIntro = inject<
76
+ | {
77
+ active: ComputedRef<boolean>;
78
+ isShifting?: ComputedRef<boolean>;
79
+ }
80
+ | undefined
81
+ >('SLIDEV_LAYOUT_SHIFTING_INTRO', undefined);
82
+
83
+ const isAnimated = computed(() => {
84
+ if (!props.animation) {
85
+ return false;
86
+ }
87
+
88
+ if (props.active !== undefined) {
89
+ return props.active;
90
+ }
91
+
92
+ if (shiftingIntro) {
93
+ return shiftingIntro.active.value;
94
+ }
95
+
96
+ return true;
97
+ });
98
+
99
+ const resolvedBorderRadius = computed(() => {
100
+ return resolveDimension(props.borderRadius) ?? DEFAULT_BORDER_RADIUS;
101
+ });
102
+
103
+ const resolvedRowHeaderWidth = computed(() => {
104
+ return resolveDimension(props.rowHeaderWidth) ?? DEFAULT_ROW_HEADER_WIDTH;
105
+ });
106
+
107
+ const resolvedSpacing = computed(() => {
108
+ return resolveDimension(props.spacing) ?? DEFAULT_SPACING;
109
+ });
110
+
111
+ const resolvedWidth = computed(() => {
112
+ return resolveDimension(props.width) ?? '100%';
113
+ });
114
+
115
+ const resolvedHeight = computed(() => {
116
+ return resolveDimension(props.height);
117
+ });
118
+
119
+ provide<IComparisonTableContext>(COMPARISON_TABLE_KEY, {
120
+ cellBg: computed(() => props.cellBg),
121
+ cellColor: computed(() => props.cellColor),
122
+ rowHeaderColor: computed(() => props.rowHeaderColor),
123
+ rowHeaderTextColor: computed(() => props.rowHeaderTextColor),
124
+ colHeaderTextColor: computed(() => props.colHeaderTextColor),
125
+ borderRadius: resolvedBorderRadius,
126
+ rowHeaderWidth: resolvedRowHeaderWidth,
127
+ spacing: resolvedSpacing,
128
+ dense: computed(() => props.dense),
129
+ animation: isAnimated,
130
+ });
131
+
132
+ function isSignificantNode(node: VNode): boolean {
133
+ if (typeof node.type === 'symbol') {
134
+ if (typeof node.children === 'string' && !node.children.trim()) {
135
+ return false;
136
+ }
137
+ }
138
+
139
+ if (typeof node.children === 'string' && !node.children.trim()) {
140
+ return false;
141
+ }
142
+
143
+ return true;
144
+ }
145
+
146
+ function flattenVNodes(nodes: VNode[]): VNode[] {
147
+ const result: VNode[] = [];
148
+
149
+ for (const node of nodes) {
150
+ if (node.type === Fragment && Array.isArray(node.children)) {
151
+ result.push(...flattenVNodes(node.children as VNode[]));
152
+ } else if (isSignificantNode(node)) {
153
+ result.push(node);
154
+ }
155
+ }
156
+
157
+ return result;
158
+ }
159
+
160
+ const defaultNodes = computed(() => {
161
+ if (!slots.default) {
162
+ return [];
163
+ }
164
+
165
+ return flattenVNodes(slots.default());
166
+ });
167
+
168
+ const hasCustomContent = computed(() => {
169
+ return defaultNodes.value.length > 0;
170
+ });
171
+
172
+ const tableStyle = computed(() => {
173
+ return {
174
+ width: resolvedWidth.value,
175
+ height: resolvedHeight.value,
176
+ borderCollapse: 'separate' as const,
177
+ borderSpacing: resolvedSpacing.value,
178
+ tableLayout: props.tableLayout,
179
+ };
180
+ });
181
+
182
+ const { className, forwardedAttrs } = useMergedUnoAttrs(
183
+ 'alpha-comparison-table w-full select-text font-sans relative my-auto',
184
+ );
185
+ </script>
186
+
187
+ <template>
188
+ <div class="alpha-comparison-table-wrapper w-full flex items-center justify-center overflow-x-auto">
189
+ <table
190
+ v-bind="forwardedAttrs()"
191
+ :class="[
192
+ className(),
193
+ { 'alpha-comparison-table--animated': isAnimated },
194
+ ]"
195
+ :style="tableStyle"
196
+ >
197
+ <template v-if="hasCustomContent">
198
+ <slot />
199
+ </template>
200
+ <template v-else>
201
+ <ComparisonTableCols>
202
+ <ComparisonTableCol
203
+ v-for="col in DEFAULT_MOCKUP_COLS"
204
+ :key="col.title"
205
+ :color="col.color"
206
+ >
207
+ {{ col.title }}
208
+ </ComparisonTableCol>
209
+ </ComparisonTableCols>
210
+ <ComparisonTableRows>
211
+ <ComparisonTableRow
212
+ v-for="row in DEFAULT_MOCKUP_ROWS"
213
+ :key="row.title"
214
+ :title="row.title"
215
+ >
216
+ <ComparisonTableCell
217
+ v-for="(cellText, idx) in row.cells"
218
+ :key="idx"
219
+ >
220
+ {{ cellText }}
221
+ </ComparisonTableCell>
222
+ </ComparisonTableRow>
223
+ </ComparisonTableRows>
224
+ </template>
225
+ </table>
226
+ </div>
227
+ </template>
228
+
229
+ <style scoped>
230
+ .alpha-comparison-table--animated {
231
+ animation: alpha-table-appear 0.35s ease-out;
232
+ }
233
+
234
+ @keyframes alpha-table-appear {
235
+ from {
236
+ opacity: 0;
237
+ transform: translateY(4px);
238
+ }
239
+ to {
240
+ opacity: 1;
241
+ transform: translateY(0);
242
+ }
243
+ }
244
+ </style>
@@ -0,0 +1,88 @@
1
+ <script setup lang="ts">
2
+ import { computed, inject } from 'vue';
3
+
4
+ import {
5
+ COMPARISON_TABLE_KEY,
6
+ DEFAULT_CELL_BG,
7
+ DEFAULT_CELL_COLOR,
8
+ resolveDimension,
9
+ } from '../../utils/comparisonTable';
10
+ import { useMergedUnoAttrs } from '../../utils/useMergedUnoAttrs';
11
+
12
+ defineOptions({
13
+ inheritAttrs: false,
14
+ name: 'ComparisonTableCell',
15
+ });
16
+
17
+ export interface IComparisonTableCellProps {
18
+ readonly text?: string | number;
19
+ readonly color?: string;
20
+ readonly bg?: string;
21
+ readonly textColor?: string;
22
+ readonly borderRadius?: number | string;
23
+ readonly align?: 'left' | 'center' | 'right';
24
+ }
25
+
26
+ const props = withDefaults(defineProps<IComparisonTableCellProps>(), {
27
+ text: undefined,
28
+ color: undefined,
29
+ bg: undefined,
30
+ textColor: undefined,
31
+ borderRadius: undefined,
32
+ align: 'center',
33
+ });
34
+
35
+ const tableContext = inject(COMPARISON_TABLE_KEY, undefined);
36
+
37
+ const resolvedBg = computed(() => {
38
+ return (
39
+ props.bg ?? props.color ?? tableContext?.cellBg.value ?? DEFAULT_CELL_BG
40
+ );
41
+ });
42
+
43
+ const resolvedTextColor = computed(() => {
44
+ return props.textColor ?? tableContext?.cellColor.value ?? DEFAULT_CELL_COLOR;
45
+ });
46
+
47
+ const resolvedBorderRadius = computed(() => {
48
+ return (
49
+ resolveDimension(props.borderRadius) ??
50
+ tableContext?.borderRadius.value ??
51
+ '8px'
52
+ );
53
+ });
54
+
55
+ const resolvedPadding = computed(() => {
56
+ return tableContext?.dense.value ? 'py-2 px-3' : 'py-3 px-4';
57
+ });
58
+
59
+ const cellStyle = computed(() => {
60
+ return {
61
+ backgroundColor: resolvedBg.value,
62
+ color: resolvedTextColor.value,
63
+ borderRadius: resolvedBorderRadius.value,
64
+ fontSize: '1rem',
65
+ textAlign: props.align,
66
+ verticalAlign: 'middle' as const,
67
+ };
68
+ });
69
+
70
+ const { className, forwardedAttrs } = useMergedUnoAttrs(() => {
71
+ return `alpha-comparison-table-cell font-medium text-[1rem] leading-relaxed align-middle transition-all duration-200 select-text [&_p]:text-[1rem] [&_p]:m-0 ${resolvedPadding.value}`;
72
+ });
73
+ </script>
74
+
75
+ <template>
76
+ <td
77
+ v-bind="forwardedAttrs()"
78
+ :class="[
79
+ className(),
80
+ align === 'center' ? 'text-center [&_p]:text-center' : '',
81
+ align === 'left' ? 'text-left [&_p]:text-left' : '',
82
+ align === 'right' ? 'text-right [&_p]:text-right' : '',
83
+ ]"
84
+ :style="cellStyle"
85
+ >
86
+ <slot>{{ text }}</slot>
87
+ </td>
88
+ </template>
@@ -0,0 +1,97 @@
1
+ <script setup lang="ts">
2
+ import { computed, inject } from 'vue';
3
+
4
+ import {
5
+ COMPARISON_TABLE_COLS_KEY,
6
+ COMPARISON_TABLE_KEY,
7
+ DEFAULT_COL_COLORS,
8
+ DEFAULT_COL_HEADER_TEXT_COLOR,
9
+ resolveDimension,
10
+ } from '../../utils/comparisonTable';
11
+ import { useMergedUnoAttrs } from '../../utils/useMergedUnoAttrs';
12
+
13
+ defineOptions({
14
+ inheritAttrs: false,
15
+ name: 'ComparisonTableCol',
16
+ });
17
+
18
+ export interface IComparisonTableColProps {
19
+ readonly title?: string;
20
+ readonly color?: string;
21
+ readonly textColor?: string;
22
+ readonly width?: number | string;
23
+ readonly borderRadius?: number | string;
24
+ }
25
+
26
+ const props = withDefaults(defineProps<IComparisonTableColProps>(), {
27
+ title: undefined,
28
+ color: undefined,
29
+ textColor: undefined,
30
+ width: undefined,
31
+ borderRadius: undefined,
32
+ });
33
+
34
+ const tableContext = inject(COMPARISON_TABLE_KEY, undefined);
35
+ const colsContext = inject(COMPARISON_TABLE_COLS_KEY, undefined);
36
+
37
+ const autoIndex = colsContext?.registerCol() ?? 0;
38
+
39
+ const resolvedColor = computed(() => {
40
+ if (props.color) {
41
+ return props.color;
42
+ }
43
+
44
+ return DEFAULT_COL_COLORS[autoIndex % DEFAULT_COL_COLORS.length];
45
+ });
46
+
47
+ const resolvedTextColor = computed(() => {
48
+ return (
49
+ props.textColor ??
50
+ tableContext?.colHeaderTextColor.value ??
51
+ DEFAULT_COL_HEADER_TEXT_COLOR
52
+ );
53
+ });
54
+
55
+ const resolvedBorderRadius = computed(() => {
56
+ return (
57
+ resolveDimension(props.borderRadius) ??
58
+ tableContext?.borderRadius.value ??
59
+ '8px'
60
+ );
61
+ });
62
+
63
+ const resolvedWidth = computed(() => {
64
+ return resolveDimension(props.width);
65
+ });
66
+
67
+ const resolvedPadding = computed(() => {
68
+ return tableContext?.dense.value ? 'py-2 px-3' : 'py-3 px-4';
69
+ });
70
+
71
+ const colStyle = computed(() => {
72
+ return {
73
+ backgroundColor: resolvedColor.value,
74
+ color: resolvedTextColor.value,
75
+ borderRadius: resolvedBorderRadius.value,
76
+ width: resolvedWidth.value,
77
+ fontSize: '1rem',
78
+ textAlign: 'center' as const,
79
+ verticalAlign: 'middle' as const,
80
+ };
81
+ });
82
+
83
+ const { className, forwardedAttrs } = useMergedUnoAttrs(() => {
84
+ return `alpha-comparison-table-col font-bold uppercase tracking-wider text-[1rem] leading-snug text-center align-middle select-text transition-all duration-200 [&_p]:text-[1rem] [&_p]:text-center [&_p]:m-0 ${resolvedPadding.value}`;
85
+ });
86
+ </script>
87
+
88
+ <template>
89
+ <th
90
+ scope="col"
91
+ v-bind="forwardedAttrs()"
92
+ :class="className()"
93
+ :style="colStyle"
94
+ >
95
+ <slot>{{ title }}</slot>
96
+ </th>
97
+ </template>
@@ -0,0 +1,74 @@
1
+ <script setup lang="ts">
2
+ import { computed, inject, onBeforeUpdate, provide } from 'vue';
3
+
4
+ import {
5
+ COMPARISON_TABLE_COLS_KEY,
6
+ COMPARISON_TABLE_KEY,
7
+ DEFAULT_ROW_HEADER_WIDTH,
8
+ resolveDimension,
9
+ } from '../../utils/comparisonTable';
10
+ import { useMergedUnoAttrs } from '../../utils/useMergedUnoAttrs';
11
+
12
+ defineOptions({
13
+ inheritAttrs: false,
14
+ name: 'ComparisonTableCols',
15
+ });
16
+
17
+ export interface IComparisonTableColsProps {
18
+ readonly cornerWidth?: number | string;
19
+ }
20
+
21
+ const props = withDefaults(defineProps<IComparisonTableColsProps>(), {
22
+ cornerWidth: undefined,
23
+ });
24
+
25
+ const tableContext = inject(COMPARISON_TABLE_KEY, undefined);
26
+
27
+ let colCounter = 0;
28
+ onBeforeUpdate(() => {
29
+ colCounter = 0;
30
+ });
31
+
32
+ provide(COMPARISON_TABLE_COLS_KEY, {
33
+ registerCol: () => {
34
+ return colCounter++;
35
+ },
36
+ });
37
+
38
+ const resolvedCornerWidth = computed(() => {
39
+ return (
40
+ resolveDimension(props.cornerWidth) ??
41
+ tableContext?.rowHeaderWidth.value ??
42
+ DEFAULT_ROW_HEADER_WIDTH
43
+ );
44
+ });
45
+
46
+ const cornerStyle = computed(() => {
47
+ return {
48
+ width: resolvedCornerWidth.value,
49
+ backgroundColor: 'transparent',
50
+ border: 'none',
51
+ };
52
+ });
53
+
54
+ const { className, forwardedAttrs } = useMergedUnoAttrs(
55
+ 'alpha-comparison-table-cols',
56
+ );
57
+ </script>
58
+
59
+ <template>
60
+ <thead
61
+ v-bind="forwardedAttrs()"
62
+ :class="className()"
63
+ >
64
+ <tr>
65
+ <th
66
+ scope="col"
67
+ class="alpha-comparison-table-corner p-0 bg-transparent border-none pointer-events-none select-none"
68
+ :style="cornerStyle"
69
+ aria-hidden="true"
70
+ />
71
+ <slot />
72
+ </tr>
73
+ </thead>
74
+ </template>
@@ -0,0 +1,92 @@
1
+ <script setup lang="ts">
2
+ import { computed, inject } from 'vue';
3
+
4
+ import {
5
+ COMPARISON_TABLE_KEY,
6
+ DEFAULT_ROW_HEADER_COLOR,
7
+ DEFAULT_ROW_HEADER_TEXT_COLOR,
8
+ resolveDimension,
9
+ } from '../../utils/comparisonTable';
10
+ import { useMergedUnoAttrs } from '../../utils/useMergedUnoAttrs';
11
+
12
+ defineOptions({
13
+ inheritAttrs: false,
14
+ name: 'ComparisonTableRow',
15
+ });
16
+
17
+ export interface IComparisonTableRowProps {
18
+ readonly title?: string;
19
+ readonly color?: string;
20
+ readonly textColor?: string;
21
+ readonly borderRadius?: number | string;
22
+ }
23
+
24
+ const props = withDefaults(defineProps<IComparisonTableRowProps>(), {
25
+ title: undefined,
26
+ color: undefined,
27
+ textColor: undefined,
28
+ borderRadius: undefined,
29
+ });
30
+
31
+ const tableContext = inject(COMPARISON_TABLE_KEY, undefined);
32
+
33
+ const resolvedBg = computed(() => {
34
+ return (
35
+ props.color ??
36
+ tableContext?.rowHeaderColor.value ??
37
+ DEFAULT_ROW_HEADER_COLOR
38
+ );
39
+ });
40
+
41
+ const resolvedTextColor = computed(() => {
42
+ return (
43
+ props.textColor ??
44
+ tableContext?.rowHeaderTextColor.value ??
45
+ DEFAULT_ROW_HEADER_TEXT_COLOR
46
+ );
47
+ });
48
+
49
+ const resolvedBorderRadius = computed(() => {
50
+ return (
51
+ resolveDimension(props.borderRadius) ??
52
+ tableContext?.borderRadius.value ??
53
+ '8px'
54
+ );
55
+ });
56
+
57
+ const resolvedPadding = computed(() => {
58
+ return tableContext?.dense.value ? 'py-2 px-3' : 'py-3 px-4';
59
+ });
60
+
61
+ const headerStyle = computed(() => {
62
+ return {
63
+ backgroundColor: resolvedBg.value,
64
+ color: resolvedTextColor.value,
65
+ borderRadius: resolvedBorderRadius.value,
66
+ fontSize: '1rem',
67
+ textAlign: 'center' as const,
68
+ verticalAlign: 'middle' as const,
69
+ };
70
+ });
71
+
72
+ const { className, forwardedAttrs } = useMergedUnoAttrs(
73
+ 'alpha-comparison-table-row',
74
+ );
75
+ </script>
76
+
77
+ <template>
78
+ <tr
79
+ v-bind="forwardedAttrs()"
80
+ :class="className()"
81
+ >
82
+ <th
83
+ scope="row"
84
+ class="alpha-comparison-table-row-title font-bold uppercase tracking-wider text-[1rem] leading-snug text-center align-middle select-text transition-all duration-200 [&_p]:text-[1rem] [&_p]:text-center [&_p]:m-0"
85
+ :class="resolvedPadding"
86
+ :style="headerStyle"
87
+ >
88
+ <slot name="title">{{ title }}</slot>
89
+ </th>
90
+ <slot />
91
+ </tr>
92
+ </template>
@@ -0,0 +1,21 @@
1
+ <script setup lang="ts">
2
+ import { useMergedUnoAttrs } from '../../utils/useMergedUnoAttrs';
3
+
4
+ defineOptions({
5
+ inheritAttrs: false,
6
+ name: 'ComparisonTableRows',
7
+ });
8
+
9
+ const { className, forwardedAttrs } = useMergedUnoAttrs(
10
+ 'alpha-comparison-table-rows',
11
+ );
12
+ </script>
13
+
14
+ <template>
15
+ <tbody
16
+ v-bind="forwardedAttrs()"
17
+ :class="className()"
18
+ >
19
+ <slot />
20
+ </tbody>
21
+ </template>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alphacifer/slidev-addon-theme",
3
- "version": "0.0.6",
3
+ "version": "0.0.7",
4
4
  "description": "All Slidev addons for Alpha presentations",
5
5
  "type": "module",
6
6
  "keywords": [
@@ -0,0 +1,72 @@
1
+ export const DEFAULT_COL_COLORS: readonly string[] = [
2
+ '#354f82',
3
+ '#5b8bb3',
4
+ '#00a8a8',
5
+ '#00b884',
6
+ '#00875a',
7
+ ];
8
+
9
+ export const DEFAULT_ROW_HEADER_COLOR = '#2e8b9a';
10
+ export const DEFAULT_ROW_HEADER_TEXT_COLOR = '#ffffff';
11
+ export const DEFAULT_COL_HEADER_TEXT_COLOR = '#ffffff';
12
+ export const DEFAULT_CELL_BG = '#d6e5ef';
13
+ export const DEFAULT_CELL_COLOR = '#475569';
14
+ export const DEFAULT_BORDER_RADIUS = '8px';
15
+ export const DEFAULT_SPACING = '6px';
16
+ export const DEFAULT_ROW_HEADER_WIDTH = '160px';
17
+
18
+ export interface IDefaultMockupCol {
19
+ readonly title: string;
20
+ readonly color: string;
21
+ }
22
+
23
+ export interface IDefaultMockupRow {
24
+ readonly title: string;
25
+ readonly cells: readonly string[];
26
+ }
27
+
28
+ export const DEFAULT_MOCKUP_COLS: readonly IDefaultMockupCol[] = [
29
+ { title: 'COLUMN 1', color: '#354f82' },
30
+ { title: 'COLUMN 2', color: '#5b8bb3' },
31
+ { title: 'COLUMN 3', color: '#00a8a8' },
32
+ { title: 'COLUMN 4', color: '#00b884' },
33
+ { title: 'COLUMN 5', color: '#00875a' },
34
+ ];
35
+
36
+ export const DEFAULT_MOCKUP_ROWS: readonly IDefaultMockupRow[] = [
37
+ { title: 'ROW 1', cells: ['TEXT', 'TEXT', 'TEXT', 'TEXT', 'TEXT'] },
38
+ { title: 'ROW 2', cells: ['TEXT', 'TEXT', 'TEXT', 'TEXT', 'TEXT'] },
39
+ { title: 'ROW 3', cells: ['TEXT', 'TEXT', 'TEXT', 'TEXT', 'TEXT'] },
40
+ { title: 'ROW 4', cells: ['TEXT', 'TEXT', 'TEXT', 'TEXT', 'TEXT'] },
41
+ { title: 'ROW 5', cells: ['TEXT', 'TEXT', 'TEXT', 'TEXT', 'TEXT'] },
42
+ { title: 'ROW 6', cells: ['TEXT', 'TEXT', 'TEXT', 'TEXT', 'TEXT'] },
43
+ ];
44
+
45
+ /**
46
+ * Resolves a dimension input (number or string) into a CSS-ready unit string.
47
+ */
48
+ export function resolveDimension(
49
+ value: number | string | undefined,
50
+ defaultUnit = 'px',
51
+ ): string | undefined {
52
+ if (value === undefined || value === null) {
53
+ return undefined;
54
+ }
55
+
56
+ if (typeof value === 'number') {
57
+ return `${value}${defaultUnit}`;
58
+ }
59
+
60
+ const trimmed = value.trim();
61
+
62
+ if (!trimmed) {
63
+ return undefined;
64
+ }
65
+
66
+ // If already contains unit or percentage or calc/var, return as is
67
+ if (/^[+-]?\d+(\.\d+)?$/.test(trimmed)) {
68
+ return `${trimmed}${defaultUnit}`;
69
+ }
70
+
71
+ return trimmed;
72
+ }
@@ -0,0 +1,24 @@
1
+ import type { ComputedRef, InjectionKey } from 'vue';
2
+
3
+ export interface IComparisonTableContext {
4
+ readonly cellBg: ComputedRef<string>;
5
+ readonly cellColor: ComputedRef<string>;
6
+ readonly rowHeaderColor: ComputedRef<string>;
7
+ readonly rowHeaderTextColor: ComputedRef<string>;
8
+ readonly colHeaderTextColor: ComputedRef<string>;
9
+ readonly borderRadius: ComputedRef<string>;
10
+ readonly rowHeaderWidth: ComputedRef<string | undefined>;
11
+ readonly spacing: ComputedRef<string>;
12
+ readonly dense: ComputedRef<boolean>;
13
+ readonly animation: ComputedRef<boolean>;
14
+ }
15
+
16
+ export interface IComparisonTableColsContext {
17
+ readonly registerCol: () => number;
18
+ }
19
+
20
+ export const COMPARISON_TABLE_KEY: InjectionKey<IComparisonTableContext> =
21
+ Symbol('COMPARISON_TABLE_KEY');
22
+
23
+ export const COMPARISON_TABLE_COLS_KEY: InjectionKey<IComparisonTableColsContext> =
24
+ Symbol('COMPARISON_TABLE_COLS_KEY');
@@ -0,0 +1,2 @@
1
+ export * from './constants';
2
+ export * from './context';