-
Notifications
You must be signed in to change notification settings - Fork 3
/
get-priority-index.ts
156 lines (137 loc) · 5.12 KB
/
get-priority-index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
// Adapted from
// https://github.com/yukukotani/eslint-plugin-chakra-ui/blob/dba8a50774e7b133ff9a9d3ae099202ac4d620c4/src/rules/props-order.ts
import type { CssSemanticGroup } from '@pandacss/types'
import type { PluginOptions } from './options'
export const groupNames = [
'System',
'Container',
'Display',
'Visibility',
'Position',
'Transform',
'Flex Layout',
'Grid Layout',
'Layout',
'Border',
'Border Radius',
'Width',
'Height',
'Margin',
'Padding',
'Color',
'Typography',
'Background',
'Shadow',
'Table',
'List',
'Scroll',
'Interactivity',
'Transition',
'Effect',
'Other',
'Conditions',
'Arbitrary conditions',
'Css',
] as const
export type PriorityGroupName = CssSemanticGroup | (typeof groupNames)[number]
export const groupPriorities = groupNames.reduce(
(acc, key, index) => {
acc[key] = index + 1
return acc
},
{} as Record<PriorityGroupName, number>,
)
type Priority = typeof groupPriorities
export type PriorityGroup = {
name: PriorityGroupName
keys: string[]
priority: Priority[PriorityGroupName]
}
/**
* getPriority returns a number. The smaller is the higher priority.
* Internally, each property should have 2 priorities.
* One is its "group priority", determined by which group property belongs,
* and the other is its "inGroup priority", determined by index in that group.
*/
export function getPropPriority(key: string, config: PluginOptions, priorityGroups: PriorityGroup[]): number {
const { pandaFirstProps: firstProps = [], pandaLastProps: lastProps = [], } = config
const indexInFirstProps = firstProps.indexOf(key)
const indexInLastProps = lastProps.indexOf(key)
const componentSpecificProps = [] as string[]
if (indexInFirstProps !== -1) {
return calcPriorityFromIndex({ type: 'reservedFirstProps', value: indexInFirstProps }, config, priorityGroups)
}
if (indexInLastProps !== -1) {
return calcPriorityFromIndex({ type: 'reservedLastProps', value: indexInLastProps }, config, priorityGroups)
}
if (componentSpecificProps) {
const index = componentSpecificProps.indexOf(key)
if (index !== -1) {
return calcPriorityFromIndex({ type: 'componentSpecificProps', value: index }, config, priorityGroups)
}
}
// Then it can be either `stylePropsPriority` or `otherPropsPriority`
const groupIndex = priorityGroups.findIndex((group) => {
return group.keys.includes(key)
})
const isStyleProps = groupIndex > -1
if (isStyleProps) {
const keyIndex = priorityGroups[groupIndex].keys.indexOf(key)
return calcPriorityFromIndex({ type: 'styleProps', groupIndex, keyIndex }, config, priorityGroups)
}
return calcPriorityFromIndex({ type: 'otherProps' }, config, priorityGroups)
}
type Index =
| { type: 'reservedFirstProps' | 'componentSpecificProps' | 'reservedLastProps'; value: number }
| { type: 'styleProps'; groupIndex: number; keyIndex: number }
| { type: 'otherProps' }
const calcPriorityFromIndex = (index: Index, config: PluginOptions, priorityGroups: PriorityGroup[]) => {
// This calculates the priority, in which every property has different priority.
// As an exception, non-predefined properties have the same priority.
// They will be treated as "other Props".
// Currently, the priority is determined from the index of the array.
// We assume that the length of each array is at most 100.
// When changing the specification, be sure to check that the stylePropsPriority range does not overlap with others.
// Now its range is 20000 <= x < 30000;
// Perhaps we may want to handle -1 as error in some future.
// Therefore I set the priority to numbers greater than or equal to zero.
// const isComponentSpecBeforeStyle = config.isCompPropsBeforeStyleProps
const isComponentSpecBeforeStyle = true
const basePriorities = {
firstProps: 0,
styleProps: 20000,
componentSpecificProps: isComponentSpecBeforeStyle ? 10000 : 30000,
otherProps: 40000,
lastProps: 50000,
}
switch (index.type) {
case 'reservedFirstProps': {
const groupPriority = basePriorities.firstProps
const InGroupPriority = index.value
return groupPriority + InGroupPriority
}
case 'styleProps': {
const { groupIndex, keyIndex } = index
const basePriority = basePriorities.styleProps
const groupPriority = priorityGroups[groupIndex].priority
const InGroupPriority = keyIndex
// By using the following formula, we can assign a unique priority to each props of style props.
// Justification: Since priorityGroups[**].length is less than 100, there is no duplicate.
return basePriority + groupPriority * 100 + InGroupPriority
}
case 'componentSpecificProps': {
const groupPriority = basePriorities.componentSpecificProps
return groupPriority
}
case 'otherProps': {
const groupPriority = basePriorities.otherProps
// This will always return same priority value. It needs non-priority-based sorting.
return groupPriority
}
case 'reservedLastProps': {
const groupPriority = basePriorities.lastProps
const InGroupPriority = index.value
return groupPriority + InGroupPriority
}
}
}