Skip to content

Commit 690bb69

Browse files
authored
feat(QIntersection): new prop "root" (quasarframework#7861)
Uses Intersection directive "root" config. Using the "root" property allows an ancestor to be defined. Currently, none of the QIntersection/Intersection examples work on Codepen. I have added one for QIntersection that will work because it uses it's immediate parent as root.
1 parent b96682f commit 690bb69

File tree

8 files changed

+92
-15
lines changed

8 files changed

+92
-15
lines changed
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<template>
2+
<div class="q-pa-md">
3+
<div ref="myList" class="row justify-center q-gutter-sm">
4+
<q-intersection
5+
v-for="index in 60"
6+
:key="index"
7+
:root="listEl"
8+
transition="scale"
9+
class="example-item"
10+
>
11+
<q-card class="q-ma-sm">
12+
<img src="https://cdn.quasar.dev/img/mountains.jpg">
13+
14+
<q-card-section>
15+
<div class="text-h6">Card #{{ index }}</div>
16+
<div class="text-subtitle2">by John Doe</div>
17+
</q-card-section>
18+
</q-card>
19+
</q-intersection>
20+
</div>
21+
</div>
22+
</template>
23+
24+
<script>
25+
export default {
26+
computed: {
27+
listEl () {
28+
return this.$refs.myList ? this.$refs.myList.$el : null
29+
}
30+
}
31+
}
32+
</script>
33+
34+
<style lang="sass" scoped>
35+
.example-item
36+
height: 290px
37+
width: 290px
38+
</style>

docs/src/pages/vue-components/intersection.md

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,23 +32,31 @@ An example of such needed CSS would be, for example, a fixed height or at least
3232
If using the `transition` prop, it is required that the content be wrapped in one and only one element.
3333
:::
3434

35+
::: tip
36+
There are edge cases where the default viewport won't work. For instance, when your code is hosted in an iframe (like Codepen). This is where you need to use the `root` property. It allows you define an alternative to the viewport as your root (through its DOM element). It is important to keep in mind that root needs to be an ancestor of the observed element.
37+
:::
38+
3539
### Basic
3640

37-
<doc-example title="Basic" file="QIntersection/Basic" scrollable />
41+
<doc-example title="Basic" file="QIntersection/Basic" scrollable no-edit />
3842

3943
### With transition
4044

4145
In the example below we used a Quasar transition. For a full list, please head to [Transitions](/options/transitions) page.
4246

43-
<doc-example title="With transition" file="QIntersection/Transition" scrollable />
47+
<doc-example title="With transition" file="QIntersection/Transition" scrollable no-edit />
4448

45-
<doc-example title="A list with transition" file="QIntersection/List" scrollable />
49+
<doc-example title="A list with transition" file="QIntersection/List" scrollable no-edit />
4650

4751
### Only once
4852

4953
Triggering only once means, however, that you lose the benefit of freeing up the DOM tree. The content will remain in DOM regardless of visibility.
5054

51-
<doc-example title="Triggering only once" file="QIntersection/Once" scrollable />
55+
<doc-example title="Triggering only once" file="QIntersection/Once" scrollable no-edit />
56+
57+
The example below uses the `root` property and therefore can be seen in a Codepen (which hosts in an iframe).
58+
59+
<doc-example title="Root viewport" file="QIntersection/Root" scrollable />
5260

5361
## QIntersection API
5462
<doc-api file="QIntersection" />

docs/src/pages/vue-directives/intersection.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,31 +50,31 @@ Scroll within the examples below until the observed element is in view. Then scr
5050

5151
### Basic
5252

53-
<doc-example title="Basic" file="Intersection/Basic" />
53+
<doc-example title="Basic" file="Intersection/Basic" no-edit />
5454

5555
### Trigger once
5656

5757
The directive can be used with the `once` modifier (ex: `v-intersection.once`). Once the observed element comes into view, the handler Function will be called and the observing will stop. This allows you to control the processing overhead if all you need is to be notified when the observed element starts to be visible on screen.
5858

59-
<doc-example title="Once" file="Intersection/Once" />
59+
<doc-example title="Once" file="Intersection/Once" no-edit />
6060

6161
### Using an Object
6262

6363
By passing in an Object as the directive's value (instead of a Function), you can control all the options (like threshold) of the Intersection Observer.
6464

65-
<doc-example title="Supplying configuration Object" file="Intersection/ObjectForm" />
65+
<doc-example title="Supplying configuration Object" file="Intersection/ObjectForm" no-edit />
6666

6767
### Advanced
6868

6969
Below is a more advanced example of what you can do. The code takes advantage of the HTML `data` attribute. Basically, by setting `data-id` with the index of the element in a loop, this can be retrieved via the passed in `entry` to the handler as `entry.target.dataset.id`. If you are unfamiliar with the `data` attribute you can read more [here](https://developer.mozilla.org/en-US/docs/Learn/HTML/Howto/Use_data_attributes) about using the `data` attribute.
7070

71-
<doc-example title="Advanced" file="Intersection/Advanced" />
71+
<doc-example title="Advanced" file="Intersection/Advanced" no-edit />
7272

7373
In the example below, we show multiple cards, but only the visible ones get rendered. The secret is in the wrapper which has `v-intersection` attached to it and a fixed height and width (which acts as a necessary filler when the inner content is not rendered -- so that scrolling won't erratically jump).
7474

7575
> The example below can also be written by using [QIntersection](/vue-components/intersection) component which makes everything even more easy.
7676
77-
<doc-example title="Scrolling Cards" file="Intersection/ScrollingCards" scrollable />
77+
<doc-example title="Scrolling Cards" file="Intersection/ScrollingCards" scrollable no-edit />
7878

7979
::: tip
8080
In the example above we used a Quasar transition. For a full list, please head to [Transitions](/options/transitions) page.

ui/build/build.api.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -107,13 +107,13 @@ const objectTypes = {
107107

108108
// special type, not common
109109
Error: {
110-
props: [ 'desc' ],
110+
props: [ 'desc', 'category', 'examples', 'addedIn' ],
111111
required: [ 'desc' ]
112112
},
113113

114114
// special type, not common
115115
Component: {
116-
props: [ 'desc' ],
116+
props: [ 'desc', 'category', 'examples', 'addedIn' ],
117117
required: [ 'desc' ]
118118
},
119119

@@ -124,19 +124,19 @@ const objectTypes = {
124124

125125
// special type, not common
126126
Element: {
127-
props: [ 'desc', 'examples' ],
127+
props: [ 'desc', 'category', 'examples', 'addedIn' ],
128128
required: [ 'desc' ]
129129
},
130130

131131
// special type, not common
132132
File: {
133-
props: [ 'desc', 'required' ],
133+
props: [ 'desc', 'required', 'category', 'examples', 'addedIn' ],
134134
required: [ 'desc' ]
135135
},
136136

137137
// special type, not common
138138
FileList: {
139-
props: [ 'desc', 'required' ],
139+
props: [ 'desc', 'required', 'category', 'examples', 'addedIn' ],
140140
required: [ 'desc' ]
141141
},
142142

ui/dev/src/pages/components/intersection-3.vue

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<q-toggle v-model="once" label="Once" />
66
<q-select v-model="transition" :options="['', 'fade', 'scale', 'flip-right']" style="min-width: 250px" />
77
</div>
8-
<table v-if="visible">
8+
<table v-if="visible" ref="table">
99
<tr
1010
v-for="index in 10"
1111
:key="index"
@@ -16,6 +16,7 @@
1616
:once="once"
1717
:transition="transition"
1818
tag="td"
19+
:root="tableEl"
1920
class="int-example-item"
2021
>
2122
<q-card class="q-ma-sm">
@@ -44,6 +45,11 @@ export default {
4445
once: false,
4546
transition: 'scale'
4647
}
48+
},
49+
computed: {
50+
tableEl () {
51+
return this.$refs.table ? this.$refs.table.$el : null
52+
}
4753
}
4854
}
4955
</script>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<template>
2+
<div class="q-pa-md bordered column">
3+
QIntersection hosted in an iframe
4+
<iframe
5+
src="/components/intersection-3"
6+
class="rounded-borders q-pa-sm"
7+
style="max-width: 800px; width: 100%; height: 400px; border: 1px solid #2196f3"
8+
>
9+
</iframe>
10+
</div>
11+
</template>

ui/src/components/intersection/QIntersection.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ export default Vue.extend({
2626

2727
margin: String,
2828
threshold: [ Number, Array ],
29+
root: {
30+
type: Element,
31+
default: null
32+
},
2933

3034
disable: Boolean
3135
},
@@ -42,6 +46,7 @@ export default Vue.extend({
4246
? {
4347
handler: this.__trigger,
4448
cfg: {
49+
root: this.root,
4550
rootMargin: this.margin,
4651
threshold: this.threshold
4752
}

ui/src/components/intersection/QIntersection.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
"props": {
1515
"tag": {
16+
"type": "String",
1617
"examples": [ "div", "span", "blockquote" ],
1718
"addedIn": "v1.9.3"
1819
},
@@ -30,6 +31,14 @@
3031
"addedIn": "v1.9.5"
3132
},
3233

34+
"root": {
35+
"type": "Element",
36+
"desc": "[Intersection API root prop] Lets you define an alternative to the viewport as your root (through its DOM element); It is important to keep in mind that root needs to be an ancestor of the observed element",
37+
"examples": [ "$refs.myTable.$el", "getElementById(\"myTable\")" ],
38+
"category": "behavior",
39+
"addedIn": "v1.14.1"
40+
},
41+
3342
"margin": {
3443
"type": "String",
3544
"desc": "[Intersection API rootMargin prop] Allows you to specify the margins for the root, effectively allowing you to either grow or shrink the area used for intersections",

0 commit comments

Comments
 (0)