@popmenu/ordering-ui 0.145.0 → 0.148.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.
Files changed (61) hide show
  1. package/build/cjs/components/MenuTab/MenuTab.styles.d.ts +1 -0
  2. package/build/cjs/components/MenuTab/MenuTabProps.d.ts +8 -2
  3. package/build/cjs/components/MenuTabGroup/MenuTabGroup.styles.d.ts +1 -1
  4. package/build/cjs/components/MenuTabGroup/MenuTabGroupProps.d.ts +6 -6
  5. package/build/cjs/components/QuantityPicker/QuantityPicker.d.ts +1 -1
  6. package/build/cjs/components/QuantityPicker/QuantityPickerProps.d.ts +7 -1
  7. package/build/cjs/components/ReactionCounter/ReactionCounterProps.d.ts +1 -1
  8. package/build/cjs/components/SelectableChip/SelectableChipProps.d.ts +7 -2
  9. package/build/cjs/components/SelectableChipGroup/SelectableChipGroup.d.ts +5 -1
  10. package/build/cjs/components/SelectableChipGroup/index.d.ts +0 -1
  11. package/build/cjs/components/index.d.ts +0 -1
  12. package/build/cjs/index.js +324 -126
  13. package/build/cjs/index.js.map +1 -1
  14. package/build/esm/components/DishModifierCard/DishModifierCard.styles.js +6 -0
  15. package/build/esm/components/DishModifierCard/DishModifierCard.styles.js.map +1 -1
  16. package/build/esm/components/DishModifierCard/ModifierControls.js +6 -5
  17. package/build/esm/components/DishModifierCard/ModifierControls.js.map +1 -1
  18. package/build/esm/components/MenuItem/MenuItem.js +3 -3
  19. package/build/esm/components/MenuItem/MenuItem.js.map +1 -1
  20. package/build/esm/components/MenuSection/MenuSection.js +3 -3
  21. package/build/esm/components/MenuSection/MenuSection.js.map +1 -1
  22. package/build/esm/components/MenuTab/MenuTab.js +22 -6
  23. package/build/esm/components/MenuTab/MenuTab.js.map +1 -1
  24. package/build/esm/components/MenuTab/MenuTab.styles.d.ts +1 -0
  25. package/build/esm/components/MenuTab/MenuTab.styles.js +26 -14
  26. package/build/esm/components/MenuTab/MenuTab.styles.js.map +1 -1
  27. package/build/esm/components/MenuTab/MenuTabProps.d.ts +8 -2
  28. package/build/esm/components/MenuTabGroup/MenuTabGroup.js +46 -6
  29. package/build/esm/components/MenuTabGroup/MenuTabGroup.js.map +1 -1
  30. package/build/esm/components/MenuTabGroup/MenuTabGroup.styles.d.ts +1 -1
  31. package/build/esm/components/MenuTabGroup/MenuTabGroup.styles.js +41 -39
  32. package/build/esm/components/MenuTabGroup/MenuTabGroup.styles.js.map +1 -1
  33. package/build/esm/components/MenuTabGroup/MenuTabGroupProps.d.ts +6 -6
  34. package/build/esm/components/QuantityPicker/QuantityPicker.d.ts +1 -1
  35. package/build/esm/components/QuantityPicker/QuantityPicker.js +91 -16
  36. package/build/esm/components/QuantityPicker/QuantityPicker.js.map +1 -1
  37. package/build/esm/components/QuantityPicker/QuantityPicker.styles.js +8 -3
  38. package/build/esm/components/QuantityPicker/QuantityPicker.styles.js.map +1 -1
  39. package/build/esm/components/QuantityPicker/QuantityPickerProps.d.ts +7 -1
  40. package/build/esm/components/ReactionCounter/ReactionCounter.js +5 -2
  41. package/build/esm/components/ReactionCounter/ReactionCounter.js.map +1 -1
  42. package/build/esm/components/ReactionCounter/ReactionCounterProps.d.ts +1 -1
  43. package/build/esm/components/SelectableChip/SelectableChip.js +16 -5
  44. package/build/esm/components/SelectableChip/SelectableChip.js.map +1 -1
  45. package/build/esm/components/SelectableChip/SelectableChip.styles.js +9 -21
  46. package/build/esm/components/SelectableChip/SelectableChip.styles.js.map +1 -1
  47. package/build/esm/components/SelectableChip/SelectableChipProps.d.ts +7 -2
  48. package/build/esm/components/SelectableChipGroup/SelectableChipGroup.d.ts +5 -1
  49. package/build/esm/components/SelectableChipGroup/SelectableChipGroup.js +4 -6
  50. package/build/esm/components/SelectableChipGroup/SelectableChipGroup.js.map +1 -1
  51. package/build/esm/components/SelectableChipGroup/SelectableChipGroup.styles.js +4 -4
  52. package/build/esm/components/SelectableChipGroup/SelectableChipGroup.styles.js.map +1 -1
  53. package/build/esm/components/SelectableChipGroup/index.d.ts +0 -1
  54. package/build/esm/components/index.d.ts +0 -1
  55. package/build/esm/theme/overrides.js +36 -1
  56. package/build/esm/theme/overrides.js.map +1 -1
  57. package/build/esm/theme/props.js +9 -0
  58. package/build/esm/theme/props.js.map +1 -1
  59. package/package.json +2 -2
  60. package/build/cjs/components/SelectableChipGroup/SelectableChipGroupProps.d.ts +0 -6
  61. package/build/esm/components/SelectableChipGroup/SelectableChipGroupProps.d.ts +0 -6
