Skip to content
This repository was archived by the owner on Sep 20, 2024. It is now read-only.

Commit fe21223

Browse files
Merge pull request #188 from Shyrro/feature/pinInput
feat(cpininput): add c pin input
2 parents 70a6fe7 + 2840953 commit fe21223

20 files changed

+541
-6
lines changed

components.d.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*
77
* This is a generated file. Do not edit it's contents.
88
*
9-
* This file was generated on 2022-09-12T04:00:56.880Z
9+
* This file was generated on 2022-10-06T19:08:38.068Z
1010
*/
1111

1212
import { ChakraProps, chakra } from "@chakra-ui/vue-system"
@@ -79,6 +79,7 @@ declare module "@vue/runtime-core" {
7979
CButtonGroup: typeof import("@chakra-ui/vue-next")["CButtonGroup"]
8080
CIconButton: typeof import("@chakra-ui/vue-next")["CIconButton"]
8181
CCheckbox: typeof import("@chakra-ui/vue-next")["CCheckbox"]
82+
CCheckboxGroup: typeof import("@chakra-ui/vue-next")["CCheckboxGroup"]
8283
CFocusLock: typeof import("@chakra-ui/vue-next")["CFocusLock"]
8384
CFormErrorIcon: typeof import("@chakra-ui/vue-next")["CFormErrorIcon"]
8485
CFormErrorMessage: typeof import("@chakra-ui/vue-next")["CFormErrorMessage"]
@@ -144,7 +145,11 @@ declare module "@vue/runtime-core" {
144145
CAnimatePresence: typeof import("@chakra-ui/vue-next")["CAnimatePresence"]
145146
CCollapse: typeof import("@chakra-ui/vue-next")["CCollapse"]
146147
CMotion: typeof import("@chakra-ui/vue-next")["CMotion"]
148+
CPinInput: typeof import("@chakra-ui/vue-next")["CPinInput"]
149+
CPinInputField: typeof import("@chakra-ui/vue-next")["CPinInputField"]
147150
CPortal: typeof import("@chakra-ui/vue-next")["CPortal"]
151+
CSkipNavContent: typeof import("@chakra-ui/vue-next")["CSkipNavContent"]
152+
CSkipNavLink: typeof import("@chakra-ui/vue-next")["CSkipNavLink"]
148153
CScrollLock: typeof import("@chakra-ui/vue-next")["CScrollLock"]
149154
CVisuallyHidden: typeof import("@chakra-ui/vue-next")["CVisuallyHidden"]
150155
CVisuallyHiddenInput: typeof import("@chakra-ui/vue-next")["CVisuallyHiddenInput"]

packages/c-pin-input/README.md

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# @chakra-ui/c-pin-input
2+
3+
The pin input component is similar to the input component but is optimized for entering sequences of digits quickly
4+
5+
## Installation
6+
7+
```sh
8+
yarn add @chakra-ui/c-pin-input
9+
# or
10+
npm i @chakra-ui/c-pin-input
11+
```
12+
13+
## Import
14+
15+
This package exports the following components :
16+
17+
- **CPinInput** : The wrapper for all the field elements.
18+
- **CPinInputField**: The field element.
19+
- **CPinInputClearButton**: The button to clear all the fields.
20+
21+
## Usage :
22+
23+
### Basic :
24+
25+
```html
26+
<c-pin-input :value="['1', '2']">
27+
<c-pin-input-field />
28+
<c-pin-input-field />
29+
<c-pin-input-field />
30+
<c-pin-input-field />
31+
</c-pin-input>
32+
```
33+
34+
### Event handling :
35+
36+
The `CPinInput` will trigger 3 events :
37+
38+
- `change` : Whenever the value changes. It also returns the new value of the input as an array in an object. `{ value: [] }`
39+
- `complete`: Trigger uppon completion of all the fields. Returns the value as an array, but also as a string. `{ value: [], valueAsString: '123' }`
40+
- `invalid`: Triggers if the input is invalid.
41+
42+
```html
43+
<c-pin-input @change="triggerChange" @complete="complete">
44+
<c-pin-input-field />
45+
<c-pin-input-field />
46+
<c-pin-input-field />
47+
<c-pin-input-field />
48+
</c-pin-input>
49+
```
50+
51+
### Props
52+
53+
`value`: Value of the input (Type: `Array`).
54+
`placeholder`: Changes the default placeholder (o)
55+
`blurOnComplete`: To blur the last input when the user completes the input.
56+
`type`: "alphanumeric" | "numeric"
57+
`otp`: To trigger smartphone OTP suggestion.
58+
`dir`: "rtl" | "ltr" . (Right-To-Left or Left-To-Right)
59+
`spacing`: Space between the fields.
60+
`mask` : Masks the value of the input by changing their type to "password"
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<template>
2+
<c-pin-input v-model="value">
3+
<c-pin-input-field />
4+
<c-pin-input-field />
5+
<c-pin-input-field />
6+
<c-pin-input-field />
7+
</c-pin-input>
8+
</template>
9+
<script setup>
10+
import { ref } from "vue"
11+
import { CPinInput, CPinInputField } from "../src"
12+
const value = ref(["1", "2"])
13+
</script>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export * as BaseCPinInput from "./base-c-pin-input.vue"
2+
export * as WithClearButton from "./with-clear-button.vue"
3+
export * as WithEvents from "./with-events.vue"
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<template>
2+
<c-pin-input>
3+
<c-pin-input-field />
4+
<c-pin-input-field />
5+
<c-pin-input-field />
6+
<c-pin-input-field />
7+
<c-pin-input-clear-button>Clear</c-pin-input-clear-button>
8+
</c-pin-input>
9+
</template>
10+
<script setup>
11+
import { CPinInput, CPinInputField, CPinInputClearButton } from "../src"
12+
</script>
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<template>
2+
<c-stack>
3+
<c-alert status="info" mb="3" v-if="alertVisible">
4+
<c-alert-title> Change </c-alert-title>
5+
<c-alert-description>
6+
CPinInput value changed, new value : {{ value }}
7+
</c-alert-description>
8+
</c-alert>
9+
<c-alert status="success" mb="3" v-if="completed">
10+
<c-alert-title> Success </c-alert-title>
11+
<c-alert-description>
12+
CPinInput value completed. Value : {{ value }}</c-alert-description
13+
>
14+
</c-alert>
15+
<chakra.p>An alert will show on change and on complete</chakra.p>
16+
<c-pin-input @change="triggerChange" @complete="complete">
17+
<c-pin-input-field />
18+
<c-pin-input-field />
19+
<c-pin-input-field />
20+
<c-pin-input-field />
21+
</c-pin-input>
22+
</c-stack>
23+
</template>
24+
<script setup>
25+
import { ref } from "vue"
26+
import { CPinInput, CPinInputField } from "../src"
27+
const alertVisible = ref(false)
28+
const completed = ref(false)
29+
const value = ref("")
30+
31+
const triggerChange = (result) => {
32+
console.log(result?.value)
33+
alertVisible.value = true
34+
const currentValue = result?.value?.filter((item) => item)
35+
if (currentValue?.length < 4) completed.value = false
36+
value.value = result?.value?.join("")
37+
}
38+
39+
const complete = (details) => {
40+
completed.value = true
41+
value.value = details.valueAsString
42+
}
43+
</script>

packages/c-pin-input/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './src'

packages/c-pin-input/package.json

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
{
2+
"name": "@chakra-ui/c-pin-input",
3+
"description": "Chakra UI Vue | The pin input component is similar to the input component but is optimized for entering sequences of digits quickly component",
4+
"version": "0.0.0-alpha.0",
5+
"main": "dist/chakra-ui-c-pin-input.cjs.js",
6+
"module": "dist/chakra-ui-c-pin-input.esm.js",
7+
"author": "Shyrro <[email protected]>",
8+
"homepage": "https://github.com/chakra-ui/chakra-ui-vue-next#readme",
9+
"license": "MIT",
10+
"files": [
11+
"dist"
12+
],
13+
"exports": {
14+
".": {
15+
"require": "./dist/chakra-ui-c-pin-input.cjs.js",
16+
"default": "./dist/chakra-ui-c-pin-input.esm.js"
17+
}
18+
},
19+
"repository": {
20+
"type": "git",
21+
"url": "git+https://github.com/chakra-ui/chakra-ui-vue-next.git"
22+
},
23+
"bugs": {
24+
"url": "https://github.com/chakra-ui/chakra-ui-vue-next/issues"
25+
},
26+
"scripts": {
27+
"clean": "rimraf dist"
28+
},
29+
"dependencies": {
30+
"@chakra-ui/vue-system": "0.1.0-alpha.10",
31+
"@chakra-ui/vue-utils": "0.1.0-alpha.10",
32+
"@zag-js/vue": "^0.1.14",
33+
"@zag-js/pin-input": "0.1.14",
34+
"@chakra-ui/c-input": "^0.0.0-alpha.5",
35+
"@chakra-ui/utils": "^2.0.3"
36+
},
37+
"devDependencies": {
38+
"vue": "^3.2.37"
39+
},
40+
"peerDependencies": {
41+
"vue": "^3.2.37"
42+
},
43+
"publishConfig": {
44+
"access": "public"
45+
}
46+
}
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
/**
2+
* Hey! Welcome to @chakra-ui/vue-next CPinInput
3+
*
4+
* The pin input component is similar to the input component but is optimized for entering sequences of digits quickly
5+
*
6+
* @see Docs https://next.vue.chakra-ui.com/c-pin-input
7+
* @see Source https://github.com/chakra-ui/chakra-ui-vue-next/blob/master/packages/c-pin-input/src/c-pin-input/c-pin-input.tsx
8+
* @see WAI-ARIA https://www.w3.org/TR/wai-aria-practices-1.2
9+
*/
10+
11+
import { h, defineComponent, computed, PropType, ComputedRef } from "vue"
12+
import {
13+
chakra,
14+
createStylesContext,
15+
useStyleConfig,
16+
} from "@chakra-ui/vue-system"
17+
import {
18+
createContext,
19+
getValidChildren,
20+
vueThemingProps,
21+
} from "@chakra-ui/vue-utils"
22+
import { CInput } from "@chakra-ui/c-input"
23+
import { connect } from "@zag-js/pin-input"
24+
import { PinInputProps, usePinInputMachine } from "./use-pin-input"
25+
26+
const [StylesProvider, useStyles] = createStylesContext("CPinInput")
27+
const [PinInputProvider, usePinInput] =
28+
createContext<ComputedRef<ReturnType<typeof connect>>>()
29+
30+
export { PinInputProvider, usePinInput }
31+
32+
export const CPinInputProps = {
33+
value: {
34+
type: Object as PropType<Array<string>>,
35+
default: [],
36+
},
37+
modelValue: {
38+
type: Object as PropType<Array<string>>,
39+
default: false,
40+
},
41+
id: {
42+
type: String,
43+
default: "0",
44+
},
45+
placeholder: {
46+
type: String,
47+
default: "o",
48+
},
49+
type: {
50+
type: String as PropType<"alphanumeric" | "numeric">,
51+
default: "numeric",
52+
},
53+
otp: {
54+
type: Boolean,
55+
default: false,
56+
},
57+
mask: {
58+
type: Boolean,
59+
default: false,
60+
},
61+
blurOnComplete: {
62+
type: Boolean,
63+
default: false,
64+
},
65+
dir: {
66+
type: String as PropType<"rtl" | "ltr">,
67+
default: "ltr",
68+
},
69+
spacing: {
70+
type: [String, Number],
71+
default: "0.75",
72+
},
73+
...vueThemingProps,
74+
}
75+
76+
export const CPinInput = defineComponent({
77+
name: "CPinInput",
78+
props: CPinInputProps,
79+
emits: ["change", "invalid", "complete", "update:modelValue"],
80+
setup(props, { slots, attrs, emit }) {
81+
const styles = useStyleConfig("PinInput", props)
82+
83+
const inputStyles = computed(() => ({
84+
...styles.value,
85+
mx: props.spacing,
86+
}))
87+
StylesProvider(inputStyles)
88+
89+
const api = usePinInputMachine(props as unknown as PinInputProps, emit)
90+
91+
PinInputProvider(api)
92+
93+
return () => (
94+
<chakra.div __label="pin-input" {...api.value.rootProps} {...attrs}>
95+
{() =>
96+
getValidChildren(slots).map((child, index) =>
97+
(child.type as any).name === "CPinInputField"
98+
? h(child, { index })
99+
: child
100+
)
101+
}
102+
</chakra.div>
103+
)
104+
},
105+
})
106+
107+
export const CPinInputField = defineComponent({
108+
name: "CPinInputField",
109+
props: {
110+
index: {
111+
type: Number,
112+
default: 0,
113+
},
114+
},
115+
setup(props, { attrs }) {
116+
const styles = useStyles()
117+
const api = usePinInput()
118+
119+
return () => (
120+
<CInput
121+
__label="pin-input-field"
122+
__css={styles.value}
123+
{...api.value.getInputProps({ index: props.index })}
124+
{...attrs}
125+
/>
126+
)
127+
},
128+
})
129+
130+
export const CPinInputClearButton = defineComponent({
131+
name: "CPinInputClearButton",
132+
setup(_, { slots, attrs }) {
133+
const api = usePinInput()
134+
return () => (
135+
<chakra.button
136+
__label="pin-input-clear-button"
137+
onClick={() => api.value.clearValue()}
138+
{...attrs}
139+
>
140+
{() => getValidChildren(slots)}
141+
</chakra.button>
142+
)
143+
},
144+
})

packages/c-pin-input/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from "./c-pin-input"

0 commit comments

Comments
 (0)