@khanacademy/wonder-blocks-birthday-picker 4.1.69 → 4.1.71
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/CHANGELOG.md +14 -0
- package/dist/components/birthday-picker.d.ts +2 -67
- package/dist/es/index.js +2 -2
- package/dist/index.js +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# @khanacademy/wonder-blocks-birthday-picker
|
|
2
2
|
|
|
3
|
+
## 4.1.71
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- @khanacademy/wonder-blocks-dropdown@10.13.2
|
|
8
|
+
|
|
9
|
+
## 4.1.70
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- 0600a87: Convert `BirthdayPicker` from a class component to a functional component
|
|
14
|
+
- Updated dependencies [4421914]
|
|
15
|
+
- @khanacademy/wonder-blocks-dropdown@10.13.1
|
|
16
|
+
|
|
3
17
|
## 4.1.69
|
|
4
18
|
|
|
5
19
|
### Patch Changes
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { Temporal } from "temporal-polyfill";
|
|
2
1
|
import * as React from "react";
|
|
3
2
|
import { StyleType } from "@khanacademy/wonder-blocks-core";
|
|
4
3
|
export type Labels = {
|
|
@@ -65,70 +64,6 @@ type Props = {
|
|
|
65
64
|
*/
|
|
66
65
|
locale?: string;
|
|
67
66
|
};
|
|
68
|
-
type State = {
|
|
69
|
-
/**
|
|
70
|
-
* The currently selected month.
|
|
71
|
-
*/
|
|
72
|
-
month: string | null;
|
|
73
|
-
/**
|
|
74
|
-
* The currently selected day.
|
|
75
|
-
*/
|
|
76
|
-
day: string | null;
|
|
77
|
-
/**
|
|
78
|
-
* The currently selected year.
|
|
79
|
-
*/
|
|
80
|
-
year: string | null;
|
|
81
|
-
/**
|
|
82
|
-
* The error message to display (in case there's an invalid date).
|
|
83
|
-
*/
|
|
84
|
-
error: string | null;
|
|
85
|
-
};
|
|
86
67
|
export declare const defaultLabels: Labels;
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
* Strings used for placeholders and error message. These are used this way
|
|
90
|
-
* to support i18n.
|
|
91
|
-
* NOTE: This is a field rather than state to avoid re-rendering the entire
|
|
92
|
-
* component. Also, we don't need to use state because these strings are
|
|
93
|
-
* only needed on mount.
|
|
94
|
-
*/
|
|
95
|
-
labels: Labels;
|
|
96
|
-
constructor(props: Props);
|
|
97
|
-
/**
|
|
98
|
-
* Calculates the initial state values based on the default value.
|
|
99
|
-
*/
|
|
100
|
-
getStateFromDefault(): State;
|
|
101
|
-
/**
|
|
102
|
-
* Determines whether a given date is in the future.
|
|
103
|
-
*
|
|
104
|
-
* @param date - The Temporal.PlainDate to check.
|
|
105
|
-
* @returns True if the provided date comes after today's date, false otherwise.
|
|
106
|
-
*/
|
|
107
|
-
isFutureDate(date: Temporal.PlainDate): boolean;
|
|
108
|
-
lastChangeValue: string | null | undefined;
|
|
109
|
-
/**
|
|
110
|
-
* Report changes back to the calling component, but only if the value
|
|
111
|
-
* has actually changed since the last time it was reported
|
|
112
|
-
* (or initialized).
|
|
113
|
-
*
|
|
114
|
-
* @param value the value to report back to the calling component.
|
|
115
|
-
*/
|
|
116
|
-
reportChange: (value?: string | null | undefined) => void;
|
|
117
|
-
/**
|
|
118
|
-
* Handle a change to any of the input fields, confirming if the input is
|
|
119
|
-
* valid, and then reporting the result back to the calling component via
|
|
120
|
-
* reportChange.
|
|
121
|
-
*/
|
|
122
|
-
handleChange: () => void;
|
|
123
|
-
handleMonthChange: (month: string) => void;
|
|
124
|
-
handleDayChange: (day: string) => void;
|
|
125
|
-
handleYearChange: (year: string) => void;
|
|
126
|
-
maybeRenderError(): React.ReactNode | null | undefined;
|
|
127
|
-
monthsShort(): string[];
|
|
128
|
-
renderMonth(): React.ReactNode;
|
|
129
|
-
maybeRenderDay(): React.ReactNode | null | undefined;
|
|
130
|
-
getMonthYearWidth(monthYearOnly: boolean | undefined): number;
|
|
131
|
-
renderYear(): React.ReactNode;
|
|
132
|
-
render(): React.ReactNode;
|
|
133
|
-
}
|
|
134
|
-
export {};
|
|
68
|
+
declare const BirthdayPicker: (props: Props) => React.JSX.Element;
|
|
69
|
+
export default BirthdayPicker;
|
package/dist/es/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { jsxs,
|
|
1
|
+
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
2
2
|
import { Temporal } from 'temporal-polyfill';
|
|
3
3
|
import * as React from 'react';
|
|
4
4
|
import { StyleSheet } from 'aphrodite';
|
|
@@ -9,6 +9,6 @@ import { PhosphorIcon } from '@khanacademy/wonder-blocks-icon';
|
|
|
9
9
|
import { SingleSelect, OptionItem } from '@khanacademy/wonder-blocks-dropdown';
|
|
10
10
|
import infoIcon from '@phosphor-icons/core/bold/info-bold.svg';
|
|
11
11
|
|
|
12
|
-
const CUR_YEAR=new Date().getYear()+1900;const defaultLabels=Object.freeze({errorMessage:"Please select a valid birthdate.",month:"Month",year:"Year",day:"Day"});const FIELD_MIN_WIDTH_FULL=110;const FIELD_MIN_WIDTH_MONTH_YEAR=167;const FIELD_MIN_WIDTH_DAY=100;const xsMin="520px";const screenSizes={small:`@media (max-width: ${xsMin})`};const defaultStyles=StyleSheet.create({wrapper:{flexDirection:"row",gap:sizing.size_080,[screenSizes.small]:{flexDirection:"column"}},input:{[screenSizes.small]:{minInlineSize:"100%"}},errorRow:{flexDirection:"row",placeItems:"center",gap:sizing.size_040,marginBlockStart:sizing.size_040},errorText:{color:semanticColor.core.foreground.critical.default}});
|
|
12
|
+
const CUR_YEAR=new Date().getYear()+1900;const defaultLabels=Object.freeze({errorMessage:"Please select a valid birthdate.",month:"Month",year:"Year",day:"Day"});const FIELD_MIN_WIDTH_FULL=110;const FIELD_MIN_WIDTH_MONTH_YEAR=167;const FIELD_MIN_WIDTH_DAY=100;const xsMin="520px";const screenSizes={small:`@media (max-width: ${xsMin})`};const defaultStyles=StyleSheet.create({wrapper:{flexDirection:"row",gap:sizing.size_080,[screenSizes.small]:{flexDirection:"column"}},input:{[screenSizes.small]:{minInlineSize:"100%"}},errorRow:{flexDirection:"row",placeItems:"center",gap:sizing.size_040,marginBlockStart:sizing.size_040},errorText:{color:semanticColor.core.foreground.critical.default}});const isFutureDate=date=>{return Temporal.PlainDate.compare(date,Temporal.Now.plainDateISO())===1};const getStateFromDefault=(defaultValue,monthYearOnly,labels)=>{const initialState={month:null,day:monthYearOnly?"1":null,year:null,error:null};if(defaultValue){let date=null;try{date=Temporal.PlainDate.from(defaultValue);}catch(err){initialState.error=labels.errorMessage;return initialState}if(monthYearOnly){date=date.with({day:date.daysInMonth});}initialState.month=String(date.month);initialState.day=String(date.day);initialState.year=String(date.year);if(isFutureDate(date)){initialState.error=labels.errorMessage;}}return initialState};const getMonthYearWidth=monthYearOnly=>{return monthYearOnly?FIELD_MIN_WIDTH_MONTH_YEAR:FIELD_MIN_WIDTH_FULL};const BirthdayPicker=props=>{const{defaultValue,disabled,dropdownStyle,locale,monthYearOnly,onChange,style}=props;const labelsRef=React.useRef({...defaultLabels,...props.labels});const labels=labelsRef.current;const[initialState]=React.useState(()=>getStateFromDefault(defaultValue,monthYearOnly,labels));const[month,setMonth]=React.useState(initialState.month);const[day,setDay]=React.useState(initialState.day);const[year,setYear]=React.useState(initialState.year);const[error,setError]=React.useState(initialState.error);const valuesRef=React.useRef({month:initialState.month,day:initialState.day,year:initialState.year});const lastChangeValueRef=React.useRef(defaultValue||null);const reportChange=React.useCallback(value=>{if(value!==lastChangeValueRef.current){lastChangeValueRef.current=value;onChange(value);}},[onChange]);const handleChange=React.useCallback(()=>{const{month,day,year}=valuesRef.current;const dateFields=[year,month];if(!monthYearOnly){dateFields.push(day);}if(dateFields.some(field=>field===null)){reportChange(null);return}let date;try{if(monthYearOnly){date=Temporal.PlainDate.from({year:Number(year),month:Number(month),day:31});}else {date=Temporal.PlainDate.from({year:Number(year),month:Number(month),day:Number(day)},{overflow:"reject"});}}catch(err){setError(labels.errorMessage);reportChange(null);return}if(isFutureDate(date)){setError(labels.errorMessage);reportChange(null);}else {setError(null);reportChange(date.toString());}},[labels,monthYearOnly,reportChange]);const handleMonthChange=React.useCallback(month=>{valuesRef.current={...valuesRef.current,month};setMonth(month);handleChange();},[handleChange]);const handleDayChange=React.useCallback(day=>{valuesRef.current={...valuesRef.current,day};setDay(day);handleChange();},[handleChange]);const handleYearChange=React.useCallback(year=>{valuesRef.current={...valuesRef.current,year};setYear(year);handleChange();},[handleChange]);const maybeRenderError=()=>{if(!error){return null}return jsxs(View,{style:defaultStyles.errorRow,role:"alert",children:[jsx(PhosphorIcon,{size:"small",icon:infoIcon,color:semanticColor.core.foreground.critical.default,"aria-hidden":"true"}),jsx(BodyText,{tag:"span",style:defaultStyles.errorText,children:error})]})};const monthsShort=React.useMemo(()=>{const format=new Intl.DateTimeFormat(locale??navigator.language,{month:"short"}).format;return [...Array(12).keys()].map(m=>format(new Date(2021,m,15)))},[locale]);const renderMonth=()=>{const minWidth=getMonthYearWidth(monthYearOnly);return jsx(SingleSelect,{"aria-label":labels.month,"aria-invalid":!!error,error:!!error,disabled:disabled,placeholder:labels.month,onChange:handleMonthChange,selectedValue:month,style:[{minWidth},defaultStyles.input,dropdownStyle],testId:"birthday-picker-month",children:monthsShort.map((monthShort,i)=>jsx(OptionItem,{label:monthShort,value:String(i+1)},monthShort))})};const maybeRenderDay=()=>{if(monthYearOnly){return null}return jsx(SingleSelect,{"aria-label":labels.day,"aria-invalid":!!error,error:!!error,disabled:disabled,placeholder:labels.day,onChange:handleDayChange,selectedValue:day,style:[{minInlineSize:FIELD_MIN_WIDTH_DAY},defaultStyles.input,dropdownStyle],testId:"birthday-picker-day",children:Array.from(Array(31)).map((_,day)=>jsx(OptionItem,{label:String(day+1),value:String(day+1)},String(day+1)))})};const renderYear=()=>{const minWidth=getMonthYearWidth(monthYearOnly);return jsx(SingleSelect,{"aria-label":labels.year,"aria-invalid":!!error,error:!!error,disabled:disabled,placeholder:labels.year,onChange:handleYearChange,selectedValue:year,style:[{minWidth},defaultStyles.input,dropdownStyle],dropdownStyle:{minWidth:150},testId:"birthday-picker-year",children:Array.from(Array(120)).map((_,yearOffset)=>jsx(OptionItem,{label:String(CUR_YEAR-yearOffset),value:String(CUR_YEAR-yearOffset)},String(CUR_YEAR-yearOffset)))})};return jsxs(Fragment,{children:[jsxs(View,{testId:"birthday-picker",style:[defaultStyles.wrapper,style],children:[renderMonth(),maybeRenderDay(),renderYear()]}),maybeRenderError()]})};
|
|
13
13
|
|
|
14
14
|
export { BirthdayPicker as default };
|
package/dist/index.js
CHANGED
|
@@ -34,6 +34,6 @@ function _interopNamespace(e) {
|
|
|
34
34
|
var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
35
35
|
var infoIcon__default = /*#__PURE__*/_interopDefaultLegacy(infoIcon);
|
|
36
36
|
|
|
37
|
-
const CUR_YEAR=new Date().getYear()+1900;const defaultLabels=Object.freeze({errorMessage:"Please select a valid birthdate.",month:"Month",year:"Year",day:"Day"});const FIELD_MIN_WIDTH_FULL=110;const FIELD_MIN_WIDTH_MONTH_YEAR=167;const FIELD_MIN_WIDTH_DAY=100;const xsMin="520px";const screenSizes={small:`@media (max-width: ${xsMin})`};const defaultStyles=aphrodite.StyleSheet.create({wrapper:{flexDirection:"row",gap:wonderBlocksTokens.sizing.size_080,[screenSizes.small]:{flexDirection:"column"}},input:{[screenSizes.small]:{minInlineSize:"100%"}},errorRow:{flexDirection:"row",placeItems:"center",gap:wonderBlocksTokens.sizing.size_040,marginBlockStart:wonderBlocksTokens.sizing.size_040},errorText:{color:wonderBlocksTokens.semanticColor.core.foreground.critical.default}});
|
|
37
|
+
const CUR_YEAR=new Date().getYear()+1900;const defaultLabels=Object.freeze({errorMessage:"Please select a valid birthdate.",month:"Month",year:"Year",day:"Day"});const FIELD_MIN_WIDTH_FULL=110;const FIELD_MIN_WIDTH_MONTH_YEAR=167;const FIELD_MIN_WIDTH_DAY=100;const xsMin="520px";const screenSizes={small:`@media (max-width: ${xsMin})`};const defaultStyles=aphrodite.StyleSheet.create({wrapper:{flexDirection:"row",gap:wonderBlocksTokens.sizing.size_080,[screenSizes.small]:{flexDirection:"column"}},input:{[screenSizes.small]:{minInlineSize:"100%"}},errorRow:{flexDirection:"row",placeItems:"center",gap:wonderBlocksTokens.sizing.size_040,marginBlockStart:wonderBlocksTokens.sizing.size_040},errorText:{color:wonderBlocksTokens.semanticColor.core.foreground.critical.default}});const isFutureDate=date=>{return temporalPolyfill.Temporal.PlainDate.compare(date,temporalPolyfill.Temporal.Now.plainDateISO())===1};const getStateFromDefault=(defaultValue,monthYearOnly,labels)=>{const initialState={month:null,day:monthYearOnly?"1":null,year:null,error:null};if(defaultValue){let date=null;try{date=temporalPolyfill.Temporal.PlainDate.from(defaultValue);}catch(err){initialState.error=labels.errorMessage;return initialState}if(monthYearOnly){date=date.with({day:date.daysInMonth});}initialState.month=String(date.month);initialState.day=String(date.day);initialState.year=String(date.year);if(isFutureDate(date)){initialState.error=labels.errorMessage;}}return initialState};const getMonthYearWidth=monthYearOnly=>{return monthYearOnly?FIELD_MIN_WIDTH_MONTH_YEAR:FIELD_MIN_WIDTH_FULL};const BirthdayPicker=props=>{const{defaultValue,disabled,dropdownStyle,locale,monthYearOnly,onChange,style}=props;const labelsRef=React__namespace.useRef({...defaultLabels,...props.labels});const labels=labelsRef.current;const[initialState]=React__namespace.useState(()=>getStateFromDefault(defaultValue,monthYearOnly,labels));const[month,setMonth]=React__namespace.useState(initialState.month);const[day,setDay]=React__namespace.useState(initialState.day);const[year,setYear]=React__namespace.useState(initialState.year);const[error,setError]=React__namespace.useState(initialState.error);const valuesRef=React__namespace.useRef({month:initialState.month,day:initialState.day,year:initialState.year});const lastChangeValueRef=React__namespace.useRef(defaultValue||null);const reportChange=React__namespace.useCallback(value=>{if(value!==lastChangeValueRef.current){lastChangeValueRef.current=value;onChange(value);}},[onChange]);const handleChange=React__namespace.useCallback(()=>{const{month,day,year}=valuesRef.current;const dateFields=[year,month];if(!monthYearOnly){dateFields.push(day);}if(dateFields.some(field=>field===null)){reportChange(null);return}let date;try{if(monthYearOnly){date=temporalPolyfill.Temporal.PlainDate.from({year:Number(year),month:Number(month),day:31});}else {date=temporalPolyfill.Temporal.PlainDate.from({year:Number(year),month:Number(month),day:Number(day)},{overflow:"reject"});}}catch(err){setError(labels.errorMessage);reportChange(null);return}if(isFutureDate(date)){setError(labels.errorMessage);reportChange(null);}else {setError(null);reportChange(date.toString());}},[labels,monthYearOnly,reportChange]);const handleMonthChange=React__namespace.useCallback(month=>{valuesRef.current={...valuesRef.current,month};setMonth(month);handleChange();},[handleChange]);const handleDayChange=React__namespace.useCallback(day=>{valuesRef.current={...valuesRef.current,day};setDay(day);handleChange();},[handleChange]);const handleYearChange=React__namespace.useCallback(year=>{valuesRef.current={...valuesRef.current,year};setYear(year);handleChange();},[handleChange]);const maybeRenderError=()=>{if(!error){return null}return jsxRuntime.jsxs(wonderBlocksCore.View,{style:defaultStyles.errorRow,role:"alert",children:[jsxRuntime.jsx(wonderBlocksIcon.PhosphorIcon,{size:"small",icon:infoIcon__default["default"],color:wonderBlocksTokens.semanticColor.core.foreground.critical.default,"aria-hidden":"true"}),jsxRuntime.jsx(wonderBlocksTypography.BodyText,{tag:"span",style:defaultStyles.errorText,children:error})]})};const monthsShort=React__namespace.useMemo(()=>{const format=new Intl.DateTimeFormat(locale??navigator.language,{month:"short"}).format;return [...Array(12).keys()].map(m=>format(new Date(2021,m,15)))},[locale]);const renderMonth=()=>{const minWidth=getMonthYearWidth(monthYearOnly);return jsxRuntime.jsx(wonderBlocksDropdown.SingleSelect,{"aria-label":labels.month,"aria-invalid":!!error,error:!!error,disabled:disabled,placeholder:labels.month,onChange:handleMonthChange,selectedValue:month,style:[{minWidth},defaultStyles.input,dropdownStyle],testId:"birthday-picker-month",children:monthsShort.map((monthShort,i)=>jsxRuntime.jsx(wonderBlocksDropdown.OptionItem,{label:monthShort,value:String(i+1)},monthShort))})};const maybeRenderDay=()=>{if(monthYearOnly){return null}return jsxRuntime.jsx(wonderBlocksDropdown.SingleSelect,{"aria-label":labels.day,"aria-invalid":!!error,error:!!error,disabled:disabled,placeholder:labels.day,onChange:handleDayChange,selectedValue:day,style:[{minInlineSize:FIELD_MIN_WIDTH_DAY},defaultStyles.input,dropdownStyle],testId:"birthday-picker-day",children:Array.from(Array(31)).map((_,day)=>jsxRuntime.jsx(wonderBlocksDropdown.OptionItem,{label:String(day+1),value:String(day+1)},String(day+1)))})};const renderYear=()=>{const minWidth=getMonthYearWidth(monthYearOnly);return jsxRuntime.jsx(wonderBlocksDropdown.SingleSelect,{"aria-label":labels.year,"aria-invalid":!!error,error:!!error,disabled:disabled,placeholder:labels.year,onChange:handleYearChange,selectedValue:year,style:[{minWidth},defaultStyles.input,dropdownStyle],dropdownStyle:{minWidth:150},testId:"birthday-picker-year",children:Array.from(Array(120)).map((_,yearOffset)=>jsxRuntime.jsx(wonderBlocksDropdown.OptionItem,{label:String(CUR_YEAR-yearOffset),value:String(CUR_YEAR-yearOffset)},String(CUR_YEAR-yearOffset)))})};return jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsxs(wonderBlocksCore.View,{testId:"birthday-picker",style:[defaultStyles.wrapper,style],children:[renderMonth(),maybeRenderDay(),renderYear()]}),maybeRenderError()]})};
|
|
38
38
|
|
|
39
39
|
module.exports = BirthdayPicker;
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"description": "",
|
|
4
4
|
"author": "Khan Academy",
|
|
5
5
|
"license": "MIT",
|
|
6
|
-
"version": "4.1.
|
|
6
|
+
"version": "4.1.71",
|
|
7
7
|
"publishConfig": {
|
|
8
8
|
"access": "public"
|
|
9
9
|
},
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"types": "dist/index.d.ts",
|
|
22
22
|
"dependencies": {
|
|
23
23
|
"@khanacademy/wonder-blocks-core": "12.5.0",
|
|
24
|
-
"@khanacademy/wonder-blocks-dropdown": "10.13.
|
|
24
|
+
"@khanacademy/wonder-blocks-dropdown": "10.13.2",
|
|
25
25
|
"@khanacademy/wonder-blocks-icon": "6.0.2",
|
|
26
26
|
"@khanacademy/wonder-blocks-layout": "3.1.62",
|
|
27
27
|
"@khanacademy/wonder-blocks-tokens": "18.0.0",
|