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

Commit b6a9cc6

Browse files
authored
Add Slot/Fill to discounts area in cart sidebar (#4248)
* Move text-input to checkout package * Pass validation props directly to ValidatedTextInput * Import label relatively instead of from package * Pass validation functions to ValidatedTextInput This is so it doesn't need to get them from useValidationContext. * Add InputProps to ValidatedTextInput This will be used to control additional props on the input element of TextInput * Spread inputProps onto <input> element of TextInput * Export TextInput from @woocommerce/blocks-checkout * Add @woocommerce/blocks-checkout package to tsconfig * Allow styling to be applied to number inputs and when value is 0 * Make style order consistent * Remove inputProps to rely on rest in TextInput * Add specific prop for the inputErrorComponent * Only disallow active state if value is 0 AND type is number * Change all uses of ValidatedTextInput to also pass inputErrorComponent * Revert "Change all uses of ValidatedTextInput to also pass inputErrorComponent" This reverts commit ec734b9. * Revert "Remove inputProps to rely on rest in TextInput" This reverts commit 1fc64cc. * Revert "Revert "Change all uses of ValidatedTextInput to also pass inputErrorComponent"" This reverts commit 110e360. * Revert "Revert "Remove inputProps to rely on rest in TextInput"" This reverts commit aeb0352. * Don't pass errorMessage to ValidatedTextInput * Add DiscountsMetaSlot * Add ExperimentalDiscountsMeta.Slot to Cart sidebar * Add extra styles for Button and Panel components * Export ExperimentalDiscountsMeta from checkout package * Add updateCartFromApi util to @woocommerce/blocks-checkout * Add comment to updateCartFromApi * Change updateCartFromApi to TypeScript * Revert "Move `TextInput` to checkout package and allow it to be used for input type=number (#4238)" This reverts commit 15c1779. * Stop passing contexts through the discounts slot fill * Allow ValidatedTextInput to be used for type=number * Remove contexts from Discounts slot fill * Update snapshots * Stop `errorMessage` being spread onto input fields in checkout * Add paths to tsconfig * Remove contexts from Discounts slot * Accept step min and max on ValidatedTextInput * Remove "no-margin" option on buttons * Remove spinners from input type number * Remove `no-top-border` style from panel * Prevent text in buttons from breaking in the middle of words * Add checkout package to tsconfig file list * Stop passing components through DiscountsMetaSlot
1 parent 09be5ad commit b6a9cc6

File tree

12 files changed

+136
-5
lines changed

12 files changed

+136
-5
lines changed

assets/js/base/components/text-input/style.scss

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
input[type="tel"],
4141
input[type="url"],
4242
input[type="text"],
43+
input[type="number"],
4344
input[type="email"] {
4445
@include font-size(regular);
4546
background-color: #fff;
@@ -72,9 +73,20 @@
7273
}
7374
}
7475

76+
input[type="number"] {
77+
-moz-appearance: textfield;
78+
79+
&::-webkit-outer-spin-button,
80+
&::-webkit-inner-spin-button {
81+
appearance: none;
82+
margin: 0;
83+
}
84+
}
85+
7586
&.is-active input[type="tel"],
7687
&.is-active input[type="url"],
7788
&.is-active input[type="text"],
89+
&.is-active input[type="number"],
7890
&.is-active input[type="email"] {
7991
padding: em($gap-large) 0 em($gap-smallest) $gap;
8092
}

assets/js/base/components/text-input/text-input.tsx

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,13 @@ import { Label } from '@woocommerce/blocks-checkout';
1111
*/
1212
import './style.scss';
1313

14+
interface TextInputPropsWithNumberType {
15+
type: 'number';
16+
step?: number;
17+
min?: number;
18+
max?: number;
19+
}
20+
1421
interface TextInputProps
1522
extends Omit<
1623
InputHTMLAttributes< HTMLInputElement >,
@@ -28,7 +35,10 @@ interface TextInputProps
2835
onBlur?: ( newValue: string ) => void;
2936
}
3037

