@mackin.com/styleguide 9.9.1 → 9.11.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 (4) hide show
  1. package/index.d.ts +53 -45
  2. package/index.esm.js +254 -178
  3. package/index.js +254 -178
  4. package/package.json +1 -1
package/index.d.ts CHANGED
@@ -440,6 +440,51 @@ interface OmniLinkProps extends LinkProps {
440
440
  }
441
441
  declare const OmniLink: (props: OmniLinkProps) => JSX.Element;
442
442
 
443
+ interface PagedResultDto<T> {
444
+ total: number;
445
+ /** The zero-based page index. */
446
+ page: number;
447
+ limit: number;
448
+ items: T[];
449
+ }
450
+
451
+ /** A page of data with helpers props. */
452
+ declare class PagedResult<T> {
453
+ constructor(items?: T[], total?: number, page?: number, limit?: number);
454
+ /** @deprecated Use fromPagedResultDto going forward. */
455
+ static fromDto<T>(dto: {
456
+ [key: string]: any;
457
+ }): PagedResult<T>;
458
+ static fromPagedResultDto<TDto, TDomain>(dto: PagedResultDto<TDto>, convert?: (dto: TDto) => TDomain): PagedResult<TDomain>;
459
+ total: number;
460
+ /** The zero-based page index. */
461
+ page: number;
462
+ limit: number;
463
+ items: T[];
464
+ /** Helper for items.length */
465
+ get length(): number;
466
+ get hasItems(): boolean;
467
+ get previousPage(): number;
468
+ get hasPrevious(): boolean;
469
+ get nextPage(): number;
470
+ get hasNext(): boolean;
471
+ get lastPage(): number;
472
+ get totalPages(): number;
473
+ get minPageItemIndex(): number;
474
+ get maxPageItemIndex(): number;
475
+ /** Returns the first item on the current page. */
476
+ get firstPageItem(): T;
477
+ /** Returns the last item on the current page */
478
+ get lastPageItem(): T;
479
+ getPageRelativeItemIndex(item: T): number;
480
+ getResultRelativeItemIndex(item: T): number | undefined;
481
+ getPreviousItem(fromItem: T): T | undefined;
482
+ getNextItem(fromItem: T): T | undefined;
483
+ getPagingRange(radius: number): number[];
484
+ toJSON(): PagedResultDto<T>;
485
+ clone(newItems?: T[]): PagedResult<T>;
486
+ }
487
+
443
488
  declare type SortDirection = 'asc' | 'desc';
