Skip to content

Commit

Permalink
Merge pull request #2452 from exadel-inc/feat/ingore-tuple-by-query
Browse files Browse the repository at this point in the history
feat(esl-media-query): ingore tuple values if query syntax passed
  • Loading branch information
ala-n committed Jul 18, 2024
2 parents 06d2bd3 + 025166e commit 80f567a
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 29 deletions.
3 changes: 3 additions & 0 deletions .eslintrc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,6 @@ rules:
'editorconfig/eol-last': warn
# Require no trailing spaces
'editorconfig/no-trailing-spaces': warn

# Exclude migration rules for 5.0.0-beta.24 revision
'@exadel/esl/deprecated-4/media-rule-list-parse': off
11 changes: 6 additions & 5 deletions src/modules/esl-media-query/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -204,20 +204,21 @@ ESLMediaRuleList.parse('1 | @XS => 2', String); // the same as sample above
ESLMediaRuleList.parse('1 | @XS => 2', Number); // first query from the sample above that store numeric values
ESLMediaRuleList.parse('@XS => {option: 1} | @+SM => {option: 2}', ESLMediaRuleList.OBJECT_PARSER); // second query from the sample above with an object payloads
ESLMediaRuleList.parse('@XS => {option: 1} | @+SM => {option: 2}', evaluate); // the same as the sample above
ESLMediaRuleList.parse('1|2|3|4|5', '@xs|@sm|@md|@lg|@xl') // parses tuple payloads
ESLMediaRuleList.parse('@mqAlt1 => value1| @mqAlt2 => value2', '@mq1|@mq2'); // parses first argument as an arrow syntax without default tuple consideration.

