Skip to content

Commit 92730ba

Browse files
committed
Component block params
1 parent 5d989bb commit 92730ba

File tree

9 files changed

+416
-60
lines changed

9 files changed

+416
-60
lines changed

README.md

Lines changed: 63 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,11 @@ This addon is in active development.
6464
* [x] Updates on arugments change
6565
* [x] Add fool-proof exceptions
6666
* [x] Disabling
67-
* [ ] `<ElementQuery>` component
67+
* [x] `<ElementQuery>` component
6868
* [x] Exists
6969
* [x] Applies attributes to itself
70-
* [ ] Yields block params
70+
* [x] Calls the `onResize` callback with params
71+
* [x] Yields block params
7172
* [x] Accepts `sizes`
7273
* [x] Accepts `prefix`
7374
* [x] Accepts `dimension`
@@ -272,7 +273,7 @@ Usage
272273

273274
### As a modifier
274275

275-
Using the modifier is preferred if you only do CSS transformations.
276+
Using the modifier is preferred if you only do **CSS transformations**, which is recommended according to the Responsiv Web Design doctrine.
276277

277278
Simply apply the `{{element-query}}` modifier to any element or angle bracket component like this:
278279

@@ -290,30 +291,45 @@ As a result, element query attributes will be applied to the element. The result
290291

291292
### As a component
292293

293-
The component is useful when you need to do template transformations.
294+
The component is useful when you need to do **template transformations**.
294295

295-
Use it like this:
296+
If you want to render chunks of template conditionally, use this syntax:
296297

