@ainias42/react-bootstrap-mobile 0.1.32 → 0.2.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.
@@ -1,2 +1,2 @@
1
- import { useLayoutEffect } from "react";
2
- export declare function useClientLayoutEffect(...params: Parameters<typeof useLayoutEffect>): void;
1
+ import React from "react";
2
+ export declare function useClientLayoutEffect(...params: Parameters<typeof React.useLayoutEffect>): void;
@@ -0,0 +1,11 @@
1
+ /// <reference types="react" />
2
+ export declare const ToastContext: import("react").Context<(<Data>(text: string, action?: {
3
+ name: string;
4
+ onClick: (data?: Data) => void;
5
+ onClickData?: Data;
6
+ }, duration?: number) => void)>;
7
+ export declare function useToast(): <Data>(text: string, action?: {
8
+ name: string;
9
+ onClick: (data?: Data | undefined) => void;
10
+ onClickData?: Data | undefined;
11
+ } | undefined, duration?: number | undefined) => void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ainias42/react-bootstrap-mobile",
3
- "version": "0.1.32",
3
+ "version": "0.2.0",
4
4
  "description": "Mobile React Components using Bootstrap",
5
5
  "main": "dist/bootstrapReactMobile",
6
6
  "scripts": {
@@ -1,6 +1,6 @@
1
1
  @import "src/scss/variables";
2
- @import "src/scss/mobileMixin";
2
+ @import "src/scss/designMixin";
3
+ @import "src/scss/flavorMixin";
3
4
  @import "src/scss/default";
4
- @import "src/scss/animations";
5
5
  @import "src/scss/baseClasses";
6
6
  @import "src/scss/colors";
@@ -1,9 +1,9 @@
1
1
  import * as React from 'react';
2
- import {ComponentType, ForwardedRef, PropsWithChildren, useCallback, useImperativeHandle, useState} from 'react';
2
+ import { ComponentType, ForwardedRef, PropsWithChildren, useCallback, useImperativeHandle, useState } from 'react';
3
3
  import { PromiseWithHandlers } from '@ainias42/js-helper';
4
4
  import { DialogProvider, ShowDialog } from './DialogContext';
5
5
  import { Dialog } from './Dialog';
6
- import {withForwardRef} from "../../helper/withForwardRef";
6
+ import { withForwardRef } from "../../helper/withForwardRef";
7
7
  import { Block } from "../Layout/Block";
8
8
 
9
9
  export type DialogContainerProps = PropsWithChildren<{
@@ -21,7 +21,10 @@ export type DialogContainerRef = {
21
21
  showDialog: ShowDialog;
22
22
  }
23
23
 
24
- export const DialogContainer = withForwardRef(function DialogContainer({ children, dialogClassName }: DialogContainerProps, ref: ForwardedRef<DialogContainerRef>) {
24
+ export const DialogContainer = withForwardRef(function DialogContainer({
25
+ children,
26
+ dialogClassName
27
+ }: DialogContainerProps, ref: ForwardedRef<DialogContainerRef>) {
25
28
  // Variables
26
29
  const [dialogs, setDialogs] = useState<DialogData[]>([]);
27
30
  const [, setLastId] = useState(0);
@@ -38,7 +41,7 @@ export const DialogContainer = withForwardRef(function DialogContainer({ childre
38
41
  setLastId((oldId) => {
39
42
  const id = oldId + 1;
40
43
  setDialogs((oldDialogs) => {
41
- return [...oldDialogs, { id, component, props, resultPromise: promise }] as DialogData[];
44
+ return [...oldDialogs, {id, component, props, resultPromise: promise}] as DialogData[];
42
45
  });
43
46
  return id;
44
47
  });
@@ -71,14 +74,14 @@ export const DialogContainer = withForwardRef(function DialogContainer({ childre
71
74
  <DialogProvider value={showDialog}>
72
75
  {children}
73
76
  <Block className={dialogClassName}>
74
- {dialogs.map((d) => {
75
- const DialogComponent = d.component;
76
- return (
77
- <Dialog {...d.props} key={d.id} onClose={onClose} identifier={d.id}>
78
- <DialogComponent {...d.props} />
79
- </Dialog>
80
- );
81
- })}
77
+ {dialogs.map((d) => {
78
+ const DialogComponent = d.component;
79
+ return (
80
+ <Dialog {...d.props} key={d.id} onClose={onClose} identifier={d.id}>
81
+ <DialogComponent {...d.props} />
82
+ </Dialog>
83
+ );
84
+ })}
82
85
  </Block>
83
86
  </DialogProvider>
84
87
  );
@@ -12,7 +12,10 @@ export type ShowDialog = <
12
12
  props?: Omit<P, 'close'>
13
13
  ) => Promise<R | void>;
14
14
 
15
- const DialogContext = React.createContext<ShowDialog>(() => Promise.reject());
15
+ const DialogContext = React.createContext<ShowDialog>(() => {
16
+ console.error("DialogContext not initialized");
17
+ return Promise.reject("DialogContext not initialized")
18
+ });
16
19
  export const DialogProvider = DialogContext.Provider;
17
20
 
18
21
  export function useDialog() {
@@ -5,7 +5,7 @@ import {
5
5
  KeyboardEvent,
6
6
  MutableRefObject,
7
7
  useCallback, useEffect,
8
- useMemo, useRef,
8
+ useMemo,
9
9
  } from 'react';
10
10
  import { RbmComponentProps } from '../../RbmComponentProps';
11
11
  import { Override } from '../../../TypeHelpers';
@@ -1,8 +1,8 @@
1
- import { useLayoutEffect } from "react";
1
+ import React from "react";
2
2
 
3
- export function useClientLayoutEffect(...params: Parameters<typeof useLayoutEffect>) {
3
+ export function useClientLayoutEffect(...params: Parameters<typeof React.useLayoutEffect>) {
4
4
  if (typeof window !== 'undefined') {
5
5
  // eslint-disable-next-line react-hooks/exhaustive-deps,react-hooks/rules-of-hooks
6
- useLayoutEffect(...params);
6
+ React.useLayoutEffect(...params);
7
7
  }
8
8
  }
@@ -1,7 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import { ComponentRef, ForwardedRef, PropsWithChildren } from 'react';
3
3
  import { Override } from '../../TypeHelpers';
4
- import { withMemo } from "../../helper/withMemo";
5
4
  import { withForwardRef } from "../../helper/withForwardRef";
6
5
 
7
6
  export type ViewProps<AsType extends keyof JSX.IntrinsicElements> = PropsWithChildren<
@@ -1,7 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import { ComponentRef, DOMAttributes, ForwardedRef } from 'react';
3
3
  import { View, ViewProps } from './View';
4
- import { withMemo } from "../../helper/withMemo";
5
4
  import { withForwardRef } from "../../helper/withForwardRef";
6
5
 
7
6
  export type ViewWithoutListenersProps<AsType extends keyof JSX.IntrinsicElements> = Omit<
@@ -6,17 +6,61 @@ import styles from './toast.scss';
6
6
  import classNames from 'classnames';
7
7
  import { withMemo } from '../../helper/withMemo';
8
8
  import { EmptyProps } from '../../helper/EmptyProps';
9
+ import { useCallback, useRef, useState } from "react";
10
+ import { ObjectHelper, URecord } from "@ainias42/js-helper";
11
+ import { Toast } from "./Toast";
12
+ import { Text } from "../Text/Text";
13
+ import { ToastContext } from "./ToastContext";
9
14
 
10
15
  export type ToastContainerProps = RbmComponentProps<EmptyProps>;
11
16
 
12
- function ToastContainer({ className, children, style }: ToastContainerProps) {
17
+ function ToastContainer({className, children, style}: ToastContainerProps) {
13
18
  // Variables
14
19
 
15
20
  // States
21
+ const lastId = useRef(0);
22
+ const [toasts, setToasts] = useState<URecord<number, {
23
+ id: number,
24
+ text: string,
25
+ duration: number,
26
+ action?: { name: string, onClick: (data?: any) => void, onClickData?: any }
27
+ }>>({});
16
28
 
17
29
  // Refs
18
30
 
19
31
  // Callbacks
32
+ const removeToast = useCallback((id: number) => {
33
+ setToasts((oldToasts) => {
34
+ const newToasts = {...oldToasts};
35
+ delete newToasts[id];
36
+ return newToasts;
37
+ });
38
+ }, []);
39
+
40
+ const addToast = useCallback((
41
+ text: string,
42
+ action?: {
43
+ name: string,
44
+ onClick: (data?: any) => void,
45
+ onClickData?: any
46
+ },
47
+ duration = 2500
48
+ ) => {
49
+ lastId.current++;
50
+ const id = lastId.current;
51
+
52
+ setToasts((oldToasts) => {
53
+ return {
54
+ ...oldToasts,
55
+ [id]: {
56
+ id,
57
+ text,
58
+ duration,
59
+ action
60
+ }
61
+ };
62
+ });
63
+ }, []);
20
64
 
21
65
  // Effects
22
66
 
@@ -25,9 +69,21 @@ function ToastContainer({ className, children, style }: ToastContainerProps) {
25
69
  // Render Functions
26
70
 
27
71
  return (
28
- <Container className={classNames(styles.toastContainer, className)} fluid __allowChildren="all" style={style}>
72
+ <ToastContext.Provider value={addToast}>
29
73
  {children}
30
- </Container>
74
+ <Container className={classNames(styles.toastContainer, className)} fluid __allowChildren="all"
75
+ style={style}>
76
+ {ObjectHelper.values(toasts).map((toast) => <Toast key={toast.id}
77
+ timeToShow={toast.duration}
78
+ onDismissed={removeToast}
79
+ onDismissedData={toast.id} {...(toast.action ? {
80
+ ...toast.action,
81
+ actionName: toast.action.name
82
+ } : {})}>
83
+ <Text>{toast.text}</Text>
84
+ </Toast>)}
85
+ </Container>
86
+ </ToastContext.Provider>
31
87
  );
32
88
  }
33
89
 
@@ -0,0 +1,9 @@
1
+ import { createContext, useContext } from "react";
2
+
3
+ export const ToastContext = createContext<<Data>(text: string, action?: {name: string, onClick: (data?: Data) => void, onClickData?: Data }, duration?: number) => void>(() => {
4
+ console.error("ToastContext not initialized");
5
+ });
6
+
7
+ export function useToast() {
8
+ return useContext(ToastContext);
9
+ }
@@ -1,5 +1,4 @@
1
1
  import * as React from 'react';
2
- import { useCallback } from 'react';
3
2
  import { RbmComponentProps } from '../RbmComponentProps';
4
3
 
5
4
  import styles from './topBar.scss';
@@ -12,13 +11,12 @@ export type TopBarButtonProps = RbmComponentProps<{
12
11
  }>;
13
12
 
14
13
  function TopBarButton({ disabled = false, onClick, className, children, ...rbmProps }: TopBarButtonProps) {
15
- const cb = useCallback(() => (onClick ? onClick() : null), [onClick]);
16
14
  return (
17
15
  <a
18
16
  role="button"
19
17
  {...rbmProps}
20
- onClick={cb}
21
- className={classNames(styles.button, { [styles.disabled]: disabled }, className)}
18
+ onClick={onClick}
19
+ className={classNames(styles.button, { [styles.disabled]: disabled, [styles.active]: !disabled && onClick }, className)}
22
20
  >
23
21
  {children}
24
22
  </a>
@@ -24,6 +24,10 @@
24
24
  }
25
25
 
26
26
  .button {
27
+ &.active {
28
+ cursor: pointer;
29
+ }
30
+
27
31
  display: block;
28
32
  padding: 0.5rem 1rem;
29
33
  color: #0d3efd; // TODO change color
@@ -1,26 +1,26 @@
1
- .full-height {
1
+ :global(.full-height) {
2
2
  height: 100%;
3
3
  }
4
4
 
5
- .full-min-height {
5
+ :global(.full-min-height) {
6
6
  min-height: 100%;
7
7
  }
8
8
 
9
- .scrollable {
9
+ :global(.scrollable) {
10
10
  overflow-y: auto;
11
11
  }
12
12
 
13
- .full-width {
13
+ :global(.full-width) {
14
14
  width: 100%;
15
15
  }
16
16
 
17
- .flat-hidden {
17
+ :global(.flat-hidden) {
18
18
  @include design($flat) {
19
19
  display: none;
20
20
  }
21
21
  }
22
22
 
23
- .material-hidden {
23
+ :global(.material-hidden) {
24
24
  @include design($material) {
25
25
  display: none;
26
26
  }
@@ -1,3 +1,5 @@
1
+ @import "designMixin";
2
+
1
3
  * {
2
4
  box-sizing: border-box;
3
5
  -webkit-font-smoothing: antialiased;
@@ -1,5 +1,5 @@
1
- @import 'bootstrap/scss/functions';
2
- @import 'bootstrap/scss/variables';
1
+ @import '~bootstrap/scss/functions';
2
+ @import '~bootstrap/scss/variables';
3
3
 
4
4
  $classPrefix: "rbm-";
5
5
 
package/webpack.config.js CHANGED
@@ -28,7 +28,7 @@ module.exports = (env) => {
28
28
  output: {
29
29
  filename: 'bootstrapReactMobile.js',
30
30
  path: path.resolve(__dirname, 'dist'),
31
- library: { type: 'umd' },
31
+ library: { type: 'commonjs-static' },
32
32
  clean: true,
33
33
  globalObject: 'this',
34
34
  },
@@ -1,46 +0,0 @@
1
- @keyframes material-new-site {
2
- 0% {
3
- transform: translate(0, 100%);
4
- z-index: 1;
5
- }
6
- 100% {
7
- transform: translate(0, 0);
8
- z-index: 1;
9
- }
10
- }
11
-
12
- @keyframes flat-new-site {
13
- 0% {
14
- transform: translate(100%, 0);
15
- z-index: 1;
16
- }
17
- 100% {
18
- transform: translate(0, 0);
19
- z-index: 1;
20
- }
21
- }
22
-
23
- .animation-new-site {
24
- background: green;
25
- @include design($material) {
26
- animation: material-new-site;
27
- animation-duration: $animationDurationMaterial;
28
- }
29
- @include design($flat) {
30
- animation: flat-new-site;
31
- animation-duration: $animationDurationMaterial;
32
- }
33
- }
34
-
35
- .animation-end-site {
36
- @include design($material) {
37
- animation: material-new-site;
38
- animation-duration: $animationDurationMaterial;
39
- animation-direction: reverse;
40
- }
41
- @include design($flat) {
42
- animation: flat-new-site;
43
- animation-duration: $animationDurationMaterial;
44
- animation-direction: reverse;
45
- }
46
- }
@@ -1,35 +0,0 @@
1
- @use 'sass:selector';
2
-
3
- @mixin design($designName) {
4
- @if & {
5
- @at-root #{selector.nest('.'+$designName, &)} {
6
- @content
7
- }
8
- } @else {
9
- .#{$designName} {
10
- @content
11
- }
12
- }
13
- }
14
-
15
- @mixin subPrefix($className) {
16
- .#{$classPrefix+$className} {
17
- @content
18
- }
19
- }
20
-
21
- @mixin prefix($className, $concatSelectors: false) {
22
- @if $concatSelectors == true {
23
- &.#{$classPrefix+$className} {
24
- @content
25
- }
26
- } @else if ($concatSelectors != false) {
27
- #{$concatSelectors}.#{$classPrefix+$className} {
28
- @content
29
- }
30
- } @else {
31
- @include subPrefix($className) {
32
- @content
33
- }
34
- }
35
- }