Skip to content

Commit 074e50b

Browse files
authored
fix: Global selector sorting and chaining logic (#124)
1 parent 6c922ae commit 074e50b

File tree

2 files changed

+16
-5
lines changed

2 files changed

+16
-5
lines changed

src/shared/declaration/__tests__/selector.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ describe('Selector', () => {
2020
test('creates selector for context', () => {
2121
expect(selector.for({ global: ['.theme'], local: ['.context'] })).toEqual('.theme .context');
2222
expect(selector.for({ global: [':root'], local: ['.context'] })).toEqual('.context');
23-
expect(selector.for({ global: ['html', '.theme'], local: ['.context'] })).toEqual('.theme .context');
23+
expect(selector.for({ global: ['html', '.awsui-theme'], local: ['.context'] })).toEqual('.awsui-theme .context');
2424
});
2525

2626
test('creates selector for context within mode', () => {
@@ -34,6 +34,7 @@ describe('Selector', () => {
3434
test('customizes each selector when multiple', () => {
3535
const selector = new Selector((sel) => `${sel}:not(.theme)`);
3636
expect(selector.for({ global: [':root', '.mode'], local: ['.context'] })).toEqual('.mode .context:not(.theme)');
37+
expect(selector.for({ global: ['body', '.mode'], local: ['.context'] })).toEqual('.mode .context:not(.theme)');
3738
});
3839

3940
test('applies global selectors alone when no local selectors', () => {

src/shared/declaration/selector.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@ export class Selector {
2020
// Global selectors (:root, body, html) are only applied alone
2121
return this.customizer(global[0]);
2222
}
23-
const customGlobal = global.filter((f) => !isGlobalSelector(f));
23+
const nonGlobalSelectors = global.filter((f) => !isGlobalSelector(f));
2424

25-
let selector = this.toSelector(customGlobal);
25+
let selector = this.toSelector(nonGlobalSelectors);
2626
if (local?.length) {
2727
selector += ` ${this.toSelector(local)}`;
2828
}
@@ -31,7 +31,17 @@ export class Selector {
3131
}
3232

3333
private toSelector(individuals: string[]): string {
34-
// Sort to guarantee a stable generation
35-
return individuals.slice().sort().join('');
34+
// Sort to guarantee a stable generation - element selectors first, then class selectors
35+
const isElement = (selector: string) => {
36+
return ['.', ':', '#'].indexOf(selector.charAt(0)) === -1;
37+
};
38+
return individuals
39+
.slice()
40+
.sort((a, b) => {
41+
if (isElement(a) && !isElement(b)) return -1;
42+
if (!isElement(a) && isElement(b)) return 1;
43+
return a.localeCompare(b);
44+
})
45+
.join('');
3646
}
3747
}

0 commit comments

Comments
 (0)