@@ -192,8 +192,11 @@ const MenuItemPrice = (props) => {
192
192
  const ReactionCounter = (props) => {
193
193
  const { count, icon, label } = props;
194
194
  return (React.createElement(commonUi.Box, { display: "flex", alignItems: "center", gridGap: 6, color: "grey.900" },
195
- React.createElement(commonUi.Icon, { icon: icon, size: "large", color: "inherit", "aria-label": label }),
196
- React.createElement(commonUi.Typography, { variant: "body2", color: "grey.900" }, count)));
195
+ React.createElement(commonUi.Icon, { icon: icon, size: "large", color: "inherit", "aria-hidden": "true" }),
196
+ React.createElement(commonUi.Typography, { variant: "body2", color: "grey.900" },
197
+ count,
198
+ " ",
199
+ React.createElement("span", { className: "sr-only" }, label))));
197
200
  };
198
201
 
199
202
  const ReactionCounterGroup = (props) => {
@@ -245,17 +248,17 @@ const MenuItemTags = (props) => {
245
248
  };
246
249
 
247
250
  const MenuItem = React.forwardRef((props, ref) => {
248
- const { ariaLabel, onClick, id, description, title, loading, statusTags, image, likeCount, reviewCount, price, available, itemTags, className, ...restProps } = props;
251
+ const { ariaLabel, onClick, description, title, loading, statusTags, image, likeCount, reviewCount, price, available, itemTags, className, ...restProps } = props;
249
252
  const classes = useMenuItemStyles(props);
250
253
  const handleClick = (event) => {
251
- onClick(id, event);
254
+ onClick(props.id, event);
252
255
  };
253
256
  return (React.createElement(core.Card, { className: classNames(classes.card, className), ref: ref, elevation: 0, "data-component-type": "menu-item", ...restProps },
254
257
  React.createElement(core.CardActionArea, { className: classes.cardActionArea, onClick: handleClick, disabled: loading, "aria-label": ariaLabel },
255
258
  React.createElement(MenuItemInfo, null,
256
259
  statusTags?.featured && React.createElement(StatusTag, { ...statusTags.featured }),
257
260
  React.createElement(core.Box, { display: "flex", gridGap: 8, alignItems: "center" },
258
- React.createElement(core.Typography, { component: "h2", className: classes.cardTitle },
261
+ React.createElement(core.Typography, { component: "h3", className: classes.cardTitle },
259
262
  loading ? React.createElement(lab.Skeleton, null) : title,
260
263
  statusTags?.outOfStock && (React.createElement("span", { className: classes.statusTags },
261
264
  React.createElement(StatusTag, { ...statusTags.outOfStock }))),
@@ -276,84 +279,151 @@ MenuItem.displayName = 'MenuItem';
276
279
  const useMenuTabStyles = core.makeStyles(({ palette, spacing }) => ({
277
280
  icon: {
278
281
  minWidth: spacing(2.5),
282
+ marginRight: spacing(1),
279
283
  },
280
- root: ({ isUnavailable }) => ({
281
- color: isUnavailable ? `${palette.grey[700]} !important` : 'inherit',
282
- '&.MuiTab-labelIcon': {
283
- minHeight: 'unset',
284
- },
284
+ root: {
285
+ display: 'inline-flex',
286
+ alignItems: 'center',
287
+ justifyContent: 'center',
288
+ textDecoration: 'none',
289
+ color: ({ isUnavailable }) => (isUnavailable ? palette.grey[700] : 'inherit'),
290
+ padding: spacing(1.5, 2),
291
+ whiteSpace: 'nowrap',
285
292
  maxWidth: spacing(29.5),
286
- '& > .MuiTab-wrapper': {
287
- flexDirection: 'row-reverse',
288
- gridGap: spacing(1),
289
- textAlign: 'center',
290
- '& > svg': {
291
- marginBottom: '0 !important',
292
- },
293
- },
294
- }),
293
+ outlineOffset: -2,
294
+ },
295
+ selected: {
296
+ fontWeight: 500,
297
+ borderBottom: `2px solid ${palette.primary.main}`,
298
+ },
299
+ visuallyHidden: {
300
+ position: 'absolute',
301
+ width: 1,
302
+ height: 1,
303
+ padding: 0,
304
+ margin: -1,
305
+ overflow: 'hidden',
306
+ clip: 'rect(0, 0, 0, 0)',
307
+ whiteSpace: 'nowrap',
308
+ border: 0,
309
+ },
295
310
  }));
296
311
 
297
312
  const MenuTab = (props) => {
298
- const { isUnavailable, value } = props;
299
- const classes = useMenuTabStyles({ isUnavailable });
300
- return (React.createElement(core.Tab, { "data-tab-for-section-id": value, classes: {
301
- root: classes.root,
302
- }, icon: isUnavailable ? React.createElement(commonUi.Icon, { icon: webIcons.Clock, size: "large", className: classes.icon }) : undefined, ...props }));
313
+ const { href, value, label, onClick, selected, isUnavailable, unavailableLabel } = props;
314
+ const classes = useMenuTabStyles({ isUnavailable, selected });
315
+ const handleClick = (event) => {
316
+ event.preventDefault();
317
+ onClick(event, value);
318
+ };
319
+ const handleKeyDown = (event) => {
320
+ if (event.key === ' ') {
321
+ event.preventDefault();
322
+ onClick(event, value);
323
+ }
324
+ };
325
+ return (React.createElement("li", null,
326
+ React.createElement(core.Typography, { variant: "body2" },
327
+ React.createElement("a", { href: href, className: classNames(classes.root, { [classes.selected]: selected }), onClick: handleClick, onKeyDown: handleKeyDown, "aria-current": selected ? 'page' : undefined },
328
+ isUnavailable && React.createElement(commonUi.Icon, { icon: webIcons.Clock, "aria-hidden": "true", size: "large", className: classes.icon }),
329
+ label,
330
+ isUnavailable && React.createElement("span", { className: classes.visuallyHidden },
331
+ ", ",
332
+ unavailableLabel)))));
303
333
  };
304
334
 
335
+ const scrollButtonBase = {
336
+ position: 'absolute',
337
+ zIndex: 1,
338
+ backgroundColor: 'white',
339
+ height: '100%',
340
+ top: 0,
341
+ display: 'flex',
342
+ alignItems: 'center',
343
+ justifyContent: 'center',
344
+ width: 40,
345
+ opacity: 1,
346
+ '& svg': {
347
+ height: 24,
348
+ width: 24,
349
+ },
350
+ };
305
351
  const useMenuTabGroupStyles = core.makeStyles(() => ({
306
352
  root: {
307
- position: 'relative' /* Establish positioning context */,
308
- overflow: 'hidden' /* Prevent scroll buttons from overflowing */,
309
- '& .MuiTabScrollButton-root': {
310
- position: 'absolute',
311
- zIndex: '1',
312
- backgroundColor: 'white',
313
- height: '100%' /* Inherit full height of parent */,
314
- top: '0',
315
- display: 'flex',
316
- alignItems: 'center',
317
- justifyContent: 'center',
318
- width: '40px',
319
- opacity: 1,
320
- /* Position scroller buttons and add gradient to inner sections */
321
- '&:first-child': {
322
- left: 0,
323
- background: 'linear-gradient(to right, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 1) calc(100% - 8px), rgba(255, 255, 255, 0) 100%)',
324
- },
325
- '&:last-child': {
326
- right: 0,
327
- background: 'linear-gradient(to left, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 1) calc(100% - 8px), rgba(255, 255, 255, 0) 100%)',
328
- },
329
- /* Ensure tab container fills height */
330
- '& .MuiSvgIcon-root': {
331
- height: '24px',
332
- width: '24px',
333
- },
334
- },
335
- /* Adjust scroller to prevent tabs from being hidden */
336
- '.MuiTabs-scroller': {
337
- padding: '0 40px' /* Match scroll button width */,
338
- height: '100%' /* Ensure it fills parent height */,
339
- },
340
- /* Ensure tab container fills height */
341
- '.MuiTabs-flexContainer': {
342
- height: '100%',
343
- },
344
- /* Remove buttons when scroll is all the way to the left or right */
345
- '& .MuiTabScrollButton-root.Mui-disabled': {
353
+ position: 'relative',
354
+ overflow: 'hidden',
355
+ display: 'flex',
356
+ alignItems: 'center',
357
+ },
358
+ flexContainer: {
359
+ display: 'flex',
360
+ listStyle: 'none',
361
+ margin: 0,
362
+ padding: 0,
363
+ overflowX: 'auto',
364
+ scrollbarWidth: 'none',
365
+ msOverflowStyle: 'none',
366
+ '&::-webkit-scrollbar': {
346
367
  display: 'none',
347
368
  },
369
+ height: '100%',
370
+ },
371
+ scrollButtonLeft: {
372
+ ...scrollButtonBase,
373
+ left: 0,
374
+ background: 'linear-gradient(to right, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 1) calc(100% - 8px), rgba(255, 255, 255, 0) 100%)',
375
+ },
376
+ scrollButtonRight: {
377
+ ...scrollButtonBase,
378
+ right: 0,
379
+ background: 'linear-gradient(to left, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 1) calc(100% - 8px), rgba(255, 255, 255, 0) 100%)',
348
380
  },
349
381
  }));
350
382
 
351
383
  const MenuTabGroup = (props) => {
352
- const { children, ...muiProps } = props;
384
+ const { children, scrollLeftLabel, scrollRightLabel, ...restProps } = props;
353
385
  const classes = useMenuTabGroupStyles();
354
- return (React.createElement(core.Tabs, { scrollButtons: "on", variant: "scrollable", classes: {
355
- root: classes.root,
356
- }, ...muiProps }, children));
386
+ const scrollContainerRef = React.useRef(null);
387
+ const [showLeftButton, setShowLeftButton] = React.useState(false);
388
+ const [showRightButton, setShowRightButton] = React.useState(false);
389
+ const updateScrollButtons = React.useCallback(() => {
390
+ const container = scrollContainerRef.current;
391
+ if (!container)
392
+ return;
393
+ const { scrollLeft, scrollWidth, clientWidth } = container;
394
+ setShowLeftButton(scrollLeft > 0);
395
+ setShowRightButton(scrollLeft + clientWidth < scrollWidth - 1);
396
+ }, []);
397
+ React.useEffect(() => {
398
+ const container = scrollContainerRef.current;
399
+ if (!container)
400
+ return;
401
+ updateScrollButtons();
402
+ container.addEventListener('scroll', updateScrollButtons);
403
+ window.addEventListener('resize', updateScrollButtons);
404
+ return () => {
405
+ container.removeEventListener('scroll', updateScrollButtons);
406
+ window.removeEventListener('resize', updateScrollButtons);
407
+ };
408
+ }, [updateScrollButtons]);
409
+ const scrollLeft = () => {
410
+ const container = scrollContainerRef.current;
411
+ if (!container)
412
+ return;
413
+ container.scrollBy({ left: -container.clientWidth, behavior: 'smooth' });
414
+ };
415
+ const scrollRight = () => {
416
+ const container = scrollContainerRef.current;
417
+ if (!container)
418
+ return;
419
+ container.scrollBy({ left: container.clientWidth, behavior: 'smooth' });
420
+ };
421
+ return (React.createElement("nav", { className: classes.root, ...restProps },
422
+ showLeftButton && (React.createElement(core.IconButton, { className: classes.scrollButtonLeft, onClick: scrollLeft, "aria-label": scrollLeftLabel, size: "small" },
423
+ React.createElement(commonUi.Icon, { icon: webIcons.ChevronLeft, "aria-hidden": "true" }))),
424
+ React.createElement("ul", { ref: scrollContainerRef, className: classes.flexContainer }, children),
425
+ showRightButton && (React.createElement(core.IconButton, { className: classes.scrollButtonRight, onClick: scrollRight, "aria-label": scrollRightLabel, size: "small" },
426
+ React.createElement(commonUi.Icon, { icon: webIcons.ChevronRight, "aria-hidden": "true" })))));
357
427
  };
358
428
 
359
429
  const useMenuItemModifiersListStyles = core.makeStyles((theme) => ({
@@ -616,6 +686,9 @@ const useDishModifierCardStyles = core.makeStyles((theme) => ({
616
686
  },
617
687
  }));
618
688
  const useRadioModifierFormStyles = core.makeStyles((theme) => ({
689
+ radioGroup: {
690
+ gap: theme.spacing(1),
691
+ },
619
692
  label: {
620
693
  alignItems: 'center',
621
694
  display: 'flex',
@@ -642,6 +715,9 @@ const useRadioModifierFormStyles = core.makeStyles((theme) => ({
642
715
  },
643
716
  }));
644
717
  const useCheckboxModifierFormStyles = core.makeStyles((theme) => ({
718
+ formGroup: {
719
+ gap: theme.spacing(1),
720
+ },
645
721
  label: {
646
722
  alignItems: 'center',
647
723
  display: 'flex',
@@ -690,6 +766,9 @@ const useQuantityPickerStyles = core.makeStyles((theme) => ({
690
766
  root: {
691
767
  height: theme.spacing(7),
692
768
  backgroundColor: 'none',
769
+ '&:has(:focus-visible)': {
770
+ outline: `2px solid ${theme.palette.info.main}`,
771
+ },
693
772
  },
694
773
  }));
695
774
  const useQuantityInputStyles = core.makeStyles((theme) => ({
@@ -705,15 +784,17 @@ const useQuantityInputStyles = core.makeStyles((theme) => ({
705
784
  },
706
785
  '-moz-appearance': 'textfield',
707
786
  fontWeight: 600,
708
- padding: 0,
709
787
  textAlign: 'center',
710
788
  zIndex: (props) => (props.value === 0 && props.variation === 'modifierCount' ? -1 : 1),
711
789
  backgroundColor: (props) => (props.variation === 'modifierCount' ? theme.palette.grey[100] : 'unset'),
712
790
  alignSelf: (props) => (props.variation === 'modifierCount' ? 'stretch' : 'unset'),
713
791
  height: (props) => (props.variation === 'modifierCount' ? 'auto' : 'unset'),
714
- minWidth: (props) => (props.variation === 'modifierCount' ? theme.spacing(5) : theme.spacing(2.75)),
792
+ minHeight: theme.spacing(3),
793
+ minWidth: (props) => (props.variation === 'modifierCount' ? theme.spacing(5) : theme.spacing(3)),
715
794
  borderRadius: (props) => (props.variation === 'modifierCount' ? theme.spacing(1) : 'unset'),
716
- margin: (props) => (props.variation === 'modifierCount' ? theme.spacing(0.5, 0) : 0),
795
+ margin: theme.spacing(1),
796
+ padding: 0,
797
+ outline: 'none !important',
717
798
  },
718
799
  }));
719
800
  const useStartAdornmentStyles = core.makeStyles((theme) => ({
@@ -728,18 +809,76 @@ const useEndAdornmentStyles = core.makeStyles((theme) => ({
728
809
  },
729
810
  }));
730
811
 
731
- const QuantityPicker = ({ value, onChange, disabled, preventManualChange, disableIncrement, variation, name, min = 0, max = 99, }) => {
812
+ const LIVE_REGION_CLEAR_DELAY = 2000;
813
+ const QuantityPicker = ({ id, value, onChange, disabled, preventManualChange, disableIncrement, variation, name, min = 0, max = 99, incrementButtonTitle, decrementButtonTitle, }) => {
732
814
  const fieldClasses = useQuantityPickerStyles();
733
815
  const inputClasses = useQuantityInputStyles({ variation, value });
734
816
  const startAdornmentClasses = useStartAdornmentStyles({ variation, value });
735
817
  const endAdornmentClasses = useEndAdornmentStyles({ variation, value });
736
818
  const inputRef = React.useRef(null);
737
819
  const [shouldSelect, setShouldSelect] = React.useState(false);
820
+ const [liveRegionMessage, setLiveRegionMessage] = React.useState('');
821
+ const liveRegionTimeoutRef = React.useRef(null);
822
+ // Clear the live region message after a delay to avoid stale announcements
823
+ const announceLiveRegion = React.useCallback((message) => {
824
+ if (liveRegionTimeoutRef.current) {
825
+ clearTimeout(liveRegionTimeoutRef.current);
826
+ }
827
+ setLiveRegionMessage(message);
828
+ liveRegionTimeoutRef.current = setTimeout(() => {
829
+ setLiveRegionMessage('');
830
+ }, LIVE_REGION_CLEAR_DELAY);
831
+ }, []);
832
+ // Cleanup timeout on unmount
833
+ React.useEffect(() => {
834
+ return () => {
835
+ if (liveRegionTimeoutRef.current) {
836
+ clearTimeout(liveRegionTimeoutRef.current);
837
+ }
838
+ };
839
+ }, []);
738
840
  const onIncrement = (event) => {
739
- onChange(event, { quantity: value + 1, reason: 'increment' });
841
+ const newValue = value + 1;
842
+ onChange(event, { quantity: newValue, reason: 'increment' });
843
+ announceLiveRegion(String(newValue));
740
844
  };
741
845
  const onDecrement = (event) => {
742
- onChange(event, { quantity: value - 1, reason: 'decrement' });
846
+ const newValue = value - 1;
847
+ onChange(event, { quantity: newValue, reason: 'decrement' });
848
+ announceLiveRegion(String(newValue));
849
+ };
850
+ const handleKeyDown = (event) => {
851
+ let newValue = null;
852
+ switch (event.key) {
853
+ case 'ArrowUp':
854
+ event.preventDefault();
855
+ if (value < max && !disableIncrement) {
856
+ newValue = value + 1;
857
+ onChange(event, { quantity: newValue, reason: 'increment' });
858
+ }
859
+ break;
860
+ case 'ArrowDown':
861
+ event.preventDefault();
862
+ if (value > min) {
863
+ newValue = value - 1;
864
+ onChange(event, { quantity: newValue, reason: 'decrement' });
865
+ }
866
+ break;
867
+ case 'Home':
868
+ event.preventDefault();
869
+ if (value !== min) {
870
+ newValue = min;
871
+ onChange(event, { quantity: newValue, reason: 'decrement' });
872
+ }
873
+ break;
874
+ case 'End':
875
+ event.preventDefault();
876
+ if (value !== max && !disableIncrement) {
877
+ newValue = max;
878
+ onChange(event, { quantity: newValue, reason: 'increment' });
879
+ }
880
+ break;
881
+ }
743
882
  };
744
883
  const handleChange = (event) => {
745
884
  if (preventManualChange) {
@@ -768,28 +907,46 @@ const QuantityPicker = ({ value, onChange, disabled, preventManualChange, disabl
768
907
  setShouldSelect(false);
769
908
  }
770
909
  }, [shouldSelect, value]);
771
- return (React.createElement(core.TextField, { "aria-label": `${name} Quantity`, classes: fieldClasses, type: "number", variant: variation === 'itemCount' ? 'filled' : 'standard', value: value, disabled: disabled, onChange: handleChange, inputRef: inputRef, InputProps: {
772
- classes: inputClasses,
773
- disableUnderline: true,
774
- endAdornment: (React.createElement(commonUi.IconButton, { "aria-label": `increase quantity ${name}`, className: endAdornmentClasses.root, color: "default", onClick: onIncrement, disabled: disabled || value >= max || disableIncrement },
775
- React.createElement(commonUi.Icon, { icon: webIcons.PlusCircle }))),
776
- startAdornment: (React.createElement(commonUi.IconButton, { "aria-label": `decrease quantity ${name}`, className: startAdornmentClasses.root, color: "default", onClick: onDecrement, disabled: disabled || value <= min },
777
- React.createElement(commonUi.Icon, { icon: webIcons.MinusCircle }))),
778
- }, inputProps: {
779
- 'aria-label': `${name} quantity`,
780
- min,
781
- max,
782
- } }));
910
+ const isAtMin = value <= min;
911
+ const isAtMax = value >= max || disableIncrement;
912
+ return (React.createElement(React.Fragment, null,
913
+ React.createElement(core.TextField, { id: id, classes: fieldClasses, type: "text", variant: variation === 'itemCount' ? 'filled' : 'standard', value: value, disabled: disabled, onChange: handleChange, onKeyDown: handleKeyDown, inputRef: inputRef, InputProps: {
914
+ classes: inputClasses,
915
+ disableUnderline: true,
916
+ endAdornment: (React.createElement(commonUi.IconButton, { title: incrementButtonTitle, "aria-controls": id, "aria-disabled": isAtMax || disabled, tabIndex: -1, className: endAdornmentClasses.root, color: "default", onClick: onIncrement, disabled: disabled || isAtMax },
917
+ React.createElement(commonUi.Icon, { icon: webIcons.PlusCircle, "aria-hidden": "true" }))),
918
+ startAdornment: (React.createElement(commonUi.IconButton, { title: decrementButtonTitle, "aria-controls": id, "aria-disabled": isAtMin || disabled, tabIndex: -1, className: startAdornmentClasses.root, color: "default", onClick: onDecrement, disabled: disabled || isAtMin },
919
+ React.createElement(commonUi.Icon, { icon: webIcons.MinusCircle, "aria-hidden": "true" }))),
920
+ }, inputProps: {
921
+ role: 'spinbutton',
922
+ inputMode: 'numeric',
923
+ 'aria-label': `${name} quantity`,
924
+ 'aria-valuenow': value,
925
+ 'aria-valuemin': min,
926
+ 'aria-valuemax': max,
927
+ } }),
928
+ React.createElement("output", { "aria-live": "polite", style: {
929
+ position: 'absolute',
930
+ width: 1,
931
+ height: 1,
932
+ padding: 0,
933
+ margin: -1,
934
+ overflow: 'hidden',
935
+ clip: 'rect(0, 0, 0, 0)',
936
+ whiteSpace: 'nowrap',
937
+ border: 0,
938
+ } }, liveRegionMessage)));
783
939
  };
784
940
 
785
941
  const Label = (props) => {
786
942
  const { name, price, disabled = false, hidePrice = false } = props;
787
943
  const classes = useLabelStyles();
788
- const priceLabel = hidePrice ? React.createElement(React.Fragment, null, "\u00A0") : `+ ${price}`;
944
+ const numericPrice = price ? parseFloat(price.replace(/[^0-9.-]/g, '')) : NaN;
945
+ const shouldHidePrice = hidePrice || !price || numericPrice === 0 || isNaN(numericPrice);
789
946
  return (React.createElement(core.Box, { display: "flex", flexDirection: "column", className: classes.label },
790
947
  React.createElement(core.Box, { display: "flex", alignItems: "center", gridGap: 8 },
791
948
  React.createElement(core.Typography, { className: classNames({ [classes.disabled]: disabled }) }, name)),
792
- price && (React.createElement(core.Typography, { className: classNames({ [classes.price]: !disabled }, { [classes.disabled]: disabled }) }, priceLabel))));
949
+ !shouldHidePrice && (React.createElement(core.Typography, { className: classNames({ [classes.price]: !disabled }, { [classes.disabled]: disabled }) }, `+ ${price}`))));
793
950
  };
794
951
  const Options = (props) => {
795
952
  const { handleOptionsClick } = props;
@@ -817,7 +974,7 @@ const SingleSelectModifierControl = (props) => {
817
974
  });
818
975
  };
819
976
  return (React.createElement(core.FormControl, { fullWidth: true },
820
- React.createElement(core.RadioGroup, { "aria-label": name }, modifiers.map((modifier) => (React.createElement(core.Box, { key: modifier.id },
977
+ React.createElement(core.RadioGroup, { className: radioClasses.radioGroup, "aria-label": name }, modifiers.map((modifier) => (React.createElement(core.Box, { key: modifier.id },
821
978
  React.createElement(core.FormControlLabel, { key: modifier.id, value: modifier.id, className: radioClasses.root, control: React.createElement(core.Radio, { checked: value[0]?.modifierId === modifier.id, className: classNames({
822
979
  [radioClasses.hideRadio]: modifier.outOfStock,
823
980
  [radioClasses.radio]: !modifier.outOfStock,
@@ -845,7 +1002,7 @@ const MultipleSelectControl = (props) => {
845
1002
  });
846
1003
  };
847
1004
  return (React.createElement(core.FormControl, { fullWidth: true },
848
- React.createElement(core.FormGroup, null, modifiers.map((modifier) => {
1005
+ React.createElement(core.FormGroup, { className: classes.formGroup }, modifiers.map((modifier) => {
849
1006
  return (React.createElement(core.Box, { key: modifier.id },
850
1007
  React.createElement(core.FormControlLabel, { key: modifier.id, value: modifier.id, className: classes.root, checked: value.some((v) => v.modifierId === modifier.id), onChange: makeHandleChange(modifier), control: React.createElement(core.Checkbox, { className: classNames({ [classes.hideCheckbox]: modifier.outOfStock }, { [classes.checkbox]: !modifier.outOfStock }), disabled: isOutOfStock || modifier.outOfStock || (!modifier.quantity && disableNewSelections) }), label: React.createElement(core.Box, { className: classes.label },
851
1008
  React.createElement(Label, { name: modifier.name, price: aggregatePrice[modifier.id] || modifier.formattedPrice, disabled: isOutOfStock || modifier.outOfStock, hidePrice: modifier.hidePrice }),
@@ -872,7 +1029,7 @@ const MultipleQuantitySelectControl = (props) => {
872
1029
  React.createElement(Label, { name: modifier.name, price: modifier.formattedPrice, disabled: isOutOfStock || modifier.outOfStock, hidePrice: modifier.hidePrice }),
873
1030
  modifier.outOfStock && (React.createElement(core.Box, { minWidth: "90px", marginLeft: 2 },
874
1031
  React.createElement(StatusTag, { color: "warning", label: "Out of stock", variant: "outlined", size: "md" }))),
875
- !modifier.outOfStock && (React.createElement(QuantityPicker, { variation: "modifierCount", value: modifier.quantity, disableIncrement: disableNewSelections, preventManualChange: true, onChange: makeHandleChange(modifier), disabled: isOutOfStock || modifier.outOfStock, name: modifier.name }))),
1032
+ !modifier.outOfStock && (React.createElement(QuantityPicker, { incrementButtonTitle: `Add ${modifier.name}`, decrementButtonTitle: `Remove ${modifier.name}`, id: `${modifier.id}-quantity-picker`, variation: "modifierCount", value: modifier.quantity, disableIncrement: disableNewSelections, preventManualChange: true, onChange: makeHandleChange(modifier), disabled: isOutOfStock || modifier.outOfStock, name: modifier.name }))),
876
1033
  React.createElement(core.Box, { display: "flex", alignItems: "flex-start", gridGap: 4 },
877
1034
  modifier.hasModifiers && !modifier.outOfStock && (React.createElement(Options, { handleOptionsClick: () => handleOptionsClick(modifier.id) })),
878
1035
  selectionQuantity[modifier.id] &&
@@ -1171,66 +1328,63 @@ const MenuFilter = (props) => {
1171
1328
 
1172
1329
  const useSelectableChipStyles = core.makeStyles((theme) => ({
1173
1330
  root: {
1174
- border: '2px solid',
1175
- borderColor: theme.palette.grey[100],
1331
+ border: '2px solid transparent',
1176
1332
  borderRadius: '50px',
1333
+ boxSizing: 'border-box',
1177
1334
  backgroundColor: theme.palette.grey[100],
1178
- color: theme.palette.grey[900],
1335
+ color: theme.palette.text.primary,
1336
+ display: 'block',
1179
1337
  padding: theme.spacing(1, 2),
1180
- fontSize: '0.875rem',
1181
- fontWeight: 400,
1182
- minWidth: 'unset',
1183
- minHeight: 'unset',
1184
- opacity: 'unset',
1185
- textTransform: 'none',
1186
- textAlign: 'left',
1187
1338
  '&:hover': {
1188
- boxShadow: '0px 0px 0px 1px #757575',
1339
+ boxShadow: `0px 0px 0px 1px ${theme.palette.grey[100]}`,
1189
1340
  },
1190
1341
  '&::-webkit-scrollbar': {
1191
1342
  display: 'none',
1192
1343
  },
1193
- '&.Mui-selected': {
1194
- backgroundColor: theme.palette.grey[100],
1195
- borderColor: '#0A202F',
1196
- color: theme.palette.grey[900],
1197
- fontWeight: 400,
1198
- '&:hover': {
1199
- background: theme.palette.grey[100],
1200
- boxShadow: 'none',
1201
- },
1202
- },
1344
+ },
1345
+ selected: {
1346
+ fontWeight: 500,
1347
+ border: `2px solid ${theme.palette.text.primary}`,
1203
1348
  },
1204
1349
  }));
1205
1350
 
1206
1351
  const SelectableChip = (props) => {
1352
+ const { href, value, label, onClick, selected } = props;
1207
1353
  const classes = useSelectableChipStyles(props);
1208
- return (React.createElement(core.Tab, { "data-tab-for-section-id": props.value, classes: {
1209
- root: classes.root,
1210
- selected: classes.selected,
1211
- }, ...props }));
1354
+ const handleClick = (event) => {
1355
+ event.preventDefault();
1356
+ onClick(event, value);
1357
+ };
1358
+ const handleKeyDown = (event) => {
1359
+ if (event.key === ' ') {
1360
+ event.preventDefault();
1361
+ onClick(event, value);
1362
+ }
1363
+ };
1364
+ return (React.createElement("li", null,
1365
+ React.createElement(core.Typography, { variant: "body2" },
1366
+ React.createElement("a", { href: href, className: classNames({ [classes.root]: true, [classes.selected]: selected }), onClick: handleClick, onKeyDown: handleKeyDown, "aria-current": selected ? 'true' : undefined }, label))));
1212
1367
  };
1213
1368
 
1214
1369
  const useSelectableChipGroupStyles = core.makeStyles(({ breakpoints, spacing }) => ({
1215
1370
  flexContainer: {
1216
1371
  [breakpoints.up('lg')]: {
1372
+ flexDirection: 'column',
1217
1373
  alignItems: 'flex-start',
1218
1374
  },
1375
+ display: 'flex',
1219
1376
  gridGap: spacing(1.5),
1377
+ listStyle: 'none',
1220
1378
  padding: 2,
1221
- },
1222
- flexContainerVertical: {
1223
- gridGap: spacing(1.5),
1224
- padding: 2,
1379
+ margin: 0,
1225
1380
  },
1226
1381
  }));
1227
1382
 
1228
1383
  const SelectableChipGroup = (props) => {
1229
- const { children, ...muiProps } = props;
1230
- const classes = useSelectableChipGroupStyles(props);
1231
- return (React.createElement(core.Tabs, { TabIndicatorProps: {
1232
- hidden: true,
1233
- }, variant: "scrollable", scrollButtons: "off", classes: classes, ...muiProps }, children));
1384
+ const { children, ...restProps } = props;
1385
+ const classes = useSelectableChipGroupStyles();
1386
+ return (React.createElement("nav", { ...restProps },
1387
+ React.createElement("ul", { className: classes.flexContainer }, children)));
1234
1388
  };
1235
1389
 
1236
1390
  const useStyles$4 = core.makeStyles(({ spacing }) => ({
@@ -1268,7 +1422,7 @@ const MenuSection = React.forwardRef((props, ref) => {
1268
1422
  const classes = useStyles$3();
1269
1423
  return (React.createElement(core.Box, { ...restProps, ref, component: 'section', "data-component-type": "menu-section", style: { scrollMarginTop: '70px' } },
1270
1424
  React.createElement(core.Box, { marginTop: 1, marginBottom: 4 },
1271
- React.createElement(core.Typography, { component: "h1", className: classes.title }, loading ? React.createElement(lab.Skeleton, null) : name)),
1425
+ React.createElement(core.Typography, { component: "h2", className: classes.title, tabIndex: -1 }, loading ? React.createElement(lab.Skeleton, null) : name)),
1272
1426
  children));
1273
1427
  });
1274
1428
  MenuSection.displayName = 'MenuSection';
@@ -1537,6 +1691,14 @@ const overrides = {
1537
1691
  },
1538
1692
  },
1539
1693
  },
1694
+ MuiOutlinedInput: {
1695
+ input: {
1696
+ '&::placeholder': {
1697
+ color: '#757575',
1698
+ opacity: 1,
1699
+ },
1700
+ },
1701
+ },
1540
1702
  MuiInputLabel: {
1541
1703
  root: {
1542
1704
  color: '#757575',
@@ -1561,12 +1723,39 @@ const overrides = {
1561
1723
  },
1562
1724
  inputMultiline: {},
1563
1725
  },
1726
+ MuiRadio: {
1727
+ root: {
1728
+ '&.Mui-focusVisible': {
1729
+ outline: `2px solid ${palette.info.main} !important`,
1730
+ },
1731
+ },
1732
+ },
1564
1733
  MuiCssBaseline: {
1565
1734
  '@global': {
1735
+ a: {
1736
+ color: 'inherit',
1737
+ textDecoration: 'none',
1738
+ fontWeight: 'inherit',
1739
+ '&:hover': {
1740
+ color: 'inherit',
1741
+ textDecoration: 'none',
1742
+ },
1743
+ '&:focus': {
1744
+ color: 'inherit',
1745
+ textDecoration: 'none',
1746
+ },
1747
+ '&:active': {
1748
+ color: 'inherit',
1749
+ textDecoration: 'none',
1750
+ },
1751
+ '&:visited': {
1752
+ color: 'inherit',
1753
+ textDecoration: 'none',
1754
+ },
1755
+ },
1566
1756
  '*:focus-visible, a:focus-visible': {
1567
1757
  '&': {
1568
1758
  outline: `2px solid ${palette.info.main} !important`,
1569
- borderRadius: 8,
1570
1759
  },
1571
1760
  },
1572
1761
  'sr-only': {
@@ -1589,6 +1778,11 @@ const props = {
1589
1778
  disableElevation: true,
1590
1779
  disableFocusRipple: true,
1591
1780
  },
1781
+ MuiDialog: {
1782
+ PaperProps: {
1783
+ 'aria-modal': 'true',
1784
+ },
1785
+ },
1592
1786
  MuiDialogTitle: {
1593
1787
  disableTypography: true,
1594
1788
  },
@@ -1598,6 +1792,10 @@ const props = {
1598
1792
  MuiTab: {
1599
1793
  disableFocusRipple: true,
1600
1794
  },
1795
+ MuiPaper: {
1796
+ elevation: 0,
1797
+ square: true,
1798
+ },
1601
1799
  };
1602
1800
 
1603
1801
  const fonts = ['"Poppins"', '"sans-serif"'];