297298
```html
298-
<ElementQuery as |at from to|>
299-
<at.m>
299+
<ElementQuery as |EQ|>
300+
<EQ.at-m>
300301
{{! This will only be rendered when the `<ElementQuery>` component is of size `m`. }}
301302
</at.m>
302303

303-
<from.m>
304+
<EQ.from-m>
304305
{{! This will only be rendered when the `<ElementQuery>` component is of size `m` or larger. }}
305-
</from.m>
306+
</EQ.from-m>
306307

307-
<to.m>
308+
<EQ.to-m>
308309
{{! This will only be rendered when the `<ElementQuery>` component is of size `m` or smaller. }}
309-
</to.m>
310+
</EQ.to-m>
310311

311-
<from.s><to.l>
312+
<EQ.from-s><EQ.to-l>
312313
{{! This will only be rendered when the `<ElementQuery>` component is of size `s`, `m` or `l`. }}
313-
</to.l></from.s>
314+
</EQ.to-l></EQ.from-s>
315+
</ElementQuery>
316+
```
317+
318+
If you want to "sprinke" your tempalte with small responsive bits, you may find it more convenient to use the `{{#if}}` syntax together with [ember-truth-helpers](https://github.com/jmurphyau/ember-truth-helpers):
319+
320+
```html
321+
<ElementQuery as |EQ EQInfo|>
322+
<SomeOtherComponent
323+
@isMedium={{eq EQInfo.size "s"}}
324+
@isMediumOrLarger={{bool EQ.from-m}}
325+
>
314326
</ElementQuery>
315327
```
316328

329+
The first yield argument `EQ` is a hash of current element query attributes. Keys are attribute names and values are truthy strings, so `{{bool EQ.from-m}}` gives you `true` when the element is of size `m` or larger, and `false` when the element is smaller than `m`.
330+
331+
The second argument `EQInfo` is the same hash that is passed to the [onResize callback](#onresize-callback).
332+
317333

318334

319335
Advanced usage
@@ -325,12 +341,16 @@ You can pass a callback to the `onResize` argument and it will be called wheneve
325341

326342
```js
327343
@action
328-
reportResize(data) {
329-
data.element // => current element
330-
data.width // => current element's width in px (number)
331-
data.height // => current element's height in px (number)
332-
data.ratio // => current element's aspect ratio (width/height, number)
333-
data.size // => current element's size (string)
344+
reportResize(info) {
345+
info.element // => current element
346+
info.width // => current element's width in px (number)
347+
info.height // => current element's height in px (number)
348+
info.ratio // => current element's aspect ratio (width/height, number)
349+
info.size // => current element's width size (string or undefined)
350+
info.sizeHeight // => current element's height size (string or undefined)
351+
info.dimension // => current dimension ('width', 'height' or 'both')
352+
info.prefix // => current prefix (string or undefined)
353+
info.attributes // => element query attributes used on the element (array of strings)
334354
}
335355
```
336356

@@ -415,11 +435,11 @@ You can customize height sizes into `@sizesHeight`. Make sure that height size n
415435
<ElementQuery
416436
@dimension="height"
417437
@sizesHeight={{hash small-height=0 medium-height=200 large-height=400}}
418-
as |at from to|
438+
as |EQ|
419439
>
420-
<to.small-width><from.large-height>
440+
<EQ.to-small-width><EQ.from-large-height>
421441
I am thin and tall.
422-
</from.large-height></to.small-width>
442+
</EQ.from-large-height></EQ.to-small-width>
423443
</ElementQuery>
424444
```
425445

@@ -466,11 +486,11 @@ You can customize height sizes into `@sizesHeight`. Make sure that height size n
466486
<ElementQuery
467487
@sizes={{hash smallWidth=0 mediumWidth=350 largeWidth=700}}
468488
@sizesHeight={{hash small-height=0 medium-height=200 large-height=400}}
469-
as |at from to|
489+
as |EQ|
470490
>
471-
<to.small-width><from.large-height>
491+
<EQ.to-small-width><EQ.from-large-height>
472492
I am thin and tall.
473-
</from.large-height></to.small-width>
493+
</EQ.from-large-height></EQ.to-small-width>
474494
</ElementQuery>
475495
```
476496

@@ -726,19 +746,19 @@ Given breakpoints 350, 700 and 1050:
726746
<ElementQuery
727747
class="my-component"
728748
@sizes=(hash small=0 medium=350 large=700 extraLarge=1050)
729-
as |at from to|
749+
as |EQ|
730750
>
731-
<at.small>...</at.small>
732-
<at.medium>...</at.medium>
733-
<at.large>...</at.large>
734-
<at.extraLarge>...</at.extraLarge>
751+
<EQ.at-small>...</EQ.at-small>
752+
<EQ.at-medium>...</EQ.at-medium>
753+
<EQ.at-large>...</EQ.at-large>
754+
<EQ.at-extraLarge>...</EQ.at-extraLarge>
735755

736-
<from.medium>...</from.medium>
737-
<from.large>...</from.large>
738-
<to.medium>...</to.medium>
739-
<to.large>...</to.large>
756+
<EQ.from-medium>...</EQ.from-medium>
757+
<EQ.from-large>...</EQ.from-large>
758+
<EQ.to-medium>...</EQ.to-medium>
759+
<EQ.to-large>...</EQ.to-large>
740760

741-
<from.medium><to.large>...</to.large></from.medium>
761+
<EQ.from-medium><EQ.to-large>...</EQ.to-large></EQ.from-medium>
742762
</ElementQuery>
743763
```
744764

@@ -941,23 +961,23 @@ Given breakpoints 350, 700 and 1050:
941961

942962
```html
943963
<ElementQuery
944-
@sizes=(hash smallWidth=0 mediumWidth=350 largeWidth=700)
945-
@sizesHeight=(hash smallHeight=0 mediumHeight=200 largeHeight=400)
946-
as |at from to|
964+
@sizes=(hash small-width=0 medium-width=350 large-width=700)
965+
@sizesHeight=(hash small-height=0 medium-height=200 large-height=400)
966+
as |EQ|
947967
>
948-
<at.smallWidth><at.largeHeight>
968+
<EQ.to-small-width><EQ.from-large-height>
949969
I am thin and tall.
950-
</at.largeHeight></to.smallWidth>
970+
</EQ.from-large-height></EQ.to-small-width>
951971
</ElementQuery>
952972
```
953973

954974
When usign default sizes, this gets even shorter:
955975

956976
```html
957-
<ElementQuery @heightRules=true as |at from to|>
958-
<at.s><at.lHeight>
977+
<ElementQuery @heightRules=true as |EQ|>
978+
<EQ.to-s><EQ.from-l-height>
959979
I am thin and tall.
960-
</at.lHeight></at.s>
980+
</EQ.from-l-height></EQ.to-s>
961981
</ElementQuery>
962982
```
963983

addon/-private/component.ts

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,45 @@
11
import Component from '@glimmer/component';
2-
import { Yield, Sizes, Dimension } from './modifier';
2+
import { CallbackArgs, Sizes, Dimension } from './modifier';
3+
import { tracked } from '@glimmer/tracking';
4+
import { action } from '@ember/object';
35

46
interface ElementQueryArgs {
57
dimension?: Dimension;
68
isDisabled?: boolean;
79
prefix?: string;
810
sizes?: Sizes;
911
sizesHeight?: Sizes | true;
10-
onResize?: (params: Yield) => void;
12+
onResize?: (params: CallbackArgs) => void;
1113
}
1214

13-
export default class ElementQuery extends Component<ElementQueryArgs> {}
15+
type BlankTemplate = 'element-query-blank-template';
16+
const BLANK_TEMPLATE: BlankTemplate = 'element-query-blank-template';
17+
18+
interface Gates {
19+
[attr: string]: BlankTemplate;
20+
}
21+
22+
export default class ElementQuery extends Component<ElementQueryArgs> {
23+
@tracked
24+
params?: CallbackArgs;
25+
26+
get gates(): Gates | undefined {
27+
return this.params?.attributes.reduce((result, attribute) => {
28+
const prefix = this.params?.prefix || '';
29+
const attributeEffective = attribute.slice(prefix.length);
30+
31+
result[attributeEffective] = BLANK_TEMPLATE;
32+
33+
return result;
34+
}, {} as Gates);
35+
}
36+
37+
@action
38+
onResize(params: CallbackArgs): void {
39+
this.params = params;
40+
41+
if (this.args.onResize) {
42+
this.args.onResize(params);
43+
}
44+
}
45+
}

addon/-private/modifier.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import window from 'ember-window-mock';
66
interface Args extends ModifierArgs {
77
positional: [];
88
named: {
9-
onResize?: (params: Yield) => void;
9+
onResize?: (params: CallbackArgs) => void;
1010
sizes?: Sizes;
1111
sizesHeight?: Sizes;
1212
prefix?: string;
@@ -15,12 +15,15 @@ interface Args extends ModifierArgs {
1515
};
1616
}
1717

18-
export interface Yield {
18+
export interface CallbackArgs {
1919
element: ElementStub;
2020
width: number;
2121
height: number;
2222
ratio: number;
23-
size: string;
23+
size?: string;
24+
sizeHeight?: string;
25+
dimension: Dimension;
26+
prefix?: string;
2427
attributes: string[];
2528
}
2629

@@ -217,15 +220,18 @@ export default class ElementQueryModifier extends Modifier<Args> {
217220
];
218221
}
219222

220-
get yield(): Yield {
223+
get yield(): CallbackArgs {
221224
if (!this._element) throw new Error('Expected this._element to be available');
222225

223226
return {
224227
element: this._element,
225228
width: this.width,
226229
height: this.height,
227230
ratio: this.ratio,
228-
size: this.sizeObjectWidthAt.name,
231+
size: this.isDimensionWidth ? this.sizeObjectWidthAt.name : undefined,
232+
sizeHeight: this.isDimensionHeight ? this.sizeObjectHeightAt.name : undefined,
233+
dimension: this.args.named.dimension || 'width',
234+
prefix: this.args.named.prefix,
229235
attributes: this.attributes,
230236
};
231237
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{{yield}}

app/templates/components/element-query.hbs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@
77
prefix=@prefix
88
sizes=@sizes
99
sizesHeight=@sizesHeight
10-
onResize=@onResize
10+
onResize=this.onResize
1111
}}
1212

1313
...attributes
1414
>
15-
{{yield}}
15+
{{yield this.gates this.params}}
1616
</div>

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
},
2929
"dependencies": {
3030
"ember-cli-babel": "^7.19.0",
31-
"ember-cli-htmlbars": "^4.3.1",
31+
"ember-cli-htmlbars": "5.0.0",
3232
"ember-cli-typescript": "^3.1.4",
3333
"ember-modifier": "^1.0.3",
3434
"ember-resize-observer-modifier": "^1.1.0",
@@ -62,9 +62,10 @@
6262
"ember-maybe-import-regenerator": "^0.1.6",
6363
"ember-qunit": "^4.6.0",
6464
"ember-resolver": "^8.0.0",
65-
"ember-source": "~3.18.0",
65+
"ember-source": "^3.19.0",
6666
"ember-source-channel-url": "^2.0.1",
6767
"ember-template-lint": "^2.6.0",
68+
"ember-truth-helpers": "^2.1.0",
6869
"ember-try": "^1.4.0",
6970
"eslint": "^7.2.0",
7071
"eslint-config-prettier": "^6.11.0",

0 commit comments

Comments
 (0)