@zuzjs/ui 0.2.4 → 0.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/index.js +214 -15
- package/package.json +4 -2
- package/src/actions/addForm.tsx +0 -0
- package/src/actions/index.tsx +29 -0
- package/src/actions/redo.tsx +1 -0
- package/src/actions/reset.tsx +1 -0
- package/src/actions/undo.tsx +1 -0
- package/src/comps/app.tsx +34 -0
- package/src/comps/box.tsx +23 -0
- package/src/comps/button.tsx +45 -0
- package/src/comps/checkbox.tsx +74 -0
- package/src/comps/component.tsx +32 -0
- package/src/comps/contextmenu.tsx +43 -0
- package/src/comps/cover.tsx +34 -0
- package/src/comps/form.tsx +89 -0
- package/src/comps/heading.tsx +31 -0
- package/src/comps/icon.tsx +36 -0
- package/src/comps/image.tsx +26 -0
- package/src/comps/input.tsx +80 -0
- package/src/comps/masonry.tsx +192 -0
- package/src/comps/placeholder.tsx +58 -0
- package/src/comps/root.tsx +32 -0
- package/src/comps/select.tsx +63 -0
- package/src/comps/spacer.tsx +20 -0
- package/src/comps/spinner.tsx +36 -0
- package/src/comps/text.tsx +27 -0
- package/src/comps/toaster.tsx +115 -0
- package/src/comps/tweet.tsx +48 -0
- package/src/context/AppContext.tsx +3 -0
- package/src/context/AppProvider.tsx +101 -0
- package/src/context/_AppProvider.tsx +116 -0
- package/src/context/combineReducers.tsx +47 -0
- package/src/context/combineState.tsx +14 -0
- package/src/context/createSlice.tsx +40 -0
- package/src/context/index.tsx +6 -0
- package/src/context/reduceReducers.tsx +6 -0
- package/src/context/store/appbase.tsx +19 -0
- package/src/context/store/theme.tsx +53 -0
- package/src/core/defaultTheme.ts +89 -0
- package/src/core/extractCurrentDesignState.tsx +0 -0
- package/src/core/index.ts +285 -0
- package/src/core/router.ts +86 -0
- package/src/core/styles.ts +361 -0
- package/src/hooks/index.tsx +8 -0
- package/src/hooks/useAppReducer.tsx +40 -0
- package/src/hooks/useChooseEffect.tsx +6 -0
- package/src/hooks/useDevice.tsx +164 -0
- package/src/hooks/useDispatch.tsx +37 -0
- package/src/hooks/useImage.tsx +58 -0
- package/src/hooks/useResizeObserver.tsx +84 -0
- package/src/hooks/useRouter.tsx +45 -0
- package/src/hooks/useSelector.tsx +9 -0
- package/src/hooks/useStore.tsx +27 -0
- package/src/hooks/useTheme.tsx +9 -0
- package/src/hooks/useToast.tsx +11 -0
- package/src/index.tsx +33 -0
- package/src/kit/Builder.tsx +18 -0
- package/src/kit/Component.tsx +32 -0
- package/src/kit/Header.tsx +21 -0
- package/src/redux/slices/app.js +26 -0
- package/src/redux/slices/form.js +46 -0
- package/src/redux/store.js +33 -0
- package/src/scss/constants.scss +4 -0
- package/src/scss/mixins.scss +3 -0
- package/src/scss/props.scss +60 -0
- package/src/scss/style.scss +106 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/** External Dependencies */
|
|
2
|
+
import { useCallback, useEffect, useMemo, useRef } from 'react';
|
|
3
|
+
|
|
4
|
+
const useResizeObserver = (onResized) => {
|
|
5
|
+
|
|
6
|
+
const onResize = onResized ? onResized : () => {};
|
|
7
|
+
const onResizeCallback = useRef(onResize);
|
|
8
|
+
const resizeObserver = useRef();
|
|
9
|
+
|
|
10
|
+
const observerCallback = useCallback((entries) => {
|
|
11
|
+
entries.forEach((entry) => {
|
|
12
|
+
if (entry.contentRect) {
|
|
13
|
+
const { width, height } = entry.contentRect;
|
|
14
|
+
|
|
15
|
+
onResizeCallback.current({
|
|
16
|
+
entry,
|
|
17
|
+
width,
|
|
18
|
+
height,
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
}, []);
|
|
23
|
+
|
|
24
|
+
const updateOnResizeCallback = useCallback((newOnResizeCallback) => {
|
|
25
|
+
onResizeCallback.current = newOnResizeCallback;
|
|
26
|
+
}, []);
|
|
27
|
+
|
|
28
|
+
const initObserver = useCallback(() => {
|
|
29
|
+
if (!resizeObserver.current) {
|
|
30
|
+
{/*
|
|
31
|
+
// @ts-ignore */}
|
|
32
|
+
resizeObserver.current = new ResizeObserver(observerCallback);
|
|
33
|
+
}
|
|
34
|
+
}, []);
|
|
35
|
+
|
|
36
|
+
const observeElement = useCallback((element, newOnResizeCallback) => {
|
|
37
|
+
if (element) {
|
|
38
|
+
if (!resizeObserver.current) {
|
|
39
|
+
initObserver();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
{/*
|
|
43
|
+
// @ts-ignore */}
|
|
44
|
+
resizeObserver.current.observe(element);
|
|
45
|
+
|
|
46
|
+
if (newOnResizeCallback) {
|
|
47
|
+
onResizeCallback.current = newOnResizeCallback;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}, []);
|
|
51
|
+
|
|
52
|
+
const unobserveElement = useCallback((element, newOnResizeCallback) => {
|
|
53
|
+
if (resizeObserver.current && element) {
|
|
54
|
+
|
|
55
|
+
{/*
|
|
56
|
+
// @ts-ignore */}
|
|
57
|
+
resizeObserver.current.unobserve(element);
|
|
58
|
+
|
|
59
|
+
if (newOnResizeCallback) {
|
|
60
|
+
onResizeCallback.current = newOnResizeCallback;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}, []);
|
|
64
|
+
|
|
65
|
+
const removeObserver = useCallback(() => {
|
|
66
|
+
if (resizeObserver.current) {
|
|
67
|
+
{/*
|
|
68
|
+
// @ts-ignore */}
|
|
69
|
+
resizeObserver.current.disconnect();
|
|
70
|
+
}
|
|
71
|
+
}, []);
|
|
72
|
+
|
|
73
|
+
useEffect(() => {
|
|
74
|
+
initObserver();
|
|
75
|
+
return removeObserver;
|
|
76
|
+
}, []);
|
|
77
|
+
|
|
78
|
+
return useMemo(
|
|
79
|
+
() => [observeElement, unobserveElement, updateOnResizeCallback],
|
|
80
|
+
[],
|
|
81
|
+
);
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
export default useResizeObserver;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Fragment, Suspense } from 'react'
|
|
2
|
+
import { createBrowserRouter, Outlet, RouterProvider, useLocation } from 'react-router-dom'
|
|
3
|
+
import type { ActionFunction, RouteObject, LoaderFunction } from 'react-router-dom'
|
|
4
|
+
|
|
5
|
+
import { generateModalRoutes, generatePreservedRoutes, generateRegularRoutes } from '../core'
|
|
6
|
+
|
|
7
|
+
type Element = () => JSX.Element
|
|
8
|
+
type Module = { default: Element; Loader?: LoaderFunction; Action?: ActionFunction; Catch?: Element; Pending?: Element }
|
|
9
|
+
|
|
10
|
+
const PRESERVED = import.meta.glob<Module>('/src/pages/(_app|404).{jsx,tsx}', { eager: true })
|
|
11
|
+
const MODALS = import.meta.glob<Pick<Module, 'default'>>('/src/pages/**/[+]*.{jsx,tsx}', { eager: true })
|
|
12
|
+
const ROUTES = import.meta.glob<Module>(['/src/pages/**/[\\w[-]*.{jsx,tsx}', '!**/(_app|404).*'], { eager: true })
|
|
13
|
+
|
|
14
|
+
const preservedRoutes = generatePreservedRoutes<Omit<Module, 'Action'>>(PRESERVED)
|
|
15
|
+
const modalRoutes = generateModalRoutes<Element>(MODALS)
|
|
16
|
+
|
|
17
|
+
const regularRoutes = generateRegularRoutes<RouteObject, Partial<Module>>(ROUTES, (module, key) => {
|
|
18
|
+
const index = /index\.(jsx|tsx)$/.test(key) && !key.includes('pages/index') ? { index: true } : {}
|
|
19
|
+
const Element = module?.default || Fragment
|
|
20
|
+
const Page = () => (module?.Pending ? <Suspense fallback={<module.Pending />} children={<Element />} /> : <Element />)
|
|
21
|
+
return { ...index, Component: Page, ErrorBoundary: module?.Catch, loader: module?.Loader, action: module?.Action }
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
const _app = preservedRoutes?.['_app']
|
|
25
|
+
const _404 = preservedRoutes?.['404']
|
|
26
|
+
|
|
27
|
+
const Element = _app?.default || Fragment
|
|
28
|
+
const App = () => (_app?.Pending ? <Suspense fallback={<_app.Pending />} children={<Element />} /> : <Element />)
|
|
29
|
+
|
|
30
|
+
const app = { Component: _app?.default ? App : Outlet, ErrorBoundary: _app?.Catch, loader: _app?.Loader }
|
|
31
|
+
const fallback = { path: '*', Component: _404?.default || Fragment }
|
|
32
|
+
|
|
33
|
+
export const routes: RouteObject[] = [{ ...app, children: [...regularRoutes, fallback] }]
|
|
34
|
+
export const Routes = () => <RouterProvider router={createBrowserRouter(routes)} />
|
|
35
|
+
|
|
36
|
+
export const Modals = () => {
|
|
37
|
+
const Modal = modalRoutes[useLocation().state?.modal] || Fragment
|
|
38
|
+
return <Modal />
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const useRouter = (root : string) => {
|
|
42
|
+
return Routes;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export default useRouter;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { useContext } from 'react'
|
|
2
|
+
import AppContext from '../context'
|
|
3
|
+
import { STORE_KEY } from '../context/AppProvider'
|
|
4
|
+
|
|
5
|
+
const useStore = (callback? : any, withFilter = true) => {
|
|
6
|
+
// if(withInititalState){
|
|
7
|
+
// return useContext(AppContext)
|
|
8
|
+
// }
|
|
9
|
+
let _state = useContext(AppContext)
|
|
10
|
+
let state = withFilter ? {} : _state
|
|
11
|
+
|
|
12
|
+
if(withFilter){
|
|
13
|
+
const filters = ['defaultState', 'theme', 'dispatch', `${STORE_KEY}base`,`${STORE_KEY}forms`]
|
|
14
|
+
Object.keys(_state).map(k => {
|
|
15
|
+
if(filters.indexOf(k) == -1){
|
|
16
|
+
state[k] = _state[k]
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if("function" == typeof callback){
|
|
22
|
+
return callback(state)
|
|
23
|
+
}
|
|
24
|
+
return state
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export default useStore
|
package/src/index.tsx
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import './scss/style.scss'
|
|
2
|
+
import { Provider, createSlice } from './context'
|
|
3
|
+
|
|
4
|
+
export * from './core/index';
|
|
5
|
+
export * from './hooks/index';
|
|
6
|
+
|
|
7
|
+
export { default as App } from './comps/app'
|
|
8
|
+
export { default as Box } from './comps/box'
|
|
9
|
+
export { default as Button } from './comps/button'
|
|
10
|
+
export { default as Block } from './comps/component'
|
|
11
|
+
export { default as Checkbox } from './comps/checkbox'
|
|
12
|
+
export { default as Cover } from './comps/cover'
|
|
13
|
+
export { default as Form } from './comps/form'
|
|
14
|
+
export { default as Heading } from './comps/heading'
|
|
15
|
+
export { default as Icon } from './comps/icon'
|
|
16
|
+
export { default as Input } from './comps/input'
|
|
17
|
+
export { default as Image } from './comps/image'
|
|
18
|
+
export { default as Masonry } from './comps/masonry'
|
|
19
|
+
export { default as Placeholder } from './comps/placeholder'
|
|
20
|
+
export { default as Toaster } from './comps/toaster'
|
|
21
|
+
export { default as Select } from './comps/select'
|
|
22
|
+
export { default as Spacer } from './comps/spacer'
|
|
23
|
+
export { default as Spinner } from './comps/spinner'
|
|
24
|
+
export { default as Text } from './comps/text'
|
|
25
|
+
export { default as Tweet } from './comps/tweet'
|
|
26
|
+
export { default as ContextMenu } from './comps/contextmenu'
|
|
27
|
+
|
|
28
|
+
export { default as Header } from './kit/Header'
|
|
29
|
+
|
|
30
|
+
export {
|
|
31
|
+
Provider,
|
|
32
|
+
createSlice
|
|
33
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import Box from '../comps/box'
|
|
2
|
+
import { nanoid } from 'nanoid'
|
|
3
|
+
|
|
4
|
+
const buildElement = (el) => {
|
|
5
|
+
switch(el.is){
|
|
6
|
+
case "Box":
|
|
7
|
+
return <Box key={el.key || nanoid()} {...(el.props || {})}>{el.children || null}</Box>
|
|
8
|
+
break;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const buildComponent = (data) => {
|
|
13
|
+
return data.map(e => buildElement(e))
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export {
|
|
17
|
+
buildComponent
|
|
18
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import {
|
|
2
|
+
forwardRef,
|
|
3
|
+
useCallback,
|
|
4
|
+
useEffect
|
|
5
|
+
} from 'react';
|
|
6
|
+
import { Box } from '../index'
|
|
7
|
+
|
|
8
|
+
const Component = forwardRef((props : { [ key: string ] : any }, ref) => {
|
|
9
|
+
|
|
10
|
+
const data = props.data || [
|
|
11
|
+
{ is: 'Box' }
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
const Element = useCallback((el) => {
|
|
15
|
+
switch(el.is){
|
|
16
|
+
case "Box":
|
|
17
|
+
return <Box {...(el.props || {})}>{el.children || null}</Box>
|
|
18
|
+
break;
|
|
19
|
+
}
|
|
20
|
+
}, [])
|
|
21
|
+
|
|
22
|
+
return (
|
|
23
|
+
<>
|
|
24
|
+
{data.map(el => Element(el))}
|
|
25
|
+
</>
|
|
26
|
+
// <Box w={`100vw`} h={60} bg={`#eee`}>
|
|
27
|
+
// {}
|
|
28
|
+
// </Box>
|
|
29
|
+
)
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
export default Component;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import {
|
|
2
|
+
forwardRef,
|
|
3
|
+
useEffect
|
|
4
|
+
} from 'react';
|
|
5
|
+
import { Box } from '../index'
|
|
6
|
+
import { buildComponent } from './Builder'
|
|
7
|
+
|
|
8
|
+
const Header = forwardRef((props : { [ key: string ] : any }, ref) => {
|
|
9
|
+
|
|
10
|
+
const data = [
|
|
11
|
+
{ is: `Box` }
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
return (
|
|
15
|
+
<>
|
|
16
|
+
{buildComponent(data)}
|
|
17
|
+
</>
|
|
18
|
+
)
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
export default Header;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { createSlice } from '@reduxjs/toolkit'
|
|
2
|
+
|
|
3
|
+
export const appSlice = createSlice({
|
|
4
|
+
name: `app`,
|
|
5
|
+
initialState: {
|
|
6
|
+
debug: true,
|
|
7
|
+
loading: true,
|
|
8
|
+
theme: null,
|
|
9
|
+
_tmp: Math.random()
|
|
10
|
+
},
|
|
11
|
+
reducers: {
|
|
12
|
+
setLoading: (state, action) => {
|
|
13
|
+
state.loading = action.payload || false;
|
|
14
|
+
},
|
|
15
|
+
setTheme: (state, action) => { state.theme = action.payload },
|
|
16
|
+
forceUpdate: (state, action) => { state._tmp = Math.random() }
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
export const {
|
|
21
|
+
setLoading,
|
|
22
|
+
setTheme,
|
|
23
|
+
forceUpdate
|
|
24
|
+
} = appSlice.actions;
|
|
25
|
+
|
|
26
|
+
export default appSlice.reducer;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { createSlice } from '@reduxjs/toolkit'
|
|
2
|
+
|
|
3
|
+
export const formSlice = createSlice({
|
|
4
|
+
name: `form`,
|
|
5
|
+
initialState: {
|
|
6
|
+
forms: {}
|
|
7
|
+
},
|
|
8
|
+
reducers: {
|
|
9
|
+
addForm: (state, action) => {
|
|
10
|
+
state.forms[action.payload] = { touched: false, loading: false }
|
|
11
|
+
},
|
|
12
|
+
updateForm: (state, action) => {
|
|
13
|
+
// console.log(action.payload)
|
|
14
|
+
const { name, k, v } = action.payload;
|
|
15
|
+
if(state.forms[name]) state.forms[name][k] = v;
|
|
16
|
+
},
|
|
17
|
+
addFields: (state, action) => {
|
|
18
|
+
const { form, fields } = action.payload;
|
|
19
|
+
if(state.forms[form]) state.forms[form] = { ...state.forms[form], ...fields };
|
|
20
|
+
},
|
|
21
|
+
addField: (state, action) => {
|
|
22
|
+
// console.log('addField', action.payload)
|
|
23
|
+
// state.forms[action.payload.form][action.payload.name] = action.payload.value
|
|
24
|
+
// if(
|
|
25
|
+
// state.forms[action.payload.form] &&
|
|
26
|
+
// !state.forms[action.payload.form][action.payload.name]
|
|
27
|
+
// ){
|
|
28
|
+
// state.forms[action.payload.form][action.payload.name] = action.payload.value
|
|
29
|
+
// }
|
|
30
|
+
},
|
|
31
|
+
updateField: (state, action) => {
|
|
32
|
+
const { form, name, value } = action.payload;
|
|
33
|
+
// console.log(`updatingField: ${form} = ${name} => ${value}`, state.forms[form])
|
|
34
|
+
state.forms[form][name] = value;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
export const {
|
|
40
|
+
addForm,
|
|
41
|
+
updateForm,
|
|
42
|
+
addField,
|
|
43
|
+
addFields,
|
|
44
|
+
updateField
|
|
45
|
+
} = formSlice.actions;
|
|
46
|
+
export default formSlice.reducer;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import {
|
|
2
|
+
configureStore,
|
|
3
|
+
combineReducers
|
|
4
|
+
} from '@reduxjs/toolkit'
|
|
5
|
+
import appReducer from './slices/app'
|
|
6
|
+
import formReducer from './slices/form'
|
|
7
|
+
|
|
8
|
+
const staticReducers = {
|
|
9
|
+
app: appReducer,
|
|
10
|
+
form: formReducer
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const appstore = configureStore({
|
|
14
|
+
reducer: staticReducers,
|
|
15
|
+
middleware: getDefaultMiddleware => getDefaultMiddleware({
|
|
16
|
+
serializableCheck: false
|
|
17
|
+
})
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
appstore.asyncReducers = {}
|
|
21
|
+
appstore.injectReducer = (k, asyncReducer) => {
|
|
22
|
+
appstore.asyncReducers[k] = asyncReducer;
|
|
23
|
+
appstore.replaceReducer(createReducer(appstore.asyncReducers))
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const createReducer = asyncReducers => {
|
|
27
|
+
return combineReducers({
|
|
28
|
+
...staticReducers,
|
|
29
|
+
...asyncReducers
|
|
30
|
+
})
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export default appstore;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
*, *:before, *:after{
|
|
2
|
+
-moz-box-sizing: border-box;
|
|
3
|
+
-webkit-box-sizing: border-box;
|
|
4
|
+
box-sizing: border-box;
|
|
5
|
+
}
|
|
6
|
+
*, html, body, div, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, pre, form, label, fieldset, input, p, blockquote, th, td{margin: 0;padding: 0;}
|
|
7
|
+
table{border-collapse: collapse; border-spacing: 0;}
|
|
8
|
+
fieldset, img {border: 0}
|
|
9
|
+
address, caption, cite, code, dfn, em, strong, th, var {font-style: normal; font-weight: normal}
|
|
10
|
+
ol, ul, li{list-style: none;}
|
|
11
|
+
caption, th{text-align: left;}
|
|
12
|
+
h1, h2, h3, h4, h5, h6{font-size: 100%; font-weight: normal;}
|
|
13
|
+
div, img, button, input, textarea, select{outline: none}
|
|
14
|
+
strong{font-weight: bold}
|
|
15
|
+
em{font-style: italic;}
|
|
16
|
+
a img{border: none;}
|
|
17
|
+
|
|
18
|
+
*, .f{ font-family: var(--primary-font); }
|
|
19
|
+
.fb{ font-family: var(--primary-font-bold); }
|
|
20
|
+
|
|
21
|
+
button{cursor: pointer;}
|
|
22
|
+
.fixed{ position: fixed; }
|
|
23
|
+
.block{display: block;}
|
|
24
|
+
.iblock{display: inline-block;}
|
|
25
|
+
.tdn{ text-decoration: none; }
|
|
26
|
+
.tdh:hover{ text-decoration: underline; }
|
|
27
|
+
.cprimary, .color{ color: var(--primary-color); }
|
|
28
|
+
.primary{ background-color: var(--primary-color); }
|
|
29
|
+
.tdnh, .tdn{ text-decoration: none; }
|
|
30
|
+
.tdnh:hover{ text-decoration: underline; }
|
|
31
|
+
.flex{
|
|
32
|
+
display: flex;
|
|
33
|
+
&.ass{align-self: flex-start;}
|
|
34
|
+
&.asc{align-self: center;}
|
|
35
|
+
&.ase{align-self: flex-end;}
|
|
36
|
+
&.ais{align-items: flex-start;}
|
|
37
|
+
&.aic{align-items: center;}
|
|
38
|
+
&.aie{align-items: flex-end;}
|
|
39
|
+
&.jcs{justify-content: flex-start;}
|
|
40
|
+
&.jcc{justify-content: center;}
|
|
41
|
+
&.jce{justify-content: flex-end;}
|
|
42
|
+
}
|
|
43
|
+
/*
|
|
44
|
+
COLORS
|
|
45
|
+
It will generate .cfff { color: #fff; } from 'fff'
|
|
46
|
+
*/
|
|
47
|
+
$colors: 'fff','111','222','333','444','555','666','777','888','999';
|
|
48
|
+
@each $n in $colors{
|
|
49
|
+
.c#{$n} { color: unquote("#"+#{$n}); }
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/*
|
|
53
|
+
FONT SIZES
|
|
54
|
+
It will generate .s10 { font-size: 12px; } from '12'
|
|
55
|
+
*/
|
|
56
|
+
@for $i from 10 through 72 {
|
|
57
|
+
@if $i % 2 == 0 {
|
|
58
|
+
.s#{$i} { font-size: #{$i}px; }
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
@import './constants.scss';
|
|
2
|
+
@import './mixins.scss';
|
|
3
|
+
@import './props.scss';
|
|
4
|
+
|
|
5
|
+
@-webkit-keyframes rotating /* Safari and Chrome */ {
|
|
6
|
+
from {
|
|
7
|
+
-webkit-transform: rotate(0deg);
|
|
8
|
+
-o-transform: rotate(0deg);
|
|
9
|
+
transform: rotate(0deg);
|
|
10
|
+
}
|
|
11
|
+
to {
|
|
12
|
+
-webkit-transform: rotate(360deg);
|
|
13
|
+
-o-transform: rotate(360deg);
|
|
14
|
+
transform: rotate(360deg);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
@keyframes rotating {
|
|
18
|
+
from {
|
|
19
|
+
-ms-transform: rotate(0deg);
|
|
20
|
+
-moz-transform: rotate(0deg);
|
|
21
|
+
-webkit-transform: rotate(0deg);
|
|
22
|
+
-o-transform: rotate(0deg);
|
|
23
|
+
transform: rotate(0deg);
|
|
24
|
+
}
|
|
25
|
+
to {
|
|
26
|
+
-ms-transform: rotate(360deg);
|
|
27
|
+
-moz-transform: rotate(360deg);
|
|
28
|
+
-webkit-transform: rotate(360deg);
|
|
29
|
+
-o-transform: rotate(360deg);
|
|
30
|
+
transform: rotate(360deg);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
.rotating {
|
|
34
|
+
-webkit-animation: rotating 2s linear infinite;
|
|
35
|
+
-moz-animation: rotating 2s linear infinite;
|
|
36
|
+
-ms-animation: rotating 2s linear infinite;
|
|
37
|
+
-o-animation: rotating 2s linear infinite;
|
|
38
|
+
animation: rotating 2s linear infinite;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.button{
|
|
42
|
+
background: var(--primary-color);
|
|
43
|
+
color: #fff;
|
|
44
|
+
border: 0px;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.zuz-toast{
|
|
48
|
+
border-radius: 5px;
|
|
49
|
+
@include anim($duration: 0.15s);
|
|
50
|
+
&.hidden{
|
|
51
|
+
transform: translate(-50%, -300px) scale(0.5) !important;
|
|
52
|
+
}
|
|
53
|
+
&.showing{
|
|
54
|
+
transform: translate(-50%, -50px) scale(0.9) !important;
|
|
55
|
+
}
|
|
56
|
+
&.visible{
|
|
57
|
+
transform: translate(-50%, 0px) scale(1) !important;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.zuz-checkbox{
|
|
62
|
+
opacity: 0; // hides checkbox
|
|
63
|
+
position: absolute;
|
|
64
|
+
& + label {
|
|
65
|
+
position: relative;
|
|
66
|
+
display: inline-block;
|
|
67
|
+
user-select: none;
|
|
68
|
+
transition: .4s ease;
|
|
69
|
+
height: 26px;
|
|
70
|
+
width: 44px;
|
|
71
|
+
border-radius: 60px;
|
|
72
|
+
background: #eee;
|
|
73
|
+
&:before {
|
|
74
|
+
content: "";
|
|
75
|
+
position: absolute;
|
|
76
|
+
display: block;
|
|
77
|
+
transition: .2s cubic-bezier(.24, 0, .5, 1);
|
|
78
|
+
height: 26px;
|
|
79
|
+
width: 44px;
|
|
80
|
+
top: 0;
|
|
81
|
+
left: 0;
|
|
82
|
+
border-radius: 30px;
|
|
83
|
+
}
|
|
84
|
+
&:after {
|
|
85
|
+
content: "";
|
|
86
|
+
position: absolute;
|
|
87
|
+
display: block;
|
|
88
|
+
transition: .35s cubic-bezier(.54, 1.60, .5, 1);
|
|
89
|
+
background: #fff;
|
|
90
|
+
height: 22px;
|
|
91
|
+
width: 22px;
|
|
92
|
+
top: 2px;
|
|
93
|
+
left: 2px;
|
|
94
|
+
border-radius: 60px;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
&:checked {
|
|
98
|
+
& + label:before {
|
|
99
|
+
background: green; // Active Color
|
|
100
|
+
transition: width .2s cubic-bezier(0, 0, 0, .1);
|
|
101
|
+
}
|
|
102
|
+
& + label:after {
|
|
103
|
+
left: 20px;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|