drab 2.8.1 → 2.8.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +64 -4
- package/dist/components/Accordion.svelte +36 -42
- package/dist/components/Accordion.svelte.d.ts +37 -40
- package/dist/components/ContextMenu.svelte +10 -11
- package/dist/components/ContextMenu.svelte.d.ts +4 -4
- package/dist/components/DataTable.svelte +54 -88
- package/dist/components/DataTable.svelte.d.ts +37 -63
- package/dist/components/FullscreenButton.svelte +2 -2
- package/dist/components/FullscreenButton.svelte.d.ts +2 -2
- package/dist/components/Popover.svelte +16 -20
- package/dist/components/Popover.svelte.d.ts +13 -15
- package/dist/components/Sheet.svelte +9 -6
- package/dist/components/Sheet.svelte.d.ts +2 -2
- package/dist/components/Tabs.svelte +36 -49
- package/dist/components/Tabs.svelte.d.ts +33 -37
- package/dist/index.d.ts +6 -11
- package/dist/index.js +5 -5
- package/dist/util/transition.d.ts +2 -1
- package/dist/util/transition.js +2 -1
- package/package.json +18 -16
package/README.md
CHANGED
@@ -1,7 +1,67 @@
|
|
1
|
-
#
|
1
|
+
# An unstyled Svelte component library
|
2
2
|
|
3
|
-
|
3
|
+
- [GitHub](https://github.com/rossrobino/drab)
|
4
|
+
- [npm](https://www.npmjs.com/package/drab)
|
5
|
+
- [MIT License](https://github.com/rossrobino/drab/blob/main/LICENSE.md)
|
6
|
+
- One dependency - [Svelte](https://svelte.dev)
|
4
7
|
|
5
|
-
|
8
|
+
## About
|
6
9
|
|
7
|
-
|
10
|
+
**drab** focuses on providing JavaScript functionality where it's most useful, while leaving out components that can be easily created using HTML, such as a label or badge. Whenever possible, components are [progressively enhanced](/docs/ShareButton) or provide a fallback [noscript](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/noscript) message. Additionally, transitions are disabled for users who prefer reduced motion.
|
11
|
+
|
12
|
+
This library takes a more opinionated approach compared to some headless UI libraries by providing the basic HTML structure for every component, as well as default positioning for elements like the [sheet](/docs/Sheet) or [popover](/docs/Popover). However, these components can still be further customized using styles, [slots](https://svelte.dev/tutorial/slots), and [slot props](https://svelte.dev/tutorial/slot-props).
|
13
|
+
|
14
|
+
Components without styles can appear rather drab. You have the freedom to bring your own styles to these components! Using unstyled components allows you to selectively choose what you need, seamlessly integrate with existing designs, and avoid being tied to any specific library.
|
15
|
+
|
16
|
+
To style the components, you can make use of [global styles](https://joyofcode.xyz/global-styles-in-sveltekit). This process can be expedited by utilizing CSS frameworks like [TailwindCSS](https://tailwindcss.com/). TailwindCSS generates a global stylesheet based on the utility classes used in your project. Each component exports `class` and `id` props that can be leveraged for this purpose.
|
17
|
+
|
18
|
+
## Install
|
19
|
+
|
20
|
+
If you haven't used Svelte before, start with the [tutorial](https://svelte.dev/tutorial/basics).
|
21
|
+
|
22
|
+
- [SvelteKit](https://kit.svelte.dev)
|
23
|
+
- [Astro](https://docs.astro.build/en/tutorial/1-setup/2/)
|
24
|
+
- [Vite](https://vitejs.dev/guide/)
|
25
|
+
|
26
|
+
```bash
|
27
|
+
npm install -D drab
|
28
|
+
```
|
29
|
+
|
30
|
+
## Documentation
|
31
|
+
|
32
|
+
The library provides inline documentation for each component, allowing you to conveniently access the documentation by hovering over the component in your text editor after importing it. Additionally, every prop is documented using JSDoc and TypeScript. By hovering over a prop, you can retrieve its type and description.
|
33
|
+
|
34
|
+
These docs use the [TailwindCSS Typography plugin](https://tailwindcss.com/docs/typography-plugin) for base styles along with a few custom utility classes you can find [here](https://github.com/rossrobino/drab/blob/main/src/app.postcss). Styles on this site are based on [shadcn/ui](https://ui.shadcn.com/).
|
35
|
+
|
36
|
+
## Alternatives
|
37
|
+
|
38
|
+
If **drab** isn't what you are looking for, here are some other Svelte UI libraries to check out.
|
39
|
+
|
40
|
+
- [Skeleton](https://skeleton.dev)
|
41
|
+
- [Melt UI](https://www.melt-ui.com/)
|
42
|
+
- [shadcn-svelte](https://www.shadcn-svelte.com/)
|
43
|
+
- [Svelte-HeadlessUI](https://captaincodeman.github.io/svelte-headlessui/)
|
44
|
+
|
45
|
+
## Contributing
|
46
|
+
|
47
|
+
Find an bug or have an idea? Feel free to create an issue on [GitHub](https://github.com/rossrobino/drab).
|
48
|
+
|
49
|
+
Since this is an unstyled library, simple components like a badge that can be easily created with HTML and CSS are not included.
|
50
|
+
|
51
|
+
### Local Development
|
52
|
+
|
53
|
+
Contribute to the project, or use **drab** as a template for another component library. This library is built with SvelteKit, TypeScript, and npm. The package contents are located in `src/lib`, the site is contained within `src/routes` and `src/site`. The site is deployed to Vercel using `@sveltejs/adapter-vercel`. If you are using this project as a template, be sure to [update the adapter](https://kit.svelte.dev/docs/adapters) based on how you deploy.
|
54
|
+
|
55
|
+
#### Make changes
|
56
|
+
|
57
|
+
1. Clone the [repository](https://github.com/rossrobino/drab)
|
58
|
+
2. `npm install`
|
59
|
+
3. `npm run dev -- --open`
|
60
|
+
|
61
|
+
#### Add or edit a component
|
62
|
+
|
63
|
+
1. Add/edit the component in `src/lib/components/Component.svelte`, if you're adding a new one, copy and paste an existing one to get started with the conventions
|
64
|
+
2. Add/edit the example in `src/routes/docs/Component/+page.svelte`
|
65
|
+
3. Document the component with an `@component` comment, include a description, and the `@slots` available. Add a placeholder `@props` and `@example` to the comment. These sections will be generated based on the JSDoc comment above each prop and the example route created upon running `npm run doc`
|
66
|
+
4. If new, add the link to `src/site/components/NavItems.svelte`
|
67
|
+
5. Run `npm run build` to verify your build
|
@@ -3,20 +3,19 @@
|
|
3
3
|
|
4
4
|
### Accordion
|
5
5
|
|
6
|
-
Displays a list of `details` elements with helpful defaults and transitions.
|
6
|
+
Displays a list of `details` elements with helpful defaults and transitions.
|
7
7
|
|
8
8
|
@props
|
9
9
|
|
10
10
|
- `autoClose` - if `true`, other items close when a new one is opened
|
11
11
|
- `classContent` - class of all the `div`s that wrap the `content` slot
|
12
12
|
- `classDetails` - class of the `div` around each `details` element
|
13
|
-
- `
|
14
|
-
- `
|
15
|
-
- `classSummary` - class of all the `div`s that wrap the `summary` slot
|
13
|
+
- `classIcon` - class of the `div` that wraps the icon if displayed
|
14
|
+
- `classSummary` - class of all the `summary` elements
|
16
15
|
- `class`
|
16
|
+
- `data` - data to display in the accordion
|
17
17
|
- `icon`
|
18
18
|
- `id`
|
19
|
-
- `items` - array of `AccordionItem` elements
|
20
19
|
- `transition` - rotates the icon, slides the content, set to `false` to remove
|
21
20
|
|
22
21
|
@slots
|
@@ -31,18 +30,10 @@ Displays a list of `details` elements with helpful defaults and transitions. Use
|
|
31
30
|
|
32
31
|
```svelte
|
33
32
|
<script lang="ts">
|
34
|
-
import { Accordion } from "drab";
|
35
|
-
import
|
36
|
-
import { Chevron } from "../../site/svg/Chevron.svelte";
|
37
|
-
</script>
|
33
|
+
import { Accordion, type AccordionItem, FullscreenButton } from "drab";
|
34
|
+
import Chevron from "../../site/svg/Chevron.svelte";
|
38
35
|
|
39
|
-
|
40
|
-
icon={Chevron}
|
41
|
-
class="mb-12"
|
42
|
-
classDetails="border-b"
|
43
|
-
classHeader="flex gap-8 cursor-pointer items-center justify-between p-4 font-bold underline hover:decoration-dotted"
|
44
|
-
classContent="pb-4 px-4"
|
45
|
-
items={[
|
36
|
+
const data: AccordionItem[] = [
|
46
37
|
{ summary: "Is it accessible?", content: "Yes." },
|
47
38
|
{
|
48
39
|
summary: "Is it styled?",
|
@@ -52,35 +43,42 @@ Displays a list of `details` elements with helpful defaults and transitions. Use
|
|
52
43
|
summary: "Is it animated?",
|
53
44
|
content: "Yes, with the transition prop.",
|
54
45
|
},
|
46
|
+
{
|
47
|
+
summary: "Is it customizable?",
|
48
|
+
content: "Yes, customize with slots.",
|
49
|
+
class: "uppercase",
|
50
|
+
component: FullscreenButton,
|
51
|
+
},
|
55
52
|
{ summary: "Does it work without JavaScript?", content: "Yes." },
|
56
|
-
]
|
53
|
+
];
|
54
|
+
</script>
|
55
|
+
|
56
|
+
<Accordion
|
57
|
+
{data}
|
58
|
+
icon={Chevron}
|
59
|
+
class="mb-12"
|
60
|
+
classDetails="border-b"
|
61
|
+
classSummary="flex gap-8 cursor-pointer items-center justify-between p-4 font-bold underline hover:decoration-dotted"
|
62
|
+
classContent="pb-4 px-4"
|
57
63
|
/>
|
58
64
|
|
59
65
|
<Accordion
|
66
|
+
{data}
|
60
67
|
icon={Chevron}
|
61
68
|
classDetails="border-b"
|
62
|
-
|
69
|
+
classSummary="flex gap-8 cursor-pointer items-center justify-between p-4 font-bold underline hover:decoration-dotted"
|
63
70
|
classContent="pb-4 px-4"
|
64
71
|
autoClose={false}
|
65
|
-
items={[
|
66
|
-
{ summary: "Summary", content: "Content" },
|
67
|
-
{ summary: "Summary", content: "Content", data: { uppercase: true } },
|
68
|
-
{
|
69
|
-
summary: "Summary",
|
70
|
-
content: "Content",
|
71
|
-
data: { component: FullscreenButton },
|
72
|
-
},
|
73
|
-
]}
|
74
72
|
>
|
75
73
|
<svelte:fragment slot="summary" let:item let:index>
|
76
|
-
<span class
|
74
|
+
<span class={item.class ? item.class : ""}>
|
75
|
+
{index + 1}.
|
77
76
|
{item.summary}
|
78
|
-
{index + 1}
|
79
77
|
</span>
|
80
78
|
</svelte:fragment>
|
81
79
|
<svelte:fragment slot="content" let:item>
|
82
80
|
<span>{item.content}</span>
|
83
|
-
{#if item.
|
81
|
+
{#if item.component === FullscreenButton}
|
84
82
|
<div><svelte:component this={FullscreenButton} class="btn mt-4" /></div>
|
85
83
|
{/if}
|
86
84
|
</svelte:fragment>
|
@@ -97,23 +95,21 @@ import { duration } from "../util/transition";
|
|
97
95
|
let className = "";
|
98
96
|
export { className as class };
|
99
97
|
export let id = "";
|
100
|
-
export let
|
98
|
+
export let data;
|
101
99
|
export let icon = "";
|
102
100
|
export let classDetails = "";
|
103
|
-
export let classHeader = "";
|
104
101
|
export let classSummary = "";
|
105
102
|
export let classContent = "";
|
106
103
|
export let classIcon = "";
|
107
104
|
export let transition = { duration };
|
108
|
-
const cssDuration = transition ? transition.duration : 0;
|
109
105
|
export let autoClose = true;
|
110
106
|
let clientJs = false;
|
111
107
|
const toggleOpen = (i) => {
|
112
|
-
|
108
|
+
data[i].open = !data[i].open;
|
113
109
|
if (autoClose) {
|
114
|
-
for (let j = 0; j <
|
110
|
+
for (let j = 0; j < data.length; j++) {
|
115
111
|
if (j !== i)
|
116
|
-
|
112
|
+
data[j].open = false;
|
117
113
|
}
|
118
114
|
}
|
119
115
|
};
|
@@ -125,14 +121,14 @@ onMount(() => {
|
|
125
121
|
</script>
|
126
122
|
|
127
123
|
<div class={className} {id}>
|
128
|
-
{#each
|
124
|
+
{#each data as item, index}
|
129
125
|
<div class={classDetails}>
|
130
126
|
<details bind:open={item.open}>
|
131
127
|
<!-- svelte-ignore a11y-no-redundant-roles -->
|
132
128
|
<summary
|
133
129
|
role="button"
|
134
130
|
tabindex="0"
|
135
|
-
class={
|
131
|
+
class={classSummary}
|
136
132
|
on:click|preventDefault={() => toggleOpen(index)}
|
137
133
|
on:keydown={(e) => {
|
138
134
|
if (e.key === "Enter") {
|
@@ -141,16 +137,14 @@ onMount(() => {
|
|
141
137
|
}
|
142
138
|
}}
|
143
139
|
>
|
144
|
-
<
|
145
|
-
<slot name="summary" {item} {index}>{item.summary}</slot>
|
146
|
-
</div>
|
140
|
+
<slot name="summary" {item} {index}>{item.summary}</slot>
|
147
141
|
<slot name="icon" {item} {index}>
|
148
142
|
{#if icon}
|
149
143
|
<div
|
150
144
|
class={classIcon}
|
151
145
|
class:d-rotate-180={item.open}
|
152
146
|
class:d-transition={transition}
|
153
|
-
style="--duration: {
|
147
|
+
style="--duration: {transition ? transition.duration : 0}ms;"
|
154
148
|
>
|
155
149
|
{#if typeof icon !== "string"}
|
156
150
|
<svelte:component this={icon} />
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import { SvelteComponent } from "svelte";
|
2
|
-
export
|
2
|
+
export type AccordionItem = {
|
3
3
|
/** text summary of the item */
|
4
4
|
summary?: string;
|
5
5
|
/** text content of the item */
|
@@ -7,21 +7,20 @@ export interface AccordionItem<T = any> {
|
|
7
7
|
/** controls whether the content is displayed */
|
8
8
|
open?: boolean;
|
9
9
|
/** any data to pass back to the parent */
|
10
|
-
|
11
|
-
}
|
10
|
+
[key: string | number]: any;
|
11
|
+
};
|
12
12
|
import { type ComponentType } from "svelte";
|
13
13
|
import { type SlideParams } from "svelte/transition";
|
14
14
|
declare const __propDef: {
|
15
15
|
props: {
|
16
16
|
class?: string | undefined;
|
17
17
|
id?: string | undefined;
|
18
|
-
/**
|
18
|
+
/** data to display in the accordion */ data: AccordionItem[];
|
19
19
|
icon?: string | ComponentType | undefined;
|
20
20
|
/** class of the `div` around each `details` element */ classDetails?: string | undefined;
|
21
|
-
/** class of all the `summary` elements */
|
22
|
-
/** class of all the `div`s that wrap the `summary` slot */ classSummary?: string | undefined;
|
21
|
+
/** class of all the `summary` elements */ classSummary?: string | undefined;
|
23
22
|
/** class of all the `div`s that wrap the `content` slot */ classContent?: string | undefined;
|
24
|
-
/** class of the `div` that
|
23
|
+
/** class of the `div` that wraps the icon if displayed */ classIcon?: string | undefined;
|
25
24
|
/** rotates the icon, slides the content, set to `false` to remove */ transition?: false | SlideParams | undefined;
|
26
25
|
/** if `true`, other items close when a new one is opened */ autoClose?: boolean | undefined;
|
27
26
|
};
|
@@ -30,15 +29,15 @@ declare const __propDef: {
|
|
30
29
|
};
|
31
30
|
slots: {
|
32
31
|
summary: {
|
33
|
-
item: AccordionItem
|
32
|
+
item: AccordionItem;
|
34
33
|
index: any;
|
35
34
|
};
|
36
35
|
icon: {
|
37
|
-
item: AccordionItem
|
36
|
+
item: AccordionItem;
|
38
37
|
index: any;
|
39
38
|
};
|
40
39
|
content: {
|
41
|
-
item: AccordionItem
|
40
|
+
item: AccordionItem;
|
42
41
|
index: any;
|
43
42
|
};
|
44
43
|
};
|
@@ -49,20 +48,19 @@ export type AccordionSlots = typeof __propDef.slots;
|
|
49
48
|
/**
|
50
49
|
* ### Accordion
|
51
50
|
*
|
52
|
-
* Displays a list of `details` elements with helpful defaults and transitions.
|
51
|
+
* Displays a list of `details` elements with helpful defaults and transitions.
|
53
52
|
*
|
54
53
|
* @props
|
55
54
|
*
|
56
55
|
* - `autoClose` - if `true`, other items close when a new one is opened
|
57
56
|
* - `classContent` - class of all the `div`s that wrap the `content` slot
|
58
57
|
* - `classDetails` - class of the `div` around each `details` element
|
59
|
-
* - `
|
60
|
-
* - `
|
61
|
-
* - `classSummary` - class of all the `div`s that wrap the `summary` slot
|
58
|
+
* - `classIcon` - class of the `div` that wraps the icon if displayed
|
59
|
+
* - `classSummary` - class of all the `summary` elements
|
62
60
|
* - `class`
|
61
|
+
* - `data` - data to display in the accordion
|
63
62
|
* - `icon`
|
64
63
|
* - `id`
|
65
|
-
* - `items` - array of `AccordionItem` elements
|
66
64
|
* - `transition` - rotates the icon, slides the content, set to `false` to remove
|
67
65
|
*
|
68
66
|
* @slots
|
@@ -77,18 +75,10 @@ export type AccordionSlots = typeof __propDef.slots;
|
|
77
75
|
*
|
78
76
|
* ```svelte
|
79
77
|
* <script lang="ts">
|
80
|
-
* import { Accordion } from "drab";
|
81
|
-
* import
|
82
|
-
* import { Chevron } from "../../site/svg/Chevron.svelte";
|
83
|
-
* </script>
|
78
|
+
* import { Accordion, type AccordionItem, FullscreenButton } from "drab";
|
79
|
+
* import Chevron from "../../site/svg/Chevron.svelte";
|
84
80
|
*
|
85
|
-
*
|
86
|
-
* icon={Chevron}
|
87
|
-
* class="mb-12"
|
88
|
-
* classDetails="border-b"
|
89
|
-
* classHeader="flex gap-8 cursor-pointer items-center justify-between p-4 font-bold underline hover:decoration-dotted"
|
90
|
-
* classContent="pb-4 px-4"
|
91
|
-
* items={[
|
81
|
+
* const data: AccordionItem[] = [
|
92
82
|
* { summary: "Is it accessible?", content: "Yes." },
|
93
83
|
* {
|
94
84
|
* summary: "Is it styled?",
|
@@ -98,35 +88,42 @@ export type AccordionSlots = typeof __propDef.slots;
|
|
98
88
|
* summary: "Is it animated?",
|
99
89
|
* content: "Yes, with the transition prop.",
|
100
90
|
* },
|
91
|
+
* {
|
92
|
+
* summary: "Is it customizable?",
|
93
|
+
* content: "Yes, customize with slots.",
|
94
|
+
* class: "uppercase",
|
95
|
+
* component: FullscreenButton,
|
96
|
+
* },
|
101
97
|
* { summary: "Does it work without JavaScript?", content: "Yes." },
|
102
|
-
* ]
|
98
|
+
* ];
|
99
|
+
* </script>
|
100
|
+
*
|
101
|
+
* <Accordion
|
102
|
+
* {data}
|
103
|
+
* icon={Chevron}
|
104
|
+
* class="mb-12"
|
105
|
+
* classDetails="border-b"
|
106
|
+
* classSummary="flex gap-8 cursor-pointer items-center justify-between p-4 font-bold underline hover:decoration-dotted"
|
107
|
+
* classContent="pb-4 px-4"
|
103
108
|
* />
|
104
109
|
*
|
105
110
|
* <Accordion
|
111
|
+
* {data}
|
106
112
|
* icon={Chevron}
|
107
113
|
* classDetails="border-b"
|
108
|
-
*
|
114
|
+
* classSummary="flex gap-8 cursor-pointer items-center justify-between p-4 font-bold underline hover:decoration-dotted"
|
109
115
|
* classContent="pb-4 px-4"
|
110
116
|
* autoClose={false}
|
111
|
-
* items={[
|
112
|
-
* { summary: "Summary", content: "Content" },
|
113
|
-
* { summary: "Summary", content: "Content", data: { uppercase: true } },
|
114
|
-
* {
|
115
|
-
* summary: "Summary",
|
116
|
-
* content: "Content",
|
117
|
-
* data: { component: FullscreenButton },
|
118
|
-
* },
|
119
|
-
* ]}
|
120
117
|
* >
|
121
118
|
* <svelte:fragment slot="summary" let:item let:index>
|
122
|
-
* <span class
|
119
|
+
* <span class={item.class ? item.class : ""}>
|
120
|
+
* {index + 1}.
|
123
121
|
* {item.summary}
|
124
|
-
* {index + 1}
|
125
122
|
* </span>
|
126
123
|
* </svelte:fragment>
|
127
124
|
* <svelte:fragment slot="content" let:item>
|
128
125
|
* <span>{item.content}</span>
|
129
|
-
* {#if item.
|
126
|
+
* {#if item.component === FullscreenButton}
|
130
127
|
* <div><svelte:component this={FullscreenButton} class="btn mt-4" /></div>
|
131
128
|
* {/if}
|
132
129
|
* </svelte:fragment>
|
@@ -11,7 +11,7 @@ Displays when the `target` element is right clicked, or long pressed on mobile.
|
|
11
11
|
- `display` - shows / hides the menu
|
12
12
|
- `id`
|
13
13
|
- `target` - target element to right click, defaults to the parent element
|
14
|
-
- `transition` -
|
14
|
+
- `transition` - scales the menu, set to `false` to disable
|
15
15
|
|
16
16
|
@slots
|
17
17
|
|
@@ -40,7 +40,7 @@ Displays when the `target` element is right clicked, or long pressed on mobile.
|
|
40
40
|
</ContextMenu>
|
41
41
|
</div>
|
42
42
|
|
43
|
-
<button class="btn" bind:this={target}>Target Right Click</button>
|
43
|
+
<button type="button" class="btn" bind:this={target}>Target Right Click</button>
|
44
44
|
<ContextMenu {target}>
|
45
45
|
<div class="flex w-48 flex-col gap-2 rounded border bg-white p-2 shadow">
|
46
46
|
<div class="font-bold">Context Menu</div>
|
@@ -53,15 +53,15 @@ Displays when the `target` element is right clicked, or long pressed on mobile.
|
|
53
53
|
-->
|
54
54
|
|
55
55
|
<script>import { onMount, tick } from "svelte";
|
56
|
-
import {
|
57
|
-
import { duration } from "../util/transition";
|
56
|
+
import { scale } from "svelte/transition";
|
57
|
+
import { duration, start } from "../util/transition";
|
58
58
|
import { prefersReducedMotion } from "../util/accessibility";
|
59
59
|
import { delay } from "../util/delay";
|
60
60
|
let className = "";
|
61
61
|
export { className as class };
|
62
62
|
export let id = "";
|
63
63
|
export let display = false;
|
64
|
-
export let transition = { duration };
|
64
|
+
export let transition = { duration, start };
|
65
65
|
export let target = null;
|
66
66
|
let contextMenu;
|
67
67
|
let base;
|
@@ -102,11 +102,10 @@ const onTouchStart = (e) => {
|
|
102
102
|
const onTouchEnd = () => {
|
103
103
|
clearTimeout(timer);
|
104
104
|
};
|
105
|
-
onMount(() => {
|
106
|
-
if (prefersReducedMotion())
|
107
|
-
|
108
|
-
|
109
|
-
}
|
105
|
+
onMount(async () => {
|
106
|
+
if (prefersReducedMotion())
|
107
|
+
transition = false;
|
108
|
+
await tick();
|
110
109
|
if (!target) {
|
111
110
|
target = base.parentElement;
|
112
111
|
}
|
@@ -131,7 +130,7 @@ onMount(() => {
|
|
131
130
|
bind:this={contextMenu}
|
132
131
|
style:top="{coordinates.y}px"
|
133
132
|
style:left="{coordinates.x}px"
|
134
|
-
transition:
|
133
|
+
transition:scale={transition ? transition : { duration: 0 }}
|
135
134
|
>
|
136
135
|
<slot>Context Menu</slot>
|
137
136
|
</div>
|
@@ -1,11 +1,11 @@
|
|
1
1
|
import { SvelteComponent } from "svelte";
|
2
|
-
import { type
|
2
|
+
import { type ScaleParams } from "svelte/transition";
|
3
3
|
declare const __propDef: {
|
4
4
|
props: {
|
5
5
|
class?: string | undefined;
|
6
6
|
id?: string | undefined;
|
7
7
|
/** shows / hides the menu */ display?: boolean | undefined;
|
8
|
-
/**
|
8
|
+
/** scales the menu, set to `false` to disable */ transition?: false | ScaleParams | undefined;
|
9
9
|
/** target element to right click, defaults to the parent element */ target?: HTMLElement | null | undefined;
|
10
10
|
};
|
11
11
|
events: {
|
@@ -29,7 +29,7 @@ export type ContextMenuSlots = typeof __propDef.slots;
|
|
29
29
|
* - `display` - shows / hides the menu
|
30
30
|
* - `id`
|
31
31
|
* - `target` - target element to right click, defaults to the parent element
|
32
|
-
* - `transition` -
|
32
|
+
* - `transition` - scales the menu, set to `false` to disable
|
33
33
|
*
|
34
34
|
* @slots
|
35
35
|
*
|
@@ -58,7 +58,7 @@ export type ContextMenuSlots = typeof __propDef.slots;
|
|
58
58
|
* </ContextMenu>
|
59
59
|
* </div>
|
60
60
|
*
|
61
|
-
* <button class="btn" bind:this={target}>Target Right Click</button>
|
61
|
+
* <button type="button" class="btn" bind:this={target}>Target Right Click</button>
|
62
62
|
* <ContextMenu {target}>
|
63
63
|
* <div class="flex w-48 flex-col gap-2 rounded border bg-white p-2 shadow">
|
64
64
|
* <div class="font-bold">Context Menu</div>
|