Skip to content

Commit 8093f5f

Browse files
feat: toast
1 parent d43bdb7 commit 8093f5f

File tree

11 files changed

+270
-17
lines changed

11 files changed

+270
-17
lines changed

packages/vue-primitives/eslint.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import antfu from '@antfu/eslint-config'
22

33
export default antfu({
44
rules: {
5-
'import/extensions': ['error', 'ignorePackages'],
5+
'import/extensions': ['error', 'always'],
66
},
77
ignores: [
88
'packages',

packages/vue-primitives/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
"@vitejs/plugin-vue-jsx": "^4.0.0",
2424
"@vue/shared": "^3.4.27",
2525
"@vue/test-utils": "^2.4.6",
26+
"@vueuse/core": "^10.10.0",
2627
"jsdom": "^24.1.0",
2728
"npm-run-all2": "^6.2.0",
2829
"vite": "^5.2.13",

packages/vue-primitives/src/App.vue

Lines changed: 60 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,85 @@
11
<script setup lang="ts">
2-
import { shallowRef } from 'vue'
3-
import Foo from '../src/Foo.vue'
4-
import Primitive from './primitive/Primitive.vue'
2+
import { computed, shallowRef, watchEffect } from 'vue'
3+
// import Foo from '../src/Foo.vue'
4+
// import Primitive from './primitive/Primitive.vue'
5+
import Toggle from './toggle/Toggle.vue'
56
6-
const a1 = shallowRef()
7-
const a2 = shallowRef()
8-
const a3 = shallowRef()
9-
const a4 = shallowRef()
7+
const open = shallowRef(true)
8+
const dis = shallowRef(true)
9+
function toggle() {
10+
open.value = !open.value
11+
}
12+
function toggleDis() {
13+
dis.value = !dis.value
14+
}
15+
16+
const on = computed(() => {
17+
if (!open.value) {
18+
return {}
19+
}
20+
21+
return {
22+
click: log,
23+
}
24+
})
25+
26+
// watchEffect(() => {
27+
// console.log('open', on.value)
28+
// })
1029
11-
function log() {
30+
// const a1 = shallowRef()
31+
// const a2 = shallowRef()
32+
// const a3 = shallowRef()
33+
// const a4 = shallowRef()
34+
35+
function log(event: Event) {
36+
if (dis.value) {
37+
event.preventDefault()
38+
}
1239
console.error('click')
1340
}
1441
</script>
1542

1643
<template>
1744
<div>
45+
<button @click="toggle">
46+
ON {{ open }}
47+
</button>
48+
<button @click="toggleDis">
49+
Dis {{ dis }}
50+
</button>
1851
<div>
19-
<Primitive ref="a1" class="baz" @click="log">
52+
<!-- <Primitive ref="a1" class="baz" @click="log">
2053
content
21-
</Primitive>
54+
</Primitive> -->
2255
</div>
2356
<div>
24-
<Primitive ref="a2" as="button" type="button" class="baz" @click="log">
57+
<!-- <Primitive ref="a2" as="button" type="button" class="baz" @click="log">
2558
content
26-
</Primitive>
59+
</Primitive> -->
2760
</div>
2861
<div>
29-
<Primitive ref="a3" as-child class="baz" @click="log">
62+
<!-- <Primitive ref="a3" as-child class="baz" @click="log">
3063
<button type="button">
3164
content
3265
</button>
33-
</Primitive>
66+
</Primitive> -->
3467
</div>
3568
<div>
36-
<Primitive ref="a4" :as="Foo" class="baz" @click="log">
69+
<!-- <Primitive ref="a4" :as="Foo" class="baz" @click="log">
3770
content
38-
</Primitive>
71+
</Primitive> -->
72+
</div>
73+
<div>
74+
<Toggle v-on="on">
75+
Toggle
76+
</Toggle>
77+
<!-- <button @click="log">
78+
Toggle
79+
</button> -->
80+
</div>
81+
<div>
82+
<pre>{{ on }}</pre>
3983
</div>
4084
</div>
4185
</template>
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import type { PrimitiveProps } from '../primitive/index.ts'
2+
3+
export const d = 1
4+
export interface ToggleProps extends PrimitiveProps {
5+
/**
6+
* The controlled state of the toggle.
7+
*/
8+
pressed?: boolean
9+
/**
10+
* The state of the toggle when initially rendered. Use `defaultPressed`
11+
* if you do not need to control the state of the toggle.
12+
* @defaultValue false
13+
*/
14+
defaultPressed?: boolean
15+
16+
disabled?: boolean
17+
}
18+
19+
// eslint-disable-next-line ts/consistent-type-definitions
20+
export type ToggleEmits = {
21+
/**
22+
* The callback that fires when the state of the toggle changes.
23+
*/
24+
'update:pressed': [value: boolean]
25+
26+
'click': [value: Event]
27+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<script setup lang="ts">
2+
import { Primitive } from '../primitive/index.ts'
3+
import { useControllableState } from '../utils/useControllableState.ts'
4+
import { composeEventHandlers } from '../utils/composeEventHandlers.ts'
5+
import type { ToggleEmits, ToggleProps } from './Toggle.ts'
6+
7+
defineOptions({
8+
name: 'Toggle',
9+
})
10+
11+
const props = withDefaults(defineProps<ToggleProps>(), {
12+
pressed: undefined,
13+
as: 'button',
14+
})
15+
16+
const emit = defineEmits<ToggleEmits>()
17+
18+
const pressed = useControllableState(props, 'pressed', emit, {
19+
defaultValue: props.defaultPressed,
20+
passive: (props.pressed === undefined) as false,
21+
})
22+
23+
const onClick = composeEventHandlers((e: Event) => {
24+
emit('click', e)
25+
}, () => {
26+
if (!props.disabled) {
27+
pressed.value = !pressed.value
28+
}
29+
})
30+
</script>
31+
32+
<template>
33+
<Primitive
34+
:as="as"
35+
:as-child="asChild"
36+
type="button"
37+
:aria-pressed="pressed"
38+
:data-state="pressed ? 'on' : 'off'"
39+
:data-disabled="$attrs.disabled ? '' : undefined"
40+
@click="onClick"
41+
>
42+
<slot :pressed="pressed" />
43+
</Primitive>
44+
</template>
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import type { PrimitiveProps } from '../primitive/index.ts'
2+
3+
export const d = 1
4+
export interface ToggleProps extends PrimitiveProps {
5+
/**
6+
* The controlled state of the toggle.
7+
*/
8+
pressed?: boolean
9+
/**
10+
* The state of the toggle when initially rendered. Use `defaultPressed`
11+
* if you do not need to control the state of the toggle.
12+
* @defaultValue false
13+
*/
14+
defaultPressed?: boolean
15+
16+
disabled?: boolean
17+
}
18+
19+
// eslint-disable-next-line ts/consistent-type-definitions
20+
export type ToggleEmits = {
21+
/**
22+
* The callback that fires when the state of the toggle changes.
23+
*/
24+
'update:pressed': [value: boolean]
25+
26+
'click': [value: Event]
27+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<script setup lang="ts">
2+
import { Primitive } from '../primitive/index.ts'
3+
import { useControllableState } from '../utils/useControllableState.ts'
4+
import { composeEventHandlers } from '../utils/composeEventHandlers.ts'
5+
import type { ToggleEmits, ToggleProps } from './Toggle.ts'
6+
7+
defineOptions({
8+
name: 'Toggle',
9+
})
10+
11+
const props = withDefaults(defineProps<ToggleProps>(), {
12+
pressed: undefined,
13+
as: 'button',
14+
})
15+
16+
const emit = defineEmits<ToggleEmits>()
17+
18+
const pressed = useControllableState(props, 'pressed', emit, {
19+
defaultValue: props.defaultPressed,
20+
passive: (props.pressed === undefined) as false,
21+
})
22+
23+
const onClick = composeEventHandlers((e: Event) => {
24+
emit('click', e)
25+
}, () => {
26+
if (!props.disabled) {
27+
pressed.value = !pressed.value
28+
}
29+
})
30+
</script>
31+
32+
<template>
33+
<Primitive
34+
:as="as"
35+
:as-child="asChild"
36+
type="button"
37+
:aria-pressed="pressed"
38+
:data-state="pressed ? 'on' : 'off'"
39+
:data-disabled="$attrs.disabled ? '' : undefined"
40+
@click="onClick"
41+
>
42+
<slot :pressed="pressed" />
43+
</Primitive>
44+
</template>
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export { default as Toggle } from './Toggle.vue'
2+
export type { ToggleProps, ToggleEmits } from './Toggle.ts'
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
export function composeEventHandlers<E>(
2+
originalEventHandler?: (event: E) => void,
3+
ourEventHandler?: (event: E) => void,
4+
{ checkForDefaultPrevented = true } = {},
5+
) {
6+
return function handleEvent(event: E) {
7+
originalEventHandler?.(event)
8+
9+
if (checkForDefaultPrevented === false || !((event as unknown) as Event).defaultPrevented)
10+
return ourEventHandler?.(event)
11+
}
12+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { useVModel as useControllableState } from '@vueuse/core'

0 commit comments

Comments
 (0)