31-
const TextInput = forwardRef< HTMLInputElement, TextInputProps >(
38+
const TextInput = forwardRef<
39+
HTMLInputElement,
40+
TextInputProps & ( Record< string, never > | TextInputPropsWithNumberType )
41+
>(
3242
(
3343
{
3444
className,
@@ -44,6 +54,9 @@ const TextInput = forwardRef< HTMLInputElement, TextInputProps >(
4454
autoComplete = 'off',
4555
value = '',
4656
onChange,
57+
min,
58+
max,
59+
step,
4760
required = false,
4861
onBlur = () => {
4962
/* Do nothing */
@@ -54,6 +67,28 @@ const TextInput = forwardRef< HTMLInputElement, TextInputProps >(
5467
) => {
5568
const [ isActive, setIsActive ] = useState( false );
5669

70+
const numberAttributesFromProps: {
71+
[ prop: string ]: string | number | undefined;
72+
} =
73+
type === 'number'
74+
? {
75+
step,
76+
min,
77+
max,
78+
}
79+
: {};
80+
81+
const numberProps: {
82+
[ prop: string ]: string | number | undefined;
83+
} = {};
84+
85+
Object.keys( numberAttributesFromProps ).forEach( ( key ) => {
86+
if ( typeof numberAttributesFromProps[ key ] === 'undefined' ) {
87+
return;
88+
}
89+
numberProps[ key ] = numberAttributesFromProps[ key ];
90+
} );
91+
5792
return (
5893
<div
5994
className={ classnames(
@@ -87,6 +122,7 @@ const TextInput = forwardRef< HTMLInputElement, TextInputProps >(
87122
: ariaDescribedBy
88123
}
89124
required={ required }
125+
{ ...numberProps }
90126
/>
91127
<Label
92128
label={ label }

assets/js/base/components/text-input/validated-text-input.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
useValidationContext,
1010
} from '@woocommerce/base-context';
1111
import { withInstanceId } from '@woocommerce/base-hocs/with-instance-id';
12+
import { isString } from '@woocommerce/types';
1213

1314
/**
1415
* Internal dependencies
@@ -36,6 +37,7 @@ type ValidatedTextInputProps = (
3637
validateOnMount?: boolean;
3738
focusOnMount?: boolean;
3839
showError?: boolean;
40+
errorMessage?: string;
3941
onChange: ( newValue: string ) => void;
4042
};
4143

@@ -49,6 +51,7 @@ const ValidatedTextInput = ( {
4951
focusOnMount = false,
5052
onChange,
5153
showError = true,
54+
errorMessage: passedErrorMessage = '',
5255
...rest
5356
}: ValidatedTextInputProps ) => {
5457
const [ isPristine, setIsPristine ] = useState( true );
@@ -123,6 +126,9 @@ const ValidatedTextInput = ( {
123126
message?: string;
124127
hidden?: boolean;
125128
};
129+
if ( isString( passedErrorMessage ) && passedErrorMessage !== '' ) {
130+
errorMessage.message = passedErrorMessage;
131+
}
126132
const hasError = errorMessage.message && ! errorMessage.hidden;
127133
const describedBy =
128134
showError && hasError && getValidationErrorId( errorIdString )
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"extends": "../../../../tsconfig.base.json",
33
"compilerOptions": {},
4-
"include": [ ".", "../../../../packages/prices", "../context/hooks", "../../type-defs" ],
4+
"include": [ ".", "../../../../packages/prices", "../../../../packages/checkout", "../context", "../../type-defs", "../hocs" ],
55
"exclude": [ "**/test/**" ]
66
}

assets/js/blocks/cart-checkout/cart/full-cart/index.tsx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ import {
1313
TotalsFees,
1414
TotalsTaxes,
1515
ExperimentalOrderMeta,
16+
ExperimentalDiscountsMeta,
1617
} from '@woocommerce/blocks-checkout';
17-
1818
import { getCurrencyFromPriceResponse } from '@woocommerce/price-format';
1919
import {
2020
useStoreCartCoupons,
@@ -40,7 +40,6 @@ import CheckoutButton from '../checkout-button';
4040
import CartLineItemsTitle from './cart-line-items-title';
4141
import CartLineItemsTable from './cart-line-items-table';
4242
import { CartExpressPayment } from '../../payment-methods';
43-
4443
import './style.scss';
4544

4645
interface CartAttributes {
@@ -114,6 +113,11 @@ const Cart = ( { attributes }: CartProps ) => {
114113
cart,
115114
};
116115

116+
const discountsSlotFillProps = {
117+
extensions,
118+
cart,
119+
};
120+
117121
return (
118122
<>
119123
<CartLineItemsTitle itemCount={ cartItemsCount } />
@@ -152,6 +156,10 @@ const Cart = ( { attributes }: CartProps ) => {
152156
isLoading={ isApplyingCoupon }
153157
/>
154158
) }
159+
<ExperimentalDiscountsMeta.Slot
160+
{ ...discountsSlotFillProps }
161+
/>
162+
155163
{ cartNeedsShipping && (
156164
<TotalsShipping
157165
showCalculator={ isShippingCalculatorEnabled }

assets/js/blocks/cart-checkout/cart/test/__snapshots__/block.js.snap

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,9 @@ exports[`Testing cart Contains a Taxes section if Core options are set to show i
455455
</div>
456456
</div>
457457
</div>
458+
<div
459+
class="wc-block-components-discounts-meta"
460+
/>
458461
<div
459462
class="wc-block-components-totals-shipping"
460463
>
@@ -1146,6 +1149,9 @@ exports[`Testing cart Shows individual tax lines if the store is set to do so 1`
11461149
</div>
11471150
</div>
11481151
</div>
1152+
<div
1153+
class="wc-block-components-discounts-meta"
1154+
/>
11491155
<div
11501156
class="wc-block-components-totals-shipping"
11511157
>
@@ -1842,6 +1848,9 @@ exports[`Testing cart Shows rate percentages after tax lines if the block is set
18421848
</div>
18431849
</div>
18441850
</div>
1851+
<div
1852+
class="wc-block-components-discounts-meta"
1853+
/>
18451854
<div
18461855
class="wc-block-components-totals-shipping"
18471856
>
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/**
2+
* External dependencies
3+
*/
4+
import classnames from 'classnames';
5+
6+
/**
7+
* Internal dependencies
8+
*/
9+
import { createSlotFill } from '../slot';
10+
11+
const slotName = '__experimentalDiscountsMeta';
12+
13+
const {
14+
Fill: ExperimentalDiscountsMeta,
15+
Slot: DiscountsMetaSlot,
16+
} = createSlotFill( slotName );
17+
18+
const Slot = ( { className, extensions, cart } ) => {
19+
return (
20+
<DiscountsMetaSlot
21+
className={ classnames(
22+
className,
23+
'wc-block-components-discounts-meta'
24+
) }
25+
fillProps={ { extensions, cart } }
26+
/>
27+
);
28+
};
29+
30+
ExperimentalDiscountsMeta.Slot = Slot;
31+
32+
export default ExperimentalDiscountsMeta;

packages/checkout/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ export * from './utils';
33
export * from './slot';
44
export * from './registry';
55
export { default as ExperimentalOrderMeta } from './order-meta';
6+
export { default as ExperimentalDiscountsMeta } from './discounts-meta';
67
export { default as ExperimentalOrderShippingPackages } from './order-shipping-packages';
78
export { default as Panel } from './panel';
89
export { SlotFillProvider } from 'wordpress-components';

packages/checkout/panel/style.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
position: relative;
1919
text-align: left;
2020
width: 100%;
21+
word-break: break-word;
2122

2223
&,
2324
&:hover,

packages/checkout/utils/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
export * from './validation';
2+
export { updateCartFromApi } from './update-cart-from-api';

0 commit comments

Comments
 (0)