This repository was archived by the owner on Sep 20, 2024. It is now read-only.
File tree Expand file tree Collapse file tree 3 files changed +103
-0
lines changed Expand file tree Collapse file tree 3 files changed +103
-0
lines changed Original file line number Diff line number Diff line change @@ -9,6 +9,7 @@ export * from './tabbable'
9
9
export * from './assertion'
10
10
export * from 'css-box-model'
11
11
export * from './responsive'
12
+ export * from './vue-helpers'
12
13
13
14
export function orient ( options : {
14
15
orientation ?: 'vertical' | 'horizontal'
Original file line number Diff line number Diff line change
1
+ import { inject , InjectionKey , provide } from 'vue'
2
+
3
+ export interface CreateContextOptions {
4
+ /**
5
+ * If `true`, Vue will throw if context is `null` or `undefined`
6
+ * In some cases, you might want to support nested context, so you can set it to `false`
7
+ */
8
+ strict ?: boolean
9
+ /**
10
+ * Error message to throw if the context is `undefined`
11
+ */
12
+ errorMessage ?: string
13
+ /**
14
+ * The display name of the context
15
+ */
16
+ name ?: string
17
+ }
18
+
19
+ type CreateContextReturn < T > = [ ( opts : T ) => void , ( ) => T ]
20
+
21
+ /**
22
+ * Creates a named context, provider, and hook.
23
+ *
24
+ * @param options create context options
25
+ */
26
+ export function createContext < ContextType > ( options : CreateContextOptions = { } ) {
27
+ const {
28
+ strict = true ,
29
+ errorMessage = 'useContext: `context` is undefined. Seems you forgot to wrap component within the Provider' ,
30
+ name,
31
+ } = options
32
+
33
+ let contextSymbol = Symbol ( `${ name } Symbol` ) as InjectionKey < ContextType >
34
+
35
+ function Provider ( payload : ContextType ) {
36
+ provide < ContextType > ( contextSymbol , payload )
37
+ }
38
+
39
+ function useContext ( ) {
40
+ const context = inject ( contextSymbol , null )
41
+
42
+ if ( ! context && strict ) {
43
+ throw new Error ( errorMessage )
44
+ }
45
+
46
+ return context
47
+ }
48
+
49
+ return [ Provider , useContext ] as CreateContextReturn < ContextType >
50
+ }
Original file line number Diff line number Diff line change
1
+ import { createContext } from '@chakra-ui/vue-utils/src'
2
+ import { defineComponent , h } from 'vue'
3
+ import { render } from '../../test-utils/src'
4
+
5
+ interface ExampleContext {
6
+ example : string
7
+ }
8
+
9
+ const [ ExampleProvider , useExampleContext ] = createContext < ExampleContext > ( {
10
+ name : 'ExampleContext' ,
11
+ errorMessage :
12
+ 'useContext: `context` is undefined. Seems you forgot to wrap component within the Provider' ,
13
+ } )
14
+
15
+ const ExampleComponent = defineComponent ( {
16
+ setup ( ) {
17
+ const { example } = useExampleContext ( )
18
+ return ( ) => h ( 'div' , `injected: ${ example } ` )
19
+ } ,
20
+ } )
21
+
22
+ beforeEach ( ( ) => {
23
+ // disable console.warn
24
+ jest . spyOn ( console , 'warn' ) . mockImplementation ( ( ) => { } )
25
+ } )
26
+
27
+ it ( 'should provide and inject a context' , ( ) => {
28
+ const { getByText } = render ( {
29
+ components : { ExampleComponent } ,
30
+ template : `
31
+ <div>
32
+ <ExampleComponent />
33
+ </div>
34
+ ` ,
35
+ setup ( ) {
36
+ ExampleProvider ( { example : 'works' } )
37
+ } ,
38
+ } )
39
+ getByText ( / w o r k s / )
40
+ } )
41
+
42
+ it ( 'should throw an error when there is no provider' , ( ) => {
43
+ expect ( ( ) => {
44
+ render ( {
45
+ components : { ExampleComponent } ,
46
+ template : `<ExampleComponent />` ,
47
+ setup ( ) { } ,
48
+ } )
49
+ } ) . toThrowError (
50
+ 'useContext: `context` is undefined. Seems you forgot to wrap component within the Provider'
51
+ )
52
+ } )
You can’t perform that action at this time.
0 commit comments