Skip to content

Commit 910f4af

Browse files
committed
Add option to override a rule's position, enabling us to move it before another rule
1 parent 7da896e commit 910f4af

File tree

4 files changed

+54
-110
lines changed

4 files changed

+54
-110
lines changed

src/debug.js

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
export function classesInRange(byClassname, start, end) {
2+
return Object.entries(byClassname).filter((_, i) => i >= start && i <= end);
3+
}
4+
5+
export function classesByName(byClassname, ...names) {
6+
return Object.entries(byClassname).find(([key]) => {
7+
for (const name of names) {
8+
if (key.includes(name)) {
9+
return true;
10+
}
11+
}
12+
});
13+
}

src/plugins.js

+34-5
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,13 @@ export function classnameByProperties(cfg) {
6161
return byProperties;
6262
}
6363

64-
export function loadPlugin(cfg, name, load) {
64+
export function loadPlugin(cfg, plugin, load) {
65+
let name = plugin;
66+
let overrides = [];
67+
if (typeof plugin === 'object') {
68+
name = plugin.name;
69+
overrides = plugin.overrides;
70+
}
6571
if (!(name in plugins)) {
6672
throw new Error(`plugin '${name}' doesn't exist`);
6773
}
@@ -89,7 +95,7 @@ export function loadPlugin(cfg, name, load) {
8995
calculatedRules[classname] = properties;
9096
}
9197
}
92-
loadPluginRules(calculatedRules, load);
98+
loadPluginRules(calculatedRules, overrides, load);
9399
},
94100
addUtilities: (rules) => {
95101
let source = rules;
@@ -105,7 +111,7 @@ export function loadPlugin(cfg, name, load) {
105111
source = rules[0];
106112
}
107113
}
108-
loadPluginRules(source, load);
114+
loadPluginRules(source, overrides, load);
109115
},
110116
theme: themeForConfig(cfg),
111117
variants: () => {},
@@ -116,8 +122,21 @@ export function loadPlugin(cfg, name, load) {
116122
});
117123
}
118124

