Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit0cae3ba

Browse files
committed
Init git repo
0 parents  commit0cae3ba

23 files changed

+1039
-0
lines changed

‎.eslintignore‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
.DS_Store
2+
node_modules
3+
/build
4+
/.svelte-kit
5+
/package
6+
.env
7+
.env.*
8+
!.env.example
9+
10+
# Ignore files for PNPM, NPM and YARN
11+
pnpm-lock.yaml
12+
package-lock.json
13+
yarn.lock

‎.eslintrc.cjs‎

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/**@type { import("eslint").Linter.FlatConfig} */
2+
module.exports={
3+
root:true,
4+
extends:[
5+
"eslint:recommended",
6+
"plugin:@typescript-eslint/recommended",
7+
"plugin:svelte/recommended",
8+
"prettier",
9+
],
10+
parser:"@typescript-eslint/parser",
11+
plugins:["@typescript-eslint"],
12+
parserOptions:{
13+
sourceType:"module",
14+
ecmaVersion:2020,
15+
extraFileExtensions:[".svelte"],
16+
},
17+
env:{
18+
browser:true,
19+
es2017:true,
20+
node:true,
21+
},
22+
overrides:[
23+
{
24+
files:["*.svelte"],
25+
parser:"svelte-eslint-parser",
26+
parserOptions:{
27+
parser:"@typescript-eslint/parser",
28+
},
29+
},
30+
],
31+
};

‎.gitignore‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
.DS_Store
2+
node_modules
3+
/build
4+
/dist
5+
/.svelte-kit
6+
/package
7+
.env
8+
.env.*
9+
!.env.example
10+
vite.config.js.timestamp-*
11+
vite.config.ts.timestamp-*

‎.npmrc‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
engine-strict=true

‎.prettierignore‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
.DS_Store
2+
node_modules
3+
/build
4+
/.svelte-kit
5+
/package
6+
.env
7+
.env.*
8+
!.env.example
9+
10+
# Ignore files for PNPM, NPM and YARN
11+
pnpm-lock.yaml
12+
package-lock.json
13+
yarn.lock

‎.prettierrc‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"plugins": ["prettier-plugin-svelte"],
3+
"overrides": [
4+
{ "files": "*.svelte", "options": { "parser": "svelte" } },
5+
{
6+
"files": "*.md",
7+
"options": {
8+
"proseWrap": "always"
9+
}
10+
}
11+
]
12+
}

‎LICENSE‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2023 Dexter Lui
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

‎README.md‎

