react-french-ssn 1.3.0

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 ADDED
@@ -0,0 +1,192 @@
1
+ # react-french-ssn
2
+
3
+ <div align="center">
4
+
5
+ **React component for French Social Security Numbers (NIR)**
6
+
7
+ [![npm version](https://badge.fury.io/js/react-french-ssn.svg)](https://www.npmjs.com/package/react-french-ssn)
8
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
9
+ [![TypeScript](https://img.shields.io/badge/TypeScript-007ACC?logo=typescript&logoColor=white)](https://www.typescriptlang.org/)
10
+
11
+ </div>
12
+
13
+ ## 🚀 Overview
14
+
15
+ `react-french-ssn` is a React library specialized in handling French Social Security Numbers (NIR - Numéro d'Identification au Répertoire). It provides a `SocialSecurityInput` component with automatic formatting, validation, and advanced features, built with TypeScript for an optimal development experience.
16
+
17
+ ## ✨ Features
18
+
19
+ - 🔢 **Automatic Formatting** - Guided input by Social Security Number segments
20
+ - ✅ **Built-in Validation** - Automatic control key verification
21
+ - 📋 **Copy Button** - Easy copying of the complete number to clipboard
22
+ - 🎯 **TypeScript First** - Fully typed with complete type definitions
23
+ - 🎨 **Modular Styling** - CSS Modules for encapsulated and customizable styling
24
+ - 🌙 **Dark Mode Support** - Automatic dark mode detection
25
+ - 🧪 **Complete Testing** - Jest and React Testing Library with high coverage
26
+ - 📚 **Interactive Documentation** - Storybook to explore the component
27
+ - 🔧 **Code Quality** - ESLint, Prettier, and strict TypeScript configuration
28
+
29
+ ## 📦 Installation
30
+
31
+ ```bash
32
+ npm install react-french-ssn
33
+ ```
34
+
35
+ ```bash
36
+ yarn add react-french-ssn
37
+ ```
38
+
39
+ ```bash
40
+ pnpm add react-french-ssn
41
+ ```
42
+
43
+ ## 🎯 Quick Start
44
+
45
+ ```tsx
46
+ import React from 'react';
47
+ import { SocialSecurityInput } from 'react-french-ssn';
48
+
49
+ function App() {
50
+ return (
51
+ <SocialSecurityInput
52
+ label="Social Security Number"
53
+ placeholder="269054958815780"
54
+ onChange={(value) => console.log(value)}
55
+ />
56
+ );
57
+ }
58
+ ```
59
+
60
+ ## 🧩 Main Component
61
+
62
+ ### SocialSecurityInput
63
+
64
+ The main component of this library, specifically designed for French Social Security Number input. It automatically divides input into logical segments and calculates the control key.
65
+
66
+ ```tsx
67
+ import { SocialSecurityInput } from 'react-french-ssn';
68
+
69
+ <SocialSecurityInput
70
+ label="Social Security Number"
71
+ placeholder="269054958815780"
72
+ value={ssnValue}
73
+ onChange={handleSSNChange}
74
+ error={errorMessage}
75
+ showCopyButton={true}
76
+ disabled={false}
77
+ className="custom-class"
78
+ />
79
+ ```
80
+
81
+ #### Props
82
+
83
+ | Prop | Type | Default | Description |
84
+ |------|------|---------|-------------|
85
+ | `label` | `string` | `'Social Security Number'` | Field label |
86
+ | `placeholder` | `string` | `'269054958815780'` | Placeholder text |
87
+ | `value` | `string` | - | Controlled value |
88
+ | `onChange` | `(value: string) => void` | - | Change callback |
89
+ | `error` | `string` | - | Error message |
90
+ | `disabled` | `boolean` | `false` | Disabled state |
91
+ | `className` | `string` | `''` | Custom CSS classes |
92
+ | `showCopyButton` | `boolean` | `false` | Show copy button |
93
+
94
+ ### Optional ThemeProvider
95
+
96
+ Optional context provider for theme configuration (not required for basic usage).
97
+
98
+ ```tsx
99
+ import { ThemeProvider, SocialSecurityInput } from 'react-french-ssn';
100
+
101
+ <ThemeProvider theme={{ colors: { primary: '#custom-color' } }}>
102
+ <SocialSecurityInput />
103
+ </ThemeProvider>
104
+ ```
105
+
106
+ ## 🎣 Custom Hook
107
+
108
+ ### useSocialSecurityInput
109
+
110
+ Internal hook that handles the formatting and validation logic for Social Security Numbers.
111
+
112
+ ```tsx
113
+ import { useSocialSecurityInput } from 'react-french-ssn';
114
+
115
+ const { values, handlers, placeholders } = useSocialSecurityInput({
116
+ onChange: handleChange,
117
+ placeholder: '269054958815780',
118
+ value: currentValue,
119
+ });
120
+ ```
121
+
122
+ ## 🛠️ Utilities
123
+
124
+ ### Global Configuration
125
+
126
+ ```tsx
127
+ import { setGlobalConfig, getGlobalConfig, resetGlobalConfig } from 'react-french-ssn';
128
+
129
+ setGlobalConfig({
130
+ theme: 'light',
131
+ locale: 'fr-FR',
132
+ });
133
+
134
+ const config = getGlobalConfig();
135
+ ```
136
+
137
+ ### CSS Variables
138
+
139
+ ```tsx
140
+ import { getCSSVariable, createCSSVariables } from 'react-french-ssn';
141
+
142
+ const primaryColor = getCSSVariable('--primary-color');
143
+ const variables = createCSSVariables({
144
+ '--primary-color': '#007bff',
145
+ '--secondary-color': '#6c757d'
146
+ });
147
+ ```
148
+
149
+ ## 🎯 Use Cases
150
+
151
+ This component is perfect for:
152
+
153
+ - **Administrative Forms** - Social Security Number input
154
+ - **HR Applications** - Employee data management
155
+ - **Healthcare Systems** - Patient identification
156
+ - **Government Applications** - Public services online
157
+
158
+ ## 📝 TypeScript Support
159
+
160
+ This library is fully built with TypeScript and provides complete type definitions.
161
+
162
+ ```tsx
163
+ import type {
164
+ SocialSecurityInputProps,
165
+ GlobalConfig,
166
+ ThemeConfig
167
+ } from 'react-french-ssn';
168
+
169
+ const props: SocialSecurityInputProps = {
170
+ label: 'Social Security Number',
171
+ onChange: (value: string) => console.log(value)
172
+ };
173
+ ```
174
+
175
+
176
+
177
+ ## 📄 License
178
+
179
+ MIT © JatoCool Company
180
+
181
+ ## 🔗 Links
182
+
183
+ - [NPM Package](https://www.npmjs.com/package/react-french-ssn)
184
+
185
+ ---
186
+
187
+ <div align="center">
188
+
189
+ **Specialized in French Social Security Numbers**
190
+ **Built with ❤️ by JatoCool Company**
191
+
192
+ </div>
@@ -0,0 +1,5 @@
1
+ import React from 'react';
2
+ import { SocialSecurityInputProps } from '../../types';
3
+ declare const SocialSecurityInput: React.FC<SocialSecurityInputProps>;
4
+ export default SocialSecurityInput;
5
+ //# sourceMappingURL=SocialSecurityInput.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SocialSecurityInput.d.ts","sourceRoot":"","sources":["../../../src/components/SocialSecurityInput/SocialSecurityInput.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AACxC,OAAO,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAIvD,QAAA,MAAM,mBAAmB,EAAE,KAAK,CAAC,EAAE,CAAC,wBAAwB,CAmK3D,CAAC;AAEF,eAAe,mBAAmB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { default } from './SocialSecurityInput';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/SocialSecurityInput/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC"}
@@ -0,0 +1,56 @@
1
+ interface UseSocialSecurityInputProps {
2
+ onChange?: (value: string) => void;
3
+ placeholder?: string;
4
+ value?: string;
5
+ }
6
+ interface SocialSecurityState {
7
+ sex: string;
8
+ year: string;
9
+ month: string;
10
+ department: string;
11
+ insee: string;
12
+ order: string;
13
+ controlKey: string;
14
+ error: string;
15
+ }
16
+ export declare const useSocialSecurityInput: ({ onChange, placeholder, value }: UseSocialSecurityInputProps) => {
17
+ values: SocialSecurityState;
18
+ handlers: {
19
+ sex: {
20
+ onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
21
+ onPaste: (e: React.ClipboardEvent<HTMLInputElement>) => void;
22
+ };
23
+ year: {
24
+ onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
25
+ onKeyDown: (e: React.KeyboardEvent<HTMLInputElement>) => void;
26
+ };
27
+ month: {
28
+ onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
29
+ onKeyDown: (e: React.KeyboardEvent<HTMLInputElement>) => void;
30
+ };
31
+ department: {
32
+ onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
33
+ onKeyDown: (e: React.KeyboardEvent<HTMLInputElement>) => void;
34
+ };
35
+ insee: {
36
+ onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
37
+ onKeyDown: (e: React.KeyboardEvent<HTMLInputElement>) => void;
38
+ };
39
+ order: {
40
+ onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
41
+ onKeyDown: (e: React.KeyboardEvent<HTMLInputElement>) => void;
42
+ };
43
+ };
44
+ parseSocialSecurityNumber: (fullNumber: string) => void;
45
+ placeholders: {
46
+ sex: string;
47
+ year: string;
48
+ month: string;
49
+ department: string;
50
+ insee: string;
51
+ order: string;
52
+ controlKey: string;
53
+ };
54
+ };
55
+ export {};
56
+ //# sourceMappingURL=useSocialSecurityInput.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useSocialSecurityInput.d.ts","sourceRoot":"","sources":["../../../src/components/SocialSecurityInput/useSocialSecurityInput.ts"],"names":[],"mappings":"AAEA,UAAU,2BAA2B;IACnC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,mBAAmB;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,eAAO,MAAM,sBAAsB,GAAI,kCAAsD,2BAA2B;;;;0BAsJpG,KAAK,CAAC,WAAW,CAAC,gBAAgB,CAAC;yBAUpC,KAAK,CAAC,cAAc,CAAC,gBAAgB,CAAC;;;0BAarC,KAAK,CAAC,WAAW,CAAC,gBAAgB,CAAC;2BAWlC,KAAK,CAAC,aAAa,CAAC,gBAAgB,CAAC;;;0BAStC,KAAK,CAAC,WAAW,CAAC,gBAAgB,CAAC;2BAWlC,KAAK,CAAC,aAAa,CAAC,gBAAgB,CAAC;;;0BAStC,KAAK,CAAC,WAAW,CAAC,gBAAgB,CAAC;2BAkBlC,KAAK,CAAC,aAAa,CAAC,gBAAgB,CAAC;;;0BAStC,KAAK,CAAC,WAAW,CAAC,gBAAgB,CAAC;2BAWlC,KAAK,CAAC,aAAa,CAAC,gBAAgB,CAAC;;;0BAStC,KAAK,CAAC,WAAW,CAAC,gBAAgB,CAAC;2BAOlC,KAAK,CAAC,aAAa,CAAC,gBAAgB,CAAC;;;4CAvJT,MAAM;;;;;;;;;;CAsKtD,CAAC"}
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ import { ThemeConfig } from '../config';
3
+ interface ThemeProviderProps {
4
+ children: React.ReactNode;
5
+ theme?: Partial<ThemeConfig>;
6
+ }
7
+ export declare const ThemeProvider: React.FC<ThemeProviderProps>;
8
+ export {};
9
+ //# sourceMappingURL=ThemeProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ThemeProvider.d.ts","sourceRoot":"","sources":["../../src/components/ThemeProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoB,MAAM,OAAO,CAAC;AAEzC,OAAO,EAAoC,WAAW,EAAE,MAAM,WAAW,CAAC;AAE1E,UAAU,kBAAkB;IAC1B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,KAAK,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;CAC9B;AAED,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAiCtD,CAAC"}
@@ -0,0 +1,83 @@
1
+ export interface ThemeConfig {
2
+ colors: {
3
+ primary: string;
4
+ secondary: string;
5
+ success: string;
6
+ warning: string;
7
+ error: string;
8
+ info: string;
9
+ background: string;
10
+ surface: string;
11
+ text: {
12
+ primary: string;
13
+ secondary: string;
14
+ disabled: string;
15
+ };
16
+ border: {
17
+ default: string;
18
+ focus: string;
19
+ error: string;
20
+ };
21
+ };
22
+ spacing: {
23
+ xs: string;
24
+ sm: string;
25
+ md: string;
26
+ lg: string;
27
+ xl: string;
28
+ };
29
+ typography: {
30
+ fontFamily: string;
31
+ fontSize: {
32
+ xs: string;
33
+ sm: string;
34
+ base: string;
35
+ lg: string;
36
+ xl: string;
37
+ };
38
+ fontWeight: {
39
+ normal: number;
40
+ medium: number;
41
+ semibold: number;
42
+ bold: number;
43
+ };
44
+ };
45
+ borderRadius: {
46
+ sm: string;
47
+ md: string;
48
+ lg: string;
49
+ full: string;
50
+ };
51
+ shadows: {
52
+ sm: string;
53
+ md: string;
54
+ lg: string;
55
+ };
56
+ breakpoints: {
57
+ sm: string;
58
+ md: string;
59
+ lg: string;
60
+ xl: string;
61
+ };
62
+ }
63
+ export interface ComponentConfig {
64
+ button: {
65
+ defaultVariant: 'primary' | 'secondary' | 'outline';
66
+ defaultSize: 'small' | 'medium' | 'large';
67
+ disabledOpacity: number;
68
+ };
69
+ input: {
70
+ defaultType: 'text' | 'email' | 'password' | 'number';
71
+ disabledOpacity: number;
72
+ };
73
+ }
74
+ export interface GlobalConfig {
75
+ theme: ThemeConfig;
76
+ components: ComponentConfig;
77
+ prefix: string;
78
+ }
79
+ export declare const defaultConfig: GlobalConfig;
80
+ export declare const setGlobalConfig: (config: Partial<GlobalConfig>) => void;
81
+ export declare const getGlobalConfig: () => GlobalConfig;
82
+ export declare const resetGlobalConfig: () => void;
83
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE;QACN,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,UAAU,EAAE,MAAM,CAAC;QACnB,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,EAAE;YACJ,OAAO,EAAE,MAAM,CAAC;YAChB,SAAS,EAAE,MAAM,CAAC;YAClB,QAAQ,EAAE,MAAM,CAAC;SAClB,CAAC;QACF,MAAM,EAAE;YACN,OAAO,EAAE,MAAM,CAAC;YAChB,KAAK,EAAE,MAAM,CAAC;YACd,KAAK,EAAE,MAAM,CAAC;SACf,CAAC;KACH,CAAC;IACF,OAAO,EAAE;QACP,EAAE,EAAE,MAAM,CAAC;QACX,EAAE,EAAE,MAAM,CAAC;QACX,EAAE,EAAE,MAAM,CAAC;QACX,EAAE,EAAE,MAAM,CAAC;QACX,EAAE,EAAE,MAAM,CAAC;KACZ,CAAC;IACF,UAAU,EAAE;QACV,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE;YACR,EAAE,EAAE,MAAM,CAAC;YACX,EAAE,EAAE,MAAM,CAAC;YACX,IAAI,EAAE,MAAM,CAAC;YACb,EAAE,EAAE,MAAM,CAAC;YACX,EAAE,EAAE,MAAM,CAAC;SACZ,CAAC;QACF,UAAU,EAAE;YACV,MAAM,EAAE,MAAM,CAAC;YACf,MAAM,EAAE,MAAM,CAAC;YACf,QAAQ,EAAE,MAAM,CAAC;YACjB,IAAI,EAAE,MAAM,CAAC;SACd,CAAC;KACH,CAAC;IACF,YAAY,EAAE;QACZ,EAAE,EAAE,MAAM,CAAC;QACX,EAAE,EAAE,MAAM,CAAC;QACX,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;IACF,OAAO,EAAE;QACP,EAAE,EAAE,MAAM,CAAC;QACX,EAAE,EAAE,MAAM,CAAC;QACX,EAAE,EAAE,MAAM,CAAC;KACZ,CAAC;IACF,WAAW,EAAE;QACX,EAAE,EAAE,MAAM,CAAC;QACX,EAAE,EAAE,MAAM,CAAC;QACX,EAAE,EAAE,MAAM,CAAC;QACX,EAAE,EAAE,MAAM,CAAC;KACZ,CAAC;CACH;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE;QACN,cAAc,EAAE,SAAS,GAAG,WAAW,GAAG,SAAS,CAAC;QACpD,WAAW,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;QAC1C,eAAe,EAAE,MAAM,CAAC;KACzB,CAAC;IACF,KAAK,EAAE;QACL,WAAW,EAAE,MAAM,GAAG,OAAO,GAAG,UAAU,GAAG,QAAQ,CAAC;QACtD,eAAe,EAAE,MAAM,CAAC;KACzB,CAAC;CACH;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,WAAW,CAAC;IACnB,UAAU,EAAE,eAAe,CAAC;IAC5B,MAAM,EAAE,MAAM,CAAC;CAChB;AA6ED,eAAO,MAAM,aAAa,EAAE,YAI3B,CAAC;AAIF,eAAO,MAAM,eAAe,GAAI,QAAQ,OAAO,CAAC,YAAY,CAAC,KAAG,IAa/D,CAAC;AAEF,eAAO,MAAM,eAAe,QAAO,YAElC,CAAC;AAEF,eAAO,MAAM,iBAAiB,QAAO,IAEpC,CAAC"}
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ import { ThemeConfig } from '../config';
3
+ export declare const withTheme: (Story: React.ComponentType, context: {
4
+ args: {
5
+ theme?: Partial<ThemeConfig>;
6
+ };
7
+ }) => import("react/jsx-runtime").JSX.Element;
8
+ //# sourceMappingURL=withTheme.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"withTheme.d.ts","sourceRoot":"","sources":["../../src/decorators/withTheme.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAExC,eAAO,MAAM,SAAS,GAAI,OAAO,KAAK,CAAC,aAAa,EAAE,SAAS;IAAE,IAAI,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAA;KAAE,CAAA;CAAE,4CAQxG,CAAC"}
@@ -0,0 +1,8 @@
1
+ import './styles/theme.css';
2
+ export { default as SocialSecurityInput } from './components/SocialSecurityInput';
3
+ export { ThemeProvider } from './components/ThemeProvider';
4
+ export { getCSSVariable, createCSSVariables } from './utils/cssVariables';
5
+ export { setGlobalConfig, getGlobalConfig, resetGlobalConfig, defaultConfig } from './config';
6
+ export type { SocialSecurityInputProps } from './types';
7
+ export type { GlobalConfig, ThemeConfig, ComponentConfig } from './config';
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,oBAAoB,CAAC;AAE5B,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AAClF,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1E,OAAO,EACL,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,aAAa,EACd,MAAM,UAAU,CAAC;AAClB,YAAY,EAAE,wBAAwB,EAAE,MAAM,SAAS,CAAC;AACxD,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC"}