119-
function loadPluginRules(rules, load) {
120-
Object.entries(rules).forEach(([classname, properties]) => {
125+
function loadPluginRules(rules, overrides, load) {
126+
let entries = Object.entries(rules);
127+
128+
if (overrides.length > 0) {
129+
for (const ovr of overrides) {
130+
const ruleIdx = entries.findIndex(([classname]) => classname === '.' + ovr.rule);
131+
const [kind, destRule] = ovr.place;
132+
const destIdx = entries.findIndex(([classname]) => classname === '.' + destRule);
133+
if (kind === 'before') {
134+
arrayMove(entries, ruleIdx, destIdx);
135+
}
136+
}
137+
}
138+
139+
entries.forEach(([classname, properties]) => {
121140
// `space-{}` classnames contain the full CSS selector, which is like `.space-y-150 > :not([hidden]) ~ :not([hidden])`
122141
// but we only want the first part, so copy everything until the first space.
123142
let spaceIdx = classname.indexOf(' ');
@@ -156,3 +175,13 @@ function themeForConfig(cfg) {
156175
function getConfigValue(cfg, path, defaultValue) {
157176
return path ? get(cfg, path, defaultValue) : cfg;
158177
}
178+
179+
function arrayMove(arr, oldIndex, newIndex) {
180+
if (newIndex >= arr.length) {
181+
let k = newIndex - arr.length + 1;
182+
while (k--) {
183+
arr.push(undefined);
184+
}
185+
}
186+
arr.splice(newIndex, 0, arr.splice(oldIndex, 1)[0]);
187+
}

src/sort.js

+2-105
Original file line numberDiff line numberDiff line change
@@ -2,139 +2,66 @@
22
export const variants = ['hover'].map((v) => `(${v}:)?`).join('');
33

44
export let order = [
5-
// Utils
65
'container',
7-
8-
// Position
96
'position',
10-
11-
// Z-Index
127
'zIndex',
13-
14-
// Display
15-
'display',
16-
17-
// Visibility
8+
{ name: 'display', overrides: [{ rule: 'hidden', place: ['before', 'block'] }] },
189
'visibility',
19-
20-
// Pointer Events
2110
'pointerEvents',
22-
23-
// Flex Direction
24-
'flexDirection',
25-
// Flex Wrap
11+
{ name: 'flexDirection', overrides: [{ rule: 'flex-col', place: ['before', 'flex-row'] }] },
2612
'flexWrap',
27-
// Flex Grow
2813
'flexGrow',
29-
// Flex Shrink
3014
'flexShrink',
31-
32-
// Grid Auto Flow
3315
'gridAutoFlow',
34-
// Grid Template Columns
3516
'gridTemplateColumns',
36-
// Grid Auto Columns
3717
'gridAutoColumns',
38-
// Grid Column Start / End
3918
'gridColumn',
4019
'gridColumnStart',
4120
'gridColumnEnd',
42-
43-
// Grid Template Rows
4421
'gridTemplateRows',
45-
// Grid Auto Rows
4622
'gridAutoRows',
47-
// Grid Row Start / End
4823
'gridRow',
4924
'gridRowStart',
5025
'gridRowEnd',
51-
52-
// Order
5326
'order',
54-
55-
// Justify Content
5627
'justifyContent',
57-
// Justify Items
5828
'justifyItems',
59-
// Justify Self
6029
'justifySelf',
61-
// Align Content
6230
'alignContent',
63-
// Align Items
6431
'alignItems',
65-
// Align Self
6632
'alignSelf',
67-
// Place Content
6833
'placeContent',
69-
// Place Items
7034
'placeItems',
71-
// Place Self
7235
'placeSelf',
73-
74-
// Object Fit
7536
'objectFit',
76-
// Object Position
7737
'objectPosition',
78-
79-
// Overflow
8038
'overflow',
81-
82-
// Overscroll Behavior
8339
'overscrollBehavior',
84-
85-
// Inset, Top / Bottom / Left / Right
8640
'inset',
87-
88-
// Size
8941
'width',
9042
'minWidth',
9143
'maxWidth',
9244
'height',
9345
'minHeight',
9446
'maxHeight',
95-
96-
// Cursor
9747
'cursor',
98-
99-
// Text Alignment
10048
'textAlign',
101-
// Vertical Alignment
10249
'verticalAlign',
103-
104-
// List Style Type
10550
'listStyleType',
106-
107-
// Text Transform
10851
'textTransform',
109-
// Font Style
11052
'fontStyle',
111-
// Text Decoration
11253
'textDecoration',
113-
// Font Weight, Size, Color
11454
'fontWeight',
11555
'fontSize',
11656
'textColor',
117-
// Text Opacity
11857
'textOpacity',
119-
// Letter Spacing
12058
'letterSpacing',
121-
// Line Height
12259
'lineHeight',
123-
124-
// Text Overflow
12560
'textOverflow',
126-
127-
// Whitespace
12861
'whitespace',
129-
// Word Break
13062
'wordBreak',
131-
132-
// Placeholder Color
13363
'placeholderColor',
134-
// Placeholder Opacity
13564
'placeholderOpacity',
136-
137-
// Background
13865
'backgroundPosition',
13966
'backgroundRepeat',
14067
'backgroundSize',
@@ -145,63 +72,33 @@ export let order = [
14572
'backgroundAttachment',
14673
'backgroundBlendMode',
14774
'backgroundClip',
148-
149-
// Opacity
15075
'opacity',
151-
152-
// Box Shadow
15376
'boxShadow',
154-
155-
// Border
15677
'borderStyle',
15778
'borderWidth',
15879
'borderColor',
15980
'borderOpacity',
16081
'borderRadius',
16182
'borderCollapse',
162-
163-
// Outline
16483
'outline',
165-
166-
// Ring
16784
'ringWidth',
16885
'ringOpacity',
16986
'ringOffsetWidth',
170-
171-
// Transform
17287
'transform',
173-
// Transform Origin
17488
'transformOrigin',
175-
// Scale
17689
'scale',
177-
// Rotate
17890
'rotate',
179-
// Translate
18091
'translate',
181-
// Skew
18292
'skew',
183-
184-
// Transition Property
18593
'transitionProperty',
18694
'transitionDuration',
18795
'transitionDelay',
18896
'transitionTimingFunction',
189-
// Animation
19097
'animation',
191-
192-
// Box Sizing
19398
'boxSizing',
194-
195-
// Padding
19699
'padding',
197-
198-
// Spacing
199100
'space',
200-
201-
// Gap
202101
'gap',
203-
204-
// Margin
205102
'margin',
206103
];
207104

test/sort.js

+5
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,10 @@ s('sorts', () => {
1414
assert.equal(sort('mt-4 relative'), 'relative mt-4');
1515
assert.equal(sort('xl:mt-8 mt-4 relative'), 'relative mt-4 xl:mt-8');
1616
assert.equal(sort('space-x-8 xl:mt-8 mt-4 relative'), 'relative space-x-8 mt-4 xl:mt-8');
17+
assert.equal(
18+
sort('hidden lg:block text-base leading-none text-neutrals-l00 ml-6 mr-4'),
19+
'hidden lg:block text-base text-neutrals-l00 leading-none mr-4 ml-6'
20+
);
21+
assert.equal(sort('sm:flex-row flex flex-col'), 'flex flex-col sm:flex-row');
1722
});
1823
s.run();

0 commit comments

Comments
 (0)