444
489
  interface PagerSortOption<TItem> {
445
490
  id: string;
@@ -492,6 +537,8 @@ declare class ItemPager<TItem> {
492
537
  * @param sortId The ID or partial ID (no '-asc' or '-desc') of a sort option created through addToggleSortOption
493
538
  */
494
539
  toggleSort(sortId: string): void;
540
+ /** Filters the current results by the filtering function ONCE.
541
+ * You will need to re-add the filter if the contents of the filtering function changes. */
495
542
  applyFilter(filter?: (item: TItem) => boolean, keepPage?: boolean): void;
496
543
  next(): void;
497
544
  previous(): void;
@@ -501,6 +548,8 @@ declare class ItemPager<TItem> {
501
548
  /** Removes the matched item(s). */
502
549
  remove(comparer: (item: TItem) => boolean, keepPage?: boolean): void;
503
550
  replace(newItem: TItem, comparer: (item: TItem) => boolean): void;
551
+ /** Returns a clone of the underlying PagedResult. */
552
+ toPagedResult(): PagedResult<TItem>;
504
553
  private _allItems;
505
554
  private _page;
506
555
  private _limit;
@@ -572,51 +621,6 @@ interface Props<T> extends PagerStyleProps {
572
621
  }
573
622
  declare const BoundStaticPager: <T>(p: Props<T>) => JSX.Element;
574
623
 
575
- interface PagedResultDto<T> {
576
- total: number;
577
- /** The zero-based page index. */
578
- page: number;
579
- limit: number;
580
- items: T[];
581
- }
582
-
583
- /** A page of data with helpers props. */
584
- declare class PagedResult<T> {
585
- constructor(items?: T[], total?: number, page?: number, limit?: number);
586
- /** @deprecated Use fromPagedResultDto going forward. */
587
- static fromDto<T>(dto: {
588
- [key: string]: any;
589
- }): PagedResult<T>;
590
- static fromPagedResultDto<TDto, TDomain>(dto: PagedResultDto<TDto>, convert?: (dto: TDto) => TDomain): PagedResult<TDomain>;
591
- total: number;
592
- /** The zero-based page index. */
593
- page: number;
594
- limit: number;
595
- items: T[];
596
- /** Helper for items.length */
597
- get length(): number;
598
- get hasItems(): boolean;
599
- get previousPage(): number;
600
- get hasPrevious(): boolean;
601
- get nextPage(): number;
602
- get hasNext(): boolean;
603
- get lastPage(): number;
604
- get totalPages(): number;
605
- get minPageItemIndex(): number;
606
- get maxPageItemIndex(): number;
607
- /** Returns the first item on the current page. */
608
- get firstPageItem(): T;
609
- /** Returns the last item on the current page */
610
- get lastPageItem(): T;
611
- getPageRelativeItemIndex(item: T): number;
612
- getResultRelativeItemIndex(item: T): number | undefined;
613
- getPreviousItem(fromItem: T): T | undefined;
614
- getNextItem(fromItem: T): T | undefined;
615
- getPagingRange(radius: number): number[];
616
- toJSON(): PagedResultDto<T>;
617
- clone(newItems?: T[]): PagedResult<T>;
618
- }
619
-
620
624
  declare type PickerValue = string | number;
621
625
  declare type PickerOption<T> = T | {
622
626
  id: T;
@@ -1069,6 +1073,7 @@ interface LinkContentProps {
1069
1073
  rightIcon?: JSX.Element;
1070
1074
  leftIcon?: JSX.Element;
1071
1075
  children?: ReactNode;
1076
+ waiting?: boolean;
1072
1077
  }
1073
1078
 
1074
1079
  interface LinkProps extends LinkContentProps, React.DetailedHTMLProps<React.AnchorHTMLAttributes<HTMLAnchorElement>, HTMLAnchorElement> {
@@ -1082,6 +1087,9 @@ interface LinkProps extends LinkContentProps, React.DetailedHTMLProps<React.Anch
1082
1087
  round?: boolean;
1083
1088
  /** Only for button variants. */
1084
1089
  small?: boolean;
1090
+ /** Only for button variants. */
1091
+ waiting?: boolean;
1092
+ disabled?: boolean;
1085
1093
  /** Overrides the `theme.colors.link` for non-button variants or `theme.colors.font` for the `button` variant. Does not apply to themed button variants like `primary`. */
1086
1094
  colorOverride?: string;
1087
1095
  }
package/index.esm.js CHANGED
@@ -318,7 +318,7 @@ const Button = React.forwardRef((props, ref) => {
318
318
  z-index: 2;
319
319
  }
320
320
 
321
- &:active {
321
+ &:active:not(:disabled) {
322
322
  box-shadow: none;
323
323
  }
324
324
 
@@ -2790,7 +2790,7 @@ const LinkContent = (props) => {
2790
2790
  minWidth: '1.5rem',
2791
2791
  verticalAlign: 'middle'
2792
2792
  }) }, props.leftIcon),
2793
- props.children),
2793
+ props.waiting ? React.createElement(Icon, { id: "waiting", spin: true }) : props.children),
2794
2794
  props.rightIcon && React.createElement("span", { className: css({
2795
2795
  label: 'LinkRightIcon',
2796
2796
  marginLeft: '1rem',
@@ -2800,179 +2800,241 @@ const LinkContent = (props) => {
2800
2800
 
2801
2801
  //TB: FUTURE de-dup these styles. create individual styles and compose them manually.
2802
2802
  const generateLinkStyles = (props, theme) => {
2803
- var _a, _b, _c, _d, _e;
2804
- const linkStyles = css `
2805
- label: Link;
2806
- display: inline-block;
2807
- cursor: pointer;
2808
- text-decoration: none;
2809
- color: ${(_a = props.colorOverride) !== null && _a !== void 0 ? _a : theme.colors.link};
2810
- transition: ${theme.controls.transition};
2811
- &:hover {
2812
- filter: ${theme.controls.hoverBrightness};
2813
- text-decoration: underline;
2814
- }
2815
- &:active,
2816
- &:visited {
2817
- color: ${(_b = props.colorOverride) !== null && _b !== void 0 ? _b : theme.colors.link};
2818
- }
2819
- &:focus {
2820
- text-decoration: underline;
2821
- outline: none;
2822
- color: ${(_c = props.colorOverride) !== null && _c !== void 0 ? _c : theme.colors.link};
2823
- }
2824
- ${!!props.variant && `
2825
- padding-left: ${theme.controls.padding};
2826
- padding-right: ${theme.controls.padding};
2827
- border: ${theme.controls.border};
2828
- border-radius: ${theme.controls.borderRadius};
2829
- box-shadow: ${theme.controls.buttonBoxShadow};
2830
- height: ${theme.controls.height};
2831
- line-height: ${theme.controls.height};
2832
- font-weight: bold;
2833
- color: ${(_d = props.colorOverride) !== null && _d !== void 0 ? _d : theme.colors.font};
2834
- &:active,
2835
- &:focus,
2836
- &:visited {
2837
- color: ${(_e = props.colorOverride) !== null && _e !== void 0 ? _e : theme.colors.font};
2838
- }
2839
- &:focus {
2840
- outline: none;
2841
- box-shadow: ${theme.controls.focusOutlineShadow};
2842
- text-decoration: none;
2843
- }
2844
- &:active {
2845
- box-shadow: none;
2846
- }
2847
- &:hover {
2848
- text-decoration: none;
2849
- }
2850
- `}
2851
- ${props.variant === 'button' && `
2852
- text-align: center;
2853
- &:hover {
2854
- background-color: ${theme.controls.hoverBackground};
2855
- }
2856
- `}
2857
- ${props.variant === 'circle' && `
2858
- text-align: center;
2859
- &:hover {
2860
- background-color: ${theme.controls.hoverBackground};
2861
- }
2862
- width: ${theme.controls.height};
2863
- border-radius: 100%;
2864
- display: flex;
2865
- justify-content: center;
2866
- align-items: center;
2867
- ${props.small && `
2868
- width: ${theme.controls.heightSmall};
2869
- min-width: ${theme.controls.heightSmall};
2870
- `}
2871
- `}
2872
- ${props.variant === 'primary' && `
2873
- text-align: center;
2874
- background-color: ${theme.colors.primary};
2875
- color: ${theme.colors.primaryFont};
2876
- &:active,
2877
- &:focus,
2878
- &:visited {
2879
- color: ${theme.colors.primaryFont};
2880
- }
2881
- `}
2882
- ${props.variant === 'primary2' && `
2883
- text-align: center;
2884
- background-color: ${theme.colors.primary2};
2885
- color: ${theme.colors.primary2Font};
2886
- &:active,
2887
- &:focus,
2888
- &:visited {
2889
- color: ${theme.colors.primary2Font};
2890
- }
2891
- `}
2892
- ${props.variant === 'secondary' && `
2893
- text-align: center;
2894
- background-color: ${theme.colors.secondary};
2895
- color: ${theme.colors.secondary2Font};
2896
- &:active,
2897
- &:focus,
2898
- &:visited {
2899
- color: ${theme.colors.secondary2Font};
2900
- }
2901
- `}
2902
- ${props.variant === 'positive' && `
2903
- text-align: center;
2904
- background-color: ${theme.colors.positive};
2905
- color: ${theme.colors.positiveFont};
2906
- &:active,
2907
- &:focus,
2908
- &:visited {
2909
- color: ${theme.colors.positiveFont};
2910
- }
2911
- `}
2912
- ${props.variant === 'negative' && `
2913
- text-align: center;
2914
- background-color: ${theme.colors.negative};
2915
- color: ${theme.colors.negativeFont};
2916
- &:active,
2917
- &:focus,
2918
- &:visited {
2919
- color: ${theme.colors.negativeFont};
2920
- }
2921
- `}
2922
- ${props.variant === 'omg' && `
2923
- text-align: center;
2924
- background-color: ${theme.colors.omg};
2925
- color: ${theme.colors.omgFont};
2926
- &:active,
2927
- &:focus,
2928
- &:visited {
2929
- color: ${theme.colors.omgFont};
2930
- }
2931
- `}
2932
- ${props.variant === 'label' && `
2933
- box-shadow: none;
2934
- border: none;
2935
- &:hover {
2936
- background-color: ${theme.controls.hoverBackground};
2937
- }
2938
- `}
2939
- ${props.variant === 'text' && `
2940
- font-weight: normal;
2941
- box-shadow: none;
2942
- border: none;
2943
- cursor: auto;
2944
- `}
2945
- ${props.variant === 'icon' && `
2946
- box-shadow: none;
2947
- border: none;
2948
- border-radius: 100%;
2949
- width: ${theme.controls.height};
2950
- text-align: center;
2951
- font-size: 1.6rem;
2952
- padding-left: 0;
2953
- padding-right: 0;
2954
- &:hover {
2955
- background-color: ${theme.controls.hoverBackground};
2956
- }
2957
- `}
2958
- ${props.block && `
2959
- display: block;
2960
- width:100%;
2961
- `}
2962
- ${props.iconBlock && `
2963
- display: flex;
2964
- justify-content: space-between;
2965
- align-items: center;
2966
- `}
2967
- ${props.round && `
2968
- border-radius: ${theme.controls.roundRadius};
2969
- `}
2970
- ${props.small && `
2971
- font-size: 0.8rem;
2972
- height: ${theme.controls.heightSmall};
2973
- line-height: ${theme.controls.heightSmall};
2974
- `}
2975
- `;
2803
+ const disabled = props.disabled || props.waiting;
2804
+ let color = props.colorOverride;
2805
+ if (!color) {
2806
+ if (!props.variant) {
2807
+ color = theme.colors.link;
2808
+ }
2809
+ else {
2810
+ switch (props.variant) {
2811
+ case 'primary':
2812
+ color = theme.colors.primaryFont;
2813
+ break;
2814
+ case 'primary2':
2815
+ color = theme.colors.primary2Font;
2816
+ break;
2817
+ case 'secondary':
2818
+ color = theme.colors.secondaryFont;
2819
+ break;
2820
+ case 'positive':
2821
+ color = theme.colors.positiveFont;
2822
+ break;
2823
+ case 'negative':
2824
+ color = theme.colors.negativeFont;
2825
+ break;
2826
+ case 'omg':
2827
+ color = theme.colors.omgFont;
2828
+ break;
2829
+ default:
2830
+ color = theme.colors.font;
2831
+ break;
2832
+ }
2833
+ }
2834
+ }
2835
+ const linkStyles = cx([
2836
+ css({
2837
+ label: 'Link',
2838
+ display: 'inline-block',
2839
+ cursor: 'pointer',
2840
+ textDecoration: 'none',
2841
+ color,
2842
+ transition: theme.controls.transition,
2843
+ ':active': {
2844
+ color,
2845
+ },
2846
+ ':visited': {
2847
+ color,
2848
+ },
2849
+ ':focus': {
2850
+ outline: 'none',
2851
+ textDecorationLine: 'underline',
2852
+ color,
2853
+ },
2854
+ ':hover': {
2855
+ filter: theme.controls.hoverBrightness,
2856
+ textDecoration: 'underline'
2857
+ }
2858
+ }),
2859
+ disabled ? css({
2860
+ opacity: theme.controls.disabledOpacity,
2861
+ cursor: 'not-allowed',
2862
+ textDecoration: 'none !important'
2863
+ }) : undefined,
2864
+ // all variants
2865
+ props.variant ? css({
2866
+ paddingLeft: theme.controls.padding,
2867
+ paddingRight: theme.controls.padding,
2868
+ border: theme.controls.border,
2869
+ borderRadius: theme.controls.borderRadius,
2870
+ boxShadow: theme.controls.buttonBoxShadow,
2871
+ height: theme.controls.height,
2872
+ lineHeight: theme.controls.height,
2873
+ fontWeight: 'bold',
2874
+ color,
2875
+ ':active': {
2876
+ color,
2877
+ boxShadow: 'none'
2878
+ },
2879
+ ':focus': {
2880
+ color,
2881
+ outline: 'none',
2882
+ boxShadow: disabled ? theme.controls.buttonBoxShadow : theme.controls.focusOutlineShadow,
2883
+ textDecoration: 'none'
2884
+ },
2885
+ ':visited': {
2886
+ color,
2887
+ },
2888
+ ':hover': {
2889
+ textDecoration: 'none'
2890
+ }
2891
+ }) : undefined,
2892
+ props.variant === 'button' ? css({
2893
+ textAlign: 'center',
2894
+ ':hover': {
2895
+ backgroundColor: disabled ? undefined : theme.controls.hoverBackground
2896
+ }
2897
+ }) : undefined,
2898
+ props.variant === 'circle' ? css({
2899
+ textAlign: 'center',
2900
+ ':hover': {
2901
+ backgroundColor: disabled ? undefined : theme.controls.hoverBackground
2902
+ },
2903
+ width: props.small ? theme.controls.heightSmall : theme.controls.height,
2904
+ minWidth: props.small ? theme.controls.heightSmall : undefined,
2905
+ borderRadius: '100%',
2906
+ display: 'flex',
2907
+ justifyContent: 'center',
2908
+ alignItems: 'center',
2909
+ }) : undefined,
2910
+ props.variant === 'primary' ? css({
2911
+ textAlign: 'center',
2912
+ backgroundColor: theme.colors.primary,
2913
+ color,
2914
+ ':active': {
2915
+ color,
2916
+ },
2917
+ ':focus': {
2918
+ color,
2919
+ },
2920
+ ':visited': {
2921
+ color,
2922
+ }
2923
+ }) : undefined,
2924
+ props.variant === 'primary2' ? css({
2925
+ textAlign: 'center',
2926
+ backgroundColor: theme.colors.primary2,
2927
+ color,
2928
+ ':active': {
2929
+ color,
2930
+ },
2931
+ ':focus': {
2932
+ color,
2933
+ },
2934
+ ':visited': {
2935
+ color,
2936
+ }
2937
+ }) : undefined,
2938
+ props.variant === 'secondary' ? css({
2939
+ textAlign: 'center',
2940
+ backgroundColor: theme.colors.secondary,
2941
+ color,
2942
+ ':active': {
2943
+ color,
2944
+ },
2945
+ ':focus': {
2946
+ color,
2947
+ },
2948
+ ':visited': {
2949
+ color,
2950
+ }
2951
+ }) : undefined,
2952
+ props.variant === 'positive' ? css({
2953
+ textAlign: 'center',
2954
+ backgroundColor: theme.colors.positive,
2955
+ color,
2956
+ ':active': {
2957
+ color,
2958
+ },
2959
+ ':focus': {
2960
+ color,
2961
+ },
2962
+ ':visited': {
2963
+ color,
2964
+ }
2965
+ }) : undefined,
2966
+ props.variant === 'negative' ? css({
2967
+ textAlign: 'center',
2968
+ backgroundColor: theme.colors.negative,
2969
+ color,
2970
+ ':active': {
2971
+ color,
2972
+ },
2973
+ ':focus': {
2974
+ color,
2975
+ },
2976
+ ':visited': {
2977
+ color,
2978
+ }
2979
+ }) : undefined,
2980
+ props.variant === 'omg' ? css({
2981
+ textAlign: 'center',
2982
+ backgroundColor: theme.colors.omg,
2983
+ color,
2984
+ ':active': {
2985
+ color,
2986
+ },
2987
+ ':focus': {
2988
+ color,
2989
+ },
2990
+ ':visited': {
2991
+ color,
2992
+ }
2993
+ }) : undefined,
2994
+ props.variant === 'label' ? css({
2995
+ boxShadow: 'none',
2996
+ border: 'none',
2997
+ ':hover': {
2998
+ backgroundColor: disabled ? undefined : theme.controls.hoverBackground
2999
+ }
3000
+ }) : undefined,
3001
+ props.variant === 'text' ? css({
3002
+ fontWeight: 'normal',
3003
+ boxShadow: 'none',
3004
+ border: 'none',
3005
+ cursor: 'auto'
3006
+ }) : undefined,
3007
+ props.variant === 'icon' ? css({
3008
+ boxShadow: 'none',
3009
+ border: 'none',
3010
+ borderRadius: '100%',
3011
+ width: theme.controls.height,
3012
+ textAlign: 'center',
3013
+ fontSize: '1.6rem',
3014
+ paddingLeft: 0,
3015
+ paddingRight: 0,
3016
+ ':hover': {
3017
+ backgroundColor: disabled ? undefined : theme.controls.hoverBackground
3018
+ }
3019
+ }) : undefined,
3020
+ props.block ? css({
3021
+ display: 'block',
3022
+ width: '100%',
3023
+ }) : undefined,
3024
+ props.iconBlock ? css({
3025
+ display: 'flex',
3026
+ justifyContent: 'space-between',
3027
+ alignItems: 'center'
3028
+ }) : undefined,
3029
+ props.round ? css({
3030
+ borderRadius: theme.controls.roundRadius
3031
+ }) : undefined,
3032
+ props.small ? css({
3033
+ fontSize: '0.8rem',
3034
+ height: theme.controls.heightSmall,
3035
+ lineHeight: theme.controls.heightSmall
3036
+ }) : undefined
3037
+ ]);
2976
3038
  return linkStyles;
2977
3039
  };
2978
3040
 
@@ -2988,7 +3050,11 @@ const OmniLink = (props) => {
2988
3050
  if (props.noRouter) {
2989
3051
  return (React.createElement("a", Object.assign({}, linkProps, { target: props.target, className: mainClassName }), content));
2990
3052
  }
2991
- return (React.createElement(Link$1, Object.assign({}, linkProps, { className: mainClassName, to: props.href }), content));
3053
+ const isDisabled = props.disabled || props.waiting;
3054
+ return (React.createElement(Link$1, Object.assign({}, linkProps, { className: mainClassName, to: props.href, onClick: isDisabled ? e => {
3055
+ e.stopPropagation();
3056
+ e.preventDefault();
3057
+ } : undefined }), content));
2992
3058
  };
2993
3059
 
2994
3060
  const roundPxPadding = '4px';
@@ -3481,6 +3547,8 @@ class ItemPager {
3481
3547
  }
3482
3548
  this.sort = nextSort;
3483
3549
  }
3550
+ /** Filters the current results by the filtering function ONCE.
3551
+ * You will need to re-add the filter if the contents of the filtering function changes. */
3484
3552
  applyFilter(filter, keepPage) {
3485
3553
  this._currentFilter = filter;
3486
3554
  if (!this._currentFilter) {
@@ -3541,6 +3609,10 @@ class ItemPager {
3541
3609
  });
3542
3610
  this.applyFilter(this._currentFilter, true);
3543
3611
  }
3612
+ /** Returns a clone of the underlying PagedResult. */
3613
+ toPagedResult() {
3614
+ return this.createPageResult();
3615
+ }
3544
3616
  createPageResult() {
3545
3617
  const page = new PagedResult([], this._filteredItems.length, this.page, this.limit);
3546
3618
  page.items = this._filteredItems.slice(page.minPageItemIndex, page.maxPageItemIndex + 1) || [];
@@ -4583,14 +4655,18 @@ const enumToEntities = (enumObj) => {
4583
4655
  };
4584
4656
 
4585
4657
  const Link = (props) => {
4586
- const { rightIcon, leftIcon, block, iconBlock, variant, round, small, colorOverride, children, ref } = props, linkProps = __rest(props, ["rightIcon", "leftIcon", "block", "iconBlock", "variant", "round", "small", "colorOverride", "children", "ref"]);
4658
+ const { rightIcon, leftIcon, block, iconBlock, variant, round, small, colorOverride, children, disabled, ref, waiting } = props, linkProps = __rest(props, ["rightIcon", "leftIcon", "block", "iconBlock", "variant", "round", "small", "colorOverride", "children", "disabled", "ref", "waiting"]);
4587
4659
  const theme = useThemeSafely();
4588
4660
  const linkStyles = generateLinkStyles(props, theme);
4589
4661
  const mainClassName = cx('link', linkStyles, props.className);
4590
4662
  if (variant === 'text') {
4591
4663
  return React.createElement(Text, { className: mainClassName, tag: "div" }, props.children);
4592
4664
  }
4593
- return (React.createElement("a", Object.assign({}, linkProps, { target: props.target, className: mainClassName }),
4665
+ const isDisabled = props.disabled || props.waiting;
4666
+ return (React.createElement("a", Object.assign({}, linkProps, { tabIndex: disabled ? -1 : undefined, target: props.target, className: mainClassName, onClick: isDisabled ? e => {
4667
+ e.stopPropagation();
4668
+ e.preventDefault();
4669
+ } : undefined }),
4594
4670
  React.createElement(LinkContent, Object.assign({}, props))));
4595
4671
  };
4596
4672
 
package/index.js CHANGED
@@ -345,7 +345,7 @@ const Button = React__namespace.forwardRef((props, ref) => {
345
345
  z-index: 2;
346
346
  }
347
347
 
348
- &:active {
348
+ &:active:not(:disabled) {
349
349
  box-shadow: none;
350
350
  }
351
351
 
@@ -2817,7 +2817,7 @@ const LinkContent = (props) => {
2817
2817
  minWidth: '1.5rem',
2818
2818
  verticalAlign: 'middle'
2819
2819
  }) }, props.leftIcon),
2820
- props.children),
2820
+ props.waiting ? React__namespace.createElement(Icon, { id: "waiting", spin: true }) : props.children),
2821
2821
  props.rightIcon && React__namespace.createElement("span", { className: css.css({
2822
2822
  label: 'LinkRightIcon',
2823
2823
  marginLeft: '1rem',
@@ -2827,179 +2827,241 @@ const LinkContent = (props) => {
2827
2827
 
2828
2828
  //TB: FUTURE de-dup these styles. create individual styles and compose them manually.
2829
2829
  const generateLinkStyles = (props, theme) => {
2830
- var _a, _b, _c, _d, _e;
2831
- const linkStyles = css.css `
2832
- label: Link;
2833
- display: inline-block;
2834
- cursor: pointer;
2835
- text-decoration: none;
2836
- color: ${(_a = props.colorOverride) !== null && _a !== void 0 ? _a : theme.colors.link};
2837
- transition: ${theme.controls.transition};
2838
- &:hover {
2839
- filter: ${theme.controls.hoverBrightness};
2840
- text-decoration: underline;
2841
- }
2842
- &:active,
2843
- &:visited {
2844
- color: ${(_b = props.colorOverride) !== null && _b !== void 0 ? _b : theme.colors.link};
2845
- }
2846
- &:focus {
2847
- text-decoration: underline;
2848
- outline: none;
2849
- color: ${(_c = props.colorOverride) !== null && _c !== void 0 ? _c : theme.colors.link};
2850
- }
2851
- ${!!props.variant && `
2852
- padding-left: ${theme.controls.padding};
2853
- padding-right: ${theme.controls.padding};
2854
- border: ${theme.controls.border};
2855
- border-radius: ${theme.controls.borderRadius};
2856
- box-shadow: ${theme.controls.buttonBoxShadow};
2857
- height: ${theme.controls.height};
2858
- line-height: ${theme.controls.height};
2859
- font-weight: bold;
2860
- color: ${(_d = props.colorOverride) !== null && _d !== void 0 ? _d : theme.colors.font};
2861
- &:active,
2862
- &:focus,
2863
- &:visited {
2864
- color: ${(_e = props.colorOverride) !== null && _e !== void 0 ? _e : theme.colors.font};
2865
- }
2866
- &:focus {
2867
- outline: none;
2868
- box-shadow: ${theme.controls.focusOutlineShadow};
2869
- text-decoration: none;
2870
- }
2871
- &:active {
2872
- box-shadow: none;
2873
- }
2874
- &:hover {
2875
- text-decoration: none;
2876
- }
2877
- `}
2878
- ${props.variant === 'button' && `
2879
- text-align: center;
2880
- &:hover {
2881
- background-color: ${theme.controls.hoverBackground};
2882
- }
2883
- `}
2884
- ${props.variant === 'circle' && `
2885
- text-align: center;
2886
- &:hover {
2887
- background-color: ${theme.controls.hoverBackground};
2888
- }
2889
- width: ${theme.controls.height};
2890
- border-radius: 100%;
2891
- display: flex;
2892
- justify-content: center;
2893
- align-items: center;
2894
- ${props.small && `
2895
- width: ${theme.controls.heightSmall};
2896
- min-width: ${theme.controls.heightSmall};
2897
- `}
2898
- `}
2899
- ${props.variant === 'primary' && `
2900
- text-align: center;
2901
- background-color: ${theme.colors.primary};
2902
- color: ${theme.colors.primaryFont};
2903
- &:active,
2904
- &:focus,
2905
- &:visited {
2906
- color: ${theme.colors.primaryFont};
2907
- }
2908
- `}
2909
- ${props.variant === 'primary2' && `
2910
- text-align: center;
2911
- background-color: ${theme.colors.primary2};
2912
- color: ${theme.colors.primary2Font};
2913
- &:active,
2914
- &:focus,
2915
- &:visited {
2916
- color: ${theme.colors.primary2Font};
2917
- }
2918
- `}
2919
- ${props.variant === 'secondary' && `
2920
- text-align: center;
2921
- background-color: ${theme.colors.secondary};
2922
- color: ${theme.colors.secondary2Font};
2923
- &:active,
2924
- &:focus,
2925
- &:visited {
2926
- color: ${theme.colors.secondary2Font};
2927
- }
2928
- `}
2929
- ${props.variant === 'positive' && `
2930
- text-align: center;
2931
- background-color: ${theme.colors.positive};
2932
- color: ${theme.colors.positiveFont};
2933
- &:active,
2934
- &:focus,
2935
- &:visited {
2936
- color: ${theme.colors.positiveFont};
2937
- }
2938
- `}
2939
- ${props.variant === 'negative' && `
2940
- text-align: center;
2941
- background-color: ${theme.colors.negative};
2942
- color: ${theme.colors.negativeFont};
2943
- &:active,
2944
- &:focus,
2945
- &:visited {
2946
- color: ${theme.colors.negativeFont};
2947
- }
2948
- `}
2949
- ${props.variant === 'omg' && `
2950
- text-align: center;
2951
- background-color: ${theme.colors.omg};
2952
- color: ${theme.colors.omgFont};
2953
- &:active,
2954
- &:focus,
2955
- &:visited {
2956
- color: ${theme.colors.omgFont};
2957
- }
2958
- `}
2959
- ${props.variant === 'label' && `
2960
- box-shadow: none;
2961
- border: none;
2962
- &:hover {
2963
- background-color: ${theme.controls.hoverBackground};
2964
- }
2965
- `}
2966
- ${props.variant === 'text' && `
2967
- font-weight: normal;
2968
- box-shadow: none;
2969
- border: none;
2970
- cursor: auto;
2971
- `}
2972
- ${props.variant === 'icon' && `
2973
- box-shadow: none;
2974
- border: none;
2975
- border-radius: 100%;
2976
- width: ${theme.controls.height};
2977
- text-align: center;
2978
- font-size: 1.6rem;
2979
- padding-left: 0;
2980
- padding-right: 0;
2981
- &:hover {
2982
- background-color: ${theme.controls.hoverBackground};
2983
- }
2984
- `}
2985
- ${props.block && `
2986
- display: block;
2987
- width:100%;
2988
- `}
2989
- ${props.iconBlock && `
2990
- display: flex;
2991
- justify-content: space-between;
2992
- align-items: center;
2993
- `}
2994
- ${props.round && `
2995
- border-radius: ${theme.controls.roundRadius};
2996
- `}
2997
- ${props.small && `
2998
- font-size: 0.8rem;
2999
- height: ${theme.controls.heightSmall};
3000
- line-height: ${theme.controls.heightSmall};
3001
- `}
3002
- `;
2830
+ const disabled = props.disabled || props.waiting;
2831
+ let color = props.colorOverride;
2832
+ if (!color) {
2833
+ if (!props.variant) {
2834
+ color = theme.colors.link;
2835
+ }
2836
+ else {
2837
+ switch (props.variant) {
2838
+ case 'primary':
2839
+ color = theme.colors.primaryFont;
2840
+ break;
2841
+ case 'primary2':
2842
+ color = theme.colors.primary2Font;
2843
+ break;
2844
+ case 'secondary':
2845
+ color = theme.colors.secondaryFont;
2846
+ break;
2847
+ case 'positive':
2848
+ color = theme.colors.positiveFont;
2849
+ break;
2850
+ case 'negative':
2851
+ color = theme.colors.negativeFont;
2852
+ break;
2853
+ case 'omg':
2854
+ color = theme.colors.omgFont;
2855
+ break;
2856
+ default:
2857
+ color = theme.colors.font;
2858
+ break;
2859
+ }
2860
+ }
2861
+ }
2862
+ const linkStyles = css.cx([
2863
+ css.css({
2864
+ label: 'Link',
2865
+ display: 'inline-block',
2866
+ cursor: 'pointer',
2867
+ textDecoration: 'none',
2868
+ color,
2869
+ transition: theme.controls.transition,
2870
+ ':active': {
2871
+ color,
2872
+ },
2873
+ ':visited': {
2874
+ color,
2875
+ },
2876
+ ':focus': {
2877
+ outline: 'none',
2878
+ textDecorationLine: 'underline',
2879
+ color,
2880
+ },
2881
+ ':hover': {
2882
+ filter: theme.controls.hoverBrightness,
2883
+ textDecoration: 'underline'
2884
+ }
2885
+ }),
2886
+ disabled ? css.css({
2887
+ opacity: theme.controls.disabledOpacity,
2888
+ cursor: 'not-allowed',
2889
+ textDecoration: 'none !important'
2890
+ }) : undefined,
2891
+ // all variants
2892
+ props.variant ? css.css({
2893
+ paddingLeft: theme.controls.padding,
2894
+ paddingRight: theme.controls.padding,
2895
+ border: theme.controls.border,
2896
+ borderRadius: theme.controls.borderRadius,
2897
+ boxShadow: theme.controls.buttonBoxShadow,
2898
+ height: theme.controls.height,
2899
+ lineHeight: theme.controls.height,
2900
+ fontWeight: 'bold',
2901
+ color,
2902
+ ':active': {
2903
+ color,
2904
+ boxShadow: 'none'
2905
+ },
2906
+ ':focus': {
2907
+ color,
2908
+ outline: 'none',
2909
+ boxShadow: disabled ? theme.controls.buttonBoxShadow : theme.controls.focusOutlineShadow,
2910
+ textDecoration: 'none'
2911
+ },
2912
+ ':visited': {
2913
+ color,
2914
+ },
2915
+ ':hover': {
2916
+ textDecoration: 'none'
2917
+ }
2918
+ }) : undefined,
2919
+ props.variant === 'button' ? css.css({
2920
+ textAlign: 'center',
2921
+ ':hover': {
2922
+ backgroundColor: disabled ? undefined : theme.controls.hoverBackground
2923
+ }
2924
+ }) : undefined,
2925
+ props.variant === 'circle' ? css.css({
2926
+ textAlign: 'center',
2927
+ ':hover': {
2928
+ backgroundColor: disabled ? undefined : theme.controls.hoverBackground
2929
+ },
2930
+ width: props.small ? theme.controls.heightSmall : theme.controls.height,
2931
+ minWidth: props.small ? theme.controls.heightSmall : undefined,
2932
+ borderRadius: '100%',
2933
+ display: 'flex',
2934
+ justifyContent: 'center',
2935
+ alignItems: 'center',
2936
+ }) : undefined,
2937
+ props.variant === 'primary' ? css.css({
2938
+ textAlign: 'center',
2939
+ backgroundColor: theme.colors.primary,
2940
+ color,
2941
+ ':active': {
2942
+ color,
2943
+ },
2944
+ ':focus': {
2945
+ color,
2946
+ },
2947
+ ':visited': {
2948
+ color,
2949
+ }
2950
+ }) : undefined,
2951
+ props.variant === 'primary2' ? css.css({
2952
+ textAlign: 'center',
2953
+ backgroundColor: theme.colors.primary2,
2954
+ color,
2955
+ ':active': {
2956
+ color,
2957
+ },
2958
+ ':focus': {
2959
+ color,
2960
+ },
2961
+ ':visited': {
2962
+ color,
2963
+ }
2964
+ }) : undefined,
2965
+ props.variant === 'secondary' ? css.css({
2966
+ textAlign: 'center',
2967
+ backgroundColor: theme.colors.secondary,
2968
+ color,
2969
+ ':active': {
2970
+ color,
2971
+ },
2972
+ ':focus': {
2973
+ color,
2974
+ },
2975
+ ':visited': {
2976
+ color,
2977
+ }
2978
+ }) : undefined,
2979
+ props.variant === 'positive' ? css.css({
2980
+ textAlign: 'center',
2981
+ backgroundColor: theme.colors.positive,
2982
+ color,
2983
+ ':active': {
2984
+ color,
2985
+ },
2986
+ ':focus': {
2987
+ color,
2988
+ },
2989
+ ':visited': {
2990
+ color,
2991
+ }
2992
+ }) : undefined,
2993
+ props.variant === 'negative' ? css.css({
2994
+ textAlign: 'center',
2995
+ backgroundColor: theme.colors.negative,
2996
+ color,
2997
+ ':active': {
2998
+ color,
2999
+ },
3000
+ ':focus': {
3001
+ color,
3002
+ },
3003
+ ':visited': {
3004
+ color,
3005
+ }
3006
+ }) : undefined,
3007
+ props.variant === 'omg' ? css.css({
3008
+ textAlign: 'center',
3009
+ backgroundColor: theme.colors.omg,
3010
+ color,
3011
+ ':active': {
3012
+ color,
3013
+ },
3014
+ ':focus': {
3015
+ color,
3016
+ },
3017
+ ':visited': {
3018
+ color,
3019
+ }
3020
+ }) : undefined,
3021
+ props.variant === 'label' ? css.css({
3022
+ boxShadow: 'none',
3023
+ border: 'none',
3024
+ ':hover': {
3025
+ backgroundColor: disabled ? undefined : theme.controls.hoverBackground
3026
+ }
3027
+ }) : undefined,
3028
+ props.variant === 'text' ? css.css({
3029
+ fontWeight: 'normal',
3030
+ boxShadow: 'none',
3031
+ border: 'none',
3032
+ cursor: 'auto'
3033
+ }) : undefined,
3034
+ props.variant === 'icon' ? css.css({
3035
+ boxShadow: 'none',
3036
+ border: 'none',
3037
+ borderRadius: '100%',
3038
+ width: theme.controls.height,
3039
+ textAlign: 'center',
3040
+ fontSize: '1.6rem',
3041
+ paddingLeft: 0,
3042
+ paddingRight: 0,
3043
+ ':hover': {
3044
+ backgroundColor: disabled ? undefined : theme.controls.hoverBackground
3045
+ }
3046
+ }) : undefined,
3047
+ props.block ? css.css({
3048
+ display: 'block',
3049
+ width: '100%',
3050
+ }) : undefined,
3051
+ props.iconBlock ? css.css({
3052
+ display: 'flex',
3053
+ justifyContent: 'space-between',
3054
+ alignItems: 'center'
3055
+ }) : undefined,
3056
+ props.round ? css.css({
3057
+ borderRadius: theme.controls.roundRadius
3058
+ }) : undefined,
3059
+ props.small ? css.css({
3060
+ fontSize: '0.8rem',
3061
+ height: theme.controls.heightSmall,
3062
+ lineHeight: theme.controls.heightSmall
3063
+ }) : undefined
3064
+ ]);
3003
3065
  return linkStyles;
3004
3066
  };
3005
3067
 
@@ -3015,7 +3077,11 @@ const OmniLink = (props) => {
3015
3077
  if (props.noRouter) {
3016
3078
  return (React__namespace.createElement("a", Object.assign({}, linkProps, { target: props.target, className: mainClassName }), content));
3017
3079
  }
3018
- return (React__namespace.createElement(reactRouterDom.Link, Object.assign({}, linkProps, { className: mainClassName, to: props.href }), content));
3080
+ const isDisabled = props.disabled || props.waiting;
3081
+ return (React__namespace.createElement(reactRouterDom.Link, Object.assign({}, linkProps, { className: mainClassName, to: props.href, onClick: isDisabled ? e => {
3082
+ e.stopPropagation();
3083
+ e.preventDefault();
3084
+ } : undefined }), content));
3019
3085
  };
3020
3086
 
3021
3087
  const roundPxPadding = '4px';
@@ -3508,6 +3574,8 @@ class ItemPager {
3508
3574
  }
3509
3575
  this.sort = nextSort;
3510
3576
  }
3577
+ /** Filters the current results by the filtering function ONCE.
3578
+ * You will need to re-add the filter if the contents of the filtering function changes. */
3511
3579
  applyFilter(filter, keepPage) {
3512
3580
  this._currentFilter = filter;
3513
3581
  if (!this._currentFilter) {
@@ -3568,6 +3636,10 @@ class ItemPager {
3568
3636
  });
3569
3637
  this.applyFilter(this._currentFilter, true);
3570
3638
  }
3639
+ /** Returns a clone of the underlying PagedResult. */
3640
+ toPagedResult() {
3641
+ return this.createPageResult();
3642
+ }
3571
3643
  createPageResult() {
3572
3644
  const page = new PagedResult([], this._filteredItems.length, this.page, this.limit);
3573
3645
  page.items = this._filteredItems.slice(page.minPageItemIndex, page.maxPageItemIndex + 1) || [];
@@ -4610,14 +4682,18 @@ const enumToEntities = (enumObj) => {
4610
4682
  };
4611
4683
 
4612
4684
  const Link = (props) => {
4613
- const { rightIcon, leftIcon, block, iconBlock, variant, round, small, colorOverride, children, ref } = props, linkProps = __rest(props, ["rightIcon", "leftIcon", "block", "iconBlock", "variant", "round", "small", "colorOverride", "children", "ref"]);
4685
+ const { rightIcon, leftIcon, block, iconBlock, variant, round, small, colorOverride, children, disabled, ref, waiting } = props, linkProps = __rest(props, ["rightIcon", "leftIcon", "block", "iconBlock", "variant", "round", "small", "colorOverride", "children", "disabled", "ref", "waiting"]);
4614
4686
  const theme = useThemeSafely();
4615
4687
  const linkStyles = generateLinkStyles(props, theme);
4616
4688
  const mainClassName = css.cx('link', linkStyles, props.className);
4617
4689
  if (variant === 'text') {
4618
4690
  return React__namespace.createElement(Text, { className: mainClassName, tag: "div" }, props.children);
4619
4691
  }
4620
- return (React__namespace.createElement("a", Object.assign({}, linkProps, { target: props.target, className: mainClassName }),
4692
+ const isDisabled = props.disabled || props.waiting;
4693
+ return (React__namespace.createElement("a", Object.assign({}, linkProps, { tabIndex: disabled ? -1 : undefined, target: props.target, className: mainClassName, onClick: isDisabled ? e => {
4694
+ e.stopPropagation();
4695
+ e.preventDefault();
4696
+ } : undefined }),
4621
4697
  React__namespace.createElement(LinkContent, Object.assign({}, props))));
4622
4698
  };
4623
4699
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mackin.com/styleguide",
3
- "version": "9.9.1",
3
+ "version": "9.11.0",
4
4
  "description": "",
5
5
  "main": "./index.js",
6
6
  "module": "./index.esm.js",