// Tupple parsing
ESLMediaRuleList.parseTuple('@xs|@sm|@md|@lg|@xl', '1|2|3|4|5') // String payload example
ESLMediaRuleList.parseTuple('@xs|@sm|@md|@lg|@xl', '1|2|3|4|5', Number) // Numeric payload sample
```
**Note**: Method `ESLMediaRuleList.parse` is deprecated, and will be reintroduced in ESL v5.0.0 with a different signature. For now use `ESLMediaRuleList.parseTuple` or `ESLMediaRuleList.parseQuery` instead.

#### ESLMediaRuleList API

- `ESLMediaRuleList.parse(ruleset: string)` - parse media ruleset defined with classic syntax mentioned in section above.
Rules separated by `|` symbol, query and value separated by `=>` for each rule, query is optional.
- `ESLMediaRuleList.parseTuple(queries: string, values: string)` - parse media ruleset from tuple of queries and values, all separated via `|` symbol.

- `ESLMediaRuleList.parseTuple(queries: string, values: string)` - parse media ruleset from tuple of
queries and values, all separated via `|` symbol
- `ESLMediaRuleList.parseQuery(ruleset: string)` - parse media ruleset defined with syntax, where query and value are a single argument separated by `=>` for each rule.

- `ESLMediaRuleList.parse(values: string, queries: string)` - parse media ruleset adaptively. Method can support both notations with a ruleset from tuple of queries and values, all separated via `|` symbol, and can parse cases where query syntax with rules separated by `=>` is being used as a value for a tuple.

- `ESLMediaRuleList.prototype.rules` - array of rules that defines `ESLMediaRuleList` object
- `ESLMediaRuleList.prototype.active` - array of active (matched) rules
Expand Down
39 changes: 15 additions & 24 deletions src/modules/esl-media-query/core/esl-media-rule-list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,64 +35,55 @@ export class ESLMediaRuleList<T = any> extends SyntheticEventTarget {
public static OBJECT_PARSER = <U = any>(val: string): U | undefined => evaluate(val);

/**
* @deprecated Method will be reintroduced in v5.0.0 with a different signature. For now use ESLMediaRuleList.parseQuery instead
*
* Creates `ESLMediaRuleList` from string query representation
* Creates {@link ESLMediaRuleList} from string query representation
* Expect serialized {@link ESLMediaRule}s separated by '|'
* Uses exact strings as rule list values
*
* @param query - query string
*/
public static parse(query: string): ESLMediaRuleList<string>;
/**
* @deprecated Method will be reintroduced in v5.0.0 with a different signature. For now use ESLMediaRuleList.parseQuery instead
*
* Creates `ESLMediaRuleList` from string query representation.
* Creates {@link ESLMediaRuleList} from string query representation.
* Expect serialized {@link ESLMediaRule}s separated by '|'
*
* @param query - query string
* @param parser - value parser function
*/
public static parse<U>(query: string, parser: RulePayloadParser<U>): ESLMediaRuleList<U>;
/**
* @deprecated Method will be reintroduced in v5.0.0 with a different signature. For now use ESLMediaRuleList.parseTuple instead
* Creates `ESLMediaRuleList` from two strings with conditions and values sequences
* Creates {@link ESLMediaRuleList} from two strings with conditions and values sequences
*
* @param mask - media conditions tuple string (uses '|' as separator)
* @param values - values tuple string (uses '|' as separator)
* @param mask - media conditions tuple string (uses '|' as separator)
*
* @example
* ```ts
* ESLMediaRuleList.parse('@XS|@SM|@MD|@LG|@XL', '1|2|3|4|5')
* ```
*/
public static parse(mask: string, values: string): ESLMediaRuleList<string>;
public static parse(values: string, mask: string): ESLMediaRuleList<string>;
/**
* @deprecated Method will be reintroduced in v5.0.0 with a different signature. For now use ESLMediaRuleList.parseTuple instead
*
* Creates `ESLMediaRuleList` from two strings with conditions and values sequences
* Creates {@link ESLMediaRuleList} from two strings with conditions and values sequences
*
* @param mask - media conditions tuple string (uses '|' as separator)
* @param values - values tuple string (uses '|' as separator)
* @param mask - media conditions tuple string (uses '|' as separator)
* @param parser - value parser function
*
* @example
* ```ts
* ESLMediaRuleList.parseTuple('@XS|@SM|@MD|@LG|@XL', '1|2|3|4|5', Number)
* ```
*/
public static parse<U>(mask: string, values: string, parser: RulePayloadParser<U>): ESLMediaRuleList<U>;
public static parse<U>(values: string, mask: string, parser: RulePayloadParser<U>): ESLMediaRuleList<U>;
public static parse(query: string, ...common: (string | RulePayloadParser<any>)[]): ESLMediaRuleList {
const parser: RulePayloadParser<any> = typeof common[common.length - 1] === 'function' ? common.pop() as any : String;
const value = common.pop();
return typeof value === 'string' ?
ESLMediaRuleList.parseTuple(query, value, parser) :
ESLMediaRuleList.parseQuery(query, parser);
const mask = common.pop();
if (query.includes('=>') || typeof mask !== 'string') return ESLMediaRuleList.parseQuery(query, parser);
return ESLMediaRuleList.parseTuple(mask, query, parser);
}

/**
* Creates `ESLMediaRuleList` from string query representation
* Creates {@link ESLMediaRuleList} from string query representation
* Uses exact strings as rule list values
* @param query - query string
*/
Expand All @@ -111,7 +102,7 @@ export class ESLMediaRuleList<T = any> extends SyntheticEventTarget {
}

/**
* Creates `ESLMediaRuleList` from two strings with conditions and values sequences
* Creates {@link ESLMediaRuleList} from two strings with conditions and values sequences
*
* @param mask - media conditions tuple string (uses '|' as separator)
* @param values - values tuple string (uses '|' as separator)
Expand All @@ -123,7 +114,7 @@ export class ESLMediaRuleList<T = any> extends SyntheticEventTarget {
*/
public static parseTuple(mask: string, values: string): ESLMediaRuleList<string>;
/**
* Creates `ESLMediaRuleList` from two strings with conditions and values sequences
* Creates {@link ESLMediaRuleList} from two strings with conditions and values sequences
*
* @param mask - media conditions tuple string (uses '|' as separator)
* @param values - values tuple string (uses '|' as separator)
Expand Down Expand Up @@ -216,7 +207,7 @@ export class ESLMediaRuleList<T = any> extends SyntheticEventTarget {

/** @returns serialized {@link ESLMediaRuleList} object representation*/
public override toString(): string {
return this.rules.join('|');
return this.rules.join(' | ');
}
}

Expand Down
25 changes: 25 additions & 0 deletions src/modules/esl-media-query/test/esl-media-rule-list.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,4 +178,29 @@ describe('ESLMediaRuleList', () => {
expect(() => ESLMediaRuleList.parseTuple('@xs', '1|2|3')).toThrowError();
});
});

describe('Adaptive cases parsing', () => {
test.each([
// [ [.. Call Args], 'Canonical form']
[['1'], 'all => 1'],

// Tuples
[['1', '@-sm'], '(max-width: 991px) => 1'],
[['1', '@+sm'], '(min-width: 768px) => 1'],
[['1', '@sm'], '(min-width: 768px) and (max-width: 991px) => 1'],
[['0 | 1', '@+xs | @+sm'], '(min-width: 1px) => 0 | (min-width: 768px) => 1'],
[['1|2|3', 'all|@sm|@md'], 'all => 1 | (min-width: 768px) and (max-width: 991px) => 2 | (min-width: 992px) and (max-width: 1199px) => 3'],
[['f=|s>|t<', 'all | @-xs | @-sm',], 'all => f= | (max-width: 767px) => s> | (max-width: 991px) => t<'],

// Arrow syntax
[['0 | (min-width: 100px) => 1 | (min-width: 200px) => 2'], 'all => 0 | (min-width: 100px) => 1 | (min-width: 200px) => 2'],
[['1 | @+sm => 2 | @+md => 3'], 'all => 1 | (min-width: 768px) => 2 | (min-width: 992px) => 3'],
[['1 | @+sm => 2', '@sm'], 'all => 1 | (min-width: 768px) => 2'],
[['1 | screen and @sm => 2'], 'all => 1 | screen and (min-width: 768px) and (max-width: 991px) => 2'],
[['1 | @-xs or @+md => 2'], 'all => 1 | (max-width: 767px), (min-width: 992px) => 2'],
[['@-xs => hello | @+sm => world'], '(max-width: 767px) => hello | (min-width: 768px) => world'],
])('Should correctly parse "%s" with media condition "%s"', (params: any[], canonical: string) => {
expect(ESLMediaRuleList.parse.apply(null, params).toString()).toBe(canonical);
});
});
});

0 comments on commit 80f567a

Please sign in to comment.