Lines changed: 244 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,244 @@
1+
#Svelte ScrollSpy
2+
3+
Svelte ScrollSpy is a[Svelte store](https://svelte.dev/docs/svelte-store) that
4+
tracks the intersecting state of a set of elements. The store provides a
5+
[Svelte action](https://svelte.dev/docs/svelte-action) that allows you to easily
6+
register any element for tracking.
7+
8+
#Installation
9+
10+
##NPM
11+
12+
```
13+
npm i -D svelte-scrollspy
14+
```
15+
16+
##Yarn
17+
18+
```
19+
yarn add -D svelte-scrollspy
20+
```
21+
22+
##bun
23+
24+
```
25+
bun i -d svelte-scrollspy
26+
```
27+
28+
#Why Svelte ScrollSpy?
29+
30+
Although there are many intersection observer libraries out there, this library
31+
leverages the power of Svelte actions to provide a simple and intuitive API.
32+
Here are some of the benefits of using this library in a Svelte project.
33+
34+
- Have a cleaner DOM without needing to add wrapper elements.
35+
- Easily register any elements, even nested elements, for tracking.
36+
- No need to worry about cleaning up when elements being tracked are removed
37+
from the DOM. Callbacks in Svelte action automatically do that.
38+
39+
#API
40+
41+
The object stored in the ScrollSpy store has the following properties:
42+
43+
| Property| Description|
44+
| ------------------| ---------------------------------------------------------------------------------------------------------------------------------------------|
45+
|`amount`| The number of targets being spied on.|
46+
|`targets`| The ordered set of all targets being spied on, in the order of them being added as a target.|
47+
|`activeTargets`| The ordered set of all intersecting targets, in the order of entering intersection.|
48+
|`activeTarget`| The target that became active most recently and is still active. I.e. the last item in`activeTargets`.|
49+
|`lastActiveTarget`| The target that became active most recently. It may or may not be active now. If this target is no longer being spied on, this value is null.|
50+
|`activeId`| The id of`activeTarget`.|
51+
|`lastActiveId`| The id of`lastActiveTarget`.|
52+
|`isActive`| A function that checks if an element is active. Returns`null` if the given element is not a target being spied on.|
53+
54+
The ScrollSpy store also has the following methods besides the`subscribe`
55+
method of a Svelte store.
56+
57+
| Method| Description|
58+
| ----------| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
59+
|`spy`| A svelte action to add an element to the target list and start spying on it.|
60+
|`unspy`| Stop spying on a target and remove it from the target list. Accepts either the element itself or the id as the argument. This method is automatically called on all registered targets after they are removed from the DOM.|
61+
|`unspyAll`| Stop spying on all existing targets and remove them from the target list.|
62+
63+
#Usage
64+
65+
##Basic
66+
67+
To use ScrollSpy to track the current section in view on the page. First create
68+
a scroll spy store with the imported`createScrollSpy` function. You can pass in
69+
an IntersectionObserverInit object to configure the IntersectionObserver used
70+
for tracking.
71+
72+
In the example, we set the`rootMargin` to`-50% 0px` so that a section starts
73+
intersecting when it touches the vertical center of the viewport.
74+
75+
```javascript
76+
importcreateScrollSpyfrom"svelte-scrollspy";
77+
exportconstscrollSpy=createScrollSpy({ rootMargin:"-50% 0px" });
78+
```
79+
80+
Then in any component file you can import the created store and use its`spy`
81+
method as a Svelte action to start spying on that element.
82+
83+
```svelte
84+
<script>
85+
import scrollSpy from "$lib/stores/scroll-spy";
86+
</script>
87+
88+
<section id="my-section" use:scrollSpy.spy><!-- ... --></section>
89+
<!-- Other sections... -->
90+
```
91+
92+
Element id is not required for spying. We gave an id to the element here only
93+
for scrolling with URL hash. Now, it is easy to make a navbar that highlights
94+
the current section.
95+
96+
```svelte
97+
<script>
98+
import scrollSpy from "$lib/stores/scroll-spy";
99+
import kebabCaseToCapWords from "$lib/utils.js";
100+
</script>
101+
102+
<nav>
103+
<ul>
104+
{#each $scrollSpy.targets as section (section)}
105+
<li class={$scrollSpy.lastActiveTarget === section ? "active" : ""}>
106+
<a href={"#" + section.id}>{kebabCaseToCapWords(section.id)}</a>
107+
</li>
108+
{/each}
109+
</ul>
110+
</nav>
111+
112+
<style>
113+
/* Styling... */
114+
</style>
115+
```
116+
117+
##Restricting What Can Be Spied On
118+
119+
You can augment Scroll Spy with additional properties and methods. For example,
120+
we can enforce that all elements being spied on must have an ID, and we can
121+
assign an arbitrary label to each element when they are registered.
122+
123+
To do this, we create our custom Svelte store by extending the functionality of
124+
Scroll Spy.
125+
126+
```javascript
127+
importcreateScrollSpyfrom'svelte-scrollspy';
128+
importtype {ActionReturn }from'svelte/action';
129+
130+
exportconstsectionSpy= (()=> {
131+
// use spy store's functionality
132+
constspy=createScrollSpy({ rootMargin:'-50% 0px' });
133+
134+
return {
135+
...spy,
136+
137+
// Overwrite spy() to add restriction on targets and apply custom attribute
138+
139+
/**
140+
* A svelte action to register an element as a section to spy on. The
141+
* element must have an id.
142+
*
143+
*@param [label] - an arbitrary label for the section. This action assigns
144+
* the label value to the element's `data-section-label` attribute. If no
145+
* label is given, the element's id is transformed into a capitalized
146+
* string and used as the label.
147+
*/
148+
spy(
149+
target: string|Element,
150+
label?: string,
151+
): ActionReturn<string, { id: string }> {
152+
constelem=
153+
targetinstanceofElement? target:document.getElementById(target);
154+
155+
if (!elem||!elem.id)return {};
156+
157+
label??=elem.id// kebab-case to Capitalized Words
158+
.replace(/-./g, (m)=>""+ m[1].toUpperCase())
159+
.replace(/^(.)/, (m)=>m.toUpperCase());
160+
161+
const {destroy }=spy.spy(elem);
162+
if (destroy)elem.setAttribute("data-section-label", label);
163+
return { destroy };
164+
},
165+
};
166+
})();
167+
```
168+
169+
We can then use our custom store to assign labels with Svelte action syntax.
170+
171+
```svelte
172+
<section id="my-section" use:sectionSpy.spy={"My Label"}><!--...--></section>
173+
<!-- Other sections...-->
174+
<footer>You're at the section: {$sectionSpy.activeLabel}</footer>
175+
```
176+
177+
## Adding Custom Properties to the Store
178+
179+
You can even add custom properties to the store.
180+
181+
```typescript
182+
export const sectionSpy = (() => {
183+
const spy = createSpy({ rootMargin: "-50% 0px" });
184+
185+
// extend spy store's properties
186+
interface SectionSpyextends Spy {
187+
/** The label of the active target (attribute: "data-section-label")*/
188+
activeLabel: string|null;
189+
190+
/**
191+
* The label of the last active section (attribute: "data-section-label")
192+
*/
193+
lastActiveLabel: string|null;
194+
}
195+
196+
functiongetSectionSpy(): SectionSpy {
197+
return {
198+
...get(spy),
199+
getactiveLabel() {
200+
returnthis.activeTarget?.getAttribute("data-section-label")??null;
201+
},
202+
getlastActiveLabel() {
203+
return (
204+
this.lastActiveTarget?.getAttribute("data-section-label")??null
205+
);
206+
},
207+
};
208+
}
209+
210+
// Create our own custom store
211+
const {subscribe,set }= writable<SectionSpy>(getSectionSpy());
212+
// Update our custom store whenever the spy store updates
213+
spy.subscribe(()=>set(getSectionSpy()));
214+
215+
return {
216+
...spy,
217+
subscribe,
218+
219+
// Implement our own spy() method to add restriction on spied targets and
220+
// add custom attribute to the targets
221+
spy(
222+
target: string|Element,
223+
label?: string,
224+
): ActionReturn<string, { id: string }> {
225+
constelem=
226+
targetinstanceofElement? target:document.getElementById(target);
227+
228+
if (!elem||!elem.id)return {};
229+
230+
label??=elem.id// kebab-case to Capitalized Words
231+
.replace(/-./g, (m)=>""+ m[1].toUpperCase())
232+
.replace(/^(.)/, (m)=>m.toUpperCase());
233+
234+
const {destroy }=spy.spy(elem);
235+
if (destroy)elem.setAttribute("data-section-label", label);
236+
return { destroy };
237+
},
238+
};
239+
})();
240+
```
241+
242+
# License
243+
244+
[MIT](./LICENSE)

‎bun.lockb‎

127 KB
Binary file not shown.

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp